Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .changeset/good-ghosts-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
"@itwin/unified-selection": minor
---

Expose `CLEAR_SELECTION_STORAGE_SOURCE` constant that is used as selection change event source when selection storage is cleared. This should allow consumers to detect when selection change happened due to selection storage being cleared.

```ts
import { createStorage, CLEAR_SELECTION_STORAGE_SOURCE } from "@itwin/unified-selection";

const storage = createStorage();
storage.selectionChangeEvent.addListener((args) => {
if (args.source === CLEAR_SELECTION_STORAGE_SOURCE) {
// ignore change if it was caused by clearing selection storage
}
// handle selection change
});

// this will trigger the `selectionChangeEvent` with `{ source: CLEAR_SELECTION_STORAGE_SOURCE }`
storage.clearStorage({ imodelKey: imodel.key });
```
3 changes: 3 additions & 0 deletions packages/unified-selection/api/unified-selection.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ interface CachingHiliteSetProviderProps {
selectionStorage: SelectionStorage;
}

// @public
export const CLEAR_SELECTION_STORAGE_SOURCE = "Unified selection storage: clear";

// @public
export function computeSelection(props: ComputeSelectionProps): AsyncIterableIterator<SelectableInstanceKey>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ sep=;
Release Tag;API Item Type;API Item Name
public;interface;CachingHiliteSetProvider
deprecated;interface;CachingHiliteSetProvider
public;const;CLEAR_SELECTION_STORAGE_SOURCE
public;function;computeSelection
public;function;createCachingHiliteSetProvider
deprecated;function;createCachingHiliteSetProvider
Expand Down
10 changes: 9 additions & 1 deletion packages/unified-selection/src/test/SelectionStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

import { beforeEach, describe, expect, it, vi } from "vitest";
import { SelectableInstanceKey, Selectables } from "../unified-selection/Selectable.js";
import { createStorage, SelectionStorage } from "../unified-selection/SelectionStorage.js";
import {
CLEAR_SELECTION_STORAGE_SOURCE,
createStorage,
SelectionStorage,
} from "../unified-selection/SelectionStorage.js";
import { createSelectableInstanceKey } from "./_helpers/SelectablesCreator.js";

const generateSelection = (): SelectableInstanceKey[] => {
Expand Down Expand Up @@ -36,6 +40,10 @@ describe("SelectionStorage", () => {
selectionStorage.clearStorage({ imodelKey });
expect(Selectables.isEmpty(selectionStorage.getSelection({ imodelKey }))).toBe(true);
expect(listenerSpy, "Expected selectionChange.onSelectionChange to be called").toHaveBeenCalledOnce();
expect(listenerSpy).toHaveBeenCalledWith(
expect.objectContaining({ source: CLEAR_SELECTION_STORAGE_SOURCE }),
selectionStorage,
);
});
});

Expand Down
1 change: 1 addition & 0 deletions packages/unified-selection/src/unified-selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export {
StorageSelectionChangeEventArgs,
StorageSelectionChangesListener,
} from "./unified-selection/SelectionChangeEvent.js";
export { CLEAR_SELECTION_STORAGE_SOURCE } from "./unified-selection/SelectionStorage.js";
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { eachValueFrom } from "rxjs-for-await";
import { ECClassHierarchyInspector, ECSqlQueryExecutor } from "@itwin/presentation-shared";
import { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from "./HiliteSetProvider.js";
import { StorageSelectionChangeEventArgs } from "./SelectionChangeEvent.js";
import { IMODEL_CLOSE_SELECTION_CLEAR_SOURCE, SelectionStorage } from "./SelectionStorage.js";
import { CLEAR_SELECTION_STORAGE_SOURCE, SelectionStorage } from "./SelectionStorage.js";

/**
* Props for creating an `IModelHiliteSetProvider` instance.
Expand Down Expand Up @@ -81,7 +81,7 @@ class IModelHiliteSetProviderImpl implements IModelHiliteSetProvider {
this._removeListener = this._selectionStorage.selectionChangeEvent.addListener(
(args: StorageSelectionChangeEventArgs) => {
this._cache.delete(args.imodelKey);
if (args.changeType === "clear" && args.source === IMODEL_CLOSE_SELECTION_CLEAR_SOURCE) {
if (args.changeType === "clear" && args.source === CLEAR_SELECTION_STORAGE_SOURCE) {
this._hiliteSetProviders.delete(args.imodelKey);
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,11 @@ export function createStorage(): SelectionStorage {
return new SelectionStorageImpl();
}

/** @internal */
export const IMODEL_CLOSE_SELECTION_CLEAR_SOURCE = "Unified selection storage: clear";
/**
* The source name used when selection change is caused by clearing the selection storage. Used when change is performed by `clearStorage`.
* @public
*/
export const CLEAR_SELECTION_STORAGE_SOURCE = "Unified selection storage: clear";

class SelectionStorageImpl implements SelectionStorage {
private _storage = new Map<string, MultiLevelSelectablesContainer>();
Expand Down Expand Up @@ -170,7 +173,7 @@ class SelectionStorageImpl implements SelectionStorage {

public clearStorage(props: IModelKeyProp): void {
const imodelKey = getIModelKey(props);
this.clearSelection({ source: IMODEL_CLOSE_SELECTION_CLEAR_SOURCE, imodelKey });
this.clearSelection({ source: CLEAR_SELECTION_STORAGE_SOURCE, imodelKey });
this._storage.delete(imodelKey);
Comment thread
saskliutas marked this conversation as resolved.
}

Expand Down
Loading