Dataset Profile Editor. Drag n drop fix on Import Template. Feedback messages on update/save template. Code cleanups. MultiAutoComplete Preview Fix.

This commit is contained in:
Kristian Ntavidi 2021-03-31 18:31:57 +03:00
parent cc8c771ae5
commit 2df5c6820a
23 changed files with 321 additions and 582 deletions

View File

@ -59,6 +59,6 @@ export const GENERAL_ANIMATIONS = [
trigger('fadeElement',[ trigger('fadeElement',[
state('updated',style({opacity:0})), state('updated',style({opacity:0})),
transition("*=>updated", transition("*=>updated",
animate('2s 40ms ease-out')) animate('2s 1s ease-out'))
]) ])
] ]

View File

@ -17,7 +17,7 @@
<div class="col-2 col-xl-auto ml-4" *ngIf="!selectedFieldSetId && !viewOnly"> <div class="col-2 col-xl-auto ml-4" *ngIf="!selectedFieldSetId && !viewOnly">
<div class="row bg-white actions-list"> <div class="row bg-white actions-list">
<nav *ngIf="!viewOnly"> <nav>
<label class="action-list-label">{{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.GENERAL-TOOLS' | translate}}</label> <label class="action-list-label">{{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.GENERAL-TOOLS' | translate}}</label>
<ul class="list-unstyled"> <ul class="list-unstyled">
<li class="mli"> <li class="mli">
@ -36,7 +36,7 @@
</div> </div>
<!-- FIELDSET INFO --> <!-- FIELDSET INFO -->
<div class="col-12 drop-list" dragula="FIELDSETS" [(dragulaModel)]="form.get('fieldSets').controls"> <div class="col-12" dragula="FIELDSETS" [(dragulaModel)]="form.get('fieldSets').controls">
<div style="margin-bottom: 2em;" class="row" <div style="margin-bottom: 2em;" class="row"
*ngFor="let fieldset of form.get('fieldSets')?.controls ; let i=index"[id]="idprefix+fieldset.get('id').value" *ngFor="let fieldset of form.get('fieldSets')?.controls ; let i=index"[id]="idprefix+fieldset.get('id').value"

View File

@ -9,77 +9,52 @@ $blue-color-light: #5cf7f2;
.fieldset-actions-list li{ .fieldset-actions-list li{
cursor: pointer; cursor: pointer;
} }
//cdkDrag .actions-list{
// border: 1px solid $blue-color;
// box-shadow: 0px 3px 12px #129D9999;
border-radius: 4px;
// padding-top: 1rem;
padding: 1em 0.9em;
padding-bottom: 3em;
min-width: 166px;
.cdk-drag-preview { .mat-list-item-content{
box-sizing: border-box; padding: 0px;
border-radius: 4px;
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12);
} }
.cdk-drag-placeholder {
opacity: 0;
// background-color: black;
}
.cdk-drag-animating { .action-list-item{
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); display: flex;
} align-items: center;
cursor: pointer;
.example-box:last-child {
border: none;
}
.drop-list.cdk-drop-list-dragging { .action-list-icon{
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); font-size: 1.2em;
} // padding-right: 1em;
width: 14px;
.actions-list{ margin-right: 0.5em;
// border: 1px solid $blue-color; margin-left: -.09em;
// box-shadow: 0px 3px 12px #129D9999; height: auto;
border-radius: 4px; color: #129D99;;
// padding-top: 1rem;
padding: 1em 0.9em;
padding-bottom: 3em;
min-width: 166px;
.mat-list-item-content{
padding: 0px;
} }
.input_icon{
width: 14px;
.action-list-item{ margin-right: .5em;
display: flex;
align-items: center;
cursor: pointer;
.action-list-icon{
font-size: 1.2em;
// padding-right: 1em;
width: 14px;
margin-right: 0.5em;
margin-left: -.09em;
height: auto;
color: #129D99;;
}
.input_icon{
width: 14px;
margin-right: .5em;
}
.action-list-text{
font-size: 0.9em;
}
} }
.action-list-label{ .action-list-text{
color: #212121; font-size: 0.9em;
font-size: small;
opacity: 0.6;
} }
.list-unstyled{ }
margin-bottom: 0.2rem; .action-list-label{
} color: #212121;
} font-size: small;
opacity: 0.6;
}
.list-unstyled{
margin-bottom: 0.2rem;
}
}

View File

@ -193,7 +193,6 @@
<dataset-profile-table-of-contents class="toc-pane-container col" <dataset-profile-table-of-contents class="toc-pane-container col"
[links]="toCEntries" [links]="toCEntries"
(itemClick)="displayItem($event)" (itemClick)="displayItem($event)"
(newEntry)="addNewEntry($event)"
(createEntry) = "addNewEntry($event)" (createEntry) = "addNewEntry($event)"
(removeEntry)="onRemoveEntry($event)" (removeEntry)="onRemoveEntry($event)"
[itemSelected]="selectedTocEntry" [itemSelected]="selectedTocEntry"

View File

