@ng-formworks/core 15.2.7
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/karma.conf.js +46 -0
- package/ng-package.json +11 -0
- package/package.json +54 -0
- package/src/lib/framework-library/framework-library.service.ts +195 -0
- package/src/lib/framework-library/framework.ts +11 -0
- package/src/lib/framework-library/no-framework.component.html +2 -0
- package/src/lib/framework-library/no-framework.component.ts +11 -0
- package/src/lib/framework-library/no-framework.module.ts +18 -0
- package/src/lib/framework-library/no.framework.ts +11 -0
- package/src/lib/json-schema-form.component.html +7 -0
- package/src/lib/json-schema-form.component.ts +809 -0
- package/src/lib/json-schema-form.module.ts +17 -0
- package/src/lib/json-schema-form.service.ts +907 -0
- package/src/lib/locale/de-validation-messages.ts +58 -0
- package/src/lib/locale/en-validation-messages.ts +58 -0
- package/src/lib/locale/es-validation-messages.ts +55 -0
- package/src/lib/locale/fr-validation-messages.ts +58 -0
- package/src/lib/locale/index.ts +7 -0
- package/src/lib/locale/it-validation-messages.ts +58 -0
- package/src/lib/locale/pt-validation-messages.ts +58 -0
- package/src/lib/locale/zh-validation-messages.ts +58 -0
- package/src/lib/locale-dates/en-US.ts +5 -0
- package/src/lib/shared/convert-schema-to-draft6.function.ts +321 -0
- package/src/lib/shared/form-group.functions.ts +522 -0
- package/src/lib/shared/format-regex.constants.ts +73 -0
- package/src/lib/shared/index.ts +40 -0
- package/src/lib/shared/json-schema.functions.ts +788 -0
- package/src/lib/shared/json.validators.ts +878 -0
- package/src/lib/shared/jsonpointer.functions.ts +1012 -0
- package/src/lib/shared/jspointer.functions.json.spec.ts +103 -0
- package/src/lib/shared/layout.functions.ts +1233 -0
- package/src/lib/shared/merge-schemas.function.ts +329 -0
- package/src/lib/shared/utility.functions.ts +373 -0
- package/src/lib/shared/validator.functions.spec.ts +55 -0
- package/src/lib/shared/validator.functions.ts +601 -0
- package/src/lib/widget-library/add-reference.component.ts +59 -0
- package/src/lib/widget-library/button.component.ts +54 -0
- package/src/lib/widget-library/checkbox.component.ts +74 -0
- package/src/lib/widget-library/checkboxes.component.ts +104 -0
- package/src/lib/widget-library/file.component.ts +36 -0
- package/src/lib/widget-library/hidden.component.ts +39 -0
- package/src/lib/widget-library/index.ts +56 -0
- package/src/lib/widget-library/input.component.ts +76 -0
- package/src/lib/widget-library/message.component.ts +29 -0
- package/src/lib/widget-library/none.component.ts +12 -0
- package/src/lib/widget-library/number.component.ts +79 -0
- package/src/lib/widget-library/one-of.component.ts +36 -0
- package/src/lib/widget-library/orderable.directive.ts +130 -0
- package/src/lib/widget-library/radios.component.ts +101 -0
- package/src/lib/widget-library/root.component.ts +78 -0
- package/src/lib/widget-library/section.component.ts +133 -0
- package/src/lib/widget-library/select-framework.component.ts +50 -0
- package/src/lib/widget-library/select-widget.component.ts +46 -0
- package/src/lib/widget-library/select.component.ts +96 -0
- package/src/lib/widget-library/submit.component.ts +68 -0
- package/src/lib/widget-library/tab.component.ts +29 -0
- package/src/lib/widget-library/tabs.component.ts +83 -0
- package/src/lib/widget-library/template.component.ts +52 -0
- package/src/lib/widget-library/textarea.component.ts +68 -0
- package/src/lib/widget-library/widget-library.module.ts +13 -0
- package/src/lib/widget-library/widget-library.service.ts +234 -0
- package/src/public_api.ts +21 -0
- package/src/test.ts +18 -0
- package/tsconfig.lib.json +25 -0
- package/tsconfig.lib.prod.json +9 -0
- package/tsconfig.spec.json +17 -0
- package/tslint.json +11 -0
package/karma.conf.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Karma configuration file, see link for more information
|
|
2
|
+
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
|
3
|
+
|
|
4
|
+
module.exports = function (config) {
|
|
5
|
+
config.set({
|
|
6
|
+
basePath: '',
|
|
7
|
+
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
|
8
|
+
plugins: [
|
|
9
|
+
require('karma-jasmine'),
|
|
10
|
+
require('karma-chrome-launcher'),
|
|
11
|
+
require('karma-jasmine-html-reporter'),
|
|
12
|
+
require('karma-coverage'),
|
|
13
|
+
require('@angular-devkit/build-angular/plugins/karma'),
|
|
14
|
+
],
|
|
15
|
+
client: {
|
|
16
|
+
clearContext: false, // leave Jasmine Spec Runner output visible in browser
|
|
17
|
+
},
|
|
18
|
+
coverageReporter: {
|
|
19
|
+
dir: require('path').join(__dirname, '../../coverage/ajsf-core'),
|
|
20
|
+
reporters: [
|
|
21
|
+
{
|
|
22
|
+
type: 'html',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: 'lcov',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: 'text-summary',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
reporters: ['progress', 'kjhtml'],
|
|
33
|
+
port: 9876,
|
|
34
|
+
colors: true,
|
|
35
|
+
logLevel: config.LOG_INFO,
|
|
36
|
+
autoWatch: true,
|
|
37
|
+
singleRun: false,
|
|
38
|
+
browsers: ['Chrome', 'ChromeHeadlessCI'],
|
|
39
|
+
customLaunchers: {
|
|
40
|
+
ChromeHeadlessCI: {
|
|
41
|
+
base: 'ChromeHeadless',
|
|
42
|
+
flags: ['--no-sandbox'],
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
};
|
package/ng-package.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ng-formworks/core",
|
|
3
|
+
"version": "15.2.7",
|
|
4
|
+
"description": "Angular ng-formworks - JSON Schema Form builder core",
|
|
5
|
+
"author": "https://github.com/zahmo/ng-formworks/graphs/contributors",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"Angular",
|
|
8
|
+
"ng",
|
|
9
|
+
"Angular15",
|
|
10
|
+
"Angular 15",
|
|
11
|
+
"Angular16",
|
|
12
|
+
"Angular 16",
|
|
13
|
+
"Angular17",
|
|
14
|
+
"Angular 17",
|
|
15
|
+
"ng15",
|
|
16
|
+
"ng16",
|
|
17
|
+
"ng17",
|
|
18
|
+
"JSON Schema",
|
|
19
|
+
"form",
|
|
20
|
+
"forms",
|
|
21
|
+
"form builder",
|
|
22
|
+
"form themes",
|
|
23
|
+
"form generator",
|
|
24
|
+
"ajsf",
|
|
25
|
+
"ng-formworks",
|
|
26
|
+
"ng formworks",
|
|
27
|
+
"formworks",
|
|
28
|
+
"angular json schema form"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/zahmo/ng-formworks"
|
|
34
|
+
},
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/zahmo/ng-formworks/issues"
|
|
37
|
+
},
|
|
38
|
+
"private": false,
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"lodash-es": "~4.17.21",
|
|
41
|
+
"ajv": "^8.12.0",
|
|
42
|
+
"tslib": "^2.0.0"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@angular/common": ">=15.0.0",
|
|
46
|
+
"@angular/core": ">=15.0.0",
|
|
47
|
+
"@angular/forms": ">=15.0.0",
|
|
48
|
+
"@angular/platform-browser": ">=15.0.0",
|
|
49
|
+
"rxjs": "^7.0.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/lodash-es": "^4.17.6"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
|
+
import { Inject, Injectable } from '@angular/core';
|
|
3
|
+
import { Observable, Subject, lastValueFrom } from 'rxjs';
|
|
4
|
+
import { hasOwn } from '../shared/utility.functions';
|
|
5
|
+
import { WidgetLibraryService } from '../widget-library/widget-library.service';
|
|
6
|
+
import { Framework } from './framework';
|
|
7
|
+
|
|
8
|
+
// Possible future frameworks:
|
|
9
|
+
// - Foundation 6:
|
|
10
|
+
// http://justindavis.co/2017/06/15/using-foundation-6-in-angular-4/
|
|
11
|
+
// https://github.com/zurb/foundation-sites
|
|
12
|
+
// - Semantic UI:
|
|
13
|
+
// https://github.com/edcarroll/ng2-semantic-ui
|
|
14
|
+
// https://github.com/vladotesanovic/ngSemantic
|
|
15
|
+
|
|
16
|
+
@Injectable({
|
|
17
|
+
providedIn: 'root',
|
|
18
|
+
})
|
|
19
|
+
export class FrameworkLibraryService {
|
|
20
|
+
activeFramework: Framework = null;
|
|
21
|
+
stylesheets: (HTMLStyleElement|HTMLLinkElement)[];
|
|
22
|
+
scripts: HTMLScriptElement[];
|
|
23
|
+
loadExternalAssets = false;
|
|
24
|
+
defaultFramework: string;
|
|
25
|
+
frameworkLibrary: { [name: string]: Framework } = {};
|
|
26
|
+
|
|
27
|
+
activeFrameworkName$: Observable<string>;
|
|
28
|
+
private activeFrameworkNameSubject: Subject<string>;
|
|
29
|
+
private activeFrameworkName:string;
|
|
30
|
+
|
|
31
|
+
constructor(
|
|
32
|
+
@Inject(Framework) private frameworks: any[],
|
|
33
|
+
@Inject(WidgetLibraryService) private widgetLibrary: WidgetLibraryService,
|
|
34
|
+
private http: HttpClient,
|
|
35
|
+
) {
|
|
36
|
+
this.frameworks.forEach(framework =>
|
|
37
|
+
this.frameworkLibrary[framework.name] = framework
|
|
38
|
+
);
|
|
39
|
+
this.defaultFramework = this.frameworks[0].name;
|
|
40
|
+
//this.setFramework(this.defaultFramework);
|
|
41
|
+
|
|
42
|
+
this.activeFrameworkName=this.defaultFramework;
|
|
43
|
+
this.activeFrameworkNameSubject = new Subject<string>();
|
|
44
|
+
this.activeFrameworkName$ = this.activeFrameworkNameSubject.asObservable();
|
|
45
|
+
this.setFramework(this.defaultFramework);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public setLoadExternalAssets(loadExternalAssets = true): void {
|
|
49
|
+
this.loadExternalAssets = !!loadExternalAssets;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public setFramework(
|
|
53
|
+
framework: string|Framework = this.defaultFramework,
|
|
54
|
+
loadExternalAssets = this.loadExternalAssets
|
|
55
|
+
): boolean {
|
|
56
|
+
this.activeFramework =
|
|
57
|
+
typeof framework === 'string' && this.hasFramework(framework) ?
|
|
58
|
+
this.frameworkLibrary[framework] :
|
|
59
|
+
typeof framework === 'object' && hasOwn(framework, 'framework') ?
|
|
60
|
+
framework :
|
|
61
|
+
this.frameworkLibrary[this.defaultFramework];
|
|
62
|
+
if(this.activeFramework.name !=this.activeFrameworkName){
|
|
63
|
+
this.activeFrameworkName=this.activeFramework.name;
|
|
64
|
+
this.activeFrameworkNameSubject.next(this.activeFrameworkName);
|
|
65
|
+
}
|
|
66
|
+
return this.registerFrameworkWidgets(this.activeFramework);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
registerFrameworkWidgets(framework: Framework): boolean {
|
|
70
|
+
return hasOwn(framework, 'widgets') ?
|
|
71
|
+
this.widgetLibrary.registerFrameworkWidgets(framework.widgets) :
|
|
72
|
+
this.widgetLibrary.unRegisterFrameworkWidgets();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public hasFramework(type: string): boolean {
|
|
76
|
+
return hasOwn(this.frameworkLibrary, type);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public getFramework(): any {
|
|
80
|
+
if (!this.activeFramework) { this.setFramework('default', true); }
|
|
81
|
+
return this.activeFramework.framework;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public getFrameworkList():{name:string,text:string}[] {
|
|
85
|
+
return this.frameworks.map(fw=>{
|
|
86
|
+
return {name:fw.name,text:fw.text};
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public getFrameworkWidgets(): any {
|
|
92
|
+
return this.activeFramework.widgets || {};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
public getFrameworkStylesheets(load: boolean = this.loadExternalAssets): string[] {
|
|
98
|
+
return (load && this.activeFramework.stylesheets) || [];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public getFrameworkScripts(load: boolean = this.loadExternalAssets): string[] {
|
|
102
|
+
return (load && this.activeFramework.scripts) || [];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
//applies to CssFramework classes
|
|
106
|
+
public getFrameworkConfig(existingFramework?:any): any {
|
|
107
|
+
let actFramework:Framework& { [key: string]: any; }=existingFramework||this.activeFramework;
|
|
108
|
+
return actFramework.config;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
//this will load the list of assets to be loaded at runtime in case the dependent framework
|
|
112
|
+
//scripts and styles are include locally with the parent app
|
|
113
|
+
public getFrameworkAssetConfig(existingFramework?:any,useAssetRelPath=true):Promise<{stylesheets:string[],scripts:string[]}>{
|
|
114
|
+
let actFramework:Framework& { [key: string]: any; }=existingFramework||this.activeFramework;
|
|
115
|
+
//TODO move this into config
|
|
116
|
+
const assetConfigPath = `assets/${actFramework.name}/cssframework`
|
|
117
|
+
const assetConfigURL = `${assetConfigPath}/assets.json`;
|
|
118
|
+
let subs=this.http
|
|
119
|
+
.get(assetConfigURL, { responseType: 'text' })
|
|
120
|
+
//.subscribe(assetConfig => {
|
|
121
|
+
// assetConfig
|
|
122
|
+
//})
|
|
123
|
+
|
|
124
|
+
return lastValueFrom(subs).then(assetCfgText=>{
|
|
125
|
+
let assetCfg=JSON.parse(assetCfgText);
|
|
126
|
+
if(useAssetRelPath){
|
|
127
|
+
assetCfg.stylesheets=assetCfg.stylesheets.map(styleLink=>{
|
|
128
|
+
//ignore relative path if url starts with known protocol or //
|
|
129
|
+
let nonRelPrefixes=["/","//","http:","https:"];//"//" list for completeness
|
|
130
|
+
let isNonRel=false;
|
|
131
|
+
nonRelPrefixes.forEach(prefix=>{
|
|
132
|
+
isNonRel=isNonRel||styleLink.indexOf(prefix)==0;
|
|
133
|
+
})
|
|
134
|
+
if(isNonRel){
|
|
135
|
+
return styleLink;
|
|
136
|
+
}
|
|
137
|
+
return `${assetConfigPath}/${styleLink}`;
|
|
138
|
+
})
|
|
139
|
+
assetCfg.scripts=assetCfg.scripts.map(scriptLink=>{
|
|
140
|
+
return `${assetConfigPath}/${scriptLink}`;
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
return assetCfg
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
//applies to CssFramework classes
|
|
148
|
+
public getFrameworkThemes():{name:string,text:string}[] {
|
|
149
|
+
let cssfwConfig=this.getFrameworkConfig();
|
|
150
|
+
let themes;
|
|
151
|
+
if(cssfwConfig){
|
|
152
|
+
themes=cssfwConfig?.widgetstyles?.__themes__||[]
|
|
153
|
+
}
|
|
154
|
+
return themes
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
//applies to CssFramework classes
|
|
158
|
+
public requestThemeChange(name:string,validateThemeExists:boolean=false,existingFramework?:any){
|
|
159
|
+
let actFramework:Framework& { [key: string]: any; }=existingFramework||this.activeFramework;
|
|
160
|
+
if(actFramework.requestThemeChange){
|
|
161
|
+
if(validateThemeExists){
|
|
162
|
+
let themes=this.getFrameworkThemes();
|
|
163
|
+
let foundThemes=themes.filter(thm=>{return thm.name==name});
|
|
164
|
+
if(!foundThemes|| foundThemes.length==0){
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
actFramework.requestThemeChange(name);
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
//applies to CssFramework classes
|
|
173
|
+
public getActiveTheme(existingFramework?:any):{name:string,text:string}{
|
|
174
|
+
let actFramework:Framework& { [key: string]: any; }=existingFramework||this.activeFramework;
|
|
175
|
+
if(actFramework.getActiveTheme){
|
|
176
|
+
return actFramework.getActiveTheme();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
//applies to CssFramework classes
|
|
181
|
+
public registerTheme(newTheme:{name:string,text:string},existingFramework?:any):boolean{
|
|
182
|
+
let actFramework:Framework& { [key: string]: any; }=existingFramework||this.activeFramework;
|
|
183
|
+
if(actFramework.registerTheme){
|
|
184
|
+
return actFramework.registerTheme(newTheme);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
//applies to CssFramework classes
|
|
189
|
+
public unregisterTheme(name:string,existingFramework?:any):boolean{
|
|
190
|
+
let actFramework:Framework& { [key: string]: any; }=existingFramework||this.activeFramework;
|
|
191
|
+
if(actFramework.registerTheme){
|
|
192
|
+
return actFramework.unregisterTheme(name);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Component, Input } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
selector: 'no-framework',
|
|
5
|
+
templateUrl: './no-framework.component.html',
|
|
6
|
+
})
|
|
7
|
+
export class NoFrameworkComponent {
|
|
8
|
+
@Input() layoutNode: any;
|
|
9
|
+
@Input() layoutIndex: number[];
|
|
10
|
+
@Input() dataIndex: number[];
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Framework } from './framework';
|
|
3
|
+
import { NgModule } from '@angular/core';
|
|
4
|
+
import { NoFramework } from './no.framework';
|
|
5
|
+
import { NoFrameworkComponent } from './no-framework.component';
|
|
6
|
+
import { WidgetLibraryModule } from '../widget-library/widget-library.module';
|
|
7
|
+
|
|
8
|
+
// No framework - plain HTML controls (styles from form layout only)
|
|
9
|
+
|
|
10
|
+
@NgModule({
|
|
11
|
+
imports: [CommonModule, WidgetLibraryModule],
|
|
12
|
+
declarations: [NoFrameworkComponent],
|
|
13
|
+
exports: [NoFrameworkComponent],
|
|
14
|
+
providers: [
|
|
15
|
+
{ provide: Framework, useClass: NoFramework, multi: true }
|
|
16
|
+
]
|
|
17
|
+
})
|
|
18
|
+
export class NoFrameworkModule { }
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { Framework } from './framework';
|
|
3
|
+
import { NoFrameworkComponent } from './no-framework.component';
|
|
4
|
+
// No framework - plain HTML controls (styles from form layout only)
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class NoFramework extends Framework {
|
|
8
|
+
name = 'no-framework';
|
|
9
|
+
text ='None (plain HTML)';
|
|
10
|
+
framework = NoFrameworkComponent;
|
|
11
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<form [autocomplete]="jsf?.formOptions?.autocomplete ? 'on' : 'off'" class="json-schema-form" (ngSubmit)="submitForm()">
|
|
2
|
+
<root-widget [layout]="jsf?.layout"></root-widget>
|
|
3
|
+
</form>
|
|
4
|
+
<div *ngIf="debug || jsf?.formOptions?.debug">
|
|
5
|
+
Debug output:
|
|
6
|
+
<pre>{{debugOutput}}</pre>
|
|
7
|
+
</div>
|