@equinor/echo-framework 2.2.3 → 2.4.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 (57) hide show
  1. package/README.md +23 -3
  2. package/index.cjs.js +3 -3
  3. package/package.json +12 -8
  4. package/src/index.d.ts +8 -3
  5. package/src/lib/components/index.d.ts +2 -0
  6. package/src/lib/components/prepview/Prepview.d.ts +11 -1
  7. package/src/lib/components/prepview/context/PrepviewContext.d.ts +1 -1
  8. package/src/lib/components/prepview/panels/objects/EquipmentListItem.d.ts +9 -0
  9. package/src/lib/components/prepview/panels/objects/NotificationListItem.d.ts +9 -0
  10. package/src/lib/components/requestAccess/MissingAccessInfoButton.d.ts +6 -0
  11. package/src/lib/components/requestAccess/RequestAccessButton.d.ts +2 -1
  12. package/src/lib/components/requestAccess/RequestProCoSysAccess.d.ts +0 -1
  13. package/src/lib/components/verticalTabsSplitView/VerticalTabsSplitView.d.ts +1 -1
  14. package/src/lib/coreApplication/EchoUserInterfaceStore.d.ts +5 -0
  15. package/src/lib/feature/equipment/hooks/useEquipmentWithMeasuringPoints.d.ts +1 -1
  16. package/src/lib/feature/globalSelection/globalSelectionStore/globalSelectionStore.d.ts +205 -2
  17. package/src/lib/feature/globalSelection/hooks/useGlobalSelectionItemsByTypeAsMap.d.ts +7 -0
  18. package/src/lib/feature/globalSelection/index.d.ts +1 -0
  19. package/src/lib/feature/globalSelection/selectionMenu/selectionTreeStore/persist/selectionTree.load.utils.d.ts +7 -0
  20. package/src/lib/feature/globalSelection/selectionMenu/selectionTreeStore/selectionTree.store.d.ts +78 -2
  21. package/src/lib/feature/legend/components/legendTextSelector/LegendTextSelector.d.ts +5 -6
  22. package/src/lib/feature/legend/components/pdfMarkers/PositionalItem.d.ts +1 -1
  23. package/src/lib/feature/legend/components/pdfMarkers/subComponents/LegendColoredMarkerIcon.d.ts +2 -2
  24. package/src/lib/feature/legend/components/pdfMarkers/subComponents/LegendMarkersRenderer.d.ts +1 -1
  25. package/src/lib/feature/legend/components/pdfMarkers/subComponents/MarkerWithPopover.d.ts +13 -0
  26. package/src/lib/feature/legend/components/pdfMarkers/subComponents/MultipleMarkersByLegends.d.ts +1 -5
  27. package/src/lib/feature/legend/components/pdfMarkers/subComponents/MultipleMarkersBySingleLegend.d.ts +1 -2
  28. package/src/lib/feature/legend/components/pdfMarkers/subComponents/hooks/useMarkerPopover.d.ts +19 -0
  29. package/src/lib/feature/legend/components/pdfMarkers/utils/markerId.utils.d.ts +18 -0
  30. package/src/lib/feature/legend/components/pdfMarkers/utils/splitMarkerByBadgeSelectionGroup.types.d.ts +4 -1
  31. package/src/lib/feature/legend/components/selectionLegend/SelectionLegend.d.ts +1 -1
  32. package/src/lib/feature/legend/components/selectionLegend/SelectionLegendChip.d.ts +1 -1
  33. package/src/lib/feature/legend/components/selectionLegend/components/SelectionLegendActions.d.ts +5 -0
  34. package/src/lib/feature/legend/components/selectionLegend/components/SelectionLegendOtherMarkers.d.ts +4 -0
  35. package/src/lib/feature/legend/components/selectionLegend/hooks/useSelectionGroupsForLegendRenderer.d.ts +5 -0
  36. package/src/lib/feature/legend/components/selectionLegend/hooks/useSelectionGroupsForLegendRenderer.utils.d.ts +17 -0
  37. package/src/lib/feature/legend/components/selectionLegend/selectionLegend.utils.d.ts +18 -7
  38. package/src/lib/feature/legend/legendFacade.d.ts +36 -9
  39. package/src/lib/feature/legend/stores/legendDataStore/legendStore.d.ts +35 -39
  40. package/src/lib/feature/legend/stores/legendUIStore/legendUIStore.d.ts +8 -3
  41. package/src/lib/feature/legend/stores/legendUIStore/legendUIStore.types.d.ts +15 -1
  42. package/src/lib/feature/legend/stores/legendVisibleDataAsTagsStore/legendVisibleDataAsTagsStore.d.ts +34 -1
  43. package/src/lib/feature/legend/stores/legendVisibleDataStore/legendVisibleDataStore.d.ts +20 -1
  44. package/src/lib/feature/legend/types/legendStrategy.type.d.ts +7 -3
  45. package/src/lib/hooks/useOpenPrepview.d.ts +1 -1
  46. package/src/lib/services/dataLayerPanel/dataLayerPanel.store.d.ts +53 -21
  47. package/src/lib/services/leftPanelNavigation/leftPanelNavigation.store.d.ts +14 -11
  48. package/src/lib/services/userSetting/userSettingStore.d.ts +8 -4
  49. package/src/lib/utils/dataAccess/accessGuidanceSections.d.ts +27 -0
  50. package/src/lib/{types → utils}/dataAccess/dataAccessLinks.d.ts +6 -1
  51. package/src/lib/utils/dataAccess/dataAccessLinks.utils.d.ts +9 -0
  52. package/src/types/procosysProject.d.ts +20 -0
  53. package/src/lib/components/requestAccess/RequestSapAccess.d.ts +0 -7
  54. package/src/lib/feature/legend/components/pdfMarkers/subComponents/hooks/usePopoverHandler.d.ts +0 -7
  55. package/src/lib/feature/legend/components/pdfMarkers/subComponents/hooks/usePopoverHandler.types.d.ts +0 -14
  56. package/src/lib/feature/legend/components/selectionLegend/hooks/useIsSelectionLegendVisible.d.ts +0 -6
  57. package/src/lib/types/dataAccess/index.d.ts +0 -1
