@tinacms/app 1.2.26 → 1.2.27

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @tinacms/app
2
2
 
3
+ ## 1.2.27
4
+
5
+ ### Patch Changes
6
+
7
+ - 7e4de0b2a: Improvements to error handling with auth
8
+ - 1144af060: Improve error messaging when onPut / onDelete hooks throw errors
9
+ - Updated dependencies [7e4de0b2a]
10
+ - Updated dependencies [1144af060]
11
+ - tinacms@1.5.20
12
+ - @tinacms/mdx@1.3.18
13
+
3
14
  ## 1.2.26
4
15
 
5
16
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinacms/app",
3
- "version": "1.2.26",
3
+ "version": "1.2.27",
4
4
  "main": "src/main.tsx",
5
5
  "license": "Apache-2.0",
6
6
  "devDependencies": {
@@ -14,7 +14,7 @@
14
14
  "@headlessui/react": "1.6.6",
15
15
  "@heroicons/react": "1.0.6",
16
16
  "@monaco-editor/react": "4.4.5",
17
- "@tinacms/mdx": "1.3.17",
17
+ "@tinacms/mdx": "1.3.18",
18
18
  "@xstate/react": "3.0.0",
19
19
  "final-form": "4.20.7",
20
20
  "graphiql": "3.0.0-alpha.1",
@@ -25,7 +25,7 @@
25
25
  "react-dom": "17.0.2",
26
26
  "react-router-dom": "6.3.0",
27
27
  "tailwindcss": "^3.2.7",
28
- "tinacms": "1.5.19",
28
+ "tinacms": "1.5.20",
29
29
  "typescript": "^4.6.4",
30
30
  "zod": "^3.14.3"
31
31
  }
package/src/App.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, { Suspense } from 'react'
1
+ import React, { Suspense, useEffect } from 'react'
2
2
  import TinaCMS, { TinaAdmin, useCMS, MdxFieldPluginExtendible } from 'tinacms'
3
3
  import { TinaEditProvider, useEditState } from 'tinacms/dist/edit-state'
4
4
  import { Preview } from './preview'
