sanity-plugin-workflow 1.0.0-beta.5 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanity-plugin-workflow",
3
- "version": "1.0.0-beta.5",
3
+ "version": "1.0.0-beta.6",
4
4
  "description": "A demonstration of a custom content publishing workflow using Sanity.",
5
5
  "keywords": [
6
6
  "sanity",
@@ -45,45 +45,6 @@ export function DocumentCard(props: DocumentCardProps) {
45
45
  const schema = useSchema()
46
46
  const state = states.find((s) => s.id === item._metadata?.state)
47
47
 
48
- // Perform document operations after State changes
49
- // If State has changed and the document needs to be un/published
50
- // This functionality was deemed too dangerous / unexpected
51
- // Revisit with improved UX
52
- // const currentState = useMemo(
53
- // () => states.find((state) => state.id === item._metadata?.state),
54
- // [states, item]
55
- // )
56
- // const ops = useDocumentOperation(documentId ?? ``, item._type)
57
- // const toast = useToast()
58
-
59
- // useEffect(() => {
60
- // const isDraft = item._id.startsWith('drafts.')
61
-
62
- // if (isDraft && currentState?.operation === 'publish' && !item?._metadata?.optimistic) {
63
- // if (!ops.publish.disabled) {
64
- // ops.publish.execute()
65
- // toast.push({
66
- // title: 'Published Document',
67
- // description: documentId,
68
- // status: 'success',
69
- // })
70
- // }
71
- // } else if (
72
- // !isDraft &&
73
- // currentState?.operation === 'unpublish' &&
74
- // !item?._metadata?.optimistic
75
- // ) {
76
- // if (!ops.unpublish.disabled) {
77
- // ops.unpublish.execute()
78
- // toast.push({
79
- // title: 'Unpublished Document',
80
- // description: documentId,
81
- // status: 'success',
82
- // })
83
- // }
84
- // }
85
- // }, [currentState, documentId, item, ops, toast])
86
-
87
48
  const isDarkMode = useTheme().sanity.color.dark
88
49
  const defaultCardTone = isDarkMode ? `transparent` : `default`
89
50
 
@@ -51,7 +51,7 @@ export default function DocumentList(props: DocumentListProps) {
51
51
  getScrollElement: () => parentRef.current,
52
52
  getItemKey: (index) => dataFiltered[index]?._metadata?.documentId ?? index,
53
53
  estimateSize: () => 113,
54
- overscan: 5,
54
+ overscan: 10,
55
55
  })
56
56
 
57
57
  if (!data.length) {
@@ -1,21 +1,9 @@
1
- import {Flex, Card, Badge, BadgeTone} from '@sanity/ui'
2
1
  import {InfoOutlineIcon, UserIcon} from '@sanity/icons'
2
+ import {Badge, BadgeTone, Box, Card, Flex, Text} from '@sanity/ui'
3
3
  import styled, {css} from 'styled-components'
4
4
 
5
+ import {State} from '../../types'
5
6
  import {Status} from './Status'
6
- import {
7
- // Operation,
8
- State,
9
- } from '../../types'
10
-
11
- type StateTitleProps = {
12
- state: State
13
- requireAssignment: boolean
14
- userRoleCanDrop: boolean
15
- isDropDisabled: boolean
16
- draggingFrom: string
17
- // operation?: Operation
18
- }
19
7
 
20
8
  const StyledStickyCard = styled(Card)(
21
9
  () => css`
@@ -25,8 +13,24 @@ const StyledStickyCard = styled(Card)(
25
13
  `
26
14
  )
27
15
 
16
+ type StateTitleProps = {
17
+ state: State
18
+ requireAssignment: boolean
19
+ userRoleCanDrop: boolean
20
+ isDropDisabled: boolean
21
+ draggingFrom: string
22
+ documentCount: number
23
+ }
24
+
28
25
  export default function StateTitle(props: StateTitleProps) {
29
- const {state, requireAssignment, userRoleCanDrop, isDropDisabled, draggingFrom} = props
26
+ const {
27
+ state,
28
+ requireAssignment,
29
+ userRoleCanDrop,
30
+ isDropDisabled,
31
+ draggingFrom,
32
+ documentCount,
33
+ } = props
30
34
 
31
35
  let tone: BadgeTone = 'default'
32
36
  const isSource = draggingFrom === state.id
@@ -39,7 +43,11 @@ export default function StateTitle(props: StateTitleProps) {
39
43
  <StyledStickyCard paddingY={4} padding={3} tone="inherit">
40
44
  <Flex gap={3} align="center">
41
45
  <Badge
42
- mode={(draggingFrom && !isDropDisabled) || isSource ? 'default' : 'outline'}
46
+ mode={
47
+ (draggingFrom && !isDropDisabled) || isSource
48
+ ? 'default'
49
+ : 'outline'
50
+ }
43
51
  tone={tone}
44
52
  muted={!userRoleCanDrop || isDropDisabled}
45
53
  >
@@ -57,16 +65,13 @@ export default function StateTitle(props: StateTitleProps) {
57
65
  icon={UserIcon}
58
66
  />
59
67
  ) : null}
60
- {/* {operation ? (
61
- <Status
62
- text={
63
- operation === 'publish'
64
- ? `A document moved to this State will also publish the current Draft`
65
- : `A document moved to this State will also unpublish the current Published version`
66
- }
67
- icon={operation === 'publish' ? PublishIcon : UnpublishIcon}
68
- />
69
- ) : null} */}
68
+ <Box flex={1}>
69
+ {documentCount > 0 ? (
70
+ <Text weight="semibold" align="right" size={1}>
71
+ {documentCount}
72
+ </Text>
73
+ ) : null}
74
+ </Box>
70
75
  </Flex>
71
76
  </StyledStickyCard>
72
77
  )
@@ -51,6 +51,18 @@ export default function Verify(props: VerifyProps) {
51
51
  }, [] as string[])
52
52
  : []
53
53
 
54
+ const documentsWithDuplicatedOrderIds = data?.length
55
+ ? data.reduce((acc, cur) => {
56
+ const {documentId, orderRank} = cur._metadata ?? {}
57
+
58
+ return orderRank &&
59
+ data.filter((d) => d._metadata?.orderRank === orderRank).length > 1 &&
60
+ documentId
61
+ ? [...acc, documentId]
62
+ : acc
63
+ }, [] as string[])
64
+ : []
65
+
54
66
  // Updates metadata documents to a valid, existing state
55
67
  const correctDocuments = React.useCallback(
56
68
  async (ids: string[]) => {
@@ -208,6 +220,17 @@ export default function Verify(props: VerifyProps) {
208
220
  }
209
221
  />
210
222
  ) : null}
223
+ {documentsWithDuplicatedOrderIds.length > 0 ? (
224
+ <Button
225
+ tone="caution"
226
+ onClick={() => addOrderToDocuments(documentsWithDuplicatedOrderIds)}
227
+ text={
228
+ documentsWithDuplicatedOrderIds.length === 1
229
+ ? `Set Unique Order for 1 Document`
230
+ : `Set Unique Order for ${documentsWithDuplicatedOrderIds.length} Documents`
231
+ }
232
+ />
233
+ ) : null}
211
234
  {orphanedMetadataDocumentIds.length > 0 ? (
212
235
  <Button
213
236
  text="Cleanup orphaned metadata"
@@ -107,7 +107,7 @@ export default function WorkflowTool(props: WorkflowToolProps) {
107
107
  )
108
108
 
109
109
  const handleDragEnd = React.useCallback(
110
- (result: DropResult) => {
110
+ async (result: DropResult) => {
111
111
  // Reset undroppable states
112
112
  setUndroppableStates([])
113
113
  setDraggingFrom(``)
@@ -280,9 +280,16 @@ export default function WorkflowTool(props: WorkflowToolProps) {
280
280
  state={state}
281
281
  requireAssignment={state.requireAssignment ?? false}
282
282
  userRoleCanDrop={userRoleCanDrop}
283
- // operation={state.operation}
284
283
  isDropDisabled={isDropDisabled}
285
284
  draggingFrom={draggingFrom}
285
+ documentCount={
286
+ filterItemsAndSort(
287
+ data,
288
+ state.id,
289
+ selectedUserIds,
290
+ selectedSchemaTypes
291
+ ).length
292
+ }
286
293
  />
287
294
  <Box flex={1}>
288
295
  <Droppable
@@ -65,7 +65,7 @@ export function useWorkflowDocuments(schemaTypes: string[]): WorkflowDocuments {
65
65
  }, [data])
66
66
 
67
67
  const move = React.useCallback(
68
- (
68
+ async (
69
69
  draggedId: string,
70
70
  destination: DraggableLocation,
71
71
  states: State[],
@@ -122,11 +122,13 @@ export function useWorkflowDocuments(schemaTypes: string[]): WorkflowDocuments {
122
122
  const {_id, _type} = document
123
123
 
124
124
  // Metadata + useDocumentOperation always uses Published id
125
- const {_rev, documentId} = document._metadata || {}
125
+ const {documentId} = document._metadata || {}
126
126
 
127
- client
127
+ await client
128
128
  .patch(`workflow-metadata.${documentId}`)
129
- .ifRevisionId(_rev as string)
129
+ // Removed because it was effecting fast-updates between columns
130
+ // TODO: Prevent dragging while patching instead while keeping optimistic updates and revert when patch fails
131
+ // .ifRevisionId(document._metadata._rev)
130
132
  .set({state: newStateId, orderRank: newOrder})
131
133
  .commit()
132
134
  .then(() => {
@@ -135,12 +137,13 @@ export function useWorkflowDocuments(schemaTypes: string[]): WorkflowDocuments {
135
137
  status: 'success',
136
138
  })
137
139
  })
138
- .catch(() => {
140
+ .catch((err) => {
139
141
  // Revert optimistic update
140
142
  setLocalDocuments(currentLocalData)
141
143
 
142
144
  return toast.push({
143
145
  title: `Failed to move to "${newState?.title ?? newStateId}"`,
146
+ description: err.message,
144
147
  status: 'error',
145
148
  })
146
149
  })
@@ -1,12 +1,9 @@
1
1
  import {SanityDocumentLike} from 'sanity'
2
2
 
3
- // export type Operation = 'publish' | 'unpublish'
4
-
5
3
  export type State = {
6
4
  id: string
7
5
  transitions: string[]
8
6
  title: string
9
- // operation?: Operation
10
7
  roles?: string[]
11
8
  requireAssignment?: boolean
12
9
  requireValidation?: boolean