@burdenoff/microfe-movethewheels 2026.1013.2 → 2026.1016.1
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 +7 -0
- package/dist/components/EntityCombobox.js +80 -74
- package/dist/components/pending-pick/PendingPickHistory.js +47 -38
- package/dist/components/pending-pick/PickReviewPanel.js +317 -0
- package/dist/generated/pending-pick-operations.d.ts +356 -0
- package/dist/movethewheels/components/pending-pick/PickReviewPanel.d.ts +5 -0
- package/dist/movethewheels/utils/pickReviewAcknowledgement.d.ts +4 -0
- package/dist/src/generated/pending-pick-operations.js +75 -6
- package/dist/stories/EntityCombobox.stories.d.ts +7 -0
- package/dist/utils/pickReviewAcknowledgement.js +10 -0
- package/package.json +5 -3
- package/src/generated/pending-pick-operations.ts +239 -1
- package/src/movethewheels/components/EntityCombobox.tsx +8 -2
- package/src/movethewheels/components/pending-pick/PendingPickHistory.tsx +6 -0
- package/src/movethewheels/components/pending-pick/PickReviewPanel.tsx +326 -0
- package/src/movethewheels/utils/pickReviewAcknowledgement.ts +51 -0
- package/src/operations/pending-pick/pick-review.graphql +14 -0
- package/src/stories/EntityCombobox.stories.tsx +58 -0
package/README.md
CHANGED
|
@@ -80,3 +80,10 @@ function App() {
|
|
|
80
80
|
## License
|
|
81
81
|
|
|
82
82
|
Proprietary - Copyright Burdenoff Consultancy Services Pvt. Ltd.
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
### F04 move-review candidate
|
|
86
|
+
|
|
87
|
+
The existing pending-plan receipt can open an independent review panel. It reuses canonical workspace permissions and the shared Files exact-version picker, typed owning candidate operations, bounded history, explicit handling/SOP references, action/quantity/exclusive validity and approve/reject/revoke decisions. Before dispatch, the panel preserves the intended nonsecret idempotency UUID in tab sessionStorage scoped to actor/workspace/task/intent. A missing storage capability holds before submission; an uncertain result stops further decisions and remains stopped across a same-tab refresh. The owning mutation receipt must match its kind, task, intent hash, subject, request key, reviewer, predecessor/version and declared action/quantity/time scope before the saved key is cleared or success shown. A missing/null/mismatched receipt remains unknown with the key retained. Read-only receipts display request keys for reconciliation; an absent paginated result is not proof of no commit. There is no resend/clear control or automatic mutation retry. Closing the tab/clearing storage is not a durable no-replay certificate; preserve the intended key and reconcile the unknown before another decision. The backend's exact-body idempotency remains authoritative.
|
|
88
|
+
|
|
89
|
+
An approval is review-only: reserved/staged quantities stay zero. No stock move, scan execution, safety/qualification certificate, live deployment or full F04/UI acceptance is claimed by this source candidate. `graphql/pending-pick.graphql` is regenerated from the owning backend candidate and explicitly is not a published Hive contract; actual Both schema/package/host/ordinary-actor/Files and Playwright acceptance remain release gates.
|
|
@@ -3,105 +3,111 @@ import { ChevronsUpDown as t } from "../node_modules/lucide-react/dist/esm/icons
|
|
|
3
3
|
import { cn as n } from "../utils/cn.js";
|
|
4
4
|
import { Command as r, CommandEmpty as i, CommandInput as a, CommandItem as o, CommandList as s, Popover as c, PopoverContent as l, PopoverTrigger as u } from "./ui.js";
|
|
5
5
|
import { useDebouncedValue as d } from "../hooks/useDebouncedValue.js";
|
|
6
|
-
import {
|
|
7
|
-
import { jsx as
|
|
6
|
+
import { useCallback as f, useEffect as p, useState as m } from "react";
|
|
7
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
8
8
|
//#region src/movethewheels/components/EntityCombobox.tsx
|
|
9
|
-
function
|
|
10
|
-
let [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
function _({ value: _, onChange: v, options: y, loading: b = !1, getId: x, renderOption: S, getLabel: C, selectedOption: w = null, selectedLoading: T = !1, required: E = !1, placeholder: D = "Select…", searchPlaceholder: O = "Search…", emptyText: k = "No results found.", noneLabel: A = "None", disabled: j = !1, id: M, error: N, className: P, onSearchChange: F, hasMore: I = !1, totalCount: L, onLoadMore: R, loadingMore: z = !1 }) {
|
|
10
|
+
let [B, V] = m(!1), [H, U] = m(""), [W, G] = m(), K = f((e) => {
|
|
11
|
+
G(e?.id);
|
|
12
|
+
}, []), q = d(H.trim(), 200);
|
|
13
|
+
p(() => {
|
|
14
|
+
F && F(q);
|
|
15
|
+
}, [q]);
|
|
16
|
+
let J = w ? C(w) : _ ? T ? "Loading…" : _ : D, Y = n("w-full flex items-center justify-between gap-2 px-3 py-2", "bg-surface", "border border-default", "rounded-lg", "text-left text-sm text-text-primary", "focus:outline-none focus:ring-2 focus:ring-[var(--color-border-focus)]", "disabled:bg-bg-sunken disabled:cursor-not-allowed", "transition-all duration-200", N && "border-[var(--color-status-error)]", !w && "text-text-tertiary", P), X = !!(R && I);
|
|
17
|
+
return /* @__PURE__ */ g(c, {
|
|
18
|
+
open: B,
|
|
17
19
|
onOpenChange: (e) => {
|
|
18
|
-
|
|
20
|
+
V(e), e || U("");
|
|
19
21
|
},
|
|
20
|
-
children: [/* @__PURE__ */
|
|
22
|
+
children: [/* @__PURE__ */ h(u, {
|
|
21
23
|
asChild: !0,
|
|
22
|
-
children: /* @__PURE__ */
|
|
24
|
+
children: /* @__PURE__ */ g("button", {
|
|
23
25
|
type: "button",
|
|
24
|
-
id:
|
|
26
|
+
id: M,
|
|
25
27
|
role: "combobox",
|
|
26
|
-
"aria-expanded":
|
|
27
|
-
"aria-
|
|
28
|
-
"aria-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
"aria-expanded": B,
|
|
29
|
+
"aria-controls": W,
|
|
30
|
+
"aria-required": E,
|
|
31
|
+
"aria-invalid": N ? !0 : void 0,
|
|
32
|
+
disabled: j,
|
|
33
|
+
className: Y,
|
|
34
|
+
children: [/* @__PURE__ */ h("span", {
|
|
32
35
|
className: "truncate",
|
|
33
|
-
children:
|
|
34
|
-
}), /* @__PURE__ */
|
|
36
|
+
children: J
|
|
37
|
+
}), /* @__PURE__ */ h(t, {
|
|
35
38
|
size: 16,
|
|
36
39
|
className: "shrink-0 text-text-tertiary",
|
|
37
40
|
"aria-hidden": "true"
|
|
38
41
|
})]
|
|
39
42
|
})
|
|
40
|
-
}), /* @__PURE__ */
|
|
43
|
+
}), /* @__PURE__ */ h(l, {
|
|
41
44
|
align: "start",
|
|
42
45
|
className: "w-[var(--radix-popover-trigger-width)] p-0 border border-default bg-surface",
|
|
43
|
-
children: /* @__PURE__ */
|
|
46
|
+
children: /* @__PURE__ */ g(r, {
|
|
44
47
|
shouldFilter: !1,
|
|
45
48
|
className: "bg-surface text-text-primary",
|
|
46
|
-
children: [
|
|
47
|
-
value:
|
|
48
|
-
onValueChange:
|
|
49
|
-
placeholder:
|
|
49
|
+
children: [F && /* @__PURE__ */ h(a, {
|
|
50
|
+
value: H,
|
|
51
|
+
onValueChange: U,
|
|
52
|
+
placeholder: O,
|
|
50
53
|
className: "text-text-primary placeholder:text-text-tertiary"
|
|
51
|
-
}), /* @__PURE__ */
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
},
|
|
61
|
-
className: "text-text-tertiary",
|
|
62
|
-
children: [/* @__PURE__ */ m(e, {
|
|
63
|
-
size: 16,
|
|
64
|
-
className: n("shrink-0", g === "" ? "opacity-100" : "opacity-0"),
|
|
65
|
-
"aria-hidden": "true"
|
|
66
|
-
}), /* @__PURE__ */ m("span", {
|
|
67
|
-
className: "truncate italic",
|
|
68
|
-
children: k
|
|
69
|
-
})]
|
|
70
|
-
}),
|
|
71
|
-
v.map((t) => {
|
|
72
|
-
let r = b(t);
|
|
73
|
-
return /* @__PURE__ */ h(o, {
|
|
74
|
-
value: r,
|
|
54
|
+
}), /* @__PURE__ */ g(s, {
|
|
55
|
+
ref: K,
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ h(i, {
|
|
58
|
+
className: "text-text-tertiary",
|
|
59
|
+
children: b ? "Searching…" : k
|
|
60
|
+
}),
|
|
61
|
+
!E && /* @__PURE__ */ g(o, {
|
|
62
|
+
value: "__none__",
|
|
75
63
|
onSelect: () => {
|
|
76
|
-
|
|
64
|
+
v(""), V(!1);
|
|
77
65
|
},
|
|
78
|
-
className: "text-text-
|
|
79
|
-
children: [/* @__PURE__ */
|
|
66
|
+
className: "text-text-tertiary",
|
|
67
|
+
children: [/* @__PURE__ */ h(e, {
|
|
80
68
|
size: 16,
|
|
81
|
-
className: n("shrink-0",
|
|
69
|
+
className: n("shrink-0", _ === "" ? "opacity-100" : "opacity-0"),
|
|
82
70
|
"aria-hidden": "true"
|
|
83
|
-
}), /* @__PURE__ */
|
|
84
|
-
className: "truncate",
|
|
85
|
-
children:
|
|
71
|
+
}), /* @__PURE__ */ h("span", {
|
|
72
|
+
className: "truncate italic",
|
|
73
|
+
children: A
|
|
86
74
|
})]
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
75
|
+
}),
|
|
76
|
+
y.map((t) => {
|
|
77
|
+
let r = x(t);
|
|
78
|
+
return /* @__PURE__ */ g(o, {
|
|
79
|
+
value: r,
|
|
80
|
+
onSelect: () => {
|
|
81
|
+
v(r), V(!1);
|
|
82
|
+
},
|
|
83
|
+
className: "text-text-primary",
|
|
84
|
+
children: [/* @__PURE__ */ h(e, {
|
|
85
|
+
size: 16,
|
|
86
|
+
className: n("shrink-0", r === _ ? "opacity-100" : "opacity-0"),
|
|
87
|
+
"aria-hidden": "true"
|
|
88
|
+
}), /* @__PURE__ */ h("span", {
|
|
89
|
+
className: "truncate",
|
|
90
|
+
children: S(t)
|
|
91
|
+
})]
|
|
92
|
+
}, r);
|
|
93
|
+
}),
|
|
94
|
+
X && /* @__PURE__ */ h("div", {
|
|
95
|
+
className: "border-t border-border-seam p-2",
|
|
96
|
+
children: /* @__PURE__ */ h("button", {
|
|
97
|
+
type: "button",
|
|
98
|
+
className: "w-full rounded-md px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/10 focus:outline-none focus:ring-2 focus:ring-[var(--color-border-focus)] disabled:cursor-not-allowed disabled:opacity-60",
|
|
99
|
+
onClick: () => void R?.(),
|
|
100
|
+
disabled: b || z,
|
|
101
|
+
"aria-busy": z,
|
|
102
|
+
"aria-label": z ? "Loading more options" : `Load more options${typeof L == "number" ? ` (${y.length} of ${L} shown)` : ""}`,
|
|
103
|
+
children: z ? "Loading more…" : `Load more${typeof L == "number" ? ` (${y.length} of ${L})` : ""}`
|
|
104
|
+
})
|
|
99
105
|
})
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
]
|
|
107
|
+
})]
|
|
102
108
|
})
|
|
103
109
|
})]
|
|
104
110
|
});
|
|
105
111
|
}
|
|
106
112
|
//#endregion
|
|
107
|
-
export {
|
|
113
|
+
export { _ as EntityCombobox };
|
|
@@ -3,104 +3,113 @@ import { useConditionQuery as n } from "../../hooks/useContainerCondition.js";
|
|
|
3
3
|
import { ReusePager as r, ReuseState as i, reuseCard as a } from "../ReuseControls.js";
|
|
4
4
|
import { ExactPendingPickDocument as o, PendingPickHistoryDocument as s } from "../../src/generated/pending-pick-operations.js";
|
|
5
5
|
import { PickCapture as c } from "./PickCapture.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { PickReviewPanel as l } from "./PickReviewPanel.js";
|
|
7
|
+
import { useState as u } from "react";
|
|
8
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
8
9
|
//#region src/movethewheels/components/pending-pick/PendingPickHistory.tsx
|
|
9
|
-
function
|
|
10
|
-
|
|
10
|
+
function p({ task: t }) {
|
|
11
|
+
let [n, r] = u(!1);
|
|
12
|
+
return /* @__PURE__ */ f("article", {
|
|
11
13
|
className: `${a} min-w-0 break-words`,
|
|
12
14
|
children: [
|
|
13
|
-
/* @__PURE__ */
|
|
15
|
+
/* @__PURE__ */ d("h3", {
|
|
14
16
|
className: "font-semibold",
|
|
15
17
|
children: "Pending plan · needs review"
|
|
16
18
|
}),
|
|
17
|
-
/* @__PURE__ */
|
|
19
|
+
/* @__PURE__ */ f("p", {
|
|
18
20
|
className: "break-all",
|
|
19
|
-
children: ["Task ",
|
|
21
|
+
children: ["Task ", t.id]
|
|
20
22
|
}),
|
|
21
|
-
/* @__PURE__ */
|
|
22
|
-
|
|
23
|
+
/* @__PURE__ */ f("p", { children: [
|
|
24
|
+
t.requestedQuantity,
|
|
23
25
|
" reported count · ",
|
|
24
|
-
|
|
26
|
+
t.note
|
|
25
27
|
] }),
|
|
26
|
-
/* @__PURE__ */
|
|
28
|
+
/* @__PURE__ */ f("p", { children: [
|
|
27
29
|
"Reserved ",
|
|
28
|
-
|
|
30
|
+
t.reservedQuantity,
|
|
29
31
|
"; staged ",
|
|
30
|
-
|
|
32
|
+
t.stagedQuantity,
|
|
31
33
|
". No movement is recorded."
|
|
32
34
|
] }),
|
|
33
|
-
/* @__PURE__ */
|
|
35
|
+
/* @__PURE__ */ f("p", {
|
|
34
36
|
className: "break-all",
|
|
35
37
|
children: [
|
|
36
38
|
"Recorded ",
|
|
37
|
-
|
|
39
|
+
t.recordedAt,
|
|
38
40
|
"; creator and proposed executor ",
|
|
39
|
-
|
|
41
|
+
t.executorActorId,
|
|
40
42
|
"."
|
|
41
43
|
]
|
|
42
44
|
}),
|
|
43
|
-
/* @__PURE__ */
|
|
45
|
+
/* @__PURE__ */ f("details", { children: [/* @__PURE__ */ d("summary", { children: "Captured source and staging context" }), /* @__PURE__ */ f("div", {
|
|
44
46
|
className: "mt-3 grid gap-3 lg:grid-cols-2",
|
|
45
|
-
children: [/* @__PURE__ */
|
|
47
|
+
children: [/* @__PURE__ */ d(c, {
|
|
46
48
|
title: "Source",
|
|
47
|
-
line:
|
|
48
|
-
}), /* @__PURE__ */
|
|
49
|
+
line: t.source
|
|
50
|
+
}), /* @__PURE__ */ d(c, {
|
|
49
51
|
title: "Staging",
|
|
50
|
-
line:
|
|
52
|
+
line: t.destination
|
|
51
53
|
})]
|
|
52
|
-
})] })
|
|
54
|
+
})] }),
|
|
55
|
+
/* @__PURE__ */ d(e, {
|
|
56
|
+
type: "button",
|
|
57
|
+
variant: "outline",
|
|
58
|
+
onClick: () => r(!n),
|
|
59
|
+
children: n ? "Close move review" : "Review this exact pending plan"
|
|
60
|
+
}),
|
|
61
|
+
n && /* @__PURE__ */ d(l, { task: t })
|
|
53
62
|
]
|
|
54
63
|
});
|
|
55
64
|
}
|
|
56
|
-
function
|
|
57
|
-
let [m, h] =
|
|
65
|
+
function m({ revision: a, sourceId: c, destinationId: l }) {
|
|
66
|
+
let [m, h] = u(0), [g, _] = u(""), [v, y] = u(""), b = n(s, {
|
|
58
67
|
pagination: {
|
|
59
68
|
limit: 10,
|
|
60
69
|
offset: m
|
|
61
70
|
},
|
|
62
71
|
sourceInventoryItemId: c || null,
|
|
63
|
-
destinationInventoryItemId:
|
|
72
|
+
destinationInventoryItemId: l || null
|
|
64
73
|
}, a), x = n(o, v ? { id: v } : null, a), S = b.data?.mtwPickTaskPage;
|
|
65
|
-
return /* @__PURE__ */
|
|
74
|
+
return /* @__PURE__ */ f("section", {
|
|
66
75
|
className: "space-y-3",
|
|
67
76
|
"aria-label": "Pending plan history",
|
|
68
77
|
children: [
|
|
69
|
-
/* @__PURE__ */
|
|
78
|
+
/* @__PURE__ */ d("h2", {
|
|
70
79
|
className: "font-semibold",
|
|
71
80
|
children: "Recorded pending plans"
|
|
72
81
|
}),
|
|
73
|
-
/* @__PURE__ */
|
|
82
|
+
/* @__PURE__ */ d("p", {
|
|
74
83
|
className: "text-sm",
|
|
75
84
|
children: "History retains captured references after a line is retired. Use a known task ID; this is not an archived stock-line browser."
|
|
76
85
|
}),
|
|
77
|
-
/* @__PURE__ */
|
|
86
|
+
/* @__PURE__ */ f("label", {
|
|
78
87
|
className: "block",
|
|
79
|
-
children: ["Known task ID", /* @__PURE__ */
|
|
88
|
+
children: ["Known task ID", /* @__PURE__ */ d(t, {
|
|
80
89
|
value: g,
|
|
81
90
|
maxLength: 255,
|
|
82
91
|
onChange: (e) => _(e.target.value)
|
|
83
92
|
})]
|
|
84
93
|
}),
|
|
85
|
-
/* @__PURE__ */
|
|
94
|
+
/* @__PURE__ */ d(e, {
|
|
86
95
|
type: "button",
|
|
87
96
|
variant: "outline",
|
|
88
97
|
disabled: !g.trim(),
|
|
89
98
|
onClick: () => y(g.trim()),
|
|
90
99
|
children: "Read exact task"
|
|
91
100
|
}),
|
|
92
|
-
/* @__PURE__ */
|
|
101
|
+
/* @__PURE__ */ d(i, {
|
|
93
102
|
loading: x.loading,
|
|
94
103
|
error: x.error
|
|
95
104
|
}),
|
|
96
|
-
x.data && /* @__PURE__ */
|
|
97
|
-
/* @__PURE__ */
|
|
105
|
+
x.data && /* @__PURE__ */ d(p, { task: x.data.mtwPickTask }),
|
|
106
|
+
/* @__PURE__ */ d(i, {
|
|
98
107
|
loading: b.loading,
|
|
99
108
|
error: b.error
|
|
100
109
|
}),
|
|
101
|
-
S?.items.map((e) => /* @__PURE__ */
|
|
102
|
-
S?.total === 0 && /* @__PURE__ */
|
|
103
|
-
/* @__PURE__ */
|
|
110
|
+
S?.items.map((e) => /* @__PURE__ */ d(p, { task: e }, e.id)),
|
|
111
|
+
S?.total === 0 && /* @__PURE__ */ d("p", { children: "No recorded pending plans in this filter." }),
|
|
112
|
+
/* @__PURE__ */ d(r, {
|
|
104
113
|
page: S,
|
|
105
114
|
offset: m,
|
|
106
115
|
onChange: h,
|
|
@@ -110,4 +119,4 @@ function p({ revision: a, sourceId: c, destinationId: p }) {
|
|
|
110
119
|
});
|
|
111
120
|
}
|
|
112
121
|
//#endregion
|
|
113
|
-
export {
|
|
122
|
+
export { m as PendingPickHistory };
|