@cqa-lib/cqa-ui 1.1.445 → 1.1.447
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.
- package/esm2020/lib/change-history/change-history.component.mjs +34 -33
- package/esm2020/lib/questionnaire-list/questionnaire-list.component.mjs +24 -23
- package/esm2020/lib/version-history/new-version-history-detail/new-version-history-detail.component.mjs +11 -3
- package/esm2020/lib/version-history/version-history-restore-confirm/version-history-restore-confirm.component.mjs +3 -42
- package/fesm2015/cqa-lib-cqa-ui.mjs +68 -97
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +68 -97
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/version-history/new-version-history-detail/new-version-history-detail.component.d.ts +13 -1
- package/lib/version-history/version-history-restore-confirm/version-history-restore-confirm.component.d.ts +0 -8
- package/package.json +1 -1
- package/styles.css +1 -1
|
@@ -42515,6 +42515,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
42515
42515
|
type: Output
|
|
42516
42516
|
}] } });
|
|
42517
42517
|
|
|
42518
|
+
const QUESTIONNAIRE_LIST_STYLES = `
|
|
42519
|
+
:host { display: block; width: 100%; }
|
|
42520
|
+
.ql-wrapper { background: #ffffff; border: 1px solid #e8eaf0; border-radius: 8px; padding: 24px; box-shadow: 0 1px 4px rgba(0,0,0,.06); width: 100%; box-sizing: border-box; }
|
|
42521
|
+
.ql-header { margin-bottom: 20px; }
|
|
42522
|
+
.ql-title { font-size: 16px; font-weight: 600; color: #1a1d23; margin: 0 0 4px 0; line-height: 1.4; }
|
|
42523
|
+
.ql-subtitle { font-size: 13px; font-weight: 400; color: #6b7280; margin: 0; line-height: 1.5; }
|
|
42524
|
+
.ql-body { display: flex; flex-direction: column; }
|
|
42525
|
+
.ql-item { display: flex; flex-direction: column; gap: 6px; padding-bottom: 16px; margin-bottom: 16px; border-bottom: 1px solid #f3f4f6; }
|
|
42526
|
+
.ql-item.ql-item--last { border-bottom: none; margin-bottom: 0; }
|
|
42527
|
+
.ql-badge { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; background: #eef0ff; color: #4f46e5; font-size: 12px; font-weight: 600; flex-shrink: 0; }
|
|
42528
|
+
.ql-label { display: block; font-size: 13px; font-weight: 500; color: #374151; }
|
|
42529
|
+
.ql-input { width: 100%; }
|
|
42530
|
+
.ql-empty { padding: 24px 0; font-size: 13px; color: #6b7280; text-align: center; }
|
|
42531
|
+
.ql-footer { display: flex; align-items: center; justify-content: space-between; padding-top: 16px; margin-top: 8px; border-top: 1px solid #f3f4f6; }
|
|
42532
|
+
.ql-footer-left { display: flex; align-items: center; }
|
|
42533
|
+
.ql-footer-label { font-size: 13px; color: #6b7280; margin-right: 8px; }
|
|
42534
|
+
.ql-page-size-select { width: 72px; height: 28px; border: 1px solid #e5e7eb; border-radius: 4px; padding: 0 6px; font-size: 13px; color: #374151; background: #ffffff; cursor: pointer; outline: none; }
|
|
42535
|
+
.ql-page-size-select:focus { border-color: #6366f1; }
|
|
42536
|
+
.ql-footer-right { display: flex; align-items: center; gap: 4px; }
|
|
42537
|
+
.ql-range-label { font-size: 13px; color: #374151; margin-right: 8px; }
|
|
42538
|
+
.ql-nav-btn { width: 28px; height: 28px; }
|
|
42539
|
+
`;
|
|
42518
42540
|
class QuestionnaireListComponent {
|
|
42519
42541
|
constructor() {
|
|
42520
42542
|
this.items = [];
|
|
@@ -42580,28 +42602,7 @@ QuestionnaireListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0
|
|
|
42580
42602
|
QuestionnaireListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: QuestionnaireListComponent, selector: "cqa-questionnaire-list", inputs: { items: "items", defaultPageSize: "defaultPageSize", pageSizeOptions: "pageSizeOptions", inputPlaceholder: "inputPlaceholder" }, outputs: { answerChange: "answerChange" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"ql-wrapper\" role=\"region\" aria-label=\"Clarification Questionnaire\">\n\n <!-- Header -->\n <div class=\"ql-header\">\n <h2 class=\"ql-title\">Clarification Questionnaire</h2>\n <p class=\"ql-subtitle\">\n The AI has generated these questions to resolve ambiguities in the requirement.\n Answering these will regenerate specific test cases.\n </p>\n </div>\n\n <!-- Question rows -->\n <div class=\"ql-body\">\n <ng-container *ngIf=\"visibleItems.length; else emptyState\">\n <div\n class=\"ql-item\"\n *ngFor=\"let item of visibleItems; last as isLast; trackBy: trackById\"\n [class.ql-item--last]=\"isLast\"\n >\n <span class=\"ql-badge\">{{ item.index }}</span>\n <label class=\"ql-label\" [for]=\"getInputId(item.id)\">{{ item.question }}</label>\n <cqa-custom-input\n [inputId]=\"getInputId(item.id)\"\n [value]=\"item.answer\"\n [placeholder]=\"inputPlaceholder\"\n [fullWidth]=\"true\"\n (valueChange)=\"onAnswerInput(item.id, $event)\"\n class=\"ql-input\"\n ></cqa-custom-input>\n </div>\n </ng-container>\n <ng-template #emptyState>\n <div class=\"ql-empty\">No questions available.</div>\n </ng-template>\n </div>\n\n <!-- Footer: per-page selector + range + nav -->\n <div class=\"ql-footer\" aria-live=\"polite\">\n\n <div class=\"ql-footer-left\">\n <span class=\"ql-footer-label\">Questions per page</span>\n <select\n class=\"ql-page-size-select\"\n [value]=\"pageSize\"\n (change)=\"onPageSizeChange(+$any($event.target).value)\"\n >\n <option *ngFor=\"let opt of pageSizeOptions\" [value]=\"opt\">{{ opt }}</option>\n </select>\n </div>\n\n <div class=\"ql-footer-right\">\n <span class=\"ql-range-label\">\n {{ totalItems ? startIndex + 1 : 0 }}–{{ endIndex }} of {{ totalItems }}\n </span>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n icon=\"chevron_left\"\n [disabled]=\"isPrevDisabled\"\n (clicked)=\"prevPage()\"\n aria-label=\"Previous page\"\n class=\"ql-nav-btn\"\n ></cqa-button>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n icon=\"chevron_right\"\n [disabled]=\"isNextDisabled\"\n (clicked)=\"nextPage()\"\n aria-label=\"Next page\"\n class=\"ql-nav-btn\"\n ></cqa-button>\n </div>\n\n </div>\n\n</div>\n", styles: [":host{display:block;width:100%}.ql-wrapper{background:#ffffff;border:1px solid #e8eaf0;border-radius:8px;padding:24px;box-shadow:0 1px 4px #0000000f;width:100%;box-sizing:border-box}.ql-header{margin-bottom:20px}.ql-title{font-size:16px;font-weight:600;color:#1a1d23;margin:0 0 4px;line-height:1.4}.ql-subtitle{font-size:13px;font-weight:400;color:#6b7280;margin:0;line-height:1.5}.ql-body{display:flex;flex-direction:column}.ql-item{display:flex;flex-direction:column;gap:6px;padding-bottom:16px;margin-bottom:16px;border-bottom:1px solid #f3f4f6}.ql-item.ql-item--last{border-bottom:none;margin-bottom:0}.ql-badge{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background:#eef0ff;color:#4f46e5;font-size:12px;font-weight:600;flex-shrink:0}.ql-label{display:block;font-size:13px;font-weight:500;color:#374151}.ql-input{width:100%}.ql-empty{padding:24px 0;font-size:13px;color:#6b7280;text-align:center}.ql-footer{display:flex;align-items:center;justify-content:space-between;padding-top:16px;margin-top:8px;border-top:1px solid #f3f4f6}.ql-footer-left{display:flex;align-items:center}.ql-footer-label{font-size:13px;color:#6b7280;margin-right:8px}.ql-page-size-select{width:72px;height:28px;border:1px solid #e5e7eb;border-radius:4px;padding:0 6px;font-size:13px;color:#374151;background:#ffffff;cursor:pointer;outline:none}.ql-page-size-select:focus{border-color:#6366f1}.ql-footer-right{display:flex;align-items:center;gap:4px}.ql-range-label{font-size:13px;color:#374151;margin-right:8px}.ql-nav-btn{width:28px;height:28px}\n"], components: [{ type: CustomInputComponent, selector: "cqa-custom-input", inputs: ["inputId", "label", "type", "placeholder", "value", "disabled", "errors", "required", "ariaLabel", "size", "fullWidth", "maxLength", "showCharCount", "inputInlineStyle", "labelInlineStyle"], outputs: ["valueChange", "blurred", "focused", "enterPressed"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }] });
|
|
42581
42603
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: QuestionnaireListComponent, decorators: [{
|
|
42582
42604
|
type: Component,
|
|
42583
|
-
args: [{ selector: 'cqa-questionnaire-list', styles: [
|
|
42584
|
-
:host { display: block; width: 100%; }
|
|
42585
|
-
.ql-wrapper { background: #ffffff; border: 1px solid #e8eaf0; border-radius: 8px; padding: 24px; box-shadow: 0 1px 4px rgba(0,0,0,.06); width: 100%; box-sizing: border-box; }
|
|
42586
|
-
.ql-header { margin-bottom: 20px; }
|
|
42587
|
-
.ql-title { font-size: 16px; font-weight: 600; color: #1a1d23; margin: 0 0 4px 0; line-height: 1.4; }
|
|
42588
|
-
.ql-subtitle { font-size: 13px; font-weight: 400; color: #6b7280; margin: 0; line-height: 1.5; }
|
|
42589
|
-
.ql-body { display: flex; flex-direction: column; }
|
|
42590
|
-
.ql-item { display: flex; flex-direction: column; gap: 6px; padding-bottom: 16px; margin-bottom: 16px; border-bottom: 1px solid #f3f4f6; }
|
|
42591
|
-
.ql-item.ql-item--last { border-bottom: none; margin-bottom: 0; }
|
|
42592
|
-
.ql-badge { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; background: #eef0ff; color: #4f46e5; font-size: 12px; font-weight: 600; flex-shrink: 0; }
|
|
42593
|
-
.ql-label { display: block; font-size: 13px; font-weight: 500; color: #374151; }
|
|
42594
|
-
.ql-input { width: 100%; }
|
|
42595
|
-
.ql-empty { padding: 24px 0; font-size: 13px; color: #6b7280; text-align: center; }
|
|
42596
|
-
.ql-footer { display: flex; align-items: center; justify-content: space-between; padding-top: 16px; margin-top: 8px; border-top: 1px solid #f3f4f6; }
|
|
42597
|
-
.ql-footer-left { display: flex; align-items: center; }
|
|
42598
|
-
.ql-footer-label { font-size: 13px; color: #6b7280; margin-right: 8px; }
|
|
42599
|
-
.ql-page-size-select { width: 72px; height: 28px; border: 1px solid #e5e7eb; border-radius: 4px; padding: 0 6px; font-size: 13px; color: #374151; background: #ffffff; cursor: pointer; outline: none; }
|
|
42600
|
-
.ql-page-size-select:focus { border-color: #6366f1; }
|
|
42601
|
-
.ql-footer-right { display: flex; align-items: center; gap: 4px; }
|
|
42602
|
-
.ql-range-label { font-size: 13px; color: #374151; margin-right: 8px; }
|
|
42603
|
-
.ql-nav-btn { width: 28px; height: 28px; }
|
|
42604
|
-
`], host: { class: 'cqa-ui-root' }, template: "<div class=\"ql-wrapper\" role=\"region\" aria-label=\"Clarification Questionnaire\">\n\n <!-- Header -->\n <div class=\"ql-header\">\n <h2 class=\"ql-title\">Clarification Questionnaire</h2>\n <p class=\"ql-subtitle\">\n The AI has generated these questions to resolve ambiguities in the requirement.\n Answering these will regenerate specific test cases.\n </p>\n </div>\n\n <!-- Question rows -->\n <div class=\"ql-body\">\n <ng-container *ngIf=\"visibleItems.length; else emptyState\">\n <div\n class=\"ql-item\"\n *ngFor=\"let item of visibleItems; last as isLast; trackBy: trackById\"\n [class.ql-item--last]=\"isLast\"\n >\n <span class=\"ql-badge\">{{ item.index }}</span>\n <label class=\"ql-label\" [for]=\"getInputId(item.id)\">{{ item.question }}</label>\n <cqa-custom-input\n [inputId]=\"getInputId(item.id)\"\n [value]=\"item.answer\"\n [placeholder]=\"inputPlaceholder\"\n [fullWidth]=\"true\"\n (valueChange)=\"onAnswerInput(item.id, $event)\"\n class=\"ql-input\"\n ></cqa-custom-input>\n </div>\n </ng-container>\n <ng-template #emptyState>\n <div class=\"ql-empty\">No questions available.</div>\n </ng-template>\n </div>\n\n <!-- Footer: per-page selector + range + nav -->\n <div class=\"ql-footer\" aria-live=\"polite\">\n\n <div class=\"ql-footer-left\">\n <span class=\"ql-footer-label\">Questions per page</span>\n <select\n class=\"ql-page-size-select\"\n [value]=\"pageSize\"\n (change)=\"onPageSizeChange(+$any($event.target).value)\"\n >\n <option *ngFor=\"let opt of pageSizeOptions\" [value]=\"opt\">{{ opt }}</option>\n </select>\n </div>\n\n <div class=\"ql-footer-right\">\n <span class=\"ql-range-label\">\n {{ totalItems ? startIndex + 1 : 0 }}–{{ endIndex }} of {{ totalItems }}\n </span>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n icon=\"chevron_left\"\n [disabled]=\"isPrevDisabled\"\n (clicked)=\"prevPage()\"\n aria-label=\"Previous page\"\n class=\"ql-nav-btn\"\n ></cqa-button>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n icon=\"chevron_right\"\n [disabled]=\"isNextDisabled\"\n (clicked)=\"nextPage()\"\n aria-label=\"Next page\"\n class=\"ql-nav-btn\"\n ></cqa-button>\n </div>\n\n </div>\n\n</div>\n" }]
|
|
42605
|
+
args: [{ selector: 'cqa-questionnaire-list', styles: [QUESTIONNAIRE_LIST_STYLES], host: { class: 'cqa-ui-root' }, template: "<div class=\"ql-wrapper\" role=\"region\" aria-label=\"Clarification Questionnaire\">\n\n <!-- Header -->\n <div class=\"ql-header\">\n <h2 class=\"ql-title\">Clarification Questionnaire</h2>\n <p class=\"ql-subtitle\">\n The AI has generated these questions to resolve ambiguities in the requirement.\n Answering these will regenerate specific test cases.\n </p>\n </div>\n\n <!-- Question rows -->\n <div class=\"ql-body\">\n <ng-container *ngIf=\"visibleItems.length; else emptyState\">\n <div\n class=\"ql-item\"\n *ngFor=\"let item of visibleItems; last as isLast; trackBy: trackById\"\n [class.ql-item--last]=\"isLast\"\n >\n <span class=\"ql-badge\">{{ item.index }}</span>\n <label class=\"ql-label\" [for]=\"getInputId(item.id)\">{{ item.question }}</label>\n <cqa-custom-input\n [inputId]=\"getInputId(item.id)\"\n [value]=\"item.answer\"\n [placeholder]=\"inputPlaceholder\"\n [fullWidth]=\"true\"\n (valueChange)=\"onAnswerInput(item.id, $event)\"\n class=\"ql-input\"\n ></cqa-custom-input>\n </div>\n </ng-container>\n <ng-template #emptyState>\n <div class=\"ql-empty\">No questions available.</div>\n </ng-template>\n </div>\n\n <!-- Footer: per-page selector + range + nav -->\n <div class=\"ql-footer\" aria-live=\"polite\">\n\n <div class=\"ql-footer-left\">\n <span class=\"ql-footer-label\">Questions per page</span>\n <select\n class=\"ql-page-size-select\"\n [value]=\"pageSize\"\n (change)=\"onPageSizeChange(+$any($event.target).value)\"\n >\n <option *ngFor=\"let opt of pageSizeOptions\" [value]=\"opt\">{{ opt }}</option>\n </select>\n </div>\n\n <div class=\"ql-footer-right\">\n <span class=\"ql-range-label\">\n {{ totalItems ? startIndex + 1 : 0 }}–{{ endIndex }} of {{ totalItems }}\n </span>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n icon=\"chevron_left\"\n [disabled]=\"isPrevDisabled\"\n (clicked)=\"prevPage()\"\n aria-label=\"Previous page\"\n class=\"ql-nav-btn\"\n ></cqa-button>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n icon=\"chevron_right\"\n [disabled]=\"isNextDisabled\"\n (clicked)=\"nextPage()\"\n aria-label=\"Next page\"\n class=\"ql-nav-btn\"\n ></cqa-button>\n </div>\n\n </div>\n\n</div>\n" }]
|
|
42605
42606
|
}], propDecorators: { items: [{
|
|
42606
42607
|
type: Input
|
|
42607
42608
|
}], defaultPageSize: [{
|
|
@@ -42622,6 +42623,38 @@ const EVENT_ICON_MAP = {
|
|
|
42622
42623
|
questionnaire_generated: 'assignment',
|
|
42623
42624
|
};
|
|
42624
42625
|
const DEFAULT_ICON = 'description';
|
|
42626
|
+
const CHANGE_HISTORY_STYLES = `
|
|
42627
|
+
:host { display: block; width: 100%; }
|
|
42628
|
+
.ch-wrapper { background: #ffffff; border: 1px solid #e8eaf0; border-radius: 8px; padding: 24px; box-shadow: 0 1px 4px rgba(0,0,0,.06); width: 100%; box-sizing: border-box; }
|
|
42629
|
+
.ch-header { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 24px; }
|
|
42630
|
+
.ch-header-icon { display: inline-flex; align-items: center; color: #6b7280; flex-shrink: 0; }
|
|
42631
|
+
.ch-header-icon mat-icon { font-size: 20px; width: 20px; height: 20px; }
|
|
42632
|
+
.ch-title { font-size: 15px; font-weight: 600; color: #1a1d23; margin: 0 0 2px 0; line-height: 1.4; }
|
|
42633
|
+
.ch-subtitle { font-size: 13px; font-weight: 400; color: #6b7280; margin: 0; }
|
|
42634
|
+
.ch-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 24px; gap: 12px; }
|
|
42635
|
+
.ch-empty p { font-size: 14px; color: #9ca3af; margin: 0; }
|
|
42636
|
+
.ch-empty-icon { font-size: 32px; width: 32px; height: 32px; color: #d1d5db; }
|
|
42637
|
+
.ch-timeline { list-style: none; margin: 0; padding: 0; }
|
|
42638
|
+
.ch-event { display: flex; align-items: flex-start; }
|
|
42639
|
+
.ch-track { width: 24px; display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
|
|
42640
|
+
.ch-track::after { content: ''; width: 2px; flex: 1; background-color: #e5e7eb; margin-top: 4px; }
|
|
42641
|
+
.ch-event--last .ch-track::after { display: none; }
|
|
42642
|
+
.ch-dot { display: block; width: 10px; height: 10px; border-radius: 50%; background: #ffffff; border: 2px solid #d1d5db; margin-top: 4px; z-index: 1; flex-shrink: 0; }
|
|
42643
|
+
.ch-card { display: flex; align-items: flex-start; gap: 12px; padding: 0 0 28px 12px; width: 100%; }
|
|
42644
|
+
.ch-event-icon { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 6px; background: #f3f4f6; flex-shrink: 0; }
|
|
42645
|
+
.ch-event-icon mat-icon { font-size: 16px; width: 16px; height: 16px; color: #6b7280; }
|
|
42646
|
+
.ch-event-body { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
|
|
42647
|
+
.ch-event-title { font-size: 14px; font-weight: 600; color: #1a1d23; }
|
|
42648
|
+
.ch-event-meta { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #6b7280; }
|
|
42649
|
+
.ch-meta-icon { font-size: 12px; width: 12px; height: 12px; color: #9ca3af; }
|
|
42650
|
+
.ch-meta-actor, .ch-meta-timestamp { font-size: 12px; color: #6b7280; }
|
|
42651
|
+
.ch-badges { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
|
|
42652
|
+
.ch-badge { font-size: 12px; font-weight: 500; padding: 2px 8px; border-radius: 4px; }
|
|
42653
|
+
.ch-badge--added { background: #dcfce7; color: #15803d; }
|
|
42654
|
+
.ch-badge--modified { background: #fef9c3; color: #854d0e; }
|
|
42655
|
+
.ch-badge--removed { background: #fee2e2; color: #b91c1c; }
|
|
42656
|
+
.ch-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }
|
|
42657
|
+
`;
|
|
42625
42658
|
class ChangeHistoryComponent {
|
|
42626
42659
|
constructor() {
|
|
42627
42660
|
this.items = [];
|
|
@@ -42646,38 +42679,7 @@ ChangeHistoryComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", v
|
|
|
42646
42679
|
ChangeHistoryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ChangeHistoryComponent, selector: "cqa-change-history", inputs: { items: "items", title: "title" }, outputs: { viewDetails: "viewDetails", revert: "revert" }, host: { classAttribute: "cqa-ui-root" }, ngImport: i0, template: "<div class=\"ch-wrapper\" role=\"region\" [attr.aria-label]=\"title\">\n\n <!-- Header -->\n <div class=\"ch-header\">\n <span class=\"ch-header-icon\" aria-hidden=\"true\">\n <mat-icon>history</mat-icon>\n </span>\n <div>\n <h2 class=\"ch-title\">{{ title }}</h2>\n <p class=\"ch-subtitle\">{{ items.length }} events recorded</p>\n </div>\n </div>\n\n <!-- Empty state -->\n <div class=\"ch-empty\" *ngIf=\"!items.length\">\n <mat-icon class=\"ch-empty-icon\" aria-hidden=\"true\">history</mat-icon>\n <p>No history events recorded yet.</p>\n </div>\n\n <!-- Timeline -->\n <ol class=\"ch-timeline\" *ngIf=\"items.length\" aria-label=\"Change history events\">\n <li\n class=\"ch-event\"\n *ngFor=\"let item of items; last as isLast; trackBy: trackById\"\n [class.ch-event--last]=\"isLast\"\n >\n <!-- Track: dot + vertical line -->\n <div class=\"ch-track\">\n <span class=\"ch-dot\" aria-hidden=\"true\"></span>\n </div>\n\n <!-- Card -->\n <div class=\"ch-card\">\n\n <!-- Event icon -->\n <span class=\"ch-event-icon\" aria-hidden=\"true\">\n <mat-icon>{{ getEventIcon(item.eventType) }}</mat-icon>\n </span>\n\n <!-- Body -->\n <div class=\"ch-event-body\">\n <span class=\"ch-event-title\">{{ item.title }}</span>\n\n <div class=\"ch-event-meta\">\n <mat-icon class=\"ch-meta-icon\" aria-hidden=\"true\">person</mat-icon>\n <span class=\"ch-meta-actor\">{{ item.actor }}</span>\n <mat-icon class=\"ch-meta-icon\" aria-hidden=\"true\">schedule</mat-icon>\n <span class=\"ch-meta-timestamp\">{{ item.timestamp }}</span>\n </div>\n\n <div class=\"ch-badges\" *ngIf=\"item.badges?.length\">\n <span\n *ngFor=\"let badge of item.badges\"\n class=\"ch-badge\"\n [ngClass]=\"'ch-badge--' + badge.variant\"\n >{{ badge.label }}</span>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"ch-actions\">\n <cqa-button\n variant=\"text\"\n btnSize=\"sm\"\n icon=\"visibility\"\n [text]=\"'View Details'\"\n [attr.aria-label]=\"'View details for ' + item.title\"\n (clicked)=\"onViewDetails(item.id)\"\n ></cqa-button>\n\n <cqa-button\n *ngIf=\"item.canRevert\"\n variant=\"text\"\n btnSize=\"sm\"\n icon=\"history\"\n [text]=\"'Revert'\"\n [attr.aria-label]=\"'Revert ' + item.title\"\n (clicked)=\"onRevert(item.id)\"\n ></cqa-button>\n </div>\n\n </div>\n </li>\n </ol>\n\n</div>\n", styles: [":host{display:block;width:100%}.ch-wrapper{background:#ffffff;border:1px solid #e8eaf0;border-radius:8px;padding:24px;box-shadow:0 1px 4px #0000000f;width:100%;box-sizing:border-box}.ch-header{display:flex;align-items:flex-start;gap:10px;margin-bottom:24px}.ch-header-icon{display:inline-flex;align-items:center;color:#6b7280;flex-shrink:0}.ch-header-icon mat-icon{font-size:20px;width:20px;height:20px}.ch-title{font-size:15px;font-weight:600;color:#1a1d23;margin:0 0 2px;line-height:1.4}.ch-subtitle{font-size:13px;font-weight:400;color:#6b7280;margin:0}.ch-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 24px;gap:12px}.ch-empty p{font-size:14px;color:#9ca3af;margin:0}.ch-empty-icon{font-size:32px;width:32px;height:32px;color:#d1d5db}.ch-timeline{list-style:none;margin:0;padding:0}.ch-event{display:flex;align-items:flex-start}.ch-track{width:24px;display:flex;flex-direction:column;align-items:center;flex-shrink:0}.ch-track:after{content:\"\";width:2px;flex:1;background-color:#e5e7eb;margin-top:4px}.ch-event--last .ch-track:after{display:none}.ch-dot{display:block;width:10px;height:10px;border-radius:50%;background:#ffffff;border:2px solid #d1d5db;margin-top:4px;z-index:1;flex-shrink:0}.ch-card{display:flex;align-items:flex-start;gap:12px;padding:0 0 28px 12px;width:100%}.ch-event-icon{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:6px;background:#f3f4f6;flex-shrink:0}.ch-event-icon mat-icon{font-size:16px;width:16px;height:16px;color:#6b7280}.ch-event-body{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.ch-event-title{font-size:14px;font-weight:600;color:#1a1d23}.ch-event-meta{display:flex;align-items:center;gap:6px;font-size:12px;color:#6b7280}.ch-meta-icon{font-size:12px;width:12px;height:12px;color:#9ca3af}.ch-meta-actor,.ch-meta-timestamp{font-size:12px;color:#6b7280}.ch-badges{display:flex;gap:6px;margin-top:6px;flex-wrap:wrap}.ch-badge{font-size:12px;font-weight:500;padding:2px 8px;border-radius:4px}.ch-badge--added{background:#dcfce7;color:#15803d}.ch-badge--modified{background:#fef9c3;color:#854d0e}.ch-badge--removed{background:#fee2e2;color:#b91c1c}.ch-actions{display:flex;align-items:center;gap:8px;margin-left:auto;flex-shrink:0}\n"], components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
42647
42680
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ChangeHistoryComponent, decorators: [{
|
|
42648
42681
|
type: Component,
|
|
42649
|
-
args: [{ selector: 'cqa-change-history', styles: [
|
|
42650
|
-
:host { display: block; width: 100%; }
|
|
42651
|
-
.ch-wrapper { background: #ffffff; border: 1px solid #e8eaf0; border-radius: 8px; padding: 24px; box-shadow: 0 1px 4px rgba(0,0,0,.06); width: 100%; box-sizing: border-box; }
|
|
42652
|
-
.ch-header { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 24px; }
|
|
42653
|
-
.ch-header-icon { display: inline-flex; align-items: center; color: #6b7280; flex-shrink: 0; }
|
|
42654
|
-
.ch-header-icon mat-icon { font-size: 20px; width: 20px; height: 20px; }
|
|
42655
|
-
.ch-title { font-size: 15px; font-weight: 600; color: #1a1d23; margin: 0 0 2px 0; line-height: 1.4; }
|
|
42656
|
-
.ch-subtitle { font-size: 13px; font-weight: 400; color: #6b7280; margin: 0; }
|
|
42657
|
-
.ch-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 24px; gap: 12px; }
|
|
42658
|
-
.ch-empty p { font-size: 14px; color: #9ca3af; margin: 0; }
|
|
42659
|
-
.ch-empty-icon { font-size: 32px; width: 32px; height: 32px; color: #d1d5db; }
|
|
42660
|
-
.ch-timeline { list-style: none; margin: 0; padding: 0; }
|
|
42661
|
-
.ch-event { display: flex; align-items: flex-start; }
|
|
42662
|
-
.ch-track { width: 24px; display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
|
|
42663
|
-
.ch-track::after { content: ''; width: 2px; flex: 1; background-color: #e5e7eb; margin-top: 4px; }
|
|
42664
|
-
.ch-event--last .ch-track::after { display: none; }
|
|
42665
|
-
.ch-dot { display: block; width: 10px; height: 10px; border-radius: 50%; background: #ffffff; border: 2px solid #d1d5db; margin-top: 4px; z-index: 1; flex-shrink: 0; }
|
|
42666
|
-
.ch-card { display: flex; align-items: flex-start; gap: 12px; padding: 0 0 28px 12px; width: 100%; }
|
|
42667
|
-
.ch-event-icon { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 6px; background: #f3f4f6; flex-shrink: 0; }
|
|
42668
|
-
.ch-event-icon mat-icon { font-size: 16px; width: 16px; height: 16px; color: #6b7280; }
|
|
42669
|
-
.ch-event-body { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
|
|
42670
|
-
.ch-event-title { font-size: 14px; font-weight: 600; color: #1a1d23; }
|
|
42671
|
-
.ch-event-meta { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #6b7280; }
|
|
42672
|
-
.ch-meta-icon { font-size: 12px; width: 12px; height: 12px; color: #9ca3af; }
|
|
42673
|
-
.ch-meta-actor, .ch-meta-timestamp { font-size: 12px; color: #6b7280; }
|
|
42674
|
-
.ch-badges { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
|
|
42675
|
-
.ch-badge { font-size: 12px; font-weight: 500; padding: 2px 8px; border-radius: 4px; }
|
|
42676
|
-
.ch-badge--added { background: #dcfce7; color: #15803d; }
|
|
42677
|
-
.ch-badge--modified { background: #fef9c3; color: #854d0e; }
|
|
42678
|
-
.ch-badge--removed { background: #fee2e2; color: #b91c1c; }
|
|
42679
|
-
.ch-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }
|
|
42680
|
-
`], host: { class: 'cqa-ui-root' }, template: "<div class=\"ch-wrapper\" role=\"region\" [attr.aria-label]=\"title\">\n\n <!-- Header -->\n <div class=\"ch-header\">\n <span class=\"ch-header-icon\" aria-hidden=\"true\">\n <mat-icon>history</mat-icon>\n </span>\n <div>\n <h2 class=\"ch-title\">{{ title }}</h2>\n <p class=\"ch-subtitle\">{{ items.length }} events recorded</p>\n </div>\n </div>\n\n <!-- Empty state -->\n <div class=\"ch-empty\" *ngIf=\"!items.length\">\n <mat-icon class=\"ch-empty-icon\" aria-hidden=\"true\">history</mat-icon>\n <p>No history events recorded yet.</p>\n </div>\n\n <!-- Timeline -->\n <ol class=\"ch-timeline\" *ngIf=\"items.length\" aria-label=\"Change history events\">\n <li\n class=\"ch-event\"\n *ngFor=\"let item of items; last as isLast; trackBy: trackById\"\n [class.ch-event--last]=\"isLast\"\n >\n <!-- Track: dot + vertical line -->\n <div class=\"ch-track\">\n <span class=\"ch-dot\" aria-hidden=\"true\"></span>\n </div>\n\n <!-- Card -->\n <div class=\"ch-card\">\n\n <!-- Event icon -->\n <span class=\"ch-event-icon\" aria-hidden=\"true\">\n <mat-icon>{{ getEventIcon(item.eventType) }}</mat-icon>\n </span>\n\n <!-- Body -->\n <div class=\"ch-event-body\">\n <span class=\"ch-event-title\">{{ item.title }}</span>\n\n <div class=\"ch-event-meta\">\n <mat-icon class=\"ch-meta-icon\" aria-hidden=\"true\">person</mat-icon>\n <span class=\"ch-meta-actor\">{{ item.actor }}</span>\n <mat-icon class=\"ch-meta-icon\" aria-hidden=\"true\">schedule</mat-icon>\n <span class=\"ch-meta-timestamp\">{{ item.timestamp }}</span>\n </div>\n\n <div class=\"ch-badges\" *ngIf=\"item.badges?.length\">\n <span\n *ngFor=\"let badge of item.badges\"\n class=\"ch-badge\"\n [ngClass]=\"'ch-badge--' + badge.variant\"\n >{{ badge.label }}</span>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"ch-actions\">\n <cqa-button\n variant=\"text\"\n btnSize=\"sm\"\n icon=\"visibility\"\n [text]=\"'View Details'\"\n [attr.aria-label]=\"'View details for ' + item.title\"\n (clicked)=\"onViewDetails(item.id)\"\n ></cqa-button>\n\n <cqa-button\n *ngIf=\"item.canRevert\"\n variant=\"text\"\n btnSize=\"sm\"\n icon=\"history\"\n [text]=\"'Revert'\"\n [attr.aria-label]=\"'Revert ' + item.title\"\n (clicked)=\"onRevert(item.id)\"\n ></cqa-button>\n </div>\n\n </div>\n </li>\n </ol>\n\n</div>\n" }]
|
|
42682
|
+
args: [{ selector: 'cqa-change-history', styles: [CHANGE_HISTORY_STYLES], host: { class: 'cqa-ui-root' }, template: "<div class=\"ch-wrapper\" role=\"region\" [attr.aria-label]=\"title\">\n\n <!-- Header -->\n <div class=\"ch-header\">\n <span class=\"ch-header-icon\" aria-hidden=\"true\">\n <mat-icon>history</mat-icon>\n </span>\n <div>\n <h2 class=\"ch-title\">{{ title }}</h2>\n <p class=\"ch-subtitle\">{{ items.length }} events recorded</p>\n </div>\n </div>\n\n <!-- Empty state -->\n <div class=\"ch-empty\" *ngIf=\"!items.length\">\n <mat-icon class=\"ch-empty-icon\" aria-hidden=\"true\">history</mat-icon>\n <p>No history events recorded yet.</p>\n </div>\n\n <!-- Timeline -->\n <ol class=\"ch-timeline\" *ngIf=\"items.length\" aria-label=\"Change history events\">\n <li\n class=\"ch-event\"\n *ngFor=\"let item of items; last as isLast; trackBy: trackById\"\n [class.ch-event--last]=\"isLast\"\n >\n <!-- Track: dot + vertical line -->\n <div class=\"ch-track\">\n <span class=\"ch-dot\" aria-hidden=\"true\"></span>\n </div>\n\n <!-- Card -->\n <div class=\"ch-card\">\n\n <!-- Event icon -->\n <span class=\"ch-event-icon\" aria-hidden=\"true\">\n <mat-icon>{{ getEventIcon(item.eventType) }}</mat-icon>\n </span>\n\n <!-- Body -->\n <div class=\"ch-event-body\">\n <span class=\"ch-event-title\">{{ item.title }}</span>\n\n <div class=\"ch-event-meta\">\n <mat-icon class=\"ch-meta-icon\" aria-hidden=\"true\">person</mat-icon>\n <span class=\"ch-meta-actor\">{{ item.actor }}</span>\n <mat-icon class=\"ch-meta-icon\" aria-hidden=\"true\">schedule</mat-icon>\n <span class=\"ch-meta-timestamp\">{{ item.timestamp }}</span>\n </div>\n\n <div class=\"ch-badges\" *ngIf=\"item.badges?.length\">\n <span\n *ngFor=\"let badge of item.badges\"\n class=\"ch-badge\"\n [ngClass]=\"'ch-badge--' + badge.variant\"\n >{{ badge.label }}</span>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"ch-actions\">\n <cqa-button\n variant=\"text\"\n btnSize=\"sm\"\n icon=\"visibility\"\n [text]=\"'View Details'\"\n [attr.aria-label]=\"'View details for ' + item.title\"\n (clicked)=\"onViewDetails(item.id)\"\n ></cqa-button>\n\n <cqa-button\n *ngIf=\"item.canRevert\"\n variant=\"text\"\n btnSize=\"sm\"\n icon=\"history\"\n [text]=\"'Revert'\"\n [attr.aria-label]=\"'Revert ' + item.title\"\n (clicked)=\"onRevert(item.id)\"\n ></cqa-button>\n </div>\n\n </div>\n </li>\n </ol>\n\n</div>\n" }]
|
|
42681
42683
|
}], propDecorators: { items: [{
|
|
42682
42684
|
type: Input
|
|
42683
42685
|
}], title: [{
|
|
@@ -42875,51 +42877,12 @@ class VersionHistoryRestoreConfirmComponent {
|
|
|
42875
42877
|
return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }) + ', ' +
|
|
42876
42878
|
d.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' });
|
|
42877
42879
|
}
|
|
42878
|
-
getChangeInfo(change) {
|
|
42879
|
-
const op = (change?.op || '').toLowerCase();
|
|
42880
|
-
// Sentence comes entirely from the parent via getChangeHeadlineFn
|
|
42881
|
-
const sentence = this.getChangeHeadlineFn
|
|
42882
|
-
? this.getChangeHeadlineFn(change)
|
|
42883
|
-
: this.fallbackSentence(change);
|
|
42884
|
-
const fromDisplay = this.toDisplayHtml(change?.fromValue);
|
|
42885
|
-
const toDisplay = this.toDisplayHtml(change?.toValue);
|
|
42886
|
-
return { sentence, fromDisplay, toDisplay, op };
|
|
42887
|
-
}
|
|
42888
|
-
// Basic fallback if no getChangeHeadlineFn is provided
|
|
42889
|
-
fallbackSentence(change) {
|
|
42890
|
-
const field = change?.field || 'Step';
|
|
42891
|
-
const op = (change?.op || '').toLowerCase();
|
|
42892
|
-
const step = change?.stepId != null ? `Step #${change.stepId} ` : '';
|
|
42893
|
-
if (op === 'add') {
|
|
42894
|
-
return `${step}${field} added`;
|
|
42895
|
-
}
|
|
42896
|
-
if (op === 'remove') {
|
|
42897
|
-
return `${step}${field} removed`;
|
|
42898
|
-
}
|
|
42899
|
-
if (op === 'replace') {
|
|
42900
|
-
return `${step}${field} changed`;
|
|
42901
|
-
}
|
|
42902
|
-
return `${step}${field} updated`;
|
|
42903
|
-
}
|
|
42904
|
-
// Preserve HTML for detail pills — objects resolved to a readable string
|
|
42905
|
-
toDisplayHtml(value) {
|
|
42906
|
-
if (value == null) {
|
|
42907
|
-
return '';
|
|
42908
|
-
}
|
|
42909
|
-
if (typeof value === 'string') {
|
|
42910
|
-
return value.trim();
|
|
42911
|
-
}
|
|
42912
|
-
if (typeof value === 'object') {
|
|
42913
|
-
return value.action || value.type || value.name || JSON.stringify(value, null, 2);
|
|
42914
|
-
}
|
|
42915
|
-
return String(value);
|
|
42916
|
-
}
|
|
42917
42880
|
}
|
|
42918
42881
|
VersionHistoryRestoreConfirmComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: VersionHistoryRestoreConfirmComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
42919
|
-
VersionHistoryRestoreConfirmComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: VersionHistoryRestoreConfirmComponent, selector: "cqa-version-history-restore-confirm", inputs: { restoringToVersion: "restoringToVersion", currentVersionNumber: "currentVersionNumber", newVersionNumber: "newVersionNumber", authorName: "authorName", getChangeHeadlineFn: "getChangeHeadlineFn" }, ngImport: i0, template: "<div class=\"cqa-vh-restore-confirm\">\n\n <!-- Info grid -->\n <div class=\"cqa-vh-restore-info-grid\">\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Restoring to</span>\n <span class=\"cqa-vh-restore-info-value\">{{ getRestoreToLabel() }}</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">New version created</span>\n <span class=\"cqa-vh-restore-info-value\">v{{ newVersionNumber }} (auto-incremented)</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Current version</span>\n <span class=\"cqa-vh-restore-info-value\">v{{ currentVersionNumber }} \u2014 preserved in history</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Author</span>\n <span class=\"cqa-vh-restore-info-value\">{{ authorName }}</span>\n </div>\n </div>\n\n <!-- Changes that will be reverted -->\n <div *ngIf=\"restoringToVersion?.changes?.length\">\n <div class=\"cqa-vh-restore-changes-title\">Changes that will be reverted</div>\n <div class=\"cqa-vh-restore-changes-list\">\n <div *ngFor=\"let change of restoringToVersion.changes; let i = index\"\n class=\"cqa-vh-restore-change-item\">\n
|
|
42882
|
+
VersionHistoryRestoreConfirmComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: VersionHistoryRestoreConfirmComponent, selector: "cqa-version-history-restore-confirm", inputs: { restoringToVersion: "restoringToVersion", currentVersionNumber: "currentVersionNumber", newVersionNumber: "newVersionNumber", authorName: "authorName", getChangeHeadlineFn: "getChangeHeadlineFn" }, ngImport: i0, template: "<div class=\"cqa-vh-restore-confirm\">\n\n <!-- Info grid -->\n <div class=\"cqa-vh-restore-info-grid\">\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Restoring to</span>\n <span class=\"cqa-vh-restore-info-value\">{{ getRestoreToLabel() }}</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">New version created</span>\n <span class=\"cqa-vh-restore-info-value\">v{{ newVersionNumber }} (auto-incremented)</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Current version</span>\n <span class=\"cqa-vh-restore-info-value\">v{{ currentVersionNumber }} \u2014 preserved in history</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Author</span>\n <span class=\"cqa-vh-restore-info-value\">{{ authorName }}</span>\n </div>\n </div>\n\n <!-- Changes that will be reverted -->\n <div *ngIf=\"restoringToVersion?.changes?.length\">\n <div class=\"cqa-vh-restore-changes-title\">Changes that will be reverted</div>\n <div class=\"cqa-vh-restore-changes-list\">\n <div *ngFor=\"let change of restoringToVersion.changes; let i = index\"\n class=\"cqa-vh-restore-change-item\">\n <div class=\"cqa-vh-restore-change-index\">{{ i + 1 }}</div>\n <span class=\"cqa-vh-restore-change-sentence\">{{ getChangeHeadlineFn ? getChangeHeadlineFn(change) : change?.sentence || '' }}</span>\n </div>\n </div>\n </div>\n\n <!-- Preservation note -->\n <div class=\"cqa-vh-restore-note\">\n <span class=\"material-symbols-outlined cqa-vh-restore-note-icon\">info</span>\n <span class=\"cqa-vh-restore-note-text\">\n All version history will be fully preserved. This restore action will itself appear as a new version entry in the timeline.\n </span>\n </div>\n\n</div>\n", directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
42920
42883
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: VersionHistoryRestoreConfirmComponent, decorators: [{
|
|
42921
42884
|
type: Component,
|
|
42922
|
-
args: [{ selector: 'cqa-version-history-restore-confirm', template: "<div class=\"cqa-vh-restore-confirm\">\n\n <!-- Info grid -->\n <div class=\"cqa-vh-restore-info-grid\">\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Restoring to</span>\n <span class=\"cqa-vh-restore-info-value\">{{ getRestoreToLabel() }}</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">New version created</span>\n <span class=\"cqa-vh-restore-info-value\">v{{ newVersionNumber }} (auto-incremented)</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Current version</span>\n <span class=\"cqa-vh-restore-info-value\">v{{ currentVersionNumber }} \u2014 preserved in history</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Author</span>\n <span class=\"cqa-vh-restore-info-value\">{{ authorName }}</span>\n </div>\n </div>\n\n <!-- Changes that will be reverted -->\n <div *ngIf=\"restoringToVersion?.changes?.length\">\n <div class=\"cqa-vh-restore-changes-title\">Changes that will be reverted</div>\n <div class=\"cqa-vh-restore-changes-list\">\n <div *ngFor=\"let change of restoringToVersion.changes; let i = index\"\n class=\"cqa-vh-restore-change-item\">\n
|
|
42885
|
+
args: [{ selector: 'cqa-version-history-restore-confirm', template: "<div class=\"cqa-vh-restore-confirm\">\n\n <!-- Info grid -->\n <div class=\"cqa-vh-restore-info-grid\">\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Restoring to</span>\n <span class=\"cqa-vh-restore-info-value\">{{ getRestoreToLabel() }}</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">New version created</span>\n <span class=\"cqa-vh-restore-info-value\">v{{ newVersionNumber }} (auto-incremented)</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Current version</span>\n <span class=\"cqa-vh-restore-info-value\">v{{ currentVersionNumber }} \u2014 preserved in history</span>\n </div>\n <div class=\"cqa-vh-restore-info-row\">\n <span class=\"cqa-vh-restore-info-label\">Author</span>\n <span class=\"cqa-vh-restore-info-value\">{{ authorName }}</span>\n </div>\n </div>\n\n <!-- Changes that will be reverted -->\n <div *ngIf=\"restoringToVersion?.changes?.length\">\n <div class=\"cqa-vh-restore-changes-title\">Changes that will be reverted</div>\n <div class=\"cqa-vh-restore-changes-list\">\n <div *ngFor=\"let change of restoringToVersion.changes; let i = index\"\n class=\"cqa-vh-restore-change-item\">\n <div class=\"cqa-vh-restore-change-index\">{{ i + 1 }}</div>\n <span class=\"cqa-vh-restore-change-sentence\">{{ getChangeHeadlineFn ? getChangeHeadlineFn(change) : change?.sentence || '' }}</span>\n </div>\n </div>\n </div>\n\n <!-- Preservation note -->\n <div class=\"cqa-vh-restore-note\">\n <span class=\"material-symbols-outlined cqa-vh-restore-note-icon\">info</span>\n <span class=\"cqa-vh-restore-note-text\">\n All version history will be fully preserved. This restore action will itself appear as a new version entry in the timeline.\n </span>\n </div>\n\n</div>\n", styles: [] }]
|
|
42923
42886
|
}], propDecorators: { restoringToVersion: [{
|
|
42924
42887
|
type: Input
|
|
42925
42888
|
}], currentVersionNumber: [{
|
|
@@ -42945,6 +42908,10 @@ class NewVersionHistoryDetailComponent {
|
|
|
42945
42908
|
this.getStepActionHtmlFn = () => '';
|
|
42946
42909
|
this.hiddenFields = [];
|
|
42947
42910
|
this.parseFieldAsTableFn = () => null;
|
|
42911
|
+
/** Return a badge config to render before the value text, or null for no badge. */
|
|
42912
|
+
this.getValueBadgeConfigFn = () => null;
|
|
42913
|
+
/** Return { oldHtml, newHtml } with inline diff markup, or null to use plain text rendering. */
|
|
42914
|
+
this.getInlineDiffFn = () => null;
|
|
42948
42915
|
this.compare = new EventEmitter();
|
|
42949
42916
|
this.restore = new EventEmitter();
|
|
42950
42917
|
}
|
|
@@ -43060,10 +43027,10 @@ class NewVersionHistoryDetailComponent {
|
|
|
43060
43027
|
}
|
|
43061
43028
|
}
|
|
43062
43029
|
NewVersionHistoryDetailComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: NewVersionHistoryDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
43063
|
-
NewVersionHistoryDetailComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: NewVersionHistoryDetailComponent, selector: "cqa-new-version-history-detail", inputs: { selectedVersion: "selectedVersion", selectedIsCurrent: "selectedIsCurrent", isRestoring: "isRestoring", getAuthorLabelFn: "getAuthorLabelFn", getFieldLabelFn: "getFieldLabelFn", getStepPrefixFn: "getStepPrefixFn", getCategoryLabelFn: "getCategoryLabelFn", formatDisplayValueFn: "formatDisplayValueFn", getStepActionHtmlFn: "getStepActionHtmlFn", hiddenFields: "hiddenFields", parseFieldAsTableFn: "parseFieldAsTableFn" }, outputs: { compare: "compare", restore: "restore" }, ngImport: i0, template: "<ng-container *ngIf=\"selectedVersion; else noSelection\">\n <!-- ========== Header (same as old component) ========== -->\n <div class=\"d-flex align-items-start justify-content-between cqa-nvh-detail-header\">\n <div>\n <div class=\"d-flex align-items-center\" style=\"gap: 8px; margin-bottom: 6px;\">\n <h3 class=\"cqa-nvh-detail-version-number\">Version {{ selectedVersion.versionNumber }}</h3>\n <cqa-badge *ngIf=\"selectedIsCurrent\" label=\"Current\" size=\"small\" variant=\"info\" backgroundColor=\"#EFF4FF\"\n textColor=\"#3f43ee\" borderColor=\"#C7D7FE\"></cqa-badge>\n </div>\n <div class=\"cqa-nvh-detail-meta\">\n {{ getAuthorLabelFn(selectedVersion) }} \u00B7 {{ selectedVersion.createdDate | date:'MMM d, yyyy \u00B7 h:mm a' }}\n </div>\n <div *ngIf=\"selectedVersion.changeSummary\" class=\"cqa-nvh-detail-summary\">\n {{ selectedVersion.changeSummary }}\n </div>\n </div>\n <div *ngIf=\"!selectedIsCurrent\" class=\"cqa-nvh-detail-actions\">\n <!-- <cqa-button variant=\"outlined\" text=\"Compare with Current\" (clicked)=\"compare.emit()\"></cqa-button> -->\n <cqa-button variant=\"filled\" icon=\"refresh\" [text]=\"isRestoring ? 'Restoring...' : 'Restore this Version'\"\n [disabled]=\"isRestoring\" (clicked)=\"restore.emit()\"></cqa-button>\n </div>\n </div>\n\n <!-- ========== Summary bar ========== -->\n <!-- <div *ngIf=\"stepsSummary\" class=\"cqa-nvh-detail-summary-bar\">\n <span *ngIf=\"stepsSummary.added\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--added\">+{{ stepsSummary.added }} added</span>\n <span *ngIf=\"stepsSummary.modified\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--modified\">{{ stepsSummary.modified }} modified</span>\n <span *ngIf=\"stepsSummary.removed\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--removed\">{{ stepsSummary.removed }} removed</span>\n <span *ngIf=\"stepsSummary.unchanged\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--unchanged\">{{ stepsSummary.unchanged }} unchanged</span>\n </div> -->\n\n <!-- ========== Test Case Changes ========== -->\n <ng-container *ngIf=\"hasTestCaseChanges\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Test Case Changes</span>\n <cqa-badge [label]=\"'' + testCaseChangedFields.length\" size=\"small\" variant=\"info\"\n backgroundColor=\"#EFF4FF\" textColor=\"#3f43ee\" borderColor=\"#C7D7FE\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let field of testCaseChangedFields; trackBy: trackByField\" class=\"cqa-nvh-change-card\">\n <div class=\"cqa-nvh-change-field-label\">{{ getFieldLabelFn(field) }}</div>\n <ng-container\n *ngTemplateOutlet=\"beforeAfterBlock; context: {\n oldValue: selectedVersion.testCase.old?.[field],\n newValue: selectedVersion.testCase.new?.[field],\n field: field,\n oldStepData: selectedVersion.testCase.old,\n newStepData: selectedVersion.testCase.new\n }\">\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Added ========== -->\n <ng-container *ngIf=\"stepsAdded.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Added</span>\n <cqa-badge [label]=\"'' + stepsAdded.length\" size=\"small\" backgroundColor=\"#ECFDF3\"\n textColor=\"#027A48\" borderColor=\"#A7F3D0\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsAdded; trackBy: trackByStepId\" class=\"cqa-nvh-change-card cqa-nvh-change-card--added\">\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge label=\"Added\" size=\"small\" backgroundColor=\"#ECFDF3\" textColor=\"#027A48\"\n borderColor=\"#A7F3D0\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Deleted ========== -->\n <ng-container *ngIf=\"stepsDeleted.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Removed</span>\n <cqa-badge [label]=\"'' + stepsDeleted.length\" size=\"small\" backgroundColor=\"#FEF3F2\"\n textColor=\"#B42318\" borderColor=\"#FECDCA\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsDeleted; trackBy: trackByStepId\" class=\"cqa-nvh-change-card cqa-nvh-change-card--removed\">\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge label=\"Removed\" size=\"small\" backgroundColor=\"#FEF3F2\" textColor=\"#B42318\"\n borderColor=\"#FECDCA\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Updated ========== -->\n <ng-container *ngIf=\"stepsUpdated.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Modified</span>\n <cqa-badge [label]=\"'' + stepsUpdated.length\" size=\"small\" backgroundColor=\"#FFFAEB\"\n textColor=\"#B54708\" borderColor=\"#FEDF89\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsUpdated; trackBy: trackByStepId\" class=\"cqa-nvh-change-card\">\n <!-- Step header with category badge -->\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge [label]=\"getCategoryLabelFn(step.category)\" size=\"small\" backgroundColor=\"#EDF1F3\"\n textColor=\"#636A71\" borderColor=\"#DBDEE1\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n\n <!-- Changed fields with before/after -->\n <div *ngFor=\"let field of visibleChangedFields(step); trackBy: trackByField\" class=\"cqa-nvh-field-diff\">\n <div class=\"cqa-nvh-change-field-label\">{{ getFieldLabelFn(field) }}</div>\n <ng-container\n *ngTemplateOutlet=\"beforeAfterBlock; context: {\n oldValue: step.old?.[field],\n newValue: step.new?.[field],\n field: field,\n oldStepData: step.old,\n newStepData: step.new\n }\">\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Empty state ========== -->\n <div *ngIf=\"!hasAnyChanges\" class=\"cqa-nvh-detail-empty\">\n <cqa-empty-state title=\"No changes\" description=\"No changes recorded for this version.\"></cqa-empty-state>\n </div>\n</ng-container>\n\n<ng-template #noSelection>\n <div class=\"cqa-nvh-detail-no-selection\">\n Select a version to view details.\n </div>\n</ng-template>\n\n<!-- ===== Reusable before/after block ===== -->\n<ng-template #beforeAfterBlock let-oldValue=\"oldValue\" let-newValue=\"newValue\" let-field=\"field\" let-oldStepData=\"oldStepData\" let-newStepData=\"newStepData\">\n <!-- 1. Custom table via parseFieldAsTableFn (e.g. testDataList) -->\n <ng-container *ngIf=\"parseFieldAsTableFn(field, oldValue, oldStepData) || parseFieldAsTableFn(field, newValue, newStepData); else nativeObjectCheck\">\n <ng-container\n *ngTemplateOutlet=\"objTable; context: {\n oldObj: parseFieldAsTableFn(field, oldValue, oldStepData),\n newObj: parseFieldAsTableFn(field, newValue, newStepData)\n }\">\n </ng-container>\n </ng-container>\n\n <!-- 2. Native object / JSON string -->\n <ng-template #nativeObjectCheck>\n <ng-container *ngIf=\"parseObjectValue(oldValue) || parseObjectValue(newValue); else simpleValue\">\n <ng-container\n *ngTemplateOutlet=\"objTable; context: {\n oldObj: parseObjectValue(oldValue),\n newObj: parseObjectValue(newValue)\n }\">\n </ng-container>\n </ng-container>\n </ng-template>\n\n <!-- 3. Primitive fallback -->\n <ng-template #simpleValue>\n <div class=\"cqa-nvh-before-after\">\n <div class=\"cqa-nvh-value-row cqa-nvh-value-row--before\">\n <cqa-badge label=\"Before\" size=\"small\" backgroundColor=\"#FEF2F2\" textColor=\"#FB2C36\"\n borderColor=\"#FFE2E2\"></cqa-badge>\n <span class=\"cqa-nvh-value-text\">{{ formatDisplayValueFn(oldValue, field, oldStepData) }}</span>\n </div>\n <div class=\"cqa-nvh-value-row cqa-nvh-value-row--after\">\n <cqa-badge label=\"After\" size=\"small\" backgroundColor=\"#ECFDF5\" textColor=\"#009966\"\n borderColor=\"#D0FAE5\"></cqa-badge>\n <span class=\"cqa-nvh-value-text\">{{ formatDisplayValueFn(newValue, field, newStepData) }}</span>\n </div>\n </div>\n </ng-template>\n</ng-template>\n\n<!-- ===== Shared object table ===== -->\n<ng-template #objTable let-oldObj=\"oldObj\" let-newObj=\"newObj\">\n <div class=\"cqa-nvh-obj-table\" *ngIf=\"objectKeys(oldObj, newObj).length > 0\">\n <div class=\"cqa-nvh-obj-header\">\n <span></span>\n <span class=\"cqa-nvh-obj-col-label cqa-nvh-obj-col-label--before\">Before</span>\n <span class=\"cqa-nvh-obj-col-label cqa-nvh-obj-col-label--after\">After</span>\n </div>\n <div\n *ngFor=\"let key of objectKeys(oldObj, newObj); trackBy: trackByKey\"\n class=\"cqa-nvh-obj-row\">\n <span class=\"cqa-nvh-obj-key\">{{ getFieldLabelFn(key) }}</span>\n <span class=\"cqa-nvh-obj-val cqa-nvh-obj-val--before\">\n {{ formatPrimitiveValue(oldObj?.[key]) }}\n </span>\n <span class=\"cqa-nvh-obj-val cqa-nvh-obj-val--after\">\n {{ formatPrimitiveValue(newObj?.[key]) }}\n </span>\n </div>\n </div>\n</ng-template>\n", components: [{ type: BadgeComponent, selector: "cqa-badge", inputs: ["type", "label", "icon", "iconLibrary", "variant", "size", "backgroundColor", "textColor", "borderColor", "iconBackgroundColor", "iconColor", "iconSize", "inlineStyles", "key", "value", "keyTextColor", "valueTextColor", "isLoading", "fullWidth", "centerContent", "title"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: EmptyStateComponent, selector: "cqa-empty-state", inputs: ["preset", "imageUrl", "title", "description", "actions"], outputs: ["actionClick"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "date": i2.DatePipe } });
|
|
43030
|
+
NewVersionHistoryDetailComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: NewVersionHistoryDetailComponent, selector: "cqa-new-version-history-detail", inputs: { selectedVersion: "selectedVersion", selectedIsCurrent: "selectedIsCurrent", isRestoring: "isRestoring", getAuthorLabelFn: "getAuthorLabelFn", getFieldLabelFn: "getFieldLabelFn", getStepPrefixFn: "getStepPrefixFn", getCategoryLabelFn: "getCategoryLabelFn", formatDisplayValueFn: "formatDisplayValueFn", getStepActionHtmlFn: "getStepActionHtmlFn", hiddenFields: "hiddenFields", parseFieldAsTableFn: "parseFieldAsTableFn", getValueBadgeConfigFn: "getValueBadgeConfigFn", getInlineDiffFn: "getInlineDiffFn" }, outputs: { compare: "compare", restore: "restore" }, ngImport: i0, template: "<ng-container *ngIf=\"selectedVersion; else noSelection\">\n <!-- ========== Header (same as old component) ========== -->\n <div class=\"d-flex align-items-start justify-content-between cqa-nvh-detail-header\">\n <div>\n <div class=\"d-flex align-items-center\" style=\"gap: 8px; margin-bottom: 6px;\">\n <h3 class=\"cqa-nvh-detail-version-number\">Version {{ selectedVersion.versionNumber }}</h3>\n <cqa-badge *ngIf=\"selectedIsCurrent\" label=\"Current\" size=\"small\" variant=\"info\" backgroundColor=\"#EFF4FF\"\n textColor=\"#3f43ee\" borderColor=\"#C7D7FE\"></cqa-badge>\n </div>\n <div class=\"cqa-nvh-detail-meta\">\n {{ getAuthorLabelFn(selectedVersion) }} \u00B7 {{ selectedVersion.createdDate | date:'MMM d, yyyy \u00B7 h:mm a' }}\n </div>\n <div *ngIf=\"selectedVersion.changeSummary\" class=\"cqa-nvh-detail-summary\">\n {{ selectedVersion.changeSummary }}\n </div>\n </div>\n <div *ngIf=\"!selectedIsCurrent\" class=\"cqa-nvh-detail-actions\">\n <!-- <cqa-button variant=\"outlined\" text=\"Compare with Current\" (clicked)=\"compare.emit()\"></cqa-button> -->\n <cqa-button variant=\"filled\" icon=\"refresh\" [text]=\"isRestoring ? 'Restoring...' : 'Restore this Version'\"\n [disabled]=\"isRestoring\" (clicked)=\"restore.emit()\"></cqa-button>\n </div>\n </div>\n\n <!-- ========== Summary bar ========== -->\n <!-- <div *ngIf=\"stepsSummary\" class=\"cqa-nvh-detail-summary-bar\">\n <span *ngIf=\"stepsSummary.added\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--added\">+{{ stepsSummary.added }} added</span>\n <span *ngIf=\"stepsSummary.modified\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--modified\">{{ stepsSummary.modified }} modified</span>\n <span *ngIf=\"stepsSummary.removed\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--removed\">{{ stepsSummary.removed }} removed</span>\n <span *ngIf=\"stepsSummary.unchanged\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--unchanged\">{{ stepsSummary.unchanged }} unchanged</span>\n </div> -->\n\n <!-- ========== Test Case Changes ========== -->\n <ng-container *ngIf=\"hasTestCaseChanges\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Test Case Changes</span>\n <cqa-badge [label]=\"'' + testCaseChangedFields.length\" size=\"small\" variant=\"info\"\n backgroundColor=\"#EFF4FF\" textColor=\"#3f43ee\" borderColor=\"#C7D7FE\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let field of testCaseChangedFields; trackBy: trackByField\" class=\"cqa-nvh-change-card\">\n <div class=\"cqa-nvh-change-field-label\">{{ getFieldLabelFn(field) }}</div>\n <ng-container\n *ngTemplateOutlet=\"beforeAfterBlock; context: {\n oldValue: selectedVersion.testCase.old?.[field],\n newValue: selectedVersion.testCase.new?.[field],\n field: field,\n oldStepData: selectedVersion.testCase.old,\n newStepData: selectedVersion.testCase.new\n }\">\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Added ========== -->\n <ng-container *ngIf=\"stepsAdded.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Added</span>\n <cqa-badge [label]=\"'' + stepsAdded.length\" size=\"small\" backgroundColor=\"#ECFDF3\"\n textColor=\"#027A48\" borderColor=\"#A7F3D0\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsAdded; trackBy: trackByStepId\" class=\"cqa-nvh-change-card cqa-nvh-change-card--added\">\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge label=\"Added\" size=\"small\" backgroundColor=\"#ECFDF3\" textColor=\"#027A48\"\n borderColor=\"#A7F3D0\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Deleted ========== -->\n <ng-container *ngIf=\"stepsDeleted.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Removed</span>\n <cqa-badge [label]=\"'' + stepsDeleted.length\" size=\"small\" backgroundColor=\"#FEF3F2\"\n textColor=\"#B42318\" borderColor=\"#FECDCA\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsDeleted; trackBy: trackByStepId\" class=\"cqa-nvh-change-card cqa-nvh-change-card--removed\">\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge label=\"Removed\" size=\"small\" backgroundColor=\"#FEF3F2\" textColor=\"#B42318\"\n borderColor=\"#FECDCA\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Updated ========== -->\n <ng-container *ngIf=\"stepsUpdated.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Modified</span>\n <cqa-badge [label]=\"'' + stepsUpdated.length\" size=\"small\" backgroundColor=\"#FFFAEB\"\n textColor=\"#B54708\" borderColor=\"#FEDF89\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsUpdated; trackBy: trackByStepId\" class=\"cqa-nvh-change-card\">\n <!-- Step header with category badge -->\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge [label]=\"getCategoryLabelFn(step.category)\" size=\"small\" backgroundColor=\"#EDF1F3\"\n textColor=\"#636A71\" borderColor=\"#DBDEE1\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n\n <!-- Changed fields with before/after -->\n <div *ngFor=\"let field of visibleChangedFields(step); trackBy: trackByField\" class=\"cqa-nvh-field-diff\">\n <div class=\"cqa-nvh-change-field-label\">{{ getFieldLabelFn(field) }}</div>\n <ng-container\n *ngTemplateOutlet=\"beforeAfterBlock; context: {\n oldValue: step.old?.[field],\n newValue: step.new?.[field],\n field: field,\n oldStepData: step.old,\n newStepData: step.new\n }\">\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Empty state ========== -->\n <div *ngIf=\"!hasAnyChanges\" class=\"cqa-nvh-detail-empty\">\n <cqa-empty-state title=\"No changes\" description=\"No changes recorded for this version.\"></cqa-empty-state>\n </div>\n</ng-container>\n\n<ng-template #noSelection>\n <div class=\"cqa-nvh-detail-no-selection\">\n Select a version to view details.\n </div>\n</ng-template>\n\n<!-- ===== Reusable before/after block ===== -->\n<ng-template #beforeAfterBlock let-oldValue=\"oldValue\" let-newValue=\"newValue\" let-field=\"field\" let-oldStepData=\"oldStepData\" let-newStepData=\"newStepData\">\n <!-- 1. Custom table via parseFieldAsTableFn (e.g. testDataList) -->\n <ng-container *ngIf=\"parseFieldAsTableFn(field, oldValue, oldStepData) || parseFieldAsTableFn(field, newValue, newStepData); else nativeObjectCheck\">\n <ng-container\n *ngTemplateOutlet=\"objTable; context: {\n oldObj: parseFieldAsTableFn(field, oldValue, oldStepData),\n newObj: parseFieldAsTableFn(field, newValue, newStepData)\n }\">\n </ng-container>\n </ng-container>\n\n <!-- 2. Native object / JSON string -->\n <ng-template #nativeObjectCheck>\n <ng-container *ngIf=\"parseObjectValue(oldValue) || parseObjectValue(newValue); else simpleValue\">\n <ng-container\n *ngTemplateOutlet=\"objTable; context: {\n oldObj: parseObjectValue(oldValue),\n newObj: parseObjectValue(newValue)\n }\">\n </ng-container>\n </ng-container>\n </ng-template>\n\n <!-- 3. Primitive fallback -->\n <ng-template #simpleValue>\n <ng-container *ngIf=\"getInlineDiffFn(oldValue, newValue, field, oldStepData, newStepData) as diff; else plainBeforeAfter\">\n <!-- Inline diff view: no --before/--after color modifiers; diff HTML owns all token colors -->\n <div class=\"cqa-nvh-before-after\">\n <div class=\"cqa-nvh-value-row\">\n <cqa-badge label=\"Before\" size=\"small\" backgroundColor=\"#FEF2F2\" textColor=\"#FB2C36\"\n borderColor=\"#FFE2E2\"></cqa-badge>\n <ng-container *ngIf=\"getValueBadgeConfigFn(oldValue, field, oldStepData) as badge\">\n <cqa-badge [label]=\"badge.label\" size=\"small\"\n [backgroundColor]=\"badge.backgroundColor\" [textColor]=\"badge.textColor\"\n [borderColor]=\"badge.borderColor\"></cqa-badge>\n </ng-container>\n <span class=\"cqa-nvh-value-text\" [innerHTML]=\"diff.oldHtml\"></span>\n </div>\n <div class=\"cqa-nvh-value-row\">\n <cqa-badge label=\"After\" size=\"small\" backgroundColor=\"#ECFDF5\" textColor=\"#009966\"\n borderColor=\"#D0FAE5\"></cqa-badge>\n <ng-container *ngIf=\"getValueBadgeConfigFn(newValue, field, newStepData) as badge\">\n <cqa-badge [label]=\"badge.label\" size=\"small\"\n [backgroundColor]=\"badge.backgroundColor\" [textColor]=\"badge.textColor\"\n [borderColor]=\"badge.borderColor\"></cqa-badge>\n </ng-container>\n <span class=\"cqa-nvh-value-text\" [innerHTML]=\"diff.newHtml\"></span>\n </div>\n </div>\n </ng-container>\n\n <!-- Plain text fallback (no diff) -->\n <ng-template #plainBeforeAfter>\n <div class=\"cqa-nvh-before-after\">\n <div class=\"cqa-nvh-value-row cqa-nvh-value-row--before\">\n <cqa-badge label=\"Before\" size=\"small\" backgroundColor=\"#FEF2F2\" textColor=\"#FB2C36\"\n borderColor=\"#FFE2E2\"></cqa-badge>\n <ng-container *ngIf=\"getValueBadgeConfigFn(oldValue, field, oldStepData) as badge\">\n <cqa-badge [label]=\"badge.label\" size=\"small\"\n [backgroundColor]=\"badge.backgroundColor\" [textColor]=\"badge.textColor\"\n [borderColor]=\"badge.borderColor\"></cqa-badge>\n </ng-container>\n <span class=\"cqa-nvh-value-text\">{{ formatDisplayValueFn(oldValue, field, oldStepData) }}</span>\n </div>\n <div class=\"cqa-nvh-value-row cqa-nvh-value-row--after\">\n <cqa-badge label=\"After\" size=\"small\" backgroundColor=\"#ECFDF5\" textColor=\"#009966\"\n borderColor=\"#D0FAE5\"></cqa-badge>\n <ng-container *ngIf=\"getValueBadgeConfigFn(newValue, field, newStepData) as badge\">\n <cqa-badge [label]=\"badge.label\" size=\"small\"\n [backgroundColor]=\"badge.backgroundColor\" [textColor]=\"badge.textColor\"\n [borderColor]=\"badge.borderColor\"></cqa-badge>\n </ng-container>\n <span class=\"cqa-nvh-value-text\">{{ formatDisplayValueFn(newValue, field, newStepData) }}</span>\n </div>\n </div>\n </ng-template>\n </ng-template>\n</ng-template>\n\n<!-- ===== Shared object table ===== -->\n<ng-template #objTable let-oldObj=\"oldObj\" let-newObj=\"newObj\">\n <div class=\"cqa-nvh-obj-table\" *ngIf=\"objectKeys(oldObj, newObj).length > 0\">\n <div class=\"cqa-nvh-obj-header\">\n <span></span>\n <span class=\"cqa-nvh-obj-col-label cqa-nvh-obj-col-label--before\">Before</span>\n <span class=\"cqa-nvh-obj-col-label cqa-nvh-obj-col-label--after\">After</span>\n </div>\n <div\n *ngFor=\"let key of objectKeys(oldObj, newObj); trackBy: trackByKey\"\n class=\"cqa-nvh-obj-row\">\n <span class=\"cqa-nvh-obj-key\">{{ getFieldLabelFn(key) }}</span>\n <span class=\"cqa-nvh-obj-val cqa-nvh-obj-val--before\">\n {{ formatPrimitiveValue(oldObj?.[key]) }}\n </span>\n <span class=\"cqa-nvh-obj-val cqa-nvh-obj-val--after\">\n {{ formatPrimitiveValue(newObj?.[key]) }}\n </span>\n </div>\n </div>\n</ng-template>\n", components: [{ type: BadgeComponent, selector: "cqa-badge", inputs: ["type", "label", "icon", "iconLibrary", "variant", "size", "backgroundColor", "textColor", "borderColor", "iconBackgroundColor", "iconColor", "iconSize", "inlineStyles", "key", "value", "keyTextColor", "valueTextColor", "isLoading", "fullWidth", "centerContent", "title"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: EmptyStateComponent, selector: "cqa-empty-state", inputs: ["preset", "imageUrl", "title", "description", "actions"], outputs: ["actionClick"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "date": i2.DatePipe } });
|
|
43064
43031
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: NewVersionHistoryDetailComponent, decorators: [{
|
|
43065
43032
|
type: Component,
|
|
43066
|
-
args: [{ selector: 'cqa-new-version-history-detail', template: "<ng-container *ngIf=\"selectedVersion; else noSelection\">\n <!-- ========== Header (same as old component) ========== -->\n <div class=\"d-flex align-items-start justify-content-between cqa-nvh-detail-header\">\n <div>\n <div class=\"d-flex align-items-center\" style=\"gap: 8px; margin-bottom: 6px;\">\n <h3 class=\"cqa-nvh-detail-version-number\">Version {{ selectedVersion.versionNumber }}</h3>\n <cqa-badge *ngIf=\"selectedIsCurrent\" label=\"Current\" size=\"small\" variant=\"info\" backgroundColor=\"#EFF4FF\"\n textColor=\"#3f43ee\" borderColor=\"#C7D7FE\"></cqa-badge>\n </div>\n <div class=\"cqa-nvh-detail-meta\">\n {{ getAuthorLabelFn(selectedVersion) }} \u00B7 {{ selectedVersion.createdDate | date:'MMM d, yyyy \u00B7 h:mm a' }}\n </div>\n <div *ngIf=\"selectedVersion.changeSummary\" class=\"cqa-nvh-detail-summary\">\n {{ selectedVersion.changeSummary }}\n </div>\n </div>\n <div *ngIf=\"!selectedIsCurrent\" class=\"cqa-nvh-detail-actions\">\n <!-- <cqa-button variant=\"outlined\" text=\"Compare with Current\" (clicked)=\"compare.emit()\"></cqa-button> -->\n <cqa-button variant=\"filled\" icon=\"refresh\" [text]=\"isRestoring ? 'Restoring...' : 'Restore this Version'\"\n [disabled]=\"isRestoring\" (clicked)=\"restore.emit()\"></cqa-button>\n </div>\n </div>\n\n <!-- ========== Summary bar ========== -->\n <!-- <div *ngIf=\"stepsSummary\" class=\"cqa-nvh-detail-summary-bar\">\n <span *ngIf=\"stepsSummary.added\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--added\">+{{ stepsSummary.added }} added</span>\n <span *ngIf=\"stepsSummary.modified\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--modified\">{{ stepsSummary.modified }} modified</span>\n <span *ngIf=\"stepsSummary.removed\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--removed\">{{ stepsSummary.removed }} removed</span>\n <span *ngIf=\"stepsSummary.unchanged\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--unchanged\">{{ stepsSummary.unchanged }} unchanged</span>\n </div> -->\n\n <!-- ========== Test Case Changes ========== -->\n <ng-container *ngIf=\"hasTestCaseChanges\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Test Case Changes</span>\n <cqa-badge [label]=\"'' + testCaseChangedFields.length\" size=\"small\" variant=\"info\"\n backgroundColor=\"#EFF4FF\" textColor=\"#3f43ee\" borderColor=\"#C7D7FE\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let field of testCaseChangedFields; trackBy: trackByField\" class=\"cqa-nvh-change-card\">\n <div class=\"cqa-nvh-change-field-label\">{{ getFieldLabelFn(field) }}</div>\n <ng-container\n *ngTemplateOutlet=\"beforeAfterBlock; context: {\n oldValue: selectedVersion.testCase.old?.[field],\n newValue: selectedVersion.testCase.new?.[field],\n field: field,\n oldStepData: selectedVersion.testCase.old,\n newStepData: selectedVersion.testCase.new\n }\">\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Added ========== -->\n <ng-container *ngIf=\"stepsAdded.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Added</span>\n <cqa-badge [label]=\"'' + stepsAdded.length\" size=\"small\" backgroundColor=\"#ECFDF3\"\n textColor=\"#027A48\" borderColor=\"#A7F3D0\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsAdded; trackBy: trackByStepId\" class=\"cqa-nvh-change-card cqa-nvh-change-card--added\">\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge label=\"Added\" size=\"small\" backgroundColor=\"#ECFDF3\" textColor=\"#027A48\"\n borderColor=\"#A7F3D0\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Deleted ========== -->\n <ng-container *ngIf=\"stepsDeleted.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Removed</span>\n <cqa-badge [label]=\"'' + stepsDeleted.length\" size=\"small\" backgroundColor=\"#FEF3F2\"\n textColor=\"#B42318\" borderColor=\"#FECDCA\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsDeleted; trackBy: trackByStepId\" class=\"cqa-nvh-change-card cqa-nvh-change-card--removed\">\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge label=\"Removed\" size=\"small\" backgroundColor=\"#FEF3F2\" textColor=\"#B42318\"\n borderColor=\"#FECDCA\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Updated ========== -->\n <ng-container *ngIf=\"stepsUpdated.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Modified</span>\n <cqa-badge [label]=\"'' + stepsUpdated.length\" size=\"small\" backgroundColor=\"#FFFAEB\"\n textColor=\"#B54708\" borderColor=\"#FEDF89\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsUpdated; trackBy: trackByStepId\" class=\"cqa-nvh-change-card\">\n <!-- Step header with category badge -->\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge [label]=\"getCategoryLabelFn(step.category)\" size=\"small\" backgroundColor=\"#EDF1F3\"\n textColor=\"#636A71\" borderColor=\"#DBDEE1\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n\n <!-- Changed fields with before/after -->\n <div *ngFor=\"let field of visibleChangedFields(step); trackBy: trackByField\" class=\"cqa-nvh-field-diff\">\n <div class=\"cqa-nvh-change-field-label\">{{ getFieldLabelFn(field) }}</div>\n <ng-container\n *ngTemplateOutlet=\"beforeAfterBlock; context: {\n oldValue: step.old?.[field],\n newValue: step.new?.[field],\n field: field,\n oldStepData: step.old,\n newStepData: step.new\n }\">\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Empty state ========== -->\n <div *ngIf=\"!hasAnyChanges\" class=\"cqa-nvh-detail-empty\">\n <cqa-empty-state title=\"No changes\" description=\"No changes recorded for this version.\"></cqa-empty-state>\n </div>\n</ng-container>\n\n<ng-template #noSelection>\n <div class=\"cqa-nvh-detail-no-selection\">\n Select a version to view details.\n </div>\n</ng-template>\n\n<!-- ===== Reusable before/after block ===== -->\n<ng-template #beforeAfterBlock let-oldValue=\"oldValue\" let-newValue=\"newValue\" let-field=\"field\" let-oldStepData=\"oldStepData\" let-newStepData=\"newStepData\">\n <!-- 1. Custom table via parseFieldAsTableFn (e.g. testDataList) -->\n <ng-container *ngIf=\"parseFieldAsTableFn(field, oldValue, oldStepData) || parseFieldAsTableFn(field, newValue, newStepData); else nativeObjectCheck\">\n <ng-container\n *ngTemplateOutlet=\"objTable; context: {\n oldObj: parseFieldAsTableFn(field, oldValue, oldStepData),\n newObj: parseFieldAsTableFn(field, newValue, newStepData)\n }\">\n </ng-container>\n </ng-container>\n\n <!-- 2. Native object / JSON string -->\n <ng-template #nativeObjectCheck>\n <ng-container *ngIf=\"parseObjectValue(oldValue) || parseObjectValue(newValue); else simpleValue\">\n <ng-container\n *ngTemplateOutlet=\"objTable; context: {\n oldObj: parseObjectValue(oldValue),\n newObj: parseObjectValue(newValue)\n }\">\n </ng-container>\n </ng-container>\n </ng-template>\n\n <!-- 3. Primitive fallback -->\n <ng-template #simpleValue>\n <div class=\"cqa-nvh-before-after\">\n <div class=\"cqa-nvh-value-row cqa-nvh-value-row--before\">\n <cqa-badge label=\"Before\" size=\"small\" backgroundColor=\"#FEF2F2\" textColor=\"#FB2C36\"\n borderColor=\"#FFE2E2\"></cqa-badge>\n <span class=\"cqa-nvh-value-text\">{{ formatDisplayValueFn(oldValue, field, oldStepData) }}</span>\n </div>\n <div class=\"cqa-nvh-value-row cqa-nvh-value-row--after\">\n <cqa-badge label=\"After\" size=\"small\" backgroundColor=\"#ECFDF5\" textColor=\"#009966\"\n borderColor=\"#D0FAE5\"></cqa-badge>\n <span class=\"cqa-nvh-value-text\">{{ formatDisplayValueFn(newValue, field, newStepData) }}</span>\n </div>\n </div>\n </ng-template>\n</ng-template>\n\n<!-- ===== Shared object table ===== -->\n<ng-template #objTable let-oldObj=\"oldObj\" let-newObj=\"newObj\">\n <div class=\"cqa-nvh-obj-table\" *ngIf=\"objectKeys(oldObj, newObj).length > 0\">\n <div class=\"cqa-nvh-obj-header\">\n <span></span>\n <span class=\"cqa-nvh-obj-col-label cqa-nvh-obj-col-label--before\">Before</span>\n <span class=\"cqa-nvh-obj-col-label cqa-nvh-obj-col-label--after\">After</span>\n </div>\n <div\n *ngFor=\"let key of objectKeys(oldObj, newObj); trackBy: trackByKey\"\n class=\"cqa-nvh-obj-row\">\n <span class=\"cqa-nvh-obj-key\">{{ getFieldLabelFn(key) }}</span>\n <span class=\"cqa-nvh-obj-val cqa-nvh-obj-val--before\">\n {{ formatPrimitiveValue(oldObj?.[key]) }}\n </span>\n <span class=\"cqa-nvh-obj-val cqa-nvh-obj-val--after\">\n {{ formatPrimitiveValue(newObj?.[key]) }}\n </span>\n </div>\n </div>\n</ng-template>\n", styles: [] }]
|
|
43033
|
+
args: [{ selector: 'cqa-new-version-history-detail', template: "<ng-container *ngIf=\"selectedVersion; else noSelection\">\n <!-- ========== Header (same as old component) ========== -->\n <div class=\"d-flex align-items-start justify-content-between cqa-nvh-detail-header\">\n <div>\n <div class=\"d-flex align-items-center\" style=\"gap: 8px; margin-bottom: 6px;\">\n <h3 class=\"cqa-nvh-detail-version-number\">Version {{ selectedVersion.versionNumber }}</h3>\n <cqa-badge *ngIf=\"selectedIsCurrent\" label=\"Current\" size=\"small\" variant=\"info\" backgroundColor=\"#EFF4FF\"\n textColor=\"#3f43ee\" borderColor=\"#C7D7FE\"></cqa-badge>\n </div>\n <div class=\"cqa-nvh-detail-meta\">\n {{ getAuthorLabelFn(selectedVersion) }} \u00B7 {{ selectedVersion.createdDate | date:'MMM d, yyyy \u00B7 h:mm a' }}\n </div>\n <div *ngIf=\"selectedVersion.changeSummary\" class=\"cqa-nvh-detail-summary\">\n {{ selectedVersion.changeSummary }}\n </div>\n </div>\n <div *ngIf=\"!selectedIsCurrent\" class=\"cqa-nvh-detail-actions\">\n <!-- <cqa-button variant=\"outlined\" text=\"Compare with Current\" (clicked)=\"compare.emit()\"></cqa-button> -->\n <cqa-button variant=\"filled\" icon=\"refresh\" [text]=\"isRestoring ? 'Restoring...' : 'Restore this Version'\"\n [disabled]=\"isRestoring\" (clicked)=\"restore.emit()\"></cqa-button>\n </div>\n </div>\n\n <!-- ========== Summary bar ========== -->\n <!-- <div *ngIf=\"stepsSummary\" class=\"cqa-nvh-detail-summary-bar\">\n <span *ngIf=\"stepsSummary.added\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--added\">+{{ stepsSummary.added }} added</span>\n <span *ngIf=\"stepsSummary.modified\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--modified\">{{ stepsSummary.modified }} modified</span>\n <span *ngIf=\"stepsSummary.removed\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--removed\">{{ stepsSummary.removed }} removed</span>\n <span *ngIf=\"stepsSummary.unchanged\" class=\"cqa-nvh-summary-chip cqa-nvh-summary-chip--unchanged\">{{ stepsSummary.unchanged }} unchanged</span>\n </div> -->\n\n <!-- ========== Test Case Changes ========== -->\n <ng-container *ngIf=\"hasTestCaseChanges\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Test Case Changes</span>\n <cqa-badge [label]=\"'' + testCaseChangedFields.length\" size=\"small\" variant=\"info\"\n backgroundColor=\"#EFF4FF\" textColor=\"#3f43ee\" borderColor=\"#C7D7FE\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let field of testCaseChangedFields; trackBy: trackByField\" class=\"cqa-nvh-change-card\">\n <div class=\"cqa-nvh-change-field-label\">{{ getFieldLabelFn(field) }}</div>\n <ng-container\n *ngTemplateOutlet=\"beforeAfterBlock; context: {\n oldValue: selectedVersion.testCase.old?.[field],\n newValue: selectedVersion.testCase.new?.[field],\n field: field,\n oldStepData: selectedVersion.testCase.old,\n newStepData: selectedVersion.testCase.new\n }\">\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Added ========== -->\n <ng-container *ngIf=\"stepsAdded.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Added</span>\n <cqa-badge [label]=\"'' + stepsAdded.length\" size=\"small\" backgroundColor=\"#ECFDF3\"\n textColor=\"#027A48\" borderColor=\"#A7F3D0\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsAdded; trackBy: trackByStepId\" class=\"cqa-nvh-change-card cqa-nvh-change-card--added\">\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge label=\"Added\" size=\"small\" backgroundColor=\"#ECFDF3\" textColor=\"#027A48\"\n borderColor=\"#A7F3D0\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Deleted ========== -->\n <ng-container *ngIf=\"stepsDeleted.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Removed</span>\n <cqa-badge [label]=\"'' + stepsDeleted.length\" size=\"small\" backgroundColor=\"#FEF3F2\"\n textColor=\"#B42318\" borderColor=\"#FECDCA\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsDeleted; trackBy: trackByStepId\" class=\"cqa-nvh-change-card cqa-nvh-change-card--removed\">\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge label=\"Removed\" size=\"small\" backgroundColor=\"#FEF3F2\" textColor=\"#B42318\"\n borderColor=\"#FECDCA\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Steps Updated ========== -->\n <ng-container *ngIf=\"stepsUpdated.length\">\n <div class=\"cqa-nvh-section-header\">\n <span class=\"cqa-nvh-section-label\">Steps Modified</span>\n <cqa-badge [label]=\"'' + stepsUpdated.length\" size=\"small\" backgroundColor=\"#FFFAEB\"\n textColor=\"#B54708\" borderColor=\"#FEDF89\"></cqa-badge>\n </div>\n\n <div class=\"cqa-nvh-changes-list\">\n <div *ngFor=\"let step of stepsUpdated; trackBy: trackByStepId\" class=\"cqa-nvh-change-card\">\n <!-- Step header with category badge -->\n <div class=\"cqa-nvh-step-header\">\n <cqa-badge [label]=\"getCategoryLabelFn(step.category)\" size=\"small\" backgroundColor=\"#EDF1F3\"\n textColor=\"#636A71\" borderColor=\"#DBDEE1\"></cqa-badge>\n <span class=\"cqa-nvh-step-prefix\">{{ getStepPrefixFn(step) }}</span>\n <span class=\"cqa-nvh-step-action cqa-action-format\" [innerHTML]=\"getStepActionHtmlFn(step)\"></span>\n </div>\n\n <!-- Changed fields with before/after -->\n <div *ngFor=\"let field of visibleChangedFields(step); trackBy: trackByField\" class=\"cqa-nvh-field-diff\">\n <div class=\"cqa-nvh-change-field-label\">{{ getFieldLabelFn(field) }}</div>\n <ng-container\n *ngTemplateOutlet=\"beforeAfterBlock; context: {\n oldValue: step.old?.[field],\n newValue: step.new?.[field],\n field: field,\n oldStepData: step.old,\n newStepData: step.new\n }\">\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- ========== Empty state ========== -->\n <div *ngIf=\"!hasAnyChanges\" class=\"cqa-nvh-detail-empty\">\n <cqa-empty-state title=\"No changes\" description=\"No changes recorded for this version.\"></cqa-empty-state>\n </div>\n</ng-container>\n\n<ng-template #noSelection>\n <div class=\"cqa-nvh-detail-no-selection\">\n Select a version to view details.\n </div>\n</ng-template>\n\n<!-- ===== Reusable before/after block ===== -->\n<ng-template #beforeAfterBlock let-oldValue=\"oldValue\" let-newValue=\"newValue\" let-field=\"field\" let-oldStepData=\"oldStepData\" let-newStepData=\"newStepData\">\n <!-- 1. Custom table via parseFieldAsTableFn (e.g. testDataList) -->\n <ng-container *ngIf=\"parseFieldAsTableFn(field, oldValue, oldStepData) || parseFieldAsTableFn(field, newValue, newStepData); else nativeObjectCheck\">\n <ng-container\n *ngTemplateOutlet=\"objTable; context: {\n oldObj: parseFieldAsTableFn(field, oldValue, oldStepData),\n newObj: parseFieldAsTableFn(field, newValue, newStepData)\n }\">\n </ng-container>\n </ng-container>\n\n <!-- 2. Native object / JSON string -->\n <ng-template #nativeObjectCheck>\n <ng-container *ngIf=\"parseObjectValue(oldValue) || parseObjectValue(newValue); else simpleValue\">\n <ng-container\n *ngTemplateOutlet=\"objTable; context: {\n oldObj: parseObjectValue(oldValue),\n newObj: parseObjectValue(newValue)\n }\">\n </ng-container>\n </ng-container>\n </ng-template>\n\n <!-- 3. Primitive fallback -->\n <ng-template #simpleValue>\n <ng-container *ngIf=\"getInlineDiffFn(oldValue, newValue, field, oldStepData, newStepData) as diff; else plainBeforeAfter\">\n <!-- Inline diff view: no --before/--after color modifiers; diff HTML owns all token colors -->\n <div class=\"cqa-nvh-before-after\">\n <div class=\"cqa-nvh-value-row\">\n <cqa-badge label=\"Before\" size=\"small\" backgroundColor=\"#FEF2F2\" textColor=\"#FB2C36\"\n borderColor=\"#FFE2E2\"></cqa-badge>\n <ng-container *ngIf=\"getValueBadgeConfigFn(oldValue, field, oldStepData) as badge\">\n <cqa-badge [label]=\"badge.label\" size=\"small\"\n [backgroundColor]=\"badge.backgroundColor\" [textColor]=\"badge.textColor\"\n [borderColor]=\"badge.borderColor\"></cqa-badge>\n </ng-container>\n <span class=\"cqa-nvh-value-text\" [innerHTML]=\"diff.oldHtml\"></span>\n </div>\n <div class=\"cqa-nvh-value-row\">\n <cqa-badge label=\"After\" size=\"small\" backgroundColor=\"#ECFDF5\" textColor=\"#009966\"\n borderColor=\"#D0FAE5\"></cqa-badge>\n <ng-container *ngIf=\"getValueBadgeConfigFn(newValue, field, newStepData) as badge\">\n <cqa-badge [label]=\"badge.label\" size=\"small\"\n [backgroundColor]=\"badge.backgroundColor\" [textColor]=\"badge.textColor\"\n [borderColor]=\"badge.borderColor\"></cqa-badge>\n </ng-container>\n <span class=\"cqa-nvh-value-text\" [innerHTML]=\"diff.newHtml\"></span>\n </div>\n </div>\n </ng-container>\n\n <!-- Plain text fallback (no diff) -->\n <ng-template #plainBeforeAfter>\n <div class=\"cqa-nvh-before-after\">\n <div class=\"cqa-nvh-value-row cqa-nvh-value-row--before\">\n <cqa-badge label=\"Before\" size=\"small\" backgroundColor=\"#FEF2F2\" textColor=\"#FB2C36\"\n borderColor=\"#FFE2E2\"></cqa-badge>\n <ng-container *ngIf=\"getValueBadgeConfigFn(oldValue, field, oldStepData) as badge\">\n <cqa-badge [label]=\"badge.label\" size=\"small\"\n [backgroundColor]=\"badge.backgroundColor\" [textColor]=\"badge.textColor\"\n [borderColor]=\"badge.borderColor\"></cqa-badge>\n </ng-container>\n <span class=\"cqa-nvh-value-text\">{{ formatDisplayValueFn(oldValue, field, oldStepData) }}</span>\n </div>\n <div class=\"cqa-nvh-value-row cqa-nvh-value-row--after\">\n <cqa-badge label=\"After\" size=\"small\" backgroundColor=\"#ECFDF5\" textColor=\"#009966\"\n borderColor=\"#D0FAE5\"></cqa-badge>\n <ng-container *ngIf=\"getValueBadgeConfigFn(newValue, field, newStepData) as badge\">\n <cqa-badge [label]=\"badge.label\" size=\"small\"\n [backgroundColor]=\"badge.backgroundColor\" [textColor]=\"badge.textColor\"\n [borderColor]=\"badge.borderColor\"></cqa-badge>\n </ng-container>\n <span class=\"cqa-nvh-value-text\">{{ formatDisplayValueFn(newValue, field, newStepData) }}</span>\n </div>\n </div>\n </ng-template>\n </ng-template>\n</ng-template>\n\n<!-- ===== Shared object table ===== -->\n<ng-template #objTable let-oldObj=\"oldObj\" let-newObj=\"newObj\">\n <div class=\"cqa-nvh-obj-table\" *ngIf=\"objectKeys(oldObj, newObj).length > 0\">\n <div class=\"cqa-nvh-obj-header\">\n <span></span>\n <span class=\"cqa-nvh-obj-col-label cqa-nvh-obj-col-label--before\">Before</span>\n <span class=\"cqa-nvh-obj-col-label cqa-nvh-obj-col-label--after\">After</span>\n </div>\n <div\n *ngFor=\"let key of objectKeys(oldObj, newObj); trackBy: trackByKey\"\n class=\"cqa-nvh-obj-row\">\n <span class=\"cqa-nvh-obj-key\">{{ getFieldLabelFn(key) }}</span>\n <span class=\"cqa-nvh-obj-val cqa-nvh-obj-val--before\">\n {{ formatPrimitiveValue(oldObj?.[key]) }}\n </span>\n <span class=\"cqa-nvh-obj-val cqa-nvh-obj-val--after\">\n {{ formatPrimitiveValue(newObj?.[key]) }}\n </span>\n </div>\n </div>\n</ng-template>\n", styles: [] }]
|
|
43067
43034
|
}], propDecorators: { selectedVersion: [{
|
|
43068
43035
|
type: Input
|
|
43069
43036
|
}], selectedIsCurrent: [{
|
|
@@ -43086,6 +43053,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
43086
43053
|
type: Input
|
|
43087
43054
|
}], parseFieldAsTableFn: [{
|
|
43088
43055
|
type: Input
|
|
43056
|
+
}], getValueBadgeConfigFn: [{
|
|
43057
|
+
type: Input
|
|
43058
|
+
}], getInlineDiffFn: [{
|
|
43059
|
+
type: Input
|
|
43089
43060
|
}], compare: [{
|
|
43090
43061
|
type: Output
|
|
43091
43062
|
}], restore: [{
|