sanity-plugin-workflow 1.0.0-beta.6 → 1.0.0-beta.8
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/lib/index.esm.js +215 -73
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +215 -73
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/DocumentCard/CompleteButton.tsx +47 -32
- package/src/components/DocumentCard/index.tsx +20 -3
- package/src/components/DocumentList.tsx +6 -2
- package/src/components/Filters.tsx +1 -1
- package/src/components/Verify.tsx +80 -39
- package/src/components/WorkflowTool.tsx +113 -49
- package/src/helpers/generateMultipleOrderRanks.ts +80 -0
- package/src/hooks/useWorkflowDocuments.tsx +11 -8
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import {LexoRank} from 'lexorank'
|
|
2
|
+
|
|
3
|
+
function generateMiddleValue(ranks: (LexoRank | undefined)[]) {
|
|
4
|
+
// Has no undefined values
|
|
5
|
+
if (!ranks.some((rank) => !rank)) {
|
|
6
|
+
return ranks
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Find the first undefined value
|
|
10
|
+
const firstUndefined = ranks.findIndex((rank) => !rank)
|
|
11
|
+
|
|
12
|
+
// Find the first defined value after the undefined value
|
|
13
|
+
const firstDefinedAfter = ranks.findIndex(
|
|
14
|
+
(rank, index) => rank && index > firstUndefined
|
|
15
|
+
)
|
|
16
|
+
// Find the first defined value before the undefined value
|
|
17
|
+
const firstDefinedBefore = ranks.findLastIndex(
|
|
18
|
+
(rank, index) => rank && index < firstUndefined
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
if (firstDefinedAfter === -1 || firstDefinedBefore === -1) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Unable to generate middle value between indexes ${firstDefinedBefore} and ${firstDefinedAfter}`
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const beforeRank = ranks[firstDefinedBefore]
|
|
28
|
+
const afterRank = ranks[firstDefinedAfter]
|
|
29
|
+
|
|
30
|
+
if (
|
|
31
|
+
!beforeRank ||
|
|
32
|
+
typeof beforeRank === 'undefined' ||
|
|
33
|
+
!afterRank ||
|
|
34
|
+
typeof afterRank === 'undefined'
|
|
35
|
+
) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Unable to generate middle value between indexes ${firstDefinedBefore} and ${firstDefinedAfter}`
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Generate a new value between the two
|
|
42
|
+
const between = beforeRank.between(afterRank)
|
|
43
|
+
|
|
44
|
+
// Calculate the middle index between the defined values
|
|
45
|
+
const middle = Math.floor((firstDefinedAfter + firstDefinedBefore) / 2)
|
|
46
|
+
|
|
47
|
+
if (ranks[middle]) {
|
|
48
|
+
throw new Error(`Should not have overwritten value at index ${middle}`)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Insert the new value into the array
|
|
52
|
+
ranks[middle] = between
|
|
53
|
+
|
|
54
|
+
// Return as a new array
|
|
55
|
+
return ranks
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Generates an array of LexoRanks between two values
|
|
59
|
+
export function generateMultipleOrderRanks(
|
|
60
|
+
count: number,
|
|
61
|
+
start?: LexoRank,
|
|
62
|
+
end?: LexoRank
|
|
63
|
+
): LexoRank[] {
|
|
64
|
+
// Begin array with correct size
|
|
65
|
+
let ranks = [...Array(count)]
|
|
66
|
+
|
|
67
|
+
// Use or create default values
|
|
68
|
+
const rankStart = start ?? LexoRank.min().genNext().genNext()
|
|
69
|
+
const rankEnd = end ?? LexoRank.max().genPrev().genPrev()
|
|
70
|
+
|
|
71
|
+
ranks[0] = rankStart
|
|
72
|
+
ranks[count - 1] = rankEnd
|
|
73
|
+
|
|
74
|
+
// Keep processing the array until every value between undefined values is defined
|
|
75
|
+
for (let i = 0; i < count; i++) {
|
|
76
|
+
ranks = generateMiddleValue(ranks)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return ranks.sort((a, b) => a.toString().localeCompare(b.toString()))
|
|
80
|
+
}
|
|
@@ -122,30 +122,33 @@ export function useWorkflowDocuments(schemaTypes: string[]): WorkflowDocuments {
|
|
|
122
122
|
const {_id, _type} = document
|
|
123
123
|
|
|
124
124
|
// Metadata + useDocumentOperation always uses Published id
|
|
125
|
-
const {documentId} = document._metadata || {}
|
|
125
|
+
const {documentId, _rev} = document._metadata || {}
|
|
126
126
|
|
|
127
127
|
await client
|
|
128
128
|
.patch(`workflow-metadata.${documentId}`)
|
|
129
|
-
|
|
130
|
-
// TODO: Prevent dragging while patching instead while keeping optimistic updates and revert when patch fails
|
|
131
|
-
// .ifRevisionId(document._metadata._rev)
|
|
129
|
+
.ifRevisionId(_rev)
|
|
132
130
|
.set({state: newStateId, orderRank: newOrder})
|
|
133
131
|
.commit()
|
|
134
|
-
.then(() => {
|
|
135
|
-
|
|
136
|
-
title:
|
|
132
|
+
.then((res) => {
|
|
133
|
+
toast.push({
|
|
134
|
+
title:
|
|
135
|
+
newState.id === document._metadata.state
|
|
136
|
+
? `Reordered in "${newState?.title ?? newStateId}"`
|
|
137
|
+
: `Moved to "${newState?.title ?? newStateId}"`,
|
|
137
138
|
status: 'success',
|
|
138
139
|
})
|
|
140
|
+
return res
|
|
139
141
|
})
|
|
140
142
|
.catch((err) => {
|
|
141
143
|
// Revert optimistic update
|
|
142
144
|
setLocalDocuments(currentLocalData)
|
|
143
145
|
|
|
144
|
-
|
|
146
|
+
toast.push({
|
|
145
147
|
title: `Failed to move to "${newState?.title ?? newStateId}"`,
|
|
146
148
|
description: err.message,
|
|
147
149
|
status: 'error',
|
|
148
150
|
})
|
|
151
|
+
return null
|
|
149
152
|
})
|
|
150
153
|
|
|
151
154
|
// Send back to the workflow board so a document update can happen
|