@@ -1,12 +1,8 @@
1
1
  import { LegendDataId } from '../../../types/legendType';
2
- import { PopoverContent, RequestPopoverHandler } from './hooks/usePopoverHandler.types';
3
2
  interface MultipleMarkersByLegendsProps {
4
3
  itemId: LegendDataId;
5
4
  hasPointer: boolean;
6
- onOpenPopover: RequestPopoverHandler;
7
- onClosePopover: () => void;
8
- currentPopover?: PopoverContent;
9
- uniqueIdentifier: string;
5
+ positionId: string;
10
6
  }
11
7
  export declare const MultipleMarkersByLegends: import("react").MemoExoticComponent<(props: MultipleMarkersByLegendsProps) => import("react/jsx-runtime").JSX.Element>;
12
8
  export {};
@@ -3,8 +3,7 @@ interface MultipleMarkersBySingleLegendComponentProps {
3
3
  legendId: LegendId;
4
4
  itemId: LegendDataId;
5
5
  hasPointer: boolean;
6
- isActive: boolean;
7
- onClick: () => void;
6
+ positionId: string;
8
7
  }
9
8
  export declare const MultipleMarkersBySingleLegend: import("react").MemoExoticComponent<(props: MultipleMarkersBySingleLegendComponentProps) => import("react/jsx-runtime").JSX.Element[] | null>;
10
9
  export {};
@@ -0,0 +1,19 @@
1
+ import { LegendDataId, LegendId } from '../../../../types/legendType';
2
+ import { MarkerId } from '../../utils/markerId.utils';
3
+ import { GroupedMarker } from '../../utils/splitMarkerByBadgeSelectionGroup.types';
4
+ /**
5
+ * Hook to manage popover state and async content loading for legend markers.
6
+ * When fetching, it will show a loading spinner if content takes too long to load.
7
+ *
8
+ * @param markerId - Unique identifier for this marker
9
+ * @param legendId - The legend this marker belongs to
10
+ * @param itemId - The data ID for this legend item
11
+ * @param marker - The grouped marker data containing badges
12
+ * @returns Object with isActive state, elements array, and handlers for open/close
13
+ */
14
+ export declare function useMarkerPopover(markerId: MarkerId, legendId: LegendId, itemId: LegendDataId, marker: GroupedMarker): {
15
+ isPopoverActive: boolean;
16
+ elements: readonly import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>[];
17
+ handleOpen: () => Promise<void>;
18
+ handleClose: () => void;
19
+ };
@@ -0,0 +1,18 @@
1
+ import { Brand } from '@equinor/echo-utils';
2
+ import { LegendId } from '../../../types/legendType';
3
+ export type MarkerId = Brand<string, 'MarkerId'>;
4
+ /**
5
+ * Creates a unique marker ID from its component parts.
6
+ * Format: positionId::legendId::groupKey
7
+ */
8
+ export declare function createMarkerId(positionId: string, legendId: LegendId, groupKey: string): MarkerId;
9
+ /**
10
+ * Extracts the position ID from a marker ID.
11
+ * Returns undefined if the marker ID is invalid.
12
+ * @internal - Only exported for testing purposes
13
+ */
14
+ export declare function getPositionIdFromMarkerId(markerId: MarkerId): string | undefined;
15
+ /**
16
+ * Checks if a marker ID belongs to a specific position.
17
+ */
18
+ export declare function isMarkerAtPosition(markerId: MarkerId | undefined, positionId: string): boolean;
@@ -1,10 +1,13 @@
1
1
  import { Guid } from '@equinor/echo-utils';
2
+ import { GlobalSelectionItemType } from '../../../../globalSelection';
2
3
  import { Badge, Marker } from '../../../types/legendMarkerBadge.type';
3
4
  export interface GroupKey {
4
- /** Helper to get the full string representation of the group key based on groupId and color */
5
+ /** Helper to get the full string representation of the group key based on groupId, color, and optional itemType */
5
6
  toString: () => string;
6
7
  groupId: Guid;
7
8
  color: string;
9
+ /** Optional item type for local selection which will be split by type */
10
+ itemType?: GlobalSelectionItemType;
8
11
  }