@@ -78,7 +78,9 @@ export const TinaAdminWrapper = () => {
78
78
 
79
79
  const GoToEdit = () => {
80
80
  const { setEdit } = useEditState()
81
- setEdit(true)
81
+ useEffect(() => {
82
+ setEdit(true)
83
+ }, [])
82
84
  return <div>Going into edit mode</div>
83
85
  }
84
86
 
@@ -0,0 +1,24 @@
1
+ import React from 'react'
2
+ import { TinaCMS } from 'tinacms'
3
+
4
+ const ErrorModalContent = (props: { title: string; errors: string[] }) => {
5
+ const { title, errors } = props
6
+ return (
7
+ <>
8
+ <div>{title}</div>
9
+ <ul>
10
+ {errors.map((error, i) => (
11
+ <li key={i}>{error}</li>
12
+ ))}
13
+ </ul>
14
+ </>
15
+ )
16
+ }
17
+
18
+ export const showErrorModal = (
19
+ title: string,
20
+ errors: string[],
21
+ cms: TinaCMS
22
+ ) => {
23
+ cms.alerts.error(() => <ErrorModalContent title={title} errors={errors} />)
24
+ }
@@ -19,6 +19,7 @@ import {
19
19
  FormOptions,
20
20
  GlobalFormPlugin,
21
21
  TinaState,
22
+ ErrorDialog,
22
23
  } from 'tinacms'
23
24
  import { createForm, createGlobalForm, FormifyCallback } from './build-form'
24
25
  import type {
@@ -29,6 +30,7 @@ import type {
29
30
  } from './types'
30
31
  import { getFormAndFieldNameFromMetadata } from './util'
31
32
  import { useSearchParams } from 'react-router-dom'
33
+ import { showErrorModal } from './errors'
32
34
 
33
35
  const sysSchema = z.object({
34
36
  breadcrumbs: z.array(z.string()),
@@ -152,6 +154,14 @@ const astNodeWithMeta: G.DocumentNode = {
152
154
  const schema = G.buildASTSchema(astNode)
153
155
  const schemaForResolver = G.buildASTSchema(astNodeWithMeta)
154
156
 
157
+ const isRejected = (
158
+ input: PromiseSettledResult<unknown>
159
+ ): input is PromiseRejectedResult => input.status === 'rejected'
160
+
161
+ const isFulfilled = <T>(
162
+ input: PromiseSettledResult<T>
163
+ ): input is PromiseFulfilledResult<T> => input.status === 'fulfilled'
164
+
155
165
  export const useGraphQLReducer = (
156
166
  iframe: React.MutableRefObject<HTMLIFrameElement>,
157
167
  url: string
@@ -159,6 +169,7 @@ export const useGraphQLReducer = (
159
169
  const cms = useCMS()
160
170
  const tinaSchema = cms.api.tina.schema as TinaSchema
161
171
  const [payloads, setPayloads] = React.useState<Payload[]>([])
172
+ const [requestErrors, setRequestErrors] = React.useState<string[]>([])
162
173
  const [searchParams, setSearchParams] = useSearchParams()
163
174
  const [results, setResults] = React.useState<
164
175
  {
@@ -204,7 +215,9 @@ export const useGraphQLReducer = (
204
215
  */
205
216
  React.useEffect(() => {
206
217
  const run = async () => {
207
- return Promise.all(
218
+ setRequestErrors([])
219
+ // gather the errors and display an error message containing each error unique message
220
+ return Promise.allSettled(
208
221
  payloads.map(async (payload) => {
209
222
  // This payload has already been expanded, skip it.
210
223
  if (payload.expandedQuery) {
@@ -219,7 +232,10 @@ export const useGraphQLReducer = (
219
232
  }
220
233
  if (payloads.length) {
221
234
  run().then((updatedPayloads) => {
222
- setPayloads(updatedPayloads)
235
+ setPayloads(updatedPayloads.filter(isFulfilled).map((p) => p.value))
236
+ setRequestErrors(
237
+ updatedPayloads.filter(isRejected).map((p) => String(p.reason))
238
+ )
223
239
  })
224
240
  }
225
241
  }, [JSON.stringify(payloads), cms])
@@ -575,6 +591,12 @@ export const useGraphQLReducer = (
575
591
  cms.dispatch({ type: 'set-edit-mode', value: 'basic' })
576
592
  }
577
593
  }, [iframe.current, JSON.stringify(results)])
594
+
595
+ React.useEffect(() => {
596
+ if (requestErrors.length) {
597
+ showErrorModal('Unexpected error querying content', requestErrors, cms)
598
+ }
599
+ }, [requestErrors])
578
600
  }
579
601
 
580
602
  const onSubmit = async (
@@ -602,7 +624,13 @@ const onSubmit = async (
602
624
  })
603
625
  cms.alerts.success('Document saved!')
604
626
  } catch (e) {
605
- cms.alerts.error('There was a problem saving your document')
627
+ cms.alerts.error(() =>
628
+ ErrorDialog({
629
+ title: 'There was a problem saving your document',
630
+ message: 'Tina caught an error while updating the page',
631
+ error: e,
632
+ })
633
+ )
606
634
  console.error(e)
607
635
  }
608
636
  }
@@ -834,12 +862,15 @@ _internalSys: _sys {
834
862
  return response.node
835
863
  }
836
864
 
837
- const expandPayload = async (payload: Payload, cms: TinaCMS) => {
865
+ const expandPayload = async (
866
+ payload: Payload,
867
+ cms: TinaCMS
868
+ ): Promise<Payload> => {
838
869
  const { query, variables } = payload
839
870
  const documentNode = G.parse(query)
840
871
  const expandedDocumentNode = expandQuery({ schema, documentNode })
841
872
  const expandedQuery = G.print(expandedDocumentNode)
842
- const expandedData = await cms.api.tina.request(expandedQuery, {
873
+ const expandedData = await cms.api.tina.request<object>(expandedQuery, {
843
874
  variables,
844
875
  })
845
876