@theseam/ui-common 0.4.4 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/datatable/models/preferences-accessor.d.ts +3 -15
  2. package/datatable/models/preferences.d.ts +2 -1
  3. package/datatable/services/datatable-preferences.service.d.ts +11 -14
  4. package/datatable/tokens/datatable-preferences-accessor.d.ts +2 -2
  5. package/esm2020/datatable/datatable/datatable.component.mjs +3 -3
  6. package/esm2020/datatable/models/preferences-accessor.mjs +1 -1
  7. package/esm2020/datatable/models/preferences.mjs +1 -1
  8. package/esm2020/datatable/services/datatable-preferences.service.mjs +34 -106
  9. package/esm2020/datatable/tokens/datatable-preferences-accessor.mjs +1 -1
  10. package/esm2020/framework/dashboard/dashboard-widgets/dashboard-widgets.service.mjs +9 -3
  11. package/esm2020/services/preferences/preferences-accessor.mjs +2 -0
  12. package/esm2020/services/preferences/preferences-manager.service.mjs +69 -0
  13. package/esm2020/services/preferences/preferences-record.mjs +74 -0
  14. package/esm2020/services/preferences/preferences.models.mjs +2 -0
  15. package/esm2020/services/public-api.mjs +5 -1
  16. package/esm2020/story-helpers/public-api.mjs +2 -1
  17. package/esm2020/story-helpers/story-preferences-accessor.service.mjs +34 -0
  18. package/esm2020/widget/preferences/widget-preferences.models.mjs +5 -0
  19. package/esm2020/widget/preferences/widget-preferences.service.mjs +78 -0
  20. package/esm2020/widget/preferences/widget-preferences.token.mjs +3 -0
  21. package/esm2020/widget/widget/widget.component.mjs +68 -31
  22. package/esm2020/widget/widget-token.mjs +2 -1
  23. package/fesm2015/theseam-ui-common-datatable.mjs +45 -116
  24. package/fesm2015/theseam-ui-common-datatable.mjs.map +1 -1
  25. package/fesm2015/theseam-ui-common-framework.mjs +9 -3
  26. package/fesm2015/theseam-ui-common-framework.mjs.map +1 -1
  27. package/fesm2015/theseam-ui-common-services.mjs +144 -8
  28. package/fesm2015/theseam-ui-common-services.mjs.map +1 -1
  29. package/fesm2015/theseam-ui-common-story-helpers.mjs +32 -1
  30. package/fesm2015/theseam-ui-common-story-helpers.mjs.map +1 -1
  31. package/fesm2015/theseam-ui-common-widget.mjs +152 -36
  32. package/fesm2015/theseam-ui-common-widget.mjs.map +1 -1
  33. package/fesm2020/theseam-ui-common-datatable.mjs +45 -116
  34. package/fesm2020/theseam-ui-common-datatable.mjs.map +1 -1
  35. package/fesm2020/theseam-ui-common-framework.mjs +8 -3
  36. package/fesm2020/theseam-ui-common-framework.mjs.map +1 -1
  37. package/fesm2020/theseam-ui-common-services.mjs +144 -8
  38. package/fesm2020/theseam-ui-common-services.mjs.map +1 -1
  39. package/fesm2020/theseam-ui-common-story-helpers.mjs +32 -1
  40. package/fesm2020/theseam-ui-common-story-helpers.mjs.map +1 -1
  41. package/fesm2020/theseam-ui-common-widget.mjs +148 -36
  42. package/fesm2020/theseam-ui-common-widget.mjs.map +1 -1
  43. package/package.json +1 -1
  44. package/services/preferences/preferences-accessor.d.ts +15 -0
  45. package/services/preferences/preferences-manager.service.d.ts +15 -0
  46. package/services/preferences/preferences-record.d.ts +28 -0
  47. package/services/preferences/preferences.models.d.ts +3 -0
  48. package/services/public-api.d.ts +4 -0
  49. package/story-helpers/public-api.d.ts +1 -0
  50. package/story-helpers/story-preferences-accessor.service.d.ts +19 -0
  51. package/widget/preferences/widget-preferences.models.d.ts +8 -0
  52. package/widget/preferences/widget-preferences.service.d.ts +21 -0
  53. package/widget/preferences/widget-preferences.token.d.ts +3 -0
  54. package/widget/widget/widget.component.d.ts +10 -2
  55. package/widget/widget-token.d.ts +1 -0
@@ -1,14 +1,14 @@
1
1
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
2
2
  import * as i0 from '@angular/core';
3
- import { InjectionToken, Directive, Optional, Inject, Input, Component, ChangeDetectionStrategy, NgModule, ViewEncapsulation, HostBinding, ContentChild, EventEmitter, Output, isDevMode, Injectable } from '@angular/core';
4
- import { Subject, BehaviorSubject, throwError, of } from 'rxjs';
5
- import { auditTime, takeUntil, take, switchMap, filter, map } from 'rxjs/operators';
6
- import { getClosestWidgetCdkDrag } from '@theseam/ui-common/utils';
3
+ import { InjectionToken, Directive, Optional, Inject, Input, Component, ChangeDetectionStrategy, NgModule, ViewEncapsulation, HostBinding, ContentChild, EventEmitter, Output, Injectable, isDevMode } from '@angular/core';
4
+ import { Subject, BehaviorSubject, of, tap as tap$1, takeUntil as takeUntil$1, throwError } from 'rxjs';
5
+ import { auditTime, takeUntil, take, switchMap, filter, map, tap } from 'rxjs/operators';
6
+ import { getClosestWidgetCdkDrag, hasProperty } from '@theseam/ui-common/utils';
7
7
  import * as i1 from '@angular/cdk/drag-drop';