9
12
  export interface BadgeGroup {
10
13
  groupKey: GroupKey;
@@ -1 +1 @@
1
- export declare const SelectionLegendRenderer: import("react").MemoExoticComponent<() => import("react/jsx-runtime").JSX.Element>;
1
+ export declare const SelectionLegendRenderer: import("react").MemoExoticComponent<() => import("react/jsx-runtime").JSX.Element | null>;
@@ -1,7 +1,7 @@
1
1
  interface LegendItemProps {
2
2
  label: string;
3
- backgroundColor?: string;
4
3
  onClick: (isDisabled: boolean) => void;
4
+ colors: string[];
5
5
  }
6
6
  export declare const SelectionLegendChip: import("react").MemoExoticComponent<(props: LegendItemProps) => import("react/jsx-runtime").JSX.Element>;
7
7
  export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * SelectionLegendActions renders the action buttons for the Selection Legend.
3
+ * It provides options to toggle the visibility of highlights around selection group markers.
4
+ */
5
+ export declare const SelectionLegendActions: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Allows the user to select how to display markers that are not in any selection group.
3
+ */
4
+ export declare const SelectionLegendOtherMarkers: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { SelectionGroupDisplay } from './useSelectionGroupsForLegendRenderer.utils';
2
+ /**
3
+ * Hook to get selection groups formatted for the legend renderer.
4
+ */
5
+ export declare const useSelectionGroupsForLegendRenderer: () => SelectionGroupDisplay[];
@@ -0,0 +1,17 @@
1
+ import { Guid } from '@equinor/echo-utils';
2
+ import { GlobalSelectionItemType, SelectionGroup } from '../../../../globalSelection';
3
+ import { GroupedMarker } from '../../pdfMarkers/utils/splitMarkerByBadgeSelectionGroup.types';
4
+ export interface SelectionGroupDisplay {
5
+ readonly label: string;
6
+ readonly highlightColors: string[];
7
+ readonly selectionGroupId: Guid;
8
+ readonly itemType?: GlobalSelectionItemType;
9
+ }
10
+ type GroupMapKey = string;
11
+ type GroupMap = Record<GroupMapKey, SelectionGroupDisplay>;
12
+ /**
13
+ * Builds a map of selection groups with their colors from grouped markers.
14
+ * Groups markers by selection group, collecting all unique colors for each group.
15
+ */
16
+ export declare function buildSelectionGroupMap(allGroupedMarkers: GroupedMarker[] | undefined, selectionGroups: SelectionGroup[]): GroupMap;
17
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { Guid } from '@equinor/echo-utils';
2
- import { GlobalSelectionTypes, SelectionGroup } from '../../../globalSelection';
3
- import { GroupKey } from '../pdfMarkers/utils/splitMarkerByBadgeSelectionGroup.types';
2
+ import { GlobalSelectionItemType, GlobalSelectionTypes, SelectionGroup } from '../../../globalSelection';
3
+ import { GroupedMarker, GroupKey } from '../pdfMarkers/utils/splitMarkerByBadgeSelectionGroup.types';
4
4
  /**
5
5
  * TODO: Remove this flag when Selection Legend is stable and ready for production
6
6
  * Flag to enable/disable Selection Legend feature
@@ -15,20 +15,31 @@ export declare const NOT_IN_SELECTION_GROUP_KEY: GroupKey;
15
15
  */
16
16
  export declare const extractSelectionGroupItemIds: (selectionGroup: SelectionGroup) => GlobalSelectionTypes.ItemId[];
17
17
  /**
18
- * Gets the most frequently used color for a selection group
18
+ * Determines if groups should be split by item type.
19
+ * Only true for the default local selection group (Local Selection).
19
20
  */
20
- export declare const getSelectionGroupMostUsedColor: (selectionGroup: SelectionGroup, allGroups: SelectionGroup[]) => string | undefined;
21
+ export declare const shouldSplitGroupsByItemType: (groupId: Guid) => boolean;
21
22
  /**
22
23
  * Creates a standardized group key for a selection group.
23
- * This key is used across the legend system to:
24
+ *
25
+ * Used across the legend system to:
24
26
  * - Identify marker variants split by selection groups (viewport)
25
27
  * - Toggle visibility of selection groups (SelectionLegendRenderer)
26
28
  * - Filter hidden selection groups (groupMarkersBySelection)
27
29
  *
28
- * Format as string: `group_${groupId}_${color}`
30
+ * Format: `group_${groupId}_${color}` or `group_${groupId}_${itemType}_${color}` for global selection
29
31
  *
30
32
  * @param groupId - The unique identifier of the selection group
31
33
  * @param color - The highlight color for the group
34
+ * @param itemType - Optional item type for local selection which will be split by type
32
35
  * @returns The standardized group key
33
36
  */
34
- export declare const createSelectionGroupKey: (groupId: Guid, color: string) => GroupKey;
37
+ export declare const createSelectionGroupKey: (groupId: Guid, color: string, itemType?: GlobalSelectionItemType) => GroupKey;
38
+ /**
39
+ * Checks if a marker belongs to the "Not in Selection" group.
40
+ *
41
+ * @param marker - The marker to check.
42
+ *
43
+ * @returns True if the marker is in the "Not in Selection" group, false otherwise.
44
+ */
45
+ export declare const isMarkerOutsideSelection: (marker: GroupedMarker) => boolean;
@@ -1,6 +1,6 @@
1
1
  import { getLegendStrategy, injectLegendStrategy } from './legendStrategies/legendCollections';
2
2
  import { isLegendDataIdEqualWithTag } from './logic/isLegendDataIdEqualWithTag';
3
- import { legendExistsInLegendStore, legendSnapShot, useAllLegends, useLegendById } from './stores/legendDataStore/legendStore';
3
+ import { legendExistsInLegendStore, legendSnapShot, legendStoreSubscribe, useAllLegends, useLegendById } from './stores/legendDataStore/legendStore';
4
4
  import { legendExistsInLegendUIStore, useLegendUIById } from './stores/legendUIStore/legendUIStore';
5
5
  import { visibleDataAsTagsSnapshot } from './stores/legendVisibleDataAsTagsStore/legendVisibleDataAsTagsStore';
6
6
  import { LegendId } from './types/legendType';
@@ -17,13 +17,7 @@ export declare const legendFacade: Readonly<{
17
17
  useById: typeof useLegendById;
18
18
  exists: typeof legendExistsInLegendStore;
19
19
  snapshot: typeof legendSnapShot;
20
- subscribe: {
21
- (listener: (selectedState: import("./stores/legendDataStore/legendStore").LegendStoreData & import("./stores/legendDataStore/legendStore").LegendStoreActions, previousSelectedState: import("./stores/legendDataStore/legendStore").LegendStoreData & import("./stores/legendDataStore/legendStore").LegendStoreActions) => void): () => void;
22
- <U>(selector: (state: import("./stores/legendDataStore/legendStore").LegendStoreData & import("./stores/legendDataStore/legendStore").LegendStoreActions) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
23
- equalityFn?: ((a: U, b: U) => boolean) | undefined;
24
- fireImmediately?: boolean;
25
- } | undefined): () => void;
26
- };
20
+ subscribe: typeof legendStoreSubscribe;
27
21
  };
