diff --git a/src/main/react/src/components/userMenu.tsx b/src/main/react/src/components/userMenu.tsx index b961377..02abef5 100644 --- a/src/main/react/src/components/userMenu.tsx +++ b/src/main/react/src/components/userMenu.tsx @@ -14,80 +14,80 @@ import { setUsername } from '@/slices/login'; export const UserMenu: React.FC = () => { const { username } = useAppSelector(state => state.login); - const [anchorEl, setAnchorEl] = useState(null); + const [anchorEl, setAnchorEl] = useState(null); const dropdownOpen = Boolean(anchorEl); const dispatch = useDispatch(); const navigate = useNavigate(); - const handleClick = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - const handleClose = () => { - setAnchorEl(null); - }; + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; - return ( + return ( - {username ? ( - - ) : ( - - )} - - { - localStorage.removeItem('login'); - dispatch(setUsername(null)); - setAnchorEl(null); - navigate('/login'); - }} - > - - - - Logout - - + {username ? ( + + ) : ( + + )} + + { + localStorage.removeItem('login'); + dispatch(setUsername(null)); + setAnchorEl(null); + navigate('/login'); + }} + > + + + + Logout + + - ); + ); } diff --git a/src/main/react/src/lib/api.ts b/src/main/react/src/lib/api.ts index b09ca61..d5f1e92 100644 --- a/src/main/react/src/lib/api.ts +++ b/src/main/react/src/lib/api.ts @@ -1,4 +1,4 @@ -import { UserToken } from '../model/token'; +import { UserToken } from '../types/token'; const inMemoryInitialState: any = localStorage.getItem('login') ? JSON.parse(localStorage.getItem('login') || '') diff --git a/src/main/react/src/pages/home.tsx b/src/main/react/src/pages/home.tsx index 8a746a2..e2b8e89 100644 --- a/src/main/react/src/pages/home.tsx +++ b/src/main/react/src/pages/home.tsx @@ -15,7 +15,7 @@ import TableRow from '@mui/material/TableRow'; import TextField from '@mui/material/TextField'; import Paper from '@mui/material/Paper'; -import { IJob, Jobs } from '../model/job'; +import { IJob, Jobs } from '../types/job'; import { useAppDispatch, useAppSelector } from '../slices/hook'; import { createJob, @@ -51,7 +51,7 @@ const Home = () => { return ( - + - setConfirm(false)}> - Delete job - Are your confirm? + setConfirm(false)} + aria-labelledby="alert-dialog-title" + aria-describedby="alert-dialog-description" + > + Delete job + Are your confirm? - )} - {j.state === 'PAUSED' && ( + + {j.state === 'NORMAL' && ( + + )} + {j.state === 'PAUSED' && ( + + )} - )} - + ))} diff --git a/src/main/react/src/pages/repos.tsx b/src/main/react/src/pages/repos.tsx index c221605..2320efa 100644 --- a/src/main/react/src/pages/repos.tsx +++ b/src/main/react/src/pages/repos.tsx @@ -12,10 +12,12 @@ import dayjs from 'dayjs'; import { fetchCommits } from '../slices/repos'; import { useAppDispatch, useAppSelector } from '../slices/hook'; +import { Box, CircularProgress } from '@mui/material'; +import { RequestStatus } from '@/types/request-status'; const Repos = () => { const dispatch = useAppDispatch(); - const { commits } = useAppSelector(state => state.repos); + const { commits, status } = useAppSelector(state => state.repos); useEffect(() => { dispatch(fetchCommits()); }, [dispatch]) @@ -23,6 +25,7 @@ const Repos = () => { return ( + @@ -52,6 +55,9 @@ const Repos = () => { ))}
+ {status === RequestStatus.LOADING && ( + + )}
) diff --git a/src/main/react/src/slices/job.ts b/src/main/react/src/slices/job.ts index b5f5be1..8186764 100644 --- a/src/main/react/src/slices/job.ts +++ b/src/main/react/src/slices/job.ts @@ -1,5 +1,5 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; -import { IJob, Jobs } from '../model/job'; +import { IJob, Jobs } from '../types/job'; import { api } from '../lib/api'; export const fetchJobs = createAsyncThunk('job/fetchJobs', async () => { diff --git a/src/main/react/src/slices/repos.ts b/src/main/react/src/slices/repos.ts index 99452ee..c27a4d4 100644 --- a/src/main/react/src/slices/repos.ts +++ b/src/main/react/src/slices/repos.ts @@ -1,6 +1,7 @@ import { createSlice, createAsyncThunk } from '@reduxjs/toolkit' import { api } from '../lib/api' import { ReposCommits } from '../types/respo' +import { RequestStatus } from '@/types/request-status' export const fetchCommits = createAsyncThunk('repos/fetchCommits', async () => { const url = '/api/v1/repos/commits' @@ -13,10 +14,12 @@ export const fetchCommits = createAsyncThunk('repos/fetchCommits', async () => { }) interface RepoState { - commits: ReposCommits + status: RequestStatus, + commits: ReposCommits, } const initialState: Partial = { + status: RequestStatus.IDLE, commits: [], } @@ -30,11 +33,25 @@ const reposSlice = createSlice({ }, }, extraReducers: builder => { + builder.addCase(fetchCommits.pending, (state) => { + state = { + ...state, + status: RequestStatus.LOADING, + } + }) builder.addCase(fetchCommits.fulfilled, (state, { payload }) => { - state.commits = payload ?? [] + state = { + ...state, + commits: payload ?? [], + status: RequestStatus.SUCCEEDED, + } }) builder.addCase(fetchCommits.rejected, (state, action) => { - console.error(state, action) + state = { + ...state, + status: RequestStatus.FAILED, + } + console.error(state, action); }) }, }) diff --git a/src/main/react/src/model/job.ts b/src/main/react/src/types/job.ts similarity index 100% rename from src/main/react/src/model/job.ts rename to src/main/react/src/types/job.ts diff --git a/src/main/react/src/types/request-status.ts b/src/main/react/src/types/request-status.ts new file mode 100644 index 0000000..7f6e4b1 --- /dev/null +++ b/src/main/react/src/types/request-status.ts @@ -0,0 +1,6 @@ +export enum RequestStatus { + IDLE = 'IDLE', + LOADING = 'LOADING', + SUCCEEDED = 'SUCCEEDED', + FAILED = 'FAILED', +} diff --git a/src/main/react/src/model/token.ts b/src/main/react/src/types/token.ts similarity index 100% rename from src/main/react/src/model/token.ts rename to src/main/react/src/types/token.ts