@tinacms/app 0.0.0-8eeb2df-20241010045955 → 0.0.0-8f7f815-20250623000754
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 +178 -12
- package/package.json +12 -8
- package/src/App.tsx +24 -24
- package/src/Playground.tsx +56 -56
- 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 +59 -59
- package/src/fields/rich-text/monaco/index.tsx +68 -74
- package/src/fields/rich-text/monaco/use-debounce.ts +8 -8
- package/src/global.css +3 -3
- package/src/index.css +19 -15
- package/src/lib/build-form.ts +24 -24
- package/src/lib/errors.tsx +7 -7
- package/src/lib/expand-query.ts +74 -69
- package/src/lib/graphql-reducer.ts +301 -276
- package/src/lib/types.ts +35 -33
- package/src/lib/util.ts +48 -53
- 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,36 +1,36 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import * as G from 'graphql'
|
|
3
|
-
import { getIn } from 'final-form'
|
|
4
|
-
import { z } from 'zod'
|
|
5
1
|
// @ts-expect-error
|
|
6
|
-
import schemaJson from 'SCHEMA_IMPORT'
|
|
7
|
-
import {
|
|
2
|
+
import schemaJson from 'SCHEMA_IMPORT';
|
|
3
|
+
import { getIn } from 'final-form';
|
|
4
|
+
import * as G from 'graphql';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { useSearchParams } from 'react-router-dom';
|
|
8
7
|
import {
|
|
8
|
+
Client,
|
|
9
|
+
Collection,
|
|
10
|
+
ErrorDialog,
|
|
9
11
|
Form,
|
|
10
|
-
|
|
12
|
+
FormOptions,
|
|
13
|
+
GlobalFormPlugin,
|
|
11
14
|
NAMER,
|
|
12
|
-
TinaSchema,
|
|
13
|
-
useCMS,
|
|
14
|
-
resolveField,
|
|
15
|
-
Collection,
|
|
16
15
|
Template,
|
|
16
|
+
TinaCMS,
|
|
17
17
|
TinaField,
|
|
18
|
-
|
|
19
|
-
FormOptions,
|
|
20
|
-
GlobalFormPlugin,
|
|
18
|
+
TinaSchema,
|
|
21
19
|
TinaState,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
resolveField,
|
|
21
|
+
useCMS,
|
|
22
|
+
} from 'tinacms';
|
|
23
|
+
import { z } from 'zod';
|
|
24
|
+
import { FormifyCallback, createForm, createGlobalForm } from './build-form';
|
|
25
|
+
import { showErrorModal } from './errors';
|
|
26
|
+
import { expandQuery, isConnectionType, isNodeType } from './expand-query';
|
|
25
27
|
import type {
|
|
26
|
-
PostMessage,
|
|
27
28
|
Payload,
|
|
28
|
-
|
|
29
|
+
PostMessage,
|
|
29
30
|
ResolvedDocument,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
import {
|
|
33
|
-
import { showErrorModal } from './errors'
|
|
31
|
+
SystemInfo,
|
|
32
|
+
} from './types';
|
|
33
|
+
import { getFormAndFieldNameFromMetadata } from './util';
|
|
34
34
|
|
|
35
35
|
const sysSchema = z.object({
|
|
36
36
|
breadcrumbs: z.array(z.string()),
|
|
@@ -41,22 +41,23 @@ 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(),
|
|
47
|
-
label: z.string(),
|
|
48
|
+
label: z.string().optional().nullable(),
|
|
48
49
|
path: z.string(),
|
|
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,80 @@ export const useGraphQLReducer = (
|
|
|
300
303
|
id: null,
|
|
301
304
|
fields: [],
|
|
302
305
|
prefix: '',
|
|
303
|
-
}
|
|
306
|
+
};
|
|
304
307
|
}
|
|
308
|
+
|
|
305
309
|
if (isConnectionType(info.returnType)) {
|
|
306
|
-
const name = G.getNamedType(info.returnType).name
|
|
310
|
+
const name = G.getNamedType(info.returnType).name;
|
|
307
311
|
const connectionCollection = tinaSchema
|
|
308
312
|
.getCollections()
|
|
309
313
|
.find((collection) => {
|
|
310
314
|
const collectionName = NAMER.referenceConnectionType(
|
|
311
315
|
collection.namespace
|
|
312
|
-
)
|
|
316
|
+
);
|
|
313
317
|
if (collectionName === name) {
|
|
314
|
-
return true
|
|
318
|
+
return true;
|
|
315
319
|
}
|
|
316
|
-
return false
|
|
317
|
-
})
|
|
320
|
+
return false;
|
|
321
|
+
});
|
|
318
322
|
if (connectionCollection) {
|
|
319
323
|
formListItems.push({
|
|
320
324
|
type: 'list',
|
|
321
325
|
label: connectionCollection.label || connectionCollection.name,
|
|
322
|
-
})
|
|
326
|
+
});
|
|
323
327
|
}
|
|
324
328
|
}
|
|
325
329
|
if (isNodeType(info.returnType)) {
|
|
326
330
|
if (!value) {
|
|
327
|
-
return
|
|
331
|
+
return;
|
|
328
332
|
}
|
|
329
|
-
let resolvedDocument: ResolvedDocument
|
|
333
|
+
let resolvedDocument: ResolvedDocument;
|
|
330
334
|
// This is a reference from another form
|
|
331
335
|
if (typeof value === 'string') {
|
|
332
336
|
const valueFromSetup = getIn(
|
|
333
337
|
expandedData,
|
|
334
338
|
G.responsePathAsArray(info.path).join('.')
|
|
335
|
-
)
|
|
339
|
+
);
|
|
336
340
|
const maybeResolvedDocument = resolvedDocuments.find(
|
|
337
341
|
(doc) => doc._internalSys.path === value
|
|
338
|
-
)
|
|
342
|
+
);
|
|
343
|
+
|
|
339
344
|
// If we already have this document, use it.
|
|
340
345
|
if (maybeResolvedDocument) {
|
|
341
|
-
resolvedDocument = maybeResolvedDocument
|
|
346
|
+
resolvedDocument = maybeResolvedDocument;
|
|
342
347
|
} else if (valueFromSetup) {
|
|
343
348
|
// Else, even though in this context the value is a string because it's
|
|
344
349
|
// resolved from a parent form, if the reference hasn't changed
|
|
345
350
|
// from when we ran the setup query, we can avoid a data fetch
|
|
346
351
|
// here and just grab it from the response
|
|
347
352
|
const maybeResolvedDocument =
|
|
348
|
-
documentSchema.parse(valueFromSetup)
|
|
353
|
+
documentSchema.parse(valueFromSetup);
|
|
354
|
+
|
|
349
355
|
if (maybeResolvedDocument._internalSys.path === value) {
|
|
350
|
-
resolvedDocument = maybeResolvedDocument
|
|
356
|
+
resolvedDocument = maybeResolvedDocument;
|
|
351
357
|
} else {
|
|
352
|
-
throw new NoFormError(`No form found`, value)
|
|
358
|
+
throw new NoFormError(`No form found`, value);
|
|
353
359
|
}
|
|
354
360
|
} else {
|
|
355
|
-
throw new NoFormError(`No form found`, value)
|
|
361
|
+
throw new NoFormError(`No form found`, value);
|
|
356
362
|
}
|
|
357
363
|
} else {
|
|
358
|
-
resolvedDocument = documentSchema.parse(value)
|
|
364
|
+
resolvedDocument = documentSchema.parse(value);
|
|
359
365
|
}
|
|
360
|
-
const id = resolvedDocument._internalSys.path
|
|
361
|
-
formIds.push(id)
|
|
366
|
+
const id = resolvedDocument._internalSys.path;
|
|
367
|
+
formIds.push(id);
|
|
362
368
|
const existingForm = cms.state.forms.find(
|
|
363
369
|
(f) => f.tinaForm.id === id
|
|
364
|
-
)
|
|
370
|
+
);
|
|
365
371
|
|
|
366
|
-
const pathArray = G.responsePathAsArray(info.path)
|
|
367
|
-
const pathString = pathArray.join('.')
|
|
372
|
+
const pathArray = G.responsePathAsArray(info.path);
|
|
373
|
+
const pathString = pathArray.join('.');
|
|
368
374
|
const ancestors = formListItems.filter((item) => {
|
|
369
375
|
if (item.type === 'document') {
|
|
370
|
-
return pathString.startsWith(item.path)
|
|
376
|
+
return pathString.startsWith(item.path);
|
|
371
377
|
}
|
|
372
|
-
})
|
|
373
|
-
const parent = ancestors[ancestors.length - 1]
|
|
378
|
+
});
|
|
379
|
+
const parent = ancestors[ancestors.length - 1];
|
|
374
380
|
if (parent) {
|
|
375
381
|
if (parent.type === 'document') {
|
|
376
382
|
parent.subItems.push({
|
|
@@ -378,7 +384,7 @@ export const useGraphQLReducer = (
|
|
|
378
384
|
path: pathString,
|
|
379
385
|
formId: id,
|
|
380
386
|
subItems: [],
|
|
381
|
-
})
|
|
387
|
+
});
|
|
382
388
|
}
|
|
383
389
|
} else {
|
|
384
390
|
formListItems.push({
|
|
@@ -386,7 +392,7 @@ export const useGraphQLReducer = (
|
|
|
386
392
|
path: pathString,
|
|
387
393
|
formId: id,
|
|
388
394
|
subItems: [],
|
|
389
|
-
})
|
|
395
|
+
});
|
|
390
396
|
}
|
|
391
397
|
|
|
392
398
|
if (!existingForm) {
|
|
@@ -395,65 +401,65 @@ export const useGraphQLReducer = (
|
|
|
395
401
|
tinaSchema,
|
|
396
402
|
payloadId: payload.id,
|
|
397
403
|
cms,
|
|
398
|
-
})
|
|
404
|
+
});
|
|
399
405
|
form.subscribe(
|
|
400
406
|
() => {
|
|
401
|
-
setOperationIndex((i) => i + 1)
|
|
407
|
+
setOperationIndex((i) => i + 1);
|
|
402
408
|
},
|
|
403
409
|
{ values: true }
|
|
404
|
-
)
|
|
410
|
+
);
|
|
405
411
|
return resolveDocument(
|
|
406
412
|
resolvedDocument,
|
|
407
413
|
template,
|
|
408
414
|
form,
|
|
409
415
|
pathString
|
|
410
|
-
)
|
|
416
|
+
);
|
|
411
417
|
} else {
|
|
412
|
-
existingForm.tinaForm.addQuery(payload.id)
|
|
418
|
+
existingForm.tinaForm.addQuery(payload.id);
|
|
413
419
|
const { template } = getTemplateForDocument(
|
|
414
420
|
resolvedDocument,
|
|
415
421
|
tinaSchema
|
|
416
|
-
)
|
|
417
|
-
existingForm.tinaForm.addQuery(payload.id)
|
|
422
|
+
);
|
|
423
|
+
existingForm.tinaForm.addQuery(payload.id);
|
|
418
424
|
return resolveDocument(
|
|
419
425
|
resolvedDocument,
|
|
420
426
|
template,
|
|
421
427
|
existingForm.tinaForm,
|
|
422
428
|
pathString
|
|
423
|
-
)
|
|
429
|
+
);
|
|
424
430
|
}
|
|
425
431
|
}
|
|
426
|
-
return value
|
|
432
|
+
return value;
|
|
427
433
|
},
|
|
428
|
-
})
|
|
434
|
+
});
|
|
429
435
|
if (result.errors) {
|
|
430
436
|
result.errors.forEach((error) => {
|
|
431
437
|
if (
|
|
432
438
|
error instanceof G.GraphQLError &&
|
|
433
439
|
error.originalError instanceof NoFormError
|
|
434
440
|
) {
|
|
435
|
-
const id = error.originalError.id
|
|
441
|
+
const id = error.originalError.id;
|
|
436
442
|
setDocumentsToResolve((docs) => [
|
|
437
443
|
...docs.filter((doc) => doc !== id),
|
|
438
444
|
id,
|
|
439
|
-
])
|
|
445
|
+
]);
|
|
440
446
|
} else {
|
|
441
|
-
console.log(error)
|
|
447
|
+
console.log(error);
|
|
442
448
|
// throw new Error(
|
|
443
449
|
// `Error processing value change, please contact support`
|
|
444
450
|
// )
|
|
445
451
|
}
|
|
446
|
-
})
|
|
452
|
+
});
|
|
447
453
|
} else {
|
|
448
454
|
if (result.data) {
|
|
449
455
|
setResults((results) => [
|
|
450
456
|
...results.filter((result) => result.id !== payload.id),
|
|
451
457
|
{ id: payload.id, data: result.data },
|
|
452
|
-
])
|
|
458
|
+
]);
|
|
453
459
|
}
|
|
454
460
|
if (activeField) {
|
|
455
|
-
setSearchParams({})
|
|
456
|
-
const [queryId, eventFieldName] = activeField.split('---')
|
|
461
|
+
setSearchParams({});
|
|
462
|
+
const [queryId, eventFieldName] = activeField.split('---');
|
|
457
463
|
if (queryId === payload.id) {
|
|
458
464
|
if (result?.data) {
|
|
459
465
|
cms.dispatch({
|
|
@@ -462,19 +468,19 @@ export const useGraphQLReducer = (
|
|
|
462
468
|
result.data,
|
|
463
469
|
eventFieldName
|
|
464
470
|
),
|
|
465
|
-
})
|
|
471
|
+
});
|
|
466
472
|
}
|
|
467
473
|
cms.dispatch({
|
|
468
474
|
type: 'sidebar:set-display-state',
|
|
469
475
|
value: 'openOrFull',
|
|
470
|
-
})
|
|
476
|
+
});
|
|
471
477
|
}
|
|
472
478
|
}
|
|
473
479
|
iframe.current?.contentWindow?.postMessage({
|
|
474
480
|
type: 'updateData',
|
|
475
481
|
id: payload.id,
|
|
476
482
|
data: result.data,
|
|
477
|
-
})
|
|
483
|
+
});
|
|
478
484
|
}
|
|
479
485
|
cms.dispatch({
|
|
480
486
|
type: 'form-lists:add',
|
|
@@ -484,57 +490,64 @@ export const useGraphQLReducer = (
|
|
|
484
490
|
items: formListItems,
|
|
485
491
|
formIds,
|
|
486
492
|
},
|
|
487
|
-
})
|
|
493
|
+
});
|
|
488
494
|
},
|
|
489
495
|
[
|
|
490
496
|
resolvedDocuments.map((doc) => doc._internalSys.path).join('.'),
|
|
491
497
|
activeField,
|
|
492
498
|
]
|
|
493
|
-
)
|
|
499
|
+
);
|
|
494
500
|
|
|
495
501
|
const handleMessage = React.useCallback(
|
|
496
502
|
(event: MessageEvent<PostMessage>) => {
|
|
503
|
+
if (event.data.type === 'user-select-form') {
|
|
504
|
+
cms.dispatch({
|
|
505
|
+
type: 'forms:set-active-form-id',
|
|
506
|
+
value: event.data.formId,
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
|
|
497
510
|
if (event?.data?.type === 'quick-edit') {
|
|
498
511
|
cms.dispatch({
|
|
499
512
|
type: 'set-quick-editing-supported',
|
|
500
513
|
value: event.data.value,
|
|
501
|
-
})
|
|
514
|
+
});
|
|
502
515
|
iframe.current?.contentWindow?.postMessage({
|
|
503
516
|
type: 'quickEditEnabled',
|
|
504
517
|
value: cms.state.sidebarDisplayState === 'open',
|
|
505
|
-
})
|
|
518
|
+
});
|
|
506
519
|
}
|
|
507
520
|
if (event?.data?.type === 'isEditMode') {
|
|
508
521
|
iframe?.current?.contentWindow?.postMessage({
|
|
509
522
|
type: 'tina:editMode',
|
|
510
|
-
})
|
|
523
|
+
});
|
|
511
524
|
}
|
|
512
525
|
if (event.data.type === 'field:selected') {
|
|
513
|
-
const [queryId, eventFieldName] = event.data.fieldName.split('---')
|
|
514
|
-
const result = results.find((res) => res.id === queryId)
|
|
526
|
+
const [queryId, eventFieldName] = event.data.fieldName.split('---');
|
|
527
|
+
const result = results.find((res) => res.id === queryId);
|
|
515
528
|
if (result?.data) {
|
|
516
529
|
cms.dispatch({
|
|
517
530
|
type: 'forms:set-active-field-name',
|
|
518
531
|
value: getFormAndFieldNameFromMetadata(result.data, eventFieldName),
|
|
519
|
-
})
|
|
532
|
+
});
|
|
520
533
|
}
|
|
521
534
|
cms.dispatch({
|
|
522
535
|
type: 'sidebar:set-display-state',
|
|
523
536
|
value: 'openOrFull',
|
|
524
|
-
})
|
|
537
|
+
});
|
|
525
538
|
}
|
|
526
539
|
if (event.data.type === 'close') {
|
|
527
|
-
const payloadSchema = z.object({ id: z.string() })
|
|
528
|
-
const { id } = payloadSchema.parse(event.data)
|
|
540
|
+
const payloadSchema = z.object({ id: z.string() });
|
|
541
|
+
const { id } = payloadSchema.parse(event.data);
|
|
529
542
|
setPayloads((previous) =>
|
|
530
543
|
previous.filter((payload) => payload.id !== id)
|
|
531
|
-
)
|
|
532
|
-
setResults((previous) => previous.filter((result) => result.id !== id))
|
|
544
|
+
);
|
|
545
|
+
setResults((previous) => previous.filter((result) => result.id !== id));
|
|
533
546
|
cms.forms.all().map((form) => {
|
|
534
|
-
form.removeQuery(id)
|
|
535
|
-
})
|
|
536
|
-
cms.removeOrphanedForms()
|
|
537
|
-
cms.dispatch({ type: 'form-lists:remove', value: id })
|
|
547
|
+
form.removeQuery(id);
|
|
548
|
+
});
|
|
549
|
+
cms.removeOrphanedForms();
|
|
550
|
+
cms.dispatch({ type: 'form-lists:remove', value: id });
|
|
538
551
|
}
|
|
539
552
|
if (event.data.type === 'open') {
|
|
540
553
|
const payloadSchema = z.object({
|
|
@@ -542,60 +555,66 @@ export const useGraphQLReducer = (
|
|
|
542
555
|
query: z.string(),
|
|
543
556
|
variables: z.record(z.unknown()),
|
|
544
557
|
data: z.record(z.unknown()),
|
|
545
|
-
})
|
|
546
|
-
const payload = payloadSchema.parse(event.data)
|
|
558
|
+
});
|
|
559
|
+
const payload = payloadSchema.parse(event.data);
|
|
547
560
|
setPayloads((payloads) => [
|
|
548
561
|
...payloads.filter(({ id }) => id !== payload.id),
|
|
549
562
|
payload,
|
|
550
|
-
])
|
|
563
|
+
]);
|
|
564
|
+
}
|
|
565
|
+
if (event.data.type === 'url-changed') {
|
|
566
|
+
cms.dispatch({
|
|
567
|
+
type: 'sidebar:set-loading-state',
|
|
568
|
+
value: true,
|
|
569
|
+
});
|
|
551
570
|
}
|
|
552
571
|
},
|
|
553
572
|
[cms, JSON.stringify(results)]
|
|
554
|
-
)
|
|
573
|
+
);
|
|
555
574
|
|
|
556
575
|
React.useEffect(() => {
|
|
557
576
|
payloads.forEach((payload) => {
|
|
558
577
|
if (payload.expandedData) {
|
|
559
|
-
processPayload(payload)
|
|
578
|
+
processPayload(payload);
|
|
560
579
|
}
|
|
561
|
-
})
|
|
562
|
-
}, [operationIndex])
|
|
580
|
+
});
|
|
581
|
+
}, [operationIndex]);
|
|
563
582
|
|
|
564
583
|
React.useEffect(() => {
|
|
565
584
|
return () => {
|
|
566
|
-
setPayloads([])
|
|
567
|
-
setResults([])
|
|
568
|
-
cms.removeAllForms()
|
|
569
|
-
cms.dispatch({ type: 'form-lists:clear' })
|
|
570
|
-
}
|
|
571
|
-
}, [url])
|
|
585
|
+
setPayloads([]);
|
|
586
|
+
setResults([]);
|
|
587
|
+
cms.removeAllForms();
|
|
588
|
+
cms.dispatch({ type: 'form-lists:clear' });
|
|
589
|
+
};
|
|
590
|
+
}, [url]);
|
|
572
591
|
|
|
573
592
|
React.useEffect(() => {
|
|
574
593
|
iframe.current?.contentWindow?.postMessage({
|
|
575
594
|
type: 'quickEditEnabled',
|
|
576
595
|
value: cms.state.sidebarDisplayState === 'open',
|
|
577
|
-
})
|
|
578
|
-
}, [cms.state.sidebarDisplayState])
|
|
596
|
+
});
|
|
597
|
+
}, [cms.state.sidebarDisplayState]);
|
|
579
598
|
|
|
580
599
|
React.useEffect(() => {
|
|
581
|
-
cms.dispatch({ type: 'set-edit-mode', value: 'visual' })
|
|
600
|
+
cms.dispatch({ type: 'set-edit-mode', value: 'visual' });
|
|
582
601
|
if (iframe) {
|
|
583
|
-
window.addEventListener('message', handleMessage)
|
|
602
|
+
window.addEventListener('message', handleMessage);
|
|
584
603
|
}
|
|
585
604
|
|
|
586
605
|
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)])
|
|
606
|
+
window.removeEventListener('message', handleMessage);
|
|
607
|
+
cms.removeAllForms();
|
|
608
|
+
cms.dispatch({ type: 'set-edit-mode', value: 'basic' });
|
|
609
|
+
};
|
|
610
|
+
}, [iframe.current, JSON.stringify(results)]);
|
|
592
611
|
|
|
593
612
|
React.useEffect(() => {
|
|
594
613
|
if (requestErrors.length) {
|
|
595
|
-
showErrorModal('Unexpected error querying content', requestErrors, cms)
|
|
614
|
+
showErrorModal('Unexpected error querying content', requestErrors, cms);
|
|
596
615
|
}
|
|
597
|
-
}, [requestErrors])
|
|
598
|
-
}
|
|
616
|
+
}, [requestErrors]);
|
|
617
|
+
};
|
|
599
618
|
|
|
600
619
|
const onSubmit = async (
|
|
601
620
|
collection: Collection<true>,
|
|
@@ -603,7 +622,7 @@ const onSubmit = async (
|
|
|
603
622
|
payload: Record<string, unknown>,
|
|
604
623
|
cms: TinaCMS
|
|
605
624
|
) => {
|
|
606
|
-
const tinaSchema = cms.api.tina.schema
|
|
625
|
+
const tinaSchema = cms.api.tina.schema;
|
|
607
626
|
try {
|
|
608
627
|
const mutationString = `#graphql
|
|
609
628
|
mutation UpdateDocument($collection: String!, $relativePath: String!, $params: DocumentUpdateMutation!) {
|
|
@@ -611,7 +630,7 @@ const onSubmit = async (
|
|
|
611
630
|
__typename
|
|
612
631
|
}
|
|
613
632
|
}
|
|
614
|
-
|
|
633
|
+
`;
|
|
615
634
|
|
|
616
635
|
await cms.api.tina.request(mutationString, {
|
|
617
636
|
variables: {
|
|
@@ -619,8 +638,8 @@ const onSubmit = async (
|
|
|
619
638
|
relativePath: relativePath,
|
|
620
639
|
params: tinaSchema.transformPayload(collection.name, payload),
|
|
621
640
|
},
|
|
622
|
-
})
|
|
623
|
-
cms.alerts.success('Document saved!')
|
|
641
|
+
});
|
|
642
|
+
cms.alerts.success('Document saved!');
|
|
624
643
|
} catch (e) {
|
|
625
644
|
cms.alerts.error(() =>
|
|
626
645
|
ErrorDialog({
|
|
@@ -628,12 +647,12 @@ const onSubmit = async (
|
|
|
628
647
|
message: 'Tina caught an error while updating the page',
|
|
629
648
|
error: e,
|
|
630
649
|
})
|
|
631
|
-
)
|
|
632
|
-
console.error(e)
|
|
650
|
+
);
|
|
651
|
+
console.error(e);
|
|
633
652
|
}
|
|
634
|
-
}
|
|
653
|
+
};
|
|
635
654
|
|
|
636
|
-
type Path = (string | number)[]
|
|
655
|
+
type Path = (string | number)[];
|
|
637
656
|
|
|
638
657
|
const resolveDocument = (
|
|
639
658
|
doc: ResolvedDocument,
|
|
@@ -642,20 +661,20 @@ const resolveDocument = (
|
|
|
642
661
|
pathToDocument: string
|
|
643
662
|
): ResolvedDocument => {
|
|
644
663
|
// @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 = []
|
|
664
|
+
const fields = form.fields as TinaField<true>[];
|
|
665
|
+
const id = doc._internalSys.path;
|
|
666
|
+
const path: Path = [];
|
|
648
667
|
const formValues = resolveFormValue({
|
|
649
668
|
fields: fields,
|
|
650
669
|
values: form.values,
|
|
651
670
|
path,
|
|
652
671
|
id,
|
|
653
672
|
pathToDocument,
|
|
654
|
-
})
|
|
655
|
-
const metadataFields: Record<string, string> = {}
|
|
673
|
+
});
|
|
674
|
+
const metadataFields: Record<string, string> = {};
|
|
656
675
|
Object.keys(formValues).forEach((key) => {
|
|
657
|
-
metadataFields[key] = [...path, key].join('.')
|
|
658
|
-
})
|
|
676
|
+
metadataFields[key] = [...path, key].join('.');
|
|
677
|
+
});
|
|
659
678
|
|
|
660
679
|
return {
|
|
661
680
|
...formValues,
|
|
@@ -671,8 +690,8 @@ const resolveDocument = (
|
|
|
671
690
|
_internalSys: doc._internalSys,
|
|
672
691
|
_internalValues: doc._internalValues,
|
|
673
692
|
__typename: NAMER.dataTypeName(template.namespace),
|
|
674
|
-
}
|
|
675
|
-
}
|
|
693
|
+
};
|
|
694
|
+
};
|
|
676
695
|
|
|
677
696
|
const resolveFormValue = <T extends Record<string, unknown>>({
|
|
678
697
|
fields,
|
|
@@ -682,21 +701,21 @@ const resolveFormValue = <T extends Record<string, unknown>>({
|
|
|
682
701
|
pathToDocument,
|
|
683
702
|
}: // tinaSchema,
|
|
684
703
|
{
|
|
685
|
-
fields: TinaField<true>[]
|
|
686
|
-
values: T
|
|
687
|
-
path: Path
|
|
688
|
-
id: string
|
|
689
|
-
pathToDocument: string
|
|
704
|
+
fields: TinaField<true>[];
|
|
705
|
+
values: T;
|
|
706
|
+
path: Path;
|
|
707
|
+
id: string;
|
|
708
|
+
pathToDocument: string;
|
|
690
709
|
// tinaSchema: TinaSchema
|
|
691
710
|
}): T & { __typename?: string } => {
|
|
692
|
-
const accum: Record<string, unknown> = {}
|
|
711
|
+
const accum: Record<string, unknown> = {};
|
|
693
712
|
fields.forEach((field) => {
|
|
694
|
-
const v = values[field.name]
|
|
713
|
+
const v = values[field.name];
|
|
695
714
|
if (typeof v === 'undefined') {
|
|
696
|
-
return
|
|
715
|
+
return;
|
|
697
716
|
}
|
|
698
717
|
if (v === null) {
|
|
699
|
-
return
|
|
718
|
+
return;
|
|
700
719
|
}
|
|
701
720
|
accum[field.name] = resolveFieldValue({
|
|
702
721
|
field,
|
|
@@ -704,10 +723,10 @@ const resolveFormValue = <T extends Record<string, unknown>>({
|
|
|
704
723
|
path,
|
|
705
724
|
id,
|
|
706
725
|
pathToDocument,
|
|
707
|
-
})
|
|
708
|
-
})
|
|
709
|
-
return accum as T & { __typename?: string }
|
|
710
|
-
}
|
|
726
|
+
});
|
|
727
|
+
});
|
|
728
|
+
return accum as T & { __typename?: string };
|
|
729
|
+
};
|
|
711
730
|
const resolveFieldValue = ({
|
|
712
731
|
field,
|
|
713
732
|
value,
|
|
@@ -715,11 +734,11 @@ const resolveFieldValue = ({
|
|
|
715
734
|
id,
|
|
716
735
|
pathToDocument,
|
|
717
736
|
}: {
|
|
718
|
-
field: TinaField<true
|
|
719
|
-
value: unknown
|
|
720
|
-
path: Path
|
|
721
|
-
id: string
|
|
722
|
-
pathToDocument: string
|
|
737
|
+
field: TinaField<true>;
|
|
738
|
+
value: unknown;
|
|
739
|
+
path: Path;
|
|
740
|
+
id: string;
|
|
741
|
+
pathToDocument: string;
|
|
723
742
|
}) => {
|
|
724
743
|
switch (field.type) {
|
|
725
744
|
case 'object': {
|
|
@@ -727,15 +746,17 @@ const resolveFieldValue = ({
|
|
|
727
746
|
if (field.list) {
|
|
728
747
|
if (Array.isArray(value)) {
|
|
729
748
|
return value.map((item, index) => {
|
|
730
|
-
const template = field.templates[item._template]
|
|
749
|
+
const template = field.templates[item._template];
|
|
731
750
|
if (typeof template === 'string') {
|
|
732
|
-
throw new Error('Global templates not supported')
|
|
751
|
+
throw new Error('Global templates not supported');
|
|
733
752
|
}
|
|
734
|
-
const nextPath = [...path, field.name, index]
|
|
735
|
-
const metadataFields: Record<string, string> = {}
|
|
753
|
+
const nextPath = [...path, field.name, index];
|
|
754
|
+
const metadataFields: Record<string, string> = {};
|
|
736
755
|
template.fields.forEach((field) => {
|
|
737
|
-
metadataFields[field.name] = [...nextPath, field.name].join(
|
|
738
|
-
|
|
756
|
+
metadataFields[field.name] = [...nextPath, field.name].join(
|
|
757
|
+
'.'
|
|
758
|
+
);
|
|
759
|
+
});
|
|
739
760
|
return {
|
|
740
761
|
__typename: NAMER.dataTypeName(template.namespace),
|
|
741
762
|
_tina_metadata: {
|
|
@@ -751,29 +772,29 @@ const resolveFieldValue = ({
|
|
|
751
772
|
id,
|
|
752
773
|
pathToDocument,
|
|
753
774
|
}),
|
|
754
|
-
}
|
|
755
|
-
})
|
|
775
|
+
};
|
|
776
|
+
});
|
|
756
777
|
}
|
|
757
778
|
} else {
|
|
758
779
|
// not implemented
|
|
759
780
|
}
|
|
760
781
|
}
|
|
761
782
|
|
|
762
|
-
const templateFields = field.fields
|
|
783
|
+
const templateFields = field.fields;
|
|
763
784
|
if (typeof templateFields === 'string') {
|
|
764
|
-
throw new Error('Global templates not supported')
|
|
785
|
+
throw new Error('Global templates not supported');
|
|
765
786
|
}
|
|
766
787
|
if (!templateFields) {
|
|
767
|
-
throw new Error(`Expected to find sub-fields on field ${field.name}`)
|
|
788
|
+
throw new Error(`Expected to find sub-fields on field ${field.name}`);
|
|
768
789
|
}
|
|
769
790
|
if (field.list) {
|
|
770
791
|
if (Array.isArray(value)) {
|
|
771
792
|
return value.map((item, index) => {
|
|
772
|
-
const nextPath = [...path, field.name, index]
|
|
773
|
-
const metadataFields: Record<string, string> = {}
|
|
793
|
+
const nextPath = [...path, field.name, index];
|
|
794
|
+
const metadataFields: Record<string, string> = {};
|
|
774
795
|
templateFields.forEach((field) => {
|
|
775
|
-
metadataFields[field.name] = [...nextPath, field.name].join('.')
|
|
776
|
-
})
|
|
796
|
+
metadataFields[field.name] = [...nextPath, field.name].join('.');
|
|
797
|
+
});
|
|
777
798
|
return {
|
|
778
799
|
__typename: NAMER.dataTypeName(field.namespace),
|
|
779
800
|
_tina_metadata: {
|
|
@@ -789,15 +810,15 @@ const resolveFieldValue = ({
|
|
|
789
810
|
id,
|
|
790
811
|
pathToDocument,
|
|
791
812
|
}),
|
|
792
|
-
}
|
|
793
|
-
})
|
|
813
|
+
};
|
|
814
|
+
});
|
|
794
815
|
}
|
|
795
816
|
} else {
|
|
796
|
-
const nextPath = [...path, field.name]
|
|
797
|
-
const metadataFields: Record<string, string> = {}
|
|
817
|
+
const nextPath = [...path, field.name];
|
|
818
|
+
const metadataFields: Record<string, string> = {};
|
|
798
819
|
templateFields.forEach((field) => {
|
|
799
|
-
metadataFields[field.name] = [...nextPath, field.name].join('.')
|
|
800
|
-
})
|
|
820
|
+
metadataFields[field.name] = [...nextPath, field.name].join('.');
|
|
821
|
+
});
|
|
801
822
|
return {
|
|
802
823
|
__typename: NAMER.dataTypeName(field.namespace),
|
|
803
824
|
_tina_metadata: {
|
|
@@ -813,18 +834,21 @@ const resolveFieldValue = ({
|
|
|
813
834
|
id,
|
|
814
835
|
pathToDocument,
|
|
815
836
|
}),
|
|
816
|
-
}
|
|
837
|
+
};
|
|
817
838
|
}
|
|
818
839
|
}
|
|
819
840
|
default: {
|
|
820
|
-
return value
|
|
841
|
+
return value;
|
|
821
842
|
}
|
|
822
843
|
}
|
|
823
|
-
}
|
|
844
|
+
};
|
|
824
845
|
|
|
825
846
|
const getDocument = async (id: string, tina: Client) => {
|
|
826
847
|
const response = await tina.request<{
|
|
827
|
-
node: {
|
|
848
|
+
node: {
|
|
849
|
+
_internalSys: SystemInfo;
|
|
850
|
+
_internalValues: Record<string, unknown>;
|
|
851
|
+
};
|
|
828
852
|
}>(
|
|
829
853
|
`query GetNode($id: String!) {
|
|
830
854
|
node(id: $id) {
|
|
@@ -838,6 +862,7 @@ _internalSys: _sys {
|
|
|
838
862
|
extension
|
|
839
863
|
relativePath
|
|
840
864
|
title
|
|
865
|
+
hasReferences
|
|
841
866
|
template
|
|
842
867
|
collection {
|
|
843
868
|
name
|
|
@@ -856,29 +881,29 @@ _internalSys: _sys {
|
|
|
856
881
|
}
|
|
857
882
|
}`,
|
|
858
883
|
{ variables: { id: id } }
|
|
859
|
-
)
|
|
860
|
-
return response.node
|
|
861
|
-
}
|
|
884
|
+
);
|
|
885
|
+
return response.node;
|
|
886
|
+
};
|
|
862
887
|
|
|
863
888
|
const expandPayload = async (
|
|
864
889
|
payload: Payload,
|
|
865
890
|
cms: TinaCMS
|
|
866
891
|
): 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)
|
|
892
|
+
const { query, variables } = payload;
|
|
893
|
+
const documentNode = G.parse(query);
|
|
894
|
+
const expandedDocumentNode = expandQuery({ schema, documentNode });
|
|
895
|
+
const expandedQuery = G.print(expandedDocumentNode);
|
|
871
896
|
const expandedData = await cms.api.tina.request<object>(expandedQuery, {
|
|
872
897
|
variables,
|
|
873
|
-
})
|
|
898
|
+
});
|
|
874
899
|
|
|
875
900
|
const expandedDocumentNodeForResolver = expandQuery({
|
|
876
901
|
schema: schemaForResolver,
|
|
877
902
|
documentNode,
|
|
878
|
-
})
|
|
879
|
-
const expandedQueryForResolver = G.print(expandedDocumentNodeForResolver)
|
|
880
|
-
return { ...payload, expandedQuery, expandedData, expandedQueryForResolver }
|
|
881
|
-
}
|
|
903
|
+
});
|
|
904
|
+
const expandedQueryForResolver = G.print(expandedDocumentNodeForResolver);
|
|
905
|
+
return { ...payload, expandedQuery, expandedData, expandedQueryForResolver };
|
|
906
|
+
};
|
|
882
907
|
|
|
883
908
|
/**
|
|
884
909
|
* When we resolve the graphql data we check for these errors,
|
|
@@ -886,11 +911,11 @@ const expandPayload = async (
|
|
|
886
911
|
* process it once we have that document
|
|
887
912
|
*/
|
|
888
913
|
class NoFormError extends Error {
|
|
889
|
-
id: string
|
|
914
|
+
id: string;
|
|
890
915
|
constructor(msg: string, id: string) {
|
|
891
|
-
super(msg)
|
|
892
|
-
this.id = id
|
|
893
|
-
Object.setPrototypeOf(this, NoFormError.prototype)
|
|
916
|
+
super(msg);
|
|
917
|
+
this.id = id;
|
|
918
|
+
Object.setPrototypeOf(this, NoFormError.prototype);
|
|
894
919
|
}
|
|
895
920
|
}
|
|
896
921
|
|
|
@@ -898,22 +923,22 @@ const getTemplateForDocument = (
|
|
|
898
923
|
resolvedDocument: ResolvedDocument,
|
|
899
924
|
tinaSchema: TinaSchema
|
|
900
925
|
) => {
|
|
901
|
-
const id = resolvedDocument._internalSys.path
|
|
902
|
-
let collection: Collection<true> | undefined
|
|
926
|
+
const id = resolvedDocument._internalSys.path;
|
|
927
|
+
let collection: Collection<true> | undefined;
|
|
903
928
|
try {
|
|
904
|
-
collection = tinaSchema.getCollectionByFullPath(id)
|
|
929
|
+
collection = tinaSchema.getCollectionByFullPath(id);
|
|
905
930
|
} catch (e) {}
|
|
906
931
|
|
|
907
932
|
if (!collection) {
|
|
908
|
-
throw new Error(`Unable to determine collection for path ${id}`)
|
|
933
|
+
throw new Error(`Unable to determine collection for path ${id}`);
|
|
909
934
|
}
|
|
910
935
|
|
|
911
936
|
const template = tinaSchema.getTemplateForData({
|
|
912
937
|
data: resolvedDocument._internalValues,
|
|
913
938
|
collection,
|
|
914
|
-
})
|
|
915
|
-
return { template, collection }
|
|
916
|
-
}
|
|
939
|
+
});
|
|
940
|
+
return { template, collection };
|
|
941
|
+
};
|
|
917
942
|
|
|
918
943
|
const buildForm = ({
|
|
919
944
|
resolvedDocument,
|
|
@@ -921,18 +946,18 @@ const buildForm = ({
|
|
|
921
946
|
payloadId,
|
|
922
947
|
cms,
|
|
923
948
|
}: {
|
|
924
|
-
resolvedDocument: ResolvedDocument
|
|
925
|
-
tinaSchema: TinaSchema
|
|
926
|
-
payloadId: string
|
|
927
|
-
cms: TinaCMS
|
|
949
|
+
resolvedDocument: ResolvedDocument;
|
|
950
|
+
tinaSchema: TinaSchema;
|
|
951
|
+
payloadId: string;
|
|
952
|
+
cms: TinaCMS;
|
|
928
953
|
}) => {
|
|
929
954
|
const { template, collection } = getTemplateForDocument(
|
|
930
955
|
resolvedDocument,
|
|
931
956
|
tinaSchema
|
|
932
|
-
)
|
|
933
|
-
const id = resolvedDocument._internalSys.path
|
|
934
|
-
let form: Form | undefined
|
|
935
|
-
let shouldRegisterForm = true
|
|
957
|
+
);
|
|
958
|
+
const id = resolvedDocument._internalSys.path;
|
|
959
|
+
let form: Form | undefined;
|
|
960
|
+
let shouldRegisterForm = true;
|
|
936
961
|
const formConfig: FormOptions<any> = {
|
|
937
962
|
id,
|
|
938
963
|
initialValues: resolvedDocument._internalValues,
|
|
@@ -945,10 +970,10 @@ const buildForm = ({
|
|
|
945
970
|
cms
|
|
946
971
|
),
|
|
947
972
|
label: collection.label || collection.name,
|
|
948
|
-
}
|
|
973
|
+
};
|
|
949
974
|
if (tinaSchema.config.config?.formifyCallback) {
|
|
950
975
|
const callback = tinaSchema.config.config
|
|
951
|
-
?.formifyCallback as FormifyCallback
|
|
976
|
+
?.formifyCallback as FormifyCallback;
|
|
952
977
|
form =
|
|
953
978
|
callback(
|
|
954
979
|
{
|
|
@@ -958,30 +983,30 @@ const buildForm = ({
|
|
|
958
983
|
formConfig,
|
|
959
984
|
},
|
|
960
985
|
cms
|
|
961
|
-
) || undefined
|
|
986
|
+
) || undefined;
|
|
962
987
|
if (!form) {
|
|
963
988
|
// If the form isn't created from formify, we still
|
|
964
989
|
// need it, just don't show it to the user.
|
|
965
|
-
shouldRegisterForm = false
|
|
966
|
-
form = new Form(formConfig)
|
|
990
|
+
shouldRegisterForm = false;
|
|
991
|
+
form = new Form(formConfig);
|
|
967
992
|
}
|
|
968
993
|
} else {
|
|
969
994
|
if (collection.ui?.global) {
|
|
970
|
-
form = createGlobalForm(formConfig)
|
|
995
|
+
form = createGlobalForm(formConfig);
|
|
971
996
|
} else {
|
|
972
|
-
form = createForm(formConfig)
|
|
997
|
+
form = createForm(formConfig);
|
|
973
998
|
}
|
|
974
999
|
}
|
|
975
1000
|
if (form) {
|
|
976
1001
|
if (shouldRegisterForm) {
|
|
977
1002
|
if (collection.ui?.global) {
|
|
978
|
-
cms.plugins.add(new GlobalFormPlugin(form))
|
|
1003
|
+
cms.plugins.add(new GlobalFormPlugin(form));
|
|
979
1004
|
}
|
|
980
|
-
cms.dispatch({ type: 'forms:add', value: form })
|
|
1005
|
+
cms.dispatch({ type: 'forms:add', value: form });
|
|
981
1006
|
}
|
|
982
1007
|
}
|
|
983
1008
|
if (!form) {
|
|
984
|
-
throw new Error(`No form registered for ${id}.`)
|
|
1009
|
+
throw new Error(`No form registered for ${id}.`);
|
|
985
1010
|
}
|
|
986
|
-
return { template, form }
|
|
987
|
-
}
|
|
1011
|
+
return { template, form };
|
|
1012
|
+
};
|