Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Commit 5530ccf

Browse files
author
noah
committed
Add the state for the activities page
1 parent 16ee740 commit 5530ccf

File tree

5 files changed

+129
-10
lines changed

5 files changed

+129
-10
lines changed

ui/src/apis/deployment.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ export const searchDeployments = async (statuses: DeploymentStatusEnum[], owned:
157157
})
158158

159159
const fromParam = (from)? `from=${from.toISOString()}` : ""
160-
const toParam = (to)? `&to=to.toISOString()` : ""
160+
const toParam = (to)? `&to=${to.toISOString()}` : ""
161161

162162
const deployments: Deployment[] = await _fetch(`${instance}/api/v1/search/deployments?statuses=${ss.join(",")}&owned=${owned}&${fromParam}&${toParam}&page=${page}&per_page=${perPage}`, {
163163
headers,

ui/src/components/SearchActivities.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Form, DatePicker, Button, Switch } from "antd"
22
import moment from "moment"
33

44
interface SearchActivitiesProps {
5-
onChangePeriod(start: moment.Moment, end: moment.Moment): void
5+
onChangePeriod(start: Date, end: Date): void
66
onClickSearch(): void
77
}
88

@@ -11,21 +11,27 @@ export default function SearchActivities(props: SearchActivitiesProps): JSX.Elem
1111
<Form
1212
layout="inline"
1313
>
14-
<Form.Item label="Period" required>
14+
<Form.Item label="Period">
1515
<DatePicker.RangePicker
1616
format="YYYY-MM-DD HH:mm"
1717
showTime={{
1818
showSecond: false,
1919
defaultValue: [moment().hour(0).minute(0), moment().hour(23).minute(59)],
2020
}}
21-
onChange={(_, dateStrings) => props.onChangePeriod(moment(dateStrings[0]), moment(dateStrings[1])) }
21+
onChange={(_, dateStrings) => props.onChangePeriod(new Date(dateStrings[0]), new Date(dateStrings[1])) }
2222
/>
2323
</Form.Item>
2424
<Form.Item label="Production">
2525
<Switch size="small" />
2626
</Form.Item>
2727
<Form.Item >
28-
<Button type="primary" onClick={props.onClickSearch}>Search</Button>
28+
<Button
29+
htmlType="submit"
30+
type="primary"
31+
onClick={props.onClickSearch}
32+
>
33+
Search
34+
</Button>
2935
</Form.Item>
3036
</Form>
3137
)

ui/src/redux/activities.tsx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit"
2+
3+
import {
4+
searchDeployments as _searchDeployments,
5+
} from "../apis"
6+
import { Deployment, } from "../models"
7+
8+
export const perPage = 30
9+
10+
interface ActivitiesState {
11+
start?: Date
12+
end?: Date
13+
loading: boolean
14+
deployments: Deployment[]
15+
page: number
16+
}
17+
18+
const initialState: ActivitiesState = {
19+
loading: false,
20+
deployments: [],
21+
page: 1,
22+
}
23+
24+
export const searchDeployments = createAsyncThunk<Deployment[], void, { state: { activities: ActivitiesState } }>(
25+
"activities/searchDeployments",
26+
async (_, { getState, rejectWithValue }) => {
27+
const {start, end, page} = getState().activities
28+
try {
29+
return await _searchDeployments([], false, start, end, page, perPage)
30+
} catch (e) {
31+
return rejectWithValue(e)
32+
}
33+
}
34+
)
35+
36+
export const activitiesSlice = createSlice({
37+
name: "activities",
38+
initialState,
39+
reducers: {
40+
setStart: (state, action: PayloadAction<Date>) => {
41+
state.start = action.payload
42+
},
43+
setEnd: (state, action: PayloadAction<Date>) => {
44+
state.end = action.payload
45+
},
46+
increasePage: (state) => {
47+
state.page = state.page + 1
48+
},
49+
decreasePage: (state) => {
50+
state.page = state.page - 1
51+
},
52+
},
53+
extraReducers: builder => {
54+
builder
55+
.addCase(searchDeployments.pending, (state) => {
56+
state.loading = true
57+
state.deployments = []
58+
})
59+
.addCase(searchDeployments.fulfilled, (state, action) => {
60+
state.loading = false
61+
state.deployments = action.payload
62+
})
63+
.addCase(searchDeployments.rejected, (state) => {
64+
state.loading = false
65+
})
66+
}
67+
})

