@itwin/saved-views-react 0.7.0 → 0.9.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.
@@ -123,10 +123,6 @@ export class ITwinSavedViewsClient {
123
123
  return groupResponseToSavedViewGroup(group);
124
124
  }
125
125
  async deleteGroup(args) {
126
- const savedViewPages = this.#client.getAllSavedViewsMinimal({ groupId: args.groupId, signal: args.signal });
127
- for await (const { savedViews } of savedViewPages) {
128
- await Promise.all(savedViews.map(({ id }) => this.#client.deleteSavedView({ savedViewId: id, signal: args.signal })));
129
- }
130
126
  await this.#client.deleteGroup({ groupId: args.groupId, signal: args.signal });
131
127
  }
132
128
  async createTag(args) {
@@ -1,5 +1,6 @@
1
1
  import { ViewChangeOptions, ViewPose, ViewState, type IModelConnection, type Viewport } from "@itwin/core-frontend";
2
2
  import type { SavedViewData } from "./SavedView.js";
3
+ import { type DefaultExtensionHandlersApplyOverrides } from "./translation/SavedViewsExtensionHandlers.js";
3
4
  export interface ApplySavedViewSettings {
4
5
  /**
5
6
  * How to make use of captured {@link ViewState} data. The default behavior is
@@ -65,5 +66,5 @@ type ApplyStrategy = "apply" | "keep";
65
66
  * applySavedView(iModel, viewport2, savedView, { viewState }),
66
67
  * ]);
67
68
  */
68
- export declare function applySavedView(iModel: IModelConnection, viewport: Viewport, savedViewData: SavedViewData, settings?: ApplySavedViewSettings | undefined): Promise<void>;
69
+ export declare function applySavedView(iModel: IModelConnection, viewport: Viewport, savedViewData: SavedViewData, settings?: ApplySavedViewSettings | undefined, overrides?: DefaultExtensionHandlersApplyOverrides): Promise<void>;
69
70
  export {};
@@ -1,10 +1,10 @@
1
1
  /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
- * See LICENSE.md in the project root for license terms and full copyright notice.
4
- *--------------------------------------------------------------------------------------------*/
5
- import { ViewPose, ViewState } from "@itwin/core-frontend";
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { ViewPose, ViewState, } from "@itwin/core-frontend";
6
6
  import { createViewState } from "./createViewState.js";
7
- import { extensionHandlers } from "./translation/SavedViewsExtensionHandlers.js";
7
+ import { extensionHandlers, } from "./translation/SavedViewsExtensionHandlers.js";
8
8
  /**
9
9
  * Updates {@linkcode viewport} state to match captured Saved View.
10
10
  *
@@ -17,7 +17,7 @@ import { extensionHandlers } from "./translation/SavedViewsExtensionHandlers.js"
17
17
  * applySavedView(iModel, viewport2, savedView, { viewState }),
18
18
  * ]);
19
19
  */
20
- export async function applySavedView(iModel, viewport, savedViewData, settings = {}) {
20
+ export async function applySavedView(iModel, viewport, savedViewData, settings = {}, overrides) {
21
21
  if (settings.viewState !== "keep") {
22
22
  // We use "hidden" as the default value for modelAndCategoryVisibilityFallback
23
23
  // because users expect modelSelector.enabled and categorySelector.enabled to
@@ -26,7 +26,9 @@ export async function applySavedView(iModel, viewport, savedViewData, settings =
26
26
  const { modelAndCategoryVisibilityFallback = "hidden" } = settings;
27
27
  const viewState = settings.viewState instanceof ViewState
28
28
  ? settings.viewState
29
- : await createViewState(iModel, savedViewData.viewData, { modelAndCategoryVisibilityFallback });
29
+ : await createViewState(iModel, savedViewData.viewData, {
30
+ modelAndCategoryVisibilityFallback,
31
+ });
30
32
  if (settings.camera instanceof ViewPose) {
31
33
  viewState.applyPose(settings.camera);
32
34
  }
@@ -37,19 +39,29 @@ export async function applySavedView(iModel, viewport, savedViewData, settings =
37
39
  }
38
40
  const extensions = findKnownExtensions(savedViewData.extensions ?? []);
39
41
  if (extensions.emphasis) {
42
+ const override = overrides?.emphasizeElements;
40
43
  if (settings.emphasis !== "keep") {
41
- extensionHandlers.emphasizeElements.reset(viewport);
44
+ override?.reset
45
+ ? override.reset(viewport)
46
+ : extensionHandlers.emphasizeElements.reset(viewport);
42
47
  }
43
48
  if (settings.emphasis === "apply") {
44
- extensionHandlers.emphasizeElements.apply(extensions.emphasis, viewport);
49
+ override?.apply
50
+ ? override.apply(extensions.emphasis, viewport)
51
+ : extensionHandlers.emphasizeElements.apply(extensions.emphasis, viewport);
45
52
  }
46
53
  }
47
54
  if (extensions.perModelCategoryVisibility) {
55
+ const override = overrides?.perModelCategoryVisibility;
48
56
  if (settings.perModelCategoryVisibility !== "keep") {
49
- extensionHandlers.perModelCategoryVisibility.reset(viewport);
57
+ override?.reset
58
+ ? override.reset(viewport)
59
+ : extensionHandlers.perModelCategoryVisibility.reset(viewport);
50
60
  }
51
61
  if (settings.perModelCategoryVisibility === "apply") {
52
- extensionHandlers.perModelCategoryVisibility.apply(extensions.perModelCategoryVisibility, viewport);
62
+ override?.apply
63
+ ? override.apply(extensions.perModelCategoryVisibility, viewport)
64
+ : extensionHandlers.perModelCategoryVisibility.apply(extensions.perModelCategoryVisibility, viewport);
53
65
  }
54
66
  }
55
67
  }
@@ -61,14 +73,16 @@ function findKnownExtensions(extensions) {
61
73
  };
62
74
  for (const extension of extensions) {
63
75
  if (result.emphasis === undefined &&
64
- extension.extensionName === extensionHandlers.emphasizeElements.extensionName) {
76
+ extension.extensionName ===
77
+ extensionHandlers.emphasizeElements.extensionName) {
65
78
  result.emphasis = extension.data;
66
79
  if (result.perModelCategoryVisibility) {
67
80
  break;
68
81
  }
69
82
  }
70
83
  if (result.perModelCategoryVisibility === undefined &&
71
- extension.extensionName === extensionHandlers.perModelCategoryVisibility.extensionName) {
84
+ extension.extensionName ===
85
+ extensionHandlers.perModelCategoryVisibility.extensionName) {
72
86
  result.perModelCategoryVisibility = extension.data;
73
87
  if (result.emphasis) {
74
88
  break;
@@ -1,6 +1,7 @@
1
1
  import { Id64Array } from "@itwin/core-bentley";
2
2
  import type { IModelConnection, Viewport } from "@itwin/core-frontend";
3
3
  import type { SavedViewData } from "./SavedView.js";
4
+ import { type DefaultExtensionHandlersCaptureOverrides } from "./translation/SavedViewsExtensionHandlers.js";
4
5
  interface CaptureSavedViewDataArgs {
5
6
  /** Viewport to capture. */
6
7
  viewport: Viewport;
@@ -14,6 +15,10 @@ interface CaptureSavedViewDataArgs {
14
15
  * @default false
15
16
  */
16
17
  omitPerModelCategoryVisibility?: boolean | undefined;
18
+ /**
19
+ * Overrides for the capture function of default extension handlers .
20
+ */
21
+ overrides?: DefaultExtensionHandlersCaptureOverrides;
17
22
  }
18
23
  /**
19
24
  * Captures current {@link Viewport} state into serializable format. The returned
@@ -19,10 +19,16 @@ import { extractDisplayStyle2dFromLegacy, extractDisplayStyle3dFromLegacy, } fro
19
19
  export async function captureSavedViewData(args) {
20
20
  const extensions = [];
21
21
  if (!args.omitEmphasis) {
22
- extensions.push(extensionHandlers.emphasizeElements);
22
+ extensions.push({
23
+ ...extensionHandlers.emphasizeElements,
24
+ capture: args.overrides?.emphasizeElements?.capture ?? extensionHandlers.emphasizeElements.capture,
25
+ });
23
26
  }
24
27
  if (!args.omitPerModelCategoryVisibility) {
25
- extensions.push(extensionHandlers.perModelCategoryVisibility);
28
+ extensions.push({
29
+ ...extensionHandlers.perModelCategoryVisibility,
30
+ capture: args.overrides?.perModelCategoryVisibility?.capture ?? extensionHandlers.perModelCategoryVisibility.capture,
31
+ });
26
32
  }
27
33
  return {
28
34
  viewData: await createSavedViewVariant(args.viewport),
@@ -5,6 +5,14 @@ export interface ExtensionHandler {
5
5
  reset: (viewport: Viewport) => void;
6
6
  capture: (viewport: Viewport) => string | undefined;
7
7
  }
8
+ export interface DefaultExtensionHandlersApplyOverrides {
9
+ emphasizeElements?: Partial<Pick<ExtensionHandler, "apply" | "reset">>;
10
+ perModelCategoryVisibility?: Partial<Pick<ExtensionHandler, "apply" | "reset">>;
11
+ }
12
+ export interface DefaultExtensionHandlersCaptureOverrides {
13
+ emphasizeElements?: Partial<Pick<ExtensionHandler, "capture">>;
14
+ perModelCategoryVisibility?: Partial<Pick<ExtensionHandler, "capture">>;
15
+ }
8
16
  export declare const extensionHandlers: {
9
17
  emphasizeElements: {
10
18
  extensionName: string;
@@ -1,9 +1,9 @@
1
1
  /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
- * See LICENSE.md in the project root for license terms and full copyright notice.
4
- *--------------------------------------------------------------------------------------------*/
5
- import { EmphasizeElements, PerModelCategoryVisibility } from "@itwin/core-frontend";
6
- import { extractEmphasizeElements, extractPerModelCategoryVisibility } from "./extensionExtractor.js";
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { EmphasizeElements, PerModelCategoryVisibility, } from "@itwin/core-frontend";
6
+ import { extractEmphasizeElements, extractPerModelCategoryVisibility, } from "./extensionExtractor.js";
7
7
  export const extensionHandlers = {
8
8
  emphasizeElements: {
9
9
  extensionName: "EmphasizeElements",
@@ -184,7 +184,7 @@ export interface SavedViewsActions {
184
184
  *
185
185
  * return <MySavedViewsWidget savedViews={savedViews} onOpenSavedView={handleOpenSavedView} />;
186
186
  */
187
- export declare const useSavedViews: ((args: UseSavedViewsArgs) => UseSavedViewsResult) & ((args: UseSavedViewsArgs) => UseSavedViewsResult) & {
187
+ export declare const useSavedViews: ((args: UseSavedViewsArgs) => UseSavedViewsResult) & {
188
188
  /** Suggested initial state of custom Saved View stores. Immutable. */
189
189
  emptyState: SavedViewsState;
190
190
  };
@@ -132,94 +132,6 @@ export const useSavedViews = Object.assign((args) => {
132
132
  },
133
133
  });
134
134
  return useMemo(() => ({ ...events, store: state }), [events, state]);
135
- }, (args) => {
136
- const { iTwinId, iModelId, client } = args;
137
- const [state, setState] = useControlledState(args.state ?? emptyState, args.state, args.setState);
138
- const stateRef = useRef({ iTwinId, iModelId, client, state, setState });
139
- stateRef.current = { iTwinId, iModelId, client, state, setState };
140
- const [events] = useState({
141
- ...createActions(stateRef),
142
- startLoadingData: (callback) => {
143
- const { iTwinId, iModelId, client, setState } = stateRef.current;
144
- const abortController = new AbortController();
145
- const signal = abortController.signal;
146
- const observer = new CustomObserver((savedViewId) => {
147
- void (async () => {
148
- const loadSavedViewData = async () => {
149
- let savedViewData;
150
- try {
151
- savedViewData = await client.getSavedViewDataById({ savedViewId, signal });
152
- }
153
- catch {
154
- savedViewData = undefined;
155
- }
156
- if (savedViewData && !signal.aborted) {
157
- setState((prev) => {
158
- const newState = { ...prev };
159
- newState.savedViewData = new Map(prev.savedViewData);
160
- newState.savedViewData.set(savedViewId, savedViewData);
161
- return newState;
162
- });
163
- }
164
- };
165
- const loadThumbnail = async () => {
166
- let thumbnailUrl;
167
- try {
168
- thumbnailUrl = await client.getThumbnailUrl({ savedViewId, signal });
169
- }
170
- catch {
171
- thumbnailUrl = undefined;
172
- }
173
- if (!signal.aborted) {
174
- setState((prev) => {
175
- const newState = { ...prev };
176
- newState.thumbnails = new Map(prev.thumbnails);
177
- newState.thumbnails.set(savedViewId, thumbnailUrl && _jsx("img", { src: thumbnailUrl }));
178
- return newState;
179
- });
180
- }
181
- };
182
- await Promise.all([loadSavedViewData(), loadThumbnail()]);
183
- })();
184
- });
185
- void (async () => {
186
- try {
187
- const result = await getSavedViewInfo(client, iTwinId, iModelId, signal);
188
- signal.throwIfAborted();
189
- setState((prev) => {
190
- const newState = { ...prev };
191
- newState.savedViews = new Map(prev.savedViews);
192
- result.savedViews.forEach((savedView) => newState.savedViews.set(savedView.savedViewId, savedView));
193
- newState.groups = new Map(prev.groups);
194
- result.groups.forEach((group) => newState.groups.set(group.groupId, group));
195
- newState.tags = new Map(prev.tags);
196
- result.tags.forEach((tag) => newState.tags.set(tag.tagId, tag));
197
- newState.thumbnails = new Map(prev.thumbnails);
198
- result.savedViews
199
- .filter(({ savedViewId }) => !prev.thumbnails.has(savedViewId))
200
- .forEach(({ savedViewId }) => {
201
- newState.thumbnails.set(savedViewId, _jsx(ThumbnailPlaceholder, { savedViewId: savedViewId, observer: observer }));
202
- });
203
- return newState;
204
- });
205
- callback?.();
206
- }
207
- catch (error) {
208
- if (callback) {
209
- callback(error);
210
- }
211
- else {
212
- throw error;
213
- }
214
- }
215
- })();
216
- return () => {
217
- abortController.abort();
218
- observer.disconnect();
219
- };
220
- },
221
- });
222
- return useMemo(() => ({ ...events, store: state }), [events, state]);
223
135
  }, {
224
136
  /** Suggested initial state of custom Saved View stores. Immutable. */
225
137
  emptyState,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/saved-views-react",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -29,12 +29,16 @@
29
29
  "./public"
30
30
  ],
31
31
  "devDependencies": {
32
- "@itwin/core-bentley": "^4.0.6",
33
- "@itwin/core-common": "^4.0.6",
34
- "@itwin/core-frontend": "^4.0.6",
35
- "@itwin/core-geometry": "^4.0.6",
36
- "@testing-library/react": "^12.1.5",
37
- "@types/react": "^17.0.39",
32
+ "@itwin/core-bentley": "^4.10.6",
33
+ "@itwin/core-common": "^4.10.6",
34
+ "@itwin/core-frontend": "^4.10.6",
35
+ "@itwin/core-geometry": "^4.10.6",
36
+ "@testing-library/react": "^16.2.0",
37
+ "@itwin/appui-abstract": "^4.10.6",
38
+ "@itwin/core-orbitgt": "^4.10.6",
39
+ "@itwin/core-quantity": "^4.10.6",
40
+ "@testing-library/dom": "^10.0.0",
41
+ "@types/react": "^18.0.0",
38
42
  "@types/recursive-readdir": "^2.2.2",
39
43
  "@vitejs/plugin-react-swc": "^3.5.0",
40
44
  "@vitest/coverage-v8": "^2.1.4",
@@ -43,25 +47,28 @@
43
47
  "npm-run-all": "^4.1.5",
44
48
  "postcss-cli": "^10.1.0",
45
49
  "postcss-modules": "^6.0.0",
46
- "react": "^17.0.0",
47
- "react-dom": "^17.0.0",
50
+ "react": "^18.0.0",
51
+ "react-dom": "^18.0.0",
48
52
  "recursive-readdir": "^2.2.3",
49
53
  "typescript": "^5.5.4",
50
54
  "vite": "^5.4.11",
51
55
  "vitest": "^2.1.4"
52
56
  },
53
57
  "peerDependencies": {
54
- "@itwin/core-common": "^4.0.6",
55
- "@itwin/core-frontend": "^4.0.6",
56
- "@itwin/core-geometry": "^4.0.6",
57
- "react": "^17.0.0 || ^18.0.0",
58
- "react-dom": "^17.0.0 || ^18.0.0"
58
+ "@itwin/core-common": "^4.10.6",
59
+ "@itwin/core-frontend": "^4.10.6",
60
+ "@itwin/core-geometry": "^4.10.6",
61
+ "@itwin/appui-abstract": "^4.10.6",
62
+ "@itwin/core-orbitgt": "^4.10.6",
63
+ "@itwin/core-quantity": "^4.10.6",
64
+ "react": "^18.0.0",
65
+ "react-dom": "^18.0.0"
59
66
  },
60
67
  "dependencies": {
61
68
  "@itwin/itwinui-icons-react": "^2.9.0",
62
- "@itwin/itwinui-react": "^3.8.1",
69
+ "@itwin/itwinui-react": "^3.15.0",
63
70
  "fuse.js": "^6.6.2",
64
- "@itwin/saved-views-client": "^0.4.0"
71
+ "@itwin/saved-views-client": "^0.5.0"
65
72
  },
66
73
  "scripts": {
67
74
  "build": "run-p build:*",