8
8
  import { DragDropModule } from '@angular/cdk/drag-drop';
9
9
  import * as i2 from '@angular/common';
10
10
  import { CommonModule } from '@angular/common';
11
- import * as i5 from '@theseam/ui-common/buttons';
11
+ import * as i6 from '@theseam/ui-common/buttons';
12
12
  import { TheSeamButtonsModule } from '@theseam/ui-common/buttons';
13
13
  import { mixinTheme, mixinActive, mixinDisabled, InputBoolean, mixinTabIndex } from '@theseam/ui-common/core';
14
14
  import * as i1$1 from '@angular/cdk/a11y';
@@ -20,12 +20,13 @@ import { TheSeamTableModule } from '@theseam/ui-common/table';
20
20
  import { TheSeamTableCellTypesModule } from '@theseam/ui-common/table-cell-types';
21
21
  import { trigger, transition, style, animate, state } from '@angular/animations';
22
22
  import { faCog, faAngleDown } from '@fortawesome/free-solid-svg-icons';
23
- import * as i2$1 from '@fortawesome/angular-fontawesome';
23
+ import * as i1$3 from '@theseam/ui-common/services';
24
+ import * as i3$1 from '@fortawesome/angular-fontawesome';
24
25
  import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
25
- import * as i4 from '@theseam/ui-common/loading';
26
+ import * as i5 from '@theseam/ui-common/loading';
26
27
  import { TheSeamLoadingModule } from '@theseam/ui-common/loading';
27
28
  import { ComponentPortal } from '@angular/cdk/portal';
28
- import * as i1$3 from '@theseam/ui-common/dynamic-component-loader';
29
+ import * as i1$4 from '@theseam/ui-common/dynamic-component-loader';
29
30
  import { CdkTableModule } from '@angular/cdk/table';
30
31
  import { RouterModule } from '@angular/router';
31
32
 
@@ -946,6 +947,89 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
946
947
  }]
947
948
  }] });
948
949
 
950
+ const THESEAM_WIDGET_PREFERENCES_ACCESSOR = new InjectionToken('TheSeamWidgetPreferencesAccessor');
951
+
952
+ const CURRENT_WIDGET_PREFERENCES_VERSION = 1;
953
+ const EMPTY_WIDGET_PREFERENCES = {
954
+ version: 1,
955
+ };
956
+
957
+ // TODO: Rethink this. I originally implemented this to be shared widget's then
958
+ // changed it to be per widget, for the accessor injection.
959
+ // @Injectable({ providedIn: 'root' })
960
+ class WidgetPreferencesService {
961
+ constructor(_preferencesManager, _prefsAccessor) {
962
+ this._preferencesManager = _preferencesManager;
963
+ this._prefsAccessor = _prefsAccessor;
964
+ this._pendingPatches = {};
965
+ }
966
+ isPatchPending(preferenceKey) {
967
+ return this._pendingPatches[preferenceKey] && this._pendingPatches[preferenceKey].length > 0;
968
+ }
969
+ isPending(preferenceKey) {
970
+ return this._preferencesManager.isPending(preferenceKey);
971
+ }
972
+ isLoaded(preferenceKey) {
973
+ return this._preferencesManager.isLoaded(preferenceKey);
974
+ }
975
+ preferences(preferenceKey) {
976
+ if (!this._prefsAccessor) {
977
+ return of(JSON.parse(JSON.stringify(EMPTY_WIDGET_PREFERENCES)));
978
+ }
979
+ return this._preferencesManager.preferences(preferenceKey, this._prefsAccessor, EMPTY_WIDGET_PREFERENCES).pipe(map(prefs => {
980
+ if (this._isValidPreferences(prefs)) {
981
+ return prefs;
982
+ }
983
+ throw Error(`Preferences for key '${preferenceKey}' is not a valid widget preferences.`);
984
+ }));
985
+ }
986
+ refresh(preferenceKey) {
987
+ this._preferencesManager.refresh(preferenceKey);
988
+ }
989
+ patchPreferences(preferenceKey, preferences) {
990
+ if (!this._prefsAccessor) {
991
+ return;
992
+ }
993
+ if (!this._pendingPatches[preferenceKey]) {
994
+ this._pendingPatches[preferenceKey] = [];
995
+ }
996
+ if (this._pendingPatches[preferenceKey].length > 0) {
997
+ this._pendingPatches[preferenceKey].push(preferences);
998
+ return;
999
+ }
1000
+ this._pendingPatches[preferenceKey].push(preferences);
1001
+ this.preferences(preferenceKey).pipe(take(1), map(prefs => {
1002
+ const pendingPatches = this._pendingPatches[preferenceKey];
1003
+ this._pendingPatches[preferenceKey] = [];
1004
+ const newPrefs = pendingPatches.reduce((acc, patch) => {
1005
+ return Object.assign(Object.assign({}, acc), patch);
1006
+ }, prefs); // Typescript isn't recognizing that 'version' is included in the initial value.
1007
+ if (!this._isValidPreferences(newPrefs)) {
1008
+ throw Error(`Attempted to patch preferences for key '${preferenceKey}' with invalid preferences.`);
1009
+ }
1010
+ this._preferencesManager.update(preferenceKey, newPrefs);
1011
+ }), tap(() => this.refresh(preferenceKey))).subscribe();
1012
+ }
1013
+ _isValidPreferences(prefs) {
1014
+ return prefs.version === CURRENT_WIDGET_PREFERENCES_VERSION;
1015
+ }
1016
+ }
1017
+ WidgetPreferencesService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WidgetPreferencesService, deps: [{ token: i1$3.TheSeamPreferencesManagerService }, { token: THESEAM_WIDGET_PREFERENCES_ACCESSOR, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1018
+ WidgetPreferencesService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WidgetPreferencesService });
1019
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WidgetPreferencesService, decorators: [{
1020
+ type: Injectable
1021
+ }], ctorParameters: function () {
1022
+ return [{ type: i1$3.TheSeamPreferencesManagerService }, { type: undefined, decorators: [{
1023
+ type: Optional
1024
+ }, {
1025
+ type: Inject,
1026
+ args: [THESEAM_WIDGET_PREFERENCES_ACCESSOR]
1027
+ }] }];
1028
+ } });
1029
+
1030
+ const THESEAM_WIDGETS = new InjectionToken('TheSeamWidgets');
1031
+ const THESEAM_WIDGET_DATA = new InjectionToken('TheSeamWidgetData');
1032
+
949
1033
  const EXPANDED_STATE = 'expanded';
