@panoramax/web-viewer 3.2.3-develop-6e69906d → 3.2.3-develop-8b82a4e5

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 (61) hide show
  1. package/build/index.css +2 -2
  2. package/build/index.css.map +1 -1
  3. package/build/index.js +535 -216
  4. package/build/index.js.map +1 -1
  5. package/build/widgets.html +1 -1
  6. package/docs/reference/components/core/PhotoViewer.md +2 -0
  7. package/docs/reference/components/core/Viewer.md +2 -0
  8. package/docs/reference/components/layout/BottomDrawer.md +35 -0
  9. package/docs/reference/components/layout/Tabs.md +45 -0
  10. package/docs/reference/components/menus/PictureLegend.md +1 -0
  11. package/docs/reference/components/ui/Button.md +3 -2
  12. package/docs/reference/components/ui/CopyButton.md +7 -4
  13. package/docs/reference/components/ui/LinkButton.md +1 -0
  14. package/docs/reference/components/ui/ListGroup.md +22 -0
  15. package/docs/reference/components/ui/widgets/Legend.md +11 -0
  16. package/docs/reference/components/ui/widgets/OSMEditors.md +15 -0
  17. package/docs/reference/components/ui/widgets/PictureLegendActions.md +32 -0
  18. package/docs/reference.md +6 -2
  19. package/mkdocs.yml +5 -1
  20. package/package.json +1 -1
  21. package/public/widgets.html +45 -9
  22. package/src/components/core/Basic.css +1 -0
  23. package/src/components/core/PhotoViewer.css +0 -23
  24. package/src/components/core/PhotoViewer.js +41 -22
  25. package/src/components/core/Viewer.css +6 -31
  26. package/src/components/core/Viewer.js +40 -11
  27. package/src/components/layout/BottomDrawer.js +204 -0
  28. package/src/components/layout/CorneredGrid.js +3 -0
  29. package/src/components/layout/Tabs.js +133 -0
  30. package/src/components/layout/index.js +2 -0
  31. package/src/components/menus/PictureLegend.js +162 -23
  32. package/src/components/menus/PictureMetadata.js +220 -110
  33. package/src/components/menus/Share.js +2 -142
  34. package/src/components/styles.js +47 -47
  35. package/src/components/ui/Button.js +4 -2
  36. package/src/components/ui/CopyButton.js +34 -5
  37. package/src/components/ui/LinkButton.js +6 -7
  38. package/src/components/ui/ListGroup.js +66 -0
  39. package/src/components/ui/Map.js +4 -1
  40. package/src/components/ui/QualityScore.js +19 -24
  41. package/src/components/ui/TogglableGroup.js +47 -53
  42. package/src/components/ui/index.js +1 -0
  43. package/src/components/ui/widgets/Legend.js +29 -6
  44. package/src/components/ui/widgets/OSMEditors.js +153 -0
  45. package/src/components/ui/widgets/PictureLegendActions.js +131 -0
  46. package/src/components/ui/widgets/index.js +5 -4
  47. package/src/translations/en.json +14 -8
  48. package/src/translations/fr.json +14 -8
  49. package/src/utils/InitParameters.js +2 -1
  50. package/src/utils/geocoder.js +3 -1
  51. package/src/utils/picture.js +1 -2
  52. package/src/utils/widgets.js +5 -43
  53. package/tests/components/core/__snapshots__/PhotoViewer.test.js.snap +12 -32
  54. package/tests/components/core/__snapshots__/Viewer.test.js.snap +5 -25
  55. package/tests/components/ui/__snapshots__/Photo.test.js.snap +6 -2
  56. package/tests/utils/InitParameters.test.js +7 -9
  57. package/tests/utils/__snapshots__/picture.test.js.snap +13 -4
  58. package/tests/utils/picture.test.js +2 -2
  59. package/tests/utils/widgets.test.js +0 -59
  60. package/docs/reference/components/ui/widgets/Share.md +0 -15
  61. package/src/components/ui/widgets/Share.js +0 -30
