Skip to content

Commit 2abb9c7

Browse files
eneufeldedgarmueller
authored andcommitted
Add readonly utility function (eclipsesource#1371)
* Add support for angular renderers * Add button to set/unset readonly in example
1 parent 5228425 commit 2abb9c7

File tree

12 files changed

+107
-10
lines changed

12 files changed

+107
-10
lines changed

packages/angular-material/example/app/app.component.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,14 @@
2424
*/
2525
import { NgRedux, select } from '@angular-redux/store';
2626
import { Component } from '@angular/core';
27-
import { Actions, JsonFormsState, setLocale } from '@jsonforms/core';
27+
import {
28+
Actions,
29+
getUiSchema,
30+
JsonFormsState,
31+
setLocale,
32+
setReadonly,
33+
unsetReadonly
34+
} from '@jsonforms/core';
2835
import { ExampleDescription } from '@jsonforms/examples';
2936
import { Observable } from 'rxjs';
3037
@Component({
@@ -48,13 +55,17 @@ import { Observable } from 'rxjs';
4855
<button (click)="changeLocale('de-DE')">Change locale to de-DE</button>
4956
<button (click)="changeLocale('en-US')">Change locale to en-US</button>
5057
Current locale: {{ currentLocale }}
58+
<button (click)="setReadonly()">
59+
{{ readonly ? 'Unset' : 'Set' }} Readonly
60+
</button>
5161
</div>
5262
<jsonforms-outlet></jsonforms-outlet>
5363
`
5464
})
5565
export class AppComponent {
5666
@select(['examples', 'data']) readonly exampleData$: Observable<any>;
5767
currentLocale = 'en-US';
68+
private readonly = false;
5869

5970
constructor(
6071
private ngRedux: NgRedux<
@@ -80,4 +91,15 @@ export class AppComponent {
8091
this.currentLocale = locale;
8192
this.ngRedux.dispatch(setLocale(locale));
8293
}
94+
95+
setReadonly() {
96+
const uischema = getUiSchema(this.ngRedux.getState());
97+
if (this.readonly) {
98+
unsetReadonly(uischema);
99+
} else {
100+
setReadonly(uischema);
101+
}
102+
this.readonly = !this.readonly;
103+
this.ngRedux.dispatch(Actions.setUISchema(uischema));
104+
}
83105
}

packages/angular-material/example/app/store.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const rootReducer: Reducer<JsonFormsState> = combineReducers({
3232
examples: (state: ExampleDescription[] = []) => state
3333
});
3434

35-
export const initialState: any = {
35+
export const initialState = {
3636
jsonforms: {
3737
renderers: angularMaterialRenderers
3838
},

packages/angular-material/src/controls/boolean.renderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import {
4444
<mat-checkbox
4545
(change)="onChange($event)"
4646
[checked]="isChecked()"
47-
[disabled]="!enabled"
47+
[disabled]="!isEnabled()"
4848
[id]="id"
4949
>
5050
{{ label }}

packages/angular-material/src/controls/range.renderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import {
4242
<mat-slider
4343
[value]="data || scopedSchema.default"
4444
(change)="onChange($event)"
45-
[disabled]="!enabled"
45+
[disabled]="!isEnabled()"
4646
[max]="max"
4747
[min]="min"
4848
[step]="multipleOf"

packages/angular-material/src/controls/toggle.renderer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import {
4141
<mat-slide-toggle
4242
(change)="onChange($event)"
4343
[checked]="isChecked()"
44-
[disabled]="!enabled"
44+
[disabled]="!isEnabled()"
4545
[id]="id"
4646
>
4747
{{ label }}

packages/angular-material/src/other/master-detail/master.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
mapStateToArrayControlProps,
3838
RankedTester,
3939
rankWith,
40+
setReadonly,
4041
uiTypeIs
4142
} from '@jsonforms/core';
4243

@@ -75,6 +76,7 @@ export const removeSchemaKeywords = (path: string) => {
7576
class="button hide"
7677
(click)="onDeleteClick(i)"
7778
[ngClass]="{ show: highlightedIdx == i }"
79+
*ngIf="isEnabled()"
7880
>
7981
<mat-icon mat-list-icon>delete</mat-icon>
8082
</button>
@@ -85,6 +87,7 @@ export const removeSchemaKeywords = (path: string) => {
8587
color="primary"
8688
class="add-button"
8789
(click)="onAddClick()"
90+
*ngIf="isEnabled()"
8891
>
8992
<mat-icon aria-label="Add item to list">add</mat-icon>
9093
</button>
@@ -173,6 +176,9 @@ export class MasterListComponent extends JsonFormsArrayControl {
173176
props.path,
174177
'VerticalLayout'
175178
);
179+
if (!this.isEnabled()) {
180+
setReadonly(detailUISchema);
181+
}
176182

177183
const masterItems = (data || []).map((d: any, index: number) => {
178184
const labelRefInstancePath = removeSchemaKeywords(

packages/angular-material/src/other/object.renderer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
JsonFormsState,
3636
RankedTester,
3737
rankWith,
38+
setReadonly,
3839
UISchemaElement
3940
} from '@jsonforms/core';
4041

@@ -69,6 +70,9 @@ export class ObjectControlRenderer extends JsonFormsControlWithDetail {
6970
} else {
7071
(this.detailUiSchema as GroupLayout).label = startCase(props.path);
7172
}
73+
if (!this.isEnabled()) {
74+
setReadonly(this.detailUiSchema);
75+
}
7276
}
7377
}
7478
export const ObjectControlRendererTester: RankedTester = rankWith(

packages/angular/src/abstract-control.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export abstract class JsonFormsAbstractControl<
109109
this.data = data;
110110
this.error = errors;
111111
this.enabled = enabled;
112-
this.enabled ? this.form.enable() : this.form.disable();
112+
this.isEnabled() ? this.form.enable() : this.form.disable();
113113
this.hidden = !visible;
114114
this.scopedSchema = schema;
115115
this.rootSchema = rootSchema;
@@ -138,6 +138,13 @@ export abstract class JsonFormsAbstractControl<
138138
}
139139
}
140140

141+
isEnabled(): boolean {
142+
return (
143+
this.enabled &&
144+
(this.uischema.options ? !this.uischema.options.readonly : true)
145+
);
146+
}
147+
141148
protected getOwnProps(): OwnPropsOfControl {
142149
const props: OwnPropsOfControl = {
143150
uischema: this.uischema,

packages/core/src/generators/uischema.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { JsonSchema } from '../models/jsonSchema';
2929
import {
3030
ControlElement,
3131
isGroup,
32+
isLayout,
3233
LabelElement,
3334
Layout,
3435
UISchemaElement
@@ -54,9 +55,6 @@ export const createControlElement = (ref: string): ControlElement => ({
5455
scope: ref
5556
});
5657

57-
const isLayout = (uischema: UISchemaElement): uischema is Layout =>
58-
(uischema as Layout).elements !== undefined;
59-
6058
/**
6159
* Wraps the given {@code uiSchema} in a Layout if there is none already.
6260
* @param uischema The ui schema to wrap in a layout.

packages/core/src/models/uischema.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export interface UISchemaElement {
137137
/**
138138
* Any additional options.
139139
*/
140-
options?: any;
140+
options?: { [key: string]: any };
141141
}
142142

143143
/**
@@ -245,3 +245,6 @@ export interface Categorization extends UISchemaElement {
245245

246246
export const isGroup = (layout: Layout): layout is GroupLayout =>
247247
layout.type === 'Group';
248+
249+
export const isLayout = (uischema: UISchemaElement): uischema is Layout =>
250+
(uischema as Layout).elements !== undefined;

0 commit comments

Comments
 (0)