@ -29,7 +29,7 @@ import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { Link, LinkToScroll } from '@app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents'; import { Link, LinkToScroll } from '@app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents';
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
import { DatasetWizardEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model'; import { DatasetWizardEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model';
import { Foo, ToCEntry, ToCEntryType } from '../table-of-contents/table-of-contents-entry'; import { NewEntryType, ToCEntry, ToCEntryType } from '../table-of-contents/table-of-contents-entry';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FieldSetEditorModel } from '../admin/field-set-editor-model'; import { FieldSetEditorModel } from '../admin/field-set-editor-model';
import { Guid } from '@common/types/guid'; import { Guid } from '@common/types/guid';
@ -263,25 +263,27 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
// (<FormArray>this.form.get('sections')).push(section.buildForm()); // (<FormArray>this.form.get('sections')).push(section.buildForm());
// } // }
addPage() { // addPage() {
const page: PageEditorModel = new PageEditorModel(this.dataModel.pages.length); // const page: PageEditorModel = new PageEditorModel(this.dataModel.pages.length);
this.dataModel.pages.push(page); // this.dataModel.pages.push(page);
(<FormArray>this.form.get('pages')).push(page.buildForm()); // (<FormArray>this.form.get('pages')).push(page.buildForm());
} // }
DeleteSection(index) { // DeleteSection(index) {
this.dataModel.sections.splice(index, 1); // this.dataModel.sections.splice(index, 1);
(<FormArray>this.form.get('sections')).removeAt(index); // (<FormArray>this.form.get('sections')).removeAt(index);
} // }
onSubmit() { onSubmit() {
let data = this.form.value; let data = this.form.value;
if (this.datasetProfileId) { if (this.datasetProfileId) {
this.datasetProfileService.updateForm(this.datasetProfileId, data) this.datasetProfileService.updateForm(this.datasetProfileId, data)
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(() => { .subscribe(() => {
this.router.navigate(['/dataset-profiles']); this.router.navigate(['/dataset-profiles']);
}); this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-PROFILE-EDITOR.FEEDBACK-MESSAGES.SAVE-SUCCESS'), SnackBarNotificationLevel.Success);
},error=> this.onCallbackError(error));
} else if (this.newVersionId) { } else if (this.newVersionId) {
data.label = this.form.get('label').value; data.label = this.form.get('label').value;
data.description = this.form.get('description').value; data.description = this.form.get('description').value;
@ -289,17 +291,21 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(() => { .subscribe(() => {
this.router.navigate(['/dataset-profiles']); this.router.navigate(['/dataset-profiles']);
this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-PROFILE-EDITOR.FEEDBACK-MESSAGES.SAVE-SUCCESS'), SnackBarNotificationLevel.Success);
}, },
error => this.onCallbackErrorNewVersion(error) error => this.onCallbackErrorNewVersion(error)
); );
} else { } else {
this.form.get('status').setValue(DatasetStatus.Draft); if(this.form.get('status').value != DatasetStatus.Finalized){// forn created and finalized instantly
this.form.get('status').setValue(DatasetStatus.Draft);
}
data = this.form.value; data = this.form.value;
this.datasetProfileService.createForm(data) this.datasetProfileService.createForm(data)
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(() => { .subscribe(() => {
this.router.navigate(['/dataset-profiles']); this.router.navigate(['/dataset-profiles']);
}); this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-PROFILE-EDITOR.FEEDBACK-MESSAGES.SAVE-SUCCESS'), SnackBarNotificationLevel.Success);
}, error=> this.onCallbackError(error));
} }
} }
@ -315,21 +321,22 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(() => { .subscribe(() => {
this.router.navigate(['/dataset-profiles']); this.router.navigate(['/dataset-profiles']);
}); this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-PROFILE-EDITOR.FEEDBACK-MESSAGES.SAVE-SUCCESS'), SnackBarNotificationLevel.Success)
},error=>this.onCallbackError(error));
} }
showUpdateButton() { showUpdateButton() {
return !this.isNew && this.dataModel.status === DatasetProfileEnum.FINALIZED; return !this.isNew && this.dataModel.status === DatasetProfileEnum.FINALIZED;
} }
isStepActive(step: number) { // isStepActive(step: number) {
return this.stepper && this.stepper.selectedIndex === step; // return this.stepper && this.stepper.selectedIndex === step;
} // }
onCallbackSuccess(): void { // onCallbackSuccess(): void {
this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); // this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
this.router.navigate(['/master-items']); // this.router.navigate(['/master-items']);
} // }
onCallbackErrorNewVersion(errorResponse: HttpErrorResponse) { onCallbackErrorNewVersion(errorResponse: HttpErrorResponse) {
this.uiNotificationService.snackBarNotification(errorResponse.error.message, SnackBarNotificationLevel.Error); this.uiNotificationService.snackBarNotification(errorResponse.error.message, SnackBarNotificationLevel.Error);
@ -430,68 +437,70 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
// } // }
} }
printErrors(rootform: FormGroup) {
if (!rootform.valid) {
Object.keys(rootform.controls).forEach(key => {
const errors = rootform.get(key).errors;
if (errors !== null) {
let numbering: string = '';
for (let j = 0; j < this.nestedCount.length; j++) {
numbering += this.nestedCount[j];
if (j < this.nestedIndex) {
numbering += '.';
} else {
break;
}
}
Object.keys(errors).forEach(keyError => {
if (typeof errors[keyError] === 'boolean') {
this.errorMessages.push(numbering + ' ' + key + ' is ' + keyError);
} else {
this.errorMessages.push(numbering + ' ' + key + ': ' + keyError + ': ' + JSON.stringify(errors[keyError]));
}
});
} else {
if (rootform.get(key) instanceof FormGroup) {
this.printErrors(<FormGroup>rootform.get(key));
} else if (rootform.get(key) instanceof FormArray) {
this.nestedIndex++;
this.nestedCount[this.nestedIndex] = 0;
for (let childForm of (<FormArray>rootform.get(key)).controls) {
this.nestedCount[this.nestedIndex]++;
this.printErrors(<any>childForm);
}
this.nestedCount[this.nestedIndex] = 0;
this.nestedIndex--;
} //BEFORE REDESIGN
} // printErrors(rootform: FormGroup) {
}); // if (!rootform.valid) {
} // Object.keys(rootform.controls).forEach(key => {
} // const errors = rootform.get(key).errors;
// if (errors !== null) {
// let numbering: string = '';
// for (let j = 0; j < this.nestedCount.length; j++) {
// numbering += this.nestedCount[j];
// if (j < this.nestedIndex) {
// numbering += '.';
// } else {
// break;
// }
// }
// Object.keys(errors).forEach(keyError => {
// if (typeof errors[keyError] === 'boolean') {
// this.errorMessages.push(numbering + ' ' + key + ' is ' + keyError);
// } else {
// this.errorMessages.push(numbering + ' ' + key + ': ' + keyError + ': ' + JSON.stringify(errors[keyError]));
// }
// });
// } else {
// if (rootform.get(key) instanceof FormGroup) {
// this.printErrors(<FormGroup>rootform.get(key));
// } else if (rootform.get(key) instanceof FormArray) {
// this.nestedIndex++;
// this.nestedCount[this.nestedIndex] = 0;
// for (let childForm of (<FormArray>rootform.get(key)).controls) {
// this.nestedCount[this.nestedIndex]++;
// this.printErrors(<any>childForm);
// }
// this.nestedCount[this.nestedIndex] = 0;
// this.nestedIndex--;
private showValidationErrorsDialog(projectOnly?: boolean) { // }
const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { // }
disableClose: true, // });
autoFocus: false, // }
restoreFocus: false, // }
data: {
errorMessages: this.errorMessages, // private showValidationErrorsDialog(projectOnly?: boolean) {
projectOnly: projectOnly // const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, {
}, // disableClose: true,
}); // autoFocus: false,
} // restoreFocus: false,
// data: {
// errorMessages: this.errorMessages,
// projectOnly: projectOnly
// },
// });
// }
links: Link[] = []; // links: Link[] = [];
getLinks(currentLinks: Link[]) { // getLinks(currentLinks: Link[]) {
this.links = currentLinks; // this.links = currentLinks;
} // }
datasetWizardModel: DatasetWizardEditorModel; datasetWizardModel: DatasetWizardEditorModel;
@ -751,7 +760,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
return tocEntryFound? tocEntryFound: null; return tocEntryFound? tocEntryFound: null;
} }
addNewEntry(tce: Foo) { addNewEntry(tce: NewEntryType) {
const parent = tce.parent; const parent = tce.parent;
@ -1514,7 +1523,7 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
} }
isStepCompleted(stepIndex: number){ //TODO NA TO DOUME MIPOS DEN XREIAZETAI isStepCompleted(stepIndex: number){
let stepCompleted = false; let stepCompleted = false;
this.steps.forEach((step,index)=>{ this.steps.forEach((step,index)=>{
@ -1708,41 +1717,6 @@ export class DatasetProfileEditorComponent extends BaseComponent implements OnIn
return fieldsets; return fieldsets;
} }
// private _printToCentriesErrrors(entries: ToCEntry[]){
// if(!entries || !entries.length) return;
// entries.forEach(e=>{
// // if(e.form instanceof FormGroup) console.log('is Formgroup');
// // if(e.form instanceof FormControl) console.log('is formcontrols');
// // if(e.form instanceof FormArray) console.log('isForm array');
// const form = e.form as FormGroup;
// if(form.invalid){
// const controls = form.controls;
// const keys = Object.keys(controls);
// keys.forEach(key=>{
// const control = controls[key];
// if(control.invalid){
// console.log('control ', key, 'is invalid');
// }
// })
// // console.log('keys,', keys);
// this._printToCentriesErrrors(e.subEntries);
// }
// });
// }
private _getErrors(aControl: AbstractControl):InvalidControl[]{ private _getErrors(aControl: AbstractControl):InvalidControl[]{

View File

@ -21,7 +21,13 @@ export class DialogConfirmationUploadDatasetProfiles {
selectXML(event) { selectXML(event) {
const file: FileList = event.target.files; let file: FileList = null;
if(event.target && event.target.files){
file = event.target.files;
}else if(event.addedFiles && event.addedFiles.length){
file = event.addedFiles;
}
if(!file) return;//no select closed with cancel . no file selected if(!file) return;//no select closed with cancel . no file selected
const size: number = file[0].size; // Get file size. const size: number = file[0].size; // Get file size.
this.sizeError = size > this.maxFileSize; // Checks if file size is valid. this.sizeError = size > this.maxFileSize; // Checks if file size is valid.

View File

@ -217,7 +217,14 @@ export class DatasetProfileListingComponent extends BaseComponent implements OnI
if (data && data.sucsess && data.name != null && data.file != null) { if (data && data.sucsess && data.name != null && data.file != null) {
this.datasetService.uploadFile(data.file, data.name) this.datasetService.uploadFile(data.file, data.name)
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(); .subscribe(_=>{
this.uiNotificationService.snackBarNotification('Template successfully uploaded', SnackBarNotificationLevel.Success);
this.refresh();
},
error=>{
this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error);
}
);
} }
}); });
} }

View File

@ -18,7 +18,7 @@ export enum ToCEntryType {
Field = 3 Field = 3
} }
export interface Foo { export interface NewEntryType {
childType: ToCEntryType, childType: ToCEntryType,
parent: ToCEntry parent: ToCEntry
} }

