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