950
1034
  const COLLAPSED_STATE = 'collapsed';
951
1035
  const EXPAND_TRANSITION = `${EXPANDED_STATE} <=> ${COLLAPSED_STATE}`;
@@ -987,9 +1071,31 @@ const collapseAnimation = trigger('collapseAnim', [
987
1071
  * used then the situation should be considered for becoming a widget component.
988
1072
  */
989
1073
  class WidgetComponent {
990
- constructor() {
1074
+ /**
1075
+ * Icon displayed in the top header.
1076
+ *
1077
+ * If a more advanced icon is needed you can use `seamWidgetIconTpl` template
1078
+ * directive, but a `SeamIcon` input is recommended, because allowing custom
1079
+ * icons that do not follow the tested types can lead to inconsitency quickly
1080
+ * as different developers keep making tweaks.
1081
+ */
1082
+ get icon() { return this._iconUrl || this._iconObj; }
1083
+ set icon(value) {
1084
+ if (typeof value === 'string') {
1085
+ this._iconUrl = value;
1086
+ this._iconObj = undefined;
1087
+ }
1088
+ else {
1089
+ this._iconUrl = undefined;
1090
+ this._iconObj = value;
1091
+ }
1092
+ }
1093
+ constructor(_widgetPreferences, _data) {
1094
+ this._widgetPreferences = _widgetPreferences;
1095
+ this._data = _data;
991
1096
  this.configIcon = faCog;
992
1097
  this.collapseIcon = faAngleDown;
1098
+ this._ngUnsubscribe = new Subject();
993
1099
  /**
994
1100
  * Toggles the collapsed state of a widget.
995
1101
  */
@@ -1009,26 +1115,19 @@ class WidgetComponent {
1009
1115
  * header to toggle the collapsed state.
1010
1116
  */
1011
1117
  this.canCollapse = false;
1012
- }
1013
- /**
1014
- * Icon displayed in the top header.
1015
- *
1016
- * If a more advanced icon is needed you can use `seamWidgetIconTpl` template
1017
- * directive, but a `SeamIcon` input is recommended, because allowing custom
1018
- * icons that do not follow the tested types can lead to inconsitency quickly
1019
- * as different developers keep making tweaks.
1020
- */
1021
- get icon() { return this._iconUrl || this._iconObj; }
1022
- set icon(value) {
1023
- if (typeof value === 'string') {
1024
- this._iconUrl = value;
1025
- this._iconObj = undefined;
1026
- }
1027
- else {
1028
- this._iconUrl = undefined;
1029
- this._iconObj = value;
1118
+ if (this._data && this._data.widgetId) {
1119
+ this._preferencesKey = `widget:${this._data.widgetId}`;
1120
+ this._widgetPreferences.preferences(this._preferencesKey).pipe(tap$1(prefs => {
1121
+ if (hasProperty(prefs, 'collapsed')) {
1122
+ this.collapsed = prefs.collapsed;
1123
+ }
1124
+ }), takeUntil$1(this._ngUnsubscribe)).subscribe();
1030
1125
  }
1031
1126
  }
1127
+ ngOnDestroy() {
1128
+ this._ngUnsubscribe.next();
1129
+ this._ngUnsubscribe.complete();
1130
+ }
1032
1131
  /**
1033
1132
  * Toggles a widget's collapsed state.
1034
1133
  */
@@ -1040,11 +1139,21 @@ class WidgetComponent {
1040
1139
  return;
1041
1140
  }
1042
1141
  this.collapsed = !this.collapsed;
1142
+ // Only update the preference, if collapse method is called, because it is
1143
+ // assumed that the user is collapsing the widget. If the collapsed state is
1144
+ // changed by other means, such using the widget's `collapsed` input, then
1145
+ // the preference should not be updated, because that is assumed to be an
1146
+ // app controlled change that should not be persisted.
1147
+ if (this._preferencesKey) {
1148
+ this._widgetPreferences.patchPreferences(this._preferencesKey, { collapsed: this.collapsed });
1149
+ }
1043
1150
  }
1044
1151
  get collapseState() { return this.collapsed ? COLLAPSED_STATE : EXPANDED_STATE; }
1045
1152
  }
1046
- WidgetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1047
- WidgetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.7", type: WidgetComponent, selector: "seam-widget", inputs: { collapsed: "collapsed", hasHeader: "hasHeader", titleText: "titleText", icon: "icon", iconClass: "iconClass", loading: "loading", hasConfig: "hasConfig", canCollapse: "canCollapse" }, queries: [{ propertyName: "iconTpl", first: true, predicate: WidgetIconTplDirective, descendants: true, static: true }, { propertyName: "titleTpl", first: true, predicate: WidgetTitleTplDirective, descendants: true, static: true }], ngImport: i0, template: "<div class=\"seam-widget border rounded overflow-hidden\">\n <div class=\"widget-header\" seamWidgetDragHandle *ngIf=\"hasHeader\">\n <div class=\"widget-header-content p-2 text-nowrap\">\n <span class=\"mr-1 widget-header-icon\">\n <ng-container *ngIf=\"iconTpl; else noIconTpl\">\n <ng-template\n [ngTemplateOutlet]=\"iconTpl.template\"\n [ngTemplateOutletContext]=\"{ $implicit: icon, icon: icon, title: titleText }\">\n </ng-template>\n </ng-container>\n <ng-template #noIconTpl>\n <fa-icon *ngIf=\"_iconObj\"\n class=\"widget-header-icon--fa {{ iconClass }}\"\n [icon]=\"_iconObj\"></fa-icon>\n <img *ngIf=\"_iconUrl\"\n class=\"widget-header-icon--img {{ iconClass }}\"\n [src]=\"_iconUrl\" [alt]=\"titleText\">\n </ng-template>\n </span>\n <span class=\"widget-header-title text-truncate\">\n <ng-container *ngIf=\"titleTpl; else noTitleTpl\">\n <ng-template\n [ngTemplateOutlet]=\"titleTpl.template\"\n [ngTemplateOutletContext]=\"{ $implicit: titleText, icon: icon, title: titleText }\">\n </ng-template>\n </ng-container>\n <ng-template #noTitleTpl>{{ titleText }}</ng-template>\n </span>\n </div>\n <div class=\"widget-header-btns-container\" *ngIf=\"hasConfig || canCollapse\">\n <!-- <div *ngIf=\"hasConfig\">\n <button seamIconBtn [icon]=\"configIcon\"\n class=\"widget-header-btn-config\"\n [iconType]=\"null\">\n <span class=\"sr-only\">Widget configuration menu</span>\n </button>\n <button seamButton class=\"widget-header-btn-config p-0\">\n <seam-icon class=\"d-block\" [icon]=\"configIcon\" iconClass=\"text-secondary\"></seam-icon>\n <span class=\"sr-only\">Widget configuration menu</span>\n </button>\n </div> -->\n\n <div *ngIf=\"canCollapse\" class=\"px-0\">\n\n <button seamButton class=\"widget-header-btn-collapse p-0 mr-1 h-100\" (click)=\"collapse()\" [class.widget-header-btn-collapse--active]=\"collapsed\">\n <seam-icon class=\"d-block\"\n [icon]=\"collapseIcon\"\n iconClass=\"text-secondary\">\n </seam-icon>\n <span class=\"sr-only\">Widget collapse</span>\n </button>\n <!-- iconType=\"borderless-styled-square\" -->\n <!-- style=\"margin-left: -10px; margin-right: -5px;\" -->\n\n <!-- <button seamIconBtn class=\"widget-header-btn-collapse\" (click)=\"collapse()\" [class.widget-header-btn-collapse--active]=\"collapsed\"\n btnTheme=\"secondary\"\n [icon]=\"collapseIcon\"\n iconType=\"borderless-styled-square\"\n size=\"xs\"\n btnSize=\"sm\"\n >\n <seam-icon class=\"d-block\"\n [icon]=\"collapseIcon\"\n iconClass=\"text-secondary\"\n style=\"margin-left: -10px; margin-right: -5px;\"\n iconType=\"borderless-styled-square\"></seam-icon>\n <span class=\"sr-only\">Widget collapse</span>\n </button> -->\n </div>\n </div>\n </div>\n <div class=\"position-relative overflow-hidden\" [style.height.px]=\"loading ? 150 : undefined\" [@collapseAnim]=\"collapseState\">\n <ng-container *ngIf=\"!collapsed\">\n <div class=\"p-2\" *ngIf=\"!loading else loadingTpl\" @keepContentAnim>\n <ng-content></ng-content>\n </div>\n <ng-content select=\"seam-widget-footer\"></ng-content>\n <ng-template #loadingTpl>\n <div class=\"position-absolute\" @loadingAnim style=\"top:0;right:0;bottom:0;left:0\">\n <seam-loading [theme]=\"'primary'\"></seam-loading>\n </div>\n </ng-template>\n </ng-container>\n </div>\n</div>\n", styles: ["seam-widget{display:block;font-size:15px}seam-widget .seam-widget{background:#FFFFFF;box-shadow:none}seam-widget .widget-header{display:flex;flex-direction:row;border-bottom:1px solid #dee2e6;background:#F4F4F4;font-size:17px}seam-widget .widget-header .widget-header-content{flex:1 1 100%}seam-widget .widget-header .widget-header-btns-container{display:flex;flex-direction:row}seam-widget .widget-header .widget-header-btns-container>div{display:flex;flex-direction:column;justify-content:center;padding:4px}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-config .seam-icon--fa{display:flex;flex-direction:row;justify-content:center;text-align:center;height:25px;width:30px}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-config .seam-icon--fa .svg-inline--fa{max-width:100%;height:100%;width:100%}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse .seam-icon--fa{display:flex;flex-direction:row;justify-content:center;text-align:center;height:25px;width:30px}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse .seam-icon--fa .svg-inline--fa{max-width:100%;height:100%;width:100%}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse .svg-inline--fa{transform:rotate(0);transition:.3s ease-in-out transform}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse.widget-header-btn-collapse--active .svg-inline--fa{transform:rotate(90deg)}seam-widget .widget-header .widget-header-title{font-size:17px}seam-widget .widget-header-icon{display:inline-block;vertical-align:top;max-height:20px;max-width:20px;height:20px;width:20px;color:currentColor}seam-widget .widget-header-icon .widget-header-icon--fa{display:flex;flex-direction:row;justify-content:center;text-align:center;max-height:20px;max-width:20px;height:20px;width:20px}seam-widget .widget-header-icon .widget-header-icon--fa .svg-inline--fa{max-width:100%;height:100%;width:100%}seam-widget .widget-header-icon .widget-header-icon--img{height:100%;max-height:20px;max-width:20px}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2$1.FaIconComponent, selector: "fa-icon", inputs: ["classes", "icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "component", type: i3.IconComponent, selector: "seam-icon", inputs: ["grayscaleOnDisable", "disabled", "iconClass", "icon", "size", "showDefaultOnError", "defaultIcon", "iconType"] }, { kind: "component", type: i4.LoadingComponent, selector: "seam-loading", inputs: ["theme"] }, { kind: "component", type: i5.ButtonComponent, selector: "button[seamButton]", inputs: ["disabled", "theme", "size", "type"], exportAs: ["seamButton"] }, { kind: "directive", type: WidgetDragHandleDirective, selector: "[seamWidgetDragHandle]", inputs: ["cdkDragHandleDisabled"] }], animations: [
1153
+ WidgetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WidgetComponent, deps: [{ token: WidgetPreferencesService }, { token: THESEAM_WIDGET_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1154
+ WidgetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.7", type: WidgetComponent, selector: "seam-widget", inputs: { collapsed: "collapsed", hasHeader: "hasHeader", titleText: "titleText", icon: "icon", iconClass: "iconClass", loading: "loading", hasConfig: "hasConfig", canCollapse: "canCollapse" }, providers: [
1155
+ WidgetPreferencesService,
1156
+ ], queries: [{ propertyName: "iconTpl", first: true, predicate: WidgetIconTplDirective, descendants: true, static: true }, { propertyName: "titleTpl", first: true, predicate: WidgetTitleTplDirective, descendants: true, static: true }], ngImport: i0, template: "<div class=\"seam-widget border rounded overflow-hidden\">\n <div class=\"widget-header\" seamWidgetDragHandle *ngIf=\"hasHeader\">\n <div class=\"widget-header-content p-2 text-nowrap\">\n <span class=\"mr-1 widget-header-icon\">\n <ng-container *ngIf=\"iconTpl; else noIconTpl\">\n <ng-template\n [ngTemplateOutlet]=\"iconTpl.template\"\n [ngTemplateOutletContext]=\"{ $implicit: icon, icon: icon, title: titleText }\">\n </ng-template>\n </ng-container>\n <ng-template #noIconTpl>\n <fa-icon *ngIf=\"_iconObj\"\n class=\"widget-header-icon--fa {{ iconClass }}\"\n [icon]=\"_iconObj\"></fa-icon>\n <img *ngIf=\"_iconUrl\"\n class=\"widget-header-icon--img {{ iconClass }}\"\n [src]=\"_iconUrl\" [alt]=\"titleText\">\n </ng-template>\n </span>\n <span class=\"widget-header-title text-truncate\">\n <ng-container *ngIf=\"titleTpl; else noTitleTpl\">\n <ng-template\n [ngTemplateOutlet]=\"titleTpl.template\"\n [ngTemplateOutletContext]=\"{ $implicit: titleText, icon: icon, title: titleText }\">\n </ng-template>\n </ng-container>\n <ng-template #noTitleTpl>{{ titleText }}</ng-template>\n </span>\n </div>\n <div class=\"widget-header-btns-container\" *ngIf=\"hasConfig || canCollapse\">\n <!-- <div *ngIf=\"hasConfig\">\n <button seamIconBtn [icon]=\"configIcon\"\n class=\"widget-header-btn-config\"\n [iconType]=\"null\">\n <span class=\"sr-only\">Widget configuration menu</span>\n </button>\n <button seamButton class=\"widget-header-btn-config p-0\">\n <seam-icon class=\"d-block\" [icon]=\"configIcon\" iconClass=\"text-secondary\"></seam-icon>\n <span class=\"sr-only\">Widget configuration menu</span>\n </button>\n </div> -->\n\n <div *ngIf=\"canCollapse\" class=\"px-0\">\n\n <button seamButton class=\"widget-header-btn-collapse p-0 mr-1 h-100\" (click)=\"collapse()\" [class.widget-header-btn-collapse--active]=\"collapsed\">\n <seam-icon class=\"d-block\"\n [icon]=\"collapseIcon\"\n iconClass=\"text-secondary\">\n </seam-icon>\n <span class=\"sr-only\">Widget collapse</span>\n </button>\n <!-- iconType=\"borderless-styled-square\" -->\n <!-- style=\"margin-left: -10px; margin-right: -5px;\" -->\n\n <!-- <button seamIconBtn class=\"widget-header-btn-collapse\" (click)=\"collapse()\" [class.widget-header-btn-collapse--active]=\"collapsed\"\n btnTheme=\"secondary\"\n [icon]=\"collapseIcon\"\n iconType=\"borderless-styled-square\"\n size=\"xs\"\n btnSize=\"sm\"\n >\n <seam-icon class=\"d-block\"\n [icon]=\"collapseIcon\"\n iconClass=\"text-secondary\"\n style=\"margin-left: -10px; margin-right: -5px;\"\n iconType=\"borderless-styled-square\"></seam-icon>\n <span class=\"sr-only\">Widget collapse</span>\n </button> -->\n </div>\n </div>\n </div>\n <div class=\"position-relative overflow-hidden\" [style.height.px]=\"loading ? 150 : undefined\" [@collapseAnim]=\"collapseState\">\n <ng-container *ngIf=\"!collapsed\">\n <div class=\"p-2\" *ngIf=\"!loading else loadingTpl\" @keepContentAnim>\n <ng-content></ng-content>\n </div>\n <ng-content select=\"seam-widget-footer\"></ng-content>\n <ng-template #loadingTpl>\n <div class=\"position-absolute\" @loadingAnim style=\"top:0;right:0;bottom:0;left:0\">\n <seam-loading [theme]=\"'primary'\"></seam-loading>\n </div>\n </ng-template>\n </ng-container>\n </div>\n</div>\n", styles: ["seam-widget{display:block;font-size:15px}seam-widget .seam-widget{background:#FFFFFF;box-shadow:none}seam-widget .widget-header{display:flex;flex-direction:row;border-bottom:1px solid #dee2e6;background:#F4F4F4;font-size:17px}seam-widget .widget-header .widget-header-content{flex:1 1 100%}seam-widget .widget-header .widget-header-btns-container{display:flex;flex-direction:row}seam-widget .widget-header .widget-header-btns-container>div{display:flex;flex-direction:column;justify-content:center;padding:4px}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-config .seam-icon--fa{display:flex;flex-direction:row;justify-content:center;text-align:center;height:25px;width:30px}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-config .seam-icon--fa .svg-inline--fa{max-width:100%;height:100%;width:100%}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse .seam-icon--fa{display:flex;flex-direction:row;justify-content:center;text-align:center;height:25px;width:30px}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse .seam-icon--fa .svg-inline--fa{max-width:100%;height:100%;width:100%}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse .svg-inline--fa{transform:rotate(0);transition:.3s ease-in-out transform}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse.widget-header-btn-collapse--active .svg-inline--fa{transform:rotate(90deg)}seam-widget .widget-header .widget-header-title{font-size:17px}seam-widget .widget-header-icon{display:inline-block;vertical-align:top;max-height:20px;max-width:20px;height:20px;width:20px;color:currentColor}seam-widget .widget-header-icon .widget-header-icon--fa{display:flex;flex-direction:row;justify-content:center;text-align:center;max-height:20px;max-width:20px;height:20px;width:20px}seam-widget .widget-header-icon .widget-header-icon--fa .svg-inline--fa{max-width:100%;height:100%;width:100%}seam-widget .widget-header-icon .widget-header-icon--img{height:100%;max-height:20px;max-width:20px}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3$1.FaIconComponent, selector: "fa-icon", inputs: ["classes", "icon", "title", "spin", "pulse", "mask", "styles", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "component", type: i3.IconComponent, selector: "seam-icon", inputs: ["grayscaleOnDisable", "disabled", "iconClass", "icon", "size", "showDefaultOnError", "defaultIcon", "iconType"] }, { kind: "component", type: i5.LoadingComponent, selector: "seam-loading", inputs: ["theme"] }, { kind: "component", type: i6.ButtonComponent, selector: "button[seamButton]", inputs: ["disabled", "theme", "size", "type"], exportAs: ["seamButton"] }, { kind: "directive", type: WidgetDragHandleDirective, selector: "[seamWidgetDragHandle]", inputs: ["cdkDragHandleDisabled"] }], animations: [
1048
1157
  loadingAnimation,
1049
1158
  collapseAnimation,
1050
1159
  keepContentAnimation,
@@ -1066,12 +1175,21 @@ __decorate([
1066
1175
  ], WidgetComponent.prototype, "canCollapse", void 0);
1067
1176
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WidgetComponent, decorators: [{
1068
1177
  type: Component,
1069
- args: [{ selector: 'seam-widget', encapsulation: ViewEncapsulation.None, animations: [
1178
+ args: [{ selector: 'seam-widget', providers: [
1179
+ WidgetPreferencesService,
1180
+ ], encapsulation: ViewEncapsulation.None, animations: [
1070
1181
  loadingAnimation,
1071
1182
  collapseAnimation,
1072
1183
  keepContentAnimation,
1073
1184
  ], template: "<div class=\"seam-widget border rounded overflow-hidden\">\n <div class=\"widget-header\" seamWidgetDragHandle *ngIf=\"hasHeader\">\n <div class=\"widget-header-content p-2 text-nowrap\">\n <span class=\"mr-1 widget-header-icon\">\n <ng-container *ngIf=\"iconTpl; else noIconTpl\">\n <ng-template\n [ngTemplateOutlet]=\"iconTpl.template\"\n [ngTemplateOutletContext]=\"{ $implicit: icon, icon: icon, title: titleText }\">\n </ng-template>\n </ng-container>\n <ng-template #noIconTpl>\n <fa-icon *ngIf=\"_iconObj\"\n class=\"widget-header-icon--fa {{ iconClass }}\"\n [icon]=\"_iconObj\"></fa-icon>\n <img *ngIf=\"_iconUrl\"\n class=\"widget-header-icon--img {{ iconClass }}\"\n [src]=\"_iconUrl\" [alt]=\"titleText\">\n </ng-template>\n </span>\n <span class=\"widget-header-title text-truncate\">\n <ng-container *ngIf=\"titleTpl; else noTitleTpl\">\n <ng-template\n [ngTemplateOutlet]=\"titleTpl.template\"\n [ngTemplateOutletContext]=\"{ $implicit: titleText, icon: icon, title: titleText }\">\n </ng-template>\n </ng-container>\n <ng-template #noTitleTpl>{{ titleText }}</ng-template>\n </span>\n </div>\n <div class=\"widget-header-btns-container\" *ngIf=\"hasConfig || canCollapse\">\n <!-- <div *ngIf=\"hasConfig\">\n <button seamIconBtn [icon]=\"configIcon\"\n class=\"widget-header-btn-config\"\n [iconType]=\"null\">\n <span class=\"sr-only\">Widget configuration menu</span>\n </button>\n <button seamButton class=\"widget-header-btn-config p-0\">\n <seam-icon class=\"d-block\" [icon]=\"configIcon\" iconClass=\"text-secondary\"></seam-icon>\n <span class=\"sr-only\">Widget configuration menu</span>\n </button>\n </div> -->\n\n <div *ngIf=\"canCollapse\" class=\"px-0\">\n\n <button seamButton class=\"widget-header-btn-collapse p-0 mr-1 h-100\" (click)=\"collapse()\" [class.widget-header-btn-collapse--active]=\"collapsed\">\n <seam-icon class=\"d-block\"\n [icon]=\"collapseIcon\"\n iconClass=\"text-secondary\">\n </seam-icon>\n <span class=\"sr-only\">Widget collapse</span>\n </button>\n <!-- iconType=\"borderless-styled-square\" -->\n <!-- style=\"margin-left: -10px; margin-right: -5px;\" -->\n\n <!-- <button seamIconBtn class=\"widget-header-btn-collapse\" (click)=\"collapse()\" [class.widget-header-btn-collapse--active]=\"collapsed\"\n btnTheme=\"secondary\"\n [icon]=\"collapseIcon\"\n iconType=\"borderless-styled-square\"\n size=\"xs\"\n btnSize=\"sm\"\n >\n <seam-icon class=\"d-block\"\n [icon]=\"collapseIcon\"\n iconClass=\"text-secondary\"\n style=\"margin-left: -10px; margin-right: -5px;\"\n iconType=\"borderless-styled-square\"></seam-icon>\n <span class=\"sr-only\">Widget collapse</span>\n </button> -->\n </div>\n </div>\n </div>\n <div class=\"position-relative overflow-hidden\" [style.height.px]=\"loading ? 150 : undefined\" [@collapseAnim]=\"collapseState\">\n <ng-container *ngIf=\"!collapsed\">\n <div class=\"p-2\" *ngIf=\"!loading else loadingTpl\" @keepContentAnim>\n <ng-content></ng-content>\n </div>\n <ng-content select=\"seam-widget-footer\"></ng-content>\n <ng-template #loadingTpl>\n <div class=\"position-absolute\" @loadingAnim style=\"top:0;right:0;bottom:0;left:0\">\n <seam-loading [theme]=\"'primary'\"></seam-loading>\n </div>\n </ng-template>\n </ng-container>\n </div>\n</div>\n", styles: ["seam-widget{display:block;font-size:15px}seam-widget .seam-widget{background:#FFFFFF;box-shadow:none}seam-widget .widget-header{display:flex;flex-direction:row;border-bottom:1px solid #dee2e6;background:#F4F4F4;font-size:17px}seam-widget .widget-header .widget-header-content{flex:1 1 100%}seam-widget .widget-header .widget-header-btns-container{display:flex;flex-direction:row}seam-widget .widget-header .widget-header-btns-container>div{display:flex;flex-direction:column;justify-content:center;padding:4px}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-config .seam-icon--fa{display:flex;flex-direction:row;justify-content:center;text-align:center;height:25px;width:30px}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-config .seam-icon--fa .svg-inline--fa{max-width:100%;height:100%;width:100%}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse .seam-icon--fa{display:flex;flex-direction:row;justify-content:center;text-align:center;height:25px;width:30px}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse .seam-icon--fa .svg-inline--fa{max-width:100%;height:100%;width:100%}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse .svg-inline--fa{transform:rotate(0);transition:.3s ease-in-out transform}seam-widget .widget-header .widget-header-btns-container .widget-header-btn-collapse.widget-header-btn-collapse--active .svg-inline--fa{transform:rotate(90deg)}seam-widget .widget-header .widget-header-title{font-size:17px}seam-widget .widget-header-icon{display:inline-block;vertical-align:top;max-height:20px;max-width:20px;height:20px;width:20px;color:currentColor}seam-widget .widget-header-icon .widget-header-icon--fa{display:flex;flex-direction:row;justify-content:center;text-align:center;max-height:20px;max-width:20px;height:20px;width:20px}seam-widget .widget-header-icon .widget-header-icon--fa .svg-inline--fa{max-width:100%;height:100%;width:100%}seam-widget .widget-header-icon .widget-header-icon--img{height:100%;max-height:20px;max-width:20px}\n"] }]
1074
- }], propDecorators: { collapsed: [{
1185
+ }], ctorParameters: function () {
1186
+ return [{ type: WidgetPreferencesService }, { type: undefined, decorators: [{
1187
+ type: Optional
1188
+ }, {
1189
+ type: Inject,
1190
+ args: [THESEAM_WIDGET_DATA]
1191
+ }] }];
1192
+ }, propDecorators: { collapsed: [{
1075
1193
  type: Input
1076
1194
  }], hasHeader: [{
1077
1195
  type: Input
@@ -1104,8 +1222,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
1104
1222
  args: [{ selector: 'seam-widget-footer', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"widget-footer--left\">\n <ng-content select=\"seam-widget-footer-text\"></ng-content>\n</div>\n<div class=\"widget-footer--right\">\n <ng-content select=\"seam-widget-button-group\"></ng-content>\n</div>\n", styles: ["seam-widget-footer{display:flex;flex-direction:row;margin:.25rem}seam-widget-footer .widget-footer--left{flex:1 1 100%}seam-widget-footer .widget-footer--right{flex:0 0 auto}\n"] }]
1105
1223
  }] });
1106
1224
 
1107
- const THESEAM_WIDGETS = new InjectionToken('TheSeamWidgets');
1108
-
1109
1225
  /**
1110
1226
  * Registry is to provide a way to manage widgets in a way that we can load them
1111
1227
  * the same way throughout the app, whether the component itself is registered,
@@ -1143,7 +1259,7 @@ class WidgetRegistryService {
1143
1259
  }
1144
1260
  }
1145
1261
  }
1146
- WidgetRegistryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WidgetRegistryService, deps: [{ token: THESEAM_WIDGETS }, { token: i1$3.TheSeamDynamicComponentLoader }], target: i0.ɵɵFactoryTarget.Injectable });
1262
+ WidgetRegistryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WidgetRegistryService, deps: [{ token: THESEAM_WIDGETS }, { token: i1$4.TheSeamDynamicComponentLoader }], target: i0.ɵɵFactoryTarget.Injectable });
1147
1263
  WidgetRegistryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WidgetRegistryService, providedIn: 'root' });
1148
1264
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WidgetRegistryService, decorators: [{
1149
1265
  type: Injectable,
@@ -1154,7 +1270,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
1154
1270
  return [{ type: undefined, decorators: [{
1155
1271
  type: Inject,
1156
1272
  args: [THESEAM_WIDGETS]
1157
- }] }, { type: i1$3.TheSeamDynamicComponentLoader }];
1273
+ }] }, { type: i1$4.TheSeamDynamicComponentLoader }];
1158
1274
  } });
1159
1275
 
1160
1276
  const contentModules = [
@@ -1260,5 +1376,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImpor
1260
1376
  * Generated bundle index. Do not edit.
1261
1377
  */
1262
1378
 
1263
- export { THESEAM_WIDGETS, THESEAM_WIDGET_ACCESSOR, TheSeamWidgetButtonGroupModule, TheSeamWidgetContentHeaderModule, TheSeamWidgetDescriptionModule, TheSeamWidgetEmptyLabelModule, TheSeamWidgetFooterLinkModule, TheSeamWidgetFooterTextModule, TheSeamWidgetHeaderBadgeModule, TheSeamWidgetListGroupModule, TheSeamWidgetModule, TheSeamWidgetTableModule, TheSeamWidgetTileListModule, TheSeamWidgetTileModule, WidgetButtonGroupComponent, WidgetComponent, WidgetContentHeaderComponent, WidgetDescriptionComponent, WidgetDragHandleDirective, WidgetEmptyLabelComponent, WidgetFooterComponent, WidgetFooterLinkComponent, WidgetFooterTextComponent, WidgetHeaderBadgeComponent, WidgetIconTplDirective, WidgetListGroupComponent, WidgetListGroupItemAnchorComponent, WidgetListGroupItemButtonComponent, WidgetListGroupItemComponent, WidgetListGroupItemIconTplDirective, WidgetRegistryService, WidgetTableComponent, WidgetTileComponent, WidgetTileFooterComponent, WidgetTileFooterItemComponent, WidgetTileGroupComponent, WidgetTileListComponent, WidgetTileSecondaryIconDirective, WidgetTitleTplDirective, extendStyles, toggleNativeDragInteractions };
1379
+ export { THESEAM_WIDGETS, THESEAM_WIDGET_ACCESSOR, THESEAM_WIDGET_DATA, TheSeamWidgetButtonGroupModule, TheSeamWidgetContentHeaderModule, TheSeamWidgetDescriptionModule, TheSeamWidgetEmptyLabelModule, TheSeamWidgetFooterLinkModule, TheSeamWidgetFooterTextModule, TheSeamWidgetHeaderBadgeModule, TheSeamWidgetListGroupModule, TheSeamWidgetModule, TheSeamWidgetTableModule, TheSeamWidgetTileListModule, TheSeamWidgetTileModule, WidgetButtonGroupComponent, WidgetComponent, WidgetContentHeaderComponent, WidgetDescriptionComponent, WidgetDragHandleDirective, WidgetEmptyLabelComponent, WidgetFooterComponent, WidgetFooterLinkComponent, WidgetFooterTextComponent, WidgetHeaderBadgeComponent, WidgetIconTplDirective, WidgetListGroupComponent, WidgetListGroupItemAnchorComponent, WidgetListGroupItemButtonComponent, WidgetListGroupItemComponent, WidgetListGroupItemIconTplDirective, WidgetRegistryService, WidgetTableComponent, WidgetTileComponent, WidgetTileFooterComponent, WidgetTileFooterItemComponent, WidgetTileGroupComponent, WidgetTileListComponent, WidgetTileSecondaryIconDirective, WidgetTitleTplDirective, extendStyles, toggleNativeDragInteractions };
1264
1380
  //# sourceMappingURL=theseam-ui-common-widget.mjs.map