sanity-plugin-workflow 1.0.0-beta.5 → 1.0.0-beta.7
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 +9 -5
- package/lib/index.esm.js +171 -71
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +171 -71
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/DocumentCard/CompleteButton.tsx +47 -32
- package/src/components/DocumentCard/index.tsx +20 -42
- package/src/components/DocumentList.tsx +5 -2
- package/src/components/Filters.tsx +1 -1
- package/src/components/StateTitle/index.tsx +31 -26
- package/src/components/Verify.tsx +36 -4
- package/src/components/WorkflowTool.tsx +122 -51
- package/src/hooks/useWorkflowDocuments.tsx +11 -8
- package/src/types/index.ts +0 -3
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
|
})
|
|
@@ -101,10 +103,12 @@ Once the Workflow is complete, the metadata can be removed by using the "Complet
|
|
|
101
103
|
|
|
102
104
|
This plugin is largely based on the original Workflow Demo built into a Sanity Studio v2 project. The major differences are:
|
|
103
105
|
|
|
104
|
-
* This plugin
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
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.
|
|
108
112
|
|
|
109
113
|
## License
|
|
110
114
|
|
package/lib/index.esm.js
CHANGED
|
@@ -633,7 +633,7 @@ function useWorkflowDocuments(schemaTypes) {
|
|
|
633
633
|
setLocalDocuments(data);
|
|
634
634
|
}
|
|
635
635
|
}, [data]);
|
|
636
|
-
const move = React.useCallback((draggedId, destination, states, newOrder) => {
|
|
636
|
+
const move = React.useCallback(async (draggedId, destination, states, newOrder) => {
|
|
637
637
|
const currentLocalData = localDocuments;
|
|
638
638
|
const newLocalDocuments = localDocuments.map(item => {
|
|
639
639
|
var _a;
|
|
@@ -680,25 +680,28 @@ function useWorkflowDocuments(schemaTypes) {
|
|
|
680
680
|
_type
|
|
681
681
|
} = document;
|
|
682
682
|
const {
|
|
683
|
-
|
|
684
|
-
|
|
683
|
+
documentId,
|
|
684
|
+
_rev
|
|
685
685
|
} = document._metadata || {};
|
|
686
|
-
client.patch("workflow-metadata.".concat(documentId)).ifRevisionId(_rev).set({
|
|
686
|
+
await client.patch("workflow-metadata.".concat(documentId)).ifRevisionId(_rev).set({
|
|
687
687
|
state: newStateId,
|
|
688
688
|
orderRank: newOrder
|
|
689
|
-
}).commit().then(
|
|
689
|
+
}).commit().then(res => {
|
|
690
690
|
var _a;
|
|
691
|
-
|
|
691
|
+
toast.push({
|
|
692
692
|
title: "Moved to \"".concat((_a = newState == null ? void 0 : newState.title) != null ? _a : newStateId, "\""),
|
|
693
693
|
status: "success"
|
|
694
694
|
});
|
|
695
|
-
|
|
695
|
+
return res;
|
|
696
|
+
}).catch(err => {
|
|
696
697
|
var _a;
|
|
697
698
|
setLocalDocuments(currentLocalData);
|
|
698
|
-
|
|
699
|
+
toast.push({
|
|
699
700
|
title: "Failed to move to \"".concat((_a = newState == null ? void 0 : newState.title) != null ? _a : newStateId, "\""),
|
|
701
|
+
description: err.message,
|
|
700
702
|
status: "error"
|
|
701
703
|
});
|
|
704
|
+
return null;
|
|
702
705
|
});
|
|
703
706
|
return {
|
|
704
707
|
_id,
|
|
@@ -812,31 +815,44 @@ function CompleteButton(props) {
|
|
|
812
815
|
apiVersion: API_VERSION
|
|
813
816
|
});
|
|
814
817
|
const toast = useToast();
|
|
815
|
-
const handleComplete = React.useCallback(
|
|
818
|
+
const handleComplete = React.useCallback(event => {
|
|
819
|
+
const id = event.currentTarget.value;
|
|
820
|
+
if (!id) {
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
816
823
|
client.delete("workflow-metadata.".concat(id)).then(() => {
|
|
817
824
|
toast.push({
|
|
818
825
|
status: "success",
|
|
819
|
-
title: "Workflow completed"
|
|
820
|
-
description: id
|
|
826
|
+
title: "Workflow completed"
|
|
821
827
|
});
|
|
822
828
|
}).catch(() => {
|
|
823
829
|
toast.push({
|
|
824
830
|
status: "error",
|
|
825
|
-
title: "Could not complete Workflow"
|
|
826
|
-
description: id
|
|
831
|
+
title: "Could not complete Workflow"
|
|
827
832
|
});
|
|
828
833
|
});
|
|
829
834
|
}, [client, toast]);
|
|
830
|
-
return /* @__PURE__ */jsx(
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
835
|
+
return /* @__PURE__ */jsx(Tooltip, {
|
|
836
|
+
portal: true,
|
|
837
|
+
content: /* @__PURE__ */jsx(Box, {
|
|
838
|
+
padding: 2,
|
|
839
|
+
children: /* @__PURE__ */jsx(Text, {
|
|
840
|
+
size: 1,
|
|
841
|
+
children: "Remove this document from Workflow"
|
|
842
|
+
})
|
|
843
|
+
}),
|
|
844
|
+
children: /* @__PURE__ */jsx(Button, {
|
|
845
|
+
value: documentId,
|
|
846
|
+
onClick: handleComplete,
|
|
847
|
+
text: "Complete",
|
|
848
|
+
icon: CheckmarkIcon,
|
|
849
|
+
tone: "positive",
|
|
850
|
+
mode: "ghost",
|
|
851
|
+
fontSize: 1,
|
|
852
|
+
padding: 2,
|
|
853
|
+
tabIndex: -1,
|
|
854
|
+
disabled
|
|
855
|
+
})
|
|
840
856
|
});
|
|
841
857
|
}
|
|
842
858
|
function TimeAgo(_ref2) {
|
|
@@ -953,6 +969,7 @@ function DocumentCard(props) {
|
|
|
953
969
|
var _a, _b;
|
|
954
970
|
const {
|
|
955
971
|
isDragDisabled,
|
|
972
|
+
isPatching,
|
|
956
973
|
userRoleCanDrop,
|
|
957
974
|
isDragging,
|
|
958
975
|
item,
|
|
@@ -986,6 +1003,7 @@ function DocumentCard(props) {
|
|
|
986
1003
|
let tone = defaultCardTone;
|
|
987
1004
|
if (!userRoleCanDrop) return isDarkMode ? "default" : "transparent";
|
|
988
1005
|
if (!documentId) return tone;
|
|
1006
|
+
if (isPatching) tone = isDarkMode ? "default" : "transparent";
|
|
989
1007
|
if (isDragging) tone = "positive";
|
|
990
1008
|
if ((state == null ? void 0 : state.requireValidation) && !isValidating && validation.length > 0) {
|
|
991
1009
|
if (validation.some(v => v.level === "error")) {
|
|
@@ -995,7 +1013,7 @@ function DocumentCard(props) {
|
|
|
995
1013
|
}
|
|
996
1014
|
}
|
|
997
1015
|
return tone;
|
|
998
|
-
}, [defaultCardTone, userRoleCanDrop, isDarkMode, documentId, isDragging, isValidating, validation, state == null ? void 0 : state.requireValidation]);
|
|
1016
|
+
}, [defaultCardTone, userRoleCanDrop, isPatching, isDarkMode, documentId, isDragging, isValidating, validation, state == null ? void 0 : state.requireValidation]);
|
|
999
1017
|
useEffect(() => {
|
|
1000
1018
|
if (!isValidating && validation.length > 0) {
|
|
1001
1019
|
if (validation.some(v => v.level === "error")) {
|
|
@@ -1041,7 +1059,7 @@ function DocumentCard(props) {
|
|
|
1041
1059
|
children: [/* @__PURE__ */jsx(Box, {
|
|
1042
1060
|
flex: 1,
|
|
1043
1061
|
children: /* @__PURE__ */jsx(Preview, {
|
|
1044
|
-
layout: "
|
|
1062
|
+
layout: "block",
|
|
1045
1063
|
value: item,
|
|
1046
1064
|
schemaType: schema.get(item._type)
|
|
1047
1065
|
})
|
|
@@ -1049,14 +1067,14 @@ function DocumentCard(props) {
|
|
|
1049
1067
|
style: {
|
|
1050
1068
|
flexShrink: 0
|
|
1051
1069
|
},
|
|
1052
|
-
children: hasError || isDragDisabled ? null : /* @__PURE__ */jsx(DragHandleIcon, {})
|
|
1070
|
+
children: hasError || isDragDisabled || isPatching ? null : /* @__PURE__ */jsx(DragHandleIcon, {})
|
|
1053
1071
|
})]
|
|
1054
1072
|
})
|
|
1055
|
-
}), /* @__PURE__ */
|
|
1073
|
+
}), /* @__PURE__ */jsxs(Card, {
|
|
1056
1074
|
padding: 2,
|
|
1057
1075
|
radius: 2,
|
|
1058
1076
|
tone: "inherit",
|
|
1059
|
-
children: /* @__PURE__ */jsxs(Flex, {
|
|
1077
|
+
children: [/* @__PURE__ */jsxs(Flex, {
|
|
1060
1078
|
align: "center",
|
|
1061
1079
|
justify: "space-between",
|
|
1062
1080
|
gap: 3,
|
|
@@ -1078,11 +1096,17 @@ function DocumentCard(props) {
|
|
|
1078
1096
|
id: item._id,
|
|
1079
1097
|
type: item._type,
|
|
1080
1098
|
disabled: !userRoleCanDrop
|
|
1081
|
-
}), isLastState ? /* @__PURE__ */jsx(CompleteButton, {
|
|
1099
|
+
}), isLastState && states.length <= 3 ? /* @__PURE__ */jsx(CompleteButton, {
|
|
1082
1100
|
documentId,
|
|
1083
1101
|
disabled: !userRoleCanDrop
|
|
1084
1102
|
}) : null]
|
|
1085
|
-
})
|
|
1103
|
+
}), isLastState && states.length > 3 ? /* @__PURE__ */jsx(Stack, {
|
|
1104
|
+
paddingTop: 2,
|
|
1105
|
+
children: /* @__PURE__ */jsx(CompleteButton, {
|
|
1106
|
+
documentId,
|
|
1107
|
+
disabled: !userRoleCanDrop
|
|
1108
|
+
})
|
|
1109
|
+
}) : null]
|
|
1086
1110
|
})]
|
|
1087
1111
|
})
|
|
1088
1112
|
})
|
|
@@ -1093,6 +1117,7 @@ function DocumentList(props) {
|
|
|
1093
1117
|
const {
|
|
1094
1118
|
data = [],
|
|
1095
1119
|
invalidDocumentIds,
|
|
1120
|
+
patchingIds,
|
|
1096
1121
|
selectedSchemaTypes,
|
|
1097
1122
|
selectedUserIds,
|
|
1098
1123
|
state,
|
|
@@ -1114,7 +1139,7 @@ function DocumentList(props) {
|
|
|
1114
1139
|
return (_c = (_b = (_a = dataFiltered[index]) == null ? void 0 : _a._metadata) == null ? void 0 : _b.documentId) != null ? _c : index;
|
|
1115
1140
|
},
|
|
1116
1141
|
estimateSize: () => 113,
|
|
1117
|
-
overscan:
|
|
1142
|
+
overscan: 10
|
|
1118
1143
|
});
|
|
1119
1144
|
if (!data.length) {
|
|
1120
1145
|
return null;
|
|
@@ -1141,7 +1166,7 @@ function DocumentList(props) {
|
|
|
1141
1166
|
}
|
|
1142
1167
|
const isInvalid = invalidDocumentIds.includes(documentId);
|
|
1143
1168
|
const meInAssignees = (user == null ? void 0 : user.id) ? assignees == null ? void 0 : assignees.includes(user.id) : false;
|
|
1144
|
-
const isDragDisabled = !userRoleCanDrop || isInvalid || !(state.requireAssignment ? state.requireAssignment && meInAssignees : true);
|
|
1169
|
+
const isDragDisabled = patchingIds.includes(documentId) || !userRoleCanDrop || isInvalid || !(state.requireAssignment ? state.requireAssignment && meInAssignees : true);
|
|
1145
1170
|
return /* @__PURE__ */jsx(Draggable, {
|
|
1146
1171
|
draggableId: documentId,
|
|
1147
1172
|
index: virtualItem.index,
|
|
@@ -1153,6 +1178,7 @@ function DocumentList(props) {
|
|
|
1153
1178
|
children: /* @__PURE__ */jsx(DocumentCard, {
|
|
1154
1179
|
userRoleCanDrop,
|
|
1155
1180
|
isDragDisabled,
|
|
1181
|
+
isPatching: patchingIds.includes(documentId),
|
|
1156
1182
|
isDragging: draggableSnapshot.isDragging,
|
|
1157
1183
|
item,
|
|
1158
1184
|
toggleInvalidDocumentId,
|
|
@@ -1278,7 +1304,7 @@ function Filters(props) {
|
|
|
1278
1304
|
icon: ResetIcon
|
|
1279
1305
|
}) : null]
|
|
1280
1306
|
})
|
|
1281
|
-
}), schemaTypes.length >
|
|
1307
|
+
}), schemaTypes.length > 1 ? /* @__PURE__ */jsx(Flex, {
|
|
1282
1308
|
align: "center",
|
|
1283
1309
|
gap: 1,
|
|
1284
1310
|
children: schemaTypes.map(typeName => {
|
|
@@ -1326,7 +1352,8 @@ function StateTitle(props) {
|
|
|
1326
1352
|
requireAssignment,
|
|
1327
1353
|
userRoleCanDrop,
|
|
1328
1354
|
isDropDisabled,
|
|
1329
|
-
draggingFrom
|
|
1355
|
+
draggingFrom,
|
|
1356
|
+
documentCount
|
|
1330
1357
|
} = props;
|
|
1331
1358
|
let tone = "default";
|
|
1332
1359
|
const isSource = draggingFrom === state.id;
|
|
@@ -1351,7 +1378,15 @@ function StateTitle(props) {
|
|
|
1351
1378
|
}), requireAssignment ? /* @__PURE__ */jsx(Status, {
|
|
1352
1379
|
text: "You must be assigned to the document to move documents to this State",
|
|
1353
1380
|
icon: UserIcon
|
|
1354
|
-
}) : null
|
|
1381
|
+
}) : null, /* @__PURE__ */jsx(Box, {
|
|
1382
|
+
flex: 1,
|
|
1383
|
+
children: documentCount > 0 ? /* @__PURE__ */jsx(Text, {
|
|
1384
|
+
weight: "semibold",
|
|
1385
|
+
align: "right",
|
|
1386
|
+
size: 1,
|
|
1387
|
+
children: documentCount
|
|
1388
|
+
}) : null
|
|
1389
|
+
})]
|
|
1355
1390
|
})
|
|
1356
1391
|
});
|
|
1357
1392
|
}
|
|
@@ -1421,6 +1456,17 @@ function Verify(props) {
|
|
|
1421
1456
|
} = (_a = cur._metadata) != null ? _a : {};
|
|
1422
1457
|
return !orderRank && documentId ? [...acc, documentId] : acc;
|
|
1423
1458
|
}, []) : [];
|
|
1459
|
+
const documentsWithDuplicatedOrderIds = (data == null ? void 0 : data.length) ? data.reduce((acc, cur) => {
|
|
1460
|
+
var _a;
|
|
1461
|
+
const {
|
|
1462
|
+
documentId,
|
|
1463
|
+
orderRank
|
|
1464
|
+
} = (_a = cur._metadata) != null ? _a : {};
|
|
1465
|
+
return orderRank && data.filter(d => {
|
|
1466
|
+
var _a2;
|
|
1467
|
+
return ((_a2 = d._metadata) == null ? void 0 : _a2.orderRank) === orderRank;
|
|
1468
|
+
}).length > 1 && documentId ? [...acc, documentId] : acc;
|
|
1469
|
+
}, []) : [];
|
|
1424
1470
|
const correctDocuments = React.useCallback(async ids => {
|
|
1425
1471
|
toast.push({
|
|
1426
1472
|
title: "Correcting...",
|
|
@@ -1468,16 +1514,21 @@ function Verify(props) {
|
|
|
1468
1514
|
});
|
|
1469
1515
|
}, [client, data, toast, userList]);
|
|
1470
1516
|
const addOrderToDocuments = React.useCallback(async ids => {
|
|
1471
|
-
var _a, _b;
|
|
1472
1517
|
toast.push({
|
|
1473
1518
|
title: "Adding ordering...",
|
|
1474
1519
|
status: "info"
|
|
1475
1520
|
});
|
|
1476
|
-
const firstOrder
|
|
1477
|
-
|
|
1521
|
+
const [firstOrder, secondOrder] = [...data].slice(0, 2).map(d => {
|
|
1522
|
+
var _a;
|
|
1523
|
+
return (_a = d._metadata) == null ? void 0 : _a.orderRank;
|
|
1524
|
+
});
|
|
1525
|
+
const minLexo = firstOrder && data.length !== ids.length ? LexoRank.parse(firstOrder) : LexoRank.min();
|
|
1526
|
+
const maxLexo = secondOrder && data.length !== ids.length ? LexoRank.parse(secondOrder) : LexoRank.max();
|
|
1527
|
+
let newLexo = minLexo.between(maxLexo);
|
|
1528
|
+
const lastLexo = maxLexo;
|
|
1478
1529
|
const tx = client.transaction();
|
|
1479
1530
|
for (let index = 0; index < ids.length; index += 1) {
|
|
1480
|
-
newLexo = newLexo.
|
|
1531
|
+
newLexo = newLexo.between(lastLexo);
|
|
1481
1532
|
tx.patch("workflow-metadata.".concat(ids[index]), {
|
|
1482
1533
|
set: {
|
|
1483
1534
|
orderRank: newLexo.toString()
|
|
@@ -1521,6 +1572,10 @@ function Verify(props) {
|
|
|
1521
1572
|
tone: "caution",
|
|
1522
1573
|
onClick: () => addOrderToDocuments(documentsWithoutOrderIds),
|
|
1523
1574
|
text: documentsWithoutOrderIds.length === 1 ? "Set Order for 1 Document" : "Set Order for ".concat(documentsWithoutOrderIds.length, " Documents")
|
|
1575
|
+
}) : null, documentsWithDuplicatedOrderIds.length > 0 ? /* @__PURE__ */jsx(Button, {
|
|
1576
|
+
tone: "caution",
|
|
1577
|
+
onClick: () => addOrderToDocuments(documentsWithDuplicatedOrderIds),
|
|
1578
|
+
text: documentsWithDuplicatedOrderIds.length === 1 ? "Set Unique Order for 1 Document" : "Set Unique Order for ".concat(documentsWithDuplicatedOrderIds.length, " Documents")
|
|
1524
1579
|
}) : null, orphanedMetadataDocumentIds.length > 0 ? /* @__PURE__ */jsx(Button, {
|
|
1525
1580
|
text: "Cleanup orphaned metadata",
|
|
1526
1581
|
onClick: handleOrphans,
|
|
@@ -1536,6 +1591,7 @@ function WorkflowTool(props) {
|
|
|
1536
1591
|
} = (_b = (_a = props == null ? void 0 : props.tool) == null ? void 0 : _a.options) != null ? _b : {};
|
|
1537
1592
|
const isDarkMode = useTheme().sanity.color.dark;
|
|
1538
1593
|
const defaultCardTone = isDarkMode ? "default" : "transparent";
|
|
1594
|
+
const toast = useToast();
|
|
1539
1595
|
const userList = useProjectUsers({
|
|
1540
1596
|
apiVersion: API_VERSION
|
|
1541
1597
|
});
|
|
@@ -1545,6 +1601,7 @@ function WorkflowTool(props) {
|
|
|
1545
1601
|
workflowData,
|
|
1546
1602
|
operations
|
|
1547
1603
|
} = useWorkflowDocuments(schemaTypes);
|
|
1604
|
+
const [patchingIds, setPatchingIds] = React.useState([]);
|
|
1548
1605
|
const {
|
|
1549
1606
|
data,
|
|
1550
1607
|
loading,
|
|
@@ -1592,7 +1649,7 @@ function WorkflowTool(props) {
|
|
|
1592
1649
|
setUndroppableStates(undroppableExceptSelf);
|
|
1593
1650
|
}
|
|
1594
1651
|
}, [data, states, user]);
|
|
1595
|
-
const handleDragEnd = React.useCallback(result => {
|
|
1652
|
+
const handleDragEnd = React.useCallback(async result => {
|
|
1596
1653
|
var _a2, _b2, _c2, _d, _e, _f;
|
|
1597
1654
|
setUndroppableStates([]);
|
|
1598
1655
|
setDraggingFrom("");
|
|
@@ -1609,26 +1666,65 @@ function WorkflowTool(props) {
|
|
|
1609
1666
|
return;
|
|
1610
1667
|
}
|
|
1611
1668
|
const destinationStateItems = [...filterItemsAndSort(data, destination.droppableId, [], null)];
|
|
1669
|
+
const destinationStateIndex = states.findIndex(s => s.id === destination.droppableId);
|
|
1670
|
+
const globalStateMinimumRank = data[0]._metadata.orderRank;
|
|
1671
|
+
const globalStateMaximumRank = data[data.length - 1]._metadata.orderRank;
|
|
1612
1672
|
let newOrder;
|
|
1613
1673
|
if (!destinationStateItems.length) {
|
|
1614
|
-
|
|
1674
|
+
if (destinationStateIndex === 0) {
|
|
1675
|
+
newOrder = LexoRank.min().toString();
|
|
1676
|
+
} else {
|
|
1677
|
+
newOrder = LexoRank.parse(globalStateMinimumRank).between(LexoRank.min()).toString();
|
|
1678
|
+
}
|
|
1615
1679
|
} else if (destination.index === 0) {
|
|
1616
1680
|
const firstItemOrderRank = (_b2 = (_a2 = [...destinationStateItems].shift()) == null ? void 0 : _a2._metadata) == null ? void 0 : _b2.orderRank;
|
|
1617
|
-
|
|
1681
|
+
if (firstItemOrderRank && typeof firstItemOrderRank === "string") {
|
|
1682
|
+
newOrder = LexoRank.parse(firstItemOrderRank).genPrev().toString();
|
|
1683
|
+
} else if (destinationStateIndex === 0) {
|
|
1684
|
+
newOrder = LexoRank.min().toString();
|
|
1685
|
+
} else {
|
|
1686
|
+
newOrder = LexoRank.parse(globalStateMinimumRank).between(LexoRank.min()).toString();
|
|
1687
|
+
}
|
|
1618
1688
|
} else if (destination.index + 1 === destinationStateItems.length) {
|
|
1619
1689
|
const lastItemOrderRank = (_d = (_c2 = [...destinationStateItems].pop()) == null ? void 0 : _c2._metadata) == null ? void 0 : _d.orderRank;
|
|
1620
|
-
|
|
1690
|
+
if (lastItemOrderRank && typeof lastItemOrderRank === "string") {
|
|
1691
|
+
newOrder = LexoRank.parse(lastItemOrderRank).genNext().toString();
|
|
1692
|
+
} else if (destinationStateIndex === states.length - 1) {
|
|
1693
|
+
newOrder = LexoRank.max().toString();
|
|
1694
|
+
} else {
|
|
1695
|
+
newOrder = LexoRank.parse(globalStateMaximumRank).between(LexoRank.min()).toString();
|
|
1696
|
+
}
|
|
1621
1697
|
} else {
|
|
1622
1698
|
const itemBefore = destinationStateItems[destination.index - 1];
|
|
1623
1699
|
const itemBeforeRank = (_e = itemBefore == null ? void 0 : itemBefore._metadata) == null ? void 0 : _e.orderRank;
|
|
1624
|
-
|
|
1700
|
+
let itemBeforeRankParsed;
|
|
1701
|
+
if (itemBeforeRank) {
|
|
1702
|
+
itemBeforeRankParsed = LexoRank.parse(itemBeforeRank);
|
|
1703
|
+
} else if (destinationStateIndex === 0) {
|
|
1704
|
+
itemBeforeRankParsed = LexoRank.min();
|
|
1705
|
+
} else {
|
|
1706
|
+
itemBeforeRankParsed = LexoRank.parse(globalStateMinimumRank);
|
|
1707
|
+
}
|
|
1625
1708
|
const itemAfter = destinationStateItems[destination.index];
|
|
1626
1709
|
const itemAfterRank = (_f = itemAfter == null ? void 0 : itemAfter._metadata) == null ? void 0 : _f.orderRank;
|
|
1627
|
-
|
|
1710
|
+
let itemAfterRankParsed;
|
|
1711
|
+
if (itemAfterRank) {
|
|
1712
|
+
itemAfterRankParsed = LexoRank.parse(itemAfterRank);
|
|
1713
|
+
} else if (destinationStateIndex === states.length - 1) {
|
|
1714
|
+
itemAfterRankParsed = LexoRank.max();
|
|
1715
|
+
} else {
|
|
1716
|
+
itemAfterRankParsed = LexoRank.parse(globalStateMaximumRank);
|
|
1717
|
+
}
|
|
1628
1718
|
newOrder = itemBeforeRankParsed.between(itemAfterRankParsed).toString();
|
|
1629
1719
|
}
|
|
1630
|
-
|
|
1631
|
-
|
|
1720
|
+
setPatchingIds([...patchingIds, draggableId]);
|
|
1721
|
+
toast.push({
|
|
1722
|
+
status: "info",
|
|
1723
|
+
title: "Updating document state..."
|
|
1724
|
+
});
|
|
1725
|
+
await move(draggableId, destination, states, newOrder);
|
|
1726
|
+
setPatchingIds(ids => ids.filter(id => id !== draggableId));
|
|
1727
|
+
}, [data, patchingIds, toast, move, states]);
|
|
1632
1728
|
const uniqueAssignedUsers = React.useMemo(() => {
|
|
1633
1729
|
const uniqueUserIds = data.reduce((acc, item) => {
|
|
1634
1730
|
var _a2;
|
|
@@ -1655,6 +1751,30 @@ function WorkflowTool(props) {
|
|
|
1655
1751
|
const toggleInvalidDocumentId = React.useCallback((docId, action) => {
|
|
1656
1752
|
setInvalidDocumentIds(prev => action === "ADD" ? [...prev, docId] : prev.filter(id => id !== docId));
|
|
1657
1753
|
}, []);
|
|
1754
|
+
const Clone = React.useCallback((provided, snapshot, rubric) => {
|
|
1755
|
+
const item = data.find(doc => {
|
|
1756
|
+
var _a2;
|
|
1757
|
+
return ((_a2 = doc == null ? void 0 : doc._metadata) == null ? void 0 : _a2.documentId) === rubric.draggableId;
|
|
1758
|
+
});
|
|
1759
|
+
return /* @__PURE__ */jsx("div", {
|
|
1760
|
+
...provided.draggableProps,
|
|
1761
|
+
...provided.dragHandleProps,
|
|
1762
|
+
ref: provided.innerRef,
|
|
1763
|
+
children: item ? /* @__PURE__ */jsx(DocumentCard, {
|
|
1764
|
+
isDragDisabled: false,
|
|
1765
|
+
isPatching: false,
|
|
1766
|
+
userRoleCanDrop: true,
|
|
1767
|
+
isDragging: snapshot.isDragging,
|
|
1768
|
+
item,
|
|
1769
|
+
states,
|
|
1770
|
+
toggleInvalidDocumentId,
|
|
1771
|
+
userList
|
|
1772
|
+
}) : /* @__PURE__ */jsx(Feedback, {
|
|
1773
|
+
title: "Item not found",
|
|
1774
|
+
tone: "caution"
|
|
1775
|
+
})
|
|
1776
|
+
});
|
|
1777
|
+
}, [data, states, toggleInvalidDocumentId, userList]);
|
|
1658
1778
|
if (!(states == null ? void 0 : states.length)) {
|
|
1659
1779
|
return /* @__PURE__ */jsx(Container, {
|
|
1660
1780
|
width: 1,
|
|
@@ -1713,36 +1833,15 @@ function WorkflowTool(props) {
|
|
|
1713
1833
|
requireAssignment: (_b2 = state.requireAssignment) != null ? _b2 : false,
|
|
1714
1834
|
userRoleCanDrop,
|
|
1715
1835
|
isDropDisabled,
|
|
1716
|
-
draggingFrom
|
|
1836
|
+
draggingFrom,
|
|
1837
|
+
documentCount: filterItemsAndSort(data, state.id, selectedUserIds, selectedSchemaTypes).length
|
|
1717
1838
|
}), /* @__PURE__ */jsx(Box, {
|
|
1718
1839
|
flex: 1,
|
|
1719
1840
|
children: /* @__PURE__ */jsx(Droppable, {
|
|
1720
1841
|
droppableId: state.id,
|
|
1721
1842
|
isDropDisabled,
|
|
1722
1843
|
mode: "virtual",
|
|
1723
|
-
renderClone:
|
|
1724
|
-
const item = data.find(doc => {
|
|
1725
|
-
var _a3;
|
|
1726
|
-
return ((_a3 = doc == null ? void 0 : doc._metadata) == null ? void 0 : _a3.documentId) === rubric.draggableId;
|
|
1727
|
-
});
|
|
1728
|
-
return /* @__PURE__ */jsx("div", {
|
|
1729
|
-
...provided.draggableProps,
|
|
1730
|
-
...provided.dragHandleProps,
|
|
1731
|
-
ref: provided.innerRef,
|
|
1732
|
-
children: item ? /* @__PURE__ */jsx(DocumentCard, {
|
|
1733
|
-
isDragDisabled: false,
|
|
1734
|
-
userRoleCanDrop,
|
|
1735
|
-
isDragging: snapshot.isDragging,
|
|
1736
|
-
item,
|
|
1737
|
-
states,
|
|
1738
|
-
toggleInvalidDocumentId,
|
|
1739
|
-
userList
|
|
1740
|
-
}) : /* @__PURE__ */jsx(Feedback, {
|
|
1741
|
-
title: "Item not found",
|
|
1742
|
-
tone: "caution"
|
|
1743
|
-
})
|
|
1744
|
-
});
|
|
1745
|
-
},
|
|
1844
|
+
renderClone: Clone,
|
|
1746
1845
|
children: (provided, snapshot) => /* @__PURE__ */jsxs(Card, {
|
|
1747
1846
|
ref: provided.innerRef,
|
|
1748
1847
|
tone: snapshot.isDraggingOver ? "primary" : defaultCardTone,
|
|
@@ -1758,6 +1857,7 @@ function WorkflowTool(props) {
|
|
|
1758
1857
|
}) : null, /* @__PURE__ */jsx(DocumentList, {
|
|
1759
1858
|
data,
|
|
1760
1859
|
invalidDocumentIds,
|
|
1860
|
+
patchingIds,
|
|
1761
1861
|
selectedSchemaTypes,
|
|
1762
1862
|
selectedUserIds,
|
|
1763
1863
|
state,
|