View File

@ -23,7 +23,7 @@
[ngStyle]="{'font-size' : (parentLink.type == tocEntryType.FieldSet? '.9rem':'1rem')}" [ngStyle]="{'font-size' : (parentLink.type == tocEntryType.FieldSet? '.9rem':'1rem')}"
> --> > -->
<span class="table-label-element" <span class="table-label-element"
[ngClass]="{'table-label-element-active': itemSelected?.id == parentLink?.id, 'text-danger': colorError() ||(!colorError() && !selectedItemInLinks && parentLink?.form.invalid && colorizeInvalid && (itemSelected?.id != parentLink?.id) && !_findTocEntryById(itemSelected?.id, parentLink?.subEntries))}" [ngClass]="{'table-label-element-active': itemSelected?.id == parentLink?.id, 'text-danger': colorError() ||( (parentLink?.subEntriesType === tocEntryType.FieldSet )&& !colorError() && !selectedItemInLinks && parentLink?.form.invalid && colorizeInvalid && (itemSelected?.id != parentLink?.id) && !_findTocEntryById(itemSelected?.id, parentLink?.subEntries))}"
(click)="itemClicked(parentLink)" (click)="itemClicked(parentLink)"
[ngStyle]="{'font-size' : (parentLink.type == tocEntryType.FieldSet? '.9rem':'1rem')}" [ngStyle]="{'font-size' : (parentLink.type == tocEntryType.FieldSet? '.9rem':'1rem')}"
[id]="'TABLE_ENTRY'+parentLink.id" [id]="'TABLE_ENTRY'+parentLink.id"
@ -122,9 +122,6 @@
(createFooEntry)="createNewEntry($event)" (createFooEntry)="createNewEntry($event)"
[viewOnly]="viewOnly" [viewOnly]="viewOnly"
(dataNeedsRefresh)="onDataNeedsRefresh()" (dataNeedsRefresh)="onDataNeedsRefresh()"
[dropListGroup]="dropListGroup"
[dragHoveringOver]="dragHoveringOver"
[depth]="depth+1"
[DRAGULA_ITEM_ID_PREFIX]="DRAGULA_ITEM_ID_PREFIX" [DRAGULA_ITEM_ID_PREFIX]="DRAGULA_ITEM_ID_PREFIX"
[overContainerId]="overContainerId" [overContainerId]="overContainerId"
[isDragging]="isDragging" [isDragging]="isDragging"
@ -161,7 +158,6 @@
</ng-container> </ng-container>
</button> </button>
<!-- <button (click)="showDroplists()">show droplist</button> -->
</ng-container> </ng-container>
<!-- </div> --> <!-- </div> -->
</ng-container> </ng-container>

