@panoramax/web-viewer 5.1.1-develop-942a7005 → 5.1.1-develop-4f8bcb22

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.
@@ -29,6 +29,7 @@
29
29
  --widget-bg-primary: var(--blue-semi);
30
30
  --widget-bg-primary-hover: #e0e7ff;
31
31
  --widget-bg-warn: #FFECB3;
32
+ --widget-bg-danger: #FFCDD2;
32
33
  --widget-bg-success: #C8E6C9;
33
34
  --widget-border-div: var(--grey-pale);
34
35
  --widget-border-btn: var(--blue);
@@ -36,6 +37,7 @@
36
37
  --widget-font-active: var(--white);
37
38
  --widget-font-direct: var(--blue);
38
39
  --widget-font-warn: #BF360C;
40
+ --widget-font-danger: #B71C1C;
39
41
  --widget-font-success: #1B5E20;
40
42
  --font-family: "Atkinson Hyperlegible Next", sans-serif;
41
43
  --widget-option-left: #6A1B9A;
@@ -9,7 +9,7 @@ import BasicStyles from "./Basic.css" with { type: "css" };
9
9
  document.adoptedStyleSheets.push(AtkinsonStyles);
10
10
  document.adoptedStyleSheets.push(BasicStyles);
11
11
 
12
- const __COMMIT_HASH__ = "942a700";
12
+ const __COMMIT_HASH__ = "4f8bcb2";
13
13
  const __PACKAGE_VERSION__ = "5.1.1";
14
14
  const __PACKAGE_ISSUES_URL__ = "https://gitlab.com/panoramax/clients/web-viewer/-/work_items";
15
15
 
@@ -4,7 +4,7 @@ import { classMap } from "lit/directives/class-map.js";
4
4
  import { fa, onceParentAvailable } from "../../utils/widgets.js";
5
5
  import {
6
6
  faArrowLeft, faCalendarAlt, faChevronDown, faChevronUp, faShareNodes,
7
- faTriangleExclamation, faUser, faUserLock,
7
+ faTriangleExclamation, faUser, faUserLock, faTrash,
8
8
  } from "@fortawesome/free-solid-svg-icons";
9
9
  import { hidden, panel, placeholder } from "../styles.js";
10
10
  import { reverseGeocodingNominatim } from "../../utils/geocoder.js";
@@ -250,6 +250,28 @@ export default class PictureLegend extends LitElement {
250
250
  }
251
251
  }
252
252
 
253
+ /** @private */
254
+ _onDeleteClick() {
255
+ if(confirm(this._parent?._t.pnx.delete_picture_warn)) {
256
+ const meta = this._parent.psv.getPictureMetadata();
257
+ const nextId = meta.sequence.nextPic || meta.sequence.prevPic || null;
258
+ this._parent.api.deletePicture(meta.sequence.id, meta.id)
259
+ .then(() => {
260
+ // Clear cache
261
+ this._parent.psv.clearPictureMetadataCache();
262
+ this._parent.map?.reloadVectorTiles();
263
+
264
+ alert(this._parent?._t.pnx.delete_picture_ok);
265
+ if(nextId) {
266
+ this._parent.select(meta.sequence.id, nextId);
267
+ } else {
268
+ this._parent.select(null, null);
269
+ }
270
+ })
271
+ .catch(e => alert(this._parent?._t.pnx.delete_picture_error.replace("{e}", e)));
272
+ }
273
+ }
274
+
253
275
  /**
254
276
  * Force legend to not go anywhere beyond tags editor.
255
277
  * @memberof Panoramax.components.menus.PictureLegend#
@@ -349,11 +371,15 @@ export default class PictureLegend extends LitElement {
349
371
  ${fa(faShareNodes)} ${this._parent?._t.pnx.share}
350
372
  </pnx-button>
351
373
 
352
- ${this._parent.getAPI()._endpoints.report ? html`
353
- <pnx-button kind="fullwarn" size="sm" @click=${() => this._parent._showReportForm()}>
354
- ${fa(faTriangleExclamation)} ${this._parent?._t.pnx.report}
355
- </pnx-button>
356
- ` : nothing}
374
+ ${this._parent.psv.getPictureMetadata().permissions.delete_picture ? html`
375
+ <pnx-button kind="fulldanger" size="sm" @click=${this._onDeleteClick.bind(this)}>
376
+ ${fa(faTrash)} ${this._parent?._t.pnx.delete_picture}
377
+ </pnx-button>` : (
378
+ this._parent.getAPI()._endpoints.report ? html`
379
+ <pnx-button kind="fullwarn" size="sm" @click=${() => this._parent._showReportForm()}>
380
+ ${fa(faTriangleExclamation)} ${this._parent?._t.pnx.report}
381
+ </pnx-button>
382
+ ` : nothing)}
357
383
 
358
384
  <slot name="editors">
359
385
  <pnx-widget-osmeditors ._parent=${this._parent} />
@@ -227,6 +227,17 @@ export const btn = css`
227
227
  background-color: var(--widget-bg-warn);
228
228
  }
229
229
 
230
+ /* Fully-filled danger style */
231
+ .pnx-btn-fulldanger {
232
+ background-color: var(--widget-bg-danger);
233
+ color: var(--widget-font-danger);
234
+ border: none;
235
+ }
236
+
237
+ .pnx-btn-fulldanger:not(:disabled):hover {
238
+ background-color: var(--widget-bg-danger);
239
+ }
240
+
230
241
  /* Fully-filled success style */
