@itwin/saved-views-react 0.4.1 → 0.6.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.
@@ -1,3 +1,10 @@
1
1
  import { type Viewport } from "@itwin/core-frontend";
2
- /** Generates Saved View thumbnail based on what is currently visible in the {@linkcode viewport}. */
2
+ /**
3
+ * Generates Saved View thumbnail based on what is currently displayed on the {@linkcode viewport}.
4
+ * @returns base64-encoded URL string
5
+ *
6
+ * @example
7
+ * const thumbnail = captureSavedViewThumbnail(viewport);
8
+ * console.log(thumbnail); // "data:image/png;base64,iVBORw0KGoAAAANSUhEUg..."
9
+ */
3
10
  export declare function captureSavedViewThumbnail(viewport: Viewport, width?: number, height?: number): string | undefined;
@@ -1,6 +1,13 @@
1
1
  import { getCenteredViewRect, imageBufferToCanvas } from "@itwin/core-frontend";
2
2
  import { Point2d } from "@itwin/core-geometry";
3
- /** Generates Saved View thumbnail based on what is currently visible in the {@linkcode viewport}. */
3
+ /**
4
+ * Generates Saved View thumbnail based on what is currently displayed on the {@linkcode viewport}.
5
+ * @returns base64-encoded URL string
6
+ *
7
+ * @example
8
+ * const thumbnail = captureSavedViewThumbnail(viewport);
9
+ * console.log(thumbnail); // "data:image/png;base64,iVBORw0KGoAAAANSUhEUg..."
10
+ */
4
11
  export function captureSavedViewThumbnail(viewport, width = 280, height = 200) {
5
12
  const thumbnail = getThumbnail(viewport, width, height);
6
13
  if (!thumbnail) {
@@ -1,3 +1,32 @@
1
1
  import { type IModelConnection, type ViewState } from "@itwin/core-frontend";
2
- import { type SavedViewRepresentation } from "@itwin/saved-views-client";
3
- export declare function createViewState(iModel: IModelConnection, savedViewRsp: SavedViewRepresentation, useHiddenModelsAndCategories?: boolean): Promise<ViewState | undefined>;
2
+ import { ViewData } from "@itwin/saved-views-client";
3
+ export interface ViewStateCreateSettings {
4
+ /**
5
+ * Normally {@link createViewState} function invokes and awaits {@linkcode ViewState.load} method before returning.
6
+ * You may skip this step if you intend to perform it later.
7
+ * @default false
8
+ *
9
+ * @example
10
+ * const viewState = await createViewState(iModel, savedView.viewdata, { skipViewStateLoad: true });
11
+ * viewState.categorySelector.addCategories("<additional_category_id>");
12
+ * await viewState.load();
13
+ */
14
+ skipViewStateLoad?: boolean | undefined;
15
+ /**
16
+ * How to handle visibility of models and categories that exist in iModel but are not captured in Saved View data.
17
+ * @default "hidden"
18
+ */
19
+ modelAndCategoryVisibilityFallback?: "visible" | "hidden" | undefined;
20
+ }
21
+ /**
22
+ * Creates {@link ViewState} object out of Saved View data. It provides a lower-level access to view data for advanced
23
+ * use.
24
+ *
25
+ * @example
26
+ * const viewState = await createViewState(iModel, savedViewData.viewData);
27
+ * await applySavedView(iModel, viewport, savedViewData, { viewState });
28
+ *
29
+ * // The two lines above are equivalent to
30
+ * await applySavedView(iModel, viewport, savedViewData);
31
+ */
32
+ export declare function createViewState(iModel: IModelConnection, viewData: ViewData, settings?: ViewStateCreateSettings): Promise<ViewState>;
@@ -8,22 +8,35 @@ import { isViewDataITwin3d, isViewDataITwinDrawing, isViewDataITwinSheet, } from
8
8
  import { getMissingCategories, getMissingModels } from "./captureSavedViewData.js";
9
9
  import { extractClipVectors } from "./translation/clipVectorsExtractor.js";
10
10
  import { extractDisplayStyle, extractDisplayStyle3d } from "./translation/displayStyleExtractor.js";
11
- export async function createViewState(iModel, savedViewRsp, useHiddenModelsAndCategories = true) {
12
- const viewState = await createViewStateVariant(iModel, savedViewRsp);
13
- if (useHiddenModelsAndCategories) {
14
- await applyHiddenModelsAndCategories(iModel, viewState, savedViewRsp);
11
+ /**
12
+ * Creates {@link ViewState} object out of Saved View data. It provides a lower-level access to view data for advanced
13
+ * use.
14
+ *
15
+ * @example
16
+ * const viewState = await createViewState(iModel, savedViewData.viewData);
17
+ * await applySavedView(iModel, viewport, savedViewData, { viewState });
18
+ *
19
+ * // The two lines above are equivalent to
20
+ * await applySavedView(iModel, viewport, savedViewData);
21
+ */
22
+ export async function createViewState(iModel, viewData, settings = {}) {
23
+ const viewState = await createViewStateVariant(iModel, viewData);
24
+ if (settings.modelAndCategoryVisibilityFallback === "visible") {
25
+ await unhideNewModelsAndCategories(iModel, viewState, viewData);
26
+ }
27
+ if (!settings.skipViewStateLoad) {
28
+ await viewState.load();
15
29
  }
16
- await viewState.load();
17
30
  return viewState;
18
31
  }
19
- async function createViewStateVariant(iModel, savedViewRsp) {
20
- if (isViewDataITwinDrawing(savedViewRsp.savedViewData)) {
21
- return createDrawingViewState(iModel, savedViewRsp.savedViewData.itwinDrawingView);
32
+ async function createViewStateVariant(iModel, savedViewData) {
33
+ if (isViewDataITwinDrawing(savedViewData)) {
34
+ return createDrawingViewState(iModel, savedViewData.itwinDrawingView);
22
35
  }
23
- if (isViewDataITwinSheet(savedViewRsp.savedViewData)) {
24
- return createSheetViewState(iModel, savedViewRsp.savedViewData.itwinSheetView);
36
+ if (isViewDataITwinSheet(savedViewData)) {
37
+ return createSheetViewState(iModel, savedViewData.itwinSheetView);
25
38
  }
26
- return createSpatialViewState(iModel, savedViewRsp.savedViewData.itwin3dView);
39
+ return createSpatialViewState(iModel, savedViewData.itwin3dView);
27
40
  }
28
41
  async function createSpatialViewState(iModel, viewData) {
29
42
  const seedViewState = await fetchIModelViewData(iModel, SpatialViewState.classFullName);
@@ -217,29 +230,29 @@ async function getDefaultViewIdFromClassName(iModel, viewClassName) {
217
230
  function cloneCode({ spec, scope, value }) {
218
231
  return { spec, scope, value };
219
232
  }
220
- async function applyHiddenModelsAndCategories(iModel, viewState, savedViewRsp) {
221
- if (isViewDataITwin3d(savedViewRsp.savedViewData)) {
233
+ async function unhideNewModelsAndCategories(iModel, viewState, savedViewData) {
234
+ if (isViewDataITwin3d(savedViewData)) {
222
235
  if (!viewState.isSpatialView()) {
223
236
  return;
224
237
  }
225
- const savedViewData = savedViewRsp.savedViewData.itwin3dView;
226
- if (!savedViewData.categories?.disabled || !savedViewData.models?.disabled) {
238
+ const viewData = savedViewData.itwin3dView;
239
+ if (!viewData.categories?.disabled || !viewData.models?.disabled) {
227
240
  return;
228
241
  }
229
242
  const [visibleCategories, visibleModels] = await Promise.all([
230
- getMissingCategories(iModel, new Set(savedViewData.categories.disabled)),
231
- getMissingModels(iModel, new Set(savedViewData.models.disabled)),
243
+ getMissingCategories(iModel, new Set(viewData.categories.disabled)),
244
+ getMissingModels(iModel, new Set(viewData.models.disabled)),
232
245
  ]);
233
246
  viewState.categorySelector.addCategories(visibleCategories);
234
247
  viewState.modelSelector.addModels(visibleModels);
235
248
  return;
236
249
  }
237
- const savedViewData = isViewDataITwinDrawing(savedViewRsp.savedViewData)
238
- ? savedViewRsp.savedViewData.itwinDrawingView
239
- : savedViewRsp.savedViewData.itwinSheetView;
240
- if (!savedViewData.categories?.disabled) {
250
+ const viewData = isViewDataITwinDrawing(savedViewData)
251
+ ? savedViewData.itwinDrawingView
252
+ : savedViewData.itwinSheetView;
253
+ if (!viewData.categories?.disabled) {
241
254
  return;
242
255
  }
243
- const visibleCategories = await getMissingCategories(iModel, new Set(savedViewData.categories.disabled));
256
+ const visibleCategories = await getMissingCategories(iModel, new Set(viewData.categories.disabled));
244
257
  viewState.categorySelector.addCategories(visibleCategories);
245
258
  }
@@ -1,6 +1,3 @@
1
1
  export { createSavedViewOptions, type CreateSavedViewOptionsParams } from "./SavedViewTile/SavedViewOptions.js";
2
2
  export { SavedViewsExpandableBlockWidget } from "./SavedViewsWidget/SavedViewsExpandableBlockWidget.js";
3
3
  export { SavedViewsFolderWidget } from "./SavedViewsWidget/SavedViewsFolderWidget.js";
4
- export { applyExtensionsToViewport } from "./translation/SavedViewTranslation.js";
5
- export { createViewState } from "./createViewState.js";
6
- export { ModelCategoryOverrideProvider } from "./ModelCategoryOverrideProvider.js";
@@ -5,6 +5,3 @@
5
5
  export { createSavedViewOptions } from "./SavedViewTile/SavedViewOptions.js";
6
6
  export { SavedViewsExpandableBlockWidget } from "./SavedViewsWidget/SavedViewsExpandableBlockWidget.js";
7
7
  export { SavedViewsFolderWidget } from "./SavedViewsWidget/SavedViewsFolderWidget.js";
8
- export { applyExtensionsToViewport } from "./translation/SavedViewTranslation.js";
9
- export { createViewState } from "./createViewState.js";
10
- export { ModelCategoryOverrideProvider } from "./ModelCategoryOverrideProvider.js";
package/lib/index.d.ts CHANGED
@@ -4,11 +4,13 @@ export { SavedViewOptions } from "./SavedViewTile/SavedViewOptions.js";
4
4
  export { SavedViewTile } from "./SavedViewTile/SavedViewTile.js";
5
5
  export { useSavedViewTileContext, type SavedViewTileContext } from "./SavedViewTile/SavedViewTileContext.js";
6
6
  export { ITwinSavedViewsClient } from "./SavedViewsClient/ITwinSavedViewsClient.js";
7
- export type { CreateGroupParams, CreateSavedViewParams, CreateTagParams, DeleteGroupParams, DeleteSavedViewParams, DeleteTagParams, GetSavedViewInfoParams, GetSingularSavedViewParams, GetThumbnailUrlParams, SavedViewInfo, SavedViewsClient, UpdateGroupParams, UpdateSavedViewParams, UpdateTagParams, UploadThumbnailParams, } from "./SavedViewsClient/SavedViewsClient.js";
7
+ export type { CreateGroupParams, CreateSavedViewParams, CreateTagParams, DeleteGroupParams, DeleteSavedViewParams, DeleteTagParams, GetAllGroupsParams, GetAllSavedViewsParams, GetAllTagsParams, GetSavedViewParams, GetThumbnailUrlParams, SavedViewsClient, UpdateGroupParams, UpdateSavedViewParams, UpdateTagParams, UploadThumbnailParams, } from "./SavedViewsClient/SavedViewsClient.js";
8
8
  export { SavedViewsContextProvider, type SavedViewsContext } from "./SavedViewsContext.js";
9
9
  export { StickyExpandableBlock } from "./StickyExpandableBlock/StickyExpandableBlock.js";
10
10
  export { TileGrid } from "./TileGrid/TileGrid.js";
11
+ export { applySavedView, type ApplySavedViewSettings } from "./applySavedView.js";
11
12
  export { captureSavedViewData } from "./captureSavedViewData.js";
12
13
  export { captureSavedViewThumbnail } from "./captureSavedViewThumbnail.js";
14
+ export { createViewState, type ViewStateCreateSettings } from "./createViewState.js";
13
15
  export { defaultLocalization, type LocalizationStrings } from "./localization.js";
14
16
  export { useSavedViews, type SavedViewActions } from "./useSavedViews.js";
package/lib/index.js CHANGED
@@ -10,7 +10,9 @@ export { ITwinSavedViewsClient } from "./SavedViewsClient/ITwinSavedViewsClient.
10
10
  export { SavedViewsContextProvider } from "./SavedViewsContext.js";
11
11
  export { StickyExpandableBlock } from "./StickyExpandableBlock/StickyExpandableBlock.js";
12
12
  export { TileGrid } from "./TileGrid/TileGrid.js";
13
+ export { applySavedView } from "./applySavedView.js";
13
14
  export { captureSavedViewData } from "./captureSavedViewData.js";
14
15
  export { captureSavedViewThumbnail } from "./captureSavedViewThumbnail.js";
16
+ export { createViewState } from "./createViewState.js";
15
17
  export { defaultLocalization } from "./localization.js";
16
18
  export { useSavedViews } from "./useSavedViews.js";
@@ -1,7 +1,6 @@
1
1
  import type { Id64Array } from "@itwin/core-bentley";
2
2
  import type { CategorySelectorProps, DisplayStyle3dProps, DisplayStyleProps, EmphasizeElementsProps, ModelSelectorProps, SectionDrawingViewProps, SheetProps, SpatialViewDefinitionProps, ViewDefinition2dProps } from "@itwin/core-common";
3
3
  import type { Range3dProps } from "@itwin/core-geometry";
4
- import type { ModelCategoryOverrideProviderProps } from "../ModelCategoryOverrideProvider.js";
5
4
  export interface LegacySavedView3d extends LegacySavedViewBase {
6
5
  displayStyleProps: DisplayStyle3dProps;
7
6
  modelSelectorProps: ModelSelectorProps;
@@ -33,7 +32,6 @@ export interface LegacySavedViewBase {
33
32
  thumbnail?: string;
34
33
  categorySelectorProps: CategorySelectorProps;
35
34
  emphasizeElementsProps?: EmphasizeElementsProps;
36
- visibilityOverrideProps?: ModelCategoryOverrideProviderProps;
37
35
  tags?: LegacyTag[];
38
36
  hiddenCategories?: Id64Array;
39
37
  extensions?: Map<string, string>;
@@ -1,13 +1,21 @@
1
1
  import { type Viewport } from "@itwin/core-frontend";
2
2
  export interface ExtensionHandler {
3
3
  extensionName: string;
4
- onViewApply: (extensionData: string, vp: Viewport) => Promise<void>;
5
- }
6
- /**
7
- * Collection of default extension handlers
8
- */
9
- export declare class SavedViewsExtensionHandlers {
10
- static EmphasizeElements: ExtensionHandler;
11
- static PerModelCategoryVisibility: ExtensionHandler;
12
- static VisibilityOverride: ExtensionHandler;
4
+ apply: (extensionData: string, viewport: Viewport) => void;
5
+ reset: (viewport: Viewport) => void;
6
+ capture: (viewport: Viewport) => string | undefined;
13
7
  }
8
+ export declare const extensionHandlers: {
9
+ emphasizeElements: {
10
+ extensionName: string;
11
+ apply: (extensionData: string, viewport: Viewport) => void;
12
+ reset: (viewport: Viewport) => void;
13
+ capture: (viewport: Viewport) => string | undefined;
14
+ };
15
+ perModelCategoryVisibility: {
16
+ extensionName: string;
17
+ apply: (extensionData: string, viewport: Viewport) => void;
18
+ reset: (viewport: Viewport) => void;
19
+ capture: (viewport: Viewport) => string | undefined;
20
+ };
21
+ };
@@ -1,42 +1,53 @@
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
+ *--------------------------------------------------------------------------------------------*/
1
5
  import { EmphasizeElements, PerModelCategoryVisibility } from "@itwin/core-frontend";
2
- import { ModelCategoryOverrideProvider } from "../ModelCategoryOverrideProvider.js";
3
- import { extractEmphasizeElements, extractPerModelCategoryVisibility, extractVisibilityOverride, } from "./extensionExtractor.js";
4
- /**
5
- * Collection of default extension handlers
6
- */
7
- export class SavedViewsExtensionHandlers {
8
- static EmphasizeElements = {
6
+ import { extractEmphasizeElements, extractPerModelCategoryVisibility } from "./extensionExtractor.js";
7
+ export const extensionHandlers = {
8
+ emphasizeElements: {
9
9
  extensionName: "EmphasizeElements",
10
- onViewApply: async (extensionData, vp) => {
10
+ apply: (extensionData, viewport) => {
11
11
  if (extensionData) {
12
12
  const props = extractEmphasizeElements(extensionData);
13
13
  if (props !== undefined) {
14
- EmphasizeElements.getOrCreate(vp).fromJSON(props, vp);
14
+ EmphasizeElements.getOrCreate(viewport).fromJSON(props, viewport);
15
15
  }
16
16
  }
17
17
  },
18
- };
19
- static PerModelCategoryVisibility = {
18
+ reset: (viewport) => {
19
+ if (EmphasizeElements.get(viewport)) {
20
+ EmphasizeElements.clear(viewport);
21
+ viewport.isFadeOutActive = false;
22
+ }
23
+ },
24
+ capture: (viewport) => {
25
+ const emphasizeElementsProps = EmphasizeElements.get(viewport)?.toJSON(viewport);
26
+ return emphasizeElementsProps ? JSON.stringify({ emphasizeElementsProps }) : undefined;
27
+ },
28
+ },
29
+ perModelCategoryVisibility: {
20
30
  extensionName: "PerModelCategoryVisibility",
21
- onViewApply: async (extensionData, vp) => {
31
+ apply: (extensionData, viewport) => {
22
32
  const props = extractPerModelCategoryVisibility(extensionData) ?? [];
23
- vp.perModelCategoryVisibility.clearOverrides();
24
33
  for (const override of props) {
25
- vp.perModelCategoryVisibility.setOverride(override.modelId, override.categoryId, override.visible
34
+ viewport.perModelCategoryVisibility.setOverride(override.modelId, override.categoryId, override.visible
26
35
  ? PerModelCategoryVisibility.Override.Show
27
36
  : PerModelCategoryVisibility.Override.Hide);
28
37
  }
29
38
  },
30
- };
31
- static VisibilityOverride = {
32
- extensionName: "VisibilityOverride",
33
- onViewApply: async (extensionData, vp) => {
34
- if (extensionData) {
35
- const props = extractVisibilityOverride(extensionData);
36
- if (props !== undefined) {
37
- ModelCategoryOverrideProvider.getOrCreate(vp).fromJSON(props);
38
- }
39
+ reset: (viewport) => {
40
+ viewport.perModelCategoryVisibility.clearOverrides();
41
+ },
42
+ capture: (viewport) => {
43
+ if (!viewport.view.isSpatialView()) {
44
+ return undefined;
45
+ }
46
+ const props = [];
47
+ for (const { modelId, categoryId, visible } of viewport.perModelCategoryVisibility) {
48
+ props.push({ modelId, categoryId, visible });
39
49
  }
50
+ return props.length > 0 ? JSON.stringify({ perModelCategoryVisibilityProps: props }) : undefined;
40
51
  },
41
- };
42
- }
52
+ },
53
+ };
@@ -14,9 +14,18 @@ const viewFlagMappings = [
14
14
  extractBoolean("hiddenEdges", "hidEdges"),
15
15
  extractBoolean("shadows"),
16
16
  extractBoolean("clipVolume", "clipVol"),
17
+ extractBoolean("hiddenLineMaterialColors", "hlMatColors"),
17
18
  extractBoolean("monochrome"),
18
19
  extractBoolean("backgroundMap"),
19
20
  extractBoolean("ambientOcclusion"),
21
+ extractBoolean("acs"),
22
+ extractBoolean("thematicDisplay"),
23
+ extractBoolean("wiremesh"),
24
+ extractBoolean("forceSurfaceDiscard"),
25
+ extractBoolean("noWhiteOnWhiteReversal"),
26
+ extractBoolean("noSolarLight"),
27
+ extractBoolean("noSourceLights"),
28
+ extractBoolean("noCameraLights"),
20
29
  ];
21
30
  const viewFlagLegacyMappings = [
22
31
  extractNumber("renderMode"),
@@ -33,9 +42,18 @@ const viewFlagLegacyMappings = [
33
42
  extractBoolean("hidEdges", "hiddenEdges"),
34
43
  extractBoolean("shadows"),
35
44
  extractBoolean("clipVol", "clipVolume"),
45
+ extractBoolean("hlMatColors", "hiddenLineMaterialColors"),
36
46
  extractBoolean("monochrome"),
37
47
  extractBoolean("backgroundMap"),
38
48
  extractBoolean("ambientOcclusion"),
49
+ extractBoolean("acs"),
50
+ extractBoolean("thematicDisplay"),
51
+ extractBoolean("wiremesh"),
52
+ extractBoolean("forceSurfaceDiscard"),
53
+ extractBoolean("noWhiteOnWhiteReversal"),
54
+ extractBoolean("noSolarLight"),
55
+ extractBoolean("noSourceLights"),
56
+ extractBoolean("noCameraLights"),
39
57
  ];
40
58
  const planarClipMaskMappings = [
41
59
  extractNumber("mode"),
@@ -284,6 +302,56 @@ const hiddenLineSettingsLegacyMappings = [
284
302
  extractObject(hiddenLineStyleLegacyMappings, "hidden"),
285
303
  extractNumber("transThreshold", "transparencyThreshold"),
286
304
  ];
305
+ const keyColorPropsMappings = [
306
+ extractNumber("value"),
307
+ extractColor("color"),
308
+ ];
309
+ const keyColorPropsLegacyMappings = [
310
+ extractNumber("value"),
311
+ extractColorLegacy("color"),
312
+ ];
313
+ const thematicGradientSettingsPropsMappings = [
314
+ extractNumber("mode"),
315
+ extractNumber("stepCount"),
316
+ extractColor("marginColor"),
317
+ extractNumber("colorScheme"),
318
+ extractArray(keyColorPropsMappings, "customKeys"),
319
+ extractNumber("colorMix"),
320
+ extractNumber("transparencyMode"),
321
+ ];
322
+ const thematicGradientSettingsPropsLegacyMappings = [
323
+ extractNumber("mode"),
324
+ extractNumber("stepCount"),
325
+ extractColorLegacy("marginColor"),
326
+ extractNumber("colorScheme"),
327
+ extractArray(keyColorPropsLegacyMappings, "customKeys"),
328
+ extractNumber("colorMix"),
329
+ extractNumber("transparencyMode"),
330
+ ];
331
+ const thematicDisplaySensorPropsMappings = [
332
+ extractSimpleArray(simpleTypeOf("number"), "position"),
333
+ extractNumber("value"),
334
+ ];
335
+ const thematicDisplaySensorSettingsPropsMappings = [
336
+ extractArray(thematicDisplaySensorPropsMappings, "sensors"),
337
+ extractNumber("distanceCutoff"),
338
+ ];
339
+ const thematicDisplaySettingsMappings = [
340
+ extractNumber("displayMode"),
341
+ extractObject(thematicGradientSettingsPropsMappings, "gradientSettings"),
342
+ extractSimpleArray(simpleTypeOf("number"), "range"),
343
+ extractSimpleArray(simpleTypeOf("number"), "axis"),
344
+ extractSimpleArray(simpleTypeOf("number"), "sunDirection"),
345
+ extractObject(thematicDisplaySensorSettingsPropsMappings, "gradientSettings"),
346
+ ];
347
+ const thematicDisplaySettingsLegacyMappings = [
348
+ extractNumber("displayMode"),
349
+ extractObject(thematicGradientSettingsPropsLegacyMappings, "gradientSettings"),
350
+ extractSimpleArray(simpleTypeOf("number"), "range"),
351
+ extractSimpleArray(simpleTypeOf("number"), "axis"),
352
+ extractSimpleArray(simpleTypeOf("number"), "sunDirection"),
353
+ extractObject(thematicDisplaySensorSettingsPropsMappings, "gradientSettings"),
354
+ ];
287
355
  const cutStyleMappings = [
288
356
  extractObject(viewFlagOverridesMapping, "viewflags"),
289
357
  extractObject(hiddenLineSettingsMappings, "hiddenLine"),
@@ -475,6 +543,8 @@ const displayStyle3dMapping = [
475
543
  extractObject(solarShadowMappings, "solarShadows"),
476
544
  extractObject(lightsMappings, "lights"),
477
545
  extractPlainTypedMap(planProjectionSettingsMappings, simpleTypeOf("string"), "planProjections"),
546
+ extractObject(thematicDisplaySettingsMappings, "thematic"),
547
+ extractObject(hiddenLineSettingsMappings, "hiddenLine", "hline"),
478
548
  ];
479
549
  const displayStyle3dLegacyMapping = [
480
550
  ...displayStylesLegacyMapping,
@@ -483,6 +553,8 @@ const displayStyle3dLegacyMapping = [
483
553
  extractObject(solarShadowLegacyMappings, "solarShadows"),
484
554
  extractObject(lightsLegacyMappings, "lights"),
485
555
  extractPlainTypedMap(planProjectionSettingsMappings, simpleTypeOf("string"), "planProjections"),
556
+ extractObject(thematicDisplaySettingsLegacyMappings, "thematic"),
557
+ extractObject(hiddenLineSettingsLegacyMappings, "hline", "hiddenLine"),
486
558
  ];
487
559
  /**
488
560
  * Extracts the display style from a legacy view displayStyle field
@@ -1,5 +1,4 @@
1
1
  import { type EmphasizeElementsProps } from "@itwin/core-common";
2
- import { ModelCategoryOverrideProviderProps } from "../ModelCategoryOverrideProvider.js";
3
2
  import type { PerModelCategoryVisibilityProps } from "./SavedViewTypes.js";
4
3
  /**
5
4
  * Extracts the EmphasizeElementsProps from string data in an extension
@@ -11,8 +10,3 @@ export declare const extractEmphasizeElements: (extensionData: string) => Emphas
11
10
  * @param extensionData
12
11
  */
13
12
  export declare const extractPerModelCategoryVisibility: (extensionData: string) => PerModelCategoryVisibilityProps[];
14
- /**
15
- * Extracts the VisibilityOverrideProps (ie ModelCategoryOverrideProviderProps) from string data in an extension
16
- * @param extensionData
17
- */
18
- export declare const extractVisibilityOverride: (extensionData: string) => ModelCategoryOverrideProviderProps | undefined;
@@ -6,11 +6,6 @@ const appearanceOverrideEmphElemMappings = [
6
6
  extractColor("color"),
7
7
  extractSimpleArray(simpleTypeOf("string"), "ids"),
8
8
  ];
9
- /** Appearance Override type for VisibilityOverrides (ie ModelCategoryOverrideProviderProps) */
10
- const appearanceOverrideVisibOvrMappings = [
11
- extractSimpleArray(simpleTypeOf("string"), "ids"),
12
- extractObject(featureAppearanceMappings, "app"),
13
- ];
14
9
  const emphasizeElementsMapping = [
15
10
  extractSimpleArray(simpleTypeOf("string"), "neverDrawn"),
16
11
  extractSimpleArray(simpleTypeOf("string"), "alwaysDrawn"),
@@ -26,12 +21,6 @@ const perModelCategoryVisibilityMapping = [
26
21
  extractString("categoryId"),
27
22
  extractBoolean("visible"),
28
23
  ];
29
- const visibilityOverrideMapping = [
30
- extractArray(appearanceOverrideVisibOvrMappings, "subCategoryOverrides"),
31
- extractArray(appearanceOverrideVisibOvrMappings, "modelOverrides"),
32
- extractObject(appearanceOverrideVisibOvrMappings, "catEmphasizeOverride"),
33
- extractObject(appearanceOverrideVisibOvrMappings, "modelEmphasizeOverride"),
34
- ];
35
24
  /**
36
25
  * Extracts the EmphasizeElementsProps from string data in an extension
37
26
  * @param extensionData
@@ -64,16 +53,3 @@ export const extractPerModelCategoryVisibility = (extensionData) => {
64
53
  }
65
54
  return outputArray;
66
55
  };
67
- /**
68
- * Extracts the VisibilityOverrideProps (ie ModelCategoryOverrideProviderProps) from string data in an extension
69
- * @param extensionData
70
- */
71
- export const extractVisibilityOverride = (extensionData) => {
72
- const dataObj = JSON.parse(extensionData);
73
- if (dataObj === undefined || dataObj.visibilityOverrideProps === undefined) {
74
- return undefined;
75
- }
76
- const output = {};
77
- applyExtraction(dataObj.visibilityOverrideProps, output, visibilityOverrideMapping);
78
- return output;
79
- };
@@ -1,6 +1,6 @@
1
- import type { ViewData } from "@itwin/saved-views-client";
2
- import type { SavedView, SavedViewGroup, SavedViewTag } from "./SavedView.js";
1
+ import type { SavedView, SavedViewGroup, SavedViewTag, WriteableSavedViewProperties } from "./SavedView.js";
3
2
  import type { SavedViewsClient } from "./SavedViewsClient/SavedViewsClient.js";
3
+ import type { PartialExcept } from "./utils.js";
4
4
  interface UseSavedViewsParams {
5
5
  /** iTwin identifier. */
6
6
  iTwinId: string;
@@ -25,7 +25,7 @@ interface UseSavedViewsResult {
25
25
  actions: SavedViewActions;
26
26
  }
27
27
  export interface SavedViewActions {
28
- submitSavedView: (savedView: string | Partial<SavedView> & Pick<SavedView, "displayName">, savedViewData: ViewData) => Promise<string>;
28
+ submitSavedView: (savedView: SavedViewCreationProps | SavedViewUpdateProps) => Promise<string>;
29
29
  renameSavedView: (savedViewId: string, newName: string | undefined) => void;
30
30
  shareSavedView: (savedViewId: string, share: boolean) => void;
31
31
  deleteSavedView: (savedViewId: string) => void;
@@ -40,11 +40,16 @@ export interface SavedViewActions {
40
40
  removeTag: (savedViewId: string, tagId: string) => void;
41
41
  uploadThumbnail: (savedViewId: string, imageDataUrl: string) => void;
42
42
  }
43
+ type SavedViewCreationProps = PartialExcept<WriteableSavedViewProperties, "displayName" | "viewData">;
44
+ type SavedViewUpdateProps = WriteableSavedViewProperties & {
45
+ id: string;
46
+ };
43
47
  /**
44
48
  * Pulls Saved View data from a store and provides means to update and synchronize the data back to it. Interaction with
45
49
  * the store is performed via {@linkcode SavedViewsClient} interface which could communicate, for instance, with
46
50
  * [iTwin Saved Views API](https://developer.bentley.com/apis/savedviews/overview/) using `ITwinSavedViewsClient`.
47
51
  *
52
+ * @remarks
48
53
  * Note on the current implementation limitations. While the result of the first update action is reflected immediately,
49
54
  * subsequent actions are put in a queue and executed serially. This may cause the UI to feel sluggish when user makes
50
55
  * changes to Saved Views faster than the Saved Views store can be updated.
@@ -1,10 +1,15 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
2
6
  import { useCallback, useEffect, useRef, useState, } from "react";
3
7
  /**
4
8
  * Pulls Saved View data from a store and provides means to update and synchronize the data back to it. Interaction with
5
9
  * the store is performed via {@linkcode SavedViewsClient} interface which could communicate, for instance, with
6
10
  * [iTwin Saved Views API](https://developer.bentley.com/apis/savedviews/overview/) using `ITwinSavedViewsClient`.
7
11
  *
12
+ * @remarks
8
13
  * Note on the current implementation limitations. While the result of the first update action is reflected immediately,
9
14
  * subsequent actions are put in a queue and executed serially. This may cause the UI to feel sluggish when user makes
10
15
  * changes to Saved Views faster than the Saved Views store can be updated.
@@ -66,11 +71,7 @@ export function useSavedViews(args) {
66
71
  providerRef.current.actionQueue = [];
67
72
  void (async () => {
68
73
  try {
69
- const result = await args.client.getSavedViewInfo({
70
- iTwinId: args.iTwinId,
71
- iModelId: args.iModelId,
72
- signal: signal,
73
- });
74
+ const result = await getSavedViewInfo(args.client, args.iTwinId, args.iModelId, signal);
74
75
  if (signal.aborted) {
75
76
  return;
76
77
  }
@@ -118,28 +119,30 @@ function useEvent(handleEvent) {
118
119
  handleEventRef.current = handleEvent;
119
120
  return useCallback((...args) => handleEventRef.current(...args), []);
120
121
  }
122
+ async function getSavedViewInfo(client, iTwinId, iModelId, signal) {
123
+ const args = { iTwinId, iModelId, signal };
124
+ const collectSavedViews = async () => {
125
+ let savedViews = [];
126
+ const iterable = client.getAllSavedViews(args);
127
+ for await (const page of iterable) {
128
+ savedViews = savedViews.concat(page);
129
+ }
130
+ return savedViews;
131
+ };
132
+ const [savedViews, groups, tags] = await Promise.all([
133
+ collectSavedViews(),
134
+ client.getAllGroups(args),
135
+ client.getAllTags(args),
136
+ ]);
137
+ return { savedViews, groups, tags };
138
+ }
121
139
  function createSavedViewActions(iTwinId, iModelId, client, setState, ref, onUpdateInProgress, onUpdateComplete, onUpdateError) {
122
140
  const signal = ref.current.abortController.signal;
123
141
  return {
124
- submitSavedView: actionWrapper(async (savedView, savedViewData) => {
125
- let newSavedView;
126
- if (typeof savedView !== "string" && savedView.id) {
127
- newSavedView = await client.updateSavedView({
128
- // TypeScript cannot tell that `savedView` object contains `id` string without a little help
129
- savedView: { id: savedView.id, ...savedView },
130
- savedViewData,
131
- signal,
132
- });
133
- }
134
- else {
135
- newSavedView = await client.createSavedView({
136
- iTwinId: iTwinId,
137
- iModelId: iModelId,
138
- savedView: typeof savedView === "string" ? { displayName: savedView } : savedView,
139
- savedViewData,
140
- signal,
141
- });
142
- }
142
+ submitSavedView: actionWrapper(async (savedView) => {
143
+ const newSavedView = "id" in savedView
144
+ ? await client.updateSavedView({ savedView, signal })
145
+ : await client.createSavedView({ iTwinId, iModelId, savedView, signal });
143
146
  updateSavedViews((savedViews) => {
144
147
  const entries = Array.from(savedViews.values());
145
148
  entries.push(newSavedView);
package/lib/utils.d.ts CHANGED
@@ -1 +1,2 @@
1
+ export type PartialExcept<T, K extends keyof T> = Partial<Omit<T, K>> & Pick<Required<T>, K>;
1
2
  export declare function trimInputString(string: string): string;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@itwin/saved-views-react",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/iTwin/saved-views.git",
8
8
  "directory": "packages/saved-views-react"
9
9
  },
10
- "homepage": "https://github.com/iTwin/saved-views",
10
+ "homepage": "https://github.com/iTwin/saved-views/tree/master/packages/saved-views-react",
11
11
  "author": {
12
12
  "name": "Bentley Systems, Inc.",
13
13
  "url": "https://www.bentley.com"
@@ -58,10 +58,10 @@
58
58
  "react-dom": "^17.0.0 || ^18.0.0"
59
59
  },
60
60
  "dependencies": {
61
- "@itwin/itwinui-icons-react": "^2.4.0",
61
+ "@itwin/itwinui-icons-react": "^2.9.0",
62
62
  "@itwin/itwinui-react": "^3.8.1",
63
63
  "fuse.js": "^6.6.2",
64
- "@itwin/saved-views-client": "^0.3.0"
64
+ "@itwin/saved-views-client": "^0.4.0"
65
65
  },
66
66
  "scripts": {
67
67
  "build": "run-p build:*",