@tinacms/app 0.0.0-e70425b-20241028042614 → 0.0.0-ea204c9-20250318044256
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 +118 -10
- package/package.json +8 -8
- package/src/App.tsx +24 -24
- package/src/Playground.tsx +54 -54
- package/src/dummy-client.ts +1 -1
- package/src/fields/rich-text/index.tsx +2 -2
- package/src/fields/rich-text/monaco/error-message.tsx +54 -54
- package/src/fields/rich-text/monaco/index.tsx +56 -56
- package/src/fields/rich-text/monaco/use-debounce.ts +8 -8
- package/src/global.css +3 -3
- package/src/index.css +15 -15
- package/src/lib/build-form.ts +24 -24
- package/src/lib/errors.tsx +7 -7
- package/src/lib/expand-query.ts +66 -61
- package/src/lib/graphql-reducer.ts +280 -264
- package/src/lib/types.ts +34 -33
- package/src/lib/util.ts +41 -41
- package/src/main.tsx +7 -7
- package/src/preflight.css +10 -10
- package/src/preview.tsx +12 -12
- package/src/vite-env.d.ts +3 -3
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import * as G from 'graphql'
|
|
3
|
-
import { getIn } from 'final-form'
|
|
4
|
-
import { z } from 'zod'
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import * as G from 'graphql';
|
|
3
|
+
import { getIn } from 'final-form';
|
|
4
|
+
import { z } from 'zod';
|
|
5
5
|
// @ts-expect-error
|
|
6
|
-
import schemaJson from 'SCHEMA_IMPORT'
|
|
7
|
-
import { expandQuery, isConnectionType, isNodeType } from './expand-query'
|
|
6
|
+
import schemaJson from 'SCHEMA_IMPORT';
|
|
7
|
+
import { expandQuery, isConnectionType, isNodeType } from './expand-query';
|
|
8
8
|
import {
|
|
9
9
|
Form,
|
|
10
10
|
TinaCMS,
|
|
@@ -20,17 +20,17 @@ import {
|
|
|
20
20
|
GlobalFormPlugin,
|
|
21
21
|
TinaState,
|
|
22
22
|
ErrorDialog,
|
|
23
|
-
} from 'tinacms'
|
|
24
|
-
import { createForm, createGlobalForm, FormifyCallback } from './build-form'
|
|
23
|
+
} from 'tinacms';
|
|
24
|
+
import { createForm, createGlobalForm, FormifyCallback } from './build-form';
|
|
25
25
|
import type {
|
|
26
26
|
PostMessage,
|
|
27
27
|
Payload,
|
|
28
28
|
SystemInfo,
|
|
29
29
|
ResolvedDocument,
|
|
30
|
-
} from './types'
|
|
31
|
-
import { getFormAndFieldNameFromMetadata } from './util'
|
|
32
|
-
import { useSearchParams } from 'react-router-dom'
|
|
33
|
-
import { showErrorModal } from './errors'
|
|
30
|
+
} from './types';
|
|
31
|
+
import { getFormAndFieldNameFromMetadata } from './util';
|
|
32
|
+
import { useSearchParams } from 'react-router-dom';
|
|
33
|
+
import { showErrorModal } from './errors';
|
|
34
34
|
|
|
35
35
|
const sysSchema = z.object({
|
|
36
36
|
breadcrumbs: z.array(z.string()),
|
|
@@ -41,6 +41,7 @@ const sysSchema = z.object({
|
|
|
41
41
|
relativePath: z.string(),
|
|
42
42
|
title: z.string().optional().nullable(),
|
|
43
43
|
template: z.string(),
|
|
44
|
+
hasReferences: z.boolean().optional().nullable(),
|
|
44
45
|
collection: z.object({
|
|
45
46
|
name: z.string(),
|
|
46
47
|
slug: z.string(),
|
|
@@ -49,14 +50,14 @@ const sysSchema = z.object({
|
|
|
49
50
|
format: z.string().optional().nullable(),
|
|
50
51
|
matches: z.string().optional().nullable(),
|
|
51
52
|
}),
|
|
52
|
-
})
|
|
53
|
+
});
|
|
53
54
|
|
|
54
55
|
const documentSchema: z.ZodType<ResolvedDocument> = z.object({
|
|
55
56
|
_internalValues: z.record(z.unknown()),
|
|
56
57
|
_internalSys: sysSchema,
|
|
57
|
-
})
|
|
58
|
+
});
|
|
58
59
|
|
|
59
|
-
const astNode = schemaJson as G.DocumentNode
|
|
60
|
+
const astNode = schemaJson as G.DocumentNode;
|
|
60
61
|
const astNodeWithMeta: G.DocumentNode = {
|
|
61
62
|
...astNode,
|
|
62
63
|
definitions: astNode.definitions.map((def) => {
|
|
@@ -102,7 +103,7 @@ const astNodeWithMeta: G.DocumentNode = {
|
|
|
102
103
|
},
|
|
103
104
|
},
|
|
104
105
|
],
|
|
105
|
-
}
|
|
106
|
+
};
|
|
106
107
|
}
|
|
107
108
|
if (def.kind === 'ObjectTypeDefinition') {
|
|
108
109
|
return {
|
|
@@ -146,68 +147,68 @@ const astNodeWithMeta: G.DocumentNode = {
|
|
|
146
147
|
},
|
|
147
148
|
},
|
|
148
149
|
],
|
|
149
|
-
}
|
|
150
|
+
};
|
|
150
151
|
}
|
|
151
|
-
return def
|
|
152
|
+
return def;
|
|
152
153
|
}),
|
|
153
|
-
}
|
|
154
|
-
const schema = G.buildASTSchema(astNode)
|
|
155
|
-
const schemaForResolver = G.buildASTSchema(astNodeWithMeta)
|
|
154
|
+
};
|
|
155
|
+
const schema = G.buildASTSchema(astNode);
|
|
156
|
+
const schemaForResolver = G.buildASTSchema(astNodeWithMeta);
|
|
156
157
|
|
|
157
158
|
const isRejected = (
|
|
158
159
|
input: PromiseSettledResult<unknown>
|
|
159
|
-
): input is PromiseRejectedResult => input.status === 'rejected'
|
|
160
|
+
): input is PromiseRejectedResult => input.status === 'rejected';
|
|
160
161
|
|
|
161
162
|
const isFulfilled = <T>(
|
|
162
163
|
input: PromiseSettledResult<T>
|
|
163
|
-
): input is PromiseFulfilledResult<T> => input.status === 'fulfilled'
|
|
164
|
+
): input is PromiseFulfilledResult<T> => input.status === 'fulfilled';
|
|
164
165
|
|
|
165
166
|
export const useGraphQLReducer = (
|
|
166
167
|
iframe: React.MutableRefObject<HTMLIFrameElement>,
|
|
167
168
|
url: string
|
|
168
169
|
) => {
|
|
169
|
-
const cms = useCMS()
|
|
170
|
-
const tinaSchema = cms.api.tina.schema as TinaSchema
|
|
171
|
-
const [payloads, setPayloads] = React.useState<Payload[]>([])
|
|
172
|
-
const [requestErrors, setRequestErrors] = React.useState<string[]>([])
|
|
173
|
-
const [searchParams, setSearchParams] = useSearchParams()
|
|
170
|
+
const cms = useCMS();
|
|
171
|
+
const tinaSchema = cms.api.tina.schema as TinaSchema;
|
|
172
|
+
const [payloads, setPayloads] = React.useState<Payload[]>([]);
|
|
173
|
+
const [requestErrors, setRequestErrors] = React.useState<string[]>([]);
|
|
174
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
174
175
|
const [results, setResults] = React.useState<
|
|
175
176
|
{
|
|
176
|
-
id: string
|
|
177
|
+
id: string;
|
|
177
178
|
data:
|
|
178
179
|
| {
|
|
179
|
-
[key: string]: any
|
|
180
|
+
[key: string]: any;
|
|
180
181
|
}
|
|
181
182
|
| null
|
|
182
|
-
| undefined
|
|
183
|
+
| undefined;
|
|
183
184
|
}[]
|
|
184
|
-
>([])
|
|
185
|
+
>([]);
|
|
185
186
|
const [documentsToResolve, setDocumentsToResolve] = React.useState<string[]>(
|
|
186
187
|
[]
|
|
187
|
-
)
|
|
188
|
+
);
|
|
188
189
|
const [resolvedDocuments, setResolvedDocuments] = React.useState<
|
|
189
190
|
ResolvedDocument[]
|
|
190
|
-
>([])
|
|
191
|
-
const [operationIndex, setOperationIndex] = React.useState(0)
|
|
191
|
+
>([]);
|
|
192
|
+
const [operationIndex, setOperationIndex] = React.useState(0);
|
|
192
193
|
|
|
193
|
-
const activeField = searchParams.get('active-field')
|
|
194
|
+
const activeField = searchParams.get('active-field');
|
|
194
195
|
|
|
195
196
|
React.useEffect(() => {
|
|
196
197
|
const run = async () => {
|
|
197
198
|
return Promise.all(
|
|
198
199
|
documentsToResolve.map(async (documentId) => {
|
|
199
|
-
return await getDocument(documentId, cms.api.tina)
|
|
200
|
+
return await getDocument(documentId, cms.api.tina);
|
|
200
201
|
})
|
|
201
|
-
)
|
|
202
|
-
}
|
|
202
|
+
);
|
|
203
|
+
};
|
|
203
204
|
if (documentsToResolve.length) {
|
|
204
205
|
run().then((docs) => {
|
|
205
|
-
setResolvedDocuments((resolvedDocs) => [...resolvedDocs, ...docs])
|
|
206
|
-
setDocumentsToResolve([])
|
|
207
|
-
setOperationIndex((i) => i + 1)
|
|
208
|
-
})
|
|
206
|
+
setResolvedDocuments((resolvedDocs) => [...resolvedDocs, ...docs]);
|
|
207
|
+
setDocumentsToResolve([]);
|
|
208
|
+
setOperationIndex((i) => i + 1);
|
|
209
|
+
});
|
|
209
210
|
}
|
|
210
|
-
}, [documentsToResolve.join('.')])
|
|
211
|
+
}, [documentsToResolve.join('.')]);
|
|
211
212
|
|
|
212
213
|
/**
|
|
213
214
|
* Note: since React runs effects twice in development this will run twice for a given query
|
|
@@ -215,39 +216,41 @@ export const useGraphQLReducer = (
|
|
|
215
216
|
*/
|
|
216
217
|
React.useEffect(() => {
|
|
217
218
|
const run = async () => {
|
|
218
|
-
setRequestErrors([])
|
|
219
|
+
setRequestErrors([]);
|
|
219
220
|
// gather the errors and display an error message containing each error unique message
|
|
220
221
|
return Promise.allSettled(
|
|
221
222
|
payloads.map(async (payload) => {
|
|
222
223
|
// This payload has already been expanded, skip it.
|
|
223
224
|
if (payload.expandedQuery) {
|
|
224
|
-
return payload
|
|
225
|
+
return payload;
|
|
225
226
|
} else {
|
|
226
|
-
const expandedPayload = await expandPayload(payload, cms)
|
|
227
|
-
processPayload(expandedPayload)
|
|
228
|
-
return expandedPayload
|
|
227
|
+
const expandedPayload = await expandPayload(payload, cms);
|
|
228
|
+
processPayload(expandedPayload);
|
|
229
|
+
return expandedPayload;
|
|
229
230
|
}
|
|
230
231
|
})
|
|
231
|
-
)
|
|
232
|
-
}
|
|
232
|
+
);
|
|
233
|
+
};
|
|
233
234
|
if (payloads.length) {
|
|
234
235
|
run().then((updatedPayloads) => {
|
|
235
|
-
setPayloads(updatedPayloads.filter(isFulfilled).map((p) => p.value))
|
|
236
|
+
setPayloads(updatedPayloads.filter(isFulfilled).map((p) => p.value));
|
|
236
237
|
setRequestErrors(
|
|
237
238
|
updatedPayloads.filter(isRejected).map((p) => String(p.reason))
|
|
238
|
-
)
|
|
239
|
-
})
|
|
239
|
+
);
|
|
240
|
+
});
|
|
240
241
|
}
|
|
241
|
-
}, [JSON.stringify(payloads), cms])
|
|
242
|
+
}, [JSON.stringify(payloads), cms]);
|
|
242
243
|
|
|
243
244
|
const processPayload = React.useCallback(
|
|
244
245
|
(payload: Payload) => {
|
|
245
|
-
const { expandedQueryForResolver, variables, expandedData } = payload
|
|
246
|
+
const { expandedQueryForResolver, variables, expandedData } = payload;
|
|
246
247
|
if (!expandedQueryForResolver || !expandedData) {
|
|
247
|
-
throw new Error(
|
|
248
|
+
throw new Error(
|
|
249
|
+
`Unable to process payload which has not been expanded`
|
|
250
|
+
);
|
|
248
251
|
}
|
|
249
|
-
const formListItems: TinaState['formLists'][number]['items'] = []
|
|
250
|
-
const formIds: string[] = []
|
|
252
|
+
const formListItems: TinaState['formLists'][number]['items'] = [];
|
|
253
|
+
const formIds: string[] = [];
|
|
251
254
|
|
|
252
255
|
const result = G.graphqlSync({
|
|
253
256
|
schema: schemaForResolver,
|
|
@@ -255,7 +258,7 @@ export const useGraphQLReducer = (
|
|
|
255
258
|
variableValues: variables,
|
|
256
259
|
rootValue: expandedData,
|
|
257
260
|
fieldResolver: (source, args, context, info) => {
|
|
258
|
-
const fieldName = info.fieldName
|
|
261
|
+
const fieldName = info.fieldName;
|
|
259
262
|
/**
|
|
260
263
|
* Since the `source` for this resolver is the query that
|
|
261
264
|
* ran before passing it into `useTina`, we need to take aliases
|
|
@@ -264,35 +267,35 @@ export const useGraphQLReducer = (
|
|
|
264
267
|
* solution as the `value` gets overwritten depending on the alias
|
|
265
268
|
* query.
|
|
266
269
|
*/
|
|
267
|
-
const aliases: string[] = []
|
|
270
|
+
const aliases: string[] = [];
|
|
268
271
|
info.fieldNodes.forEach((fieldNode) => {
|
|
269
272
|
if (fieldNode.alias) {
|
|
270
|
-
aliases.push(fieldNode.alias.value)
|
|
273
|
+
aliases.push(fieldNode.alias.value);
|
|
271
274
|
}
|
|
272
|
-
})
|
|
273
|
-
let value = source[fieldName] as unknown
|
|
275
|
+
});
|
|
276
|
+
let value = source[fieldName] as unknown;
|
|
274
277
|
aliases.forEach((alias) => {
|
|
275
|
-
const aliasValue = source[alias]
|
|
278
|
+
const aliasValue = source[alias];
|
|
276
279
|
if (aliasValue) {
|
|
277
|
-
value = aliasValue
|
|
280
|
+
value = aliasValue;
|
|
278
281
|
}
|
|
279
|
-
})
|
|
282
|
+
});
|
|
280
283
|
if (fieldName === '_sys') {
|
|
281
|
-
return source._internalSys
|
|
284
|
+
return source._internalSys;
|
|
282
285
|
}
|
|
283
286
|
if (fieldName === '_values') {
|
|
284
|
-
return source._internalValues
|
|
287
|
+
return source._internalValues;
|
|
285
288
|
}
|
|
286
289
|
if (info.fieldName === '_content_source') {
|
|
287
|
-
const pathArray = G.responsePathAsArray(info.path)
|
|
290
|
+
const pathArray = G.responsePathAsArray(info.path);
|
|
288
291
|
return {
|
|
289
292
|
queryId: payload.id,
|
|
290
293
|
path: pathArray.slice(0, pathArray.length - 1),
|
|
291
|
-
}
|
|
294
|
+
};
|
|
292
295
|
}
|
|
293
296
|
if (info.fieldName === '_tina_metadata') {
|
|
294
297
|
if (value) {
|
|
295
|
-
return value
|
|
298
|
+
return value;
|
|
296
299
|
}
|
|
297
300
|
// TODO: ensure all fields that have _tina_metadata
|
|
298
301
|
// actually need it
|
|
@@ -300,77 +303,77 @@ export const useGraphQLReducer = (
|
|
|
300
303
|
id: null,
|
|
301
304
|
fields: [],
|
|
302
305
|
prefix: '',
|
|
303
|
-
}
|
|
306
|
+
};
|
|
304
307
|
}
|
|
305
308
|
if (isConnectionType(info.returnType)) {
|
|
306
|
-
const name = G.getNamedType(info.returnType).name
|
|
309
|
+
const name = G.getNamedType(info.returnType).name;
|
|
307
310
|
const connectionCollection = tinaSchema
|
|
308
311
|
.getCollections()
|
|
309
312
|
.find((collection) => {
|
|
310
313
|
const collectionName = NAMER.referenceConnectionType(
|
|
311
314
|
collection.namespace
|
|
312
|
-
)
|
|
315
|
+
);
|
|
313
316
|
if (collectionName === name) {
|
|
314
|
-
return true
|
|
317
|
+
return true;
|
|
315
318
|
}
|
|
316
|
-
return false
|
|
317
|
-
})
|
|
319
|
+
return false;
|
|
320
|
+
});
|
|
318
321
|
if (connectionCollection) {
|
|
319
322
|
formListItems.push({
|
|
320
323
|
type: 'list',
|
|
321
324
|
label: connectionCollection.label || connectionCollection.name,
|
|
322
|
-
})
|
|
325
|
+
});
|
|
323
326
|
}
|
|
324
327
|
}
|
|
325
328
|
if (isNodeType(info.returnType)) {
|
|
326
329
|
if (!value) {
|
|
327
|
-
return
|
|
330
|
+
return;
|
|
328
331
|
}
|
|
329
|
-
let resolvedDocument: ResolvedDocument
|
|
332
|
+
let resolvedDocument: ResolvedDocument;
|
|
330
333
|
// This is a reference from another form
|
|
331
334
|
if (typeof value === 'string') {
|
|
332
335
|
const valueFromSetup = getIn(
|
|
333
336
|
expandedData,
|
|
334
337
|
G.responsePathAsArray(info.path).join('.')
|
|
335
|
-
)
|
|
338
|
+
);
|
|
336
339
|
const maybeResolvedDocument = resolvedDocuments.find(
|
|
337
340
|
(doc) => doc._internalSys.path === value
|
|
338
|
-
)
|
|
341
|
+
);
|
|
339
342
|
// If we already have this document, use it.
|
|
340
343
|
if (maybeResolvedDocument) {
|
|
341
|
-
resolvedDocument = maybeResolvedDocument
|
|
344
|
+
resolvedDocument = maybeResolvedDocument;
|
|
342
345
|
} else if (valueFromSetup) {
|
|
343
346
|
// Else, even though in this context the value is a string because it's
|
|
344
347
|
// resolved from a parent form, if the reference hasn't changed
|
|
345
348
|
// from when we ran the setup query, we can avoid a data fetch
|
|
346
349
|
// here and just grab it from the response
|
|
347
350
|
const maybeResolvedDocument =
|
|
348
|
-
documentSchema.parse(valueFromSetup)
|
|
351
|
+
documentSchema.parse(valueFromSetup);
|
|
349
352
|
if (maybeResolvedDocument._internalSys.path === value) {
|
|
350
|
-
resolvedDocument = maybeResolvedDocument
|
|
353
|
+
resolvedDocument = maybeResolvedDocument;
|
|
351
354
|
} else {
|
|
352
|
-
throw new NoFormError(`No form found`, value)
|
|
355
|
+
throw new NoFormError(`No form found`, value);
|
|
353
356
|
}
|
|
354
357
|
} else {
|
|
355
|
-
throw new NoFormError(`No form found`, value)
|
|
358
|
+
throw new NoFormError(`No form found`, value);
|
|
356
359
|
}
|
|
357
360
|
} else {
|
|
358
|
-
resolvedDocument = documentSchema.parse(value)
|
|
361
|
+
resolvedDocument = documentSchema.parse(value);
|
|
359
362
|
}
|
|
360
|
-
const id = resolvedDocument._internalSys.path
|
|
361
|
-
formIds.push(id)
|
|
363
|
+
const id = resolvedDocument._internalSys.path;
|
|
364
|
+
formIds.push(id);
|
|
362
365
|
const existingForm = cms.state.forms.find(
|
|
363
366
|
(f) => f.tinaForm.id === id
|
|
364
|
-
)
|
|
367
|
+
);
|
|
365
368
|
|
|
366
|
-
const pathArray = G.responsePathAsArray(info.path)
|
|
367
|
-
const pathString = pathArray.join('.')
|
|
369
|
+
const pathArray = G.responsePathAsArray(info.path);
|
|
370
|
+
const pathString = pathArray.join('.');
|
|
368
371
|
const ancestors = formListItems.filter((item) => {
|
|
369
372
|
if (item.type === 'document') {
|
|
370
|
-
return pathString.startsWith(item.path)
|
|
373
|
+
return pathString.startsWith(item.path);
|
|
371
374
|
}
|
|
372
|
-
})
|
|
373
|
-
const parent = ancestors[ancestors.length - 1]
|
|
375
|
+
});
|
|
376
|
+
const parent = ancestors[ancestors.length - 1];
|
|
374
377
|
if (parent) {
|
|
375
378
|
if (parent.type === 'document') {
|
|
376
379
|
parent.subItems.push({
|
|
@@ -378,7 +381,7 @@ export const useGraphQLReducer = (
|
|
|
378
381
|
path: pathString,
|
|
379
382
|
formId: id,
|
|
380
383
|
subItems: [],
|
|
381
|
-
})
|
|
384
|
+
});
|
|
382
385
|
}
|
|
383
386
|
} else {
|
|
384
387
|
formListItems.push({
|
|
@@ -386,7 +389,7 @@ export const useGraphQLReducer = (
|
|
|
386
389
|
path: pathString,
|
|
387
390
|
formId: id,
|
|
388
391
|
subItems: [],
|
|
389
|
-
})
|
|
392
|
+
});
|
|
390
393
|
}
|
|
391
394
|
|
|
392
395
|
if (!existingForm) {
|
|
@@ -395,65 +398,65 @@ export const useGraphQLReducer = (
|
|
|
395
398
|
tinaSchema,
|
|
396
399
|
payloadId: payload.id,
|
|
397
400
|
cms,
|
|
398
|
-
})
|
|
401
|
+
});
|
|
399
402
|
form.subscribe(
|
|
400
403
|
() => {
|
|
401
|
-
setOperationIndex((i) => i + 1)
|
|
404
|
+
setOperationIndex((i) => i + 1);
|
|
402
405
|
},
|
|
403
406
|
{ values: true }
|
|
404
|
-
)
|
|
407
|
+
);
|
|
405
408
|
return resolveDocument(
|
|
406
409
|
resolvedDocument,
|
|
407
410
|
template,
|
|
408
411
|
form,
|
|
409
412
|
pathString
|
|
410
|
-
)
|
|
413
|
+
);
|
|
411
414
|
} else {
|
|
412
|
-
existingForm.tinaForm.addQuery(payload.id)
|
|
415
|
+
existingForm.tinaForm.addQuery(payload.id);
|
|
413
416
|
const { template } = getTemplateForDocument(
|
|
414
417
|
resolvedDocument,
|
|
415
418
|
tinaSchema
|
|
416
|
-
)
|
|
417
|
-
existingForm.tinaForm.addQuery(payload.id)
|
|
419
|
+
);
|
|
420
|
+
existingForm.tinaForm.addQuery(payload.id);
|
|
418
421
|
return resolveDocument(
|
|
419
422
|
resolvedDocument,
|
|
420
423
|
template,
|
|
421
424
|
existingForm.tinaForm,
|
|
422
425
|
pathString
|
|
423
|
-
)
|
|
426
|
+
);
|
|
424
427
|
}
|
|
425
428
|
}
|
|
426
|
-
return value
|
|
429
|
+
return value;
|
|
427
430
|
},
|
|
428
|
-
})
|
|
431
|
+
});
|
|
429
432
|
if (result.errors) {
|
|
430
433
|
result.errors.forEach((error) => {
|
|
431
434
|
if (
|
|
432
435
|
error instanceof G.GraphQLError &&
|
|
433
436
|
error.originalError instanceof NoFormError
|
|
434
437
|
) {
|
|
435
|
-
const id = error.originalError.id
|
|
438
|
+
const id = error.originalError.id;
|
|
436
439
|
setDocumentsToResolve((docs) => [
|
|
437
440
|
...docs.filter((doc) => doc !== id),
|
|
438
441
|
id,
|
|
439
|
-
])
|
|
442
|
+
]);
|
|
440
443
|
} else {
|
|
441
|
-
console.log(error)
|
|
444
|
+
console.log(error);
|
|
442
445
|
// throw new Error(
|
|
443
446
|
// `Error processing value change, please contact support`
|
|
444
447
|
// )
|
|
445
448
|
}
|
|
446
|
-
})
|
|
449
|
+
});
|
|
447
450
|
} else {
|
|
448
451
|
if (result.data) {
|
|
449
452
|
setResults((results) => [
|
|
450
453
|
...results.filter((result) => result.id !== payload.id),
|
|
451
454
|
{ id: payload.id, data: result.data },
|
|
452
|
-
])
|
|
455
|
+
]);
|
|
453
456
|
}
|
|
454
457
|
if (activeField) {
|
|
455
|
-
setSearchParams({})
|
|
456
|
-
const [queryId, eventFieldName] = activeField.split('---')
|
|
458
|
+
setSearchParams({});
|
|
459
|
+
const [queryId, eventFieldName] = activeField.split('---');
|
|
457
460
|
if (queryId === payload.id) {
|
|
458
461
|
if (result?.data) {
|
|
459
462
|
cms.dispatch({
|
|
@@ -462,19 +465,19 @@ export const useGraphQLReducer = (
|
|
|
462
465
|
result.data,
|
|
463
466
|
eventFieldName
|
|
464
467
|
),
|
|
465
|
-
})
|
|
468
|
+
});
|
|
466
469
|
}
|
|
467
470
|
cms.dispatch({
|
|
468
471
|
type: 'sidebar:set-display-state',
|
|
469
472
|
value: 'openOrFull',
|
|
470
|
-
})
|
|
473
|
+
});
|
|
471
474
|
}
|
|
472
475
|
}
|
|
473
476
|
iframe.current?.contentWindow?.postMessage({
|
|
474
477
|
type: 'updateData',
|
|
475
478
|
id: payload.id,
|
|
476
479
|
data: result.data,
|
|
477
|
-
})
|
|
480
|
+
});
|
|
478
481
|
}
|
|
479
482
|
cms.dispatch({
|
|
480
483
|
type: 'form-lists:add',
|
|
@@ -484,57 +487,64 @@ export const useGraphQLReducer = (
|
|
|
484
487
|
items: formListItems,
|
|
485
488
|
formIds,
|
|
486
489
|
},
|
|
487
|
-
})
|
|
490
|
+
});
|
|
488
491
|
},
|
|
489
492
|
[
|
|
490
493
|
resolvedDocuments.map((doc) => doc._internalSys.path).join('.'),
|
|
491
494
|
activeField,
|
|
492
495
|
]
|
|
493
|
-
)
|
|
496
|
+
);
|
|
494
497
|
|
|
495
498
|
const handleMessage = React.useCallback(
|
|
496
499
|
(event: MessageEvent<PostMessage>) => {
|
|
500
|
+
if (event.data.type === 'user-select-form') {
|
|
501
|
+
cms.dispatch({
|
|
502
|
+
type: 'forms:set-active-form-id',
|
|
503
|
+
value: event.data.formId,
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
|
|
497
507
|
if (event?.data?.type === 'quick-edit') {
|
|
498
508
|
cms.dispatch({
|
|
499
509
|
type: 'set-quick-editing-supported',
|
|
500
510
|
value: event.data.value,
|
|
501
|
-
})
|
|
511
|
+
});
|
|
502
512
|
iframe.current?.contentWindow?.postMessage({
|
|
503
513
|
type: 'quickEditEnabled',
|
|
504
514
|
value: cms.state.sidebarDisplayState === 'open',
|
|
505
|
-
})
|
|
515
|
+
});
|
|
506
516
|
}
|
|
507
517
|
if (event?.data?.type === 'isEditMode') {
|
|
508
518
|
iframe?.current?.contentWindow?.postMessage({
|
|
509
519
|
type: 'tina:editMode',
|
|
510
|
-
})
|
|
520
|
+
});
|
|
511
521
|
}
|
|
512
522
|
if (event.data.type === 'field:selected') {
|
|
513
|
-
const [queryId, eventFieldName] = event.data.fieldName.split('---')
|
|
514
|
-
const result = results.find((res) => res.id === queryId)
|
|
523
|
+
const [queryId, eventFieldName] = event.data.fieldName.split('---');
|
|
524
|
+
const result = results.find((res) => res.id === queryId);
|
|
515
525
|
if (result?.data) {
|
|
516
526
|
cms.dispatch({
|
|
517
527
|
type: 'forms:set-active-field-name',
|
|
518
528
|
value: getFormAndFieldNameFromMetadata(result.data, eventFieldName),
|
|
519
|
-
})
|
|
529
|
+
});
|
|
520
530
|
}
|
|
521
531
|
cms.dispatch({
|
|
522
532
|
type: 'sidebar:set-display-state',
|
|
523
533
|
value: 'openOrFull',
|
|
524
|
-
})
|
|
534
|
+
});
|
|
525
535
|
}
|
|
526
536
|
if (event.data.type === 'close') {
|
|
527
|
-
const payloadSchema = z.object({ id: z.string() })
|
|
528
|
-
const { id } = payloadSchema.parse(event.data)
|
|
537
|
+
const payloadSchema = z.object({ id: z.string() });
|
|
538
|
+
const { id } = payloadSchema.parse(event.data);
|
|
529
539
|
setPayloads((previous) =>
|
|
530
540
|
previous.filter((payload) => payload.id !== id)
|
|
531
|
-
)
|
|
532
|
-
setResults((previous) => previous.filter((result) => result.id !== id))
|
|
541
|
+
);
|
|
542
|
+
setResults((previous) => previous.filter((result) => result.id !== id));
|
|
533
543
|
cms.forms.all().map((form) => {
|
|
534
|
-
form.removeQuery(id)
|
|
535
|
-
})
|
|
536
|
-
cms.removeOrphanedForms()
|
|
537
|
-
cms.dispatch({ type: 'form-lists:remove', value: id })
|
|
544
|
+
form.removeQuery(id);
|
|
545
|
+
});
|
|
546
|
+
cms.removeOrphanedForms();
|
|
547
|
+
cms.dispatch({ type: 'form-lists:remove', value: id });
|
|
538
548
|
}
|
|
539
549
|
if (event.data.type === 'open') {
|
|
540
550
|
const payloadSchema = z.object({
|
|
@@ -542,60 +552,60 @@ export const useGraphQLReducer = (
|
|
|
542
552
|
query: z.string(),
|
|
543
553
|
variables: z.record(z.unknown()),
|
|
544
554
|
data: z.record(z.unknown()),
|
|
545
|
-
})
|
|
546
|
-
const payload = payloadSchema.parse(event.data)
|
|
555
|
+
});
|
|
556
|
+
const payload = payloadSchema.parse(event.data);
|
|
547
557
|
setPayloads((payloads) => [
|
|
548
558
|
...payloads.filter(({ id }) => id !== payload.id),
|
|
549
559
|
payload,
|
|
550
|
-
])
|
|
560
|
+
]);
|
|
551
561
|
}
|
|
552
562
|
},
|
|
553
563
|
[cms, JSON.stringify(results)]
|
|
554
|
-
)
|
|
564
|
+
);
|
|
555
565
|
|
|
556
566
|
React.useEffect(() => {
|
|
557
567
|
payloads.forEach((payload) => {
|
|
558
568
|
if (payload.expandedData) {
|
|
559
|
-
processPayload(payload)
|
|
569
|
+
processPayload(payload);
|
|
560
570
|
}
|
|
561
|
-
})
|
|
562
|
-
}, [operationIndex])
|
|
571
|
+
});
|
|
572
|
+
}, [operationIndex]);
|
|
563
573
|
|
|
564
574
|
React.useEffect(() => {
|
|
565
575
|
return () => {
|
|
566
|
-
setPayloads([])
|
|
567
|
-
setResults([])
|
|
568
|
-
cms.removeAllForms()
|
|
569
|
-
cms.dispatch({ type: 'form-lists:clear' })
|
|
570
|
-
}
|
|
571
|
-
}, [url])
|
|
576
|
+
setPayloads([]);
|
|
577
|
+
setResults([]);
|
|
578
|
+
cms.removeAllForms();
|
|
579
|
+
cms.dispatch({ type: 'form-lists:clear' });
|
|
580
|
+
};
|
|
581
|
+
}, [url]);
|
|
572
582
|
|
|
573
583
|
React.useEffect(() => {
|
|
574
584
|
iframe.current?.contentWindow?.postMessage({
|
|
575
585
|
type: 'quickEditEnabled',
|
|
576
586
|
value: cms.state.sidebarDisplayState === 'open',
|
|
577
|
-
})
|
|
578
|
-
}, [cms.state.sidebarDisplayState])
|
|
587
|
+
});
|
|
588
|
+
}, [cms.state.sidebarDisplayState]);
|
|
579
589
|
|
|
580
590
|
React.useEffect(() => {
|
|
581
|
-
cms.dispatch({ type: 'set-edit-mode', value: 'visual' })
|
|
591
|
+
cms.dispatch({ type: 'set-edit-mode', value: 'visual' });
|
|
582
592
|
if (iframe) {
|
|
583
|
-
window.addEventListener('message', handleMessage)
|
|
593
|
+
window.addEventListener('message', handleMessage);
|
|
584
594
|
}
|
|
585
595
|
|
|
586
596
|
return () => {
|
|
587
|
-
window.removeEventListener('message', handleMessage)
|
|
588
|
-
cms.removeAllForms()
|
|
589
|
-
cms.dispatch({ type: 'set-edit-mode', value: 'basic' })
|
|
590
|
-
}
|
|
591
|
-
}, [iframe.current, JSON.stringify(results)])
|
|
597
|
+
window.removeEventListener('message', handleMessage);
|
|
598
|
+
cms.removeAllForms();
|
|
599
|
+
cms.dispatch({ type: 'set-edit-mode', value: 'basic' });
|
|
600
|
+
};
|
|
601
|
+
}, [iframe.current, JSON.stringify(results)]);
|
|
592
602
|
|
|
593
603
|
React.useEffect(() => {
|
|
594
604
|
if (requestErrors.length) {
|
|
595
|
-
showErrorModal('Unexpected error querying content', requestErrors, cms)
|
|
605
|
+
showErrorModal('Unexpected error querying content', requestErrors, cms);
|
|
596
606
|
}
|
|
597
|
-
}, [requestErrors])
|
|
598
|
-
}
|
|
607
|
+
}, [requestErrors]);
|
|
608
|
+
};
|
|
599
609
|
|
|
600
610
|
const onSubmit = async (
|
|
601
611
|
collection: Collection<true>,
|
|
@@ -603,7 +613,7 @@ const onSubmit = async (
|
|
|
603
613
|
payload: Record<string, unknown>,
|
|
604
614
|
cms: TinaCMS
|
|
605
615
|
) => {
|
|
606
|
-
const tinaSchema = cms.api.tina.schema
|
|
616
|
+
const tinaSchema = cms.api.tina.schema;
|
|
607
617
|
try {
|
|
608
618
|
const mutationString = `#graphql
|
|
609
619
|
mutation UpdateDocument($collection: String!, $relativePath: String!, $params: DocumentUpdateMutation!) {
|
|
@@ -611,7 +621,7 @@ const onSubmit = async (
|
|
|
611
621
|
__typename
|
|
612
622
|
}
|
|
613
623
|
}
|
|
614
|
-
|
|
624
|
+
`;
|
|
615
625
|
|
|
616
626
|
await cms.api.tina.request(mutationString, {
|
|
617
627
|
variables: {
|
|
@@ -619,8 +629,8 @@ const onSubmit = async (
|
|
|
619
629
|
relativePath: relativePath,
|
|
620
630
|
params: tinaSchema.transformPayload(collection.name, payload),
|
|
621
631
|
},
|
|
622
|
-
})
|
|
623
|
-
cms.alerts.success('Document saved!')
|
|
632
|
+
});
|
|
633
|
+
cms.alerts.success('Document saved!');
|
|
624
634
|
} catch (e) {
|
|
625
635
|
cms.alerts.error(() =>
|
|
626
636
|
ErrorDialog({
|
|
@@ -628,12 +638,12 @@ const onSubmit = async (
|
|
|
628
638
|
message: 'Tina caught an error while updating the page',
|
|
629
639
|
error: e,
|
|
630
640
|
})
|
|
631
|
-
)
|
|
632
|
-
console.error(e)
|
|
641
|
+
);
|
|
642
|
+
console.error(e);
|
|
633
643
|
}
|
|
634
|
-
}
|
|
644
|
+
};
|
|
635
645
|
|
|
636
|
-
type Path = (string | number)[]
|
|
646
|
+
type Path = (string | number)[];
|
|
637
647
|
|
|
638
648
|
const resolveDocument = (
|
|
639
649
|
doc: ResolvedDocument,
|
|
@@ -642,20 +652,20 @@ const resolveDocument = (
|
|
|
642
652
|
pathToDocument: string
|
|
643
653
|
): ResolvedDocument => {
|
|
644
654
|
// @ts-ignore AnyField and TinaField don't mix
|
|
645
|
-
const fields = form.fields as TinaField<true>[]
|
|
646
|
-
const id = doc._internalSys.path
|
|
647
|
-
const path: Path = []
|
|
655
|
+
const fields = form.fields as TinaField<true>[];
|
|
656
|
+
const id = doc._internalSys.path;
|
|
657
|
+
const path: Path = [];
|
|
648
658
|
const formValues = resolveFormValue({
|
|
649
659
|
fields: fields,
|
|
650
660
|
values: form.values,
|
|
651
661
|
path,
|
|
652
662
|
id,
|
|
653
663
|
pathToDocument,
|
|
654
|
-
})
|
|
655
|
-
const metadataFields: Record<string, string> = {}
|
|
664
|
+
});
|
|
665
|
+
const metadataFields: Record<string, string> = {};
|
|
656
666
|
Object.keys(formValues).forEach((key) => {
|
|
657
|
-
metadataFields[key] = [...path, key].join('.')
|
|
658
|
-
})
|
|
667
|
+
metadataFields[key] = [...path, key].join('.');
|
|
668
|
+
});
|
|
659
669
|
|
|
660
670
|
return {
|
|
661
671
|
...formValues,
|
|
@@ -671,8 +681,8 @@ const resolveDocument = (
|
|
|
671
681
|
_internalSys: doc._internalSys,
|
|
672
682
|
_internalValues: doc._internalValues,
|
|
673
683
|
__typename: NAMER.dataTypeName(template.namespace),
|
|
674
|
-
}
|
|
675
|
-
}
|
|
684
|
+
};
|
|
685
|
+
};
|
|
676
686
|
|
|
677
687
|
const resolveFormValue = <T extends Record<string, unknown>>({
|
|
678
688
|
fields,
|
|
@@ -682,21 +692,21 @@ const resolveFormValue = <T extends Record<string, unknown>>({
|
|
|
682
692
|
pathToDocument,
|
|
683
693
|
}: // tinaSchema,
|
|
684
694
|
{
|
|
685
|
-
fields: TinaField<true>[]
|
|
686
|
-
values: T
|
|
687
|
-
path: Path
|
|
688
|
-
id: string
|
|
689
|
-
pathToDocument: string
|
|
695
|
+
fields: TinaField<true>[];
|
|
696
|
+
values: T;
|
|
697
|
+
path: Path;
|
|
698
|
+
id: string;
|
|
699
|
+
pathToDocument: string;
|
|
690
700
|
// tinaSchema: TinaSchema
|
|
691
701
|
}): T & { __typename?: string } => {
|
|
692
|
-
const accum: Record<string, unknown> = {}
|
|
702
|
+
const accum: Record<string, unknown> = {};
|
|
693
703
|
fields.forEach((field) => {
|
|
694
|
-
const v = values[field.name]
|
|
704
|
+
const v = values[field.name];
|
|
695
705
|
if (typeof v === 'undefined') {
|
|
696
|
-
return
|
|
706
|
+
return;
|
|
697
707
|
}
|
|
698
708
|
if (v === null) {
|
|
699
|
-
return
|
|
709
|
+
return;
|
|
700
710
|
}
|
|
701
711
|
accum[field.name] = resolveFieldValue({
|
|
702
712
|
field,
|
|
@@ -704,10 +714,10 @@ const resolveFormValue = <T extends Record<string, unknown>>({
|
|
|
704
714
|
path,
|
|
705
715
|
id,
|
|
706
716
|
pathToDocument,
|
|
707
|
-
})
|
|
708
|
-
})
|
|
709
|
-
return accum as T & { __typename?: string }
|
|
710
|
-
}
|
|
717
|
+
});
|
|
718
|
+
});
|
|
719
|
+
return accum as T & { __typename?: string };
|
|
720
|
+
};
|
|
711
721
|
const resolveFieldValue = ({
|
|
712
722
|
field,
|
|
713
723
|
value,
|
|
@@ -715,11 +725,11 @@ const resolveFieldValue = ({
|
|
|
715
725
|
id,
|
|
716
726
|
pathToDocument,
|
|
717
727
|
}: {
|
|
718
|
-
field: TinaField<true
|
|
719
|
-
value: unknown
|
|
720
|
-
path: Path
|
|
721
|
-
id: string
|
|
722
|
-
pathToDocument: string
|
|
728
|
+
field: TinaField<true>;
|
|
729
|
+
value: unknown;
|
|
730
|
+
path: Path;
|
|
731
|
+
id: string;
|
|
732
|
+
pathToDocument: string;
|
|
723
733
|
}) => {
|
|
724
734
|
switch (field.type) {
|
|
725
735
|
case 'object': {
|
|
@@ -727,15 +737,17 @@ const resolveFieldValue = ({
|
|
|
727
737
|
if (field.list) {
|
|
728
738
|
if (Array.isArray(value)) {
|
|
729
739
|
return value.map((item, index) => {
|
|
730
|
-
const template = field.templates[item._template]
|
|
740
|
+
const template = field.templates[item._template];
|
|
731
741
|
if (typeof template === 'string') {
|
|
732
|
-
throw new Error('Global templates not supported')
|
|
742
|
+
throw new Error('Global templates not supported');
|
|
733
743
|
}
|
|
734
|
-
const nextPath = [...path, field.name, index]
|
|
735
|
-
const metadataFields: Record<string, string> = {}
|
|
744
|
+
const nextPath = [...path, field.name, index];
|
|
745
|
+
const metadataFields: Record<string, string> = {};
|
|
736
746
|
template.fields.forEach((field) => {
|
|
737
|
-
metadataFields[field.name] = [...nextPath, field.name].join(
|
|
738
|
-
|
|
747
|
+
metadataFields[field.name] = [...nextPath, field.name].join(
|
|
748
|
+
'.'
|
|
749
|
+
);
|
|
750
|
+
});
|
|
739
751
|
return {
|
|
740
752
|
__typename: NAMER.dataTypeName(template.namespace),
|
|
741
753
|
_tina_metadata: {
|
|
@@ -751,29 +763,29 @@ const resolveFieldValue = ({
|
|
|
751
763
|
id,
|
|
752
764
|
pathToDocument,
|
|
753
765
|
}),
|
|
754
|
-
}
|
|
755
|
-
})
|
|
766
|
+
};
|
|
767
|
+
});
|
|
756
768
|
}
|
|
757
769
|
} else {
|
|
758
770
|
// not implemented
|
|
759
771
|
}
|
|
760
772
|
}
|
|
761
773
|
|
|
762
|
-
const templateFields = field.fields
|
|
774
|
+
const templateFields = field.fields;
|
|
763
775
|
if (typeof templateFields === 'string') {
|
|
764
|
-
throw new Error('Global templates not supported')
|
|
776
|
+
throw new Error('Global templates not supported');
|
|
765
777
|
}
|
|
766
778
|
if (!templateFields) {
|
|
767
|
-
throw new Error(`Expected to find sub-fields on field ${field.name}`)
|
|
779
|
+
throw new Error(`Expected to find sub-fields on field ${field.name}`);
|
|
768
780
|
}
|
|
769
781
|
if (field.list) {
|
|
770
782
|
if (Array.isArray(value)) {
|
|
771
783
|
return value.map((item, index) => {
|
|
772
|
-
const nextPath = [...path, field.name, index]
|
|
773
|
-
const metadataFields: Record<string, string> = {}
|
|
784
|
+
const nextPath = [...path, field.name, index];
|
|
785
|
+
const metadataFields: Record<string, string> = {};
|
|
774
786
|
templateFields.forEach((field) => {
|
|
775
|
-
metadataFields[field.name] = [...nextPath, field.name].join('.')
|
|
776
|
-
})
|
|
787
|
+
metadataFields[field.name] = [...nextPath, field.name].join('.');
|
|
788
|
+
});
|
|
777
789
|
return {
|
|
778
790
|
__typename: NAMER.dataTypeName(field.namespace),
|
|
779
791
|
_tina_metadata: {
|
|
@@ -789,15 +801,15 @@ const resolveFieldValue = ({
|
|
|
789
801
|
id,
|
|
790
802
|
pathToDocument,
|
|
791
803
|
}),
|
|
792
|
-
}
|
|
793
|
-
})
|
|
804
|
+
};
|
|
805
|
+
});
|
|
794
806
|
}
|
|
795
807
|
} else {
|
|
796
|
-
const nextPath = [...path, field.name]
|
|
797
|
-
const metadataFields: Record<string, string> = {}
|
|
808
|
+
const nextPath = [...path, field.name];
|
|
809
|
+
const metadataFields: Record<string, string> = {};
|
|
798
810
|
templateFields.forEach((field) => {
|
|
799
|
-
metadataFields[field.name] = [...nextPath, field.name].join('.')
|
|
800
|
-
})
|
|
811
|
+
metadataFields[field.name] = [...nextPath, field.name].join('.');
|
|
812
|
+
});
|
|
801
813
|
return {
|
|
802
814
|
__typename: NAMER.dataTypeName(field.namespace),
|
|
803
815
|
_tina_metadata: {
|
|
@@ -813,18 +825,21 @@ const resolveFieldValue = ({
|
|
|
813
825
|
id,
|
|
814
826
|
pathToDocument,
|
|
815
827
|
}),
|
|
816
|
-
}
|
|
828
|
+
};
|
|
817
829
|
}
|
|
818
830
|
}
|
|
819
831
|
default: {
|
|
820
|
-
return value
|
|
832
|
+
return value;
|
|
821
833
|
}
|
|
822
834
|
}
|
|
823
|
-
}
|
|
835
|
+
};
|
|
824
836
|
|
|
825
837
|
const getDocument = async (id: string, tina: Client) => {
|
|
826
838
|
const response = await tina.request<{
|
|
827
|
-
node: {
|
|
839
|
+
node: {
|
|
840
|
+
_internalSys: SystemInfo;
|
|
841
|
+
_internalValues: Record<string, unknown>;
|
|
842
|
+
};
|
|
828
843
|
}>(
|
|
829
844
|
`query GetNode($id: String!) {
|
|
830
845
|
node(id: $id) {
|
|
@@ -838,6 +853,7 @@ _internalSys: _sys {
|
|
|
838
853
|
extension
|
|
839
854
|
relativePath
|
|
840
855
|
title
|
|
856
|
+
hasReferences
|
|
841
857
|
template
|
|
842
858
|
collection {
|
|
843
859
|
name
|
|
@@ -856,29 +872,29 @@ _internalSys: _sys {
|
|
|
856
872
|
}
|
|
857
873
|
}`,
|
|
858
874
|
{ variables: { id: id } }
|
|
859
|
-
)
|
|
860
|
-
return response.node
|
|
861
|
-
}
|
|
875
|
+
);
|
|
876
|
+
return response.node;
|
|
877
|
+
};
|
|
862
878
|
|
|
863
879
|
const expandPayload = async (
|
|
864
880
|
payload: Payload,
|
|
865
881
|
cms: TinaCMS
|
|
866
882
|
): Promise<Payload> => {
|
|
867
|
-
const { query, variables } = payload
|
|
868
|
-
const documentNode = G.parse(query)
|
|
869
|
-
const expandedDocumentNode = expandQuery({ schema, documentNode })
|
|
870
|
-
const expandedQuery = G.print(expandedDocumentNode)
|
|
883
|
+
const { query, variables } = payload;
|
|
884
|
+
const documentNode = G.parse(query);
|
|
885
|
+
const expandedDocumentNode = expandQuery({ schema, documentNode });
|
|
886
|
+
const expandedQuery = G.print(expandedDocumentNode);
|
|
871
887
|
const expandedData = await cms.api.tina.request<object>(expandedQuery, {
|
|
872
888
|
variables,
|
|
873
|
-
})
|
|
889
|
+
});
|
|
874
890
|
|
|
875
891
|
const expandedDocumentNodeForResolver = expandQuery({
|
|
876
892
|
schema: schemaForResolver,
|
|
877
893
|
documentNode,
|
|
878
|
-
})
|
|
879
|
-
const expandedQueryForResolver = G.print(expandedDocumentNodeForResolver)
|
|
880
|
-
return { ...payload, expandedQuery, expandedData, expandedQueryForResolver }
|
|
881
|
-
}
|
|
894
|
+
});
|
|
895
|
+
const expandedQueryForResolver = G.print(expandedDocumentNodeForResolver);
|
|
896
|
+
return { ...payload, expandedQuery, expandedData, expandedQueryForResolver };
|
|
897
|
+
};
|
|
882
898
|
|
|
883
899
|
/**
|
|
884
900
|
* When we resolve the graphql data we check for these errors,
|
|
@@ -886,11 +902,11 @@ const expandPayload = async (
|
|
|
886
902
|
* process it once we have that document
|
|
887
903
|
*/
|
|
888
904
|
class NoFormError extends Error {
|
|
889
|
-
id: string
|
|
905
|
+
id: string;
|
|
890
906
|
constructor(msg: string, id: string) {
|
|
891
|
-
super(msg)
|
|
892
|
-
this.id = id
|
|
893
|
-
Object.setPrototypeOf(this, NoFormError.prototype)
|
|
907
|
+
super(msg);
|
|
908
|
+
this.id = id;
|
|
909
|
+
Object.setPrototypeOf(this, NoFormError.prototype);
|
|
894
910
|
}
|
|
895
911
|
}
|
|
896
912
|
|
|
@@ -898,22 +914,22 @@ const getTemplateForDocument = (
|
|
|
898
914
|
resolvedDocument: ResolvedDocument,
|
|
899
915
|
tinaSchema: TinaSchema
|
|
900
916
|
) => {
|
|
901
|
-
const id = resolvedDocument._internalSys.path
|
|
902
|
-
let collection: Collection<true> | undefined
|
|
917
|
+
const id = resolvedDocument._internalSys.path;
|
|
918
|
+
let collection: Collection<true> | undefined;
|
|
903
919
|
try {
|
|
904
|
-
collection = tinaSchema.getCollectionByFullPath(id)
|
|
920
|
+
collection = tinaSchema.getCollectionByFullPath(id);
|
|
905
921
|
} catch (e) {}
|
|
906
922
|
|
|
907
923
|
if (!collection) {
|
|
908
|
-
throw new Error(`Unable to determine collection for path ${id}`)
|
|
924
|
+
throw new Error(`Unable to determine collection for path ${id}`);
|
|
909
925
|
}
|
|
910
926
|
|
|
911
927
|
const template = tinaSchema.getTemplateForData({
|
|
912
928
|
data: resolvedDocument._internalValues,
|
|
913
929
|
collection,
|
|
914
|
-
})
|
|
915
|
-
return { template, collection }
|
|
916
|
-
}
|
|
930
|
+
});
|
|
931
|
+
return { template, collection };
|
|
932
|
+
};
|
|
917
933
|
|
|
918
934
|
const buildForm = ({
|
|
919
935
|
resolvedDocument,
|
|
@@ -921,18 +937,18 @@ const buildForm = ({
|
|
|
921
937
|
payloadId,
|
|
922
938
|
cms,
|
|
923
939
|
}: {
|
|
924
|
-
resolvedDocument: ResolvedDocument
|
|
925
|
-
tinaSchema: TinaSchema
|
|
926
|
-
payloadId: string
|
|
927
|
-
cms: TinaCMS
|
|
940
|
+
resolvedDocument: ResolvedDocument;
|
|
941
|
+
tinaSchema: TinaSchema;
|
|
942
|
+
payloadId: string;
|
|
943
|
+
cms: TinaCMS;
|
|
928
944
|
}) => {
|
|
929
945
|
const { template, collection } = getTemplateForDocument(
|
|
930
946
|
resolvedDocument,
|
|
931
947
|
tinaSchema
|
|
932
|
-
)
|
|
933
|
-
const id = resolvedDocument._internalSys.path
|
|
934
|
-
let form: Form | undefined
|
|
935
|
-
let shouldRegisterForm = true
|
|
948
|
+
);
|
|
949
|
+
const id = resolvedDocument._internalSys.path;
|
|
950
|
+
let form: Form | undefined;
|
|
951
|
+
let shouldRegisterForm = true;
|
|
936
952
|
const formConfig: FormOptions<any> = {
|
|
937
953
|
id,
|
|
938
954
|
initialValues: resolvedDocument._internalValues,
|
|
@@ -945,10 +961,10 @@ const buildForm = ({
|
|
|
945
961
|
cms
|
|
946
962
|
),
|
|
947
963
|
label: collection.label || collection.name,
|
|
948
|
-
}
|
|
964
|
+
};
|
|
949
965
|
if (tinaSchema.config.config?.formifyCallback) {
|
|
950
966
|
const callback = tinaSchema.config.config
|
|
951
|
-
?.formifyCallback as FormifyCallback
|
|
967
|
+
?.formifyCallback as FormifyCallback;
|
|
952
968
|
form =
|
|
953
969
|
callback(
|
|
954
970
|
{
|
|
@@ -958,30 +974,30 @@ const buildForm = ({
|
|
|
958
974
|
formConfig,
|
|
959
975
|
},
|
|
960
976
|
cms
|
|
961
|
-
) || undefined
|
|
977
|
+
) || undefined;
|
|
962
978
|
if (!form) {
|
|
963
979
|
// If the form isn't created from formify, we still
|
|
964
980
|
// need it, just don't show it to the user.
|
|
965
|
-
shouldRegisterForm = false
|
|
966
|
-
form = new Form(formConfig)
|
|
981
|
+
shouldRegisterForm = false;
|
|
982
|
+
form = new Form(formConfig);
|
|
967
983
|
}
|
|
968
984
|
} else {
|
|
969
985
|
if (collection.ui?.global) {
|
|
970
|
-
form = createGlobalForm(formConfig)
|
|
986
|
+
form = createGlobalForm(formConfig);
|
|
971
987
|
} else {
|
|
972
|
-
form = createForm(formConfig)
|
|
988
|
+
form = createForm(formConfig);
|
|
973
989
|
}
|
|
974
990
|
}
|
|
975
991
|
if (form) {
|
|
976
992
|
if (shouldRegisterForm) {
|
|
977
993
|
if (collection.ui?.global) {
|
|
978
|
-
cms.plugins.add(new GlobalFormPlugin(form))
|
|
994
|
+
cms.plugins.add(new GlobalFormPlugin(form));
|
|
979
995
|
}
|
|
980
|
-
cms.dispatch({ type: 'forms:add', value: form })
|
|
996
|
+
cms.dispatch({ type: 'forms:add', value: form });
|
|
981
997
|
}
|
|
982
998
|
}
|
|
983
999
|
if (!form) {
|
|
984
|
-
throw new Error(`No form registered for ${id}.`)
|
|
1000
|
+
throw new Error(`No form registered for ${id}.`);
|
|
985
1001
|
}
|
|
986
|
-
return { template, form }
|
|
987
|
-
}
|
|
1002
|
+
return { template, form };
|
|
1003
|
+
};
|