make inputs standalone

This commit is contained in:
Dan Percic 2023-03-19 12:01:43 +02:00
parent 0057b3c4b0
commit c9c2f3e0f9
15 changed files with 56 additions and 87 deletions

View File

@ -8,7 +8,6 @@ import { ToastComponent } from './shared';
import { ConnectionStatusComponent, FullPageErrorComponent } from './error';
import { IqserListingModule } from './listing';
import { IqserFiltersModule } from './filtering';
import { IqserInputsModule } from './inputs';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button';
import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/legacy-checkbox';
@ -33,7 +32,7 @@ const matModules = [
MatTooltipModule,
MatProgressBarModule,
];
const modules = [IqserListingModule, IqserFiltersModule, IqserInputsModule, HttpClientModule];
const modules = [IqserListingModule, IqserFiltersModule, HttpClientModule];
const components = [ConnectionStatusComponent, FullPageErrorComponent, ConfirmationDialogComponent, ToastComponent];
@NgModule({

View File

@ -2,3 +2,4 @@ export * from './hidden-action.directive';
export * from './stop-propagation.directive';
export * from './prevent-default.directive';
export * from './has-scrollbar.directive';
export * from './sync-width.directive';

View File

@ -2,27 +2,28 @@ import { Directive, ElementRef, HostListener, Input, OnDestroy } from '@angular/
@Directive({
selector: '[iqserSyncWidth]',
standalone: true,
})
export class SyncWidthDirective implements OnDestroy {
@Input() iqserSyncWidth!: string;
private readonly _interval: number;
readonly #interval: number;
constructor(private readonly _elementRef: ElementRef) {
this._interval = window.setInterval(() => {
this._matchWidth();
this.#interval = window.setInterval(() => {
this.#matchWidth();
}, 1000);
}
ngOnDestroy(): void {
window.clearInterval(this._interval);
ngOnDestroy() {
window.clearInterval(this.#interval);
}
@HostListener('window:resize')
onResize(): void {
this._matchWidth();
onResize() {
this.#matchWidth();
}
private _matchWidth() {
#matchWidth() {
const headerItems = (this._elementRef.nativeElement as HTMLElement).children;
const tableRows = (this._elementRef.nativeElement as HTMLElement).parentElement?.parentElement?.getElementsByClassName(
this.iqserSyncWidth,
@ -34,7 +35,7 @@ export class SyncWidthDirective implements OnDestroy {
(this._elementRef.nativeElement as HTMLElement).setAttribute('synced', 'true');
const { columns, length } = this._sampleRow(tableRows);
const { columns, length } = this.#sampleRow(tableRows);
if (!columns) {
return;
}
@ -57,7 +58,7 @@ export class SyncWidthDirective implements OnDestroy {
}
}
private _sampleRow(tableRows: HTMLCollectionOf<Element>): {
#sampleRow(tableRows: HTMLCollectionOf<Element>): {
columns?: Element[];
length: number;
} {

View File

@ -6,12 +6,12 @@ import { TranslateModule } from '@ngx-translate/core';
import { ChevronButtonComponent, IconButtonComponent } from '../buttons';
import { PopupFilterComponent } from './popup-filter/popup-filter.component';
import { QuickFiltersComponent } from './quick-filters/quick-filters.component';
import { IqserInputsModule } from '../inputs';
import { IqserHelpModeModule } from '../help-mode';
import { SingleFilterComponent } from './single-filter/single-filter.component';
import { FilterCardComponent } from './filter-card/filter-card.component';
import { MatIconModule } from '@angular/material/icon';
import { PreventDefaultDirective, StopPropagationDirective } from '../directives';
import { InputWithActionComponent } from '../inputs';
const matModules = [MatCheckboxModule, MatMenuModule];
const components = [QuickFiltersComponent, PopupFilterComponent, SingleFilterComponent, FilterCardComponent];
@ -23,13 +23,13 @@ const components = [QuickFiltersComponent, PopupFilterComponent, SingleFilterCom
CommonModule,
...matModules,
TranslateModule,
IqserInputsModule,
IqserHelpModeModule,
IconButtonComponent,
ChevronButtonComponent,
MatIconModule,
StopPropagationDirective,
PreventDefaultDirective,
InputWithActionComponent,
],
})
export class IqserFiltersModule {}

View File

@ -1,16 +1,17 @@
<div class="iqser-input-group" [class.row]="displayInRow">
<div [class.row]="displayInRow" class="iqser-input-group">
<div
[id]="groupId(option)"
(click)="toggleOption(option)"
*ngFor="let option of options"
[class.active]="option.value === value?.value"
class="option pointer"
[id]="groupId(option)"
[ngClass]="{ 'mb-8': !displayInRow, 'mr-8': displayInRow }"
class="option pointer"
>
<div class="flex-align-items-center mb-8">
<iqser-round-checkbox [active]="option.value === value?.value" class="mr-6"></iqser-round-checkbox>
<label class="details-radio-label pointer">{{ option.label | translate }}</label>
</div>
<span class="hint">{{ option.description | translate }}</span>
</div>
</div>

View File

@ -2,11 +2,15 @@ import { Component, Input } from '@angular/core';
import { DetailsRadioOption } from './details-radio-option';
import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
import { FormFieldComponent } from '../form-field/form-field-component.directive';
import { NgClass, NgForOf } from '@angular/common';
import { RoundCheckboxComponent } from '../round-checkbox/round-checkbox.component';
import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'iqser-details-radio [options]',
templateUrl: './details-radio.component.html',
styleUrls: ['./details-radio.component.scss'],
standalone: true,
providers: [
{
provide: NG_VALUE_ACCESSOR,
@ -19,10 +23,11 @@ import { FormFieldComponent } from '../form-field/form-field-component.directive
useExisting: DetailsRadioComponent,
},
],
imports: [NgForOf, NgClass, RoundCheckboxComponent, TranslateModule],
})
export class DetailsRadioComponent<I> extends FormFieldComponent<DetailsRadioOption<I>> {
@Input() options: DetailsRadioOption<I>[] = [];
@Input() displayInRow?: boolean = false;
@Input() displayInRow = false;
toggleOption(option: DetailsRadioOption<I>): void {
this.markAsTouched();

View File

@ -1,6 +1,11 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
import { FormsModule, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
import { FormFieldComponent } from '../form-field/form-field-component.directive';
import { NgClass, NgIf } from '@angular/common';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { StopPropagationDirective } from '../../directives';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
const InputTypes = {
DATE: 'DATE',
@ -18,6 +23,7 @@ type DynamicInput = number | string | Date;
templateUrl: './dynamic-input.component.html',
styleUrls: ['./dynamic-input.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
providers: [
{
provide: NG_VALUE_ACCESSOR,
@ -30,23 +36,17 @@ type DynamicInput = number | string | Date;
useExisting: DynamicInputComponent,
},
],
imports: [NgClass, NgIf, FormsModule, MatDatepickerModule, StopPropagationDirective, MatIconModule, MatInputModule],
})
export class DynamicInputComponent extends FormFieldComponent<DynamicInput> {
@Input() label?: string;
@Input() type!: InputType;
@Input() placeholder?: string;
@Input() id?: string;
@Input() name?: string;
@Input() classList?: string = '';
@Input() input!: DynamicInput;
@Output() closedDatepicker = new EventEmitter<boolean>();
@Output() readonly closedDatepicker = new EventEmitter<boolean>();
get isDate() {
return this.type === InputTypes.DATE;

View File

@ -1,11 +1,15 @@
import { ChangeDetectionStrategy, Component, EventEmitter, HostBinding, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { CircleButtonType } from '../../buttons';
import { CircleButtonComponent, CircleButtonType } from '../../buttons';
import { NgIf } from '@angular/common';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'iqser-editable-input [value]',
templateUrl: './editable-input.component.html',
styleUrls: ['./editable-input.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [NgIf, CircleButtonComponent, FormsModule],
})
export class EditableInputComponent implements OnChanges {
@Input() value!: string;

View File

@ -1,4 +1,3 @@
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';

View File

@ -1,35 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
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 { DetailsRadioComponent } from './details-radio/details-radio.component';
import { TranslateModule } from '@ngx-translate/core';
import { DynamicInputComponent } from './dynamic-input/dynamic-input.component';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatInputModule } from '@angular/material/input';
import { CircleButtonComponent } from '../buttons';
import { MatIconModule } from '@angular/material/icon';
import { StopPropagationDirective } from '../directives';
const components = [RoundCheckboxComponent, EditableInputComponent, DetailsRadioComponent, DynamicInputComponent];
const deleteThisWhenAllComponentsAreStandalone = [InputWithActionComponent];
@NgModule({
declarations: [...components],
exports: [...components, ...deleteThisWhenAllComponentsAreStandalone],
imports: [
CommonModule,
MatIconModule,
TranslateModule,
FormsModule,
ReactiveFormsModule,
MatDatepickerModule,
MatInputModule,
...deleteThisWhenAllComponentsAreStandalone,
CircleButtonComponent,
StopPropagationDirective,
],
})
export class IqserInputsModule {}

View File

@ -1,10 +1,14 @@
import { ChangeDetectionStrategy, Component, ElementRef, HostBinding, Input, OnInit, ViewChild } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';
import { NgIf } from '@angular/common';
@Component({
selector: 'iqser-round-checkbox',
templateUrl: './round-checkbox.component.html',
styleUrls: ['./round-checkbox.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [MatIconModule, NgIf],
})
export class RoundCheckboxComponent implements OnInit {
@Input() size = 20;

View File

@ -9,8 +9,6 @@ export * from './table-header/table-header.component';
export * from './workflow/workflow.component';
export * from './sync-width.directive';
export * from './listing.module';
export * from './listing-component.directive';

View File

@ -3,12 +3,11 @@ import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { TableHeaderComponent } from './table-header/table-header.component';
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 { HasScrollbarDirective, SyncWidthDirective } from '../directives';
import { ScrollingModule } from '@angular/cdk/scrolling';
import { RouterModule } from '@angular/router';
import { WorkflowComponent } from './workflow/workflow.component';
@ -21,9 +20,9 @@ import { ColumnHeaderComponent } from './workflow/column-header/column-header.co
import { CircleButtonComponent, IconButtonComponent } from '../buttons';
import { MatIconModule } from '@angular/material/icon';
import { EmptyStateComponent } from '../empty-state';
import { HasScrollbarDirective } from '../scrollbar';
import { InputWithActionComponent, RoundCheckboxComponent } from '../inputs';
const matModules = [MatTooltipModule];
const matModules = [MatTooltipModule, MatIconModule];
const components = [
TableHeaderComponent,
TableComponent,
@ -35,21 +34,11 @@ const components = [
TableItemComponent,
ColumnHeaderComponent,
];
const modules = [
DragDropModule,
TranslateModule,
IqserFiltersModule,
IqserInputsModule,
MatIconModule,
ScrollingModule,
RouterModule,
IqserHelpModeModule,
];
const utils = [SyncWidthDirective];
const modules = [DragDropModule, TranslateModule, IqserFiltersModule, ScrollingModule, RouterModule, IqserHelpModeModule];
@NgModule({
declarations: [...components, ...utils],
exports: [...components, ...utils],
declarations: [...components],
exports: [...components],
imports: [
CommonModule,
...modules,
@ -58,6 +47,9 @@ const utils = [SyncWidthDirective];
IconButtonComponent,
EmptyStateComponent,
HasScrollbarDirective,
RoundCheckboxComponent,
InputWithActionComponent,
SyncWidthDirective,
],
})
export class IqserListingModule {}

View File

@ -6,7 +6,7 @@ import { IListable } from '../models';
import { IconButtonTypes } from '../../buttons';
import { SearchService } from '../../search';
import { FilterService } from '../../filtering';
import { filterEach } from '../../utils';
import { filterEach, List } from '../../utils';
@Component({
selector: 'iqser-page-header',
@ -22,8 +22,8 @@ export class PageHeaderComponent<T extends IListable> {
@Input() searchInputId?: string;
@Input() showCloseButton = false;
@Input() hideResetButton = false;
@Input() actionConfigs?: readonly ActionConfig[];
@Input() buttonConfigs?: readonly ButtonConfig[];
@Input() actionConfigs?: List<ActionConfig>;
@Input() buttonConfigs?: List<ButtonConfig>;
@Input() viewModeSelection?: TemplateRef<unknown>;
@Input() searchPlaceholder?: string;
@Input() searchWidth?: number | 'full';

View File

@ -5,9 +5,9 @@ import { delay, tap } from 'rxjs/operators';
import { AutoUnsubscribe, trackByFactory } from '../../utils';
import { Id, IListable } from '../models';
import { ListingComponent, ListingService } from '../index';
import { HasScrollbarDirective } from '../../scrollbar';
import { BehaviorSubject } from 'rxjs';
import { HelpModeService } from '../../help-mode';
import { HasScrollbarDirective } from '../../directives';
@Component({
selector: 'iqser-table-content',