@aphexcms/cms-core 0.1.16 → 0.2.1

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.
Files changed (120) hide show
  1. package/dist/api/client.d.ts.map +1 -1
  2. package/dist/api/client.js +7 -1
  3. package/dist/api/types.d.ts +2 -0
  4. package/dist/api/types.d.ts.map +1 -1
  5. package/dist/cli/generate-types.js +62 -17
  6. package/dist/cli/index.js +1 -1
  7. package/dist/client/index.d.ts +0 -1
  8. package/dist/client/index.d.ts.map +1 -1
  9. package/dist/client/index.js +0 -1
  10. package/dist/components/AdminApp.svelte +278 -45
  11. package/dist/components/AdminApp.svelte.d.ts +2 -0
  12. package/dist/components/AdminApp.svelte.d.ts.map +1 -1
  13. package/dist/components/admin/DocumentEditor.svelte +60 -13
  14. package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
  15. package/dist/components/admin/ObjectModal.svelte +15 -4
  16. package/dist/components/admin/ObjectModal.svelte.d.ts +1 -0
  17. package/dist/components/admin/ObjectModal.svelte.d.ts.map +1 -1
  18. package/dist/components/admin/SchemaField.svelte +64 -5
  19. package/dist/components/admin/SchemaField.svelte.d.ts +1 -0
  20. package/dist/components/admin/SchemaField.svelte.d.ts.map +1 -1
  21. package/dist/components/admin/fields/ArrayField.svelte +402 -111
  22. package/dist/components/admin/fields/ArrayField.svelte.d.ts +1 -0
  23. package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
  24. package/dist/components/admin/fields/DateField.svelte +145 -0
  25. package/dist/components/admin/fields/DateField.svelte.d.ts +14 -0
  26. package/dist/components/admin/fields/DateField.svelte.d.ts.map +1 -0
  27. package/dist/components/admin/fields/DateTimeField.svelte +225 -0
  28. package/dist/components/admin/fields/DateTimeField.svelte.d.ts +14 -0
  29. package/dist/components/admin/fields/DateTimeField.svelte.d.ts.map +1 -0
  30. package/dist/components/admin/fields/ImageField.svelte +221 -110
  31. package/dist/components/admin/fields/ImageField.svelte.d.ts +2 -0
  32. package/dist/components/admin/fields/ImageField.svelte.d.ts.map +1 -1
  33. package/dist/components/admin/fields/ReferenceField.svelte +1 -1
  34. package/dist/components/admin/fields/SlugField.svelte +21 -13
  35. package/dist/components/admin/fields/SlugField.svelte.d.ts +2 -2
  36. package/dist/components/admin/fields/SlugField.svelte.d.ts.map +1 -1
  37. package/dist/components/admin/fields/StringField.svelte +156 -12
  38. package/dist/components/admin/fields/StringField.svelte.d.ts +3 -2
  39. package/dist/components/admin/fields/StringField.svelte.d.ts.map +1 -1
  40. package/dist/components/admin/fields/URLField.svelte +41 -0
  41. package/dist/components/admin/fields/URLField.svelte.d.ts +14 -0
  42. package/dist/components/admin/fields/URLField.svelte.d.ts.map +1 -0
  43. package/dist/components/index.d.ts +0 -1
  44. package/dist/components/index.d.ts.map +1 -1
  45. package/dist/components/index.js +0 -1
  46. package/dist/db/interfaces/asset.d.ts.map +1 -1
  47. package/dist/db/interfaces/document.d.ts +0 -2
  48. package/dist/db/interfaces/document.d.ts.map +1 -1
  49. package/dist/db/interfaces/index.d.ts +2 -1
  50. package/dist/db/interfaces/index.d.ts.map +1 -1
  51. package/dist/db/interfaces/user.d.ts +2 -0
  52. package/dist/db/interfaces/user.d.ts.map +1 -1
  53. package/dist/db/utils/reference-resolver.js +1 -1
  54. package/dist/engine.d.ts.map +1 -1
  55. package/dist/engine.js +3 -0
  56. package/dist/field-validation/date-utils.d.ts +30 -0
  57. package/dist/field-validation/date-utils.d.ts.map +1 -0
  58. package/dist/field-validation/date-utils.js +147 -0
  59. package/dist/field-validation/rule.d.ts +4 -0
  60. package/dist/field-validation/rule.d.ts.map +1 -1
  61. package/dist/field-validation/rule.js +170 -4
  62. package/dist/field-validation/utils.d.ts +7 -3
  63. package/dist/field-validation/utils.d.ts.map +1 -1
  64. package/dist/field-validation/utils.js +130 -38
  65. package/dist/hooks.d.ts.map +1 -1
  66. package/dist/hooks.js +38 -21
  67. package/dist/lib/field-validation/date-utils.js +147 -0
  68. package/dist/lib/field-validation/rule.js +170 -4
  69. package/dist/lib/field-validation/utils.js +130 -38
  70. package/dist/local-api/collection-api.d.ts +16 -4
  71. package/dist/local-api/collection-api.d.ts.map +1 -1
  72. package/dist/local-api/collection-api.js +51 -17
  73. package/dist/local-api/index.d.ts +1 -1
  74. package/dist/local-api/index.d.ts.map +1 -1
  75. package/dist/routes/assets-cdn.d.ts.map +1 -1
  76. package/dist/routes/assets-cdn.js +14 -7
  77. package/dist/routes/assets.d.ts.map +1 -1
  78. package/dist/routes/assets.js +6 -1
  79. package/dist/routes/documents-by-id.d.ts.map +1 -1
  80. package/dist/routes/documents-by-id.js +18 -7
  81. package/dist/routes/documents-publish.js +2 -2
  82. package/dist/routes/documents-query.d.ts +3 -1
  83. package/dist/routes/documents-query.d.ts.map +1 -1
  84. package/dist/routes/documents-query.js +6 -2
  85. package/dist/routes/documents.d.ts.map +1 -1
  86. package/dist/routes/documents.js +20 -4
  87. package/dist/routes/index.d.ts +1 -0
  88. package/dist/routes/index.d.ts.map +1 -1
  89. package/dist/routes/index.js +2 -0
  90. package/dist/routes/user-preferences.d.ts +4 -0
  91. package/dist/routes/user-preferences.d.ts.map +1 -0
  92. package/dist/routes/user-preferences.js +77 -0
  93. package/dist/schema-utils/utils.d.ts +4 -0
  94. package/dist/schema-utils/utils.d.ts.map +1 -1
  95. package/dist/schema-utils/utils.js +23 -2
  96. package/dist/schema-utils/validator.d.ts +4 -0
  97. package/dist/schema-utils/validator.d.ts.map +1 -1
  98. package/dist/schema-utils/validator.js +120 -0
  99. package/dist/types/filters.d.ts +13 -0
  100. package/dist/types/filters.d.ts.map +1 -1
  101. package/dist/types/organization.d.ts +3 -0
  102. package/dist/types/organization.d.ts.map +1 -1
  103. package/dist/types/schemas.d.ts +67 -7
  104. package/dist/types/schemas.d.ts.map +1 -1
  105. package/dist/utils/default-orderings.d.ts +10 -0
  106. package/dist/utils/default-orderings.d.ts.map +1 -0
  107. package/dist/utils/default-orderings.js +63 -0
  108. package/dist/utils/field-defaults.d.ts +8 -0
  109. package/dist/utils/field-defaults.d.ts.map +1 -0
  110. package/dist/utils/field-defaults.js +20 -0
  111. package/dist/utils/index.d.ts +1 -0
  112. package/dist/utils/index.d.ts.map +1 -1
  113. package/dist/utils/index.js +1 -0
  114. package/dist/utils/initial-value-helpers.d.ts +50 -0
  115. package/dist/utils/initial-value-helpers.d.ts.map +1 -0
  116. package/dist/utils/initial-value-helpers.js +70 -0
  117. package/package.json +6 -4
  118. package/dist/components/admin/DocumentTypesList.svelte +0 -97
  119. package/dist/components/admin/DocumentTypesList.svelte.d.ts +0 -14
  120. package/dist/components/admin/DocumentTypesList.svelte.d.ts.map +0 -1
