Feat/front forge graphql query (#2007)
* wip * Wip * Wip * Finished v1 * Wip * Fix from PR * Removed unused fragment masking feature * Fix from PR * Removed POC from nav bar * Fix lint --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -5,18 +5,21 @@
|
|||||||
"editor.formatOnSave": false,
|
"editor.formatOnSave": false,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": true,
|
"source.fixAll.eslint": true,
|
||||||
|
"source.addMissingImports": "always"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"[javascript]": {
|
"[javascript]": {
|
||||||
"editor.formatOnSave": false,
|
"editor.formatOnSave": false,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": true,
|
"source.fixAll.eslint": true,
|
||||||
|
"source.addMissingImports": "always"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"[typescriptreact]": {
|
"[typescriptreact]": {
|
||||||
"editor.formatOnSave": false,
|
"editor.formatOnSave": false,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": true,
|
"source.fixAll.eslint": true,
|
||||||
|
"source.addMissingImports": "always"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"[json]": {
|
"[json]": {
|
||||||
|
|||||||
@ -28,6 +28,8 @@ import { SettingsWorkspaceMembers } from '~/pages/settings/SettingsWorkspaceMemb
|
|||||||
import { Tasks } from '~/pages/tasks/Tasks';
|
import { Tasks } from '~/pages/tasks/Tasks';
|
||||||
import { getPageTitleFromPath } from '~/utils/title-utils';
|
import { getPageTitleFromPath } from '~/utils/title-utils';
|
||||||
|
|
||||||
|
import { ObjectTablePage } from './pages/companies/ObjectsTable';
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const pageTitle = getPageTitleFromPath(pathname);
|
const pageTitle = getPageTitleFromPath(pathname);
|
||||||
@ -54,6 +56,16 @@ export const App = () => {
|
|||||||
<Route path={AppPath.Impersonate} element={<ImpersonateEffect />} />
|
<Route path={AppPath.Impersonate} element={<ImpersonateEffect />} />
|
||||||
|
|
||||||
<Route path={AppPath.OpportunitiesPage} element={<Opportunities />} />
|
<Route path={AppPath.OpportunitiesPage} element={<Opportunities />} />
|
||||||
|
<Route
|
||||||
|
path={AppPath.ObjectTablePage}
|
||||||
|
element={
|
||||||
|
<ObjectTablePage
|
||||||
|
objectName="supplier"
|
||||||
|
objectNameSingular="Supplier"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path={AppPath.SettingsCatchAll}
|
path={AppPath.SettingsCatchAll}
|
||||||
element={
|
element={
|
||||||
|
|||||||
@ -186,3 +186,39 @@ export const companiesAvailableColumnDefinitions: ColumnDefinition<FieldMetadata
|
|||||||
infoTooltipContent: 'The company Twitter account.',
|
infoTooltipContent: 'The company Twitter account.',
|
||||||
} satisfies ColumnDefinition<FieldURLMetadata>,
|
} satisfies ColumnDefinition<FieldURLMetadata>,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const suppliersAvailableColumnDefinitions: ColumnDefinition<FieldMetadata>[] =
|
||||||
|
[
|
||||||
|
{
|
||||||
|
key: 'name',
|
||||||
|
name: 'Name',
|
||||||
|
Icon: IconBuildingSkyscraper,
|
||||||
|
size: 180,
|
||||||
|
index: 0,
|
||||||
|
type: 'text',
|
||||||
|
metadata: {
|
||||||
|
fieldName: 'name',
|
||||||
|
placeHolder: 'Company Name',
|
||||||
|
},
|
||||||
|
isVisible: true,
|
||||||
|
buttonIcon: IconArrowUpRight,
|
||||||
|
infoTooltipContent: 'The company name.',
|
||||||
|
basePathToShowPage: '/companies/',
|
||||||
|
} satisfies ColumnDefinition<FieldTextMetadata>,
|
||||||
|
{
|
||||||
|
key: 'city',
|
||||||
|
name: 'City',
|
||||||
|
Icon: IconBuildingSkyscraper,
|
||||||
|
size: 180,
|
||||||
|
index: 0,
|
||||||
|
type: 'text',
|
||||||
|
metadata: {
|
||||||
|
fieldName: 'city',
|
||||||
|
placeHolder: 'Company Name',
|
||||||
|
},
|
||||||
|
isVisible: true,
|
||||||
|
buttonIcon: IconArrowUpRight,
|
||||||
|
infoTooltipContent: 'The company name.',
|
||||||
|
basePathToShowPage: '/companies/',
|
||||||
|
} satisfies ColumnDefinition<FieldTextMetadata>,
|
||||||
|
];
|
||||||
|
|||||||
@ -21,7 +21,10 @@ export const FetchMetadataEffect = () => {
|
|||||||
query: GET_ALL_OBJECTS,
|
query: GET_ALL_OBJECTS,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (objects.data.objects.edges.length > 0) {
|
if (
|
||||||
|
objects.data.objects.edges.length > 0 &&
|
||||||
|
metadataObjects.length === 0
|
||||||
|
) {
|
||||||
const formattedObjects: MetadataObject[] =
|
const formattedObjects: MetadataObject[] =
|
||||||
objects.data.objects.edges.map((object) => ({
|
objects.data.objects.edges.map((object) => ({
|
||||||
...object.node,
|
...object.node,
|
||||||
|
|||||||
@ -0,0 +1,68 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useSearchParams } from 'react-router-dom';
|
||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
import { TableRecoilScopeContext } from '@/ui/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
|
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
|
||||||
|
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||||
|
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
|
||||||
|
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
|
||||||
|
import { savedSortsFamilyState } from '@/ui/view-bar/states/savedSortsFamilyState';
|
||||||
|
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
|
||||||
|
|
||||||
|
import { useFindManyCustomObjects } from '../hooks/useFindManyCustomObjects';
|
||||||
|
|
||||||
|
import { useSetObjectDataTableData } from './useSetDataTableData';
|
||||||
|
|
||||||
|
export const ObjectDataTableEffect = ({
|
||||||
|
objectName,
|
||||||
|
objectNameSingular,
|
||||||
|
}: {
|
||||||
|
objectNameSingular: string;
|
||||||
|
objectName: string;
|
||||||
|
}) => {
|
||||||
|
const setDataTableData = useSetObjectDataTableData();
|
||||||
|
|
||||||
|
const { data } = useFindManyCustomObjects({ objectName });
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const entities = data?.['findMany' + objectNameSingular]?.edges ?? [];
|
||||||
|
|
||||||
|
setDataTableData(entities);
|
||||||
|
}, [data, objectNameSingular, setDataTableData]);
|
||||||
|
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
const tableRecoilScopeId = useRecoilScopeId(TableRecoilScopeContext);
|
||||||
|
const handleViewSelect = useRecoilCallback(
|
||||||
|
({ set, snapshot }) =>
|
||||||
|
async (viewId: string) => {
|
||||||
|
const currentView = await snapshot.getPromise(
|
||||||
|
currentViewIdScopedState(tableRecoilScopeId),
|
||||||
|
);
|
||||||
|
if (currentView === viewId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const savedFilters = await snapshot.getPromise(
|
||||||
|
savedFiltersFamilyState(viewId),
|
||||||
|
);
|
||||||
|
const savedSorts = await snapshot.getPromise(
|
||||||
|
savedSortsFamilyState(viewId),
|
||||||
|
);
|
||||||
|
|
||||||
|
set(filtersScopedState(tableRecoilScopeId), savedFilters);
|
||||||
|
set(sortsScopedState(tableRecoilScopeId), savedSorts);
|
||||||
|
set(currentViewIdScopedState(tableRecoilScopeId), viewId);
|
||||||
|
},
|
||||||
|
[tableRecoilScopeId],
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const viewId = searchParams.get('view');
|
||||||
|
if (viewId) {
|
||||||
|
handleViewSelect(viewId);
|
||||||
|
}
|
||||||
|
}, [handleViewSelect, searchParams]);
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
};
|
||||||
57
front/src/modules/metadata/components/ObjectTable.tsx
Normal file
57
front/src/modules/metadata/components/ObjectTable.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { suppliersAvailableColumnDefinitions } from '@/companies/constants/companiesAvailableColumnDefinitions';
|
||||||
|
import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport';
|
||||||
|
import { DataTable } from '@/ui/data-table/components/DataTable';
|
||||||
|
import { TableContext } from '@/ui/data-table/contexts/TableContext';
|
||||||
|
import { TableRecoilScopeContext } from '@/ui/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
|
import { ViewBarContext } from '@/ui/view-bar/contexts/ViewBarContext';
|
||||||
|
import { useTableViews } from '@/views/hooks/useTableViews';
|
||||||
|
|
||||||
|
import { ObjectDataTableEffect } from './ObjectDataTableEffect';
|
||||||
|
|
||||||
|
export const ObjectTable = ({
|
||||||
|
objectName,
|
||||||
|
objectNameSingular,
|
||||||
|
}: {
|
||||||
|
objectNameSingular: string;
|
||||||
|
objectName: string;
|
||||||
|
}) => {
|
||||||
|
const { createView, deleteView, submitCurrentView, updateView } =
|
||||||
|
useTableViews({
|
||||||
|
objectId: 'company',
|
||||||
|
columnDefinitions: suppliersAvailableColumnDefinitions,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableContext.Provider
|
||||||
|
value={{
|
||||||
|
onColumnsChange: () => {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ObjectDataTableEffect
|
||||||
|
objectName={objectName}
|
||||||
|
objectNameSingular={objectNameSingular}
|
||||||
|
/>
|
||||||
|
<ViewBarContext.Provider
|
||||||
|
value={{
|
||||||
|
defaultViewName: 'All Suppliers',
|
||||||
|
onCurrentViewSubmit: submitCurrentView,
|
||||||
|
onViewCreate: createView,
|
||||||
|
onViewEdit: updateView,
|
||||||
|
onViewRemove: deleteView,
|
||||||
|
onImport: openCompanySpreadsheetImport,
|
||||||
|
ViewBarRecoilScopeContext: TableRecoilScopeContext,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DataTable
|
||||||
|
updateEntityMutation={() => {
|
||||||
|
//
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ViewBarContext.Provider>
|
||||||
|
</TableContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
61
front/src/modules/metadata/components/useSetDataTableData.ts
Normal file
61
front/src/modules/metadata/components/useSetDataTableData.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
import { useResetTableRowSelection } from '@/ui/data-table/hooks/useResetTableRowSelection';
|
||||||
|
import { isFetchingDataTableDataState } from '@/ui/data-table/states/isFetchingDataTableDataState';
|
||||||
|
import { numberOfTableRowsState } from '@/ui/data-table/states/numberOfTableRowsState';
|
||||||
|
import { TableRecoilScopeContext } from '@/ui/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
|
import { tableRowIdsState } from '@/ui/data-table/states/tableRowIdsState';
|
||||||
|
import { entityFieldsFamilyState } from '@/ui/field/states/entityFieldsFamilyState';
|
||||||
|
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
|
||||||
|
import { availableFiltersScopedState } from '@/ui/view-bar/states/availableFiltersScopedState';
|
||||||
|
import { availableSortsScopedState } from '@/ui/view-bar/states/availableSortsScopedState';
|
||||||
|
import { entityCountInCurrentViewState } from '@/ui/view-bar/states/entityCountInCurrentViewState';
|
||||||
|
|
||||||
|
export const useSetObjectDataTableData = () => {
|
||||||
|
const resetTableRowSelection = useResetTableRowSelection();
|
||||||
|
|
||||||
|
const tableContextScopeId = useRecoilScopeId(TableRecoilScopeContext);
|
||||||
|
|
||||||
|
return useRecoilCallback(
|
||||||
|
({ set, snapshot }) =>
|
||||||
|
<T extends { node: { id: string } }>(newEntityArrayRaw: T[]) => {
|
||||||
|
const newEntityArray = newEntityArrayRaw.map((entity) => entity.node);
|
||||||
|
|
||||||
|
for (const entity of newEntityArray) {
|
||||||
|
const currentEntity = snapshot
|
||||||
|
.getLoadable(entityFieldsFamilyState(entity.id))
|
||||||
|
.valueOrThrow();
|
||||||
|
|
||||||
|
if (JSON.stringify(currentEntity) !== JSON.stringify(entity)) {
|
||||||
|
set(entityFieldsFamilyState(entity.id), entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const entityIds = newEntityArray.map((entity) => entity.id);
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log({ newEntityArray, entityIds });
|
||||||
|
|
||||||
|
set(tableRowIdsState, (currentRowIds) => {
|
||||||
|
if (JSON.stringify(currentRowIds) !== JSON.stringify(entityIds)) {
|
||||||
|
return entityIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentRowIds;
|
||||||
|
});
|
||||||
|
|
||||||
|
resetTableRowSelection();
|
||||||
|
|
||||||
|
set(numberOfTableRowsState, entityIds.length);
|
||||||
|
|
||||||
|
set(entityCountInCurrentViewState, entityIds.length);
|
||||||
|
|
||||||
|
set(availableFiltersScopedState(tableContextScopeId), []);
|
||||||
|
|
||||||
|
set(availableSortsScopedState(tableContextScopeId), []);
|
||||||
|
|
||||||
|
set(isFetchingDataTableDataState, false);
|
||||||
|
},
|
||||||
|
[resetTableRowSelection, tableContextScopeId],
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
// TODO: add zod to validate that we have at least id on each object
|
||||||
|
export const useCreateOneCustomObject = ({
|
||||||
|
_objectName,
|
||||||
|
}: {
|
||||||
|
_objectName: string;
|
||||||
|
}) => {
|
||||||
|
// TODO : code
|
||||||
|
};
|
||||||
59
front/src/modules/metadata/hooks/useFindManyCustomObjects.ts
Normal file
59
front/src/modules/metadata/hooks/useFindManyCustomObjects.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { gql, useQuery } from '@apollo/client';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { metadataObjectsState } from '../states/metadataObjectsState';
|
||||||
|
import { generateFindManyCustomObjectsQuery } from '../utils/generateFindManyCustomObjectsQuery';
|
||||||
|
|
||||||
|
// TODO: add zod to validate that we have at least id on each object
|
||||||
|
export const useFindManyCustomObjects = ({
|
||||||
|
objectName,
|
||||||
|
}: {
|
||||||
|
objectName: string;
|
||||||
|
}) => {
|
||||||
|
const [metadataObjects] = useRecoilState(metadataObjectsState);
|
||||||
|
|
||||||
|
const foundObject = metadataObjects.find(
|
||||||
|
(object) => object.nameSingular === objectName,
|
||||||
|
);
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log({ foundObject });
|
||||||
|
|
||||||
|
const generatedQuery = foundObject
|
||||||
|
? generateFindManyCustomObjectsQuery({
|
||||||
|
metadataObject: foundObject,
|
||||||
|
})
|
||||||
|
: gql`
|
||||||
|
query EmptyQuery {
|
||||||
|
empty
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const {
|
||||||
|
fetchMore: fetchMoreBase,
|
||||||
|
data,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
} = useQuery(generatedQuery, {
|
||||||
|
skip: !foundObject,
|
||||||
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log({ data, loading, error });
|
||||||
|
|
||||||
|
const fetchMore = ({ fromCursor }: { fromCursor: string }) => {
|
||||||
|
fetchMoreBase({
|
||||||
|
variables: { fromCursor },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const objectNotFoundInMetadata = metadataObjects.length > 0 && !foundObject;
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
fetchMore,
|
||||||
|
objectNotFoundInMetadata,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
import { MetadataObject } from '../types/MetadataObject';
|
||||||
|
|
||||||
|
export const generateFindManyCustomObjectsQuery = ({
|
||||||
|
metadataObject,
|
||||||
|
_fromCursor,
|
||||||
|
}: {
|
||||||
|
metadataObject: MetadataObject;
|
||||||
|
_fromCursor?: string;
|
||||||
|
}) => {
|
||||||
|
return gql`
|
||||||
|
query CustomQuery${metadataObject.nameSingular} {
|
||||||
|
findMany${metadataObject.nameSingular}{
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
${metadataObject.fields
|
||||||
|
.map((field) => field.nameSingular)
|
||||||
|
.join('\n')}
|
||||||
|
}
|
||||||
|
cursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
};
|
||||||
@ -17,6 +17,8 @@ export enum AppPath {
|
|||||||
PersonShowPage = '/person/:personId',
|
PersonShowPage = '/person/:personId',
|
||||||
TasksPage = '/tasks',
|
TasksPage = '/tasks',
|
||||||
OpportunitiesPage = '/opportunities',
|
OpportunitiesPage = '/opportunities',
|
||||||
|
ObjectTablePage = '/:objectName',
|
||||||
|
|
||||||
SettingsCatchAll = `/settings/*`,
|
SettingsCatchAll = `/settings/*`,
|
||||||
|
|
||||||
// Impersonate
|
// Impersonate
|
||||||
|
|||||||
@ -27,6 +27,9 @@ export const DataTableBody = () => {
|
|||||||
|
|
||||||
const tableRowIds = useRecoilValue(tableRowIdsState);
|
const tableRowIds = useRecoilValue(tableRowIdsState);
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log({ tableRowIds });
|
||||||
|
|
||||||
const isNavbarSwitchingSize = useRecoilValue(isNavbarSwitchingSizeState);
|
const isNavbarSwitchingSize = useRecoilValue(isNavbarSwitchingSizeState);
|
||||||
const isFetchingDataTableData = useRecoilValue(isFetchingDataTableDataState);
|
const isFetchingDataTableData = useRecoilValue(isFetchingDataTableDataState);
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,9 @@ export const DataTableCell = ({ cellIndex }: { cellIndex: number }) => {
|
|||||||
|
|
||||||
const updateEntityMutation = useContext(EntityUpdateMutationContext);
|
const updateEntityMutation = useContext(EntityUpdateMutationContext);
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log({ columnDefinition, currentRowId });
|
||||||
|
|
||||||
if (!columnDefinition || !currentRowId) {
|
if (!columnDefinition || !currentRowId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,8 @@ export const DataTableRow = forwardRef<HTMLTableRowElement, DataTableRowProps>(
|
|||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const { currentRowSelected } = useCurrentRowSelected();
|
const { currentRowSelected } = useCurrentRowSelected();
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log({ visibleTableColumns });
|
||||||
return (
|
return (
|
||||||
<StyledRow
|
<StyledRow
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@ -18,6 +18,9 @@ export const TableCell = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { fieldDefinition } = useContext(FieldContext);
|
const { fieldDefinition } = useContext(FieldContext);
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log({ fieldDefinition });
|
||||||
|
|
||||||
const { closeTableCell } = useTableCell();
|
const { closeTableCell } = useTableCell();
|
||||||
|
|
||||||
const { moveLeft, moveRight, moveDown } = useMoveSoftFocus();
|
const { moveLeft, moveRight, moveDown } = useMoveSoftFocus();
|
||||||
|
|||||||
58
front/src/pages/companies/ObjectsTable.tsx
Normal file
58
front/src/pages/companies/ObjectsTable.tsx
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
|
import { ObjectTable } from '@/metadata/components/ObjectTable';
|
||||||
|
import { DataTableActionBar } from '@/ui/data-table/action-bar/components/DataTableActionBar';
|
||||||
|
import { DataTableContextMenu } from '@/ui/data-table/context-menu/components/DataTableContextMenu';
|
||||||
|
import { TableRecoilScopeContext } from '@/ui/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
|
import { IconBuildingSkyscraper } from '@/ui/icon';
|
||||||
|
import { PageAddButton } from '@/ui/layout/components/PageAddButton';
|
||||||
|
import { PageBody } from '@/ui/layout/components/PageBody';
|
||||||
|
import { PageContainer } from '@/ui/layout/components/PageContainer';
|
||||||
|
import { PageHeader } from '@/ui/layout/components/PageHeader';
|
||||||
|
import { PageHotkeysEffect } from '@/ui/layout/components/PageHotkeysEffect';
|
||||||
|
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||||
|
|
||||||
|
const StyledTableContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ObjectTablePage = ({
|
||||||
|
objectName,
|
||||||
|
objectNameSingular,
|
||||||
|
}: {
|
||||||
|
objectNameSingular: string;
|
||||||
|
objectName: string;
|
||||||
|
}) => {
|
||||||
|
const handleAddButtonClick = async () => {
|
||||||
|
const newCompanyId: string = v4();
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('newCompanyId', newCompanyId);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer>
|
||||||
|
<PageHeader title="Objects" Icon={IconBuildingSkyscraper}>
|
||||||
|
<PageHotkeysEffect onAddButtonClick={handleAddButtonClick} />
|
||||||
|
<PageAddButton onClick={handleAddButtonClick} />
|
||||||
|
</PageHeader>
|
||||||
|
<PageBody>
|
||||||
|
<RecoilScope
|
||||||
|
scopeId="objects"
|
||||||
|
CustomRecoilScopeContext={TableRecoilScopeContext}
|
||||||
|
>
|
||||||
|
<StyledTableContainer>
|
||||||
|
<ObjectTable
|
||||||
|
objectName={objectName}
|
||||||
|
objectNameSingular={objectNameSingular}
|
||||||
|
/>
|
||||||
|
</StyledTableContainer>
|
||||||
|
<DataTableActionBar />
|
||||||
|
<DataTableContextMenu />
|
||||||
|
</RecoilScope>
|
||||||
|
</PageBody>
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user