@7365admin1/layer-common 4.124.1 → 4.124.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @iservice365/layer-common
2
2
 
3
+ ## 4.124.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 2279860: Robot screens fit a 390px phone (header, map pickers, schedule rows, saved-points hint, 3D map readout wrap instead of running off screen). Robot setup now reports "Setup x/N" to its host so the Super Admin drill-down can show it beside the site views.
8
+
9
+ ## 4.124.2
10
+
11
+ ### Patch Changes
12
+
13
+ - aefd40e: Robot detail: Cancel now says the robot drives back to its charger (core sends it home after a cancel), and the confirm offers "Stop here" to leave it where it stops.
14
+
3
15
  ## 4.124.1
4
16
 
5
17
  ### Patch Changes
@@ -3270,11 +3282,11 @@ Monthly report: a month that had patrols opens the list of that month's patrol r
3270
3282
  `utils/console-tier.ts` + `composables/useConsoleTier.ts` mirror the server's
3271
3283
  own rule from two endpoints the console already calls, unprojected:
3272
3284
 
3273
- GET /api/members/user/:user/app/admin the Seven365 staff membership
3274
- GET /api/roles/id/:role that membership's role document
3285
+ GET /api/members/user/:user/app/admin the Seven365 staff membership
3286
+ GET /api/roles/id/:role that membership's role document
3275
3287
 
3276
- owner = member.type === "admin" && role.type === "admin" && role.default === true
3277
- staff = member.type === "admin" && role.type === "admin"
3288
+ owner = member.type === "admin" && role.type === "admin" && role.default === true
3289
+ staff = member.type === "admin" && role.type === "admin"
3278
3290
 
3279
3291
  `role.default` is the marker because it is the only property of a platform
3280
3292
  staff role no API caller can set - `role.controller.ts` validates create and
@@ -524,6 +524,7 @@
524
524
  /* Asides: Needs attention, Clients drill down. */
525
525
  .hero-aside__head {
526
526
  display: flex;
527
+ flex-wrap: wrap;
527
528
  align-items: baseline;
528
529
  gap: 8px;
529
530
  border-top: 2px solid var(--hero-divider);
@@ -531,7 +532,7 @@
531
532
  margin-bottom: 8px;
532
533
  }
533
534
  .hero-aside__title { font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase; white-space: nowrap; font-weight: 600; }
534
- .hero-aside__hint { opacity: 0.6; font-size: 12px; }
535
+ .hero-aside__hint { opacity: 0.6; font-size: 12px; overflow-wrap: anywhere; min-width: 0; }
535
536
  .hero-aside__count { margin-left: auto; font-size: 12px; padding: 1px 7px; background: var(--hero-accent); color: #fff; font-weight: 600; }
536
537
  .hero-aside__empty { opacity: 0.6; padding: 10px 0; }
537
538
  .hero-attn { display: flex; flex-direction: column; gap: 1px; background: var(--hero-divider); }
@@ -610,7 +611,7 @@
610
611
  .hero-brand__name { font-family: var(--hero-font); font-weight: 800; font-size: 17px; letter-spacing: 0.06em; line-height: 1; }
611
612
  .hero-brand__org { font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; opacity: 0.6; margin-top: 3px; white-space: nowrap; }
612
613
  .hero-header__site { display: flex; align-items: center; gap: 8px; }
613
- .hero-header__right { display: flex; align-items: center; gap: 12px; margin-left: auto; }
614
+ .hero-header__right { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-left: auto; min-width: 0; max-width: 100%; }
614
615
 
615
616
  /* Cleaning | Security: selected = accent fill, white text. */
616
617
  .hero-switch { display: flex; border: 1px solid var(--hero-divider); }
@@ -763,7 +764,8 @@
763
764
 
764
765
  .hero-mini { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
765
766
  .hero-seen { opacity: 0.65; }
766
- .hero-mini__head { display: flex; align-items: center; gap: 8px; border-top: 2px solid var(--hero-divider); padding-top: 8px; }
767
+ .hero-mini__head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; border-top: 2px solid var(--hero-divider); padding-top: 8px; }
768
+ .hero-mini__head select { min-width: 0; max-width: 100%; }
767
769
  .hero-mini__foot { font-size: 12px; opacity: 0.6; display: flex; gap: 12px; white-space: nowrap; }
768
770
  .hero-mini__foot > span:first-child { overflow: hidden; text-overflow: ellipsis; }
769
771
  .hero-mini__legend { display: inline-block; width: 12px; height: 0; border-top: 2px dashed var(--hero-accent); vertical-align: middle; margin-right: 5px; }
@@ -858,6 +860,7 @@
858
860
  .hero-sched__row { display: grid; grid-template-columns: 90px 100px 1fr; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--hero-divider); font-size: 14px; }
859
861
  .hero-sched__row > span:nth-child(2) { font-variant-numeric: tabular-nums; }
860
862
  .hero-sched__row > span:nth-child(3) { opacity: 0.8; }
863
+ .hero-sched__row > span { min-width: 0; overflow-wrap: anywhere; }
861
864
 
862
865
  /* Detail plan: trail, crosshair, readout, radar, robot, spot points. */
863
866
  .hero-trail { position: absolute; width: 6px; height: 6px; margin: -3px; background: var(--hero-accent); }