@@ -48,7 +48,7 @@ export function getExifFloat(val) {
48
48
  * @private
49
49
  */
50
50
  export function getGPSPrecision(picture) {
51
- let quality = "❓";
51
+ let quality = null;
52
52
  const gpsHPosError = picture?.properties?.["quality:horizontal_accuracy"] || getExifFloat(picture?.properties?.exif?.["Exif.GPSInfo.GPSHPositioningError"]);
53
53
  const gpsDop = getExifFloat(picture?.properties?.exif?.["Exif.GPSInfo.GPSDOP"]);
54
54
 
@@ -259,7 +259,6 @@ export function getNodeCaption(metadata, t) {
259
259
  const better = pv.find(v => v.toLowerCase() != v);
260
260
  caption.producer.push(better || deflt);
261
261
  });
262
- caption.producer = caption.producer.join(", ");
263
262
  }
264
263
  }
265
264
 
@@ -13,49 +13,6 @@ export function fa(i, o) {
13
13
  return icon(i, o).node[0];
14
14
  }
15
15
 
16
- /**
17
- * Table cell with a copy link
18
- * @private
19
- */
20
- export function createLinkCell(id, url, title, _t) {
21
- const link = document.createElement("a");
22
- link.href = url;
23
- link.target = "_blank";
24
- link.title = title;
25
- link.textContent = id;
26
-
27
- const buttonContainer = createWebComp("pnx-copy-button", {text: id, _t});
28
- return [link, buttonContainer];
29
- }
30
-
31
- /**
32
- * Create a light table
33
- * @private
34
- */
35
- export function createTable(className, rows) {
36
- const table = document.createElement("table");
37
- table.className = className;
38
-
39
- rows.forEach(({ section, value, values, classes }) => {
40
- const tr = document.createElement("tr");
41
- const th = document.createElement("th");
42
- th.scope = "row";
43
- th.textContent = section;
44
- tr.appendChild(th);
45
-
46
- const td = document.createElement("td");
47
- if(classes) { td.classList.add(...classes); }
48
- if(values) { values.forEach(v => td.appendChild(v)); }
49
- else if(value instanceof HTMLElement) { td.appendChild(value); }
50
- else { td.innerHTML = value; }
51
- tr.appendChild(td);
52
-
53
- table.appendChild(tr);
54
- });
55
-
56
- return table;
57
- }
58
-
59
16
  /**
60
17
  * Create a web component with its initial properties
61
18
  * @private
@@ -90,4 +47,9 @@ export function listenForMenuClosure(me, callback) {
90
47
  me._parent?.oncePSVReady?.().then(() => {
91
48
  me._parent.psv.addEventListener("click", () => callback());
92
49
  });
50
+
51
+ // Legend click
52
+ me._parent?.onceReady?.().then(() => {
53
+ me._parent.legend?.addEventListener("click", () => callback());
54
+ });
93
55
  }
@@ -4,13 +4,14 @@ exports[`_initWidgets should handle widgets if width is not small 1`] = `
4
4
  [MockFunction] {
5
5
  "calls": Array [
6
6
  Array [
7
- <pnx-widget-zoom
8
- class="pnx-print-hidden"
9
- slot="bottom-right"
7
+ <pnx-widget-player
8
+ class="pnx-only-psv pnx-print-hidden"
9
+ size="xl"
10
+ slot="top"
10
11
  />,
11
12
  ],
12
13
  Array [
13
- <pnx-widget-share
14
+ <pnx-widget-zoom
14
15
  class="pnx-print-hidden"
15
16
  slot="bottom-right"
16
17
  />,
@@ -22,13 +23,6 @@ exports[`_initWidgets should handle widgets if width is not small 1`] = `
22
23
  slot="top-left"
23
24
  />,
24
25
  ],
25
- Array [
26
- <pnx-widget-player
27
- class="pnx-only-psv pnx-print-hidden"
28
- size="xl"
29
- slot="top"
30
- />,
31
- ],
32
26
  ],
33
27
  "results": Array [
34
28
  Object {
@@ -43,10 +37,6 @@ exports[`_initWidgets should handle widgets if width is not small 1`] = `
43
37
  "type": "return",
44
38
  "value": undefined,
45
39
  },
46
- Object {
47
- "type": "return",
48
- "value": undefined,
49
- },
50
40
  ],
51
41
  }
52
42
  `;
@@ -54,19 +44,6 @@ exports[`_initWidgets should handle widgets if width is not small 1`] = `
54
44
  exports[`_initWidgets should handle widgets if width is small 1`] = `
55
45
  [MockFunction] {
56
46
  "calls": Array [
57
- Array [
58
- <pnx-widget-share
59
- class="pnx-print-hidden"
60
- slot="bottom-right"
61
- />,
62
- ],
63
- Array [
64
- <pnx-widget-legend
65
- focus="pic"
66
- picture="somePicture"
67
- slot="top"
68
- />,
69
- ],
70
47
  Array [
71
48
  <pnx-widget-player
72
49
  class="pnx-only-psv pnx-print-hidden"
@@ -74,6 +51,13 @@ exports[`_initWidgets should handle widgets if width is small 1`] = `
74
51
  slot="top"
75
52
  />,
76
53
  ],
54
+ Array [
55
+ <pnx-bottom-drawer
56
+ slot="bottom"
57
+ >
58
+ <pnx-picture-legend />
59
+ </pnx-bottom-drawer>,
60
+ ],
77
61
  ],
78
62
  "results": Array [
79
63
  Object {
@@ -84,10 +68,6 @@ exports[`_initWidgets should handle widgets if width is small 1`] = `
84
68
  "type": "return",
85
69
  "value": undefined,
86
70
  },
87
- Object {
88
- "type": "return",
89
- "value": undefined,
90
- },
91
71
  ],
92
72
  }
93
73
  `;
@@ -9,12 +9,6 @@ exports[`_initWidgets should handle widgets if width is not small 1`] = `
9
9
  slot="bottom-right"
10
10
  />,
11
11
  ],
12
- Array [
13
- <pnx-widget-share
14
- class="pnx-print-hidden"
15
- slot="bottom-right"
16
- />,
17
- ],
18
12
  Array [
19
13
  <pnx-widget-legend
20
14
  focus="pic"
@@ -74,10 +68,6 @@ exports[`_initWidgets should handle widgets if width is not small 1`] = `
74
68
  "type": "return",
75
69
  "value": undefined,
76
70
  },
77
- Object {
78
- "type": "return",
79
- "value": undefined,
80
- },
81
71
  ],
82
72
  }
83
73
  `;
@@ -92,17 +82,11 @@ exports[`_initWidgets should handle widgets if width is small 1`] = `
92
82
  />,
93
83
  ],
94
84
  Array [
95
- <pnx-widget-share
96
- class="pnx-print-hidden"
97
- slot="bottom-right"
98
- />,
99
- ],
100
- Array [
101
- <pnx-widget-legend
102
- focus="pic"
103
- picture="somePicture"
104
- slot="top"
105
- />,
85
+ <pnx-bottom-drawer
86
+ slot="bottom"
87
+ >
88
+ <pnx-picture-legend />
89
+ </pnx-bottom-drawer>,
106
90
  ],
107
91
  Array [
108
92
  <pnx-widget-player
@@ -156,10 +140,6 @@ exports[`_initWidgets should handle widgets if width is small 1`] = `
156
140
  "type": "return",
157
141
  "value": undefined,
158
142
  },
159
- Object {
160
- "type": "return",
161
- "value": undefined,
162
- },
163
143
  ],
164
144
  }
165
145
  `;
@@ -7,7 +7,9 @@ Object {
7
7
  "toLocaleDateString": [Function],
8
8
  },
9
9
  "license": "proprietary",
10
- "producer": "User",
10
+ "producer": Array [
11
+ "User",
12
+ ],
11
13
  },
12
14
  "gps": Array [
13
15
  2.1822941,
@@ -117,7 +119,9 @@ Object {
117
119
  "toLocaleDateString": [Function],
118
120
  },
119
121
  "license": "proprietary",
120
- "producer": "User",
122
+ "producer": Array [
123
+ "User",
124
+ ],
121
125
  },
122
126
  "gps": Array [
123
127
  2.1822941,
@@ -442,7 +442,6 @@ describe("alterViewerState", () => {
442
442
  select: jest.fn(),
443
443
  setPopup: jest.fn(),
444
444
  _setFocus: jest.fn(),
445
- _showPictureMetadata: jest.fn(),
446
445
  mini: {},
447
446
  };
448
447
  });
@@ -462,14 +461,13 @@ describe("alterViewerState", () => {
462
461
  expect(viewer.select).toHaveBeenCalledWith();
463
462
  });
464
463
 
465
- it("should show picture metadata when focus is meta and picture is loaded", () => {
466
- const params = { picture: "pic1", focus: "meta" };
467
- alterViewerState(viewer, params);
468
- expect(viewer.psv.addEventListener).toHaveBeenCalledWith("picture-loaded", expect.any(Function), { once: true });
469
- const listener = viewer.psv.addEventListener.mock.calls[0][1];
470
- listener();
471
- expect(viewer._showPictureMetadata).toHaveBeenCalled();
472
- });
464
+ // it("should show picture metadata when focus is meta and picture is loaded", () => {
465
+ // const params = { picture: "pic1", focus: "meta" };
466
+ // alterViewerState(viewer, params);
467
+ // expect(viewer.psv.addEventListener).toHaveBeenCalledWith("picture-loaded", expect.any(Function), { once: true });
468
+ // const listener = viewer.psv.addEventListener.mock.calls[0][1];
469
+ // listener();
470
+ // });
473
471
 
474
472
  it("should set focus to map when focus param is map and map exists", () => {
475
473
  const params = { focus: "map", forceFocus: true };
@@ -5,7 +5,9 @@ Object {
5
5
  "caption": Object {
6
6
  "date": mockConstructor {},
7
7
  "license": "<a href=\\"https://spdx.org/licenses/CC-BY-SA-4.0.html\\" title=\\"\\" target=\\"_blank\\">CC-BY-SA-4.0</a>",
8
- "producer": "Hopen111",
8
+ "producer": Array [
9
+ "Hopen111",
10
+ ],
9
11
  },
10
12
  "gps": Array [
11
13
  -92.70188245,
@@ -263,7 +265,10 @@ Object {
263
265
  "date": Object {
264
266
  "toLocaleDateString": [Function],
265
267
  },
266
- "producer": "GeoVisio Corp., PanierAvide",
268
+ "producer": Array [
269
+ "GeoVisio Corp.",
270
+ "PanierAvide",
271
+ ],
267
272
  }
268
273
  `;
269
274
 
@@ -272,7 +277,9 @@ Object {
272
277
  "date": Object {
273
278
  "toLocaleDateString": [Function],
274
279
  },
275
- "producer": "PanierAvide",
280
+ "producer": Array [
281
+ "PanierAvide",
282
+ ],
276
283
  }
277
284
  `;
278
285
 
@@ -294,7 +301,9 @@ Object {
294
301
 
295
302
  exports[`getNodeCaption works with producer 1`] = `
296
303
  Object {
297
- "producer": "PanierAvide",
304
+ "producer": Array [
305
+ "PanierAvide",
306
+ ],
298
307
  }
299
308
  `;
300
309
 
@@ -19,7 +19,7 @@ describe("getExifFloat", () => {
19
19
 
20
20
  describe("getGPSPrecision", () => {
21
21
  it.each([
22
- [undefined, "❓"],
22
+ [undefined, null],
23
23
  [0.4, "0.4 m"],
24
24
  [0.9, "0.9 m"],
25
25
  [2.9, "2.9 m"],
@@ -34,7 +34,7 @@ describe("getGPSPrecision", () => {
34
34
  });
35
35
 
36
36
  it.each([
37
- [undefined, "❓"],
37
+ [undefined, null],
38
38
  [0.9, "ideal"],
39
39
  [1.9, "excellent"],
40
40
  [4.9, "good"],
@@ -8,65 +8,6 @@ describe("fa", () => {
8
8
  });
9
9
  });
10
10
 
11
- describe("createLinkCell", () => {
12
- it("works", () => {
13
- const id = "123";
14
- const url = "https://example.com/";
15
- const title = "Example Title";
16
- const _t = {pnx: {}};
17
-
18
- const [link, buttonContainer] = widgets.createLinkCell(id, url, title, _t);
19
-
20
- expect(link).toBeInstanceOf(HTMLAnchorElement);
21
- expect(link.href).toBe(url);
22
- expect(link.target).toBe("_blank");
23
- expect(link.title).toBe(title);
24
- expect(link.textContent).toBe(id);
25
-
26
- expect(buttonContainer).toBeInstanceOf(HTMLElement);
27
- expect(buttonContainer.tagName.toLowerCase()).toBe("pnx-copy-button");
28
- expect(buttonContainer.getAttribute("text")).toBe(id);
29
- expect(buttonContainer._t).toBe(_t);
30
- });
31
- });
32
-
33
- describe("createTable", () => {
34
- it("works", () => {
35
- const className = "test-table";
36
- const rows = [
37
- { section: "Nom", value: "Alice" },
38
- { section: "Âge", value: 30 },
39
- { section: "Adresse", values: [document.createElement("span")] },
40
- ];
41
-
42
- const table = widgets.createTable(className, rows);
43
-
44
- expect(table).toBeInstanceOf(HTMLTableElement);
45
- expect(table.className).toBe(className);
46
- expect(table.rows.length).toBe(rows.length);
47
-
48
- rows.forEach((row, index) => {
49
- const tr = table.rows[index];
50
- const th = tr.cells[0];
51
- const td = tr.cells[1];
52
-
53
- expect(th).toBeInstanceOf(HTMLTableCellElement);
54
- expect(th.textContent).toBe(row.section);
55
- expect(th.scope).toBe("row");
56
- expect(td).toBeInstanceOf(HTMLTableCellElement);
57
-
58
- if (row.values) {
59
- expect(td.children.length).toBe(row.values.length);
60
- } else if (row.value instanceof HTMLElement) {
61
- expect(td.children.length).toBe(1);
62
- expect(td.firstChild).toBe(row.value);
63
- } else {
64
- expect(td.innerHTML).toBe(String(row.value));
65
- }
66
- });
67
- });
68
- });
69
-
70
11
  describe("createWebComp", () => {
71
12
  it("works", () => {
72
13
  const tag = "custom-element";
@@ -1,15 +0,0 @@
1
- <a name="Panoramax.components.ui.widgets.Share"></a>
2
-
3
- ## Panoramax.components.ui.widgets.Share ⇐ <code>[lit.LitElement](https://lit.dev/docs/api/LitElement/)</code>
4
- **Kind**: static class of <code>Panoramax.components.ui.widgets</code>
5
- **Extends**: <code>[lit.LitElement](https://lit.dev/docs/api/LitElement/)</code>
6
- **Element**: pnx-widget-share
7
- <a name="new_Panoramax.components.ui.widgets.Share_new"></a>
8
-
9
- ### new Share()
10
- Share button handles showing/hiding share menu.
11
-
12
- **Example**
13
- ```html
14
- <pnx-widget-share _parent=${viewer} />
15
- ```
@@ -1,30 +0,0 @@
1
- import { LitElement, html } from "lit";
2
- import { fa } from "../../../utils/widgets";
3
- import { faShareNodes } from "@fortawesome/free-solid-svg-icons/faShareNodes";
4
-
5
- /**
6
- * Share button handles showing/hiding share menu.
7
- * @class Panoramax.components.ui.widgets.Share
8
- * @element pnx-widget-share
9
- * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
10
- * @example
11
- * ```html
12
- * <pnx-widget-share _parent=${viewer} />
13
- * ```
14
- */
15
- export default class Share extends LitElement {
16
- /** @private */
17
- render() {
18
- return html`<pnx-togglable-group ._parent=${this._parent}>
19
- <pnx-button
20
- slot="button"
21
- kind="flat"
22
- size="xxl"
23
- title=${this._parent?._t.pnx.share}
24
- >${fa(faShareNodes)}</pnx-button>
25
- <pnx-share-menu ._parent=${this._parent}></pnx-share-menu>
26
- </pnx-togglable-group>`;
27
- }
28
- }
29
-
30
- customElements.define("pnx-widget-share", Share);