From a6e1e60e2cd82bbd31092f083f6d91b9387b5b2d Mon Sep 17 00:00:00 2001 From: Youssef Date: Wed, 9 Feb 2022 16:15:07 +0100 Subject: [PATCH] refactor: change based on PR feedback --- .../{ => ApplicationEdit}/ApplicationEdit.tsx | 75 +++++++++---------- .../{ => ApplicationList}/ApplicationList.tsx | 26 +++---- .../ApplicationUpdate.tsx | 8 +- .../{ => ApplicationView}/ApplicationView.tsx | 14 ++-- .../application-edit-component-test.js | 2 +- frontend/src/component/menu/routes.js | 4 +- .../useApplicationsApi/useApplicationsApi.ts | 12 --- .../useApplicationsForStrategy.ts | 40 ++++++++++ 8 files changed, 101 insertions(+), 80 deletions(-) rename frontend/src/component/application/{ => ApplicationEdit}/ApplicationEdit.tsx (64%) rename frontend/src/component/application/{ => ApplicationList}/ApplicationList.tsx (72%) rename frontend/src/component/application/{ => ApplicationUpdate}/ApplicationUpdate.tsx (91%) rename frontend/src/component/application/{ => ApplicationView}/ApplicationView.tsx (94%) create mode 100644 frontend/src/hooks/api/getters/useApplicationsForStrategy/useApplicationsForStrategy.ts diff --git a/frontend/src/component/application/ApplicationEdit.tsx b/frontend/src/component/application/ApplicationEdit/ApplicationEdit.tsx similarity index 64% rename from frontend/src/component/application/ApplicationEdit.tsx rename to frontend/src/component/application/ApplicationEdit/ApplicationEdit.tsx index edfd3b1667..f272533c19 100644 --- a/frontend/src/component/application/ApplicationEdit.tsx +++ b/frontend/src/component/application/ApplicationEdit/ApplicationEdit.tsx @@ -1,50 +1,43 @@ /* eslint react/no-multi-comp:off */ -import { useContext, useEffect, useState } from 'react'; +import { useContext, useState } from 'react'; import { Avatar, Link, Icon, IconButton, - Button, LinearProgress, Typography, } from '@material-ui/core'; import { Link as LinkIcon } from '@material-ui/icons'; -import ConditionallyRender from '../common/ConditionallyRender/ConditionallyRender'; -import { - formatDateWithLocale, -} from '../common/util'; -import { UPDATE_APPLICATION } from '../providers/AccessProvider/permissions'; -import ApplicationView from './ApplicationView'; -import ApplicationUpdate from './ApplicationUpdate'; -import TabNav from '../common/TabNav/TabNav'; -import Dialogue from '../common/Dialogue'; -import PageContent from '../common/PageContent'; -import HeaderTitle from '../common/HeaderTitle'; -import AccessContext from '../../contexts/AccessContext'; -import useApplicationsApi from '../../hooks/api/actions/useApplicationsApi/useApplicationsApi'; -import useApplication from '../../hooks/api/getters/useApplication/useApplication'; +import ConditionallyRender from '../../common/ConditionallyRender/ConditionallyRender'; +import { formatDateWithLocale } from '../../common/util'; +import { UPDATE_APPLICATION } from '../../providers/AccessProvider/permissions'; +import ApplicationView from '../ApplicationView/ApplicationView'; +import ApplicationUpdate from '../ApplicationUpdate/ApplicationUpdate'; +import TabNav from '../../common/TabNav/TabNav'; +import Dialogue from '../../common/Dialogue'; +import PageContent from '../../common/PageContent'; +import HeaderTitle from '../../common/HeaderTitle'; +import AccessContext from '../../../contexts/AccessContext'; +import useApplicationsApi from '../../../hooks/api/actions/useApplicationsApi/useApplicationsApi'; +import useApplication from '../../../hooks/api/getters/useApplication/useApplication'; import { useHistory, useParams } from 'react-router-dom'; -import { useLocationSettings } from '../../hooks/useLocationSettings'; +import { useLocationSettings } from '../../../hooks/useLocationSettings'; +import useToast from '../../../hooks/useToast'; +import PermissionButton from '../../common/PermissionButton/PermissionButton'; const ApplicationEdit = () => { const history = useHistory(); const { name } = useParams<{ name: string }>(); - const { refetchApplication, application } = useApplication(name); + const { application, loading } = useApplication(name); const { appName, url, description, icon = 'apps', createdAt } = application; const { hasAccess } = useContext(AccessContext); const { deleteApplication } = useApplicationsApi(); const { locationSettings } = useLocationSettings(); + const { setToastData, setToastApiError } = useToast(); - const [loading, setLoading] = useState(true); const [showDialog, setShowDialog] = useState(false); - useEffect(() => { - refetchApplication(); - setLoading(false); - // eslint-disable-next-line - }, []); - const toggleModal = () => { setShowDialog(!showDialog); }; @@ -54,8 +47,17 @@ const ApplicationEdit = () => { const onDeleteApplication = async (evt: Event) => { evt.preventDefault(); - await deleteApplication(appName); - history.push('/applications'); + try { + await deleteApplication(appName); + setToastData({ + title: 'Deleted Successfully', + text: 'Application deleted successfully', + type: 'success', + }); + history.push('/applications'); + } catch (e: any) { + setToastApiError(e.toString()); + } }; const renderModal = () => ( @@ -115,18 +117,13 @@ const ApplicationEdit = () => { } /> - - Delete - - } - /> + + Delete + } /> diff --git a/frontend/src/component/application/ApplicationList.tsx b/frontend/src/component/application/ApplicationList/ApplicationList.tsx similarity index 72% rename from frontend/src/component/application/ApplicationList.tsx rename to frontend/src/component/application/ApplicationList/ApplicationList.tsx index 7bbed87f7b..fb175e8d83 100644 --- a/frontend/src/component/application/ApplicationList.tsx +++ b/frontend/src/component/application/ApplicationList/ApplicationList.tsx @@ -1,20 +1,16 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import { useMemo, useState } from 'react'; import { CircularProgress } from '@material-ui/core'; import { Warning } from '@material-ui/icons'; -import { AppsLinkList, styles as commonStyles } from '../common'; -import SearchField from '../common/SearchField/SearchField'; -import PageContent from '../common/PageContent/PageContent'; -import HeaderTitle from '../common/HeaderTitle'; -import useApplications from '../../hooks/api/getters/useApplications/useApplications'; +import { AppsLinkList, styles as commonStyles } from '../../common'; +import SearchField from '../../common/SearchField/SearchField'; +import PageContent from '../../common/PageContent/PageContent'; +import HeaderTitle from '../../common/HeaderTitle'; +import useApplications from '../../../hooks/api/getters/useApplications/useApplications'; const ApplicationList = () => { - const { applications, refetchApplications } = useApplications(); + const { applications } = useApplications(); const [filter, setFilter] = useState(''); - useEffect(() => { - refetchApplications(); - // eslint-disable-next-line - }, []); const filteredApplications = useMemo(() => { const regExp = new RegExp(filter, 'i'); @@ -23,8 +19,8 @@ const ApplicationList = () => { : applications; }, [applications, filter]); - const Empty = () => ( - + const RenderNoApplications = () => ( + <>


@@ -39,7 +35,7 @@ const ApplicationList = () => { documentation.
-
+ ); if (!filteredApplications) { @@ -56,7 +52,7 @@ const ApplicationList = () => { {filteredApplications.length > 0 ? ( ) : ( - + )} diff --git a/frontend/src/component/application/ApplicationUpdate.tsx b/frontend/src/component/application/ApplicationUpdate/ApplicationUpdate.tsx similarity index 91% rename from frontend/src/component/application/ApplicationUpdate.tsx rename to frontend/src/component/application/ApplicationUpdate/ApplicationUpdate.tsx index c6e425aa12..eed4150074 100644 --- a/frontend/src/component/application/ApplicationUpdate.tsx +++ b/frontend/src/component/application/ApplicationUpdate/ApplicationUpdate.tsx @@ -1,9 +1,9 @@ import { useState } from 'react'; import { TextField, Grid } from '@material-ui/core'; -import { useCommonStyles } from '../../common.styles'; -import icons from './icon-names'; -import GeneralSelect from '../common/GeneralSelect/GeneralSelect'; -import useApplicationsApi from '../../hooks/api/actions/useApplicationsApi/useApplicationsApi'; +import { useCommonStyles } from '../../../common.styles'; +import icons from '../icon-names'; +import GeneralSelect from '../../common/GeneralSelect/GeneralSelect'; +import useApplicationsApi from '../../../hooks/api/actions/useApplicationsApi/useApplicationsApi'; interface IApplication { appName: string; diff --git a/frontend/src/component/application/ApplicationView.tsx b/frontend/src/component/application/ApplicationView/ApplicationView.tsx similarity index 94% rename from frontend/src/component/application/ApplicationView.tsx rename to frontend/src/component/application/ApplicationView/ApplicationView.tsx index 1ada6f1e55..5ba8b86838 100644 --- a/frontend/src/component/application/ApplicationView.tsx +++ b/frontend/src/component/application/ApplicationView/ApplicationView.tsx @@ -15,16 +15,16 @@ import { FlagRounded, SvgIconComponent, } from '@material-ui/icons'; -import { shorten } from '../common'; +import { shorten } from '../../common'; import { CREATE_FEATURE, CREATE_STRATEGY, -} from '../providers/AccessProvider/permissions'; -import ConditionallyRender from '../common/ConditionallyRender/ConditionallyRender'; -import { getTogglePath } from '../../utils/route-path-helpers'; -import useApplication from '../../hooks/api/getters/useApplication/useApplication'; -import AccessContext from '../../contexts/AccessContext'; -import { formatFullDateTimeWithLocale } from '../common/util'; +} from '../../providers/AccessProvider/permissions'; +import ConditionallyRender from '../../common/ConditionallyRender/ConditionallyRender'; +import { getTogglePath } from '../../../utils/route-path-helpers'; +import useApplication from '../../../hooks/api/getters/useApplication/useApplication'; +import AccessContext from '../../../contexts/AccessContext'; +import { formatFullDateTimeWithLocale } from '../../common/util'; const ApplicationView = () => { const { hasAccess } = useContext(AccessContext); const { name } = useParams<{ name: string }>(); diff --git a/frontend/src/component/application/__tests__/application-edit-component-test.js b/frontend/src/component/application/__tests__/application-edit-component-test.js index e78573c722..bceb3822aa 100644 --- a/frontend/src/component/application/__tests__/application-edit-component-test.js +++ b/frontend/src/component/application/__tests__/application-edit-component-test.js @@ -1,5 +1,5 @@ import { ThemeProvider } from '@material-ui/core'; -import ApplicationEdit from '../ApplicationEdit'; +import ApplicationEdit from '../ApplicationEdit/ApplicationEdit'; import renderer from 'react-test-renderer'; import { MemoryRouter } from 'react-router-dom'; import { ADMIN } from '../../providers/AccessProvider/permissions'; diff --git a/frontend/src/component/menu/routes.js b/frontend/src/component/menu/routes.js index c39561f1b7..daab1f5d7f 100644 --- a/frontend/src/component/menu/routes.js +++ b/frontend/src/component/menu/routes.js @@ -41,8 +41,8 @@ import EditProject from '../project/Project/EditProject/EditProject'; import CreateProject from '../project/Project/CreateProject/CreateProject'; import CreateFeature from '../feature/CreateFeature/CreateFeature'; import EditFeature from '../feature/EditFeature/EditFeature'; -import ApplicationEdit from '../application/ApplicationEdit'; -import ApplicationList from '../application/ApplicationList'; +import ApplicationEdit from '../application/ApplicationEdit/ApplicationEdit'; +import ApplicationList from '../application/ApplicationList/ApplicationList'; import ContextList from '../context/ContextList/ContextList'; import RedirectFeatureView from '../feature/RedirectFeatureView/RedirectFeatureView'; diff --git a/frontend/src/hooks/api/actions/useApplicationsApi/useApplicationsApi.ts b/frontend/src/hooks/api/actions/useApplicationsApi/useApplicationsApi.ts index 09aa3cb4b3..6bf8d6e03b 100644 --- a/frontend/src/hooks/api/actions/useApplicationsApi/useApplicationsApi.ts +++ b/frontend/src/hooks/api/actions/useApplicationsApi/useApplicationsApi.ts @@ -39,20 +39,8 @@ const useApplicationsApi = () => { } }; - const fetchApplicationsWithStrategyName = async (strategyName: string) => { - const path = `${URI}?strategyName=${strategyName}`; - const req = createRequest(path, { method: 'GET' }); - try { - const res = await makeRequest(req.caller, req.id); - return res; - } catch (e) { - throw e; - } - }; - return { storeApplicationMetaData, - fetchApplicationsWithStrategyName, deleteApplication, errors, loading, diff --git a/frontend/src/hooks/api/getters/useApplicationsForStrategy/useApplicationsForStrategy.ts b/frontend/src/hooks/api/getters/useApplicationsForStrategy/useApplicationsForStrategy.ts new file mode 100644 index 0000000000..8a537e910f --- /dev/null +++ b/frontend/src/hooks/api/getters/useApplicationsForStrategy/useApplicationsForStrategy.ts @@ -0,0 +1,40 @@ +import useSWR, { mutate, SWRConfiguration } from 'swr'; +import { useState, useEffect } from 'react'; +import { formatApiPath } from '../../../../utils/format-path'; +import handleErrorResponses from '../httpErrorResponseHandler'; + +const path = formatApiPath(`api/admin/metrics/applications`); +const KEY = `api/admin/metrics/applications`; + +const useApplicationsForStrategy = ( + strategyName: string, + options: SWRConfiguration = {} +) => { + const fetcher = async () => { + const res = await fetch(`${path}?strategyName=${strategyName}`, { + method: 'GET', + }).then(handleErrorResponses('Application')); + return res.json(); + }; + + const { data, error } = useSWR(KEY, fetcher, options); + const [loading, setLoading] = useState(!error && !data); + + const refetchAddons = () => { + mutate(KEY); + }; + + useEffect(() => { + setLoading(!error && !data); + }, [data, error]); + + return { + addons: data?.addons || [], + providers: data?.providers || [], + error, + loading, + refetchAddons, + }; +}; + +export default useApplicationsForStrategy;