Skip to content

Commit

Permalink
Use reactivity-API for APIs (#369, #347)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Antonia van Eek <a.vaneek@conterra.de>
Co-authored-by: Arne Vogt <a.vogt@52north.org>
  • Loading branch information
3 people authored Oct 24, 2024
1 parent 377de9f commit e7978a8
Show file tree
Hide file tree
Showing 55 changed files with 893 additions and 1,121 deletions.
26 changes: 26 additions & 0 deletions .changeset/chatty-poets-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
"@open-pioneer/selection": minor
---

Support reactive changes on the `SelectionSource`'s `status` property using the reactivity API.
**Remove** support for the `changed:status"` event on the selection source: use signals instead.

For example, to implement a `SelectionSource` with changing availability:

```ts
class MySelectionSource implements SelectionSource {
private _status = reactive("available");

label = "My selection source";

get status() {
return this._status.value;
}

someEventHandler() {
// Change the status by updating the signal's value.
// The UI will update automatically.
this._status.value = "unavailable";
}
}
```
40 changes: 40 additions & 0 deletions .changeset/eighty-peaches-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
"@open-pioneer/map": minor
---

- **Breaking:** Remove most events from the map model and the layer interfaces.
All events that were merely used to synchronized state (e.g. `changed:title` etc.) have been removed.

The map model and related objects (layers, layer collections, etc.) are now based on the [Reactivity API](https://github.com/conterra/reactivity/blob/main/packages/reactivity-core/README.md).
This change greatly simplifies the code that is necessary to access up-to-date values and to react to changes.

For example, from inside a React component, you can now write:

```jsx
import { useReactiveSnapshot } from "@open-pioneer/reactivity";

function YourComponent() {
// Always up to date, even if the layer's title changes.
// No more need to listen to events.
const title = useReactiveSnapshot(() => layer.title, [layer]);
return <div>{title}</div>;
}
```

And inside a normal JavaScript function, you can watch for changes like this:

```js
import { watch } from "@conterra/reactivity-core";

const watchHandle = watch(
() => [layer.title],
([newTitle]) => {
console.log("The title changed to", newTitle);
},
);

// Later, cleanup:
watchHandle.destroy();
```

For more details, check the [Reactivity API documentation](https://github.com/conterra/reactivity/blob/main/packages/reactivity-core/README.md).
5 changes: 5 additions & 0 deletions .changeset/hot-lions-wash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@open-pioneer/basemap-switcher": patch
---

Use reactive map model APIs to access the current set of basemaps.
5 changes: 5 additions & 0 deletions .changeset/lazy-otters-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@open-pioneer/toc": patch
---

Use reactive map model APIs to access the current set of layers and their attributes.
5 changes: 5 additions & 0 deletions .changeset/little-lizards-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@open-pioneer/editing": minor
---

Removed EditingWorkflowEvent; the state of the EditingWorkflow is now reactive and should be used instead.
5 changes: 5 additions & 0 deletions .changeset/ninety-days-repair.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@open-pioneer/editing": patch
---

Use reactive map model APIs to access the current map container element.
5 changes: 5 additions & 0 deletions .changeset/weak-goats-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@open-pioneer/legend": patch
---

Use reactive map model APIs to access the current layers and their attributes.
5 changes: 5 additions & 0 deletions .changeset/wet-seals-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@open-pioneer/editing": patch
---

Stop draw interactions and remove tooltips before saving.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"ignoreCves": []
},
"patchedDependencies": {
"@changesets/assemble-release-plan": "patches/@changesets__assemble-release-plan.patch",
"@changesets/assemble-release-plan@6.0.4": "patches/@changesets__assemble-release-plan.patch",
"@chakra-ui/menu@2.2.1": "patches/@chakra-ui__menu@2.2.1.patch",
"@chakra-ui/react-use-outside-click@2.2.0": "patches/@chakra-ui__react-use-outside-click@2.2.0.patch",
"@chakra-ui/hooks@2.2.1": "patches/@chakra-ui__hooks@2.2.1.patch",
Expand Down
38 changes: 34 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 14 additions & 9 deletions src/packages/basemap-switcher/BasemapSwitcher.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)
// SPDX-License-Identifier: Apache-2.0
import { nextTick } from "@conterra/reactivity-core";
import { BkgTopPlusOpen, SimpleLayer } from "@open-pioneer/map";
import { createServiceOptions, setupMap } from "@open-pioneer/map-test-utils";
import { PackageContextProvider } from "@open-pioneer/test-utils/react";
import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import TileLayer from "ol/layer/Tile";
import OSM from "ol/source/OSM";
import { act } from "react";
import { describe, expect, it } from "vitest";
import { BasemapSwitcher } from "./BasemapSwitcher";

Expand Down Expand Up @@ -186,14 +188,15 @@ it("should update when a new basemap is registered", async () => {
let options = getCurrentOptions(switcherSelect);
expect(options.length).toBe(2);

act(() => {
await act(async () => {
const layer = new SimpleLayer({
id: "foo",
title: "Foo",
isBaseLayer: true,
olLayer: new TileLayer({})
});
map.layers.addLayer(layer);
await nextTick();
});

options = getCurrentOptions(switcherSelect);
Expand Down Expand Up @@ -226,8 +229,9 @@ it("should update when a different basemap is activated from somewhere else", as
expect(switcherSelect.textContent).toBe("OSM");
expect(map.layers.getActiveBaseLayer()?.id).toBe("osm");

act(() => {
await act(async () => {
map.layers.activateBaseLayer("topplus-open");
await nextTick();
});
expect(switcherSelect.textContent).toBe("TopPlus Open");
});
Expand Down Expand Up @@ -423,18 +427,19 @@ it("should update the ui when a layer title changes", async () => {
`);

// change layer title
act(() => {
await act(async () => {
activeBaseLayer?.setTitle("New Layer Title");
await nextTick();
});

options = getCurrentOptions(switcherSelect);
optionLabels = Array.from(options).map((opt) => opt.textContent);
expect(optionLabels, "basemap layer was not renamed").toMatchInlineSnapshot(`
[
"New Layer Title",
"TopPlus Open",
]
`);
[
"New Layer Title",
"TopPlus Open",
]
`);
});

function showDropdown(switcherSelect: HTMLElement) {
Expand Down
Loading

0 comments on commit e7978a8

Please sign in to comment.