@quadrel-enterprise-ui/qdc-cards 19.1.0 → 20.0.0-beta.3.1

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 (59) hide show
  1. package/esm2022/index.js +3 -0
  2. package/esm2022/index.js.map +1 -0
  3. package/esm2022/lib/card/{card.component.mjs → card.component.js} +14 -14
  4. package/esm2022/lib/card/card.component.js.map +1 -0
  5. package/esm2022/lib/card/card.model.js +2 -0
  6. package/esm2022/lib/card/card.model.js.map +1 -0
  7. package/esm2022/lib/card/card.module.js +23 -0
  8. package/esm2022/lib/card/card.module.js.map +1 -0
  9. package/esm2022/lib/card/menu/{card-menu.component.mjs → card-menu.component.js} +4 -4
  10. package/esm2022/lib/card/menu/card-menu.component.js.map +1 -0
  11. package/esm2022/lib/card/model/card-actions-config.interface.js +2 -0
  12. package/esm2022/lib/card/model/card-actions-config.interface.js.map +1 -0
  13. package/esm2022/lib/card-layout/card-layout.component.js +117 -0
  14. package/esm2022/lib/card-layout/card-layout.component.js.map +1 -0
  15. package/esm2022/lib/card-layout/card-layout.model.js +2 -0
  16. package/esm2022/lib/card-layout/card-layout.model.js.map +1 -0
  17. package/esm2022/lib/card-layout/card-layout.module.js +25 -0
  18. package/esm2022/lib/card-layout/card-layout.module.js.map +1 -0
  19. package/esm2022/lib/card-layout/card-status/card-status-height.directive.js +51 -0
  20. package/esm2022/lib/card-layout/card-status/card-status-height.directive.js.map +1 -0
  21. package/esm2022/lib/card-layout/card-status/card-status.component.js +112 -0
  22. package/esm2022/lib/card-layout/card-status/card-status.component.js.map +1 -0
  23. package/esm2022/lib/card-layout/card-status/card-status.model.js +2 -0
  24. package/esm2022/lib/card-layout/card-status/card-status.model.js.map +1 -0
  25. package/esm2022/lib/card-layout/card-status/pagination/pagination.model.js +2 -0
  26. package/esm2022/lib/card-layout/card-status/pagination/pagination.model.js.map +1 -0
  27. package/esm2022/lib/shared/popover/cards-popover.module.js +19 -0
  28. package/esm2022/lib/shared/popover/cards-popover.module.js.map +1 -0
  29. package/esm2022/lib/shared/popover/cards-popover.service.js +23 -0
  30. package/esm2022/lib/shared/popover/cards-popover.service.js.map +1 -0
  31. package/esm2022/lib/shared/popover/popover/cards-popover.component.js +14 -0
  32. package/esm2022/lib/shared/popover/popover/cards-popover.component.js.map +1 -0
  33. package/esm2022/lib/shared/popover/popover-on-click/cards-popover-on-click.directive.js +100 -0
  34. package/esm2022/lib/shared/popover/popover-on-click/cards-popover-on-click.directive.js.map +1 -0
  35. package/esm2022/quadrel-enterprise-ui-qdc-cards.js +5 -0
  36. package/esm2022/quadrel-enterprise-ui-qdc-cards.js.map +1 -0
  37. package/lib/card/card.component.d.ts +2 -3
  38. package/lib/card/model/card-actions-config.interface.d.ts +2 -5
  39. package/lib/card-layout/card-layout.component.d.ts +2 -3
  40. package/lib/card-layout/card-status/card-status-height.directive.d.ts +1 -2
  41. package/lib/shared/popover/popover-on-click/cards-popover-on-click.directive.d.ts +2 -4
  42. package/package.json +10 -10
  43. package/quadrel-enterprise-ui-qdc-cards.d.ts +5 -0
  44. package/esm2022/index.mjs +0 -3
  45. package/esm2022/lib/card/card.model.mjs +0 -2
  46. package/esm2022/lib/card/card.module.mjs +0 -23
  47. package/esm2022/lib/card/model/card-actions-config.interface.mjs +0 -2
  48. package/esm2022/lib/card-layout/card-layout.component.mjs +0 -117
  49. package/esm2022/lib/card-layout/card-layout.model.mjs +0 -2
  50. package/esm2022/lib/card-layout/card-layout.module.mjs +0 -25
  51. package/esm2022/lib/card-layout/card-status/card-status-height.directive.mjs +0 -51
  52. package/esm2022/lib/card-layout/card-status/card-status.component.mjs +0 -112
  53. package/esm2022/lib/card-layout/card-status/card-status.model.mjs +0 -2
  54. package/esm2022/lib/card-layout/card-status/pagination/pagination.model.mjs +0 -2
  55. package/esm2022/lib/shared/popover/cards-popover.module.mjs +0 -19
  56. package/esm2022/lib/shared/popover/cards-popover.service.mjs +0 -23
  57. package/esm2022/lib/shared/popover/popover/cards-popover.component.mjs +0 -14
  58. package/esm2022/lib/shared/popover/popover-on-click/cards-popover-on-click.directive.mjs +0 -100
  59. package/esm2022/quadrel-enterprise-ui-qdc-cards.mjs +0 -5
@@ -0,0 +1,3 @@
1
+ export * from './lib/card-layout/card-layout.module';
2
+ export * from './lib/card/card.module';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/qdc-cards/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAC;AACrD,cAAc,wBAAwB,CAAC","sourcesContent":["export * from './lib/card-layout/card-layout.module';\nexport * from './lib/card/card.module';\n"]}
@@ -1,23 +1,23 @@
1
- import { ChangeDetectionStrategy, Component, HostBinding, Input, TemplateRef, ViewEncapsulation } from '@angular/core';
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostBinding, inject, Input, TemplateRef, ViewEncapsulation } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
3
  import * as i1 from "@quadrel-enterprise-ui/framework";
4
4
  import * as i2 from "./menu/card-menu.component";
5
5
  import * as i3 from "@ngx-translate/core";
