@pisell/private-materials 6.12.257 → 6.12.259

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 (33) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/meta.js +1 -1
  5. package/build/lowcode/render/default/view.js +3 -3
  6. package/build/lowcode/view.js +3 -3
  7. package/es/components/HDLKiosk/runtime/application.js +12 -2
  8. package/es/components/HDLKiosk/runtime/triggers.js +52 -17
  9. package/es/components/bigSale/templates/HDLKiosk/BigSaleScaleRuntimeOwner.js +35 -7
  10. package/es/components/bigSale/templates/HDLKiosk/index.js +2 -1
  11. package/es/components/venueBooking/components/Checkout/index.js +1 -1
  12. package/es/components/venueBooking/components/Content/index.js +1 -1
  13. package/es/components/venueBooking/components/Header/index.js +5 -5
  14. package/es/components/venueBooking/components/VenueSelection/components/CourtFilter.js +1 -1
  15. package/es/components/venueBooking/components/VenueSelection/components/DateNavigator.js +3 -3
  16. package/es/components/venueBooking/components/VenueSelection/components/DayTabs.js +2 -2
  17. package/es/components/venueBooking/components/VenueSelection/components/MonthPicker.js +4 -4
  18. package/es/components/venueBooking/components/VenueSelection/components/TimeGrid.js +14 -14
  19. package/es/components/venueBooking/components/VenueSelection/index.js +2 -2
  20. package/lib/components/HDLKiosk/runtime/application.js +12 -2
  21. package/lib/components/HDLKiosk/runtime/triggers.js +52 -17
  22. package/lib/components/bigSale/templates/HDLKiosk/BigSaleScaleRuntimeOwner.js +35 -7
  23. package/lib/components/bigSale/templates/HDLKiosk/index.js +2 -1
  24. package/lib/components/venueBooking/components/Checkout/index.js +1 -1
  25. package/lib/components/venueBooking/components/Content/index.js +1 -1
  26. package/lib/components/venueBooking/components/Header/index.js +5 -5
  27. package/lib/components/venueBooking/components/VenueSelection/components/CourtFilter.js +1 -1
  28. package/lib/components/venueBooking/components/VenueSelection/components/DateNavigator.js +3 -3
  29. package/lib/components/venueBooking/components/VenueSelection/components/DayTabs.js +2 -2
  30. package/lib/components/venueBooking/components/VenueSelection/components/MonthPicker.js +4 -4
  31. package/lib/components/venueBooking/components/VenueSelection/components/TimeGrid.js +14 -14
  32. package/lib/components/venueBooking/components/VenueSelection/index.js +2 -2
  33. package/package.json +3 -3
@@ -15,6 +15,7 @@ const hdlKioskApplication = hdlKioskDefinition.implement({
15
15
  createEnvironment: ({ host, config }) => Object.freeze({
16
16
  host,
17
17
  config,
18
+ scaleEntry: { readPhase: () => "inactive" },
18
19
  sessionActivity: { notify: (_sessionId) => void 0 },
19
20
  scanner: createScannerSessionRouter({
20
21
  host,
@@ -22,7 +23,7 @@ const hdlKioskApplication = hdlKioskDefinition.implement({
22
23
  })
23
24
  }),
24
25
  disposeEnvironment: ({ scanner }) => scanner.dispose(),
25
- triggerAdapters: ({ environment }) => createHDLKioskEntryTriggerAdapters(environment.host, environment.config, environment.scanner.triggerAdapter),
26
+ triggerAdapters: ({ environment }) => createHDLKioskEntryTriggerAdapters(environment.host, environment.config, environment.scanner.triggerAdapter, () => environment.scaleEntry.readPhase()),
26
27
  admission: ({ workflowKey, cause, environment }) => evaluateHDLKioskAdmission({
27
28
  entry: workflowKey,
28
29
  enabledEntry: cause.trigger === "onScan" ? "barcode" : workflowKey,
@@ -64,7 +65,16 @@ const hdlKioskApplication = hdlKioskDefinition.implement({
64
65
  }
65
66
  },
66
67
  maxActiveSessions: 1,
67
- exposeRuntime: ({ runtime, environment }) => createHDLKioskExposedRuntime(runtime, environment)
68
+ exposeRuntime: ({ runtime, environment }) => {
69
+ environment.scaleEntry.readPhase = () => {
70
+ const snapshot = runtime.getSnapshot();
71
+ if (snapshot.state !== "active") return "inactive";
72
+ if (snapshot.pendingStartCount > 0) return "starting";
73
+ if (snapshot.sessions.length > 0) return "flow";
74
+ return "entry";
75
+ };
76
+ return createHDLKioskExposedRuntime(runtime, environment);
77
+ }
68
78
  });
69
79
  //#endregion
70
80
  export { hdlKioskApplication };
@@ -1,25 +1,60 @@
1
1
  import { createScaleIngress } from "./devices/scaleIngress.js";
2
2
  //#region src/components/HDLKiosk/runtime/triggers.ts
3
- function createHDLKioskEntryTriggerAdapters(host, config, scannerTriggerAdapter) {
3
+ function createHDLKioskEntryTriggerAdapters(host, config, scannerTriggerAdapter, readScaleEntryPhase = () => "entry") {
4
4
  const scaleIngress = createScaleIngress();
5
5
  const onWeight = Object.freeze({
6
6
  trigger: "onWeight",
7
- activate: ({ emit }) => host.devices.subscribe((event) => {
8
- if (event.type !== "weightChanged") return;
9
- const accepted = scaleIngress.accept(event, {
10
- active: true,
11
- supported: config.enabledEntries.includes("scale") && Boolean(config.primaryWeightedProductId) && host.capabilities.scale.available && host.capabilities.scale.weightChangeTrigger,
12
- workflowLocked: false,
13
- nodeAcceptsEvent: true,
14
- paymentFrozen: false
15
- });
16
- if (accepted.status !== "accepted") return;
17
- emit({
18
- channel: "weighing-product",
19
- occurrenceId: accepted.event.eventId,
20
- correlationId: `device:scale:${accepted.event.eventId}`
21
- });
22
- }, { sources: ["scale"] })
7
+ activate: ({ emit }) => {
8
+ let lastIgnoredPhase;
9
+ return host.devices.subscribe((event) => {
10
+ if (event.type !== "weightChanged") return;
11
+ const phase = readScaleEntryPhase();
12
+ const log = (name, status, reason = "") => {
13
+ try {
14
+ var _event$weight$status;
15
+ host.telemetry.emit({
16
+ name,
17
+ traceId: `device:scale:${event.eventId}`,
18
+ occurredAt: Date.now(),
19
+ attributes: {
20
+ eventId: event.eventId,
21
+ changedAt: event.weight.changedAt,
22
+ grossWeight: event.weight.gross,
23
+ unit: event.weight.unit,
24
+ scaleStatus: (_event$weight$status = event.weight.status) !== null && _event$weight$status !== void 0 ? _event$weight$status : "unknown",
25
+ phase,
26
+ status,
27
+ reason,
28
+ minimumWeightKg: config.scaleTriggerMinimumWeightKg
29
+ }
30
+ });
31
+ } catch (_unused) {}
32
+ };
33
+ if (phase !== "entry") {
34
+ if (lastIgnoredPhase !== phase) log("hdlKiosk.scale.entryDecision", "ignored", phase);
35
+ lastIgnoredPhase = phase;
36
+ return;
37
+ }
38
+ lastIgnoredPhase = void 0;
39
+ const accepted = scaleIngress.accept(event, {
40
+ active: true,
41
+ supported: config.enabledEntries.includes("scale") && Boolean(config.primaryWeightedProductId) && host.capabilities.scale.available && host.capabilities.scale.weightChangeTrigger,
42
+ workflowLocked: false,
43
+ nodeAcceptsEvent: true,
44
+ paymentFrozen: false
45
+ });
46
+ if (accepted.status !== "accepted") {
47
+ log("hdlKiosk.scale.entryDecision", "rejected", accepted.reason);
48
+ return;
49
+ }
50
+ log("hdlKiosk.scale.entryDecision", "accepted");
51
+ emit({
52
+ channel: "weighing-product",
53
+ occurrenceId: accepted.event.eventId,
54
+ correlationId: `device:scale:${accepted.event.eventId}`
55
+ }).then((result) => log("hdlKiosk.scale.startFinished", result.status, result.status === "rejected" ? result.reason : ""), () => log("hdlKiosk.scale.startFinished", "failed", "unexpectedFailure"));
56
+ }, { sources: ["scale"] });
57
+ }
23
58
  });
24
59
  return Object.freeze([scannerTriggerAdapter, onWeight]);
25
60
  }
@@ -44,8 +44,8 @@ function BigSaleScaleRuntimeOwner(props) {
44
44
  occurredAt: Date.now()
45
45
  }) }, /* @__PURE__ */ React.createElement(ActiveScaleRuntimeOwner, _objectSpread2(_objectSpread2({}, props), {}, { useNativeScale })));
46
46
  }
47
- function ActiveScaleRuntimeOwner({ active, bridge, minimumWeightKg, useNativeScale }) {
48
- const consumedReadingRef = useRef(false);
47
+ function ActiveScaleRuntimeOwner({ active, bridge, minimumWeightKg, useNativeScale, telemetry }) {
48
+ const lastEmittedWeightRef = useRef(void 0);
49
49
  const lastConnectionStateRef = useRef();
50
50
  const eventSequenceRef = useRef(0);
51
51
  const [sample, setSample] = useState({
@@ -71,6 +71,7 @@ function ActiveScaleRuntimeOwner({ active, bridge, minimumWeightKg, useNativeSca
71
71
  }, [active, bridge]);
72
72
  useEffect(() => {
73
73
  if (!active) return;
74
+ const previous = bridge.runtime.getSnapshot();
74
75
  bridge.runtime.publish(bridge.ownerId, {
75
76
  grossWeightKg: scale.grossWeight,
76
77
  status: scale.status,
@@ -80,6 +81,29 @@ function ActiveScaleRuntimeOwner({ active, bridge, minimumWeightKg, useNativeSca
80
81
  error: scale.error,
81
82
  sampleSequence: sample.sequence
82
83
  });
84
+ const current = bridge.runtime.getSnapshot();
85
+ if (previous.grossWeightKg !== current.grossWeightKg || previous.status !== current.status || previous.connectionState !== current.connectionState || previous.hasLiveSample !== current.hasLiveSample) try {
86
+ var _scale$rawData$weight, _scale$rawData2, _previous$grossWeight, _current$grossWeightK, _current$status, _current$connectionSt;
87
+ telemetry === null || telemetry === void 0 || telemetry.emit({
88
+ name: "hdlKiosk.scale.readingChanged",
89
+ traceId: `${bridge.ownerId}:sample:${sample.sequence}`,
90
+ occurredAt: Date.now(),
91
+ attributes: {
92
+ ownerId: bridge.ownerId,
93
+ sampleSequence: sample.sequence,
94
+ receivedAt: sample.receivedAt,
95
+ rawWeightGrams: String((_scale$rawData$weight = (_scale$rawData2 = scale.rawData) === null || _scale$rawData2 === void 0 ? void 0 : _scale$rawData2.weight) !== null && _scale$rawData$weight !== void 0 ? _scale$rawData$weight : ""),
96
+ previousGrossWeightKg: String((_previous$grossWeight = previous.grossWeightKg) !== null && _previous$grossWeight !== void 0 ? _previous$grossWeight : ""),
97
+ grossWeightKg: String((_current$grossWeightK = current.grossWeightKg) !== null && _current$grossWeightK !== void 0 ? _current$grossWeightK : ""),
98
+ status: (_current$status = current.status) !== null && _current$status !== void 0 ? _current$status : "unknown",
99
+ connectionState: (_current$connectionSt = current.connectionState) !== null && _current$connectionSt !== void 0 ? _current$connectionSt : "unknown",
100
+ isListening: current.isListening,
101
+ hasLiveSample: current.hasLiveSample,
102
+ hasError: Boolean(current.error),
103
+ minimumWeightKg
104
+ }
105
+ });
106
+ } catch (_unused) {}
83
107
  }, [
84
108
  active,
85
109
  bridge,
@@ -89,7 +113,10 @@ function ActiveScaleRuntimeOwner({ active, bridge, minimumWeightKg, useNativeSca
89
113
  scale.isListening,
90
114
  scale.rawData,
91
115
  scale.status,
92
- sample.sequence
116
+ sample.sequence,
117
+ sample.receivedAt,
118
+ minimumWeightKg,
119
+ telemetry
93
120
  ]);
94
121
  useEffect(() => {
95
122
  if (!active) {
@@ -112,15 +139,15 @@ function ActiveScaleRuntimeOwner({ active, bridge, minimumWeightKg, useNativeSca
112
139
  ]);
113
140
  useEffect(() => {
114
141
  if (!active) return;
115
- if (inspection.belowTriggerThreshold) {
116
- consumedReadingRef.current = false;
142
+ if (inspection.belowTriggerThreshold || scale.status === "negative" || scale.status === "overload") {
143
+ lastEmittedWeightRef.current = void 0;
117
144
  return;
118
145
  }
119
- if (consumedReadingRef.current) return;
120
146
  if (!bridge.runtime.getSnapshot().hasLiveSample) return;
121
147
  const grossWeight = inspection.validGrossWeightKg;
122
148
  if (grossWeight === void 0) return;
123
- consumedReadingRef.current = true;
149
+ if (lastEmittedWeightRef.current === grossWeight) return;
150
+ lastEmittedWeightRef.current = grossWeight;
124
151
  eventSequenceRef.current += 1;
125
152
  const occurredAt = sample.receivedAt || Date.now();
126
153
  bridge.publishWeightChange({
@@ -139,6 +166,7 @@ function ActiveScaleRuntimeOwner({ active, bridge, minimumWeightKg, useNativeSca
139
166
  inspection.belowTriggerThreshold,
140
167
  inspection.validGrossWeightKg,
141
168
  sample.receivedAt,
169
+ sample.sequence,
142
170
  scale.status
143
171
  ]);
144
172
  return null;
@@ -128,7 +128,8 @@ function HDLKioskBigSaleTemplate({ isActive = true, context, businessCode, local
128
128
  active: isActive && (config.enabledEntries.includes("scale") || config.enabledEntries.includes("quick") || config.enabledEntries.includes("barcode")) && Boolean(config.primaryWeightedProductId),
129
129
  bridge: scaleBridge,
130
130
  nativeScaleTools,
131
- minimumWeightKg: config.scaleTriggerMinimumWeightKg
131
+ minimumWeightKg: config.scaleTriggerMinimumWeightKg,
132
+ telemetry: host.telemetry
132
133
  }), /* @__PURE__ */ React.createElement(HDLKiosk, {
133
134
  host,
134
135
  config,
@@ -85,7 +85,7 @@ function Checkout() {
85
85
  setNoteValue(nextNote);
86
86
  lastNoteRef.current = nextNote;
87
87
  }, [viewModel.note]);
88
- return /* @__PURE__ */ React.createElement("div", { className: "space-y-3 md:space-y-5" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] bg-white p-4 shadow-[0_10px_40px_rgba(20,20,20,0.06)] ring-1 ring-black/6 md:rounded-[28px] md:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-[22px] font-extrabold text-zinc-900" }, locales.getText("pisell2.venue.checkout.court.summary") || "场地预订摘要"))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] bg-[#faf7f4] p-4 ring-1 ring-black/6 md:col-span-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-[#a69183]" }, locales.getText("pisell2.venue.checkout.selected.courts") || "已选场地"), /* @__PURE__ */ React.createElement("div", { className: "mt-3 space-y-2 text-[15px] font-semibold text-zinc-900" }, mergedCourtSessionLines.length ? mergedCourtSessionLines.map((line, idx) => /* @__PURE__ */ React.createElement("div", { key: `venue-session-line-${idx}` }, line)) : /* @__PURE__ */ React.createElement("div", null, locales.getText("pisell2.venue.checkout.sessions.empty") || "-"))), addonCartItems.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] bg-[#faf7f4] p-4 ring-1 ring-black/6" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-[#a69183]" }, locales.getText("pisell2.venue.checkout.addons") || "附加项"), /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-[15px] font-semibold text-zinc-900" }, addonCartItems.map((item, idx) => /* @__PURE__ */ React.createElement("div", { key: `addon-${item.id || idx}` }, item.title || item.name || "-")))) : null)), /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] bg-white p-5 shadow-[0_10px_40px_rgba(20,20,20,0.06)] ring-1 ring-black/6 md:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "mt-5 rounded-[22px] bg-[#faf7f4] p-4 ring-1 ring-black/6" }, /* @__PURE__ */ React.createElement("div", { className: "text-lg font-bold text-zinc-900" }, locales.getText("pisell2.venue.checkout.notice") || "备注"), /* @__PURE__ */ React.createElement("textarea", {
88
+ return /* @__PURE__ */ React.createElement("div", { className: "space-y-3 md:space-y-5" }, /* @__PURE__ */ React.createElement("div", { className: "grid gap-3 md:gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] bg-white p-4 md:rounded-[28px] md:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-[22px] font-extrabold text-zinc-900" }, locales.getText("pisell2.venue.checkout.court.summary") || "场地预订摘要"))), /* @__PURE__ */ React.createElement("div", { className: "mt-5 grid gap-4 md:grid-cols-2" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] bg-[#faf7f4] p-4 md:col-span-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-[#a69183]" }, locales.getText("pisell2.venue.checkout.selected.courts") || "已选场地"), /* @__PURE__ */ React.createElement("div", { className: "mt-3 space-y-2 text-[15px] font-semibold text-zinc-900" }, mergedCourtSessionLines.length ? mergedCourtSessionLines.map((line, idx) => /* @__PURE__ */ React.createElement("div", { key: `venue-session-line-${idx}` }, line)) : /* @__PURE__ */ React.createElement("div", null, locales.getText("pisell2.venue.checkout.sessions.empty") || "-"))), addonCartItems.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "rounded-[22px] bg-[#faf7f4] p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold text-[#a69183]" }, locales.getText("pisell2.venue.checkout.addons") || "附加项"), /* @__PURE__ */ React.createElement("div", { className: "mt-3 text-[15px] font-semibold text-zinc-900" }, addonCartItems.map((item, idx) => /* @__PURE__ */ React.createElement("div", { key: `addon-${item.id || idx}` }, item.title || item.name || "-")))) : null)), /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-[28px] bg-white p-5 md:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "mt-5 rounded-[22px] bg-[#faf7f4] p-4" }, /* @__PURE__ */ React.createElement("div", { className: "text-lg font-bold text-zinc-900" }, locales.getText("pisell2.venue.checkout.notice") || "备注"), /* @__PURE__ */ React.createElement("textarea", {
89
89
  className: "mt-4 min-h-[120px] w-full rounded-[20px] border border-black/10 bg-white px-4 py-4 text-sm outline-none placeholder:text-zinc-400",
90
90
  value: noteValue,
91
91
  onChange: (e) => setNoteValue(e.target.value),
@@ -115,7 +115,7 @@ function Content() {
115
115
  ref: stepHeaderRef,
116
116
  className: "sticky top-0 z-40"
117
117
  }, /* @__PURE__ */ React.createElement(Header, null)), /* @__PURE__ */ React.createElement("div", { className: "grid max-w-full gap-2 md:gap-4 lg:grid-cols-[minmax(0,1fr)_390px] xl:grid-cols-[minmax(0,1fr)_420px]" }, /* @__PURE__ */ React.createElement("section", { className: "min-w-0 space-y-3 overscroll-none md:space-y-5" }, stepRegistry[currentStep]), /* @__PURE__ */ React.createElement("aside", {
118
- className: "hidden lg:block sticky self-start z-10 rounded-[28px] bg-white shadow-[0_10px_40px_rgba(20,20,20,0.06)] ring-1 ring-black/6",
118
+ className: "hidden lg:block sticky self-start z-10 rounded-[28px] bg-white",
119
119
  style: { top: "calc(var(--vb-grid-sticky-top, 0px) + 1.5rem)" }
120
120
  }, /* @__PURE__ */ React.createElement(Cart, {
121
121
  embedded: true,
@@ -94,7 +94,7 @@ function Header() {
94
94
  });
95
95
  return /* @__PURE__ */ React.createElement("div", {
96
96
  ref: cardRef,
97
- className: "relative bg-white p-3 md:rounded-[24px] md:p-4 ring-1 ring-black/6 shadow-[0_10px_30px_rgba(20,20,20,0.04)]"
97
+ className: "relative bg-white p-3 md:rounded-[24px] md:p-4"
98
98
  }, /* @__PURE__ */ React.createElement(Modal, {
99
99
  open: confirmOpen,
100
100
  onCancel: () => setConfirmOpen(false),
@@ -138,7 +138,7 @@ function Header() {
138
138
  }, /* @__PURE__ */ React.createElement("p", { className: "text-sm text-zinc-500" }, String(locales.getText("pisell2.venue.leave.desc") || "Your selections will be lost if you leave now."))), popupOpen && backSteps.length > 0 ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", {
139
139
  className: "fixed inset-0 z-40 md:hidden",
140
140
  onClick: () => setPopupOpen(false)
141
- }), /* @__PURE__ */ React.createElement("div", { className: "absolute left-4 right-4 top-full z-50 mt-2 overflow-hidden rounded-2xl bg-white shadow-[0_8px_30px_rgba(20,20,20,0.12)] ring-1 ring-black/6 md:hidden" }, backSteps.map((item, idx) => /* @__PURE__ */ React.createElement("button", {
141
+ }), /* @__PURE__ */ React.createElement("div", { className: "absolute left-4 right-4 top-full z-50 mt-2 overflow-hidden rounded-2xl bg-white shadow-[0_8px_30px_rgba(20,20,20,0.12)] ring-1 ring-black/[0.06] md:hidden" }, backSteps.map((item, idx) => /* @__PURE__ */ React.createElement("button", {
142
142
  key: item.key,
143
143
  type: "button",
144
144
  onClick: () => {
@@ -150,7 +150,7 @@ function Header() {
150
150
  type: "button",
151
151
  "aria-label": "Back",
152
152
  onClick: handleBack,
153
- className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-zinc-50 text-zinc-700 ring-1 ring-black/10 transition hover:bg-zinc-100"
153
+ className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-zinc-50 text-zinc-700 transition hover:bg-zinc-100"
154
154
  }, /* @__PURE__ */ React.createElement("svg", {
155
155
  viewBox: "0 0 24 24",
156
156
  className: "h-5 w-5",
@@ -191,7 +191,7 @@ function Header() {
191
191
  className: `flex items-center gap-3 rounded-full px-3 py-2 transition ${status === "done" ? "bg-zinc-50" : status !== "active" ? "bg-zinc-50/80" : ""} ${clickable ? "cursor-pointer hover:bg-zinc-100" : "cursor-default"}`,
192
192
  style: status === "active" ? { backgroundColor: "var(--vb-primary-light)" } : void 0
193
193
  }, /* @__PURE__ */ React.createElement("div", {
194
- className: `flex h-8 w-8 items-center justify-center rounded-full text-sm font-bold ${status === "done" ? "bg-[#111] text-white" : status === "active" ? "text-white" : "bg-white text-zinc-400 ring-1 ring-black/8"}`,
194
+ className: `flex h-8 w-8 items-center justify-center rounded-full text-sm font-bold ${status === "done" ? "bg-[#111] text-white" : status === "active" ? "text-white" : "bg-white text-zinc-400"}`,
195
195
  style: status === "active" ? { backgroundColor: "var(--vb-primary)" } : void 0
196
196
  }, status === "done" ? /* @__PURE__ */ React.createElement(Iconfont, {
197
197
  type: "pisell2-check",
@@ -204,7 +204,7 @@ function Header() {
204
204
  type: "button",
205
205
  "aria-label": "Close",
206
206
  onClick: setConfirmOpen.bind(null, true),
207
- className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-zinc-50 text-zinc-700 ring-1 ring-black/10 transition hover:bg-zinc-100"
207
+ className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-zinc-50 text-zinc-700 transition hover:bg-zinc-100"
208
208
  }, /* @__PURE__ */ React.createElement("svg", {
209
209
  viewBox: "0 0 24 24",
210
210
  className: "h-5 w-5",
@@ -24,7 +24,7 @@ function CourtFilter() {
24
24
  return /* @__PURE__ */ React.createElement("div", { className: "mt-4 grid gap-3 md:mt-5 xl:grid-cols-[1fr_auto] xl:items-center" }, courtTypes.length > 1 ? /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, filterOptions.map((opt) => /* @__PURE__ */ React.createElement("button", {
25
25
  key: opt.value,
26
26
  onClick: () => setFilter(opt.value),
27
- className: `rounded-full px-4 py-2 text-sm font-semibold transition ${filter === opt.value ? "text-white" : "bg-[#fafafa] text-zinc-700 ring-1 ring-black/8"}`,
27
+ className: `rounded-full px-4 py-2 text-sm font-semibold transition ${filter === opt.value ? "text-white" : "bg-[#fafafa] text-zinc-700"}`,
28
28
  style: filter === opt.value ? { backgroundColor: "var(--vb-primary)" } : void 0
29
29
  }, opt.label))) : null);
30
30
  }
@@ -27,16 +27,16 @@ function DateNavigator({ onPrevWeek, onNextWeek }) {
27
27
  return _goToday.apply(this, arguments);
28
28
  }
29
29
  return /* @__PURE__ */ React.createElement("div", { className: "relative flex w-full items-center gap-2 xl:w-auto" }, /* @__PURE__ */ React.createElement("button", {
30
- className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-[#fafafa] ring-1 ring-black/8 md:h-12 md:w-12",
30
+ className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-[#fafafa] md:h-12 md:w-12",
31
31
  onClick: onPrevWeek
32
32
  }, /* @__PURE__ */ React.createElement(Iconfont, {
33
33
  type: "pisell2-chevron-left",
34
34
  style: { fontSize: 18 }
35
35
  })), /* @__PURE__ */ React.createElement("button", {
36
- className: "min-w-0 flex-1 rounded-2xl bg-[#fafafa] px-4 py-3 text-sm font-bold text-zinc-900 ring-1 ring-black/8 xl:min-w-[200px] xl:flex-none",
36
+ className: "min-w-0 flex-1 rounded-2xl bg-[#fafafa] px-4 py-3 text-sm font-bold text-zinc-900 xl:min-w-[200px] xl:flex-none",
37
37
  onClick: () => setMonthPickerOpen(!monthPickerOpen)
38
38
  }, getMonthLabel(anchorDate)), /* @__PURE__ */ React.createElement("button", {
39
- className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-[#fafafa] ring-1 ring-black/8 md:h-12 md:w-12",
39
+ className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-[#fafafa] md:h-12 md:w-12",
40
40
  onClick: onNextWeek
41
41
  }, /* @__PURE__ */ React.createElement(Iconfont, {
42
42
  type: "pisell2-chevron-right",
@@ -34,7 +34,7 @@ function DayTabs({ onPrevWeek, onNextWeek }) {
34
34
  "aria-live": "polite"
35
35
  }, Array.from({ length: 7 }).map((_, idx) => /* @__PURE__ */ React.createElement("div", {
36
36
  key: `day-skeleton-${idx}`,
37
- className: "relative min-h-[56px] overflow-hidden rounded-[12px] bg-zinc-100 px-2 py-2 ring-1 ring-black/5 md:min-h-[60px] md:rounded-[16px] md:px-3 md:py-2"
37
+ className: "relative min-h-[56px] overflow-hidden rounded-[12px] bg-zinc-100 px-2 py-2 md:min-h-[60px] md:rounded-[16px] md:px-3 md:py-2"
38
38
  }, /* @__PURE__ */ React.createElement("div", { className: "h-2 w-8 rounded bg-zinc-200/90 md:h-2.5 md:w-10" }), /* @__PURE__ */ React.createElement("div", { className: "mt-2 flex items-end justify-between gap-1" }, /* @__PURE__ */ React.createElement("div", { className: "h-3 w-5 rounded bg-zinc-200/90 md:h-4 md:w-6" }), /* @__PURE__ */ React.createElement("div", { className: "h-2 w-8 rounded bg-zinc-200/90 md:h-2.5 md:w-10" })), /* @__PURE__ */ React.createElement("span", {
39
39
  className: "vb-skeleton-shimmer",
40
40
  "aria-hidden": "true"
@@ -86,7 +86,7 @@ function DayTabs({ onPrevWeek, onNextWeek }) {
86
86
  const active = key === currentKey;
87
87
  const meta = getDateMetaFromSummary(date, viewModel.dateSummary, symbol);
88
88
  const showSelectedBadge = selectedDateKeySet.has(key) && !active;
89
- const cardClass = meta.soldOut ? "bg-zinc-50 text-zinc-400 ring-1 ring-zinc-200" : active ? "text-white shadow-sm" : "bg-white text-zinc-800 ring-1 ring-black/8 hover:bg-zinc-50";
89
+ const cardClass = meta.soldOut ? "bg-zinc-50 text-zinc-400" : active ? "text-white shadow-sm" : "bg-white text-zinc-800 hover:bg-zinc-50";
90
90
  const cardStyle = !meta.soldOut && active ? { backgroundColor: "var(--vb-primary)" } : void 0;
91
91
  const tagClass = active ? "bg-white/15 text-white ring-white/20" : meta.topTag === "Promo" ? "bg-emerald-50 text-emerald-700 ring-emerald-200" : "bg-zinc-100 text-zinc-600 ring-zinc-200";
92
92
  return /* @__PURE__ */ React.createElement("button", {
@@ -39,14 +39,14 @@ function MonthPicker() {
39
39
  });
40
40
  return _handleSelect.apply(this, arguments);
41
41
  }
42
- return /* @__PURE__ */ React.createElement("div", { className: "absolute right-0 top-[calc(100%+12px)] z-30 w-[320px] rounded-[24px] border border-black/6 bg-white p-4 shadow-[0_20px_60px_rgba(20,20,20,0.14)]" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 flex items-center justify-between" }, /* @__PURE__ */ React.createElement("button", {
43
- className: "flex h-10 w-10 items-center justify-center rounded-2xl bg-[#fafafa] ring-1 ring-black/8 hover:bg-zinc-50",
42
+ return /* @__PURE__ */ React.createElement("div", { className: "absolute right-0 top-[calc(100%+12px)] z-30 w-[320px] rounded-[24px] border border-black/[0.06] bg-white p-4 shadow-[0_20px_60px_rgba(20,20,20,0.14)]" }, /* @__PURE__ */ React.createElement("div", { className: "mb-4 flex items-center justify-between" }, /* @__PURE__ */ React.createElement("button", {
43
+ className: "flex h-10 w-10 items-center justify-center rounded-2xl bg-[#fafafa] hover:bg-zinc-50",
44
44
  onClick: () => setMonthCursor(monthCursor.subtract(1, "month"))
45
45
  }, /* @__PURE__ */ React.createElement(Iconfont, {
46
46
  type: "pisell2-chevron-left",
47
47
  style: { fontSize: 16 }
48
48
  })), /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-zinc-900" }, getMonthLabel(monthCursor)), /* @__PURE__ */ React.createElement("button", {
49
- className: "flex h-10 w-10 items-center justify-center rounded-2xl bg-[#fafafa] ring-1 ring-black/8 hover:bg-zinc-50",
49
+ className: "flex h-10 w-10 items-center justify-center rounded-2xl bg-[#fafafa] hover:bg-zinc-50",
50
50
  onClick: () => setMonthCursor(monthCursor.add(1, "month"))
51
51
  }, /* @__PURE__ */ React.createElement(Iconfont, {
52
52
  type: "pisell2-chevron-right",
@@ -71,7 +71,7 @@ function MonthPicker() {
71
71
  const isPastDate = day.isBefore(todayStart, "day");
72
72
  const isDisabledBySummary = !(!knownDateRange ? true : day.isBefore(knownDateRange.minDate, "day") || day.isAfter(knownDateRange.maxDate, "day")) && meta.soldOut;
73
73
  const isDisabled = isPastDate || isDisabledBySummary;
74
- const cellClass = isDisabled ? "bg-zinc-50 text-zinc-400 ring-1 ring-zinc-200" : selected ? "text-white shadow-sm" : isToday ? "" : "bg-[#fafafa] text-zinc-700 ring-1 ring-black/6";
74
+ const cellClass = isDisabled ? "bg-zinc-50 text-zinc-400" : selected ? "text-white shadow-sm" : isToday ? "" : "bg-[#fafafa] text-zinc-700";
75
75
  const cellStyle = selected && !meta.soldOut ? { backgroundColor: "var(--vb-primary)" } : isToday && !meta.soldOut ? {
76
76
  backgroundColor: "var(--vb-primary-light)",
77
77
  color: "var(--vb-primary)"
@@ -180,16 +180,16 @@ function TimeGrid() {
180
180
  }
181
181
  if (isGridLoading || !grid || !timeLabels.length) return /* @__PURE__ */ React.createElement(TimeGridSkeleton, null);
182
182
  return /* @__PURE__ */ React.createElement("div", { className: "relative" }, /* @__PURE__ */ React.createElement("div", {
183
- className: "sticky z-30 overflow-hidden bg-[#fff7f7]",
183
+ className: "sticky z-30 overflow-hidden rounded-t-[28px] bg-[#fff7f7]",
184
184
  style: { top: "var(--vb-grid-sticky-top, 0px)" }
185
185
  }, /* @__PURE__ */ React.createElement("div", {
186
186
  ref: headerInnerRef,
187
- className: "grid border-b border-black/6",
187
+ className: "grid border-b border-black/[0.06]",
188
188
  style: _objectSpread2(_objectSpread2({}, tableGridStyle), {}, { willChange: "transform" }),
189
189
  key: `${grid.date}-header`
190
190
  }, /* @__PURE__ */ React.createElement("div", {
191
191
  ref: headerFixedColRef,
192
- className: "relative z-20 row-span-2 flex items-center gap-2 border-r border-black/6 bg-[#fff7f7] px-2 py-4 font-bold text-zinc-900 shadow-[10px_0_16px_-14px_rgba(0,0,0,0.2)] md:px-4",
192
+ className: "relative z-20 row-span-2 flex items-center gap-2 border-r border-black/[0.06] bg-[#fff7f7] px-2 py-4 font-bold text-zinc-900 shadow-[10px_0_16px_-14px_rgba(0,0,0,0.2)] md:px-4",
193
193
  style: { willChange: "transform" }
194
194
  }, /* @__PURE__ */ React.createElement(Iconfont, {
195
195
  type: "pisell2-clock",
@@ -225,7 +225,7 @@ function TimeGrid() {
225
225
  }))), /* @__PURE__ */ React.createElement("div", {
226
226
  ref: scrollTableRef,
227
227
  onScroll: syncHeader,
228
- className: "max-w-full overflow-x-auto cursor-grab select-none touch-pan-y active:cursor-grabbing",
228
+ className: "max-w-full overflow-x-auto rounded-b-[28px] cursor-grab select-none touch-pan-y active:cursor-grabbing",
229
229
  style: _objectSpread2({ WebkitOverflowScrolling: "touch" }, scrollerOverscrollStyle)
230
230
  }, /* @__PURE__ */ React.createElement("div", {
231
231
  className: "w-full",
@@ -235,9 +235,9 @@ function TimeGrid() {
235
235
  const isMultiProduct = !!resource.hasMultipleProducts && Array.isArray(resource.products);
236
236
  const expanded = !!expandedResources[String(resource.resourceId)];
237
237
  return /* @__PURE__ */ React.createElement(React.Fragment, { key: `${resource.resourceId}-${grid.date}` }, /* @__PURE__ */ React.createElement("div", {
238
- className: "grid border-b border-black/6",
238
+ className: "grid border-b border-black/[0.06]",
239
239
  style: tableGridStyle
240
- }, /* @__PURE__ */ React.createElement("div", { className: `sticky left-0 z-10 border-r border-black/6 px-2 py-2 shadow-[10px_0_16px_-14px_rgba(0,0,0,0.2)] md:px-4 ${courtMeta.soldOut ? "bg-zinc-50" : "bg-white"}` }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1.5" }, isMultiProduct ? /* @__PURE__ */ React.createElement("button", {
240
+ }, /* @__PURE__ */ React.createElement("div", { className: `sticky left-0 z-10 border-r border-black/[0.06] px-2 py-2 shadow-[10px_0_16px_-14px_rgba(0,0,0,0.2)] md:px-4 ${courtMeta.soldOut ? "bg-zinc-50" : "bg-white"}` }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1.5" }, isMultiProduct ? /* @__PURE__ */ React.createElement("button", {
241
241
  type: "button",
242
242
  "data-cart-button": "true",
243
243
  onClick: (e) => {
@@ -301,9 +301,9 @@ function TimeGrid() {
301
301
  }), showPlusLabel ? /* @__PURE__ */ React.createElement("span", { className: `text-[13px] font-semibold leading-4 ${priceClass} md:text-sm` }, "+") : null), tag ? /* @__PURE__ */ React.createElement("div", { className: `inline-flex rounded-full px-1.5 py-0 text-[8px] font-semibold leading-4 ring-1 md:text-[9px] ${tag.className}` }, tagText) : null));
302
302
  })), isMultiProduct && expanded && resource.products.map((subRow) => /* @__PURE__ */ React.createElement("div", {
303
303
  key: `${resource.resourceId}-sub-${subRow.productId}`,
304
- className: "grid border-b border-black/6 bg-zinc-50/60",
304
+ className: "grid border-b border-black/[0.06] bg-zinc-50/60",
305
305
  style: tableGridStyle
306
- }, /* @__PURE__ */ React.createElement("div", { className: "sticky left-0 z-10 border-r border-black/6 bg-zinc-50/60 px-2 py-2 pl-8 shadow-[10px_0_16px_-14px_rgba(0,0,0,0.2)] md:px-4 md:pl-10" }, /* @__PURE__ */ React.createElement("div", { className: "text-[12px] font-semibold leading-5 text-zinc-700 md:text-[13px]" }, subRow.productTitle)), subRow.slots.map((slot, slotIndex) => {
306
+ }, /* @__PURE__ */ React.createElement("div", { className: "sticky left-0 z-10 border-r border-black/[0.06] bg-zinc-50/60 px-2 py-2 pl-8 shadow-[10px_0_16px_-14px_rgba(0,0,0,0.2)] md:px-4 md:pl-10" }, /* @__PURE__ */ React.createElement("div", { className: "text-[12px] font-semibold leading-5 text-zinc-700 md:text-[13px]" }, subRow.productTitle)), subRow.slots.map((slot, slotIndex) => {
307
307
  const isAvailable = slot.status === "available";
308
308
  const isUnavailable = slot.status === "occupied" || slot.status === "past" || slot.status === "unavailable";
309
309
  const timeLabel = timeLabels[slotIndex] || "";
@@ -353,12 +353,12 @@ function TimeGridSkeleton() {
353
353
  "aria-busy": "true",
354
354
  "aria-live": "polite"
355
355
  }, /* @__PURE__ */ React.createElement("div", {
356
- className: "sticky z-30 overflow-hidden bg-[#fff7f7]",
356
+ className: "sticky z-30 overflow-hidden rounded-t-[28px] bg-[#fff7f7]",
357
357
  style: { top: "var(--vb-grid-sticky-top, 0px)" }
358
358
  }, /* @__PURE__ */ React.createElement("div", {
359
- className: "grid border-b border-black/6",
359
+ className: "grid border-b border-black/[0.06]",
360
360
  style: { gridTemplateColumns: `120px repeat(${SKELETON_COLS}, minmax(90px, 1fr))` }
361
- }, /* @__PURE__ */ React.createElement("div", { className: "relative z-20 flex items-center gap-2 border-r border-black/6 bg-[#fff7f7] px-2 py-4 font-bold text-zinc-900 shadow-[10px_0_16px_-14px_rgba(0,0,0,0.2)] md:px-4" }, /* @__PURE__ */ React.createElement(Iconfont, {
361
+ }, /* @__PURE__ */ React.createElement("div", { className: "relative z-20 flex items-center gap-2 border-r border-black/[0.06] bg-[#fff7f7] px-2 py-4 font-bold text-zinc-900 shadow-[10px_0_16px_-14px_rgba(0,0,0,0.2)] md:px-4" }, /* @__PURE__ */ React.createElement(Iconfont, {
362
362
  type: "pisell2-clock",
363
363
  style: {
364
364
  fontSize: 16,
@@ -371,11 +371,11 @@ function TimeGridSkeleton() {
371
371
  }, /* @__PURE__ */ React.createElement("div", { className: "h-3 w-10 rounded bg-zinc-200/80" }), /* @__PURE__ */ React.createElement("span", {
372
372
  className: "vb-skeleton-shimmer",
373
373
  "aria-hidden": "true"
374
- }))))), /* @__PURE__ */ React.createElement("div", { className: "w-full" }, Array.from({ length: SKELETON_ROWS }).map((_, rowIdx) => /* @__PURE__ */ React.createElement("div", {
374
+ }))))), /* @__PURE__ */ React.createElement("div", { className: "w-full max-w-full overflow-hidden rounded-b-[28px]" }, Array.from({ length: SKELETON_ROWS }).map((_, rowIdx) => /* @__PURE__ */ React.createElement("div", {
375
375
  key: `sk-row-${rowIdx}`,
376
- className: "grid border-b border-black/6",
376
+ className: "grid border-b border-black/[0.06]",
377
377
  style: { gridTemplateColumns: `120px repeat(${SKELETON_COLS}, minmax(90px, 1fr))` }
378
- }, /* @__PURE__ */ React.createElement("div", { className: "sticky left-0 z-10 border-r border-black/6 bg-white px-2 py-4 shadow-[10px_0_16px_-14px_rgba(0,0,0,0.2)] md:px-4" }, /* @__PURE__ */ React.createElement("div", { className: "relative overflow-hidden" }, /* @__PURE__ */ React.createElement("div", { className: "h-4 w-20 rounded bg-zinc-200/80 md:w-24" }), /* @__PURE__ */ React.createElement("div", { className: "mt-2 h-2.5 w-14 rounded bg-zinc-200/60 md:w-16" }), /* @__PURE__ */ React.createElement("span", {
378
+ }, /* @__PURE__ */ React.createElement("div", { className: "sticky left-0 z-10 border-r border-black/[0.06] bg-white px-2 py-4 shadow-[10px_0_16px_-14px_rgba(0,0,0,0.2)] md:px-4" }, /* @__PURE__ */ React.createElement("div", { className: "relative overflow-hidden" }, /* @__PURE__ */ React.createElement("div", { className: "h-4 w-20 rounded bg-zinc-200/80 md:w-24" }), /* @__PURE__ */ React.createElement("div", { className: "mt-2 h-2.5 w-14 rounded bg-zinc-200/60 md:w-16" }), /* @__PURE__ */ React.createElement("span", {
379
379
  className: "vb-skeleton-shimmer",
380
380
  "aria-hidden": "true"
381
381
  }))), Array.from({ length: SKELETON_COLS }).map((_, colIdx) => /* @__PURE__ */ React.createElement("div", {
@@ -37,7 +37,7 @@ function VenueSelection() {
37
37
  function goNextWeek() {
38
38
  navigateWeek(7);
39
39
  }
40
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "rounded-b-[24px] bg-white p-3 shadow-[0_10px_40px_rgba(20,20,20,0.06)] ring-1 ring-black/6 md:rounded-[28px] md:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-2 xl:flex-row xl:items-center xl:justify-between" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-extrabold leading-tight text-zinc-900 md:text-[30px]" }, locales.getText("pisell2.venue.step1.title") || "选择场地"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-xs leading-5 text-zinc-500 md:mt-2 md:text-sm md:leading-6" }, locales.getText("pisell2.venue.step1.subtitle") || "仅显示可用时段和价格。")), /* @__PURE__ */ React.createElement(DateNavigator, {
40
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "rounded-b-[24px] bg-white p-3 md:rounded-[28px] md:p-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-2 xl:flex-row xl:items-center xl:justify-between" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-2xl font-extrabold leading-tight text-zinc-900 md:text-[30px]" }, locales.getText("pisell2.venue.step1.title") || "选择场地"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-xs leading-5 text-zinc-500 md:mt-2 md:text-sm md:leading-6" }, locales.getText("pisell2.venue.step1.subtitle") || "仅显示可用时段和价格。")), /* @__PURE__ */ React.createElement(DateNavigator, {
41
41
  onPrevWeek: goPrevWeek,
42
42
  onNextWeek: goNextWeek
43
43
  })), /* @__PURE__ */ React.createElement("div", { className: "mt-3 md:mt-5" }, /* @__PURE__ */ React.createElement(DayTabs, {
@@ -45,7 +45,7 @@ function VenueSelection() {
45
45
  onNextWeek: goNextWeek
46
46
  })), /* @__PURE__ */ React.createElement(CourtFilter, null)), /* @__PURE__ */ React.createElement("div", {
47
47
  ref: tableSectionRef,
48
- className: "w-full max-w-full isolate rounded-[28px] bg-white shadow-[0_10px_40px_rgba(20,20,20,0.06)] ring-1 ring-black/6"
48
+ className: "w-full max-w-full isolate rounded-[28px] bg-white"
49
49
  }, /* @__PURE__ */ React.createElement(TimeGrid, null)));
50
50
  }
51
51
  //#endregion
@@ -15,6 +15,7 @@ const hdlKioskApplication = require_manifest.hdlKioskDefinition.implement({
15
15
  createEnvironment: ({ host, config }) => Object.freeze({
16
16
  host,
17
17
  config,
18
+ scaleEntry: { readPhase: () => "inactive" },
18
19
  sessionActivity: { notify: (_sessionId) => void 0 },
19
20
  scanner: require_scannerSessionRouter.createScannerSessionRouter({
20
21
  host,
@@ -22,7 +23,7 @@ const hdlKioskApplication = require_manifest.hdlKioskDefinition.implement({
22
23
  })
23
24
  }),
24
25
  disposeEnvironment: ({ scanner }) => scanner.dispose(),
25
- triggerAdapters: ({ environment }) => require_triggers.createHDLKioskEntryTriggerAdapters(environment.host, environment.config, environment.scanner.triggerAdapter),
26
+ triggerAdapters: ({ environment }) => require_triggers.createHDLKioskEntryTriggerAdapters(environment.host, environment.config, environment.scanner.triggerAdapter, () => environment.scaleEntry.readPhase()),
26
27
  admission: ({ workflowKey, cause, environment }) => require_admissionPolicy.evaluateHDLKioskAdmission({
27
28
  entry: workflowKey,
28
29
  enabledEntry: cause.trigger === "onScan" ? "barcode" : workflowKey,
@@ -64,7 +65,16 @@ const hdlKioskApplication = require_manifest.hdlKioskDefinition.implement({
64
65
  }
65
66
  },
66
67
  maxActiveSessions: 1,
67
- exposeRuntime: ({ runtime, environment }) => require_exposedRuntime.createHDLKioskExposedRuntime(runtime, environment)
68
+ exposeRuntime: ({ runtime, environment }) => {
69
+ environment.scaleEntry.readPhase = () => {
70
+ const snapshot = runtime.getSnapshot();
71
+ if (snapshot.state !== "active") return "inactive";
72
+ if (snapshot.pendingStartCount > 0) return "starting";
73
+ if (snapshot.sessions.length > 0) return "flow";
74
+ return "entry";
75
+ };
76
+ return require_exposedRuntime.createHDLKioskExposedRuntime(runtime, environment);
77
+ }
68
78
  });
69
79
  //#endregion
70
80
  exports.hdlKioskApplication = hdlKioskApplication;
@@ -1,25 +1,60 @@
1
1
  const require_scaleIngress = require("./devices/scaleIngress.js");
2
2
  //#region src/components/HDLKiosk/runtime/triggers.ts
3
- function createHDLKioskEntryTriggerAdapters(host, config, scannerTriggerAdapter) {
3
+ function createHDLKioskEntryTriggerAdapters(host, config, scannerTriggerAdapter, readScaleEntryPhase = () => "entry") {
4
4
  const scaleIngress = require_scaleIngress.createScaleIngress();
5
5
  const onWeight = Object.freeze({
6
6
  trigger: "onWeight",
7
- activate: ({ emit }) => host.devices.subscribe((event) => {
8
- if (event.type !== "weightChanged") return;
9
- const accepted = scaleIngress.accept(event, {
10
- active: true,
11
- supported: config.enabledEntries.includes("scale") && Boolean(config.primaryWeightedProductId) && host.capabilities.scale.available && host.capabilities.scale.weightChangeTrigger,
12
- workflowLocked: false,
13
- nodeAcceptsEvent: true,
14
- paymentFrozen: false
15
- });
16
- if (accepted.status !== "accepted") return;
17
- emit({
18
- channel: "weighing-product",
19
- occurrenceId: accepted.event.eventId,
20
- correlationId: `device:scale:${accepted.event.eventId}`
21
- });
22
- }, { sources: ["scale"] })
7
+ activate: ({ emit }) => {
8
+ let lastIgnoredPhase;
9
+ return host.devices.subscribe((event) => {
10
+ if (event.type !== "weightChanged") return;
11
+ const phase = readScaleEntryPhase();
12
+ const log = (name, status, reason = "") => {
13
+ try {
14
+ var _event$weight$status;
15
+ host.telemetry.emit({
16
+ name,
17
+ traceId: `device:scale:${event.eventId}`,
18
+ occurredAt: Date.now(),
19
+ attributes: {
20
+ eventId: event.eventId,
21
+ changedAt: event.weight.changedAt,
22
+ grossWeight: event.weight.gross,
23
+ unit: event.weight.unit,
24
+ scaleStatus: (_event$weight$status = event.weight.status) !== null && _event$weight$status !== void 0 ? _event$weight$status : "unknown",
25
+ phase,
26
+ status,
27
+ reason,
28
+ minimumWeightKg: config.scaleTriggerMinimumWeightKg
29
+ }
30
+ });
31
+ } catch (_unused) {}
32
+ };
33
+ if (phase !== "entry") {
34
+ if (lastIgnoredPhase !== phase) log("hdlKiosk.scale.entryDecision", "ignored", phase);
35
+ lastIgnoredPhase = phase;
36
+ return;
37
+ }
38
+ lastIgnoredPhase = void 0;
39
+ const accepted = scaleIngress.accept(event, {
40
+ active: true,
41
+ supported: config.enabledEntries.includes("scale") && Boolean(config.primaryWeightedProductId) && host.capabilities.scale.available && host.capabilities.scale.weightChangeTrigger,
42
+ workflowLocked: false,
43
+ nodeAcceptsEvent: true,
44
+ paymentFrozen: false
45
+ });
46
+ if (accepted.status !== "accepted") {
47
+ log("hdlKiosk.scale.entryDecision", "rejected", accepted.reason);
48
+ return;
49
+ }
50
+ log("hdlKiosk.scale.entryDecision", "accepted");
51
+ emit({
52
+ channel: "weighing-product",
53
+ occurrenceId: accepted.event.eventId,
54
+ correlationId: `device:scale:${accepted.event.eventId}`
55
+ }).then((result) => log("hdlKiosk.scale.startFinished", result.status, result.status === "rejected" ? result.reason : ""), () => log("hdlKiosk.scale.startFinished", "failed", "unexpectedFailure"));
56
+ }, { sources: ["scale"] });
57
+ }
23
58
  });
24
59
  return Object.freeze([scannerTriggerAdapter, onWeight]);
25
60
  }