Skip to content

Commit

Permalink
feat: all dashboard is migrated to useQuery and action is removed (Si…
Browse files Browse the repository at this point in the history
…gNoz#3384)

* feat: all dashboard is migrated to useQuery and action is removed

* chore: delete functionality is updated

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
  • Loading branch information
himanshugupta714 and palashgdev authored Sep 11, 2023
1 parent dfd94f6 commit 41f7a79
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 125 deletions.
28 changes: 6 additions & 22 deletions frontend/src/api/dashboard/getAll.ts
Original file line number Diff line number Diff line change
@@ -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<PayloadProps> | 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<Dashboard[]> =>
axios
.get<ApiResponse<Dashboard[]>>('/dashboards')
.then((res) => res.data.data);
4 changes: 2 additions & 2 deletions frontend/src/container/ExportPanel/ExportPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand All @@ -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 (
<>
Expand All @@ -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 (
<WrapperDeleteButton
Expand All @@ -69,6 +83,7 @@ function Wrapper(props: Data): JSX.Element {
lastUpdatedTime,
name,
tags,
refetchDashboardList,
}}
/>
);
Expand Down
86 changes: 60 additions & 26 deletions frontend/src/container/ListOfDashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -25,27 +26,32 @@ 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';
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<AppState, DashboardReducer>(
(state) => state.dashboards,
);
const {
data: dashboardListResponse = [],
isLoading: isDashboardListLoading,
refetch: refetchDashboardList,
} = useGetAllDashboard();

const dispatch = useDispatch<Dispatch<AppActions>>();
const { role } = useSelector<AppState, AppReducer>((state) => state.app);

Expand All @@ -66,8 +72,10 @@ function ListOfAllDashboard(): JSX.Element {
const [filteredDashboards, setFilteredDashboards] = useState<Dashboard[]>();

useEffect(() => {
setFilteredDashboards(dashboards);
}, [dashboards]);
if (dashboardListResponse.length) {
setFilteredDashboards(dashboardListResponse);
}
}, [dashboardListResponse]);

const [newDashboardState, setNewDashboardState] = useState({
loading: false,
Expand Down Expand Up @@ -125,22 +133,43 @@ function ListOfAllDashboard(): JSX.Element {
title: 'Action',
dataIndex: '',
width: 40,
render: DeleteButton,
render: ({
createdBy,
description,
id,
key,
lastUpdatedTime,
name,
tags,
}: DeleteButtonProps) => (
<DeleteButton
description={description}
id={id}
key={key}
lastUpdatedTime={lastUpdatedTime}
name={name}
tags={tags}
createdBy={createdBy}
refetchDashboardList={refetchDashboardList}
/>
),
});
}

return tableColumns;
}, [action]);

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,
}));
}, [action, refetchDashboardList]);

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 {
Expand Down Expand Up @@ -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,
});
}
Expand All @@ -228,7 +257,7 @@ function ListOfAllDashboard(): JSX.Element {
});

return menuItems;
}, [createNewDashboard, loading, onNewDashboardHandler, t]);
}, [createNewDashboard, isDashboardListLoading, onNewDashboardHandler, t]);

const menu: MenuProps = useMemo(
() => ({
Expand All @@ -250,7 +279,11 @@ function ListOfAllDashboard(): JSX.Element {
}}
/>
{newDashboard && (
<Dropdown disabled={loading} trigger={['click']} menu={menu}>
<Dropdown
disabled={isDashboardListLoading}
trigger={['click']}
menu={menu}
>
<NewDashboardButton
icon={<PlusOutlined />}
type="primary"
Expand All @@ -266,7 +299,7 @@ function ListOfAllDashboard(): JSX.Element {
),
[
newDashboard,
loading,
isDashboardListLoading,
menu,
newDashboardState.loading,
newDashboardState.error,
Expand All @@ -278,9 +311,9 @@ function ListOfAllDashboard(): JSX.Element {
<Card>
{GetHeader}

{!loading && (
{!isDashboardListLoading && (
<SearchFilter
searchData={dashboards}
searchData={dashboardListResponse}
filterDashboards={setFilteredDashboards}
/>
)}
Expand All @@ -300,7 +333,7 @@ function ListOfAllDashboard(): JSX.Element {
showHeader
bordered
sticky
loading={loading}
loading={isDashboardListLoading}
dataSource={data}
showSorterTooltip
/>
Expand All @@ -317,6 +350,7 @@ export interface Data {
createdBy: string;
lastUpdatedTime: string;
id: string;
refetchDashboardList: UseQueryResult['refetch'];
}

export default ListOfAllDashboard;
16 changes: 5 additions & 11 deletions frontend/src/hooks/dashboard/useGetAllDashboard.tsx
Original file line number Diff line number Diff line change
@@ -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<Dashboard[], unknown> =>
useQuery<Dashboard[]>({
queryFn: getAllDashboardList,
queryKey: REACT_QUERY_KEY.GET_ALL_DASHBOARDS,
});

type DashboardProps = UseQueryResult<
SuccessResponse<PayloadProps> | ErrorResponse,
unknown
>;
25 changes: 2 additions & 23 deletions frontend/src/pages/Dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Space direction="vertical" size="middle" style={{ width: '100%' }}>
Expand All @@ -23,16 +14,4 @@ function Dashboard({ getAllDashboards }: DashboardProps): JSX.Element {
);
}

interface DispatchProps {
getAllDashboards: () => void;
}

const mapDispatchToProps = (
dispatch: ThunkDispatch<unknown, unknown, AppActions>,
): DispatchProps => ({
getAllDashboards: bindActionCreators(GetAllDashboards, dispatch),
});

type DashboardProps = DispatchProps;

export default connect(null, mapDispatchToProps)(Dashboard);
export default Dashboard;
5 changes: 5 additions & 0 deletions frontend/src/store/actions/dashboard/deleteDashboard.ts
Original file line number Diff line number Diff line change
@@ -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<AppActions>) => void) => async (
dispatch: Dispatch<AppActions>,
): Promise<void> => {
Expand All @@ -14,6 +16,8 @@ export const DeleteDashboard = ({
});

if (response.statusCode === 200) {
refetch();

dispatch({
type: 'DELETE_DASHBOARD_SUCCESS',
payload: {
Expand Down Expand Up @@ -41,4 +45,5 @@ export const DeleteDashboard = ({

export interface DeleteDashboardProps {
uuid: Dashboard['uuid'];
refetch: UseQueryResult['refetch'];
}
Loading

0 comments on commit 41f7a79

Please sign in to comment.