Revert 21949 (#22081)
#21949 introduced deterministic uuid utils with usage in the same PR. Usage was not uniform and expected a backfill command as well. Since we want to release I'm reverting all the changes from that PR that concerns twenty-server and only keeping the unused utils in twenty-shared and I'll introduce usages within the same PR as backfill command
This commit is contained in:
+40
-6
@@ -1,19 +1,53 @@
|
||||
import {
|
||||
getCommandMenuItemUniversalIdentifier,
|
||||
getGlobalCommandMenuItemUniversalIdentifier,
|
||||
getGlobalObjectContextCommandMenuItemUniversalIdentifier,
|
||||
getNavigationCommandUniversalIdentifier,
|
||||
getRecordSelectionCommandMenuItemUniversalIdentifier,
|
||||
} from '@/application/deterministic-identifier/get-command-menu-item-universal-identifier.util';
|
||||
|
||||
const APP = '11111111-1111-4111-8111-111111111111';
|
||||
const OBJECT = '22222222-2222-4222-8222-222222222222';
|
||||
|
||||
describe('getCommandMenuItemUniversalIdentifier', () => {
|
||||
it('derives a deterministic id from the command label within its application', () => {
|
||||
describe('getGlobalCommandMenuItemUniversalIdentifier', () => {
|
||||
it('derives a deterministic id from the engineComponentKey within GLOBAL', () => {
|
||||
expect(
|
||||
getCommandMenuItemUniversalIdentifier({
|
||||
getGlobalCommandMenuItemUniversalIdentifier({
|
||||
applicationUniversalIdentifier: APP,
|
||||
label: 'Create Record',
|
||||
engineComponentKey: 'EXPORT_RECORDS',
|
||||
}),
|
||||
).toBe('e284adf7-5332-5253-9c94-9e6b3c57237f');
|
||||
).toBe('bba78a2e-c117-52af-b25d-126702e8cf57');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getGlobalObjectContextCommandMenuItemUniversalIdentifier', () => {
|
||||
it('derives a deterministic id from the engineComponentKey within GLOBAL_OBJECT_CONTEXT', () => {
|
||||
expect(
|
||||
getGlobalObjectContextCommandMenuItemUniversalIdentifier({
|
||||
applicationUniversalIdentifier: APP,
|
||||
engineComponentKey: 'CREATE_NEW_RECORD',
|
||||
}),
|
||||
).toBe('77fb3fcd-ee35-50ea-9c3c-ab95cef5e0e2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRecordSelectionCommandMenuItemUniversalIdentifier', () => {
|
||||
it('includes the target object when scoped to one', () => {
|
||||
expect(
|
||||
getRecordSelectionCommandMenuItemUniversalIdentifier({
|
||||
applicationUniversalIdentifier: APP,
|
||||
engineComponentKey: 'COMPOSE_EMAIL',
|
||||
objectUniversalIdentifier: OBJECT,
|
||||
}),
|
||||
).toBe('dd10a2b1-229b-572a-a887-ea20e487cfd3');
|
||||
});
|
||||
|
||||
it('omits the object for object-agnostic record-selection commands', () => {
|
||||
expect(
|
||||
getRecordSelectionCommandMenuItemUniversalIdentifier({
|
||||
applicationUniversalIdentifier: APP,
|
||||
engineComponentKey: 'DELETE_RECORDS',
|
||||
}),
|
||||
).toBe('36b20ed1-6172-5da5-9a21-58de9c8acb22');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+46
-6
@@ -1,14 +1,54 @@
|
||||
import { getNavigationMenuItemUniversalIdentifier } from '@/application/deterministic-identifier/get-navigation-menu-item-universal-identifier.util';
|
||||
import {
|
||||
getFolderNavigationMenuItemUniversalIdentifier,
|
||||
getLinkNavigationMenuItemUniversalIdentifier,
|
||||
getObjectNavigationMenuItemUniversalIdentifier,
|
||||
getViewNavigationMenuItemUniversalIdentifier,
|
||||
} from '@/application/deterministic-identifier/get-navigation-menu-item-universal-identifier.util';
|
||||
|
||||
const APP = '11111111-1111-4111-8111-111111111111';
|
||||
const OBJECT = '22222222-2222-4222-8222-222222222222';
|
||||
const VIEW = '44444444-4444-4444-8444-444444444444';
|
||||
|
||||
describe('getNavigationMenuItemUniversalIdentifier', () => {
|
||||
it('derives a deterministic id from the item name within its application', () => {
|
||||
describe('getFolderNavigationMenuItemUniversalIdentifier', () => {
|
||||
it('derives a deterministic id from the folder name within its application', () => {
|
||||
expect(
|
||||
getNavigationMenuItemUniversalIdentifier({
|
||||
getFolderNavigationMenuItemUniversalIdentifier({
|
||||
applicationUniversalIdentifier: APP,
|
||||
name: 'Home',
|
||||
name: 'Workflows',
|
||||
}),
|
||||
).toBe('dc0ca522-7f09-567d-a7f7-d33824495fc4');
|
||||
).toBe('ca043c51-ac75-515d-902b-dd836626bba4');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getObjectNavigationMenuItemUniversalIdentifier', () => {
|
||||
it('derives a deterministic id from the object it targets', () => {
|
||||
expect(
|
||||
getObjectNavigationMenuItemUniversalIdentifier({
|
||||
applicationUniversalIdentifier: APP,
|
||||
objectUniversalIdentifier: OBJECT,
|
||||
}),
|
||||
).toBe('071361bd-47c8-5513-be33-998dd287f8c7');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getViewNavigationMenuItemUniversalIdentifier', () => {
|
||||
it('derives a deterministic id from the view it targets', () => {
|
||||
expect(
|
||||
getViewNavigationMenuItemUniversalIdentifier({
|
||||
applicationUniversalIdentifier: APP,
|
||||
viewUniversalIdentifier: VIEW,
|
||||
}),
|
||||
).toBe('6504fd6d-ed38-5f34-87fc-26025130260f');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLinkNavigationMenuItemUniversalIdentifier', () => {
|
||||
it('derives a deterministic id from its target URL', () => {
|
||||
expect(
|
||||
getLinkNavigationMenuItemUniversalIdentifier({
|
||||
applicationUniversalIdentifier: APP,
|
||||
link: 'https://example.com',
|
||||
}),
|
||||
).toBe('635cef97-cc61-53a3-873e-38fecf3ecbd7');
|
||||
});
|
||||
});
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { getSearchFieldUniversalIdentifier } from '@/application/deterministic-identifier/get-search-field-universal-identifier.util';
|
||||
|
||||
const APP = '11111111-1111-4111-8111-111111111111';
|
||||
const FIELD = '33333333-3333-4333-8333-333333333333';
|
||||
|
||||
describe('getSearchFieldUniversalIdentifier', () => {
|
||||
it('derives a deterministic id from the field it makes searchable', () => {
|
||||
expect(
|
||||
getSearchFieldUniversalIdentifier({
|
||||
applicationUniversalIdentifier: APP,
|
||||
fieldMetadataUniversalIdentifier: FIELD,
|
||||
}),
|
||||
).toBe('db4e5b93-15b6-5c83-a0b3-6c031e0ca072');
|
||||
});
|
||||
});
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { getViewFieldGroupUniversalIdentifier } from '@/application/deterministic-identifier/get-view-field-group-universal-identifier.util';
|
||||
|
||||
const APP = '11111111-1111-4111-8111-111111111111';
|
||||
const VIEW = '44444444-4444-4444-8444-444444444444';
|
||||
|
||||
describe('getViewFieldGroupUniversalIdentifier', () => {
|
||||
it('derives a deterministic id from the group name within its view', () => {
|
||||
expect(
|
||||
getViewFieldGroupUniversalIdentifier({
|
||||
applicationUniversalIdentifier: APP,
|
||||
viewUniversalIdentifier: VIEW,
|
||||
name: 'General',
|
||||
}),
|
||||
).toBe('26350cf1-bec3-5617-b525-c0115811963e');
|
||||
});
|
||||
});
|
||||
+43
-6
@@ -2,18 +2,55 @@ import { computeDeterministicUuid } from '@/application/deterministic-identifier
|
||||
|
||||
const NAVIGATION_COMMAND_DISCRIMINATOR = 'navigation';
|
||||
|
||||
// A command menu item is identified by its label within its application
|
||||
// (not every command is backed by a front component).
|
||||
export const getCommandMenuItemUniversalIdentifier = ({
|
||||
// A command menu item is identified by its availabilityType + engineComponentKey
|
||||
// (the same engineComponentKey is reused across availability types and, for
|
||||
// RECORD_SELECTION, across objects). One util per availabilityType, prefixed by
|
||||
// the type, with the target object added only for RECORD_SELECTION.
|
||||
|
||||
// GLOBAL: a command available everywhere, identified by its engineComponentKey.
|
||||
export const getGlobalCommandMenuItemUniversalIdentifier = ({
|
||||
applicationUniversalIdentifier,
|
||||
label,
|
||||
engineComponentKey,
|
||||
}: {
|
||||
applicationUniversalIdentifier: string;
|
||||
label: string;
|
||||
engineComponentKey: string;
|
||||
}): string =>
|
||||
computeDeterministicUuid({
|
||||
entityNamespace: 'commandMenuItem',
|
||||
value: label,
|
||||
value: `GLOBAL:${engineComponentKey}`,
|
||||
applicationUniversalIdentifier,
|
||||
});
|
||||
|
||||
// GLOBAL_OBJECT_CONTEXT: a command whose object is resolved at runtime (not stored),
|
||||
// identified by its engineComponentKey.
|
||||
export const getGlobalObjectContextCommandMenuItemUniversalIdentifier = ({
|
||||
applicationUniversalIdentifier,
|
||||
engineComponentKey,
|
||||
}: {
|
||||
applicationUniversalIdentifier: string;
|
||||
engineComponentKey: string;
|
||||
}): string =>
|
||||
computeDeterministicUuid({
|
||||
entityNamespace: 'commandMenuItem',
|
||||
value: `GLOBAL_OBJECT_CONTEXT:${engineComponentKey}`,
|
||||
applicationUniversalIdentifier,
|
||||
});
|
||||
|
||||
// RECORD_SELECTION: a command acting on selected records; the same engineComponentKey
|
||||
// is replicated per object, so the target object is part of the identity
|
||||
// (null/absent for the object-agnostic record-selection commands).
|
||||
export const getRecordSelectionCommandMenuItemUniversalIdentifier = ({
|
||||
applicationUniversalIdentifier,
|
||||
engineComponentKey,
|
||||
objectUniversalIdentifier,
|
||||
}: {
|
||||
applicationUniversalIdentifier: string;
|
||||
engineComponentKey: string;
|
||||
objectUniversalIdentifier?: string | null;
|
||||
}): string =>
|
||||
computeDeterministicUuid({
|
||||
entityNamespace: 'commandMenuItem',
|
||||
value: `RECORD_SELECTION:${engineComponentKey}:${objectUniversalIdentifier ?? ''}`,
|
||||
applicationUniversalIdentifier,
|
||||
});
|
||||
|
||||
|
||||
+50
-3
@@ -1,7 +1,12 @@
|
||||
import { computeDeterministicUuid } from '@/application/deterministic-identifier/compute-deterministic-uuid.util';
|
||||
|
||||
// A navigation menu item is identified by its name within its application.
|
||||
export const getNavigationMenuItemUniversalIdentifier = ({
|
||||
// NavigationMenuItem is a single polymorphic entity: every variant shares
|
||||
// name/icon/color/position/folder, but each type is identified by a different
|
||||
// target, so each variant has its own discriminator (prefixed by the type to
|
||||
// keep the shared `navigationMenuItem` namespace collision-free).
|
||||
|
||||
// A FOLDER navigation item is identified by its name within its application.
|
||||
export const getFolderNavigationMenuItemUniversalIdentifier = ({
|
||||
applicationUniversalIdentifier,
|
||||
name,
|
||||
}: {
|
||||
@@ -10,6 +15,48 @@ export const getNavigationMenuItemUniversalIdentifier = ({
|
||||
}): string =>
|
||||
computeDeterministicUuid({
|
||||
entityNamespace: 'navigationMenuItem',
|
||||
value: name,
|
||||
value: `FOLDER:${name}`,
|
||||
applicationUniversalIdentifier,
|
||||
});
|
||||
|
||||
// An OBJECT navigation item is identified by the object it targets.
|
||||
export const getObjectNavigationMenuItemUniversalIdentifier = ({
|
||||
applicationUniversalIdentifier,
|
||||
objectUniversalIdentifier,
|
||||
}: {
|
||||
applicationUniversalIdentifier: string;
|
||||
objectUniversalIdentifier: string;
|
||||
}): string =>
|
||||
computeDeterministicUuid({
|
||||
entityNamespace: 'navigationMenuItem',
|
||||
value: `OBJECT:${objectUniversalIdentifier}`,
|
||||
applicationUniversalIdentifier,
|
||||
});
|
||||
|
||||
// A VIEW navigation item is identified by the view it targets.
|
||||
export const getViewNavigationMenuItemUniversalIdentifier = ({
|
||||
applicationUniversalIdentifier,
|
||||
viewUniversalIdentifier,
|
||||
}: {
|
||||
applicationUniversalIdentifier: string;
|
||||
viewUniversalIdentifier: string;
|
||||
}): string =>
|
||||
computeDeterministicUuid({
|
||||
entityNamespace: 'navigationMenuItem',
|
||||
value: `VIEW:${viewUniversalIdentifier}`,
|
||||
applicationUniversalIdentifier,
|
||||
});
|
||||
|
||||
// A LINK navigation item is identified by its target URL.
|
||||
export const getLinkNavigationMenuItemUniversalIdentifier = ({
|
||||
applicationUniversalIdentifier,
|
||||
link,
|
||||
}: {
|
||||
applicationUniversalIdentifier: string;
|
||||
link: string;
|
||||
}): string =>
|
||||
computeDeterministicUuid({
|
||||
entityNamespace: 'navigationMenuItem',
|
||||
value: `LINK:${link}`,
|
||||
applicationUniversalIdentifier,
|
||||
});
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { computeDeterministicUuid } from '@/application/deterministic-identifier/compute-deterministic-uuid.util';
|
||||
|
||||
// A search field is 1:1 with the field it makes searchable, so it is keyed by that field.
|
||||
export const getSearchFieldUniversalIdentifier = ({
|
||||
applicationUniversalIdentifier,
|
||||
fieldMetadataUniversalIdentifier,
|
||||
}: {
|
||||
applicationUniversalIdentifier: string;
|
||||
fieldMetadataUniversalIdentifier: string;
|
||||
}): string =>
|
||||
computeDeterministicUuid({
|
||||
entityNamespace: 'searchFieldMetadata',
|
||||
value: fieldMetadataUniversalIdentifier,
|
||||
applicationUniversalIdentifier,
|
||||
});
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { computeDeterministicUuid } from '@/application/deterministic-identifier/compute-deterministic-uuid.util';
|
||||
|
||||
// A view field group is identified by its name within its view.
|
||||
export const getViewFieldGroupUniversalIdentifier = ({
|
||||
applicationUniversalIdentifier,
|
||||
viewUniversalIdentifier,
|
||||
name,
|
||||
}: {
|
||||
applicationUniversalIdentifier: string;
|
||||
viewUniversalIdentifier: string;
|
||||
name: string;
|
||||
}): string =>
|
||||
computeDeterministicUuid({
|
||||
entityNamespace: 'viewFieldGroup',
|
||||
value: `${viewUniversalIdentifier}:${name}`,
|
||||
applicationUniversalIdentifier,
|
||||
});
|
||||
Reference in New Issue
Block a user