@yuneta/gobj-ui 7.10.3 → 7.10.5

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.
package/README.md CHANGED
@@ -526,6 +526,45 @@ because the link can stay up and an answer still never land. A refresh
526
526
  re-pulls the page the reader is on rather than throwing them back to the
527
527
  first.
528
528
 
529
+ ### What a delete takes with it
530
+
531
+ A treedb delete is not one thing, and these views delete with **`force`**.
532
+ `force` on a node does not only remove it: its children are **UNLINKED** —
533
+ they survive, loose — and it is cleaned off its parents. So "delete this row"
534
+ can mean "detach eleven records from their only parent", and the question that
535
+ used to be asked, `are you sure`, said none of it.
536
+
537
+ The confirmation names what is going (the record's key, or how many) and adds
538
+ a line per thing at stake, **each only when there is something at stake** — a
539
+ loose record must not be dressed up as a dangerous one:
540
+
541
+ - *N children will be UNLINKED, not deleted*
542
+ - *It will be detached from M parents*
543
+
544
+ Counted off the record the table already has (`list_dict` fills the hook and
545
+ fkey columns), so asking costs no round trip. The counting is
546
+ `delete_impact.js`, pure and tested, because the shapes are the fiddly part: a
547
+ hook or fkey value arrives as a list of refs, a dict keyed by id, or a single
548
+ ref string — and a column can be BOTH hook and fkey, which counts on both
549
+ sides, because the delete does both things.
550
+
551
+ In the graph the node-delete popover carries the same two lines, and the
552
+ **unlink** popover carries the reassurance that is its whole point: *neither
553
+ record is deleted*. Next to a delete button painted the same red, that is not
554
+ obvious.
555
+
556
+ Three things this cost, worth knowing before composing any message from keys:
557
+
558
+ - `yui_shell_confirm_*` renders its message **as an i18n key**, so a composed
559
+ sentence can never be one. Pass DOM instead — the helper takes it.
560
+ - `createElement2` **trims text nodes**, so a `["span", {}, " "]` separator
561
+ vanishes and the question reads "BorrarDeveloper". Space with CSS.
562
+ - a **counted** word carries no `i18n` attribute: `yui_shell_show_modal` calls
563
+ `refresh_language()` on the dialog's content, which re-translates from the
564
+ key alone — without the count — and puts the plural back over the singular.
565
+ Nothing is lost, because a dialog with a backdrop never sees a language
566
+ change.
567
+
529
568
  ### Editing a topic table in place
530
569
 
531
570
  A writable scalar is editable in the table, in edition mode
@@ -8536,7 +8536,7 @@ function decod_coordinates(gobj, coordinates) {
8536
8536
  *
8537
8537
  ************************************************************/
8538
8538
  function get_coordinates(gobj, device) {
8539
- let coordinates = decod_coordinates(gobj, device.settings.coordinates);
8539
+ let coordinates = decod_coordinates(gobj, device.settings?.coordinates);
8540
8540
  if (coordinates.lng === 0 && coordinates.lat === 0) coordinates = decod_coordinates(gobj, device.coordinates);
8541
8541
  if (coordinates.lng === 0 && coordinates.lat === 0) {
8542
8542
  coordinates.lng = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "default_longitude");
@@ -8585,7 +8585,7 @@ function devices2geojson(gobj, devices) {
8585
8585
  id: device.id,
8586
8586
  name: device.name,
8587
8587
  image: device.image,
8588
- connected: device.connected,
8588
+ connected: !!device.connected,
8589
8589
  gobj_service_name: device.gobj_service_name
8590
8590
  }
8591
8591
  };
@@ -8873,11 +8873,9 @@ function ac_map_on_load(gobj, event, kw, src) {
8873
8873
  function ac_refresh$6(gobj, event, kw, src) {
8874
8874
  let priv = gobj.priv;
8875
8875
  let devices = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "devices");
8876
- let map = priv.xmap;
8877
- if (map.isStyleLoaded()) {
8878
- const geojson_data = devices2geojson(gobj, devices);
8879
- map.getSource("devices").setData(geojson_data);
8880
- }
8876
+ const source = priv.xmap.getSource("devices");
8877
+ if (!source) return 0;
8878
+ source.setData(devices2geojson(gobj, devices));
8881
8879
  return 0;
8882
8880
  }
8883
8881
  /************************************************************
@@ -8531,7 +8531,7 @@ function decod_coordinates(gobj, coordinates) {
8531
8531
  *
8532
8532
  ************************************************************/
8533
8533
  function get_coordinates(gobj, device) {
8534
- let coordinates = decod_coordinates(gobj, device.settings.coordinates);
8534
+ let coordinates = decod_coordinates(gobj, device.settings?.coordinates);
8535
8535
  if (coordinates.lng === 0 && coordinates.lat === 0) coordinates = decod_coordinates(gobj, device.coordinates);
8536
8536
  if (coordinates.lng === 0 && coordinates.lat === 0) {
8537
8537
  coordinates.lng = gobj_read_attr(gobj, "default_longitude");
@@ -8580,7 +8580,7 @@ function devices2geojson(gobj, devices) {
8580
8580
  id: device.id,
8581
8581
  name: device.name,
8582
8582
  image: device.image,
8583
- connected: device.connected,
8583
+ connected: !!device.connected,
8584
8584
  gobj_service_name: device.gobj_service_name
8585
8585
  }
8586
8586
  };
@@ -8868,11 +8868,9 @@ function ac_map_on_load(gobj, event, kw, src) {
8868
8868
  function ac_refresh$6(gobj, event, kw, src) {
8869
8869
  let priv = gobj.priv;
8870
8870
  let devices = gobj_read_attr(gobj, "devices");
8871
- let map = priv.xmap;
8872
- if (map.isStyleLoaded()) {
8873
- const geojson_data = devices2geojson(gobj, devices);
8874
- map.getSource("devices").setData(geojson_data);
8875
- }
8871
+ const source = priv.xmap.getSource("devices");
8872
+ if (!source) return 0;
8873
+ source.setData(devices2geojson(gobj, devices));
8876
8874
  return 0;
8877
8875
  }
8878
8876
  /************************************************************
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.10.3",
3
+ "version": "7.10.5",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
package/src/c_yui_map.js CHANGED
@@ -293,7 +293,7 @@ function get_coordinates(gobj, device)
293
293
  * Coordinates can be set in device.settings or in device
294
294
  * If devices.settings are null then get it from device
295
295
  */
296
- let coordinates = decod_coordinates(gobj, device.settings.coordinates);
296
+ let coordinates = decod_coordinates(gobj, device.settings?.coordinates);
297
297
  if(coordinates.lng === 0 && coordinates.lat === 0) {
298
298
  coordinates = decod_coordinates(gobj, device.coordinates);
299
299
  }
@@ -369,7 +369,18 @@ function devices2geojson(gobj, devices)
369
369
  id: device.id,
370
370
  name: device.name,
371
371
  image: device.image,
372
- connected: device.connected,
372
+ /*
373
+ * A REAL boolean. Four style expressions test this with
374
+ * ['case', ...], and maplibre asserts a STRICT boolean
375
+ * there, so null, absent, or the 1/0 a backend may send all
376
+ * fail the assertion. The consequences are not cosmetic:
377
+ * the point paints with the property default instead of
378
+ * green/red, and the cluster accumulator turns NULL, which
379
+ * the cluster colour compares against point_count -- never
380
+ * equal, so the whole cluster stays red as if something were
381
+ * disconnected.
382
+ */
383
+ connected: !!device.connected,
373
384
  gobj_service_name: device.gobj_service_name,
374
385
  }
375
386
  };
@@ -782,10 +793,24 @@ function ac_refresh(gobj, event, kw, src)
782
793
  let devices = gobj_read_attr(gobj, "devices");
783
794
 
784
795
  let map = priv.xmap;
785
- if (map.isStyleLoaded()) {
786
- const geojson_data = devices2geojson(gobj, devices);
787
- map.getSource('devices').setData(geojson_data);
796
+
797
+ /*
798
+ * Ask for the source, do not infer it from the style. 'devices' is added
799
+ * by load_devices() on the map 'load' event, which is a LATER milestone:
800
+ * isStyleLoaded() is already true one render frame before 'load' fires,
801
+ * and getSource() is undefined in that frame. Nothing is lost by
802
+ * skipping, load_devices() reads the same attr.
803
+ *
804
+ * Testing the style was also wrong the other way: it goes back to false
805
+ * while new tiles load, so every refresh during a pan or a zoom was
806
+ * silently dropped and the devices stopped moving.
807
+ */
808
+ const source = map.getSource('devices');
809
+ if(!source) {
810
+ return 0;
788
811
  }
812
+
813
+ source.setData(devices2geojson(gobj, devices));
789
814
  return 0;
790
815
  }
791
816