28
22
  ui: {
29
23
  useById: typeof useLegendUIById;
@@ -97,7 +91,40 @@ export declare const legendFacade: Readonly<{
97
91
  } | undefined): () => void;
98
92
  };
99
93
  }, "setState"> & {
100
- setState(nextStateOrUpdater: import("./stores/legendVisibleDataAsTagsStore/legendVisibleDataAsTagsStore").VisibleDataAsTagsStore | Partial<import("./stores/legendVisibleDataAsTagsStore/legendVisibleDataAsTagsStore").VisibleDataAsTagsStore> | ((state: import("immer").WritableDraft<import("./stores/legendVisibleDataAsTagsStore/legendVisibleDataAsTagsStore").VisibleDataAsTagsStore>) => void), shouldReplace?: boolean | undefined, action?: string | {
94
+ setState(nextStateOrUpdater: import("./stores/legendVisibleDataAsTagsStore/legendVisibleDataAsTagsStore").VisibleDataAsTagsStore | Partial<import("./stores/legendVisibleDataAsTagsStore/legendVisibleDataAsTagsStore").VisibleDataAsTagsStore> | ((state: {
95
+ tags: {
96
+ tagNo: string;
97
+ instCode: string;
98
+ equipmentId: string | undefined;
99
+ tagSummary: {
100
+ instCode: string;
101
+ pdmsPlantCode: string | undefined;
102
+ tagCategoryDescription: string;
103
+ tagCategory: number;
104
+ tagStatus: import("@equinor/echo-search").TagStatus;
105
+ tagType: string;
106
+ updatedDate: Date;
107
+ locationCode: string;
108
+ contrCode: string;
109
+ plantNo: string;
110
+ poNo: string;
111
+ xCoordinate?: number | undefined;
112
+ yCoordinate?: number | undefined;
113
+ zCoordinate?: number | undefined;
114
+ additionalFields: {
115
+ type: string;
116
+ value: string;
117
+ }[];
118
+ tagNo: string;
119
+ description: string;
120
+ projectCode: string;
121
+ system: string;
122
+ };
123
+ }[];
124
+ isPending: boolean;
125
+ updateTags: (tags: import("./stores/legendVisibleDataAsTagsStore/legendVisibleDataAsTagsStore.type").TagWithEquipmentId[]) => void;
126
+ setIsPending: (isPending: boolean) => void;
127
+ }) => void), shouldReplace?: boolean | undefined, action?: string | {
101
128
  type: string;
102
129
  } | undefined): void;
103
130
  }>;
@@ -1,4 +1,3 @@
1
- import { PersistOptions } from 'zustand/middleware';
2
1
  import { LegendId, LegendState } from '../../types/legendType';
3
2
  type LegendsDictionary = Record<LegendId, LegendState>;
4
3
  export interface LegendStoreData {
@@ -12,37 +11,6 @@ export interface LegendStoreActions {
12
11
  initializeLegendInStore: (legendId: LegendId) => void;
13
12
  }
14
13
  type LegendStore = LegendStoreData & LegendStoreActions;
15
- type PersistedLegendState = Omit<LegendState, 'isLoading'>;
16
- type PersistedLegendStoreData = {
17
- legends: Record<LegendId, PersistedLegendState>;
18
- };
19
- export declare const useLegendStore: import("zustand").UseBoundStore<Omit<Omit<Omit<Omit<import("zustand").StoreApi<LegendStore>, "setState"> & {
20
- setState<A extends string | {
21
- type: string;
22
- }>(partial: LegendStore | Partial<LegendStore> | ((state: LegendStore) => LegendStore | Partial<LegendStore>), replace?: boolean | undefined, action?: A | undefined): void;
23
- }, "subscribe"> & {
24
- subscribe: {
25
- (listener: (selectedState: LegendStore, previousSelectedState: LegendStore) => void): () => void;
26
- <U>(selector: (state: LegendStore) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
27
- equalityFn?: ((a: U, b: U) => boolean) | undefined;
28
- fireImmediately?: boolean;
29
- } | undefined): () => void;
30
- };
31
- }, "persist"> & {
32
- persist: {
33
- setOptions: (options: Partial<PersistOptions<LegendStore, PersistedLegendStoreData>>) => void;
34
- clearStorage: () => void;
35
- rehydrate: () => Promise<void> | void;
36
- hasHydrated: () => boolean;
37
- onHydrate: (fn: (state: LegendStore) => void) => () => void;
38
- onFinishHydration: (fn: (state: LegendStore) => void) => () => void;
39
- getOptions: () => Partial<PersistOptions<LegendStore, PersistedLegendStoreData>>;
40
- };
41
- }, "setState"> & {
42
- setState(nextStateOrUpdater: LegendStore | Partial<LegendStore> | ((state: import("immer").WritableDraft<LegendStore>) => void), shouldReplace?: boolean | undefined, action?: string | {
43
- type: string;
44
- } | undefined): void;
45
- }>;
46
14
  /**
47
15
  * Hook to access a legend by ID with optional property selection for optimized re-renders.
48
16
  *
@@ -90,11 +58,39 @@ export declare function legendExistsInLegendStore(legendId: LegendId): boolean;
90
58
  export declare function useAllLegends(): LegendState[];
91
59
  export declare function useAllLegends<T>(selector: (legends: LegendState[]) => T): T;
92
60
  export declare function legendSnapShot(): LegendStore;
93
- export declare const legendStoreSubscribe: {
94
- (listener: (selectedState: LegendStore, previousSelectedState: LegendStore) => void): () => void;
95
- <U>(selector: (state: LegendStore) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
96
- equalityFn?: ((a: U, b: U) => boolean) | undefined;
97
- fireImmediately?: boolean;
98
- } | undefined): () => void;
99
- };
61
+ /**
62
+ * Subscribe to legend store changes with optional selector for granular updates.
63
+ *
64
+ * NOTE: This wrapper is required because useLegendStore has an explicit type annotation
65
+ * (UseBoundStore<StoreApi<T>>) to prevent rollup build errors with useLegacyTypescriptPlugin: false.
66
+ *
67
+ * Without explicit type, TypeScript infers Immer's internal types (WritableNonArrayDraft, etc.)
68
+ * which use complex generics that rollup's @rollup/plugin-typescript cannot "name" in generated
69
+ * .d.ts files, causing TS4023: "Exported variable has or is using name 'X' but cannot be named."
70
+ *
71
+ * The explicit type hides these internals from rollup, but also removes subscribeWithSelector's
72
+ * enhanced subscribe(selector, listener) signature. This wrapper manually restores both overloads.
73
+ *
74
+ * @example
75
+ * // Watch entire store:
76
+ * const unsubscribe = legendStoreSubscribe((state) => console.log('Changed:', state));
77
+ *
78
+ * @example
79
+ * // Watch specific property:
80
+ * const unsubscribe = legendStoreSubscribe(
81
+ * (state) => state.legends['Tag Legend']?.isEnabled,
82
+ * (isEnabled, prevIsEnabled) => console.log('Enabled changed:', isEnabled)
83
+ * );
84
+ */
85
+ export declare function legendStoreSubscribe(listener: (state: LegendStore, prevState: LegendStore) => void): () => void;
86
+ export declare function legendStoreSubscribe<U>(selector: (state: LegendStore) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
87
+ equalityFn?: (a: U, b: U) => boolean;
88
+ fireImmediately?: boolean;
89
+ }): () => void;
90
+ export declare const getLegendStoreState: () => LegendStore;
91
+ /**
92
+ * TEST ONLY: Reset legend store to a specific state.
93
+ * Only use this in tests for setup/cleanup.
94
+ */
95
+ export declare const __TEST__resetLegendStore: (state: Partial<LegendStoreData>) => void;
100
96
  export {};
@@ -1,11 +1,10 @@
1
+ import { type StoreApi, type UseBoundStore } from 'zustand';
1
2
  import { LegendId } from '../../types/legendType';
2
3
  import { LegendUIState, LegendUIStore } from './legendUIStore.types';
3
4
  /**
4
5
  * Non-persisted store for managing UI state of legends, such as accordion expansion and hidden markers/badges.
5
6
  */
6
- export declare const useLegendUIStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<LegendUIStore>, "setState"> & {
7
- setState(nextStateOrUpdater: LegendUIStore | Partial<LegendUIStore> | ((state: import("immer").WritableDraft<LegendUIStore>) => void), shouldReplace?: boolean | undefined): void;
8
- }>;
7
+ export declare const useLegendUIStore: UseBoundStore<StoreApi<LegendUIStore>>;
9
8
  /**
10
9
  * Hook to access a legend by ID with optional property selection for optimized re-renders.
11
10
  *
@@ -30,3 +29,9 @@ export declare const useLegendUIStore: import("zustand").UseBoundStore<Omit<impo
30
29
  export declare function useLegendUIById(legendId: LegendId): LegendUIState | undefined;
31
30
  export declare function useLegendUIById<T>(legendId: LegendId, selector: (legend: LegendUIState | undefined) => T): T;
32
31
  export declare function legendExistsInLegendUIStore(legendId: LegendId): boolean;
32
+ /**
33
+ * Helper function to toggle visibility of an item in an array.
34
+ * Adds the item if isHidden is true and it's not present, removes it if isHidden is false and it exists.
35
+ * @internal - Exported for testing purposes only
36
+ */
37
+ export declare function toggleItemInArray(array: string[], item: string, isHidden: boolean): void;
@@ -1,3 +1,4 @@
1
+ import { MarkerId } from '../../components/pdfMarkers/utils/markerId.utils';
1
2
  import { LegendId } from '../../types/legendType';
2
3
  export interface LegendUIState {
3
4
  readonly isAccordionExpanded: boolean;
@@ -5,8 +6,17 @@ export interface LegendUIState {
5
6
  readonly hiddenBadges: string[];
6
7
  }
7
8
  export type LegendUIDictionary = Record<LegendId, LegendUIState>;
9
+ export type MarkersOutsideSelectionVisibility = 'Show' | 'Ghost' | 'Hide';
8
10
  export type LegendUIStoreValues = {
9
- legends: LegendUIDictionary;
11
+ readonly legends: LegendUIDictionary;
12
+ readonly activePopover: {
13
+ readonly id?: MarkerId;
14
+ readonly elements: ReadonlyArray<React.ReactElement>;
15
+ };
16
+ readonly selectionLegend: {
17
+ readonly isHighlightVisible: boolean;
18
+ readonly markersOutsideSelectionVisibility: MarkersOutsideSelectionVisibility;
19
+ };
10
20
  };
11
21
  export interface LegendUIStoreActions {
12
22
  toggleAccordion: (legendId: LegendId, newValue: boolean) => void;
@@ -20,6 +30,10 @@ export interface LegendUIStoreActions {
20
30
  badge: string;
21
31
  isHidden: boolean;
22
32
  }) => void;
33
+ setMarkersOutsideSelectionVisibility: (visibility: MarkersOutsideSelectionVisibility) => void;
23
34
  initializeLegendInStore: (legendId: LegendId) => void;
35
+ setSelectionLegendIsHighlightVisible: (visible: boolean) => void;
36
+ setActivePopoverId: (popoverId: MarkerId | undefined) => void;
37
+ setActivePopoverElements: (elements: ReadonlyArray<React.ReactElement>) => void;
24
38
  }
25
39
  export type LegendUIStore = LegendUIStoreValues & LegendUIStoreActions;
@@ -32,7 +32,40 @@ export declare const useVisibleDataAsTagsStore: import("zustand").UseBoundStore<
32
32
  } | undefined): () => void;
