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