sanity-plugin-dashboard-widget-vercel 3.1.1 → 3.1.3

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.mjs CHANGED
@@ -1,18 +1,17 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { LinkIcon, UploadIcon, EditIcon, ErrorOutlineIcon, AddIcon } from "@sanity/icons";
3
3
  import { useTheme, Box, Label, Flex, Text, Stack, useToast, Button, Tooltip, Inline, TextInput, Dialog, ToastProvider, Card } from "@sanity/ui";
4
- import { useMachine } from "@xstate/react";
4
+ import { useMachine, useActor } from "@xstate/react";
5
5
  import { useQuery, QueryClient, QueryClientProvider } from "@tanstack/react-query";
6
- import { Machine, assign } from "xstate";
7
- import { useRef, useMemo, useEffect, forwardRef } from "react";
6
+ import { setup, fromPromise, assign, assertEvent, toPromise } from "xstate";
7
+ import { useRef, useEffect, forwardRef } from "react";
8
8
  import useDeepCompareEffect from "use-deep-compare-effect";
9
9
  import hash from "object-hash";
10
- import fetch from "unfetch";
11
10
  import ReactTimeAgo from "react-time-ago";
12
11
  import { yupResolver } from "@hookform/resolvers/yup";
13
- import { uuid } from "@sanity/uuid";
14
12
  import { useForm } from "react-hook-form";
15
13
  import * as yup from "yup";
14
+ import { uuid } from "@sanity/uuid";
16
15
  import { styled } from "styled-components";
17
16
  import { useClient } from "sanity";
18
17
  import TimeAgo from "javascript-time-ago";
@@ -23,77 +22,99 @@ const API_ENDPOINT_DEPLOYMENTS = "https://api.vercel.com/v5/now/deployments", AP
23
22
  ERROR: "#ff0000",
24
23
  READY: "#50e3c2",
25
24
  QUEUED: "#333"