33
33
  };
34
34
  }, "setState"> & {
35
- setState(nextStateOrUpdater: VisibleDataAsTagsStore | Partial<VisibleDataAsTagsStore> | ((state: import("immer").WritableDraft<VisibleDataAsTagsStore>) => void), shouldReplace?: boolean | undefined, action?: string | {
35
+ setState(nextStateOrUpdater: VisibleDataAsTagsStore | Partial<VisibleDataAsTagsStore> | ((state: {
36
+ tags: {
37
+ tagNo: string;
38
+ instCode: string;
39
+ equipmentId: string | undefined;
40
+ tagSummary: {
41
+ instCode: string;
42
+ pdmsPlantCode: string | undefined;
43
+ tagCategoryDescription: string;
44
+ tagCategory: number;
45
+ tagStatus: import("@equinor/echo-search").TagStatus;
46
+ tagType: string;
47
+ updatedDate: Date;
48
+ locationCode: string;
49
+ contrCode: string;
50
+ plantNo: string;
51
+ poNo: string;
52
+ xCoordinate?: number | undefined;
53
+ yCoordinate?: number | undefined;
54
+ zCoordinate?: number | undefined;
55
+ additionalFields: {
56
+ type: string;
57
+ value: string;
58
+ }[];
59
+ tagNo: string;
60
+ description: string;
61
+ projectCode: string;
62
+ system: string;
63
+ };
64
+ }[];
65
+ isPending: boolean;
66
+ updateTags: (tags: TagWithEquipmentId[]) => void;
67
+ setIsPending: (isPending: boolean) => void;
68
+ }) => void), shouldReplace?: boolean | undefined, action?: string | {
36
69
  type: string;
37
70
  } | undefined): void;
38
71
  }>;
@@ -55,7 +55,26 @@ export declare const useLegendVisibleDataStore: import("zustand").UseBoundStore<
55
55
  } | undefined): () => void;
