Commit 2cd3a349 authored by Alexander Philipp Nowosad's avatar Alexander Philipp Nowosad
Browse files

Add list wrapper

parent 4f5668f5
......@@ -17,44 +17,43 @@
Create Domains to use them for knowledge elements
</div>
<div class="my-3 p-3 bg-white rounded shadow-sm">
<h6 class="border-bottom border-gray pb-2">Domains</h6>
<div *ngIf="!domains">Loading...</div>
<div *ngIf="domains && domains.length === 0">No domains defined.</div>
<div *ngIf="domains && domains.length > 0">
<ul class="list-group">
<li
class="
d-flex
list-group-item
justify-content-between
align-items-baseline
"
*ngFor="let domain of domains"
>
<div>
<span>{{ domain.name }}</span>
</div>
<div>
<a
[routerLink]="getRouterLink(domain)"
type="button"
class="btn btn-dark btn-xs mr-1"
>
View
</a>
<button
(click)="openDeleteDomainModal(domain)"
type="button"
class="btn btn-danger btn-xs"
>
Delete
</button>
</div>
</li>
</ul>
</div>
</div>
<app-list-wrapper
listTitle="Domains"
[loading]="loading"
[reloading]="reloading"
[noResults]="domains && domains.length === 0"
>
<div noResults>No domains defined.</div>
<ul results class="list-group">
<li
class="
d-flex
list-group-item
justify-content-between
align-items-baseline
"
*ngFor="let domain of domains"
>
<div>{{ domain.name }}</div>
<div>
<a
[routerLink]="getRouterLink(domain)"
type="button"
class="btn btn-dark btn-xs mr-1"
>
View
</a>
<button
(click)="openDeleteDomainModal(domain)"
type="button"
class="btn btn-danger btn-xs"
>
Delete
</button>
</div>
</li>
</ul>
</app-list-wrapper>
<div class="my-3 p-3 bg-white rounded shadow-sm">
<h6 class="border-bottom border-gray pb-2 mb-0">Add Domain</h6>
......
import { Component, OnInit, ViewChild } from '@angular/core';
import { Component, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { DomainService } from '../../development-process-registry/knowledge/domain.service';
import { Domain } from '../../development-process-registry/knowledge/domain';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { ELEMENT_SERVICE, ListService } from '../../shared/list.service';
@Component({
selector: 'app-domains',
templateUrl: './domains.component.html',
styleUrls: ['./domains.component.css'],
providers: [
ListService,
{ provide: ELEMENT_SERVICE, useExisting: DomainService },
],
})
export class DomainsComponent implements OnInit {
domains: Domain[];
export class DomainsComponent {
domainForm: FormGroup = this.fb.group({
name: ['', Validators.required],
});
......@@ -23,19 +26,13 @@ export class DomainsComponent implements OnInit {
deleteDomainModal: any;
constructor(
private domainService: DomainService,
private fb: FormBuilder,
private listService: ListService<Domain>,
private modalService: NgbModal
) {}
ngOnInit() {
this.loadDomains().then();
}
async addDomain() {
await this.domainService.add(this.domainForm.value);
this.domainForm.reset();
await this.loadDomains();
await this.listService.add(this.domainForm.value);
}
openDeleteDomainModal(domain: Domain) {
......@@ -46,15 +43,22 @@ export class DomainsComponent implements OnInit {
}
async deleteDomain(domain: Domain) {
await this.domainService.delete(domain._id);
await this.loadDomains();
}
async loadDomains() {
this.domains = (await this.domainService.getList()).docs;
await this.listService.delete(domain._id);
}
getRouterLink(domain: Domain) {
return ['/', 'domains', 'detail', domain._id];
}
get domains(): Domain[] {
return this.listService.elements;
}
get loading() {
return this.listService.loading;
}
get reloading() {
return this.listService.reloading;
}
}
<div class="my-3 p-3 bg-white rounded shadow-sm">
<div class="d-flex border-bottom border-gray mb-2">
<h6 class="pb-2 mb-0">{{ listTitle }}</h6>
<div
*ngIf="!loading && reloading"
class="spinner-border spinner-border-sm ml-auto"
role="status"
>
<span class="sr-only">Loading...</span>
</div>
</div>
<div *ngIf="loading">
<div class="d-flex justify-content-center">
<div class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
</div>
<div *ngIf="!loading && noResults">
<ng-content select="[noResults]"></ng-content>
</div>
<div *ngIf="!loading && !noResults">
<ng-content select="[results]"></ng-content>
</div>
</div>
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-list-wrapper',
templateUrl: './list-wrapper.component.html',
styleUrls: ['./list-wrapper.component.css'],
})
export class ListWrapperComponent {
@Input() listTitle: string;
@Input() loading: boolean;
@Input() reloading: boolean;
@Input() noResults: boolean;
}
import { Inject, Injectable, InjectionToken } from '@angular/core';
import { PouchdbModel } from '../database/pouchdb-model';
import { ElementService } from '../database/element-service';
export const ELEMENT_SERVICE = new InjectionToken<ElementService<any>>(
'Element service'
);
@Injectable()
export class ListService<T extends PouchdbModel> {
private _elements: T[];
get elements(): T[] {
return this._elements;
}
get loading(): boolean {
return this.elements == null;
}
private _reloading: boolean;
get reloading(): boolean {
return this._reloading;
}
constructor(
@Inject(ELEMENT_SERVICE) private elementService: ElementService<T>
) {
this.load().then();
}
async add(element: Partial<T>) {
this._reloading = true;
await this.elementService.add(element);
await this.load();
}
async delete(elementId: string) {
this._reloading = true;
const elements = this._elements;
await this.elementService.delete(elementId);
// check that no reload happened before updating the local version
if (elements === this._elements) {
this._elements = this._elements.filter(
(element) => element._id !== elementId
);
}
await this.load();
}
private async load() {
this._reloading = true;
this._elements = (await this.elementService.getList()).docs;
this._reloading = false;
}
}
......@@ -11,6 +11,7 @@ import { DomainSelectionFormComponent } from './domain-selection-form/domain-sel
import { DomainsSelectionFormComponent } from './domains-selection-form/domains-selection-form.component';
import { DeleteModalComponent } from './delete-modal/delete-modal.component';
import { SearchComponent } from './search/search.component';
import { ListWrapperComponent } from './list-wrapper/list-wrapper.component';
@NgModule({
declarations: [
......@@ -22,6 +23,7 @@ import { SearchComponent } from './search/search.component';
DomainsSelectionFormComponent,
DeleteModalComponent,
SearchComponent,
ListWrapperComponent,
],
imports: [
CommonModule,
......@@ -42,6 +44,7 @@ import { SearchComponent } from './search/search.component';
FormArrayListComponent,
DomainsSelectionFormComponent,
SearchComponent,
ListWrapperComponent,
],
})
export class SharedModule {}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment