@equinor/echo-framework 5.0.0-beta-r19-0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/{f4c85313e79b1662.svg → 1bd97dd2170d0f64.svg} +850 -850
  2. package/{063009f06499d102.svg → 47deeba42768c5d1.svg} +8 -8
  3. package/README.md +48 -48
  4. package/index.cjs.js +2 -2
  5. package/index.d.ts +2 -2
  6. package/package.json +6 -6
  7. package/src/index.d.ts +6 -1
  8. package/src/lib/components/prepview/panels/objects/selectionActionBarMultiple/logic/selectionActionBarMultiple.logic.d.ts +4 -0
  9. package/src/lib/feature/equipment/components/fullEquipmentItem/fullEquipmentItem.d.ts +3 -3
  10. package/src/lib/feature/globalSelection/components/selectionActionBar/SelectionActionBar.d.ts +3 -1
  11. package/src/lib/feature/globalSelection/components/selectionActionBar/hooks/useSelectionAction.d.ts +28 -0
  12. package/src/lib/feature/globalSelection/globalSelectionStore/actions/addItemsByStrategy.action.d.ts +17 -0
  13. package/src/lib/feature/globalSelection/globalSelectionStore/globalSelectionStore.d.ts +13 -16
  14. package/src/lib/feature/globalSelection/globalSelectionStore/globalSelectionStore.types.d.ts +9 -16
  15. package/src/lib/feature/globalSelection/globalSelectionStore/globalSelectionStore.utils.d.ts +2 -36
  16. package/src/lib/feature/globalSelection/globalSelectionStore/selectionActionFeedbackStore.d.ts +30 -0
  17. package/src/lib/feature/globalSelection/hooks/useGlobalSelectionLists.d.ts +5 -3
  18. package/src/lib/feature/globalSelection/hooks/useIsInGlobalSelection.d.ts +0 -1
  19. package/src/lib/feature/globalSelection/hooks/useSelectionCategoriesByGroupId.d.ts +3 -2
  20. package/src/lib/feature/globalSelection/selectionMenu/hooks/{useIsAllIGlobalSelectionItemsHidden.d.ts → useIsAllGlobalSelectionItemsHidden.d.ts} +4 -6
  21. package/src/lib/feature/globalSelection/selectionMenu/hooks/useSelectionColorFrequency.d.ts +5 -2
  22. package/src/lib/feature/globalSelection/strategies/equipmentSelection.strategy.d.ts +3 -0
  23. package/src/lib/feature/globalSelection/strategies/index.d.ts +2 -0
  24. package/src/lib/feature/globalSelection/strategies/isItemIdOfType.d.ts +2 -0
  25. package/src/lib/feature/globalSelection/strategies/measuringPointSelection.strategy.d.ts +3 -0
  26. package/src/lib/feature/globalSelection/strategies/registerStrategies.d.ts +1 -0
  27. package/src/lib/feature/globalSelection/strategies/selectionItemTypeRegistry.d.ts +37 -0
  28. package/src/lib/feature/globalSelection/strategies/selectionItemTypeStrategy.types.d.ts +50 -0
  29. package/src/lib/feature/globalSelection/strategies/tagSelection.strategy.d.ts +3 -0
  30. package/src/lib/feature/globalSelection/strategies/workOrderSelection.strategy.d.ts +3 -0
  31. package/src/lib/feature/legend/components/pdfMarkers/subComponents/MarkerWithPopover.d.ts +1 -1
  32. package/src/lib/feature/legend/components/pdfMarkers/subComponents/components/MultipleMarkersBySingleLegend/multipleMarkersBySingleLegend.logic.d.ts +1 -1
  33. package/src/lib/feature/legend/components/pdfMarkers/subComponents/components/MultipleMarkersBySingleLegend/useStalePopoverMarkers.d.ts +3 -3
  34. package/src/lib/feature/legend/components/pdfMarkers/subComponents/hooks/useMarkerPopover.d.ts +1 -2
  35. package/src/lib/feature/legend/components/pdfMarkers/utils/markerId.utils.d.ts +1 -2
  36. package/src/lib/feature/legend/legendAnalytics.d.ts +1 -1
  37. package/src/lib/feature/legend/legendFacade.d.ts +8 -0
  38. package/src/lib/feature/legend/legendStrategies/notificationStrategy/hooks/{useNotificationsByTagIds.d.ts → useOpenNotificationsByTagIds.d.ts} +2 -2
  39. package/src/lib/feature/legend/legendStrategies/notificationStrategy/logic/notificationLegend.logic.d.ts +1 -1
  40. package/src/lib/feature/legend/stores/legendUIStore/legendUIStore.types.d.ts +1 -12
  41. package/src/lib/feature/legend/stores/legendVisibleDataAsTagsStore/legendVisibleDataAsTagsStore.d.ts +8 -0
  42. package/src/lib/feature/shared/markerId.types.d.ts +11 -0
  43. package/src/lib/utils/index.d.ts +1 -0
  44. package/src/lib/utils/notification.utils.d.ts +2 -0
  45. package/src/lib/feature/globalSelection/globalSelectionStore/actions/addEquipmentsToSelection.action.d.ts +0 -7
  46. package/src/lib/feature/globalSelection/globalSelectionStore/actions/addItemsToSelectionFactory.d.ts +0 -21
  47. package/src/lib/feature/globalSelection/globalSelectionStore/actions/addMeasuringPointsToSelection.action.d.ts +0 -7
  48. package/src/lib/feature/globalSelection/globalSelectionStore/actions/addTagsToSelection.action.d.ts +0 -12
  49. package/src/lib/feature/globalSelection/globalSelectionStore/actions/addWorkOrdersToSelection.action.d.ts +0 -7
  50. package/src/lib/feature/globalSelection/hooks/useSelectionAction.d.ts +0 -21
  51. package/src/lib/icons/index.d.ts +0 -13
  52. package/src/lib/icons/search.d.ts +0 -3
package/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from "./src\\index";
2
- export { default } from "./src\\index";
1
+ export * from "./src/index";
2
+ export { default } from "./src/index";
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@equinor/echo-framework",
3
- "version": "5.0.0-beta-r19-0",
3
+ "version": "5.0.0",
4
4
  "peerDependencies": {
5
- "@equinor/echo-base": "5.0.0-beta-r19-0",
6
- "@equinor/echo-components": "5.0.0-beta-r19-0",
7
- "@equinor/echo-core": "5.0.0-beta-r19-0",
8
- "@equinor/echo-search": "5.0.0-beta-r19-0",
9
- "@equinor/echo-utils": "5.0.0-beta-r19-0",
5
+ "@equinor/echo-base": ">= 5.0.0 < 6.0.0",
6
+ "@equinor/echo-components": ">= 5.0.0 < 6.0.0",
7
+ "@equinor/echo-core": ">= 5.0.0 < 6.0.0",
8
+ "@equinor/echo-search": ">= 5.0.0 < 6.0.0",
9
+ "@equinor/echo-utils": ">= 5.0.0 < 6.0.0",
10
10
  "@equinor/eds-core-react": "0.49.0",
11
11
  "@equinor/eds-icons": "0.22.0",
12
12
  "@equinor/eds-tokens": "2.1.0",
package/src/index.d.ts CHANGED
@@ -7,6 +7,11 @@ export { AppLauncherButton } from './lib/components/appLauncherButton';
7
7
  export type { AppLauncherButtonProps } from './lib/components/appLauncherButton';
8
8
  export { NotificationListItem } from './lib/components/notificationListItem';
9
9
  export type { NotificationListItemType } from './lib/components/notificationListItem';
10
+ export { fetchWorkOrderObjectsWithSelectionIds } from './lib/components/prepview/panels/objects/objects.logic';
11
+ export { AddSelectionListWithSameNameDialog } from './lib/components/prepview/panels/objects/selectionActionBarMultiple/AddSelectionListWithSameNameDialog';
12
+ export { OBJECT_LIST_FOR_WORK_ORDER_LABEL_PREFIX } from './lib/components/prepview/panels/objects/selectionActionBarMultiple/logic/selectionActionBarMultiple.constants';
13
+ export { addSelectionItemsToNewSelectionGroup } from './lib/components/prepview/panels/objects/selectionActionBarMultiple/logic/selectionActionBarMultiple.orchestration';
14
+ export { doesSelectionGroupLabelExist } from './lib/components/prepview/panels/objects/selectionActionBarMultiple/logic/selectionActionBarMultiple.utils';
10
15
  export { PrepviewButton } from './lib/components/prepviewButton/prepviewButton';
11
16
  export { useFetchPlantInfo } from './lib/components/requestAccess/hooks/fetchPlantInfo';
12
17
  export { MissingAccessInfoButton } from './lib/components/requestAccess/MissingAccessInfoButton';
@@ -21,7 +26,7 @@ export * from './lib/feature/equipment/index';
21
26
  export * from './lib/feature/globalSelection';
22
27
  export { ItemDetailsSelectionActionBar, SelectionActionBar } from './lib/feature/globalSelection/components/selectionActionBar/SelectionActionBar';
23
28
  export { PanTo3DButton } from './lib/feature/globalSelection/panToEcho3d/panTo3DButton';
24
- export { useIsAllIGlobalSelectionItemsHidden } from './lib/feature/globalSelection/selectionMenu/hooks/useIsAllIGlobalSelectionItemsHidden';
29
+ export { useIsAllGlobalSelectionItemsHidden } from './lib/feature/globalSelection/selectionMenu/hooks/useIsAllGlobalSelectionItemsHidden';
25
30
  export { useSelectionColorFrequencyByIds } from './lib/feature/globalSelection/selectionMenu/hooks/useSelectionColorFrequency';
26
31
  export { useSelectionTreeAutoSave } from './lib/feature/globalSelection/selectionMenu/selectionTreeStore/persist/useSelectionTreeAutoSave';
27
32
  export { GlobalSelectionCategoryId } from './lib/feature/globalSelection/selectionMenu/selectionTreeStore/selectionTree.store.types';
@@ -0,0 +1,4 @@
1
+ import { Guid } from '@equinor/echo-utils';
2
+ import { GlobalSelectionTypes } from '../../../../../../feature/globalSelection/globalSelectionStore/globalSelectionStore.types';
3
+ export declare function findWorkOrderColorInSelection(hiddenSelectionItemIds: ReadonlyArray<GlobalSelectionTypes.ItemId>): string | undefined;
4
+ export declare function overrideGroupItemColors(groupId: Guid, color: string): void;
@@ -1,7 +1,7 @@
1
1
  interface FullEquipmentItemProps {
2
- equipmentId: string;
3
- tagNo: string | undefined;
4
- plantNo: string | undefined;
2
+ readonly equipmentId: string;
3
+ readonly tagNo: string | undefined;
4
+ readonly plantNo: string | undefined;
5
5
  }
6
6
  export declare const FullEquipmentItem: React.FC<FullEquipmentItemProps>;
7
7
  export {};
@@ -1,8 +1,10 @@
1
+ import type { MarkerId } from '../../../shared/markerId.types';
1
2
  import { GlobalSelectionTypes } from '../../globalSelectionStore/globalSelectionStore.types';
2
3
  export interface SelectionActionBarProps {
3
4
  readonly itemId: GlobalSelectionTypes.ItemId;
4
5
  readonly className?: string;
5
- readonly showPopoverUpdateDelay?: boolean;
6
+ /** MarkerId of the marker that owns this action bar. Scopes feedback to this popover only. */
7
+ readonly markerId?: MarkerId;
6
8
  }
7
9
  export declare const SelectionActionBar: React.FC<SelectionActionBarProps>;
8
10
  /**
@@ -0,0 +1,28 @@
1
+ import { Guid } from '@equinor/echo-utils';
2
+ import type { MarkerId } from '../../../../shared/markerId.types';
3
+ import { GlobalSelectionTypes } from '../../../globalSelectionStore/globalSelectionStore.types';
4
+ /**
5
+ * Hook to manage selection actions for global selection.
6
+ *
7
+ * Feedback state (isFeedbackActive, feedbackType, actionMarkerId) is stored in a dedicated
8
+ * micro Zustand store so it survives component remounts during the stale-marker holding period
9
+ * (e.g. when a remove action causes the colored marker variant to disappear and
10
+ * useStalePopoverMarkers briefly unmounts/remounts the popover tree).
11
+ *
12
+ * While isFeedbackActive is true, useMarkerPopover delays popover content refresh and
13
+ * useStalePopoverMarkers keeps the old marker rendered so the feedback stays visible —
14
+ * but only for the marker identified by actionPopoverId, not globally.
15
+ *
16
+ * @param markerId - Optional ID of the popover that owns this action bar. When provided,
17
+ * feedback state is scoped to this popover: only the matching popover sees feedback,
18
+ * and other popovers remain unaffected. Pass `undefined` for non-popover contexts
19
+ * (e.g. ItemDetails pages).
20
+ * @returns Object containing loading state, feedback type, and functions to add/remove items from selection.
21
+ */
22
+ export declare function useSelectionAction(markerId?: MarkerId): {
23
+ isFeedbackActive: boolean;
24
+ feedbackType: import("@equinor/echo-components").SelectionBarFeedbackType | undefined;
25
+ addToSelection: (groupId: Guid, itemId: GlobalSelectionTypes.ItemId) => Promise<void>;
26
+ removeFromSelection: (groupId: Guid, itemId: GlobalSelectionTypes.ItemId) => void;
27
+ changeColor: (itemId: GlobalSelectionTypes.ItemId, color: string) => void;
28
+ };
@@ -0,0 +1,17 @@
1
+ import type { ResultArray } from '@equinor/echo-search';
2
+ import type { StoreApi } from 'zustand';
3
+ import type { SelectionItemTypeStrategy } from '../../strategies/selectionItemTypeStrategy.types';
4
+ import type { GlobalSelectionAddItemResult, GlobalSelectionItemType, GlobalSelectionItemTypeToDataMap, GlobalSelectionStore, SelectionItemTypeToItemIdMap } from '../globalSelectionStore.types';
5
+ type SetFunction = (updater: (state: GlobalSelectionStore) => void, shouldReplace?: boolean, action?: string) => void;
6
+ /**
7
+ * Generic store action that adds items of any type to the global selection store.
8
+ *
9
+ * Handles two paths based on whether the strategy implements `resolveSync`:
10
+ * 1. Resolved items (e.g. PDMS tags): written directly as `loadedSuccessfully` — no loading flicker.
11
+ * 2. Remaining items: written as `isLoading` placeholders, then fetched via `strategy.fetchAsync`.
12
+ */
13
+ export declare function addItemsByStrategyAction<T extends GlobalSelectionItemType>(set: SetFunction, get: StoreApi<GlobalSelectionStore>['getState'], strategy: SelectionItemTypeStrategy<T>, args: {
14
+ itemIds: ReadonlyArray<SelectionItemTypeToItemIdMap[T]>;
15
+ color?: string;
16
+ }): Promise<GlobalSelectionAddItemResult<ResultArray<GlobalSelectionItemTypeToDataMap[T]>[]>>;
17
+ export {};
@@ -35,22 +35,11 @@ export declare const useGlobalSelectionStore: import("zustand").UseBoundStore<Om
35
35
  };
