mirror of
				https://github.com/lingble/twenty.git
				synced 2025-10-30 20:27:55 +00:00 
			
		
		
		
	Add opened section (#7265)
When object is not part of the workspace favorite list, we want to show it in the "opened section" while its record page is accessed. This PR: - adds a new component `NavigationDrawerOpenedSection` - makes workflow versions and runs not system object + creates a prefilled view index for these - do not create workspace favorites for these so these do not appear in the workspace section <img width="1129" alt="Capture d’écran 2024-09-26 à 11 45 25" src="https://github.com/user-attachments/assets/c84d773c-0bef-4dce-b66a-55d7d00b0fb6">
This commit is contained in:
		| @@ -1,7 +1,6 @@ | ||||
| import { useFavorites } from '@/favorites/hooks/useFavorites'; | ||||
| import { useFilteredObjectMetadataItemsForWorkspaceFavorites } from '@/navigation/hooks/useObjectMetadataItemsInWorkspaceFavorites'; | ||||
| import { NavigationDrawerSectionForObjectMetadataItems } from '@/object-metadata/components/NavigationDrawerSectionForObjectMetadataItems'; | ||||
| import { NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader } from '@/object-metadata/components/NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader'; | ||||
| import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; | ||||
| import { useIsPrefetchLoading } from '@/prefetch/hooks/useIsPrefetchLoading'; | ||||
| import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; | ||||
| import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; | ||||
| @@ -9,34 +8,18 @@ import { View } from '@/views/types/View'; | ||||
|  | ||||
| export const WorkspaceFavorites = () => { | ||||
|   const { records: views } = usePrefetchedData<View>(PrefetchKey.AllViews); | ||||
|  | ||||
|   const { activeObjectMetadataItems: objectMetadataItemsToDisplay } = | ||||
|     useFilteredObjectMetadataItemsForWorkspaceFavorites(); | ||||
|  | ||||
|   const loading = useIsPrefetchLoading(); | ||||
|  | ||||
|   const { workspaceFavorites } = useFavorites(); | ||||
|  | ||||
|   const workspaceFavoriteIds = new Set( | ||||
|     workspaceFavorites.map((favorite) => favorite.recordId), | ||||
|   ); | ||||
|  | ||||
|   const favoriteViewObjectMetadataIds = views.reduce<string[]>((acc, view) => { | ||||
|     if (workspaceFavoriteIds.has(view.id)) { | ||||
|       acc.push(view.objectMetadataId); | ||||
|     } | ||||
|     return acc; | ||||
|   }, []); | ||||
|  | ||||
|   const { objectMetadataItems } = useFilteredObjectMetadataItems(); | ||||
|  | ||||
|   const objectMetadataItemsToDisplay = objectMetadataItems.filter((item) => | ||||
|     favoriteViewObjectMetadataIds.includes(item.id), | ||||
|   ); | ||||
|  | ||||
|   if (loading) { | ||||
|     return <NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader />; | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <NavigationDrawerSectionForObjectMetadataItems | ||||
|       sectionTitle={'Workspace Favorites'} | ||||
|       sectionTitle={'Workspace'} | ||||
|       objectMetadataItems={objectMetadataItemsToDisplay} | ||||
|       views={views} | ||||
|       isRemote={false} | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import { IconSearch, IconSettings } from 'twenty-ui'; | ||||
| import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu'; | ||||
| import { CurrentWorkspaceMemberFavorites } from '@/favorites/components/CurrentWorkspaceMemberFavorites'; | ||||
| import { WorkspaceFavorites } from '@/favorites/components/WorkspaceFavorites'; | ||||
| import { NavigationDrawerOpenedSection } from '@/object-metadata/components/NavigationDrawerOpenedSection'; | ||||
| import { NavigationDrawerSectionForObjectMetadataItemsWrapper } from '@/object-metadata/components/NavigationDrawerSectionForObjectMetadataItemsWrapper'; | ||||
| import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; | ||||
| import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection'; | ||||
| @@ -44,6 +45,8 @@ export const MainNavigationDrawerItems = () => { | ||||
|         </NavigationDrawerSection> | ||||
|       )} | ||||
|  | ||||
|       {isWorkspaceFavoriteEnabled && <NavigationDrawerOpenedSection />} | ||||
|  | ||||
|       <CurrentWorkspaceMemberFavorites /> | ||||
|  | ||||
|       {isWorkspaceFavoriteEnabled ? ( | ||||
|   | ||||
| @@ -0,0 +1,35 @@ | ||||
| import { useFavorites } from '@/favorites/hooks/useFavorites'; | ||||
| import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; | ||||
| import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; | ||||
| import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; | ||||
| import { View } from '@/views/types/View'; | ||||
|  | ||||
| export const useFilteredObjectMetadataItemsForWorkspaceFavorites = () => { | ||||
|   const { records: views } = usePrefetchedData<View>(PrefetchKey.AllViews); | ||||
|  | ||||
|   const { workspaceFavorites } = useFavorites(); | ||||
|  | ||||
|   const workspaceFavoriteIds = new Set( | ||||
|     workspaceFavorites.map((favorite) => favorite.recordId), | ||||
|   ); | ||||
|  | ||||
|   const favoriteViewObjectMetadataIds = new Set( | ||||
|     views.reduce<string[]>((acc, view) => { | ||||
|       if (workspaceFavoriteIds.has(view.id)) { | ||||
|         acc.push(view.objectMetadataId); | ||||
|       } | ||||
|       return acc; | ||||
|     }, []), | ||||
|   ); | ||||
|  | ||||
|   const { activeObjectMetadataItems } = useFilteredObjectMetadataItems(); | ||||
|  | ||||
|   const activeObjectMetadataItemsInWorkspaceFavorites = | ||||
|     activeObjectMetadataItems.filter((item) => | ||||
|       favoriteViewObjectMetadataIds.has(item.id), | ||||
|     ); | ||||
|  | ||||
|   return { | ||||
|     activeObjectMetadataItems: activeObjectMetadataItemsInWorkspaceFavorites, | ||||
|   }; | ||||
| }; | ||||
| @@ -0,0 +1,57 @@ | ||||
| import { useParams } from 'react-router-dom'; | ||||
|  | ||||
| import { useFilteredObjectMetadataItemsForWorkspaceFavorites } from '@/navigation/hooks/useObjectMetadataItemsInWorkspaceFavorites'; | ||||
| import { NavigationDrawerSectionForObjectMetadataItems } from '@/object-metadata/components/NavigationDrawerSectionForObjectMetadataItems'; | ||||
| import { NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader } from '@/object-metadata/components/NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader'; | ||||
| import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems'; | ||||
| import { useIsPrefetchLoading } from '@/prefetch/hooks/useIsPrefetchLoading'; | ||||
| import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData'; | ||||
| import { PrefetchKey } from '@/prefetch/types/PrefetchKey'; | ||||
| import { View } from '@/views/types/View'; | ||||
|  | ||||
| export const NavigationDrawerOpenedSection = () => { | ||||
|   const { activeObjectMetadataItems } = useFilteredObjectMetadataItems(); | ||||
|   const filteredActiveObjectMetadataItems = activeObjectMetadataItems.filter( | ||||
|     (item) => !item.isRemote, | ||||
|   ); | ||||
|  | ||||
|   const { records: views } = usePrefetchedData<View>(PrefetchKey.AllViews); | ||||
|   const loading = useIsPrefetchLoading(); | ||||
|  | ||||
|   const currentObjectNamePlural = useParams().objectNamePlural; | ||||
|  | ||||
|   const { activeObjectMetadataItems: workspaceFavoritesObjectMetadataItems } = | ||||
|     useFilteredObjectMetadataItemsForWorkspaceFavorites(); | ||||
|  | ||||
|   if (!currentObjectNamePlural) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   const objectMetadataItem = filteredActiveObjectMetadataItems.find( | ||||
|     (item) => item.namePlural === currentObjectNamePlural, | ||||
|   ); | ||||
|  | ||||
|   if (!objectMetadataItem) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   const shouldDisplayObjectInOpenedSection = | ||||
|     !workspaceFavoritesObjectMetadataItems | ||||
|       .map((item) => item.id) | ||||
|       .includes(objectMetadataItem.id); | ||||
|  | ||||
|   if (loading) { | ||||
|     return <NavigationDrawerSectionForObjectMetadataItemsSkeletonLoader />; | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     shouldDisplayObjectInOpenedSection && ( | ||||
|       <NavigationDrawerSectionForObjectMetadataItems | ||||
|         sectionTitle={'Opened'} | ||||
|         objectMetadataItems={[objectMetadataItem]} | ||||
|         views={views} | ||||
|         isRemote={false} | ||||
|       /> | ||||
|     ) | ||||
|   ); | ||||
| }; | ||||
| @@ -1,40 +0,0 @@ | ||||
| import * as reactRouterDom from 'react-router-dom'; | ||||
|  | ||||
| import { useIsMenuNavbarDisplayed } from '../useIsMenuNavbarDisplayed'; | ||||
|  | ||||
| jest.mock('react-router-dom', () => ({ | ||||
|   useLocation: jest.fn(), | ||||
| })); | ||||
|  | ||||
| const setupMockLocation = (pathname: string) => { | ||||
|   jest.spyOn(reactRouterDom, 'useLocation').mockReturnValueOnce({ | ||||
|     pathname, | ||||
|     state: undefined, | ||||
|     key: '', | ||||
|     search: '', | ||||
|     hash: '', | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| describe('useIsMenuNavbarDisplayed', () => { | ||||
|   it('Should return true for paths starting with "/companies"', () => { | ||||
|     setupMockLocation('/companies'); | ||||
|  | ||||
|     const result = useIsMenuNavbarDisplayed(); | ||||
|     expect(result).toBeTruthy(); | ||||
|   }); | ||||
|  | ||||
|   it('Should return true for paths starting with "/companies/"', () => { | ||||
|     setupMockLocation('/companies/test-some-subpath'); | ||||
|  | ||||
|     const result = useIsMenuNavbarDisplayed(); | ||||
|     expect(result).toBeTruthy(); | ||||
|   }); | ||||
|  | ||||
|   it('Should return false for paths not starting with "/companies"', () => { | ||||
|     setupMockLocation('/test-path'); | ||||
|  | ||||
|     const result = useIsMenuNavbarDisplayed(); | ||||
|     expect(result).toBeFalsy(); | ||||
|   }); | ||||
| }); | ||||
| @@ -1,6 +0,0 @@ | ||||
| import { useLocation } from 'react-router-dom'; | ||||
|  | ||||
| export const useIsMenuNavbarDisplayed = () => { | ||||
|   const currentPath = useLocation().pathname; | ||||
|   return currentPath.match(/^\/companies(\/.*)?$/) !== null; | ||||
| }; | ||||
| @@ -40,6 +40,7 @@ import { DataSourceService } from 'src/engine/metadata-modules/data-source/data- | ||||
| import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata/field-metadata.service'; | ||||
| import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; | ||||
| import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service'; | ||||
| import { shouldSeedWorkspaceFavorite } from 'src/engine/utils/should-seed-workspace-favorite'; | ||||
| import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service'; | ||||
| import { viewPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/view'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
| @@ -219,7 +220,14 @@ export class DataSeedWorkspaceCommand extends CommandRunner { | ||||
|  | ||||
|             await seedWorkspaceFavorites( | ||||
|               viewDefinitionsWithId | ||||
|                 .filter((view) => view.key === 'INDEX') | ||||
|                 .filter( | ||||
|                   (view) => | ||||
|                     view.key === 'INDEX' && | ||||
|                     shouldSeedWorkspaceFavorite( | ||||
|                       view.objectMetadataId, | ||||
|                       objectMetadataMap, | ||||
|                     ), | ||||
|                 ) | ||||
|                 .map((view) => view.id), | ||||
|               entityManager, | ||||
|               dataSourceMetadata.schema, | ||||
|   | ||||
| @@ -0,0 +1,9 @@ | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const shouldSeedWorkspaceFavorite = ( | ||||
|   objectMetadataId, | ||||
|   objectMetadataMap, | ||||
| ): boolean => | ||||
|   objectMetadataId !== | ||||
|     objectMetadataMap[STANDARD_OBJECT_IDS.workflowVersion].id && | ||||
|   objectMetadataId !== objectMetadataMap[STANDARD_OBJECT_IDS.workflowRun].id; | ||||
| @@ -2,6 +2,7 @@ import { DataSource, EntityManager } from 'typeorm'; | ||||
|  | ||||
| import { seedWorkspaceFavorites } from 'src/database/typeorm-seeds/workspace/favorites'; | ||||
| import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; | ||||
| import { shouldSeedWorkspaceFavorite } from 'src/engine/utils/should-seed-workspace-favorite'; | ||||
| import { companyPrefillDemoData } from 'src/engine/workspace-manager/demo-objects-prefill-data/company'; | ||||
| import { opportunityPrefillDemoData } from 'src/engine/workspace-manager/demo-objects-prefill-data/opportunity'; | ||||
| import { personPrefillDemoData } from 'src/engine/workspace-manager/demo-objects-prefill-data/person'; | ||||
| @@ -42,7 +43,7 @@ export const demoObjectsPrefillData = async ( | ||||
|  | ||||
|       await seedWorkspaceFavorites( | ||||
|         viewDefinitionsWithId | ||||
|           .filter((view) => view.key === 'INDEX') | ||||
|           .filter((view) => view.key === 'INDEX' && shouldSeedWorkspaceFavorite(view.objectMetadataId, objectMetadataMap)) | ||||
|           .map((view) => view.id), | ||||
|         entityManager, | ||||
|         schemaName, | ||||
|   | ||||
| @@ -2,6 +2,7 @@ import { DataSource, EntityManager } from 'typeorm'; | ||||
|  | ||||
| import { seedWorkspaceFavorites } from 'src/database/typeorm-seeds/workspace/favorites'; | ||||
| import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; | ||||
| import { shouldSeedWorkspaceFavorite } from 'src/engine/utils/should-seed-workspace-favorite'; | ||||
| import { companyPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/company'; | ||||
| import { personPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/person'; | ||||
| import { viewPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/view'; | ||||
| @@ -45,7 +46,14 @@ export const standardObjectsPrefillData = async ( | ||||
|  | ||||
|     await seedWorkspaceFavorites( | ||||
|       viewDefinitionsWithId | ||||
|         .filter((view) => view.key === 'INDEX') | ||||
|         .filter( | ||||
|           (view) => | ||||
|             view.key === 'INDEX' && | ||||
|             shouldSeedWorkspaceFavorite( | ||||
|               view.objectMetadataId, | ||||
|               objectMetadataMap, | ||||
|             ), | ||||
|         ) | ||||
|         .map((view) => view.id), | ||||
|       entityManager, | ||||
|       schemaName, | ||||
|   | ||||
| @@ -9,6 +9,8 @@ import { opportunitiesByStageView } from 'src/engine/workspace-manager/standard- | ||||
| import { peopleAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/people-all.view'; | ||||
| import { tasksAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-all.view'; | ||||
| import { tasksByStatusView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-by-status.view'; | ||||
| import { workflowRunsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/workflow-runs-all.view'; | ||||
| import { workflowVersionsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/workflow-versions-all.view'; | ||||
| import { workflowsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/workflows-all.view'; | ||||
|  | ||||
| export const viewPrefillData = async ( | ||||
| @@ -18,14 +20,20 @@ export const viewPrefillData = async ( | ||||
|   isWorkflowEnabled: boolean, | ||||
| ) => { | ||||
|   const viewDefinitions = [ | ||||
|     await companiesAllView(objectMetadataMap), | ||||
|     await peopleAllView(objectMetadataMap), | ||||
|     await opportunitiesAllView(objectMetadataMap), | ||||
|     await opportunitiesByStageView(objectMetadataMap), | ||||
|     await notesAllView(objectMetadataMap), | ||||
|     await tasksAllView(objectMetadataMap), | ||||
|     await tasksByStatusView(objectMetadataMap), | ||||
|     ...(isWorkflowEnabled ? [await workflowsAllView(objectMetadataMap)] : []), | ||||
|     companiesAllView(objectMetadataMap), | ||||
|     peopleAllView(objectMetadataMap), | ||||
|     opportunitiesAllView(objectMetadataMap), | ||||
|     opportunitiesByStageView(objectMetadataMap), | ||||
|     notesAllView(objectMetadataMap), | ||||
|     tasksAllView(objectMetadataMap), | ||||
|     tasksByStatusView(objectMetadataMap), | ||||
|     ...(isWorkflowEnabled | ||||
|       ? [ | ||||
|           workflowsAllView(objectMetadataMap), | ||||
|           workflowVersionsAllView(objectMetadataMap), | ||||
|           workflowRunsAllView(objectMetadataMap), | ||||
|         ] | ||||
|       : []), | ||||
|   ]; | ||||
|  | ||||
|   const viewDefinitionsWithId = viewDefinitions.map((viewDefinition) => ({ | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import { | ||||
| } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const companiesAllView = async ( | ||||
| export const companiesAllView = ( | ||||
|   objectMetadataMap: Record<string, ObjectMetadataEntity>, | ||||
| ) => { | ||||
|   return { | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import { | ||||
| } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const notesAllView = async ( | ||||
| export const notesAllView = ( | ||||
|   objectMetadataMap: Record<string, ObjectMetadataEntity>, | ||||
| ) => { | ||||
|   return { | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat | ||||
| import { OPPORTUNITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const opportunitiesAllView = async ( | ||||
| export const opportunitiesAllView = ( | ||||
|   objectMetadataMap: Record<string, ObjectMetadataEntity>, | ||||
| ) => { | ||||
|   return { | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat | ||||
| import { OPPORTUNITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const opportunitiesByStageView = async ( | ||||
| export const opportunitiesByStageView = ( | ||||
|   objectMetadataMap: Record<string, ObjectMetadataEntity>, | ||||
| ) => { | ||||
|   return { | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import { | ||||
| } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const peopleAllView = async ( | ||||
| export const peopleAllView = ( | ||||
|   objectMetadataMap: Record<string, ObjectMetadataEntity>, | ||||
| ) => { | ||||
|   return { | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import { | ||||
| } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const tasksAllView = async ( | ||||
| export const tasksAllView = ( | ||||
|   objectMetadataMap: Record<string, ObjectMetadataEntity>, | ||||
| ) => { | ||||
|   return { | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import { | ||||
| } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const tasksByStatusView = async ( | ||||
| export const tasksByStatusView = ( | ||||
|   objectMetadataMap: Record<string, ObjectMetadataEntity>, | ||||
| ) => { | ||||
|   return { | ||||
|   | ||||
| @@ -0,0 +1,56 @@ | ||||
| import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; | ||||
| import { WORKFLOW_RUN_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const workflowRunsAllView = ( | ||||
|   objectMetadataMap: Record<string, ObjectMetadataEntity>, | ||||
| ) => { | ||||
|   return { | ||||
|     name: 'All Workflow Runs', | ||||
|     objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.workflowRun].id, | ||||
|     type: 'table', | ||||
|     key: 'INDEX', | ||||
|     position: 0, | ||||
|     icon: 'IconHistory', | ||||
|     kanbanFieldMetadataId: '', | ||||
|     filters: [], | ||||
|     fields: [ | ||||
|       { | ||||
|         fieldMetadataId: | ||||
|           objectMetadataMap[STANDARD_OBJECT_IDS.workflowRun].fields[ | ||||
|             WORKFLOW_RUN_STANDARD_FIELD_IDS.name | ||||
|           ], | ||||
|         position: 0, | ||||
|         isVisible: true, | ||||
|         size: 210, | ||||
|       }, | ||||
|       { | ||||
|         fieldMetadataId: | ||||
|           objectMetadataMap[STANDARD_OBJECT_IDS.workflowRun].fields[ | ||||
|             WORKFLOW_RUN_STANDARD_FIELD_IDS.status | ||||
|           ], | ||||
|         position: 1, | ||||
|         isVisible: true, | ||||
|         size: 150, | ||||
|       }, | ||||
|       { | ||||
|         fieldMetadataId: | ||||
|           objectMetadataMap[STANDARD_OBJECT_IDS.workflowRun].fields[ | ||||
|             WORKFLOW_RUN_STANDARD_FIELD_IDS.startedAt | ||||
|           ], | ||||
|         position: 2, | ||||
|         isVisible: true, | ||||
|         size: 150, | ||||
|       }, | ||||
|       { | ||||
|         fieldMetadataId: | ||||
|           objectMetadataMap[STANDARD_OBJECT_IDS.workflowRun].fields[ | ||||
|             WORKFLOW_RUN_STANDARD_FIELD_IDS.endedAt | ||||
|           ], | ||||
|         position: 3, | ||||
|         isVisible: true, | ||||
|         size: 150, | ||||
|       }, | ||||
|     ], | ||||
|   }; | ||||
| }; | ||||
| @@ -0,0 +1,56 @@ | ||||
| import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; | ||||
| import { WORKFLOW_VERSION_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const workflowVersionsAllView = ( | ||||
|   objectMetadataMap: Record<string, ObjectMetadataEntity>, | ||||
| ) => { | ||||
|   return { | ||||
|     name: 'All Workflow Versions', | ||||
|     objectMetadataId: objectMetadataMap[STANDARD_OBJECT_IDS.workflowVersion].id, | ||||
|     type: 'table', | ||||
|     key: 'INDEX', | ||||
|     position: 0, | ||||
|     icon: 'IconVersions', | ||||
|     kanbanFieldMetadataId: '', | ||||
|     filters: [], | ||||
|     fields: [ | ||||
|       { | ||||
|         fieldMetadataId: | ||||
|           objectMetadataMap[STANDARD_OBJECT_IDS.workflowVersion].fields[ | ||||
|             WORKFLOW_VERSION_STANDARD_FIELD_IDS.name | ||||
|           ], | ||||
|         position: 0, | ||||
|         isVisible: true, | ||||
|         size: 210, | ||||
|       }, | ||||
|       { | ||||
|         fieldMetadataId: | ||||
|           objectMetadataMap[STANDARD_OBJECT_IDS.workflowVersion].fields[ | ||||
|             WORKFLOW_VERSION_STANDARD_FIELD_IDS.status | ||||
|           ], | ||||
|         position: 1, | ||||
|         isVisible: true, | ||||
|         size: 150, | ||||
|       }, | ||||
|       { | ||||
|         fieldMetadataId: | ||||
|           objectMetadataMap[STANDARD_OBJECT_IDS.workflowVersion].fields[ | ||||
|             WORKFLOW_VERSION_STANDARD_FIELD_IDS.trigger | ||||
|           ], | ||||
|         position: 2, | ||||
|         isVisible: true, | ||||
|         size: 150, | ||||
|       }, | ||||
|       { | ||||
|         fieldMetadataId: | ||||
|           objectMetadataMap[STANDARD_OBJECT_IDS.workflowVersion].fields[ | ||||
|             WORKFLOW_VERSION_STANDARD_FIELD_IDS.steps | ||||
|           ], | ||||
|         position: 3, | ||||
|         isVisible: true, | ||||
|         size: 150, | ||||
|       }, | ||||
|     ], | ||||
|   }; | ||||
| }; | ||||
| @@ -2,7 +2,7 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat | ||||
| import { WORKFLOW_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||||
| import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||||
|  | ||||
| export const workflowsAllView = async ( | ||||
| export const workflowsAllView = ( | ||||
|   objectMetadataMap: Record<string, ObjectMetadataEntity>, | ||||
| ) => { | ||||
|   return { | ||||
|   | ||||
| @@ -412,11 +412,13 @@ export const WORKFLOW_STANDARD_FIELD_IDS = { | ||||
| }; | ||||
|  | ||||
| export const WORKFLOW_RUN_STANDARD_FIELD_IDS = { | ||||
|   name: '20202020-b840-4253-aef9-4e5013694587', | ||||
|   workflowVersion: '20202020-2f52-4ba8-8dc4-d0d6adb9578d', | ||||
|   workflow: '20202020-8c57-4e7f-84f5-f373f68e1b82', | ||||
|   startedAt: '20202020-a234-4e2d-bd15-85bcea6bb183', | ||||
|   endedAt: '20202020-e1c1-4b6b-bbbd-b2beaf2e159e', | ||||
|   status: '20202020-6b3e-4f9c-8c2b-2e5b8e6d6f3b', | ||||
|   position: '20202020-7802-4c40-ae89-1f506fe3365c', | ||||
|   createdBy: '20202020-6007-401a-8aa5-e6f38581a6f3', | ||||
|   output: '20202020-7be4-4db2-8ac6-3ff0d740843d', | ||||
| }; | ||||
| @@ -426,6 +428,7 @@ export const WORKFLOW_VERSION_STANDARD_FIELD_IDS = { | ||||
|   workflow: '20202020-afa3-46c3-91b0-0631ca6aa1c8', | ||||
|   trigger: '20202020-4eae-43e7-86e0-212b41a30b48', | ||||
|   status: '20202020-5a34-440e-8a25-39d8c3d1d4cf', | ||||
|   position: '20202020-791d-4950-ab28-0e704767ae1c', | ||||
|   runs: '20202020-1d08-46df-901a-85045f18099a', | ||||
|   steps: '20202020-5988-4a64-b94a-1f9b7b989039', | ||||
| }; | ||||
|   | ||||
| @@ -41,15 +41,25 @@ export type WorkflowRunOutput = { | ||||
| @WorkspaceEntity({ | ||||
|   standardId: STANDARD_OBJECT_IDS.workflowRun, | ||||
|   namePlural: 'workflowRuns', | ||||
|   labelSingular: 'workflowRun', | ||||
|   labelPlural: 'WorkflowRuns', | ||||
|   labelSingular: 'Workflow Run', | ||||
|   labelPlural: 'Workflow Runs', | ||||
|   description: 'A workflow run', | ||||
|   labelIdentifierStandardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.name, | ||||
|   icon: 'IconHistory', | ||||
| }) | ||||
| @WorkspaceGate({ | ||||
|   featureFlag: FeatureFlagKey.IsWorkflowEnabled, | ||||
| }) | ||||
| @WorkspaceIsSystem() | ||||
| export class WorkflowRunWorkspaceEntity extends BaseWorkspaceEntity { | ||||
|   @WorkspaceField({ | ||||
|     standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.name, | ||||
|     type: FieldMetadataType.TEXT, | ||||
|     label: 'Name', | ||||
|     description: 'Name of the workflow run', | ||||
|     icon: 'IconText', | ||||
|   }) | ||||
|   name: string; | ||||
|  | ||||
|   @WorkspaceField({ | ||||
|     standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.startedAt, | ||||
|     type: FieldMetadataType.DATE_TIME, | ||||
| @@ -75,7 +85,7 @@ export class WorkflowRunWorkspaceEntity extends BaseWorkspaceEntity { | ||||
|     type: FieldMetadataType.SELECT, | ||||
|     label: 'Workflow run status', | ||||
|     description: 'Workflow run status', | ||||
|     icon: 'IconHistory', | ||||
|     icon: 'IconStatusChange', | ||||
|     options: [ | ||||
|       { | ||||
|         value: WorkflowRunStatus.NOT_STARTED, | ||||
| @@ -128,6 +138,17 @@ export class WorkflowRunWorkspaceEntity extends BaseWorkspaceEntity { | ||||
|   @WorkspaceIsNullable() | ||||
|   output: WorkflowRunOutput | null; | ||||
|  | ||||
|   @WorkspaceField({ | ||||
|     standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.position, | ||||
|     type: FieldMetadataType.POSITION, | ||||
|     label: 'Position', | ||||
|     description: 'Workflow run position', | ||||
|     icon: 'IconHierarchy2', | ||||
|   }) | ||||
|   @WorkspaceIsSystem() | ||||
|   @WorkspaceIsNullable() | ||||
|   position: number | null; | ||||
|  | ||||
|   // Relations | ||||
|   @WorkspaceRelation({ | ||||
|     standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.workflowVersion, | ||||
|   | ||||
| @@ -61,8 +61,8 @@ const WorkflowVersionStatusOptions = [ | ||||
| @WorkspaceEntity({ | ||||
|   standardId: STANDARD_OBJECT_IDS.workflowVersion, | ||||
|   namePlural: 'workflowVersions', | ||||
|   labelSingular: 'WorkflowVersion', | ||||
|   labelPlural: 'WorkflowVersions', | ||||
|   labelSingular: 'Workflow Version', | ||||
|   labelPlural: 'Workflow Versions', | ||||
|   description: 'A workflow version', | ||||
|   icon: 'IconVersions', | ||||
|   labelIdentifierStandardId: WORKFLOW_VERSION_STANDARD_FIELD_IDS.name, | ||||
| @@ -70,7 +70,6 @@ const WorkflowVersionStatusOptions = [ | ||||
| @WorkspaceGate({ | ||||
|   featureFlag: FeatureFlagKey.IsWorkflowEnabled, | ||||
| }) | ||||
| @WorkspaceIsSystem() | ||||
| export class WorkflowVersionWorkspaceEntity extends BaseWorkspaceEntity { | ||||
|   @WorkspaceField({ | ||||
|     standardId: WORKFLOW_VERSION_STANDARD_FIELD_IDS.name, | ||||
| @@ -86,6 +85,7 @@ export class WorkflowVersionWorkspaceEntity extends BaseWorkspaceEntity { | ||||
|     type: FieldMetadataType.RAW_JSON, | ||||
|     label: 'Version trigger', | ||||
|     description: 'Json object to provide trigger', | ||||
|     icon: 'IconSettingsAutomation', | ||||
|   }) | ||||
|   @WorkspaceIsNullable() | ||||
|   trigger: WorkflowTrigger | null; | ||||
| @@ -95,6 +95,7 @@ export class WorkflowVersionWorkspaceEntity extends BaseWorkspaceEntity { | ||||
|     type: FieldMetadataType.RAW_JSON, | ||||
|     label: 'Version steps', | ||||
|     description: 'Json object to provide steps', | ||||
|     icon: 'IconSettingsAutomation', | ||||
|   }) | ||||
|   @WorkspaceIsNullable() | ||||
|   steps: WorkflowStep[] | null; | ||||
| @@ -104,11 +105,23 @@ export class WorkflowVersionWorkspaceEntity extends BaseWorkspaceEntity { | ||||
|     type: FieldMetadataType.SELECT, | ||||
|     label: 'Version status', | ||||
|     description: 'The workflow version status', | ||||
|     icon: 'IconStatusChange', | ||||
|     options: WorkflowVersionStatusOptions, | ||||
|     defaultValue: "'DRAFT'", | ||||
|   }) | ||||
|   status: WorkflowVersionStatus; | ||||
|  | ||||
|   @WorkspaceField({ | ||||
|     standardId: WORKFLOW_VERSION_STANDARD_FIELD_IDS.position, | ||||
|     type: FieldMetadataType.POSITION, | ||||
|     label: 'Position', | ||||
|     description: 'Workflow version position', | ||||
|     icon: 'IconHierarchy2', | ||||
|   }) | ||||
|   @WorkspaceIsSystem() | ||||
|   @WorkspaceIsNullable() | ||||
|   position: number | null; | ||||
|  | ||||
|   // Relations | ||||
|   @WorkspaceRelation({ | ||||
|     standardId: WORKFLOW_VERSION_STANDARD_FIELD_IDS.workflow, | ||||
|   | ||||
| @@ -84,6 +84,7 @@ export class WorkflowWorkspaceEntity extends BaseWorkspaceEntity { | ||||
|     type: FieldMetadataType.MULTI_SELECT, | ||||
|     label: 'Statuses', | ||||
|     description: 'The current statuses of the workflow versions', | ||||
|     icon: 'IconStatusChange', | ||||
|     options: WorkflowStatusOptions, | ||||
|   }) | ||||
|   @WorkspaceIsNullable() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Thomas Trompette
					Thomas Trompette