6
6
  export class QdcCardComponent {
7
- get isMobile() {
8
- if (typeof window !== 'undefined') {
9
- return window.matchMedia('(max-width: 599px)').matches;
10
- }
11
- return false;
12
- }
13
- constructor(cdr) {
14
- this.cdr = cdr;
7
+ constructor() {
15
8
  /** JSON configuration driving the visual appearance of the card. */
16
9
  this.cardConfig = {};
17
10
  /** Optional test-id for E2E / integration tests. */
18
11
  this.testId = 'card';
19
12
  this.hasHeader = false;
20
13
  this.hasFooter = false;
14
+ this.cdr = inject(ChangeDetectorRef);
15
+ }
16
+ get isMobile() {
17
+ if (typeof window !== 'undefined') {
18
+ return window.matchMedia('(max-width: 599px)').matches;
19
+ }
20
+ return false;
21
21
  }
22
22
  ngAfterContentInit() {
23
23
  this.evaluateVisibility();
@@ -32,16 +32,16 @@ export class QdcCardComponent {
32
32
  isTemplate(value) {
33
33
  return value instanceof TemplateRef;
34
34
  }
35
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: QdcCardComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
36
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: QdcCardComponent, isStandalone: false, selector: "qdc-card", inputs: { cardConfig: "cardConfig", testId: ["data-test-id", "testId"] }, host: { properties: { "attr.data-test-id": "testId", "class.mobile": "this.isMobile" }, classAttribute: "qdc-card" }, usesOnChanges: true, ngImport: i0, template: "<article class=\"qdc-card\" (click)=\"cardConfig?.onCardClick()\">\n @if (cardConfig) {\n <!-- Header -->\n @if (cardConfig.icon || cardConfig.title || cardConfig.subTitle || cardConfig.chip) {\n <header class=\"qdc-card__header\">\n <div class=\"qdc-card__header-left\">\n @if (cardConfig.icon) {\n <qd-icon class=\"qdc-card__icon\" [icon]=\"cardConfig.icon\"></qd-icon>\n }\n <div class=\"qdc-card__header-main\">\n @if (cardConfig.title) {\n <span class=\"qdc-card__title\">{{ cardConfig.title }}</span>\n } @if (cardConfig.subTitle) {\n <span class=\"qdc-card__subtitle\">{{ cardConfig.subTitle }}</span>\n }\n </div>\n </div>\n\n <div class=\"qdc-card__header-right\">\n @if (cardConfig.chip) {\n <qd-chip [state]=\"cardConfig.chip!.state\" data-test-id=\"test-chip\">\n {{ cardConfig.chip!.label.i18n | translate }}\n </qd-chip>\n } @if (cardConfig.menuActions) {\n <div class=\"qdc-card__header-actions\">\n <qdc-card-menu [actions]=\"cardConfig.menuActions\"></qdc-card-menu>\n </div>\n }\n </div>\n </header>\n }\n\n <!-- Body -->\n @if (cardConfig.bodyPairs) {\n <div class=\"qdc-card__body\">\n <div class=\"qdc-card__body-grid\">\n @for (item of cardConfig.bodyPairs; track item) {\n <div class=\"qdc-card__body-row\">\n <div class=\"qdc-card__body-label\">\n <span>{{ item.i18n | translate }}</span>\n </div>\n <div class=\"qdc-card__body-content\">\n @if (item.value) {\n <span class=\"qdc-card__body-value\">{{ item.value }}</span>\n } @if (item.status) {\n <qd-status-indicator [type]=\"item.status.type\" [level]=\"item.status.level\"></qd-status-indicator>\n } @if (item.icon) {\n <qd-icon [icon]=\"item.icon\"></qd-icon>\n } @if (item.chips) {\n <div class=\"qdc-card__body-chips\">\n @for (chip of item.chips; track chip) {\n <qd-chip [state]=\"chip.state\" class=\"qdc-card__body-chip\">\n {{ chip.label.i18n | translate }}\n </qd-chip>\n }\n </div>\n } @if (item.booleanValue !== undefined) {\n <qd-icon [icon]=\"item.booleanValue ? 'checkmark' : 'timesLarge'\"></qd-icon>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Footer -->\n @if (cardConfig.footer) {\n <footer class=\"qdc-card__footer\">\n @if (cardConfig.footer.icon || cardConfig.footer.text) {\n <div class=\"qdc-card__footer-start\">\n <qd-icon class=\"qdc-card__footer-icon\" [icon]=\"cardConfig.footer.icon\"></qd-icon>\n <span class=\"qdc-card__footer-text\">{{ cardConfig.footer.text | translate }}</span>\n </div>\n } @if (cardConfig.footer.action) {\n <div class=\"qdc-card__footer-end\">\n <button\n qdButton\n qdButtonGhost\n [disabled]=\"cardConfig.footer.action?.isDisabled\"\n (click)=\"cardConfig.footer.action?.handler()\"\n [icon]=\"cardConfig.footer.action?.icon\"\n data-test-id=\"test-footer-button\"\n >\n {{ cardConfig.footer.action?.label.i18n | translate }}\n </button>\n </div>\n }\n </footer>\n } } @else {\n <div class=\"qdc-card__empty\">\n <span class=\"qdc-card__empty-text\">No card configuration provided.</span>\n </div>\n }\n</article>\n", styles: ["@charset \"UTF-8\";:root{--border-col: #e0e0e0;--text: #222;--muted: #666;--chip-bg: #fff;--chip-bd: #bdbdbd;--chip-prio: #ff9800;--chip-status: #11a35d;--btn-bg: #fff;--btn-bd: #0067b8;--btn-tx: #0067b8;--row-gap: .6rem}.qdc-card{font-family:Roboto,sans-serif;display:flex;overflow:hidden;width:100%;flex-direction:column;border:1px solid var(--border-col);border-radius:4px;background:#fff}.qdc-card+.qdc-card{margin-top:clamp(.25rem,1vw,.5rem)}.row{display:flex;align-items:center;gap:.5rem}.wrap{flex-wrap:wrap}.ml-auto{margin-left:auto}.text-muted{color:var(--muted);font-size:.875rem}.fw-bold{font-weight:600}.chip{display:inline-flex;height:1.5rem;align-items:center;justify-content:center;padding:0 .6rem;border:1px solid var(--chip-bd);border-radius:16px;background:var(--chip-bg);font-size:.75rem;line-height:1;white-space:nowrap}.chip.prio{border-color:var(--chip-prio);color:var(--chip-prio)}.chip.status{border-color:var(--chip-status);color:var(--chip-status)}.btn{display:inline-flex;align-items:center;justify-content:center;padding:.4rem 1.2rem;border:2px solid var(--btn-bd);border-radius:2px;background:var(--btn-bg);color:var(--btn-tx);cursor:pointer;font-size:.875rem;font-weight:600;gap:.4rem;text-decoration:none}.btn:hover{background:#f0f8ff}.qdc-card__header{display:flex;align-items:center;padding:1rem;border-bottom:1px solid var(--border-col);gap:.8rem}.qdc-card__header-left{display:flex;align-items:center;gap:.5rem}.qdc-card__header-main{display:grid}.qdc-card__title{font-weight:700}.qdc-card__icon{font-size:1.4rem;line-height:1}.qdc-card__subtitle{color:var(--muted);font-size:.875rem}.qdc-card__header-right{display:flex;align-items:center;margin-left:auto;gap:.5rem}.qdc-card__menu{cursor:pointer;font-size:1.4rem;line-height:1}.qdc-card__body{display:grid;padding:1rem;column-gap:.5rem;grid-template-columns:1fr auto;row-gap:var(--row-gap)}.qdc-card__body>*{margin:0}.qdc-card__body-value{color:var(--text);font-size:.8rem}.qdc-card__body-chips{display:flex;flex-wrap:wrap;gap:.5rem}.qdc-card__footer{display:flex;justify-content:space-between;padding:.7rem 1rem;border-top:1px solid var(--border-col);gap:.8rem}.qdc-card__footer-start{display:flex;flex:1;align-items:center;justify-content:start;gap:.5rem}.qdc-card__footer-start qd-icon{font-size:1.5rem;line-height:1}.qdc-card__footer-end{display:flex;flex:2;justify-content:end;gap:.5rem}.qdc-card__footer-text{font-size:.7rem}.qdc-card__body-grid{display:flex;flex-direction:column;gap:14px}.qdc-card__body-row{display:grid;grid-template-columns:33% 66%;gap:5px}.qdc-card__body-label{color:var(--muted);font-size:.8rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.qdc-card__body-content{color:var(--text);font-size:.8rem}.qdc-card__body-content qd-icon{color:var(--text);font-size:1.4rem;line-height:1}@media (max-width: 480px){.qdc-card{max-width:100%}.qdc-card__body{grid-template-columns:1fr}.qdc-card__header-right{margin-left:0}.qdc-card__footer .btn{width:100%;justify-content:center}}\n"], dependencies: [{ kind: "component", type: i1.QdButtonComponent, selector: "button[qdButton], a[qdButton], button[qd-button]", inputs: ["disabled", "color", "icon", "data-test-id", "additionalInfo"] }, { kind: "directive", type: i1.QdButtonGhostDirective, selector: "button[qdButtonGhost], a[qdButtonGhost]" }, { kind: "component", type: i1.QdChipComponent, selector: "qd-chip", inputs: ["state", "close", "data", "data-test-id"], outputs: ["closeClickEmitter"] }, { kind: "component", type: i1.QdIconComponent, selector: "qd-icon", inputs: ["icon"] }, { kind: "component", type: i1.QdStatusIndicatorComponent, selector: "qd-status-indicator", inputs: ["type", "level", "caption", "data-test-id"] }, { kind: "component", type: i2.QdcCardMenuComponent, selector: "qdc-card-menu", inputs: ["actions", "data-test-id"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
35
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
36
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: QdcCardComponent, isStandalone: false, selector: "qdc-card", inputs: { cardConfig: "cardConfig", testId: ["data-test-id", "testId"] }, host: { properties: { "attr.data-test-id": "testId", "class.mobile": "this.isMobile" }, classAttribute: "qdc-card" }, usesOnChanges: true, ngImport: i0, template: "<article class=\"qdc-card\" (click)=\"cardConfig?.onCardClick()\">\n @if (cardConfig) {\n <!-- Header -->\n @if (cardConfig.icon || cardConfig.title || cardConfig.subTitle || cardConfig.chip) {\n <header class=\"qdc-card__header\">\n <div class=\"qdc-card__header-left\">\n @if (cardConfig.icon) {\n <qd-icon class=\"qdc-card__icon\" [icon]=\"cardConfig.icon\"></qd-icon>\n }\n <div class=\"qdc-card__header-main\">\n @if (cardConfig.title) {\n <span class=\"qdc-card__title\">{{ cardConfig.title }}</span>\n } @if (cardConfig.subTitle) {\n <span class=\"qdc-card__subtitle\">{{ cardConfig.subTitle }}</span>\n }\n </div>\n </div>\n\n <div class=\"qdc-card__header-right\">\n @if (cardConfig.chip) {\n <qd-chip [state]=\"cardConfig.chip!.state\" data-test-id=\"test-chip\">\n {{ cardConfig.chip!.label.i18n | translate }}\n </qd-chip>\n } @if (cardConfig.menuActions) {\n <div class=\"qdc-card__header-actions\">\n <qdc-card-menu [actions]=\"cardConfig.menuActions\"></qdc-card-menu>\n </div>\n }\n </div>\n </header>\n }\n\n <!-- Body -->\n @if (cardConfig.bodyPairs) {\n <div class=\"qdc-card__body\">\n <div class=\"qdc-card__body-grid\">\n @for (item of cardConfig.bodyPairs; track item) {\n <div class=\"qdc-card__body-row\">\n <div class=\"qdc-card__body-label\">\n <span>{{ item.i18n | translate }}</span>\n </div>\n <div class=\"qdc-card__body-content\">\n @if (item.value) {\n <span class=\"qdc-card__body-value\">{{ item.value }}</span>\n } @if (item.status) {\n <qd-status-indicator [type]=\"item.status.type\" [level]=\"item.status.level\"></qd-status-indicator>\n } @if (item.icon) {\n <qd-icon [icon]=\"item.icon\"></qd-icon>\n } @if (item.chips) {\n <div class=\"qdc-card__body-chips\">\n @for (chip of item.chips; track chip) {\n <qd-chip [state]=\"chip.state\" class=\"qdc-card__body-chip\">\n {{ chip.label.i18n | translate }}\n </qd-chip>\n }\n </div>\n } @if (item.booleanValue !== undefined) {\n <qd-icon [icon]=\"item.booleanValue ? 'checkmark' : 'timesLarge'\"></qd-icon>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Footer -->\n @if (cardConfig.footer) {\n <footer class=\"qdc-card__footer\">\n @if (cardConfig.footer.icon || cardConfig.footer.text) {\n <div class=\"qdc-card__footer-start\">\n <qd-icon class=\"qdc-card__footer-icon\" [icon]=\"cardConfig.footer.icon\"></qd-icon>\n <span class=\"qdc-card__footer-text\">{{ cardConfig.footer.text | translate }}</span>\n </div>\n } @if (cardConfig.footer.action) {\n <div class=\"qdc-card__footer-end\">\n <button\n qdButton\n qdButtonGhost\n [disabled]=\"cardConfig.footer.action?.isDisabled\"\n (click)=\"cardConfig.footer.action?.handler()\"\n [icon]=\"cardConfig.footer.action?.icon\"\n data-test-id=\"test-footer-button\"\n >\n {{ cardConfig.footer.action?.label.i18n | translate }}\n </button>\n </div>\n }\n </footer>\n } } @else {\n <div class=\"qdc-card__empty\">\n <span class=\"qdc-card__empty-text\">No card configuration provided.</span>\n </div>\n }\n</article>\n", styles: ["@charset \"UTF-8\";:root{--border-col: #e0e0e0;--text: #222;--muted: #666;--chip-bg: #fff;--chip-bd: #bdbdbd;--chip-prio: #ff9800;--chip-status: #11a35d;--btn-bg: #fff;--btn-bd: #0067b8;--btn-tx: #0067b8;--row-gap: .6rem}.qdc-card{font-family:Roboto,sans-serif;display:flex;overflow:hidden;width:100%;flex-direction:column;border:1px solid var(--border-col);border-radius:4px;background:#fff}.qdc-card+.qdc-card{margin-top:clamp(.25rem,1vw,.5rem)}.row{display:flex;align-items:center;gap:.5rem}.wrap{flex-wrap:wrap}.ml-auto{margin-left:auto}.text-muted{color:var(--muted);font-size:.875rem}.fw-bold{font-weight:600}.chip{display:inline-flex;height:1.5rem;align-items:center;justify-content:center;padding:0 .6rem;border:1px solid var(--chip-bd);border-radius:16px;background:var(--chip-bg);font-size:.75rem;line-height:1;white-space:nowrap}.chip.prio{border-color:var(--chip-prio);color:var(--chip-prio)}.chip.status{border-color:var(--chip-status);color:var(--chip-status)}.btn{display:inline-flex;align-items:center;justify-content:center;padding:.4rem 1.2rem;border:2px solid var(--btn-bd);border-radius:2px;background:var(--btn-bg);color:var(--btn-tx);cursor:pointer;font-size:.875rem;font-weight:600;gap:.4rem;text-decoration:none}.btn:hover{background:#f0f8ff}.qdc-card__header{display:flex;align-items:center;padding:1rem;border-bottom:1px solid var(--border-col);gap:.8rem}.qdc-card__header-left{display:flex;align-items:center;gap:.5rem}.qdc-card__header-main{display:grid}.qdc-card__title{font-weight:700}.qdc-card__icon{font-size:1.4rem;line-height:1}.qdc-card__subtitle{color:var(--muted);font-size:.875rem}.qdc-card__header-right{display:flex;align-items:center;margin-left:auto;gap:.5rem}.qdc-card__menu{cursor:pointer;font-size:1.4rem;line-height:1}.qdc-card__body{display:grid;padding:1rem;column-gap:.5rem;grid-template-columns:1fr auto;row-gap:var(--row-gap)}.qdc-card__body>*{margin:0}.qdc-card__body-value{color:var(--text);font-size:.8rem}.qdc-card__body-chips{display:flex;flex-wrap:wrap;gap:.5rem}.qdc-card__footer{display:flex;justify-content:space-between;padding:.7rem 1rem;border-top:1px solid var(--border-col);gap:.8rem}.qdc-card__footer-start{display:flex;flex:1;align-items:center;justify-content:start;gap:.5rem}.qdc-card__footer-start qd-icon{font-size:1.5rem;line-height:1}.qdc-card__footer-end{display:flex;flex:2;justify-content:end;gap:.5rem}.qdc-card__footer-text{font-size:.7rem}.qdc-card__body-grid{display:flex;flex-direction:column;gap:14px}.qdc-card__body-row{display:grid;grid-template-columns:33% 66%;gap:5px}.qdc-card__body-label{color:var(--muted);font-size:.8rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.qdc-card__body-content{color:var(--text);font-size:.8rem}.qdc-card__body-content qd-icon{color:var(--text);font-size:1.4rem;line-height:1}@media (max-width: 480px){.qdc-card{max-width:100%}.qdc-card__body{grid-template-columns:1fr}.qdc-card__header-right{margin-left:0}.qdc-card__footer .btn{width:100%;justify-content:center}}\n"], dependencies: [{ kind: "component", type: i1.QdButtonComponent, selector: "button[qdButton], a[qdButton], button[qd-button]", inputs: ["disabled", "color", "icon", "data-test-id", "additionalInfo"] }, { kind: "directive", type: i1.QdButtonGhostDirective, selector: "button[qdButtonGhost], a[qdButtonGhost]" }, { kind: "component", type: i1.QdChipComponent, selector: "qd-chip", inputs: ["state", "close", "data", "data-test-id"], outputs: ["closeClickEmitter"] }, { kind: "component", type: i1.QdIconComponent, selector: "qd-icon", inputs: ["icon"] }, { kind: "component", type: i1.QdStatusIndicatorComponent, selector: "qd-status-indicator", inputs: ["type", "level", "caption", "data-test-id"] }, { kind: "component", type: i2.QdcCardMenuComponent, selector: "qdc-card-menu", inputs: ["actions", "data-test-id"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
37
37
  }
38
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: QdcCardComponent, decorators: [{
38
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardComponent, decorators: [{
39
39
  type: Component,
40
40
  args: [{ selector: 'qdc-card', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
41
41
  class: 'qdc-card',
42
42
  '[attr.data-test-id]': 'testId'
43
43
  }, standalone: false, template: "<article class=\"qdc-card\" (click)=\"cardConfig?.onCardClick()\">\n @if (cardConfig) {\n <!-- Header -->\n @if (cardConfig.icon || cardConfig.title || cardConfig.subTitle || cardConfig.chip) {\n <header class=\"qdc-card__header\">\n <div class=\"qdc-card__header-left\">\n @if (cardConfig.icon) {\n <qd-icon class=\"qdc-card__icon\" [icon]=\"cardConfig.icon\"></qd-icon>\n }\n <div class=\"qdc-card__header-main\">\n @if (cardConfig.title) {\n <span class=\"qdc-card__title\">{{ cardConfig.title }}</span>\n } @if (cardConfig.subTitle) {\n <span class=\"qdc-card__subtitle\">{{ cardConfig.subTitle }}</span>\n }\n </div>\n </div>\n\n <div class=\"qdc-card__header-right\">\n @if (cardConfig.chip) {\n <qd-chip [state]=\"cardConfig.chip!.state\" data-test-id=\"test-chip\">\n {{ cardConfig.chip!.label.i18n | translate }}\n </qd-chip>\n } @if (cardConfig.menuActions) {\n <div class=\"qdc-card__header-actions\">\n <qdc-card-menu [actions]=\"cardConfig.menuActions\"></qdc-card-menu>\n </div>\n }\n </div>\n </header>\n }\n\n <!-- Body -->\n @if (cardConfig.bodyPairs) {\n <div class=\"qdc-card__body\">\n <div class=\"qdc-card__body-grid\">\n @for (item of cardConfig.bodyPairs; track item) {\n <div class=\"qdc-card__body-row\">\n <div class=\"qdc-card__body-label\">\n <span>{{ item.i18n | translate }}</span>\n </div>\n <div class=\"qdc-card__body-content\">\n @if (item.value) {\n <span class=\"qdc-card__body-value\">{{ item.value }}</span>\n } @if (item.status) {\n <qd-status-indicator [type]=\"item.status.type\" [level]=\"item.status.level\"></qd-status-indicator>\n } @if (item.icon) {\n <qd-icon [icon]=\"item.icon\"></qd-icon>\n } @if (item.chips) {\n <div class=\"qdc-card__body-chips\">\n @for (chip of item.chips; track chip) {\n <qd-chip [state]=\"chip.state\" class=\"qdc-card__body-chip\">\n {{ chip.label.i18n | translate }}\n </qd-chip>\n }\n </div>\n } @if (item.booleanValue !== undefined) {\n <qd-icon [icon]=\"item.booleanValue ? 'checkmark' : 'timesLarge'\"></qd-icon>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Footer -->\n @if (cardConfig.footer) {\n <footer class=\"qdc-card__footer\">\n @if (cardConfig.footer.icon || cardConfig.footer.text) {\n <div class=\"qdc-card__footer-start\">\n <qd-icon class=\"qdc-card__footer-icon\" [icon]=\"cardConfig.footer.icon\"></qd-icon>\n <span class=\"qdc-card__footer-text\">{{ cardConfig.footer.text | translate }}</span>\n </div>\n } @if (cardConfig.footer.action) {\n <div class=\"qdc-card__footer-end\">\n <button\n qdButton\n qdButtonGhost\n [disabled]=\"cardConfig.footer.action?.isDisabled\"\n (click)=\"cardConfig.footer.action?.handler()\"\n [icon]=\"cardConfig.footer.action?.icon\"\n data-test-id=\"test-footer-button\"\n >\n {{ cardConfig.footer.action?.label.i18n | translate }}\n </button>\n </div>\n }\n </footer>\n } } @else {\n <div class=\"qdc-card__empty\">\n <span class=\"qdc-card__empty-text\">No card configuration provided.</span>\n </div>\n }\n</article>\n", styles: ["@charset \"UTF-8\";:root{--border-col: #e0e0e0;--text: #222;--muted: #666;--chip-bg: #fff;--chip-bd: #bdbdbd;--chip-prio: #ff9800;--chip-status: #11a35d;--btn-bg: #fff;--btn-bd: #0067b8;--btn-tx: #0067b8;--row-gap: .6rem}.qdc-card{font-family:Roboto,sans-serif;display:flex;overflow:hidden;width:100%;flex-direction:column;border:1px solid var(--border-col);border-radius:4px;background:#fff}.qdc-card+.qdc-card{margin-top:clamp(.25rem,1vw,.5rem)}.row{display:flex;align-items:center;gap:.5rem}.wrap{flex-wrap:wrap}.ml-auto{margin-left:auto}.text-muted{color:var(--muted);font-size:.875rem}.fw-bold{font-weight:600}.chip{display:inline-flex;height:1.5rem;align-items:center;justify-content:center;padding:0 .6rem;border:1px solid var(--chip-bd);border-radius:16px;background:var(--chip-bg);font-size:.75rem;line-height:1;white-space:nowrap}.chip.prio{border-color:var(--chip-prio);color:var(--chip-prio)}.chip.status{border-color:var(--chip-status);color:var(--chip-status)}.btn{display:inline-flex;align-items:center;justify-content:center;padding:.4rem 1.2rem;border:2px solid var(--btn-bd);border-radius:2px;background:var(--btn-bg);color:var(--btn-tx);cursor:pointer;font-size:.875rem;font-weight:600;gap:.4rem;text-decoration:none}.btn:hover{background:#f0f8ff}.qdc-card__header{display:flex;align-items:center;padding:1rem;border-bottom:1px solid var(--border-col);gap:.8rem}.qdc-card__header-left{display:flex;align-items:center;gap:.5rem}.qdc-card__header-main{display:grid}.qdc-card__title{font-weight:700}.qdc-card__icon{font-size:1.4rem;line-height:1}.qdc-card__subtitle{color:var(--muted);font-size:.875rem}.qdc-card__header-right{display:flex;align-items:center;margin-left:auto;gap:.5rem}.qdc-card__menu{cursor:pointer;font-size:1.4rem;line-height:1}.qdc-card__body{display:grid;padding:1rem;column-gap:.5rem;grid-template-columns:1fr auto;row-gap:var(--row-gap)}.qdc-card__body>*{margin:0}.qdc-card__body-value{color:var(--text);font-size:.8rem}.qdc-card__body-chips{display:flex;flex-wrap:wrap;gap:.5rem}.qdc-card__footer{display:flex;justify-content:space-between;padding:.7rem 1rem;border-top:1px solid var(--border-col);gap:.8rem}.qdc-card__footer-start{display:flex;flex:1;align-items:center;justify-content:start;gap:.5rem}.qdc-card__footer-start qd-icon{font-size:1.5rem;line-height:1}.qdc-card__footer-end{display:flex;flex:2;justify-content:end;gap:.5rem}.qdc-card__footer-text{font-size:.7rem}.qdc-card__body-grid{display:flex;flex-direction:column;gap:14px}.qdc-card__body-row{display:grid;grid-template-columns:33% 66%;gap:5px}.qdc-card__body-label{color:var(--muted);font-size:.8rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.qdc-card__body-content{color:var(--text);font-size:.8rem}.qdc-card__body-content qd-icon{color:var(--text);font-size:1.4rem;line-height:1}@media (max-width: 480px){.qdc-card{max-width:100%}.qdc-card__body{grid-template-columns:1fr}.qdc-card__header-right{margin-left:0}.qdc-card__footer .btn{width:100%;justify-content:center}}\n"] }]
44
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { cardConfig: [{
44
+ }], propDecorators: { cardConfig: [{
45
45
  type: Input
46
46
  }], testId: [{
47
47
  type: Input,
@@ -50,4 +50,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
50
50
  type: HostBinding,
51
51
  args: ['class.mobile']
52
52
  }] } });
53
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FyZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL3FkYy1jYXJkcy9zcmMvbGliL2NhcmQvY2FyZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL3FkYy1jYXJkcy9zcmMvbGliL2NhcmQvY2FyZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxXQUFXLEVBQ1gsS0FBSyxFQUVMLFdBQVcsRUFDWCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7Ozs7O0FBZXZCLE1BQU0sT0FBTyxnQkFBZ0I7SUFVM0IsSUFBaUMsUUFBUTtRQUN2QyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sTUFBTSxDQUFDLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN6RCxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsWUFBb0IsR0FBc0I7UUFBdEIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFoQjFDLG9FQUFvRTtRQUMzRCxlQUFVLEdBQWtCLEVBQUUsQ0FBQztRQUV4QyxvREFBb0Q7UUFDN0IsV0FBTSxHQUFHLE1BQU0sQ0FBQztRQUV2QyxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLGNBQVMsR0FBRyxLQUFLLENBQUM7SUFTMkIsQ0FBQztJQUU5QyxrQkFBa0I7UUFDaEIsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRU8sa0JBQWtCO1FBQ3hCLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNsRyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRCxVQUFVLENBQUMsS0FBYztRQUN2QixPQUFPLEtBQUssWUFBWSxXQUFXLENBQUM7SUFDdEMsQ0FBQzsrR0FsQ1UsZ0JBQWdCO21HQUFoQixnQkFBZ0IsMFJDekI3Qix1MkdBK0ZBOzs0RkR0RWEsZ0JBQWdCO2tCQVo1QixTQUFTOytCQUNFLFVBQVUsaUJBR0wsaUJBQWlCLENBQUMsSUFBSSxtQkFDcEIsdUJBQXVCLENBQUMsTUFBTSxRQUN6Qzt3QkFDSixLQUFLLEVBQUUsVUFBVTt3QkFDakIscUJBQXFCLEVBQUUsUUFBUTtxQkFDaEMsY0FDVyxLQUFLO3NGQUlSLFVBQVU7c0JBQWxCLEtBQUs7Z0JBR2lCLE1BQU07c0JBQTVCLEtBQUs7dUJBQUMsY0FBYztnQkFLWSxRQUFRO3NCQUF4QyxXQUFXO3VCQUFDLGNBQWMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgSG9zdEJpbmRpbmcsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFFkY0NhcmRDb25maWcgfSBmcm9tICcuL2NhcmQubW9kZWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdxZGMtY2FyZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9jYXJkLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY2FyZC5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAncWRjLWNhcmQnLFxuICAgICdbYXR0ci5kYXRhLXRlc3QtaWRdJzogJ3Rlc3RJZCdcbiAgfSxcbiAgc3RhbmRhbG9uZTogZmFsc2Vcbn0pXG5leHBvcnQgY2xhc3MgUWRjQ2FyZENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQsIE9uQ2hhbmdlcyB7XG4gIC8qKiBKU09OIGNvbmZpZ3VyYXRpb24gZHJpdmluZyB0aGUgdmlzdWFsIGFwcGVhcmFuY2Ugb2YgdGhlIGNhcmQuICovXG4gIEBJbnB1dCgpIGNhcmRDb25maWc6IFFkY0NhcmRDb25maWcgPSB7fTtcblxuICAvKiogT3B0aW9uYWwgdGVzdC1pZCBmb3IgRTJFIC8gaW50ZWdyYXRpb24gdGVzdHMuICovXG4gIEBJbnB1dCgnZGF0YS10ZXN0LWlkJykgdGVzdElkID0gJ2NhcmQnO1xuXG4gIGhhc0hlYWRlciA9IGZhbHNlO1xuICBoYXNGb290ZXIgPSBmYWxzZTtcblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1vYmlsZScpIGdldCBpc01vYmlsZSgpOiBib29sZWFuIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiB3aW5kb3cubWF0Y2hNZWRpYSgnKG1heC13aWR0aDogNTk5cHgpJykubWF0Y2hlcztcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmV2YWx1YXRlVmlzaWJpbGl0eSgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5ldmFsdWF0ZVZpc2liaWxpdHkoKTtcbiAgfVxuXG4gIHByaXZhdGUgZXZhbHVhdGVWaXNpYmlsaXR5KCk6IHZvaWQge1xuICAgIHRoaXMuaGFzSGVhZGVyID0gISEodGhpcy5jYXJkQ29uZmlnPy5pY29uIHx8IHRoaXMuY2FyZENvbmZpZz8udGl0bGUgfHwgdGhpcy5jYXJkQ29uZmlnPy5zdWJUaXRsZSk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBpc1RlbXBsYXRlKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgVGVtcGxhdGVSZWY8dW5rbm93bj4ge1xuICAgIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFRlbXBsYXRlUmVmO1xuICB9XG59XG4iLCI8YXJ0aWNsZSBjbGFzcz1cInFkYy1jYXJkXCIgKGNsaWNrKT1cImNhcmRDb25maWc/Lm9uQ2FyZENsaWNrKClcIj5cbiAgQGlmIChjYXJkQ29uZmlnKSB7XG4gIDwhLS0gSGVhZGVyIC0tPlxuICBAaWYgKGNhcmRDb25maWcuaWNvbiB8fCBjYXJkQ29uZmlnLnRpdGxlIHx8IGNhcmRDb25maWcuc3ViVGl0bGUgfHwgY2FyZENvbmZpZy5jaGlwKSB7XG4gIDxoZWFkZXIgY2xhc3M9XCJxZGMtY2FyZF9faGVhZGVyXCI+XG4gICAgPGRpdiBjbGFzcz1cInFkYy1jYXJkX19oZWFkZXItbGVmdFwiPlxuICAgICAgQGlmIChjYXJkQ29uZmlnLmljb24pIHtcbiAgICAgIDxxZC1pY29uIGNsYXNzPVwicWRjLWNhcmRfX2ljb25cIiBbaWNvbl09XCJjYXJkQ29uZmlnLmljb25cIj48L3FkLWljb24+XG4gICAgICB9XG4gICAgICA8ZGl2IGNsYXNzPVwicWRjLWNhcmRfX2hlYWRlci1tYWluXCI+XG4gICAgICAgIEBpZiAoY2FyZENvbmZpZy50aXRsZSkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cInFkYy1jYXJkX190aXRsZVwiPnt7IGNhcmRDb25maWcudGl0bGUgfX08L3NwYW4+XG4gICAgICAgIH0gQGlmIChjYXJkQ29uZmlnLnN1YlRpdGxlKSB7XG4gICAgICAgIDxzcGFuIGNsYXNzPVwicWRjLWNhcmRfX3N1YnRpdGxlXCI+e3sgY2FyZENvbmZpZy5zdWJUaXRsZSB9fTwvc3Bhbj5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwicWRjLWNhcmRfX2hlYWRlci1yaWdodFwiPlxuICAgICAgQGlmIChjYXJkQ29uZmlnLmNoaXApIHtcbiAgICAgIDxxZC1jaGlwIFtzdGF0ZV09XCJjYXJkQ29uZmlnLmNoaXAhLnN0YXRlXCIgZGF0YS10ZXN0LWlkPVwidGVzdC1jaGlwXCI+XG4gICAgICAgIHt7IGNhcmRDb25maWcuY2hpcCEubGFiZWwuaTE4biB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9xZC1jaGlwPlxuICAgICAgfSBAaWYgKGNhcmRDb25maWcubWVudUFjdGlvbnMpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJxZGMtY2FyZF9faGVhZGVyLWFjdGlvbnNcIj5cbiAgICAgICAgPHFkYy1jYXJkLW1lbnUgW2FjdGlvbnNdPVwiY2FyZENvbmZpZy5tZW51QWN0aW9uc1wiPjwvcWRjLWNhcmQtbWVudT5cbiAgICAgIDwvZGl2PlxuICAgICAgfVxuICAgIDwvZGl2PlxuICA8L2hlYWRlcj5cbiAgfVxuXG4gIDwhLS0gQm9keSAtLT5cbiAgQGlmIChjYXJkQ29uZmlnLmJvZHlQYWlycykge1xuICA8ZGl2IGNsYXNzPVwicWRjLWNhcmRfX2JvZHlcIj5cbiAgICA8ZGl2IGNsYXNzPVwicWRjLWNhcmRfX2JvZHktZ3JpZFwiPlxuICAgICAgQGZvciAoaXRlbSBvZiBjYXJkQ29uZmlnLmJvZHlQYWlyczsgdHJhY2sgaXRlbSkge1xuICAgICAgPGRpdiBjbGFzcz1cInFkYy1jYXJkX19ib2R5LXJvd1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicWRjLWNhcmRfX2JvZHktbGFiZWxcIj5cbiAgICAgICAgICA8c3Bhbj57eyBpdGVtLmkxOG4gfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwicWRjLWNhcmRfX2JvZHktY29udGVudFwiPlxuICAgICAgICAgIEBpZiAoaXRlbS52YWx1ZSkge1xuICAgICAgICAgIDxzcGFuIGNsYXNzPVwicWRjLWNhcmRfX2JvZHktdmFsdWVcIj57eyBpdGVtLnZhbHVlIH19PC9zcGFuPlxuICAgICAgICAgIH0gQGlmIChpdGVtLnN0YXR1cykge1xuICAgICAgICAgIDxxZC1zdGF0dXMtaW5kaWNhdG9yIFt0eXBlXT1cIml0ZW0uc3RhdHVzLnR5cGVcIiBbbGV2ZWxdPVwiaXRlbS5zdGF0dXMubGV2ZWxcIj48L3FkLXN0YXR1cy1pbmRpY2F0b3I+XG4gICAgICAgICAgfSBAaWYgKGl0ZW0uaWNvbikge1xuICAgICAgICAgIDxxZC1pY29uIFtpY29uXT1cIml0ZW0uaWNvblwiPjwvcWQtaWNvbj5cbiAgICAgICAgICB9IEBpZiAoaXRlbS5jaGlwcykge1xuICAgICAgICAgIDxkaXYgY2xhc3M9XCJxZGMtY2FyZF9fYm9keS1jaGlwc1wiPlxuICAgICAgICAgICAgQGZvciAoY2hpcCBvZiBpdGVtLmNoaXBzOyB0cmFjayBjaGlwKSB7XG4gICAgICAgICAgICA8cWQtY2hpcCBbc3RhdGVdPVwiY2hpcC5zdGF0ZVwiIGNsYXNzPVwicWRjLWNhcmRfX2JvZHktY2hpcFwiPlxuICAgICAgICAgICAgICB7eyBjaGlwLmxhYmVsLmkxOG4gfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgIDwvcWQtY2hpcD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9IEBpZiAoaXRlbS5ib29sZWFuVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIDxxZC1pY29uIFtpY29uXT1cIml0ZW0uYm9vbGVhblZhbHVlID8gJ2NoZWNrbWFyaycgOiAndGltZXNMYXJnZSdcIj48L3FkLWljb24+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgfVxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgfVxuXG4gIDwhLS0gRm9vdGVyIC0tPlxuICBAaWYgKGNhcmRDb25maWcuZm9vdGVyKSB7XG4gIDxmb290ZXIgY2xhc3M9XCJxZGMtY2FyZF9fZm9vdGVyXCI+XG4gICAgQGlmIChjYXJkQ29uZmlnLmZvb3Rlci5pY29uIHx8IGNhcmRDb25maWcuZm9vdGVyLnRleHQpIHtcbiAgICA8ZGl2IGNsYXNzPVwicWRjLWNhcmRfX2Zvb3Rlci1zdGFydFwiPlxuICAgICAgPHFkLWljb24gY2xhc3M9XCJxZGMtY2FyZF9fZm9vdGVyLWljb25cIiBbaWNvbl09XCJjYXJkQ29uZmlnLmZvb3Rlci5pY29uXCI+PC9xZC1pY29uPlxuICAgICAgPHNwYW4gY2xhc3M9XCJxZGMtY2FyZF9fZm9vdGVyLXRleHRcIj57eyBjYXJkQ29uZmlnLmZvb3Rlci50ZXh0IHwgdHJhbnNsYXRlIH19PC9zcGFuPlxuICAgIDwvZGl2PlxuICAgIH0gQGlmIChjYXJkQ29uZmlnLmZvb3Rlci5hY3Rpb24pIHtcbiAgICA8ZGl2IGNsYXNzPVwicWRjLWNhcmRfX2Zvb3Rlci1lbmRcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgcWRCdXR0b25cbiAgICAgICAgcWRCdXR0b25HaG9zdFxuICAgICAgICBbZGlzYWJsZWRdPVwiY2FyZENvbmZpZy5mb290ZXIuYWN0aW9uPy5pc0Rpc2FibGVkXCJcbiAgICAgICAgKGNsaWNrKT1cImNhcmRDb25maWcuZm9vdGVyLmFjdGlvbj8uaGFuZGxlcigpXCJcbiAgICAgICAgW2ljb25dPVwiY2FyZENvbmZpZy5mb290ZXIuYWN0aW9uPy5pY29uXCJcbiAgICAgICAgZGF0YS10ZXN0LWlkPVwidGVzdC1mb290ZXItYnV0dG9uXCJcbiAgICAgID5cbiAgICAgICAge3sgY2FyZENvbmZpZy5mb290ZXIuYWN0aW9uPy5sYWJlbC5pMThuIHwgdHJhbnNsYXRlIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICB9XG4gIDwvZm9vdGVyPlxuICB9IH0gQGVsc2Uge1xuICA8ZGl2IGNsYXNzPVwicWRjLWNhcmRfX2VtcHR5XCI+XG4gICAgPHNwYW4gY2xhc3M9XCJxZGMtY2FyZF9fZW1wdHktdGV4dFwiPk5vIGNhcmQgY29uZmlndXJhdGlvbiBwcm92aWRlZC48L3NwYW4+XG4gIDwvZGl2PlxuICB9XG48L2FydGljbGU+XG4iXX0=
53
+ //# sourceMappingURL=card.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.component.js","sourceRoot":"","sources":["../../../../../../libs/qdc-cards/src/lib/card/card.component.ts","../../../../../../libs/qdc-cards/src/lib/card/card.component.html"],"names":[],"mappings":"AAAA,OAAO,EAEL,uBAAuB,EACvB,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,MAAM,EACN,KAAK,EAEL,WAAW,EACX,iBAAiB,EAClB,MAAM,eAAe,CAAC;;;;;AAevB,MAAM,OAAO,gBAAgB;IAZ7B;QAaE,oEAAoE;QAC3D,eAAU,GAAkB,EAAE,CAAC;QAExC,oDAAoD;QAC7B,WAAM,GAAG,MAAM,CAAC;QAEvC,cAAS,GAAG,KAAK,CAAC;QAClB,cAAS,GAAG,KAAK,CAAC;QASV,QAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;KAkBzC;IAzBC,IAAiC,QAAQ;QACvC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,OAAO,MAAM,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC;QACzD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAID,kBAAkB;QAChB,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED,WAAW;QACT,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAClG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,UAAU,CAAC,KAAc;QACvB,OAAO,KAAK,YAAY,WAAW,CAAC;IACtC,CAAC;+GAlCU,gBAAgB;mGAAhB,gBAAgB,0RC1B7B,u2GA+FA;;4FDrEa,gBAAgB;kBAZ5B,SAAS;+BACE,UAAU,iBAGL,iBAAiB,CAAC,IAAI,mBACpB,uBAAuB,CAAC,MAAM,QACzC;wBACJ,KAAK,EAAE,UAAU;wBACjB,qBAAqB,EAAE,QAAQ;qBAChC,cACW,KAAK;;sBAIhB,KAAK;;sBAGL,KAAK;uBAAC,cAAc;;sBAKpB,WAAW;uBAAC,cAAc","sourcesContent":["import {\n AfterContentInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n HostBinding,\n inject,\n Input,\n OnChanges,\n TemplateRef,\n ViewEncapsulation\n} from '@angular/core';\nimport { QdcCardConfig } from './card.model';\n\n@Component({\n selector: 'qdc-card',\n templateUrl: './card.component.html',\n styleUrls: ['./card.component.scss'],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'qdc-card',\n '[attr.data-test-id]': 'testId'\n },\n standalone: false\n})\nexport class QdcCardComponent implements AfterContentInit, OnChanges {\n /** JSON configuration driving the visual appearance of the card. */\n @Input() cardConfig: QdcCardConfig = {};\n\n /** Optional test-id for E2E / integration tests. */\n @Input('data-test-id') testId = 'card';\n\n hasHeader = false;\n hasFooter = false;\n\n @HostBinding('class.mobile') get isMobile(): boolean {\n if (typeof window !== 'undefined') {\n return window.matchMedia('(max-width: 599px)').matches;\n }\n return false;\n }\n\n private cdr = inject(ChangeDetectorRef);\n\n ngAfterContentInit(): void {\n this.evaluateVisibility();\n }\n\n ngOnChanges(): void {\n this.evaluateVisibility();\n }\n\n private evaluateVisibility(): void {\n this.hasHeader = !!(this.cardConfig?.icon || this.cardConfig?.title || this.cardConfig?.subTitle);\n this.cdr.markForCheck();\n }\n\n isTemplate(value: unknown): value is TemplateRef<unknown> {\n return value instanceof TemplateRef;\n }\n}\n","<article class=\"qdc-card\" (click)=\"cardConfig?.onCardClick()\">\n @if (cardConfig) {\n <!-- Header -->\n @if (cardConfig.icon || cardConfig.title || cardConfig.subTitle || cardConfig.chip) {\n <header class=\"qdc-card__header\">\n <div class=\"qdc-card__header-left\">\n @if (cardConfig.icon) {\n <qd-icon class=\"qdc-card__icon\" [icon]=\"cardConfig.icon\"></qd-icon>\n }\n <div class=\"qdc-card__header-main\">\n @if (cardConfig.title) {\n <span class=\"qdc-card__title\">{{ cardConfig.title }}</span>\n } @if (cardConfig.subTitle) {\n <span class=\"qdc-card__subtitle\">{{ cardConfig.subTitle }}</span>\n }\n </div>\n </div>\n\n <div class=\"qdc-card__header-right\">\n @if (cardConfig.chip) {\n <qd-chip [state]=\"cardConfig.chip!.state\" data-test-id=\"test-chip\">\n {{ cardConfig.chip!.label.i18n | translate }}\n </qd-chip>\n } @if (cardConfig.menuActions) {\n <div class=\"qdc-card__header-actions\">\n <qdc-card-menu [actions]=\"cardConfig.menuActions\"></qdc-card-menu>\n </div>\n }\n </div>\n </header>\n }\n\n <!-- Body -->\n @if (cardConfig.bodyPairs) {\n <div class=\"qdc-card__body\">\n <div class=\"qdc-card__body-grid\">\n @for (item of cardConfig.bodyPairs; track item) {\n <div class=\"qdc-card__body-row\">\n <div class=\"qdc-card__body-label\">\n <span>{{ item.i18n | translate }}</span>\n </div>\n <div class=\"qdc-card__body-content\">\n @if (item.value) {\n <span class=\"qdc-card__body-value\">{{ item.value }}</span>\n } @if (item.status) {\n <qd-status-indicator [type]=\"item.status.type\" [level]=\"item.status.level\"></qd-status-indicator>\n } @if (item.icon) {\n <qd-icon [icon]=\"item.icon\"></qd-icon>\n } @if (item.chips) {\n <div class=\"qdc-card__body-chips\">\n @for (chip of item.chips; track chip) {\n <qd-chip [state]=\"chip.state\" class=\"qdc-card__body-chip\">\n {{ chip.label.i18n | translate }}\n </qd-chip>\n }\n </div>\n } @if (item.booleanValue !== undefined) {\n <qd-icon [icon]=\"item.booleanValue ? 'checkmark' : 'timesLarge'\"></qd-icon>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Footer -->\n @if (cardConfig.footer) {\n <footer class=\"qdc-card__footer\">\n @if (cardConfig.footer.icon || cardConfig.footer.text) {\n <div class=\"qdc-card__footer-start\">\n <qd-icon class=\"qdc-card__footer-icon\" [icon]=\"cardConfig.footer.icon\"></qd-icon>\n <span class=\"qdc-card__footer-text\">{{ cardConfig.footer.text | translate }}</span>\n </div>\n } @if (cardConfig.footer.action) {\n <div class=\"qdc-card__footer-end\">\n <button\n qdButton\n qdButtonGhost\n [disabled]=\"cardConfig.footer.action?.isDisabled\"\n (click)=\"cardConfig.footer.action?.handler()\"\n [icon]=\"cardConfig.footer.action?.icon\"\n data-test-id=\"test-footer-button\"\n >\n {{ cardConfig.footer.action?.label.i18n | translate }}\n </button>\n </div>\n }\n </footer>\n } } @else {\n <div class=\"qdc-card__empty\">\n <span class=\"qdc-card__empty-text\">No card configuration provided.</span>\n </div>\n }\n</article>\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=card.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.model.js","sourceRoot":"","sources":["../../../../../../libs/qdc-cards/src/lib/card/card.model.ts"],"names":[],"mappings":"","sourcesContent":["import {\n QdcCardActionConfig,\n QdcCardBodyPair,\n QdcCardChip,\n QdcCardFooter\n} from './model/card-actions-config.interface';\n\nexport interface QdcCardConfig {\n /**\n * Optional icon name shown in the header, left of the title.\n * */\n icon?: string | null;\n\n /**\n * Main headline of the card.\n * */\n title?: string | null;\n\n /**\n * Optional subtitle shown under the title.\n * */\n subTitle?: string | null;\n\n bodyPairs?: QdcCardBodyPair[];\n\n chip?: QdcCardChip;\n\n /**\n * Optional actions to display in the card menu.\n * */\n menuActions?: QdcCardActionConfig[];\n\n footer?: QdcCardFooter;\n\n onCardClick?: () => void;\n}\n"]}
@@ -0,0 +1,23 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { NgModule } from '@angular/core';
3
+ import { TranslateModule } from '@ngx-translate/core';
4
+ import { QdUiModule } from '@quadrel-enterprise-ui/framework';
5
+ import { QdcCardComponent } from './card.component';
6
+ import { QdcCardMenuComponent } from './menu/card-menu.component';
7
+ import { QdcCardsPopoverModule } from '../shared/popover/cards-popover.module';
8
+ import * as i0 from "@angular/core";
9
+ export { QdcCardComponent, QdcCardMenuComponent };
10
+ export class QdcCardModule {
11
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
12
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.17", ngImport: i0, type: QdcCardModule, declarations: [QdcCardComponent, QdcCardMenuComponent], imports: [CommonModule, TranslateModule, QdUiModule, QdcCardsPopoverModule], exports: [QdcCardComponent, QdcCardMenuComponent] }); }
13
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardModule, imports: [CommonModule, TranslateModule, QdUiModule, QdcCardsPopoverModule] }); }
14
+ }
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardModule, decorators: [{
16
+ type: NgModule,
17
+ args: [{
18
+ imports: [CommonModule, TranslateModule, QdUiModule, QdcCardsPopoverModule],
19
+ declarations: [QdcCardComponent, QdcCardMenuComponent],
20
+ exports: [QdcCardComponent, QdcCardMenuComponent]
21
+ }]
22
+ }] });
23
+ //# sourceMappingURL=card.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.module.js","sourceRoot":"","sources":["../../../../../../libs/qdc-cards/src/lib/card/card.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;;AAE/E,OAAO,EAAE,gBAAgB,EAAiB,oBAAoB,EAAE,CAAC;AAOjE,MAAM,OAAO,aAAa;+GAAb,aAAa;gHAAb,aAAa,iBAHT,gBAAgB,EAAE,oBAAoB,aAD3C,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,qBAAqB,aAEhE,gBAAgB,EAAE,oBAAoB;gHAErC,aAAa,YAJd,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,qBAAqB;;4FAI/D,aAAa;kBALzB,QAAQ;mBAAC;oBACR,OAAO,EAAE,CAAC,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,qBAAqB,CAAC;oBAC3E,YAAY,EAAE,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;oBACtD,OAAO,EAAE,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;iBAClD","sourcesContent":["import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { TranslateModule } from '@ngx-translate/core';\n\nimport { QdUiModule } from '@quadrel-enterprise-ui/framework';\nimport { QdcCardComponent } from './card.component';\nimport { QdcCardMenuComponent } from './menu/card-menu.component';\nimport { QdcCardConfig } from './card.model';\nimport { QdcCardsPopoverModule } from '../shared/popover/cards-popover.module';\n\nexport { QdcCardComponent, QdcCardConfig, QdcCardMenuComponent };\n\n@NgModule({\n imports: [CommonModule, TranslateModule, QdUiModule, QdcCardsPopoverModule],\n declarations: [QdcCardComponent, QdcCardMenuComponent],\n exports: [QdcCardComponent, QdcCardMenuComponent]\n})\nexport class QdcCardModule {}\n"]}
@@ -22,10 +22,10 @@ export class QdcCardMenuComponent {
22
22
  this._destroyed$.next();
23
23
  this._destroyed$.complete();
24
24
  }
25
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: QdcCardMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: QdcCardMenuComponent, isStandalone: false, selector: "qdc-card-menu", inputs: { actions: "actions", testId: ["data-test-id", "testId"] }, ngImport: i0, template: "<ng-container *ngIf=\"actions$ | async as actions\">\n <qd-icon\n *ngIf=\"actions.length > 0\"\n icon=\"overflowMenuVertical\"\n class=\"menu-opener\"\n [attr.data-test-id]=\"testId + '-opener'\"\n [qdcCardsPopoverOnClick]=\"menu\"\n ></qd-icon>\n\n <ng-template #menu>\n <ng-container *ngFor=\"let action of actions$ | async\">\n <button\n class=\"menu-entry\"\n (click)=\"action.handler()\"\n [disabled]=\"action.isDisabled\"\n [attr.data-test-id]=\"testId + '-action'\"\n >\n {{ action.label.i18n | translate }}\n </button>\n </ng-container>\n </ng-template>\n</ng-container>\n", styles: [":host{font-family:Roboto,sans-serif}:host .menu-opener{position:sticky;top:1.5625rem;right:1.5rem;cursor:pointer;font-size:1.5rem;font-weight:700}button.menu-entry{display:block;overflow:hidden;width:100%;min-height:2.25rem;padding:0 1rem;background:#fff0;text-align:left;text-overflow:ellipsis;white-space:nowrap;color:inherit;font-size:.875rem;font-weight:400;line-height:1.3125rem}button.menu-entry:hover{background-color:#f2f7fa}button.menu-entry:hover[disabled]{background:#fff0;cursor:default}button.menu-entry[disabled]{color:#b4b4b4;cursor:default}button.menu-entry[disabled]:hover{background-color:#fff0}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.QdIconComponent, selector: "qd-icon", inputs: ["icon"] }, { kind: "directive", type: i3.QdcCardsPopoverOnClickDirective, selector: "[qdcCardsPopoverOnClick]", inputs: ["qdcCardsPopoverOnClick", "popoverWidth", "positionStrategy", "popoverCloseStrategy"], outputs: ["opened", "closed"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
25
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
26
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: QdcCardMenuComponent, isStandalone: false, selector: "qdc-card-menu", inputs: { actions: "actions", testId: ["data-test-id", "testId"] }, ngImport: i0, template: "<ng-container *ngIf=\"actions$ | async as actions\">\n <qd-icon\n *ngIf=\"actions.length > 0\"\n icon=\"overflowMenuVertical\"\n class=\"menu-opener\"\n [attr.data-test-id]=\"testId + '-opener'\"\n [qdcCardsPopoverOnClick]=\"menu\"\n ></qd-icon>\n\n <ng-template #menu>\n <ng-container *ngFor=\"let action of actions$ | async\">\n <button\n class=\"menu-entry\"\n (click)=\"action.handler()\"\n [disabled]=\"action.isDisabled\"\n [attr.data-test-id]=\"testId + '-action'\"\n >\n {{ action.label.i18n | translate }}\n </button>\n </ng-container>\n </ng-template>\n</ng-container>\n", styles: [":host{font-family:Roboto,sans-serif}:host .menu-opener{position:sticky;top:1.5625rem;right:1.5rem;cursor:pointer;font-size:1.5rem;font-weight:700}button.menu-entry{display:block;overflow:hidden;width:100%;min-height:2.25rem;padding:0 1rem;background:#fff0;text-align:left;text-overflow:ellipsis;white-space:nowrap;color:inherit;font-size:.875rem;font-weight:400;line-height:1.3125rem}button.menu-entry:hover{background-color:#f2f7fa}button.menu-entry:hover[disabled]{background:#fff0;cursor:default}button.menu-entry[disabled]{color:#b4b4b4;cursor:default}button.menu-entry[disabled]:hover{background-color:#fff0}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.QdIconComponent, selector: "qd-icon", inputs: ["icon"] }, { kind: "directive", type: i3.QdcCardsPopoverOnClickDirective, selector: "[qdcCardsPopoverOnClick]", inputs: ["qdcCardsPopoverOnClick", "popoverWidth", "positionStrategy", "popoverCloseStrategy"], outputs: ["opened", "closed"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27
27
  }
28
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: QdcCardMenuComponent, decorators: [{
28
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardMenuComponent, decorators: [{
29
29
  type: Component,
30
30
  args: [{ selector: 'qdc-card-menu', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<ng-container *ngIf=\"actions$ | async as actions\">\n <qd-icon\n *ngIf=\"actions.length > 0\"\n icon=\"overflowMenuVertical\"\n class=\"menu-opener\"\n [attr.data-test-id]=\"testId + '-opener'\"\n [qdcCardsPopoverOnClick]=\"menu\"\n ></qd-icon>\n\n <ng-template #menu>\n <ng-container *ngFor=\"let action of actions$ | async\">\n <button\n class=\"menu-entry\"\n (click)=\"action.handler()\"\n [disabled]=\"action.isDisabled\"\n [attr.data-test-id]=\"testId + '-action'\"\n >\n {{ action.label.i18n | translate }}\n </button>\n </ng-container>\n </ng-template>\n</ng-container>\n", styles: [":host{font-family:Roboto,sans-serif}:host .menu-opener{position:sticky;top:1.5625rem;right:1.5rem;cursor:pointer;font-size:1.5rem;font-weight:700}button.menu-entry{display:block;overflow:hidden;width:100%;min-height:2.25rem;padding:0 1rem;background:#fff0;text-align:left;text-overflow:ellipsis;white-space:nowrap;color:inherit;font-size:.875rem;font-weight:400;line-height:1.3125rem}button.menu-entry:hover{background-color:#f2f7fa}button.menu-entry:hover[disabled]{background:#fff0;cursor:default}button.menu-entry[disabled]{color:#b4b4b4;cursor:default}button.menu-entry[disabled]:hover{background-color:#fff0}\n"] }]
31
31
  }], propDecorators: { actions: [{
@@ -34,4 +34,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
34
34
  type: Input,
35
35
  args: ['data-test-id']
36
36
  }] } });
37
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FyZC1tZW51LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvcWRjLWNhcmRzL3NyYy9saWIvY2FyZC9tZW51L2NhcmQtbWVudS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL3FkYy1jYXJkcy9zcmMvbGliL2NhcmQvbWVudS9jYXJkLW1lbnUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDckYsT0FBTyxFQUFFLGVBQWUsRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDNUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7O0FBVWhELE1BQU0sT0FBTyxvQkFBb0I7SUFQakM7UUFtQnlCLFdBQU0sR0FBRyxXQUFXLENBQUM7UUFFcEMsb0JBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBd0IsRUFBRSxDQUFDLENBQUM7UUFDakUsZ0JBQVcsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO0tBTTNDO0lBcEJDLElBQWEsT0FBTyxDQUFDLE9BQThCO1FBQ2pELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUM3QyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUMzQixHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQ3RGLENBQUM7SUFDSixDQUFDO0lBT0QsV0FBVztRQUNULElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUM5QixDQUFDOytHQXBCVSxvQkFBb0I7bUdBQXBCLG9CQUFvQiw4SUNaakMsaXBCQXNCQTs7NEZEVmEsb0JBQW9CO2tCQVBoQyxTQUFTOytCQUNFLGVBQWUsbUJBR1IsdUJBQXVCLENBQUMsTUFBTSxjQUNuQyxLQUFLOzhCQUdKLE9BQU87c0JBQW5CLEtBQUs7Z0JBV2lCLE1BQU07c0JBQTVCLEtBQUs7dUJBQUMsY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIElucHV0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBRZGNDYXJkQWN0aW9uQ29uZmlnIH0gZnJvbSAnLi4vbW9kZWwvY2FyZC1hY3Rpb25zLWNvbmZpZy5pbnRlcmZhY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdxZGMtY2FyZC1tZW51JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhcmQtbWVudS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NhcmQtbWVudS5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogZmFsc2Vcbn0pXG5leHBvcnQgY2xhc3MgUWRjQ2FyZE1lbnVDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBzZXQgYWN0aW9ucyhhY3Rpb25zOiBRZGNDYXJkQWN0aW9uQ29uZmlnW10pIHtcbiAgICB0aGlzLl9hY3Rpb25zU3ViamVjdC5uZXh0KGFjdGlvbnMpO1xuICB9XG5cbiAgZ2V0IGFjdGlvbnMkKCk6IE9ic2VydmFibGU8UWRjQ2FyZEFjdGlvbkNvbmZpZ1tdPiB7XG4gICAgcmV0dXJuIHRoaXMuX2FjdGlvbnNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpLnBpcGUoXG4gICAgICB0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkJCksXG4gICAgICBtYXAoYWN0aW9ucyA9PiBhY3Rpb25zLm1hcChhY3Rpb24gPT4gKHsgLi4uYWN0aW9uLCBpc0Rpc2FibGVkOiBhY3Rpb24uaXNEaXNhYmxlZCB9KSkpXG4gICAgKTtcbiAgfVxuXG4gIEBJbnB1dCgnZGF0YS10ZXN0LWlkJykgdGVzdElkID0gJ2NhcmQtbWVudSc7XG5cbiAgcHJpdmF0ZSBfYWN0aW9uc1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFFkY0NhcmRBY3Rpb25Db25maWdbXT4oW10pO1xuICBwcml2YXRlIF9kZXN0cm95ZWQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9kZXN0cm95ZWQkLm5leHQoKTtcbiAgICB0aGlzLl9kZXN0cm95ZWQkLmNvbXBsZXRlKCk7XG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCJhY3Rpb25zJCB8IGFzeW5jIGFzIGFjdGlvbnNcIj5cbiAgPHFkLWljb25cbiAgICAqbmdJZj1cImFjdGlvbnMubGVuZ3RoID4gMFwiXG4gICAgaWNvbj1cIm92ZXJmbG93TWVudVZlcnRpY2FsXCJcbiAgICBjbGFzcz1cIm1lbnUtb3BlbmVyXCJcbiAgICBbYXR0ci5kYXRhLXRlc3QtaWRdPVwidGVzdElkICsgJy1vcGVuZXInXCJcbiAgICBbcWRjQ2FyZHNQb3BvdmVyT25DbGlja109XCJtZW51XCJcbiAgPjwvcWQtaWNvbj5cblxuICA8bmctdGVtcGxhdGUgI21lbnU+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYWN0aW9uIG9mIGFjdGlvbnMkIHwgYXN5bmNcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgY2xhc3M9XCJtZW51LWVudHJ5XCJcbiAgICAgICAgKGNsaWNrKT1cImFjdGlvbi5oYW5kbGVyKClcIlxuICAgICAgICBbZGlzYWJsZWRdPVwiYWN0aW9uLmlzRGlzYWJsZWRcIlxuICAgICAgICBbYXR0ci5kYXRhLXRlc3QtaWRdPVwidGVzdElkICsgJy1hY3Rpb24nXCJcbiAgICAgID5cbiAgICAgICAge3sgYWN0aW9uLmxhYmVsLmkxOG4gfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLXRlbXBsYXRlPlxuPC9uZy1jb250YWluZXI+XG4iXX0=
37
+ //# sourceMappingURL=card-menu.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-menu.component.js","sourceRoot":"","sources":["../../../../../../../libs/qdc-cards/src/lib/card/menu/card-menu.component.ts","../../../../../../../libs/qdc-cards/src/lib/card/menu/card-menu.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAa,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,eAAe,EAAc,OAAO,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;;;;;;AAUhD,MAAM,OAAO,oBAAoB;IAPjC;QAmByB,WAAM,GAAG,WAAW,CAAC;QAEpC,oBAAe,GAAG,IAAI,eAAe,CAAwB,EAAE,CAAC,CAAC;QACjE,gBAAW,GAAG,IAAI,OAAO,EAAQ,CAAC;KAM3C;IApBC,IAAa,OAAO,CAAC,OAA8B;QACjD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,CAAC,IAAI,CAC7C,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,EAC3B,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CACtF,CAAC;IACJ,CAAC;IAOD,WAAW;QACT,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC;+GApBU,oBAAoB;mGAApB,oBAAoB,8ICZjC,ipBAsBA;;4FDVa,oBAAoB;kBAPhC,SAAS;+BACE,eAAe,mBAGR,uBAAuB,CAAC,MAAM,cACnC,KAAK;;sBAGhB,KAAK;;sBAWL,KAAK;uBAAC,cAAc","sourcesContent":["import { ChangeDetectionStrategy, Component, Input, OnDestroy } from '@angular/core';\nimport { BehaviorSubject, Observable, Subject } from 'rxjs';\nimport { map, takeUntil } from 'rxjs/operators';\nimport { QdcCardActionConfig } from '../model/card-actions-config.interface';\n\n@Component({\n selector: 'qdc-card-menu',\n templateUrl: './card-menu.component.html',\n styleUrls: ['./card-menu.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: false\n})\nexport class QdcCardMenuComponent implements OnDestroy {\n @Input() set actions(actions: QdcCardActionConfig[]) {\n this._actionsSubject.next(actions);\n }\n\n get actions$(): Observable<QdcCardActionConfig[]> {\n return this._actionsSubject.asObservable().pipe(\n takeUntil(this._destroyed$),\n map(actions => actions.map(action => ({ ...action, isDisabled: action.isDisabled })))\n );\n }\n\n @Input('data-test-id') testId = 'card-menu';\n\n private _actionsSubject = new BehaviorSubject<QdcCardActionConfig[]>([]);\n private _destroyed$ = new Subject<void>();\n\n ngOnDestroy(): void {\n this._destroyed$.next();\n this._destroyed$.complete();\n }\n}\n","<ng-container *ngIf=\"actions$ | async as actions\">\n <qd-icon\n *ngIf=\"actions.length > 0\"\n icon=\"overflowMenuVertical\"\n class=\"menu-opener\"\n [attr.data-test-id]=\"testId + '-opener'\"\n [qdcCardsPopoverOnClick]=\"menu\"\n ></qd-icon>\n\n <ng-template #menu>\n <ng-container *ngFor=\"let action of actions$ | async\">\n <button\n class=\"menu-entry\"\n (click)=\"action.handler()\"\n [disabled]=\"action.isDisabled\"\n [attr.data-test-id]=\"testId + '-action'\"\n >\n {{ action.label.i18n | translate }}\n </button>\n </ng-container>\n </ng-template>\n</ng-container>\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=card-actions-config.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-actions-config.interface.js","sourceRoot":"","sources":["../../../../../../../libs/qdc-cards/src/lib/card/model/card-actions-config.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { QdChipColor } from '@quadrel-enterprise-ui/framework';\nimport type { QdStatusIndicator } from '@quadrel-enterprise-ui/framework';\n\nexport interface QdcCardActionConfig {\n /**\n * The label is shown as text in the UI for this action.\n */\n label: {\n /** This i18n key is translated directly inside the QdCardMenu component. */\n i18n: string;\n };\n\n /**\n * The handler to execute when the action is clicked.\n */\n handler: () => void;\n\n /**\n * Whether the action is disabled or not\n *\n * * @default false\n */\n isDisabled?: boolean;\n\n /**\n * Optional icon to display in the action.\n */\n icon?: string | null;\n}\n\nexport interface QdcCardBodyPair {\n /**\n * Translatable label text.\n * */\n i18n: string;\n\n /**\n * Value to display next to the label.\n * */\n value?: string | number | boolean | null;\n\n /**\n * Optional Qd-Status-Indicator\n * */\n status?: Pick<QdStatusIndicator, 'type' | 'level'> | null;\n\n icon?: string | null;\n\n booleanValue?: boolean | null;\n\n chips?: QdcCardChip[] | null;\n}\n\nexport interface QdcCardFooter {\n icon?: string | null;\n text?: string | null;\n action?: QdcCardActionConfig | null;\n}\n\nexport interface QdcCardChip {\n /**\n * Color of the chip. Defaults to 'primary'.\n * */\n state: QdChipColor;\n\n /**\n * Text shown inside the chip.\n * */\n label: {\n /**\n * Translatable label text.\n * */\n i18n: string;\n };\n /**\n * Optional icon to display inside the chip.\n * */\n}\n"]}
@@ -0,0 +1,117 @@
1
+ import { Component, HostListener, inject, Input, ViewChild, NgZone } from '@angular/core';
2
+ import { FormGroup } from '@angular/forms';
3
+ import { BehaviorSubject } from 'rxjs';
4
+ import { startWith } from 'rxjs/operators';
5
+ import { QdFormControl } from '@quadrel-enterprise-ui/framework';
6
+ import { QdcCardStatusSameHeightDirective } from './card-status/card-status-height.directive';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@angular/forms";
9
+ import * as i2 from "@quadrel-enterprise-ui/framework";
10
+ import * as i3 from "./card-status/card-status.component";
11
+ import * as i4 from "./card-status/card-status-height.directive";
12
+ import * as i5 from "@angular/common";
13
+ export class QdcCardLayoutComponent {
14
+ constructor() {
15
+ this.isMobile = false;
16
+ this.MAX_COLUMNS = 5;
17
+ this.statusTitlesDropDownConfig = {
18
+ label: { i18n: 'i18n.qdc-card.layout.mobile.dropdown.status.label' },
19
+ options: []
20
+ };
21
+ this.dropDownConfig = new BehaviorSubject(this.statusTitlesDropDownConfig);
22
+ this.selectedStatusTitle = new BehaviorSubject(null);
23
+ this.ngZone = inject(NgZone);
24
+ }
25
+ ngOnInit() {
26
+ this.checkColumnLimit();
27
+ this.updateLayoutState();
28
+ this.initializeDropDown();
29
+ }
30
+ ngOnChanges(changes) {
31
+ if (changes['config']?.currentValue) {
32
+ this.checkColumnLimit();
33
+ const defaultStatusLabel = this.config.cardStatusConfig[0]?.title.i18n ?? null;
34
+ if (defaultStatusLabel) {
35
+ this.updateSelectedStatus(defaultStatusLabel);
36
+ }
37
+ this.setDropDownConfig();
38
+ }
39
+ }
40
+ onPaginationChanged() {
41
+ this.ngZone.runOutsideAngular(() => {
42
+ requestAnimationFrame(() => {
43
+ queueMicrotask(() => this.cardStatusHeightDirective?.triggerUpdate());
44
+ });
45
+ });
46
+ }
47
+ onResize() {
48
+ const wasMobile = this.isMobile;
49
+ this.updateLayoutState();
50
+ if (!wasMobile && this.isMobile) {
51
+ this.initializeDropDown();
52
+ }
53
+ }
54
+ checkColumnLimit() {
55
+ if (this.config.cardStatusConfig.length > this.MAX_COLUMNS) {
56
+ throw new Error(`Too many columns. Max allowed is ${this.MAX_COLUMNS}.`);
57
+ }
58
+ }
59
+ updateLayoutState() {
60
+ this.isMobile = window.innerWidth <= 480;
61
+ }
62
+ initializeDropDown() {
63
+ const defaultStatusLabel = this.config.cardStatusConfig[0]?.title.i18n ?? null;
64
+ this.dropDownForm = new FormGroup({
65
+ statusTitle: new QdFormControl(defaultStatusLabel)
66
+ });
67
+ this.setDropDownConfig();
68
+ this.dropDownForm
69
+ .get('statusTitle')
70
+ ?.valueChanges.pipe(startWith(this.dropDownForm.get('statusTitle')?.value))
71
+ .subscribe(title => {
72
+ this.updateSelectedStatus(title);
73
+ });
74
+ }
75
+ updateSelectedStatus(title) {
76
+ if (!title) {
77
+ this.selectedStatusTitle.next(null);
78
+ return;
79
+ }
80
+ const statusConfig = this.config.cardStatusConfig.find(s => s.title.i18n === title);
81
+ if (statusConfig) {
82
+ this.selectedStatusTitle.next({
83
+ ...statusConfig,
84
+ title: { ...statusConfig.title },
85
+ cards: [...(statusConfig.cards ?? [])]
86
+ });
87
+ }
88
+ else {
89
+ this.selectedStatusTitle.next(null);
90
+ }
91
+ }
92
+ setDropDownConfig() {
93
+ const options = this.config.cardStatusConfig.map(status => ({
94
+ i18n: status.title.i18n,
95
+ value: status.title.i18n
96
+ }));
97
+ this.dropDownConfig.next({
98
+ ...this.dropDownConfig.value,
99
+ options
100
+ });
101
+ }
102
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
103
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: QdcCardLayoutComponent, isStandalone: false, selector: "qdc-card-layout", inputs: { config: "config" }, host: { listeners: { "window:resize": "onResize()" } }, viewQueries: [{ propertyName: "cardStatusHeightDirective", first: true, predicate: QdcCardStatusSameHeightDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"qdc-card-layout__wrapper\">\n <div class=\"qdc-card-layout__container\">\n <div class=\"qdc-card-layout__layout-header\">\n <h1>{{ config.layoutTitle }}</h1>\n </div>\n\n @if (isMobile) {\n <form [formGroup]=\"dropDownForm\">\n <div class=\"qdc-card-layout__mobile-filter-grid\">\n <div class=\"cell\">\n <qd-dropdown formControlName=\"statusTitle\" [config]=\"dropDownConfig | async\"> </qd-dropdown>\n </div>\n </div>\n </form>\n }\n\n <div class=\"qdc-card-layout__layout\" qdcCardStatusSameHeight>\n @if (!isMobile) {\n @for (status of config.cardStatusConfig; track status) {\n <qdc-card-status [config]=\"status\" class=\"qdc-card-status-item\" (paginationChanged)=\"onPaginationChanged()\">\n </qdc-card-status>\n }\n } @else {\n @if (selectedStatusTitle | async; as status) {\n <qdc-card-status [config]=\"status\" class=\"qdc-card-status-item\">\n </qdc-card-status>\n }\n }\n\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.qdc-card-layout__wrapper{font-family:Roboto,sans-serif;width:100%;box-sizing:border-box;justify-content:center;padding:1rem 0;background-color:#efefef;overflow-x:auto}.qdc-card-layout__container{box-sizing:border-box;flex-direction:column;gap:1rem}@media (max-width: 959.98px){.qdc-card-layout__container{width:100%}}.qdc-card-layout__layout-header{align-items:center}.qdc-card-layout__layout-header h1{margin:0;font-family:Roboto,sans-serif;font-size:16px;font-weight:500;letter-spacing:.15px;line-height:100%;vertical-align:middle}.qdc-card-layout__layout{display:flex;box-sizing:border-box;padding:10px 25px 25px;gap:1rem}@media (max-width: 959.98px){.qdc-card-layout__layout{flex-direction:column;gap:6px}}.qdc-card-status-item{min-width:400px;max-width:100%;flex:1 1 0}@media (max-width: 959.98px){.qdc-card-status-item{width:100%!important;min-width:0}}@media (max-width: 959.98px){.qdc-card-layout__mobile-filter-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;width:100%;padding-left:10px}.qdc-card-layout__mobile-filter-grid .cell{grid-column:2}}@media (max-width: 599.98px){.qdc-card-layout__mobile-filter-grid .cell{grid-column:1}}\n"], dependencies: [{ kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i2.QdDropdownComponent, selector: "qd-dropdown", inputs: ["value", "id", "formControlName", "config", "data-test-id", "qdPopoverMaxHeight", "dense"], outputs: ["valueChange", "enterClick", "clickHint", "clickReadonly", "clickViewonly"] }, { kind: "component", type: i3.QdcCardStatusComponent, selector: "qdc-card-status", inputs: ["config"], outputs: ["paginationChanged"] }, { kind: "directive", type: i4.QdcCardStatusSameHeightDirective, selector: "[qdcCardStatusSameHeight]" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }] }); }
104
+ }
105
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardLayoutComponent, decorators: [{
106
+ type: Component,
107
+ args: [{ selector: 'qdc-card-layout', standalone: false, template: "<div class=\"qdc-card-layout__wrapper\">\n <div class=\"qdc-card-layout__container\">\n <div class=\"qdc-card-layout__layout-header\">\n <h1>{{ config.layoutTitle }}</h1>\n </div>\n\n @if (isMobile) {\n <form [formGroup]=\"dropDownForm\">\n <div class=\"qdc-card-layout__mobile-filter-grid\">\n <div class=\"cell\">\n <qd-dropdown formControlName=\"statusTitle\" [config]=\"dropDownConfig | async\"> </qd-dropdown>\n </div>\n </div>\n </form>\n }\n\n <div class=\"qdc-card-layout__layout\" qdcCardStatusSameHeight>\n @if (!isMobile) {\n @for (status of config.cardStatusConfig; track status) {\n <qdc-card-status [config]=\"status\" class=\"qdc-card-status-item\" (paginationChanged)=\"onPaginationChanged()\">\n </qdc-card-status>\n }\n } @else {\n @if (selectedStatusTitle | async; as status) {\n <qdc-card-status [config]=\"status\" class=\"qdc-card-status-item\">\n </qdc-card-status>\n }\n }\n\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.qdc-card-layout__wrapper{font-family:Roboto,sans-serif;width:100%;box-sizing:border-box;justify-content:center;padding:1rem 0;background-color:#efefef;overflow-x:auto}.qdc-card-layout__container{box-sizing:border-box;flex-direction:column;gap:1rem}@media (max-width: 959.98px){.qdc-card-layout__container{width:100%}}.qdc-card-layout__layout-header{align-items:center}.qdc-card-layout__layout-header h1{margin:0;font-family:Roboto,sans-serif;font-size:16px;font-weight:500;letter-spacing:.15px;line-height:100%;vertical-align:middle}.qdc-card-layout__layout{display:flex;box-sizing:border-box;padding:10px 25px 25px;gap:1rem}@media (max-width: 959.98px){.qdc-card-layout__layout{flex-direction:column;gap:6px}}.qdc-card-status-item{min-width:400px;max-width:100%;flex:1 1 0}@media (max-width: 959.98px){.qdc-card-status-item{width:100%!important;min-width:0}}@media (max-width: 959.98px){.qdc-card-layout__mobile-filter-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;width:100%;padding-left:10px}.qdc-card-layout__mobile-filter-grid .cell{grid-column:2}}@media (max-width: 599.98px){.qdc-card-layout__mobile-filter-grid .cell{grid-column:1}}\n"] }]
108
+ }], propDecorators: { config: [{
109
+ type: Input
110
+ }], cardStatusHeightDirective: [{
111
+ type: ViewChild,
112
+ args: [QdcCardStatusSameHeightDirective]
113
+ }], onResize: [{
114
+ type: HostListener,
115
+ args: ['window:resize']
116
+ }] } });
117
+ //# sourceMappingURL=card-layout.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-layout.component.js","sourceRoot":"","sources":["../../../../../../libs/qdc-cards/src/lib/card-layout/card-layout.component.ts","../../../../../../libs/qdc-cards/src/lib/card-layout/card-layout.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAoC,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5H,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAA+B,MAAM,kCAAkC,CAAC;AAG9F,OAAO,EAAE,gCAAgC,EAAE,MAAM,4CAA4C,CAAC;;;;;;;AAS9F,MAAM,OAAO,sBAAsB;IANnC;QAYE,aAAQ,GAAG,KAAK,CAAC;QACR,gBAAW,GAAG,CAAC,CAAC;QAIjB,+BAA0B,GAAgC;YAChE,KAAK,EAAE,EAAE,IAAI,EAAE,mDAAmD,EAAE;YACpE,OAAO,EAAE,EAAE;SACZ,CAAC;QAEF,mBAAc,GAAG,IAAI,eAAe,CAA8B,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAEnG,wBAAmB,GAAG,IAAI,eAAe,CAA6B,IAAI,CAAC,CAAC;QAEpE,WAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;KA+FjC;IA7FC,QAAQ;QACN,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED,WAAW,CAAC,OAAsB;QAChC,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;YACpC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAExB,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC;YAC/E,IAAI,kBAAkB,EAAE,CAAC;gBACvB,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;YAChD,CAAC;YAED,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,mBAAmB;QACjB,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE;YACjC,qBAAqB,CAAC,GAAG,EAAE;gBACzB,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,aAAa,EAAE,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAGD,QAAQ;QACN,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAEO,gBAAgB;QACtB,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3D,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAEO,iBAAiB;QACvB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC;IAC3C,CAAC;IAEO,kBAAkB;QACxB,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC;QAE/E,IAAI,CAAC,YAAY,GAAG,IAAI,SAAS,CAAC;YAChC,WAAW,EAAE,IAAI,aAAa,CAAC,kBAAkB,CAAC;SACnD,CAAC,CAAC;QAEH,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,IAAI,CAAC,YAAY;aACd,GAAG,CAAC,aAAa,CAAC;YACnB,EAAE,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC,CAAC;aAC1E,SAAS,CAAC,KAAK,CAAC,EAAE;YACjB,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,oBAAoB,CAAC,KAAoB;QAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;QAEpF,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC;gBAC5B,GAAG,YAAY;gBACf,KAAK,EAAE,EAAE,GAAG,YAAY,CAAC,KAAK,EAAE;gBAChC,KAAK,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;aACvC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAEO,iBAAiB;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1D,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;SACzB,CAAC,CAAC,CAAC;QAEJ,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YACvB,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK;YAC5B,OAAO;SACR,CAAC,CAAC;IACL,CAAC;+GAlHU,sBAAsB;mGAAtB,sBAAsB,6NAGtB,gCAAgC,qECnB7C,6jCAgCA;;4FDhBa,sBAAsB;kBANlC,SAAS;+BACE,iBAAiB,cAGf,KAAK;;sBAGhB,KAAK;;sBAEL,SAAS;uBAAC,gCAAgC;;sBA8C1C,YAAY;uBAAC,eAAe","sourcesContent":["import { Component, HostListener, inject, Input, OnInit, OnChanges, SimpleChanges, ViewChild, NgZone } from '@angular/core';\nimport { FormGroup } from '@angular/forms';\nimport { BehaviorSubject } from 'rxjs';\nimport { startWith } from 'rxjs/operators';\nimport { QdFormControl, QdFormDropdownConfiguration } from '@quadrel-enterprise-ui/framework';\n\nimport { QdcCardLayoutConfig } from './card-layout.model';\nimport { QdcCardStatusSameHeightDirective } from './card-status/card-status-height.directive';\nimport { QdcCardStatusConfig } from './card-status/card-status.model';\n\n@Component({\n selector: 'qdc-card-layout',\n templateUrl: './card-layout.component.html',\n styleUrl: './card-layout.component.scss',\n standalone: false\n})\nexport class QdcCardLayoutComponent implements OnInit, OnChanges {\n @Input() config!: QdcCardLayoutConfig;\n\n @ViewChild(QdcCardStatusSameHeightDirective)\n cardStatusHeightDirective?: QdcCardStatusSameHeightDirective;\n\n isMobile = false;\n readonly MAX_COLUMNS = 5;\n\n dropDownForm!: FormGroup;\n\n private statusTitlesDropDownConfig: QdFormDropdownConfiguration = {\n label: { i18n: 'i18n.qdc-card.layout.mobile.dropdown.status.label' },\n options: []\n };\n\n dropDownConfig = new BehaviorSubject<QdFormDropdownConfiguration>(this.statusTitlesDropDownConfig);\n\n selectedStatusTitle = new BehaviorSubject<QdcCardStatusConfig | null>(null);\n\n private ngZone = inject(NgZone);\n\n ngOnInit(): void {\n this.checkColumnLimit();\n this.updateLayoutState();\n this.initializeDropDown();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['config']?.currentValue) {\n this.checkColumnLimit();\n\n const defaultStatusLabel = this.config.cardStatusConfig[0]?.title.i18n ?? null;\n if (defaultStatusLabel) {\n this.updateSelectedStatus(defaultStatusLabel);\n }\n\n this.setDropDownConfig();\n }\n }\n\n onPaginationChanged(): void {\n this.ngZone.runOutsideAngular(() => {\n requestAnimationFrame(() => {\n queueMicrotask(() => this.cardStatusHeightDirective?.triggerUpdate());\n });\n });\n }\n\n @HostListener('window:resize')\n onResize(): void {\n const wasMobile = this.isMobile;\n this.updateLayoutState();\n if (!wasMobile && this.isMobile) {\n this.initializeDropDown();\n }\n }\n\n private checkColumnLimit(): void {\n if (this.config.cardStatusConfig.length > this.MAX_COLUMNS) {\n throw new Error(`Too many columns. Max allowed is ${this.MAX_COLUMNS}.`);\n }\n }\n\n private updateLayoutState(): void {\n this.isMobile = window.innerWidth <= 480;\n }\n\n private initializeDropDown(): void {\n const defaultStatusLabel = this.config.cardStatusConfig[0]?.title.i18n ?? null;\n\n this.dropDownForm = new FormGroup({\n statusTitle: new QdFormControl(defaultStatusLabel)\n });\n\n this.setDropDownConfig();\n\n this.dropDownForm\n .get('statusTitle')\n ?.valueChanges.pipe(startWith(this.dropDownForm.get('statusTitle')?.value))\n .subscribe(title => {\n this.updateSelectedStatus(title);\n });\n }\n\n private updateSelectedStatus(title: string | null): void {\n if (!title) {\n this.selectedStatusTitle.next(null);\n return;\n }\n\n const statusConfig = this.config.cardStatusConfig.find(s => s.title.i18n === title);\n\n if (statusConfig) {\n this.selectedStatusTitle.next({\n ...statusConfig,\n title: { ...statusConfig.title },\n cards: [...(statusConfig.cards ?? [])]\n });\n } else {\n this.selectedStatusTitle.next(null);\n }\n }\n\n private setDropDownConfig(): void {\n const options = this.config.cardStatusConfig.map(status => ({\n i18n: status.title.i18n,\n value: status.title.i18n\n }));\n\n this.dropDownConfig.next({\n ...this.dropDownConfig.value,\n options\n });\n }\n}\n","<div class=\"qdc-card-layout__wrapper\">\n <div class=\"qdc-card-layout__container\">\n <div class=\"qdc-card-layout__layout-header\">\n <h1>{{ config.layoutTitle }}</h1>\n </div>\n\n @if (isMobile) {\n <form [formGroup]=\"dropDownForm\">\n <div class=\"qdc-card-layout__mobile-filter-grid\">\n <div class=\"cell\">\n <qd-dropdown formControlName=\"statusTitle\" [config]=\"dropDownConfig | async\"> </qd-dropdown>\n </div>\n </div>\n </form>\n }\n\n <div class=\"qdc-card-layout__layout\" qdcCardStatusSameHeight>\n @if (!isMobile) {\n @for (status of config.cardStatusConfig; track status) {\n <qdc-card-status [config]=\"status\" class=\"qdc-card-status-item\" (paginationChanged)=\"onPaginationChanged()\">\n </qdc-card-status>\n }\n } @else {\n @if (selectedStatusTitle | async; as status) {\n <qdc-card-status [config]=\"status\" class=\"qdc-card-status-item\">\n </qdc-card-status>\n }\n }\n\n </div>\n </div>\n</div>\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=card-layout.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-layout.model.js","sourceRoot":"","sources":["../../../../../../libs/qdc-cards/src/lib/card-layout/card-layout.model.ts"],"names":[],"mappings":"","sourcesContent":["import { QdcCardStatusConfig } from './card-status/card-status.model';\n\nexport interface QdcCardLayoutConfig {\n /**\n * Title of the cards layout component\n * */\n layoutTitle: string;\n\n /**\n * Column with cards (max 5)\n * */\n cardStatusConfig: QdcCardStatusConfig[];\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { NgModule } from '@angular/core';
3
+ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
4
+ import { TranslateModule } from '@ngx-translate/core';
5
+ import { QdUiModule } from '@quadrel-enterprise-ui/framework';
6
+ import { QdcCardModule } from '../card/card.module';
7
+ import { QdcCardLayoutComponent } from './card-layout.component';
8
+ import { QdcCardStatusComponent } from './card-status/card-status.component';
9
+ import { QdcCardStatusSameHeightDirective } from './card-status/card-status-height.directive';
10
+ import * as i0 from "@angular/core";
11
+ export { QdcCardLayoutComponent, QdcCardStatusComponent, QdcCardStatusSameHeightDirective };
12
+ export class QdcCardLayoutModule {
13
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardLayoutModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
14
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.17", ngImport: i0, type: QdcCardLayoutModule, declarations: [QdcCardLayoutComponent, QdcCardStatusComponent, QdcCardStatusSameHeightDirective], imports: [CommonModule, FormsModule, ReactiveFormsModule, TranslateModule, QdUiModule, QdcCardModule], exports: [QdcCardLayoutComponent, QdcCardStatusComponent, QdcCardStatusSameHeightDirective] }); }
15
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardLayoutModule, imports: [CommonModule, FormsModule, ReactiveFormsModule, TranslateModule, QdUiModule, QdcCardModule] }); }
16
+ }
17
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardLayoutModule, decorators: [{
18
+ type: NgModule,
19
+ args: [{
20
+ imports: [CommonModule, FormsModule, ReactiveFormsModule, TranslateModule, QdUiModule, QdcCardModule],
21
+ declarations: [QdcCardLayoutComponent, QdcCardStatusComponent, QdcCardStatusSameHeightDirective],
22
+ exports: [QdcCardLayoutComponent, QdcCardStatusComponent, QdcCardStatusSameHeightDirective]
23
+ }]
24
+ }] });
25
+ //# sourceMappingURL=card-layout.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-layout.module.js","sourceRoot":"","sources":["../../../../../../libs/qdc-cards/src/lib/card-layout/card-layout.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,gCAAgC,EAAE,MAAM,4CAA4C,CAAC;;AAE9F,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,gCAAgC,EAAE,CAAC;AAQ5F,MAAM,OAAO,mBAAmB;+GAAnB,mBAAmB;gHAAnB,mBAAmB,iBAHf,sBAAsB,EAAE,sBAAsB,EAAE,gCAAgC,aAFrF,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,aAG1F,sBAAsB,EAAE,sBAAsB,EAAE,gCAAgC;gHAE/E,mBAAmB,YALpB,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa;;4FAKzF,mBAAmB;kBAN/B,QAAQ;mBAAC;oBACR,OAAO,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,CAAC;oBAErG,YAAY,EAAE,CAAC,sBAAsB,EAAE,sBAAsB,EAAE,gCAAgC,CAAC;oBAChG,OAAO,EAAE,CAAC,sBAAsB,EAAE,sBAAsB,EAAE,gCAAgC,CAAC;iBAC5F","sourcesContent":["import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { TranslateModule } from '@ngx-translate/core';\n\nimport { QdUiModule } from '@quadrel-enterprise-ui/framework';\n\nimport { QdcCardModule } from '../card/card.module';\nimport { QdcCardLayoutComponent } from './card-layout.component';\nimport { QdcCardStatusComponent } from './card-status/card-status.component';\nimport { QdcCardStatusSameHeightDirective } from './card-status/card-status-height.directive';\n\nexport { QdcCardLayoutComponent, QdcCardStatusComponent, QdcCardStatusSameHeightDirective };\n\n@NgModule({\n imports: [CommonModule, FormsModule, ReactiveFormsModule, TranslateModule, QdUiModule, QdcCardModule],\n\n declarations: [QdcCardLayoutComponent, QdcCardStatusComponent, QdcCardStatusSameHeightDirective],\n exports: [QdcCardLayoutComponent, QdcCardStatusComponent, QdcCardStatusSameHeightDirective]\n})\nexport class QdcCardLayoutModule {}\n"]}
@@ -0,0 +1,51 @@
1
+ import { Directive, ElementRef, HostListener, inject, Renderer2 } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export class QdcCardStatusSameHeightDirective {
4
+ constructor() {
5
+ this.el = inject(ElementRef);
6
+ this.renderer = inject(Renderer2);
7
+ }
8
+ ngAfterViewInit() {
9
+ this.updateHeights();
10
+ }
11
+ onResize() {
12
+ this.updateHeights();
13
+ }
14
+ triggerUpdate() {
15
+ this.updateHeights();
16
+ }
17
+ updateHeights() {
18
+ const container = this.el.nativeElement;
19
+ const items = container.querySelectorAll('.qd-status__cards');
20
+ if (!items || items.length === 0)
21
+ return;
22
+ // Reset all heights
23
+ items.forEach((item) => {
24
+ this.renderer.setStyle(item, 'height', 'auto');
25
+ });
26
+ // Find the tallest one
27
+ let maxHeight = 0;
28
+ items.forEach((item) => {
29
+ const h = item.offsetHeight;
30
+ if (h > maxHeight)
31
+ maxHeight = h;
32
+ });
33
+ // Apply max height to all
34
+ items.forEach((item) => {
35
+ this.renderer.setStyle(item, 'height', `${maxHeight}px`);
36
+ });
37
+ }
38
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardStatusSameHeightDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
39
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.17", type: QdcCardStatusSameHeightDirective, isStandalone: false, selector: "[qdcCardStatusSameHeight]", host: { listeners: { "window:resize": "onResize()" } }, ngImport: i0 }); }
40
+ }
41
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: QdcCardStatusSameHeightDirective, decorators: [{
42
+ type: Directive,
43
+ args: [{
44
+ selector: '[qdcCardStatusSameHeight]',
45
+ standalone: false
46
+ }]
47
+ }], propDecorators: { onResize: [{
48
+ type: HostListener,
49
+ args: ['window:resize']
50
+ }] } });
51
+ //# sourceMappingURL=card-status-height.directive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-status-height.directive.js","sourceRoot":"","sources":["../../../../../../../libs/qdc-cards/src/lib/card-layout/card-status/card-status-height.directive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;;AAMtG,MAAM,OAAO,gCAAgC;IAJ7C;QAKU,OAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QACxB,aAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;KAsCtC;IApCC,eAAe;QACb,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAGD,QAAQ;QACN,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEM,aAAa;QAClB,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,aAAa;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,aAA4B,CAAC;QACvD,MAAM,KAAK,GAA4B,SAAS,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;QAEvF,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEzC,oBAAoB;QACpB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAiB,EAAQ,EAAE;YACxC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,uBAAuB;QACvB,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAiB,EAAQ,EAAE;YACxC,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;YAC5B,IAAI,CAAC,GAAG,SAAS;gBAAE,SAAS,GAAG,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,0BAA0B;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC,IAAiB,EAAQ,EAAE;YACxC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,SAAS,IAAI,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC;+GAvCU,gCAAgC;mGAAhC,gCAAgC;;4FAAhC,gCAAgC;kBAJ5C,SAAS;mBAAC;oBACT,QAAQ,EAAE,2BAA2B;oBACrC,UAAU,EAAE,KAAK;iBAClB;;sBASE,YAAY;uBAAC,eAAe","sourcesContent":["import { AfterViewInit, Directive, ElementRef, HostListener, inject, Renderer2 } from '@angular/core';\n\n@Directive({\n selector: '[qdcCardStatusSameHeight]',\n standalone: false\n})\nexport class QdcCardStatusSameHeightDirective implements AfterViewInit {\n private el = inject(ElementRef);\n private renderer = inject(Renderer2);\n\n ngAfterViewInit(): void {\n this.updateHeights();\n }\n\n @HostListener('window:resize')\n onResize(): void {\n this.updateHeights();\n }\n\n public triggerUpdate(): void {\n this.updateHeights();\n }\n\n private updateHeights(): void {\n const container = this.el.nativeElement as HTMLElement;\n const items: NodeListOf<HTMLElement> = container.querySelectorAll('.qd-status__cards');\n\n if (!items || items.length === 0) return;\n\n // Reset all heights\n items.forEach((item: HTMLElement): void => {\n this.renderer.setStyle(item, 'height', 'auto');\n });\n\n // Find the tallest one\n let maxHeight = 0;\n items.forEach((item: HTMLElement): void => {\n const h = item.offsetHeight;\n if (h > maxHeight) maxHeight = h;\n });\n\n // Apply max height to all\n items.forEach((item: HTMLElement): void => {\n this.renderer.setStyle(item, 'height', `${maxHeight}px`);\n });\n }\n}\n"]}