26
- }, WIDGET_NAME = "Vercel (dashboard)", Z_INDEX_DIALOG = 600001, Z_INDEX_TOAST_PROVIDER = 600002, StateDebug = (props) => null, sortByTargetName = (items) => items.sort((a, b) => a.name > b.name ? 1 : a.name < b.name ? -1 : 0), deploymentTargetListMachine = () => Machine(
27
- {
28
- context: {
29
- message: "",
30
- results: []
25
+ }, WIDGET_NAME = "Vercel (dashboard)", Z_INDEX_DIALOG = 600001, Z_INDEX_TOAST_PROVIDER = 600002, StateDebug = (props) => null, sortByTargetName = (items) => items.sort((a, b) => a.name > b.name ? 1 : a.name < b.name ? -1 : 0), deploymentTargetListMachine = setup({
26
+ types: {},
27
+ actions: {
28
+ targetCreate: assign({
29
+ results: ({ context, event }) => (assertEvent(event, "CREATE"), sortByTargetName([...context.results, event.deploymentTarget]))
30
+ }),
31
+ targetDelete: assign({
32
+ results: ({ context, event }) => (assertEvent(event, "DELETE"), context.results.filter((target) => target._id !== event.id))
33
+ }),
34
+ targetUpdate: assign({
35
+ results: ({ context, event }) => {
36
+ assertEvent(event, "UPDATE");
37
+ const { deploymentTarget } = event, index = context.results.findIndex((target) => target._id === deploymentTarget._id), updatedResults = Object.assign([], context.results, {
38
+ [index]: deploymentTarget
39
+ });
40
+ return sortByTargetName(updatedResults);
41
+ }
42
+ })
43
+ },
44
+ guards: {
45
+ hasData: ({ context }) => context?.results?.length > 0,
46
+ hasNoData: ({ context }) => context?.results?.length === 0
47
+ },
48
+ actors: {
49
+ "fetch data": fromPromise(
50
+ ({ input, signal }) => input.client.fetch(
51
+ "*[_type == $type] | order(name asc)",
52
+ {
53
+ type: DEPLOYMENT_TARGET_DOCUMENT_TYPE
54
+ },
55
+ { signal }
56
+ ).catch((error) => {
57
+ if (error instanceof Error && error.name === "AbortError")
58
+ return [];
59
+ throw console.error("Failed to fetch deployment targets", error), error;
60
+ })
61
+ )
62
+ }
63
+ }).createMachine({
64
+ /** @xstate-layout N4IgpgJg5mDOIC5QAoC2BDAxgCwJYDswBKAOgAcx8ICoBiCAe0JIIDcGBrMEgMzABccAEXT90AbQAMAXUSgyDWLn64mckAA9EAZkkBOEgHYAjAA5DAFgBsFgEwnJAVkMAaEAE9Ep4yUeT-klbGesbaoYaGAL6RbmhYeISkFFQ0tGAATukM6eQANqI82ai8AsKiEjLqCkoqakiaOvpGZpY29sZOrh6IxpYkFo5h2oaOpnqOxraSFtGxGDgExCTpYOgQ7rQAwgBKAKIAggAqu1Ky9dXKqvjqWggWHSS9eoaS9ibao6aObp4IVh8kL56OzGII2PT-WYgOILRLLVbrWhCXYAGV2x1OVUUlzqoFu90kRm8tlM2gsL1eJJ+iEGBj0gVsFm0YWmVkctihMISSxWaw2AFUAApCI4nSrnbG1a71fGSUz9WzBezTFWvb7dO5MkjjMITZykwxjTnzbmkXnrEgAV3wHHwDAA7vhaJiJTUrjces9fFZGc9TLYrGqA9SEM9CcT7sznH5HHpjfFFmaEe4rTa7Y7ncYzvJJe6ZZ7DN7fYaA0GrCHvD4xs4S+yPnGYtCTYn4XySPblNgRGJneKc27cQ0EI4BiQ2T77noAzXyxrTIESGFGd4rP9DONTPHYTzk+3OwxLfxu+he9mQBcpR7h6Px4ylWyIrPfl9bIvJhZJIYA-7zFZoo27QgOB1C5RMsQHaU8UQABaYIQ2gv9G1AuFkmofAoHAnFIKHOwQz0bRtUMcd-j8WwpnuLdTVbdZMMvfMEFsPQQxMeViQmZkLC+f0oiQ5s4XNFNrVtB1sIvPMoIQCIK1BIsmXXWxtFJcZKJbAS934Ltylo8ShysfDHl9PRxjlekrC6Z9BhIBk5MkXpzFBFT+N3DsNIPI8tNdLCr20L0Wmscw5V0e5pMJYwBiI8kwrDRC5gTOEeHQXBckgbTB1uZwQw6RwrEBd9bEcQZYzsRDoiAA */
65
+ context: ({ input }) => ({
66
+ client: input.client,
67
+ results: []
68
+ }),
69
+ initial: "pending",
70
+ states: {
71
+ pending: {
72
+ invoke: {
73
+ src: "fetch data",
74
+ id: "fetchData",
75
+ input: ({ context }) => ({ client: context.client }),
76
+ onDone: {
77
+ actions: assign({ results: ({ event }) => event.output }),
78
+ target: "ready"
79
+ },
80
+ onError: {
81
+ target: "failed"
82
+ }
83
+ }
31
84
  },
32
- initial: "pending",
33
- states: {
34
- pending: {
35
- invoke: {
36
- src: "fetchDataService",
37
- onDone: { actions: ["setResults"], target: "ready" },
38
- onError: { actions: ["setMessage"], target: "failed" }
85
+ ready: {
86
+ initial: "unknown",
87
+ on: {
88
+ CREATE: {
89
+ actions: "targetCreate"
90
+ },
91
+ DELETE: {
92
+ actions: "targetDelete"
93
+ },
94
+ UPDATE: {
95
+ actions: "targetUpdate"
39
96
  }
40
97
  },
41
- ready: {
42
- initial: "unknown",
43
- on: {
44
- CREATE: { actions: ["targetCreate"] },
45
- DELETE: { actions: ["targetDelete"] },
46
- UPDATE: { actions: ["targetUpdate"] }
98
+ states: {
99
+ unknown: {
100
+ always: [
101
+ { target: "withData", guard: "hasData" },
102
+ { target: "withoutData", guard: "hasNoData" }
103
+ ]
47
104
  },
48
- states: {
49
- unknown: {
50
- always: [
51
- { cond: "hasData", target: "withData" },
52
- { cond: "hasNoData", target: "withoutData" }
53
- ]
54
- },
55
- withData: {
56
- always: [{ cond: "hasNoData", target: "withoutData" }]
57
- },
58
- withoutData: {
59
- always: [{ cond: "hasData", target: "withData" }]
60
- }
105
+ withData: {
106
+ always: [{ target: "withoutData", guard: "hasNoData" }]
107
+ },
108
+ withoutData: {
109
+ always: [{ target: "withData", guard: "hasData" }]
61
110
  }
62
- },
63
- failed: {
64
- type: "final"
65
111
  }
66
- }
67
- },
68
- {
69
- actions: {
70
- setMessage: assign((_context, event) => ({
71
- message: event.data.details.description
72
- })),
73
- setResults: assign((_context, event) => ({
74
- results: event.data
75
- })),
76
- targetCreate: assign((context, event) => ({
77
- results: sortByTargetName([...context.results, event.deploymentTarget])
78
- })),
79
- targetDelete: assign((context, event) => ({
80
- results: context.results.filter((target) => target._id !== event.id)
81
- })),
82
- targetUpdate: assign((context, event) => {
83
- const { deploymentTarget } = event, index = context.results.findIndex((target) => target._id === deploymentTarget._id), updatedResults = Object.assign([], context.results, {
84
- [index]: event.deploymentTarget
85
- });
86
- return {
87
- results: sortByTargetName(updatedResults)
88
- };
89
- })
90
112
  },
91
- guards: {
92
- hasData: (context) => context?.results?.length > 0,
93
- hasNoData: (context) => context?.results?.length === 0
113
+ failed: {
114
+ type: "final"
94
115
  }
95
116
  }
96
- ), fetcher = (deploymentTarget) => async (url, extraParams) => {
117
+ }), fetcher = (deploymentTarget) => async (url, extraParams) => {
97
118
  const params = new URLSearchParams();
98
119
  if (params.set("projectId", deploymentTarget.projectId), deploymentTarget.teamId && params.set("teamId", deploymentTarget.teamId), extraParams)
99
120
  for (const [k, v] of extraParams.entries())
@@ -160,28 +181,43 @@ const API_ENDPOINT_DEPLOYMENTS = "https://api.vercel.com/v5/now/deployments", AP
160
181
  isSuccess: aliasesIsSuccess && deploymentsIsSuccess,
161
182
  refetch
162
183
  };
163
- }, refreshMachine = Machine({
184
+ }, refreshMachine = setup({
185
+ types: {
186
+ events: {}
187
+ }
188
+ }).createMachine({
189
+ /** @xstate-layout N4IgpgJg5mDOIC5QAoC2BDAxgCwJYDswBKAOlwgBswBiAJQFEAxBgZQAkBtABgF1FQADgHtYuAC64h+fiAAeiAIwAmAGwkuGrkoAsAZhVKlAVm0KAHABoQAT0QBOJSRN27XFXaMmz2twF9fVmhYeISkAE5gAGYRsCFQ1PS0tADytNx8SCDCohJSMvIIPnYkxhpKXGZ22kY6xla2CAq6CiQudgDsRnYqKroVfe3+gRg4BMQkEdFwcXRMrGz0ACLpMtniktKZBUUlRmUVVTXadTaISrqObUY97QodvWa6QyBBo6ETUTHYkLPM9OwrTJrXKbUDbJTFLjtMzmWraOx3doqeqKMyOeHdXp3BTHXTVZ6vELjMBhMJCMK-eaAwQidZ5LaIY6Q6Gw47wxHI04IGEkDFma5NbTtY7ufwBED4IQQOAyQljIirWkg-KIAC0nIa6oJIyJpHIVEVOQ2KsKShRCDsunUGLcHi8PhU2uC8o+U1iBCghrpoLkZ2uTk0XCq7SRRl0Zg19itXHhIZ85lMEaUTre40mX0gXuVDIQnmKRhZKk6PmaVXN2PUaLsZhj2hUOJU-JTupIJLJYSzxpzeacheLXFL2nNrkrfW8SKFnhDYt8QA */
164
190
  initial: "idle",
165
191
  states: {
166
192
  idle: {
167
193
  on: {
168
- REFRESH: "refreshing"
194
+ REFRESH: {
195
+ target: "refreshing"
196
+ }
169
197
  }
170
198
  },
171
199
  refreshing: {
172
200
  on: {
173
- ERROR: "error",
174
- REFRESHED: "refreshed"
201
+ ERROR: {
202
+ target: "error"
203
+ },
204
+ REFRESHED: {
205
+ target: "refreshed"
206
+ }
175
207
  }
176
208
  },
177
209
  refreshed: {
178
210
  on: {
179
- REFRESH: "refreshing"
211
+ REFRESH: {
212
+ target: "refreshing"
213
+ }
180
214
  }
181
215
  },
182
216
  error: {
183
217
  on: {
184
- REFRESH: "refreshing"
218
+ REFRESH: {
219
+ target: "refreshing"
220
+ }
185
221
  }
186
222
  }
187
223
  }
@@ -302,88 +338,98 @@ const TableCell = (props) => {
302
338
  }
303
339
  ) }) })
304
340
  ] });
305
- }, deployMachine = (deployHook) => Machine(
306
- // Machine
307
- {
308
- id: "deploy",
309
- initial: "idle",
310
- context: {
311
- disabled: !1,
312
- feedback: void 0,
313
- label: void 0,
314
- error: void 0
315
- },
316
- states: {
317
- idle: {
318
- entry: assign({
319
- feedback: () => {
320
- },
321
- label: () => "Deploy"
322
- }),
323
- on: {
324
- DEPLOY: "deploying"
341
+ }, deployMachine = setup({
342
+ types: {
343
+ context: {},
344
+ events: {},
345
+ input: {}
346
+ },
347
+ actors: {
348
+ deploy: fromPromise(async ({ input, signal }) => {
349
+ try {
350
+ if (!input.deployHook)
351
+ throw new Error("No deployHook URL defined");
352
+ const res = await fetch(input.deployHook, { method: "POST", signal }), data = await res.json();
353
+ if (!res.ok)
354
+ throw (data?.error).message || res.statusText;
355
+ } catch (err) {
356
+ throw typeof err == "string" ? err : (console.error("Unable to deploy with error:", err), new Error("Please check the developer console for more information"));
357
+ }
358
+ })
359
+ }
360
+ }).createMachine({
361
+ /** @xstate-layout N4IgpgJg5mDOIC5QTABwDYHsCeA6AlhOmAMQAiAogAoAyA8gJoDaADALqKiqaz4Au+TADtOIAB6IATCxa4AnADYAHAHYArArUslAZjksNAGhDZEARk3yVmhSxVyHC-QBYAvq+MoMOXF6zZ8ISgSCGEwAiEAN0wAa3C-HwSAoIRA6IBjAEMBYVY2PNFuXhyRJHFENTMzXElFJSUzNTVnWx0FY1MESXVcZzUdM2k1OTUVBoV3TzR-X2mcQOCwACclzCXcDGyAMzWAW1nvPCSF1KjMLJK8grKi-kFS0AkESura5QamlpY2jvMB+QcDkqLH0wxYEw8ICSuFgAFd0uk4LByNR6Mx2IUeHdhKIns1ZN9BtYQVpRnJfl1JM55P1BnY1Ep9CpGpMoXM8MtVksUbRGNcuFiSriKs4CQNurYRgZ7BSGr1ASNupIzEo+kp3JChJgUPAyklMcV7sKEABadomRAmtQAhW2wE6VnQwjEA3Yh7lBDOSQUsxeqyaPoWYbWFSO9kHfwLV1CspPHSSHQ1ZyA1UKJzJlQ+iz+5oKewKWrfNyQ6FwhFI6NG2OINOSXDiypKAxtMyZi1dEE1Qk6L0FpTSUMl8OctaVnHVhC1+uDRvNhStin6XDaHQ9liSXTJiUa1xAA */
362
+ id: "deploy",
363
+ initial: "idle",
364
+ context: ({ input }) => ({
365
+ disabled: !1,
366
+ feedback: void 0,
367
+ label: void 0,
368
+ error: void 0,
369
+ deployHook: input.deployHook
370
+ }),
371
+ states: {
372
+ idle: {
373
+ entry: assign({
374
+ feedback: () => {
375
+ },
376
+ label: () => "Deploy"
377
+ }),
378
+ on: {
379
+ DEPLOY: {
380
+ target: "deploying"
325
381
  }
326
- },
327
- deploying: {
328
- entry: assign({
329
- disabled: () => !0,
330
- label: () => "Deploying"
331
- }),
332
- exit: assign({
333
- disabled: () => !1,
334
- label: () => "Deploy"
335
- }),
336
- invoke: {
337
- onDone: {
338
- target: "success"
339
- },
340
- onError: {
341
- target: "error",
342
- actions: assign({
343
- error: (_context, event) => event.data
344
- })
345
- },
346
- src: "deploy"
382
+ }
383
+ },
384
+ deploying: {
385
+ entry: assign({
386
+ disabled: () => !0,
387
+ label: () => "Deploying"
388
+ }),
389
+ exit: assign({
390
+ disabled: () => !1,
391
+ label: () => "Deploy"
392
+ }),
393
+ invoke: {
394
+ src: "deploy",
395
+ input: ({ context }) => ({ deployHook: context.deployHook }),
396
+ onDone: {
397
+ target: "success"
398
+ },
399
+ onError: {
400
+ target: "error",
401
+ actions: assign({
402
+ error: ({ event }) => "error" in event ? event.error : "Unknown error"
403
+ })
347
404
  }
348
- },
349
- success: {
350
- entry: [assign({ feedback: () => "Succesfully started!" })],
351
- exit: assign({
352
- feedback: () => {
353
- }
354
- }),
355
- on: {
356
- DEPLOY: "deploying"
405
+ }
406
+ },
407
+ success: {
408
+ entry: assign({
409
+ feedback: () => "Successfully started!"
410
+ }),
411
+ exit: assign({
412
+ feedback: () => {
357
413
  }
358
- },
359
- error: {
360
- on: {
361
- DEPLOY: "deploying"
414
+ }),
415
+ on: {
416
+ DEPLOY: {
417
+ target: "deploying"
362
418
  }
363
419
  }
364
- }
365
- },
366
- // Config
367
- {
368
- services: {
369
- deploy: () => new Promise(async (resolve, reject) => {
370
- try {
371
- if (!deployHook)
372
- return reject(new Error("No deployHook URL defined"));
373
- const res = await fetch(deployHook, { method: "POST" }), data = await res.json();
374
- if (!res.ok) {
375
- const errorMessage = (data?.error).message || res.statusText;
376
- return reject(errorMessage);
377
- }
378
- return resolve();
379
- } catch (err) {
380
- return console.error("Unable to deploy with error:", err), reject(new Error("Please check the developer console for more information"));
420
+ },
421
+ error: {
422
+ on: {
423
+ DEPLOY: {
424
+ target: "deploying"
381
425
  }
382
- })
426
+ }
383
427
  }
384
428
  }
385
- ), DeployButton = (props) => {
386
- const { deployHook, onDeploySuccess, targetName } = props, machine = useMemo(() => deployMachine(deployHook), [deployHook]), [deployState, deployStateTransition, deployStateInterpreter] = useMachine(machine), toast = useToast(), isError = deployState.matches("error"), isSuccess = deployState.matches("success"), handleDeploy = () => {
429
+ }), DeployButton = (props) => {
430
+ const { deployHook, onDeploySuccess, targetName } = props, [deployState, deployStateTransition, deployStateInterpreter] = useMachine(deployMachine, {
431
+ input: { deployHook }
432
+ }), toast = useToast(), isError = deployState.matches("error"), isSuccess = deployState.matches("success"), handleDeploy = () => {
387
433
  deployStateTransition({ type: "DEPLOY" });
388
434
  };
389
435
  return useEffect(() => {
@@ -401,9 +447,10 @@ const TableCell = (props) => {
401
447
  title: WIDGET_NAME
402
448
  });
403
449
  }, [isError, isSuccess, toast, targetName, deployState.context.error]), useEffect(() => {
404
- deployStateInterpreter.onTransition((state) => {
450
+ const subscription = deployStateInterpreter.subscribe((state) => {
405
451
  state.value === "success" && onDeploySuccess && onDeploySuccess();
406
452
  });
453
+ return () => subscription.unsubscribe();
407
454
  }, [deployStateInterpreter, onDeploySuccess]), /* @__PURE__ */ jsxs(Box, { padding: 3, style: { position: "relative" }, children: [
408
455
  /* @__PURE__ */ jsx(StateDebug, { name: "Deploy", state: deployState }),
409
456
  /* @__PURE__ */ jsx(
@@ -548,88 +595,100 @@ const TableCell = (props) => {
548
595
  }, DeploymentTargets = (props) => {
549
596
  const { items, onDialogEdit } = props;
550
597
  return /* @__PURE__ */ jsx(Stack, { space: 5, children: items?.map((item) => /* @__PURE__ */ jsx(DeploymentTarget, { item, onDialogEdit }, item._id)) });
551
- }, formMachine = Machine(
552
- {
553
- context: {
554
- formData: {},
555
- message: ""
556
- },
557
- initial: "idle",
558
- states: {
559
- idle: {
560
- on: {
561
- CREATE: {
562
- actions: ["createDocument"],
563
- target: "creating"
564
- },
565
- DELETE: {
566
- actions: ["deleteDocument"],
567
- target: "deleting"
568
- },
569
- UPDATE: {
570
- actions: ["updateDocument"],
571
- target: "updating"
572
- }
573
- }
574
- },
575
- creating: {
576
- invoke: {
577
- src: "createDocumentService",
578
- onDone: { target: "success" },
579
- onError: { actions: ["setMessage"], target: "error" }
580
- },
581
- on: {
582
- RESOLVE: "success",
583
- REJECT: "error"
584
- }
585
- },
586
- updating: {
587
- invoke: {
588
- src: "updateDocumentService",
589
- onDone: { target: "success" },
590
- onError: { actions: ["setMessage"], target: "error" }
598
+ }, formMachine = setup({
599
+ types: {},
600
+ actions: {
601
+ setId: assign({
602
+ id: ({ event }) => (assertEvent(event, ["UPDATE", "DELETE"]), event.id)
603
+ }),
604
+ setFormData: assign({
605
+ formData: ({ event }) => (assertEvent(event, ["CREATE", "UPDATE"]), event.formData)
606
+ }),
607
+ setMessage: assign({
608
+ message: ({ event }) => "data" in event && event.data && typeof event.data == "object" && "details" in event.data && event.data.details && typeof event.data.details == "object" && "description" in event.data.details ? event.data.details.description : "An error occurred"
609
+ }),
610
+ setDocument: assign({
611
+ document: ({ event }) => event.output
612
+ })
613
+ },
614
+ actors: {
615
+ "create document": fromPromise(
616
+ ({ input }) => input.client.create({
617
+ _id: `vercel.${uuid()}`,
618
+ _type: DEPLOYMENT_TARGET_DOCUMENT_TYPE,
619
+ ...input.formData
620
+ })
621
+ ),
622
+ "update document": fromPromise(
623
+ ({ input }) => input.client.patch(input.id).set(input.formData).commit()
624
+ ),
625
+ "delete document": fromPromise(({ input }) => input.client.delete(input.id))
626
+ }
627
+ }).createMachine({
628
+ /** @xstate-layout N4IgpgJg5mDOIC5QAoC2BDAxgCwJYDswBKAOlwgBswBiAYQCUBRAQQBVGBtABgF1FQADgHtYuAC64h+fiAAeiAIwBmAGwkuGjQFYALAE4AHACYdWgwYA0IAJ6IjKgOwkdXFUYVa9h-Ua5KAvv5WaFh4hKTkVNQAqgAKACJsnLwywqISUjLyCMpqmtr6xqbmVrYIBgokWvlGWkpaCgZeKoHBGDgExGSUNPGMADKM7Nx8SCBp4pLSY9m56vm6hiZmljaIOipqdXpcDk1aWiYqBlqtICEd4SSYAE5g6BL4UNQQUmBk+ABuQgDW77f3MRgeJCTAAV1QYHwYmYmDEQhuI1SIkmmRmiGOShIDiUOh0SiaCgUegcDj0pTsjhI5iMewUpPsTSMZwuYS6AIeBGeYBuNwRJAEFAeADMEahrncHsDQRCoTC4QikWMJhlpqBspjsbj8YTiaTyWsEKouNT6noiX5zUpiQEgud2mzSGCBBBOU8Xm8Pt8-iRna6gSDwZDobD4YiUsqUaqshiDFicXiCea9WSKeVKiSVIclEYlIY-BUWQ7Ok6XW7ubz+YKRWLfWWAzLg-Kw0rBFGpjGEJqEzrkyTU4b6ToSHojHos7VXEc6kXQiWSBAwFRHs9XoQvb93ovl9Kg3LQ4qI230h30V241rE7r+wayro1A4dO4VHotA5fPTTnbWfPt2AV9QPJ8jcApCmIoo3OKf4NnuIYKuGozHqiapyLG8bakmRI3mmpjxk0XAuEoXAHI+DgtGc+BCIu8BjD+4TIieaLqogAC0Khpmxs6XF0kRgAxyGdk+aYKLSVR7Fweg6A4IkGFwChcY6EqAly-HRmeY7DnSY5GHGL4qFwRhpjpJpmriDjVMRLgGAp84ckCECqaezEIHoObUuZuwKH4xGPgoRnmCQpmOAcqhmPJ37Flcfrlo5TGoQgY4mgYHkeAS+iqH5hqSc4dSuCo+I6SoSjvjZUX1pAsUodkrlGO51TSd5b46JlZRebVuG7IcjRmA05FtHOVzQSpkaMVVdivs4CibHGxg6biSg4ZsJD2AccaFEVGwOKVXTQRVI0CWeNV1Z5jW+WmujDj4HjmMRnhEttpBAQilWdkdyX1V5RFNS1iAEpU1pHER9JWjogSBEAA */
629
+ context: ({ input }) => ({
630
+ client: input.client,
631
+ formData: {},
632
+ message: ""
633
+ }),
634
+ initial: "idle",
635
+ states: {
636
+ idle: {
637
+ on: {
638
+ CREATE: {
639
+ actions: ["setFormData"],
640
+ target: "creating"
591
641
  },
592
- on: {
593
- RESOLVE: "success",
594
- REJECT: "error"
595
- }
596
- },
597
- deleting: {
598
- invoke: {
599
- src: "deleteDocumentService",
600
- onDone: { target: "success" },
601
- onError: { actions: ["setMessage"], target: "error" }
642
+ UPDATE: {
643
+ actions: ["setId", "setFormData"],
644
+ target: "updating"
602
645
  },
603
- on: {
604
- RESOLVE: "success",
605
- REJECT: "error"
606
- }
607
- },
608
- success: {
609
- invoke: {
610
- src: "formSubmittedService"
646
+ DELETE: {
647
+ actions: "setId",
648
+ target: "deleting"
611
649
  }
612
- },
613
- error: {}
614
- }
615
- },
616
- {
617
- actions: {
618
- setMessage: assign((_context, event) => ({
619
- message: event.data.details.description
620
- })),
621
- createDocument: assign((_context, event) => ({
622
- formData: event.formData
623
- })),
624
- deleteDocument: assign(() => ({
625
- // id: event.id,
626
- })),
627
- updateDocument: assign((_context, event) => ({
628
- formData: event.formData
629
- }))
630
- }
650
+ }
651
+ },
652
+ creating: {
653
+ tags: ["busy"],
654
+ invoke: {
655
+ src: "create document",
656
+ id: "createDocumentActor",
657
+ input: ({ context }) => ({ client: context.client, formData: context.formData }),
658
+ onDone: { actions: "setDocument", target: "created" },
659
+ onError: { actions: "setMessage", target: "error" }
660
+ }
661
+ },
662
+ created: { type: "final" },
663
+ updating: {
664
+ tags: ["busy"],
665
+ invoke: {
666
+ src: "update document",
667
+ id: "updateDocumentActor",
668
+ input: ({ context }) => ({
669
+ client: context.client,
670
+ id: context.id,
671
+ formData: context.formData
672
+ }),
673
+ onDone: { actions: "setDocument", target: "updated" },
674
+ onError: { actions: "setMessage", target: "error" }
675
+ }
676
+ },
677
+ updated: { type: "final" },
678
+ deleting: {
679
+ tags: ["busy"],
680
+ invoke: {
681
+ src: "delete document",
682
+ id: "deleteDocumentActor",
683
+ input: ({ context }) => ({ client: context.client, id: context.id }),
684
+ onDone: { target: "deleted" },
685
+ onError: { actions: "setMessage", target: "error" }
686
+ }
687
+ },
688
+ deleted: { type: "final" },
689
+ error: { type: "final" }
631
690
  }
632
- ), sanitizeFormData = (formData) => Object.keys(formData).reduce((acc, key) => {
691
+ }), sanitizeFormData = (formData) => Object.keys(formData).reduce((acc, key) => {
633
692
  const val = formData[key];
634
693
  return typeof val == "object" && val !== null && val.constructor !== Array ? acc[key] = sanitizeFormData(val) : val === "" || typeof val > "u" || val?.length === 0 ? acc[key] = null : typeof val == "string" && val ? acc[key] = formData[key].trim() : acc[key] = formData[key], acc;
635
694
  }, {}), StyledErrorOutlineIcon = styled(ErrorOutlineIcon)(({ theme }) => ({
@@ -656,7 +715,7 @@ const TableCell = (props) => {
656
715
  description && /* @__PURE__ */ jsx(Box, { marginY: 3, children: /* @__PURE__ */ jsx(Text, { htmlFor: name, muted: !0, size: 1, children: description }) })
657
716
  ] });
658
717
  }, FormFieldInputText = forwardRef((props, ref) => {
659
- const { description, disabled, error, label, name, placeholder, value } = props;
718
+ const { description, disabled, error, label, name, placeholder, value, onChange, onBlur } = props;
660
719
  return /* @__PURE__ */ jsxs(Box, { children: [
661
720
  /* @__PURE__ */ jsx(FormFieldInputLabel, { description, error, label, name }),
662
721
  /* @__PURE__ */ jsx(
@@ -669,6 +728,8 @@ const TableCell = (props) => {
669
728
  id: name,
670
729
  name,
671
730
  placeholder,
731
+ onChange,
732
+ onBlur,
672
733
  ref
673
734
  }
674
735
  )
@@ -685,77 +746,48 @@ const formSchema = yup.object().shape({
685
746
  teamId: yup.string(),
686
747
  token: yup.string().required("Vercel Account Token cannot be empty")
687
748
  }), DialogForm = (props) => {
688
- const { deploymentTarget, onClose, onCreate, onDelete, onUpdate } = props, client = useSanityClient(), [formState, formStateTransition] = useMachine(formMachine, {
689
- services: {
690
- formSubmittedService: async () => {
691
- onClose();
692
- },
693
- // TODO: refactor
694
- createDocumentService: async (_context, event) => {
695
- let document;
696
- try {
697
- return document = await client.create({
698
- _id: `vercel.${uuid()}`,
699
- _type: DEPLOYMENT_TARGET_DOCUMENT_TYPE,
700
- ...event.formData
701
- }), onCreate && onCreate(document), Promise.resolve();
702
- } catch (e) {
703
- return Promise.reject(e);
704
- }
705
- },
706
- // TODO: refactor
707
- deleteDocumentService: async () => {
708
- if (deploymentTarget)
709
- try {
710
- return await client.delete(deploymentTarget._id), onDelete && onDelete(deploymentTarget._id), Promise.resolve();
711
- } catch (e) {
712
- return Promise.reject(e);
713
- }
714
- return Promise.resolve();
715
- },
716
- // TODO: refactor
717
- updateDocumentService: async (_context, event) => {
718
- let document;
719
- if (deploymentTarget)
720
- try {
721
- return document = await client.patch(deploymentTarget._id).set(event.formData).commit(), onUpdate && onUpdate(document), Promise.resolve();
722
- } catch (e) {
723
- return Promise.reject(e);
724
- }
725
- return Promise.resolve();
726
- }
727
- }
728
- }), formUpdating = formState.matches("creating") || formState.matches("deleting") || formState.matches("updating"), {
729
- // Read the formState before render to subscribe the form state through Proxy
749
+ const { deploymentTarget, onClose, onCreate, onDelete, onUpdate } = props, client = useSanityClient(), toast = useToast(), [formState, formStateTransition, formStateActorRef] = useActor(formMachine, {
750
+ input: { client }
751
+ }), formUpdating = formState.hasTag("busy"), {
730
752
  formState: { errors, isDirty, isValid },
731
753
  handleSubmit,
732
754
  register
733
755
  } = useForm({
756
+ // @ts-expect-error - fix typings later
734
757
  defaultValues: {
735
758
  deployHook: deploymentTarget?.deployHook || "",
736
759
  deployLimit: deploymentTarget?.deployLimit || 5,
737
- name: deploymentTarget?.name,
738
- projectId: deploymentTarget?.projectId,
760
+ name: deploymentTarget?.name || "",
761
+ projectId: deploymentTarget?.projectId || "",
739
762
  teamId: deploymentTarget?.teamId || "",
740
- token: deploymentTarget?.token
763
+ token: deploymentTarget?.token || ""
741
764
  },
742
765
  mode: "onChange",
743
766
  resolver: yupResolver(formSchema)
744
- }), onSubmit = async (formData) => {
767
+ });
768
+ useEffect(() => {
769
+ formState.matches("error") && toast.push({
770
+ status: "error",
771
+ title: formState.context.message || "An error occurred"
772
+ }), formState.status === "done" && onClose();
773
+ }, [formState, onClose, toast]);
774
+ const onSubmit = async (formData) => {
745
775
  const sanitizedFormData = sanitizeFormData(formData);
746
- await formStateTransition(deploymentTarget ? "UPDATE" : "CREATE", {
747
- formData: sanitizedFormData
748
- });
749
- }, handleDelete = () => {
750
- formStateTransition("DELETE", { id: deploymentTarget?._id });
776
+ formStateTransition(deploymentTarget ? { type: "UPDATE", id: deploymentTarget._id, formData: sanitizedFormData } : { type: "CREATE", formData: sanitizedFormData }), await toPromise(formStateActorRef);
777
+ const snapshot = formStateActorRef.getSnapshot(), { document } = snapshot.context;
778
+ document && (snapshot.matches("created") ? onCreate?.(document) : snapshot.matches("updated") && onUpdate?.(document));
779
+ }, handleDelete = async () => {
780
+ const id = deploymentTarget._id;
781
+ formStateTransition({ type: "DELETE", id }), await toPromise(formStateActorRef), formStateActorRef.getSnapshot().matches("deleted") && onDelete?.(id);
751
782
  };
752
783
  return /* @__PURE__ */ jsx(
753
784
  Dialog,
754
785
  {
755
- footer: /* @__PURE__ */ jsx(() => /* @__PURE__ */ jsx(Box, { padding: 3, children: /* @__PURE__ */ jsxs(Flex, { justify: deploymentTarget ? "space-between" : "flex-end", children: [
786
+ footer: /* @__PURE__ */ jsx(Box, { padding: 3, children: /* @__PURE__ */ jsxs(Flex, { justify: deploymentTarget ? "space-between" : "flex-end", children: [
756
787
  deploymentTarget && /* @__PURE__ */ jsx(
757
788
  Button,
758
789
  {
790
+ loading: formState.matches("deleting"),
759
791
  disabled: formUpdating,
760
792
  fontSize: 1,
761
793
  mode: "bleed",
@@ -767,14 +799,15 @@ const formSchema = yup.object().shape({
767
799
  /* @__PURE__ */ jsx(
768
800
  Button,
769
801
  {
770
- disabled: formUpdating || !isDirty || !isValid,
802
+ loading: formState.matches("creating") || formState.matches("updating"),
803
+ disabled: !isDirty || !isValid,
771
804
  fontSize: 1,
772
805
  onClick: handleSubmit(onSubmit),
773
806
  text: deploymentTarget ? "Update and close" : "Create",
774
807
  tone: "primary"
775
808
  }
776
809
  )
777
- ] }) }), {}),
810
+ ] }) }),
778
811
  header: `${deploymentTarget ? "Edit" : "Create"} deployment target`,
779
812
  id: "create",
780
813
  onClose,
@@ -790,8 +823,7 @@ const formSchema = yup.object().shape({
790
823
  description: "Name displayed in this plugin (e.g. production, staging)",
791
824
  error: errors?.name,
792
825
  label: "Name",
793
- name: "name",
794
- ref: register
826
+ ...register("name")
795
827
  }
796
828
  ),
797
829
  /* @__PURE__ */ jsx(
@@ -800,8 +832,7 @@ const formSchema = yup.object().shape({
800
832
  disabled: formUpdating,
801
833
  error: errors?.token,
802
834
  label: "Vercel Account Token",
803
- name: "token",
804
- ref: register
835
+ ...register("token")
805
836
  }
806
837
  ),
807
838
  /* @__PURE__ */ jsx(
@@ -810,8 +841,7 @@ const formSchema = yup.object().shape({
810
841
  disabled: formUpdating,
811
842
  error: errors?.projectId,
812
843
  label: "Vercel Project ID",
813
- name: "projectId",
814
- ref: register
844
+ ...register("projectId")
815
845
  }
816
846
  ),
817
847
  /* @__PURE__ */ jsx(
@@ -821,8 +851,7 @@ const formSchema = yup.object().shape({
821
851
  disabled: formUpdating,
822
852
  error: errors?.teamId,
823
853
  label: "Vercel Team ID (optional)",
824
- name: "teamId",
825
- ref: register
854
+ ...register("teamId")
826
855
  }
827
856
  ),
828
857
  /* @__PURE__ */ jsx(
@@ -832,8 +861,7 @@ const formSchema = yup.object().shape({
832
861
  disabled: formUpdating,
833
862
  error: errors?.deployHook,
834
863
  label: "Vercel Deploy Hook (optional)",
835
- name: "deployHook",
836
- ref: register
864
+ ...register("deployHook")
837
865
  }
838
866
  ),
839
867
  /* @__PURE__ */ jsx(
@@ -842,80 +870,83 @@ const formSchema = yup.object().shape({
842
870
  disabled: formUpdating,
843
871
  error: errors?.deployLimit,
844
872
  label: "Number of deploys to display",
845
- name: "deployLimit",
846
- ref: register({ valueAsNumber: !0 })
873
+ ...register("deployLimit", { valueAsNumber: !0 })
847
874
  }
848
875
  )
849
876
  ] })
850
877
  ] })
851
878
  }
852
879
  );
853
- }, dialogMachine = () => Machine(
854
- {
855
- context: {
856
- editDeploymentTarget: void 0
857
- },
858
- initial: "idle",
859
- states: {
860
- idle: {
861
- entry: assign({
862
- editDeploymentTarget: () => {
863
- }
864
- }),
865
- on: {
866
- CREATE: "create",
867
- EDIT: {
868
- actions: ["setEditDeploymentTarget"],
869
- target: "edit"
870
- }
880
+ }, dialogMachine = setup({
881
+ types: {
882
+ context: {},
883
+ events: {}
884
+ },
885
+ actions: {
886
+ setEditDeploymentTarget: assign({
887
+ editDeploymentTarget: ({ event }) => (assertEvent(event, "EDIT"), event.deploymentTarget)
888
+ })
889
+ }
890
+ }).createMachine({
891
+ /** @xstate-layout N4IgpgJg5mDOIC5QAoC2BDAxgCwJYDswBKAOlwgBswBiAYQCUBRAQQBVGBtABgF1FQADgHtYuAC64h+fiAAeiAEwKArCQCcANgAcAdmUbNOhVx0BGLQBoQAT0SmAzApJcXXexoAsW5fbWaFAL4BVmhYeISk5FTUjAAiAJKs3HxIIMKiElIy8ghKqpq6+obGZpY2ivb2zq4e5moeXKZc3kEhGDgExCSQ4nQAMgDyAMqcvDLp4pLSqTn2DSQefn7uyq5aWvZWtgjmTqsuvnU6XMoK9q0goR0RJJgATmDoYjS0gyPJ4yKTWTOIc1wLJZqFZrDZbRBaUwkfZuew6SFcepuILBED4IQQOAyK7hYifDJTbKIAC0GnBCFJFxxnUilDA+O+01AOQ8CnJGxIGn29lMpjUxhcCh0VPauNIPTEDMyTLkiA8PhIxh5Cg8DS8pgM5L5UOalSMah0cP05hFYRptweT3pqQm0qJCHlVSVphVashmvKCDUAN17j0XNMqrUyhRASAA */
892
+ context: {
893
+ editDeploymentTarget: void 0
894
+ },
895
+ initial: "idle",
896
+ states: {
897
+ idle: {
898
+ entry: assign({
899
+ editDeploymentTarget: () => {
871
900
  }
872
- },
873
- edit: {
874
- on: {
875
- CLOSE: "idle"
901
+ }),
902
+ on: {
903
+ CREATE: {
904
+ target: "create"
905
+ },
906
+ EDIT: {
907
+ actions: "setEditDeploymentTarget",
908
+ target: "edit"
876
909
  }
877
- },
878
- create: {
879
- on: {
880
- CLOSE: "idle"
910
+ }
911
+ },
912
+ edit: {
913
+ on: {
914
+ CLOSE: {
915
+ target: "idle"
916
+ }
917
+ }
918
+ },
919
+ create: {
920
+ on: {
921
+ CLOSE: {
922
+ target: "idle"
881
923
  }
882
924
  }
883
925
  }
884
- },
885
- {
886
- actions: {
887
- setEditDeploymentTarget: assign((_context, event) => ({
888
- editDeploymentTarget: event.deploymentTarget
889
- }))
926
+ }
927
+ }), queryClient = new QueryClient({
928
+ defaultOptions: {
929
+ queries: {
930
+ gcTime: 0,
931
+ staleTime: 0
890
932
  }
891
933
  }
892
- ), Widget = () => {
934
+ }), Widget = () => {
893
935
  const client = useSanityClient(), [deploymentTargetListState, deploymentTargetListStateTransition] = useMachine(
894
936
  deploymentTargetListMachine,
895
- {
896
- services: {
897
- fetchDataService: () => client.fetch(`*[_type == "${DEPLOYMENT_TARGET_DOCUMENT_TYPE}"] | order(name asc)`).then((result) => result)
898
- }
899
- }
900
- ), [dialogState, dialogStateTransition] = useMachine(dialogMachine), queryClient = new QueryClient({
901
- defaultOptions: {
902
- queries: {
903
- gcTime: 0,
904
- staleTime: 0
905
- }
906
- }
907
- }), handleDialogClose = () => {
908
- dialogStateTransition("CLOSE");
937
+ { input: { client } }
938
+ ), [dialogState, dialogStateTransition] = useMachine(dialogMachine), handleDialogClose = () => {
939
+ dialogStateTransition({ type: "CLOSE" });
909
940
  }, handleDialogShowCreate = () => {
910
- dialogStateTransition("CREATE");
941
+ dialogStateTransition({ type: "CREATE" });
911
942
  }, handleDialogShowEdit = (deploymentTarget) => {
912
- dialogStateTransition("EDIT", { deploymentTarget });
943
+ dialogStateTransition({ type: "EDIT", deploymentTarget });
913
944
  }, handleTargetCreate = (deploymentTarget) => {
914
- deploymentTargetListStateTransition("CREATE", { deploymentTarget });
945
+ deploymentTargetListStateTransition({ type: "CREATE", deploymentTarget });
915
946
  }, handleTargetDelete = (id) => {
916
- deploymentTargetListStateTransition("DELETE", { id });
947
+ deploymentTargetListStateTransition({ type: "DELETE", id });
917
948
  }, handleTargetUpdate = (deploymentTarget) => {
918
- deploymentTargetListStateTransition("UPDATE", { deploymentTarget });
949
+ deploymentTargetListStateTransition({ type: "UPDATE", deploymentTarget });
919
950
  };
920
951
  return /* @__PURE__ */ jsx(ToastProvider, { zOffset: Z_INDEX_TOAST_PROVIDER, children: /* @__PURE__ */ jsxs(QueryClientProvider, { client: queryClient, children: [
921
952
  /* @__PURE__ */ jsxs(Card, { radius: 2, style: { overflow: "hidden " }, children: [
@@ -933,12 +964,12 @@ const formSchema = yup.object().shape({
933
964
  ] }),
934
965
  /* @__PURE__ */ jsxs(Box, { children: [
935
966
  deploymentTargetListState.matches("pending") && /* @__PURE__ */ jsx(Box, { paddingX: 3, paddingY: 4, children: /* @__PURE__ */ jsx(Text, { children: "Loading..." }) }),
936
- deploymentTargetListState.matches("ready.withoutData") && /* @__PURE__ */ jsx(Box, { paddingX: 3, paddingY: 4, children: /* @__PURE__ */ jsxs(Text, { children: [
967
+ deploymentTargetListState.matches({ ready: "withoutData" }) && /* @__PURE__ */ jsx(Box, { paddingX: 3, paddingY: 4, children: /* @__PURE__ */ jsxs(Text, { children: [
937
968
  "No deployment targets found.",
938
969
  " ",
939
970
  /* @__PURE__ */ jsx("a", { onClick: handleDialogShowCreate, style: { cursor: "pointer" }, children: "Create a new target?" })
940
971
  ] }) }),
941
- deploymentTargetListState.matches("ready.withData") && /* @__PURE__ */ jsx(
972
+ deploymentTargetListState.matches({ ready: "withData" }) && /* @__PURE__ */ jsx(
942
973
  DeploymentTargets,
943
974
  {
944
975
  items: deploymentTargetListState.context.results,