sanity-plugin-workflow 1.0.0-beta.3 → 1.0.0-beta.4

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.3",
3
+ "version": "1.0.0-beta.4",
4
4
  "description": "A demonstration of a custom content publishing workflow using Sanity.",
5
5
  "keywords": [
6
6
  "sanity",
@@ -49,13 +49,14 @@
49
49
  "watch": "pkg-utils watch --strict"
50
50
  },
51
51
  "dependencies": {
52
+ "@hello-pangea/dnd": "^16.2.0",
52
53
  "@sanity/icons": "^2.2.2",
53
54
  "@sanity/incompatible-plugin": "^1.0.4",
55
+ "@tanstack/react-virtual": "^3.0.0-beta.54",
54
56
  "@types/styled-components": "^5.1.26",
55
57
  "framer-motion": "^10.6.1",
56
58
  "groq": "^3.3.1",
57
59
  "lexorank": "^1.0.5",
58
- "react-beautiful-dnd": "^13.1.1",
59
60
  "react-fast-compare": "^3.2.1",
60
61
  "sanity-plugin-utils": "^1.3.0"
61
62
  },
@@ -66,7 +67,6 @@
66
67
  "@sanity/plugin-kit": "^3.1.4",
67
68
  "@sanity/semantic-release-preset": "^4.0.1",
68
69
  "@types/react": "^18.0.27",
69
- "@types/react-beautiful-dnd": "^13.1.2",
70
70
  "@typescript-eslint/eslint-plugin": "^5.51.0",
71
71
  "@typescript-eslint/parser": "^5.51.0",
72
72
  "eslint": "^8.33.0",
@@ -75,6 +75,7 @@
75
75
  "eslint-plugin-prettier": "^4.2.1",
76
76
  "eslint-plugin-react": "^7.32.2",
77
77
  "eslint-plugin-react-hooks": "^4.6.0",
78
+ "eslint-plugin-simple-import-sort": "^10.0.0",
78
79
  "husky": "^8.0.3",
79
80
  "lint-staged": "^13.2.0",
80
81
  "npm-run-all": "^4.1.5",
@@ -1,11 +1,13 @@
1
1
  import {PublishIcon} from '@sanity/icons'
2
2
  import {PreviewValue, SanityDocument} from '@sanity/types'
3
3
  import {Box, Text, Tooltip} from '@sanity/ui'
4
+ import {TextWithTone} from 'sanity'
4
5
 
5
6
  import {TimeAgo} from './TimeAgo'
6
- import {TextWithTone} from 'sanity'
7
7
 
