diff options
Diffstat (limited to 'usecaseui-portal/src/app/shared')
9 files changed, 235 insertions, 62 deletions
diff --git a/usecaseui-portal/src/app/shared/components/description-info/description-info.component.html b/usecaseui-portal/src/app/shared/components/description-info/description-info.component.html deleted file mode 100644 index 9575dca1..00000000 --- a/usecaseui-portal/src/app/shared/components/description-info/description-info.component.html +++ /dev/null @@ -1,20 +0,0 @@ -<div *ngFor="let item of data" class="input-wrapper"> - <div class="desc-label"> - <nz-popover> - <div class="text-single-ellipsis text-label" nz-popover> - {{ item.label }} - </div> - <ng-template #nzTemplate> - {{ item.label }} - </ng-template> - </nz-popover> - </div> - <div class="desc-item"> - <nz-popover> - <div class="text-single-ellipsis" nz-popover>{{ item.value }}</div> - <ng-template #nzTemplate> - {{ item.value }} - </ng-template> - </nz-popover> - </div> -</div>
\ No newline at end of file diff --git a/usecaseui-portal/src/app/shared/components/description-info/description-info.component.less b/usecaseui-portal/src/app/shared/components/description-info/description-info.component.less deleted file mode 100644 index 51e22485..00000000 --- a/usecaseui-portal/src/app/shared/components/description-info/description-info.component.less +++ /dev/null @@ -1,24 +0,0 @@ -.input-wrapper { - display: flex; - margin: 20px 0; -} - -.desc-label { - display: inline-block; - width: 30%; - margin-left: 8px; -} -.text-single-ellipsis { - text-overflow: ellipsis; - overflow: hidden; - word-break: break-all; - white-space: nowrap; -} -.text-label::after { - content: ':' -} - -.desc-item { - display: inline-block; - width: 70%; -}
\ No newline at end of file diff --git a/usecaseui-portal/src/app/shared/components/description-info/description-info.component.ts b/usecaseui-portal/src/app/shared/components/description-info/description-info.component.ts deleted file mode 100644 index 26148dce..00000000 --- a/usecaseui-portal/src/app/shared/components/description-info/description-info.component.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Component, EventEmitter, Input, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-description-info', - templateUrl: './description-info.component.html', - styleUrls: ['./description-info.component.less'] -}) -export class DescriptionInfoComponent implements OnInit { - - constructor( - ) { } - @Input() data: Array<any>; - - ngOnInit() { - console.log('data is :', this.data) - } - -}
\ No newline at end of file diff --git a/usecaseui-portal/src/app/shared/components/description/description.component.html b/usecaseui-portal/src/app/shared/components/description/description.component.html new file mode 100644 index 00000000..fb7a188a --- /dev/null +++ b/usecaseui-portal/src/app/shared/components/description/description.component.html @@ -0,0 +1,25 @@ +<div *ngIf="nzTitle" class="descriptions-header"> + <div class="descriptions-title"> + {{ nzTitle }} + </div> +</div> +<div class="descriptions-view"> + <table class="descriptions-table"> + <tbody> + <tr *ngFor="let row of itemMatrix; let i = index" class="descriptions-row"> + <ng-container *ngFor="let item of row; trackBy item; let isLast = last"> + <td class="descriptions-item" [colSpan]="item.span"> + <div class="descriptions-item-container"> + <span class="descriptions-item-label" [class.descriptions-item-no-colon]="!nzColon"> + {{ item.title }} + </span> + <span class="descriptions-item-content"> + <ng-template [ngTemplateOutlet]="item.content"></ng-template> + </span> + </div> + </td> + </ng-container> + </tr> + </tbody> + </table> +</div>
\ No newline at end of file diff --git a/usecaseui-portal/src/app/shared/components/description/description.component.less b/usecaseui-portal/src/app/shared/components/description/description.component.less new file mode 100644 index 00000000..168f4a6a --- /dev/null +++ b/usecaseui-portal/src/app/shared/components/description/description.component.less @@ -0,0 +1,68 @@ +.descriptions-header { + display: flex; + align-items: center; + margin-bottom: 20px; +} + +.descriptions-title { + flex: auto; + overflow: hidden; + color: #000000d9; + font-weight: 700; + font-size: 16px; + line-height: 1.5715; + white-space: nowrap; + text-overflow: ellipsis; +} + +.descriptions-view { + width: 100%; + border-radius: 2px; +} + +.descriptions-table { + width: 100%; + table-layout: fixed; +} + +.descriptions-row>td { + padding-bottom: 16px; +} +.descriptions-item { + padding-bottom: 0; + vertical-align: top; +} + +.descriptions-item-container { + display: flex; +} + +.descriptions-item-container .descriptions-item-label, .descriptions-item-container .descriptions-item-content { + display: inline-flex; + align-items: baseline; +} + +.descriptions-item-label { + color: #000000d9; + font-weight: 400; + font-size: 14px; + line-height: 1.5715; + text-align: start; +} + +.descriptions-item-content { + display: table-cell; + flex: 1; + color: #000000d9; + font-size: 14px; + line-height: 1.5715; + word-break: break-word; + overflow-wrap: break-word; +} + +.descriptions-item-label::after { + content: ":"; + position: relative; + top: -.5px; + margin: 0 8px 0 2px; +}
\ No newline at end of file diff --git a/usecaseui-portal/src/app/shared/components/description/description.component.ts b/usecaseui-portal/src/app/shared/components/description/description.component.ts new file mode 100644 index 00000000..6f3469d9 --- /dev/null +++ b/usecaseui-portal/src/app/shared/components/description/description.component.ts @@ -0,0 +1,79 @@ +import { Component, ContentChildren, EventEmitter, Input, OnDestroy, OnInit, QueryList } from '@angular/core'; +import { Subject } from 'rxjs'; +import { DescriptionItemComponent } from './descriptions-item.component'; +import { DescriptionItemRenderProps } from './description.type'; +@Component({ + selector: 'app-descriptions', + templateUrl: './description.component.html', + styleUrls: ['./description.component.less'], +}) +export class DescriptionComponent implements OnInit, OnDestroy { + @ContentChildren(DescriptionItemComponent) items: QueryList<DescriptionItemComponent>; + + @Input() nzColumn: number = 3; + @Input() nzTitle: string = ''; + @Input() nzColon: boolean = true; + + itemMatrix: DescriptionItemRenderProps[][] = []; + private destroy$ = new Subject<void>(); + constructor() { } + + ngOnInit() { + } + + ngAfterContentInit(): void { + this.prepareMatrix(); + } + + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } + + /** + * Prepare the render matrix according to description items' spans. + */ + private prepareMatrix(): void { + if (!this.items) { + return; + } + + let currentRow: DescriptionItemRenderProps[] = []; + let width = 0; + + const column = this.nzColumn; + const items = this.items.toArray(); + const length = items.length; + const matrix: DescriptionItemRenderProps[][] = []; + const flushRow = (): void => { + matrix.push(currentRow); + currentRow = []; + width = 0; + }; + + for (let i = 0; i < length; i++) { + const item = items[i]; + const { nzTitle: title, content, nzSpan: span } = item; + + width += span; + + if (width >= column) { + if (width > column) { + console.warn(`"nzColumn" is ${column} but we have row length ${width}`); + flushRow(); + } + currentRow.push({ title, content, span }); + flushRow(); + } else if (i === length - 1) { + currentRow.push({ title, content, span: column - (width - span) }); + flushRow(); + } else { + currentRow.push({ title, content, span }); + } + } + + this.itemMatrix = matrix; + } + +}
\ No newline at end of file diff --git a/usecaseui-portal/src/app/shared/components/description/description.type.ts b/usecaseui-portal/src/app/shared/components/description/description.type.ts new file mode 100644 index 00000000..df707f08 --- /dev/null +++ b/usecaseui-portal/src/app/shared/components/description/description.type.ts @@ -0,0 +1,7 @@ +import { TemplateRef } from "@angular/core"; + +export interface DescriptionItemRenderProps { + title: string | TemplateRef<void>; + span: number; + content: TemplateRef<void>; + }
\ No newline at end of file diff --git a/usecaseui-portal/src/app/shared/components/description/descriptions-item.component.ts b/usecaseui-portal/src/app/shared/components/description/descriptions-item.component.ts new file mode 100644 index 00000000..9f168f02 --- /dev/null +++ b/usecaseui-portal/src/app/shared/components/description/descriptions-item.component.ts @@ -0,0 +1,28 @@ + +import { Component, Input, OnInit, TemplateRef, ViewChild, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs'; + +@Component({ + selector: 'app-descriptions-item', + template: ` + <ng-template> + <ng-content></ng-content> + </ng-template> + `, +}) +export class DescriptionItemComponent implements OnDestroy { + @ViewChild(TemplateRef) content: TemplateRef<void>; + @Input() nzSpan: number = 1; + @Input() nzTitle: string = ''; + + readonly inputChange$ = new Subject<void>(); + + ngOnChanges(): void { + this.inputChange$.next(); + } + + ngOnDestroy(): void { + this.inputChange$.complete(); + } + +} diff --git a/usecaseui-portal/src/app/shared/module/sharded.module.ts b/usecaseui-portal/src/app/shared/module/sharded.module.ts new file mode 100644 index 00000000..02fe3849 --- /dev/null +++ b/usecaseui-portal/src/app/shared/module/sharded.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { TranslateModule } from '@ngx-translate/core'; +import { NgZorroAntdModule } from 'ng-zorro-antd'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { HttpClientModule } from '@angular/common/http'; + +@NgModule({ + imports: [ + CommonModule, + TranslateModule, + NgZorroAntdModule, + FormsModule, + ReactiveFormsModule, + HttpClientModule, + ], + declarations: [ + ], + exports: [ + CommonModule, + TranslateModule, + NgZorroAntdModule, + FormsModule, + ReactiveFormsModule, + HttpClientModule, + ] +}) +export class SharedModule { } |