sanity-plugin-workflow 1.0.0-beta.4 → 1.0.0-beta.6
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 +13 -6
- package/lib/index.d.ts +1 -0
- package/lib/index.esm.js +166 -107
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +164 -105
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/actions/UpdateWorkflow.tsx +22 -24
- package/src/components/DocumentCard/Validate.tsx +21 -0
- package/src/components/DocumentCard/index.tsx +91 -103
- package/src/components/DocumentList.tsx +1 -1
- package/src/components/StateTitle/index.tsx +31 -26
- package/src/components/{Validators.tsx → Verify.tsx} +29 -2
- package/src/components/WorkflowTool.tsx +15 -6
- package/src/constants/index.ts +1 -1
- package/src/hooks/useWorkflowDocuments.tsx +8 -5
- package/src/types/index.ts +1 -3
- package/src/actions/RequestReviewAction.js +0 -55
- package/src/actions/index.js +0 -21
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ With Sanity Studio you can [customize your content tools to support arbitrary wo
|
|
|
12
12
|
|
|
13
13
|
This plugin is distributed as a **reference implementation** of these customization APIs and is not considered to be a feature-complete implementation of what workflow management requires in production. It is a starting point intended to be forked and customized to the needs of your organization and content creators.
|
|
14
14
|
|
|
15
|
+
A key intention of this plugin is that it **does not influence or modify whether a document is in draft or published**. It only tracks the values of a separate "metadata" document. In this implementation, an "Approved" document could be a draft but will still need publishing. "Approving" the document simply removes it from the Workflow process. You will decide if Publishing the document happens in the Studio like normal, using the [Scheduled Publishing plugin](https://www.sanity.io/plugins/scheduled-publishing) or the [Scheduling API](https://www.sanity.io/docs/scheduling-api#fa3bb95f83ed).
|
|
16
|
+
|
|
15
17
|

|
|
16
18
|
|
|
17
19
|
## Features
|
|
@@ -51,7 +53,7 @@ Add it as a plugin in sanity.config.ts (or .js):
|
|
|
51
53
|
// schemaTypes: ['article', 'product'],
|
|
52
54
|
schemaTypes: [],
|
|
53
55
|
// Optional, see below
|
|
54
|
-
states: [],
|
|
56
|
+
// states: [],
|
|
55
57
|
})
|
|
56
58
|
]
|
|
57
59
|
})
|
|
@@ -71,10 +73,13 @@ Documents can be promoted and demoted in the Workflow with the provided Document
|
|
|
71
73
|
// Optional settings:
|
|
72
74
|
// Used for the color of the Document Badge
|
|
73
75
|
color: 'success',
|
|
74
|
-
// Will
|
|
76
|
+
// Will limit document actions and drag-and-drop for only users with these Role
|
|
75
77
|
roles: ['publisher', 'administrator'],
|
|
76
78
|
// Requires the user to be "assigned" in order to update to this State
|
|
77
79
|
requireAssignment: true,
|
|
80
|
+
// Requires the document to be valid before being promoted out of this State
|
|
81
|
+
// Warning: With many documents in the Kanban view this can negatively impact performance
|
|
82
|
+
requireValidation: true,
|
|
78
83
|
// Defines which States a document can be moved to from this one
|
|
79
84
|
transitions: ['changesRequested', 'approved']
|
|
80
85
|
}
|
|
@@ -98,10 +103,12 @@ Once the Workflow is complete, the metadata can be removed by using the "Complet
|
|
|
98
103
|
|
|
99
104
|
This plugin is largely based on the original Workflow Demo built into a Sanity Studio v2 project. The major differences are:
|
|
100
105
|
|
|
101
|
-
* This plugin
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
106
|
+
* This plugin is not concerned with nor will modify whether a document is in draft or published.
|
|
107
|
+
* This plugin can be more easily installed and configured, not just code examples built into a Studio project.
|
|
108
|
+
* Documents must "opt-in" to and be removed from the Workflow. In the previous version, all documents were in the workflow which would fill up the interface and negatively affect performance.
|
|
109
|
+
* Document validation status can be used as a way to prevent movement through the workflow.
|
|
110
|
+
* User Roles and Assignments can affect the Workflow. Set rules to enforce which States documents can move between and if being assigned to a document is required to move it to a new State.
|
|
111
|
+
* This plugin can filter Schema types and assigned Users.
|
|
105
112
|
|
|
106
113
|
## License
|
|
107
114
|
|
package/lib/index.d.ts
CHANGED
package/lib/index.esm.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
var _templateObject, _templateObject2, _templateObject3;
|
|
2
2
|
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
|
3
|
-
import { useClient,
|
|
3
|
+
import { useClient, useCurrentUser, useValidationStatus, useSchema, Preview, useFormValue, defineType, defineField, UserAvatar, useTimeAgo, TextWithTone, definePlugin } from 'sanity';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import { UsersIcon, SplitVerticalIcon, CheckmarkIcon, ArrowRightIcon, ArrowLeftIcon, EditIcon, AddIcon, PublishIcon, ErrorOutlineIcon, WarningOutlineIcon, DragHandleIcon, UserIcon, ResetIcon, InfoOutlineIcon } from '@sanity/icons';
|
|
6
|
-
import React, { useState, useCallback,
|
|
6
|
+
import React, { useState, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
7
7
|
import { UserSelectMenu, useListeningQuery, useProjectUsers, Feedback } from 'sanity-plugin-utils';
|
|
8
8
|
import { useToast, Button, Spinner, Card, Flex, Box, Text, useClickOutside, Popover, Grid, Tooltip, useTheme, Stack, MenuButton, Menu, Badge, Container } from '@sanity/ui';
|
|
9
9
|
import { LexoRank } from 'lexorank';
|
|
@@ -36,8 +36,8 @@ const DEFAULT_CONFIG = {
|
|
|
36
36
|
title: "Approved",
|
|
37
37
|
color: "success",
|
|
38
38
|
roles: ["administrator"],
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
transitions: ["changesRequested"],
|
|
40
|
+
requireAssignment: true
|
|
41
41
|
}])
|
|
42
42
|
};
|
|
43
43
|
function UserAssignment(props) {
|
|
@@ -291,11 +291,6 @@ function UpdateWorkflow(props, allStates, actionState) {
|
|
|
291
291
|
id,
|
|
292
292
|
type
|
|
293
293
|
} = props;
|
|
294
|
-
const {
|
|
295
|
-
validation,
|
|
296
|
-
isValidating
|
|
297
|
-
} = useValidationStatus(id, type);
|
|
298
|
-
const hasValidationErrors = !isValidating && (validation == null ? void 0 : validation.length) > 0 && validation.find(v => v.level === "error");
|
|
299
294
|
const user = useCurrentUser();
|
|
300
295
|
const client = useClient({
|
|
301
296
|
apiVersion: API_VERSION
|
|
@@ -313,6 +308,11 @@ function UpdateWorkflow(props, allStates, actionState) {
|
|
|
313
308
|
const {
|
|
314
309
|
assignees = []
|
|
315
310
|
} = (_a = data == null ? void 0 : data.metadata) != null ? _a : {};
|
|
311
|
+
const {
|
|
312
|
+
validation,
|
|
313
|
+
isValidating
|
|
314
|
+
} = useValidationStatus(id, type);
|
|
315
|
+
const hasValidationErrors = (currentState == null ? void 0 : currentState.requireValidation) && !isValidating && (validation == null ? void 0 : validation.length) > 0 && validation.find(v => v.level === "error");
|
|
316
316
|
if (error) {
|
|
317
317
|
console.error(error);
|
|
318
318
|
}
|
|
@@ -342,40 +342,39 @@ function UpdateWorkflow(props, allStates, actionState) {
|
|
|
342
342
|
const direction = actionStateIndex > currentStateIndex ? "promote" : "demote";
|
|
343
343
|
const DirectionIcon = direction === "promote" ? ArrowRightIcon : ArrowLeftIcon;
|
|
344
344
|
const directionLabel = direction === "promote" ? "Promote" : "Demote";
|
|
345
|
-
let title = "".concat(directionLabel, " State to \"").concat(actionState.title, "\"");
|
|
346
345
|
const userRoleCanUpdateState = ((_b = user == null ? void 0 : user.roles) == null ? void 0 : _b.length) && ((_c = actionState == null ? void 0 : actionState.roles) == null ? void 0 : _c.length) ?
|
|
347
346
|
// If the Action state is limited to specific roles
|
|
348
347
|
// check that the current user has one of those roles
|
|
349
348
|
arraysContainMatchingString(user.roles.map(r => r.name), actionState.roles) :
|
|
350
349
|
// No roles specified on the next state, so anyone can update
|
|
351
350
|
((_d = actionState == null ? void 0 : actionState.roles) == null ? void 0 : _d.length) !== 0;
|
|
352
|
-
if (!userRoleCanUpdateState) {
|
|
353
|
-
title = "Your User role cannot ".concat(directionLabel, " State to \"").concat(actionState.title, "\"");
|
|
354
|
-
}
|
|
355
351
|
const actionStateIsAValidTransition = (currentState == null ? void 0 : currentState.id) && currentState.transitions.length ?
|
|
356
352
|
// If the Current State limits transitions to specific States
|
|
357
353
|
// Check that the Action State is in Current State's transitions array
|
|
358
354
|
currentState.transitions.includes(actionState.id) :
|
|
359
355
|
// Otherwise this isn't a problem
|
|
360
356
|
true;
|
|
361
|
-
if (!actionStateIsAValidTransition) {
|
|
362
|
-
title = "You cannot ".concat(directionLabel, " State to \"").concat(actionState.title, "\" from \"").concat(currentState == null ? void 0 : currentState.title, "\"");
|
|
363
|
-
}
|
|
364
357
|
const userAssignmentCanUpdateState = actionState.requireAssignment ?
|
|
365
358
|
// If the Action State requires assigned users
|
|
366
359
|
// Check the current user ID is in the assignees array
|
|
367
360
|
currentUser && assignees.length && assignees.includes(currentUser.id) :
|
|
368
361
|
// Otherwise this isn't a problem
|
|
369
362
|
true;
|
|
370
|
-
|
|
363
|
+
let title = "".concat(directionLabel, " State to \"").concat(actionState.title, "\"");
|
|
364
|
+
if (!userRoleCanUpdateState) {
|
|
365
|
+
title = "Your User role cannot ".concat(directionLabel, " State to \"").concat(actionState.title, "\"");
|
|
366
|
+
} else if (!actionStateIsAValidTransition) {
|
|
367
|
+
title = "You cannot ".concat(directionLabel, " State to \"").concat(actionState.title, "\" from \"").concat(currentState == null ? void 0 : currentState.title, "\"");
|
|
368
|
+
} else if (!userAssignmentCanUpdateState) {
|
|
371
369
|
title = "You must be assigned to the document to ".concat(directionLabel, " State to \"").concat(actionState.title, "\"");
|
|
372
|
-
}
|
|
373
|
-
|
|
370
|
+
} else if ((currentState == null ? void 0 : currentState.requireValidation) && isValidating) {
|
|
371
|
+
title = "Document is validating, cannot ".concat(directionLabel, " State to \"").concat(actionState.title, "\"");
|
|
372
|
+
} else if (hasValidationErrors) {
|
|
374
373
|
title = "Document has validation errors, cannot ".concat(directionLabel, " State to \"").concat(actionState.title, "\"");
|
|
375
374
|
}
|
|
376
375
|
return {
|
|
377
376
|
icon: DirectionIcon,
|
|
378
|
-
disabled: loading || error || isValidating || hasValidationErrors || !currentState || !userRoleCanUpdateState || !actionStateIsAValidTransition || !userAssignmentCanUpdateState,
|
|
377
|
+
disabled: loading || error || (currentState == null ? void 0 : currentState.requireValidation) && isValidating || hasValidationErrors || !currentState || !userRoleCanUpdateState || !actionStateIsAValidTransition || !userAssignmentCanUpdateState,
|
|
379
378
|
title,
|
|
380
379
|
label: actionState.title,
|
|
381
380
|
onHandle: () => onHandle(id, actionState)
|
|
@@ -634,7 +633,7 @@ function useWorkflowDocuments(schemaTypes) {
|
|
|
634
633
|
setLocalDocuments(data);
|
|
635
634
|
}
|
|
636
635
|
}, [data]);
|
|
637
|
-
const move = React.useCallback((draggedId, destination, states, newOrder) => {
|
|
636
|
+
const move = React.useCallback(async (draggedId, destination, states, newOrder) => {
|
|
638
637
|
const currentLocalData = localDocuments;
|
|
639
638
|
const newLocalDocuments = localDocuments.map(item => {
|
|
640
639
|
var _a;
|
|
@@ -681,10 +680,9 @@ function useWorkflowDocuments(schemaTypes) {
|
|
|
681
680
|
_type
|
|
682
681
|
} = document;
|
|
683
682
|
const {
|
|
684
|
-
_rev,
|
|
685
683
|
documentId
|
|
686
684
|
} = document._metadata || {};
|
|
687
|
-
client.patch("workflow-metadata.".concat(documentId)).
|
|
685
|
+
await client.patch("workflow-metadata.".concat(documentId)).set({
|
|
688
686
|
state: newStateId,
|
|
689
687
|
orderRank: newOrder
|
|
690
688
|
}).commit().then(() => {
|
|
@@ -693,11 +691,12 @@ function useWorkflowDocuments(schemaTypes) {
|
|
|
693
691
|
title: "Moved to \"".concat((_a = newState == null ? void 0 : newState.title) != null ? _a : newStateId, "\""),
|
|
694
692
|
status: "success"
|
|
695
693
|
});
|
|
696
|
-
}).catch(
|
|
694
|
+
}).catch(err => {
|
|
697
695
|
var _a;
|
|
698
696
|
setLocalDocuments(currentLocalData);
|
|
699
697
|
return toast.push({
|
|
700
698
|
title: "Failed to move to \"".concat((_a = newState == null ? void 0 : newState.title) != null ? _a : newStateId, "\""),
|
|
699
|
+
description: err.message,
|
|
701
700
|
status: "error"
|
|
702
701
|
});
|
|
703
702
|
});
|
|
@@ -908,6 +907,24 @@ function PublishedStatus(props) {
|
|
|
908
907
|
})
|
|
909
908
|
});
|
|
910
909
|
}
|
|
910
|
+
function Validate(props) {
|
|
911
|
+
const {
|
|
912
|
+
documentId,
|
|
913
|
+
type,
|
|
914
|
+
onChange
|
|
915
|
+
} = props;
|
|
916
|
+
const {
|
|
917
|
+
isValidating,
|
|
918
|
+
validation = []
|
|
919
|
+
} = useValidationStatus(documentId, type);
|
|
920
|
+
useEffect(() => {
|
|
921
|
+
onChange({
|
|
922
|
+
isValidating,
|
|
923
|
+
validation
|
|
924
|
+
});
|
|
925
|
+
}, [onChange, isValidating, validation]);
|
|
926
|
+
return null;
|
|
927
|
+
}
|
|
911
928
|
function ValidationStatus(props) {
|
|
912
929
|
const {
|
|
913
930
|
validation = []
|
|
@@ -933,7 +950,7 @@ function ValidationStatus(props) {
|
|
|
933
950
|
});
|
|
934
951
|
}
|
|
935
952
|
function DocumentCard(props) {
|
|
936
|
-
var _a;
|
|
953
|
+
var _a, _b;
|
|
937
954
|
const {
|
|
938
955
|
isDragDisabled,
|
|
939
956
|
userRoleCanDrop,
|
|
@@ -948,18 +965,29 @@ function DocumentCard(props) {
|
|
|
948
965
|
documentId
|
|
949
966
|
} = (_a = item._metadata) != null ? _a : {};
|
|
950
967
|
const schema = useSchema();
|
|
968
|
+
const state = states.find(s => {
|
|
969
|
+
var _a2;
|
|
970
|
+
return s.id === ((_a2 = item._metadata) == null ? void 0 : _a2.state);
|
|
971
|
+
});
|
|
951
972
|
const isDarkMode = useTheme().sanity.color.dark;
|
|
952
973
|
const defaultCardTone = isDarkMode ? "transparent" : "default";
|
|
974
|
+
const [optimisticValidation, setOptimisticValidation] = useState({
|
|
975
|
+
isValidating: (_b = state == null ? void 0 : state.requireValidation) != null ? _b : false,
|
|
976
|
+
validation: []
|
|
977
|
+
});
|
|
953
978
|
const {
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
} =
|
|
979
|
+
isValidating,
|
|
980
|
+
validation
|
|
981
|
+
} = optimisticValidation;
|
|
982
|
+
const handleValidation = useCallback(updates => {
|
|
983
|
+
setOptimisticValidation(updates);
|
|
984
|
+
}, []);
|
|
957
985
|
const cardTone = useMemo(() => {
|
|
958
986
|
let tone = defaultCardTone;
|
|
959
987
|
if (!userRoleCanDrop) return isDarkMode ? "default" : "transparent";
|
|
960
988
|
if (!documentId) return tone;
|
|
961
989
|
if (isDragging) tone = "positive";
|
|
962
|
-
if (!isValidating && validation.length > 0) {
|
|
990
|
+
if ((state == null ? void 0 : state.requireValidation) && !isValidating && validation.length > 0) {
|
|
963
991
|
if (validation.some(v => v.level === "error")) {
|
|
964
992
|
tone = "critical";
|
|
965
993
|
} else {
|
|
@@ -967,7 +995,7 @@ function DocumentCard(props) {
|
|
|
967
995
|
}
|
|
968
996
|
}
|
|
969
997
|
return tone;
|
|
970
|
-
}, [
|
|
998
|
+
}, [defaultCardTone, userRoleCanDrop, isDarkMode, documentId, isDragging, isValidating, validation, state == null ? void 0 : state.requireValidation]);
|
|
971
999
|
useEffect(() => {
|
|
972
1000
|
if (!isValidating && validation.length > 0) {
|
|
973
1001
|
if (validation.some(v => v.level === "error")) {
|
|
@@ -984,75 +1012,81 @@ function DocumentCard(props) {
|
|
|
984
1012
|
var _a2;
|
|
985
1013
|
return states[states.length - 1].id === ((_a2 = item._metadata) == null ? void 0 : _a2.state);
|
|
986
1014
|
}, [states, item._metadata.state]);
|
|
987
|
-
return /* @__PURE__ */
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1015
|
+
return /* @__PURE__ */jsxs(Fragment, {
|
|
1016
|
+
children: [(state == null ? void 0 : state.requireValidation) ? /* @__PURE__ */jsx(Validate, {
|
|
1017
|
+
documentId,
|
|
1018
|
+
type: item._type,
|
|
1019
|
+
onChange: handleValidation
|
|
1020
|
+
}) : null, /* @__PURE__ */jsx(Box, {
|
|
1021
|
+
paddingBottom: 3,
|
|
1022
|
+
paddingX: 3,
|
|
1023
|
+
children: /* @__PURE__ */jsx(Card, {
|
|
1024
|
+
radius: 2,
|
|
1025
|
+
shadow: isDragging ? 3 : 1,
|
|
1026
|
+
tone: cardTone,
|
|
1027
|
+
children: /* @__PURE__ */jsxs(Stack, {
|
|
1028
|
+
children: [/* @__PURE__ */jsx(Card, {
|
|
1029
|
+
borderBottom: true,
|
|
1030
|
+
radius: 2,
|
|
1031
|
+
padding: 3,
|
|
1032
|
+
paddingLeft: 2,
|
|
1033
|
+
tone: cardTone,
|
|
1034
|
+
style: {
|
|
1035
|
+
pointerEvents: "none"
|
|
1036
|
+
},
|
|
1037
|
+
children: /* @__PURE__ */jsxs(Flex, {
|
|
1038
|
+
align: "center",
|
|
1039
|
+
justify: "space-between",
|
|
1040
|
+
gap: 1,
|
|
1041
|
+
children: [/* @__PURE__ */jsx(Box, {
|
|
1042
|
+
flex: 1,
|
|
1043
|
+
children: /* @__PURE__ */jsx(Preview, {
|
|
1044
|
+
layout: "default",
|
|
1045
|
+
value: item,
|
|
1046
|
+
schemaType: schema.get(item._type)
|
|
1047
|
+
})
|
|
1048
|
+
}), /* @__PURE__ */jsx(Box, {
|
|
1049
|
+
style: {
|
|
1050
|
+
flexShrink: 0
|
|
1051
|
+
},
|
|
1052
|
+
children: hasError || isDragDisabled ? null : /* @__PURE__ */jsx(DragHandleIcon, {})
|
|
1053
|
+
})]
|
|
1054
|
+
})
|
|
1055
|
+
}), /* @__PURE__ */jsx(Card, {
|
|
1056
|
+
padding: 2,
|
|
1057
|
+
radius: 2,
|
|
1058
|
+
tone: "inherit",
|
|
1059
|
+
children: /* @__PURE__ */jsxs(Flex, {
|
|
1060
|
+
align: "center",
|
|
1061
|
+
justify: "space-between",
|
|
1062
|
+
gap: 3,
|
|
1063
|
+
children: [/* @__PURE__ */jsx(Box, {
|
|
1064
|
+
flex: 1,
|
|
1065
|
+
children: documentId && /* @__PURE__ */jsx(UserDisplay, {
|
|
1066
|
+
userList,
|
|
1067
|
+
assignees,
|
|
1068
|
+
documentId,
|
|
1069
|
+
disabled: !userRoleCanDrop
|
|
1070
|
+
})
|
|
1071
|
+
}), validation.length > 0 ? /* @__PURE__ */jsx(ValidationStatus, {
|
|
1072
|
+
validation
|
|
1073
|
+
}) : null, /* @__PURE__ */jsx(DraftStatus, {
|
|
1074
|
+
document: item
|
|
1075
|
+
}), /* @__PURE__ */jsx(PublishedStatus, {
|
|
1076
|
+
document: item
|
|
1077
|
+
}), /* @__PURE__ */jsx(EditButton, {
|
|
1078
|
+
id: item._id,
|
|
1079
|
+
type: item._type,
|
|
1080
|
+
disabled: !userRoleCanDrop
|
|
1081
|
+
}), isLastState ? /* @__PURE__ */jsx(CompleteButton, {
|
|
1035
1082
|
documentId,
|
|
1036
1083
|
disabled: !userRoleCanDrop
|
|
1037
|
-
})
|
|
1038
|
-
})
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
document: item
|
|
1042
|
-
}), /* @__PURE__ */jsx(PublishedStatus, {
|
|
1043
|
-
document: item
|
|
1044
|
-
}), /* @__PURE__ */jsx(EditButton, {
|
|
1045
|
-
id: item._id,
|
|
1046
|
-
type: item._type,
|
|
1047
|
-
disabled: !userRoleCanDrop
|
|
1048
|
-
}), isLastState ? /* @__PURE__ */jsx(CompleteButton, {
|
|
1049
|
-
documentId,
|
|
1050
|
-
disabled: !userRoleCanDrop
|
|
1051
|
-
}) : null]
|
|
1052
|
-
})
|
|
1053
|
-
})]
|
|
1084
|
+
}) : null]
|
|
1085
|
+
})
|
|
1086
|
+
})]
|
|
1087
|
+
})
|
|
1054
1088
|
})
|
|
1055
|
-
})
|
|
1089
|
+
})]
|
|
1056
1090
|
});
|
|
1057
1091
|
}
|
|
1058
1092
|
function DocumentList(props) {
|
|
@@ -1080,7 +1114,7 @@ function DocumentList(props) {
|
|
|
1080
1114
|
return (_c = (_b = (_a = dataFiltered[index]) == null ? void 0 : _a._metadata) == null ? void 0 : _b.documentId) != null ? _c : index;
|
|
1081
1115
|
},
|
|
1082
1116
|
estimateSize: () => 113,
|
|
1083
|
-
overscan:
|
|
1117
|
+
overscan: 10
|
|
1084
1118
|
});
|
|
1085
1119
|
if (!data.length) {
|
|
1086
1120
|
return null;
|
|
@@ -1292,7 +1326,8 @@ function StateTitle(props) {
|
|
|
1292
1326
|
requireAssignment,
|
|
1293
1327
|
userRoleCanDrop,
|
|
1294
1328
|
isDropDisabled,
|
|
1295
|
-
draggingFrom
|
|
1329
|
+
draggingFrom,
|
|
1330
|
+
documentCount
|
|
1296
1331
|
} = props;
|
|
1297
1332
|
let tone = "default";
|
|
1298
1333
|
const isSource = draggingFrom === state.id;
|
|
@@ -1317,7 +1352,15 @@ function StateTitle(props) {
|
|
|
1317
1352
|
}), requireAssignment ? /* @__PURE__ */jsx(Status, {
|
|
1318
1353
|
text: "You must be assigned to the document to move documents to this State",
|
|
1319
1354
|
icon: UserIcon
|
|
1320
|
-
}) : null
|
|
1355
|
+
}) : null, /* @__PURE__ */jsx(Box, {
|
|
1356
|
+
flex: 1,
|
|
1357
|
+
children: documentCount > 0 ? /* @__PURE__ */jsx(Text, {
|
|
1358
|
+
weight: "semibold",
|
|
1359
|
+
align: "right",
|
|
1360
|
+
size: 1,
|
|
1361
|
+
children: documentCount
|
|
1362
|
+
}) : null
|
|
1363
|
+
})]
|
|
1321
1364
|
})
|
|
1322
1365
|
});
|
|
1323
1366
|
}
|
|
@@ -1351,12 +1394,12 @@ function FloatingCard(_ref3) {
|
|
|
1351
1394
|
}, "floater") : null
|
|
1352
1395
|
});
|
|
1353
1396
|
}
|
|
1354
|
-
function
|
|
1355
|
-
|
|
1397
|
+
function Verify(props) {
|
|
1398
|
+
const {
|
|
1356
1399
|
data,
|
|
1357
1400
|
userList,
|
|
1358
1401
|
states
|
|
1359
|
-
} =
|
|
1402
|
+
} = props;
|
|
1360
1403
|
const client = useClient({
|
|
1361
1404
|
apiVersion: API_VERSION
|
|
1362
1405
|
});
|
|
@@ -1387,6 +1430,17 @@ function Validators(_ref4) {
|
|
|
1387
1430
|
} = (_a = cur._metadata) != null ? _a : {};
|
|
1388
1431
|
return !orderRank && documentId ? [...acc, documentId] : acc;
|
|
1389
1432
|
}, []) : [];
|
|
1433
|
+
const documentsWithDuplicatedOrderIds = (data == null ? void 0 : data.length) ? data.reduce((acc, cur) => {
|
|
1434
|
+
var _a;
|
|
1435
|
+
const {
|
|
1436
|
+
documentId,
|
|
1437
|
+
orderRank
|
|
1438
|
+
} = (_a = cur._metadata) != null ? _a : {};
|
|
1439
|
+
return orderRank && data.filter(d => {
|
|
1440
|
+
var _a2;
|
|
1441
|
+
return ((_a2 = d._metadata) == null ? void 0 : _a2.orderRank) === orderRank;
|
|
1442
|
+
}).length > 1 && documentId ? [...acc, documentId] : acc;
|
|
1443
|
+
}, []) : [];
|
|
1390
1444
|
const correctDocuments = React.useCallback(async ids => {
|
|
1391
1445
|
toast.push({
|
|
1392
1446
|
title: "Correcting...",
|
|
@@ -1487,6 +1541,10 @@ function Validators(_ref4) {
|
|
|
1487
1541
|
tone: "caution",
|
|
1488
1542
|
onClick: () => addOrderToDocuments(documentsWithoutOrderIds),
|
|
1489
1543
|
text: documentsWithoutOrderIds.length === 1 ? "Set Order for 1 Document" : "Set Order for ".concat(documentsWithoutOrderIds.length, " Documents")
|
|
1544
|
+
}) : null, documentsWithDuplicatedOrderIds.length > 0 ? /* @__PURE__ */jsx(Button, {
|
|
1545
|
+
tone: "caution",
|
|
1546
|
+
onClick: () => addOrderToDocuments(documentsWithDuplicatedOrderIds),
|
|
1547
|
+
text: documentsWithDuplicatedOrderIds.length === 1 ? "Set Unique Order for 1 Document" : "Set Unique Order for ".concat(documentsWithDuplicatedOrderIds.length, " Documents")
|
|
1490
1548
|
}) : null, orphanedMetadataDocumentIds.length > 0 ? /* @__PURE__ */jsx(Button, {
|
|
1491
1549
|
text: "Cleanup orphaned metadata",
|
|
1492
1550
|
onClick: handleOrphans,
|
|
@@ -1558,7 +1616,7 @@ function WorkflowTool(props) {
|
|
|
1558
1616
|
setUndroppableStates(undroppableExceptSelf);
|
|
1559
1617
|
}
|
|
1560
1618
|
}, [data, states, user]);
|
|
1561
|
-
const handleDragEnd = React.useCallback(result => {
|
|
1619
|
+
const handleDragEnd = React.useCallback(async result => {
|
|
1562
1620
|
var _a2, _b2, _c2, _d, _e, _f;
|
|
1563
1621
|
setUndroppableStates([]);
|
|
1564
1622
|
setDraggingFrom("");
|
|
@@ -1587,10 +1645,10 @@ function WorkflowTool(props) {
|
|
|
1587
1645
|
} else {
|
|
1588
1646
|
const itemBefore = destinationStateItems[destination.index - 1];
|
|
1589
1647
|
const itemBeforeRank = (_e = itemBefore == null ? void 0 : itemBefore._metadata) == null ? void 0 : _e.orderRank;
|
|
1590
|
-
const itemBeforeRankParsed =
|
|
1648
|
+
const itemBeforeRankParsed = itemBeforeRank ? LexoRank.parse(itemBeforeRank) : LexoRank.min();
|
|
1591
1649
|
const itemAfter = destinationStateItems[destination.index];
|
|
1592
1650
|
const itemAfterRank = (_f = itemAfter == null ? void 0 : itemAfter._metadata) == null ? void 0 : _f.orderRank;
|
|
1593
|
-
const itemAfterRankParsed =
|
|
1651
|
+
const itemAfterRankParsed = itemAfterRank ? LexoRank.parse(itemAfterRank) : LexoRank.max();
|
|
1594
1652
|
newOrder = itemBeforeRankParsed.between(itemAfterRankParsed).toString();
|
|
1595
1653
|
}
|
|
1596
1654
|
move(draggableId, destination, states, newOrder);
|
|
@@ -1646,7 +1704,7 @@ function WorkflowTool(props) {
|
|
|
1646
1704
|
direction: "column",
|
|
1647
1705
|
height: "fill",
|
|
1648
1706
|
overflow: "hidden",
|
|
1649
|
-
children: [/* @__PURE__ */jsx(
|
|
1707
|
+
children: [/* @__PURE__ */jsx(Verify, {
|
|
1650
1708
|
data,
|
|
1651
1709
|
userList,
|
|
1652
1710
|
states
|
|
@@ -1679,7 +1737,8 @@ function WorkflowTool(props) {
|
|
|
1679
1737
|
requireAssignment: (_b2 = state.requireAssignment) != null ? _b2 : false,
|
|
1680
1738
|
userRoleCanDrop,
|
|
1681
1739
|
isDropDisabled,
|
|
1682
|
-
draggingFrom
|
|
1740
|
+
draggingFrom,
|
|
1741
|
+
documentCount: filterItemsAndSort(data, state.id, selectedUserIds, selectedSchemaTypes).length
|
|
1683
1742
|
}), /* @__PURE__ */jsx(Box, {
|
|
1684
1743
|
flex: 1,
|
|
1685
1744
|
children: /* @__PURE__ */jsx(Droppable, {
|