ui/src/redux/store.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { repoSettingsSlice } from "./repoSettings"
1111
import { settingsSlice } from "./settings"
1212
import { deploymentSlice } from "./deployment"
1313
import { membersSlice } from "./members"
14+
import { activitiesSlice } from './activities'
1415

1516
export const store = configureStore({
1617
reducer: {
@@ -25,6 +26,7 @@ export const store = configureStore({
2526
settings: settingsSlice.reducer,
2627
deployment: deploymentSlice.reducer,
2728
members: membersSlice.reducer,
29+
activities: activitiesSlice.reducer,
2830
},
2931
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
3032
serializableCheck: false

ui/src/views/Activities.tsx

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,43 @@
1+
import { useEffect } from "react"
2+
import { shallowEqual } from 'react-redux'
13
import { Helmet } from "react-helmet"
24

5+
import { useAppSelector, useAppDispatch } from "../redux/hooks"
6+
import { perPage, activitiesSlice, searchDeployments } from "../redux/activities"
7+
38
import Main from "./Main"
49
import SearchActivities from "../components/SearchActivities"
510
import ActivityLogs from "../components/ActivityLogs"
611
import Pagination from "../components/Pagination"
12+
import Spin from '../components/Spin'
13+
14+
const { actions } = activitiesSlice
715

816
export default function Activities(): JSX.Element {
17+
const {
18+
loading,
19+
deployments,
20+
page,
21+
} = useAppSelector(state => state.activities, shallowEqual)
22+
23+
const dispatch = useAppDispatch()
24+
25+
useEffect(() => {
26+
dispatch(searchDeployments())
27+
// eslint-disable-next-line
28+
}, [dispatch])
29+
30+
const onChangePeriod = (start: Date, end: Date) => {
31+
dispatch(actions.setStart(start))
32+
dispatch(actions.setEnd(end))
33+
}
34+
35+
const onClickSearch = () => dispatch(searchDeployments())
36+
37+
const onClickPrev = () => dispatch(actions.decreasePage())
38+
39+
const onClickNext = () => dispatch(actions.increasePage())
40+
941
return (
1042
<Main>
1143
<Helmet>
@@ -15,15 +47,27 @@ export default function Activities(): JSX.Element {
1547
<div style={{marginTop: 30}}>
1648
<h2>Search</h2>
1749
<SearchActivities
18-
onChangePeriod={() => console.log("period")}
19-
onClickSearch={() => console.log("search")}
50+
onChangePeriod={onChangePeriod}
51+
onClickSearch={onClickSearch}
2052
/>
2153
</div>
22-
<div style={{marginTop: 30}}>
23-
<ActivityLogs deployments={[]}/>
54+
<div style={{marginTop: 50}}>
55+
<h2>History</h2>
56+
<div style={{marginTop: 30}}>
57+
{(loading)?
58+
<div style={{textAlign: "center"}}>
59+
<Spin />
60+
</div>
61+
:
62+
<ActivityLogs deployments={deployments}/>}
63+
</div>
2464
</div>
2565
<div style={{marginTop: 30, textAlign: "center"}}>
26-
<Pagination page={0} isLast={true} onClickPrev={() => {console.log('')}} onClickNext={() => {console.log('')}} />
66+
<Pagination
67+
page={page}
68+
isLast={deployments.length !== perPage}
69+
onClickPrev={onClickPrev}
70+
onClickNext={onClickNext} />
2771
</div>
2872
</Main>
2973
)

0 commit comments

Comments
 (0)