├── .editorconfig ├── .gitignore ├── .nvmrc ├── LICENSE ├── README.md ├── angular.json ├── package-lock.json ├── package.json ├── src ├── app │ ├── app.component.css │ ├── app.component.html │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── custom.autocomplete.ts │ ├── data.control.ts │ ├── data.ts │ └── lang.control.ts ├── assets │ ├── .gitkeep │ ├── schema.json │ └── uischema.json ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── main.ts ├── polyfills.ts ├── styles.css ├── test.ts └── typings.d.ts ├── tsconfig.app.json ├── tsconfig.json └── tsconfig.spec.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /dist-server 6 | /tmp 7 | /out-tsc 8 | 9 | # dependencies 10 | /node_modules 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | .c9/ 17 | *.launch 18 | .settings/ 19 | *.sublime-workspace 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.angular/cache 30 | /.sass-cache 31 | /connect.lock 32 | /coverage 33 | /libpeerconnection.log 34 | npm-debug.log 35 | yarn-error.log 36 | testem.log 37 | /typings 38 | 39 | # e2e 40 | /e2e/*.js 41 | /e2e/*.map 42 | 43 | # System Files 44 | .DS_Store 45 | Thumbs.db 46 | .yalc -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v18.19.0 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2019 EclipseSource Munich 4 | https://github.com/eclipsesource/jsonforms 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JSON Forms Angular Seed 2 | 3 | JSONForms Angular Seed. 4 | 5 | ## Installation 6 | 7 | Run `npm ci` to install the necessary dependencies. 8 | 9 | ## Development server 10 | 11 | Run `npm start` for a dev server. Navigate to [http://localhost:4200/](http://localhost:4200/). The app will automatically reload if you change any of the source files. 12 | 13 | ## Build 14 | 15 | Run `npm build` to build the project. The build artifacts will be stored in the `dist` directory. Use the `--configuration production` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `npm test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `npm e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Customizations 26 | 27 | For this showcase we hardcoded the schemas (`schema.json`, `uischema.json`) and the data (`data.ts`). You can replace them with your own or handle them completely dynamically. 28 | 29 | We implemented three custom controls (`custom.autocomplete.ts`, `lang.control.ts` and `data.control.ts`). If you don't need them just remove them! See also `store.ts` where these custom renderers are registered. 30 | 31 | In `app.component.ts` we customized the validation. This step is optional and can be skipped if needed. 32 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "jsonforms-angular-material-playground": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "architect": { 11 | "build": { 12 | "builder": "@angular-devkit/build-angular:browser", 13 | "options": { 14 | "outputPath": "dist", 15 | "index": "src/index.html", 16 | "main": "src/main.ts", 17 | "tsConfig": "tsconfig.app.json", 18 | "polyfills": "src/polyfills.ts", 19 | "assets": [ 20 | "src/assets", 21 | "src/favicon.ico" 22 | ], 23 | "styles": [ 24 | "src/styles.css" 25 | ], 26 | "scripts": [], 27 | "preserveSymlinks": true, 28 | "vendorChunk": true, 29 | "extractLicenses": false, 30 | "buildOptimizer": false, 31 | "sourceMap": true, 32 | "optimization": false, 33 | "namedChunks": true, 34 | "allowedCommonJsDependencies": ["lodash"] 35 | }, 36 | "configurations": { 37 | "production": { 38 | "budgets": [ 39 | { 40 | "type": "anyComponentStyle", 41 | "maximumWarning": "6kb" 42 | } 43 | ], 44 | "optimization": true, 45 | "outputHashing": "all", 46 | "sourceMap": false, 47 | "namedChunks": false, 48 | "extractLicenses": true, 49 | "vendorChunk": false, 50 | "buildOptimizer": true, 51 | "fileReplacements": [ 52 | { 53 | "replace": "src/environments/environment.ts", 54 | "with": "src/environments/environment.prod.ts" 55 | } 56 | ] 57 | } 58 | }, 59 | "defaultConfiguration": "" 60 | }, 61 | "serve": { 62 | "builder": "@angular-devkit/build-angular:dev-server", 63 | "options": { 64 | "buildTarget": "jsonforms-angular-material-playground:build" 65 | }, 66 | "configurations": { 67 | "production": { 68 | "buildTarget": "jsonforms-angular-material-playground:build:production" 69 | } 70 | } 71 | }, 72 | "extract-i18n": { 73 | "builder": "@angular-devkit/build-angular:extract-i18n", 74 | "options": { 75 | "buildTarget": "jsonforms-angular-material-playground:build" 76 | } 77 | }, 78 | "test": { 79 | "builder": "@angular-devkit/build-angular:karma", 80 | "options": { 81 | "polyfills": [ 82 | "zone.js", 83 | "zone.js/testing" 84 | ], 85 | "tsConfig": "tsconfig.spec.json", 86 | "scripts": [], 87 | "styles": [ 88 | "src/styles.css" 89 | ], 90 | "assets": [ 91 | "src/assets", 92 | "src/favicon.ico" 93 | ] 94 | } 95 | } 96 | } 97 | } 98 | }, 99 | "schematics": { 100 | "@schematics/angular:component": { 101 | "prefix": "app", 102 | "style": "css" 103 | }, 104 | "@schematics/angular:directive": { 105 | "prefix": "app" 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsonforms-angular-material-playground", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve", 8 | "build": "ng build --configuration production", 9 | "test": "ng test" 10 | }, 11 | "private": true, 12 | "dependencies": { 13 | "@angular/animations": "^19.0.0", 14 | "@angular/cdk": "^19.0.0", 15 | "@angular/common": "^19.0.0", 16 | "@angular/compiler": "^19.0.0", 17 | "@angular/core": "^19.0.0", 18 | "@angular/forms": "^19.0.0", 19 | "@angular/material": "^19.0.0", 20 | "@angular/platform-browser": "^19.0.0", 21 | "@angular/platform-browser-dynamic": "^19.0.0", 22 | "@angular/router": "^19.0.0", 23 | "@jsonforms/angular": "3.5.1", 24 | "@jsonforms/angular-material": "3.5.1", 25 | "@jsonforms/core": "3.5.1", 26 | "ajv": "^8.6.1", 27 | "core-js": "^2.4.1", 28 | "dayjs": "^1.11.10", 29 | "json-refs": "^3.0.4", 30 | "libphonenumber-js": "^1.6.8", 31 | "path": "^0.12.7", 32 | "random-words": "^2.0.0", 33 | "rxjs": "^6.5.4", 34 | "tslib": "^2.0.0", 35 | "zone.js": "~0.15.0" 36 | }, 37 | "devDependencies": { 38 | "@angular-devkit/build-angular": "^19.0.0", 39 | "@angular/cli": "^19.0.0", 40 | "@angular/compiler-cli": "^19.0.0", 41 | "@angular/language-service": "^19.0.0", 42 | "@types/jasmine": "~4.3.0", 43 | "@types/node": "^18.19.8", 44 | "jasmine-core": "~4.6.0", 45 | "jasmine-spec-reporter": "^7.0.0", 46 | "karma": "~6.4.0", 47 | "karma-chrome-launcher": "~3.2.0", 48 | "karma-coverage": "~2.2.0", 49 | "karma-jasmine": "~5.1.0", 50 | "karma-jasmine-html-reporter": "~2.1.0", 51 | "typescript": "~5.5.0" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclipsesource/jsonforms-angular-seed/1fdf9f75a7eaeb1fb937b6c479850d31d916d07e/src/app/app.component.css -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |

4 | JSONForms Angular Material Playground 5 |

6 | Angular Logo 7 |
8 | 16 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, waitForAsync } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | import { AppModule } from './app.module'; 4 | describe('AppComponent', () => { 5 | beforeEach(waitForAsync(() => { 6 | TestBed.configureTestingModule({ 7 | imports: [AppModule], 8 | declarations: [ 9 | AppComponent 10 | ], 11 | }).compileComponents(); 12 | })); 13 | it('should create the app', waitForAsync(() => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | fixture.detectChanges(); 16 | const app = fixture.debugElement.componentInstance; 17 | expect(app).toBeTruthy(); 18 | })); 19 | it('should render title in a h1 tag', waitForAsync(() => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | fixture.detectChanges(); 22 | const compiled = fixture.debugElement.nativeElement; 23 | expect(compiled.querySelector('h1').textContent).toContain('JSONForms Angular Material Playground'); 24 | })); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { angularMaterialRenderers } from '@jsonforms/angular-material'; 3 | import { and, createAjv, isControl, optionIs, rankWith, schemaTypeIs, scopeEndsWith, Tester } from '@jsonforms/core'; 4 | import { CustomAutocompleteControlRenderer } from './custom.autocomplete'; 5 | import { DataDisplayComponent } from './data.control'; 6 | import { LangComponent } from './lang.control'; 7 | import uischemaAsset from '../assets/uischema.json'; 8 | import schemaAsset from '../assets/schema.json'; 9 | import dataAsset from './data'; 10 | import { parsePhoneNumber } from 'libphonenumber-js'; 11 | import { DateAdapter } from '@angular/material/core'; 12 | 13 | const departmentTester: Tester = and( 14 | schemaTypeIs('string'), 15 | scopeEndsWith('department') 16 | ); 17 | 18 | @Component({ 19 | selector: 'app-root', 20 | templateUrl: './app.component.html', 21 | styleUrls: ['./app.component.css'], 22 | standalone: false 23 | }) 24 | export class AppComponent { 25 | renderers = [ 26 | ...angularMaterialRenderers, 27 | { tester: rankWith(5, departmentTester), renderer: CustomAutocompleteControlRenderer }, 28 | { 29 | renderer: DataDisplayComponent, 30 | tester: rankWith( 31 | 6, 32 | and( 33 | isControl, 34 | scopeEndsWith('___data') 35 | ) 36 | ) 37 | }, 38 | { 39 | renderer: LangComponent, 40 | tester: rankWith( 41 | 6, 42 | and( 43 | isControl, 44 | optionIs('lang', true) 45 | ) 46 | ) 47 | }, 48 | ]; 49 | uischema = uischemaAsset; 50 | schema = schemaAsset; 51 | data = dataAsset; 52 | i18n = {locale: 'de-DE'} 53 | dateAdapter; 54 | ajv = createAjv({ 55 | schemaId: 'id', 56 | allErrors: true 57 | }); 58 | constructor(dateAdapter: DateAdapter) { 59 | this.ajv.addFormat('time', '^([0-1][0-9]|2[0-3]):[0-5][0-9]$'); 60 | this.dateAdapter = dateAdapter; 61 | dateAdapter.setLocale(this.i18n.locale); 62 | this.ajv.addFormat('tel', maybePhoneNumber => { 63 | try { 64 | parsePhoneNumber(maybePhoneNumber, 'DE'); 65 | return true; 66 | } catch (_) { 67 | return false; 68 | } 69 | }); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { HttpClientModule } from '@angular/common/http'; 2 | import { NgModule } from '@angular/core'; 3 | import { MatAutocompleteModule } from '@angular/material/autocomplete'; 4 | import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; 5 | import { BrowserModule } from '@angular/platform-browser'; 6 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 7 | import { JsonFormsModule } from '@jsonforms/angular'; 8 | import { JsonFormsAngularMaterialModule } from '@jsonforms/angular-material'; 9 | import { AppComponent } from './app.component'; 10 | import { CustomAutocompleteControlRenderer } from './custom.autocomplete'; 11 | import { DataDisplayComponent } from './data.control'; 12 | import { LangComponent } from './lang.control'; 13 | 14 | 15 | @NgModule({ 16 | declarations: [ 17 | AppComponent, 18 | CustomAutocompleteControlRenderer, 19 | LangComponent, 20 | DataDisplayComponent 21 | ], 22 | imports: [ 23 | BrowserModule, 24 | BrowserAnimationsModule, 25 | JsonFormsModule, 26 | JsonFormsAngularMaterialModule, 27 | MatAutocompleteModule, 28 | MatProgressSpinnerModule, 29 | HttpClientModule 30 | ], 31 | schemas: [], 32 | bootstrap: [AppComponent] 33 | }) 34 | export class AppModule { 35 | } 36 | -------------------------------------------------------------------------------- /src/app/custom.autocomplete.ts: -------------------------------------------------------------------------------- 1 | import {generate} from "random-words"; 2 | import {debounceTime, finalize, tap} from 'rxjs/operators'; 3 | import {switchMap} from 'rxjs/operators'; 4 | import {delay} from 'rxjs/operators'; 5 | import {of} from 'rxjs'; 6 | import {AutocompleteControlRenderer} from '@jsonforms/angular-material'; 7 | import {Observable} from 'rxjs'; 8 | import {Component} from '@angular/core'; 9 | 10 | const words: string[] = generate(1000) as string[]; 11 | 12 | const fetchSuggestions = (input: string): Observable => { 13 | const filtered: string[] = words.filter(word => word.startsWith(input)); 14 | return of(filtered).pipe(delay(1000)); 15 | }; 16 | 17 | @Component({ 18 | selector: 'jsonforms-custom-autocomplete', 19 | template: ` 20 | 21 | {{ label }} 22 | 31 | 33 | 34 | 35 | 36 | {{ option }} 37 | 38 | 39 | 40 | {{ error }} 41 | 42 | `, 43 | standalone: false 44 | }) 45 | export class CustomAutocompleteControlRenderer extends AutocompleteControlRenderer { 46 | 47 | isLoading: boolean = false; 48 | 49 | override ngOnInit() { 50 | super.ngOnInit(); 51 | this.form.valueChanges 52 | .pipe( 53 | debounceTime(300), 54 | tap(() => this.isLoading = true), 55 | switchMap(value => fetchSuggestions(value) 56 | .pipe( 57 | finalize(() => this.isLoading = false) 58 | ) 59 | ) 60 | ) 61 | .subscribe((options: string[]) => this.options = options); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/app/data.control.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; 3 | import { ControlProps } from '@jsonforms/core'; 4 | 5 | @Component({ 6 | selector: 'app-data-component', 7 | template: '
{{dataAsString}}
', 8 | standalone: false 9 | }) 10 | export class DataDisplayComponent extends JsonFormsControl { 11 | 12 | dataAsString: string | undefined; 13 | 14 | constructor(service: JsonFormsAngularService) { 15 | super(service); 16 | } 17 | 18 | public override mapAdditionalProps(props: ControlProps) { 19 | this.dataAsString = JSON.stringify(props.data, null, 2); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/app/data.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | orders: [ 3 | { 4 | customer: { 5 | id: '471201', 6 | name: 'Sirius Cybernetics Corporation', 7 | department: 'Complaints Division', 8 | phone: '(12) 34 56 78 90' 9 | }, 10 | title: '42 killer robots', 11 | ordered: true, 12 | processId: 1890004498, 13 | assignee: 'Philip J. Fry', 14 | status: 'ordered', 15 | startDate: '2018-06-01', 16 | endDate: '2018-08-01', 17 | }, 18 | { 19 | customer: { 20 | id: '471202', 21 | name: 'Very Big Corporation of America', 22 | phone: '+49 123 456 789' 23 | }, 24 | title: '1000 gallons of MomCorp Oil', 25 | processId: 1890004499, 26 | assignee: 'Jen Barber', 27 | startDate: '2018-07-01', 28 | status: 'planned' 29 | } 30 | ] 31 | }; 32 | -------------------------------------------------------------------------------- /src/app/lang.control.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; 3 | import { getLocale, setLocale } from '@jsonforms/core'; 4 | import { DateAdapter } from '@angular/material/core'; 5 | 6 | @Component({ 7 | selector: 'app-lang-component', 8 | template: ` 9 |

Click button to set locale

10 |

Current locale: {{currentLocale}}

11 | 12 | 13 | `, 14 | standalone: false 15 | }) 16 | export class LangComponent extends JsonFormsControl { 17 | 18 | currentLocale: string | undefined; 19 | dateAdapter; 20 | 21 | constructor(service: JsonFormsAngularService, dateAdapter: DateAdapter) { 22 | super(service); 23 | this.dateAdapter = dateAdapter; 24 | } 25 | 26 | override mapAdditionalProps() { 27 | this.currentLocale = getLocale(this.jsonFormsService.getState()); 28 | } 29 | 30 | changeLocale(localeString: string) { 31 | this.jsonFormsService.updateI18n(setLocale(localeString)); 32 | this.dateAdapter.setLocale(localeString); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclipsesource/jsonforms-angular-seed/1fdf9f75a7eaeb1fb937b6c479850d31d916d07e/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/assets/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "definitions": { 3 | "order": { 4 | "type": "object", 5 | "properties": { 6 | "customer": { 7 | "type": "object", 8 | "properties": { 9 | "id": { "type": "string" }, 10 | "name": { "type": "string"}, 11 | "department": { "type": "string" }, 12 | "emailAddress": { "type": "string", "format": "email" } 13 | } 14 | }, 15 | "title": { 16 | "type": "string", 17 | "minLength": 5 18 | }, 19 | "description": { 20 | "type": "string" 21 | }, 22 | "ordered": { "type": "boolean" }, 23 | "processId": { 24 | "type": "number", 25 | "minimum": 0 26 | }, 27 | "assignee": { "type": "string" }, 28 | "startDate": { 29 | "type": "string", 30 | "format": "date" 31 | }, 32 | "endDate": { 33 | "type": "string", 34 | "format": "date" 35 | }, 36 | "status": { 37 | "type": "string", 38 | "enum": ["unordered", "planned", "ordered"] 39 | }, 40 | "amount": { 41 | "type": "integer", 42 | "minimum": 1, 43 | "maximum": 100, 44 | "default": 10, 45 | "multipleOf": 1 46 | } 47 | } 48 | } 49 | }, 50 | "type": "object", 51 | "properties": { 52 | "orders": { 53 | "type": "array", 54 | "items": { 55 | "$ref": "#/definitions/order" 56 | } 57 | } 58 | }, 59 | "required": ["title"] 60 | } 61 | -------------------------------------------------------------------------------- /src/assets/uischema.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "Categorization", 3 | "elements": [ 4 | { 5 | "type": "Category", 6 | "label": "Orders", 7 | "elements": [ 8 | { 9 | "type": "ListWithDetail", 10 | "scope": "#/properties/orders", 11 | "options": { 12 | "labelRef": "#/items/properties/customer/properties/name", 13 | "detail": { 14 | "type": "VerticalLayout", 15 | "elements": [ 16 | { 17 | "type": "HorizontalLayout", 18 | "elements": [ 19 | { 20 | "type": "Control", 21 | "scope": "#/properties/title" 22 | }, 23 | { 24 | "type": "Control", 25 | "scope": "#/properties/processId" 26 | } 27 | ] 28 | }, 29 | { 30 | "type": "VerticalLayout", 31 | "elements": [ 32 | { 33 | "type": "VerticalLayout", 34 | "elements": [ 35 | { 36 | 37 | "type": "Control", 38 | "scope": "#/properties/assignee" 39 | }, 40 | { 41 | "type": "HorizontalLayout", 42 | "elements": [ 43 | { 44 | "type": "Control", 45 | "scope": "#/properties/startDate" 46 | }, 47 | { 48 | "type": "Control", 49 | "scope": "#/properties/endDate" 50 | } 51 | ] 52 | }, 53 | { 54 | "type": "Control", 55 | "scope": "#/properties/status" 56 | }, 57 | { 58 | "type": "Control", 59 | "scope": "#/properties/ordered", 60 | "options": { 61 | "toggle": true 62 | } 63 | }, 64 | { 65 | "type": "Control", 66 | "scope": "#/properties/amount", 67 | "options": { 68 | "slider": true 69 | }, 70 | "rule": { 71 | "effect": "DISABLE", 72 | "condition": { 73 | "schema": { 74 | "const": "unordered" 75 | }, 76 | "scope": "#/properties/status" 77 | } 78 | } 79 | } 80 | 81 | ] 82 | } 83 | ] 84 | }, 85 | { 86 | "type": "Group", 87 | "label": "Customer", 88 | "elements": [ 89 | { 90 | "type": "Control", 91 | "scope": "#/properties/customer/properties/name" 92 | }, 93 | { 94 | "type": "Control", 95 | "scope": "#/properties/customer/properties/department" 96 | }, 97 | { 98 | "type": "Control", 99 | "scope": "#/properties/customer/properties/emailAddress" 100 | } 101 | ] 102 | }, 103 | { 104 | "type": "Control", 105 | "scope": "#/properties/description", 106 | "options": { 107 | "multi": true 108 | } 109 | } 110 | ] 111 | } 112 | } 113 | } 114 | ] 115 | }, 116 | { 117 | "type": "Category", 118 | "label": "Data", 119 | "elements": [ 120 | { 121 | "type": "Label", 122 | "text": "Data" 123 | }, 124 | { 125 | "type": "Control", 126 | "scope": "#/___data" 127 | } 128 | ] 129 | }, 130 | { 131 | "type": "Category", 132 | "label": "Language", 133 | "elements": [ 134 | { 135 | "type": "Label", 136 | "text": "Choose preferred locale" 137 | }, 138 | { 139 | "type": "Control", 140 | "scope": "#", 141 | "options": { 142 | "lang": true 143 | } 144 | } 145 | ] 146 | }, 147 | { 148 | "type": "Category", 149 | "label": "Contracts", 150 | "elements": [ 151 | { 152 | "type": "Label", 153 | "text": "Currently Empty Category" 154 | } 155 | ] 156 | } 157 | ] 158 | } 159 | -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclipsesource/jsonforms-angular-seed/1fdf9f75a7eaeb1fb937b6c479850d31d916d07e/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSONForms Angular Material Playground 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** 22 | * By default, zone.js will patch all possible macroTask and DomEvents 23 | * user can disable parts of macroTask/DomEvents patch by setting following flags 24 | */ 25 | 26 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 27 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 28 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 29 | 30 | /* 31 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 32 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 33 | */ 34 | // (window as any).__Zone_enable_cross_context_check = true; 35 | 36 | /*************************************************************************************************** 37 | * Zone JS is required by default for Angular itself. 38 | */ 39 | import 'zone.js'; // Included with Angular CLI. 40 | 41 | 42 | 43 | /*************************************************************************************************** 44 | * APPLICATION IMPORTS 45 | */ 46 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | @import "~@angular/material/prebuilt-themes/indigo-pink.css"; -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | // First, initialize the Angular testing environment. 11 | getTestBed().initTestEnvironment( 12 | BrowserDynamicTestingModule, 13 | platformBrowserDynamicTesting() 14 | ); 15 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ 2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ 3 | { 4 | "extends": "./tsconfig.json", 5 | "compilerOptions": { 6 | "outDir": "./out-tsc/app", 7 | "types": [] 8 | }, 9 | "files": [ 10 | "src/main.ts", 11 | "src/polyfills.ts" 12 | ], 13 | "include": [ 14 | "src/**/*.d.ts" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ 2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ 3 | { 4 | "compileOnSave": false, 5 | "compilerOptions": { 6 | "outDir": "./dist/out-tsc", 7 | "strict": true, 8 | "noImplicitOverride": true, 9 | "noPropertyAccessFromIndexSignature": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "skipLibCheck": true, 13 | "isolatedModules": true, 14 | "esModuleInterop": true, 15 | "experimentalDecorators": true, 16 | "moduleResolution": "bundler", 17 | "importHelpers": true, 18 | "target": "ES2022", 19 | "module": "ES2022" 20 | }, 21 | "angularCompilerOptions": { 22 | "enableI18nLegacyMessageIdFormat": false, 23 | "strictInjectionParameters": true, 24 | "strictInputAccessModifiers": true, 25 | "strictTemplates": true 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ 2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ 3 | { 4 | "extends": "./tsconfig.json", 5 | "compilerOptions": { 6 | "outDir": "./out-tsc/spec", 7 | "types": [ 8 | "jasmine" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.spec.ts", 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | --------------------------------------------------------------------------------