Merge pull request #15 in ~VLE2FE/definma-ui from development to master
* commit 'c0b410c4830179c6f5dcc41901da4b234134ee8e': fixed material numbers in new dialog fixed new sample material group/supplier autocomplete, template refresh after changes, template array input
This commit is contained in:
commit
c6187da945
@ -8,6 +8,7 @@ import {DocumentationComponent} from './documentation/documentation.component';
|
|||||||
import {TemplatesComponent} from './templates/templates.component';
|
import {TemplatesComponent} from './templates/templates.component';
|
||||||
import {SettingsComponent} from './settings/settings.component';
|
import {SettingsComponent} from './settings/settings.component';
|
||||||
import {UsersComponent} from './users/users.component';
|
import {UsersComponent} from './users/users.component';
|
||||||
|
import {ChangelogComponent} from './changelog/changelog.component';
|
||||||
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
@ -17,6 +18,7 @@ const routes: Routes = [
|
|||||||
{path: 'samples/new', component: SampleComponent, canActivate: [LoginService]},
|
{path: 'samples/new', component: SampleComponent, canActivate: [LoginService]},
|
||||||
{path: 'samples/edit/:id', component: SampleComponent, canActivate: [LoginService]},
|
{path: 'samples/edit/:id', component: SampleComponent, canActivate: [LoginService]},
|
||||||
{path: 'templates', component: TemplatesComponent, canActivate: [LoginService]},
|
{path: 'templates', component: TemplatesComponent, canActivate: [LoginService]},
|
||||||
|
{path: 'changelog', component: ChangelogComponent, canActivate: [LoginService]},
|
||||||
{path: 'users', component: UsersComponent, canActivate: [LoginService]},
|
{path: 'users', component: UsersComponent, canActivate: [LoginService]},
|
||||||
{path: 'settings', component: SettingsComponent, canActivate: [LoginService]},
|
{path: 'settings', component: SettingsComponent, canActivate: [LoginService]},
|
||||||
{path: 'documentation', component: DocumentationComponent},
|
{path: 'documentation', component: DocumentationComponent},
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<a routerLink="/templates" routerLinkActive="active" rbLoadingLink *ngIf="login.isLevel.dev">
|
<a routerLink="/templates" routerLinkActive="active" rbLoadingLink *ngIf="login.isLevel.dev">
|
||||||
Templates
|
Templates
|
||||||
</a>
|
</a>
|
||||||
|
<a routerLink="/changelog" routerLinkActive="active" rbLoadingLink *ngIf="login.isLevel.dev">Changelog</a>
|
||||||
<a routerLink="/users" routerLinkActive="active" rbLoadingLink *ngIf="login.isLevel.admin">Users</a>
|
<a routerLink="/users" routerLinkActive="active" rbLoadingLink *ngIf="login.isLevel.admin">Users</a>
|
||||||
<a routerLink="/documentation" routerLinkActive="active" rbLoadingLink>Documentation</a>
|
<a routerLink="/documentation" routerLinkActive="active" rbLoadingLink>Documentation</a>
|
||||||
</nav>
|
</nav>
|
||||||
@ -32,7 +33,7 @@
|
|||||||
<rb-icon-button icon="mail" mode="primary" (mouseup)="closeBugReport(close)">Send report</rb-icon-button>
|
<rb-icon-button icon="mail" mode="primary" (mouseup)="closeBugReport(close)">Send report</rb-icon-button>
|
||||||
</a>
|
</a>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<!-- <span class="dev-label" *ngIf="devMode">DEVELOPMENT</span>-->
|
<span class="dev-label" *ngIf="devMode">DEVELOPMENT</span>
|
||||||
DeFinMa
|
DeFinMa
|
||||||
</div>
|
</div>
|
||||||
</rb-full-header>
|
</rb-full-header>
|
||||||
|
@ -25,6 +25,7 @@ import { TemplatesComponent } from './templates/templates.component';
|
|||||||
import { ParametersPipe } from './parameters.pipe';
|
import { ParametersPipe } from './parameters.pipe';
|
||||||
import { SettingsComponent } from './settings/settings.component';
|
import { SettingsComponent } from './settings/settings.component';
|
||||||
import { UsersComponent } from './users/users.component';
|
import { UsersComponent } from './users/users.component';
|
||||||
|
import { ChangelogComponent } from './changelog/changelog.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -42,7 +43,8 @@ import { UsersComponent } from './users/users.component';
|
|||||||
TemplatesComponent,
|
TemplatesComponent,
|
||||||
ParametersPipe,
|
ParametersPipe,
|
||||||
SettingsComponent,
|
SettingsComponent,
|
||||||
UsersComponent
|
UsersComponent,
|
||||||
|
ChangelogComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
LocalStorageModule.forRoot({
|
LocalStorageModule.forRoot({
|
||||||
|
35
src/app/changelog/changelog.component.html
Normal file
35
src/app/changelog/changelog.component.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<h2>Changelog</h2>
|
||||||
|
|
||||||
|
<div class="header">
|
||||||
|
<rb-form-date-input name="dateInput" label="older than" [options]="{enableTime: true}"
|
||||||
|
[(ngModel)]="timestamp" (ngModelChange)="loadChangelog()">
|
||||||
|
</rb-form-date-input>
|
||||||
|
|
||||||
|
<rb-form-select name="pageSizeSelection" label="page size" [(ngModel)]="pageSize" (ngModelChange)="loadChangelog()">
|
||||||
|
<option value="3">3</option>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="25">25</option>
|
||||||
|
<option value="50">50</option>
|
||||||
|
<option value="100">100</option>
|
||||||
|
<option value="250">250</option>
|
||||||
|
<option value="500">500</option>
|
||||||
|
</rb-form-select>
|
||||||
|
|
||||||
|
<button class="rb-btn rb-link" type="button" (click)="loadChangelog(1)">
|
||||||
|
next page
|
||||||
|
<span class="rb-ic rb-ic-forward-right"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<rb-table>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Action</th>
|
||||||
|
<th>Data</th>
|
||||||
|
</tr>
|
||||||
|
<tr *ngFor="let entry of changelog">
|
||||||
|
<td>{{entry.date}}</td>
|
||||||
|
<td>{{entry.action}}</td>
|
||||||
|
<td>{{entry.data | json}}</td>
|
||||||
|
</tr>
|
||||||
|
</rb-table>
|
10
src/app/changelog/changelog.component.scss
Normal file
10
src/app/changelog/changelog.component.scss
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
.header {
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
}
|
25
src/app/changelog/changelog.component.spec.ts
Normal file
25
src/app/changelog/changelog.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ChangelogComponent } from './changelog.component';
|
||||||
|
|
||||||
|
describe('ChangelogComponent', () => {
|
||||||
|
let component: ChangelogComponent;
|
||||||
|
let fixture: ComponentFixture<ChangelogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ChangelogComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ChangelogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
32
src/app/changelog/changelog.component.ts
Normal file
32
src/app/changelog/changelog.component.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import {ChangelogModel} from '../models/changelog.model';
|
||||||
|
import {ApiService} from '../services/api.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-changelog',
|
||||||
|
templateUrl: './changelog.component.html',
|
||||||
|
styleUrls: ['./changelog.component.scss']
|
||||||
|
})
|
||||||
|
export class ChangelogComponent implements OnInit {
|
||||||
|
|
||||||
|
timestamp = new Date();
|
||||||
|
pageSize = 25;
|
||||||
|
changelog: ChangelogModel[] = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private api: ApiService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.loadChangelog();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadChangelog(page = 0) {
|
||||||
|
this.api.get<ChangelogModel[]>(`/changelog/${this.timestamp.toISOString()}/${page}/${this.pageSize}`, data => {
|
||||||
|
this.changelog = data.map(e => new ChangelogModel().deserialize(e));
|
||||||
|
this.timestamp = new Date(this.changelog[0].date);
|
||||||
|
console.log(this.changelog);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
7
src/app/models/changelog.model.spec.ts
Normal file
7
src/app/models/changelog.model.spec.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { ChangelogModel } from './changelog.model';
|
||||||
|
|
||||||
|
describe('ChangelogModel', () => {
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(new ChangelogModel()).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
9
src/app/models/changelog.model.ts
Normal file
9
src/app/models/changelog.model.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import {BaseModel} from './base.model';
|
||||||
|
|
||||||
|
export class ChangelogModel extends BaseModel {
|
||||||
|
date: Date;
|
||||||
|
action: string;
|
||||||
|
collection: string;
|
||||||
|
conditions: {[key: string]: any};
|
||||||
|
data: {[key: string]: any};
|
||||||
|
}
|
@ -19,16 +19,17 @@
|
|||||||
<div class="material shaded-container" *ngIf="newMaterial" [@inOut]>
|
<div class="material shaded-container" *ngIf="newMaterial" [@inOut]>
|
||||||
<h4>Material properties</h4>
|
<h4>Material properties</h4>
|
||||||
<rb-form-input name="supplier" label="supplier"
|
<rb-form-input name="supplier" label="supplier"
|
||||||
[rbFormInputAutocomplete]="autocomplete.bind(this, d.arr.materialSupplier)"
|
[rbFormInputAutocomplete]="autocomplete.bind(this, d.arr.materialSuppliers)"
|
||||||
[rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="string" required
|
[rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="string" required
|
||||||
[(ngModel)]="material.supplier" #supplierInput="ngModel"
|
[(ngModel)]="material.supplier" #supplierInput="ngModel"
|
||||||
(focusout)="checkTypo('materialSuppliers', 'supplier', modalWarning)">
|
(focusout)="checkTypo($event, 'materialSuppliers', 'supplier', modalWarning)">
|
||||||
<ng-template rbFormValidationMessage="failure">{{supplierInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{supplierInput.errors.failure}}</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
<rb-form-input name="group" label="group" [rbFormInputAutocomplete]="autocomplete.bind(this, d.arr.materialGroup)"
|
<rb-form-input name="group" label="group"
|
||||||
|
[rbFormInputAutocomplete]="autocomplete.bind(this, d.arr.materialGroups)"
|
||||||
[rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="string" required
|
[rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="string" required
|
||||||
[(ngModel)]="material.group" #groupInput="ngModel"
|
[(ngModel)]="material.group" #groupInput="ngModel"
|
||||||
(focusout)="checkTypo('materialGroups', 'group', modalWarning)">
|
(focusout)="checkTypo($event, 'materialGroups', 'group', modalWarning)">
|
||||||
<ng-template rbFormValidationMessage="failure">{{groupInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{groupInput.errors.failure}}</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
<ng-template #modalWarning>
|
<ng-template #modalWarning>
|
||||||
@ -44,7 +45,7 @@
|
|||||||
</rb-array-input>
|
</rb-array-input>
|
||||||
<rb-form-select name="conditionSelect" label="Type"
|
<rb-form-select name="conditionSelect" label="Type"
|
||||||
[(ngModel)]="material.properties.material_template">
|
[(ngModel)]="material.properties.material_template">
|
||||||
<option *ngFor="let m of d.arr.materialTemplates" [value]="m._id">{{m.name}}</option>
|
<option *ngFor="let m of d.latest.materialTemplates" [value]="m._id">{{m.name}}</option>
|
||||||
</rb-form-select>
|
</rb-form-select>
|
||||||
<rb-form-input *ngFor="let parameter of d.id.materialTemplates[material.properties.material_template].parameters;
|
<rb-form-input *ngFor="let parameter of d.id.materialTemplates[material.properties.material_template].parameters;
|
||||||
index as i" [name]="'materialParameter' + i"
|
index as i" [name]="'materialParameter' + i"
|
||||||
@ -157,7 +158,7 @@
|
|||||||
<div *ngIf="gSample.condition.condition_template" [@inOut]>
|
<div *ngIf="gSample.condition.condition_template" [@inOut]>
|
||||||
<rb-form-select name="conditionSelect" label="Condition"
|
<rb-form-select name="conditionSelect" label="Condition"
|
||||||
[(ngModel)]="gSample.condition.condition_template">
|
[(ngModel)]="gSample.condition.condition_template">
|
||||||
<option *ngFor="let c of d.arr.conditionTemplates" [value]="c._id">{{c.name}}</option>
|
<option *ngFor="let c of d.latest.conditionTemplates" [value]="c._id">{{c.name}}</option>
|
||||||
</rb-form-select>
|
</rb-form-select>
|
||||||
|
|
||||||
<ng-container *ngFor="let parameter of
|
<ng-container *ngFor="let parameter of
|
||||||
@ -186,7 +187,7 @@
|
|||||||
<rb-form-select [name]="'measurementTemplateSelect-' + gIndex + '-' + mIndex" label="Template"
|
<rb-form-select [name]="'measurementTemplateSelect-' + gIndex + '-' + mIndex" label="Template"
|
||||||
[(ngModel)]="measurement.measurement_template"
|
[(ngModel)]="measurement.measurement_template"
|
||||||
(ngModelChange)="clearMeasurement(gIndex, mIndex)">
|
(ngModelChange)="clearMeasurement(gIndex, mIndex)">
|
||||||
<option *ngFor="let m of d.arr.measurementTemplates" [value]="m._id">{{m.name}}</option>
|
<option *ngFor="let m of d.latest.measurementTemplates" [value]="m._id">{{m.name}}</option>
|
||||||
</rb-form-select>
|
</rb-form-select>
|
||||||
|
|
||||||
<div *ngFor="let parameter of d.id.measurementTemplates[measurement.measurement_template].parameters;
|
<div *ngFor="let parameter of d.id.measurementTemplates[measurement.measurement_template].parameters;
|
||||||
|
@ -139,7 +139,7 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
});
|
});
|
||||||
this.d.load('materialTemplates', () => {
|
this.d.load('materialTemplates', () => {
|
||||||
if (!this.material.properties.material_template) {
|
if (!this.material.properties.material_template) {
|
||||||
this.material.properties.material_template = this.d.arr.materialTemplates.filter(e => e.name === 'plastic').reverse()[0]._id;
|
this.material.properties.material_template = this.d.latest.materialTemplates.find(e => e.name === 'plastic')._id;
|
||||||
}
|
}
|
||||||
this.loading--;
|
this.loading--;
|
||||||
});
|
});
|
||||||
@ -270,6 +270,8 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
}
|
}
|
||||||
new Promise<void>(resolve => {
|
new Promise<void>(resolve => {
|
||||||
if (this.newMaterial) { // save material first if new one exists
|
if (this.newMaterial) { // save material first if new one exists
|
||||||
|
console.log(this.material);
|
||||||
|
this.material.numbers = this.material.numbers.filter(e => e !== '');
|
||||||
this.api.post<MaterialModel>('/material/new', this.material.sendFormat(), data => {
|
this.api.post<MaterialModel>('/material/new', this.material.sendFormat(), data => {
|
||||||
this.d.arr.materials.push(data); // add material to data
|
this.d.arr.materials.push(data); // add material to data
|
||||||
this.material = data;
|
this.material = data;
|
||||||
@ -348,7 +350,7 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
else { // no matching material found
|
else { // no matching material found
|
||||||
if (this.sample.material_id !== null) { // reset previous match
|
if (this.sample.material_id !== null) { // reset previous match
|
||||||
this.material = new MaterialModel();
|
this.material = new MaterialModel();
|
||||||
this.material.properties.material_template = this.d.arr.materialTemplates.filter(e => e.name === 'plastic').reverse()[0]._id;
|
this.material.properties.material_template = this.d.latest.materialTemplates.find(e => e.name === 'plastic')._id;
|
||||||
}
|
}
|
||||||
this.sample.material_id = null;
|
this.sample.material_id = null;
|
||||||
}
|
}
|
||||||
@ -376,9 +378,9 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
// add a new measurement for generated sample at index
|
// add a new measurement for generated sample at index
|
||||||
addMeasurement(gIndex) {
|
addMeasurement(gIndex) {
|
||||||
this.generatedSamples[gIndex].measurements.push(
|
this.generatedSamples[gIndex].measurements.push(
|
||||||
new MeasurementModel(this.d.arr.measurementTemplates.filter(e => e.name === 'spectrum').reverse()[0]._id)
|
new MeasurementModel(this.d.latest.measurementTemplates.find(e => e.name === 'spectrum')._id)
|
||||||
);
|
);
|
||||||
this.generatedSamples[gIndex].measurements[this.generatedSamples[gIndex].measurements.length - 1].values.device = this.defaultDevice;
|
console.log(this.d.latest.measurementTemplates.find(e => e.name === 'spectrum'));
|
||||||
if (!this.charts[gIndex]) { // add array if there are no charts yet
|
if (!this.charts[gIndex]) { // add array if there are no charts yet
|
||||||
this.charts[gIndex] = [];
|
this.charts[gIndex] = [];
|
||||||
}
|
}
|
||||||
@ -411,6 +413,8 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
this.addMeasurement(gIndex);
|
this.addMeasurement(gIndex);
|
||||||
index = this.generatedSamples[gIndex].measurements.length - 1;
|
index = this.generatedSamples[gIndex].measurements.length - 1;
|
||||||
}
|
}
|
||||||
|
this.generatedSamples[gIndex].measurements[index].values.device =
|
||||||
|
this.generatedSamples[gIndex].measurements[mIndex].values.device;
|
||||||
this.generatedSamples[gIndex].measurements[index].values.filename = files[i].name;
|
this.generatedSamples[gIndex].measurements[index].values.filename = files[i].name;
|
||||||
this.generatedSamples[gIndex].measurements[index].values[parameter] =
|
this.generatedSamples[gIndex].measurements[index].values[parameter] =
|
||||||
fileReader.result.toString().split('\r\n').map(e => e.split(','));
|
fileReader.result.toString().split('\r\n').map(e => e.split(','));
|
||||||
@ -430,12 +434,15 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
sample.condition.condition_template = null;
|
sample.condition.condition_template = null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sample.condition.condition_template = this.d.arr.conditionTemplates[0]._id;
|
sample.condition.condition_template = this.d.latest.conditionTemplates[0]._id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkTypo(list, mKey, modal: TemplateRef<any>) {
|
checkTypo(event, list, mKey, modal: TemplateRef<any>) {
|
||||||
if (this.d.arr[list].indexOf(this.material[list]) < 0) { // entry is not in list
|
// user did not click on suggestion and entry is not in list
|
||||||
|
if (!(event.relatedTarget && (event.relatedTarget.className.indexOf('rb-dropdown-item') >= 0 ||
|
||||||
|
event.relatedTarget.className.indexOf('close-btn rb-btn rb-passive-link') >= 0)) &&
|
||||||
|
this.d.arr[list].indexOf(this.material[mKey]) < 0) {
|
||||||
this.modalText.list = mKey;
|
this.modalText.list = mKey;
|
||||||
this.modalText.suggestion = this.d.arr[list] // find possible entry from list
|
this.modalText.suggestion = this.d.arr[list] // find possible entry from list
|
||||||
.map(e => ({v: e, s: strCompare.sorensenDice(e, this.material[mKey])}))
|
.map(e => ({v: e, s: strCompare.sorensenDice(e, this.material[mKey])}))
|
||||||
|
@ -15,19 +15,20 @@ export class DataService {
|
|||||||
) { }
|
) { }
|
||||||
|
|
||||||
private collectionMap = {
|
private collectionMap = {
|
||||||
materials: {path: '/materials?status=all', model: MaterialModel, array: true},
|
materials: {path: '/materials?status=all', model: MaterialModel, type: 'array'},
|
||||||
materialSuppliers: {path: '/material/suppliers', model: null, array: true},
|
materialSuppliers: {path: '/material/suppliers', model: null, type: 'array'},
|
||||||
materialGroups: {path: '/material/groups', model: null, array: true},
|
materialGroups: {path: '/material/groups', model: null, type: 'array'},
|
||||||
materialTemplates: {path: '/template/materials', model: TemplateModel, array: true},
|
materialTemplates: {path: '/template/materials', model: TemplateModel, type: 'template'},
|
||||||
measurementTemplates: {path: '/template/measurements', model: TemplateModel, array: true},
|
measurementTemplates: {path: '/template/measurements', model: TemplateModel, type: 'template'},
|
||||||
conditionTemplates: {path: '/template/conditions', model: TemplateModel, array: true},
|
conditionTemplates: {path: '/template/conditions', model: TemplateModel, type: 'template'},
|
||||||
sampleNotesFields: {path: '/sample/notes/fields', model: TemplateModel, array: true},
|
sampleNotesFields: {path: '/sample/notes/fields', model: TemplateModel, type: 'array'},
|
||||||
users: {path: '/users', model: UserModel, array: true},
|
users: {path: '/users', model: UserModel, type: 'array'},
|
||||||
user: {path: '/user', model: UserModel, array: false},
|
user: {path: '/user', model: UserModel, type: 'string'},
|
||||||
userKey: {path: '/user/key', model: BaseModel, array: false}
|
userKey: {path: '/user/key', model: BaseModel, type: 'string'}
|
||||||
};
|
};
|
||||||
|
|
||||||
arr: {[key: string]: any[]} = {}; // array of data
|
arr: {[key: string]: any[]} = {}; // array of data
|
||||||
|
latest: {[key: string]: any[]} = {}; // array of latest template versions
|
||||||
id: {[key: string]: {[id: string]: any}} = {}; // data in format _id: data
|
id: {[key: string]: {[id: string]: any}} = {}; // data in format _id: data
|
||||||
d: {[key: string]: any} = {}; // data not in array format
|
d: {[key: string]: any} = {}; // data not in array format
|
||||||
|
|
||||||
@ -37,10 +38,24 @@ export class DataService {
|
|||||||
}
|
}
|
||||||
else { // load data
|
else { // load data
|
||||||
this.api.get<any>(this.collectionMap[collection].path, data => {
|
this.api.get<any>(this.collectionMap[collection].path, data => {
|
||||||
if (this.collectionMap[collection].array) { // array data
|
if (this.collectionMap[collection].type !== 'string') { // array data
|
||||||
this.arr[collection] = data
|
this.arr[collection] = data
|
||||||
.map(e => this.collectionMap[collection].model ? new this.collectionMap[collection].model().deserialize(e) : e);
|
.map(e => this.collectionMap[collection].model ? new this.collectionMap[collection].model().deserialize(e) : e);
|
||||||
this.idReload(collection);
|
this.idReload(collection);
|
||||||
|
if (this.collectionMap[collection].type === 'template') {
|
||||||
|
const tmpTemplates = {};
|
||||||
|
this.arr[collection].forEach(template => {
|
||||||
|
if (tmpTemplates[template.first_id]) { // already found another version
|
||||||
|
if (template.version > tmpTemplates[template.first_id].version) {
|
||||||
|
tmpTemplates[template.first_id] = template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmpTemplates[template.first_id] = template;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.latest[collection] = Object.values(tmpTemplates);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else { // not array data
|
else { // not array data
|
||||||
this.d[collection] = new this.collectionMap[collection].model().deserialize(data);
|
this.d[collection] = new this.collectionMap[collection].model().deserialize(data);
|
||||||
|
@ -11,6 +11,7 @@ export class LoginService implements CanActivate {
|
|||||||
|
|
||||||
private pathPermissions = [
|
private pathPermissions = [
|
||||||
{path: 'templates', permission: 'dev'},
|
{path: 'templates', permission: 'dev'},
|
||||||
|
{path: 'changelog', permission: 'dev'},
|
||||||
{path: 'users', permission: 'admin'}
|
{path: 'users', permission: 'admin'}
|
||||||
];
|
];
|
||||||
readonly levels = [
|
readonly levels = [
|
||||||
|
@ -122,6 +122,7 @@ export class ValidationService {
|
|||||||
const {ignore, error} = Joi.string()
|
const {ignore, error} = Joi.string()
|
||||||
.max(128)
|
.max(128)
|
||||||
.invalid('condition_template', 'material_template')
|
.invalid('condition_template', 'material_template')
|
||||||
|
.allow('')
|
||||||
.pattern(/^[^.]+$/)
|
.pattern(/^[^.]+$/)
|
||||||
.required()
|
.required()
|
||||||
.messages({'string.pattern.base': 'name must not contain a dot'})
|
.messages({'string.pattern.base': 'name must not contain a dot'})
|
||||||
|
@ -55,7 +55,8 @@
|
|||||||
<rb-icon-button icon="edit" mode="secondary" (click)="group.edit = !group.edit">
|
<rb-icon-button icon="edit" mode="secondary" (click)="group.edit = !group.edit">
|
||||||
Edit template
|
Edit template
|
||||||
</rb-icon-button>
|
</rb-icon-button>
|
||||||
<rb-icon-button icon="save" mode="primary" (click)="saveTemplate(group.first_id)" *ngIf="group.edit">
|
<rb-icon-button icon="save" mode="primary" (click)="saveTemplate(group.first_id)" *ngIf="group.edit"
|
||||||
|
[disabled]="templateForm.invalid">
|
||||||
Save template
|
Save template
|
||||||
</rb-icon-button>
|
</rb-icon-button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -5,6 +5,7 @@ import {animate, style, transition, trigger} from '@angular/animations';
|
|||||||
import {ValidationService} from '../services/validation.service';
|
import {ValidationService} from '../services/validation.service';
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
import cloneDeep from 'lodash/cloneDeep';
|
||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
|
import {DataService} from '../services/data.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-templates',
|
selector: 'app-templates',
|
||||||
@ -36,7 +37,8 @@ export class TemplatesComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private api: ApiService,
|
private api: ApiService,
|
||||||
private validate: ValidationService
|
private validate: ValidationService,
|
||||||
|
public d: DataService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@ -44,8 +46,8 @@ export class TemplatesComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadTemplates() {
|
loadTemplates() {
|
||||||
this.api.get<TemplateModel[]>(`/template/${this.collection}s`, data => {
|
this.d.load(this.collection + 'Templates', () => {
|
||||||
this.templates = data;
|
this.templates = this.d.arr[this.collection + 'Templates'];
|
||||||
this.templateFormat();
|
this.templateFormat();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -99,6 +101,7 @@ export class TemplatesComponent implements OnInit {
|
|||||||
this.templates.push(data);
|
this.templates.push(data);
|
||||||
}
|
}
|
||||||
this.templateFormat();
|
this.templateFormat();
|
||||||
|
this.d.idReload(this.collection + 'Templates');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -107,6 +110,7 @@ export class TemplatesComponent implements OnInit {
|
|||||||
this.templates.push(data);
|
this.templates.push(data);
|
||||||
}
|
}
|
||||||
this.templateFormat();
|
this.templateFormat();
|
||||||
|
this.d.idReload(this.collection + 'Templates');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user