56
56
  };
57
57
  }, "setState"> & {
58
- setState(nextStateOrUpdater: LegendVisibleDataStore | Partial<LegendVisibleDataStore> | ((state: import("immer").WritableDraft<LegendVisibleDataStore>) => void), shouldReplace?: boolean | undefined, action?: string | {
58
+ setState(nextStateOrUpdater: LegendVisibleDataStore | Partial<LegendVisibleDataStore> | ((state: {
59
+ data: {
60
+ Tag: {
61
+ [x: string]: {
62
+ instCode: string;
63
+ tagNo: string;
64
+ }[];
65
+ };
66
+ Equipment: {
67
+ [x: string]: {
68
+ equipmentId: string;
69
+ }[];
70
+ };
71
+ };
72
+ addData: <T extends KnownDataTypeKeys>(type: T, key: string, value: ResolvedDataType<T>[]) => void;
73
+ removeData: (key: string) => void;
74
+ getData: <T extends KnownDataTypeKeys>(type: T) => ResolvedDataType<T>[];
75
+ useDataByType: <T extends KnownDataTypeKeys>(type: T) => ResolvedDataType<T>[];
76
+ getAll: () => LegendDataId[];
77
+ }) => void), shouldReplace?: boolean | undefined, action?: string | {
59
78
  type: string;
60
79
  } | undefined): void;
61
80
  }>;
@@ -1,3 +1,4 @@
1
+ import { GlobalSelectionTypes } from '../../globalSelection';
1
2
  import { Marker } from './legendMarkerBadge.type';
2
3
  import { LegendDataId, LegendId, LegendOptionConfig } from './legendType';
3
4
  /**
@@ -28,14 +29,17 @@ export interface LegendStrategy {
28
29
  */
29
30
  useMarkers: (itemIds: ReadonlyArray<LegendDataId>, isViewport?: boolean) => ReadonlyArray<Marker>;
30
31
  /**
31
- * Returns popover content that supports pagination for the given itemId.
32
+ * Returns popover content that supports pagination for the given legendDataId.
33
+ * One legendDataId can have multiple items associated with it, for example a tag can have multiple work orders.
34
+ * Often we don't want to show all items (eg. when items are grouped), so we provide itemIds to filter the content to only relevant items.
32
35
  *
33
36
  * This function is asynchronous because the popover content may depend on data that needs to be fetched before rendering,
34
37
  * such as related equipment, work orders, or other resources.
35
- * @param {LegendDataId} itemId - The identifier for the legend item for which to render popover content.
38
+ * @param {LegendDataId} legendDataId - The identifier for the legend item for which to render popover content.
39
+ * @param {ReadonlyArray<GlobalSelectionTypes.ItemId>} itemIds - The item ids to be included in the popover content.
36
40
  * @returns A Promise resolving to one or more React elements to display in the popover.
37
41
  */
38
- popoverContent: (itemId: LegendDataId) => Promise<React.JSX.Element | ReadonlyArray<React.JSX.Element>>;
42
+ popoverContent: (legendDataId: LegendDataId, itemIds: ReadonlyArray<GlobalSelectionTypes.ItemId>) => Promise<React.ReactElement | ReadonlyArray<React.ReactElement>>;
39
43
  /**
40
44
  * Returns the custom legend component for the legend, if this is omitted the default basicLegendRenderer will be used
41
45
  */
@@ -29,7 +29,7 @@ export declare function useOpenPrepview(): (args: {
29
29
  punchId?: string;
30
30
  instCode?: string;
31
31
  };
32
- panelKey: string;
32
+ panelKey?: string;
33
33
  keepLastNavigationItem?: boolean;
34
34
  allowToggle?: boolean;
35
35
  }) => void;
@@ -1,23 +1,37 @@
1
- import { WritableDraft } from 'immer';
2
- interface PanelUserSettings {
3
- readonly isTagsVisible: boolean;
4
- readonly isWorkOrdersVisible: boolean;
5
- readonly isEquipmentsVisible: boolean;
6
- readonly isIocAnnotationsVisible: boolean;
1
+ export interface PanelUserSettings {
2
+ isTagsVisible: boolean;
3
+ isTagsFromDocumentVisible: boolean;
4
+ isTagsFromSelectionVisible: boolean;
5
+ isWorkOrdersVisible: boolean;
6
+ isWorkOrdersFromDocumentVisible: boolean;
7
+ isWorkOrdersFromSelectionVisible: boolean;
8
+ isEquipmentsVisible: boolean;
9
+ isEquipmentsFromDocumentVisible: boolean;
10
+ isEquipmentsFromSelectionVisible: boolean;
11
+ isIocAnnotationsVisible: boolean;
12
+ isDataFromStidAnnoDetails: boolean;
7
13
  }
8
- interface DataLayerPanelState {
9
- readonly isOpen: boolean;
14
+ export interface DataLayerPanelState {
15
+ isOpen: boolean;
10
16
  readonly userSettings: PanelUserSettings;
11
17
  }
12
18
  interface DataLayerPanelActions {
13
19
  togglePanel: () => void;
20
+ toggleTags: () => void;
21
+ toggleTagsFromDocumentVisible: () => void;
22
+ toggleTagsFromSelectionVisible: () => void;
14
23
  toggleWorkOrders: () => void;
24
+ toggleWorkOrdersFromDocumentVisible: () => void;
25
+ toggleWorkOrdersFromSelectionVisible: () => void;
15
26
  toggleEquipments: () => void;
16
- toggleTags: () => void;
27
+ toggleEquipmentsFromDocumentVisible: () => void;
28
+ toggleEquipmentsFromSelectionVisible: () => void;
29
+ setEquipmentsForEcm: () => void;
17
30
  toggleIocAnnotations: () => void;
31
+ setIsDataFromStidAnnoDetails: (value: boolean) => void;
18
32
  }
19
33
  type DataLayerPanelStore = DataLayerPanelState & DataLayerPanelActions;
20
- export declare const useDataLayerPanelStore: import("zustand").UseBoundStore<Omit<Omit<Omit<Omit<import("zustand").StoreApi<DataLayerPanelStore>, "setState"> & {
34
+ export declare const useDataLayerPanelStore: import("zustand").UseBoundStore<Omit<Omit<Omit<import("zustand").StoreApi<DataLayerPanelStore>, "setState"> & {
21
35
  setState<A extends string | {
22
36
  type: string;
23
37
  }>(partial: DataLayerPanelStore | Partial<DataLayerPanelStore> | ((state: DataLayerPanelStore) => DataLayerPanelStore | Partial<DataLayerPanelStore>), replace?: boolean | undefined, action?: A | undefined): void;
@@ -29,18 +43,36 @@ export declare const useDataLayerPanelStore: import("zustand").UseBoundStore<Omi
29
43
  fireImmediately?: boolean;
30
44
  } | undefined): () => void;
31
45
  };
32
- }, "persist"> & {
33
- persist: {
34
- setOptions: (options: Partial<import("zustand/middleware").PersistOptions<DataLayerPanelStore, unknown>>) => void;
35
- clearStorage: () => void;
36
- rehydrate: () => Promise<void> | void;
37
- hasHydrated: () => boolean;
38
- onHydrate: (fn: (state: DataLayerPanelStore) => void) => () => void;
39
- onFinishHydration: (fn: (state: DataLayerPanelStore) => void) => () => void;
40
- getOptions: () => Partial<import("zustand/middleware").PersistOptions<DataLayerPanelStore, unknown>>;
41
- };
42
46
  }, "setState"> & {
43
- setState(nextStateOrUpdater: DataLayerPanelStore | Partial<DataLayerPanelStore> | ((state: WritableDraft<DataLayerPanelStore>) => void), shouldReplace?: boolean | undefined, action?: string | {
47
+ setState(nextStateOrUpdater: DataLayerPanelStore | Partial<DataLayerPanelStore> | ((state: {
48
+ isOpen: boolean;
49
+ userSettings: {
50
+ isTagsVisible: boolean;
51
+ isTagsFromDocumentVisible: boolean;
52
+ isTagsFromSelectionVisible: boolean;
53
+ isWorkOrdersVisible: boolean;
54
+ isWorkOrdersFromDocumentVisible: boolean;
55
+ isWorkOrdersFromSelectionVisible: boolean;
56
+ isEquipmentsVisible: boolean;
57
+ isEquipmentsFromDocumentVisible: boolean;
58
+ isEquipmentsFromSelectionVisible: boolean;
59
+ isIocAnnotationsVisible: boolean;
60
+ isDataFromStidAnnoDetails: boolean;
61
+ };
62
+ togglePanel: () => void;
63
+ toggleTags: () => void;
64
+ toggleTagsFromDocumentVisible: () => void;
65
+ toggleTagsFromSelectionVisible: () => void;
66
+ toggleWorkOrders: () => void;
67
+ toggleWorkOrdersFromDocumentVisible: () => void;
68
+ toggleWorkOrdersFromSelectionVisible: () => void;
69
+ toggleEquipments: () => void;
70
+ toggleEquipmentsFromDocumentVisible: () => void;
71
+ toggleEquipmentsFromSelectionVisible: () => void;
72
+ setEquipmentsForEcm: () => void;
73
+ toggleIocAnnotations: () => void;
74
+ setIsDataFromStidAnnoDetails: (value: boolean) => void;
75
+ }) => void), shouldReplace?: boolean | undefined, action?: string | {
44
76
  type: string;
45
77
  } | undefined): void;
46
78
  }>;
@@ -1,13 +1,16 @@
1
+ import { StoreApi, UseBoundStore } from 'zustand';
1
2
  import { LeftPanelNavigationStore } from './leftPanelNavigation.store.types';
2
- export declare const useLeftPanelNavigationStore: import("zustand").UseBoundStore<Omit<Omit<import("zustand").StoreApi<LeftPanelNavigationStore>, "subscribe"> & {
3
- subscribe: {
4
- (listener: (selectedState: LeftPanelNavigationStore, previousSelectedState: LeftPanelNavigationStore) => void): () => void;
5
- <U>(selector: (state: LeftPanelNavigationStore) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
6
- equalityFn?: ((a: U, b: U) => boolean) | undefined;
7
- fireImmediately?: boolean;
8
- } | undefined): () => void;
9
- };
10
- }, "setState"> & {
11
- setState(nextStateOrUpdater: LeftPanelNavigationStore | Partial<LeftPanelNavigationStore> | ((state: import("immer").WritableDraft<LeftPanelNavigationStore>) => void), shouldReplace?: boolean | undefined): void;
12
- }>;
3
+ /**
4
+ * IMPORTANT: Explicit type annotation required for rollup builds with useLegacyTypescriptPlugin: false
5
+ *
6
+ * Without explicit type, TypeScript infers the full type including Immer's internal types like
7
+ * WritableNonArrayDraft which use complex generics that rollup's @rollup/plugin-typescript cannot
8
+ * "name" in generated .d.ts files, causing TS4023 errors.
9
+ *
10
+ * Trade-off: UseBoundStore<StoreApi<T>> removes subscribeWithSelector's enhanced subscribe(selector, listener)
11
+ * signature, leaving only the base subscribe(listener). Store still fully functional via hook and .getState().
12
+ *
13
+ * Stores NOT exported from public API (index.ts) can omit this explicit type and preserve middleware signatures.
14
+ */
15
+ export declare const useLeftPanelNavigationStore: UseBoundStore<StoreApi<LeftPanelNavigationStore>>;
13
16
  export declare function getLeftPanelNavigationState(): LeftPanelNavigationStore;