diff --git a/src/index.ts b/src/index.ts index 7ab9455..7ba5ca1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,6 @@ export * from './lib/form'; export * from './lib/listing'; export * from './lib/filtering'; export * from './lib/help-mode'; -export * from './lib/icons'; export * from './lib/inputs'; export * from './lib/utils'; export * from './lib/sorting'; diff --git a/src/lib/buttons/chevron-button/chevron-button.component.ts b/src/lib/buttons/chevron-button/chevron-button.component.ts index ed99f27..97ff7ed 100644 --- a/src/lib/buttons/chevron-button/chevron-button.component.ts +++ b/src/lib/buttons/chevron-button/chevron-button.component.ts @@ -1,15 +1,15 @@ import { Component, Input } from '@angular/core'; import { randomString } from '../../utils'; import { NgIf } from '@angular/common'; -import { IqserIconsModule } from '../../icons'; import { MatLegacyButtonModule } from '@angular/material/legacy-button'; +import { MatIconModule } from '@angular/material/icon'; @Component({ selector: 'iqser-chevron-button [label]', templateUrl: './chevron-button.component.html', styleUrls: ['./chevron-button.component.scss'], standalone: true, - imports: [NgIf, IqserIconsModule, MatLegacyButtonModule], + imports: [NgIf, MatIconModule, MatLegacyButtonModule], }) export class ChevronButtonComponent { @Input() label!: string; diff --git a/src/lib/buttons/circle-button/circle-button.component.ts b/src/lib/buttons/circle-button/circle-button.component.ts index 2c54e64..4ca1718 100644 --- a/src/lib/buttons/circle-button/circle-button.component.ts +++ b/src/lib/buttons/circle-button/circle-button.component.ts @@ -4,14 +4,14 @@ import { CircleButtonType, CircleButtonTypes } from '../types/circle-button.type import { IqserTooltipPosition, IqserTooltipPositions, randomString } from '../../utils'; import { NgIf } from '@angular/common'; import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button'; -import { IqserIconsModule } from '../../icons'; +import { MatIconModule } from '@angular/material/icon'; @Component({ selector: 'iqser-circle-button [icon]', templateUrl: './circle-button.component.html', styleUrls: ['./circle-button.component.scss'], standalone: true, - imports: [MatTooltipModule, IqserIconsModule, NgIf, MatButtonModule], + imports: [MatTooltipModule, MatIconModule, NgIf, MatButtonModule], }) export class CircleButtonComponent implements OnInit { readonly circleButtonTypes = CircleButtonTypes; diff --git a/src/lib/buttons/icon-button/icon-button.component.ts b/src/lib/buttons/icon-button/icon-button.component.ts index af4b442..f1d5bfa 100644 --- a/src/lib/buttons/icon-button/icon-button.component.ts +++ b/src/lib/buttons/icon-button/icon-button.component.ts @@ -3,14 +3,14 @@ import { IconButtonType, IconButtonTypes } from '../types/icon-button.type'; import { randomString } from '../../utils'; import { NgClass, NgIf } from '@angular/common'; import { MatLegacyButtonModule as MatButtonModule } from '@angular/material/legacy-button'; -import { IqserIconsModule } from '../../icons'; +import { MatIconModule } from '@angular/material/icon'; @Component({ selector: 'iqser-icon-button [label]', templateUrl: './icon-button.component.html', styleUrls: ['./icon-button.component.scss'], standalone: true, - imports: [NgClass, MatButtonModule, NgIf, IqserIconsModule], + imports: [NgClass, MatButtonModule, NgIf, MatIconModule], }) export class IconButtonComponent { readonly iconButtonTypes = IconButtonTypes; diff --git a/src/lib/common-ui.module.ts b/src/lib/common-ui.module.ts index ff49106..7b5ec70 100644 --- a/src/lib/common-ui.module.ts +++ b/src/lib/common-ui.module.ts @@ -1,16 +1,15 @@ -import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; +import { inject, ModuleWithProviders, NgModule, Optional, Provider, SkipSelf } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { MatIconModule } from '@angular/material/icon'; +import { MatIconModule, MatIconRegistry } from '@angular/material/icon'; import { TranslateModule } from '@ngx-translate/core'; import { MatLegacyProgressSpinnerModule as MatProgressSpinnerModule } from '@angular/material/legacy-progress-spinner'; import { SortByPipe } from './sorting'; -import { CommonUiOptions, IqserAppConfig, ModuleWithOptions } from './utils'; +import { CommonUiOptions, IqserAppConfig, ModuleOptions } from './utils'; import { HiddenActionComponent, ToastComponent } from './shared'; import { ConnectionStatusComponent, FullPageErrorComponent } from './error'; import { IqserListingModule } from './listing'; import { IqserFiltersModule } from './filtering'; import { IqserInputsModule } from './inputs'; -import { IqserIconsModule } from './icons'; import { IqserScrollbarModule } from './scrollbar'; import { IqserEmptyStatesModule } from './empty-states'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -24,6 +23,8 @@ import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; import { IqserSkeletonModule } from './skeleton/skeleton.module'; import { MatDialogModule } from '@angular/material/dialog'; import { CircleButtonComponent, IconButtonComponent } from './buttons'; +import { DomSanitizer } from '@angular/platform-browser'; +import { ICONS } from './utils/constants'; const matModules = [ MatIconModule, @@ -35,7 +36,6 @@ const matModules = [ MatProgressBarModule, ]; const modules = [ - IqserIconsModule, IqserListingModule, IqserFiltersModule, IqserInputsModule, @@ -69,12 +69,19 @@ const pipes = [SortByPipe]; }, ], }) -export class CommonUiModule extends ModuleWithOptions { +export class CommonUiModule { constructor(@Optional() @SkipSelf() parentModule?: CommonUiModule) { - super(); if (parentModule) { throw new Error('CommonUiModule is already loaded. Import it in the AppModule only!'); } + + const iconRegistry = inject(MatIconRegistry); + const sanitizer = inject(DomSanitizer); + + ICONS.forEach(icon => { + const url = sanitizer.bypassSecurityTrustResourceUrl(`/assets/icons/${icon}.svg`); + iconRegistry.addSvgIconInNamespace('iqser', icon, url); + }); } static forRoot< @@ -82,7 +89,7 @@ export class CommonUiModule extends ModuleWithOptions { Config extends IqserConfigService, AppConfig extends IqserAppConfig = IqserAppConfig, >(options: CommonUiOptions): ModuleWithProviders { - const userPreferenceService = this._getService( + const userPreferenceService = ModuleOptions.getService( IqserUserPreferenceService, DefaultUserPreferenceService, options.existingUserPreferenceService, @@ -92,11 +99,11 @@ export class CommonUiModule extends ModuleWithOptions { return { ngModule: CommonUiModule, - providers: [userPreferenceService, configServiceProviders], + providers: [userPreferenceService, ...configServiceProviders], }; } - private static _getConfigServiceProviders(configServiceFactory: () => unknown, configService?: unknown) { + private static _getConfigServiceProviders(configServiceFactory: () => unknown, configService?: unknown): Provider[] { if (configService) { return [ { diff --git a/src/lib/empty-states/empty-state.module.ts b/src/lib/empty-states/empty-state.module.ts index e381ed7..2d9c626 100644 --- a/src/lib/empty-states/empty-state.module.ts +++ b/src/lib/empty-states/empty-state.module.ts @@ -1,16 +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 { IconButtonComponent } from '../buttons'; import { IqserHelpModeModule } from '../help-mode'; +import { MatIconModule } from '@angular/material/icon'; -const modules = [IqserIconsModule, IqserHelpModeModule]; const components = [EmptyStateComponent]; @NgModule({ declarations: [...components], - imports: [CommonModule, ...modules, IconButtonComponent], + imports: [CommonModule, MatIconModule, IqserHelpModeModule, IconButtonComponent], exports: [...components], }) export class IqserEmptyStatesModule {} diff --git a/src/lib/filtering/filter-card/filter-card.component.html b/src/lib/filtering/filter-card/filter-card.component.html index db78647..106abe0 100644 --- a/src/lib/filtering/filter-card/filter-card.component.html +++ b/src/lib/filtering/filter-card/filter-card.component.html @@ -42,6 +42,7 @@ {{ filter?.label }} +
@@ -61,6 +62,7 @@
+
diff --git a/src/lib/filtering/filters.module.ts b/src/lib/filtering/filters.module.ts index 733d917..6792de7 100644 --- a/src/lib/filtering/filters.module.ts +++ b/src/lib/filtering/filters.module.ts @@ -6,19 +6,19 @@ 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 { IqserIconsModule } from '../icons'; 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'; const matModules = [MatCheckboxModule, MatMenuModule]; -const modules = [TranslateModule, IqserIconsModule, IqserInputsModule, IqserHelpModeModule]; +const modules = [TranslateModule, IqserInputsModule, IqserHelpModeModule]; const components = [QuickFiltersComponent, PopupFilterComponent, SingleFilterComponent, FilterCardComponent]; @NgModule({ declarations: [...components], exports: [...components], - imports: [CommonModule, ...matModules, ...modules, IconButtonComponent, ChevronButtonComponent], + imports: [CommonModule, ...matModules, ...modules, IconButtonComponent, ChevronButtonComponent, MatIconModule], }) export class IqserFiltersModule {} diff --git a/src/lib/help-mode/help-mode.module.ts b/src/lib/help-mode/help-mode.module.ts index ca3c926..1de5c68 100644 --- a/src/lib/help-mode/help-mode.module.ts +++ b/src/lib/help-mode/help-mode.module.ts @@ -4,7 +4,6 @@ import { TranslateModule } from '@ngx-translate/core'; import { HelpModeDialogComponent } from './help-mode-dialog/help-mode-dialog.component'; import { HelpModeComponent } from './help-mode/help-mode.component'; import { HelpModeDirective } from './help-mode.directive'; -import { IqserIconsModule } from '../icons'; import { HelpButtonComponent } from './help-button/help-button.component'; import { HelpModeService } from './help-mode.service'; import { HelpDocs } from './help-docs'; @@ -12,12 +11,11 @@ import { HELP_DOCS } from './tokens'; import { MatDialogModule } from '@angular/material/dialog'; import { CircleButtonComponent } from '../buttons'; -const matModules = [MatDialogModule]; const components = [HelpModeComponent, HelpModeDialogComponent, HelpModeDirective, HelpButtonComponent]; @NgModule({ declarations: [...components], - imports: [CommonModule, IqserIconsModule, ...matModules, TranslateModule, CircleButtonComponent], + imports: [CommonModule, MatDialogModule, TranslateModule, CircleButtonComponent], exports: [...components], }) export class IqserHelpModeModule { diff --git a/src/lib/icons/icons.module.ts b/src/lib/icons/icons.module.ts deleted file mode 100644 index ff8ab25..0000000 --- a/src/lib/icons/icons.module.ts +++ /dev/null @@ -1,53 +0,0 @@ -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', - 'arrow-down-o', - 'arrow-right', - 'check', - 'close', - 'collapse', - 'copy', - 'csv', - 'document', - 'download', - 'edit', - 'expand', - 'failure', - 'help-outline', - 'lanes', - 'list', - 'logout', - 'menu', - 'more-actions', - 'ocr', - 'offline', - 'pages', - 'plus', - 'radio-indeterminate', - 'radio-selected', - 'refresh', - 'search', - 'settings', - 'sort-asc', - 'sort-desc', - 'status-collapse', - 'status-expand', - 'trash', - 'upload', - ]); - 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 deleted file mode 100644 index e93c671..0000000 --- a/src/lib/icons/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './icons.module'; diff --git a/src/lib/inputs/input-with-action/input-with-action.component.ts b/src/lib/inputs/input-with-action/input-with-action.component.ts index 0084004..8fff104 100644 --- a/src/lib/inputs/input-with-action/input-with-action.component.ts +++ b/src/lib/inputs/input-with-action/input-with-action.component.ts @@ -3,7 +3,7 @@ import { randomString } from '../../utils'; import { FormsModule } from '@angular/forms'; import { NgIf } from '@angular/common'; import { CircleButtonComponent } from '../../buttons'; -import { IqserIconsModule } from '../../icons'; +import { MatIconModule } from '@angular/material/icon'; @Component({ selector: 'iqser-input-with-action', @@ -11,7 +11,7 @@ import { IqserIconsModule } from '../../icons'; styleUrls: ['./input-with-action.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, - imports: [FormsModule, NgIf, IqserIconsModule, CircleButtonComponent], + imports: [FormsModule, NgIf, MatIconModule, CircleButtonComponent], }) export class InputWithActionComponent { @Input() inputId = `${randomString() + '-search-input'}`; diff --git a/src/lib/inputs/inputs.module.ts b/src/lib/inputs/inputs.module.ts index ef52be3..a502e9b 100644 --- a/src/lib/inputs/inputs.module.ts +++ b/src/lib/inputs/inputs.module.ts @@ -4,7 +4,6 @@ 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 { IqserIconsModule } from '../icons'; import { DetailsRadioComponent } from './details-radio/details-radio.component'; import { TranslateModule } from '@ngx-translate/core'; import { DynamicInputComponent } from './dynamic-input/dynamic-input.component'; @@ -12,15 +11,25 @@ import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatInputModule } from '@angular/material/input'; import { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field'; import { CircleButtonComponent } from '../buttons'; +import { MatIconModule } from '@angular/material/icon'; -const modules = [IqserIconsModule, TranslateModule, FormsModule, ReactiveFormsModule, MatDatepickerModule, MatInputModule]; const components = [RoundCheckboxComponent, EditableInputComponent, DetailsRadioComponent, DynamicInputComponent]; const deleteThisWhenAllComponentsAreStandalone = [InputWithActionComponent]; @NgModule({ declarations: [...components], exports: [...components, ...deleteThisWhenAllComponentsAreStandalone], - imports: [CommonModule, ...modules, ...deleteThisWhenAllComponentsAreStandalone, CircleButtonComponent], + imports: [ + CommonModule, + MatIconModule, + TranslateModule, + FormsModule, + ReactiveFormsModule, + MatDatepickerModule, + MatInputModule, + ...deleteThisWhenAllComponentsAreStandalone, + CircleButtonComponent, + ], providers: [{ provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { appearance: 'outline' } }], }) export class IqserInputsModule {} diff --git a/src/lib/listing/listing.module.ts b/src/lib/listing/listing.module.ts index acf2aa8..be31890 100644 --- a/src/lib/listing/listing.module.ts +++ b/src/lib/listing/listing.module.ts @@ -10,7 +10,6 @@ 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'; import { IqserEmptyStatesModule } from '../empty-states'; @@ -22,6 +21,7 @@ import { TableContentComponent } from './table-content/table-content.component'; import { TableItemComponent } from './table-content/table-item/table-item.component'; import { ColumnHeaderComponent } from './workflow/column-header/column-header.component'; import { CircleButtonComponent, IconButtonComponent } from '../buttons'; +import { MatIconModule } from '@angular/material/icon'; const matModules = [MatTooltipModule]; const components = [ @@ -40,7 +40,7 @@ const modules = [ TranslateModule, IqserFiltersModule, IqserInputsModule, - IqserIconsModule, + MatIconModule, IqserScrollbarModule, IqserEmptyStatesModule, ScrollingModule, diff --git a/src/lib/shared/shared.module.ts b/src/lib/shared/shared.module.ts index fcdd28e..91757e9 100644 --- a/src/lib/shared/shared.module.ts +++ b/src/lib/shared/shared.module.ts @@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'; import { LogoComponent, SideNavComponent, SmallChipComponent, StatusBarComponent } from './index'; import { CommonModule } from '@angular/common'; import { MatTooltipModule } from '@angular/material/tooltip'; -import { IqserIconsModule } from '../icons'; +import { MatIconModule } from '@angular/material/icon'; const components = [SmallChipComponent, LogoComponent]; @@ -11,6 +11,6 @@ const deleteThisWhenAllComponentsAreStandalone = [SideNavComponent, StatusBarCom @NgModule({ declarations: [...components], exports: [...components, ...deleteThisWhenAllComponentsAreStandalone], - imports: [CommonModule, MatTooltipModule, IqserIconsModule, ...deleteThisWhenAllComponentsAreStandalone], + imports: [CommonModule, MatTooltipModule, MatIconModule, ...deleteThisWhenAllComponentsAreStandalone], }) export class IqserSharedModule {} diff --git a/src/lib/users/iqser-users.module.ts b/src/lib/users/iqser-users.module.ts index b6ccf31..4d3ed8c 100644 --- a/src/lib/users/iqser-users.module.ts +++ b/src/lib/users/iqser-users.module.ts @@ -4,7 +4,7 @@ import { KeycloakAngularModule, KeycloakOptions, KeycloakService } from 'keycloa import { DefaultUserService } from './services/default-user.service'; import { IIqserUser } from './types/user.response'; import { IqserUserService } from './services/iqser-user.service'; -import { BASE_HREF, ModuleWithOptions } from '../utils'; +import { BASE_HREF, ModuleOptions } from '../utils'; import { IqserUsersModuleOptions } from './types/iqser-users-module-options'; import { IqserUser } from './iqser-user.model'; import { IqserRoleGuard } from './guards/iqser-role-guard.service'; @@ -64,15 +64,15 @@ const components = [NamePipe, InitialsAvatarComponent, UserButtonComponent]; declarations: [...components], exports: [...components], }) -export class IqserUsersModule extends ModuleWithOptions { +export class IqserUsersModule { static forRoot< Interface extends IIqserUser, Class extends IqserUser & Interface, UserService extends IqserUserService, RolesGuard extends IqserRoleGuard = IqserRoleGuard, >(options: IqserUsersModuleOptions): ModuleWithProviders { - const userService = this._getService(IqserUserService, DefaultUserService, options.existingUserService); - const roleGuard = this._getService(IqserRoleGuard, IqserRoleGuard, options.existingRoleGuard); + const userService = ModuleOptions.getService(IqserUserService, DefaultUserService, options.existingUserService); + const roleGuard = ModuleOptions.getService(IqserRoleGuard, IqserRoleGuard, options.existingRoleGuard); return { ngModule: IqserUsersModule, diff --git a/src/lib/utils/constants.ts b/src/lib/utils/constants.ts new file mode 100644 index 0000000..093ce9c --- /dev/null +++ b/src/lib/utils/constants.ts @@ -0,0 +1,36 @@ +export const ICONS = new Set([ + 'arrow-down', + 'arrow-down-o', + 'arrow-right', + 'check', + 'close', + 'collapse', + 'copy', + 'csv', + 'document', + 'download', + 'edit', + 'expand', + 'failure', + 'help-outline', + 'lanes', + 'list', + 'logout', + 'menu', + 'more-actions', + 'ocr', + 'offline', + 'pages', + 'plus', + 'radio-indeterminate', + 'radio-selected', + 'refresh', + 'search', + 'settings', + 'sort-asc', + 'sort-desc', + 'status-collapse', + 'status-expand', + 'trash', + 'upload', +]); diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 6864a2e..d6e3597 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -15,6 +15,6 @@ export * from './custom-route-reuse.strategy'; export * from './headers-configuration'; export * from './context.component'; export * from './tokens'; -export * from './module-with-options'; +export * from './module-options'; export * from './iqser-app-config'; export * from './types/common-ui-options'; diff --git a/src/lib/utils/module-with-options.ts b/src/lib/utils/module-options.ts similarity index 66% rename from src/lib/utils/module-with-options.ts rename to src/lib/utils/module-options.ts index 1f800a8..6846161 100644 --- a/src/lib/utils/module-with-options.ts +++ b/src/lib/utils/module-options.ts @@ -1,7 +1,7 @@ import { Provider, Type } from '@angular/core'; -export class ModuleWithOptions { - protected static _getService(base: B, _default: Type, existing?: E): Provider { +export class ModuleOptions { + static getService(base: B, _default: Type, existing?: E): Provider { if (existing) { return { provide: base,