Merge branch 'Development' of gitlab.eudat.eu:dmp/OpenAIRE-EUDAT-DMP-service-pilot into Development

This commit is contained in:
Nikolaos Laskaris 2017-11-27 18:34:21 +02:00
commit 722cd8b482
87 changed files with 1877 additions and 1180 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
dmp-frontend/dist.7z
.idea/

View File

@ -39,7 +39,8 @@
</div><!-- /.container-fluid -->
</nav>
<main-window [ngClass]="{false:'invisible'}[tokenService.isLoggedIn() == true]"></main-window>
<form-comp></form-comp>
<!-- <main-window [ngClass]="{false:'invisible'}[tokenService.isLoggedIn() == true]"></main-window> -->
<app-main-sign-in [ngClass]="{true:'invisible'}[tokenService.isLoggedIn() == true]"></app-main-sign-in>

View File

@ -61,6 +61,13 @@ import { DatareposEditorComponent } from './managers/datarepos-editor/datarepos-
import { DatasetprofileEditorComponent } from './managers/datasetprofile-editor/datasetprofile-editor.component';
import { DatasetProfileGUIEditorComponent } from './dataset-profile-gui-editor/dataset-profile-gui-editor.component';
import { FieldFormComponent } from './field-form/field-form.component';
import { FormComponent } from './formBuilder/form.component';
import { GroupFieldFormComponent } from './groupfield-form/groupfield-form.component';
import { RuleFormComponent } from './rule-component/rule.component';
import { SectionFormComponent } from './section-form/section-form.component';
import { CompositeFieldFormComponent } from './compositefield-form/compositefield-form.component';
@NgModule({
@ -78,6 +85,12 @@ import { DatasetProfileGUIEditorComponent } from './dataset-profile-gui-editor/d
AppComponent,
GooggleSignInComponent,
FieldFormComponent,
FormComponent,
GroupFieldFormComponent,
RuleFormComponent,
SectionFormComponent,
CompositeFieldFormComponent,
DatasetsViewerComponent,
ProfileEditorComponent,
PropertiesEditorComponent,

View File

@ -0,0 +1,12 @@
<div class= "container">
<h4>FieldSet</h4>
<div *ngFor="let field of dataModel.fields let i=index;">
<field-form [form]="form.get('fields').get(''+i)" [dataModel]="field"></field-form>
</div>
<div>
<a (click)="addNewField()" style="cursor: pointer">
Add another field +
</a>
</div>
</div>

View File

@ -0,0 +1,29 @@
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { CompositeField } from '../models/CompositeField';
import { Field } from '../models/Field';
import { FormArray } from '@angular/forms/src/model';
@Component({
selector: 'compositefield-form',
templateUrl: './compositefield-form.component.html',
styleUrls: []
})
export class CompositeFieldFormComponent {
@Input() form: FormGroup;
@Input() dataModel: CompositeField;
constructon(){}
ngOnInit(){
this.addNewField();
}
addNewField(){
let field: Field = new Field();
this.dataModel.fields.push(field);
(<FormArray>this.form.get("fields")).push(field.buildForm());
}
}

View File

@ -0,0 +1,62 @@
<div>
<h4 style="text-decoration: underline;">Fields</h4>
<div [formGroup]="form">
<div class="form-row">
<div class="form-group col-md-4">
<label>Title</label>
<input type="text" class="form-control" formControlName="title">
</div>
<div class="form-group col-md-4">
<label>Id</label>
<input type="text" class="form-control" formControlName="id">
</div>
<div class="form-row col-md-4">
<div class="form-group">
<label>View style</label>
<select class="form-control" formControlName="viewStyle">
<option>textarea</option>
<option>booleanDesicion</option>
<option>combobox</option>
<option>checkBox</option>
<option>freetext</option>
</select>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<label>description</label>
<input type="text" class="form-control" formControlName="description">
</div>
<div class="form-group col-md-4">
<label>extendedDescription</label>
<input type="text" class="form-control" formControlName="extendedDescription">
</div>
<div class="form-group col-md-4">
<label>Ordinal</label>
<input type="number" class="form-control" formControlName="extendedDescription">
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label>Default Visibility</label>
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1"> true
</label>
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2"> false
</label>
</div>
</div>
</div>
<div *ngFor="let rule of dataModel.rules let i=index;">
<rule-form [form]="form.get('rules').get(''+i)" [dataModel]="rule"></rule-form>
</div>
<div style="padding-left: 15px;">
<a (click)="addNewRule(form)" style="cursor: pointer">
Add another rule +
</a>
</div>
</div>

View File

@ -0,0 +1,29 @@
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Field } from '../models/Field';
import { Rule } from '../models/Rule';
import { FormArray } from '@angular/forms/src/model';
@Component({
selector: 'field-form',
templateUrl: './field-form.component.html',
styleUrls: []
})
export class FieldFormComponent {
@Input() form: FormGroup;
@Input() dataModel: Field;
constructon(){}
ngOnInit(){
this.addNewRule();
}
addNewRule(){
let rule: Rule = new Rule();
this.dataModel.rules.push(rule);
(<FormArray>this.form.get("rules")).push(rule.buildForm());
}
}

View File

@ -0,0 +1,15 @@
<div class="container">
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit()">
<div *ngFor="let section of dataModel.sections; let i=index;">
<section-form [form]="form.get('sections').get(''+i)" [dataModel]="section"></section-form>
</div>
<div style="margin-top:20px; padding-left: 15px;">
<a (click)="addSection()" style="cursor: pointer">
Add another section +
</a>
</div>
<button type="submit">Save</button>
<p>Form value: {{ form.value | json }}</p>
</form>
</div>

View File

@ -0,0 +1,39 @@
import { Component, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { JsonSerializer } from '../utilities/JsonSerializer';
import { SectionFormComponent } from '../section-form/section-form.component';
import { Section } from '../models/Section';
import { FieldGroup } from '../models/FieldGroup';
import { DatasetProfileModel } from '../models/DatasetProfileModel';
import { TestModel } from '../testModel/testModel';
import { FormArray } from '@angular/forms/src/model';
@Component({
selector: 'form-comp',
templateUrl: './form.component.html',
styleUrls: []
})
export class FormComponent {
dataModel: DatasetProfileModel ;
form: FormGroup;
constructor(){
}
ngOnInit(){
this.dataModel = new DatasetProfileModel();
this.dataModel = new JsonSerializer<DatasetProfileModel>().fromJSONObject(TestModel,DatasetProfileModel);
this.form = this.dataModel.buildForm();
this.addSection();
}
addSection(){
let section:Section = new Section();
this.dataModel.sections.push(section);
(<FormArray>this.form.get("sections")).push(section.buildForm());
}
}

View File

@ -0,0 +1,38 @@
<div class= "container">
<h4 style="text-decoration: underline;">GroupFields</h4>
<div [formGroup]="form">
<div class="form-row">
<div class="form-group col-md-4">
<label>Title</label>
<input type="text" class="form-control" formControlName="title">
</div>
<div class="form-group col-md-4">
<label>Id</label>
<input type="text" class="form-control" formControlName="id">
</div>
<div class="form-group col-md-4">
<label>defaultVisibility</label>
<input type="text" class="form-control" formControlName="defaultVisibility">
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label>description</label>
<input type="text" class="form-control" formControlName="description">
</div>
<div class="form-group col-md-6">
<label>extendedDescription</label>
<input type="text" class="form-control" formControlName="extendedDescription">
</div>
</div>
</div>
<div *ngFor="let field of dataModel.compositeFields let i=index;">
<compositefield-form [form]="form.get('compositeFields').get(''+i)" [dataModel]="field"></compositefield-form>
</div>
<div>
<a (click)="addNewField()" style="cursor: pointer">
Add another field Set (CompositeField) +
</a>
</div>
</div>

View File

@ -0,0 +1,29 @@
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FieldGroup } from '../models/FieldGroup';
import { CompositeField } from '../models/CompositeField';
import { FormArray } from '@angular/forms/src/model';
@Component({
selector: 'groupfield-form',
templateUrl: './groupfield-form.component.html',
styleUrls: []
})
export class GroupFieldFormComponent {
@Input() form: FormGroup;
@Input() dataModel: FieldGroup;
constructor(){}
ngOnInit(){
this.addNewField();
}
addNewField(){
let compositeField: CompositeField = new CompositeField();
this.dataModel.compositeFields.push(compositeField);
(<FormArray>this.form.get("compositeFields")).push(compositeField.buildForm());
}
}

View File

@ -0,0 +1,4 @@
import { FormBuilder } from '@angular/forms';
export abstract class BaseModel{
public formBuilder:FormBuilder = new FormBuilder();
}

View File

@ -0,0 +1,27 @@
import { FormGroup } from '@angular/forms';
import { JsonSerializer } from '../utilities/JsonSerializer';
import { Serializable } from './interfaces/Serializable';
import { BaseModel } from './BaseModel';
import {Field} from './Field'
export class CompositeField extends BaseModel implements Serializable<CompositeField> {
public fields:Array<Field> = new Array<Field>();
fromJSONObject(item:any):CompositeField{
this.fields = new JsonSerializer<Field>().fromJSONArray(item.fields,Field);
return this;
}
buildForm():FormGroup{
let formGroup = this.formBuilder.group({});
let fieldsFormArray = new Array<FormGroup>();
this.fields.forEach(item => {
let form: FormGroup = item.buildForm();
fieldsFormArray.push(form)
})
formGroup.addControl('fields', this.formBuilder.array(fieldsFormArray));
return formGroup;
}
}

View File

@ -0,0 +1,27 @@
import { BaseModel } from './BaseModel';
import { FormBuilder, FormGroup } from '@angular/forms';
import { FormGenerator } from './interfaces/FormGenerator';
import { JsonSerializer } from '../utilities/JsonSerializer';
import { Section } from './Section';
import { Serializable } from './interfaces/Serializable';
export class DatasetProfileModel extends BaseModel implements Serializable<DatasetProfileModel>,FormGenerator<FormGroup>{
public sections:Array<Section> = new Array<Section>();
fromJSONObject(item:any):DatasetProfileModel{
this.sections = new JsonSerializer<Section>().fromJSONArray(item.sections,Section);
return this;
}
buildForm():FormGroup{
let formGroup:FormGroup = new FormBuilder().group({});
let sectionsFormArray = new Array<FormGroup>();
this.sections.forEach(item => {
let form: FormGroup = item.buildForm();
sectionsFormArray.push(form)
})
formGroup.addControl('sections', this.formBuilder.array(sectionsFormArray));
return formGroup;
}
}

View File

@ -0,0 +1,57 @@
import { BaseModel } from './BaseModel';
import { FormGroup } from '@angular/forms';
import { FormGenerator } from './interfaces/FormGenerator';
import { JsonSerializer } from '../utilities/JsonSerializer';
import { Serializable } from './interfaces/Serializable';
import {Rule} from './Rule'
export class Field extends BaseModel implements Serializable<Field>,FormGenerator<FormGroup>{
public id:string;
public title:string;
public value:string;
public description:string;
public extendedDescription:string;
public viewStyle:string;
public defaultVisibility:boolean;
public page:number;
public rules: Array<Rule> = new Array<Rule>();
fromJSONObject(item:any):Field{
this.id = item.id;
this.title = item.title;
this.value = item.value;
this.description = item.description;
this.extendedDescription = item.extendedDescription;
this.viewStyle = item.viewStyle;
this.defaultVisibility = item.defaultVisibility;
this.page = item.page;
this.rules = new JsonSerializer<Rule>().fromJSONArray(item.rule, Rule);
return this;
}
buildForm():FormGroup{
let formGroup = this.formBuilder.group({
id: [this.id],
title: [this.title],
value: [this.value],
description: [this.description],
extendedDescription:[this.extendedDescription],
viewStyle: [this.viewStyle],
defaultVisibility:[this.defaultVisibility],
page:[this.page]
});
let rulesFormArray = new Array<FormGroup>();
if (this.rules){
this.rules.forEach(rule =>{
let form:FormGroup = rule.buildForm();
rulesFormArray.push(form);
});
}
formGroup.addControl("rules", this.formBuilder.array(rulesFormArray))
return formGroup;
}
}

View File

@ -0,0 +1,58 @@
import { CompositeField } from './CompositeField';
import { BaseModel } from './BaseModel';
import { FormGroup } from '@angular/forms';
import { FormGenerator } from './interfaces/FormGenerator';
import { Validation } from './Validation';
import { Rule } from './Rule';
import { JsonSerializer } from '../utilities/JsonSerializer';
import { Serializable } from './interfaces/Serializable';
import { Field } from './Field';
export class FieldGroup extends BaseModel implements Serializable<FieldGroup>, FormGenerator<FormGroup>{
public id: string;
public title: string;
public section: string;
public value: string;
public description: string;
public extendedDescription: string;
public defaultVisibility: boolean;
public page: number;
public ordinal: number;
public compositeFields: Array<CompositeField> = new Array<CompositeField>();
fromJSONObject(item: any): FieldGroup {
this.id = item.id;
this.title = item.title;
this.value = item.value;
this.description = item.description;
this.extendedDescription = item.extendedDescription;
this.defaultVisibility = item.defaultVisibility;
this.page = item.page;
this.ordinal = item.ordinal;
this.compositeFields = new JsonSerializer<CompositeField>().fromJSONArray(item.compositeFields, CompositeField);
return this;
}
buildForm(): FormGroup {
let formGroup: FormGroup = this.formBuilder.group({
id: [this.id],
title: [this.title],
value: [this.value],
description: [this.description],
extendedDescription: [this.extendedDescription],
defaultVisibility: [this.defaultVisibility],
page: [this.page],
ordinal: [this.ordinal]
});
let compositeFieldsFormArray = new Array<FormGroup>();
if (this.compositeFields) {
this.compositeFields.forEach(item => {
let form: FormGroup = item.buildForm();
compositeFieldsFormArray.push(form)
})
}
formGroup.addControl('compositeFields', this.formBuilder.array(compositeFieldsFormArray));
return formGroup;
}
}

View File

@ -0,0 +1,29 @@
import { BaseModel } from './BaseModel';
import { FormGroup } from '@angular/forms';
import { FormGenerator } from './interfaces/FormGenerator';
import { Serializable } from './interfaces/Serializable';
export class Rule extends BaseModel implements Serializable<Rule>,FormGenerator<FormGroup>{
public sourceField:string;
public targetField:string;
public requiredValue;
public type: string;
fromJSONObject(item:any):Rule{
this.sourceField = item.sourceField;
this.targetField = item.targetField;
this.requiredValue = item.requiredValue;
this.type = item.type;
return this;
}
buildForm():FormGroup{
let formGroup = this.formBuilder.group({
sourceField: [this.sourceField],
targetField: [this.targetField],
requiredValue: [this.requiredValue],
type: [this.type]
});
return formGroup;
}
}

View File

@ -0,0 +1,55 @@
import { BaseModel } from './BaseModel';
import { FormGenerator } from './interfaces/FormGenerator';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { JsonSerializer } from '../utilities/JsonSerializer';
import { Serializable } from './interfaces/Serializable';
import { FieldGroup } from './FieldGroup';
export class Section extends BaseModel implements Serializable<Section>, FormGenerator<FormGroup>{
public sections: Array<Section> = new Array<Section>();
public fieldGroups: Array<FieldGroup> = new Array<FieldGroup>();
public defaultVisibility: boolean;
public page: number;
public id: string
public title: string
public description: string;
public ordinal: number;
fromJSONObject(item: any): Section {
this.sections = new JsonSerializer<Section>().fromJSONArray(item.sections, Section);
this.fieldGroups = new JsonSerializer<FieldGroup>().fromJSONArray(item.fieldGroups, FieldGroup);
this.page = item.page;
this.defaultVisibility = item.defaultVisibility;
this.id = item.id;
this.title = item.title;
this.description = item.description;
this.ordinal = item.ordinal;
return this;
}
buildForm(): FormGroup {
let formGroup: FormGroup = new FormBuilder().group({});
let sectionsFormArray = new Array<FormGroup>();
if (this.sections) {
this.sections.forEach(item => {
let form: FormGroup = item.buildForm();
sectionsFormArray.push(form)
})
}
let fieldGroupsFormArray = new Array<FormGroup>();
if (this.fieldGroups) {
this.fieldGroups.forEach(item => {
let form: FormGroup = item.buildForm();
fieldGroupsFormArray.push(form)
})
}
formGroup.addControl('sections', this.formBuilder.array(sectionsFormArray));
formGroup.addControl('fieldGroups', this.formBuilder.array(fieldGroupsFormArray));
formGroup.addControl('defaultVisibility', new FormControl(this.defaultVisibility));
formGroup.addControl('page', new FormControl(this.page));
formGroup.addControl('id', new FormControl(this.id));
formGroup.addControl('title', new FormControl(this.title));
formGroup.addControl('description', new FormControl(this.description));
formGroup.addControl('ordinal', new FormControl(this.ordinal));
return formGroup;
}
}

View File

@ -0,0 +1,21 @@
import { BaseModel } from './BaseModel';
import { FormGroup } from '@angular/forms';
import { FormGenerator } from './interfaces/FormGenerator';
import { Serializable } from './interfaces/Serializable';
export class Validation extends BaseModel implements Serializable<Validation>,FormGenerator<FormGroup>{
public type:string;
public value:string;
fromJSONObject(item:any):Validation{
this.type = item.type;
this.value = item.value;
return this;
}
buildForm():FormGroup{
return this.formBuilder.group({
type: [this.type],
value: [this.value],
});
}
}

View File

@ -0,0 +1,4 @@
import { AbstractControl } from '@angular/forms';
export interface FormGenerator<T extends AbstractControl>{
buildForm():T
}

View File

@ -0,0 +1,3 @@
export interface Serializable<T> {
fromJSONObject(item: Object): T;
}

View File

@ -0,0 +1,34 @@
<div>
<h4 style="text-decoration: underline;">Rules</h4>
<div [formGroup]="form">
<div class="form-row">
<div class="form-group col-md-4">
<label>Rule Type</label>
<select class="form-control" formControlName="type">
<option>field value</option>
</select>
</div>
<div class="form-group col-md-4">
<label>Target</label>
<input type="text" class="form-control" placeholder="field id" formControlName="targetField">
</div>
<div class="form-group col-md-4">
<label>Rule style</label>
<select class="form-control">
<option>boolean</option>
<option>checked</option>
<option>unchecked</option>
<option>dropdown value</option>
</select>
</div>
<div class="form-group col-md-6">
<label>Value Type</label>
<input type="text" class="form-control">
</div>
<div class="form-group col-md-6">
<label>Value</label>
<input type="text" class="form-control" formControlName="requiredValue">
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,15 @@
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms'
import { Rule } from '../models/Rule'
@Component({
selector: 'rule-form',
templateUrl: './rule.component.html',
styleUrls: []
})
export class RuleFormComponent {
@Input() form: FormGroup;
@Input() dataModel: FormGroup;
}

View File

@ -0,0 +1,27 @@
<div>
<h4 style="text-decoration: underline;">Section</h4>
<div [formGroup]="form">
<div class="form-row">
<div class="form-group col-md-4">
<label>Title</label>
<input type="text" class="form-control" formControlName="title">
</div>
<div class="form-group col-md-4">
<label>Id</label>
<input type="text" class="form-control" formControlName="id">
</div>
<div class="form-group col-md-4">
<label>defaultVisibility</label>
<input type="text" class="form-control" formControlName="defaultVisibility">
</div>
</div>
</div>
<div *ngFor="let fieldGroup of dataModel.fieldGroups let i=index;">
<groupfield-form [form]="form.get('fieldGroups').get(''+i)" [dataModel]="fieldGroup" ></groupfield-form>
</div>
<div>
<a (click)="addGroupField()" style="cursor: pointer">
Add another group +
</a>
</div>
</div>

View File

@ -0,0 +1,30 @@
import { Component, OnInit, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Section } from '../models/Section';
import { FieldGroup } from '../models/FieldGroup';
import { FormArray } from '@angular/forms/src/model';
@Component({
selector: 'section-form',
templateUrl: './section-form.component.html',
styleUrls: []
})
export class SectionFormComponent {
@Input() form: FormGroup;
@Input() dataModel:Section;
constructor(){ }
ngOnInit(){
this.addGroupField();
}
addGroupField(){
let fieldGroup:FieldGroup = new FieldGroup();
this.dataModel.fieldGroups.push(fieldGroup);
(<FormArray>this.form.get("fieldGroups")).push(fieldGroup.buildForm());
}
}

View File

@ -0,0 +1,251 @@
export const TestModel = {
"sections": [
{
"id": "sumData",
"defaultVisibility": "true",
"page": "1",
"title": "1 Data Summary",
"description": " Fill in the fields to describe your data model ",
"sections": [],
"fieldGroups":
[
{
"id": "dataSummaryGroup",
"defaultVisibility": "true",
"page": "1",
"title": "Data Summary",
"description": "",
"extendedDescription": "",
"compositeFields": [
{
"fields":
[
{
"id": "dataSummary",
"defaultVisibility": "true",
"title": "",
"description": "",
"extendedDescription": "",
"viewStyle": "checkBox"
}
]
}
]
}
]
},
{
"id": "fairData",
"ordinal": "2",
"defaultVisibility": "true",
"page": "1",
"title": "2 Fair Data",
"sections": [
{
"id": "dataMetadata",
"defaultVisibility": "true",
"page": "1",
"title": "2.1 Making data findable, including provisions for metadata",
"sections": [],
"fieldGroups": [
{
"id": "FindDataMetadataGroup",
"section": "dataMetadata",
"defaultVisibility": "true",
"page": "1",
"title": "Making data findable, including provisions for metadata",
"description": "Making data findable, including provisions for metadata",
"extendedDescription": "FieldGroup Description",
"compositeFields": [
{
"fields":
[
{
"id": "useMetadataQ211",
"defaultVisibility": "true",
"title": "Q2.1.1 Will you use metadata to describe the data?",
"description": "User can select from a list of metadata standards. If they cannot find the standard in the list provided then they should choose \"not listed\". Selecting this will result in a field in which the user can insert the URL to the description of the metadata scheme used. A \"comments\" box should exist to allow users to add comments. They may select more than one metadata standard. They may specify more than one URL when selecting \"not listed\". They are also presented with a field in which to specify the location of the metadata service. Users can select the \"no metadata\" button to specify no metadata will be used to describe the data.",
"extendedDescription": "FieldGroup Description",
"viewStyle": "booleanDesicion"
}
]
},
{
"fields":
[
{
"id": "metadataStandarsA211",
"defaultVisibility": "false",
"title": "Metadata standards",
"description": "The data will be described by metadata that follows the metadata standards described in <url1>, <url2>, ? The data will be described by metadata that follows the metadata schema described in <not-listed-url1>, <not-listed-url2>. The metadata will be stored in the service located at <metadata-repo-url>",
"extendedDescription": "",
"viewStyle": "combobox"
}]
},
{
"fields":
[
{
"id": "notlistedA211",
"defaultVisibility": "false",
"title": "Not listed",
"description": "",
"extendedDescription": "",
"viewStyle": "checkBox"
}]
},
{
"fields":
[
{
"id": "notlistedUrlA211",
"defaultVisibility": "false",
"title": "Url",
"description": "URL to the description of the metadata scheme used",
"extendedDescription": "",
"viewStyle": "freetext"
}]
},
{
"fields":
[
{
"id": "notlistedCommentA211",
"defaultVisibility": "false",
"title": "Comments",
"description": "",
"extendedDescription": "",
"viewStyle": "freetext"
}]
},
{
"fields":
[
{
"id": "noMetadata",
"defaultVisibility": "false",
"title": "The data will not be described by any metadata.",
"description": "",
"extendedDescription": "",
"viewStyle": "checkBox"
}
]
}
]
},
{
"id": "VocabulariesGroup",
"defaultVisibility": "true",
"page": "1",
"title": "Vocabularies",
"description": "Vocabularies",
"extendedDescription": "FieldGroup Description",
"compositeFields": [
{
"fields": [
{
"id": "useVocabulariesQ212",
"defaultVisibility": "true",
"title": "Q2.1.2 Will your metadata use standardised vocabularies?",
"description": "User selects from a drop-down list of existing standardised vocabularies or \"not listed\" or \"none\". There should be a \"comments\" fields for additional information. If \"not listed\" is selected the user is presented with two additional fields in which the user can put the URL to the new vocabulary along with a short description. The user should be allowed to select more than one option.",
"extendedDescription": "FieldGroup Description",
"viewStyle": "booleanDesicion"
}]
},
{
"fields": [
{
"id": "standardisedVocabulariesA212",
"defaultVisibility": "false",
"title": "Existing standardised vocabularies",
"description": "The metadata will make use of the standardised vocabulary <url>",
"extendedDescription": "",
"viewStyle": "combobox"
}]
},
{
"fields": [
{
"id": "notlistedVocabularyA212",
"defaultVisibility": "false",
"title": "Not listed vocabulary",
"description": "",
"extendedDescription": "",
"viewStyle": "checkBox"
}]
},
{
"fields": [
{
"id": "notlistedVocUrlA212",
"defaultVisibility": "false",
"title": "Vocabulary Url",
"description": "The user can put the URL to the new vocabulary",
"extendedDescription": "",
"viewStyle": "freetext"
}]
},
{
"fields": [
{
"id": "notlistedVocCommentA212",
"defaultVisibility": "false",
"title": "Comments",
"description": "Vocabulary short description",
"extendedDescription": "",
"viewStyle": "freetext"
}]
},
{
"fields": [
{
"id": "noMetadataVocabularyA212",
"defaultVisibility": "false",
"title": "The metadata will not make use of any vocabulary",
"description": "",
"extendedDescription": "",
"viewStyle": "checkBox"
}
]
}
]
},
{
"id": "FreeOfChargeGroup",
"defaultVisibility": "true",
"page": "1",
"title": "Metadata Available",
"description": "Metadata Available",
"extendedDescription": "FieldGroup Description",
"compositeFields": [
{
"fields": [
{
"id": "freeOfChargeGroupQ213",
"defaultVisibility": "true",
"title": "Q2.1.3 Will you use standardised formats for some or all of your data.",
"description": "User is presented with a choice of ?yes?, ?no?. There should be a ?comments? field for additional information.",
"extendedDescription": "Field Description",
"viewStyle": "booleanDesicion"
}]
},
{
"fields": [
{
"id": "freeOfChargeGroupCommentA213",
"defaultVisibility": "true",
"title": "Comments",
"description": "",
"extendedDescription": "",
"viewStyle": "freetext"
}
]
}
]
}
]
}
]
}
]
}

View File

@ -0,0 +1,17 @@
import { Serializable } from '../models/interfaces/Serializable';
export class JsonSerializer<T extends Serializable<T>>{
public fromJSONArray(items: any[], type: { new(): T; }): T[] {
if(!items)return null;
const objectList: T[] = new Array<T>();
for (let i = 0; i < items.length; i++) {
objectList.push(new type().fromJSONObject(items[i]))
}
return objectList;
}
public fromJSONObject(item: any, type: { new(): T; }): T {
if(!item)return null;
return new type().fromJSONObject(item);
}
}

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.hibernate:hibernate-core:5.2.11.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.0.Final" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.20.0-GA" level="project" />
<orderEntry type="library" name="Maven: antlr:antlr:2.7.7" level="project" />
<orderEntry type="library" name="Maven: org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec:1.0.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss:jandex:2.0.3.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.0" level="project" />
<orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.common:hibernate-commons-annotations:5.0.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.hibernate:hibernate-c3p0:5.2.11.Final" level="project" />
<orderEntry type="library" name="Maven: com.mchange:c3p0:0.9.5.2" level="project" />
<orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.11" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:javax.servlet-api:3.0.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-orm:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:4.3.8.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:4.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: aopalliance:aopalliance:1.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-web:4.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.security:spring-security-config:4.2.3.RELEASE" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:jstl:1.2" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.2.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.4" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-hibernate5:2.8.4" level="project" />
<orderEntry type="library" name="Maven: javax.transaction:jta:1.1" level="project" />
<orderEntry type="library" name="Maven: org.json:json:20160810" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat:tomcat-jdbc:7.0.35" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.tomcat:tomcat-juli:7.0.35" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.11" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.google.code.gson:gson:2.8.2" level="project" />
<orderEntry type="library" name="Maven: org.postgresql:postgresql:9.4.1212" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: log4j:log4j:1.2.17" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.9" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.slf4j:jcl-over-slf4j:1.7.12" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.12" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.slf4j:slf4j-log4j12:1.7.12" level="project" />
<orderEntry type="library" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" name="Maven: com.google.apis:google-api-services-oauth2:v2-rev75-1.19.0" level="project" />
<orderEntry type="library" name="Maven: com.google.api-client:google-api-client:1.19.0" level="project" />
<orderEntry type="library" name="Maven: com.google.oauth-client:google-oauth-client:1.19.0" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava-jdk5:13.0" level="project" />
<orderEntry type="library" name="Maven: com.google.http-client:google-http-client-jackson2:1.19.0" level="project" />
<orderEntry type="library" name="Maven: com.google.http-client:google-http-client:1.19.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.0.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.oauth-client:google-oauth-client-jetty:1.19.0" level="project" />
<orderEntry type="library" name="Maven: com.google.oauth-client:google-oauth-client-java6:1.19.0" level="project" />
<orderEntry type="library" name="Maven: org.mortbay.jetty:jetty:6.1.26" level="project" />
<orderEntry type="library" name="Maven: org.mortbay.jetty:jetty-util:6.1.26" level="project" />
<orderEntry type="library" name="Maven: org.mortbay.jetty:servlet-api:2.5-20081211" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:23.0" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.0.18" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.1" level="project" />
<orderEntry type="library" name="Maven: org.codehaus.mojo:animal-sniffer-annotations:1.14" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.5" level="project" />
</component>
</module>

View File

@ -0,0 +1,64 @@
package models.components.datasetprofile;
public class Field {
private String id;
private String title;
private String value;
private String description;
private String extendedDescription;
private String viewStyle;
private boolean defaultVisibility;
private int page;
public Object data;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getExtendedDescription() {
return extendedDescription;
}
public void setExtendedDescription(String extendedDescription) {
this.extendedDescription = extendedDescription;
}
public String getViewStyle() {
return viewStyle;
}
public void setViewStyle(String viewStyle) {
this.viewStyle = viewStyle;
}
public boolean isDefaultVisibility() {
return defaultVisibility;
}
public void setDefaultVisibility(boolean defaultVisibility) {
this.defaultVisibility = defaultVisibility;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
}

View File

@ -0,0 +1,17 @@
package models.components.datasetprofile;
import java.util.List;
public class FieldSet {
private List<Field> fields;
public List<Field> getFields() {
return fields;
}
public void setFields(List<Field> fields) {
this.fields = fields;
}
}

View File

@ -0,0 +1,70 @@
package models.components.datasetprofile;
import java.util.List;
public class Group {
private String id;
private String title;
private String section;
private String value;
private String description;
private String extendedDescription;
private boolean defaultVisibility;
private int page;
private List<FieldSet> compositeFields;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSection() {
return section;
}
public void setSection(String section) {
this.section = section;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getExtendedDescription() {
return extendedDescription;
}
public void setExtendedDescription(String extendedDescription) {
this.extendedDescription = extendedDescription;
}
public boolean isDefaultVisibility() {
return defaultVisibility;
}
public void setDefaultVisibility(boolean defaultVisibility) {
this.defaultVisibility = defaultVisibility;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public List<FieldSet> getCompositeFields() {
return compositeFields;
}
public void setCompositeFields(List<FieldSet> compositeFields) {
this.compositeFields = compositeFields;
}
}

View File

@ -0,0 +1,57 @@
package models.components.datasetprofile;
import java.util.List;
public class Section {
private List<Section> sections;
private List<Group> fieldGroups;
private Boolean defaultVisibility;
private int page;
private String id;
private String title;
private String description;
public List<Section> getSections() {
return sections;
}
public void setSections(List<Section> sections) {
this.sections = sections;
}
public List<Group> getFieldGroups() {
return fieldGroups;
}
public void setFieldGroups(List<Group> fieldGroups) {
this.fieldGroups = fieldGroups;
}
public Boolean getDefaultVisibility() {
return defaultVisibility;
}
public void setDefaultVisibility(Boolean defaultVisibility) {
this.defaultVisibility = defaultVisibility;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@ -0,0 +1,17 @@
package models.composite;
import models.components.datasetprofile.*;
import java.util.List;
public class DatasetProfile {
private List<Section> sections;
public List<Section> getSections() {
return sections;
}
public void setSections(List<Section> sections) {
this.sections = sections;
}
}

View File

@ -0,0 +1,28 @@
package rest.entities;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import models.composite.DatasetProfile;
@RestController
@CrossOrigin
public class Admin {
@RequestMapping(method = RequestMethod.POST, value = { "/admin/addDmp" },consumes = "application/json", produces="application/json")
public ResponseEntity<Object> addDmp(@RequestBody DatasetProfile profile){
try{
return ResponseEntity.status(HttpStatus.OK).body(profile);
}catch(Exception ex){
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"reason\":\""+ex.getMessage()+"\"}");
}
}
}

View File

@ -0,0 +1,6 @@
package utilities;
public interface XmlSerializable <T>{
String toXml(T item);
T fromXml(String xml);
}

View File

@ -0,0 +1,5 @@
package utilities.builders;
public class ModelBuilder {
}

View File

@ -5,9 +5,9 @@
##########################Persistence##########################################
persistence.jdbc.driver = org.postgresql.Driver
persistence.jdbc.url = jdbc:postgresql://HOST:PORT/DB
persistence.dbusername = USER
persistence.dbpassword = PASS
persistence.jdbc.url = jdbc:postgresql://develdb1.madgik.di.uoa.gr:5432/dmptool
persistence.dbusername = dmptool
persistence.dbpassword = dmpt00lu$r
##########################/Persistence##########################################
###################Allowed Proxy Service Host ############################

View File

@ -1,6 +1,5 @@
import { Component, OnInit} from '@angular/core';
import { ServerService } from './services/server.service';
import { FieldBase } from '../app/form/fields/field-base';
import { JsonObjest } from '../app/entities/JsonObject.class';
import { TokenService, TokenProvider } from './services/login/token.service';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, ActivatedRoute, NavigationExtras } from '@angular/router';
@ -9,7 +8,6 @@ import {BreadcrumbModule,MenuItem} from 'primeng/primeng';
import { BreadcrumbComponent } from './widgets/breadcrumb/breadcrumb.component';
import { AutocompleteRemoteComponent } from './form/fields/autocomplete-remote/autocomplete-remote.component';
declare const gapi: any;

View File

@ -1,3 +1,12 @@
import {
DynamicFieldRadioBoxComponent,
} from './form/dynamic-fields/dynamic-field-radiobox/dynamic-field-radiobox.component';
import {
DynamicFieldBooleanDecisionComponent,
} from './form/dynamic-fields/dynamic-field-boolean-decision/dynamic-field-boolean-decision.component';
import { AutocompleteRemoteComponent } from './form/dynamic-fields/dynamic-field-autocomplete/autocomplete-remote.component';
import { DynamicFieldDropdownComponent } from './form/dynamic-fields/dynamic-field-dropdown/dynamic-field-dropdown';
import { DynamicFieldCheckBoxComponent } from './form/dynamic-fields/dynamic-field-checkbox/dynamic-field-checkbox';
import { VisibilityRulesService } from './visibility-rules/visibility-rules.service';
import { DynamicFormSectionComponent } from './form/dynamic-form-section/dynamic-form-section';
import { DynamicFormCompositeFieldComponent } from './form/dynamic-form-composite-field/dynamic-form-composite-field';
@ -15,17 +24,16 @@ import { DataTableModule } from "angular2-datatable";
import { AppComponent } from './app.component';
import { RestBase } from './services/rest-base';
import { DynamicFormComponent } from './form/dynamic-form.component';
import { DynamicFormFieldComponent } from './form/fields/dynamic-form-field.component';
import { DynamicFormFieldComponent } from './form/dynamic-fields/dynamic-form-field.component';
import { ServerService } from './services/server.service';
import { GlobalVariables } from './services/global-variables.service';
import { TokenService, TokenProvider } from './services/login/token.service';
import { LocalStorageService } from 'ngx-webstorage';
import { dataModelBuilder } from './services/dataModelBuilder.service';
import { DynamicFormGroupComponent } from './form/dynamic-form-group/dynamic-form-group.component';
import { AppRoutingModule } from './app-routing.module';
import { AppRoutingModule } from './app-routing.module';
import { AuthGuard } from './guards/auth.guard';
import { PageNotFoundComponent } from './not-found.component';
import { HomepageComponent } from './homepage/homepage.component';
import { PageNotFoundComponent } from './not-found.component';
import { HomepageComponent } from './homepage/homepage.component';
import { TocComponent } from './form/tableOfContents/toc.component';
import { ConfirmationComponent } from './widgets/confirmation/confirmation.component';
@ -45,16 +53,16 @@ import { NguiAutoCompleteModule } from '@ngui/auto-complete';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import {BreadcrumbModule,MenuItem} from 'primeng/primeng';
import { BreadcrumbModule, MenuItem } from 'primeng/primeng';
import { CommonModule } from '@angular/common';
import { CommonModule } from '@angular/common';
import { DatasetTableFilterPipe } from './pipes/dataset-table-filter.pipe';
import { DatasetStatusFilterPipe } from './pipes/dataset-status-filter.pipe';
import { DatasetsComponent } from './datasets/dataset.component';
import { DatasetsComponent } from './datasets/dataset.component';
import { DmpComponent } from './dmps/dmp.component';
import { DmpComponent } from './dmps/dmp.component';
import { DmpTableFilterPipe } from './pipes/dmp-table-filter.pipe';
import { DmpStatusFilterPipe } from './pipes/dmp-status-filter.pipe';
import { DmpVersionFilterPipe } from './pipes/dmp-version-filter.pipe';
@ -67,7 +75,6 @@ import { NgDatepickerModule } from 'ng2-datepicker';
import { StatusToString } from './pipes/various/status-to-string';
import { SidebarModule } from 'ng-sidebar';
import { AutocompleteRemoteComponent } from './form/fields/autocomplete-remote/autocomplete-remote.component';
import { Ng4LoadingSpinnerModule } from 'ng4-loading-spinner';
import { BreadcrumbComponent } from './widgets/breadcrumb/breadcrumb.component';
@ -84,6 +91,8 @@ import { ProjectDetailedComponent } from './viewers/project-detailed/project-det
DynamicFormFieldComponent,
DynamicFormGroupComponent,
DynamicFormCompositeFieldComponent,
DynamicFieldBooleanDecisionComponent,
DynamicFieldRadioBoxComponent,
TocComponent,
GooggleSignInComponent,
MainSignInComponent,
@ -95,14 +104,16 @@ import { ProjectDetailedComponent } from './viewers/project-detailed/project-det
DatasetsComponent,
ConfirmationComponent,
AutocompleteRemoteComponent,
DynamicFieldDropdownComponent,
DynamicFormSectionComponent,
ProjectTableFilterPipe,
DmpVersionFilterPipe,
DmpStatusFilterPipe,
ProjectTableFilterPipe,
DmpVersionFilterPipe,
DmpStatusFilterPipe,
DmpTableFilterPipe,
DatasetTableFilterPipe,
DatasetStatusFilterPipe,
StatusToString,
DatasetTableFilterPipe,
DatasetStatusFilterPipe,
StatusToString,
DynamicFieldCheckBoxComponent,
BreadcrumbComponent, DmpDetailedComponent, ProjectDetailedComponent
],
imports: [
@ -121,15 +132,15 @@ import { ProjectDetailedComponent } from './viewers/project-detailed/project-det
NguiAutoCompleteModule,
BreadcrumbModule,
SidebarModule.forRoot()
],
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: GlobalInterceptor,
multi: true,
},
ServerService, dataModelBuilder,VisibilityRulesService, GlobalVariables, AuthGuard, PaginationService, TokenService, LocalStorageService, RestBase, EestoreService,NativeLoginService
],
provide: HTTP_INTERCEPTORS,
useClass: GlobalInterceptor,
multi: true,
},
ServerService, VisibilityRulesService, GlobalVariables, AuthGuard, PaginationService, TokenService, LocalStorageService, RestBase, EestoreService, NativeLoginService
],
bootstrap: [AppComponent]
})
export class AppModule {

View File

@ -1,62 +0,0 @@
import { GroupBase } from '../form/dynamic-form-group/group-base';
import { FieldBase } from '../form/fields/field-base';
import { Attribute } from './model/attribute';
import { Source } from './model/source';
import { Section } from './model/section';
export class DataModel {
private fIndex : Map<string, FieldBase<any>>;
private fIndSources : Map<string, Source>;
groups: GroupBase<any>[] = [];
fields: FieldBase<any>[] = [];
semanticAttr: Attribute[];
sections: Section[];
//need to add more class fields to describe the remaining elements of the json object fetched from the service.
//e.g. the current dataset's metadata information, the DataRepository description information, etc
constructor(){
}
public buildIndex(){
this.fIndex = new Map<string, FieldBase<any>>();
this.fields.forEach((field) => {
//console.log("fieldid:" +field.key);
this.fIndex.set(field.key, field);
});
this.groups.forEach((group) => {
group.groupFields.forEach((field) => {
//console.log("groupid: "+group.key + "fieldid:" +field.key);
this.fIndex.set(field.key, field);
});
});
this.groups.forEach((group) => {
if (group.compositeFields != undefined){
group.compositeFields.groupFields.forEach((field) => {
//console.log("groupid: "+group.key + "fieldid:" +field.key);
this.fIndex.set(field.key, field);
});
}
});
}
public getFieldByKey(key){
return this.fIndex.get(key);
}
}

View File

@ -1,5 +1,4 @@
import { Injectable } from '@angular/core';
import { GroupBase } from '../../form/dynamic-form-group/group-base';
@Injectable()
export class Section {
@ -8,6 +7,5 @@ export class Section {
id: string;
defaultVisibility: boolean;
ordinal: number;
groupFields: GroupBase<any>[];
page:number;
}

View File

@ -0,0 +1,5 @@
<div [formGroup]="textFormGroup">
<label >{{field.title}}</label>
<input auto-complete class="form-control autocomplete" formControlName="text" [source]="values" >
</div>

View File

@ -0,0 +1,95 @@
import { Field } from '../../../models/Field';
import { Component, OnInit, Input, Output, EventEmitter, forwardRef } from '@angular/core';
import { ControlValueAccessor, FormControl, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { ServerService } from '../../../services/server.service';
import { UUID } from 'angular2-uuid';
import { NguiAutoCompleteModule } from '@ngui/auto-complete';
declare var $: any;
@Component({
selector: 'df-autocomplete',
templateUrl: './autocomplete-remote.component.html',
styleUrls: ['./autocomplete-remote.component.css']
})
export class AutocompleteRemoteComponent implements OnInit/* , ControlValueAccessor */ {
@Input() field: Field;
@Input() form: FormGroup;
private textFormGroup = new FormGroup({text:new FormControl("")});
private loading: boolean;
values: any[] = new Array();
typeaheadMS: number = 1400;
constructor(private serverService: ServerService) {
}
ngOnInit() {
let valueChanges = this.textFormGroup.controls['text'].valueChanges.share();
valueChanges.subscribe(searchTerm => {
this.loading = true;
if (this.form.controls['text'].value)
this.resetFormGroupValue();
});
valueChanges
.debounceTime(this.typeaheadMS)
.subscribe(searchTerm => {
if (typeof searchTerm === 'string') {
this.updateByQuery(searchTerm)
}
});
}
resetFormGroupValue() {
this.form.patchValue({ value: null }, { emitEvent: false });
}
updateByQuery(query: string) {
this.serverService.getThroughProxy(this.field.data.url, query).subscribe(
response => {
this.values.length = 0;
response.data.forEach(element => {
this.values.push(element.attributes.name);
});
},
error => {
console.log(error);
}
);
}
onChange: any = () => { };
onTouched: any = () => { };
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
/* writeValue(value) {
if (value) {
this.value = value;
}
} */
}

View File

@ -0,0 +1,4 @@
<div [formGroup]="form">
<input type="radio" formControlName="value" value="true">Yes<br>
<input type="radio" formControlName="value" value="false">No
</div>

View File

@ -0,0 +1,17 @@
import { FormGroup } from '@angular/forms';
import { Field } from '../../../models/Field';
import { Component, Input, OnInit } from '@angular/core';
import { FieldBase } from '../field-base';
@Component({
selector: 'df-booleanDecision',
templateUrl: './dynamic-field-boolean-decision.component.html'
})
export class DynamicFieldBooleanDecisionComponent implements OnInit{
@Input() field: Field;
@Input() form: FormGroup;
ngOnInit(){
}
}

View File

@ -0,0 +1,5 @@
<div [formGroup]="form" class="form-group" >
<label>{{field.title}}</label>
<input formControlName="value" type = "checkbox">
</div>

View File

@ -0,0 +1,14 @@
import { Field } from '../../../models/Field';
import { FormGroup } from '@angular/forms';
import { Component, Input } from '@angular/core';
import {FieldBase} from '../field-base';
@Component({
selector: 'df-checkbox',
templateUrl: './dynamic-field-checkbox.html'
})
export class DynamicFieldCheckBoxComponent{
@Input() field:Field;
@Input() form:FormGroup;
}

View File

@ -0,0 +1,5 @@
<div [formGroup]="form">
<select class="form-control" formControlName="value">
<option *ngFor="let opt of field.data.values" [value]="opt.value">{{opt.label}}</option>
</select>
</div>

View File

@ -0,0 +1,17 @@
import { FormGroup } from '@angular/forms';
import { Field } from '../../../models/Field';
import { Component, Input, OnInit } from '@angular/core';
import { FieldBase } from '../field-base';
@Component({
selector: 'df-dropdown',
templateUrl: './dynamic-field-dropdown.html'
})
export class DynamicFieldDropdownComponent implements OnInit{
@Input() field: Field;
@Input() form: FormGroup;
ngOnInit(){
}
}

View File

@ -0,0 +1,5 @@
<div [formGroup]="form">
<div *ngFor="let option of this.field.data.options">
<input type="radio" formControlName="value" value="option.value">{{option.label}}<br>
</div>
</div>

View File

@ -0,0 +1,17 @@
import { FormGroup } from '@angular/forms';
import { Field } from '../../../models/Field';
import { Component, Input, OnInit } from '@angular/core';
import { FieldBase } from '../field-base';
@Component({
selector: 'df-radiobox',
templateUrl: './dynamic-field-radiobox.component.html'
})
export class DynamicFieldRadioBoxComponent implements OnInit{
@Input() field: Field;
@Input() form: FormGroup;
ngOnInit(){
}
}

View File

@ -0,0 +1 @@
@CHARSET "UTF-8";

View File

@ -1,11 +1,11 @@
import {FieldBase} from '../field-base';
export class TextboxField extends FieldBase<string> {
controlType = 'textbox';
type: string;
constructor (options: {} = {}) {
super(options);
this.type = options['type'] || '';
}
import {FieldBase} from '../field-base';
export class TextboxField extends FieldBase<string> {
controlType = 'textbox';
type: string;
constructor (options: {} = {}) {
super(options);
this.type = options['type'] || '';
}
}

View File

@ -1,144 +1,140 @@
<!-- <div [formGroup]="form" class="form-group">
<label [attr.for]="field.key">{{field.label}}</label>
<div [ngSwitch]="field.controlType">
<input *ngSwitchCase="'textbox'" class ="form-control" [formControlName]="field.key"
[id]="field.key" [type]="field.type" required ="field.required">
<select [id]="field.key" *ngSwitchCase="'dropdown'" class ="form-control" [formControlName]="field.key">
<option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option>
</select>
<input *ngSwitchCase="'checkbox'" [formControlName]="field.key" [(ngModel)]="field.value"
[id]="field.key" [type]="field.type" (change)="field.value = ckb.checked" #ckb>
</div>
<div class="alert alert-danger" *ngIf="!isValid">{{field.label}} is required</div>
</div> -->
<div *ngIf="this.visibilityRulesService.isElementVisible(pathName,field.id)" [formGroup]="form" class="form-group" [ngSwitch]="field.viewStyle">
<div [ngClass]="{true:'show', false:'hide'}[field.visible]">
<label>{{field.description}}</label>
<div>{{field.extendedDescription}}</div>
<div *ngSwitchCase="'freetext'">
<input class="form-control" formControlName="value">
</div>
<!--input or change event
on change event the listener is triggered on blur -->
<!-- <div *ngSwitchCase="'dropdown'">
<autocomplete-remote *ngIf="field.url" formControlName="value" [url]="field.url" ></autocomplete-remote>
<select *ngIf="!field.url" class="form-control" [id]="field.key" formControlName="field.key" [required]="field.required" (change)="toggleVisibility($event, field, false)">
<option *ngFor="let opt of field.options" [value]="opt._value" >{{opt._label}}</option>
</select>
</div> -->
<div *ngSwitchCase="'comboBox'">
<!--TODO-->
<autocomplete-remote *ngIf="field.url" formControlName="value" [url]="field.url"></autocomplete-remote>
<select *ngIf="!field.url" class="form-control" [id]="field.key" formControlName="value">
<option *ngFor="let opt of field.options" >{{opt._label}}</option>
</select>
</div>
<!-- <div *ngSwitchCase="'checkbox'" class="checkbox">
<label class="checkBoxLabelCustom">
<input *ngSwitchCase="'checkbox'" class="form-check" formControlName="value" [type]="field.type"
(change)="toggleVisibility($event, field, true)" [required]="field.required" [checked]="form.get(field.key).value">{{field.label}}
</label>
</div> -->
<div *ngSwitchCase="'checkBox'" class="checkbox">
<label class="checkBoxLabelCustom">
<input class="form-check" formControlName="value" type="checkbox">{{field.title}}
</label>
</div>
<div *ngSwitchCase="'textarea'">
<textarea class="form-control" formControlName="value"> </textarea>
</div>
<div *ngSwitchCase="'radiobox'">
<ng-container *ngFor="let answrBase of field.answers">
<div style="display: inline-block;margin-right:10px;" [id]="field.key">
<label for="{{answrBase.id}}" style="padding: 8px 10px; padding-right:5px;">{{answrBase.answer}}</label>
<input type="radio" [formControlName]="value" [id]="answrBase.id" [value]="answrBase.value" [(ngModel)]="field.value" (change)="toggleVisibility($event, field,false)"
[required]="field.required" />
</div>
</ng-container>
</div>
</div>
<div *ngSwitchCase="'label'"> </div>
<div [hidden]="isValid">
<div class="invalid-feedbackCustom" *ngIf="isValidRequired">The field "{{field.label}}" is required</div>
<div class="invalid-feedbackCustom" *ngIf="isValidPattern">The field {{field.label}} must match a regular expression {{field.regex}}</div>
<div class="invalid-feedbackCustom" *ngIf="isValidCustom">The field {{field.label}} custom Validation</div>
</div>
</div>
<!-- <div [formGroup]="form" class="form-group" [ngSwitch]="field.controlType">
<div *ngIf= "field.rules; else elseBlock ">
<div *ngIf="field.rules.length > 0; else elseBlock">
<div *ngFor="let rule of field.rules">
<div *ngIf="rule._type == 'fieldVisible'; else otherRuleBlock">
<div hidden="{{ruleVisibleMethod(field, rule, dataModel)}}">
<label [attr.for]="field.key">{{field.label}}</label>
<input *ngSwitchCase="'textbox'" class="form-control" [formControlName]="field.key" [id]="field.key" [type]="field.type"
required="field.required">
<select [id]="field.key" *ngSwitchCase="'dropdown'" class="form-control" [formControlName]="field.key">
<option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option>
</select>
<input *ngSwitchCase="'checkbox'" [formControlName]="field.key" [(ngModel)]="field.value" [id]="field.key" [type]="field.type"
(change)="field.value = ckb.checked" #ckb>
</div>
</div>
</div>
</div>
</div>
<ng-template #elseBlock>
<label [attr.for]="field.key">{{field.label}}</label>
<input *ngSwitchCase="'textbox'" class="form-control" [formControlName]="field.key" [id]="field.key" [type]="field.type"
required="field.required">
<select [id]="field.key" *ngSwitchCase="'dropdown'" class="form-control" [formControlName]="field.key">
<option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option>
</select>
<input *ngSwitchCase="'checkbox'" [formControlName]="field.key" [(ngModel)]="field.value" [id]="field.key" [type]="field.type"
(change)="field.value = ckb.checked" #ckb>
</ng-template>
<ng-template #otherRuleBlock>
</ng-template>
<!-- <div [formGroup]="form" class="form-group">
<label [attr.for]="field.key">{{field.label}}</label>
<div [ngSwitch]="field.controlType">
<input *ngSwitchCase="'textbox'" class ="form-control" [formControlName]="field.key"
[id]="field.key" [type]="field.type" required ="field.required">
<select [id]="field.key" *ngSwitchCase="'dropdown'" class ="form-control" [formControlName]="field.key">
<option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option>
</select>
<input *ngSwitchCase="'checkbox'" [formControlName]="field.key" [(ngModel)]="field.value"
[id]="field.key" [type]="field.type" (change)="field.value = ckb.checked" #ckb>
</div>
<div class="alert alert-danger" *ngIf="!isValid">{{field.label}} is required</div>
</div> -->
<div *ngIf="this.visibilityRulesService.isElementVisible(pathName,field.id)" [formGroup]="form" class="form-group" [ngSwitch]="field.viewStyle">
<div [ngClass]="{true:'show', false:'hide'}[field.visible]">
<label>{{field.description}}</label>
<div>{{field.extendedDescription}}</div>
<div *ngSwitchCase="'freetext'">
<input class="form-control" formControlName="value">
</div>
<!--input or change event
on change event the listener is triggered on blur -->
<!-- <div *ngSwitchCase="'dropdown'">
<autocomplete-remote *ngIf="field.url" formControlName="value" [url]="field.url" ></autocomplete-remote>
<select *ngIf="!field.url" class="form-control" [id]="field.key" formControlName="field.key" [required]="field.required" (change)="toggleVisibility($event, field, false)">
<option *ngFor="let opt of field.options" [value]="opt._value" >{{opt._label}}</option>
</select>
</div> -->
<div *ngSwitchCase="'combobox'">
<!--TODO-->
<div *ngIf="this.field.data.type === 'autocomplete'">
<df-autocomplete [form]="form" [field]="field"></df-autocomplete>
</div>
<div *ngIf="this.field.data.type === 'wordlist'">
<df-dropdown [form]="form" [field]="field"></df-dropdown>
</div>
</div>
<!-- <div *ngSwitchCase="'checkbox'" class="checkbox">
<label class="checkBoxLabelCustom">
<input *ngSwitchCase="'checkbox'" class="form-check" formControlName="value" [type]="field.type"
(change)="toggleVisibility($event, field, true)" [required]="field.required" [checked]="form.get(field.key).value">{{field.label}}
</label>
</div> -->
<div *ngSwitchCase="'checkBox'" class="checkbox">
<df-checkbox [form]="form" [field]="field"></df-checkbox>
</div>
<div *ngSwitchCase="'textarea'">
<textarea class="form-control" formControlName="value"> </textarea>
</div>
<div *ngSwitchCase="'booleanDecision'">
<df-booleanDecision [form]="form" [field]="field"></df-booleanDecision>
</div>
<div *ngSwitchCase="'radiobox'">
<df-radiobox [form]="form" [field]="field"></df-radiobox>
</div>
</div>
<div *ngSwitchCase="'label'"> </div>
<div [hidden]="isValid">
<div class="invalid-feedbackCustom" *ngIf="isValidRequired">The field "{{field.label}}" is required</div>
<div class="invalid-feedbackCustom" *ngIf="isValidPattern">The field {{field.label}} must match a regular expression {{field.regex}}</div>
<div class="invalid-feedbackCustom" *ngIf="isValidCustom">The field {{field.label}} custom Validation</div>
</div>
</div>
<!-- <div [formGroup]="form" class="form-group" [ngSwitch]="field.controlType">
<div *ngIf= "field.rules; else elseBlock ">
<div *ngIf="field.rules.length > 0; else elseBlock">
<div *ngFor="let rule of field.rules">
<div *ngIf="rule._type == 'fieldVisible'; else otherRuleBlock">
<div hidden="{{ruleVisibleMethod(field, rule, dataModel)}}">
<label [attr.for]="field.key">{{field.label}}</label>
<input *ngSwitchCase="'textbox'" class="form-control" [formControlName]="field.key" [id]="field.key" [type]="field.type"
required="field.required">
<select [id]="field.key" *ngSwitchCase="'dropdown'" class="form-control" [formControlName]="field.key">
<option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option>
</select>
<input *ngSwitchCase="'checkbox'" [formControlName]="field.key" [(ngModel)]="field.value" [id]="field.key" [type]="field.type"
(change)="field.value = ckb.checked" #ckb>
</div>
</div>
</div>
</div>
</div>
<ng-template #elseBlock>
<label [attr.for]="field.key">{{field.label}}</label>
<input *ngSwitchCase="'textbox'" class="form-control" [formControlName]="field.key" [id]="field.key" [type]="field.type"
required="field.required">
<select [id]="field.key" *ngSwitchCase="'dropdown'" class="form-control" [formControlName]="field.key">
<option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option>
</select>
<input *ngSwitchCase="'checkbox'" [formControlName]="field.key" [(ngModel)]="field.value" [id]="field.key" [type]="field.type"
(change)="field.value = ckb.checked" #ckb>
</ng-template>
<ng-template #otherRuleBlock>
</ng-template>
</div> -->

View File

@ -0,0 +1,48 @@
import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.service';
import { VisibilityRuleSource } from '../../visibility-rules/models/VisibilityRuleSource';
import { Field } from '../../models/Field';
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup, ValidatorFn, AbstractControl, Validators } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { FieldBase } from './field-base';
import { RuleStyle } from '../../entities/common/rulestyle';
@Component({
selector: 'df-field',
templateUrl: './dynamic-form-field.component.html',
styles: ['.checkBoxLabelCustom {font-weight: 700;}']
})
export class DynamicFormFieldComponent {
@Input() field: Field;
@Input() form: FormGroup;
@Input() pathName:string;
private fragment: string;
constructor(private route: ActivatedRoute,private visibilityRulesService:VisibilityRulesService) { }
ngOnChanges(changeRecord) {
}
get isValid() {
return this.form.get("value").valid;
}
get isValidRequired() {
return this.form.get("value").hasError("required");
}
get isValidPattern() {
return this.form.get("value").hasError("pattern");
}
get isValidCustom() {
return this.form.get("value").hasError("forbiddenName");
}
public ngOnInit() {
this.route.fragment.subscribe(fragment => { this.fragment = fragment; }); //navigate to certain section of the page
}
}

View File

@ -1,51 +1,51 @@
import { Rule } from '../../entities/common/rule';
import { Attribute } from '../../entities/model/attribute';
export class FieldBase<T>{
value: T;
key: string;
label: string;
required:boolean;
order:number;
rules: Rule[];
visible: boolean | string;
controlType:string;
group:string;
description:string;
attributes: Attribute;
regex:string;
url: string;
datatype: string;
constructor(options: {
value?: T,
key?: string,
label?: string,
required?:boolean,
order?: number,
rules?: Rule[],
visible?: boolean | string,
controlType?: string
group?: string
description?: string,
attributes?: Attribute,
regex?:string,
url?: string,
datatype?:string
} = {}) {
this.value = options.value;
this.key = options.key || '';
this.label = options.label || '';
this.required = !! options.required;
this.order = options.order === undefined ? 1 : options.order;
this.rules = options.rules;
this.visible = options.visible;
this.controlType = options.controlType || '';
this.group = options.group || '';
this.description = options.description || '';
this.attributes = options.attributes || new Attribute();
this.regex = options.regex || '';
this.url = options.url || "";
this.datatype = options.datatype || "";
}
import { Rule } from '../../entities/common/rule';
import { Attribute } from '../../entities/model/attribute';
export class FieldBase<T>{
value: T;
key: string;
label: string;
required:boolean;
order:number;
rules: Rule[];
visible: boolean | string;
controlType:string;
group:string;
description:string;
attributes: Attribute;
regex:string;
url: string;
datatype: string;
constructor(options: {
value?: T,
key?: string,
label?: string,
required?:boolean,
order?: number,
rules?: Rule[],
visible?: boolean | string,
controlType?: string
group?: string
description?: string,
attributes?: Attribute,
regex?:string,
url?: string,
datatype?:string
} = {}) {
this.value = options.value;
this.key = options.key || '';
this.label = options.label || '';
this.required = !! options.required;
this.order = options.order === undefined ? 1 : options.order;
this.rules = options.rules;
this.visible = options.visible;
this.controlType = options.controlType || '';
this.group = options.group || '';
this.description = options.description || '';
this.attributes = options.attributes || new Attribute();
this.regex = options.regex || '';
this.url = options.url || "";
this.datatype = options.datatype || "";
}
}

View File

@ -1,7 +1,6 @@
import { CompositeField } from '../../models/CompositeField';
import { FormGroup } from '@angular/forms';
import { Section } from '../../entities/model/section';
import { DataModel } from '../../entities/DataModel';
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'df-composite-field',

View File

@ -1,11 +1,7 @@
import { FieldGroup } from '../../models/FieldGroup';
import { DataModel } from '../../entities/DataModel';
import { GroupBase } from './group-base';
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup, Validators, FormControl } from '@angular/forms';
import { NgForm } from '@angular/forms';
import { FieldBase } from '../fields/field-base';
import { TextboxField } from '../fields/textbox/field-textbox';
import { Rule } from '../../entities/common/rule';
@ -16,7 +12,6 @@ import { Rule } from '../../entities/common/rule';
styleUrls: ['./dynamic-form-group.component.css']
})
export class DynamicFormGroupComponent implements OnInit {
@Input() dataModel: DataModel;
@Input() group: FieldGroup
@Input() form: FormGroup;
@Input() pathName:string;

View File

@ -1,47 +0,0 @@
import { Rule } from '../../entities/common/rule';
import { FieldBase } from '../fields/field-base';
export class GroupBase<T>{
value: T;
key: string;
title: string;
rules: Rule[];
groupFields: FieldBase<T>[];
visible: boolean;
order:number;
controlType:string;
section:string;
style:string;
class: string;
page: number;
compositeFields: GroupBase<T>;
constructor(options: {
value?: T,
key?: string,
title?: string,
rules?: Rule[],
groupFields?: FieldBase<T>[],
visible?: boolean,
order?: number,
controlType?: string
section?: string,
style?:string
class?:string,
page?:number,
compositeFields?:GroupBase<T>
} = {}) {
this.value = options.value;
this.key = options.key || '';
this.title = options.title || '';
this.rules = options.rules;
this.groupFields = options.groupFields;
this.visible = options.visible;
this.order = options.order === undefined ? 1 : options.order;
this.controlType = options.controlType || '';
this.section = options.section || '';
this.style = options.style || '';
this.class = options.class || '';
this.page = options.page || 1;
this.compositeFields = options.compositeFields;
}
}

View File

@ -1,6 +1,5 @@
import { FormGroup } from '@angular/forms';
import { Section } from '../../entities/model/section';
import { DataModel } from '../../entities/DataModel';
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'df-section',

View File

@ -7,7 +7,7 @@
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit()">
<div *ngFor = "let section of dataModel.sections; let i = index;">
<df-section [section]="section" [form]="form.get('sections').get(''+i)"></df-section>
<df-section [section]="section" [form]="form.get('sections').get(''+i)" [pathName]="'sections.'+i"></df-section>
</div>
<!-- <div *ngFor="let group of dataModel.groups">

View File

@ -13,13 +13,9 @@ import 'rxjs/add/operator/switchMap';
//import { FieldBase } from '../../app/form/fields/field-base';
import { FieldControlService } from '../../app/services/field-control.service';
import { ServerService } from '../../app/services/server.service';
import { dataModelBuilder } from '../../app/services/dataModelBuilder.service';
import { DataModel } from '../entities/DataModel';
import { GroupBase } from './dynamic-form-group/group-base';
import { PaginationService } from '../../app/services/pagination.service';
import { TokenService, TokenProvider } from '../services/login/token.service';
import { ModalComponent } from '../modal/modal.component';
import { AutocompleteRemoteComponent } from './fields/autocomplete-remote/autocomplete-remote.component';
import {Location} from '@angular/common';
@ -52,7 +48,7 @@ declare var PerfectScrollbar : any;
'../../assets/perfect-scrollbar/perfect-scrollbar.css'
],
providers: [
FieldControlService, ServerService, dataModelBuilder
FieldControlService, ServerService
]
})
export class DynamicFormComponent implements OnInit {
@ -66,6 +62,7 @@ export class DynamicFormComponent implements OnInit {
finalizeStatus:boolean = false;
id: string;
datasetId: string;
pathName:string;
//datasetProperties:string;
private fragment: string;
@ -74,7 +71,7 @@ export class DynamicFormComponent implements OnInit {
expandedToc : boolean = true;
constructor(private qcs: FieldControlService, private serverService: ServerService, private dataModelService: dataModelBuilder, private router: Router,
constructor(private qcs: FieldControlService, private serverService: ServerService, private router: Router,
private _location: Location, private route: ActivatedRoute, private pagerService: PaginationService, private tokenService: TokenService,private visibilityRulesService:VisibilityRulesService) {
this.form = this.qcs.toFormGroup(new Array(), new Array());
this.xml2jsonOBJ = new X2JS();

View File

@ -1,4 +0,0 @@
<label *ngIf="label" for="{{id}}">{{label}}</label>
<input auto-complete class="form-control autocomplete" id="{{id}}" [(ngModel)]="value" (ngModelChange)="updateByQuery($event)" [source]="values" >

View File

@ -1,97 +0,0 @@
import { Component, OnInit,Input, Output, EventEmitter, forwardRef} from '@angular/core';
import { Validators, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ServerService } from '../../../services/server.service';
import { UUID } from 'angular2-uuid';
import { NguiAutoCompleteModule } from '@ngui/auto-complete';
declare var $: any;
@Component({
selector: 'autocomplete-remote',
templateUrl: './autocomplete-remote.component.html',
styleUrls: ['./autocomplete-remote.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AutocompleteRemoteComponent),
multi: true
}
]
})
export class AutocompleteRemoteComponent implements OnInit, ControlValueAccessor {
id : string = UUID.UUID();
@Input() label : string;
@Input() url : string;
selectedValue : string;
values : any[] = new Array();
query : string = "";
constructor(private serverService :ServerService) {
}
ngOnInit() {
this.updateByQuery(this.query); //just to trigger the first call
}
updateByQuery(query : string){
this.serverService.getThroughProxy(this.url, query).subscribe(
response => {
this.values.length = 0; //clear array; -- this is quite a fast and memory efficient way
response.data.forEach(element => {
this.values.push(element.attributes.name);
});
},
error => {
console.log(error);
}
);
}
onChange: any = () => { };
onTouched: any = () => { };
get value() {
this.value = this.selectedValue;
return this.selectedValue;
}
set value(val) {
this.selectedValue = val;
this.onChange(val);
this.onTouched();
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
writeValue(value) {
if (value) {
this.value = value;
}
}
}

View File

@ -1 +0,0 @@
<input [formControlName]="field.key" [(ngModel)]="field.value" [id]="field.key" [type]="field.type" (change)="field.value = ckb.checked" #ckb>

View File

@ -1,11 +0,0 @@
import {FieldBase} from '../field-base';
export class CheckBoxField extends FieldBase<boolean>{
controlType = 'checkbox';
type: "checkbox";
constructor(options: {} = {}){
super(options);
this.type = options['type'] || [];
}
}

View File

@ -1,11 +1,9 @@
import {FieldBase} from '../field-base';
export class DropdownField extends FieldBase<string>{
export class DropdownField {
controlType = 'dropdown';
options: {key: string, value: string}[] =[];
constructor(options: {} = {}){
super(options);
this.options = options['options'] || [];
}
}

View File

@ -1,229 +0,0 @@
import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.service';
import { VisibilityRuleSource } from '../../visibility-rules/models/VisibilityRuleSource';
import { Field } from '../../models/Field';
import { DataModel } from '../../entities/DataModel';
import { Component, Input, OnInit } from '@angular/core';
import { FormGroup, ValidatorFn, AbstractControl, Validators } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { FieldBase } from './field-base';
import { GroupBase } from '../../form/dynamic-form-group/group-base';
import { DropdownField } from '../../form/fields/dropdown/field-dropdown';
import { RuleStyle } from '../../entities/common/rulestyle';
@Component({
selector: 'df-field',
templateUrl: './dynamic-form-field.component.html',
styles: ['.checkBoxLabelCustom {font-weight: 700;}']
})
export class DynamicFormFieldComponent {
@Input() dataModel: DataModel;
@Input() field: Field;
@Input() form: FormGroup;
@Input() pathName:string;
private fragment: string;
constructor(private route: ActivatedRoute,private visibilityRulesService:VisibilityRulesService) { }
ngOnChanges(changeRecord) {
}
get isValid() {
return this.form.get("value").valid;
}
get isValidRequired() {
return this.form.get("value").hasError("required");
}
get isValidPattern() {
return this.form.get("value").hasError("pattern");
}
get isValidCustom() {
return this.form.get("value").hasError("forbiddenName");
}
public ngOnInit() {
this.route.fragment.subscribe(fragment => { this.fragment = fragment; }); //navigate to certain section of the page
}
ngAfterViewChecked(): void { //navigate to certain section of the page
try {
document.querySelector('#' + this.fragment).scrollIntoView();
} catch (e) { }
}
ruleVisibleMethod(field, rule, dataModel) { //visibility rule -- checks if target field is visible
dataModel.fields.forEach(fld => {
if (fld.label == rule._target && fld.visible == true)
field.visible = true;
});
if (field.visible == true)
return true;
}
FieldValueRuleMethod(field, rule, targetField) { //fieldValue rule -- checks the value of target and apply rules, at the same time when the field becomes visible /calling the AddvalidationRules we apply the validation rules for the new field
var fieldValue = this.form.get(field.key).value;//to do: change field.value
if (rule._ruleStyle == "range") {
if (parseInt(rule._from) < parseInt(field.value) && parseInt(field.value) < parseInt(rule._to)) {
console.log("visible" + field.value)
targetField.visible = true;
this.AddvalidationRules(targetField);
} else {
this.hideField(targetField, rule);
}
}
if (rule._ruleStyle == "boolean" && field.value !== undefined) { //boolean Decision field
let ruleValue = rule.value.__text;
if (field.value.toString() == ruleValue) { //field.value.value.toString() == ruleValue
targetField.visible = true;
this.AddvalidationRules(targetField);
} else {
this.hideField(targetField, rule);
}
}
if (rule._ruleStyle == "checked") { //checkbox field
if (field.value == true) {
targetField.visible = true;
this.AddvalidationRules(targetField);
} else {
this.hideField(targetField, rule);
}
}
if (rule._ruleStyle == "unchecked") { //checkbox field
if (field.value !== "") {
if (field.value == false) {
targetField.visible = true;
this.AddvalidationRules(targetField);
} else {
this.hideField(targetField, rule);
}
}
}
if (rule._ruleStyle == "existence") {
if (field.visible == "true" || field.visible == true) {
targetField.visible = true;
this.AddvalidationRules(targetField);
} else {
this.hideField(targetField, rule);
}
}
if (rule._ruleStyle == "regex") {
if (new RegExp(rule.__cdata).test(field.value)) {
targetField.visible = true;
this.AddvalidationRules(targetField);
} else {
this.hideField(targetField, rule);
}
}
if (rule._ruleStyle == "dropdownValue") { //dropdown field
let fieldValue = this.form.get(field.key).value;
let ruleValue;
let ruleValueBoolean = false;
if (rule.value.length)
rule.value.forEach(value => {
if (fieldValue.toString() == value.__text)
ruleValueBoolean = true;
return;
});
else
ruleValue = rule.value.__text;
if (fieldValue.toString() == ruleValue || ruleValueBoolean.valueOf() == true) { //field.value.value.toString() == ruleValue
targetField.visible = true;
this.AddvalidationRules(targetField);
} else {
this.hideField(targetField, rule);
}
}
}
hideField(targetField, rule) {
targetField.visible = false;
targetField.value = ' ';
if (this.form.controls[targetField.key].hasError("pattern"))
this.form.controls[targetField.key].reset(); //the regex error message didn't remove without field reset
this.form.controls[targetField.key].clearValidators(); // when a field is hidden must clear the validators and the errors
this.form.controls[targetField.key].updateValueAndValidity();
}
findTargetField (field, rule){
// var targetField = this.dataModel.getFieldByKey(rule._target);
let targetFields = new Array();
if (this.dataModel.getFieldByKey(rule._target) == undefined) {
this.dataModel.groups.forEach(gr => {
if (gr.key == rule._target) {
gr.groupFields.forEach(field=>{
targetFields.push(field);
});
if(gr.compositeFields)
gr.compositeFields.groupFields.forEach(field=>{
targetFields.push(field);
});
}
})
} else {
targetFields.push(this.dataModel.getFieldByKey(rule._target));
}
return targetFields;
}
toggleVisibility(e, field, ckb) { //ckb the checkbox only send this parameter, it's essential to change the field value
if (ckb) {
if (e) this.form.get(field.key).patchValue(e.target.checked)
field.value = this.form.get(field.key).value;
}
if (field.rules.length != undefined && field.rules.length > 1)
field.rules.forEach(rule => {
if (rule._type == "fieldValue") {
let targetFieldsArray = this.findTargetField(field,rule);
targetFieldsArray.forEach(targetField =>{
this.FieldValueRuleMethod(field, rule, targetField);
})
}
});
else if (field.rules._type == "fieldValue") {
let targetFieldsArray = this.findTargetField(field,field.rules);
targetFieldsArray.forEach(targetField =>{
this.FieldValueRuleMethod(field, field.rules, targetField);
})
}
}
AddvalidationRules(field) {
if (this.dataModel.getFieldByKey(field.key).attributes.validation != undefined) {
let arrayVal = new Array();
this.dataModel.getFieldByKey(field.key).attributes.validation.forEach(rule => {
if (rule.ruleStyle.toString() == RuleStyle[RuleStyle.existence]) {
this.dataModel.getFieldByKey(field.key).required = true;
arrayVal.push(Validators.required);
}
if (rule.ruleStyle.toString() == RuleStyle[RuleStyle.regex]) {
this.dataModel.getFieldByKey(field.key).regex = rule.regex;
arrayVal.push(Validators.pattern(rule.regex));
}
if (rule.ruleStyle.toString() == RuleStyle[RuleStyle.customValidation]) {
arrayVal.push(this.forbiddenNameValidator(/nothing/i));
}
});
this.form.controls[field.key].setValidators(arrayVal); //Multiple Validators, Usage of array because setValidator override any validators that are provided during initialistaion
this.form.controls[field.key].updateValueAndValidity(); //hide--> visible must update the validators
}
}
forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
const forbidden = nameRe.test(control.value);
return forbidden ? { 'forbiddenName': { value: control.value } } : null;
};
}
}

View File

@ -1,11 +0,0 @@
import {FieldBase} from '../field-base';
export class LabelField extends FieldBase<string> {
controlType = 'label';
type: string;
constructor (options: {} = {}) {
super(options);
this.type = options['type'] || '';
}
}

View File

@ -1 +0,0 @@
<input [formControlName]="field.key" [(ngModel)]="field.value" [type]="field.type" >

View File

@ -1,13 +0,0 @@
import {FieldBase} from '../field-base';
export class RadioBoxField extends FieldBase<boolean>{
controlType = 'radiobox';
type: "radio";
answers: Array<any>;
constructor(options: {} = {}){
super(options);
this.type = options['type'] || [];
this.answers = options['answers'] || []
}
}

View File

@ -1,5 +1,4 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { DataModel } from '../../entities/DataModel';
//import * as $ from '../../../../node_modules/jquery/dist/jquery'
@ -13,17 +12,12 @@ import * as scroll from '../../../assets/jquery.scrollTo.min.js';
})
export class TocComponent implements OnInit{
@Input() dataModel: DataModel;
private headers = new Array();
@Output()
setPage:EventEmitter<number> = new EventEmitter<number>();
ngOnInit(){
var len = this.dataModel.groups.length; // I don't use headers , I use datamodel.groupfields
for (var i=0; i<len; i++){
this.headers.push (this.dataModel.groups[i].title)
}
ngOnInit(){
}

View File

@ -13,7 +13,7 @@ export class Field extends BaseModel implements Serializable<Field>,FormGenerato
public viewStyle:string;
public defaultVisibility:boolean;
public page:number;
public data:any;
fromJSONObject(item:any):Field{
this.id = item.id;
this.title = item.title;
@ -23,6 +23,7 @@ export class Field extends BaseModel implements Serializable<Field>,FormGenerato
this.viewStyle = item.viewStyle;
this.defaultVisibility = item.defaultVisibility;
this.page = item.page;
this.data = item.data;
return this;
}
@ -35,7 +36,8 @@ export class Field extends BaseModel implements Serializable<Field>,FormGenerato
extendedDescription:[this.extendedDescription],
viewStyle: [this.viewStyle],
defaultVisibility:[this.defaultVisibility],
page:[this.page]
page:[this.page],
data:[this.data]
});
return formGroup;
}

View File

@ -1,383 +0,0 @@
import { Injectable } from '@angular/core';
import { DropdownField } from '../../app/form/fields/dropdown/field-dropdown';
import { FieldBase } from '../../app/form/fields/field-base';
import { TextboxField } from '../../app/form/fields/textbox/field-textbox';
import { CheckBoxField } from '../../app/form/fields/checkbox/field-checkbox';
import { RadioBoxField } from '../../app/form/fields/radiobox/field-radiobox';
import { TextAreaField } from '../../app/form/fields/textarea/textarea';
import { LabelField } from '../../app/form/fields/label/label';
import { DataModel } from '../entities/DataModel';
import { Rule } from '../entities/common/rule';
import { GroupBase } from '../form/dynamic-form-group/group-base';
import { Attribute } from '../entities/model/attribute';
import { Param } from '../entities/model/param';
import { Section } from '../entities/model/section';
import { RestBase } from '../services/rest-base';
@Injectable()
export class dataModelBuilder {
private dataModel: DataModel;
private fields: FieldBase<any>[];
constructor(private restBase: RestBase) { }
public getDataModel(data, dataValues) {
if (this.dataModel != null)
return this.dataModel;
this.dataModel = new DataModel();
this.fields = this.buildFields(data.viewstyle.definition.root.fields.field);
this.dataModel.semanticAttr = new Array(new Attribute);
this.dataModel.semanticAttr = this.getFieldsAttributes(data.definition.root.fields.fieldset, data.ruleset.definition.root.functions.function, this.fields);
this.dataModel.groups = this.getGroups(data.viewstyle.definition.root.fieldGroups.fieldGroup, this.fields, dataValues);
this.dataModel.sections = this.getSections(data.viewstyle.definition.root.sections.section, this.dataModel.groups);
this.dataModel.buildIndex();
this.checkDuplicateInObject('order', this.dataModel.groups[13].groupFields); //for future use , for composite field
return this.dataModel;
}
private buildFields(fields: any[]) {
let fieldsVisible: FieldBase<any>[] = [];
fields.forEach(element => {
if (element.viewStyle._renderstyle == "freetext") {
let newfield: FieldBase<any>;
let rule = new Rule();
newfield = new TextboxField({
label: element.title.__cdata,
key: element._id,
value: element.value,
order: element._ordinal,
rules: element.visible.rule != undefined ? element.visible.rule : rule,
visible: element._defaultVisibility,
group: element._group,
description: element.description.__cdata
});
fieldsVisible.push(newfield);
}
else if (element.viewStyle._renderstyle == "dropdown" || element.viewStyle._renderstyle == "combobox") {//to choose one of these in xml
let newfield: DropdownField;
let rule = new Rule();
newfield = new DropdownField({
label: element.title.__cdata,
key: element._id,
value: element.value,
order: element._ordinal,
rules: element.visible.rule != undefined ? element.visible.rule : rule,
visible: element._defaultVisibility,
description: element.description.__cdata,
group: element._group
});
fieldsVisible.push(newfield);
}
else if (element.viewStyle._renderstyle == "checkbox" || element.viewStyle._renderstyle == "checkBox") {
let newfield: CheckBoxField;
let rule = new Array<Rule>();
newfield = new CheckBoxField({
label: element.title.__cdata,
key: element._id,
value: false,
order: element._ordinal,
rules: element.visible.rule != undefined ? element.visible.rule : rule,
visible: element._defaultVisibility,
group: element._group,
description: element.description.__cdata,
type: "checkbox"
});
fieldsVisible.push(newfield);
}
else if (element.viewStyle._renderstyle == "booleanDesicion") {
let newfield: RadioBoxField;
let rule = new Array<Rule>();
newfield = new RadioBoxField({
label: element.title.__cdata,
key: element._id,
value: element.value,
order: element._ordinal,
rules: element.visible.rule != undefined ? element.visible.rule : rule,
visible: element._defaultVisibility,
group: element._group,
type: "radio",
description: element.description.__cdata,
answers: [
{
id: 1,
answer: "Yes",
value: true
},
{
id: 2,
answer: "No",
value: false
}]
});
fieldsVisible.push(newfield);
} else if (element.viewStyle._renderstyle == "textarea") {
let newfield: FieldBase<any>;
let rule = new Rule();
newfield = new TextAreaField({
label: element.title.__cdata,
key: element._id,
value: element.value,
order: element._ordinal,
rules: element.visible.rule != undefined ? element.visible.rule : rule,
visible: element._defaultVisibility,
group: element._group,
description: element.description.__cdata
});
fieldsVisible.push(newfield);
}
else if (element.viewStyle._renderstyle == "label") {
let newfield: FieldBase<any>;
let rule = new Rule();
newfield = new LabelField({
label: element.title.__cdata,
key: element._id,
value: element.value,
order: element._ordinal,
rules: element.visible.rule != undefined ? element.visible.rule : rule,
visible: element._defaultVisibility,
group: element._group,
description: element.description.__cdata
});
fieldsVisible.push(newfield);
}
});
fieldsVisible.sort((a, b) => a.order - b.order);
return fieldsVisible;
}
private getGroups(fieldGroups: any, fields: any[], dataValues) {
let groups: GroupBase<any>[] = [];
if (fieldGroups.length > 1) {
fieldGroups.forEach(fieldGroup => { // each fiedgroup fills with its fields from json
let newfldGroup = new GroupBase();
let compositeFields = new GroupBase();
newfldGroup.groupFields = new Array();
compositeFields.groupFields = new Array();
fields.forEach(field => {
if (fieldGroup._id == field.group) {
if (dataValues != "")//--------------------------SET VALUES---------------------------------------------------------------------------------------
if (dataValues[fieldGroup._id][field.key] != undefined) // to put values in fields
field.value = dataValues[fieldGroup._id][field.key].value == undefined ? dataValues[fieldGroup._id][field.key] : dataValues[fieldGroup._id][field.key].value;
if(field.order.toString().split(".").length > 1){//--------------Composite Fields Multiplicity --------------------------------------------------
compositeFields.groupFields.push(field);
newfldGroup.compositeFields = compositeFields;
}else
newfldGroup.groupFields.push(field);
} else {
//this.dataModel.fields.push(field);
}
//TO DO FIELDSET WITH MULTIPLICITY
// if (dataValues != "")
// if (dataValues[fieldGroup._id][field.key] != undefined){
// let keys = new Array<string>();
// Object.keys(dataValues[fieldGroup._id]).forEach(key=>{if(key.startsWith(field.key+"_"))keys.push(key)})
// if (keys.length)
// if (field.controlType == "textbox") {
// let newfield: FieldBase<any>;
// let rule = new Rule();
// newfield = new TextboxField({
// label: field.label+"_"+ 1,
// key: keys[0],
// value: dataValues[fieldGroup._id][keys[0]].value,
// order: field.order,
// rules: field.rules,
// visible: field.visible,
// group: field.group,
// description: field.description
// });debugger;
// newfldGroup.groupFields.push(newfield);
// }
// }
});
newfldGroup.title = fieldGroup.title.__cdata;
newfldGroup.key = fieldGroup._id;
newfldGroup.section = fieldGroup._section;
newfldGroup.style = fieldGroup.visible._style;
newfldGroup.class = fieldGroup.visible._cssclass;
newfldGroup.page = fieldGroup._page;
groups.push(newfldGroup)
});
}
else {
let newfldGroup = new GroupBase();
newfldGroup.groupFields = new Array();
fields.forEach(field => { //for one fieldgroup, because xml to json transformation doesn't create array of one fieldfroup
if (fieldGroups._id == field.group) {
newfldGroup.groupFields.push(field);
} else
this.dataModel.fields.push(field);
});
newfldGroup.title = fieldGroups.title.__cdata;
newfldGroup.key = fieldGroups._id;
newfldGroup.section = fieldGroups._section;
groups.push(newfldGroup)
}
return groups;
}
addAttributesToFields(attr, functions, fields, multiplicity){
let newAttribute = new Attribute();
newAttribute.datatype = attr._datatype;
newAttribute.defaultValue = attr.defaultValue._value;
newAttribute.id = attr._id;
newAttribute.multiplicityMax = attr.multiplicity._max;
newAttribute.multiplicityMin = attr.multiplicity._min;
newAttribute.ordinal = attr._ordinal
if (multiplicity){
fields.find(x => x.key == newAttribute.id).order = fields.find(x => x.key == newAttribute.id).order +'.'+ newAttribute.ordinal;
fields.find(x => x.key == newAttribute.id).multiplicity = true;
}
newAttribute.ordinal = attr._ordinal;
newAttribute.sources = new Array();
newAttribute.validation = new Array();
//newAttribute.validation.push(attr.validation.rule);
//-----------------Sources---------------------------------------------------------------
if (attr.sources) {
newAttribute.sources.push(attr.sources.source);
if (attr.sources.source.length != undefined) {
for (var i = 0; i < attr.sources.source.length; i++) {
if (attr.sources.source[i]._type == "url") {
newAttribute.url = attr.sources.source[i].value._value;
break;
}
}
}
if (attr.sources.source._type == "url") {
newAttribute.url = attr.sources.source.value._value;
}
}
//-----------Rules------------------------------------------------------------------------
if(attr.validation.rule != undefined)
if (attr.validation.rule.length)
for (var i = 0, len = attr.validation.rule.length; i < len; i++) {
let rule = new Rule();
rule.ruleStyle = attr.validation.rule[i]._ruleStyle;
rule.ruleType = attr.validation.rule[i]._type;
if (attr.validation.rule[i]._ruleStyle == "regex")
rule.regex = attr.validation.rule[i].__cdata;
if (attr.validation.rule[i]._ruleStyle == "customValidation") {
rule.method = attr.validation.rule[i]._method;
functions.forEach(fnc => {
if (fnc._id == rule.method)
rule.methodJs = fnc.script.__cdata;
});
}
newAttribute.validation.push(rule);
}
else {
if (attr.validation.rule) {
let rule = new Rule();
rule.ruleStyle = attr.validation.rule._ruleStyle;
rule.ruleType = attr.validation.rule._type;
if (attr.validation.rule._ruleStyle == "regex")
rule.regex = attr.validation.rule.__cdata;
if (attr.validation.rule._ruleStyle == "customValidation") {
rule.method = attr.validation.rule._method;
functions.forEach(fnc => {
if (fnc._id == rule.method)
rule.methodJs = fnc.__cdata;
});
}
newAttribute.validation.push(rule); }
}
fields.sort((a, b) => a.order - b.order);
return newAttribute;
}
private getFieldsAttributes(fieldsets: any, functions: any, fields: any[]) {
let attribute: Attribute[] = [];
let newAttribute = new Attribute();
let multiplicityParam = false;
fieldsets.forEach(fieldset => {
let multiplicityParam = false;
if (fieldset.fields.field.length){
if(fieldset.multiplicity._max >1 || fieldset.multiplicity._max == "n")
multiplicityParam = true;
fieldset.fields.field.forEach(fieldAttribute=>{
newAttribute = this.addAttributesToFields(fieldAttribute, functions, fields, multiplicityParam)
attribute.push(newAttribute);
if (newAttribute.url !== undefined)
fields.find(x => x.key == newAttribute.id).url = newAttribute.url;
fields.find(x => x.key == newAttribute.id).attributes.sources = newAttribute.sources;
fields.find(x => x.key == newAttribute.id).attributes.validation = newAttribute.validation;
})
}else{
if(fieldset.multiplicity._max >1 || fieldset.multiplicity._max == "n")
multiplicityParam = true;
newAttribute = this.addAttributesToFields(fieldset.fields.field, functions, fields, multiplicityParam)
attribute.push(newAttribute);
if (newAttribute.url !== undefined)
fields.find(x => x.key == newAttribute.id).url = newAttribute.url;
fields.find(x => x.key == newAttribute.id).attributes.sources = newAttribute.sources;
fields.find(x => x.key == newAttribute.id).attributes.validation = newAttribute.validation;
}
});
return attribute;
}
private getSections(sections: any, fieldGroups: GroupBase<any>[]) {
let sects: Section[] = [];
if (sections.length) {
sections.forEach(section => {
let newSection = new Section();
newSection.defaultVisibility = section.defaultVisibility;
newSection.description = section.description;
newSection.id = section._id;
newSection.title = section.title;
newSection.ordinal = section._ordinal;
newSection.page = section._page;
newSection.groupFields = new Array();
fieldGroups.forEach(fldgroup => {
if (fldgroup.section == newSection.id)
newSection.groupFields.push(fldgroup);
})
sects.push(newSection);
});
}
sects.sort((a, b) => a.ordinal - b.ordinal);
return sects;
}
checkDuplicateInObject(propertyName, inputArray) {
let DuplicateArray = [];
inputArray.forEach(item => {
for(var i=0; i<inputArray.length; i++){
if(item[propertyName] == inputArray[i][propertyName] && item['key'] != inputArray[i]['key']){
DuplicateArray.push(inputArray[i]);
}
}
});
console.log(DuplicateArray);
}
}

View File

@ -1,15 +1,12 @@
import { Injectable } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { FieldBase } from '../../app/form/fields/field-base';
import { GroupBase } from '../form/dynamic-form-group/group-base';
@Injectable()
export class FieldControlService {
constructor(){ }
toFormGroup(fields: FieldBase<any>[], groups: GroupBase<any>[]){
toFormGroup(fields: any, groups:any){
let form: any = {};

View File

@ -19,7 +19,7 @@ export class RestBase {
protocol: string = "http";
hostname: string ="localhost"
port: number = 7070;
port: number = 8080;
webappname: string = "dmp-backend";
/*

View File

@ -1,9 +1,6 @@
import {Injectable, ReflectiveInjector, Injector} from '@angular/core';
import {FieldBase} from '../../app/form/fields/field-base';
import {JsonObjest} from '../../app/entities/JsonObject.class';
import {dataModelBuilder} from '../../app/services/dataModelBuilder.service';
import { DatasetProfile } from '../entities/datasetprofile';
import {DataModel} from '../entities/DataModel';
import {Project} from '../entities/model/project';
import {RestBase} from './rest-base';
import 'rxjs/Rx';

View File

@ -1,11 +1,17 @@
export const TestModel = {
"rules": [
{
"sourceField": "useMetadataQ211",
"sourceField": "dataSummary",
"targetField": "metadataStandarsA211",
"requiredValue": "true",
"type": "visibility",
},
{
"sourceField": "radioChoices",
"targetField": "notlistedUrlA211",
"requiredValue": "between15and18",
"type": "visibility",
},
{
"sourceField": "dataSummary",
"targetField": "freeOfChargeGroupCommentA213",
@ -17,13 +23,7 @@ export const TestModel = {
"targetField": "noMetadata",
"requiredValue": "true",
"type": "visibility",
},
{
"sourceField": "FindDataMetadataGroup",
"targetField": "notlistedUrlA211",
"requiredValue": "true",
"type": "visibility",
},
},
{
"sourceField": "FindDataMetadataGroup",
"targetField": "notlistedCommentA211",
@ -31,7 +31,7 @@ export const TestModel = {
"type": "visibility",
},
{
"sourceField": "useVocabulariesQ212",
"sourceField": "dataSummary",
"targetField": "standardisedVocabulariesA212",
"requiredValue": "true",
"type": "visibility",
@ -88,7 +88,25 @@ export const TestModel = {
"title": "",
"description": "",
"extendedDescription": "",
"viewStyle": "checkBox"
"viewStyle": "checkBox",
"data": {
}
},
{
"id": "radioChoices",
"defaultVisibility": "true",
"title": "",
"description": "",
"extendedDescription": "",
"viewStyle": "radiobox",
"data": {
"options": [
{ "label": "Over 18", "value": "over18" },
{ "label": "Under 15", "value": "under15" },
{ "label": "Between 15 - 18", "value": "between15and18" }
]
}
}
]
}
@ -128,7 +146,10 @@ export const TestModel = {
"title": "Q2.1.1 Will you use metadata to describe the data?",
"description": "User can select from a list of metadata standards. If they cannot find the standard in the list provided then they should choose \"not listed\". Selecting this will result in a field in which the user can insert the URL to the description of the metadata scheme used. A \"comments\" box should exist to allow users to add comments. They may select more than one metadata standard. They may specify more than one URL when selecting \"not listed\". They are also presented with a field in which to specify the location of the metadata service. Users can select the \"no metadata\" button to specify no metadata will be used to describe the data.",
"extendedDescription": "FieldGroup Description",
"viewStyle": "booleanDesicion"
"viewStyle": "booleanDecision",
"data": {
}
}
]
},
@ -137,11 +158,15 @@ export const TestModel = {
[
{
"id": "metadataStandarsA211",
"defaultVisibility": "false",
"defaultVisibility": "true",
"title": "Metadata standards",
"description": "The data will be described by metadata that follows the metadata standards described in <url1>, <url2>, ? The data will be described by metadata that follows the metadata schema described in <not-listed-url1>, <not-listed-url2>. The metadata will be stored in the service located at <metadata-repo-url>",
"extendedDescription": "",
"viewStyle": "combobox"
"viewStyle": "combobox",
"data": {
"type": "autocomplete",
"url": "http://dionysus.di.uoa.gr:8080/dmp-backend/rest/external/datarepos?query=gree"
}
}]
},
{
@ -153,8 +178,12 @@ export const TestModel = {
"title": "Not listed",
"description": "",
"extendedDescription": "",
"viewStyle": "checkBox"
}]
"viewStyle": "checkBox",
"data": {
}
}
]
},
{
"fields":
@ -165,7 +194,10 @@ export const TestModel = {
"title": "Url",
"description": "URL to the description of the metadata scheme used",
"extendedDescription": "",
"viewStyle": "freetext"
"viewStyle": "freetext",
"data": {
}
}]
},
{
@ -177,7 +209,10 @@ export const TestModel = {
"title": "Comments",
"description": "",
"extendedDescription": "",
"viewStyle": "freetext"
"viewStyle": "freetext",
"data": {
}
}]
},
{
@ -189,7 +224,10 @@ export const TestModel = {
"title": "The data will not be described by any metadata.",
"description": "",
"extendedDescription": "",
"viewStyle": "checkBox"
"viewStyle": "checkBox",
"data": {
}
}
]
}
@ -211,7 +249,10 @@ export const TestModel = {
"title": "Q2.1.2 Will your metadata use standardised vocabularies?",
"description": "User selects from a drop-down list of existing standardised vocabularies or \"not listed\" or \"none\". There should be a \"comments\" fields for additional information. If \"not listed\" is selected the user is presented with two additional fields in which the user can put the URL to the new vocabulary along with a short description. The user should be allowed to select more than one option.",
"extendedDescription": "FieldGroup Description",
"viewStyle": "booleanDesicion"
"viewStyle": "booleanDesicion",
"data": {
}
}]
},
{
@ -222,7 +263,15 @@ export const TestModel = {
"title": "Existing standardised vocabularies",
"description": "The metadata will make use of the standardised vocabulary <url>",
"extendedDescription": "",
"viewStyle": "combobox"
"viewStyle": "combobox",
"data": {
"type": "wordlist",
"values": [
{ "label": "Mitsos", "value": "mitsakos" },
{ "label": "Kitsos", "value": "kitsakos" },
{ "label": "Panagiotis", "value": "mpotis" }
]
}
}]
},
{
@ -233,7 +282,10 @@ export const TestModel = {
"title": "Not listed vocabulary",
"description": "",
"extendedDescription": "",
"viewStyle": "checkBox"
"viewStyle": "checkBox",
"data": {
}
}]
},
{
@ -244,7 +296,10 @@ export const TestModel = {
"title": "Vocabulary Url",
"description": "The user can put the URL to the new vocabulary",
"extendedDescription": "",
"viewStyle": "freetext"
"viewStyle": "freetext",
"data": {
}
}]
},
{
@ -255,7 +310,10 @@ export const TestModel = {
"title": "Comments",
"description": "Vocabulary short description",
"extendedDescription": "",
"viewStyle": "freetext"
"viewStyle": "freetext",
"data": {
}
}]
},
{
@ -266,7 +324,10 @@ export const TestModel = {
"title": "The metadata will not make use of any vocabulary",
"description": "",
"extendedDescription": "",
"viewStyle": "checkBox"
"viewStyle": "checkBox",
"data": {
}
}
]
}
@ -281,28 +342,34 @@ export const TestModel = {
"extendedDescription": "FieldGroup Description",
"compositeFields": [
{
"fields": [
{
"id": "freeOfChargeGroupQ213",
"defaultVisibility": "true",
"title": "Q2.1.3 Will you use standardised formats for some or all of your data.",
"description": "User is presented with a choice of ?yes?, ?no?. There should be a ?comments? field for additional information.",
"extendedDescription": "Field Description",
"viewStyle": "booleanDesicion"
}]
},
{
"fields": [
{
"id": "freeOfChargeGroupCommentA213",
"defaultVisibility": "true",
"title": "Comments",
"description": "",
"extendedDescription": "",
"viewStyle": "freetext"
}
]
}
"fields": [
{
"id": "freeOfChargeGroupQ213",
"defaultVisibility": "true",
"title": "Q2.1.3 Will you use standardised formats for some or all of your data.",
"description": "User is presented with a choice of ?yes?, ?no?. There should be a ?comments? field for additional information.",
"extendedDescription": "Field Description",
"viewStyle": "booleanDesicion",
"data": {
}
}]
},
{
"fields": [
{
"id": "freeOfChargeGroupCommentA213",
"defaultVisibility": "true",
"title": "Comments",
"description": "",
"extendedDescription": "",
"viewStyle": "freetext",
"data": {
}
}
]
}
]
}
]

View File

@ -9,6 +9,7 @@ export class VisibilityRulesService {
public formGroup: FormGroup;
public visibilityRuleContext: VisibilityRulesContext;
public fieldsPathMemory: any = {};
public isElementVisible(pathKey: string, id: string) {
if (!this.fieldsPathMemory[id]) this.fieldsPathMemory[id] = pathKey;
let visibilityRule = this.visibilityRuleContext.getRulesFromKey(id);
@ -20,8 +21,8 @@ export class VisibilityRulesService {
let sourceVisibilityRules = visibilityRule.sourceVisibilityRules;
for (let i = 0; i < sourceVisibilityRules.length; i++) {
let sourceVisibilityRule = sourceVisibilityRules[i];
if (!this.formGroup.get( this.fieldsPathMemory[sourceVisibilityRule.sourceControlId] + '.value')||
(sourceVisibilityRule.sourceControlValue != this.formGroup.get( this.fieldsPathMemory[sourceVisibilityRule.sourceControlId] + '.value').value)) return false;
if (!this.formGroup.get( this.fieldsPathMemory[sourceVisibilityRule.sourceControlId] + '.value'))continue;
if(sourceVisibilityRule.sourceControlValue != ''+this.formGroup.get( this.fieldsPathMemory[sourceVisibilityRule.sourceControlId] + '.value').value) return false;
}
return true;
}

View File

@ -51,11 +51,6 @@
</head>
<body>
<script>
 
</script>
<app-root></app-root>
</body>
</html>