Browse Source

fix(dashboard): Improve required field validation and error visibility

- Add min(1) validation for non-nullable String/ID/DateTime fields in form schema generation
- Increase brightness of destructive color in both light and dark themes for better error visibility

Fixes #4173

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Will Nahmens 4 days ago
parent
commit
24626d0ec2

+ 40 - 0
packages/dashboard/src/lib/framework/form-engine/form-schema-tools.spec.ts

@@ -51,6 +51,46 @@ describe('form-schema-tools', () => {
             expect(() => schema.parse(123)).toThrow();
         });
 
+        it('should reject empty strings for non-nullable String fields', () => {
+            const field = createMockField('name', 'String', false);
+            const schema = getZodTypeFromField(field);
+
+            expect(() => schema.parse('test')).not.toThrow();
+            expect(() => schema.parse('')).toThrow();
+
+            try {
+                schema.parse('');
+                expect.fail('Should have thrown validation error');
+            } catch (error: any) {
+                expect(error.errors[0].message).toBe('This field is required');
+            }
+        });
+
+        it('should accept empty strings for nullable String fields', () => {
+            const field = createMockField('name', 'String', true);
+            const schema = getZodTypeFromField(field);
+
+            expect(() => schema.parse('test')).not.toThrow();
+            expect(() => schema.parse('')).not.toThrow();
+            expect(() => schema.parse(null)).not.toThrow();
+        });
+
+        it('should reject empty strings for non-nullable ID fields', () => {
+            const field = createMockField('id', 'ID', false);
+            const schema = getZodTypeFromField(field);
+
+            expect(() => schema.parse('123')).not.toThrow();
+            expect(() => schema.parse('')).toThrow();
+        });
+
+        it('should reject empty strings for non-nullable DateTime fields', () => {
+            const field = createMockField('date', 'DateTime', false);
+            const schema = getZodTypeFromField(field);
+
+            expect(() => schema.parse('2024-01-01')).not.toThrow();
+            expect(() => schema.parse('')).toThrow();
+        });
+
         it('should create number type for Int fields', () => {
             const field = createMockField('age', 'Int');
             const schema = getZodTypeFromField(field);

+ 1 - 1
packages/dashboard/src/lib/framework/form-engine/form-schema-tools.ts

@@ -388,7 +388,7 @@ export function getZodTypeFromField(field: FieldInfo): ZodTypeAny {
         case 'String':
         case 'ID':
         case 'DateTime':
-            zodType = z.string();
+            zodType = field.nullable ? z.string() : z.string().min(1, 'This field is required');
             break;
         case 'Int':
         case 'Float':

+ 2 - 2
packages/dashboard/vite/vite-plugin-theme.ts

@@ -67,7 +67,7 @@ const defaultVariables: ThemeVariables = {
         'muted-foreground': 'oklch(0.5517 0.0138 285.9385)',
         accent: 'oklch(0.9674 0.0013 286.3752)',
         'accent-foreground': 'oklch(0.2103 0.0059 285.8852)',
-        destructive: 'oklch(0.505 0.188 27.325)',
+        destructive: 'oklch(0.60 0.24 27.325)',
         'destructive-foreground': 'oklch(0.9851 0 0)',
         success: 'hsl(99deg 67.25% 33.2%)',
         'success-foreground': 'hsl(0 0% 98%)',
@@ -111,7 +111,7 @@ const defaultVariables: ThemeVariables = {
         'muted-foreground': 'oklch(0.7118 0.0129 286.0665)',
         accent: 'oklch(0.2739 0.0055 286.0326)',
         'accent-foreground': 'oklch(0.9851 0 0)',
-        destructive: 'oklch(0.4 0.15 27.11)',
+        destructive: 'oklch(0.75 0.22 25)',
         'destructive-foreground': 'oklch(0.9851 0 0)',
         success: 'hsl(100 76.42% 22.21%)',
         'success-foreground': 'hsl(0 0% 98%)',