@7365admin1/layer-common 4.122.2 → 4.122.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 +10 -4
- package/components/Robot/LiftQueue.vue +5 -2
- package/package.json +1 -1
- package/utils/robot-building.ts +35 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @iservice365/layer-common
|
|
2
2
|
|
|
3
|
+
## 4.122.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6d9f5ad: Lift queue: when no robot ride is being drawn and the lift's read-only gateway is connected, the car in the shaft now follows the real lift - it moves to the lift's current floor, the doors open and close with the lift's door state, the car shows an up/down arrow while moving, and it turns the alert colour in fire/emergency modes. Before, the card text updated but the car only ever moved for robot rides.
|
|
8
|
+
|
|
3
9
|
## 4.122.2
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -3240,11 +3246,11 @@ Monthly report: a month that had patrols opens the list of that month's patrol r
|
|
|
3240
3246
|
`utils/console-tier.ts` + `composables/useConsoleTier.ts` mirror the server's
|
|
3241
3247
|
own rule from two endpoints the console already calls, unprojected:
|
|
3242
3248
|
|
|
3243
|
-
|
|
3244
|
-
|
|
3249
|
+
GET /api/members/user/:user/app/admin the Seven365 staff membership
|
|
3250
|
+
GET /api/roles/id/:role that membership's role document
|
|
3245
3251
|
|
|
3246
|
-
|
|
3247
|
-
|
|
3252
|
+
owner = member.type === "admin" && role.type === "admin" && role.default === true
|
|
3253
|
+
staff = member.type === "admin" && role.type === "admin"
|
|
3248
3254
|
|
|
3249
3255
|
`role.default` is the marker because it is the only property of a platform
|
|
3250
3256
|
staff role no API caller can set - `role.controller.ts` validates create and
|
|
@@ -85,10 +85,13 @@
|
|
|
85
85
|
<div
|
|
86
86
|
class="hero-lift__carbox"
|
|
87
87
|
:class="`hero-lift__carbox--${l.carTone}`"
|
|
88
|
-
:style="{ height: `${l.carH}px`, top: `${l.fromTop}px`, '--from': `${l.fromTop}px`, '--to': `${l.toTop}px`, animation: l.riding ? 'heroLift 6s ease-in-out infinite alternate' : 'none' }"
|
|
88
|
+
:style="{ height: `${l.carH}px`, top: `${l.fromTop}px`, '--from': `${l.fromTop}px`, '--to': `${l.toTop}px`, animation: l.riding ? 'heroLift 6s ease-in-out infinite alternate' : 'none', transition: l.live ? 'top 1.8s linear' : 'none' }"
|
|
89
89
|
>
|
|
90
90
|
<span class="hero-lift__carlabel">{{ l.carLabel }}</span>
|
|
91
|
-
<div
|
|
91
|
+
<div
|
|
92
|
+
class="hero-lift__doors"
|
|
93
|
+
:style="l.live ? { transform: `scaleX(${1 - l.doors})`, transition: 'transform 0.8s ease' } : { animation: l.riding ? 'heroDoors 6s ease-in-out infinite' : 'none' }"
|
|
94
|
+
/>
|
|
92
95
|
</div>
|
|
93
96
|
</div>
|
|
94
97
|
</div>
|
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.122.
|
|
5
|
+
"version": "4.122.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.",
|
package/utils/robot-building.ts
CHANGED
|
@@ -1460,6 +1460,21 @@ export function liftQueueRows(lift: Record<string, any>, now = Date.now()): TLif
|
|
|
1460
1460
|
const ROW_H = 44;
|
|
1461
1461
|
const CAR_H = ROW_H - 14;
|
|
1462
1462
|
|
|
1463
|
+
/**
|
|
1464
|
+
* A floor as the real lift shows it ("B1", "L34", "34", "G") -> the car's y on the rails. Between two rails
|
|
1465
|
+
* (a floor the map has no rail for) the car sits proportionally between them; past the ends it sits on the end.
|
|
1466
|
+
*/
|
|
1467
|
+
export function liftFloorTop(display: unknown, floors: number[], topOf: (f: number) => number): number | null {
|
|
1468
|
+
const parsed = newFloorNo(String(display ?? "").replace(/\s+/g, ""), []);
|
|
1469
|
+
if (!("floorNo" in parsed) || !floors.length) return null;
|
|
1470
|
+
const v = parsed.floorNo;
|
|
1471
|
+
if (v <= floors[0]!) return topOf(floors[0]!);
|
|
1472
|
+
if (v >= floors.at(-1)!) return topOf(floors.at(-1)!);
|
|
1473
|
+
const i = floors.findIndex((f) => f >= v);
|
|
1474
|
+
const lo = floors[i - 1]!, hi = floors[i]!;
|
|
1475
|
+
return topOf(lo) + ((v - lo) / (hi - lo)) * (topOf(hi) - topOf(lo));
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1463
1478
|
/** The whole card: header words, car status, shaft geometry, rows (README §5). */
|
|
1464
1479
|
export function liftCard(lift: Record<string, any>, now = Date.now()) {
|
|
1465
1480
|
const rows = liftQueueRows(lift, now);
|
|
@@ -1472,23 +1487,37 @@ export function liftCard(lift: Record<string, any>, now = Date.now()) {
|
|
|
1472
1487
|
const rest = floors.includes(idleFloor) ? idleFloor : floors[0] ?? 1;
|
|
1473
1488
|
const from = riding ? riding.fromNo : rest;
|
|
1474
1489
|
const to = riding ? riding.toNo : rest;
|
|
1490
|
+
// The real lift (read-only gateway), when no robot ride is drawn: the car follows its floor, doors and direction.
|
|
1491
|
+
const gw = lift?.gateway;
|
|
1492
|
+
const real = !riding && gw?.status === "connected" && gw.state ? gw.state : null;
|
|
1493
|
+
const realTop = real ? liftFloorTop(real.currentFloor, floors, topOf) : null;
|
|
1494
|
+
const live = realTop != null;
|
|
1495
|
+
const realAlarm = live && [3, 4, 5].includes(Number(real.currentMode));
|
|
1496
|
+
const arrow = live ? (real.motionState === 1 ? "▲" : real.motionState === 2 ? "▼" : "") : "";
|
|
1475
1497
|
return {
|
|
1476
1498
|
name: String(lift?.liftName ?? "Lift"),
|
|
1477
1499
|
sub: rows.length ? `${riding ? 1 : 0} riding · ${waiting.length} waiting` : "idle",
|
|
1478
|
-
carText: riding
|
|
1479
|
-
|
|
1480
|
-
|
|
1500
|
+
carText: riding
|
|
1501
|
+
? `Car · ${riding.robot} · ${riding.from} → ${riding.to}`
|
|
1502
|
+
: live
|
|
1503
|
+
? `Car · floor ${real.currentFloor}${MOTION_TEXT[real.motionState] ? ` · ${MOTION_TEXT[real.motionState]!.toLowerCase()}` : ""}`
|
|
1504
|
+
: "Car idle",
|
|
1505
|
+
carLabel: riding ? riding.robot.replace(/^HERO-/, "") : arrow,
|
|
1506
|
+
carTone: riding ? "ink" : realAlarm || rows.some((r) => r.state === "timed out") ? "accent" : live ? "ink" : "neutral",
|
|
1507
|
+
/** Real lift drawn live: the car glides between readings; doors open (1) / half (0.5, moving) / shut (0). */
|
|
1508
|
+
live,
|
|
1509
|
+
doors: live ? (real.doorState === 2 ? 1 : real.doorState === 1 ? 0.5 : 0) : 0,
|
|
1481
1510
|
riding: !!riding,
|
|
1482
1511
|
empty: !rows.length,
|
|
1483
1512
|
shaftH: (n - 1) * ROW_H + 24,
|
|
1484
1513
|
carH: CAR_H,
|
|
1485
|
-
fromTop: topOf(from) - CAR_H / 2,
|
|
1486
|
-
toTop: topOf(to) - CAR_H / 2,
|
|
1514
|
+
fromTop: (live ? realTop! : topOf(from)) - CAR_H / 2,
|
|
1515
|
+
toTop: (live ? realTop! : topOf(to)) - CAR_H / 2,
|
|
1487
1516
|
rails: [...floors].reverse().map((f) => ({
|
|
1488
1517
|
floorNo: f,
|
|
1489
1518
|
name: floorName(f),
|
|
1490
1519
|
top: topOf(f),
|
|
1491
|
-
lit:
|
|
1520
|
+
lit: riding ? f === riding.fromNo || f === riding.toNo : live && realTop === topOf(f),
|
|
1492
1521
|
waiting: waiting.filter((w) => w.fromNo === f).map((w) => w.robot),
|
|
1493
1522
|
})),
|
|
1494
1523
|
rows,
|