231
242
  .pnx-btn-fullsuccess {
232
243
  background-color: var(--widget-bg-success);
@@ -23,7 +23,7 @@ export default class Button extends LitElement {
23
23
  * @memberof Panoramax.components.ui.Button#
24
24
  * @type {Object}
25
25
  * @property {boolean} [active=false] Whether the button is in an active state.
26
- * @property {string} [kind=full] The style variation of the button (full, fullwarn, fullsuccess, outline, flat, superflat, inline, superinline)
26
+ * @property {string} [kind=full] The style variation of the button (full, fullwarn, fulldanger, fullsuccess, outline, flat, superflat, inline, superinline)
27
27
  * @property {string} [size=md] The size of the button (sm, md, l, xl, xxl)
28
28
  * @property {boolean} [disabled=false] Whether the button is disabled.
29
29
  * @property {string} [type] The button type (e.g., 'submit').
@@ -254,6 +254,10 @@
254
254
  "semantics_download_title": "Download tags",
255
255
  "semantics_download_info": "All semantic data (tags) are available as open data. You can download them and use it as you like.",
256
256
  "semantics_download_cta": "Download open data",
257
+ "delete_picture": "Delete",
258
+ "delete_picture_warn": "⚠️ Caution: this deletes permanently the image.\nAre you sure you want to erase completely this image?",
259
+ "delete_picture_ok": "Picture was successfully deleted",
260
+ "delete_picture_error": "An error happened when trying to delete picture:\n{e}",
257
261
  "report": "Report",
258
262
  "report_auth": "This report will be sent using your account \"{a}\"",
259
263
  "report_nature_label": "Cause of the issue",
@@ -254,6 +254,10 @@
254
254
  "semantics_download_title": "Télécharger les tags",
255
255
  "semantics_download_info": "Toutes les données sémantiques (tags) sont disponibles en open data. Vous pouvez les télécharger et en faire un libre usage.",
256
256
  "semantics_download_cta": "Télécharger les données",
257
+ "delete_picture": "Supprimer",
258
+ "delete_picture_warn": "⚠️ Attention : ceci supprimera définitivement la photo.\nÊtes-vous sûr·e de vraiment vouloir complètement supprimer la photo ?",
259
+ "delete_picture_ok": "La photo a bien été supprimée",
260
+ "delete_picture_error": "Une erreur s'est produite lors de la suppression de la photo :\n{e}",
257
261
  "report": "Signaler",
258
262
  "report_auth": "Ce signalement sera envoyé en utilisant votre compte \"{a}\"",
259
263
  "report_nature_label": "Nature du problème",
@@ -683,6 +683,41 @@ export default class API extends EventTarget {
683
683
  });
684
684
  }
685
685
 
686
+ /**
687
+ * Delete a single picture on its origin API.
688
+ * @memberof Panoramax.utils.API#
689
+ * @param {string} sequenceId The sequence UUID
690
+ * @param {string} pictureId The picture UUID
691
+ * @returns {Promise}
692
+ * @fulfil {object} The JSON API response
693
+ */
694
+ deletePicture(sequenceId, pictureId) {
695
+ // Fake send version
696
+ // console.log("Delete", sequenceId, pictureId);
697
+ // return Promise.resolve(true);
698
+
699
+ if(!this.isReady()) { throw new Error("API is not ready to use"); }
700
+ let picLink = `${this._endpoint}/collections/${sequenceId}/items/${pictureId}`;
701
+
702
+ const opts = {
703
+ ...this._getFetchOptions(),
704
+ method: "DELETE",
705
+ };
706
+
707
+ return fetch(picLink, opts)
708
+ .then(async res => {
709
+ if(res.status >= 400) {
710
+ let txt = await res.text();
711
+ try {
712
+ txt = JSON.parse(txt)["message"];
713
+ }
714
+ catch(e) {}
715
+ return Promise.reject(txt);
716
+ }
717
+ return true;
718
+ });
719
+ }
720
+
686
721
  /**
687
722
  * Send picture semantics change to origin API.
688
723
  * @memberof Panoramax.utils.API#
@@ -491,6 +491,7 @@ export function filterRelatedPicsLinks(metadata, customFilter = null) {
491
491
  */
492
492
  export function getPermissions(f) {
493
493
  let edit_semantics = false;
494
+ let delete_picture = false;
494
495
 
495
496
  if(
496
497
  f.links.find(l => l.method === "PATCH" && l.attributes.includes("semantics"))
@@ -499,7 +500,11 @@ export function getPermissions(f) {
499
500
  edit_semantics = true;
500
501
  }
501
502
 
502
- return { edit_semantics };
503
+ if(f.links.find(l => l.method === "DELETE" && l.rel === "delete")) {
504
+ delete_picture = true;
505
+ }
506
+
507
+ return { edit_semantics, delete_picture };
503
508
  }
504
509
 
505
510
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoramax/web-viewer",
3
- "version": "5.1.1-develop-942a7005",
3
+ "version": "5.1.1-develop-4f8bcb22",
4
4
  "description": "Panoramax web viewer for geolocated pictures",
5
5
  "main": "./build/cjs/index.js",
6
6
  "module": "./build/esm/index.js",