-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merged in feature/SHIBUI-1267 (pull request #326)
SHIBUI-1267 Implemented configuration component Approved-by: Ryan Mathis <rmathis@unicon.net>
- Loading branch information
Showing
76 changed files
with
2,440 additions
and
1,001 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
ui/src/app/metadata/configuration/action/configuration.action.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import { Action } from '@ngrx/store'; | ||
import { Metadata } from '../../domain/domain.type'; | ||
import { Schema } from '../model/schema'; | ||
import { Wizard } from '../../../wizard/model'; | ||
|
||
export enum ConfigurationActionTypes { | ||
LOAD_METADATA_REQUEST = '[Metadata Configuration] Load Metadata Request', | ||
LOAD_METADATA_SUCCESS = '[Metadata Configuration] Load Metadata Success', | ||
LOAD_METADATA_ERROR = '[Metadata Configuration] Load Metadata Error', | ||
|
||
LOAD_SCHEMA_REQUEST = '[Metadata Configuration] Load Schema Request', | ||
LOAD_SCHEMA_SUCCESS = '[Metadata Configuration] Load Schema Success', | ||
LOAD_SCHEMA_ERROR = '[Metadata Configuration] Load Schema Error', | ||
|
||
LOAD_XML_REQUEST = '[Metadata Configuration] Load XML Request', | ||
LOAD_XML_SUCCESS = '[Metadata Configuration] Load XML Success', | ||
LOAD_XML_ERROR = '[Metadata Configuration] Load XML Error', | ||
|
||
SET_METADATA = '[Metadata Configuration] Set Metadata Model', | ||
SET_DEFINITION = '[Metadata Configuration] Set Metadata Definition', | ||
SET_SCHEMA = '[Metadata Configuration] Set Metadata Schema', | ||
SET_XML = '[Metadata Configuration] Set Metadata Xml', | ||
|
||
DOWNLOAD_XML = '[Metadata Configuration] Download Metadata Xml', | ||
|
||
CLEAR = '[Metadata Configuration] Clear' | ||
} | ||
|
||
export class LoadMetadataRequest implements Action { | ||
readonly type = ConfigurationActionTypes.LOAD_METADATA_REQUEST; | ||
|
||
constructor(public payload: { id: string, type: string }) { } | ||
} | ||
|
||
export class LoadMetadataSuccess implements Action { | ||
readonly type = ConfigurationActionTypes.LOAD_METADATA_SUCCESS; | ||
|
||
constructor(public payload: Metadata) { } | ||
} | ||
|
||
export class LoadMetadataError implements Action { | ||
readonly type = ConfigurationActionTypes.LOAD_METADATA_ERROR; | ||
|
||
constructor(public payload: any) { } | ||
} | ||
|
||
export class LoadSchemaRequest implements Action { | ||
readonly type = ConfigurationActionTypes.LOAD_SCHEMA_REQUEST; | ||
|
||
constructor(public payload: string) { } | ||
} | ||
|
||
export class LoadSchemaSuccess implements Action { | ||
readonly type = ConfigurationActionTypes.LOAD_SCHEMA_SUCCESS; | ||
|
||
constructor(public payload: Schema) { } | ||
} | ||
|
||
export class LoadSchemaError implements Action { | ||
readonly type = ConfigurationActionTypes.LOAD_SCHEMA_ERROR; | ||
|
||
constructor(public payload: any) { } | ||
} | ||
|
||
export class LoadXmlRequest implements Action { | ||
readonly type = ConfigurationActionTypes.LOAD_XML_REQUEST; | ||
|
||
constructor(public payload: string) { } | ||
} | ||
|
||
export class LoadXmlSuccess implements Action { | ||
readonly type = ConfigurationActionTypes.LOAD_XML_SUCCESS; | ||
|
||
constructor(public payload: string) { } | ||
} | ||
|
||
export class LoadXmlError implements Action { | ||
readonly type = ConfigurationActionTypes.LOAD_XML_ERROR; | ||
|
||
constructor(public payload: any) { } | ||
} | ||
|
||
export class SetMetadata implements Action { | ||
readonly type = ConfigurationActionTypes.SET_METADATA; | ||
|
||
constructor(public payload: Metadata) { } | ||
} | ||
|
||
export class SetDefinition implements Action { | ||
readonly type = ConfigurationActionTypes.SET_DEFINITION; | ||
|
||
constructor(public payload: Wizard<Metadata>) { } | ||
} | ||
|
||
export class SetSchema implements Action { | ||
readonly type = ConfigurationActionTypes.SET_SCHEMA; | ||
|
||
constructor(public payload: Schema) { } | ||
} | ||
|
||
export class SetXml implements Action { | ||
readonly type = ConfigurationActionTypes.SET_XML; | ||
|
||
constructor(public payload: string) { } | ||
} | ||
|
||
export class DownloadXml implements Action { | ||
readonly type = ConfigurationActionTypes.DOWNLOAD_XML; | ||
} | ||
|
||
export class ClearConfiguration implements Action { | ||
readonly type = ConfigurationActionTypes.CLEAR; | ||
} | ||
|
||
export type ConfigurationActionsUnion = | ||
| LoadMetadataRequest | ||
| LoadMetadataSuccess | ||
| LoadMetadataError | ||
| LoadSchemaRequest | ||
| LoadSchemaSuccess | ||
| LoadSchemaError | ||
| LoadXmlRequest | ||
| LoadXmlSuccess | ||
| LoadXmlError | ||
| SetMetadata | ||
| SetDefinition | ||
| SetSchema | ||
| SetXml | ||
| DownloadXml | ||
| ClearConfiguration; |
51 changes: 51 additions & 0 deletions
51
ui/src/app/metadata/configuration/component/array-property.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<div> | ||
<ng-container *ngIf="property.items.type === 'object'"> | ||
<div class="p-2" role="term" [translate]="property.name">{{ property.name }}</div> | ||
<div class="p-2" *ngIf="property.value && property.value.length"> | ||
<div *ngFor="let value of property.value; let i = index;" class="mb-2 bg-lighter"> | ||
<div *ngFor="let prop of getKeys(property.items); let n = index;" | ||
class="d-flex p-2"> | ||
<div class="w-50"> | ||
<span [class.invisible]="n">{{ i + 1 }}. </span> | ||
<span [translate]="property.items.properties[prop].title">{{ property.items.properties[prop].title }}</span> | ||
</div> | ||
<div class="w-50" [ngbPopover]="value[prop]" triggers="mouseenter:mouseleave" container="body" placement="left"> | ||
{{ value[prop] }} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</ng-container> | ||
<ng-container *ngIf="property.items.type === 'string'" [ngSwitch]="getItemType(property.items)"> | ||
<ng-container *ngSwitchCase="'datalist'"> | ||
<ng-template [ngTemplateOutlet]="listref"></ng-template> | ||
</ng-container> | ||
<ng-container *ngSwitchCase="'select'"> | ||
<ng-template [ngTemplateOutlet]="listref"></ng-template> | ||
</ng-container> | ||
<ng-container *ngSwitchDefault> | ||
<div *ngFor="let attr of attributeList$ | async" class="d-flex justify-content-between border-bottom border-light"> | ||
<span class="w-50 p-2" role="term" [translate]="attr.label">{{ attr.label }}</span> | ||
<div class="w-50 p-2"> | ||
<span *ngIf="property.value && property.value.indexOf(attr.key) > -1" translate="value.true"> | ||
true | ||
</span> | ||
<span *ngIf="!property.value || !(property.value.indexOf(attr.key) > -1)" translate="value.false"> | ||
false | ||
</span> | ||
</div> | ||
</div> | ||
</ng-container> | ||
</ng-container> | ||
</div> | ||
<ng-template #listref> | ||
<div class="d-flex border-bottom border-light"> | ||
<span class="w-50 p-2" role="term" [translate]="property.name">{{ property.name }}</span> | ||
<p class="text-secondary w-50 p-2" *ngIf="!property.value || !property.value.length">—</p> | ||
<ul class="list-unstyled w-50 py-2" *ngIf="property.value && property.value.length"> | ||
<li *ngFor="let item of property.value"> | ||
{{ item }} | ||
</li> | ||
</ul> | ||
</div> | ||
</ng-template> |
115 changes: 115 additions & 0 deletions
115
ui/src/app/metadata/configuration/component/array-property.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { Component, ViewChild, Input } from '@angular/core'; | ||
import { TestBed, async, ComponentFixture } from '@angular/core/testing'; | ||
import { RouterTestingModule } from '@angular/router/testing'; | ||
|
||
import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; | ||
import { Property } from '../../domain/model/property'; | ||
import { MockI18nModule } from '../../../../testing/i18n.stub'; | ||
import { SCHEMA } from '../../../../testing/form-schema.stub'; | ||
import { getStepProperty } from '../../domain/utility/configuration'; | ||
import { ArrayPropertyComponent } from './array-property.component'; | ||
import { AttributesService } from '../../domain/service/attributes.service'; | ||
import { MockAttributeService } from '../../../../testing/attributes.stub'; | ||
import { of } from 'rxjs'; | ||
|
||
@Component({ | ||
template: ` | ||
<array-property [property]="property"></array-property> | ||
` | ||
}) | ||
class TestHostComponent { | ||
@ViewChild(ArrayPropertyComponent) | ||
public componentUnderTest: ArrayPropertyComponent; | ||
|
||
property: Property = getStepProperty(SCHEMA.properties.list, { | ||
name: 'foo', | ||
type: 'baz', | ||
description: 'foo bar baz', | ||
list: [] | ||
}, SCHEMA.definitions); | ||
|
||
setProperty(property: Property): void { | ||
this.property = property; | ||
} | ||
} | ||
|
||
describe('Array Property Component', () => { | ||
|
||
let fixture: ComponentFixture<TestHostComponent>; | ||
let instance: TestHostComponent; | ||
let app: ArrayPropertyComponent; | ||
let service: AttributesService; | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [ | ||
NgbPopoverModule, | ||
MockI18nModule, | ||
RouterTestingModule | ||
], | ||
declarations: [ | ||
ArrayPropertyComponent, | ||
TestHostComponent | ||
], | ||
providers: [ | ||
{ provide: AttributesService, useClass: MockAttributeService } | ||
] | ||
}).compileComponents(); | ||
|
||
fixture = TestBed.createComponent(TestHostComponent); | ||
instance = fixture.componentInstance; | ||
app = instance.componentUnderTest; | ||
service = TestBed.get(AttributesService); | ||
fixture.detectChanges(); | ||
})); | ||
|
||
it('should accept a property input', async(() => { | ||
expect(app).toBeTruthy(); | ||
})); | ||
|
||
describe('attributeList$ getter', () => { | ||
it('should return an empty list when no data or dataUrl is set', () => { | ||
app.attributeList$.subscribe((list) => { | ||
expect(list).toEqual([]); | ||
}); | ||
}); | ||
it('should return a list of data items from the schema', () => { | ||
const datalist = [ | ||
{ key: 'foo', label: 'foo' }, | ||
{ key: 'bar', label: 'bar' }, | ||
{ key: 'baz', label: 'baz' }, | ||
]; | ||
instance.setProperty({ | ||
...instance.property, | ||
widget: { | ||
id: 'datalist', | ||
data: datalist | ||
} | ||
}); | ||
fixture.detectChanges(); | ||
app.attributeList$.subscribe(list => { | ||
expect(list).toEqual(datalist); | ||
}); | ||
}); | ||
|
||
it('should call the attribute service with a provided dataUrl', () => { | ||
const datalist = [ | ||
{ key: 'foo', label: 'foo' }, | ||
{ key: 'bar', label: 'bar' }, | ||
{ key: 'baz', label: 'baz' }, | ||
]; | ||
spyOn(service, 'query').and.returnValue(of(datalist)); | ||
instance.setProperty({ | ||
...instance.property, | ||
widget: { | ||
id: 'datalist', | ||
dataUrl: '/foo' | ||
} | ||
}); | ||
fixture.detectChanges(); | ||
app.attributeList$.subscribe(list => { | ||
expect(list).toEqual(datalist); | ||
}); | ||
}); | ||
}); | ||
}); |
32 changes: 32 additions & 0 deletions
32
ui/src/app/metadata/configuration/component/array-property.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Component, Input } from '@angular/core'; | ||
import { Property } from '../../domain/model/property'; | ||
import { Observable, of } from 'rxjs'; | ||
import { AttributesService } from '../../domain/service/attributes.service'; | ||
import { ConfigurationPropertyComponent } from './configuration-property.component'; | ||
|
||
@Component({ | ||
selector: 'array-property', | ||
templateUrl: './array-property.component.html', | ||
styleUrls: [] | ||
}) | ||
|
||
export class ArrayPropertyComponent extends ConfigurationPropertyComponent { | ||
@Input() property: Property; | ||
|
||
constructor( | ||
private attrService: AttributesService | ||
) { | ||
super(); | ||
} | ||
|
||
get attributeList$(): Observable<{ key: string, label: string }[]> { | ||
if (this.property.widget && this.property.widget.hasOwnProperty('data')) { | ||
return of(this.property.widget.data); | ||
} | ||
if (this.property.widget && this.property.widget.hasOwnProperty('dataUrl')) { | ||
return this.attrService.query(this.property.widget.dataUrl); | ||
} | ||
return of([]); | ||
} | ||
} | ||
|
Empty file.
Oops, something went wrong.