Skip to content

Commit

Permalink
Add support for defining a details view on a table control (#725)
Browse files Browse the repository at this point in the history
Adds support for providing an option `detail-uischema` which takes a
UISchema and uses this as the detail view instead of a generated one
  • Loading branch information
eneufeld authored and edgarmueller committed Dec 7, 2017
1 parent 5e03fe3 commit eda12a5
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 150 deletions.
166 changes: 97 additions & 69 deletions examples/data/array.data.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,112 @@
export default angular.module('jsonforms-examples.array', [])
.value('array.schema',
{
'type': 'object',
'properties': {
'name': {
'type': 'string'
},
'vegetarian': {
'type': 'boolean'
},
'birthDate': {
'type': 'string',
'format': 'date-time'
},
'nationality': {
'type': 'string',
'enum': ['DE', 'IT', 'JP', 'US', 'RU', 'Other']
},
'occupation': {
'type': 'string'
},
'comments': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'date': {
'type': 'string',
'format': 'date-time'
},
'message': {
'type': 'string'
}
{
'type': 'object',
'properties': {
'name': {
'type': 'string'
},
'vegetarian': {
'type': 'boolean'
},
'birthDate': {
'type': 'string',
'format': 'date-time'
},
'nationality': {
'type': 'string',
'enum': ['DE', 'IT', 'JP', 'US', 'RU', 'Other']
},
'occupation': {
'type': 'string'
},
'comments': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'date': {
'type': 'string',
'format': 'date-time'
},
'message': {
'type': 'string'
}
}
}
},
'required': ['occupation', 'nationality']
}
}
},
'required': ['occupation', 'nationality']
}
)
.value('array.uischema',
{
'type': 'VerticalLayout',
'elements': [
{
'type': 'Control',
'scope': {
'$ref': '#/properties/comments'
},
'options': {
'submit': true
{
'type': 'VerticalLayout',
'elements': [
{
'type': 'Control',
'scope': {
'$ref': '#/properties/comments'
},
'options': {
'submit': true,
'detail-uischema': {
'type': 'Group',
'label': 'MyGroup',
'elements': [
{
'type': 'Control',
'scope': {
'$ref': '#/properties/date'
},
'rule': {
'effect': 'HIDE',
'condition': {
'type': 'LEAF',
'scope': {
'$ref': '#/properties/message'
},
'expectedValue': 'foo'
}
}
},
{
'type': 'Control',
'scope': {
'$ref': '#/properties/message'
}
}
]
}
}
]
}
}
]
}
)
.value('array.uischema-simple',
{
'type': 'Control',
'scope': {
'$ref': '#/properties/comments'
},
'label': 'Some more comments',
'options': {
'simple': true
}
{
'type': 'Control',
'scope': {
'$ref': '#/properties/comments'
},
'label': 'Some more comments',
'options': {
'simple': true
}
}
)
.value('array.data',
{
'comments': [
{
'date': new Date(),
'message': 'This is an example message'
},
{
'date': new Date(),
'message': 'Get ready for booohay'
}
]
}
{
'comments': [
{
'date': new Date(),
'message': 'This is an example message'
},
{
'date': new Date(),
'message': 'Get ready for booohay'
}
]
}
)
.name;
.name;
165 changes: 84 additions & 81 deletions src/components/renderers/controls/array/array.directive.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import 'lodash';
import {PathUtil} from '../../../services/pathutil';
import {IUISchemaGenerator} from '../../../generators/generators';
import {AbstractControl} from '../abstract-control';
import {IGroup} from '../../../../uischema';
import {SchemaArray} from '../../../../jsonschema';
import {PathResolver} from '../../../services/path-resolver/path-resolver';
import {Testers, schemaTypeIs, optionIs} from '../../testers';
import { PathUtil } from '../../../services/pathutil';
import { IUISchemaGenerator } from '../../../generators/generators';
import { AbstractControl } from '../abstract-control';
import { IGroup } from '../../../../uischema';
import { SchemaArray } from '../../../../jsonschema';
import { PathResolver } from '../../../services/path-resolver/path-resolver';
import { Testers, schemaTypeIs, optionIs } from '../../testers';
let pluralize = require('pluralize');

const readOnlyArrayTemplate = `
Expand All @@ -25,21 +25,21 @@ const readOnlyArrayTemplate = `
</jsonforms-layout>`;

class ArrayReadOnlyDirective implements ng.IDirective {
restrict = 'E';
templateUrl = 'read-only-array.html';
controller = ArrayController;
controllerAs = 'vm';
restrict = 'E';
templateUrl = 'read-only-array.html';
controller = ArrayController;
controllerAs = 'vm';
}

const arrayTemplate = `
<jsonforms-layout>
<fieldset ng-disabled="vm.uiSchema.readOnly">
<legend>{{vm.label}}</legend>
<div ng-repeat="d in vm.resolvedData"
<div ng-repeat="d in vm.resolvedData"
ng-if="vm.fragment === undefined"
class="jsf-control-array-container">
<div class="jsf-control-array-element">
<jsonforms schema="vm.arraySchema"
<jsonforms schema="vm.arraySchema"
data="d"
uischema="vm.arrayUiSchema">
</jsonforms>
Expand All @@ -54,12 +54,12 @@ const arrayTemplate = `
</div>
</div>
<div ng-repeat="d in vm.resolvedData[vm.fragment]"
ng-if="vm.fragment !== undefined"
ng-if="vm.fragment !== undefined"
class="jsf-control-array-container">
<div class="jsf-control-array-element">
<jsonforms schema="vm.arraySchema"
data="d"
uischema="vm.arrayUiSchema">
<jsonforms schema="vm.arraySchema"
data="d"
uischema="vm.arrayUiSchema">
</jsonforms>
</div>
<div class="jsf-control-array-element-delete">
Expand All @@ -83,81 +83,84 @@ const arrayTemplate = `
</jsonforms-layout>`;

class ArrayDirective implements ng.IDirective {
restrict = 'E';
templateUrl = 'array.html';
controller = ArrayController;
controllerAs = 'vm';
restrict = 'E';
templateUrl = 'array.html';
controller = ArrayController;
controllerAs = 'vm';
}

interface ArrayControllerScope extends ng.IScope {
}

class ArrayController extends AbstractControl {
static $inject = ['$scope', 'UISchemaGenerator'];
private properties: string[];
private submitElement = {};
private arraySchema: any;
private arrayUiSchema: IGroup;
constructor(scope: ArrayControllerScope, uiGenerator: IUISchemaGenerator) {
super(scope);
let resolvedSubSchema = PathResolver.resolveSchema(
this.schema, this.schemaPath) as SchemaArray;
let items = resolvedSubSchema.items;
this.arraySchema = items;
this.properties = _.keys(items['properties']);
this.arrayUiSchema = uiGenerator.generateDefaultUISchema(items, 'HorizontalLayout');
}
static $inject = ['$scope', 'UISchemaGenerator'];
private properties: string[];
private submitElement = {};
private arraySchema: any;
private arrayUiSchema: IGroup;
constructor(scope: ArrayControllerScope, uiGenerator: IUISchemaGenerator) {
super(scope);
let resolvedSubSchema = PathResolver.resolveSchema(
this.schema, this.schemaPath) as SchemaArray;
let items = resolvedSubSchema.items;
this.arraySchema = items;
this.properties = _.keys(items['properties']);
const detailUiSchema = this.uiSchema['options'] ?
this.uiSchema['options']['detail-uischema'] : undefined;
this.arrayUiSchema = detailUiSchema ? detailUiSchema :
uiGenerator.generateDefaultUISchema(items, 'HorizontalLayout');
}

public get buttonText(){
return pluralize(PathUtil.beautifiedLastFragment(this.schemaPath), 1);
}
public submitCallback() {
if (this.resolvedData[this.fragment] === undefined) {
this.resolvedData[this.fragment] = [];
}
this.resolvedData[this.fragment].push(_.clone(this.submitElement));
this.submitElement = {};
}
public deleteCallback(element: any) {
let index = this.resolvedData[this.fragment].indexOf(element);
if (index !== -1) {
this.resolvedData[this.fragment].splice(index, 1);
}
public get buttonText() {
return pluralize(PathUtil.beautifiedLastFragment(this.schemaPath), 1);
}
public submitCallback() {
if (this.resolvedData[this.fragment] === undefined) {
this.resolvedData[this.fragment] = [];
}
public get supportsSubmit(){
return this.supports('submit');
}
public get supportsDelete(){
return this.supports('delete');
}
private supports(keyword: string) {
let options = this.uiSchema['options'];
return !(options !== undefined && options[keyword] === false);
this.resolvedData[this.fragment].push(_.clone(this.submitElement));
this.submitElement = {};
}
public deleteCallback(element: any) {
let index = this.resolvedData[this.fragment].indexOf(element);
if (index !== -1) {
this.resolvedData[this.fragment].splice(index, 1);
}
}
public get supportsSubmit() {
return this.supports('submit');
}
public get supportsDelete() {
return this.supports('delete');
}
private supports(keyword: string) {
let options = this.uiSchema['options'];
return !(options !== undefined && options[keyword] === false);
}

public get isEmpty(): boolean {
return _.isEmpty(this.resolvedData) || _.isEmpty(this.resolvedData[this.fragment]);
}
public get isEmpty(): boolean {
return _.isEmpty(this.resolvedData) || _.isEmpty(this.resolvedData[this.fragment]);
}

public get emptyMsg(): string {
return 'No ' + PathUtil.beautifiedLastFragment(this.schemaPath) + ' yet.';
}
public get emptyMsg(): string {
return 'No ' + PathUtil.beautifiedLastFragment(this.schemaPath) + ' yet.';
}
}

export default angular
.module('jsonforms.renderers.controls.array', ['jsonforms.renderers.controls'])
.directive('arrayReadonlyControl', () => new ArrayReadOnlyDirective())
.directive('arrayControl', () => new ArrayDirective())
.run(['RendererService', RendererService => {
RendererService.register('array-readonly-control',
Testers.and(
schemaTypeIs('array'),
optionIs('simple', true)
), 1);
RendererService.register('array-control', schemaTypeIs('array'), 1);
}])
.run(['$templateCache', $templateCache => {
$templateCache.put('read-only-array.html', readOnlyArrayTemplate);
$templateCache.put('array.html', arrayTemplate);
}])
.name;
.module('jsonforms.renderers.controls.array', ['jsonforms.renderers.controls'])
.directive('arrayReadonlyControl', () => new ArrayReadOnlyDirective())
.directive('arrayControl', () => new ArrayDirective())
.run(['RendererService', RendererService => {
RendererService.register('array-readonly-control',
Testers.and(
schemaTypeIs('array'),
optionIs('simple', true)
), 1);
RendererService.register('array-control', schemaTypeIs('array'), 1);
}])
.run(['$templateCache', $templateCache => {
$templateCache.put('read-only-array.html', readOnlyArrayTemplate);
$templateCache.put('array.html', arrayTemplate);
}])
.name;

0 comments on commit eda12a5

Please sign in to comment.