diff --git a/src/index.ts b/src/index.ts index 4a6eebb..4583469 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,42 +1,14 @@ export * from './lib/common-ui.module'; -export * from './lib/utils/functions'; -export * from './lib/utils/operators'; -export * from './lib/utils/auto-unsubscribe.directive'; -export * from './lib/utils/pipes/humanize.pipe'; -export * from './lib/utils/types/events.type'; -export * from './lib/utils/types/utility-types'; -export * from './lib/utils/types/tooltip-positions.type'; -export * from './lib/utils/decorators/bind.decorator'; -export * from './lib/utils/decorators/required.decorator'; -export * from './lib/utils/decorators/debounce.decorator'; -export * from './lib/filtering/filter-utils'; -export * from './lib/filtering/filter.service'; -export * from './lib/filtering/models/filter.model'; -export * from './lib/filtering/models/filter-group.model'; -export * from './lib/filtering/models/nested-filter.model'; -export * from './lib/filtering/popup-filter/popup-filter.component'; -export * from './lib/filtering/quick-filters/quick-filters.component'; -export * from './lib/sorting/sort-by.pipe'; -export * from './lib/sorting/sorting.service'; -export * from './lib/sorting/models/sorting-option.model'; -export * from './lib/sorting/models/sorting-order.type'; -export * from './lib/services/toaster.service'; -export * from './lib/services/error-message.service'; -export * from './lib/search/search.service'; -export * from './lib/tables/entities.service'; -export * from './lib/tables/listing-component.directive'; -export * from './lib/tables/models/table-column-config.model'; -export * from './lib/tables/table-column-name/table-column-name.component'; -export * from './lib/tables/table-header/table-header.component'; -export * from './lib/misc/status-bar/status-bar.component'; -export * from './lib/misc/status-bar/status-bar-config.model'; -export * from './lib/inputs/round-checkbox/round-checkbox.component'; -export * from './lib/inputs/editable-input/editable-input.component'; -export * from './lib/inputs/input-with-action/input-with-action.component'; + export * from './lib/buttons'; +export * from './lib/listing'; +export * from './lib/filtering'; export * from './lib/help-mode'; -export * from './lib/tables/models/listable'; -export * from './lib/loading/loading.service'; -export * from './lib/loading/full-page-loading-indicator/full-page-loading-indicator.component'; -export * from './lib/error/error.service'; -export * from './lib/error/full-page-error/full-page-error.component'; +export * from './lib/inputs'; +export * from './lib/utils'; +export * from './lib/sorting'; +export * from './lib/services'; +export * from './lib/misc'; +export * from './lib/loading'; +export * from './lib/error'; +export * from './lib/search'; diff --git a/src/lib/buttons/buttons.module.ts b/src/lib/buttons/buttons.module.ts index f8acc95..90e84a9 100644 --- a/src/lib/buttons/buttons.module.ts +++ b/src/lib/buttons/buttons.module.ts @@ -1,17 +1,19 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { MatIconModule } from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; import { MatTooltipModule } from '@angular/material/tooltip'; +import { TranslateModule } from '@ngx-translate/core'; import { ChevronButtonComponent } from './chevron-button/chevron-button.component'; import { CircleButtonComponent } from './circle-button/circle-button.component'; import { IconButtonComponent } from './icon-button/icon-button.component'; +import { IqserIconsModule } from '../icons'; +const matModules = [MatButtonModule, MatTooltipModule]; const components = [ChevronButtonComponent, CircleButtonComponent, IconButtonComponent]; @NgModule({ declarations: [...components], - imports: [CommonModule, MatIconModule, MatButtonModule, MatTooltipModule], + imports: [CommonModule, IqserIconsModule, TranslateModule, ...matModules], exports: [...components] }) export class IqserButtonsModule {} diff --git a/src/lib/buttons/chevron-button/chevron-button.component.ts b/src/lib/buttons/chevron-button/chevron-button.component.ts index 590c901..d515146 100644 --- a/src/lib/buttons/chevron-button/chevron-button.component.ts +++ b/src/lib/buttons/chevron-button/chevron-button.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { Required } from '../../utils/decorators/required.decorator'; +import { Required } from '../../utils'; @Component({ selector: 'iqser-chevron-button', diff --git a/src/lib/buttons/circle-button/circle-button.component.ts b/src/lib/buttons/circle-button/circle-button.component.ts index fa26439..fd5d00e 100644 --- a/src/lib/buttons/circle-button/circle-button.component.ts +++ b/src/lib/buttons/circle-button/circle-button.component.ts @@ -1,8 +1,7 @@ import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; import { MatTooltip } from '@angular/material/tooltip'; import { CircleButtonType, CircleButtonTypes } from '../types/circle-button.type'; -import { Required } from '../../utils/decorators/required.decorator'; -import { IqserTooltipPosition, IqserTooltipPositions } from '../../utils/types/tooltip-positions.type'; +import { IqserTooltipPosition, IqserTooltipPositions, Required } from '../../utils'; @Component({ selector: 'iqser-circle-button', diff --git a/src/lib/buttons/icon-button/icon-button.component.ts b/src/lib/buttons/icon-button/icon-button.component.ts index 26c602e..2e7255a 100644 --- a/src/lib/buttons/icon-button/icon-button.component.ts +++ b/src/lib/buttons/icon-button/icon-button.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; import { IconButtonType, IconButtonTypes } from '../types/icon-button.type'; -import { Required } from '../../utils/decorators/required.decorator'; +import { Required } from '../../utils'; @Component({ selector: 'iqser-icon-button', diff --git a/src/lib/buttons/index.ts b/src/lib/buttons/index.ts index 481dd0f..3bdc3e4 100644 --- a/src/lib/buttons/index.ts +++ b/src/lib/buttons/index.ts @@ -1,5 +1,8 @@ export * from './buttons.module'; + export * from './types/icon-button.type'; -export * from './icon-button/icon-button.component'; export * from './types/circle-button.type'; + +export * from './icon-button/icon-button.component'; export * from './circle-button/circle-button.component'; +export * from './chevron-button/chevron-button.component'; diff --git a/src/lib/common-ui.module.ts b/src/lib/common-ui.module.ts index 348ce5c..3f025d7 100644 --- a/src/lib/common-ui.module.ts +++ b/src/lib/common-ui.module.ts @@ -1,68 +1,36 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { MatIconModule, MatIconRegistry } from '@angular/material/icon'; -import { MatButtonModule } from '@angular/material/button'; -import { DomSanitizer } from '@angular/platform-browser'; -import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatIconModule } from '@angular/material/icon'; import { TranslateModule } from '@ngx-translate/core'; -import { FormsModule } from '@angular/forms'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatDialogModule } from '@angular/material/dialog'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { RoundCheckboxComponent } from './inputs/round-checkbox/round-checkbox.component'; -import { SortByPipe } from './sorting/sort-by.pipe'; -import { HumanizePipe } from './utils/pipes/humanize.pipe'; -import { TableColumnNameComponent } from './tables/table-column-name/table-column-name.component'; -import { QuickFiltersComponent } from './filtering/quick-filters/quick-filters.component'; -import { TableHeaderComponent } from './tables/table-header/table-header.component'; -import { SyncWidthDirective } from './tables/sync-width.directive'; -import { StatusBarComponent } from './misc/status-bar/status-bar.component'; -import { EditableInputComponent } from './inputs/editable-input/editable-input.component'; -import { PopupFilterComponent } from './filtering/popup-filter/popup-filter.component'; -import { InputWithActionComponent } from './inputs/input-with-action/input-with-action.component'; +import { SortByPipe } from './sorting'; +import { HumanizePipe } from './utils'; +import { StatusBarComponent } from './misc'; +import { FullPageLoadingIndicatorComponent } from './loading'; +import { FullPageErrorComponent } from './error'; +import { IqserListingModule } from './listing'; +import { IqserFiltersModule } from './filtering'; +import { IqserInputsModule } from './inputs'; +import { IqserHelpModeModule } from './help-mode'; +import { IqserIconsModule } from './icons'; import { IqserButtonsModule } from './buttons'; -import { FullPageLoadingIndicatorComponent } from './loading/full-page-loading-indicator/full-page-loading-indicator.component'; -import { FullPageErrorComponent } from './error/full-page-error/full-page-error.component'; -const inputs = [RoundCheckboxComponent, EditableInputComponent, InputWithActionComponent]; - -const matModules = [ - MatIconModule, - MatButtonModule, - MatTooltipModule, - MatMenuModule, - MatCheckboxModule, - MatDialogModule, - MatProgressSpinnerModule +const matModules = [MatIconModule, MatProgressSpinnerModule]; +const modules = [ + TranslateModule, + IqserIconsModule, + IqserButtonsModule, + IqserListingModule, + IqserFiltersModule, + IqserInputsModule, + IqserHelpModeModule ]; - -const modules = [...matModules, FormsModule, TranslateModule, IqserButtonsModule]; - -const components = [ - ...inputs, - TableColumnNameComponent, - QuickFiltersComponent, - PopupFilterComponent, - TableHeaderComponent, - StatusBarComponent, - FullPageLoadingIndicatorComponent, - FullPageErrorComponent -]; - -const utils = [SortByPipe, HumanizePipe, SyncWidthDirective]; +const components = [StatusBarComponent, FullPageLoadingIndicatorComponent, FullPageErrorComponent]; +const pipes = [SortByPipe, HumanizePipe]; @NgModule({ - declarations: [...components, ...utils], - imports: [CommonModule, ...modules], - exports: [...components, ...utils, ...modules] + declarations: [...components, ...pipes], + imports: [CommonModule, ...matModules, ...modules], + exports: [...components, ...pipes, ...modules] }) -export class CommonUiModule { - constructor(private readonly _iconRegistry: MatIconRegistry, private readonly _sanitizer: DomSanitizer) { - const icons = ['arrow-down', 'check', 'close', 'edit', 'error', 'refresh', 'sort-asc', 'sort-desc', 'search', 'help-outline']; - - icons.forEach(icon => { - _iconRegistry.addSvgIconInNamespace('iqser', icon, _sanitizer.bypassSecurityTrustResourceUrl(`/assets/icons/${icon}.svg`)); - }); - } -} +export class CommonUiModule {} diff --git a/src/lib/error/error.service.ts b/src/lib/error/error.service.ts index 836e387..01d91bc 100644 --- a/src/lib/error/error.service.ts +++ b/src/lib/error/error.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; import { HttpErrorResponse } from '@angular/common/http'; -import { LoadingService } from '../loading/loading.service'; +import { LoadingService } from '../loading'; export type Error = HttpErrorResponse | null; diff --git a/src/lib/error/index.ts b/src/lib/error/index.ts new file mode 100644 index 0000000..9a01d8a --- /dev/null +++ b/src/lib/error/index.ts @@ -0,0 +1,2 @@ +export * from './error.service'; +export * from './full-page-error/full-page-error.component'; diff --git a/src/lib/filtering/filter.service.ts b/src/lib/filtering/filter.service.ts index e8bdd48..d6b014c 100644 --- a/src/lib/filtering/filter.service.ts +++ b/src/lib/filtering/filter.service.ts @@ -4,17 +4,23 @@ import { distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators' import { processFilters, toFlatFilters } from './filter-utils'; import { FilterGroup } from './models/filter-group.model'; import { NestedFilter } from './models/nested-filter.model'; -import { get } from '../utils/operators'; +import { get } from '../utils'; @Injectable() export class FilterService { + readonly showResetFilters$: Observable; + readonly filterGroups$: Observable; private readonly _filterGroups$ = new BehaviorSubject([]); private readonly _refresh$ = new Subject(); - readonly filterGroups$ = this._refresh$.pipe( - startWith(''), - switchMap(() => this._filterGroups$.asObservable()) - ); - readonly showResetFilters$ = this._showResetFilters$; + + constructor() { + this.filterGroups$ = this._refresh$.pipe( + startWith(''), + switchMap(() => this._filterGroups$.asObservable()) + ); + + this.showResetFilters$ = this._showResetFilters$; + } get filterGroups(): FilterGroup[] { return Object.values(this._filterGroups$.getValue()); diff --git a/src/lib/filtering/filters.module.ts b/src/lib/filtering/filters.module.ts new file mode 100644 index 0000000..49a32da --- /dev/null +++ b/src/lib/filtering/filters.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { TranslateModule } from '@ngx-translate/core'; +import { IqserButtonsModule } from '../buttons'; +import { PopupFilterComponent } from './popup-filter/popup-filter.component'; +import { QuickFiltersComponent } from './quick-filters/quick-filters.component'; +import { IqserIconsModule } from '../icons'; + +const matModules = [MatCheckboxModule, MatMenuModule]; +const modules = [TranslateModule, IqserButtonsModule]; +const components = [QuickFiltersComponent, PopupFilterComponent]; + +@NgModule({ + declarations: [...components], + exports: [...components], + imports: [CommonModule, IqserIconsModule, ...matModules, ...modules] +}) +export class IqserFiltersModule {} diff --git a/src/lib/filtering/index.ts b/src/lib/filtering/index.ts new file mode 100644 index 0000000..0a01d7a --- /dev/null +++ b/src/lib/filtering/index.ts @@ -0,0 +1,11 @@ +export * from './filters.module'; + +export * from './filter-utils'; +export * from './filter.service'; + +export * from './models/filter.model'; +export * from './models/filter-group.model'; +export * from './models/nested-filter.model'; + +export * from './popup-filter/popup-filter.component'; +export * from './quick-filters/quick-filters.component'; diff --git a/src/lib/filtering/popup-filter/popup-filter.component.ts b/src/lib/filtering/popup-filter/popup-filter.component.ts index cf3ffc1..8b490dc 100644 --- a/src/lib/filtering/popup-filter/popup-filter.component.ts +++ b/src/lib/filtering/popup-filter/popup-filter.component.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, Input, OnInit, TemplateRef } from ' import { MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox'; import { BehaviorSubject, combineLatest, Observable, pipe } from 'rxjs'; import { delay, distinctUntilChanged, map, shareReplay } from 'rxjs/operators'; -import { any } from '../../utils/operators'; +import { any } from '../../utils'; import { handleCheckedValue } from '../filter-utils'; import { FilterService } from '../filter.service'; import { FilterGroup } from '../models/filter-group.model'; @@ -46,6 +46,14 @@ export class PopupFilterComponent implements OnInit { constructor(readonly filterService: FilterService) {} + private get _hasActiveFilters$() { + return combineLatest([this.primaryFilterGroup$, this.secondaryFilterGroup$]).pipe( + map(([primary, secondary]) => [...(primary?.filters || []), ...(secondary?.filters || [])]), + any(f => f.checked || !!f.indeterminate), + distinctUntilChanged() + ); + } + ngOnInit(): void { this.primaryFilterGroup$ = this.filterService.getGroup$(this.primaryFiltersSlug); this.secondaryFilterGroup$ = this.filterService.getGroup$(this.secondaryFiltersSlug); @@ -91,14 +99,6 @@ export class PopupFilterComponent implements OnInit { this.filterService.refresh(); } - private get _hasActiveFilters$() { - return combineLatest([this.primaryFilterGroup$, this.secondaryFilterGroup$]).pipe( - map(([primary, secondary]) => [...(primary?.filters || []), ...(secondary?.filters || [])]), - any(f => f.checked || !!f.indeterminate), - distinctUntilChanged() - ); - } - private _setFilters(filterGroup: string, checked = false) { const filters = this.filterService.getGroup(filterGroup)?.filters; filters?.forEach(f => { diff --git a/src/lib/help-mode/help-mode.module.ts b/src/lib/help-mode/help-mode.module.ts index 2d17ac7..a3fa60d 100644 --- a/src/lib/help-mode/help-mode.module.ts +++ b/src/lib/help-mode/help-mode.module.ts @@ -1,6 +1,5 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { MatIconModule } from '@angular/material/icon'; import { TranslateModule } from '@ngx-translate/core'; import { MatDialogModule } from '@angular/material/dialog'; import { HelpModeDialogComponent } from './help-mode-dialog/help-mode-dialog.component'; @@ -8,12 +7,14 @@ import { HelpModeComponent } from './help-mode/help-mode.component'; import { HelpModeDirective } from './help-mode.directive'; import { IqserButtonsModule } from '../buttons'; import { HelpModeService } from './help-mode.service'; +import { IqserIconsModule } from '../icons'; +const matModules = [MatDialogModule]; const components = [HelpModeComponent, HelpModeDialogComponent, HelpModeDirective]; @NgModule({ declarations: [...components], - imports: [CommonModule, MatIconModule, MatDialogModule, TranslateModule, IqserButtonsModule], + imports: [CommonModule, IqserIconsModule, ...matModules, TranslateModule, IqserButtonsModule], exports: [...components], providers: [HelpModeService] }) diff --git a/src/lib/help-mode/help-mode.service.ts b/src/lib/help-mode/help-mode.service.ts index 3dcb8ee..4ab95f4 100644 --- a/src/lib/help-mode/help-mode.service.ts +++ b/src/lib/help-mode/help-mode.service.ts @@ -73,9 +73,9 @@ export class HelpModeService { if (!this.isHelpModeActive) return; Object.values(this._elements).forEach(({ helperElement }) => { - this._renderer.addClass(helperElement, 'highlight'); + this._renderer.addClass(helperElement, 'help-highlight'); setTimeout(() => { - this._renderer.removeClass(helperElement, 'highlight'); + this._renderer.removeClass(helperElement, 'help-highlight'); }, 500); }); } diff --git a/src/lib/help-mode/help-mode/help-mode.component.ts b/src/lib/help-mode/help-mode/help-mode.component.ts index 5709d51..7740c6c 100644 --- a/src/lib/help-mode/help-mode/help-mode.component.ts +++ b/src/lib/help-mode/help-mode/help-mode.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core'; import { HelpModeService } from '../help-mode.service'; -import { IqserEventTarget } from '../../utils/types/events.type'; +import { IqserEventTarget } from '../../utils'; @Component({ selector: 'iqser-help-mode', diff --git a/src/lib/icons/icons.module.ts b/src/lib/icons/icons.module.ts new file mode 100644 index 0000000..f49d0d1 --- /dev/null +++ b/src/lib/icons/icons.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatIconModule, MatIconRegistry } from '@angular/material/icon'; +import { DomSanitizer } from '@angular/platform-browser'; + +@NgModule({ + imports: [CommonModule, MatIconModule], + declarations: [], + exports: [MatIconModule] +}) +export class IqserIconsModule { + constructor(private readonly _iconRegistry: MatIconRegistry, private readonly _sanitizer: DomSanitizer) { + const icons: Set = new Set([ + 'arrow-down', + 'check', + 'close', + 'edit', + 'error', + 'help-outline', + 'refresh', + 'search', + 'sort-asc', + 'sort-desc' + ]); + icons.forEach(icon => { + _iconRegistry.addSvgIconInNamespace('iqser', icon, _sanitizer.bypassSecurityTrustResourceUrl(`/assets/icons/${icon}.svg`)); + }); + } +} diff --git a/src/lib/icons/index.ts b/src/lib/icons/index.ts new file mode 100644 index 0000000..e93c671 --- /dev/null +++ b/src/lib/icons/index.ts @@ -0,0 +1 @@ +export * from './icons.module'; diff --git a/src/lib/inputs/editable-input/editable-input.component.ts b/src/lib/inputs/editable-input/editable-input.component.ts index ece127b..480fbdb 100644 --- a/src/lib/inputs/editable-input/editable-input.component.ts +++ b/src/lib/inputs/editable-input/editable-input.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, EventEmitter, HostBinding, Input, Output } from '@angular/core'; -import { Required } from '../../utils/decorators/required.decorator'; -import { CircleButtonType } from '../../buttons/types/circle-button.type'; +import { Required } from '../../utils'; +import { CircleButtonType } from '../../buttons'; @Component({ selector: 'iqser-editable-input', diff --git a/src/lib/inputs/index.ts b/src/lib/inputs/index.ts new file mode 100644 index 0000000..490b7a1 --- /dev/null +++ b/src/lib/inputs/index.ts @@ -0,0 +1,4 @@ +export * from './inputs.module'; +export * from './round-checkbox/round-checkbox.component'; +export * from './editable-input/editable-input.component'; +export * from './input-with-action/input-with-action.component'; diff --git a/src/lib/inputs/inputs.module.ts b/src/lib/inputs/inputs.module.ts new file mode 100644 index 0000000..2355853 --- /dev/null +++ b/src/lib/inputs/inputs.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { IqserButtonsModule } from '../buttons'; +import { RoundCheckboxComponent } from './round-checkbox/round-checkbox.component'; +import { EditableInputComponent } from './editable-input/editable-input.component'; +import { InputWithActionComponent } from './input-with-action/input-with-action.component'; +import { IqserIconsModule } from '../icons'; + +const modules = [IqserButtonsModule, FormsModule]; +const components = [RoundCheckboxComponent, EditableInputComponent, InputWithActionComponent]; + +@NgModule({ + declarations: [...components], + exports: [...components], + imports: [CommonModule, IqserIconsModule, ...modules] +}) +export class IqserInputsModule {} diff --git a/src/lib/tables/entities.service.ts b/src/lib/listing/entities.service.ts similarity index 72% rename from src/lib/tables/entities.service.ts rename to src/lib/listing/entities.service.ts index cfa79ad..e6dfe12 100644 --- a/src/lib/tables/entities.service.ts +++ b/src/lib/listing/entities.service.ts @@ -1,9 +1,8 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, combineLatest, Observable, pipe } from 'rxjs'; import { distinctUntilChanged, map, tap } from 'rxjs/operators'; -import { FilterService } from '../filtering/filter.service'; -import { SearchService } from '../search/search.service'; -import { getFilteredEntities } from '../filtering/filter-utils'; +import { FilterService, getFilteredEntities } from '../filtering'; +import { SearchService } from '../search'; import { Listable } from './models/listable'; const toLengthValue = (entities: unknown[]) => entities?.length ?? 0; @@ -11,25 +10,37 @@ const getLength = pipe(map(toLengthValue), distinctUntilChanged()); @Injectable() export class EntitiesService { + readonly displayed$: Observable; + readonly displayedLength$: Observable; + readonly noData$: Observable; + readonly areAllSelected$: Observable; + readonly areSomeSelected$: Observable; + readonly notAllSelected$: Observable; + readonly selected$: Observable<(string | number)[]>; + readonly selectedEntities$: Observable; + readonly selectedLength$: Observable; + readonly all$: Observable; + readonly allLength$: Observable; private readonly _all$ = new BehaviorSubject([]); - readonly all$ = this._all$.asObservable(); - readonly allLength$ = this._all$.pipe(getLength); - private _displayed: T[] = []; - readonly displayed$ = this._getDisplayed$; - readonly displayedLength$ = this.displayed$.pipe(getLength); - private readonly _selected$ = new BehaviorSubject<(string | number)[]>([]); - readonly selected$ = this._selected$.asObservable(); - readonly selectedEntities$ = this._selected$.asObservable().pipe(map(() => this.selected)); - readonly selectedLength$ = this._selected$.pipe(getLength); - readonly noData$ = this._noData$; - readonly areAllSelected$ = this._areAllSelected$; - readonly areSomeSelected$ = this._areSomeSelected$; - readonly notAllSelected$ = this._notAllSelected$; + constructor(private readonly _filterService: FilterService, private readonly _searchService: SearchService) { + this.all$ = this._all$.asObservable(); + this.allLength$ = this._all$.pipe(getLength); - constructor(private readonly _filterService: FilterService, private readonly _searchService: SearchService) {} + this.displayed$ = this._getDisplayed$; + this.displayedLength$ = this.displayed$.pipe(getLength); + + this.selected$ = this._selected$.asObservable(); + this.selectedEntities$ = this._selected$.asObservable().pipe(map(() => this.selected)); + this.selectedLength$ = this._selected$.pipe(getLength); + + this.noData$ = this._noData$; + this.areAllSelected$ = this._areAllSelected$; + this.areSomeSelected$ = this._areSomeSelected$; + this.notAllSelected$ = this._notAllSelected$; + } get all(): T[] { return Object.values(this._all$.getValue()); diff --git a/src/lib/listing/index.ts b/src/lib/listing/index.ts new file mode 100644 index 0000000..004b4bc --- /dev/null +++ b/src/lib/listing/index.ts @@ -0,0 +1,8 @@ +export * from './tables'; +export * from './workflow-listing'; + +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/tables/listing-component.directive.ts b/src/lib/listing/listing-component.directive.ts similarity index 84% rename from src/lib/tables/listing-component.directive.ts rename to src/lib/listing/listing-component.directive.ts index f878981..c28a074 100644 --- a/src/lib/tables/listing-component.directive.ts +++ b/src/lib/listing/listing-component.directive.ts @@ -1,14 +1,11 @@ import { Directive, Injector, OnDestroy } from '@angular/core'; import { combineLatest, Observable } from 'rxjs'; import { distinctUntilChanged, map, switchMap } from 'rxjs/operators'; -import { FilterService } from '../filtering/filter.service'; -import { SortingService } from '../sorting/sorting.service'; -import { SortingOrders } from '../sorting/models/sorting-order.type'; -import { Bind } from '../utils/decorators/bind.decorator'; -import { AutoUnsubscribe } from '../utils/auto-unsubscribe.directive'; -import { SearchService } from '../search/search.service'; -import { KeysOf } from '../utils/types/utility-types'; -import { TableColumnConfig } from './models/table-column-config.model'; +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'; diff --git a/src/lib/listing/listing.module.ts b/src/lib/listing/listing.module.ts new file mode 100644 index 0000000..04b5b05 --- /dev/null +++ b/src/lib/listing/listing.module.ts @@ -0,0 +1,18 @@ +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'; + +const components = [TableHeaderComponent]; +const modules = [TranslateModule, TablesModule, WorkflowListingModule, IqserFiltersModule, IqserInputsModule]; + +@NgModule({ + declarations: [...components], + exports: [...components, TablesModule, WorkflowListingModule], + imports: [CommonModule, ...modules] +}) +export class IqserListingModule {} diff --git a/src/lib/tables/models/listable.ts b/src/lib/listing/models/listable.ts similarity index 100% rename from src/lib/tables/models/listable.ts rename to src/lib/listing/models/listable.ts diff --git a/src/lib/tables/table-header/table-header.component.html b/src/lib/listing/table-header/table-header.component.html similarity index 100% rename from src/lib/tables/table-header/table-header.component.html rename to src/lib/listing/table-header/table-header.component.html diff --git a/src/lib/tables/table-header/table-header.component.scss b/src/lib/listing/table-header/table-header.component.scss similarity index 100% rename from src/lib/tables/table-header/table-header.component.scss rename to src/lib/listing/table-header/table-header.component.scss diff --git a/src/lib/tables/table-header/table-header.component.ts b/src/lib/listing/table-header/table-header.component.ts similarity index 71% rename from src/lib/tables/table-header/table-header.component.ts rename to src/lib/listing/table-header/table-header.component.ts index 158e17c..86bbb4e 100644 --- a/src/lib/tables/table-header/table-header.component.ts +++ b/src/lib/listing/table-header/table-header.component.ts @@ -1,9 +1,16 @@ import { ChangeDetectionStrategy, Component, Input, TemplateRef } from '@angular/core'; -import { Required } from '../../utils/decorators/required.decorator'; -import { FilterService } from '../../filtering/filter.service'; -import { TableColumnConfig } from '../models/table-column-config.model'; +import { Required } from '../../utils'; +import { FilterService } from '../../filtering'; import { EntitiesService } from '../entities.service'; import { Listable } from '../models/listable'; +import { TableColumnConfig } from '../tables'; + +export const ListingModes = { + list: 'list', + workflow: 'workflow' +} as const; + +export type ListingMode = keyof typeof ListingModes; @Component({ selector: 'iqser-table-header', @@ -16,6 +23,7 @@ export class TableHeaderComponent { @Input() @Required() tableColumnConfigs!: readonly TableColumnConfig[]; @Input() hasEmptyColumn = false; @Input() selectionEnabled = false; + @Input() mode: ListingMode = ListingModes.list; @Input() bulkActions?: TemplateRef; constructor(readonly entitiesService: EntitiesService, readonly filterService: FilterService) {} diff --git a/src/lib/listing/tables/index.ts b/src/lib/listing/tables/index.ts new file mode 100644 index 0000000..2cad679 --- /dev/null +++ b/src/lib/listing/tables/index.ts @@ -0,0 +1,4 @@ +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/tables/models/table-column-config.model.ts b/src/lib/listing/tables/models/table-column-config.model.ts similarity index 82% rename from src/lib/tables/models/table-column-config.model.ts rename to src/lib/listing/tables/models/table-column-config.model.ts index 502c9c0..997a7cf 100644 --- a/src/lib/tables/models/table-column-config.model.ts +++ b/src/lib/listing/tables/models/table-column-config.model.ts @@ -1,4 +1,4 @@ -import { KeysOf } from '../../utils/types/utility-types'; +import { KeysOf } from '../../../utils'; export interface TableColumnConfig { readonly label: string; diff --git a/src/lib/tables/sync-width.directive.ts b/src/lib/listing/tables/sync-width.directive.ts similarity index 100% rename from src/lib/tables/sync-width.directive.ts rename to src/lib/listing/tables/sync-width.directive.ts diff --git a/src/lib/tables/table-column-name/table-column-name.component.html b/src/lib/listing/tables/table-column-name/table-column-name.component.html similarity index 100% rename from src/lib/tables/table-column-name/table-column-name.component.html rename to src/lib/listing/tables/table-column-name/table-column-name.component.html diff --git a/src/lib/tables/table-column-name/table-column-name.component.scss b/src/lib/listing/tables/table-column-name/table-column-name.component.scss similarity index 95% rename from src/lib/tables/table-column-name/table-column-name.component.scss rename to src/lib/listing/tables/table-column-name/table-column-name.component.scss index 87a10b1..ed0a5d7 100644 --- a/src/lib/tables/table-column-name/table-column-name.component.scss +++ b/src/lib/listing/tables/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/tables/table-column-name/table-column-name.component.ts b/src/lib/listing/tables/table-column-name/table-column-name.component.ts similarity index 75% rename from src/lib/tables/table-column-name/table-column-name.component.ts rename to src/lib/listing/tables/table-column-name/table-column-name.component.ts index 1bb53a2..887cb14 100644 --- a/src/lib/tables/table-column-name/table-column-name.component.ts +++ b/src/lib/listing/tables/table-column-name/table-column-name.component.ts @@ -1,8 +1,6 @@ import { ChangeDetectionStrategy, Component, Input, Optional } from '@angular/core'; -import { SortingOrders } from '../../sorting/models/sorting-order.type'; -import { Required } from '../../utils/decorators/required.decorator'; -import { KeysOf } from '../../utils/types/utility-types'; -import { SortingService } from '../../sorting/sorting.service'; +import { SortingOrders, SortingService } from '../../../sorting'; +import { KeysOf, Required } from '../../../utils'; const ifHasRightIcon = (thisArg: TableColumnNameComponent) => !!thisArg.rightIcon; diff --git a/src/lib/listing/tables/tables-module.ts b/src/lib/listing/tables/tables-module.ts new file mode 100644 index 0000000..96a9db2 --- /dev/null +++ b/src/lib/listing/tables/tables-module.ts @@ -0,0 +1,18 @@ +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 new file mode 100644 index 0000000..87b1b5e --- /dev/null +++ b/src/lib/listing/workflow-listing/index.ts @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000..66d6d54 --- /dev/null +++ b/src/lib/listing/workflow-listing/workflow-listing.module.ts @@ -0,0 +1,12 @@ +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/loading/index.ts b/src/lib/loading/index.ts new file mode 100644 index 0000000..1e20ea8 --- /dev/null +++ b/src/lib/loading/index.ts @@ -0,0 +1,2 @@ +export * from './loading.service'; +export * from './full-page-loading-indicator/full-page-loading-indicator.component'; diff --git a/src/lib/misc/index.ts b/src/lib/misc/index.ts new file mode 100644 index 0000000..cafdfb0 --- /dev/null +++ b/src/lib/misc/index.ts @@ -0,0 +1,2 @@ +export * from './status-bar/status-bar.component'; +export * from './status-bar/status-bar-config.model'; diff --git a/src/lib/search/index.ts b/src/lib/search/index.ts new file mode 100644 index 0000000..51370b5 --- /dev/null +++ b/src/lib/search/index.ts @@ -0,0 +1 @@ +export * from './search.service'; diff --git a/src/lib/search/search.service.ts b/src/lib/search/search.service.ts index 81b55dc..2ef1dbf 100644 --- a/src/lib/search/search.service.ts +++ b/src/lib/search/search.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; -import { KeysOf } from '../utils/types/utility-types'; +import { KeysOf } from '../utils'; @Injectable() export class SearchService { diff --git a/src/lib/services/index.ts b/src/lib/services/index.ts new file mode 100644 index 0000000..819e2f9 --- /dev/null +++ b/src/lib/services/index.ts @@ -0,0 +1,2 @@ +export * from './toaster.service'; +export * from './error-message.service'; diff --git a/src/lib/sorting/index.ts b/src/lib/sorting/index.ts new file mode 100644 index 0000000..ce59a22 --- /dev/null +++ b/src/lib/sorting/index.ts @@ -0,0 +1,4 @@ +export * from './sort-by.pipe'; +export * from './sorting.service'; +export * from './models/sorting-option.model'; +export * from './models/sorting-order.type'; diff --git a/src/lib/sorting/models/sorting-option.model.ts b/src/lib/sorting/models/sorting-option.model.ts index cfdd87b..c20f4ab 100644 --- a/src/lib/sorting/models/sorting-option.model.ts +++ b/src/lib/sorting/models/sorting-option.model.ts @@ -1,5 +1,5 @@ import { SortingOrder } from './sorting-order.type'; -import { KeysOf } from '../../utils/types/utility-types'; +import { KeysOf } from '../../utils'; export interface SortingOption { readonly order: SortingOrder; diff --git a/src/lib/sorting/models/sorting-order.type.ts b/src/lib/sorting/models/sorting-order.type.ts index 587d266..8869403 100644 --- a/src/lib/sorting/models/sorting-order.type.ts +++ b/src/lib/sorting/models/sorting-order.type.ts @@ -1,4 +1,4 @@ -import { NonFunctionKeys } from '../../utils/types/utility-types'; +import { NonFunctionKeys } from '../../utils'; export const SortingOrders = { asc: 'asc', diff --git a/src/lib/sorting/sort-by.pipe.ts b/src/lib/sorting/sort-by.pipe.ts index c19a517..522a916 100644 --- a/src/lib/sorting/sort-by.pipe.ts +++ b/src/lib/sorting/sort-by.pipe.ts @@ -1,7 +1,7 @@ import { Pipe, PipeTransform } from '@angular/core'; import { SortingService } from './sorting.service'; import { SortingOrder } from './models/sorting-order.type'; -import { KeysOf } from '../utils/types/utility-types'; +import { KeysOf } from '../utils'; @Pipe({ name: 'sortBy' }) export class SortByPipe implements PipeTransform { diff --git a/src/lib/sorting/sorting.service.ts b/src/lib/sorting/sorting.service.ts index 7011051..d3a8af3 100644 --- a/src/lib/sorting/sorting.service.ts +++ b/src/lib/sorting/sorting.service.ts @@ -3,7 +3,7 @@ import { orderBy } from 'lodash'; import { BehaviorSubject } from 'rxjs'; import { SortingOption } from './models/sorting-option.model'; import { SortingOrder, SortingOrders } from './models/sorting-order.type'; -import { KeysOf } from '../utils/types/utility-types'; +import { KeysOf } from '../utils'; @Injectable() export class SortingService { diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts new file mode 100644 index 0000000..e601a91 --- /dev/null +++ b/src/lib/utils/index.ts @@ -0,0 +1,10 @@ +export * from './functions'; +export * from './operators'; +export * from './auto-unsubscribe.directive'; +export * from './pipes/humanize.pipe'; +export * from './types/events.type'; +export * from './types/utility-types'; +export * from './types/tooltip-positions.type'; +export * from './decorators/bind.decorator'; +export * from './decorators/required.decorator'; +export * from './decorators/debounce.decorator';