36
36
  }, "setState"> & {
37
37
  setState(nextStateOrUpdater: GlobalSelectionStore | Partial<GlobalSelectionStore> | ((state: {
38
- addWorkOrdersToSelection: (args: {
39
- workOrderIds: GlobalSelectionTypes.WorkOrderId[];
40
- color?: string;
41
- }) => Promise<import("./globalSelectionStore.types").GlobalSelectionAddItemResult<import("@equinor/echo-search").ResultArray<import("@equinor/echo-search").WorkOrderData>[]>>;
42
- addTagsToSelection: (args: {
43
- tagIds: GlobalSelectionTypes.TagId[];
44
- color?: string;
45
- }) => Promise<import("./globalSelectionStore.types").GlobalSelectionAddItemResult<import("@equinor/echo-search").ResultArray<import("@equinor/echo-search").TagSummaryDto>[]>>;
46
- addEquipmentsToSelection: (args: {
47
- equipmentIds: GlobalSelectionTypes.EquipmentId[];
48
- color?: string;
49
- }) => Promise<import("./globalSelectionStore.types").GlobalSelectionAddItemResult<import("@equinor/echo-search").ResultArray<import("@equinor/echo-search").EquipmentData>[]>>;
50
- addMeasuringPointsToSelection: (args: {
51
- measuringPointIds: GlobalSelectionTypes.MeasuringPointId[];
52
- color?: string;
53
- }) => Promise<import("./globalSelectionStore.types").GlobalSelectionAddItemResult<import("@equinor/echo-search").ResultArray<import("@equinor/echo-search").MeasuringPointData>[]>>;
38
+ addItemsToSelection: <T extends GlobalSelectionItemType>(args: {
39
+ readonly itemType: T;
40
+ readonly itemIds: ReadonlyArray<import("./globalSelectionStore.types").SelectionItemTypeToItemIdMap[T]>;
41
+ readonly color?: string;
42
+ }) => Promise<import("./globalSelectionStore.types").GlobalSelectionAddItemResult<import("@equinor/echo-search").ResultArray<import("./globalSelectionStore.types").GlobalSelectionItemTypeToDataMap[T]>[]>>;
54
43
  removeItemsFromSelection: (args: {
55
44
  itemIds: ReadonlyArray<GlobalSelectionTypes.ItemId>;
56
45
  }) => void;
@@ -160,6 +149,14 @@ export declare const useGlobalSelectionStore: import("zustand").UseBoundStore<Om
160
149
  type: string;
161
150
  value: string;
162
151
  }[];
152
+ coordinates: {
153
+ tagSeqNo: number;
154
+ xEasting: number;
155
+ yNorthing: number;
156
+ zElevation: number;
157
+ uom: string;
158
+ linePosition: number | undefined;
159
+ }[];
163
160
  tagNo: string;
164
161
  description: string;
165
162
  projectCode: string;
@@ -59,22 +59,15 @@ interface ItemErrorStatusUpdates {
59
59
  readonly errorStatus: string;
60
60
  }
61
61
  export interface GlobalSelectionStore extends GlobalSelectionStoreData {
62
- addWorkOrdersToSelection: (args: {
63
- workOrderIds: GlobalSelectionTypes.WorkOrderId[];
64
- color?: string;
65
- }) => Promise<GlobalSelectionAddItemResult<ResultArray<WorkOrderData>[]>>;
66
- addTagsToSelection: (args: {
67
- tagIds: GlobalSelectionTypes.TagId[];
68
- color?: string;
69
- }) => Promise<GlobalSelectionAddItemResult<ResultArray<TagSummaryDto>[]>>;
70
- addEquipmentsToSelection: (args: {
71
- equipmentIds: GlobalSelectionTypes.EquipmentId[];
72
- color?: string;
73
- }) => Promise<GlobalSelectionAddItemResult<ResultArray<EquipmentData>[]>>;
74
- addMeasuringPointsToSelection: (args: {
75
- measuringPointIds: GlobalSelectionTypes.MeasuringPointId[];
76
- color?: string;
77
- }) => Promise<GlobalSelectionAddItemResult<ResultArray<MeasuringPointData>[]>>;
62
+ /**
63
+ * Generic method to add items of any type to the selection.
64
+ * Replaces the 4 per-type methods below. Use this for all new code.
65
+ */
66
+ addItemsToSelection<T extends GlobalSelectionItemType>(args: {
67
+ readonly itemType: T;
68
+ readonly itemIds: ReadonlyArray<SelectionItemTypeToItemIdMap[T]>;
69
+ readonly color?: string;
70
+ }): Promise<GlobalSelectionAddItemResult<ResultArray<GlobalSelectionItemTypeToDataMap[T]>[]>>;
78
71
  removeItemsFromSelection: (args: {
79
72
  itemIds: ReadonlyArray<GlobalSelectionTypes.ItemId>;
80
73
  }) => void;
@@ -2,54 +2,20 @@ import { ResultArray } from '@equinor/echo-search';
2
2
  import { GlobalSelectionItemType, GlobalSelectionItemTypeToDataMap, GlobalSelectionTypes, SelectionItemTypeToItemIdMap } from './globalSelectionStore.types';
3
3
  import { isEquipmentId, isMeasuringPointId, isTagId, isWorkOrderId } from './itemIdTypeGuards';
4
4
  declare function idsEqual(itemA: GlobalSelectionTypes.ItemId, itemB: GlobalSelectionTypes.ItemId): boolean;
5
- /**
6
- * Overloaded function that maps an item to its corresponding ID type based on the item's properties.
7
- * The return type is specific to the type of item passed to the function.
8
- *
9
- * @param {GlobalSelectionTypes.WorkOrderId} item - The work order item to be mapped.
10
- * @returns {GlobalSelectionTypes.WorkOrderId} - The mapped work order ID.
11
- */
12
- /**
13
- * @param {GlobalSelectionTypes.EquipmentId} item - The equipment item to be mapped.
14
- * @returns {GlobalSelectionTypes.EquipmentId} - The mapped equipment ID.
15
- */
16
- /**
17
- * @param {GlobalSelectionTypes.TagId} item - The tag item to be mapped.
18
- * @returns {GlobalSelectionTypes.TagId} - The mapped tag ID.
19
- */
20
- /**
21
- * Maps an item to its corresponding ID object by checking the item's type and returning the appropriate ID object,
22
- * removing leading zeros from the ID string and trimming whitespace.
23
- * If the item type is not recognized, an error is thrown.
24
- *
25
- * @param {GlobalSelectionTypes.ItemId} item - The data to be mapped to its ID type.
26
- * @returns {GlobalSelectionTypes.ItemId} - The mapped tag ID.
27
- */
28
- declare function mapToId(item: GlobalSelectionTypes.WorkOrderId): GlobalSelectionTypes.WorkOrderId;
29
- declare function mapToId(item: GlobalSelectionTypes.EquipmentId): GlobalSelectionTypes.EquipmentId;
30
- declare function mapToId(item: GlobalSelectionTypes.TagId): GlobalSelectionTypes.TagId;
31
- declare function mapToId(item: GlobalSelectionTypes.MeasuringPointId): GlobalSelectionTypes.MeasuringPointId;
32
5
  declare function mapToId(item: GlobalSelectionTypes.ItemId): GlobalSelectionTypes.ItemId;
33
- /**
34
- * Converts an item ID to a string representation for use as Map keys.
35
- * This is a ONE-WAY conversion - the string cannot be converted back to the original ID.
36
- *
37
- * For tags: Always returns `tagNo-instCode` regardless of whether it's a STID or PDMS tag.
38
- * This ensures both tag types use the same key format for O(1) Map lookups.
39
- *
40
- * To preserve full ID properties (e.g., PDMS properties for API saving), use `mapToId` instead.
41
- */
42
6
  declare function itemIdToString(itemId: GlobalSelectionTypes.ItemId): GlobalSelectionTypes.ItemIdString;
43
7
  export declare function mapIdToItemType(itemId: GlobalSelectionTypes.ItemId): GlobalSelectionItemType;
44
8
  /**
45
9
  * A utility object that provides various functions for handling global selections.
46
10
  *
47
11
  * @namespace globalSelectionUtils
12
+ * @property {Function} isMeasuringPointId - Checks if the passed object is a global selection MeasuringPointID.
48
13
  * @property {Function} isWorkOrderId - Checks if the passed object is a global selection WorkOrderID.
49
14
  * @property {Function} isEquipmentId - Checks if the passed object is a global selection EquipmentID.
50
15
  * @property {Function} isTagId - Checks if the passed object is a global selection TagID.
51
16
  * @property {Function} idsEqual - Compares two global selection item IDs for equality.
52
17
  * @property {Function} mapToId - Maps an object to its global selection item ID, preserving all properties (including PDMS).
18
+ * @property {Function} mapIdToItemType - Returns the GlobalSelectionItemType enum value for a given ItemId.
53
19
  * @property {Function} itemIdToString - ONE-WAY conversion to string for Map keys. Cannot be reversed. For tags, uses only tagNo-instCode.
54
20
  */
55
21
  export declare const globalSelectionUtils: Readonly<{
@@ -0,0 +1,30 @@
1
+ import type { SelectionBarFeedbackType } from '@equinor/echo-components';
2
+ import type { MarkerId } from '../../shared/markerId.types';
3
+ /**
4
+ * How long selection-action feedback stays visible.
5
+ * Legend popovers reuse this same duration when holding stale markers rendered,
6
+ * so the popover lifecycle matches the feedback lifecycle exactly.
7
+ */
8
+ export declare const FEEDBACK_DISPLAY_DURATION_MS = 2000;
9
+ export interface SelectionActionFeedback {
10
+ readonly isFeedbackActive: boolean;
11
+ readonly feedbackType: SelectionBarFeedbackType | undefined;
12
+ /** MarkerId of the marker that initiated the action. Consumers compare this to their own markerId. */
13
+ readonly actionMarkerId: MarkerId | undefined;
14
+ }
15
+ interface SelectionActionFeedbackStore extends SelectionActionFeedback {
16
+ /**
17
+ * Updates the selection action feedback state (isFeedbackActive + feedbackType).
18
+ * Stored in a dedicated micro store so it survives component remounts during
19
+ * the stale-marker holding period. While `isFeedbackActive` is true, useMarkerPopover
20
+ * delays popover content refresh and useStalePopoverMarkers keeps the old marker
21
+ * rendered so the feedback ("Added ✓", "Removed ✓") stays visible.
22
+ */
23
+ setFeedback: (feedback: SelectionActionFeedback) => void;
24
+ }
25
+ export declare const useSelectionActionFeedbackStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<SelectionActionFeedbackStore>, "setState"> & {
26
+ setState<A extends string | {
27
+ type: string;
28
+ }>(partial: SelectionActionFeedbackStore | Partial<SelectionActionFeedbackStore> | ((state: SelectionActionFeedbackStore) => SelectionActionFeedbackStore | Partial<SelectionActionFeedbackStore>), replace?: boolean | undefined, action?: A | undefined): void;
29
+ }>;
30
+ export {};
@@ -1,6 +1,8 @@
1
+ import { GlobalSelectionTypes } from '../globalSelectionStore/globalSelectionStore.types';
2
+ export interface GlobalSelectionList {
3
+ readonly items: readonly GlobalSelectionTypes.SelectionItem[];
4
+ }
1
5
  /**
2
6
  * Hook for returning all lists stored in the global selection.
3
7
  */
4
- export declare function useGlobalSelectionLists(): {
5
- items: (import("..").GlobalSelectionGenericItem<import("..").GlobalSelectionItemType.WorkOrder> | import("..").GlobalSelectionGenericItem<import("..").GlobalSelectionItemType.Tag> | import("..").GlobalSelectionGenericItem<import("..").GlobalSelectionItemType.Equipment> | import("..").GlobalSelectionGenericItem<import("..").GlobalSelectionItemType.MeasuringPoint>)[];
6
- }[];
8
+ export declare function useGlobalSelectionLists(): readonly GlobalSelectionList[];
@@ -2,7 +2,6 @@ import { GlobalSelectionTypes } from '../globalSelectionStore/globalSelectionSto
2
2
  /**
3
3
  * Hook to check if an item is in the global selection
4
4
  * @param {GlobalSelectionTypes.ItemId} itemId - The itemId
5
- * @param {GlobalSelectionItemType} itemType - The item type
6
5
  * @returns {boolean} - True if the item is in global selection, false otherwise
7
6
  */
8
7
  export declare function useIsInGlobalSelection(itemId: GlobalSelectionTypes.ItemId): boolean;
@@ -1,9 +1,10 @@
1
1
  import { Guid } from '@equinor/echo-utils';
2
2
  import { SelectionTreeTypes } from '../selectionMenu/selectionTreeStore/selectionTree.store.types';
3
3
  /**
4
- * Custom hook to get the selection categories by group ID from the global selection tree hiearchy.
4
+ * Custom hook to get the selection categories by group ID from the global selection tree hierarchy.
5
5
  *
6
- * This hook retrieves the categories for a given group ID from the selection tree store.
6
+ * Zustand's Object.is equality check on the selector return value ensures re-renders only
7
+ * happen when this specific group's categories change, not on unrelated group mutations.
7
8
  *
8
9
  * @param {Guid} groupId - The ID of the group to get categories for.
9
10
  * @returns {SelectionTreeTypes.Category[] | undefined} The categories for the given group ID, or undefined if not found.
@@ -1,8 +1,4 @@
1
1
  import { Guid } from '@equinor/echo-utils';
2
- interface UseIsAllIGlobalSelectionItemsHiddenArgs {
3
- groupId: Guid;
4
- categoryId?: string;
5
- }
6
2
  /**
7
3
  * Custom hook to determine if all items in a selection list are hidden by the user.
8
4
  *
@@ -15,5 +11,7 @@ interface UseIsAllIGlobalSelectionItemsHiddenArgs {
15
11
  *
16
12
  * The hook returns `true` if all items in the list are hidden by the user, and `false` otherwise.
17
13
  */
18
- export declare const useIsAllIGlobalSelectionItemsHidden: (args: UseIsAllIGlobalSelectionItemsHiddenArgs) => boolean;
19
- export {};
14
+ export declare const useIsAllGlobalSelectionItemsHidden: (args: {
15
+ groupId: Guid;
16
+ categoryId?: string;
17
+ }) => boolean;
@@ -5,14 +5,17 @@ import { GlobalSelectionTypes } from '../../globalSelectionStore/globalSelection
5
5
  * This hook retrieves the global selection items and filters them based on the provided item IDs,
6
6
  * extracts their associated colors, and sorts the colors by frequency.
7
7
  *
8
+ * Callers must provide a referentially stable `itemIds` array (e.g. via `useMemo`)
9
+ * to avoid unnecessary recomputation on every render.
10
+ *
8
11
  * @param itemIds - An array of item IDs to match against global selection items.
9
12
  * @returns An array of color strings sorted by frequency, most frequent first.
10
13
  */
11
- export declare function useSelectionColorFrequencyByIds(itemIds: GlobalSelectionTypes.ItemId[]): string[];
14
+ export declare function useSelectionColorFrequencyByIds(itemIds: ReadonlyArray<GlobalSelectionTypes.ItemId>): readonly string[];
12
15
  /**
13
16
  * Returns the most frequently used selection color from the provided item IDs.
14
17
  *
15
18
  * @param itemIds - An array of item IDs to analyze for color frequency.
16
19
  * @returns The most used selection color as a string, or `undefined` if no colors are present.
17
20
  */
18
- export declare function useMostUsedSelectionColorByIds(itemIds: GlobalSelectionTypes.ItemId[]): string | undefined;
21
+ export declare function useMostUsedSelectionColorByIds(itemIds: ReadonlyArray<GlobalSelectionTypes.ItemId>): string | undefined;
@@ -0,0 +1,3 @@
1
+ import { GlobalSelectionItemType } from '../globalSelectionStore/globalSelectionStore.types';
2
+ import type { SelectionItemTypeStrategy } from './selectionItemTypeStrategy.types';
3
+ export declare const equipmentSelectionStrategy: SelectionItemTypeStrategy<GlobalSelectionItemType.Equipment>;
@@ -0,0 +1,2 @@
1
+ import './registerStrategies';
2
+ export { selectionItemTypeRegistry } from './selectionItemTypeRegistry';
@@ -0,0 +1,2 @@
1
+ import type { GlobalSelectionItemType, GlobalSelectionTypes, SelectionItemTypeToItemIdMap } from '../globalSelectionStore/globalSelectionStore.types';
2
+ export declare function isItemIdOfType<T extends GlobalSelectionItemType>(type: T, itemId: GlobalSelectionTypes.ItemId): itemId is SelectionItemTypeToItemIdMap[T];
@@ -0,0 +1,3 @@
1
+ import { GlobalSelectionItemType } from '../globalSelectionStore/globalSelectionStore.types';
2
+ import type { SelectionItemTypeStrategy } from './selectionItemTypeStrategy.types';
3
+ export declare const measuringPointSelectionStrategy: SelectionItemTypeStrategy<GlobalSelectionItemType.MeasuringPoint>;
@@ -0,0 +1,37 @@
1
+ import type { GlobalSelectionItemType } from '../globalSelectionStore/globalSelectionStore.types';
2
+ import type { OrderedSelectionItemTypeStrategy, RegistrationOptions, SelectionItemTypeStrategy } from './selectionItemTypeStrategy.types';
3
+ export declare class SelectionItemTypeRegistry {
4
+ private readonly strategies;
5
+ private cachedAll;
6
+ private cachedAllByRegistrationOrder;
7
+ /**
8
+ * Register a strategy for the given item type. Throws if the type is already registered.
9
+ * @param strategy - The strategy implementation for a specific item type.
10
+ * @param options - Registration options including categoryOrderIndex for UI sort order.
11
+ */
12
+ register<T extends GlobalSelectionItemType>(strategy: SelectionItemTypeStrategy<T>, options: RegistrationOptions): void;
13
+ /**
14
+ * Retrieve the strategy for a specific item type. Throws if no strategy is registered.
15
+ * @param type - The item type to look up (e.g. GlobalSelectionItemType.Tag).
16
+ */
17
+ get<T extends GlobalSelectionItemType>(type: T): OrderedSelectionItemTypeStrategy<T>;
18
+ /**
19
+ * Returns all strategies sorted by `categoryOrderIndex` — use for **UI rendering**.
20
+ *
21
+ * `categoryOrderIndex` is a display-order index assigned at registration time that
22
+ * controls the visual order of categories in the selection menu (e.g. Tags=0, WorkOrders=1, …).
23
+ * It is independent of registration order and can be set to any value as long as it is unique.
24
+ */
25
+ getAll(): ReadonlyArray<OrderedSelectionItemTypeStrategy>;
26
+ /**
27
+ * Returns all strategies in the order they were registered — use for **type-guard dispatch**.
28
+ *
29
+ * When identifying an unknown `ItemId` (e.g. in `mapIdToItemType`), strategies are tried
30
+ * in this order until one's `isItemId()` returns true. Registration order therefore controls
31
+ * type-guard priority: if type A's `isItemId()` can match type B's IDs,
32
+ * type B must be registered before type A so it is checked first.
33
+ * See `registerStrategies.ts` for the concrete ordering rationale.
34
+ */
35
+ getAllByRegistrationOrder(): ReadonlyArray<OrderedSelectionItemTypeStrategy>;
36
+ }
37
+ export declare const selectionItemTypeRegistry: SelectionItemTypeRegistry;
@@ -0,0 +1,50 @@
1
+ import type { ResultArray } from '@equinor/echo-search';
2
+ import type { GlobalSelectionItemType, GlobalSelectionItemTypeToDataMap, GlobalSelectionTypes, SelectionItemTypeToItemIdMap } from '../globalSelectionStore/globalSelectionStore.types';
3
+ import type { GlobalSelectionCategoryId } from '../selectionMenu/selectionTreeStore/selectionTree.store.types';
4
+ export interface SelectionItemTypeStrategy<T extends GlobalSelectionItemType> {
5
+ /** Discriminant — e.g. GlobalSelectionItemType.Tag */
6
+ readonly itemType: T;
7
+ /** Category ID for tree grouping */
8
+ readonly categoryId: GlobalSelectionCategoryId;
9
+ /** Category label shown in UI */
10
+ readonly categoryLabel: string;
11
+ /** Type guard: narrows ItemId to this type's ID */
12
+ isItemId(itemId: GlobalSelectionTypes.ItemId): itemId is SelectionItemTypeToItemIdMap[T];
13
+ /** Convert raw ItemId to canonical form (trim, normalize) */
14
+ normalizeId(itemId: SelectionItemTypeToItemIdMap[T]): SelectionItemTypeToItemIdMap[T];
15
+ /** Serialize ItemId to unique string key */
16
+ itemIdToString(itemId: SelectionItemTypeToItemIdMap[T]): GlobalSelectionTypes.ItemIdString;
17
+ /** Check equality of two IDs of this type */
18
+ idsEqual(itemA: SelectionItemTypeToItemIdMap[T], itemB: SelectionItemTypeToItemIdMap[T]): boolean;
19
+ /** Create a placeholder item for loading state */
20
+ createNullItem(itemId: SelectionItemTypeToItemIdMap[T]): GlobalSelectionItemTypeToDataMap[T];
21
+ /**
22
+ * Resolve items synchronously from the ID alone — no loading state, no API call.
23
+ * Only implement when item data is embedded in the ID itself (e.g. PDMS tags).
24
+ *
25
+ * The generic action calls this first (if present) and only passes the `remaining` IDs
26
+ * to `fetchAsync`, skipping the isLoading → fetched cycle for the resolved items.
27
+ * If absent, all IDs are forwarded directly to `fetchAsync`.
28
+ */
29
+ resolveSync?(itemIds: ReadonlyArray<SelectionItemTypeToItemIdMap[T]>): {
30
+ readonly resolved: ReadonlyArray<{
31
+ readonly data: GlobalSelectionItemTypeToDataMap[T];
32
+ readonly id: SelectionItemTypeToItemIdMap[T];
33
+ }>;
34
+ readonly remaining: ReadonlyArray<SelectionItemTypeToItemIdMap[T]>;
35
+ };
36
+ /**
37
+ * Fetch real data from the API for items that could not be resolved synchronously.
38
+ * Called only with the `remaining` IDs returned by resolveSync (or all IDs if resolveSync is absent).
39
+ */
40
+ fetchAsync(itemIds: ReadonlyArray<SelectionItemTypeToItemIdMap[T]>): Promise<ReadonlyArray<{
41
+ readonly result: ResultArray<GlobalSelectionItemTypeToDataMap[T]>;
42
+ readonly itemIdsUsed: ReadonlyArray<SelectionItemTypeToItemIdMap[T]>;
43
+ }>>;
44
+ }
45
+ export interface RegistrationOptions {
46
+ readonly categoryOrderIndex: number;
47
+ }
48
+ export type OrderedSelectionItemTypeStrategy<T extends GlobalSelectionItemType = GlobalSelectionItemType> = SelectionItemTypeStrategy<T> & {
49
+ readonly categoryOrderIndex: number;
50
+ };
@@ -0,0 +1,3 @@
1
+ import { GlobalSelectionItemType } from '../globalSelectionStore/globalSelectionStore.types';
2
+ import type { SelectionItemTypeStrategy } from './selectionItemTypeStrategy.types';
3
+ export declare const tagSelectionStrategy: SelectionItemTypeStrategy<GlobalSelectionItemType.Tag>;
@@ -0,0 +1,3 @@
1
+ import { GlobalSelectionItemType } from '../globalSelectionStore/globalSelectionStore.types';
2
+ import type { SelectionItemTypeStrategy } from './selectionItemTypeStrategy.types';
3
+ export declare const workOrderSelectionStrategy: SelectionItemTypeStrategy<GlobalSelectionItemType.WorkOrder>;
@@ -1,5 +1,5 @@
1
+ import type { MarkerId } from '../../../../shared/markerId.types';
1
2
  import { LegendDataId, LegendId } from '../../../types/legendType';
2
- import { MarkerId } from '../utils/markerId.utils';
3
3
  import { ColorGroupedMarker } from '../utils/splitMarkerByColor.types';
4
4
  interface MarkerWithPopoverProps {
5
5
  legendId: LegendId;
@@ -1,5 +1,5 @@
1
+ import type { MarkerId } from '../../../../../../shared/markerId.types';
1
2
  import { Marker } from '../../../../../types/legendMarkerBadge.type';
2
- import { MarkerId } from '../../../utils/markerId.utils';
3
3
  import { ColorGroupedMarker } from '../../../utils/splitMarkerByColor.types';
4
4
  /**
5
5
  * Builds the list of color-grouped markers to render for a single legend item.
@@ -1,4 +1,4 @@
1
- import { MarkerId } from '../../../utils/markerId.utils';
1
+ import type { MarkerId } from '../../../../../../shared/markerId.types';
2
2
  import { ColorGroupedMarker } from '../../../utils/splitMarkerByColor.types';
3
3
  interface UseStalePopoverMarkersProps {
4
4
  readonly markersToRender: ReadonlyArray<ColorGroupedMarker> | null;
@@ -8,9 +8,9 @@ interface UseStalePopoverMarkersProps {
8
8
  /**
9
9
  * Holds stale markers visible while selection feedback is displayed after a delayed close or migration.
10
10
  *
11
- * When `shouldDelayPopoverUpdate` is true and the active popover's marker disappears (e.g. last item
11
+ * When `selectionActionFeedback.isFeedbackActive` is true and the active popover's marker disappears (e.g. last item
12
12
  * removed from a color group), this hook keeps the old `MarkerWithPopover` rendered for
13
- * `POPOVER_UPDATE_DELAY_MS`. That gives the loading indicator and feedback message ("Removed",
13
+ * `FEEDBACK_DISPLAY_DURATION_MS`. That gives the loading indicator and feedback message ("Removed",
14
14
  * "Color changed") time to be visible before the popover closes or migrates to a new marker.
15
15
  *
16
16
  * @returns The markers that should be rendered — either the stale snapshot or the live `markersToRender`.
@@ -1,7 +1,6 @@
1
+ import type { MarkerId } from '../../../../../shared/markerId.types';
1
2
  import { LegendDataId, LegendId } from '../../../../types/legendType';
2
- import { MarkerId } from '../../utils/markerId.utils';
3
3
  import { ColorGroupedMarker } from '../../utils/splitMarkerByColor.types';
4
- export declare const POPOVER_UPDATE_DELAY_MS = 2000;
5
4
  /**
6
5
  * Hook to manage popover state and async content loading for legend markers.
7
6
  * When fetching, it will show a loading spinner if content takes too long to load.
@@ -1,6 +1,5 @@
1
- import { Brand } from '@equinor/echo-utils';
1
+ import type { MarkerId } from '../../../../shared/markerId.types';
2
2
  import { LegendId } from '../../../types/legendType';
3
- export type MarkerId = Brand<string, 'MarkerId'>;
4
3
  /**
5
4
  * Color key used when a marker is not in any selection group (fallback/transparent state).
6
5
  */
@@ -1,4 +1,4 @@
1
- import type { MarkerId } from './components/pdfMarkers/utils/markerId.utils';
1
+ import type { MarkerId } from '../shared/markerId.types';
2
2
  import type { LegendId, LegendState } from './types/legendType';
3
3
  export declare const LEGEND_OBJECT_NAME = "Legend";
4
4
  export declare function trackEventNewLegendSelectedMarkerOptionChanged(legendId: LegendId, legendState: LegendState): void;
@@ -126,6 +126,14 @@ export declare const legendFacade: Readonly<{
126
126
  type: string;
127
127
  value: string;
128
128
  }[];
129
+ coordinates: {
130
+ tagSeqNo: number;
131
+ xEasting: number;
132
+ yNorthing: number;
133
+ zElevation: number;
134
+ uom: string;
135
+ linePosition: number | undefined;
136
+ }[];
129
137
  tagNo: string;
130
138
  description: string;
131
139
  projectCode: string;
@@ -4,11 +4,11 @@ export interface TagNotificationGroup {
4
4
  readonly tagId: TagNo;
5
5
  readonly notifications: ReadonlyArray<NotificationDto>;
6
6
  }
7
- interface UseNotificationsByTagIdsResult {
7
+ interface UseOpenNotificationsByTagIdsResult {
8
8
  readonly data: ReadonlyArray<TagNotificationGroup>;
9
9
  readonly error: Error | undefined;
10
10
  readonly isFetching: boolean;
11
11
  }
12
- export declare const useNotificationsByTagIds: (tagIds: ReadonlyArray<LegendTagId>, enabled: boolean) => UseNotificationsByTagIdsResult;
12
+ export declare const useOpenNotificationsByTagIds: (tagIds: ReadonlyArray<LegendTagId>, enabled: boolean) => UseOpenNotificationsByTagIdsResult;
13
13
  export declare const groupNotificationsByTagId: (notifications: ReadonlyArray<NotificationDto>) => ReadonlyArray<TagNotificationGroup>;
14
14
  export {};
@@ -6,7 +6,7 @@ interface CreateMarkerFromNotificationsArgs {
6
6
  readonly selectedMarkerOption: LegendMarkerOptionConfig;
7
7
  readonly selectedBadgeOption: LegendBadgeOptionConfig;
8
8
  }
9
- export declare const createMarkerFromNotifications: ({ notifications, selectedMarkerOption, selectedBadgeOption }: CreateMarkerFromNotificationsArgs) => Marker;
9
+ export declare const createMarkerFromNotifications: ({ notifications, selectedMarkerOption, selectedBadgeOption }: CreateMarkerFromNotificationsArgs) => Marker | undefined;
10
10
  export declare const createMarkerTitle: (notifications: ReadonlyArray<NotificationLegendData>, selectedMarkerOption: LegendMarkerOptionConfig) => string;
11
11
  export declare const createBadges: (notifications: ReadonlyArray<NotificationLegendData>, selectedBadgeOption: LegendBadgeOptionConfig) => ReadonlyArray<Badge>;
12
12
  export {};