@@ -21,6 +21,8 @@
21
21
  schemaType?: string;
22
22
  fieldPath?: string;
23
23
  readonly?: boolean;
24
+ compact?: boolean; // Compact mode for arrays
25
+ organizationId?: string; // Document's organization ID for asset uploads
24
26
  }
25
27
 
26
28
  let {
@@ -30,7 +32,9 @@
30
32
  validationClasses,
31
33
  schemaType,
32
34
  fieldPath,
33
- readonly = false
35
+ readonly = false,
36
+ compact = false,
37
+ organizationId
34
38
  }: Props = $props();
35
39
 
36
40
  // Component state
@@ -48,6 +52,9 @@
48
52
  const formData = new FormData();
49
53
  formData.append('file', file);
50
54
 
55
+ // Add document's organization ID so asset belongs to document's org
56
+ if (organizationId) formData.append('organizationId', organizationId);
57
+
51
58
  // Add field metadata for privacy checking
52
59
  if (schemaType) formData.append('schemaType', schemaType);
53
60
  if (fieldPath) formData.append('fieldPath', fieldPath);
@@ -81,7 +88,7 @@
81
88
  async function handleFileSelect(files: FileList | null) {
82
89
  if (readonly || !files || files.length === 0) return;
83
90
 
84
- const file = files[0];
91
+ const file = files[0]!;
85
92
 
86
93
  const imageValue = await uploadFile(file);
87
94
  if (imageValue) {
@@ -169,6 +176,11 @@
169
176
 
170
177
  // Get asset URL for preview
171
178
  const previewUrl = $derived(assetData?.url || null);
179
+
180
+ // Get display name for the image
181
+ const displayName = $derived(
182
+ assetData?.originalFilename || assetData?.filename || value?.asset?._ref || 'Image'
183
+ );
172
184
  </script>
173
185
 
174
186
  <!-- Hidden file input -->
@@ -180,138 +192,237 @@
180
192
  onchange={handleFileInputChange}
181
193
  />
182
194
 
183
- {#if value && value.asset}
184
- <!-- Image preview with controls -->
185
- <div class="border-border overflow-hidden rounded-md border {validationClasses}">
186
- <div class="group relative">
187
- <!-- Image preview (Sanity-style aspect ratio ~2.75:1) -->
188
- <div class="bg-muted flex items-center justify-center" style="aspect-ratio: 2.75 / 1;">
195
+ {#if compact}
196
+ <!-- Compact mode for arrays -->
197
+ {#if value && value.asset}
198
+ <!-- Compact image row with thumbnail -->
199
+ <div class="border-border flex items-center gap-3 rounded-md border p-2 {validationClasses}">
200
+ <!-- Thumbnail -->
201
+ <div
202
+ class="bg-muted flex h-12 w-12 flex-shrink-0 items-center justify-center overflow-hidden rounded"
203
+ >
189
204
  {#if loadingAsset}
190
- <div class="text-muted-foreground flex flex-col items-center gap-2">
191
- <div class="border-primary h-8 w-8 animate-spin rounded-full border-b-2"></div>
192
- <span class="text-sm">Loading image...</span>
193
- </div>
205
+ <div class="border-primary h-4 w-4 animate-spin rounded-full border-b-2"></div>
194
206
  {:else if previewUrl}
195
207
  <img
196
208
  src={previewUrl}
197
- alt={assetData?.alt || 'Uploaded image'}
198
- class="h-full w-full object-contain"
209
+ alt={assetData?.alt || displayName}
210
+ class="h-full w-full object-cover"
199
211
  loading="lazy"
200
212
  />
201
213
  {:else}
202
- <div class="text-muted-foreground flex flex-col items-center gap-2">
203
- <ImageIcon size={32} />
204
- <span class="text-sm">Image: {value.asset._ref}</span>
205
- <span class="text-xs">Failed to load preview</span>
206
- </div>
214
+ <ImageIcon size={20} class="text-muted-foreground" />
207
215
  {/if}
208
216
  </div>
209
217
 
210
- <!-- Overlay controls (hidden for read-only) -->
218
+ <!-- File name -->
219
+ <div class="flex-1 overflow-hidden">
220
+ <p class="truncate text-sm font-medium">{displayName}</p>
221
+ {#if assetData?.size}
222
+ <p class="text-muted-foreground text-xs">
223
+ {(assetData.size / 1024).toFixed(1)} KB
224
+ </p>
225
+ {/if}
226
+ </div>
227
+
228
+ <!-- Options menu -->
211
229
  {#if !readonly}
212
- <div class="absolute inset-2 flex items-start justify-end gap-2">
213
- <DropdownMenu>
214
- <DropdownMenuTrigger><Ellipsis /></DropdownMenuTrigger>
215
- <DropdownMenuContent>
216
- <DropdownMenuGroup>
217
- <DropdownMenuLabel
218
- ><Button
219
- variant="secondary"
220
- size="sm"
221
- onclick={openFileDialog}
222
- disabled={isUploading}
223
- >
224
- <Upload size={16} class="mr-1" />
225
- Replace
226
- </Button></DropdownMenuLabel
230
+ <DropdownMenu>
231
+ <DropdownMenuTrigger>
232
+ <Button variant="ghost" size="sm" class="h-8 w-8 p-0">
233
+ <Ellipsis size={16} />
234
+ </Button>
235
+ </DropdownMenuTrigger>
236
+ <DropdownMenuContent align="end">
237
+ <DropdownMenuGroup>
238
+ <DropdownMenuLabel>
239
+ <Button
240
+ variant="ghost"
241
+ size="sm"
242
+ onclick={openFileDialog}
243
+ disabled={isUploading}
244
+ class="w-full justify-start"
227
245
  >
228
- <DropdownMenuLabel
229
- ><Button
230
- variant="destructive"
231
- size="sm"
232
- onclick={removeImage}
233
- disabled={isUploading}
234
- >
235
- <Trash2 size={16} class="mr-1" />
236
- Remove
237
- </Button></DropdownMenuLabel
246
+ <Upload size={16} class="mr-2" />
247
+ Replace
248
+ </Button>
249
+ </DropdownMenuLabel>
250
+ <DropdownMenuLabel>
251
+ <Button
252
+ variant="ghost"
253
+ size="sm"
254
+ onclick={removeImage}
255
+ disabled={isUploading}
256
+ class="text-destructive hover:text-destructive w-full justify-start"
238
257
  >
239
- </DropdownMenuGroup>
240
- </DropdownMenuContent>
241
- </DropdownMenu>
242
- </div>
258
+ <Trash2 size={16} class="mr-2" />
259
+ Remove
260
+ </Button>
261
+ </DropdownMenuLabel>
262
+ </DropdownMenuGroup>
263
+ </DropdownMenuContent>
264
+ </DropdownMenu>
243
265
  {/if}
244
266
  </div>
245
-
246
- <!-- Additional image controls/metadata could go here -->
247
- {#if field.fields}
248
- <div class="border-border space-y-2 border-t p-3">
249
- <!-- Custom fields like caption, alt text, etc. would be rendered here -->
250
- <p class="text-muted-foreground text-xs">Custom fields coming soon...</p>
251
- </div>
252
- {/if}
253
- </div>
267
+ {:else}
268
+ <!-- Compact upload button -->
269
+ <Button
270
+ variant="outline"
271
+ class="w-full justify-start"
272
+ onclick={openFileDialog}
273
+ disabled={isUploading || readonly}
274
+ type="button"
275
+ >
276
+ {#if isUploading}
277
+ <div class="border-primary mr-2 h-4 w-4 animate-spin rounded-full border-b-2"></div>
278
+ Uploading...
279
+ {:else}
280
+ <Upload size={16} class="mr-2" />
281
+ Upload Image
282
+ {/if}
283
+ </Button>
284
+ {/if}
254
285
  {:else}
255
- <!-- Sanity-style upload bar -->
256
- <div class="border-border overflow-hidden rounded-md border {validationClasses}">
257
- <div class="flex items-center">
258
- <!-- Drag and drop area (left side) -->
259
- <div
260
- class="flex-1 px-4 py-3 transition-colors {readonly
261
- ? ''
262
- : isDragging
263
- ? 'bg-primary/5'
264
- : 'hover:bg-muted/50'}"
265
- ondragover={readonly ? undefined : handleDragOver}
266
- ondragleave={readonly ? undefined : handleDragLeave}
267
- ondrop={readonly ? undefined : handleDrop}
268
- tabindex={readonly ? -1 : 0}
269
- role={readonly ? undefined : 'button'}
270
- >
271
- {#if isUploading}
272
- <div class="flex items-center gap-3">
273
- <div class="border-primary h-5 w-5 animate-spin rounded-full border-b-2"></div>
274
- <span class="text-muted-foreground text-sm">Uploading...</span>
275
- </div>
276
- {:else}
277
- <div class="flex items-center gap-3">
278
- <FileImage size={20} class="text-muted-foreground" />
279
- <span class="text-muted-foreground text-sm">
280
- {readonly ? 'No image' : isDragging ? 'Drop image here' : 'Drag or paste image here'}
281
- </span>
286
+ <!-- Full mode (original) -->
287
+ {#if value && value.asset}
288
+ <!-- Image preview with controls -->
289
+ <div class="border-border overflow-hidden rounded-md border {validationClasses}">
290
+ <div class="group relative">
291
+ <!-- Image preview (Sanity-style aspect ratio ~2.75:1) -->
292
+ <div class="bg-muted flex items-center justify-center" style="aspect-ratio: 2.75 / 1;">
293
+ {#if loadingAsset}
294
+ <div class="text-muted-foreground flex flex-col items-center gap-2">
295
+ <div class="border-primary h-8 w-8 animate-spin rounded-full border-b-2"></div>
296
+ <span class="text-sm">Loading image...</span>
297
+ </div>
298
+ {:else if previewUrl}
299
+ <img
300
+ src={previewUrl}
301
+ alt={assetData?.alt || 'Uploaded image'}
302
+ class="h-full w-full object-contain"
303
+ loading="lazy"
304
+ />
305
+ {:else}
306
+ <div class="text-muted-foreground flex flex-col items-center gap-2">
307
+ <ImageIcon size={32} />
308
+ <span class="text-sm">Image: {value.asset._ref}</span>
309
+ <span class="text-xs">Failed to load preview</span>
310
+ </div>
311
+ {/if}
312
+ </div>
313
+
314
+ <!-- Overlay controls (hidden for read-only) -->
315
+ {#if !readonly}
316
+ <div class="absolute inset-2 flex items-start justify-end gap-2">
317
+ <DropdownMenu>
318
+ <DropdownMenuTrigger><Ellipsis /></DropdownMenuTrigger>
319
+ <DropdownMenuContent>
320
+ <DropdownMenuGroup>
321
+ <DropdownMenuLabel
322
+ ><Button
323
+ variant="secondary"
324
+ size="sm"
325
+ onclick={openFileDialog}
326
+ disabled={isUploading}
327
+ >
328
+ <Upload size={16} class="mr-1" />
329
+ Replace
330
+ </Button></DropdownMenuLabel
331
+ >
332
+ <DropdownMenuLabel
333
+ ><Button
334
+ variant="destructive"
335
+ size="sm"
336
+ onclick={removeImage}
337
+ disabled={isUploading}
338
+ >
339
+ <Trash2 size={16} class="mr-1" />
340
+ Remove
341
+ </Button></DropdownMenuLabel
342
+ >
343
+ </DropdownMenuGroup>
344
+ </DropdownMenuContent>
345
+ </DropdownMenu>
282
346
  </div>
283
347
  {/if}
284
348
  </div>
285
349
 
286
- <!-- Buttons (right side) -->
287
- <div class="border-border bg-muted/20 flex items-center gap-2 border-l px-3 py-2">
288
- <Button
289
- variant="outline"
290
- size="sm"
291
- onclick={openFileDialog}
292
- disabled={isUploading || readonly}
293
- type="button"
350
+ <!-- Additional image controls/metadata could go here -->
351
+ {#if field.fields}
352
+ <div class="border-border space-y-2 border-t p-3">
353
+ <!-- Custom fields like caption, alt text, etc. would be rendered here -->
354
+ <p class="text-muted-foreground text-xs">Custom fields coming soon...</p>
355
+ </div>
356
+ {/if}
357
+ </div>
358
+ {:else}
359
+ <!-- Sanity-style upload bar -->
360
+ <div class="border-border overflow-hidden rounded-md border {validationClasses}">
361
+ <div class="flex flex-col items-center divide-y lg:flex-row lg:divide-x lg:divide-y-0">
362
+ <!-- Drag and drop area (left side) -->
363
+ <div
364
+ class="flex h-14 w-full px-3 py-4 transition-colors lg:flex-1 {readonly
365
+ ? ''
366
+ : isDragging
367
+ ? 'bg-primary/5'
368
+ : 'hover:bg-muted/50'}"
369
+ ondragover={readonly ? undefined : handleDragOver}
370
+ ondragleave={readonly ? undefined : handleDragLeave}
371
+ ondrop={readonly ? undefined : handleDrop}
372
+ tabindex={readonly ? -1 : 0}
373
+ role={readonly ? undefined : 'button'}
294
374
  >
295
- <Upload size={16} class="mr-1" />
296
- Upload
297
- </Button>
298
-
299
- <Button
300
- variant="outline"
301
- size="sm"
302
- disabled={isUploading || readonly}
303
- type="button"
304
- onclick={() => {
305
- // TODO: Open asset browser/selector
306
- console.log('Open asset selector');
307
- }}
375
+ {#if isUploading}
376
+ <div class="flex items-center gap-3">
377
+ <div class="border-primary h-5 w-5 animate-spin rounded-full border-b-2"></div>
378
+ <span class="text-muted-foreground text-sm">Uploading...</span>
379
+ </div>
380
+ {:else}
381
+ <div class="flex items-center gap-3">
382
+ <FileImage size={20} class="text-muted-foreground" />
383
+ <span class="text-muted-foreground text-sm">
384
+ {readonly
385
+ ? 'No image'
386
+ : isDragging
387
+ ? 'Drop image here'
388
+ : 'Drag or paste image here'}
389
+ </span>
390
+ </div>
391
+ {/if}
392
+ </div>
393
+
394
+ <!-- Buttons (right side) -->
395
+ <div
396
+ class="border-border bg-muted/20 flex h-14 w-full items-center justify-center gap-2 px-3 py-4 lg:w-1/2"
308
397
  >
309
- <ImageIcon size={16} class="mr-1" />
310
- Select
311
- </Button>
398
+ <Button
399
+ variant="outline"
400
+ size="sm"
401
+ onclick={openFileDialog}
402
+ disabled={isUploading || readonly}
403
+ type="button"
404
+ >
405
+ <Upload size={16} class="mr-1" />
406
+ Upload
407
+ </Button>
408
+
409
+ <Button
410
+ variant="outline"
411
+ size="sm"
412
+ disabled={isUploading || readonly}
413
+ type="button"
414
+ onclick={() => {
415
+ // TODO: Open asset browser/selector
416
+ console.log('Open asset selector');
417
+ }}
418
+ >
419
+ <ImageIcon size={16} class="mr-1" />
420
+ Select
421
+ </Button>
422
+ </div>
312
423
  </div>
313
424
  </div>
314
- </div>
425
+ {/if}
315
426
  {/if}
316
427
 
317
428
  <!-- Error display -->
@@ -8,6 +8,8 @@ interface Props {
8
8
  schemaType?: string;
9
9
  fieldPath?: string;
10
10
  readonly?: boolean;
11
+ compact?: boolean;
12
+ organizationId?: string;
11
13
  }
12
14
  declare const ImageField: import("svelte").Component<Props, {}, "">;
13
15
  type ImageField = ReturnType<typeof ImageField>;
@@ -1 +1 @@
1
- {"version":3,"file":"ImageField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ImageField.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAY1E,UAAU,KAAK;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAyQF,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ImageField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/ImageField.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAY1E,UAAU,KAAK;IACd,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAyVF,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -112,7 +112,7 @@
112
112
  try {
113
113
  const result = await documents.create({
114
114
  type: targetType,
115
- draftData: {
115
+ data: {
116
116
  title: 'Untitled'
117
117
  }
118
118
  });
@@ -1,11 +1,11 @@
1
1
  <script lang="ts">
2
2
  import { Input } from '@aphexcms/ui/shadcn/input';
3
3
  import { Button } from '@aphexcms/ui/shadcn/button';
4
- import type { Field } from '../../../types/schemas';
4
+ import type { SlugField } from '../../../types/schemas';
5
5
  import { generateSlug } from '../../../utils/index';
6
6
 
7
7
  interface Props {
8
- field: Field;
8
+ field: SlugField;
9
9
  value: any;
10
10
  documentData?: Record<string, any>;
11
11
  onUpdate: (value: any) => void;
@@ -26,15 +26,21 @@
26
26
  readonly = false
27
27
  }: Props = $props();
28
28
 
29
+ // Get the source field name (default to 'title' for backwards compatibility)
30
+ const sourceField = $derived(field.source || 'title');
31
+
32
+ // Get the source value from document data
33
+ const sourceValue = $derived(documentData?.[sourceField]);
34
+
29
35
  function handleInputChange(event: Event) {
30
36
  const target = event.target as HTMLInputElement;
31
37
  onUpdate(target.value);
32
38
  }
33
39
 
34
- // Generate slug from title
35
- function generateSlugFromTitle() {
36
- if (documentData?.title) {
37
- const generatedSlug = generateSlug(documentData.title);
40
+ // Generate slug from source field
41
+ function generateSlugFromSource() {
42
+ if (sourceValue && typeof sourceValue === 'string') {
43
+ const generatedSlug = generateSlug(sourceValue);
38
44
  onUpdate(generatedSlug);
39
45
  }
40
46
  }
@@ -55,20 +61,22 @@
55
61
  <Button
56
62
  variant="outline"
57
63
  size="sm"
58
- onclick={generateSlugFromTitle}
59
- disabled={!documentData?.title || readonly}
64
+ onclick={generateSlugFromSource}
65
+ disabled={!sourceValue || readonly}
60
66
  class="shrink-0"
61
67
  >
62
- Generate from Title
68
+ Generate
63
69
  </Button>
64
70
  </div>
65
- {#if documentData?.title}
71
+ {#if sourceValue}
66
72
  <p class="text-muted-foreground text-xs">
67
- Click "Generate from Title" to create slug from: "{documentData.title}"
73
+ Click "Generate" to create slug from {sourceField}: "{sourceValue}"
68
74
  </p>
69
- {:else}
75
+ {:else if field.source}
70
76
  <p class="text-muted-foreground text-xs">
71
- Enter a title first to generate a slug automatically
77
+ Enter a {sourceField} first to generate a slug automatically
72
78
  </p>
79
+ {:else}
80
+ <p class="text-muted-foreground text-xs">Click "Generate" or enter a custom slug</p>
73
81
  {/if}
74
82
  </div>
@@ -1,6 +1,6 @@
1
- import type { Field } from '../../../types/schemas.js';
1
+ import type { SlugField } from '../../../types/schemas.js';
2
2
  interface Props {
3
- field: Field;
3
+ field: SlugField;
4
4
  value: any;
5
5
  documentData?: Record<string, any>;
6
6
  onUpdate: (value: any) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"SlugField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/SlugField.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAInD,UAAU,KAAK;IACd,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,GAAG,CAAC;IACX,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAqDF,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"SlugField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/SlugField.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAIvD,UAAU,KAAK;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC;IACX,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AA6DF,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}