@kyro-cms/admin 0.10.14 → 0.10.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kyro-cms/admin",
3
- "version": "0.10.14",
3
+ "version": "0.10.18",
4
4
  "engines": {
5
5
  "node": ">=22"
6
6
  },
@@ -272,7 +272,9 @@ export function AutoForm({
272
272
 
273
273
  const result = await resp.json();
274
274
  if (result.data) {
275
- const restoredData = { ...formData, ...result.data };
275
+ // Omit historical timestamps so OCC doesn't panic on save
276
+ const { updatedAt, createdAt, ...historicalData } = result.data;
277
+ const restoredData = { ...formData, ...historicalData };
276
278
  setFormData(restoredData);
277
279
  useAutoFormStore.getState().loadDocument(restoredData, restoredData);
278
280
  onActionSuccess?.("Version restored successfully");
@@ -33,7 +33,7 @@ export function AutoFormApiView({
33
33
  <label className="text-[10px] font-bold tracking-[0.1em] text-[var(--kyro-text-secondary)] opacity-50 block mb-2">
34
34
  Reference Path
35
35
  </label>
36
- <div className="bg-[var(--kyro-bg-secondary)] px-4 py-3 rounded-xl border border-[var(--kyro-border)] text-[11px] font-mono break-all selection:bg-[var(--kyro-primary)]/20 text-[var(--kyro-text-primary)]">
36
+ <div className="bg-[var(--kyro-bg-secondary)] px-4 py-3 rounded-md border border-[var(--kyro-border)] text-[11px] font-mono break-all selection:bg-[var(--kyro-primary)]/20 text-[var(--kyro-text-primary)]">
37
37
  {globalSlug
38
38
  ? `kyro.globals('${globalSlug}').get()`
39
39
  : formData.id
@@ -167,7 +167,7 @@ export function AutoFormVersionView({
167
167
  )}
168
168
  </div>
169
169
  <div className="text-[11px] text-[var(--kyro-text-muted)]">
170
- {new Date(v.createdAt as string).toLocaleString("en-US", {
170
+ {new Date((v.createdAt || (v as any).created_at) as string).toLocaleString("en-US", {
171
171
  month: "short",
172
172
  day: "numeric",
173
173
  hour: "2-digit",
@@ -236,7 +236,7 @@ export function AutoFormVersionView({
236
236
  </div>
237
237
  <div className="flex items-center gap-2 mt-1 flex-wrap">
238
238
  <span className="text-[11px] text-[var(--kyro-text-muted)]">
239
- {new Date(v.createdAt as string).toLocaleString("en-US", {
239
+ {new Date((v.createdAt || (v as any).created_at) as string).toLocaleString("en-US", {
240
240
  month: "short",
241
241
  day: "numeric",
242
242
  hour: "2-digit",
@@ -8,9 +8,7 @@ import { CodeBlock } from "../../blocks/CodeBlock";
8
8
  import { FileBlock } from "../../blocks/FileBlock";
9
9
  import { AccordionBlock } from "../../blocks/AccordionBlock";
10
10
  import { RichTextBlock } from "../../blocks/RichTextBlock";
11
-
12
11
  import { HeroBlock } from "../../blocks/HeroBlock";
13
- import { HeadingSubheadingBlock } from "../../blocks/HeadingSubheadingBlock";
14
12
  import { CardBlock } from "../../blocks/CardBlock";
15
13
  import { ArrayBlock } from "../../blocks/ArrayBlock";
16
14
  import { RelationshipBlock } from "../../blocks/RelationshipBlock";
@@ -53,7 +51,6 @@ export const BLOCK_COMPONENTS: Record<string, React.ComponentType<{ block: Recor
53
51
  richtext: RichTextBlock,
54
52
 
55
53
  hero: HeroBlock,
56
- "heading-subheading": HeadingSubheadingBlock,
57
54
  card: CardBlock,
58
55
  array: ArrayBlock,
59
56
  relationship: RelationshipBlock,
@@ -61,19 +58,19 @@ export const BLOCK_COMPONENTS: Record<string, React.ComponentType<{ block: Recor
61
58
 
62
59
  // Block Theme mapping for consistent coloring across UI
63
60
  export const blockTheme: Record<string, { text: string; border: string; borderLeft: string }> = {
64
- "feature-split": { text: "text-indigo-500", border: "border-indigo-500", borderLeft: "border-l-indigo-500" },
65
- "feature-grid": { text: "text-blue-500", border: "border-blue-500", borderLeft: "border-l-blue-500" },
66
- "cta-banner": { text: "text-amber-500", border: "border-amber-500", borderLeft: "border-l-amber-500" },
61
+ featureSplit: { text: "text-indigo-500", border: "border-indigo-500", borderLeft: "border-l-indigo-500" },
62
+ featureGrid: { text: "text-blue-500", border: "border-blue-500", borderLeft: "border-l-blue-500" },
63
+ ctaBanner: { text: "text-amber-500", border: "border-amber-500", borderLeft: "border-l-amber-500" },
67
64
  testimonials: { text: "text-emerald-500", border: "border-emerald-500", borderLeft: "border-l-emerald-500" },
68
65
  faq: { text: "text-orange-500", border: "border-orange-500", borderLeft: "border-l-orange-500" },
69
66
  stats: { text: "text-rose-500", border: "border-rose-500", borderLeft: "border-l-rose-500" },
70
- "logo-cloud": { text: "text-cyan-500", border: "border-cyan-500", borderLeft: "border-l-cyan-500" },
67
+ logoCloud: { text: "text-cyan-500", border: "border-cyan-500", borderLeft: "border-l-cyan-500" },
71
68
  pricing: { text: "text-green-500", border: "border-green-500", borderLeft: "border-l-green-500" },
72
69
  team: { text: "text-violet-500", border: "border-violet-500", borderLeft: "border-l-violet-500" },
73
- "recent-feed": { text: "text-sky-500", border: "border-sky-500", borderLeft: "border-l-sky-500" },
74
- "process-steps": { text: "text-fuchsia-500", border: "border-fuchsia-500", borderLeft: "border-l-fuchsia-500" },
75
- "form-embed": { text: "text-pink-500", border: "border-pink-500", borderLeft: "border-l-pink-500" },
76
- "video-showcase": { text: "text-red-500", border: "border-red-500", borderLeft: "border-l-red-500" },
70
+ recentFeed: { text: "text-sky-500", border: "border-sky-500", borderLeft: "border-l-sky-500" },
71
+ processSteps: { text: "text-fuchsia-500", border: "border-fuchsia-500", borderLeft: "border-l-fuchsia-500" },
72
+ formEmbed: { text: "text-pink-500", border: "border-pink-500", borderLeft: "border-l-pink-500" },
73
+ videoShowcase: { text: "text-red-500", border: "border-red-500", borderLeft: "border-l-red-500" },
77
74
  hero: { text: "text-yellow-500", border: "border-yellow-500", borderLeft: "border-l-yellow-500" },
78
75
  card: { text: "text-teal-500", border: "border-teal-500", borderLeft: "border-l-teal-500" },
79
76
  default: { text: "text-zinc-400", border: "border-zinc-400", borderLeft: "border-l-zinc-400" },
@@ -92,25 +89,24 @@ export const blockIcons: Record<string, React.ReactNode> = {
92
89
  richtext: <AlignLeft className={`w-4 h-4 ${blockTheme.default.text}`} />,
93
90
 
94
91
  hero: <Star className={`w-4 h-4 ${blockTheme.hero.text}`} />,
95
- "heading-subheading": <Heading1 className={`w-4 h-4 ${blockTheme.default.text}`} />,
96
92
  card: <Box className={`w-4 h-4 ${blockTheme.card.text}`} />,
97
93
  array: <ListOrdered className={`w-4 h-4 ${blockTheme.default.text}`} />,
98
94
  relationship: <Link2 className={`w-4 h-4 ${blockTheme.default.text}`} />,
99
95
 
100
96
  // New Block Icons
101
- "feature-split": <Columns3 className={`w-4 h-4 ${blockTheme["feature-split"].text}`} />,
102
- "feature-grid": <Blocks className={`w-4 h-4 ${blockTheme["feature-grid"].text}`} />,
103
- "cta-banner": <Sparkles className={`w-4 h-4 ${blockTheme["cta-banner"].text}`} />,
97
+ featureSplit: <Columns3 className={`w-4 h-4 ${blockTheme.featureSplit.text}`} />,
98
+ featureGrid: <Blocks className={`w-4 h-4 ${blockTheme.featureGrid.text}`} />,
99
+ ctaBanner: <Sparkles className={`w-4 h-4 ${blockTheme.ctaBanner.text}`} />,
104
100
  testimonials: <Users className={`w-4 h-4 ${blockTheme.testimonials.text}`} />,
105
101
  faq: <HelpCircle className={`w-4 h-4 ${blockTheme.faq.text}`} />,
106
102
  stats: <Activity className={`w-4 h-4 ${blockTheme.stats.text}`} />,
107
- "logo-cloud": <Image className={`w-4 h-4 ${blockTheme["logo-cloud"].text}`} />,
103
+ logoCloud: <Image className={`w-4 h-4 ${blockTheme.logoCloud.text}`} />,
108
104
  pricing: <Tag className={`w-4 h-4 ${blockTheme.pricing.text}`} />,
109
105
  team: <Users className={`w-4 h-4 ${blockTheme.team.text}`} />,
110
- "recent-feed": <Database className={`w-4 h-4 ${blockTheme["recent-feed"].text}`} />,
111
- "process-steps": <Clock className={`w-4 h-4 ${blockTheme["process-steps"].text}`} />,
112
- "form-embed": <Mail className={`w-4 h-4 ${blockTheme["form-embed"].text}`} />,
113
- "video-showcase": <Video className={`w-4 h-4 ${blockTheme["video-showcase"].text}`} />,
106
+ recentFeed: <Database className={`w-4 h-4 ${blockTheme.recentFeed.text}`} />,
107
+ processSteps: <Clock className={`w-4 h-4 ${blockTheme.processSteps.text}`} />,
108
+ formEmbed: <Mail className={`w-4 h-4 ${blockTheme.formEmbed.text}`} />,
109
+ videoShowcase: <Video className={`w-4 h-4 ${blockTheme.videoShowcase.text}`} />,
114
110
  };
115
111
 
116
112
  // Internal utility to check if block has a specific custom react component
@@ -121,9 +117,9 @@ export function getBlockComponent(type: string) {
121
117
  // Determines if block is a native layout requiring generic rendering
122
118
  export function isGenericSemanticBlock(type: string) {
123
119
  return [
124
- "feature-split", "feature-grid", "cta-banner",
125
- "testimonials", "faq", "stats", "logo-cloud",
126
- "pricing", "team", "recent-feed", "process-steps", "form-embed", "video-showcase"
120
+ "featureSplit", "featureGrid", "ctaBanner",
121
+ "testimonials", "faq", "stats", "logoCloud",
122
+ "pricing", "team", "recentFeed", "processSteps", "formEmbed", "videoShowcase"
127
123
  ].includes(type);
128
124
  }
129
125
 
@@ -145,32 +141,31 @@ export function getBlockLabel(type: string): string {
145
141
 
146
142
  // Core Semantic Blocks
147
143
  hero: "Hero Section",
148
- "heading-subheading": "Heading + Subheading",
149
144
  card: "Card Block",
150
- "feature-split": "Feature Split",
151
- "feature-grid": "Feature Grid",
152
- "cta-banner": "CTA Banner",
145
+ featureSplit: "Feature Split",
146
+ featureGrid: "Feature Grid",
147
+ ctaBanner: "CTA Banner",
153
148
  testimonials: "Testimonials Stack",
154
149
  faq: "FAQ Section",
155
150
  stats: "Stats & Metrics",
156
- "logo-cloud": "Logo Cloud",
151
+ logoCloud: "Logo Cloud",
157
152
 
158
153
  // Brand New Blocks
159
154
  pricing: "Pricing Grid / Plan",
160
155
  team: "Team Profiles Showcase",
161
- "recent-feed": "Dynamic Content Feed",
162
- "process-steps": "Process Timeline / Steps",
163
- "form-embed": "Lead Intake Form",
164
- "video-showcase": "Cinematic Video Showcase",
156
+ recentFeed: "Dynamic Content Feed",
157
+ processSteps: "Process Timeline / Steps",
158
+ formEmbed: "Lead Intake Form",
159
+ videoShowcase: "Cinematic Video Showcase",
165
160
 
166
161
  // Inline Content Elements
167
- "heading-element": "Heading",
168
- "text-element": "Text",
169
- "image-element": "Image",
170
- "richtext-element": "Rich Text",
171
- "button-element": "Button",
172
- "video-element": "Video",
173
- "list-element": "List",
162
+ headingElement: "Heading",
163
+ textElement: "Text",
164
+ imageElement: "Image",
165
+ richtextElement: "Rich Text",
166
+ buttonElement: "Button",
167
+ videoElement: "Video",
168
+ listElement: "List",
174
169
  };
175
170
  return labelMap[type] || type;
176
171
  }