@djangocfg/layouts 1.2.38 → 1.2.40
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 +5 -5
- package/src/layouts/AppLayout/AppLayout.tsx +16 -7
- package/src/layouts/AppLayout/components/PackageVersions/packageVersions.config.ts +8 -8
- package/src/layouts/AppLayout/providers/CoreProviders.tsx +28 -9
- package/src/layouts/UILayout/config/components/forms.config.tsx +119 -0
- package/src/validation/README.md +145 -547
- package/src/validation/components/ErrorButtons.tsx +100 -0
- package/src/validation/components/ErrorToast.tsx +174 -0
- package/src/validation/hooks.ts +10 -0
- package/src/validation/index.ts +31 -23
- package/src/validation/providers/ErrorTrackingProvider.tsx +265 -0
- package/src/validation/types.ts +278 -0
- package/src/validation/utils/formatters.ts +114 -0
- package/src/validation/REFACTORING.md +0 -162
- package/src/validation/ValidationErrorButtons.tsx +0 -80
- package/src/validation/ValidationErrorContext.tsx +0 -333
- package/src/validation/ValidationErrorToast.tsx +0 -181
- /package/src/validation/{curl-generator.ts → utils/curl-generator.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/layouts",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.40",
|
|
4
4
|
"description": "Layout system and components for Unrealon applications",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "DjangoCFG",
|
|
@@ -63,9 +63,9 @@
|
|
|
63
63
|
"check": "tsc --noEmit"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"@djangocfg/api": "^1.2.
|
|
67
|
-
"@djangocfg/og-image": "^1.2.
|
|
68
|
-
"@djangocfg/ui": "^1.2.
|
|
66
|
+
"@djangocfg/api": "^1.2.40",
|
|
67
|
+
"@djangocfg/og-image": "^1.2.40",
|
|
68
|
+
"@djangocfg/ui": "^1.2.40",
|
|
69
69
|
"@hookform/resolvers": "^5.2.0",
|
|
70
70
|
"consola": "^3.4.2",
|
|
71
71
|
"lucide-react": "^0.468.0",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"vidstack": "0.6.15"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
|
-
"@djangocfg/typescript-config": "^1.2.
|
|
89
|
+
"@djangocfg/typescript-config": "^1.2.40",
|
|
90
90
|
"@types/node": "^24.7.2",
|
|
91
91
|
"@types/react": "19.2.2",
|
|
92
92
|
"@types/react-dom": "19.2.1",
|
|
@@ -37,7 +37,7 @@ import { PagePreloader } from './layouts/AdminLayout/components';
|
|
|
37
37
|
import { determineLayoutMode, getRedirectUrl } from './utils';
|
|
38
38
|
import { useAuth } from '../../auth';
|
|
39
39
|
import type { AppLayoutConfig } from './types';
|
|
40
|
-
import type { ValidationErrorConfig } from '../../validation';
|
|
40
|
+
import type { ValidationErrorConfig, CORSErrorConfig, NetworkErrorConfig } from '../../validation';
|
|
41
41
|
|
|
42
42
|
// Dynamic import for AdminLayout to prevent SSR hydration issues
|
|
43
43
|
const AdminLayout = dynamic(
|
|
@@ -78,11 +78,20 @@ export interface AppLayoutProps {
|
|
|
78
78
|
*/
|
|
79
79
|
showPackageVersions?: boolean;
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
82
|
-
* @default {
|
|
83
|
-
* @example validationConfig={{ enableToast: false }}
|
|
81
|
+
* Validation error tracking configuration
|
|
82
|
+
* @default { enabled: true, showToast: true, maxErrors: 50 }
|
|
84
83
|
*/
|
|
85
|
-
|
|
84
|
+
validation?: Partial<ValidationErrorConfig>;
|
|
85
|
+
/**
|
|
86
|
+
* CORS error tracking configuration
|
|
87
|
+
* @default { enabled: true, showToast: true }
|
|
88
|
+
*/
|
|
89
|
+
cors?: Partial<CORSErrorConfig>;
|
|
90
|
+
/**
|
|
91
|
+
* Network error tracking configuration
|
|
92
|
+
* @default { enabled: false }
|
|
93
|
+
*/
|
|
94
|
+
network?: Partial<NetworkErrorConfig>;
|
|
86
95
|
}
|
|
87
96
|
|
|
88
97
|
/**
|
|
@@ -255,7 +264,7 @@ function LayoutRouter({
|
|
|
255
264
|
* </AppLayout>
|
|
256
265
|
* ```
|
|
257
266
|
*/
|
|
258
|
-
export function AppLayout({ children, config, disableLayout = false, forceLayout, fontFamily, showPackageVersions,
|
|
267
|
+
export function AppLayout({ children, config, disableLayout = false, forceLayout, fontFamily, showPackageVersions, validation, cors, network }: AppLayoutProps) {
|
|
259
268
|
const router = useRouter();
|
|
260
269
|
|
|
261
270
|
// Check if ErrorBoundary is enabled (default: true)
|
|
@@ -298,7 +307,7 @@ export function AppLayout({ children, config, disableLayout = false, forceLayout
|
|
|
298
307
|
}} />
|
|
299
308
|
)}
|
|
300
309
|
|
|
301
|
-
<CoreProviders config={config}
|
|
310
|
+
<CoreProviders config={config} validation={validation} cors={cors} network={network}>
|
|
302
311
|
{appContent}
|
|
303
312
|
</CoreProviders>
|
|
304
313
|
</>
|
|
@@ -16,36 +16,36 @@ export interface PackageInfo {
|
|
|
16
16
|
/**
|
|
17
17
|
* Package versions registry
|
|
18
18
|
* Auto-synced from package.json files
|
|
19
|
-
* Last updated: 2025-11-
|
|
19
|
+
* Last updated: 2025-11-19T06:16:37.244Z
|
|
20
20
|
*/
|
|
21
21
|
const PACKAGE_VERSIONS: PackageInfo[] = [
|
|
22
22
|
{
|
|
23
23
|
"name": "@djangocfg/ui",
|
|
24
|
-
"version": "1.2.
|
|
24
|
+
"version": "1.2.40"
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
"name": "@djangocfg/api",
|
|
28
|
-
"version": "1.2.
|
|
28
|
+
"version": "1.2.40"
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"name": "@djangocfg/layouts",
|
|
32
|
-
"version": "1.2.
|
|
32
|
+
"version": "1.2.40"
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
"name": "@djangocfg/markdown",
|
|
36
|
-
"version": "1.2.
|
|
36
|
+
"version": "1.2.40"
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"name": "@djangocfg/og-image",
|
|
40
|
-
"version": "1.2.
|
|
40
|
+
"version": "1.2.40"
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
"name": "@djangocfg/eslint-config",
|
|
44
|
-
"version": "1.2.
|
|
44
|
+
"version": "1.2.40"
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
"name": "@djangocfg/typescript-config",
|
|
48
|
-
"version": "1.2.
|
|
48
|
+
"version": "1.2.40"
|
|
49
49
|
}
|
|
50
50
|
];
|
|
51
51
|
|
|
@@ -9,18 +9,32 @@
|
|
|
9
9
|
import React, { ReactNode } from 'react';
|
|
10
10
|
import { ThemeProvider, Toaster } from '@djangocfg/ui';
|
|
11
11
|
import { AuthProvider } from '../../../auth';
|
|
12
|
-
import {
|
|
12
|
+
import { ErrorTrackingProvider } from '../../../validation';
|
|
13
13
|
import type { AppLayoutConfig } from '../types';
|
|
14
|
-
import type { ValidationErrorConfig } from '../../../validation';
|
|
14
|
+
import type { ValidationErrorConfig, CORSErrorConfig, NetworkErrorConfig } from '../../../validation';
|
|
15
15
|
|
|
16
16
|
export interface CoreProvidersProps {
|
|
17
17
|
children: ReactNode;
|
|
18
18
|
config: AppLayoutConfig;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
* @default {
|
|
20
|
+
* Validation error tracking configuration
|
|
21
|
+
* @default { enabled: true, showToast: true, maxErrors: 50 }
|
|
22
22
|
*/
|
|
23
|
-
|
|
23
|
+
validation?: Partial<ValidationErrorConfig>;
|
|
24
|
+
/**
|
|
25
|
+
* CORS error tracking configuration
|
|
26
|
+
* @default { enabled: true, showToast: true }
|
|
27
|
+
*/
|
|
28
|
+
cors?: Partial<CORSErrorConfig>;
|
|
29
|
+
/**
|
|
30
|
+
* Network error tracking configuration
|
|
31
|
+
* @default { enabled: false }
|
|
32
|
+
*/
|
|
33
|
+
network?: Partial<NetworkErrorConfig>;
|
|
34
|
+
/**
|
|
35
|
+
* Custom error handler for all error types
|
|
36
|
+
*/
|
|
37
|
+
onError?: (error: any) => boolean | void;
|
|
24
38
|
}
|
|
25
39
|
|
|
26
40
|
/**
|
|
@@ -29,10 +43,10 @@ export interface CoreProvidersProps {
|
|
|
29
43
|
* Provides:
|
|
30
44
|
* - ThemeProvider (dark/light mode)
|
|
31
45
|
* - AuthProvider (authentication)
|
|
32
|
-
* -
|
|
46
|
+
* - ErrorTrackingProvider (validation, CORS & network error tracking)
|
|
33
47
|
* - Toaster (notifications)
|
|
34
48
|
*/
|
|
35
|
-
export function CoreProviders({ children, config,
|
|
49
|
+
export function CoreProviders({ children, config, validation, cors, network, onError }: CoreProvidersProps) {
|
|
36
50
|
return (
|
|
37
51
|
<ThemeProvider>
|
|
38
52
|
<AuthProvider
|
|
@@ -45,9 +59,14 @@ export function CoreProviders({ children, config, validationConfig }: CoreProvid
|
|
|
45
59
|
},
|
|
46
60
|
}}
|
|
47
61
|
>
|
|
48
|
-
<
|
|
62
|
+
<ErrorTrackingProvider
|
|
63
|
+
validation={validation}
|
|
64
|
+
cors={cors}
|
|
65
|
+
network={network}
|
|
66
|
+
onError={onError}
|
|
67
|
+
>
|
|
49
68
|
{children}
|
|
50
|
-
</
|
|
69
|
+
</ErrorTrackingProvider>
|
|
51
70
|
</AuthProvider>
|
|
52
71
|
|
|
53
72
|
{/* Global toast notifications */}
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
FormMessage,
|
|
34
34
|
Field,
|
|
35
35
|
} from '@djangocfg/ui';
|
|
36
|
+
import { JsonSchemaForm } from '@djangocfg/ui/tools';
|
|
36
37
|
import type { ComponentConfig } from './types';
|
|
37
38
|
|
|
38
39
|
export const FORM_COMPONENTS: ComponentConfig[] = [
|
|
@@ -463,4 +464,122 @@ function MyForm() {
|
|
|
463
464
|
</div>
|
|
464
465
|
),
|
|
465
466
|
},
|
|
467
|
+
{
|
|
468
|
+
name: 'JsonSchemaForm',
|
|
469
|
+
category: 'forms',
|
|
470
|
+
description: 'Automatic form generator from JSON Schema with validation, custom widgets, and full type safety',
|
|
471
|
+
importPath: "import { JsonSchemaForm } from '@djangocfg/ui/tools';",
|
|
472
|
+
example: `// Basic usage
|
|
473
|
+
const schema = {
|
|
474
|
+
type: 'object',
|
|
475
|
+
required: ['name', 'email'],
|
|
476
|
+
properties: {
|
|
477
|
+
name: {
|
|
478
|
+
type: 'string',
|
|
479
|
+
title: 'Full Name',
|
|
480
|
+
minLength: 2
|
|
481
|
+
},
|
|
482
|
+
email: {
|
|
483
|
+
type: 'string',
|
|
484
|
+
title: 'Email',
|
|
485
|
+
format: 'email'
|
|
486
|
+
},
|
|
487
|
+
age: {
|
|
488
|
+
type: 'number',
|
|
489
|
+
title: 'Age',
|
|
490
|
+
minimum: 18
|
|
491
|
+
},
|
|
492
|
+
subscribe: {
|
|
493
|
+
type: 'boolean',
|
|
494
|
+
title: 'Subscribe to newsletter'
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
<JsonSchemaForm
|
|
500
|
+
schema={schema}
|
|
501
|
+
onSubmit={(data) => console.log(data.formData)}
|
|
502
|
+
liveValidate={false}
|
|
503
|
+
/>
|
|
504
|
+
|
|
505
|
+
// With UI Schema for customization
|
|
506
|
+
const uiSchema = {
|
|
507
|
+
subscribe: {
|
|
508
|
+
'ui:widget': 'SwitchWidget'
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
<JsonSchemaForm
|
|
513
|
+
schema={schema}
|
|
514
|
+
uiSchema={uiSchema}
|
|
515
|
+
formData={initialData}
|
|
516
|
+
onChange={(data) => setFormData(data.formData)}
|
|
517
|
+
onSubmit={handleSubmit}
|
|
518
|
+
/>`,
|
|
519
|
+
preview: (
|
|
520
|
+
<div className="space-y-4">
|
|
521
|
+
<JsonSchemaForm
|
|
522
|
+
schema={{
|
|
523
|
+
type: 'object',
|
|
524
|
+
required: ['name', 'email'],
|
|
525
|
+
properties: {
|
|
526
|
+
name: {
|
|
527
|
+
type: 'string',
|
|
528
|
+
title: 'Full Name',
|
|
529
|
+
description: 'Enter your first and last name',
|
|
530
|
+
minLength: 2
|
|
531
|
+
},
|
|
532
|
+
email: {
|
|
533
|
+
type: 'string',
|
|
534
|
+
title: 'Email Address',
|
|
535
|
+
format: 'email'
|
|
536
|
+
},
|
|
537
|
+
role: {
|
|
538
|
+
type: 'string',
|
|
539
|
+
title: 'Role',
|
|
540
|
+
enum: ['developer', 'designer', 'manager', 'other'],
|
|
541
|
+
default: 'developer'
|
|
542
|
+
},
|
|
543
|
+
experience: {
|
|
544
|
+
type: 'number',
|
|
545
|
+
title: 'Years of Experience',
|
|
546
|
+
minimum: 0,
|
|
547
|
+
maximum: 50,
|
|
548
|
+
default: 5
|
|
549
|
+
},
|
|
550
|
+
subscribe: {
|
|
551
|
+
type: 'boolean',
|
|
552
|
+
title: 'Subscribe to newsletter',
|
|
553
|
+
default: false
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}}
|
|
557
|
+
uiSchema={{
|
|
558
|
+
subscribe: {
|
|
559
|
+
'ui:widget': 'SwitchWidget'
|
|
560
|
+
}
|
|
561
|
+
}}
|
|
562
|
+
onSubmit={(data) => {
|
|
563
|
+
console.log('Form submitted:', data.formData);
|
|
564
|
+
alert('Form submitted! Check console for data.');
|
|
565
|
+
}}
|
|
566
|
+
liveValidate={false}
|
|
567
|
+
showErrorList="top"
|
|
568
|
+
/>
|
|
569
|
+
|
|
570
|
+
<div className="p-4 border rounded-md bg-muted/50">
|
|
571
|
+
<p className="text-sm font-medium mb-2">Features:</p>
|
|
572
|
+
<ul className="space-y-1 text-sm text-muted-foreground">
|
|
573
|
+
<li>• Automatic form generation from JSON Schema 7</li>
|
|
574
|
+
<li>• Built-in validation with ajv8</li>
|
|
575
|
+
<li>• Custom widgets (Switch, Select, Textarea, etc.)</li>
|
|
576
|
+
<li>• Custom templates for fields, objects, arrays</li>
|
|
577
|
+
<li>• Live validation support</li>
|
|
578
|
+
<li>• Full TypeScript support</li>
|
|
579
|
+
<li>• Radix UI components integration</li>
|
|
580
|
+
</ul>
|
|
581
|
+
</div>
|
|
582
|
+
</div>
|
|
583
|
+
),
|
|
584
|
+
},
|
|
466
585
|
];
|