8
- export function PublishedStatus(props: {document?: PreviewValue | Partial<SanityDocument> | null}) {
8
+ export function PublishedStatus(props: {
9
+ document?: PreviewValue | Partial<SanityDocument> | null
10
+ }) {
9
11
  const {document} = props
10
12
  const updatedAt = document && '_updatedAt' in document && document._updatedAt
11
13
 
@@ -24,7 +26,12 @@ export function PublishedStatus(props: {document?: PreviewValue | Partial<Sanity
24
26
  </Box>
25
27
  }
26
28
  >
27
- <TextWithTone tone="positive" dimmed={!document} muted={!document} size={1}>
29
+ <TextWithTone
30
+ tone="positive"
31
+ dimmed={!document}
32
+ muted={!document}
33
+ size={1}
34
+ >
28
35
  <PublishIcon />
29
36
  </TextWithTone>
30
37
  </Tooltip>
@@ -1,17 +1,17 @@
1
1
  /* eslint-disable react/prop-types */
2
- import {useEffect, useMemo} from 'react'
3
- import {Box, Card, CardTone, Flex, Stack, useTheme} from '@sanity/ui'
4
2
  import {DragHandleIcon} from '@sanity/icons'
5
- import {useSchema, SchemaType, useValidationStatus} from 'sanity'
3
+ import {Box, Card, CardTone, Flex, Stack, useTheme} from '@sanity/ui'
4
+ import {useEffect, useMemo} from 'react'
5
+ import {SchemaType, useSchema, useValidationStatus} from 'sanity'
6
6
  import {Preview} from 'sanity'
7
7
 
8
- import EditButton from './EditButton'
9
8
  import {SanityDocumentWithMetadata, State, User} from '../../types'
10
9
  import UserDisplay from '../UserDisplay'
10
+ import CompleteButton from './CompleteButton'
11
11
  import {DraftStatus} from './core/DraftStatus'
12
12
  import {PublishedStatus} from './core/PublishedStatus'
13
+ import EditButton from './EditButton'
13
14
  import {ValidationStatus} from './ValidationStatus'
14
- import CompleteButton from './CompleteButton'
15
15
 
16
16
  type DocumentCardProps = {
17
17
  isDragDisabled: boolean
@@ -0,0 +1,122 @@
1
+ import {Draggable} from '@hello-pangea/dnd'
2
+ import {useVirtualizer} from '@tanstack/react-virtual'
3
+ import {useMemo, useRef} from 'react'
4
+ import {CurrentUser} from 'sanity'
5
+ import {UserExtended} from 'sanity-plugin-utils'
6
+
7
+ import {filterItemsAndSort} from '../helpers/filterItemsAndSort'
8
+ import {SanityDocumentWithMetadata, State} from '../types'
9
+ import {DocumentCard} from './DocumentCard'
10
+
11
+ type DocumentListProps = {
12
+ data: SanityDocumentWithMetadata[]
13
+ invalidDocumentIds: string[]
14
+ selectedSchemaTypes: string[]
15
+ selectedUserIds: string[]
16
+ state: State
17
+ states: State[]
18
+ toggleInvalidDocumentId: (
19
+ documentId: string,
20
+ action: 'ADD' | 'REMOVE'
21
+ ) => void
22
+ user: CurrentUser | null
23
+ userList: UserExtended[]
24
+ userRoleCanDrop: boolean
25
+ }
26
+
27
+ export default function DocumentList(props: DocumentListProps) {
28
+ const {
29
+ data = [],
30
+ invalidDocumentIds,
31
+ selectedSchemaTypes,
32
+ selectedUserIds,
33
+ state,
34
+ states,
35
+ toggleInvalidDocumentId,
36
+ user,
37
+ userList,
38
+ userRoleCanDrop,
39
+ } = props
40
+
41
+ const dataFiltered = useMemo(() => {
42
+ return data.length
43
+ ? filterItemsAndSort(data, state.id, selectedUserIds, selectedSchemaTypes)
44
+ : []
45
+ }, [data, selectedSchemaTypes, selectedUserIds, state.id])
46
+
47
+ const parentRef = useRef(null)
48
+
49
+ const rowVirtualizer = useVirtualizer({
50
+ count: data.length,
51
+ getScrollElement: () => parentRef.current,
52
+ getItemKey: (index) => dataFiltered[index]?._metadata?.documentId ?? index,
53
+ estimateSize: () => 113,
54
+ overscan: 5,
55
+ })
56
+
57
+ if (!data.length) {
58
+ return null
59
+ }
60
+
61
+ return (
62
+ <div
63
+ ref={parentRef}
64
+ style={{
65
+ height: `100%`,
66
+ overflow: 'auto',
67
+ paddingTop: 1,
68
+ // Smooths scrollbar behaviour
69
+ overflowAnchor: 'none',
70
+ scrollBehavior: 'auto',
71
+ }}
72
+ >
73
+ {/* {dataFiltered.map((item, itemIndex) => { */}
74
+ {rowVirtualizer.getVirtualItems().map((virtualItem) => {
75
+ const item = dataFiltered[virtualItem.index]
76
+
77
+ const {documentId, assignees} = item?._metadata ?? {}
78
+
79
+ if (!documentId) {
80
+ return null
81
+ }
82
+
83
+ const isInvalid = invalidDocumentIds.includes(documentId)
84
+ const meInAssignees = user?.id ? assignees?.includes(user.id) : false
85
+ const isDragDisabled =
86
+ !userRoleCanDrop ||
87
+ isInvalid ||
88
+ !(state.requireAssignment
89
+ ? state.requireAssignment && meInAssignees
90
+ : true)
91
+
92
+ return (
93
+ <Draggable
94
+ // The metadata's documentId is always the published one to avoid rerendering
95
+ key={documentId}
96
+ draggableId={documentId}
97
+ index={virtualItem.index}
98
+ isDragDisabled={isDragDisabled}
99
+ >
100
+ {(draggableProvided, draggableSnapshot) => (
101
+ <div
102
+ ref={draggableProvided.innerRef}
103
+ {...draggableProvided.draggableProps}
104
+ {...draggableProvided.dragHandleProps}
105
+ >
106
+ <DocumentCard
107
+ userRoleCanDrop={userRoleCanDrop}
108
+ isDragDisabled={isDragDisabled}
109
+ isDragging={draggableSnapshot.isDragging}
110
+ item={item}
111
+ toggleInvalidDocumentId={toggleInvalidDocumentId}
112
+ userList={userList}
113
+ states={states}
114
+ />
115
+ </div>
116
+ )}
117
+ </Draggable>
118
+ )
119
+ })}
120
+ </div>
121
+ )
122
+ }
@@ -1,8 +1,8 @@
1
- import {MenuButton, Menu, Flex, Card, Button} from '@sanity/ui'
1
+ import {ResetIcon, UserIcon} from '@sanity/icons'
2
+ import {Button, Card, Flex, Menu, MenuButton} from '@sanity/ui'
3
+ import {useCallback} from 'react'
2
4
  import {useCurrentUser, UserAvatar, useSchema} from 'sanity'
3
- import {UserIcon, ResetIcon} from '@sanity/icons'
4
5
  import {UserExtended, UserSelectMenu} from 'sanity-plugin-utils'
5
- import {useCallback} from 'react'
6
6
 
7
7
  type FiltersProps = {
8
8
  uniqueAssignedUsers: UserExtended[]
@@ -1,12 +1,12 @@
1
+ import {Button, useToast} from '@sanity/ui'
2
+ import {LexoRank} from 'lexorank'
1
3
  import React from 'react'
2
- import {useToast, Button} from '@sanity/ui'
3
4
  import {useClient} from 'sanity'
4
5
  import {UserExtended} from 'sanity-plugin-utils'
5
- import {LexoRank} from 'lexorank'
6
6
 
7
- import FloatingCard from './FloatingCard'
8
7
  import {API_VERSION} from '../constants'
9
8
  import {SanityDocumentWithMetadata, State} from '../types'
9
+ import FloatingCard from './FloatingCard'
10
10
 
11
11
  type ValidatorsProps = {
12
12
  data: SanityDocumentWithMetadata[]
@@ -143,6 +143,32 @@ export default function Validators({data, userList, states}: ValidatorsProps) {
143
143
  [data, client, toast]
144
144
  )
145
145
 
146
+ // A document could be deleted and the workflow metadata left behind
147
+ const orphanedMetadataDocumentIds = React.useMemo(() => {
148
+ return data.length
149
+ ? data.filter((doc) => !doc?._id).map((doc) => doc._metadata.documentId)
150
+ : []
151
+ }, [data])
152
+
153
+ const handleOrphans = React.useCallback(() => {
154
+ toast.push({
155
+ title: 'Removing orphaned metadata...',
156
+ status: 'info',
157
+ })
158
+
159
+ const tx = client.transaction()
160
+ orphanedMetadataDocumentIds.forEach((id) => {
161
+ tx.delete(`workflow-metadata.${id}`)
162
+ })
163
+
164
+ tx.commit()
165
+
166
+ toast.push({
167
+ title: `Removed ${orphanedMetadataDocumentIds.length} orphaned metadata documents`,
168
+ status: 'success',
169
+ })
170
+ }, [client, orphanedMetadataDocumentIds, toast])
171
+
146
172
  return (
147
173
  <FloatingCard>
148
174
  {documentsWithoutValidMetadataIds.length > 0 ? (
@@ -178,6 +204,13 @@ export default function Validators({data, userList, states}: ValidatorsProps) {
178
204
  }
179
205
  />
180
206
  ) : null}
207
+ {orphanedMetadataDocumentIds.length > 0 ? (
208
+ <Button
209
+ text="Cleanup orphaned metadata"
210
+ onClick={handleOrphans}
211
+ tone="caution"
212
+ />
213
+ ) : null}
181
214
  {/* <Button
182
215
  tone="caution"
183
216
  onClick={() =>
@@ -1,26 +1,25 @@
1
- import React from 'react'
2
- import {Flex, Card, Grid, Spinner, Container, useTheme} from '@sanity/ui'
3
- import {Feedback, useProjectUsers} from 'sanity-plugin-utils'
4
- import {Tool, useCurrentUser} from 'sanity'
5
1
  import {
6
2
  DragDropContext,
3
+ DragStart,
7
4
  Droppable,
8
- Draggable,
9
5
  DropResult,
10
- DragStart,
11
- } from 'react-beautiful-dnd'
6
+ } from '@hello-pangea/dnd'
7
+ import {Box, Card, Container, Flex, Grid, Spinner, useTheme} from '@sanity/ui'
8
+ import {LexoRank} from 'lexorank'
9
+ import React from 'react'
10
+ import {Tool, useCurrentUser} from 'sanity'
11
+ import {Feedback, useProjectUsers} from 'sanity-plugin-utils'
12
12
 
13
+ import {API_VERSION} from '../constants'
14
+ import {arraysContainMatchingString} from '../helpers/arraysContainMatchingString'
15
+ import {filterItemsAndSort} from '../helpers/filterItemsAndSort'
16
+ import {useWorkflowDocuments} from '../hooks/useWorkflowDocuments'
13
17
  import {State, WorkflowConfig} from '../types'
14
18
  import {DocumentCard} from './DocumentCard'
15
- import {useWorkflowDocuments} from '../hooks/useWorkflowDocuments'
16
- import {API_VERSION} from '../constants'
17
-
18
- import Validators from './Validators'
19
+ import DocumentList from './DocumentList'
19
20
  import Filters from './Filters'
20
- import {filterItemsAndSort} from '../helpers/filterItemsAndSort'
21
- import {arraysContainMatchingString} from '../helpers/arraysContainMatchingString'
22
21
  import StateTitle from './StateTitle'
23
- import {LexoRank} from 'lexorank'
22
+ import Validators from './Validators'
24
23
 
25
24
  type WorkflowToolProps = {
26
25
  tool: Tool<WorkflowConfig>
@@ -154,12 +153,12 @@ export default function WorkflowTool(props: WorkflowToolProps) {
154
153
  : LexoRank.min().toString()
155
154
  } else {
156
155
  // Must be between two items
157
- const itemBefore = destinationStateItems[destination.index]
156
+ const itemBefore = destinationStateItems[destination.index - 1]
158
157
  const itemBeforeRank = itemBefore?._metadata?.orderRank
159
158
  const itemBeforeRankParsed = itemBefore._metadata.orderRank
160
159
  ? LexoRank.parse(itemBeforeRank)
161
160
  : LexoRank.min()
162
- const itemAfter = destinationStateItems[destination.index + 1]
161
+ const itemAfter = destinationStateItems[destination.index]
163
162
  const itemAfterRank = itemAfter?._metadata?.orderRank
164
163
  const itemAfterRankParsed = itemAfter._metadata.orderRank
165
164
  ? LexoRank.parse(itemAfterRank)
@@ -173,6 +172,7 @@ export default function WorkflowTool(props: WorkflowToolProps) {
173
172
  [data, move, states]
174
173
  )
175
174
 
175
+ // Used for the user filter UI
176
176
  const uniqueAssignedUsers = React.useMemo(() => {
177
177
  const uniqueUserIds = data.reduce((acc, item) => {
178
178
  const {assignees = []} = item._metadata ?? {}
@@ -185,6 +185,7 @@ export default function WorkflowTool(props: WorkflowToolProps) {
185
185
  return userList.filter((u) => uniqueUserIds.includes(u.id))
186
186
  }, [data, userList])
187
187
 
188
+ // Selected user IDs filter the visible workflow documents
188
189
  const [selectedUserIds, setSelectedUserIds] = React.useState<string[]>(
189
190
  uniqueAssignedUsers.map((u) => u.id)
190
191
  )
@@ -199,6 +200,7 @@ export default function WorkflowTool(props: WorkflowToolProps) {
199
200
  setSelectedUserIds([])
200
201
  }, [])
201
202
 
203
+ // Selected schema types filter the visible workflow documents
202
204
  const [selectedSchemaTypes, setSelectedSchemaTypes] =
203
205
  React.useState<string[]>(schemaTypes)
204
206
  const toggleSelectedSchemaType = React.useCallback((schemaType: string) => {
@@ -209,6 +211,7 @@ export default function WorkflowTool(props: WorkflowToolProps) {
209
211
  )
210
212
  }, [])
211
213
 
214
+ // Document IDs that have validation errors
212
215
  const [invalidDocumentIds, setInvalidDocumentIds] = React.useState<string[]>(
213
216
  []
214
217
  )
@@ -245,7 +248,7 @@ export default function WorkflowTool(props: WorkflowToolProps) {
245
248
  }
246
249
 
247
250
  return (
248
- <Card height="fill" overflow="hidden">
251
+ <Flex direction="column" height="fill" overflow="hidden">
249
252
  <Validators data={data} userList={userList} states={states} />
250
253
  <Filters
251
254
  uniqueAssignedUsers={uniqueAssignedUsers}
@@ -270,100 +273,95 @@ export default function WorkflowTool(props: WorkflowToolProps) {
270
273
  key={state.id}
271
274
  borderLeft={stateIndex > 0}
272
275
  tone={defaultCardTone}
273
- height="fill"
274
- overflow="auto"
275
276
  >
276
- <StateTitle
277
- state={state}
278
- requireAssignment={state.requireAssignment ?? false}
279
- userRoleCanDrop={userRoleCanDrop}
280
- // operation={state.operation}
281
- isDropDisabled={isDropDisabled}
282
- draggingFrom={draggingFrom}
283
- />
284
- <Droppable
285
- droppableId={state.id}
286
- isDropDisabled={isDropDisabled}
287
- >
288
- {(provided, snapshot) => (
289
- <Card
290
- ref={provided.innerRef}
291
- tone={
292
- snapshot.isDraggingOver ? `primary` : defaultCardTone
293
- }
294
- height="fill"
295
- paddingTop={1}
277
+ <Flex direction="column" height="fill">
278
+ <StateTitle
279
+ state={state}
280
+ requireAssignment={state.requireAssignment ?? false}
281
+ userRoleCanDrop={userRoleCanDrop}
282
+ // operation={state.operation}
283
+ isDropDisabled={isDropDisabled}
284
+ draggingFrom={draggingFrom}
285
+ />
286
+ <Box flex={1}>
287
+ <Droppable
288
+ droppableId={state.id}
289
+ isDropDisabled={isDropDisabled}
290
+ // props required for virtualization
291
+ mode="virtual"
292
+ renderClone={(provided, snapshot, rubric) => {
293
+ const item = data.find(
294
+ (doc) =>
295
+ doc?._metadata?.documentId === rubric.draggableId
296
+ )
297
+
298
+ return (
299
+ <div
300
+ {...provided.draggableProps}
301
+ {...provided.dragHandleProps}
302
+ ref={provided.innerRef}
303
+ >
304
+ {item ? (
305
+ <DocumentCard
306
+ isDragDisabled={false}
307
+ userRoleCanDrop={userRoleCanDrop}
308
+ isDragging={snapshot.isDragging}
309
+ item={item}
310
+ states={states}
311
+ toggleInvalidDocumentId={
312
+ toggleInvalidDocumentId
313
+ }
314
+ userList={userList}
315
+ />
316
+ ) : (
317
+ <Feedback title="Item not found" tone="caution" />
318
+ )}
319
+ </div>
320
+ )
321
+ }}
296
322
  >
297
- {loading ? (
298
- <Flex padding={5} align="center" justify="center">
299
- <Spinner muted />
300
- </Flex>
301
- ) : null}
302
-
303
- {data.length > 0 &&
304
- filterItemsAndSort(
305
- data,
306
- state.id,
307
- selectedUserIds,
308
- selectedSchemaTypes
309
- ).map((item, itemIndex) => {
310
- const isInvalid = invalidDocumentIds.includes(
311
- String(item?._metadata?.documentId)
312
- )
313
- const meInAssignees = user?.id
314
- ? item?._metadata?.assignees?.includes(user.id)
315
- : false
316
- const isDragDisabled =
317
- !userRoleCanDrop ||
318
- isInvalid ||
319
- !(state.requireAssignment
320
- ? state.requireAssignment && meInAssignees
321
- : true)
322
- const {documentId} = item._metadata ?? {}
323
-
324
- if (!documentId) {
325
- return null
323
+ {(provided, snapshot) => (
324
+ <Card
325
+ ref={provided.innerRef}
326
+ tone={
327
+ snapshot.isDraggingOver
328
+ ? `primary`
329
+ : defaultCardTone
326
330
  }
327
-
328
- return (
329
- <Draggable
330
- // The metadata's documentId is always the published one to avoid rerendering
331
- key={documentId}
332
- draggableId={documentId}
333
- index={itemIndex}
334
- isDragDisabled={isDragDisabled}
335
- >
336
- {(draggableProvided, draggableSnapshot) => (
337
- <div
338
- ref={draggableProvided.innerRef}
339
- {...draggableProvided.draggableProps}
340
- {...draggableProvided.dragHandleProps}
341
- >
342
- <DocumentCard
343
- userRoleCanDrop={userRoleCanDrop}
344
- isDragDisabled={isDragDisabled}
345
- isDragging={draggableSnapshot.isDragging}
346
- item={item}
347
- toggleInvalidDocumentId={
348
- toggleInvalidDocumentId
349
- }
350
- userList={userList}
351
- states={states}
352
- />
353
- </div>
354
- )}
355
- </Draggable>
356
- )
357
- })}
358
- {provided.placeholder}
359
- </Card>
360
- )}
361
- </Droppable>
331
+ height="fill"
332
+ paddingTop={1}
333
+ >
334
+ {loading ? (
335
+ <Flex padding={5} align="center" justify="center">
336
+ <Spinner muted />
337
+ </Flex>
338
+ ) : null}
339
+
340
+ <DocumentList
341
+ data={data}
342
+ invalidDocumentIds={invalidDocumentIds}
343
+ selectedSchemaTypes={selectedSchemaTypes}
344
+ selectedUserIds={selectedUserIds}
345
+ state={state}
346
+ states={states}
347
+ toggleInvalidDocumentId={toggleInvalidDocumentId}
348
+ user={user}
349
+ userList={userList}
350
+ userRoleCanDrop={userRoleCanDrop}
351
+ />
352
+
353
+ {/* Not required for virtualized lists */}
354
+ {/* {provided.placeholder} */}
355
+ </Card>
356
+ )}
357
+ </Droppable>
358
+ </Box>
359
+ </Flex>
362
360
  </Card>
363
361
  )
364
362
  })}
365
363
  </Grid>
366
364
  </DragDropContext>
367
- </Card>
365
+ </Flex>
368
366
  )
