diff --git a/src/common/constants.ts b/src/common/constants.ts index 489514cc..5db9c774 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -10,7 +10,9 @@ export const COLLATOR_CASE_INSENSITIVE = new Intl.Collator("en", { * Values to determine the index for each param. * https://host/explore/[slug]/[param-uuid]/[param-tab] * - ExploreView 0 returns the current UUID - * - ExploreView 1 returns the current tab + * - ExploreView 1 returns the current tab (or choose export) + * - ExportView 2 returns the export method */ export const PARAMS_INDEX_UUID = 0; -export const PARAMS_INDEX_TAB = 1; +export const PARAMS_INDEX_TAB = 1; // Note "export" (i.e. not a tab) can possibly be at this index too +export const PARAMS_INDEX_EXPORT_METHOD = 2; diff --git a/src/config/entities.ts b/src/config/entities.ts index 270eba93..52252dd4 100644 --- a/src/config/entities.ts +++ b/src/config/entities.ts @@ -176,8 +176,10 @@ export interface EntityConfig extends TabConfig { entityMapper?: EntityMapper; exploreMode: ExploreMode; explorerTitle?: SiteConfig["explorerTitle"]; + export?: ExportConfig; getId?: GetIdFunction; getTitle?: GetTitleFunction; + hideTabs?: boolean; list: ListConfig; listView?: ListViewConfig; options?: Options; diff --git a/src/hooks/useEntityExportConfig.ts b/src/hooks/useEntityExportConfig.ts new file mode 100644 index 00000000..1c804267 --- /dev/null +++ b/src/hooks/useEntityExportConfig.ts @@ -0,0 +1,16 @@ +import { ExportConfig } from "../config/entities"; +import { useConfig } from "./useConfig"; + +/** + * Returns the export configuration for the given entity. + * @returns export configuration. + */ +export const useEntityExportConfig = (): ExportConfig => { + const { entityConfig } = useConfig(); + + if (!entityConfig.export) { + throw new Error("This entity config does not have an export field set"); + } + + return entityConfig.export; +}; diff --git a/src/views/EntityDetailView/entityDetailView.tsx b/src/views/EntityDetailView/entityDetailView.tsx index aa8a8d2e..05041115 100644 --- a/src/views/EntityDetailView/entityDetailView.tsx +++ b/src/views/EntityDetailView/entityDetailView.tsx @@ -41,11 +41,11 @@ export const EntityDetailView = (props: EntityDetailViewProps): JSX.Element => { const { push, query } = useRouter(); const { entityConfig } = useConfig(); const { mainColumn, sideColumn } = currentTab; - const { detail, route: entityRoute } = entityConfig; + const { detail, hideTabs, route: entityRoute } = entityConfig; const { detailOverviews, top } = detail; const uuid = query.params?.[PARAMS_INDEX_UUID]; const isDetailOverview = detailOverviews?.includes(currentTab.label); - const tabs = getTabs(entityConfig); + const tabs = hideTabs ? [] : getTabs(entityConfig); const title = useEntityHeadTitle(response); if (!response) { @@ -78,7 +78,13 @@ export const EntityDetailView = (props: EntityDetailViewProps): JSX.Element => { ) : undefined } - Tabs={} + Tabs={ + hideTabs ? ( + <> + ) : ( + + ) + } top={} /> diff --git a/src/views/EntityExportMethodView/entityExportMethodView.tsx b/src/views/EntityExportMethodView/entityExportMethodView.tsx new file mode 100644 index 00000000..9d7156a2 --- /dev/null +++ b/src/views/EntityExportMethodView/entityExportMethodView.tsx @@ -0,0 +1,67 @@ +import { useRouter } from "next/router"; +import type { ParsedUrlQuery } from "querystring"; +import React from "react"; +import { EntityDetailViewProps } from "views/EntityDetailView/entityDetailView"; +import { PARAMS_INDEX_EXPORT_METHOD } from "../../common/constants"; +import { ComponentCreator } from "../../components/ComponentCreator/ComponentCreator"; +import { BackPageView } from "../../components/Layout/components/BackPage/backPageView"; +import { ExportMethodConfig } from "../../config/entities"; +import { useEntityExportConfig } from "../../hooks/useEntityExportConfig"; +import { useFetchEntity } from "../../hooks/useFetchEntity"; +import { useUpdateURLCatalogParams } from "../../hooks/useUpdateURLCatalogParam"; + +export const EntityExportMethodView = ( + props: EntityDetailViewProps +): JSX.Element => { + // Update the catalog param if necessary. + useUpdateURLCatalogParams(); + + // Grab the entity to be exported. + const { response } = useFetchEntity(props); + + // Get the column definitions for the entity export. + const { query } = useRouter(); + const { exportMethods, tabs } = useEntityExportConfig(); + const { sideColumn } = tabs[0]; + const { mainColumn, top } = getExportMethodConfig(exportMethods, query) || {}; + + // Wait for the entity to be fetched. + if (!response) { + return ; + } + + return ( + + } + sideColumn={ + sideColumn ? ( + + ) : undefined + } + top={} + /> + ); +}; + +/** + * Returns the export method configuration for the given pathname. + * @param exportMethods - Export methods config. + * @param query - Router query object. + * @returns export method configuration. + */ +function getExportMethodConfig( + exportMethods: ExportMethodConfig[], + query: ParsedUrlQuery +): ExportMethodConfig | undefined { + // Determine the selected export method from the URL. + const exportMethodRoute = query.params?.[PARAMS_INDEX_EXPORT_METHOD]; + if (!exportMethodRoute) { + return; + } + // Find the config for the selected export method. + return exportMethods.find(({ route }) => { + return route.includes(exportMethodRoute); + }); +} diff --git a/src/views/EntityExportView/entityExportView.tsx b/src/views/EntityExportView/entityExportView.tsx new file mode 100644 index 00000000..2a07a442 --- /dev/null +++ b/src/views/EntityExportView/entityExportView.tsx @@ -0,0 +1,39 @@ +import React from "react"; +import { EntityDetailViewProps } from "views/EntityDetailView/entityDetailView"; +import { ComponentCreator } from "../../components/ComponentCreator/ComponentCreator"; +import { BackPageView } from "../../components/Layout/components/BackPage/backPageView"; +import { useEntityExportConfig } from "../../hooks/useEntityExportConfig"; +import { useFetchEntity } from "../../hooks/useFetchEntity"; +import { useUpdateURLCatalogParams } from "../../hooks/useUpdateURLCatalogParam"; + +export const EntityExportView = (props: EntityDetailViewProps): JSX.Element => { + // Update the catalog param if necessary. + useUpdateURLCatalogParams(); + + // Grab the entity to be exported. + const { response } = useFetchEntity(props); + + // Get the column definitions for the entity export. + const { tabs, top } = useEntityExportConfig(); + const currentTab = tabs[0]; + const { mainColumn, sideColumn } = currentTab; + + // Wait for the entity to be fetched. + if (!response) { + return ; + } + + return ( + + } + sideColumn={ + sideColumn ? ( + + ) : undefined + } + top={} + /> + ); +};