Skip to content

Commit 77a0a2c

Browse files
committed
frontend: Extract activitySlice into a separate file
1 parent 93b5426 commit 77a0a2c

File tree

5 files changed

+115
-95
lines changed

5 files changed

+115
-95
lines changed

frontend/src/components/activity/Activity.stories.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import { Meta, StoryFn } from '@storybook/react';
1919
import { Provider } from 'react-redux';
2020
import { MemoryRouter } from 'react-router-dom';
2121
import store from '../../redux/stores/store';
22-
import { ActivitiesRenderer, Activity, activitySlice } from './Activity';
22+
import { ActivitiesRenderer, Activity } from './Activity';
23+
import { activitySlice } from './activitySlice';
2324

2425
export default {
2526
title: 'Activity',

frontend/src/components/activity/Activity.test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { Activity, activitySlice, ActivityState } from './Activity';
17+
import { Activity } from './Activity';
18+
import { activitySlice, ActivityState } from './activitySlice';
1819

1920
const { reducer, actions } = activitySlice;
2021
const { launchActivity, close, update } = actions;

frontend/src/components/activity/Activity.tsx

Lines changed: 1 addition & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import {
2525
useMediaQuery,
2626
useTheme,
2727
} from '@mui/material';
28-
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
2928
import { clamp, throttle } from 'lodash';
3029
import React, {
3130
createContext,
@@ -43,6 +42,7 @@ import { useHotkeys } from 'react-hotkeys-hook';
4342
import { Trans, useTranslation } from 'react-i18next';
4443
import { useTypedSelector } from '../../redux/hooks';
4544
import store from '../../redux/stores/store';
45+
import { activitySlice } from './activitySlice';
4646

4747
const areWindowsEnabled = false;
4848

@@ -74,97 +74,6 @@ export interface Activity {
7474
cluster?: string;
7575
}
7676

77-
export interface ActivityState {
78-
/** History of opened activites, list of IDs */
79-
history: string[];
80-
/** Map of all open activities, key is the ID */
81-
activities: Record<string, Activity>;
82-
}
83-
84-
const initialState: ActivityState = {
85-
history: [],
86-
activities: {},
87-
};
88-
89-
export const activitySlice = createSlice({
90-
name: 'activity',
91-
initialState,
92-
reducers: {
93-
launchActivity(state, action: PayloadAction<Activity>) {
94-
// Add to history
95-
if (!action.payload.minimized) {
96-
state.history = state.history.filter(it => it !== action.payload.id);
97-
state.history.push(action.payload.id);
98-
}
99-
100-
// Close other temporary tabs
101-
Object.values(state.activities).forEach(activity => {
102-
if (activity.temporary) {
103-
delete state.activities[activity.id];
104-
state.history = state.history.filter(it => it !== activity.id);
105-
}
106-
});
107-
108-
if (!state.activities[action.payload.id]) {
109-
// New activity, add it to the state
110-
state.activities[action.payload.id] = action.payload;
111-
} else {
112-
// Existing activity, un-minimize it
113-
state.activities[action.payload.id].minimized = false;
114-
}
115-
116-
// Make it fullscreen on small windows
117-
if (window.innerWidth < 1280) {
118-
state.activities[action.payload.id] = {
119-
...state.activities[action.payload.id],
120-
location: 'full',
121-
};
122-
}
123-
124-
// Dispatch resize event so the content adjusts
125-
// 200ms delay for animations
126-
setTimeout(() => {
127-
window?.dispatchEvent?.(new Event('resize'));
128-
}, 200);
129-
},
130-
close(state, action: PayloadAction<string>) {
131-
// Remove the activity from history
132-
state.history = state.history.filter(it => it !== action.payload);
133-
// Remove from state
134-
delete state.activities[action.payload];
135-
},
136-
update(state, action: PayloadAction<Partial<Activity> & { id: string }>) {
137-
// Bump this activity in history
138-
if (!action.payload.minimized) {
139-
state.history = state.history.filter(it => it !== action.payload.id);
140-
state.history.push(action.payload.id);
141-
}
142-
143-
// Remove from history it it's minimized
144-
if (action.payload.minimized) {
145-
state.history = state.history.filter(it => it !== action.payload.id);
146-
}
147-
148-
// Update the state
149-
state.activities[action.payload.id] = {
150-
...state.activities[action.payload.id],
151-
...action.payload,
152-
};
153-
154-
// Dispatch resize event so the content adjusts
155-
// 200ms delay for animations
156-
setTimeout(() => {
157-
window?.dispatchEvent?.(new Event('resize'));
158-
}, 200);
159-
},
160-
reset() {
161-
return initialState;
162-
},
163-
},
164-
});
165-
166-
export const activityReducer = activitySlice.reducer;
167-
16877
export const Activity = {
16978
/** Launches new Activity */
17079
launch(activity: Activity) {
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright 2025 The Kubernetes Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
18+
import type { Activity } from './Activity';
19+
20+
export interface ActivityState {
21+
/** History of opened activities, list of IDs */
22+
history: string[];
23+
/** Map of all open activities, key is the ID */
24+
activities: Record<string, Activity>;
25+
}
26+
27+
const initialState: ActivityState = {
28+
history: [],
29+
activities: {},
30+
};
31+
32+
export const activitySlice = createSlice({
33+
name: 'activity',
34+
initialState,
35+
reducers: {
36+
launchActivity(state, action: PayloadAction<Activity>) {
37+
// Add to history
38+
if (!action.payload.minimized) {
39+
state.history = state.history.filter(it => it !== action.payload.id);
40+
state.history.push(action.payload.id);
41+
}
42+
43+
// Close other temporary tabs
44+
Object.values(state.activities).forEach(activity => {
45+
if (activity.temporary) {
46+
delete state.activities[activity.id];
47+
state.history = state.history.filter(it => it !== activity.id);
48+
}
49+
});
50+
51+
if (!state.activities[action.payload.id]) {
52+
// New activity, add it to the state
53+
state.activities[action.payload.id] = action.payload;
54+
} else {
55+
// Existing activity, un-minimize it
56+
state.activities[action.payload.id].minimized = false;
57+
}
58+
59+
// Make it fullscreen on small windows
60+
if (window.innerWidth < 1280) {
61+
state.activities[action.payload.id] = {
62+
...state.activities[action.payload.id],
63+
location: 'full',
64+
};
65+
}
66+
67+
// Dispatch resize event so the content adjusts
68+
// 200ms delay for animations
69+
setTimeout(() => {
70+
window?.dispatchEvent?.(new Event('resize'));
71+
}, 200);
72+
},
73+
close(state, action: PayloadAction<string>) {
74+
// Remove the activity from history
75+
state.history = state.history.filter(it => it !== action.payload);
76+
// Remove from state
77+
delete state.activities[action.payload];
78+
},
79+
update(state, action: PayloadAction<Partial<Activity> & { id: string }>) {
80+
// Bump this activity in history
81+
if (!action.payload.minimized) {
82+
state.history = state.history.filter(it => it !== action.payload.id);
83+
state.history.push(action.payload.id);
84+
}
85+
86+
// Remove from history if it's minimized
87+
if (action.payload.minimized) {
88+
state.history = state.history.filter(it => it !== action.payload.id);
89+
}
90+
91+
// Update the state
92+
state.activities[action.payload.id] = {
93+
...state.activities[action.payload.id],
94+
...action.payload,
95+
};
96+
97+
// Dispatch resize event so the content adjusts
98+
// 200ms delay for animations
99+
setTimeout(() => {
100+
window?.dispatchEvent?.(new Event('resize'));
101+
}, 200);
102+
},
103+
reset() {
104+
return initialState;
105+
},
106+
},
107+
});
108+
109+
export const activityReducer = activitySlice.reducer;

frontend/src/redux/reducers/reducers.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
import { combineReducers } from 'redux';
18-
import { activityReducer } from '../../components/activity/Activity';
18+
import { activityReducer } from '../../components/activity/activitySlice';
1919
import notificationsReducer from '../../components/App/Notifications/notificationsSlice';
2020
import themeReducer from '../../components/App/themeSlice';
2121
import graphViewReducer from '../../components/resourceMap/graphViewSlice';

0 commit comments

Comments
 (0)