369
367
  }
@@ -1,4 +1,4 @@
1
- import {WorkflowConfig, defineStates} from '../types'
1
+ import {defineStates, WorkflowConfig} from '../types'
2
2
 
3
3
  export const API_VERSION = `2023-01-01`
4
4
 
@@ -8,6 +8,8 @@ export function filterItemsAndSort(
8
8
  ): SanityDocumentWithMetadata[] {
9
9
  return (
10
10
  items
11
+ // Only items that have existing documents
12
+ .filter((item) => item?._id)
11
13
  // Only items of this state
12
14
  .filter((item) => item?._metadata?.state === stateId)
13
15
  // Only items with selected users, if the document has any assigned users
@@ -1,12 +1,12 @@
1
- import React from 'react'
2
- import {useListeningQuery} from 'sanity-plugin-utils'
1
+ import {DraggableLocation} from '@hello-pangea/dnd'
3
2
  import {useToast} from '@sanity/ui'
4
- import {useClient} from 'sanity'
5
- import {DraggableLocation} from 'react-beautiful-dnd'
6
3
  import groq from 'groq'
4
+ import React from 'react'
5
+ import {useClient} from 'sanity'
6
+ import {useListeningQuery} from 'sanity-plugin-utils'
7
7
 
8
- import {SanityDocumentWithMetadata, State} from '../types'
9
8
  import {API_VERSION} from '../constants'
9
+ import {SanityDocumentWithMetadata, State} from '../types'
10
10
 
11
11
  const QUERY = groq`*[_type == "workflow.metadata"]|order(orderRank){
12
12
  "_metadata": {
@@ -24,7 +24,7 @@ const QUERY = groq`*[_type == "workflow.metadata"]|order(orderRank){
24
24
  _updatedAt
25
25
  }
26
26
  )
27
- }[defined(_id)]`
27
+ }`
28
28
 
29
29
  type WorkflowDocuments = {
30
30
  workflowData: {
package/src/index.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  import {definePlugin, DocumentActionProps} from 'sanity'
2
2
 
3
- import {DEFAULT_CONFIG} from './constants'
4
- import {WorkflowConfig} from './types'
5
- import {workflowTool} from './tools'
6
- import metadata from './schema/workflow/workflow.metadata'
7
3
  import {AssignWorkflow} from './actions/AssignWorkflow'
8
4
  import {BeginWorkflow} from './actions/BeginWorkflow'
9
5
  import {CompleteWorkflow} from './actions/CompleteWorkflow'
6
+ import {UpdateWorkflow} from './actions/UpdateWorkflow'
10
7
  import {AssigneesBadge} from './badges/AssigneesBadge'
11
8
  import {StateBadge} from './badges/StateBadge'
12
- import {UpdateWorkflow} from './actions/UpdateWorkflow'
9
+ import {DEFAULT_CONFIG} from './constants'
10
+ import metadata from './schema/workflow/workflow.metadata'
11
+ import {workflowTool} from './tools'
12
+ import {WorkflowConfig} from './types'
13
13
 
14
14
  export const workflow = definePlugin<WorkflowConfig>(
15
15
  (config = DEFAULT_CONFIG) => {
@@ -1,4 +1,4 @@
1
- import {defineType, defineField} from 'sanity'
1
+ import {defineField, defineType} from 'sanity'
2
2
 
3
3
  import Field from '../../components/DocumentCard/Field'
4
4
  import UserAssignmentInput from '../../components/UserAssignmentInput'
@@ -1,5 +1,5 @@
1
- import {Tool} from 'sanity'
2
1
  import {SplitVerticalIcon} from '@sanity/icons'
2
+ import {Tool} from 'sanity'
3
3
 
4
4
  import WorkflowTool from '../components/WorkflowTool'
5
5
  import {WorkflowConfig} from '../types'