From a659dcecd7115eda1320d9d7188788e1e00ccb18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Fri, 27 Aug 2021 16:51:13 +0300 Subject: [PATCH] Empty states, table updates --- src/index.ts | 1 + src/lib/common-ui.module.ts | 4 ++- src/lib/empty-states/empty-state.module.ts | 15 ++++++++ .../empty-state/empty-state.component.html | 21 +++++++++++ .../empty-state/empty-state.component.scss | 27 ++++++++++++++ .../empty-state/empty-state.component.ts | 26 ++++++++++++++ src/lib/empty-states/index.ts | 2 ++ src/lib/listing/listing.module.ts | 2 ++ .../models/table-column-config.model.ts | 3 +- src/lib/listing/table/table.component.html | 35 ++++++++----------- src/lib/listing/table/table.component.scss | 3 -- src/lib/listing/table/table.component.ts | 33 ++++++++++++++--- 12 files changed, 142 insertions(+), 30 deletions(-) create mode 100644 src/lib/empty-states/empty-state.module.ts create mode 100644 src/lib/empty-states/empty-state/empty-state.component.html create mode 100644 src/lib/empty-states/empty-state/empty-state.component.scss create mode 100644 src/lib/empty-states/empty-state/empty-state.component.ts create mode 100644 src/lib/empty-states/index.ts diff --git a/src/index.ts b/src/index.ts index 4583469..0a56bbd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,3 +12,4 @@ export * from './lib/misc'; export * from './lib/loading'; export * from './lib/error'; export * from './lib/search'; +export * from './lib/empty-states'; diff --git a/src/lib/common-ui.module.ts b/src/lib/common-ui.module.ts index 62a5f66..d255dc3 100644 --- a/src/lib/common-ui.module.ts +++ b/src/lib/common-ui.module.ts @@ -15,6 +15,7 @@ import { IqserHelpModeModule } from './help-mode'; import { IqserIconsModule } from './icons'; import { IqserButtonsModule } from './buttons'; import { IqserScrollbarModule } from './scrollbar'; +import { IqserEmptyStatesModule } from './empty-states'; const matModules = [MatIconModule, MatProgressSpinnerModule]; const modules = [ @@ -25,7 +26,8 @@ const modules = [ IqserFiltersModule, IqserInputsModule, IqserHelpModeModule, - IqserScrollbarModule + IqserScrollbarModule, + IqserEmptyStatesModule ]; const components = [StatusBarComponent, FullPageLoadingIndicatorComponent, FullPageErrorComponent]; const pipes = [SortByPipe, HumanizePipe]; diff --git a/src/lib/empty-states/empty-state.module.ts b/src/lib/empty-states/empty-state.module.ts new file mode 100644 index 0000000..0e352a1 --- /dev/null +++ b/src/lib/empty-states/empty-state.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { IqserIconsModule } from '../icons'; +import { EmptyStateComponent } from './empty-state/empty-state.component'; +import { IqserButtonsModule } from '../buttons'; + +const modules = [IqserIconsModule, IqserButtonsModule]; +const components = [EmptyStateComponent]; + +@NgModule({ + declarations: [...components], + imports: [CommonModule, ...modules], + exports: [...components] +}) +export class IqserEmptyStatesModule {} diff --git a/src/lib/empty-states/empty-state/empty-state.component.html b/src/lib/empty-states/empty-state/empty-state.component.html new file mode 100644 index 0000000..cc9bca5 --- /dev/null +++ b/src/lib/empty-states/empty-state/empty-state.component.html @@ -0,0 +1,21 @@ +
+ +
+ +
+
{{ text }}
+ +
diff --git a/src/lib/empty-states/empty-state/empty-state.component.scss b/src/lib/empty-states/empty-state/empty-state.component.scss new file mode 100644 index 0000000..042e4c1 --- /dev/null +++ b/src/lib/empty-states/empty-state/empty-state.component.scss @@ -0,0 +1,27 @@ +@import '../../../assets/styles/common'; + +.empty-state { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + + > mat-icon { + height: 60px; + width: 60px; + opacity: 0.1; + } + + .heading-l { + color: $grey-7; + } + + > .heading-l, + iqser-icon-button { + margin-top: 24px; + } + + .ng-content-wrapper:not(:empty) + .heading-l { + display: none; + } +} diff --git a/src/lib/empty-states/empty-state/empty-state.component.ts b/src/lib/empty-states/empty-state/empty-state.component.ts new file mode 100644 index 0000000..56a99e1 --- /dev/null +++ b/src/lib/empty-states/empty-state/empty-state.component.ts @@ -0,0 +1,26 @@ +import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { IconButtonTypes } from '../../buttons'; +import { Required } from '../../utils'; + +@Component({ + selector: 'iqser-empty-state', + templateUrl: './empty-state.component.html', + styleUrls: ['./empty-state.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class EmptyStateComponent implements OnInit { + readonly iconButtonTypes = IconButtonTypes; + + @Input() @Required() text!: string; + @Input() icon?: string; + @Input() showButton = true; + @Input() buttonIcon = 'red:plus'; + @Input() buttonLabel?: string; + @Input() horizontalPadding = 100; + @Input() verticalPadding = 120; + @Output() readonly action = new EventEmitter(); + + ngOnInit(): void { + this.showButton = this.showButton && this.action.observers.length > 0; + } +} diff --git a/src/lib/empty-states/index.ts b/src/lib/empty-states/index.ts new file mode 100644 index 0000000..987730b --- /dev/null +++ b/src/lib/empty-states/index.ts @@ -0,0 +1,2 @@ +export * from './empty-state.module'; +export * from './empty-state/empty-state.component'; diff --git a/src/lib/listing/listing.module.ts b/src/lib/listing/listing.module.ts index d6b3cda..6f4172b 100644 --- a/src/lib/listing/listing.module.ts +++ b/src/lib/listing/listing.module.ts @@ -13,6 +13,7 @@ import { ScrollingModule } from '@angular/cdk/scrolling'; import { IqserIconsModule } from '../icons'; import { IqserScrollbarModule } from '../scrollbar'; import { RouterModule } from '@angular/router'; +import { IqserEmptyStatesModule } from '../empty-states'; const matModules = [MatTooltipModule]; const components = [TableHeaderComponent, TableComponent, TableColumnNameComponent, ScrollButtonComponent]; @@ -22,6 +23,7 @@ const modules = [ IqserInputsModule, IqserIconsModule, IqserScrollbarModule, + IqserEmptyStatesModule, ScrollingModule, RouterModule ]; diff --git a/src/lib/listing/models/table-column-config.model.ts b/src/lib/listing/models/table-column-config.model.ts index 2e9d7dc..28bf880 100644 --- a/src/lib/listing/models/table-column-config.model.ts +++ b/src/lib/listing/models/table-column-config.model.ts @@ -9,6 +9,7 @@ export interface TableColumnConfig { readonly rightIcon?: string; readonly rightIconTooltip?: string; readonly notTranslatable?: boolean; - readonly width?: string; // TODO: make required + readonly width?: string; readonly template?: TemplateRef; // TODO: make required + last?: boolean; } diff --git a/src/lib/listing/table/table.component.html b/src/lib/listing/table/table.component.html index c07daff..305879a 100644 --- a/src/lib/listing/table/table.component.html +++ b/src/lib/listing/table/table.component.html @@ -4,22 +4,20 @@ [selectionEnabled]="selectionEnabled" [tableColumnConfigs]="tableColumnConfigs" [tableHeaderLabel]="tableHeaderLabel" -> +> + + - - - - - - - - - + - - - - +
- - - - - -
n
+
-
+
diff --git a/src/lib/listing/table/table.component.scss b/src/lib/listing/table/table.component.scss index 55f6016..9fb63ed 100644 --- a/src/lib/listing/table/table.component.scss +++ b/src/lib/listing/table/table.component.scss @@ -1,6 +1,3 @@ -//iqser-table-header::ng-deep .header-item { -// padding-right: 16px; -//} @import '../../../assets/styles/common'; cdk-virtual-scroll-viewport { diff --git a/src/lib/listing/table/table.component.ts b/src/lib/listing/table/table.component.ts index 8afad4b..1939c36 100644 --- a/src/lib/listing/table/table.component.ts +++ b/src/lib/listing/table/table.component.ts @@ -1,9 +1,22 @@ -import { ChangeDetectionStrategy, Component, forwardRef, Inject, Input, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + forwardRef, + Inject, + Input, + OnInit, + Output, + TemplateRef, + ViewChild +} from '@angular/core'; import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; import { Required } from '../../utils'; import { Listable, TableColumnConfig } from '../models'; import { ListingComponent } from '../listing-component.directive'; +const SCROLLBAR_WIDTH = 11; + @Component({ selector: 'iqser-table', templateUrl: './table.component.html', @@ -13,6 +26,7 @@ import { ListingComponent } from '../listing-component.directive'; export class TableComponent implements OnInit { @Input() bulkActions?: TemplateRef; @Input() actionsTemplate?: TemplateRef; + @Input() headerTemplate?: TemplateRef; @Input() @Required() itemSize!: number; @Input() @Required() tableColumnConfigs!: readonly TableColumnConfig[]; @Input() @Required() tableHeaderLabel!: string; @@ -21,6 +35,12 @@ export class TableComponent implements OnInit { @Input() emptyColumnWidth?: string; @Input() classes?: string; @Input() routerLinkFn?: (entity: T) => string | string[]; + @Input() noDataText?: string; + @Input() noDataIcon?: string; + @Input() noDataButtonLabel?: string; + @Input() showNoDataButton = false; + @Output() readonly noDataAction = new EventEmitter(); + @Input() noMatchText?: string; @ViewChild(CdkVirtualScrollViewport, { static: true }) private readonly _viewport!: CdkVirtualScrollViewport; constructor(@Inject(forwardRef(() => ListingComponent)) private _parent: ListingComponent) {} @@ -30,9 +50,14 @@ export class TableComponent implements OnInit { } ngOnInit(): void { + this._patchConfig(); this._setStyles(); } + private _patchConfig() { + this.tableColumnConfigs[this.tableColumnConfigs.length - 1].last = true; + } + private _setStyles(): void { const element = this._viewport.elementRef.nativeElement; this._setColumnsWidth(element); @@ -46,10 +71,10 @@ export class TableComponent implements OnInit { gridTemplateColumnsHover += 'auto '; } for (const config of this.tableColumnConfigs) { - gridTemplateColumnsHover += `${config.width as string} `; // TODO remove cast + gridTemplateColumnsHover += `${config.width || '1fr'} `; } - gridTemplateColumnsHover += this.emptyColumnWidth; - const gridTemplateColumns = gridTemplateColumnsHover + ' 11px'; + gridTemplateColumnsHover += this.emptyColumnWidth || ''; // TODO: Check if it's always 1fr + const gridTemplateColumns = `${gridTemplateColumnsHover} ${SCROLLBAR_WIDTH}px`; element.style.setProperty('--gridTemplateColumns', gridTemplateColumns); element.style.setProperty('--gridTemplateColumnsHover', gridTemplateColumnsHover);