@seedtactics/insight-client 17.0.1-beta.13 → 17.0.1-beta.15
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 +5 -4
- package/dist/assets/index-Z6GAS_qc.js +367 -0
- package/dist/cell-status/loading.d.ts +7 -0
- package/dist/cell-status/loading.js +25 -0
- package/dist/components/App.d.ts +0 -5
- package/dist/components/App.js +1 -1
- package/dist/components/operations/AllMaterial.js +9 -12
- package/dist/components/station-monitor/BasketLoadStationWork.d.ts +1 -7
- package/dist/components/station-monitor/BasketLoadStationWork.js +11 -7
- package/dist/components/station-monitor/InvalidateCycle.js +21 -17
- package/dist/components/station-monitor/LoadStation.d.ts +0 -5
- package/dist/components/station-monitor/LoadStation.js +29 -69
- package/dist/components/station-monitor/Material.js +4 -2
- package/dist/components/station-monitor/QuarantineButton.js +17 -26
- package/dist/components/station-monitor/Whiteboard.js +14 -15
- package/dist/data/material-operation-policy.d.ts +6 -0
- package/dist/data/material-operation-policy.js +26 -2
- package/dist/extension.d.ts +0 -1
- package/dist/index.html +1 -1
- package/dist/index.js +1 -6
- package/dist/network/api.d.ts +16 -34
- package/dist/network/api.js +64 -64
- package/dist/network/backend-mock.js +3 -0
- package/dist/network/backend.d.ts +1 -0
- package/docs/material-quarantine.md +5 -4
- package/docs/mazak.md +9 -12
- package/docs/operator-procedures.md +14 -0
- package/package.json +9 -4
- package/dist/assets/index-Dxxgr-QV.js +0 -367
- package/dist/components/station-monitor/BasketMovementArrival.d.ts +0 -40
- package/dist/components/station-monitor/BasketMovementArrival.js +0 -165
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ICurrentStatus, IHistoricData, ILogEntry, IRecentHistoricData, IServerEvent } from "../network/api.js";
|
|
2
|
+
import * as currentSt from "./current-status.js";
|
|
2
3
|
import { Atom } from "jotai";
|
|
3
4
|
export interface ServerEventAndTime {
|
|
4
5
|
readonly evt: Readonly<IServerEvent>;
|
|
@@ -24,6 +25,12 @@ export declare const onLoadLast30Log: import("jotai").WritableAtom<null, [log: r
|
|
|
24
25
|
export declare const onLoadCurrentSt: import("jotai").WritableAtom<null, [curSt: Readonly<ICurrentStatus>], void> & {
|
|
25
26
|
init: null;
|
|
26
27
|
};
|
|
28
|
+
export interface QueuedMatMove extends currentSt.QueueReordering {
|
|
29
|
+
readonly operator: string | null;
|
|
30
|
+
}
|
|
31
|
+
export declare const moveQueuedMatInCurrentStatus: import("jotai").WritableAtom<null, [QueuedMatMove], Promise<void>> & {
|
|
32
|
+
init: null;
|
|
33
|
+
};
|
|
27
34
|
export declare const onLoadSpecificMonthJobs: import("jotai").WritableAtom<null, [historicData: Readonly<IHistoricData>], void> & {
|
|
28
35
|
init: null;
|
|
29
36
|
};
|
|
@@ -30,6 +30,8 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
30
30
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
31
31
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
32
32
|
*/
|
|
33
|
+
import { QueuePosition, } from "../network/api.js";
|
|
34
|
+
import { JobsBackend } from "../network/backend.js";
|
|
33
35
|
import { LazySeq } from "@seedtactics/immutable-collections";
|
|
34
36
|
import * as simProd from "./sim-production.js";
|
|
35
37
|
import * as simUse from "./sim-station-use.js";
|
|
@@ -112,6 +114,29 @@ export const onLoadCurrentSt = atom(null, (_, set, curSt) => {
|
|
|
112
114
|
set(customSt.replaceCustomState, curSt.customState ?? null);
|
|
113
115
|
set(names.setNamesFromCurrentStatus, curSt);
|
|
114
116
|
});
|
|
117
|
+
// Show queue drops immediately. Recovery must not replace intervening live updates or drags.
|
|
118
|
+
export const moveQueuedMatInCurrentStatus = atom(null, async (get, set, { operator, ...move }) => {
|
|
119
|
+
const before = get(currentSt.currentStatus);
|
|
120
|
+
set(currentSt.reorderQueuedMatInCurrentStatus, move);
|
|
121
|
+
const optimistic = get(currentSt.currentStatus);
|
|
122
|
+
try {
|
|
123
|
+
await JobsBackend.setMaterialInQueue(move.matId, operator, new QueuePosition({ queue: move.queue, position: move.newIdx }));
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
const beforeReload = get(currentSt.currentStatus);
|
|
127
|
+
try {
|
|
128
|
+
const refreshed = await JobsBackend.currentStatus();
|
|
129
|
+
if (get(currentSt.currentStatus) === beforeReload)
|
|
130
|
+
set(onLoadCurrentSt, refreshed);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// If the server is unreachable, undo only this move's untouched optimistic snapshot.
|
|
134
|
+
if (get(currentSt.currentStatus) === optimistic)
|
|
135
|
+
set(onLoadCurrentSt, before);
|
|
136
|
+
}
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
});
|
|
115
140
|
export const onLoadSpecificMonthJobs = atom(null, (_, set, historicData) => {
|
|
116
141
|
set(simUse.setSpecificMonthSimStatUse, historicData);
|
|
117
142
|
set(simProd.setSpecificMonthJobProduction, historicData);
|
package/dist/components/App.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { ReactNode, ComponentType } from "react";
|
|
2
2
|
import { ChooseModeItem } from "./ChooseMode.js";
|
|
3
3
|
import * as serverSettings from "../network/server-settings.js";
|
|
4
|
-
import type { SubmitBasketLoadStationCommand } from "./station-monitor/BasketLoadStationWork.js";
|
|
5
|
-
import type { SubmitBasketLocationCorrection, SubmitBasketMovementCompletion } from "./station-monitor/BasketMovementArrival.js";
|
|
6
4
|
export declare function NavTabs({ children }: {
|
|
7
5
|
children?: ReactNode;
|
|
8
6
|
}): import("react").JSX.Element;
|
|
@@ -12,9 +10,6 @@ export interface AppProps {
|
|
|
12
10
|
readonly page: ReactNode;
|
|
13
11
|
};
|
|
14
12
|
readonly chooseModes?: (i: serverSettings.FMSInfoAndUser) => ReadonlyArray<ChooseModeItem> | null;
|
|
15
|
-
readonly submitBasketLoadStationCommand?: SubmitBasketLoadStationCommand;
|
|
16
|
-
readonly submitBasketMovementCompletion?: SubmitBasketMovementCompletion;
|
|
17
|
-
readonly submitBasketLocationCorrection?: SubmitBasketLocationCorrection;
|
|
18
13
|
}
|
|
19
14
|
declare const App: import("react").MemoExoticComponent<(props: AppProps) => import("react").JSX.Element>;
|
|
20
15
|
export default App;
|
package/dist/components/App.js
CHANGED
|
@@ -310,7 +310,7 @@ const App = memo(function App(props) {
|
|
|
310
310
|
else {
|
|
311
311
|
switch (route.route) {
|
|
312
312
|
case routes.RouteLocation.Station_LoadMonitor:
|
|
313
|
-
page = (_jsx(LoadStation, { loadNum: route.loadNum, queues: route.queues, completed: route.completed
|
|
313
|
+
page = (_jsx(LoadStation, { loadNum: route.loadNum, queues: route.queues, completed: route.completed }, route.loadNum));
|
|
314
314
|
nav1 = StationToolbar;
|
|
315
315
|
nav2 = StationToolbarOverviewButton;
|
|
316
316
|
showOperator = true;
|
|
@@ -33,8 +33,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
33
33
|
*/
|
|
34
34
|
import { forwardRef, memo, PureComponent, useState, useCallback, useMemo, } from "react";
|
|
35
35
|
import { selectAllMaterialIntoBins, MaterialBinType, moveMaterialBin, currentMaterialBinOrder, moveMaterialInBin, findMaterialInQuarantineQueues, findQueueInQuarantineQueues, } from "../../data/all-material-bins.js";
|
|
36
|
-
import * as matDetails from "../../cell-status/material-details.js";
|
|
37
36
|
import * as currentSt from "../../cell-status/current-status.js";
|
|
37
|
+
import { moveQueuedMatInCurrentStatus } from "../../cell-status/loading.js";
|
|
38
38
|
import { Box } from "@mui/material";
|
|
39
39
|
import { Typography } from "@mui/material";
|
|
40
40
|
import { LazySeq } from "@seedtactics/immutable-collections";
|
|
@@ -48,6 +48,7 @@ import { useSetTitle } from "../routes.js";
|
|
|
48
48
|
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
49
49
|
import { fmsInformation } from "../../network/server-settings.js";
|
|
50
50
|
import { basketDisplayName, loadStationDisplayName } from "../../cell-status/station-cycles.js";
|
|
51
|
+
import { canSetMaterialInQueue } from "../../data/material-operation-policy.js";
|
|
51
52
|
const ColumnWithTitle = forwardRef(function MaterialBin(props, ref) {
|
|
52
53
|
return (_jsxs(Box, { sx: {
|
|
53
54
|
margin: props.isDragOverlay ? undefined : "0.75em",
|
|
@@ -187,8 +188,7 @@ export function AllMaterial(props) {
|
|
|
187
188
|
useSetTitle("All Material");
|
|
188
189
|
const st = useAtomValue(currentSt.currentStatus);
|
|
189
190
|
const [matBinOrder, setMatBinOrder] = useAtom(currentMaterialBinOrder);
|
|
190
|
-
const
|
|
191
|
-
const reorderQueuedMat = useSetAtom(currentSt.reorderQueuedMatInCurrentStatus);
|
|
191
|
+
const moveQueuedMat = useSetAtom(moveQueuedMatInCurrentStatus);
|
|
192
192
|
const [activeDrag, setActiveDrag] = useState(null);
|
|
193
193
|
const allBins = useMemo(() => {
|
|
194
194
|
const bins = selectAllMaterialIntoBins(st, matBinOrder);
|
|
@@ -232,6 +232,8 @@ export function AllMaterial(props) {
|
|
|
232
232
|
: findMaterialInQuarantineQueues(over.id, allBins);
|
|
233
233
|
if (!overCol)
|
|
234
234
|
return;
|
|
235
|
+
if (!canSetMaterialInQueue(activeDrag.mat, overCol.bin.queueName))
|
|
236
|
+
return;
|
|
235
237
|
if (overCol.bin.binId !== activeDrag.curOverBinId) {
|
|
236
238
|
setActiveDrag({
|
|
237
239
|
...activeDrag,
|
|
@@ -258,18 +260,13 @@ export function AllMaterial(props) {
|
|
|
258
260
|
const overCol = typeof over.id === "string"
|
|
259
261
|
? findQueueInQuarantineQueues(over.id, allBins)
|
|
260
262
|
: findMaterialInQuarantineQueues(over.id, allBins);
|
|
261
|
-
if (overCol) {
|
|
262
|
-
|
|
263
|
-
materialId: activeDrag.mat.materialID,
|
|
264
|
-
queue: overCol.bin.queueName,
|
|
265
|
-
queuePosition: overCol.idx,
|
|
266
|
-
operator: null,
|
|
267
|
-
}).catch(console.error);
|
|
268
|
-
reorderQueuedMat({
|
|
263
|
+
if (overCol && canSetMaterialInQueue(activeDrag.mat, overCol.bin.queueName)) {
|
|
264
|
+
moveQueuedMat({
|
|
269
265
|
queue: overCol.bin.queueName,
|
|
270
266
|
matId: activeDrag.mat.materialID,
|
|
271
267
|
newIdx: overCol.idx,
|
|
272
|
-
|
|
268
|
+
operator: null,
|
|
269
|
+
}).catch(console.error);
|
|
273
270
|
}
|
|
274
271
|
}
|
|
275
272
|
setActiveDrag(null);
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import * as api from "../../network/api.js";
|
|
2
2
|
import { MatCardFontSize } from "./Material.js";
|
|
3
|
-
export interface BasketLoadStationCommand {
|
|
4
|
-
readonly workId: string;
|
|
5
|
-
}
|
|
6
|
-
export type SubmitBasketLoadStationCommand = (stationNumber: number, command: BasketLoadStationCommand) => Promise<"accepted" | "conflict">;
|
|
7
3
|
interface BasketLoadStationWorkflowProps {
|
|
8
|
-
readonly stationNumber: number;
|
|
9
4
|
readonly basket: Readonly<api.IBasketStatus>;
|
|
10
5
|
readonly material: ReadonlyArray<Readonly<api.IInProcessMaterial>>;
|
|
11
6
|
readonly fsize: MatCardFontSize;
|
|
12
|
-
readonly submitCommand: SubmitBasketLoadStationCommand | undefined;
|
|
13
7
|
}
|
|
14
|
-
export declare function BasketLoadStationWorkflow({
|
|
8
|
+
export declare function BasketLoadStationWorkflow({ basket, material, fsize, }: BasketLoadStationWorkflowProps): import("react").JSX.Element;
|
|
15
9
|
export {};
|
|
@@ -33,6 +33,7 @@ import { Alert, Box, Button, Stack, Typography } from "@mui/material";
|
|
|
33
33
|
import { LazySeq } from "@seedtactics/immutable-collections";
|
|
34
34
|
import { basketSlotLabel } from "../../cell-status/station-cycles.js";
|
|
35
35
|
import * as api from "../../network/api.js";
|
|
36
|
+
import { JobsBackend } from "../../network/backend.js";
|
|
36
37
|
import { InProcMaterial } from "./Material.js";
|
|
37
38
|
import { MoveMaterialArrowNode } from "./MoveMaterialArrows.js";
|
|
38
39
|
import { MoveMaterialNodeKindType } from "../../data/move-arrows.js";
|
|
@@ -138,10 +139,11 @@ function loadingInstruction(mat) {
|
|
|
138
139
|
function SlotMaterial({ material, fsize, }) {
|
|
139
140
|
return material.map((mat) => (_jsx(MoveMaterialArrowNode, { kind: { type: MoveMaterialNodeKindType.Material, material: mat }, children: _jsx(InProcMaterial, { mat: mat, fsize: fsize }) }, mat.materialID)));
|
|
140
141
|
}
|
|
141
|
-
export function BasketLoadStationWorkflow({
|
|
142
|
+
export function BasketLoadStationWorkflow({ basket, material, fsize, }) {
|
|
142
143
|
const [submission, setSubmission] = useState();
|
|
143
144
|
const workState = useMemo(() => stationWork(material, basket), [basket, material]);
|
|
144
145
|
const blockedReason = basket.loadStationWork?.confirmationBlockedReason?.trim();
|
|
146
|
+
const instructionWarning = basket.loadStationWork?.instructionWarning?.trim();
|
|
145
147
|
const work = workState.type === "active" ? workState.work : undefined;
|
|
146
148
|
const submissionState = submission !== undefined &&
|
|
147
149
|
submission.workId === work?.workId &&
|
|
@@ -170,17 +172,19 @@ export function BasketLoadStationWorkflow({ stationNumber, basket, material, fsi
|
|
|
170
172
|
.distinctBy((slot) => slot)
|
|
171
173
|
.toSortedArray((slot) => slot), [basket.emptySlots, basket.unknownSlots, materialBySlot, loadsBySlot]);
|
|
172
174
|
async function submit() {
|
|
173
|
-
if (work === undefined || !work.ready
|
|
175
|
+
if (work === undefined || !work.ready)
|
|
174
176
|
return;
|
|
175
177
|
const submittedWorkId = work.workId;
|
|
176
178
|
const pending = { workId: submittedWorkId, basket, material, state: "submitting" };
|
|
177
179
|
setSubmission(pending);
|
|
178
180
|
try {
|
|
179
|
-
|
|
181
|
+
await JobsBackend.completeBasketLoadStation(new api.BasketLoadStationCompletion({ workId: submittedWorkId }));
|
|
182
|
+
const state = "accepted";
|
|
180
183
|
setSubmission((current) => (current === pending ? { ...pending, state } : current));
|
|
181
184
|
}
|
|
182
|
-
catch {
|
|
183
|
-
|
|
185
|
+
catch (error) {
|
|
186
|
+
const state = api.ApiException.isApiException(error) && error.status === 409 ? "conflict" : "error";
|
|
187
|
+
setSubmission((current) => (current === pending ? { ...pending, state } : current));
|
|
184
188
|
}
|
|
185
189
|
}
|
|
186
190
|
const submissionDisabled = !work?.ready ||
|
|
@@ -202,8 +206,8 @@ export function BasketLoadStationWorkflow({ stationNumber, basket, material, fsi
|
|
|
202
206
|
}, children: _jsxs(Box, { component: "section", "data-testid": `basket-load-station-slot-${slot}`, sx: { border: "1px solid", borderColor: "text.primary", p: 2 }, children: [_jsxs(Typography, { variant: "h6", children: ["Slot ", basketSlotLabel(slot)] }), loads.length > 0 &&
|
|
203
207
|
slotMaterial.some((mat) => mat.action.type === api.ActionType.UnloadToInProcess ||
|
|
204
208
|
mat.action.type === api.ActionType.UnloadToCompletedMaterial) && (_jsx(Typography, { children: "Unload the current material before preparing the replacement." })), slotMaterial.length > 0 ? (_jsx(SlotMaterial, { material: slotMaterial, fsize: fsize })) : (_jsx(Typography, { color: isUnknown ? "warning.main" : "text.secondary", children: isUnknown ? "Unknown" : "Empty" })), loads.map((mat, index) => (_jsxs(Box, { sx: { mt: 1 }, children: [_jsx(Typography, { children: loadingInstruction(mat) }), _jsxs(Typography, { variant: "body2", color: "text.secondary", children: [mat.partName, " \u00B7 Process ", mat.action.processAfterLoad ?? mat.process] })] }, `${mat.jobUnique}-${mat.process}-${index}`)))] }) }, slot));
|
|
205
|
-
}) }), work?.confirmEmpty && _jsxs(Typography, { children: ["Confirm basket ", basket.basketId, " is empty."] }), work && !work.ready && (_jsx(Alert, { severity: "info", children: blockedReason ||
|
|
209
|
+
}) }), work?.confirmEmpty && _jsxs(Typography, { children: ["Confirm basket ", basket.basketId, " is empty."] }), instructionWarning && _jsx(Alert, { severity: "warning", children: instructionWarning }), work && !work.ready && (_jsx(Alert, { severity: "info", children: blockedReason ||
|
|
206
210
|
(work.awaitingSlots.length > 0
|
|
207
211
|
? `Waiting for material for slots ${work.awaitingSlots.map(basketSlotLabel).join(", ")}.`
|
|
208
|
-
: "Basket work is not ready for confirmation.") })), work
|
|
212
|
+
: "Basket work is not ready for confirmation.") })), work ? (_jsx(Box, { sx: { display: "flex", justifyContent: "flex-end" }, children: _jsx(Button, { variant: "contained", disabled: submissionDisabled, onClick: () => void submit(), children: "Confirm" }) })) : workState.type === "inconsistent" ? (_jsx(Alert, { severity: "warning", children: "Basket work is inconsistent. Wait for refreshed material actions before confirming." })) : null, submissionState === "accepted" ? (_jsx(Alert, { severity: "success", children: "Confirmation accepted. Waiting for refreshed work." })) : submissionState === "conflict" ? (_jsx(Alert, { severity: "warning", children: "Basket work changed before confirmation. Review the refreshed slots and try again." })) : submissionState === "error" ? (_jsx(Alert, { severity: "error", children: "Unable to confirm basket work. No work was assumed complete." })) : null] }));
|
|
209
213
|
}
|
|
@@ -82,12 +82,15 @@ function InvalidateSelect(props) {
|
|
|
82
82
|
job: currentSt.jobs[j.jobUnique] ?? history.get(j.jobUnique) ?? null,
|
|
83
83
|
}));
|
|
84
84
|
const hasProc = lastMat !== null && lastMat.process >= 1;
|
|
85
|
-
const
|
|
85
|
+
const canChangeAssignment = lastMat === null || lastMat.process <= 1;
|
|
86
|
+
const hasChangeMat = canChangeAssignment && (castings.length > 0 || jobs.length > 0);
|
|
86
87
|
const selectedCasting = props.st?.changeRawMat !== null &&
|
|
87
88
|
props.st?.changeRawMat !== undefined &&
|
|
89
|
+
canChangeAssignment &&
|
|
88
90
|
castings.includes(props.st.changeRawMat);
|
|
89
91
|
const selectedJob = props.st?.changeJobUnique !== null &&
|
|
90
92
|
props.st?.changeJobUnique !== undefined &&
|
|
93
|
+
canChangeAssignment &&
|
|
91
94
|
jobs.some((job) => job.jobUnique === props.st?.changeJobUnique);
|
|
92
95
|
function change(e) {
|
|
93
96
|
props.setState({
|
|
@@ -102,7 +105,7 @@ function InvalidateSelect(props) {
|
|
|
102
105
|
? "rawMat" + props.st.changeRawMat
|
|
103
106
|
: selectedJob
|
|
104
107
|
? "job" + props.st.changeJobUnique
|
|
105
|
-
: props.st?.process && hasProc
|
|
108
|
+
: props.st?.process && hasProc && props.st.process === lastMat.process
|
|
106
109
|
? "proc" + props.st.process.toString()
|
|
107
110
|
: "", select: true, onChange: (e) => change(e.target.value), variant: "outlined", label: props.st?.changeRawMat
|
|
108
111
|
? "Change Raw Material"
|
|
@@ -119,11 +122,6 @@ function InvalidateSelect(props) {
|
|
|
119
122
|
hasProc
|
|
120
123
|
? [
|
|
121
124
|
_jsxs(MenuItem, { value: "proc" + lastMat.process.toString(), children: ["Invalidate Process ", lastMat.process] }, lastMat.process),
|
|
122
|
-
...(lastMat.process > 1
|
|
123
|
-
? [
|
|
124
|
-
_jsx(MenuItem, { value: "proc1", children: "Invalidate All Processes" }, "all"),
|
|
125
|
-
]
|
|
126
|
-
: []),
|
|
127
125
|
]
|
|
128
126
|
: [],
|
|
129
127
|
hasProc && hasChangeMat
|
|
@@ -131,8 +129,9 @@ function InvalidateSelect(props) {
|
|
|
131
129
|
: [],
|
|
132
130
|
hasChangeMat
|
|
133
131
|
? [
|
|
134
|
-
...castings.map((c) => (_jsxs(MenuItem, { value: "rawMat" + c, children: ["Invalidate
|
|
135
|
-
...jobs.map(({ jobUnique, job }) => (_jsxs(MenuItem, { value: "job" + jobUnique, children: [job ? (_jsx(ListItemIcon, { children: _jsx(PartIdenticon, { part: job.partName }) })) : undefined, _jsx(ListItemText, { primary: "Invalidate
|
|
132
|
+
...castings.map((c) => (_jsxs(MenuItem, { value: "rawMat" + c, children: [hasProc ? "Invalidate Process 1 and Change to " : "Change to ", c] }, "rawMat" + c))),
|
|
133
|
+
...jobs.map(({ jobUnique, job }) => (_jsxs(MenuItem, { value: "job" + jobUnique, children: [job ? (_jsx(ListItemIcon, { children: _jsx(PartIdenticon, { part: job.partName }) })) : undefined, _jsx(ListItemText, { primary: (hasProc ? "Invalidate Process 1 and Change to Job " : "Change to Job ") +
|
|
134
|
+
jobUnique, secondary: job?.partName })] }, "job" + jobUnique))),
|
|
136
135
|
]
|
|
137
136
|
: [],
|
|
138
137
|
] }));
|
|
@@ -183,13 +182,15 @@ export function InvalidateCycleDialogButton(props) {
|
|
|
183
182
|
return null;
|
|
184
183
|
if (!canInvalidateMaterial(inProcMat))
|
|
185
184
|
return null;
|
|
186
|
-
const allowChange =
|
|
185
|
+
const allowChange = (lastMat === null || lastMat.process <= 1) &&
|
|
186
|
+
possibleNew !== null &&
|
|
187
187
|
(!LazySeq.ofObject(possibleNew.possibleCastingsByQueue ?? {}).isEmpty() ||
|
|
188
188
|
!LazySeq.ofObject(possibleNew.possibleJobsByQueue ?? {}).isEmpty());
|
|
189
189
|
if (!allowChange && (lastMat === null || lastMat.process < 1))
|
|
190
190
|
return null;
|
|
191
191
|
if (props.ignoreOperator)
|
|
192
192
|
operator = null;
|
|
193
|
+
const changingAssignment = props.st !== null && (props.st.changeRawMat !== null || props.st.changeJobUnique !== null);
|
|
193
194
|
function showInvalidate() {
|
|
194
195
|
props.setState({
|
|
195
196
|
process: null,
|
|
@@ -230,17 +231,20 @@ export function InvalidateCycleDialogButton(props) {
|
|
|
230
231
|
}
|
|
231
232
|
}
|
|
232
233
|
return (_jsxs(_Fragment, { children: [props.st === null ? (_jsx(Button, { color: "primary", onClick: showInvalidate, children: "Invalidate Cycle" })) : undefined, props.st !== null ? (_jsx(Button, { color: "primary", onClick: invalidateCycle, disabled: props.st.updating ||
|
|
234
|
+
(changingAssignment && !allowChange) ||
|
|
235
|
+
(!changingAssignment &&
|
|
236
|
+
props.st.process !== null &&
|
|
237
|
+
props.st.process !== lastMat?.process) ||
|
|
233
238
|
(props.st.process === null &&
|
|
234
239
|
props.st.changeRawMat === null &&
|
|
235
240
|
props.st.changeJobUnique === null), children: props.st.changeJobUnique !== null
|
|
236
|
-
?
|
|
241
|
+
? (lastMat?.process === 1
|
|
242
|
+
? "Invalidate Process 1 and Change to Job "
|
|
243
|
+
: "Change to Job ") + props.st.changeJobUnique
|
|
237
244
|
: props.st.changeRawMat !== null
|
|
238
|
-
? "Invalidate
|
|
245
|
+
? (lastMat?.process === 1 ? "Invalidate Process 1 and Change to " : "Change to ") +
|
|
246
|
+
props.st.changeRawMat
|
|
239
247
|
: props.st.process !== null
|
|
240
|
-
? props.st.process
|
|
241
|
-
? lastMat && lastMat.process > 1
|
|
242
|
-
? "Invalidate All Processes"
|
|
243
|
-
: "Invalidate Process 1"
|
|
244
|
-
: "Invalidate Process " + props.st.process.toString()
|
|
248
|
+
? "Invalidate Process " + props.st.process.toString()
|
|
245
249
|
: "Invalidate Cycle" })) : undefined] }));
|
|
246
250
|
}
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
import { SubmitBasketLoadStationCommand } from "./BasketLoadStationWork.js";
|
|
3
|
-
import { SubmitBasketLocationCorrection, SubmitBasketMovementCompletion } from "./BasketMovementArrival.js";
|
|
4
2
|
interface LoadStationProps {
|
|
5
3
|
readonly loadNum: number;
|
|
6
4
|
readonly queues: ReadonlyArray<string>;
|
|
7
5
|
readonly completed: boolean;
|
|
8
6
|
readonly whiteBackground?: boolean;
|
|
9
|
-
readonly submitBasketLoadStationCommand?: SubmitBasketLoadStationCommand;
|
|
10
|
-
readonly submitBasketMovementCompletion?: SubmitBasketMovementCompletion;
|
|
11
|
-
readonly submitBasketLocationCorrection?: SubmitBasketLocationCorrection;
|
|
12
7
|
}
|
|
13
8
|
export declare function LoadStation(props: LoadStationProps): import("react").JSX.Element;
|
|
14
9
|
declare function LoadStationCheckWidth(props: LoadStationProps): ReactNode;
|
|
@@ -31,7 +31,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
31
31
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
32
32
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
33
33
|
*/
|
|
34
|
-
import { useMemo, memo, useState, useCallback
|
|
34
|
+
import { useMemo, memo, useState, useCallback } from "react";
|
|
35
35
|
import { Box, useMediaQuery, Button, Typography } from "@mui/material";
|
|
36
36
|
import { LazySeq, OrderedMap } from "@seedtactics/immutable-collections";
|
|
37
37
|
import { FolderOpen as FolderOpenIcon } from "@mui/icons-material";
|
|
@@ -63,8 +63,7 @@ import { PrintLabelButton } from "./PrintedLabel.js";
|
|
|
63
63
|
import { hideNonLoadingMaterialOnLoadStation } from "../../data/queue-material.js";
|
|
64
64
|
import { basketDisplayName, loadStationDisplayName } from "../../cell-status/station-cycles.js";
|
|
65
65
|
import { canAddOrMoveMaterialToQueue } from "../../data/material-operation-policy.js";
|
|
66
|
-
import { BasketLoadStationWorkflow
|
|
67
|
-
import { BasketMovementArrival, loadStationArrivalInstruction, } from "./BasketMovementArrival.js";
|
|
66
|
+
import { BasketLoadStationWorkflow } from "./BasketLoadStationWork.js";
|
|
68
67
|
function encodeLoadStationRegionIdPart(value) {
|
|
69
68
|
return encodeURIComponent(value.toString());
|
|
70
69
|
}
|
|
@@ -393,7 +392,7 @@ function ElapsedLoadTime({ elapsedLoadTime }) {
|
|
|
393
392
|
return null;
|
|
394
393
|
}
|
|
395
394
|
}
|
|
396
|
-
function PalletFace({ data, faceNum
|
|
395
|
+
function PalletFace({ data, faceNum }) {
|
|
397
396
|
const face = data.face.get(faceNum);
|
|
398
397
|
const fmsInfo = useAtomValue(fmsInformation);
|
|
399
398
|
const basketName = basketDisplayName(fmsInfo.basketName);
|
|
@@ -408,7 +407,7 @@ function PalletFace({ data, faceNum, loadNum, submitBasketLoadStationCommand, })
|
|
|
408
407
|
}, children: _jsx(ElapsedLoadTime, { elapsedLoadTime: data.elapsedLoadingTime }) })] })) : null, _jsx(Box, { sx: { ml: "4em", mr: "4em" }, children: _jsx(MoveMaterialArrowNode, { kind: {
|
|
409
408
|
type: MoveMaterialNodeKindType.BasketZone,
|
|
410
409
|
basketId: data.activeBasket.basketId,
|
|
411
|
-
}, children: _jsx(BasketLoadStationWorkflow, {
|
|
410
|
+
}, children: _jsx(BasketLoadStationWorkflow, { basket: data.activeBasket, material: data.allMaterial, fsize: data.fsize }) }) })] }));
|
|
412
411
|
}
|
|
413
412
|
if (!data.pallet)
|
|
414
413
|
return null;
|
|
@@ -680,23 +679,6 @@ export function LoadStation(props) {
|
|
|
680
679
|
const currentSt = useAtomValue(currentStatus);
|
|
681
680
|
const hideNonLoading = useAtomValue(hideNonLoadingMaterialOnLoadStation);
|
|
682
681
|
const data = useMemo(() => selectLoadStationAndQueueProps(props.loadNum, props.queues, currentSt, hideNonLoading), [currentSt, props.loadNum, props.queues, hideNonLoading]);
|
|
683
|
-
const arrivalInstruction = loadStationArrivalInstruction(currentSt.basketMoveInstructions ?? [], props.loadNum);
|
|
684
|
-
const [recentArrivalReceipt, setRecentArrivalReceipt] = useState();
|
|
685
|
-
useEffect(() => {
|
|
686
|
-
if (recentArrivalReceipt !== undefined &&
|
|
687
|
-
(recentArrivalReceipt.stationNumber !== props.loadNum ||
|
|
688
|
-
(arrivalInstruction !== undefined &&
|
|
689
|
-
arrivalInstruction.instructionId !== recentArrivalReceipt.instruction.instructionId))) {
|
|
690
|
-
// This state is an ephemeral receipt; discard it permanently when a new instruction supersedes it.
|
|
691
|
-
// oxlint-disable-next-line react/set-state-in-effect -- intentional invalidation of stale UI state.
|
|
692
|
-
setRecentArrivalReceipt(undefined);
|
|
693
|
-
}
|
|
694
|
-
}, [arrivalInstruction, props.loadNum, recentArrivalReceipt]);
|
|
695
|
-
const displayedArrivalInstruction = arrivalInstruction ?? recentArrivalReceipt?.instruction;
|
|
696
|
-
const displayedArrivalReceipt = recentArrivalReceipt?.stationNumber === props.loadNum &&
|
|
697
|
-
displayedArrivalInstruction?.instructionId === recentArrivalReceipt?.instruction.instructionId
|
|
698
|
-
? recentArrivalReceipt
|
|
699
|
-
: undefined;
|
|
700
682
|
const queueCols = LazySeq.of(data.queues)
|
|
701
683
|
.sortBy(([q]) => q)
|
|
702
684
|
.map(([q, mats]) => ({
|
|
@@ -743,53 +725,31 @@ export function LoadStation(props) {
|
|
|
743
725
|
horizontal: fillViewPort,
|
|
744
726
|
showMatInCompleted: props.completed,
|
|
745
727
|
});
|
|
746
|
-
return (
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
gridTemplate: grid,
|
|
772
|
-
minHeight: {
|
|
773
|
-
xs: "calc(100vh - 64px - 32px)",
|
|
774
|
-
sm: "calc(100vh - 64px - 40px)",
|
|
775
|
-
md: "calc(100vh - 64px)",
|
|
776
|
-
},
|
|
777
|
-
padding: fillViewPort ? undefined : "8px",
|
|
778
|
-
}, children: [matCols.map((col, idx) => (_jsx(Box, { "data-testid": materialColumnTestId(col), sx: {
|
|
779
|
-
gridArea: `mat${idx}`,
|
|
780
|
-
padding: "8px",
|
|
781
|
-
borderRight: fillViewPort ? "1px solid black" : undefined,
|
|
782
|
-
borderBottom: !fillViewPort ? "1px solid black" : undefined,
|
|
783
|
-
}, children: _jsx(MaterialColumn, { data: data, region: col }) }, idx))), data.face.keysToAscLazySeq().map((faceNum, idx) => (_jsx(Box, { sx: {
|
|
784
|
-
marginLeft: "15px",
|
|
785
|
-
gridArea: `palface${idx}`,
|
|
786
|
-
padding: "8px",
|
|
787
|
-
borderTop: data.pallet && idx !== 0 ? "1px solid black" : undefined,
|
|
788
|
-
}, children: _jsx(PalletFace, { data: data, faceNum: faceNum, loadNum: props.loadNum, submitBasketLoadStationCommand: props.submitBasketLoadStationCommand }) }, faceNum))), _jsx(Box, { "data-testid": "load-station-completed", sx: {
|
|
789
|
-
borderLeft: fillViewPort ? "1px solid black" : undefined,
|
|
790
|
-
borderTop: !fillViewPort ? "1px solid black" : undefined,
|
|
791
|
-
gridArea: "completed",
|
|
792
|
-
}, children: _jsx(CompletedCol, { fillViewPort: fillViewPort, showMaterial: props.completed }) }), _jsx(MultiInstructionButton, { loadData: data }), _jsx(SelectWorkorderDialog, {}), _jsx(SelectInspTypeDialog, {}), _jsx(LoadMatDialog, { pallet: data.pallet?.palletNum ?? null, queues: props.queues })] }) })] }));
|
|
728
|
+
return (_jsx(_Fragment, { children: _jsx(MoveMaterialArrowContainer, { hideArrows: !fillViewPort, whiteBackground: props.whiteBackground, children: _jsxs(Box, { component: "main", sx: {
|
|
729
|
+
width: "100%",
|
|
730
|
+
display: "grid",
|
|
731
|
+
gridTemplate: grid,
|
|
732
|
+
minHeight: {
|
|
733
|
+
xs: "calc(100vh - 64px - 32px)",
|
|
734
|
+
sm: "calc(100vh - 64px - 40px)",
|
|
735
|
+
md: "calc(100vh - 64px)",
|
|
736
|
+
},
|
|
737
|
+
padding: fillViewPort ? undefined : "8px",
|
|
738
|
+
}, children: [matCols.map((col, idx) => (_jsx(Box, { "data-testid": materialColumnTestId(col), sx: {
|
|
739
|
+
gridArea: `mat${idx}`,
|
|
740
|
+
padding: "8px",
|
|
741
|
+
borderRight: fillViewPort ? "1px solid black" : undefined,
|
|
742
|
+
borderBottom: !fillViewPort ? "1px solid black" : undefined,
|
|
743
|
+
}, children: _jsx(MaterialColumn, { data: data, region: col }) }, idx))), data.face.keysToAscLazySeq().map((faceNum, idx) => (_jsx(Box, { sx: {
|
|
744
|
+
marginLeft: "15px",
|
|
745
|
+
gridArea: `palface${idx}`,
|
|
746
|
+
padding: "8px",
|
|
747
|
+
borderTop: data.pallet && idx !== 0 ? "1px solid black" : undefined,
|
|
748
|
+
}, children: _jsx(PalletFace, { data: data, faceNum: faceNum }) }, faceNum))), _jsx(Box, { "data-testid": "load-station-completed", sx: {
|
|
749
|
+
borderLeft: fillViewPort ? "1px solid black" : undefined,
|
|
750
|
+
borderTop: !fillViewPort ? "1px solid black" : undefined,
|
|
751
|
+
gridArea: "completed",
|
|
752
|
+
}, children: _jsx(CompletedCol, { fillViewPort: fillViewPort, showMaterial: props.completed }) }), _jsx(MultiInstructionButton, { loadData: data }), _jsx(SelectWorkorderDialog, {}), _jsx(SelectInspTypeDialog, {}), _jsx(LoadMatDialog, { pallet: data.pallet?.palletNum ?? null, queues: props.queues })] }) }) }));
|
|
793
753
|
}
|
|
794
754
|
function LoadStationCheckWidth(props) {
|
|
795
755
|
const fmsInfo = useAtomValue(fmsInformation);
|
|
@@ -49,7 +49,7 @@ import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
|
49
49
|
import { last30Rebookings } from "../../cell-status/rebookings.js";
|
|
50
50
|
import { fmsInformation } from "../../network/server-settings.js";
|
|
51
51
|
import { basketDisplayName, basketSlotLabel } from "../../cell-status/station-cycles.js";
|
|
52
|
-
import { materialOperationState } from "../../data/material-operation-policy.js";
|
|
52
|
+
import { canAddOrMoveMaterialToQueue, canReorderQueuedMaterial, materialOperationState, } from "../../data/material-operation-policy.js";
|
|
53
53
|
export class PartIdenticon extends PureComponent {
|
|
54
54
|
render() {
|
|
55
55
|
const iconSize = this.props.size || 50;
|
|
@@ -402,10 +402,12 @@ export const InProcMaterial = memo(function InProcMaterial(props) {
|
|
|
402
402
|
return (_jsx(MatCard, { mat: inproc_mat_to_summary(props.mat), inProcMat: props.mat, displayActionForSinglePallet: props.displayActionForSinglePallet, fsize: props.fsize, hideAvatar: props.hideAvatar, displayJob: props.displayJob, showDragHandle: props.showHandle, hideEmptySerial: props.hideEmptySerial, showRawMaterial: props.showRawMaterial, showJobComment: props.showJobComment, shake: props.shake }));
|
|
403
403
|
});
|
|
404
404
|
export const SortableInProcMaterial = memo(function SortableInProcMaterial(props) {
|
|
405
|
+
const canDrag = canReorderQueuedMaterial(props.mat) || canAddOrMoveMaterialToQueue(props.mat);
|
|
405
406
|
const d = { mat: props.mat };
|
|
406
407
|
const { active, isDragging, attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, } = useSortable({
|
|
407
408
|
id: props.mat.materialID,
|
|
408
409
|
data: d,
|
|
410
|
+
disabled: { draggable: !canDrag },
|
|
409
411
|
});
|
|
410
412
|
const handleProps = {
|
|
411
413
|
...listeners,
|
|
@@ -421,7 +423,7 @@ export const SortableInProcMaterial = memo(function SortableInProcMaterial(props
|
|
|
421
423
|
: undefined,
|
|
422
424
|
transition: active !== null ? transition : undefined,
|
|
423
425
|
};
|
|
424
|
-
return (_jsx(MatCard, { ref: setNodeRef, dragRootProps: { style }, showDragHandle:
|
|
426
|
+
return (_jsx(MatCard, { ref: setNodeRef, dragRootProps: { style }, showDragHandle: canDrag, dragHandleProps: handleProps, setDragHandleRef: setActivatorNodeRef, isActiveDrag: isDragging, mat: inproc_mat_to_summary(props.mat), inProcMat: props.mat, displayActionForSinglePallet: props.displayActionForSinglePallet, hideAvatar: props.hideAvatar, displayJob: props.displayJob, hideEmptySerial: props.hideEmptySerial, fsize: props.fsize, shake: active ? undefined : props.shake, showRawMaterial: props.showRawMaterial }));
|
|
425
427
|
});
|
|
426
428
|
export function DragOverlayInProcMaterial(props) {
|
|
427
429
|
return (_jsx(MatCard, { mat: inproc_mat_to_summary(props.mat), inProcMat: props.mat, displayActionForSinglePallet: props.displayActionForSinglePallet, showDragHandle: true, hideAvatar: props.hideAvatar, displayJob: props.displayJob, fsize: props.fsize, hideEmptySerial: props.hideEmptySerial, isDragOverlay: true }));
|
|
@@ -40,15 +40,16 @@ import { currentOperator } from "../../data/operators.js";
|
|
|
40
40
|
import { ApiException, LocType, QueueRole, } from "../../network/api.js";
|
|
41
41
|
import { fmsInformation } from "../../network/server-settings.js";
|
|
42
42
|
import { useAtomValue, useSetAtom } from "jotai";
|
|
43
|
-
import { canDirectlyQuarantine, canRemoveFromQueue, canSignalQuarantine,
|
|
43
|
+
import { canDirectlyQuarantine, canRemoveFromQueue, canSignalQuarantine, quarantineRoute, } from "../../data/material-operation-policy.js";
|
|
44
44
|
function hasSupportedQuarantineExit(material, status) {
|
|
45
45
|
const job = status.jobs[material.jobUnique];
|
|
46
46
|
if (!job)
|
|
47
47
|
return false;
|
|
48
|
-
const
|
|
48
|
+
const route = quarantineRoute(material);
|
|
49
|
+
const path = job.procsAndPaths[route.process - 1]?.paths[route.path - 1];
|
|
49
50
|
if (!path)
|
|
50
51
|
return false;
|
|
51
|
-
return
|
|
52
|
+
return route.process === job.procsAndPaths.length || Boolean(path.outputQueue);
|
|
52
53
|
}
|
|
53
54
|
function useQuarantineMaterial() {
|
|
54
55
|
const fmsInfo = useAtomValue(fmsInformation);
|
|
@@ -56,8 +57,6 @@ function useQuarantineMaterial() {
|
|
|
56
57
|
const curSt = useAtomValue(currentStatus);
|
|
57
58
|
if (inProcMat === null || inProcMat.materialID < 0)
|
|
58
59
|
return null;
|
|
59
|
-
if (isActiveLoadStationOperation(inProcMat))
|
|
60
|
-
return null;
|
|
61
60
|
if (inProcMat.quarantineAfterUnload)
|
|
62
61
|
return null;
|
|
63
62
|
const quarantineQueue = fmsInfo.quarantineQueue?.length ? fmsInfo.quarantineQueue : null;
|
|
@@ -80,7 +79,8 @@ function useQuarantineMaterial() {
|
|
|
80
79
|
.filter(([qname]) => !activeQueues.has(qname))
|
|
81
80
|
.toRSet(([qname]) => qname);
|
|
82
81
|
// If in a quarantine queue, allow removal from system
|
|
83
|
-
if (inProcMat
|
|
82
|
+
if (canRemoveFromQueue(inProcMat) &&
|
|
83
|
+
inProcMat.location.type === LocType.InQueue &&
|
|
84
84
|
inProcMat.location.currentQueue &&
|
|
85
85
|
quarantineQueues.has(inProcMat.location.currentQueue)) {
|
|
86
86
|
return {
|
|
@@ -91,25 +91,16 @@ function useQuarantineMaterial() {
|
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
93
|
let type = null;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
case LocType.InQueue:
|
|
103
|
-
if (!canDirectlyQuarantine(inProcMat))
|
|
104
|
-
return null;
|
|
105
|
-
if (inProcMat.location.currentQueue === undefined ||
|
|
106
|
-
quarantineQueues.has(inProcMat.location.currentQueue)) {
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
type = "Scrap";
|
|
110
|
-
break;
|
|
111
|
-
case LocType.Free:
|
|
94
|
+
if (canSignalQuarantine(inProcMat)) {
|
|
95
|
+
if (!hasSupportedQuarantineExit(inProcMat, curSt))
|
|
96
|
+
return null;
|
|
97
|
+
type = "SignalForScrap";
|
|
98
|
+
}
|
|
99
|
+
else if (canDirectlyQuarantine(inProcMat)) {
|
|
100
|
+
if (inProcMat.location.currentQueue === undefined ||
|
|
101
|
+
quarantineQueues.has(inProcMat.location.currentQueue))
|
|
112
102
|
return null;
|
|
103
|
+
type = "Scrap";
|
|
113
104
|
}
|
|
114
105
|
if (type) {
|
|
115
106
|
return {
|
|
@@ -214,7 +205,7 @@ export function QuarantineMatButton({ onClose, ignoreOperator, }) {
|
|
|
214
205
|
title = displayedSnapshot.destination
|
|
215
206
|
? `The current automated operation will continue. When the material leaves automation control, move it to ${displayedSnapshot.destination}`
|
|
216
207
|
: "The current automated operation will continue. When the material leaves automation control, remove it from normal production flow as scrap";
|
|
217
|
-
btnTxt = displayedSnapshot.destination ? "
|
|
208
|
+
btnTxt = displayedSnapshot.destination ? "Signal for quarantine" : "Scrap";
|
|
218
209
|
break;
|
|
219
210
|
}
|
|
220
211
|
async function quarantine() {
|
|
@@ -266,5 +257,5 @@ export function QuarantineMatButton({ onClose, ignoreOperator, }) {
|
|
|
266
257
|
? quarantiningQueued
|
|
267
258
|
: removingFromQueue);
|
|
268
259
|
const removeFromQueues = q?.canRemoveFromQueues === true ? () => removeFromQueue(q.material.materialID, operator) : null;
|
|
269
|
-
return (_jsxs(_Fragment, { children: [q ? (_jsx(Tooltip, { title: title, children: _jsx(Button, { color: "primary", disabled: removing, onClick: openQuarantine, children: btnTxt }) })) : null, removeFromQueues && q ? (_jsx(RemoveFromQueuesButton, { material: q.material, removeFromQueues: removeFromQueues, removing: removingFromQueue })) : null, _jsxs(Dialog, { open: open && snapshot !== null, onClose: closeQuarantine, children: [_jsx(DialogTitle, { children: "Quarantine Material" }), _jsxs(DialogContent, { children: [_jsx("p", { children: title }), _jsx(TextField, { label: "Reason", value: reason, onChange: (e) => setReason(e.target.value), fullWidth: true, autoFocus: true, multiline: true }), error ? _jsx("p", { role: "alert", children: error }) : null] }), _jsxs(DialogActions, { children: [_jsx(Button, { color: "primary", disabled: removing, onClick: quarantine, children: btnTxt }), _jsx(Button, { color: "secondary", disabled: removing, onClick: closeQuarantine, children: "Cancel" })] })] })] }));
|
|
260
|
+
return (_jsxs(_Fragment, { children: [q ? (_jsx(Tooltip, { title: title, describeChild: displayedSnapshot.operation === "DeferredQuarantine", children: _jsx(Button, { color: "primary", disabled: removing, onClick: openQuarantine, children: btnTxt }) })) : null, removeFromQueues && q ? (_jsx(RemoveFromQueuesButton, { material: q.material, removeFromQueues: removeFromQueues, removing: removingFromQueue })) : null, _jsxs(Dialog, { open: open && snapshot !== null, onClose: closeQuarantine, children: [_jsx(DialogTitle, { children: "Quarantine Material" }), _jsxs(DialogContent, { children: [_jsx("p", { children: title }), _jsx(TextField, { label: "Reason", value: reason, onChange: (e) => setReason(e.target.value), fullWidth: true, autoFocus: true, multiline: true }), error ? _jsx("p", { role: "alert", children: error }) : null] }), _jsxs(DialogActions, { children: [_jsx(Button, { color: "primary", disabled: removing, onClick: quarantine, children: btnTxt }), _jsx(Button, { color: "secondary", disabled: removing, onClick: closeQuarantine, children: "Cancel" })] })] })] }));
|
|
270
261
|
}
|