diff --git a/front/src/App.tsx b/front/src/App.tsx
index b89be02e3..1e184234d 100644
--- a/front/src/App.tsx
+++ b/front/src/App.tsx
@@ -59,15 +59,7 @@ export const App = () => {
} />
} />
-
- }
- />
+ } />
{
Icon={IconTargetArrow}
active={currentPath === '/opportunities'}
/>
+
) : (
diff --git a/front/src/modules/metadata/components/MetadataObjectNavItems.tsx b/front/src/modules/metadata/components/MetadataObjectNavItems.tsx
new file mode 100644
index 000000000..18dcb4c61
--- /dev/null
+++ b/front/src/modules/metadata/components/MetadataObjectNavItems.tsx
@@ -0,0 +1,29 @@
+import { IconBuildingSkyscraper } from '@/ui/display/icon';
+import NavItem from '@/ui/navigation/navbar/components/NavItem';
+import { useGetClientConfigQuery } from '~/generated/graphql';
+import { capitalize } from '~/utils/string/capitalize';
+
+import { useFindManyMetadataObjects } from '../hooks/useFindManyMetadataObjects';
+
+export const MetadataObjectNavItems = () => {
+ const { data } = useGetClientConfigQuery();
+
+ const { metadataObjects } = useFindManyMetadataObjects();
+
+ const isFlexibleBackendEnabled = data?.clientConfig?.flexibleBackendEnabled;
+
+ if (!isFlexibleBackendEnabled) return <>>;
+
+ return (
+ <>
+ {metadataObjects.map((metadataObject) => (
+
+ ))}
+ >
+ );
+};
diff --git a/front/src/modules/metadata/components/ObjectDataTableEffect.tsx b/front/src/modules/metadata/components/ObjectDataTableEffect.tsx
index 524f10f9c..fd51fd0dd 100644
--- a/front/src/modules/metadata/components/ObjectDataTableEffect.tsx
+++ b/front/src/modules/metadata/components/ObjectDataTableEffect.tsx
@@ -12,25 +12,24 @@ import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilSco
import { useFindManyObjects } from '../hooks/useFindManyObjects';
import { useSetObjectDataTableData } from '../hooks/useSetDataTableData';
+import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
+
+export type ObjectDataTableEffectProps = MetadataObjectIdentifier;
export const ObjectDataTableEffect = ({
- objectNameSingular,
objectNamePlural,
-}: {
- objectNamePlural: string;
- objectNameSingular: string;
-}) => {
+}: ObjectDataTableEffectProps) => {
const setDataTableData = useSetObjectDataTableData();
const { objects } = useFindManyObjects({
- objectNamePlural: objectNamePlural,
+ objectNamePlural,
});
useEffect(() => {
const entities = objects ?? [];
setDataTableData(entities);
- }, [objects, objectNameSingular, setDataTableData]);
+ }, [objects, setDataTableData]);
const [searchParams] = useSearchParams();
const tableRecoilScopeId = useRecoilScopeId(TableRecoilScopeContext);
diff --git a/front/src/modules/metadata/components/ObjectTable.tsx b/front/src/modules/metadata/components/ObjectTable.tsx
index 0be4b1a71..c0525104e 100644
--- a/front/src/modules/metadata/components/ObjectTable.tsx
+++ b/front/src/modules/metadata/components/ObjectTable.tsx
@@ -1,27 +1,43 @@
import { suppliersAvailableColumnDefinitions } from '@/companies/constants/companiesAvailableColumnDefinitions';
-import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport';
import { DataTable } from '@/ui/data/data-table/components/DataTable';
import { TableContext } from '@/ui/data/data-table/contexts/TableContext';
import { TableRecoilScopeContext } from '@/ui/data/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { ViewBarContext } from '@/ui/data/view-bar/contexts/ViewBarContext';
import { useTableViews } from '@/views/hooks/useTableViews';
+import { useUpdateOneObject } from '../hooks/useUpdateOneObject';
+import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
+
import { ObjectDataTableEffect } from './ObjectDataTableEffect';
-export const ObjectTable = ({
- objectNamePlural,
- objectNameSingular,
-}: {
- objectNameSingular: string;
- objectNamePlural: string;
-}) => {
+export type ObjectTableProps = MetadataObjectIdentifier;
+
+export const ObjectTable = ({ objectNamePlural }: ObjectTableProps) => {
const { createView, deleteView, submitCurrentView, updateView } =
useTableViews({
objectId: 'company',
columnDefinitions: suppliersAvailableColumnDefinitions,
});
- const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport();
+ const { updateOneObject } = useUpdateOneObject({
+ objectNamePlural,
+ });
+
+ const updateEntity = ({
+ variables,
+ }: {
+ variables: {
+ where: { id: string };
+ data: {
+ [fieldName: string]: any;
+ };
+ };
+ }) => {
+ updateOneObject?.({
+ idToUpdate: variables.where.id,
+ input: variables.data,
+ });
+ };
return (
-
+
- {
- //
- }}
- />
+
);
diff --git a/front/src/modules/metadata/hooks/useCreateOneObject.ts b/front/src/modules/metadata/hooks/useCreateOneObject.ts
index ef7bee16c..e7bbe8e91 100644
--- a/front/src/modules/metadata/hooks/useCreateOneObject.ts
+++ b/front/src/modules/metadata/hooks/useCreateOneObject.ts
@@ -1,19 +1,17 @@
import { gql, useMutation } from '@apollo/client';
+import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
import { generateCreateOneObjectMutation } from '../utils/generateCreateOneObjectMutation';
-import { useFindManyMetadataObjects } from './useFindManyMetadataObjects';
+import { useFindOneMetadataObject } from './useFindOneMetadataObject';
export const useCreateOneObject = ({
objectNamePlural,
-}: {
- objectNamePlural: string;
-}) => {
- const { metadataObjects } = useFindManyMetadataObjects();
-
- const foundMetadataObject = metadataObjects.find(
- (object) => object.namePlural === objectNamePlural,
- );
+}: MetadataObjectIdentifier) => {
+ const { foundMetadataObject, objectNotFoundInMetadata } =
+ useFindOneMetadataObject({
+ objectNamePlural,
+ });
const generatedMutation = foundMetadataObject
? generateCreateOneObjectMutation({
@@ -25,6 +23,7 @@ export const useCreateOneObject = ({
}
`;
+ // TODO: type this with a minimal type at least with Record
const [mutate] = useMutation(generatedMutation);
const createOneObject = foundMetadataObject
@@ -39,9 +38,6 @@ export const useCreateOneObject = ({
}
: undefined;
- const objectNotFoundInMetadata =
- metadataObjects.length > 0 && !foundMetadataObject;
-
return {
createOneObject,
objectNotFoundInMetadata,
diff --git a/front/src/modules/metadata/hooks/useFindManyObjects.ts b/front/src/modules/metadata/hooks/useFindManyObjects.ts
index cb88e2112..3b0678452 100644
--- a/front/src/modules/metadata/hooks/useFindManyObjects.ts
+++ b/front/src/modules/metadata/hooks/useFindManyObjects.ts
@@ -1,11 +1,12 @@
import { useMemo } from 'react';
import { gql, useQuery } from '@apollo/client';
+import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
import { PaginatedObjectType } from '../types/PaginatedObjectType';
import { formatPagedObjectsToObjects } from '../utils/formatPagedObjectsToObjects';
import { generateFindManyCustomObjectsQuery } from '../utils/generateFindManyCustomObjectsQuery';
-import { useFindManyMetadataObjects } from './useFindManyMetadataObjects';
+import { useFindOneMetadataObject } from './useFindOneMetadataObject';
// TODO: test with a wrong name
// TODO: add zod to validate that we have at least id on each object
@@ -13,14 +14,11 @@ export const useFindManyObjects = <
ObjectType extends { id: string } & Record,
>({
objectNamePlural,
-}: {
- objectNamePlural: string;
-}) => {
- const { metadataObjects } = useFindManyMetadataObjects();
-
- const foundMetadataObject = metadataObjects.find(
- (object) => object.namePlural === objectNamePlural,
- );
+}: MetadataObjectIdentifier) => {
+ const { foundMetadataObject, objectNotFoundInMetadata } =
+ useFindOneMetadataObject({
+ objectNamePlural,
+ });
const generatedQuery = foundMetadataObject
? generateFindManyCustomObjectsQuery({
@@ -48,9 +46,6 @@ export const useFindManyObjects = <
[data, objectNamePlural],
);
- const objectNotFoundInMetadata =
- metadataObjects.length > 0 && !foundMetadataObject;
-
return {
objects,
loading,
diff --git a/front/src/modules/metadata/hooks/useFindOneMetadataObject.ts b/front/src/modules/metadata/hooks/useFindOneMetadataObject.ts
new file mode 100644
index 000000000..e4c584c27
--- /dev/null
+++ b/front/src/modules/metadata/hooks/useFindOneMetadataObject.ts
@@ -0,0 +1,21 @@
+import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
+
+import { useFindManyMetadataObjects } from './useFindManyMetadataObjects';
+
+export const useFindOneMetadataObject = ({
+ objectNamePlural,
+}: MetadataObjectIdentifier) => {
+ const { metadataObjects } = useFindManyMetadataObjects();
+
+ const foundMetadataObject = metadataObjects.find(
+ (object) => object.namePlural === objectNamePlural,
+ );
+
+ const objectNotFoundInMetadata =
+ metadataObjects.length > 0 && !foundMetadataObject;
+
+ return {
+ foundMetadataObject,
+ objectNotFoundInMetadata,
+ };
+};
diff --git a/front/src/modules/metadata/hooks/useUpdateOneMetadataObject.ts b/front/src/modules/metadata/hooks/useUpdateOneMetadataObject.ts
index 1faa6650a..5198f9afb 100644
--- a/front/src/modules/metadata/hooks/useUpdateOneMetadataObject.ts
+++ b/front/src/modules/metadata/hooks/useUpdateOneMetadataObject.ts
@@ -16,8 +16,7 @@ import { useFindManyMetadataObjects } from './useFindManyMetadataObjects';
export const useUpdateOneMetadataObject = () => {
const apolloClientMetadata = useApolloMetadataClient();
- const { getMetadataObjectsFromCache: queryMetadataObjects } =
- useFindManyMetadataObjects();
+ const { getMetadataObjectsFromCache } = useFindManyMetadataObjects();
const [mutate] = useMutation<
UpdateOneMetadataObjectMutation,
@@ -38,7 +37,7 @@ export const useUpdateOneMetadataObject = () => {
>
>;
}) => {
- const metadataObjects = queryMetadataObjects();
+ const metadataObjects = getMetadataObjectsFromCache();
const foundMetadataObject = metadataObjects.find(
(metadataObject) => metadataObject.id === idToUpdate,
diff --git a/front/src/modules/metadata/hooks/useUpdateOneObject.ts b/front/src/modules/metadata/hooks/useUpdateOneObject.ts
new file mode 100644
index 000000000..579a3e31b
--- /dev/null
+++ b/front/src/modules/metadata/hooks/useUpdateOneObject.ts
@@ -0,0 +1,52 @@
+import { gql, useMutation } from '@apollo/client';
+
+import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
+import { generateUpdateOneObjectMutation } from '../utils/generateUpdateOneObjectMutation';
+
+import { useFindOneMetadataObject } from './useFindOneMetadataObject';
+
+export const useUpdateOneObject = ({
+ objectNamePlural,
+}: MetadataObjectIdentifier) => {
+ const { foundMetadataObject, objectNotFoundInMetadata } =
+ useFindOneMetadataObject({
+ objectNamePlural,
+ });
+
+ const generatedMutation = foundMetadataObject
+ ? generateUpdateOneObjectMutation({
+ metadataObject: foundMetadataObject,
+ })
+ : gql`
+ mutation EmptyMutation {
+ empty
+ }
+ `;
+
+ // TODO: type this with a minimal type at least with Record
+ const [mutate] = useMutation(generatedMutation);
+
+ const updateOneObject = foundMetadataObject
+ ? ({
+ idToUpdate,
+ input,
+ }: {
+ idToUpdate: string;
+ input: Record;
+ }) => {
+ return mutate({
+ variables: {
+ idToUpdate: idToUpdate,
+ input: {
+ ...input,
+ },
+ },
+ });
+ }
+ : undefined;
+
+ return {
+ updateOneObject,
+ objectNotFoundInMetadata,
+ };
+};
diff --git a/front/src/modules/metadata/types/MetadataObjectIdentifier.ts b/front/src/modules/metadata/types/MetadataObjectIdentifier.ts
new file mode 100644
index 000000000..05c3f1be0
--- /dev/null
+++ b/front/src/modules/metadata/types/MetadataObjectIdentifier.ts
@@ -0,0 +1,3 @@
+export type MetadataObjectIdentifier = {
+ objectNamePlural: string;
+};
diff --git a/front/src/modules/metadata/utils/generateUpdateOneObjectMutation.ts b/front/src/modules/metadata/utils/generateUpdateOneObjectMutation.ts
new file mode 100644
index 000000000..47b3014dc
--- /dev/null
+++ b/front/src/modules/metadata/utils/generateUpdateOneObjectMutation.ts
@@ -0,0 +1,21 @@
+import { gql } from '@apollo/client';
+
+import { capitalize } from '~/utils/string/capitalize';
+
+import { MetadataObject } from '../types/MetadataObject';
+
+export const generateUpdateOneObjectMutation = ({
+ metadataObject,
+}: {
+ metadataObject: MetadataObject;
+}) => {
+ const capitalizedObjectName = capitalize(metadataObject.nameSingular);
+
+ return gql`
+ mutation UpdateOne${capitalizedObjectName}($idToUpdate: ID!, $input: ${capitalizedObjectName}UpdateInput!) {
+ updateOne${capitalizedObjectName}(id: $idToUpdate, data: $input) {
+ id
+ }
+ }
+ `;
+};
diff --git a/front/src/modules/types/AppPath.ts b/front/src/modules/types/AppPath.ts
index 51e7af629..24ea00f44 100644
--- a/front/src/modules/types/AppPath.ts
+++ b/front/src/modules/types/AppPath.ts
@@ -17,7 +17,7 @@ export enum AppPath {
PersonShowPage = '/person/:personId',
TasksPage = '/tasks',
OpportunitiesPage = '/opportunities',
- ObjectTablePage = '/:objectName',
+ ObjectTablePage = '/objects/:objectNamePlural',
SettingsCatchAll = `/settings/*`,
diff --git a/front/src/pages/companies/ObjectsTable.tsx b/front/src/pages/companies/ObjectsTable.tsx
index ec99da921..20c17e571 100644
--- a/front/src/pages/companies/ObjectsTable.tsx
+++ b/front/src/pages/companies/ObjectsTable.tsx
@@ -1,6 +1,8 @@
+import { useParams } from 'react-router-dom';
import styled from '@emotion/styled';
import { ObjectTable } from '@/metadata/components/ObjectTable';
+import { MetadataObjectIdentifier } from '@/metadata/types/MetadataObjectIdentifier';
import { DataTableActionBar } from '@/ui/data/data-table/action-bar/components/DataTableActionBar';
import { DataTableContextMenu } from '@/ui/data/data-table/context-menu/components/DataTableContextMenu';
import { TableRecoilScopeContext } from '@/ui/data/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
@@ -17,13 +19,11 @@ const StyledTableContainer = styled.div`
width: 100%;
`;
-export const ObjectTablePage = ({
- objectNamePlural,
- objectNameSingular,
-}: {
- objectNameSingular: string;
- objectNamePlural: string;
-}) => {
+export type ObjectTablePageProps = MetadataObjectIdentifier;
+
+export const ObjectTablePage = () => {
+ const objectNamePlural = useParams().objectNamePlural ?? '';
+
const handleAddButtonClick = async () => {
//
};
@@ -40,10 +40,7 @@ export const ObjectTablePage = ({
CustomRecoilScopeContext={TableRecoilScopeContext}
>
-
+