View File

@ -1,88 +1,52 @@
.docs-toc-container { // .docs-toc-container {
width: 100%; // width: 100%;
padding: 5px 0 10px 0px; // padding: 5px 0 10px 0px;
// cursor: pointer; // // cursor: pointer;
// border-left: solid 4px #0c7489; // // border-left: solid 4px #0c7489;
.scroll-container { // .scroll-container {
overflow-y: auto; // overflow-y: auto;
// calc(100vh - 250px) // // calc(100vh - 250px)
// height: calc(100vh - 250px); // // height: calc(100vh - 250px);
} // }
.docs-link { // .docs-link {
color: rgba(0, 0, 0, 0.54); // color: rgba(0, 0, 0, 0.54);
// color: mat-color($app-blue-theme-foreground, secondary-text); // // color: mat-color($app-blue-theme-foreground, secondary-text);
transition: color 100ms; // transition: color 100ms;
&:hover, // &:hover,
&.docs-active { // &.docs-active {
.link-name { // .link-name {
background-color: #ececec; // background-color: #ececec;
border-radius: 6px; // border-radius: 6px;
cursor: pointer;; // cursor: pointer;;
// color: #0c7489; // // color: #0c7489;
} // }
// color: mat-color($primary, if($is-dark-theme, 200, default)); // // color: mat-color($primary, if($is-dark-theme, 200, default));
} // }
}
}
.docs-toc-heading {
margin: 0;
padding: 0;
font-size: 13px;
font-weight: bold;
}
// span {
// line-height: 16px;
// margin: 6px 0 0;
// position: relative;
// text-decoration: none;
// display: block;
// overflow: hidden;
// color: #21212194;
// font-weight: 400;
// max-width: 290px;
// min-width: 290px;
// padding: 0rem .4rem;
// span {
// white-space: nowrap;
// overflow: hidden;
// text-overflow: ellipsis;
// display: inline-block;
// width: 100%;
// } // }
// } // }
.selected { // .docs-toc-heading {
color: #212121 !important; // margin: 0;
font-weight: 700 !important; // padding: 0;
opacity: 1 !important; // font-size: 13px;
} // font-weight: bold;
// .docs-level-mat-expansion-panel {
// margin-left: 12px;
// } // }
.docs-level-h5 { // .table-item-actions{
margin-left: 24px; // // display: none;
} // display: inline-block;
// visibility: hidden;
// }
// .table-item:hover {
.table-item-actions{ // .table-item-actions{
// display: none; // // display: inline-block;
display: inline-block; // visibility: visible;
visibility: hidden; // }
} // }
.table-item:hover {
.table-item-actions{
// display: inline-block;
visibility: visible;
}
}
// .table-item col{ // .table-item col{
// text-overflow: ellipsis; // text-overflow: ellipsis;
@ -117,49 +81,6 @@
overflow: hidden; overflow: hidden;
} }
.link-box {
padding: 20px 10px;
border-bottom: solid 1px #ccc;
color: rgba(0, 0, 0, 0.87);
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
cursor: move;
background: white;
font-size: 14px;
}
.cdk-drag-preview {
background-color: #FFF;
box-sizing: border-box;
border-radius: 4px;
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12);
.add-new-entry{
display: none;
}
}
.cdk-drag-placeholder {
opacity: 0;
// background-color: black;
}
.cdk-drag-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.link-box:last-child {
border: none;
}
.cdk-link-list.cdk-drop-list-dragging .link-box:not(.cdk-drag-placeholder) {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
$blue-color : #129D99; $blue-color : #129D99;

View File

@ -3,7 +3,7 @@ import { DOCUMENT } from '@angular/common';
import { Component, EventEmitter, Inject, Input, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'; import { Component, EventEmitter, Inject, Input, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms'; import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { Foo, ToCEntry, ToCEntryType } from '../table-of-contents-entry'; import { NewEntryType, ToCEntry, ToCEntryType } from '../table-of-contents-entry';
@Component({ @Component({
selector: 'app-dataset-profile-table-of-contents-internal-section', selector: 'app-dataset-profile-table-of-contents-internal-section',
@ -14,10 +14,9 @@ export class DatasetProfileTableOfContentsInternalSection extends BaseComponent
@Input() links: ToCEntry[]; @Input() links: ToCEntry[];
@Output() itemClick = new EventEmitter<ToCEntry>(); @Output() itemClick = new EventEmitter<ToCEntry>();
@Output() newEntry = new EventEmitter<ToCEntry>();
@Output() removeEntry = new EventEmitter<ToCEntry>(); @Output() removeEntry = new EventEmitter<ToCEntry>();
@Output() createFooEntry = new EventEmitter<Foo>(); @Output() createFooEntry = new EventEmitter<NewEntryType>();
@Output() dataNeedsRefresh = new EventEmitter<void>(); @Output() dataNeedsRefresh = new EventEmitter<void>();
@ -35,10 +34,10 @@ export class DatasetProfileTableOfContentsInternalSection extends BaseComponent
@Input() viewOnly: boolean; @Input() viewOnly: boolean;
// @Input() dropListGroup: Set<string> = new Set<string>(); // @Input() dropListGroup: Set<string> = new Set<string>();
@Input() dropListGroup: string[]; // @Input() dropListGroup: string[];
@Input() dragHoveringOver: boolean = false; // @Input() dragHoveringOver: boolean = false;
@Input() depth: number = 0; // @Input() depth: number = 0;
// @Input() dropListStruct: { id: string, depth: number}[] = []; // @Input() dropListStruct: { id: string, depth: number}[] = [];
@ -49,60 +48,25 @@ export class DatasetProfileTableOfContentsInternalSection extends BaseComponent
tocEntryType = ToCEntryType; tocEntryType = ToCEntryType;
// showStructs(){
// console.log(this.dropListStruct.sort(this.compareFn)); // compareFn(a, b){
// if(a.depth> b.depth) return -1;
// if(a.depth< b.depth) return 1;
// return 0;
// } // }
// get orderedListGroup(){
// return this.dropListStruct.sort(this.compareFn).map(element=> element.id);
// }
compareFn(a, b){
if(a.depth> b.depth) return -1;
if(a.depth< b.depth) return 1;
return 0;
}
ngOnInit(): void { ngOnInit(): void {
// if(this.parentLink.id && this.dropListGroup){
// if(!this.dropListGroup.includes(this.parentLink.id)){
// this.dropListGroup.unshift(this.parentLink.id);//TODO
// }
// }
// this.dropListStruct.push({
// id: this.parentLink.id,
// depth: this.depth
// });
// if(this.links){
// this.links.forEach(link=>{
// this.dropListGroup.push(link.id);
// })
// }
// this.dropListGroup.add(this.parentLink.id)
} }
showDroplists(){ // hoveroverEnter(){
console.log(this.dropListGroup); // // console.log('user hovering drag over', this.parentLink.id, this.parentLink.label);
} // this.dragHoveringOver = true;
// }
// hoveroverLeft(){
// this.dragHoveringOver = false;
// }
hoveroverEnter(){
// console.log('user hovering drag over', this.parentLink.id, this.parentLink.label);
this.dragHoveringOver = true;
}
hoveroverLeft(){
this.dragHoveringOver = false;
}
fellowContainers(){
return this.dropListGroup.filter(dl=> dl != this.parentLink.id);
}
ngOnChanges(changes: SimpleChanges) { ngOnChanges(changes: SimpleChanges) {
} }
@ -119,30 +83,30 @@ export class DatasetProfileTableOfContentsInternalSection extends BaseComponent
this.removeEntry.emit(currentLink); this.removeEntry.emit(currentLink);
} }
createNewEntry(foo: Foo){ createNewEntry(foo: NewEntryType){
this.createFooEntry.emit(foo); this.createFooEntry.emit(foo);
} }
tocEntryIsChildOf(testingChild: ToCEntry,parent: ToCEntry): boolean{ // tocEntryIsChildOf(testingChild: ToCEntry,parent: ToCEntry): boolean{
if(!testingChild || !parent) return false; // if(!testingChild || !parent) return false;
if(testingChild.id == parent.id){return true;} // if(testingChild.id == parent.id){return true;}
if(parent.subEntries){ // if(parent.subEntries){
let childFound:boolean = false; // let childFound:boolean = false;
parent.subEntries.forEach(subEntry=>{ // parent.subEntries.forEach(subEntry=>{
if(this.tocEntryIsChildOf(testingChild, subEntry)){ // if(this.tocEntryIsChildOf(testingChild, subEntry)){
childFound = true; // childFound = true;
return true; // return true;
} // }
}) // })
return childFound; // return childFound;
} // }
return false; // return false;
} // }
get selectedItemInLinks(){ get selectedItemInLinks(){
if(!this.links || !this.itemSelected) return false; if(!this.links || !this.itemSelected) return false;
@ -158,59 +122,59 @@ export class DatasetProfileTableOfContentsInternalSection extends BaseComponent
// return this.dropListGroup; // return this.dropListGroup;
// } // }
drop(event: CdkDragDrop<string[]>) { // drop(event: CdkDragDrop<string[]>) {
// if(!this.links || !this.links.length) return; // // if(!this.links || !this.links.length) return;
if(event.container === event.previousContainer){ // if(event.container === event.previousContainer){
moveItemInArray(this.links, event.previousIndex, event.currentIndex); // moveItemInArray(this.links, event.previousIndex, event.currentIndex);
let arrayToUpdate: FormArray = this.links[0].form.parent as FormArray; // let arrayToUpdate: FormArray = this.links[0].form.parent as FormArray;
// if(this.parentLink && this.parentLink.form){ // // if(this.parentLink && this.parentLink.form){
// switch(this.parentLink.subEntriesType){ // // switch(this.parentLink.subEntriesType){
// case this.tocEntryType.Field: // // case this.tocEntryType.Field:
// arrayToUpdate = (this.parentLink.form.get('fields') as FormArray); // // arrayToUpdate = (this.parentLink.form.get('fields') as FormArray);
// break; // // break;
// case this.tocEntryType.FieldSet: // // case this.tocEntryType.FieldSet:
// arrayToUpdate = (this.parentLink.form.get('fieldSets') as FormArray); // // arrayToUpdate = (this.parentLink.form.get('fieldSets') as FormArray);
// break; // // break;
// case this.tocEntryType.Section: // // case this.tocEntryType.Section:
// arrayToUpdate = (this.parentLink.form.get('sections') as FormArray); // // arrayToUpdate = (this.parentLink.form.get('sections') as FormArray);
// break // // break
// } // // }
// } // // }
if(arrayToUpdate.controls){ // if(arrayToUpdate.controls){
moveItemInArray(arrayToUpdate.controls, event.previousIndex, event.currentIndex); // moveItemInArray(arrayToUpdate.controls, event.previousIndex, event.currentIndex);
//update ordinality // //update ordinality
arrayToUpdate.controls.forEach((element,idx ) => { // arrayToUpdate.controls.forEach((element,idx ) => {
element.get('ordinal').setValue(idx); // element.get('ordinal').setValue(idx);
element.updateValueAndValidity(); // element.updateValueAndValidity();
}); // });
} // }
this.dataNeedsRefresh.emit(); // this.dataNeedsRefresh.emit();
}else{ // }else{
console.log('not same container'); // console.log('not same container');
} // }
console.log(event.container.id); // console.log(event.container.id);
} // }
onDataNeedsRefresh(){ onDataNeedsRefresh(){
this.dataNeedsRefresh.emit(); this.dataNeedsRefresh.emit();
} }
get hoveringOverParent(){ // get hoveringOverParent(){
if(!this.overContainerId) return false; // if(!this.overContainerId) return false;
const child = this._findTocEntryById(this.overContainerId, this.parentLink.subEntries); // const child = this._findTocEntryById(this.overContainerId, this.parentLink.subEntries);
if(!child) return false; // if(!child) return false;
return true; // return true;
} // }
private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{ public _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{
if(!tocentries){ if(!tocentries){
return null; return null;
} }

View File

@ -1,16 +1,14 @@
<div class=""> <div>
<h3 id="guide-steps">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.TEMPLATE-OUTLINE' | translate}}</h3> <h3 id="guide-steps">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.TEMPLATE-OUTLINE' | translate}}</h3>
<div class="scroll-container" id="tocentrytable"> <div class="scroll-container" id="tocentrytable">
<app-dataset-profile-table-of-contents-internal-section [links]="links" (itemClick)="itemClicked($event)" <app-dataset-profile-table-of-contents-internal-section [links]="links" (itemClick)="itemClicked($event)"
(newEntry)="addNewEntry($event)" (removeEntry)="deleteEntry($event)" (removeEntry)="deleteEntry($event)"
(createFooEntry)="createNewEntry($event)" (createFooEntry)="createNewEntry($event)"
[parentLink]="{ subEntriesType: tocEntryType.Page, subEntries : links , id: ROOT_ID}" [parentLink]="{ subEntriesType: tocEntryType.Page, subEntries : links , id: ROOT_ID}"
[itemSelected]="itemSelected" [itemSelected]="itemSelected"
[viewOnly]="viewOnly" [viewOnly]="viewOnly"
(dataNeedsRefresh)="onDataNeedsRefresh()" (dataNeedsRefresh)="onDataNeedsRefresh()"
[dropListGroup]="[]"
[DRAGULA_ITEM_ID_PREFIX]="DRAGULA_ITEM_ID_PREFIX" [DRAGULA_ITEM_ID_PREFIX]="DRAGULA_ITEM_ID_PREFIX"
[overContainerId]="overcontainer" [overContainerId]="overcontainer"
[isDragging]="isDragging" [isDragging]="isDragging"

View File

@ -1,33 +1,3 @@
.docs-toc-container {
width: 100%;
padding: 5px 0 10px 0px;
// cursor: pointer;
// border-left: solid 4px #0c7489;
.scroll-container {
// overflow-y: auto;
max-height: 60vh;
overflow-y: scroll;
// calc(100vh - 250px)
// height: calc(100vh - 250px);
}
.docs-link {
color: rgba(0, 0, 0, 0.54);
// color: mat-color($app-blue-theme-foreground, secondary-text);
transition: color 100ms;
&:hover,
&.docs-active {
.link-name {
background-color: #ececec;
border-radius: 6px;
// color: #0c7489;
}
// color: mat-color($primary, if($is-dark-theme, 200, default));
}
}
}
.scroll-container { .scroll-container {
// overflow-y: auto; // overflow-y: auto;
@ -35,82 +5,32 @@
overflow-y: scroll; overflow-y: scroll;
padding-left: .2em; padding-left: .2em;
padding-right: 1em; padding-right: 1em;
// padding-right: 0em 1em;
// calc(100vh - 250px)
// height: calc(100vh - 250px);
} }
.docs-toc-heading { // #style-6::-webkit-scrollbar-track
margin: 0; // {
padding: 0; // -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
font-size: 13px; // background-color: #F5F5F5;
font-weight: bold;
}
span {
line-height: 16px;
margin: 6px 0 0;
position: relative;
text-decoration: none;
display: block;
overflow: hidden;
color: #21212194;
font-weight: 400;
max-width: 290px;
min-width: 290px;
padding: 0rem .4rem;
span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
width: 100%;
}
}
.selected {
color: #212121 !important;
font-weight: 700 !important;
opacity: 1 !important;
}
// .docs-level-mat-expansion-panel {
// margin-left: 12px;
// } // }
.docs-level-h5 { // #style-6::-webkit-scrollbar
margin-left: 24px; // {
} // width: 6px;
// background-color: #F5F5F5;
#style-6::-webkit-scrollbar-track // }
{
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
background-color: #F5F5F5;
}
#style-6::-webkit-scrollbar
{
width: 6px;
background-color: #F5F5F5;
}
#style-6::-webkit-scrollbar-thumb
{
background-color: rgb(162, 163, 163);
background-image: -webkit-linear-gradient(45deg,
rgba(255, 255, 255, .2) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, .2) 50%,
rgba(255, 255, 255, .2) 75%,
transparent 75%,
transparent)
}
// #style-6::-webkit-scrollbar-thumb
// {
// background-color: rgb(162, 163, 163);
// background-image: -webkit-linear-gradient(45deg,
// rgba(255, 255, 255, .2) 25%,
// transparent 25%,
// transparent 50%,
// rgba(255, 255, 255, .2) 50%,
// rgba(255, 255, 255, .2) 75%,
// transparent 75%,
// transparent)
// }
#tocentrytable::-webkit-scrollbar-track #tocentrytable::-webkit-scrollbar-track

View File

@ -5,29 +5,13 @@ import { interval, Subject, Subscription } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators'; import { distinctUntilChanged } from 'rxjs/operators';
import { type } from 'os'; import { type } from 'os';
import { SimpleChanges } from '@angular/core'; import { SimpleChanges } from '@angular/core';
import { Foo, TableUpdateInfo, ToCEntry, ToCEntryType } from './table-of-contents-entry'; import { NewEntryType, TableUpdateInfo, ToCEntry, ToCEntryType } from './table-of-contents-entry';
import { DragulaService } from 'ng2-dragula'; import { DragulaService } from 'ng2-dragula';
import { FormArray } from '@angular/forms'; import { FormArray } from '@angular/forms';
import { MatSnackBar, MatSnackBarConfig } from '@angular/material'; import { MatSnackBar, MatSnackBarConfig } from '@angular/material';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { ContentObserver } from '@angular/cdk/observers'; import { ContentObserver } from '@angular/cdk/observers';
// export interface Link {
// /* id of the section*/
// id: string;
// /* header type h3/h4 */
// type: string;
// /* If the anchor is in view of the page */
// active: boolean;
// /* name of the anchor */
// name: string;
// /* top offset px of the anchor */
// top: number;
// page: number;
// section: number;
// show: boolean;
// selected: boolean;
// }
@Component({ @Component({
selector: 'dataset-profile-table-of-contents', selector: 'dataset-profile-table-of-contents',
@ -37,41 +21,26 @@ import { ContentObserver } from '@angular/cdk/observers';
export class DatasetProfileTableOfContents extends BaseComponent implements OnInit { export class DatasetProfileTableOfContents extends BaseComponent implements OnInit {
@Input() links: ToCEntry[]; @Input() links: ToCEntry[];
@Output() itemClick = new EventEmitter<ToCEntry>();
@Output() newEntry = new EventEmitter<ToCEntry>();
@Output() removeEntry = new EventEmitter<ToCEntry>();
@Output() createEntry = new EventEmitter<Foo>();//TODO
@Output() dataNeedsRefresh = new EventEmitter<TableUpdateInfo>();
@Input() itemSelected: ToCEntry; @Input() itemSelected: ToCEntry;
@Input() colorizeInvalid: boolean = false; @Input() colorizeInvalid: boolean = false;
// @Input() set itemSelected(entry:ToCEntry){
// this._itemSelected = entry;
// };
// get itemSelected():ToCEntry{
// return this._itemSelected;
// }
// private _itemSelected:ToCEntry;
@Input() viewOnly: boolean; @Input() viewOnly: boolean;
show: boolean = false;
@Output() itemClick = new EventEmitter<ToCEntry>();
// @Output() newEntry = new EventEmitter<ToCEntry>();
@Output() removeEntry = new EventEmitter<ToCEntry>();
@Output() createEntry = new EventEmitter<NewEntryType>();
@Output() dataNeedsRefresh = new EventEmitter<TableUpdateInfo>();
isDragging: boolean = false; isDragging: boolean = false;
draggingItemId: string = null; draggingItemId: string = null;
tocEntryType = ToCEntryType; tocEntryType = ToCEntryType;
DRAGULA_ITEM_ID_PREFIX="table_item_id_"; DRAGULA_ITEM_ID_PREFIX="table_item_id_";
ROOT_ID: string = "ROOT_ID";//no special meaning ROOT_ID: string = "ROOT_ID";//no special meaning
private _dragStartedAt; private _dragStartedAt;
private VALID_DROP_TIME = 500;//ms private VALID_DROP_TIME = 500;//ms
overcontainer: string = null;
constructor( constructor(
@Inject(DOCUMENT) private _document: Document, @Inject(DOCUMENT) private _document: Document,
@ -80,8 +49,6 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
private language: TranslateService private language: TranslateService
) { ) {
super(); super();
if(this.dragulaService.find('TABLEDRAG')){ if(this.dragulaService.find('TABLEDRAG')){
this.dragulaService.destroy('TABLEDRAG'); this.dragulaService.destroy('TABLEDRAG');
@ -456,7 +423,7 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
drake.on('drag',(el,source)=>{ drake.on('drag',(el,source)=>{
this._dragStartedAt = new Date().getTime(); this._dragStartedAt = new Date().getTime();
console.log('drag fired'); // console.log('drag fired');
this.isDragging = true; this.isDragging = true;
this.draggingItemId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX, ''); this.draggingItemId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX, '');
@ -484,10 +451,6 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
} }
overcontainer: string = null;
private _scrollIntoDragginItem(id: string){ private _scrollIntoDragginItem(id: string){
// const table = document.getElementById('tocentrytable'); // const table = document.getElementById('tocentrytable');
@ -561,23 +524,15 @@ export class DatasetProfileTableOfContents extends BaseComponent implements OnIn
this.itemClick.emit(item); this.itemClick.emit(item);
} }
// propagateClickToParent(childIds:ToCEntry[], currentItem: ToCEntry){ // addNewEntry(tce: ToCEntry){
// childIds.push(currentItem); // this.newEntry.emit(tce);
// this.itemClick.emit(childIds);
// } // }
addNewEntry(tce: ToCEntry){
this.newEntry.emit(tce);
}
deleteEntry(currentLink: ToCEntry){ deleteEntry(currentLink: ToCEntry){
this.removeEntry.emit(currentLink); this.removeEntry.emit(currentLink);
} }
createNewEntry(newEntry: NewEntryType){
this.createEntry.emit(newEntry);
createNewEntry(foo: Foo){
this.createEntry.emit(foo);
} }
onDataNeedsRefresh(){ onDataNeedsRefresh(){
this.dataNeedsRefresh.emit(); this.dataNeedsRefresh.emit();

View File

@ -335,8 +335,8 @@ export class FormFieldComponent extends BaseComponent implements OnInit {
this.multipleAutoCompleteConfiguration = { this.multipleAutoCompleteConfiguration = {
filterFn: myfunc.bind(this), filterFn: myfunc.bind(this),
initialItems: (extraData) => myfunc(''), initialItems: (extraData) => myfunc(''),
displayFn: (item) => { try{return typeof (item) == 'string' ? JSON.parse(item)['label'] : item['label']}catch{return''}}, displayFn: (item) => { try{return typeof (item) == 'string' ? JSON.parse(item)[title] : item[title]}catch{return''}},
titleFn: (item) => { try{return typeof (item) == 'string' ? JSON.parse(item)['label'] : item['label']}catch{return''}}, titleFn: (item) => { try{return typeof (item) == 'string' ? JSON.parse(item)[title] : item[title]}catch{return''}},
valueAssign: (item) => { try{return typeof (item) == 'string' ? item : JSON.stringify(item)}catch{return''}}, valueAssign: (item) => { try{return typeof (item) == 'string' ? item : JSON.stringify(item)}catch{return''}},
subtitleFn: (item) => { try{return item[subtitle]}catch{return''}} subtitleFn: (item) => { try{return item[subtitle]}catch{return''}}
} }

View File

@ -520,6 +520,9 @@
"MULTIPLICITY": "Multiplicity", "MULTIPLICITY": "Multiplicity",
"MORE": "More.." "MORE": "More.."
} }
},
"FEEDBACK-MESSAGES":{
"SAVE-SUCCESS":"Changes were saved successfully."
} }
}, },
"GRANT-LISTING": { "GRANT-LISTING": {

View File

@ -520,6 +520,9 @@
"MULTIPLICITY": "Multiplicity", "MULTIPLICITY": "Multiplicity",
"MORE": "More.." "MORE": "More.."
} }
},
"FEEDBACK-MESSAGES":{
"SAVE-SUCCESS":"Changes were saved successfully."
} }
}, },
"GRANT-LISTING": { "GRANT-LISTING": {

View File

@ -520,6 +520,9 @@
"MULTIPLICITY": "Multiplicity", "MULTIPLICITY": "Multiplicity",
"MORE": "More.." "MORE": "More.."
} }
},
"FEEDBACK-MESSAGES":{
"SAVE-SUCCESS":"Changes were saved successfully."
} }
}, },
"GRANT-LISTING": { "GRANT-LISTING": {

View File

@ -520,6 +520,9 @@
"MULTIPLICITY": "Multiplicity", "MULTIPLICITY": "Multiplicity",
"MORE": "More.." "MORE": "More.."
} }
},
"FEEDBACK-MESSAGES":{
"SAVE-SUCCESS":"Changes were saved successfully."
} }
}, },
"GRANT-LISTING": { "GRANT-LISTING": {

View File

@ -520,6 +520,9 @@
"MULTIPLICITY": "Multiplicity", "MULTIPLICITY": "Multiplicity",
"MORE": "More.." "MORE": "More.."
} }
},
"FEEDBACK-MESSAGES":{
"SAVE-SUCCESS":"Changes were saved successfully."
} }
}, },
"GRANT-LISTING": { "GRANT-LISTING": {

View File

@ -520,6 +520,9 @@
"MULTIPLICITY": "Multiplicity", "MULTIPLICITY": "Multiplicity",
"MORE": "More.." "MORE": "More.."
} }
},
"FEEDBACK-MESSAGES":{
"SAVE-SUCCESS":"Changes were saved successfully."
} }
}, },
"GRANT-LISTING": { "GRANT-LISTING": {

View File

@ -520,6 +520,9 @@
"MULTIPLICITY": "Multiplicity", "MULTIPLICITY": "Multiplicity",
"MORE": "More.." "MORE": "More.."
} }
},
"FEEDBACK-MESSAGES":{
"SAVE-SUCCESS":"Changes were saved successfully."
} }
}, },
"GRANT-LISTING": { "GRANT-LISTING": {

View File

@ -520,6 +520,9 @@
"MULTIPLICITY": "Multiplicity", "MULTIPLICITY": "Multiplicity",
"MORE": "More.." "MORE": "More.."
} }
},
"FEEDBACK-MESSAGES":{
"SAVE-SUCCESS":"Changes were saved successfully."
} }
}, },
"GRANT-LISTING": { "GRANT-LISTING": {