From 608e1bf29e17315aa0c359d98b7c131ac0bf8e85 Mon Sep 17 00:00:00 2001 From: Matthew Goodwin <49927862+m4ttheweric@users.noreply.github.com> Date: Wed, 31 May 2023 16:02:26 -0500 Subject: [PATCH] console: Add edit/view for native queries PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9307 GitOrigin-RevId: dddc9c2701a2f7958c423a5ddda6eb35163f425d --- .../components/Services/Data/DataRouter.js | 10 +- ...ueryRoute.tsx => AddNativeQuery.route.tsx} | 4 +- .../AddNativeQuery/AddNativeQuery.stories.tsx | 2 +- .../AddNativeQuery/AddNativeQuery.tsx | 198 ++++++++++-------- .../UpdateNativeQuery.route.tsx | 58 +++++ .../LogicalModels/AddNativeQuery/index.ts | 3 + .../LogicalModels/AddNativeQuery/utils.ts | 15 +- .../LogicalModels/LandingPage/LandingPage.tsx | 55 ++--- .../components/ListNativeQueries.tsx | 16 +- .../LogicalModels/components/RouteWrapper.tsx | 85 +++----- .../features/Data/LogicalModels/constants.ts | 42 ++++ .../src/lib/new-components/Button/Button.tsx | 14 +- 12 files changed, 314 insertions(+), 188 deletions(-) rename frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/{AddNativeQueryRoute.tsx => AddNativeQuery.route.tsx} (75%) create mode 100644 frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/UpdateNativeQuery.route.tsx create mode 100644 frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/index.ts diff --git a/frontend/libs/console/legacy-ce/src/lib/components/Services/Data/DataRouter.js b/frontend/libs/console/legacy-ce/src/lib/components/Services/Data/DataRouter.js index f4cc230cb82..6f100c54a7b 100644 --- a/frontend/libs/console/legacy-ce/src/lib/components/Services/Data/DataRouter.js +++ b/frontend/libs/console/legacy-ce/src/lib/components/Services/Data/DataRouter.js @@ -37,9 +37,13 @@ import { TableEditItemContainer } from './TableEditItem/TableEditItemContainer'; import { TableInsertItemContainer } from './TableInsertItem/TableInsertItemContainer'; import { ModifyTableContainer } from './TableModify/ModifyTableContainer'; import { LandingPageRoute as NativeQueries } from '../../../features/Data/LogicalModels/LandingPage/LandingPage'; -import { AddNativeQueryRoute } from '../../../features/Data/LogicalModels/AddNativeQuery/AddNativeQueryRoute'; + import { TrackStoredProcedureRoute } from '../../../features/Data/LogicalModels/StoredProcedures/StoredProcedureWidget.route'; import { ManageFunction } from '../../../features/Data/ManageFunction/ManageFunction'; +import { + UpdateNativeQueryRoute, + AddNativeQueryRoute, +} from '../../../features/Data/LogicalModels/AddNativeQuery'; const makeDataRouter = ( connect, @@ -82,6 +86,10 @@ const makeDataRouter = ( + (({ location, router }) => { return ( - - + + ); }); diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.stories.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.stories.tsx index ec395c1063d..7132610c3eb 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.stories.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.stories.tsx @@ -92,7 +92,7 @@ export const Basic: Story = { export const WithRouteWrapper: Story = { render: args => ( - + ), diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.tsx index 794b73130f0..7c9524d01b5 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.tsx @@ -8,9 +8,11 @@ import { useConsoleForm, } from '../../../../new-components/Form'; // import { FormDebugWindow } from '../../../../new-components/Form/dev-components/FormDebugWindow'; +import Skeleton from 'react-loading-skeleton'; import { Driver, drivers } from '../../../../dataSources'; import { IndicatorCard } from '../../../../new-components/IndicatorCard'; import { hasuraToast } from '../../../../new-components/Toasts'; +import { usePushRoute } from '../../../ConnectDBRedesign/hooks'; import { Feature } from '../../../DataSource'; import { useMetadata } from '../../../hasura-metadata-api'; import { useSupportedDataTypes } from '../../hooks/useSupportedDataTypes'; @@ -21,16 +23,15 @@ import { SqlEditorField } from './components/SqlEditorField'; import { schema } from './schema'; import { NativeQueryForm } from './types'; import { transformFormOutputToMetadata } from './utils'; -import Skeleton from 'react-loading-skeleton'; type AddNativeQueryProps = { defaultFormValues?: Partial; - push?: (path: string) => void; + mode?: 'create' | 'update'; }; export const AddNativeQuery = ({ defaultFormValues, - push, + mode = 'create', }: AddNativeQueryProps) => { const { Form, @@ -40,6 +41,8 @@ export const AddNativeQuery = ({ options: { defaultValues: defaultFormValues }, }); + const push = usePushRoute(); + const { data: sources, isLoading: isSourcesLoading, @@ -59,7 +62,7 @@ export const AddNativeQuery = ({ s => s.name === selectedSource )?.logical_models; - const { trackNativeQuery, isLoading } = useTrackNativeQuery(); + const { trackNativeQuery, isLoading: isSaving } = useTrackNativeQuery(); const [isLogicalModelsDialogOpen, setIsLogicalModelsDialogOpen] = React.useState(false); @@ -77,7 +80,7 @@ export const AddNativeQuery = ({ toastOptions: { duration: 3000 }, }); // Go to list - push?.('/data/native-queries'); + push('/data/native-queries'); }, onError: err => { hasuraToast({ @@ -127,96 +130,107 @@ export const AddNativeQuery = ({ ); return ( -
- {/* */} -
- - - ({ - label: m.name, - value: m.name, - }))} - /> - -
- {isLogicalModelsDialogOpen ? ( - { - setIsLogicalModelsDialogOpen(false); - }} - onSubmit={() => { - setIsLogicalModelsDialogOpen(false); - }} - asDialog - /> - ) : null} -
- {/* + +
+ {/* */} +
+ + + ({ + label: m.name, + value: m.name, + }))} + /> + +
+ {isLogicalModelsDialogOpen ? ( + { + setIsLogicalModelsDialogOpen(false); + }} + onSubmit={() => { + setIsLogicalModelsDialogOpen(false); + }} + asDialog + /> + ) : null} +
+ {/* Validate Button will remain hidden until we have more information about how to handle standalone validation Slack thread: https://hasurahq.slack.com/archives/C04LV93JNSH/p1682965503376129 */} - {/* */} - -
- + {/* */} + +
+ + + ); }; diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/UpdateNativeQuery.route.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/UpdateNativeQuery.route.tsx new file mode 100644 index 00000000000..aa1d1b07bd0 --- /dev/null +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/UpdateNativeQuery.route.tsx @@ -0,0 +1,58 @@ +import { InjectedRouter, withRouter } from 'react-router'; +import { IndicatorCard } from '../../../../new-components/IndicatorCard'; +import { MetadataUtils, useMetadata } from '../../../hasura-metadata-api'; +import { RouteWrapper } from '../components/RouteWrapper'; +import { AddNativeQuery } from './AddNativeQuery'; +import { normalizeArguments } from './utils'; +import Skeleton from 'react-loading-skeleton'; + +export const UpdateNativeQueryRoute = withRouter<{ + location: Location; + router: InjectedRouter; + params: { source: string; name: string }; +}>(({ location, router, params: { source, name } }) => { + if (!source || !name) { + return ( + + Unable to parse data from url. + + ); + } + + const { data: sourceQueries, isLoading } = useMetadata( + m => MetadataUtils.findMetadataSource(source, m)?.native_queries + ); + + const nativeQuery = sourceQueries?.find(s => s.root_field_name === name); + + if (!nativeQuery) { + return ( + + Native Query {name} not found in {source} + + ); + } + + return ( + + {isLoading ? ( +
+ +
+ ) : ( + + )} +
+ ); +}); diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/index.ts b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/index.ts new file mode 100644 index 00000000000..b30e68f341a --- /dev/null +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/index.ts @@ -0,0 +1,3 @@ +export { AddNativeQueryRoute } from './AddNativeQuery.route'; +export { AddNativeQuery } from './AddNativeQuery'; +export { UpdateNativeQueryRoute } from './UpdateNativeQuery.route'; diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/utils.ts b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/utils.ts index 3bc93d08da1..e52ce0a0e20 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/utils.ts +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/utils.ts @@ -1,5 +1,8 @@ -import { NativeQueryForm } from './types'; -import { NativeQuery as NativeQueryMetadataType } from '../../../hasura-metadata-types'; +import { + NativeQueryArgument, + NativeQuery as NativeQueryMetadataType, +} from '../../../hasura-metadata-types'; +import { NativeQueryArgumentNormalized, NativeQueryForm } from './types'; export const transformFormOutputToMetadata = ( formValues: NativeQueryForm @@ -28,3 +31,11 @@ export const transformFormOutputToMetadata = ( type, }; }; + +export const normalizeArguments = ( + args: Record +): NativeQueryArgumentNormalized[] => + Object.entries(args).map(([name, argument]) => ({ + name, + ...argument, + })); diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LandingPage/LandingPage.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LandingPage/LandingPage.tsx index 24dbb7e8806..7bdf0247280 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LandingPage/LandingPage.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LandingPage/LandingPage.tsx @@ -1,30 +1,25 @@ -import { Tabs } from '../../../../new-components/Tabs'; -import { useMetadata } from '../../../hasura-metadata-api'; -import { ListLogicalModels } from './components/ListLogicalModels'; -import { ListNativeQueries } from './components/ListNativeQueries'; -import { extractModelsAndQueriesFromMetadata } from '../utils'; -import { - useDestructiveAlert, - useHasuraAlert, -} from '../../../../new-components/Alert'; -import { LogicalModelWithSource, NativeQueryWithSource } from '../types'; -import { useTrackNativeQuery } from '../../hooks/useTrackNativeQuery'; -import { useTrackLogicalModel } from '../../hooks/useTrackLogicalModel'; -import { hasuraToast } from '../../../../new-components/Toasts'; import { useState } from 'react'; import { InjectedRouter, Link, withRouter } from 'react-router'; -import { LogicalModelWidget } from '../LogicalModelWidget/LogicalModelWidget'; +import { useDestructiveAlert } from '../../../../new-components/Alert'; import { Button } from '../../../../new-components/Button'; +import { Tabs } from '../../../../new-components/Tabs'; +import { hasuraToast } from '../../../../new-components/Toasts'; +import { usePushRoute } from '../../../ConnectDBRedesign/hooks'; +import { useMetadata } from '../../../hasura-metadata-api'; +import { useTrackLogicalModel } from '../../hooks/useTrackLogicalModel'; +import { useTrackNativeQuery } from '../../hooks/useTrackNativeQuery'; +import { LogicalModelWidget } from '../LogicalModelWidget/LogicalModelWidget'; import { RouteWrapper } from '../components/RouteWrapper'; -import { ListStoredProcedures } from './components/ListStoredProcedures'; -export const LandingPage = ({ - push, - pathname, -}: { - pathname: string | undefined; - push?: (to: string) => void; -}) => { +import { LogicalModelWithSource, NativeQueryWithSource } from '../types'; +import { extractModelsAndQueriesFromMetadata } from '../utils'; +import { ListLogicalModels } from './components/ListLogicalModels'; +import { ListNativeQueries } from './components/ListNativeQueries'; +import { ListStoredProcedures } from './components/ListStoredProcedures'; +import { NATIVE_QUERY_ROUTES } from '../constants'; + +export const LandingPage = ({ pathname }: { pathname: string }) => { + const push = usePushRoute(); const { data, isLoading } = useMetadata(m => extractModelsAndQueriesFromMetadata(m) ); @@ -44,8 +39,6 @@ export const LandingPage = ({ const [isLogicalModelsDialogOpen, setIsLogicalModelsDialogOpen] = useState(false); - const { hasuraAlert } = useHasuraAlert(); - const { destructiveConfirm } = useDestructiveAlert(); const { untrackNativeQuery } = useTrackNativeQuery(); @@ -133,12 +126,10 @@ export const LandingPage = ({ { - hasuraAlert({ - title: 'Not Implemented', - message: - 'Editing is not implemented in the alpha release', - }); + onEditClick={query => { + push?.( + `data/native-queries/native-query/${query.source.name}/${query.root_field_name}` + ); }} onRemoveClick={handleRemoveNativeQuery} /> @@ -202,8 +193,8 @@ export const LandingPageRoute = withRouter<{ router: InjectedRouter; }>(({ location, router }) => { return ( - - + + ); }); diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LandingPage/components/ListNativeQueries.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LandingPage/components/ListNativeQueries.tsx index 70b7f299be1..20ad887a414 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LandingPage/components/ListNativeQueries.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LandingPage/components/ListNativeQueries.tsx @@ -4,10 +4,12 @@ import { useReactTable, } from '@tanstack/react-table'; import React from 'react'; +import { CgDetailsMore } from 'react-icons/cg'; +import { FaTrash } from 'react-icons/fa'; import Skeleton from 'react-loading-skeleton'; import { Button } from '../../../../../new-components/Button'; -import { NativeQueryWithSource } from '../../types'; import { CardedTableFromReactTable } from '../../components/CardedTableFromReactTable'; +import { NativeQueryWithSource } from '../../types'; const columnHelper = createColumnHelper(); @@ -44,10 +46,18 @@ export const ListNativeQueries = ({ header: 'Actions', cell: ({ cell, row }) => (
- {/* Re add once we implement Edit functionality */} - {/* */} +