@@ -1280,6 +1283,7 @@ div.hero-editor__wp.hero-editor__sel, div.hero-editor__fid.hero-editor__sel { ou
1280
1283
  .hero-lift { grid-template-columns: 1fr; }
1281
1284
  .hero-bmap__bar { right: 14px; }
1282
1285
  .hero-bmap__live { display: none; }
1286
+ .hero-bmap__readout { white-space: normal; }
1283
1287
  }
1284
1288
 
1285
1289
  @keyframes heroScan { from { background-position: 0 -60px; } to { background-position: 0 120%; } }
@@ -245,6 +245,8 @@
245
245
  <div class="hero-dialog__body">{{ confirming.text.body }}</div>
246
246
  <div class="hero-dialog__actions">
247
247
  <v-btn variant="outlined" @click="confirmOpen = false">Don't send</v-btn>
248
+ <!-- Cancel sends the robot home (core 2026-10-15); this keeps it where it stops. -->
249
+ <v-btn v-if="confirming.kind === 'cancel'" variant="outlined" @click="confirmSend(true)">Stop here</v-btn>
248
250
  <v-btn color="primary" variant="flat" :disabled="!!confirming.zones && !confirming.zoneNames?.length" @click="confirmSend">{{ confirming.text.action }}</v-btn>
249
251
  </div>
250
252
  </div>
@@ -796,10 +798,10 @@ function pickRoute(id: unknown) {
796
798
  c.what = /^patrol/i.test(name) ? name : `patrolling ${name}`;
797
799
  c.text = commandConfirm("area", { type: "security", name: record.value?.name, route: { name, stops }, map });
798
800
  }
799
- function confirmSend() {
801
+ function confirmSend(stayHere = false) {
800
802
  const c = confirming.value;
801
803
  confirmOpen.value = false;
802
- if (c) run(c.kind, c.body, c.what);
804
+ if (c) run(c.kind, stayHere === true ? { ...c.body, stayHere: true } : c.body, c.what);
803
805
  }
804
806
 
805
807
  /** The robot's plan image size for its floor, for turning plan clicks into pixels. */
@@ -72,6 +72,8 @@ const emit = defineEmits<{
72
72
  /** A step's button: a site view (fleet / map / lifts), the client's details, or Add robot. */
73
73
  go: [target: TSetupTarget];
74
74
  network: [];
75
+ /** "Setup 5/8" once worked out, so the host can show it beside its site views. */
76
+ progress: [progress: { done: number; total: number }];
75
77
  }>();
76
78
 
77
79
  const TONE: Record<TSetupStatus, string> = { done: "success", action: "warning", waiting: "info", check: "neutral" };
@@ -146,6 +148,7 @@ const steps = computed(() =>
146
148
  }),
147
149
  );
148
150
  const progress = computed(() => setupProgress(steps.value));
151
+ watch([loaded, progress], () => loaded.value && emit("progress", progress.value), { immediate: true });
149
152
  const next = computed(() => (loaded.value ? steps.value.find((s) => !s.optional && s.key !== "ready" && s.status !== "done") ?? null : null));
150
153
 
151
154
  function go(target: TSetupTarget) {
@@ -46,6 +46,7 @@
46
46
  :back-to-network="backToNetwork"
47
47
  @go="onSetupGo"
48
48
  @network="emit('network')"
49
+ @progress="(p) => emit('setupProgress', p)"
49
50
  />
50
51
  <RobotBuildingMap
51
52
  v-else-if="view === 'map'"
@@ -200,6 +201,8 @@ const emit = defineEmits<{
200
201
  * (fleet / map / lifts / setup) or the client's details page ("client").
201
202
  */
202
203
  navigate: [target: string];
204
+ /** Super Admin setup: required steps done of total, once the setup view has worked it out. */
205
+ setupProgress: [progress: { done: number; total: number }];
203
206
  /** Live feed health + open faults, for a host drawing its own header. */
204
207
  status: [status: { connected: boolean; faults: number }];
205
208
  }>();
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@7365admin1/layer-common",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "4.124.1",
5
+ "version": "4.124.3",
6
6
  "author": "7365admin1",
7
7
  "main": "./nuxt.config.ts",
8
8
  "//files": "What a consumer extending this layer actually loads. Without this npm ships the whole working tree - the changesets, the CI workflows, the render harness in tools/ and any scratch directory that happened to exist at publish time. Nuxt resolves a layer by directory, so every runtime directory below has to stay listed; adding a new top-level runtime directory means adding it here too.",
@@ -1767,7 +1767,7 @@ export function commandConfirm(
1767
1767
  return: `${who} stops what it is doing and drives back to its charger.`,
1768
1768
  pause: `${who} stops where it is and waits. Press Resume to carry on.`,
1769
1769
  resume: `${who} carries on with the job it paused.`,
1770
- cancel: `${who} stops the current job and stays where it is. It will not carry on by itself.`,
1770
+ cancel: `${who} stops the current job and drives back to its charger. Choose "Stop here" to leave it where it stops instead.`,
1771
1771
  navigate: at ? `${who} drives to ${at}.` : `${who} drives to the point you pick.`,
1772
1772
  relocalize: at
1773
1773
  ? `${who} is told it is standing at ${at}. Only do this if it really is there - a wrong position gets it lost.`