diff --git a/frontend/src/api/dashboard/getAll.ts b/frontend/src/api/dashboard/getAll.ts index abd3e8fc93..aafe44b3ed 100644 --- a/frontend/src/api/dashboard/getAll.ts +++ b/frontend/src/api/dashboard/getAll.ts @@ -1,24 +1,8 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; -import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps } from 'types/api/dashboard/getAll'; +import { ApiResponse } from 'types/api'; +import { Dashboard } from 'types/api/dashboard/getAll'; -const getAll = async (): Promise< - SuccessResponse | ErrorResponse -> => { - try { - const response = await axios.get('/dashboards'); - - return { - statusCode: 200, - error: null, - message: response.data.message, - payload: response.data.data, - }; - } catch (error) { - return ErrorResponseHandler(error as AxiosError); - } -}; - -export default getAll; +export const getAllDashboardList = (): Promise => + axios + .get>('/dashboards') + .then((res) => res.data.data); diff --git a/frontend/src/container/ExportPanel/ExportPanel.tsx b/frontend/src/container/ExportPanel/ExportPanel.tsx index 24e9ed210e..eda643dde9 100644 --- a/frontend/src/container/ExportPanel/ExportPanel.tsx +++ b/frontend/src/container/ExportPanel/ExportPanel.tsx @@ -44,10 +44,10 @@ function ExportPanel({ isLoading, onExport }: ExportPanelProps): JSX.Element { onError: handleError, }); - const options = useMemo(() => getSelectOptions(data?.payload || []), [data]); + const options = useMemo(() => getSelectOptions(data || []), [data]); const handleExportClick = useCallback((): void => { - const currentSelectedDashboard = data?.payload?.find( + const currentSelectedDashboard = data?.find( ({ uuid }) => uuid === selectedDashboardId, ); diff --git a/frontend/src/container/ListOfDashboard/TableComponents/DeleteButton.tsx b/frontend/src/container/ListOfDashboard/TableComponents/DeleteButton.tsx index fb13155841..39d3c02a23 100644 --- a/frontend/src/container/ListOfDashboard/TableComponents/DeleteButton.tsx +++ b/frontend/src/container/ListOfDashboard/TableComponents/DeleteButton.tsx @@ -10,7 +10,11 @@ import AppActions from 'types/actions'; import { Data } from '../index'; import { TableLinkText } from './styles'; -function DeleteButton({ deleteDashboard, id }: DeleteButtonProps): JSX.Element { +function DeleteButton({ + deleteDashboard, + id, + refetchDashboardList, +}: DeleteButtonProps): JSX.Element { const [modal, contextHolder] = Modal.useModal(); const openConfirmationDialog = useCallback((): void => { @@ -20,13 +24,14 @@ function DeleteButton({ deleteDashboard, id }: DeleteButtonProps): JSX.Element { onOk() { deleteDashboard({ uuid: id, + refetch: refetchDashboardList, }); }, okText: 'Delete', okButtonProps: { danger: true }, centered: true, }); - }, [id, modal, deleteDashboard]); + }, [modal, deleteDashboard, id, refetchDashboardList]); return ( <> @@ -51,13 +56,22 @@ const mapDispatchToProps = ( deleteDashboard: bindActionCreators(DeleteDashboard, dispatch), }); -type DeleteButtonProps = Data & DispatchProps; +export type DeleteButtonProps = Data & DispatchProps; const WrapperDeleteButton = connect(null, mapDispatchToProps)(DeleteButton); // This is to avoid the type collision function Wrapper(props: Data): JSX.Element { - const { createdBy, description, id, key, lastUpdatedTime, name, tags } = props; + const { + createdBy, + description, + id, + key, + refetchDashboardList, + lastUpdatedTime, + name, + tags, + } = props; return ( ); diff --git a/frontend/src/container/ListOfDashboard/index.tsx b/frontend/src/container/ListOfDashboard/index.tsx index bcd5d81fca..669ee75942 100644 --- a/frontend/src/container/ListOfDashboard/index.tsx +++ b/frontend/src/container/ListOfDashboard/index.tsx @@ -14,6 +14,7 @@ import { ResizeTable } from 'components/ResizeTable'; import TextToolTip from 'components/TextToolTip'; import ROUTES from 'constants/routes'; import SearchFilter from 'container/ListOfDashboard/SearchFilter'; +import { useGetAllDashboard } from 'hooks/dashboard/useGetAllDashboard'; import useComponentPermission from 'hooks/useComponentPermission'; import history from 'lib/history'; import { @@ -25,6 +26,7 @@ import { useState, } from 'react'; import { useTranslation } from 'react-i18next'; +import { UseQueryResult } from 'react-query'; import { useDispatch, useSelector } from 'react-redux'; import { generatePath } from 'react-router-dom'; import { AppState } from 'store/reducers'; @@ -32,20 +34,24 @@ import AppActions from 'types/actions'; import { GET_ALL_DASHBOARD_SUCCESS } from 'types/actions/dashboard'; import { Dashboard } from 'types/api/dashboard/getAll'; import AppReducer from 'types/reducer/app'; -import DashboardReducer from 'types/reducer/dashboards'; import ImportJSON from './ImportJSON'; import { ButtonContainer, NewDashboardButton, TableContainer } from './styles'; import Createdby from './TableComponents/CreatedBy'; import DateComponent from './TableComponents/Date'; -import DeleteButton from './TableComponents/DeleteButton'; +import DeleteButton, { + DeleteButtonProps, +} from './TableComponents/DeleteButton'; import Name from './TableComponents/Name'; import Tags from './TableComponents/Tags'; function ListOfAllDashboard(): JSX.Element { - const { dashboards, loading } = useSelector( - (state) => state.dashboards, - ); + const { + data: dashboardListResponse = [], + isLoading: isDashboardListLoading, + refetch: refetchDashboardList, + } = useGetAllDashboard(); + const dispatch = useDispatch>(); const { role } = useSelector((state) => state.app); @@ -66,8 +72,10 @@ function ListOfAllDashboard(): JSX.Element { const [filteredDashboards, setFilteredDashboards] = useState(); useEffect(() => { - setFilteredDashboards(dashboards); - }, [dashboards]); + if (dashboardListResponse.length) { + setFilteredDashboards(dashboardListResponse); + } + }, [dashboardListResponse]); const [newDashboardState, setNewDashboardState] = useState({ loading: false, @@ -125,22 +133,43 @@ function ListOfAllDashboard(): JSX.Element { title: 'Action', dataIndex: '', width: 40, - render: DeleteButton, + render: ({ + createdBy, + description, + id, + key, + lastUpdatedTime, + name, + tags, + }: DeleteButtonProps) => ( + + ), }); } return tableColumns; - }, [action]); + }, [action, refetchDashboardList]); - const data: Data[] = (filteredDashboards || dashboards).map((e) => ({ - createdBy: e.created_at, - description: e.data.description || '', - id: e.uuid, - lastUpdatedTime: e.updated_at, - name: e.data.title, - tags: e.data.tags || [], - key: e.uuid, - })); + const data: Data[] = + filteredDashboards?.map((e) => ({ + createdBy: e.created_at, + description: e.data.description || '', + id: e.uuid, + lastUpdatedTime: e.updated_at, + name: e.data.title, + tags: e.data.tags || [], + key: e.uuid, + refetchDashboardList, + })) || []; const onNewDashboardHandler = useCallback(async () => { try { @@ -209,7 +238,7 @@ function ListOfAllDashboard(): JSX.Element { menuItems.push({ key: t('create_dashboard').toString(), label: t('create_dashboard'), - disabled: loading, + disabled: isDashboardListLoading, onClick: onNewDashboardHandler, }); } @@ -228,7 +257,7 @@ function ListOfAllDashboard(): JSX.Element { }); return menuItems; - }, [createNewDashboard, loading, onNewDashboardHandler, t]); + }, [createNewDashboard, isDashboardListLoading, onNewDashboardHandler, t]); const menu: MenuProps = useMemo( () => ({ @@ -250,7 +279,11 @@ function ListOfAllDashboard(): JSX.Element { }} /> {newDashboard && ( - + } type="primary" @@ -266,7 +299,7 @@ function ListOfAllDashboard(): JSX.Element { ), [ newDashboard, - loading, + isDashboardListLoading, menu, newDashboardState.loading, newDashboardState.error, @@ -278,9 +311,9 @@ function ListOfAllDashboard(): JSX.Element { {GetHeader} - {!loading && ( + {!isDashboardListLoading && ( )} @@ -300,7 +333,7 @@ function ListOfAllDashboard(): JSX.Element { showHeader bordered sticky - loading={loading} + loading={isDashboardListLoading} dataSource={data} showSorterTooltip /> @@ -317,6 +350,7 @@ export interface Data { createdBy: string; lastUpdatedTime: string; id: string; + refetchDashboardList: UseQueryResult['refetch']; } export default ListOfAllDashboard; diff --git a/frontend/src/hooks/dashboard/useGetAllDashboard.tsx b/frontend/src/hooks/dashboard/useGetAllDashboard.tsx index aced8e6e2e..91fea33517 100644 --- a/frontend/src/hooks/dashboard/useGetAllDashboard.tsx +++ b/frontend/src/hooks/dashboard/useGetAllDashboard.tsx @@ -1,16 +1,10 @@ -import getAll from 'api/dashboard/getAll'; +import { getAllDashboardList } from 'api/dashboard/getAll'; import { REACT_QUERY_KEY } from 'constants/reactQueryKeys'; import { useQuery, UseQueryResult } from 'react-query'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps } from 'types/api/dashboard/getAll'; +import { Dashboard } from 'types/api/dashboard/getAll'; -export const useGetAllDashboard = (): DashboardProps => - useQuery({ - queryFn: getAll, +export const useGetAllDashboard = (): UseQueryResult => + useQuery({ + queryFn: getAllDashboardList, queryKey: REACT_QUERY_KEY.GET_ALL_DASHBOARDS, }); - -type DashboardProps = UseQueryResult< - SuccessResponse | ErrorResponse, - unknown ->; diff --git a/frontend/src/pages/Dashboard/index.tsx b/frontend/src/pages/Dashboard/index.tsx index 35ccabcec5..35b801387a 100644 --- a/frontend/src/pages/Dashboard/index.tsx +++ b/frontend/src/pages/Dashboard/index.tsx @@ -1,19 +1,10 @@ import { Space } from 'antd'; import ReleaseNote from 'components/ReleaseNote'; import ListOfAllDashboard from 'container/ListOfDashboard'; -import { useEffect } from 'react'; -import { connect } from 'react-redux'; import { useLocation } from 'react-router-dom'; -import { bindActionCreators } from 'redux'; -import { ThunkDispatch } from 'redux-thunk'; -import { GetAllDashboards } from 'store/actions'; -import AppActions from 'types/actions'; -function Dashboard({ getAllDashboards }: DashboardProps): JSX.Element { +function Dashboard(): JSX.Element { const location = useLocation(); - useEffect(() => { - getAllDashboards(); - }, [getAllDashboards]); return ( @@ -23,16 +14,4 @@ function Dashboard({ getAllDashboards }: DashboardProps): JSX.Element { ); } -interface DispatchProps { - getAllDashboards: () => void; -} - -const mapDispatchToProps = ( - dispatch: ThunkDispatch, -): DispatchProps => ({ - getAllDashboards: bindActionCreators(GetAllDashboards, dispatch), -}); - -type DashboardProps = DispatchProps; - -export default connect(null, mapDispatchToProps)(Dashboard); +export default Dashboard; diff --git a/frontend/src/store/actions/dashboard/deleteDashboard.ts b/frontend/src/store/actions/dashboard/deleteDashboard.ts index 139df48f6f..a8add8002a 100644 --- a/frontend/src/store/actions/dashboard/deleteDashboard.ts +++ b/frontend/src/store/actions/dashboard/deleteDashboard.ts @@ -1,10 +1,12 @@ import deleteDashboardApi from 'api/dashboard/delete'; +import { UseQueryResult } from 'react-query'; import { Dispatch } from 'redux'; import AppActions from 'types/actions'; import { Dashboard } from 'types/api/dashboard/getAll'; export const DeleteDashboard = ({ uuid, + refetch, }: DeleteDashboardProps): ((dispatch: Dispatch) => void) => async ( dispatch: Dispatch, ): Promise => { @@ -14,6 +16,8 @@ export const DeleteDashboard = ({ }); if (response.statusCode === 200) { + refetch(); + dispatch({ type: 'DELETE_DASHBOARD_SUCCESS', payload: { @@ -41,4 +45,5 @@ export const DeleteDashboard = ({ export interface DeleteDashboardProps { uuid: Dashboard['uuid']; + refetch: UseQueryResult['refetch']; } diff --git a/frontend/src/store/actions/dashboard/getAllDashboard.ts b/frontend/src/store/actions/dashboard/getAllDashboard.ts deleted file mode 100644 index 93727d80fb..0000000000 --- a/frontend/src/store/actions/dashboard/getAllDashboard.ts +++ /dev/null @@ -1,36 +0,0 @@ -import getAll from 'api/dashboard/getAll'; -import { AxiosError } from 'axios'; -import { Dispatch } from 'redux'; -import AppActions from 'types/actions'; - -export const GetAllDashboards = (): (( - dispatch: Dispatch, -) => void) => async (dispatch: Dispatch): Promise => { - try { - dispatch({ - type: 'GET_ALL_DASHBOARD_LOADING_START', - }); - const response = await getAll(); - - if (response.statusCode === 200) { - dispatch({ - type: 'GET_ALL_DASHBOARD_SUCCESS', - payload: response.payload, - }); - } else { - dispatch({ - type: 'GET_ALL_DASHBOARD_ERROR', - payload: { - errorMessage: response.error || 'Something went wrong', - }, - }); - } - } catch (error) { - dispatch({ - type: 'GET_ALL_DASHBOARD_ERROR', - payload: { - errorMessage: (error as AxiosError).toString() || 'Something went wrong', - }, - }); - } -}; diff --git a/frontend/src/store/actions/dashboard/index.ts b/frontend/src/store/actions/dashboard/index.ts index 3e6abb6d77..b01947fe3d 100644 --- a/frontend/src/store/actions/dashboard/index.ts +++ b/frontend/src/store/actions/dashboard/index.ts @@ -1,7 +1,6 @@ export * from './applySettingsToPanel'; export * from './deleteDashboard'; export * from './deleteQuery'; -export * from './getAllDashboard'; export * from './getDashboard'; export * from './toggleEditMode'; export * from './updateDashboardTitle'; diff --git a/frontend/src/types/api/index.ts b/frontend/src/types/api/index.ts index c2f4d44ca0..49fdb21a4e 100644 --- a/frontend/src/types/api/index.ts +++ b/frontend/src/types/api/index.ts @@ -1,5 +1,7 @@ import { ErrorStatusCode, SuccessStatusCode } from 'types/common'; +export type ApiResponse = { data: T }; + export interface ErrorResponse { statusCode: ErrorStatusCode; payload: null;