8191 command k workflow trigger for selected record (#8315)

Closes #8191 


https://github.com/user-attachments/assets/694da229-cc91-4df2-97a0-49cd5dabcf12
This commit is contained in:
Raphaël Bosi
2024-11-05 13:37:29 +01:00
committed by GitHub
parent 0893774cc1
commit d1531aa1b6
44 changed files with 543 additions and 209 deletions

View File

@ -1,5 +1,5 @@
import * as Apollo from '@apollo/client';
import { gql } from '@apollo/client'; import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
export type Maybe<T> = T | null; export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>; export type InputMaybe<T> = Maybe<T>;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] }; export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
@ -1849,6 +1849,13 @@ export type DeactivateWorkflowVersionMutationVariables = Exact<{
export type DeactivateWorkflowVersionMutation = { __typename?: 'Mutation', deactivateWorkflowVersion: boolean }; export type DeactivateWorkflowVersionMutation = { __typename?: 'Mutation', deactivateWorkflowVersion: boolean };
export type RunWorkflowVersionMutationVariables = Exact<{
input: RunWorkflowVersionInput;
}>;
export type RunWorkflowVersionMutation = { __typename?: 'Mutation', runWorkflowVersion: { __typename?: 'WorkflowRun', workflowRunId: any } };
export type DeleteWorkspaceInvitationMutationVariables = Exact<{ export type DeleteWorkspaceInvitationMutationVariables = Exact<{
appTokenId: Scalars['String']; appTokenId: Scalars['String'];
}>; }>;
@ -3525,6 +3532,39 @@ export function useDeactivateWorkflowVersionMutation(baseOptions?: Apollo.Mutati
export type DeactivateWorkflowVersionMutationHookResult = ReturnType<typeof useDeactivateWorkflowVersionMutation>; export type DeactivateWorkflowVersionMutationHookResult = ReturnType<typeof useDeactivateWorkflowVersionMutation>;
export type DeactivateWorkflowVersionMutationResult = Apollo.MutationResult<DeactivateWorkflowVersionMutation>; export type DeactivateWorkflowVersionMutationResult = Apollo.MutationResult<DeactivateWorkflowVersionMutation>;
export type DeactivateWorkflowVersionMutationOptions = Apollo.BaseMutationOptions<DeactivateWorkflowVersionMutation, DeactivateWorkflowVersionMutationVariables>; export type DeactivateWorkflowVersionMutationOptions = Apollo.BaseMutationOptions<DeactivateWorkflowVersionMutation, DeactivateWorkflowVersionMutationVariables>;
export const RunWorkflowVersionDocument = gql`
mutation RunWorkflowVersion($input: RunWorkflowVersionInput!) {
runWorkflowVersion(input: $input) {
workflowRunId
}
}
`;
export type RunWorkflowVersionMutationFn = Apollo.MutationFunction<RunWorkflowVersionMutation, RunWorkflowVersionMutationVariables>;
/**
* __useRunWorkflowVersionMutation__
*
* To run a mutation, you first call `useRunWorkflowVersionMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useRunWorkflowVersionMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [runWorkflowVersionMutation, { data, loading, error }] = useRunWorkflowVersionMutation({
* variables: {
* input: // value for 'input'
* },
* });
*/
export function useRunWorkflowVersionMutation(baseOptions?: Apollo.MutationHookOptions<RunWorkflowVersionMutation, RunWorkflowVersionMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<RunWorkflowVersionMutation, RunWorkflowVersionMutationVariables>(RunWorkflowVersionDocument, options);
}
export type RunWorkflowVersionMutationHookResult = ReturnType<typeof useRunWorkflowVersionMutation>;
export type RunWorkflowVersionMutationResult = Apollo.MutationResult<RunWorkflowVersionMutation>;
export type RunWorkflowVersionMutationOptions = Apollo.BaseMutationOptions<RunWorkflowVersionMutation, RunWorkflowVersionMutationVariables>;
export const DeleteWorkspaceInvitationDocument = gql` export const DeleteWorkspaceInvitationDocument = gql`
mutation DeleteWorkspaceInvitation($appTokenId: String!) { mutation DeleteWorkspaceInvitation($appTokenId: String!) {
deleteWorkspaceInvitation(appTokenId: $appTokenId) deleteWorkspaceInvitation(appTokenId: $appTokenId)

View File

@ -97,6 +97,7 @@ export const DeleteRecordsActionEffect = ({
useEffect(() => { useEffect(() => {
if (canDelete) { if (canDelete) {
addActionMenuEntry({ addActionMenuEntry({
type: 'standard',
key: 'delete', key: 'delete',
label: 'Delete', label: 'Delete',
position, position,

View File

@ -3,10 +3,12 @@ import {
displayedExportProgress, displayedExportProgress,
useExportRecordData, useExportRecordData,
} from '@/action-menu/hooks/useExportRecordData'; } from '@/action-menu/hooks/useExportRecordData';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { IconDatabaseExport } from 'twenty-ui';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { IconFileExport } from 'twenty-ui';
export const ExportRecordsActionEffect = ({ export const ExportRecordsActionEffect = ({
position, position,
@ -16,6 +18,9 @@ export const ExportRecordsActionEffect = ({
objectMetadataItem: ObjectMetadataItem; objectMetadataItem: ObjectMetadataItem;
}) => { }) => {
const { addActionMenuEntry, removeActionMenuEntry } = useActionMenuEntries(); const { addActionMenuEntry, removeActionMenuEntry } = useActionMenuEntries();
const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2(
contextStoreNumberOfSelectedRecordsComponentState,
);
const { progress, download } = useExportRecordData({ const { progress, download } = useExportRecordData({
delayMs: 100, delayMs: 100,
@ -26,10 +31,14 @@ export const ExportRecordsActionEffect = ({
useEffect(() => { useEffect(() => {
addActionMenuEntry({ addActionMenuEntry({
type: 'standard',
key: 'export', key: 'export',
position, position,
label: displayedExportProgress(progress), label: displayedExportProgress(
Icon: IconFileExport, contextStoreNumberOfSelectedRecords > 0 ? 'selection' : 'all',
progress,
),
Icon: IconDatabaseExport,
accent: 'default', accent: 'default',
onClick: () => download(), onClick: () => download(),
}); });
@ -37,6 +46,14 @@ export const ExportRecordsActionEffect = ({
return () => { return () => {
removeActionMenuEntry('export'); removeActionMenuEntry('export');
}; };
}, [download, progress, addActionMenuEntry, removeActionMenuEntry, position]); }, [
contextStoreNumberOfSelectedRecords,
download,
progress,
addActionMenuEntry,
removeActionMenuEntry,
position,
]);
return null; return null;
}; };

View File

@ -44,6 +44,7 @@ export const ManageFavoritesActionEffect = ({
} }
addActionMenuEntry({ addActionMenuEntry({
type: 'standard',
key: 'manage-favorites', key: 'manage-favorites',
label: isFavorite ? 'Remove from favorites' : 'Add to favorites', label: isFavorite ? 'Remove from favorites' : 'Add to favorites',
position, position,

View File

@ -1,21 +1,20 @@
import { DeleteRecordsActionEffect } from '@/action-menu/actions/record-actions/components/DeleteRecordsActionEffect'; import { DeleteRecordsActionEffect } from '@/action-menu/actions/record-actions/components/DeleteRecordsActionEffect';
import { ExportRecordsActionEffect } from '@/action-menu/actions/record-actions/components/ExportRecordsActionEffect'; import { ExportRecordsActionEffect } from '@/action-menu/actions/record-actions/components/ExportRecordsActionEffect';
import { ManageFavoritesActionEffect } from '@/action-menu/actions/record-actions/components/ManageFavoritesActionEffect'; import { ManageFavoritesActionEffect } from '@/action-menu/actions/record-actions/components/ManageFavoritesActionEffect';
import { WorkflowRunRecordActionEffect } from '@/action-menu/actions/record-actions/workflow-run-record-actions/components/WorkflowRunRecordActionEffect';
import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState'; import { contextStoreCurrentObjectMetadataIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataIdComponentState';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState'; import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById'; import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
const globalRecordActionEffects = [ExportRecordsActionEffect];
const singleRecordActionEffects = [ const singleRecordActionEffects = [
ManageFavoritesActionEffect, ManageFavoritesActionEffect,
ExportRecordsActionEffect,
DeleteRecordsActionEffect, DeleteRecordsActionEffect,
]; ];
const multipleRecordActionEffects = [ const multipleRecordActionEffects = [DeleteRecordsActionEffect];
ExportRecordsActionEffect,
DeleteRecordsActionEffect,
];
export const RecordActionMenuEntriesSetter = () => { export const RecordActionMenuEntriesSetter = () => {
const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2( const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2(
@ -36,10 +35,6 @@ export const RecordActionMenuEntriesSetter = () => {
); );
} }
if (!contextStoreNumberOfSelectedRecords) {
return null;
}
const actions = const actions =
contextStoreNumberOfSelectedRecords === 1 contextStoreNumberOfSelectedRecords === 1
? singleRecordActionEffects ? singleRecordActionEffects
@ -47,13 +42,25 @@ export const RecordActionMenuEntriesSetter = () => {
return ( return (
<> <>
{actions.map((ActionEffect, index) => ( {globalRecordActionEffects.map((ActionEffect, index) => (
<ActionEffect <ActionEffect
key={index} key={index}
position={index} position={index}
objectMetadataItem={objectMetadataItem} objectMetadataItem={objectMetadataItem}
/> />
))} ))}
{actions.map((ActionEffect, index) => (
<ActionEffect
key={index}
position={globalRecordActionEffects.length + index}
objectMetadataItem={objectMetadataItem}
/>
))}
{contextStoreNumberOfSelectedRecords === 1 && (
<WorkflowRunRecordActionEffect
objectMetadataItem={objectMetadataItem}
/>
)}
</> </>
); );
}; };

View File

@ -0,0 +1,104 @@
import { useActionMenuEntries } from '@/action-menu/hooks/useActionMenuEntries';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useAllActiveWorkflowVersionsForObject } from '@/workflow/hooks/useAllActiveWorkflowVersionsForObject';
import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion';
import { useTheme } from '@emotion/react';
import { useEffect } from 'react';
import { useRecoilValue } from 'recoil';
import { IconSettingsAutomation, isDefined } from 'twenty-ui';
import { capitalize } from '~/utils/string/capitalize';
export const WorkflowRunRecordActionEffect = ({
objectMetadataItem,
}: {
objectMetadataItem: ObjectMetadataItem;
}) => {
const { addActionMenuEntry, removeActionMenuEntry } = useActionMenuEntries();
const contextStoreTargetedRecordsRule = useRecoilComponentValueV2(
contextStoreTargetedRecordsRuleComponentState,
);
const selectedRecordId =
contextStoreTargetedRecordsRule.mode === 'selection'
? contextStoreTargetedRecordsRule.selectedRecordIds[0]
: undefined;
const selectedRecord = useRecoilValue(
recordStoreFamilyState(selectedRecordId ?? ''),
);
const { records: activeWorkflowVersions } =
useAllActiveWorkflowVersionsForObject({
objectNameSingular: objectMetadataItem.nameSingular,
triggerType: 'MANUAL',
});
const { runWorkflowVersion } = useRunWorkflowVersion();
const { enqueueSnackBar } = useSnackBar();
const theme = useTheme();
useEffect(() => {
if (!isDefined(objectMetadataItem) || objectMetadataItem.isRemote) {
return;
}
for (const [
index,
activeWorkflowVersion,
] of activeWorkflowVersions.entries()) {
addActionMenuEntry({
type: 'workflow-run',
key: `workflow-run-${activeWorkflowVersion.workflow.name}`,
label: capitalize(activeWorkflowVersion.workflow.name),
position: index,
Icon: IconSettingsAutomation,
onClick: async () => {
if (!isDefined(selectedRecord)) {
return;
}
await runWorkflowVersion(activeWorkflowVersion.id, selectedRecord);
enqueueSnackBar('', {
variant: SnackBarVariant.Success,
title: `${capitalize(activeWorkflowVersion.workflow.name)} starting...`,
icon: (
<IconSettingsAutomation
size={16}
color={theme.snackBar.success.color}
/>
),
});
},
});
}
return () => {
for (const activeWorkflowVersion of activeWorkflowVersions) {
removeActionMenuEntry(
`workflow-run-${activeWorkflowVersion.workflow.name}`,
);
}
};
}, [
activeWorkflowVersions,
addActionMenuEntry,
enqueueSnackBar,
objectMetadataItem,
removeActionMenuEntry,
runWorkflowVersion,
selectedRecord,
theme.snackBar.success.color,
]);
return null;
};

View File

@ -33,7 +33,7 @@ export const RecordIndexActionMenuBar = () => {
const pinnedEntries = actionMenuEntries.filter((entry) => entry.isPinned); const pinnedEntries = actionMenuEntries.filter((entry) => entry.isPinned);
if (pinnedEntries.length === 0) { if (contextStoreNumberOfSelectedRecords === 0) {
return null; return null;
} }

View File

@ -5,6 +5,7 @@ import { RecoilRoot } from 'recoil';
import { RecordIndexActionMenuBar } from '@/action-menu/components/RecordIndexActionMenuBar'; import { RecordIndexActionMenuBar } from '@/action-menu/components/RecordIndexActionMenuBar';
import { actionMenuEntriesComponentState } from '@/action-menu/states/actionMenuEntriesComponentState'; import { actionMenuEntriesComponentState } from '@/action-menu/states/actionMenuEntriesComponentState';
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext'; import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry';
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext'; import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState'; import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
@ -34,30 +35,33 @@ const meta: Meta<typeof RecordIndexActionMenuBar> = {
selectedRecordIds: ['1', '2', '3'], selectedRecordIds: ['1', '2', '3'],
}, },
); );
set( set(
contextStoreNumberOfSelectedRecordsComponentState.atomFamily({ contextStoreNumberOfSelectedRecordsComponentState.atomFamily({
instanceId: 'story-action-menu', instanceId: 'story-action-menu',
}), }),
3, 3,
); );
const map = new Map<string, ActionMenuEntry>();
map.set('delete', {
isPinned: true,
type: 'standard',
key: 'delete',
label: 'Delete',
position: 0,
Icon: IconTrash,
onClick: deleteMock,
});
set( set(
actionMenuEntriesComponentState.atomFamily({ actionMenuEntriesComponentState.atomFamily({
instanceId: 'story-action-menu', instanceId: 'story-action-menu',
}), }),
new Map([ map,
[
'delete',
{
isPinned: true,
key: 'delete',
label: 'Delete',
position: 0,
Icon: IconTrash,
onClick: deleteMock,
},
],
]),
); );
set( set(
isBottomBarOpenedComponentState.atomFamily({ isBottomBarOpenedComponentState.atomFamily({
instanceId: 'action-bar-story-action-menu', instanceId: 'action-bar-story-action-menu',

View File

@ -21,6 +21,7 @@ const markAsDoneMock = jest.fn();
export const Default: Story = { export const Default: Story = {
args: { args: {
entry: { entry: {
type: 'standard',
key: 'delete', key: 'delete',
label: 'Delete', label: 'Delete',
position: 0, position: 0,
@ -33,6 +34,7 @@ export const Default: Story = {
export const WithDangerAccent: Story = { export const WithDangerAccent: Story = {
args: { args: {
entry: { entry: {
type: 'standard',
key: 'delete', key: 'delete',
label: 'Delete', label: 'Delete',
position: 0, position: 0,
@ -46,6 +48,7 @@ export const WithDangerAccent: Story = {
export const WithInteraction: Story = { export const WithInteraction: Story = {
args: { args: {
entry: { entry: {
type: 'standard',
key: 'markAsDone', key: 'markAsDone',
label: 'Mark as done', label: 'Mark as done',
position: 0, position: 0,

View File

@ -7,6 +7,7 @@ import { RecordIndexActionMenuDropdown } from '@/action-menu/components/RecordIn
import { actionMenuEntriesComponentState } from '@/action-menu/states/actionMenuEntriesComponentState'; import { actionMenuEntriesComponentState } from '@/action-menu/states/actionMenuEntriesComponentState';
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext'; import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
import { recordIndexActionMenuDropdownPositionComponentState } from '@/action-menu/states/recordIndexActionMenuDropdownPositionComponentState'; import { recordIndexActionMenuDropdownPositionComponentState } from '@/action-menu/states/recordIndexActionMenuDropdownPositionComponentState';
import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry';
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState'; import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
import { IconCheckbox, IconHeart, IconTrash } from 'twenty-ui'; import { IconCheckbox, IconHeart, IconTrash } from 'twenty-ui';
@ -29,43 +30,43 @@ const meta: Meta<typeof RecordIndexActionMenuDropdown> = {
), ),
{ x: 10, y: 10 }, { x: 10, y: 10 },
); );
const map = new Map<string, ActionMenuEntry>();
set( set(
actionMenuEntriesComponentState.atomFamily({ actionMenuEntriesComponentState.atomFamily({
instanceId: 'story-action-menu', instanceId: 'story-action-menu',
}), }),
new Map([ map,
[
'delete',
{
key: 'delete',
label: 'Delete',
position: 0,
Icon: IconTrash,
onClick: deleteMock,
},
],
[
'markAsDone',
{
key: 'markAsDone',
label: 'Mark as done',
position: 1,
Icon: IconCheckbox,
onClick: markAsDoneMock,
},
],
[
'addToFavorites',
{
key: 'addToFavorites',
label: 'Add to favorites',
position: 2,
Icon: IconHeart,
onClick: addToFavoritesMock,
},
],
]),
); );
map.set('delete', {
type: 'standard',
key: 'delete',
label: 'Delete',
position: 0,
Icon: IconTrash,
onClick: deleteMock,
});
map.set('markAsDone', {
type: 'standard',
key: 'markAsDone',
label: 'Mark as done',
position: 1,
Icon: IconCheckbox,
onClick: markAsDoneMock,
});
map.set('addToFavorites', {
type: 'standard',
key: 'addToFavorites',
label: 'Add to favorites',
position: 2,
Icon: IconHeart,
onClick: addToFavoritesMock,
});
set( set(
extractComponentState( extractComponentState(
isDropdownOpenComponentState, isDropdownOpenComponentState,

View File

@ -5,6 +5,7 @@ import { RecoilRoot } from 'recoil';
import { RecordShowRightDrawerActionMenuBar } from '@/action-menu/components/RecordShowRightDrawerActionMenuBar'; import { RecordShowRightDrawerActionMenuBar } from '@/action-menu/components/RecordShowRightDrawerActionMenuBar';
import { actionMenuEntriesComponentState } from '@/action-menu/states/actionMenuEntriesComponentState'; import { actionMenuEntriesComponentState } from '@/action-menu/states/actionMenuEntriesComponentState';
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext'; import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
import { ActionMenuEntry } from '@/action-menu/types/ActionMenuEntry';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState'; import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState'; import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/states/contextStoreTargetedRecordsRuleComponentState';
import { MenuItemAccent } from '@/ui/navigation/menu-item/types/MenuItemAccent'; import { MenuItemAccent } from '@/ui/navigation/menu-item/types/MenuItemAccent';
@ -42,44 +43,43 @@ const meta: Meta<typeof RecordShowRightDrawerActionMenuBar> = {
}), }),
1, 1,
); );
const map = new Map<string, ActionMenuEntry>();
set( set(
actionMenuEntriesComponentState.atomFamily({ actionMenuEntriesComponentState.atomFamily({
instanceId: 'story-action-menu', instanceId: 'story-action-menu',
}), }),
new Map([ map,
[
'addToFavorites',
{
key: 'addToFavorites',
label: 'Add to favorites',
position: 0,
Icon: IconHeart,
onClick: addToFavoritesMock,
},
],
[
'export',
{
key: 'export',
label: 'Export',
position: 1,
Icon: IconFileExport,
onClick: exportMock,
},
],
[
'delete',
{
key: 'delete',
label: 'Delete',
position: 2,
Icon: IconTrash,
onClick: deleteMock,
accent: 'danger' as MenuItemAccent,
},
],
]),
); );
map.set('addToFavorites', {
type: 'standard',
key: 'addToFavorites',
label: 'Add to favorites',
position: 0,
Icon: IconHeart,
onClick: addToFavoritesMock,
});
map.set('export', {
type: 'standard',
key: 'export',
label: 'Export',
position: 1,
Icon: IconFileExport,
onClick: exportMock,
});
map.set('delete', {
type: 'standard',
key: 'delete',
label: 'Delete',
position: 2,
Icon: IconTrash,
onClick: deleteMock,
accent: 'danger' as MenuItemAccent,
});
}} }}
> >
<ActionMenuComponentInstanceContext.Provider <ActionMenuComponentInstanceContext.Provider

View File

@ -86,7 +86,7 @@ describe('csvDownloader', () => {
describe('displayedExportProgress', () => { describe('displayedExportProgress', () => {
it.each([ it.each([
[undefined, undefined, 'percentage', 'Export'], [undefined, undefined, 'percentage', 'Export View as CSV'],
[20, 50, 'percentage', 'Export (40%)'], [20, 50, 'percentage', 'Export (40%)'],
[0, 100, 'number', 'Export (0)'], [0, 100, 'number', 'Export (0)'],
[10, 10, 'percentage', 'Export (100%)'], [10, 10, 'percentage', 'Export (100%)'],
@ -96,7 +96,7 @@ describe('displayedExportProgress', () => {
'displays the export progress', 'displays the export progress',
(exportedRecordCount, totalRecordCount, displayType, expected) => { (exportedRecordCount, totalRecordCount, displayType, expected) => {
expect( expect(
displayedExportProgress({ displayedExportProgress('all', {
exportedRecordCount, exportedRecordCount,
totalRecordCount, totalRecordCount,
displayType: displayType as 'percentage' | 'number', displayType: displayType as 'percentage' | 'number',

View File

@ -108,9 +108,12 @@ const percentage = (part: number, whole: number): number => {
return Math.round((part / whole) * 100); return Math.round((part / whole) * 100);
}; };
export const displayedExportProgress = (progress?: ExportProgress): string => { export const displayedExportProgress = (
mode: 'all' | 'selection' = 'all',
progress?: ExportProgress,
): string => {
if (isUndefinedOrNull(progress?.exportedRecordCount)) { if (isUndefinedOrNull(progress?.exportedRecordCount)) {
return 'Export'; return mode === 'all' ? 'Export View as CSV' : 'Export Selection as CSV';
} }
if ( if (

View File

@ -4,6 +4,7 @@ import { IconComponent } from 'twenty-ui';
import { MenuItemAccent } from '@/ui/navigation/menu-item/types/MenuItemAccent'; import { MenuItemAccent } from '@/ui/navigation/menu-item/types/MenuItemAccent';
export type ActionMenuEntry = { export type ActionMenuEntry = {
type: 'standard' | 'workflow-run';
key: string; key: string;
label: string; label: string;
position: number; position: number;

View File

@ -288,12 +288,20 @@ export const CommandMenu = () => {
: true) && cmd.type === CommandType.Create, : true) && cmd.type === CommandType.Create,
); );
const matchingActionCommands = commandMenuCommands.filter( const matchingStandardActionCommands = commandMenuCommands.filter(
(cmd) => (cmd) =>
(deferredCommandMenuSearch.length > 0 (deferredCommandMenuSearch.length > 0
? checkInShortcuts(cmd, deferredCommandMenuSearch) || ? checkInShortcuts(cmd, deferredCommandMenuSearch) ||
checkInLabels(cmd, deferredCommandMenuSearch) checkInLabels(cmd, deferredCommandMenuSearch)
: true) && cmd.type === CommandType.Action, : true) && cmd.type === CommandType.StandardAction,
);
const matchingWorkflowRunCommands = commandMenuCommands.filter(
(cmd) =>
(deferredCommandMenuSearch.length > 0
? checkInShortcuts(cmd, deferredCommandMenuSearch) ||
checkInLabels(cmd, deferredCommandMenuSearch)
: true) && cmd.type === CommandType.WorkflowRun,
); );
useListenClickOutside({ useListenClickOutside({
@ -321,7 +329,7 @@ export const CommandMenu = () => {
const selectableItemIds = copilotCommands const selectableItemIds = copilotCommands
.map((cmd) => cmd.id) .map((cmd) => cmd.id)
.concat(matchingActionCommands.map((cmd) => cmd.id)) .concat(matchingStandardActionCommands.map((cmd) => cmd.id))
.concat(matchingCreateCommand.map((cmd) => cmd.id)) .concat(matchingCreateCommand.map((cmd) => cmd.id))
.concat(matchingNavigateCommand.map((cmd) => cmd.id)) .concat(matchingNavigateCommand.map((cmd) => cmd.id))
.concat(people?.map((person) => person.id)) .concat(people?.map((person) => person.id))
@ -330,7 +338,8 @@ export const CommandMenu = () => {
.concat(notes?.map((note) => note.id)); .concat(notes?.map((note) => note.id));
const isNoResults = const isNoResults =
!matchingActionCommands.length && !matchingStandardActionCommands.length &&
!matchingWorkflowRunCommands.length &&
!matchingCreateCommand.length && !matchingCreateCommand.length &&
!matchingNavigateCommand.length && !matchingNavigateCommand.length &&
!people?.length && !people?.length &&
@ -410,38 +419,44 @@ export const CommandMenu = () => {
</CommandGroup> </CommandGroup>
)} )}
{mainContextStoreComponentInstanceId && ( {mainContextStoreComponentInstanceId && (
<CommandGroup heading="Actions"> <>
{matchingActionCommands?.map((actionCommand) => ( <CommandGroup heading="Standard Actions">
<SelectableItem {matchingStandardActionCommands?.map(
itemId={actionCommand.id} (standardActionCommand) => (
key={actionCommand.id} <SelectableItem
> itemId={standardActionCommand.id}
<CommandMenuItem key={standardActionCommand.id}
id={actionCommand.id} >
label={actionCommand.label} <CommandMenuItem
Icon={actionCommand.Icon} id={standardActionCommand.id}
onClick={actionCommand.onCommandClick} label={standardActionCommand.label}
/> Icon={standardActionCommand.Icon}
</SelectableItem> onClick={standardActionCommand.onCommandClick}
))} />
</CommandGroup> </SelectableItem>
),
)}
</CommandGroup>
<CommandGroup heading="Workflows">
{matchingWorkflowRunCommands?.map(
(workflowRunCommand) => (
<SelectableItem
itemId={workflowRunCommand.id}
key={workflowRunCommand.id}
>
<CommandMenuItem
id={workflowRunCommand.id}
label={workflowRunCommand.label}
Icon={workflowRunCommand.Icon}
onClick={workflowRunCommand.onCommandClick}
/>
</SelectableItem>
),
)}
</CommandGroup>
</>
)} )}
<CommandGroup heading="Create">
{matchingCreateCommand.map((cmd) => (
<SelectableItem itemId={cmd.id} key={cmd.id}>
<CommandMenuItem
id={cmd.id}
to={cmd.to}
key={cmd.id}
Icon={cmd.Icon}
label={cmd.label}
onClick={cmd.onCommandClick}
firstHotKey={cmd.firstHotKey}
secondHotKey={cmd.secondHotKey}
/>
</SelectableItem>
))}
</CommandGroup>
<CommandGroup heading="Navigate"> <CommandGroup heading="Navigate">
{matchingNavigateCommand.map((cmd) => ( {matchingNavigateCommand.map((cmd) => (
<SelectableItem itemId={cmd.id} key={cmd.id}> <SelectableItem itemId={cmd.id} key={cmd.id}>
@ -458,6 +473,22 @@ export const CommandMenu = () => {
</SelectableItem> </SelectableItem>
))} ))}
</CommandGroup> </CommandGroup>
<CommandGroup heading="Other">
{matchingCreateCommand.map((cmd) => (
<SelectableItem itemId={cmd.id} key={cmd.id}>
<CommandMenuItem
id={cmd.id}
to={cmd.to}
key={cmd.id}
Icon={cmd.Icon}
label={cmd.label}
onClick={cmd.onCommandClick}
firstHotKey={cmd.firstHotKey}
secondHotKey={cmd.secondHotKey}
/>
</SelectableItem>
))}
</CommandGroup>
<CommandGroup heading="People"> <CommandGroup heading="People">
{people?.map((person) => ( {people?.map((person) => (
<SelectableItem itemId={person.id} key={person.id}> <SelectableItem itemId={person.id} key={person.id}>

View File

@ -47,15 +47,29 @@ export const useCommandMenu = () => {
const actionCommands = actionMenuEntries const actionCommands = actionMenuEntries
.getValue() .getValue()
?.filter((actionMenuEntry) => actionMenuEntry.type === 'standard')
?.map((actionMenuEntry) => ({ ?.map((actionMenuEntry) => ({
id: actionMenuEntry.key, id: actionMenuEntry.key,
label: actionMenuEntry.label, label: actionMenuEntry.label,
Icon: actionMenuEntry.Icon, Icon: actionMenuEntry.Icon,
onCommandClick: actionMenuEntry.onClick, onCommandClick: actionMenuEntry.onClick,
type: CommandType.Action, type: CommandType.StandardAction,
})); }));
setCommands([...commands, ...actionCommands]); const workflowRunCommands = actionMenuEntries
.getValue()
?.filter(
(actionMenuEntry) => actionMenuEntry.type === 'workflow-run',
)
?.map((actionMenuEntry) => ({
id: actionMenuEntry.key,
label: actionMenuEntry.label,
Icon: actionMenuEntry.Icon,
onCommandClick: actionMenuEntry.onClick,
type: CommandType.WorkflowRun,
}));
setCommands([...commands, ...actionCommands, ...workflowRunCommands]);
} }
setIsCommandMenuOpened(true); setIsCommandMenuOpened(true);

View File

@ -3,14 +3,19 @@ import { IconComponent } from 'twenty-ui';
export enum CommandType { export enum CommandType {
Navigate = 'Navigate', Navigate = 'Navigate',
Create = 'Create', Create = 'Create',
Action = 'Action', StandardAction = 'StandardAction',
WorkflowRun = 'WorkflowRun',
} }
export type Command = { export type Command = {
id: string; id: string;
to?: string; to?: string;
label: string; label: string;
type: CommandType.Navigate | CommandType.Create | CommandType.Action; type:
| CommandType.Navigate
| CommandType.Create
| CommandType.StandardAction
| CommandType.WorkflowRun;
Icon?: IconComponent; Icon?: IconComponent;
firstHotKey?: string; firstHotKey?: string;
secondHotKey?: string; secondHotKey?: string;

View File

@ -1,4 +1,4 @@
import { ApolloClient, useMutation } from '@apollo/client'; import { useMutation } from '@apollo/client';
import { CREATE_ONE_DATABASE_CONNECTION } from '@/databases/graphql/mutations/createOneDatabaseConnection'; import { CREATE_ONE_DATABASE_CONNECTION } from '@/databases/graphql/mutations/createOneDatabaseConnection';
import { GET_MANY_DATABASE_CONNECTIONS } from '@/databases/graphql/queries/findManyDatabaseConnections'; import { GET_MANY_DATABASE_CONNECTIONS } from '@/databases/graphql/queries/findManyDatabaseConnections';
@ -17,7 +17,7 @@ export const useCreateOneDatabaseConnection = () => {
CreateServerMutation, CreateServerMutation,
CreateServerMutationVariables CreateServerMutationVariables
>(CREATE_ONE_DATABASE_CONNECTION, { >(CREATE_ONE_DATABASE_CONNECTION, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const createOneDatabaseConnection = async ( const createOneDatabaseConnection = async (

View File

@ -1,4 +1,4 @@
import { ApolloClient, useMutation } from '@apollo/client'; import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities'; import { getOperationName } from '@apollo/client/utilities';
import { DELETE_ONE_DATABASE_CONNECTION } from '@/databases/graphql/mutations/deleteOneDatabaseConnection'; import { DELETE_ONE_DATABASE_CONNECTION } from '@/databases/graphql/mutations/deleteOneDatabaseConnection';
@ -17,7 +17,7 @@ export const useDeleteOneDatabaseConnection = () => {
DeleteServerMutation, DeleteServerMutation,
DeleteServerMutationVariables DeleteServerMutationVariables
>(DELETE_ONE_DATABASE_CONNECTION, { >(DELETE_ONE_DATABASE_CONNECTION, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const deleteOneDatabaseConnection = async (input: RemoteServerIdInput) => { const deleteOneDatabaseConnection = async (input: RemoteServerIdInput) => {

View File

@ -1,5 +1,5 @@
import { useApolloClient, useMutation } from '@apollo/client';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { ApolloClient, useApolloClient, useMutation } from '@apollo/client';
import { SYNC_REMOTE_TABLE } from '@/databases/graphql/mutations/syncRemoteTable'; import { SYNC_REMOTE_TABLE } from '@/databases/graphql/mutations/syncRemoteTable';
import { modifyRemoteTableFromCache } from '@/databases/utils/modifyRemoteTableFromCache'; import { modifyRemoteTableFromCache } from '@/databases/utils/modifyRemoteTableFromCache';
@ -28,7 +28,7 @@ export const useSyncRemoteTable = () => {
SyncRemoteTableMutation, SyncRemoteTableMutation,
SyncRemoteTableMutationVariables SyncRemoteTableMutationVariables
>(SYNC_REMOTE_TABLE, { >(SYNC_REMOTE_TABLE, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const syncRemoteTable = useCallback( const syncRemoteTable = useCallback(

View File

@ -1,5 +1,5 @@
import { useApolloClient, useMutation } from '@apollo/client';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { ApolloClient, useApolloClient, useMutation } from '@apollo/client';
import { SYNC_REMOTE_TABLE_SCHEMA_CHANGES } from '@/databases/graphql/mutations/syncRemoteTableSchemaChanges'; import { SYNC_REMOTE_TABLE_SCHEMA_CHANGES } from '@/databases/graphql/mutations/syncRemoteTableSchemaChanges';
import { modifyRemoteTableFromCache } from '@/databases/utils/modifyRemoteTableFromCache'; import { modifyRemoteTableFromCache } from '@/databases/utils/modifyRemoteTableFromCache';
@ -29,7 +29,7 @@ export const useSyncRemoteTableSchemaChanges = () => {
SyncRemoteTableSchemaChangesMutation, SyncRemoteTableSchemaChangesMutation,
SyncRemoteTableSchemaChangesMutationVariables SyncRemoteTableSchemaChangesMutationVariables
>(SYNC_REMOTE_TABLE_SCHEMA_CHANGES, { >(SYNC_REMOTE_TABLE_SCHEMA_CHANGES, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const syncRemoteTableSchemaChanges = useCallback( const syncRemoteTableSchemaChanges = useCallback(

View File

@ -1,5 +1,5 @@
import { useMutation } from '@apollo/client';
import { useCallback } from 'react'; import { useCallback } from 'react';
import { ApolloClient, useMutation } from '@apollo/client';
import { UNSYNC_REMOTE_TABLE } from '@/databases/graphql/mutations/unsyncRemoteTable'; import { UNSYNC_REMOTE_TABLE } from '@/databases/graphql/mutations/unsyncRemoteTable';
import { modifyRemoteTableFromCache } from '@/databases/utils/modifyRemoteTableFromCache'; import { modifyRemoteTableFromCache } from '@/databases/utils/modifyRemoteTableFromCache';
@ -21,7 +21,7 @@ export const useUnsyncRemoteTable = () => {
UnsyncRemoteTableMutation, UnsyncRemoteTableMutation,
UnsyncRemoteTableMutationVariables UnsyncRemoteTableMutationVariables
>(UNSYNC_REMOTE_TABLE, { >(UNSYNC_REMOTE_TABLE, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const unsyncRemoteTable = useCallback( const unsyncRemoteTable = useCallback(

View File

@ -1,4 +1,4 @@
import { ApolloClient, useMutation } from '@apollo/client'; import { useMutation } from '@apollo/client';
import { UPDATE_ONE_DATABASE_CONNECTION } from '@/databases/graphql/mutations/updateOneDatabaseConnection'; import { UPDATE_ONE_DATABASE_CONNECTION } from '@/databases/graphql/mutations/updateOneDatabaseConnection';
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient'; import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
@ -15,7 +15,7 @@ export const useUpdateOneDatabaseConnection = () => {
UpdateServerMutation, UpdateServerMutation,
UpdateServerMutationVariables UpdateServerMutationVariables
>(UPDATE_ONE_DATABASE_CONNECTION, { >(UPDATE_ONE_DATABASE_CONNECTION, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const updateOneDatabaseConnection = async ( const updateOneDatabaseConnection = async (

View File

@ -10,5 +10,9 @@ export const useApolloMetadataClient = () => {
return apolloClient; return apolloClient;
} }
if (!apolloMetadataClient) {
throw new Error('ApolloMetadataClient not found');
}
return apolloMetadataClient; return apolloMetadataClient;
}; };

View File

@ -1,4 +1,4 @@
import { ApolloClient, useMutation } from '@apollo/client'; import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities'; import { getOperationName } from '@apollo/client/utilities';
import { import {
@ -19,7 +19,7 @@ export const useCreateOneFieldMetadataItem = () => {
CreateOneFieldMetadataItemMutation, CreateOneFieldMetadataItemMutation,
CreateOneFieldMetadataItemMutationVariables CreateOneFieldMetadataItemMutationVariables
>(CREATE_ONE_FIELD_METADATA_ITEM, { >(CREATE_ONE_FIELD_METADATA_ITEM, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const createOneFieldMetadataItem = async (input: CreateFieldInput) => { const createOneFieldMetadataItem = async (input: CreateFieldInput) => {

View File

@ -1,4 +1,4 @@
import { ApolloClient, useApolloClient, useMutation } from '@apollo/client'; import { useApolloClient, useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities'; import { getOperationName } from '@apollo/client/utilities';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
@ -26,7 +26,7 @@ export const useCreateOneObjectMetadataItem = () => {
CreateOneObjectMetadataItemMutation, CreateOneObjectMetadataItemMutation,
CreateOneObjectMetadataItemMutationVariables CreateOneObjectMetadataItemMutationVariables
>(CREATE_ONE_OBJECT_METADATA_ITEM, { >(CREATE_ONE_OBJECT_METADATA_ITEM, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const createOneObjectMetadataItem = async (input: CreateObjectInput) => { const createOneObjectMetadataItem = async (input: CreateObjectInput) => {

View File

@ -1,4 +1,4 @@
import { ApolloClient, useMutation } from '@apollo/client'; import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities'; import { getOperationName } from '@apollo/client/utilities';
import { import {
@ -22,7 +22,7 @@ export const useCreateOneRelationMetadataItem = () => {
CreateOneRelationMetadataMutation, CreateOneRelationMetadataMutation,
CreateOneRelationMetadataMutationVariables CreateOneRelationMetadataMutationVariables
>(CREATE_ONE_RELATION_METADATA_ITEM, { >(CREATE_ONE_RELATION_METADATA_ITEM, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const createOneRelationMetadataItem = async ( const createOneRelationMetadataItem = async (

View File

@ -1,4 +1,4 @@
import { ApolloClient, useMutation } from '@apollo/client'; import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities'; import { getOperationName } from '@apollo/client/utilities';
import { import {
@ -18,7 +18,7 @@ export const useDeleteOneFieldMetadataItem = () => {
DeleteOneFieldMetadataItemMutation, DeleteOneFieldMetadataItemMutation,
DeleteOneFieldMetadataItemMutationVariables DeleteOneFieldMetadataItemMutationVariables
>(DELETE_ONE_FIELD_METADATA_ITEM, { >(DELETE_ONE_FIELD_METADATA_ITEM, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const deleteOneFieldMetadataItem = async ( const deleteOneFieldMetadataItem = async (

View File

@ -1,4 +1,4 @@
import { ApolloClient, useMutation } from '@apollo/client'; import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities'; import { getOperationName } from '@apollo/client/utilities';
import { import {
@ -18,7 +18,7 @@ export const useDeleteOneObjectMetadataItem = () => {
DeleteOneObjectMetadataItemMutation, DeleteOneObjectMetadataItemMutation,
DeleteOneObjectMetadataItemMutationVariables DeleteOneObjectMetadataItemMutationVariables
>(DELETE_ONE_OBJECT_METADATA_ITEM, { >(DELETE_ONE_OBJECT_METADATA_ITEM, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const deleteOneObjectMetadataItem = async ( const deleteOneObjectMetadataItem = async (

View File

@ -1,4 +1,4 @@
import { ApolloClient, useMutation } from '@apollo/client'; import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities'; import { getOperationName } from '@apollo/client/utilities';
import { DELETE_ONE_RELATION_METADATA_ITEM } from '@/object-metadata/graphql/mutations'; import { DELETE_ONE_RELATION_METADATA_ITEM } from '@/object-metadata/graphql/mutations';
@ -18,7 +18,7 @@ export const useDeleteOneRelationMetadataItem = () => {
DeleteOneRelationMetadataItemMutation, DeleteOneRelationMetadataItemMutation,
DeleteOneRelationMetadataItemMutationVariables DeleteOneRelationMetadataItemMutationVariables
>(DELETE_ONE_RELATION_METADATA_ITEM, { >(DELETE_ONE_RELATION_METADATA_ITEM, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const deleteOneRelationMetadataItem = async ( const deleteOneRelationMetadataItem = async (

View File

@ -21,6 +21,7 @@ import {
displayedExportProgress, displayedExportProgress,
useExportRecordData, useExportRecordData,
} from '@/action-menu/hooks/useExportRecordData'; } from '@/action-menu/hooks/useExportRecordData';
import { contextStoreNumberOfSelectedRecordsComponentState } from '@/context-store/states/contextStoreNumberOfSelectedRecordsComponentState';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useRecordGroupReorder } from '@/object-record/record-group/hooks/useRecordGroupReorder'; import { useRecordGroupReorder } from '@/object-record/record-group/hooks/useRecordGroupReorder';
import { useRecordGroups } from '@/object-record/record-group/hooks/useRecordGroups'; import { useRecordGroups } from '@/object-record/record-group/hooks/useRecordGroups';
@ -41,6 +42,7 @@ import { MenuItemToggle } from '@/ui/navigation/menu-item/components/MenuItemTog
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection'; import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
import { ViewGroupsVisibilityDropdownSection } from '@/views/components/ViewGroupsVisibilityDropdownSection'; import { ViewGroupsVisibilityDropdownSection } from '@/views/components/ViewGroupsVisibilityDropdownSection';
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
@ -182,6 +184,12 @@ export const RecordIndexOptionsDropdownContent = ({
viewGroupFieldMetadataItem && viewGroupFieldMetadataItem &&
(visibleRecordGroups.length > 0 || hiddenRecordGroups.length > 0); (visibleRecordGroups.length > 0 || hiddenRecordGroups.length > 0);
const contextStoreNumberOfSelectedRecords = useRecoilComponentValueV2(
contextStoreNumberOfSelectedRecordsComponentState,
);
const mode = contextStoreNumberOfSelectedRecords > 0 ? 'selection' : 'all';
useEffect(() => { useEffect(() => {
if (currentMenu === 'hiddenViewGroups' && hiddenRecordGroups.length === 0) { if (currentMenu === 'hiddenViewGroups' && hiddenRecordGroups.length === 0) {
setCurrentMenu('viewGroups'); setCurrentMenu('viewGroups');
@ -214,7 +222,7 @@ export const RecordIndexOptionsDropdownContent = ({
<MenuItem <MenuItem
onClick={download} onClick={download}
LeftIcon={IconFileExport} LeftIcon={IconFileExport}
text={displayedExportProgress(progress)} text={displayedExportProgress(mode, progress)}
/> />
<MenuItem <MenuItem
onClick={() => { onClick={() => {

View File

@ -1,14 +1,14 @@
import { ApolloClient, useMutation } from '@apollo/client'; import { useMutation } from '@apollo/client';
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient'; import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
import { CREATE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/createOneServerlessFunction';
import { FIND_MANY_SERVERLESS_FUNCTIONS } from '@/settings/serverless-functions/graphql/queries/findManyServerlessFunctions';
import { getOperationName } from '@apollo/client/utilities';
import { import {
CreateServerlessFunctionInput,
CreateOneServerlessFunctionItemMutation, CreateOneServerlessFunctionItemMutation,
CreateOneServerlessFunctionItemMutationVariables, CreateOneServerlessFunctionItemMutationVariables,
CreateServerlessFunctionInput,
} from '~/generated-metadata/graphql'; } from '~/generated-metadata/graphql';
import { getOperationName } from '@apollo/client/utilities';
import { FIND_MANY_SERVERLESS_FUNCTIONS } from '@/settings/serverless-functions/graphql/queries/findManyServerlessFunctions';
import { CREATE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/createOneServerlessFunction';
export const useCreateOneServerlessFunction = () => { export const useCreateOneServerlessFunction = () => {
const apolloMetadataClient = useApolloMetadataClient(); const apolloMetadataClient = useApolloMetadataClient();
@ -16,7 +16,7 @@ export const useCreateOneServerlessFunction = () => {
CreateOneServerlessFunctionItemMutation, CreateOneServerlessFunctionItemMutation,
CreateOneServerlessFunctionItemMutationVariables CreateOneServerlessFunctionItemMutationVariables
>(CREATE_ONE_SERVERLESS_FUNCTION, { >(CREATE_ONE_SERVERLESS_FUNCTION, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const createOneServerlessFunction = async ( const createOneServerlessFunction = async (

View File

@ -1,13 +1,13 @@
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient'; import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
import { ApolloClient, useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import { DELETE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/deleteOneServerlessFunction'; import { DELETE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/deleteOneServerlessFunction';
import { FIND_ONE_SERVERLESS_FUNCTION_SOURCE_CODE } from '@/settings/serverless-functions/graphql/queries/findOneServerlessFunctionSourceCode';
import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import { import {
ServerlessFunctionIdInput,
DeleteOneServerlessFunctionMutation, DeleteOneServerlessFunctionMutation,
DeleteOneServerlessFunctionMutationVariables, DeleteOneServerlessFunctionMutationVariables,
ServerlessFunctionIdInput,
} from '~/generated-metadata/graphql'; } from '~/generated-metadata/graphql';
import { FIND_ONE_SERVERLESS_FUNCTION_SOURCE_CODE } from '@/settings/serverless-functions/graphql/queries/findOneServerlessFunctionSourceCode';
export const useDeleteOneServerlessFunction = () => { export const useDeleteOneServerlessFunction = () => {
const apolloMetadataClient = useApolloMetadataClient(); const apolloMetadataClient = useApolloMetadataClient();
@ -15,7 +15,7 @@ export const useDeleteOneServerlessFunction = () => {
DeleteOneServerlessFunctionMutation, DeleteOneServerlessFunctionMutation,
DeleteOneServerlessFunctionMutationVariables DeleteOneServerlessFunctionMutationVariables
>(DELETE_ONE_SERVERLESS_FUNCTION, { >(DELETE_ONE_SERVERLESS_FUNCTION, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const deleteOneServerlessFunction = async ( const deleteOneServerlessFunction = async (

View File

@ -1,10 +1,10 @@
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient'; import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
import { ApolloClient, useMutation } from '@apollo/client';
import { EXECUTE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/executeOneServerlessFunction'; import { EXECUTE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/executeOneServerlessFunction';
import { useMutation } from '@apollo/client';
import { import {
ExecuteServerlessFunctionInput,
ExecuteOneServerlessFunctionMutation, ExecuteOneServerlessFunctionMutation,
ExecuteOneServerlessFunctionMutationVariables, ExecuteOneServerlessFunctionMutationVariables,
ExecuteServerlessFunctionInput,
} from '~/generated-metadata/graphql'; } from '~/generated-metadata/graphql';
export const useExecuteOneServerlessFunction = () => { export const useExecuteOneServerlessFunction = () => {
@ -13,7 +13,7 @@ export const useExecuteOneServerlessFunction = () => {
ExecuteOneServerlessFunctionMutation, ExecuteOneServerlessFunctionMutation,
ExecuteOneServerlessFunctionMutationVariables ExecuteOneServerlessFunctionMutationVariables
>(EXECUTE_ONE_SERVERLESS_FUNCTION, { >(EXECUTE_ONE_SERVERLESS_FUNCTION, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const executeOneServerlessFunction = async ( const executeOneServerlessFunction = async (

View File

@ -1,13 +1,13 @@
import { ApolloClient, useMutation } from '@apollo/client';
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient'; import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
import { PUBLISH_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/publishOneServerlessFunction'; import { PUBLISH_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/publishOneServerlessFunction';
import { FIND_ONE_SERVERLESS_FUNCTION_SOURCE_CODE } from '@/settings/serverless-functions/graphql/queries/findOneServerlessFunctionSourceCode';
import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import { import {
PublishServerlessFunctionInput,
PublishOneServerlessFunctionMutation, PublishOneServerlessFunctionMutation,
PublishOneServerlessFunctionMutationVariables, PublishOneServerlessFunctionMutationVariables,
PublishServerlessFunctionInput,
} from '~/generated-metadata/graphql'; } from '~/generated-metadata/graphql';
import { getOperationName } from '@apollo/client/utilities';
import { FIND_ONE_SERVERLESS_FUNCTION_SOURCE_CODE } from '@/settings/serverless-functions/graphql/queries/findOneServerlessFunctionSourceCode';
export const usePublishOneServerlessFunction = () => { export const usePublishOneServerlessFunction = () => {
const apolloMetadataClient = useApolloMetadataClient(); const apolloMetadataClient = useApolloMetadataClient();
@ -15,7 +15,7 @@ export const usePublishOneServerlessFunction = () => {
PublishOneServerlessFunctionMutation, PublishOneServerlessFunctionMutation,
PublishOneServerlessFunctionMutationVariables PublishOneServerlessFunctionMutationVariables
>(PUBLISH_ONE_SERVERLESS_FUNCTION, { >(PUBLISH_ONE_SERVERLESS_FUNCTION, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const publishOneServerlessFunction = async ( const publishOneServerlessFunction = async (

View File

@ -1,13 +1,13 @@
import { ApolloClient, useMutation } from '@apollo/client';
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient'; import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
import { UPDATE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/updateOneServerlessFunction'; import { UPDATE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/updateOneServerlessFunction';
import { FIND_MANY_SERVERLESS_FUNCTIONS } from '@/settings/serverless-functions/graphql/queries/findManyServerlessFunctions';
import { useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';
import { import {
UpdateServerlessFunctionInput,
UpdateOneServerlessFunctionMutation, UpdateOneServerlessFunctionMutation,
UpdateOneServerlessFunctionMutationVariables, UpdateOneServerlessFunctionMutationVariables,
UpdateServerlessFunctionInput,
} from '~/generated-metadata/graphql'; } from '~/generated-metadata/graphql';
import { getOperationName } from '@apollo/client/utilities';
import { FIND_MANY_SERVERLESS_FUNCTIONS } from '@/settings/serverless-functions/graphql/queries/findManyServerlessFunctions';
export const useUpdateOneServerlessFunction = () => { export const useUpdateOneServerlessFunction = () => {
const apolloMetadataClient = useApolloMetadataClient(); const apolloMetadataClient = useApolloMetadataClient();
@ -15,7 +15,7 @@ export const useUpdateOneServerlessFunction = () => {
UpdateOneServerlessFunctionMutation, UpdateOneServerlessFunctionMutation,
UpdateOneServerlessFunctionMutationVariables UpdateOneServerlessFunctionMutationVariables
>(UPDATE_ONE_SERVERLESS_FUNCTION, { >(UPDATE_ONE_SERVERLESS_FUNCTION, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const updateOneServerlessFunction = async ( const updateOneServerlessFunction = async (

View File

@ -0,0 +1,9 @@
import { gql } from '@apollo/client';
export const RUN_WORKFLOW_VERSION = gql`
mutation RunWorkflowVersion($input: RunWorkflowVersionInput!) {
runWorkflowVersion(input: $input) {
workflowRunId
}
}
`;

View File

@ -1,5 +1,5 @@
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient'; import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
import { ApolloClient, useApolloClient, useMutation } from '@apollo/client'; import { useApolloClient, useMutation } from '@apollo/client';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
@ -18,7 +18,7 @@ export const useActivateWorkflowVersion = () => {
ActivateWorkflowVersionMutation, ActivateWorkflowVersionMutation,
ActivateWorkflowVersionMutationVariables ActivateWorkflowVersionMutationVariables
>(ACTIVATE_WORKFLOW_VERSION, { >(ACTIVATE_WORKFLOW_VERSION, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const { objectMetadataItem: objectMetadataItemWorkflowVersion } = const { objectMetadataItem: objectMetadataItemWorkflowVersion } =

View File

@ -0,0 +1,52 @@
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import {
Workflow,
WorkflowTriggerType,
WorkflowVersion,
} from '@/workflow/types/Workflow';
export const useAllActiveWorkflowVersionsForObject = ({
objectNameSingular,
triggerType,
}: {
objectNameSingular: string;
triggerType: WorkflowTriggerType;
}) => {
const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular,
});
const { records } = useFindManyRecords<
WorkflowVersion & { workflow: Workflow }
>({
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
filter: {
and: [
{
status: {
eq: 'ACTIVE',
},
},
{
trigger: {
like: `%"type": "${triggerType}"%`,
},
},
{
trigger: {
like: `%"objectType": "${objectNameSingular}"%`,
},
},
],
},
recordGqlFields: {
...generateDepthOneRecordGqlFields({ objectMetadataItem }),
workflow: true,
},
});
return { records };
};

View File

@ -1,11 +1,11 @@
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient'; import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
import { ApolloClient, useMutation } from '@apollo/client'; import { COMPUTE_STEP_OUTPUT_SCHEMA } from '@/workflow/graphql/mutations/computeStepOutputSchema';
import { useMutation } from '@apollo/client';
import { import {
ComputeStepOutputSchemaInput, ComputeStepOutputSchemaInput,
ComputeStepOutputSchemaMutation, ComputeStepOutputSchemaMutation,
ComputeStepOutputSchemaMutationVariables, ComputeStepOutputSchemaMutationVariables,
} from '~/generated/graphql'; } from '~/generated/graphql';
import { COMPUTE_STEP_OUTPUT_SCHEMA } from '@/workflow/graphql/mutations/computeStepOutputSchema';
export const useComputeStepOutputSchema = () => { export const useComputeStepOutputSchema = () => {
const apolloMetadataClient = useApolloMetadataClient(); const apolloMetadataClient = useApolloMetadataClient();
@ -13,7 +13,7 @@ export const useComputeStepOutputSchema = () => {
ComputeStepOutputSchemaMutation, ComputeStepOutputSchemaMutation,
ComputeStepOutputSchemaMutationVariables ComputeStepOutputSchemaMutationVariables
>(COMPUTE_STEP_OUTPUT_SCHEMA, { >(COMPUTE_STEP_OUTPUT_SCHEMA, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const computeStepOutputSchema = async ( const computeStepOutputSchema = async (

View File

@ -1,5 +1,5 @@
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient'; import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
import { ApolloClient, useApolloClient, useMutation } from '@apollo/client'; import { useApolloClient, useMutation } from '@apollo/client';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
@ -17,7 +17,7 @@ export const useDeactivateWorkflowVersion = () => {
ActivateWorkflowVersionMutation, ActivateWorkflowVersionMutation,
ActivateWorkflowVersionMutationVariables ActivateWorkflowVersionMutationVariables
>(DEACTIVATE_WORKFLOW_VERSION, { >(DEACTIVATE_WORKFLOW_VERSION, {
client: apolloMetadataClient ?? ({} as ApolloClient<any>), client: apolloMetadataClient,
}); });
const { objectMetadataItem: objectMetadataItemWorkflowVersion } = const { objectMetadataItem: objectMetadataItemWorkflowVersion } =

View File

@ -0,0 +1,28 @@
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
import { RUN_WORKFLOW_VERSION } from '@/workflow/graphql/mutations/runWorkflowVersion';
import { useMutation } from '@apollo/client';
import {
RunWorkflowVersionMutation,
RunWorkflowVersionMutationVariables,
} from '~/generated/graphql';
export const useRunWorkflowVersion = () => {
const apolloMetadataClient = useApolloMetadataClient();
const [mutate] = useMutation<
RunWorkflowVersionMutation,
RunWorkflowVersionMutationVariables
>(RUN_WORKFLOW_VERSION, {
client: apolloMetadataClient,
});
const runWorkflowVersion = async (
workflowVersionId: string,
payload: Record<string, any>,
) => {
await mutate({
variables: { input: { workflowVersionId, payload } },
});
};
return { runWorkflowVersion };
};

View File

@ -108,6 +108,7 @@ export {
IconCurrencyYuan, IconCurrencyYuan,
IconCurrencyZloty, IconCurrencyZloty,
IconDatabase, IconDatabase,
IconDatabaseExport,
IconDeviceFloppy, IconDeviceFloppy,
IconDoorEnter, IconDoorEnter,
IconDotsVertical, IconDotsVertical,
@ -125,8 +126,8 @@ export {
IconFileUpload, IconFileUpload,
IconFileZip, IconFileZip,
IconFilter, IconFilter,
IconFilterOff,
IconFilterCog, IconFilterCog,
IconFilterOff,
IconFocusCentered, IconFocusCentered,
IconForbid, IconForbid,
IconFunction, IconFunction,
@ -136,6 +137,7 @@ export {
IconH2, IconH2,
IconH3, IconH3,
IconHandClick, IconHandClick,
IconHandMove,
IconHeadphones, IconHeadphones,
IconHeart, IconHeart,
IconHeartOff, IconHeartOff,
@ -181,13 +183,12 @@ export {
IconPlayerPlay, IconPlayerPlay,
IconPlayerStop, IconPlayerStop,
IconPlaylistAdd, IconPlaylistAdd,
IconHandMove,
IconSquare,
IconPlaystationSquare, IconPlaystationSquare,
IconPlug, IconPlug,
IconPlus, IconPlus,
IconPower, IconPower,
IconPresentation, IconPresentation,
IconPrinter,
IconProgressCheck, IconProgressCheck,
IconPuzzle, IconPuzzle,
IconQuestionMark, IconQuestionMark,
@ -209,6 +210,7 @@ export {
IconSortDescending, IconSortDescending,
IconSparkles, IconSparkles,
IconSql, IconSql,
IconSquare,
IconSquareKey, IconSquareKey,
IconSquareRoundedCheck, IconSquareRoundedCheck,
IconTable, IconTable,
@ -221,7 +223,6 @@ export {
IconTimelineEvent, IconTimelineEvent,
IconTool, IconTool,
IconTrash, IconTrash,
IconPrinter,
IconUnlink, IconUnlink,
IconUpload, IconUpload,
IconUser, IconUser,

View File

@ -1,13 +1,13 @@
/* eslint-disable no-restricted-imports */ /* eslint-disable no-restricted-imports */
import { import {
Icon123,
Icon24Hours,
Icon2fa, Icon2fa,
Icon360,
Icon360View,
Icon3dCubeSphere, Icon3dCubeSphere,
Icon3dCubeSphereOff, Icon3dCubeSphereOff,
Icon3dRotate, Icon3dRotate,
Icon24Hours,
Icon123,
Icon360,
Icon360View,
IconAB, IconAB,
IconAB2, IconAB2,
IconAbacus, IconAbacus,
@ -1240,6 +1240,9 @@ import {
IconClockExclamation, IconClockExclamation,
IconClockHeart, IconClockHeart,
IconClockHour1, IconClockHour1,
IconClockHour10,
IconClockHour11,
IconClockHour12,
IconClockHour2, IconClockHour2,
IconClockHour3, IconClockHour3,
IconClockHour4, IconClockHour4,
@ -1248,9 +1251,6 @@ import {
IconClockHour7, IconClockHour7,
IconClockHour8, IconClockHour8,
IconClockHour9, IconClockHour9,
IconClockHour10,
IconClockHour11,
IconClockHour12,
IconClockMinus, IconClockMinus,
IconClockOff, IconClockOff,
IconClockPause, IconClockPause,
@ -2917,10 +2917,10 @@ import {
IconMovieOff, IconMovieOff,
IconMug, IconMug,
IconMugOff, IconMugOff,
IconMultiplier1x,
IconMultiplier2x,
IconMultiplier05x, IconMultiplier05x,
IconMultiplier15x, IconMultiplier15x,
IconMultiplier1x,
IconMultiplier2x,
IconMushroom, IconMushroom,
IconMushroomOff, IconMushroomOff,
IconMusic, IconMusic,
@ -3315,20 +3315,20 @@ import {
IconReservedLine, IconReservedLine,
IconResize, IconResize,
IconRestore, IconRestore,
IconRewindBackward5,
IconRewindBackward10, IconRewindBackward10,
IconRewindBackward15, IconRewindBackward15,
IconRewindBackward20, IconRewindBackward20,
IconRewindBackward30, IconRewindBackward30,
IconRewindBackward40, IconRewindBackward40,
IconRewindBackward5,
IconRewindBackward50, IconRewindBackward50,
IconRewindBackward60, IconRewindBackward60,
IconRewindForward5,
IconRewindForward10, IconRewindForward10,
IconRewindForward15, IconRewindForward15,
IconRewindForward20, IconRewindForward20,
IconRewindForward30, IconRewindForward30,
IconRewindForward40, IconRewindForward40,
IconRewindForward5,
IconRewindForward50, IconRewindForward50,
IconRewindForward60, IconRewindForward60,
IconRibbonHealth, IconRibbonHealth,
@ -3880,11 +3880,11 @@ import {
IconTiltShift, IconTiltShift,
IconTiltShiftOff, IconTiltShiftOff,
IconTimeDuration0, IconTimeDuration0,
IconTimeDuration5,
IconTimeDuration10, IconTimeDuration10,
IconTimeDuration15, IconTimeDuration15,
IconTimeDuration30, IconTimeDuration30,
IconTimeDuration45, IconTimeDuration45,
IconTimeDuration5,
IconTimeDuration60, IconTimeDuration60,
IconTimeDuration90, IconTimeDuration90,
IconTimeDurationOff, IconTimeDurationOff,