From 1b7104ba14b1e3fae3276fd5f82d098e8a3b90c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Fri, 27 Aug 2021 00:09:37 +0300 Subject: [PATCH 01/11] Table component WIP --- src/assets/icons/arrow-down-o.svg | 18 +++ src/lib/common-ui.module.ts | 4 +- src/lib/icons/icons.module.ts | 1 + src/lib/listing/index.ts | 14 +- .../listing/listing-component.directive.ts | 5 +- src/lib/listing/listing.module.ts | 31 ++++- src/lib/listing/models/index.ts | 2 + .../models/table-column-config.model.ts | 5 +- .../scroll-button.component.html | 7 + .../scroll-button.component.scss | 30 +++++ .../scroll-button/scroll-button.component.ts | 61 +++++++++ .../{ => services}/entities.service.ts | 6 +- src/lib/listing/services/index.ts | 1 + .../{tables => }/sync-width.directive.ts | 0 .../table-column-name.component.html | 0 .../table-column-name.component.scss | 2 +- .../table-column-name.component.ts | 4 +- .../table-header/table-header.component.ts | 5 +- src/lib/listing/table/table.component.html | 52 ++++++++ src/lib/listing/table/table.component.scss | 121 ++++++++++++++++++ src/lib/listing/table/table.component.ts | 66 ++++++++++ src/lib/listing/tables/index.ts | 4 - src/lib/listing/tables/tables-module.ts | 18 --- src/lib/listing/workflow-listing/index.ts | 1 - .../workflow-listing.module.ts | 12 -- src/lib/scrollbar/has-scrollbar.directive.ts | 27 ++++ src/lib/scrollbar/index.ts | 2 + src/lib/scrollbar/scrollbar.module.ts | 13 ++ 28 files changed, 451 insertions(+), 61 deletions(-) create mode 100644 src/assets/icons/arrow-down-o.svg create mode 100644 src/lib/listing/models/index.ts rename src/lib/listing/{tables => }/models/table-column-config.model.ts (57%) create mode 100644 src/lib/listing/scroll-button/scroll-button.component.html create mode 100644 src/lib/listing/scroll-button/scroll-button.component.scss create mode 100644 src/lib/listing/scroll-button/scroll-button.component.ts rename src/lib/listing/{ => services}/entities.service.ts (96%) create mode 100644 src/lib/listing/services/index.ts rename src/lib/listing/{tables => }/sync-width.directive.ts (100%) rename src/lib/listing/{tables => }/table-column-name/table-column-name.component.html (100%) rename src/lib/listing/{tables => }/table-column-name/table-column-name.component.scss (95%) rename src/lib/listing/{tables => }/table-column-name/table-column-name.component.ts (87%) create mode 100644 src/lib/listing/table/table.component.html create mode 100644 src/lib/listing/table/table.component.scss create mode 100644 src/lib/listing/table/table.component.ts delete mode 100644 src/lib/listing/tables/index.ts delete mode 100644 src/lib/listing/tables/tables-module.ts delete mode 100644 src/lib/listing/workflow-listing/index.ts delete mode 100644 src/lib/listing/workflow-listing/workflow-listing.module.ts create mode 100644 src/lib/scrollbar/has-scrollbar.directive.ts create mode 100644 src/lib/scrollbar/index.ts create mode 100644 src/lib/scrollbar/scrollbar.module.ts diff --git a/src/assets/icons/arrow-down-o.svg b/src/assets/icons/arrow-down-o.svg new file mode 100644 index 0000000..384b3c9 --- /dev/null +++ b/src/assets/icons/arrow-down-o.svg @@ -0,0 +1,18 @@ + + + + diff --git a/src/lib/common-ui.module.ts b/src/lib/common-ui.module.ts index 3f025d7..62a5f66 100644 --- a/src/lib/common-ui.module.ts +++ b/src/lib/common-ui.module.ts @@ -14,6 +14,7 @@ import { IqserInputsModule } from './inputs'; import { IqserHelpModeModule } from './help-mode'; import { IqserIconsModule } from './icons'; import { IqserButtonsModule } from './buttons'; +import { IqserScrollbarModule } from './scrollbar'; const matModules = [MatIconModule, MatProgressSpinnerModule]; const modules = [ @@ -23,7 +24,8 @@ const modules = [ IqserListingModule, IqserFiltersModule, IqserInputsModule, - IqserHelpModeModule + IqserHelpModeModule, + IqserScrollbarModule ]; const components = [StatusBarComponent, FullPageLoadingIndicatorComponent, FullPageErrorComponent]; const pipes = [SortByPipe, HumanizePipe]; diff --git a/src/lib/icons/icons.module.ts b/src/lib/icons/icons.module.ts index f49d0d1..bc0aa02 100644 --- a/src/lib/icons/icons.module.ts +++ b/src/lib/icons/icons.module.ts @@ -12,6 +12,7 @@ export class IqserIconsModule { constructor(private readonly _iconRegistry: MatIconRegistry, private readonly _sanitizer: DomSanitizer) { const icons: Set = new Set([ 'arrow-down', + 'arrow-down-o', 'check', 'close', 'edit', diff --git a/src/lib/listing/index.ts b/src/lib/listing/index.ts index 004b4bc..29623f2 100644 --- a/src/lib/listing/index.ts +++ b/src/lib/listing/index.ts @@ -1,8 +1,12 @@ -export * from './tables'; -export * from './workflow-listing'; +export * from './models'; +export * from './services'; + +export * from './scroll-button/scroll-button.component'; +export * from './table/table.component'; +export * from './table-column-name/table-column-name.component'; +export * from './table-header/table-header.component'; + +export * from './sync-width.directive'; export * from './listing.module'; -export * from './entities.service'; export * from './listing-component.directive'; -export * from './table-header/table-header.component'; -export * from './models/listable'; diff --git a/src/lib/listing/listing-component.directive.ts b/src/lib/listing/listing-component.directive.ts index c28a074..9c212f5 100644 --- a/src/lib/listing/listing-component.directive.ts +++ b/src/lib/listing/listing-component.directive.ts @@ -5,9 +5,8 @@ import { FilterService } from '../filtering'; import { SortingOrders, SortingService } from '../sorting'; import { AutoUnsubscribe, Bind, KeysOf } from '../utils'; import { SearchService } from '../search'; -import { TableColumnConfig } from './tables'; -import { EntitiesService } from './entities.service'; -import { Listable } from './models/listable'; +import { EntitiesService } from './services'; +import { Listable, TableColumnConfig } from './models'; export const DefaultListingServices = [FilterService, SearchService, EntitiesService, SortingService] as const; diff --git a/src/lib/listing/listing.module.ts b/src/lib/listing/listing.module.ts index 04b5b05..d6b3cda 100644 --- a/src/lib/listing/listing.module.ts +++ b/src/lib/listing/listing.module.ts @@ -1,18 +1,35 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; -import { TablesModule } from './tables'; import { TableHeaderComponent } from './table-header/table-header.component'; -import { WorkflowListingModule } from './workflow-listing'; import { IqserFiltersModule } from '../filtering'; import { IqserInputsModule } from '../inputs'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { TableColumnNameComponent } from './table-column-name/table-column-name.component'; +import { ScrollButtonComponent } from './scroll-button/scroll-button.component'; +import { TableComponent } from './table/table.component'; +import { SyncWidthDirective } from './sync-width.directive'; +import { ScrollingModule } from '@angular/cdk/scrolling'; +import { IqserIconsModule } from '../icons'; +import { IqserScrollbarModule } from '../scrollbar'; +import { RouterModule } from '@angular/router'; -const components = [TableHeaderComponent]; -const modules = [TranslateModule, TablesModule, WorkflowListingModule, IqserFiltersModule, IqserInputsModule]; +const matModules = [MatTooltipModule]; +const components = [TableHeaderComponent, TableComponent, TableColumnNameComponent, ScrollButtonComponent]; +const modules = [ + TranslateModule, + IqserFiltersModule, + IqserInputsModule, + IqserIconsModule, + IqserScrollbarModule, + ScrollingModule, + RouterModule +]; +const utils = [SyncWidthDirective]; @NgModule({ - declarations: [...components], - exports: [...components, TablesModule, WorkflowListingModule], - imports: [CommonModule, ...modules] + declarations: [...components, ...utils], + exports: [...components, ...utils], + imports: [CommonModule, ...modules, ...matModules] }) export class IqserListingModule {} diff --git a/src/lib/listing/models/index.ts b/src/lib/listing/models/index.ts new file mode 100644 index 0000000..24d6869 --- /dev/null +++ b/src/lib/listing/models/index.ts @@ -0,0 +1,2 @@ +export * from './listable'; +export * from './table-column-config.model'; diff --git a/src/lib/listing/tables/models/table-column-config.model.ts b/src/lib/listing/models/table-column-config.model.ts similarity index 57% rename from src/lib/listing/tables/models/table-column-config.model.ts rename to src/lib/listing/models/table-column-config.model.ts index 997a7cf..2e9d7dc 100644 --- a/src/lib/listing/tables/models/table-column-config.model.ts +++ b/src/lib/listing/models/table-column-config.model.ts @@ -1,4 +1,5 @@ -import { KeysOf } from '../../../utils'; +import { KeysOf } from '../../utils'; +import { TemplateRef } from '@angular/core'; export interface TableColumnConfig { readonly label: string; @@ -8,4 +9,6 @@ export interface TableColumnConfig { readonly rightIcon?: string; readonly rightIconTooltip?: string; readonly notTranslatable?: boolean; + readonly width?: string; // TODO: make required + readonly template?: TemplateRef; // TODO: make required } diff --git a/src/lib/listing/scroll-button/scroll-button.component.html b/src/lib/listing/scroll-button/scroll-button.component.html new file mode 100644 index 0000000..b04b249 --- /dev/null +++ b/src/lib/listing/scroll-button/scroll-button.component.html @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/listing/scroll-button/scroll-button.component.scss b/src/lib/listing/scroll-button/scroll-button.component.scss new file mode 100644 index 0000000..093aaa9 --- /dev/null +++ b/src/lib/listing/scroll-button/scroll-button.component.scss @@ -0,0 +1,30 @@ +@import '../../../assets/styles/common'; + +.scroll-button { + background-color: $white; + position: absolute; + right: 0; + height: 40px; + width: 44px; + border: none; + border-radius: 8px 0 0 8px; + box-shadow: -1px 1px 5px 0 rgba(40, 50, 65, 0.25); + + &.bottom { + bottom: 30px; + } + + &.top { + top: 100px; + + mat-icon { + transform: rotate(180deg); + } + } +} + +mat-icon { + width: 22px; + height: 22px; + color: $grey-7; +} diff --git a/src/lib/listing/scroll-button/scroll-button.component.ts b/src/lib/listing/scroll-button/scroll-button.component.ts new file mode 100644 index 0000000..09ad966 --- /dev/null +++ b/src/lib/listing/scroll-button/scroll-button.component.ts @@ -0,0 +1,61 @@ +import { ChangeDetectionStrategy, Component, HostListener, Input, OnInit } from '@angular/core'; +import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; +import { concatMap, delay, distinctUntilChanged, map, startWith } from 'rxjs/operators'; +import { Observable, of } from 'rxjs'; +import { Required } from '../../utils'; + +const ButtonTypes = { + top: 'top', + bottom: 'bottom' +} as const; + +type ButtonType = keyof typeof ButtonTypes; + +@Component({ + selector: 'iqser-scroll-button', + templateUrl: './scroll-button.component.html', + styleUrls: ['./scroll-button.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ScrollButtonComponent implements OnInit { + readonly buttonType = ButtonTypes; + + @Input() @Required() scrollViewport!: CdkVirtualScrollViewport; + @Input() @Required() itemSize!: number; + + showScrollUp$?: Observable; + showScrollDown$?: Observable; + + ngOnInit(): void { + const scrollSize = () => this.scrollViewport.getDataLength() * this.itemSize; + const scrollIsNeeded = () => this.scrollViewport.getViewportSize() < scrollSize(); + const reachedEnd = (type: ButtonType) => this.scrollViewport.measureScrollOffset(type) === 0; + + const showScrollUp = () => scrollIsNeeded() && !reachedEnd(ButtonTypes.top); + const showScrollDown = () => scrollIsNeeded() && !reachedEnd(ButtonTypes.bottom); + + const scroll$ = this.scrollViewport.elementScrolled().pipe( + startWith(''), + /** Delay first value so that we can wait for items to be rendered in viewport and get correct values */ + concatMap((value, index) => (index === 0 ? of(value).pipe(delay(0)) : of(value))) + ); + this.showScrollUp$ = scroll$.pipe(map(showScrollUp), distinctUntilChanged()); + this.showScrollDown$ = scroll$.pipe(map(showScrollDown), distinctUntilChanged()); + } + + scroll(type: ButtonType): void { + const viewportSize = (this.scrollViewport?.getViewportSize() - this.itemSize) * (type === ButtonTypes.top ? -1 : 1); + const scrollOffset = this.scrollViewport?.measureScrollOffset('top'); + this.scrollViewport?.scrollToOffset(scrollOffset + viewportSize, 'smooth'); + } + + @HostListener('document:keyup', ['$event']) + spaceAndPageDownScroll(event: KeyboardEvent): void { + const target = event.target as EventTarget & { tagName: string }; + if (['Space', 'PageDown'].includes(event.code) && target.tagName === 'BODY') { + this.scroll(ButtonTypes.bottom); + } else if (['PageUp'].includes(event.code) && target.tagName === 'BODY') { + this.scroll(ButtonTypes.top); + } + } +} diff --git a/src/lib/listing/entities.service.ts b/src/lib/listing/services/entities.service.ts similarity index 96% rename from src/lib/listing/entities.service.ts rename to src/lib/listing/services/entities.service.ts index c73f34b..b4edab1 100644 --- a/src/lib/listing/entities.service.ts +++ b/src/lib/listing/services/entities.service.ts @@ -1,9 +1,9 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, combineLatest, Observable, pipe } from 'rxjs'; import { distinctUntilChanged, map, tap } from 'rxjs/operators'; -import { FilterService, getFilteredEntities } from '../filtering'; -import { SearchService } from '../search'; -import { Listable } from './models/listable'; +import { FilterService, getFilteredEntities } from '../../filtering'; +import { SearchService } from '../../search'; +import { Listable } from '../models'; const toLengthValue = (entities: unknown[]) => entities?.length ?? 0; const getLength = pipe(map(toLengthValue), distinctUntilChanged()); diff --git a/src/lib/listing/services/index.ts b/src/lib/listing/services/index.ts new file mode 100644 index 0000000..8d6e94c --- /dev/null +++ b/src/lib/listing/services/index.ts @@ -0,0 +1 @@ +export * from './entities.service'; diff --git a/src/lib/listing/tables/sync-width.directive.ts b/src/lib/listing/sync-width.directive.ts similarity index 100% rename from src/lib/listing/tables/sync-width.directive.ts rename to src/lib/listing/sync-width.directive.ts diff --git a/src/lib/listing/tables/table-column-name/table-column-name.component.html b/src/lib/listing/table-column-name/table-column-name.component.html similarity index 100% rename from src/lib/listing/tables/table-column-name/table-column-name.component.html rename to src/lib/listing/table-column-name/table-column-name.component.html diff --git a/src/lib/listing/tables/table-column-name/table-column-name.component.scss b/src/lib/listing/table-column-name/table-column-name.component.scss similarity index 95% rename from src/lib/listing/tables/table-column-name/table-column-name.component.scss rename to src/lib/listing/table-column-name/table-column-name.component.scss index ed0a5d7..87a10b1 100644 --- a/src/lib/listing/tables/table-column-name/table-column-name.component.scss +++ b/src/lib/listing/table-column-name/table-column-name.component.scss @@ -1,4 +1,4 @@ -@import '../../../../assets/styles/common'; +@import '../../../assets/styles/common'; :host { display: flex; diff --git a/src/lib/listing/tables/table-column-name/table-column-name.component.ts b/src/lib/listing/table-column-name/table-column-name.component.ts similarity index 87% rename from src/lib/listing/tables/table-column-name/table-column-name.component.ts rename to src/lib/listing/table-column-name/table-column-name.component.ts index 887cb14..8977bf2 100644 --- a/src/lib/listing/tables/table-column-name/table-column-name.component.ts +++ b/src/lib/listing/table-column-name/table-column-name.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, Input, Optional } from '@angular/core'; -import { SortingOrders, SortingService } from '../../../sorting'; -import { KeysOf, Required } from '../../../utils'; +import { SortingOrders, SortingService } from '../../sorting'; +import { KeysOf, Required } from '../../utils'; const ifHasRightIcon = (thisArg: TableColumnNameComponent) => !!thisArg.rightIcon; diff --git a/src/lib/listing/table-header/table-header.component.ts b/src/lib/listing/table-header/table-header.component.ts index 86bbb4e..c9d9df7 100644 --- a/src/lib/listing/table-header/table-header.component.ts +++ b/src/lib/listing/table-header/table-header.component.ts @@ -1,9 +1,8 @@ import { ChangeDetectionStrategy, Component, Input, TemplateRef } from '@angular/core'; import { Required } from '../../utils'; import { FilterService } from '../../filtering'; -import { EntitiesService } from '../entities.service'; -import { Listable } from '../models/listable'; -import { TableColumnConfig } from '../tables'; +import { EntitiesService } from '../services'; +import { Listable, TableColumnConfig } from '../models'; export const ListingModes = { list: 'list', diff --git a/src/lib/listing/table/table.component.html b/src/lib/listing/table/table.component.html new file mode 100644 index 0000000..c07daff --- /dev/null +++ b/src/lib/listing/table/table.component.html @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + + + + +
n
+
+ +
+ +
+ +
+
+
+ + diff --git a/src/lib/listing/table/table.component.scss b/src/lib/listing/table/table.component.scss new file mode 100644 index 0000000..55f6016 --- /dev/null +++ b/src/lib/listing/table/table.component.scss @@ -0,0 +1,121 @@ +//iqser-table-header::ng-deep .header-item { +// padding-right: 16px; +//} +@import '../../../assets/styles/common'; + +cdk-virtual-scroll-viewport { + height: calc(100vh - 50px - 31px - 111px); + overflow-y: hidden !important; + + &.has-scrollbar:hover ::ng-deep.cdk-virtual-scroll-content-wrapper { + grid-template-columns: var(--gridTemplateColumnsHover); + } + + ::ng-deep.cdk-virtual-scroll-content-wrapper { + grid-template-columns: var(--gridTemplateColumns); + display: grid; + + .table-item { + display: contents; + + > div { + display: flex; + flex-direction: column; + justify-content: center; + position: relative; + box-sizing: border-box; + border-bottom: 1px solid $separator; + height: var(--itemSize); + padding: 0 24px 0 var(--paddingLeft); + + &:not(.scrollbar-placeholder):not(.selection-column) { + min-width: 110px; + } + + &.selection-column { + padding-right: 0 !important; + + iqser-round-checkbox .wrapper { + opacity: 0; + transition: opacity 0.2s; + + &.active { + opacity: 1; + } + } + } + } + + .table-item-title { + font-weight: 600; + @include line-clamp(1); + } + + .action-buttons { + position: absolute; + display: none; + right: -11px; + top: 0; + height: 100%; + width: fit-content; + flex-direction: row; + align-items: center; + padding-left: 100px; + padding-right: 24px; + z-index: 1; + background: linear-gradient(to right, rgba(244, 245, 247, 0) 0%, $grey-2 35%); + + mat-icon { + width: 14px; + } + + iqser-circle-button:not(:last-child) { + margin-right: 2px; + } + + &.active { + display: flex; + // compensate for scroll + padding-right: 23px; + } + } + + input, + mat-select { + margin-top: 0; + } + + &:hover { + > div { + background-color: $grey-8; + + &.selection-column iqser-round-checkbox .wrapper { + opacity: 1; + } + } + + .action-buttons { + display: flex; + } + } + } + } + + &:hover { + overflow-y: auto !important; + @include scroll-bar; + + &.has-scrollbar { + .table-item { + .action-buttons { + right: 0; + padding-right: 13px; + } + + .scrollbar-placeholder { + display: none; + } + } + } + } +} diff --git a/src/lib/listing/table/table.component.ts b/src/lib/listing/table/table.component.ts new file mode 100644 index 0000000..8afad4b --- /dev/null +++ b/src/lib/listing/table/table.component.ts @@ -0,0 +1,66 @@ +import { ChangeDetectionStrategy, Component, forwardRef, Inject, Input, OnInit, 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'; + +@Component({ + selector: 'iqser-table', + templateUrl: './table.component.html', + styleUrls: ['./table.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class TableComponent implements OnInit { + @Input() bulkActions?: TemplateRef; + @Input() actionsTemplate?: TemplateRef; + @Input() @Required() itemSize!: number; + @Input() @Required() tableColumnConfigs!: readonly TableColumnConfig[]; + @Input() @Required() tableHeaderLabel!: string; + @Input() selectionEnabled = false; + @Input() hasScrollButton = false; + @Input() emptyColumnWidth?: string; + @Input() classes?: string; + @Input() routerLinkFn?: (entity: T) => string | string[]; + @ViewChild(CdkVirtualScrollViewport, { static: true }) private readonly _viewport!: CdkVirtualScrollViewport; + + constructor(@Inject(forwardRef(() => ListingComponent)) private _parent: ListingComponent) {} + + get listingComponent(): ListingComponent { + return this._parent; + } + + ngOnInit(): void { + this._setStyles(); + } + + private _setStyles(): void { + const element = this._viewport.elementRef.nativeElement; + this._setColumnsWidth(element); + this._setItemSize(element); + this._setPadding(element); + } + + private _setColumnsWidth(element: HTMLElement) { + let gridTemplateColumnsHover = ''; + if (this.selectionEnabled) { + gridTemplateColumnsHover += 'auto '; + } + for (const config of this.tableColumnConfigs) { + gridTemplateColumnsHover += `${config.width as string} `; // TODO remove cast + } + gridTemplateColumnsHover += this.emptyColumnWidth; + const gridTemplateColumns = gridTemplateColumnsHover + ' 11px'; + + element.style.setProperty('--gridTemplateColumns', gridTemplateColumns); + element.style.setProperty('--gridTemplateColumnsHover', gridTemplateColumnsHover); + } + + private _setItemSize(element: HTMLElement) { + element.style.setProperty('--itemSize', `${this.itemSize}px`); + } + + private _setPadding(element: HTMLElement) { + const paddingLeft = this.selectionEnabled ? 10 : 24; + element.style.setProperty('--paddingLeft', `${paddingLeft}px`); + } +} diff --git a/src/lib/listing/tables/index.ts b/src/lib/listing/tables/index.ts deleted file mode 100644 index 2cad679..0000000 --- a/src/lib/listing/tables/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './tables-module'; -export * from './table-column-name/table-column-name.component'; -export * from './models/table-column-config.model'; -export * from './sync-width.directive'; diff --git a/src/lib/listing/tables/tables-module.ts b/src/lib/listing/tables/tables-module.ts deleted file mode 100644 index 96a9db2..0000000 --- a/src/lib/listing/tables/tables-module.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { MatTooltipModule } from '@angular/material/tooltip'; -import { TranslateModule } from '@ngx-translate/core'; -import { TableColumnNameComponent } from './table-column-name/table-column-name.component'; -import { SyncWidthDirective } from './sync-width.directive'; -import { IqserIconsModule } from '../../icons'; - -const matModules = [MatTooltipModule]; -const components = [TableColumnNameComponent]; -const utils = [SyncWidthDirective]; - -@NgModule({ - declarations: [...components, ...utils], - exports: [...components, ...utils], - imports: [CommonModule, TranslateModule, IqserIconsModule, ...matModules] -}) -export class TablesModule {} diff --git a/src/lib/listing/workflow-listing/index.ts b/src/lib/listing/workflow-listing/index.ts deleted file mode 100644 index 87b1b5e..0000000 --- a/src/lib/listing/workflow-listing/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './workflow-listing.module'; diff --git a/src/lib/listing/workflow-listing/workflow-listing.module.ts b/src/lib/listing/workflow-listing/workflow-listing.module.ts deleted file mode 100644 index 66d6d54..0000000 --- a/src/lib/listing/workflow-listing/workflow-listing.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { DragDropModule } from '@angular/cdk/drag-drop'; -import { TranslateModule } from '@ngx-translate/core'; - -const matModules = [DragDropModule]; - -@NgModule({ - declarations: [], - imports: [CommonModule, TranslateModule, ...matModules] -}) -export class WorkflowListingModule {} diff --git a/src/lib/scrollbar/has-scrollbar.directive.ts b/src/lib/scrollbar/has-scrollbar.directive.ts new file mode 100644 index 0000000..c2edf2f --- /dev/null +++ b/src/lib/scrollbar/has-scrollbar.directive.ts @@ -0,0 +1,27 @@ +import { AfterContentChecked, Directive, ElementRef, HostBinding } from '@angular/core'; + +@Directive({ + selector: '[iqserHasScrollbar]', + exportAs: 'iqserHasScrollbar' +}) +export class HasScrollbarDirective implements AfterContentChecked { + @HostBinding('class') class = ''; + + constructor(private readonly _elementRef: ElementRef) {} + + get hasScrollbar(): boolean { + const element = this._elementRef?.nativeElement as HTMLElement; + return element.clientHeight < element.scrollHeight; + } + + ngAfterContentChecked(): void { + this._process(); + } + + _process(): void { + const newClass = this.hasScrollbar ? 'has-scrollbar' : ''; + if (this.class !== newClass) { + this.class = newClass; + } + } +} diff --git a/src/lib/scrollbar/index.ts b/src/lib/scrollbar/index.ts new file mode 100644 index 0000000..19629b5 --- /dev/null +++ b/src/lib/scrollbar/index.ts @@ -0,0 +1,2 @@ +export * from '../scrollbar/has-scrollbar.directive'; +export * from './scrollbar.module'; diff --git a/src/lib/scrollbar/scrollbar.module.ts b/src/lib/scrollbar/scrollbar.module.ts new file mode 100644 index 0000000..5efb8f1 --- /dev/null +++ b/src/lib/scrollbar/scrollbar.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { HasScrollbarDirective } from './has-scrollbar.directive'; + +const utils = [HasScrollbarDirective]; + +@NgModule({ + declarations: [...utils], + exports: [...utils], + imports: [CommonModule], + providers: [HasScrollbarDirective] +}) +export class IqserScrollbarModule {} 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 02/11] 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); From 704ea8221e6a6a198811c91f2a5fd15ed25c46da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Fri, 27 Aug 2021 20:16:49 +0300 Subject: [PATCH 03/11] Get table properties from parent component --- src/lib/listing/listing-component.directive.ts | 4 ++++ src/lib/listing/table/table.component.ts | 14 +++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/lib/listing/listing-component.directive.ts b/src/lib/listing/listing-component.directive.ts index 9c212f5..23372a8 100644 --- a/src/lib/listing/listing-component.directive.ts +++ b/src/lib/listing/listing-component.directive.ts @@ -20,7 +20,11 @@ export abstract class ListingComponent extends AutoUnsubscri readonly noMatch$ = this._noMatch$; readonly sortedDisplayedEntities$ = this._sortedDisplayedEntities$; + // TODO: These should be somewhere in table listing, not generic listing abstract readonly tableColumnConfigs: readonly TableColumnConfig[]; + readonly tableHeaderLabel?: string; + readonly routerLinkFn?: (entity: T) => string | string[]; + /** * Key used in the *trackBy* function with **ngFor* or **cdkVirtualFor* * and in the default sorting and as the search field diff --git a/src/lib/listing/table/table.component.ts b/src/lib/listing/table/table.component.ts index 1939c36..2ac2934 100644 --- a/src/lib/listing/table/table.component.ts +++ b/src/lib/listing/table/table.component.ts @@ -28,20 +28,20 @@ export class TableComponent implements OnInit { @Input() actionsTemplate?: TemplateRef; @Input() headerTemplate?: TemplateRef; @Input() @Required() itemSize!: number; - @Input() @Required() tableColumnConfigs!: readonly TableColumnConfig[]; - @Input() @Required() tableHeaderLabel!: string; @Input() selectionEnabled = false; @Input() hasScrollButton = false; @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; + routerLinkFn?: (entity: T) => string | string[]; + tableColumnConfigs!: readonly TableColumnConfig[]; + tableHeaderLabel?: string; // todo not optional + @ViewChild(CdkVirtualScrollViewport, { static: true }) readonly scrollViewport!: CdkVirtualScrollViewport; constructor(@Inject(forwardRef(() => ListingComponent)) private _parent: ListingComponent) {} @@ -50,6 +50,10 @@ export class TableComponent implements OnInit { } ngOnInit(): void { + this.tableColumnConfigs = this.listingComponent.tableColumnConfigs; + this.tableHeaderLabel = this.listingComponent.tableHeaderLabel; + this.routerLinkFn = this.listingComponent.routerLinkFn; + this._patchConfig(); this._setStyles(); } @@ -59,7 +63,7 @@ export class TableComponent implements OnInit { } private _setStyles(): void { - const element = this._viewport.elementRef.nativeElement; + const element = this.scrollViewport.elementRef.nativeElement; this._setColumnsWidth(element); this._setItemSize(element); this._setPadding(element); From 3c693625e774ff61f89a49bf8a915e012320acc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 30 Aug 2021 13:06:36 +0300 Subject: [PATCH 04/11] Table & error service updates --- src/lib/error/error.service.ts | 7 ++++++- .../listing/models/table-column-config.model.ts | 1 + src/lib/listing/table/table.component.html | 5 ++--- src/lib/listing/table/table.component.scss | 2 +- src/lib/listing/table/table.component.ts | 14 ++++++++++++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/lib/error/error.service.ts b/src/lib/error/error.service.ts index 01d91bc..a130be5 100644 --- a/src/lib/error/error.service.ts +++ b/src/lib/error/error.service.ts @@ -2,6 +2,8 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; import { HttpErrorResponse } from '@angular/common/http'; import { LoadingService } from '../loading'; +import { filter } from 'rxjs/operators'; +import { NavigationStart, Router } from '@angular/router'; export type Error = HttpErrorResponse | null; @@ -10,8 +12,11 @@ export class ErrorService { readonly hasError$: Observable; private readonly _errorEvent$ = new BehaviorSubject(null); - constructor(private readonly _loadingService: LoadingService) { + constructor(private readonly _loadingService: LoadingService, private readonly _router: Router) { this.hasError$ = this._errorEvent$.asObservable(); + _router.events.pipe(filter(event => event instanceof NavigationStart)).subscribe(() => { + this.clear(); + }); } private _error: Error = null; diff --git a/src/lib/listing/models/table-column-config.model.ts b/src/lib/listing/models/table-column-config.model.ts index 28bf880..70ba78f 100644 --- a/src/lib/listing/models/table-column-config.model.ts +++ b/src/lib/listing/models/table-column-config.model.ts @@ -11,5 +11,6 @@ export interface TableColumnConfig { readonly notTranslatable?: boolean; readonly width?: string; readonly template?: TemplateRef; // TODO: make required + readonly extra?: unknown; last?: boolean; } diff --git a/src/lib/listing/table/table.component.html b/src/lib/listing/table/table.component.html index 305879a..4a14415 100644 --- a/src/lib/listing/table/table.component.html +++ b/src/lib/listing/table/table.component.html @@ -22,16 +22,15 @@
- +
diff --git a/src/lib/listing/table/table.component.scss b/src/lib/listing/table/table.component.scss index 9fb63ed..ed541f1 100644 --- a/src/lib/listing/table/table.component.scss +++ b/src/lib/listing/table/table.component.scss @@ -23,7 +23,7 @@ cdk-virtual-scroll-viewport { box-sizing: border-box; border-bottom: 1px solid $separator; height: var(--itemSize); - padding: 0 24px 0 var(--paddingLeft); + padding: 0 13px 0 var(--paddingLeft); &:not(.scrollbar-placeholder):not(.selection-column) { min-width: 110px; diff --git a/src/lib/listing/table/table.component.ts b/src/lib/listing/table/table.component.ts index 2ac2934..956d5f1 100644 --- a/src/lib/listing/table/table.component.ts +++ b/src/lib/listing/table/table.component.ts @@ -38,6 +38,7 @@ export class TableComponent implements OnInit { @Input() showNoDataButton = false; @Output() readonly noDataAction = new EventEmitter(); @Input() noMatchText?: string; + @Input() tableItemClasses?: { [key: string]: (e: T) => boolean }; routerLinkFn?: (entity: T) => string | string[]; tableColumnConfigs!: readonly TableColumnConfig[]; tableHeaderLabel?: string; // todo not optional @@ -58,6 +59,19 @@ export class TableComponent implements OnInit { this._setStyles(); } + getTableItemClasses(entity: T): { [key: string]: boolean } { + const classes: { [key: string]: boolean } = { + 'table-item': true, + pointer: !!this.routerLinkFn && this.routerLinkFn(entity).length > 0 + }; + for (const key in this.tableItemClasses) { + if (Object.prototype.hasOwnProperty.call(this.tableItemClasses, key)) { + classes[key] = this.tableItemClasses[key](entity); + } + } + return classes; + } + private _patchConfig() { this.tableColumnConfigs[this.tableColumnConfigs.length - 1].last = true; } From 7a59cd09946221a444fad4d2aaf82597819d5679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 30 Aug 2021 14:56:53 +0300 Subject: [PATCH 05/11] Fixed routerlink --- src/lib/listing/table/table.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/listing/table/table.component.html b/src/lib/listing/table/table.component.html index 4a14415..fa8d2c1 100644 --- a/src/lib/listing/table/table.component.html +++ b/src/lib/listing/table/table.component.html @@ -23,7 +23,7 @@
From 70f3c560d3b312d9707f367c2b8d3289ccbf908d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 30 Aug 2021 16:49:20 +0300 Subject: [PATCH 06/11] Fixes --- .../listing/table-column-name/table-column-name.component.html | 2 +- src/lib/listing/table/table.component.html | 1 + src/lib/listing/table/table.component.ts | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lib/listing/table-column-name/table-column-name.component.html b/src/lib/listing/table-column-name/table-column-name.component.html index b9331ee..745d01d 100644 --- a/src/lib/listing/table-column-name/table-column-name.component.html +++ b/src/lib/listing/table-column-name/table-column-name.component.html @@ -3,7 +3,7 @@ {{ label }} - +
diff --git a/src/lib/listing/table/table.component.html b/src/lib/listing/table/table.component.html index fa8d2c1..9aea9f6 100644 --- a/src/lib/listing/table/table.component.html +++ b/src/lib/listing/table/table.component.html @@ -11,6 +11,7 @@ implements OnInit { @Input() classes?: string; @Input() noDataText?: string; @Input() noDataIcon?: string; + @Input() noDataButtonIcon?: string; @Input() noDataButtonLabel?: string; @Input() showNoDataButton = false; @Output() readonly noDataAction = new EventEmitter(); @@ -91,7 +92,7 @@ export class TableComponent implements OnInit { for (const config of this.tableColumnConfigs) { gridTemplateColumnsHover += `${config.width || '1fr'} `; } - gridTemplateColumnsHover += this.emptyColumnWidth || ''; // TODO: Check if it's always 1fr + gridTemplateColumnsHover += this.emptyColumnWidth || ''; const gridTemplateColumns = `${gridTemplateColumnsHover} ${SCROLLBAR_WIDTH}px`; element.style.setProperty('--gridTemplateColumns', gridTemplateColumns); From af46a45b97a42380a316396635fecc58372b78eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Tue, 31 Aug 2021 16:31:17 +0300 Subject: [PATCH 07/11] Table item mouse enter/leave & some styles --- src/assets/styles/_tables.scss | 50 ------------------- .../table-column-name.component.scss | 10 +++- .../table-header/table-header.component.scss | 39 +++++++++++++++ src/lib/listing/table/table.component.html | 2 + src/lib/listing/table/table.component.scss | 25 ++++++---- src/lib/listing/table/table.component.ts | 20 ++++---- 6 files changed, 76 insertions(+), 70 deletions(-) diff --git a/src/assets/styles/_tables.scss b/src/assets/styles/_tables.scss index 1579698..db1da5e 100644 --- a/src/assets/styles/_tables.scss +++ b/src/assets/styles/_tables.scss @@ -1,53 +1,3 @@ -@import 'variables'; - -.table-header { - display: flex; - border-bottom: 1px solid $separator; - - &.no-data:not([synced='true']) { - padding-left: 30px; - } - - iqser-table-column-name:last-of-type { - > div { - padding-right: 13px; - } - } - - &.selection-enabled iqser-table-column-name > div { - padding-left: 10px; - } -} - -.header-item { - background-color: $btn-bg; - height: 50px; - padding: 0 24px; - display: flex; - align-items: center; - z-index: 1; - border-bottom: 1px solid $separator; - box-sizing: border-box; - - > *:not(:last-child) { - margin-right: 10px; - } - - .actions { - display: flex; - align-items: center; - justify-content: flex-end; - - > *:not(:last-child) { - margin-right: 16px; - } - } - - &.selection-enabled { - padding-left: 10px; - } -} - .scrollbar-placeholder { width: 11px; padding: 0 !important; diff --git a/src/lib/listing/table-column-name/table-column-name.component.scss b/src/lib/listing/table-column-name/table-column-name.component.scss index 87a10b1..731b910 100644 --- a/src/lib/listing/table-column-name/table-column-name.component.scss +++ b/src/lib/listing/table-column-name/table-column-name.component.scss @@ -10,7 +10,7 @@ display: flex; width: 100%; line-height: 11px; - padding: 0 24px; + padding: 0 10px; > mat-icon { width: 10px; @@ -24,6 +24,14 @@ } } + &:first-child > div { + padding: 0 24px; + } + + &:last-of-type > div { + padding: 0 13px 0 10px; + } + .flex-end { min-width: 58px; } diff --git a/src/lib/listing/table-header/table-header.component.scss b/src/lib/listing/table-header/table-header.component.scss index e69de29..8222ce0 100644 --- a/src/lib/listing/table-header/table-header.component.scss +++ b/src/lib/listing/table-header/table-header.component.scss @@ -0,0 +1,39 @@ +@import '../../../assets/styles/common'; + +.table-header { + display: flex; + border-bottom: 1px solid $separator; + + &.no-data:not([synced='true']) { + padding-left: 30px; + } +} + +.header-item { + background-color: $btn-bg; + height: 50px; + display: flex; + align-items: center; + z-index: 1; + border-bottom: 1px solid $separator; + box-sizing: border-box; + padding: 0 24px; + + &.selection-enabled { + padding: 0 24px 0 10px; + } + + > *:not(:last-child) { + margin-right: 10px; + } + + .actions { + display: flex; + align-items: center; + justify-content: flex-end; + + > *:not(:last-child) { + margin-right: 16px; + } + } +} diff --git a/src/lib/listing/table/table.component.html b/src/lib/listing/table/table.component.html index 9aea9f6..e4281f0 100644 --- a/src/lib/listing/table/table.component.html +++ b/src/lib/listing/table/table.component.html @@ -22,6 +22,8 @@