tango-app-ui-analyse-trax 4.0.48 → 4.0.49

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.
@@ -20,7 +20,7 @@ import * as i2 from 'tango-app-ui-global';
20
20
  import dayjs from 'dayjs';
21
21
  import dayjsEsm from 'dayjs/esm';
22
22
  import utcEsm from 'dayjs/esm/plugin/utc';
23
- import { T as TraxService, D as DateRangePickerComponent, A as AddTaskComponent, E as ExportGalleryComponent, C as ChecklistPopupComponent, n as noWhitespaceValidator, r as rangeValidator, u as uniqueStringValidator, a as TraxpopupComponent, b as AutoTaskPopupComponent, c as TraxRunAIPopupComponent, d as CreateTaskComponent, e as TaskConfigureComponent } from './tango-app-ui-analyse-trax-tango-app-ui-analyse-trax-C4oOKSEZ.mjs';
23
+ import { T as TraxService, D as DateRangePickerComponent, A as AddTaskComponent, E as ExportGalleryComponent, C as ChecklistPopupComponent, n as noWhitespaceValidator, r as rangeValidator, u as uniqueStringValidator, a as TraxpopupComponent, b as AutoTaskPopupComponent, c as TraxRunAIPopupComponent, d as CreateTaskComponent, e as TaskConfigureComponent } from './tango-app-ui-analyse-trax-tango-app-ui-analyse-trax-Cuk5lK5L.mjs';
24
24
  import utc from 'dayjs/plugin/utc';
25
25
  import * as XLSX from 'xlsx';
26
26
  import timezone from 'dayjs/plugin/timezone';
@@ -2969,7 +2969,7 @@ const DISPUTE_REJECT_REASONS = [
2969
2969
  /** Export pages through the answers API this many submissions at a time, up to EXPORT_MAX. */
2970
2970
  /** userEmail filter value no real user has (see resolveScope). */
2971
2971
  const NO_MATCH_EMAIL = 'no-team-user@invalid';
2972
- const EXPORT_PAGE = 100;
2972
+ const EXPORT_PAGE$1 = 100;
2973
2973
  const EXPORT_MAX = 3000;
2974
2974
  const DEFAULTS = {
2975
2975
  type: 'Audit',
@@ -4960,16 +4960,16 @@ class AuditV2GalleryComponent {
4960
4960
  return;
4961
4961
  }
4962
4962
  const wanted = Math.min(this.total, EXPORT_MAX);
4963
- const pages = Math.ceil(wanted / EXPORT_PAGE);
4963
+ const pages = Math.ceil(wanted / EXPORT_PAGE$1);
4964
4964
  const records = [];
4965
4965
  const scopeName = [this.fName, this.fStart + ' to ' + (this.fEnd || this.fStart)].join(' - ');
4966
4966
  this.exporting = true;
4967
4967
  const fetch = (page) => {
4968
- this.answersRequest(page, EXPORT_PAGE).pipe(takeUntil$1(this.destroy$)).subscribe({
4968
+ this.answersRequest(page, EXPORT_PAGE$1).pipe(takeUntil$1(this.destroy$)).subscribe({
4969
4969
  next: (res) => {
4970
4970
  const batch = res?.code === 200 ? res.data?.checklistAnswers || [] : [];
4971
4971
  records.push(...batch);
4972
- if (batch.length === EXPORT_PAGE && page + 1 < pages) {
4972
+ if (batch.length === EXPORT_PAGE$1 && page + 1 < pages) {
4973
4973
  fetch(page + 1);
4974
4974
  return;
4975
4975
  }
@@ -6050,15 +6050,23 @@ class AuditV2ScheduleEditorComponent {
6050
6050
  ? n + ' of ' + total + ' rows selected'
6051
6051
  : total + (total === 1 ? ' row' : ' rows') + ' in this schedule';
6052
6052
  }
6053
+ /** Rows the header checkbox acts on: past (locked) rows cannot be selected. */
6054
+ get selectableRows() {
6055
+ return this.shownRows.filter(r => !this.isLocked(r));
6056
+ }
6053
6057
  get allRowsSelected() {
6054
- return this.shownRows.length > 0 && this.shownRows.every(r => r.selected);
6058
+ const rows = this.selectableRows;
6059
+ return rows.length > 0 && rows.every(r => r.selected);
6055
6060
  }
6056
6061
  toggleAllRows() {
6057
6062
  const on = !this.allRowsSelected;
6058
- this.shownRows.forEach(r => this.groupRows(r).forEach(m => m.selected = on));
6063
+ this.selectableRows.forEach(r => this.groupRows(r).forEach(m => m.selected = on));
6059
6064
  }
6060
- /** A shown row's checkbox selects every audit of its group. */
6065
+ /** A shown row's checkbox selects every audit of its group; a past (locked) row cannot be selected. */
6061
6066
  toggleRow(row) {
6067
+ if (this.isLocked(row)) {
6068
+ return;
6069
+ }
6062
6070
  const on = !row.selected;
6063
6071
  this.groupRows(row).forEach(m => m.selected = on);
6064
6072
  }
@@ -6639,11 +6647,11 @@ class AuditV2ScheduleEditorComponent {
6639
6647
  URL.revokeObjectURL(url);
6640
6648
  }
6641
6649
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuditV2ScheduleEditorComponent, deps: [{ token: TraxService }, { token: i3.ToastService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
6642
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AuditV2ScheduleEditorComponent, selector: "lib-audit-v2-schedule-editor", inputs: { clientId: "clientId", audits: "audits", preselect: "preselect", lockAudits: "lockAudits", backLabel: "backLabel", scheduleId: "scheduleId" }, outputs: { closed: "closed" }, host: { listeners: { "window:scroll": "onViewportChange()", "window:resize": "onViewportChange()" } }, viewQueries: [{ propertyName: "csvInput", first: true, predicate: ["csvInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<input #csvInput type=\"file\" accept=\".xlsx,.csv,text/csv\" class=\"se-hidden\" (change)=\"onCsvPicked($event)\">\n\n<!-- Editing opens on the Rows step, so its skeleton mirrors that screen. -->\n<ng-container *ngIf=\"loadingEdit\">\n <div class=\"se-titlebar\">\n <div class=\"se-titletext\">\n <span class=\"av2-sk se-sk-crumb\"></span>\n <span class=\"av2-sk av2-sk--title se-sk-name\"></span>\n </div>\n </div>\n\n <div class=\"se-card se-card--table\">\n <lib-audit-v2-shimmer></lib-audit-v2-shimmer>\n </div>\n</ng-container>\n\n<!-- ============ Create schedule ============ -->\n<ng-container *ngIf=\"step === 'create' && !loadingEdit\">\n <div class=\"se-backbar\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm se-back\" (click)=\"back()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\n {{ backLabel }}\n </button>\n <div class=\"se-crumb\"><a href=\"#\" (click)=\"back($event)\">Schedule</a> \u203A {{ scheduleId ? name || 'Schedule' : 'Create schedule' }}</div>\n </div>\n\n <div class=\"se-create\">\n <div class=\"se-card se-card--form\">\n <span class=\"se-badge\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M12 8v8M8 12h8\"></path></svg>\n </span>\n <div class=\"se-head\">\n <div class=\"se-title\">{{ scheduleId ? 'Edit schedule' : 'Create schedule' }}</div>\n <div class=\"se-sub\">{{ scheduleId ? 'Rename the schedule, or add rows from the template.' : (locked ? 'Name the schedule, then add rows for this audit.' : 'Name the schedule, then add rows.') }}</div>\n </div>\n\n <!-- Opened from an audit's Configure page: that audit is the schedule's audit, named once here\n instead of an audit picker card (QA: the card is not needed when the audit is already chosen). -->\n <div class=\"se-fixed-audit\" *ngIf=\"locked\">\n <span class=\"se-label\">{{ pickedAudits.length > 1 ? 'Audits' : 'Audit' }}</span>\n <span class=\"se-fixed-audit-name\">{{ lockedAuditNames || 'Loading audit\u2026' }}</span>\n </div>\n\n <label class=\"se-field\">\n <span class=\"se-label\">Schedule name</span>\n <input type=\"text\" class=\"se-input\" [(ngModel)]=\"name\" placeholder=\"e.g. February hygiene round\">\n </label>\n\n <!-- Every audit, with the ones picked on the previous page (Not scheduled) already ticked.\n Create only: Edit schedule keeps the schedule's audits and does not ask for them (QA).\n Hidden for now on both (showAuditPicker). -->\n <div class=\"se-field\" *ngIf=\"showAuditPicker && !locked && !scheduleId\">\n <div class=\"se-row\">\n <span class=\"se-label se-grow\">Audits to schedule</span>\n <span class=\"se-count\">{{ pickCount }}</span>\n </div>\n <label class=\"se-search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"pickQuery\" placeholder=\"Search audits\">\n <a class=\"se-clear\" *ngIf=\"pickQuery.trim()\" title=\"Clear search\" (click)=\"pickQuery = ''\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\n </a>\n </label>\n <div class=\"se-picklist\">\n <div class=\"se-pickrow se-pickrow--all\" (click)=\"toggleAllPicks()\">\n <span class=\"se-box\" [class.is-on]=\"allPicked\">\n <svg *ngIf=\"allPicked\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickall\">{{ allLabel }}</span>\n </div>\n <div class=\"se-empty-sm\" *ngIf=\"!pickables.length\">No audits match that search.</div>\n <div class=\"se-pickrow\" *ngFor=\"let a of pickables; trackBy: trackByAudit\" [class.is-on]=\"isPicked(a)\" (click)=\"togglePick(a)\">\n <span class=\"se-box\" [class.is-on]=\"isPicked(a)\">\n <svg *ngIf=\"isPicked(a)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickname\">\n <span class=\"se-ellipsis\">{{ a.name }}</span>\n <span class=\"se-meta\">{{ a.meta }}{{ a.questions ? ' \u00B7 ' + a.questions + ' questions' : '' }}</span>\n </span>\n </div>\n </div>\n </div>\n\n <ol class=\"se-steps\">\n <li>Use the template to schedule multiple users at once.</li>\n <li>Download the template here \u2014 <a href=\"#\" (click)=\"downloadTemplate($event)\">{{ templateLoading || templateWaiting ? 'Preparing\u2026' : 'Download template' }}</a></li>\n <li>Add your data, then upload it below.</li>\n </ol>\n\n <div class=\"se-actions\">\n <button type=\"button\" class=\"se-btn-lg se-btn-lg--primary\" [class.is-off]=\"!ready\" [attr.aria-disabled]=\"!ready\"\n [ngbTooltip]=\"notReadyReason\" [disableTooltip]=\"ready\" placement=\"top\" (click)=\"importCsv()\">Import from CSV</button>\n <span class=\"se-or\">or</span>\n <button type=\"button\" class=\"se-btn-lg se-btn-lg--ghost\" [class.is-off]=\"!ready\" [attr.aria-disabled]=\"!ready\"\n [ngbTooltip]=\"notReadyReason\" [disableTooltip]=\"ready\" placement=\"top\" (click)=\"addSingle()\">Add a single row</button>\n </div>\n </div>\n\n <!-- Hidden for now on both Create and Edit (showTemplatePreview). -->\n <div class=\"se-card se-card--side\" *ngIf=\"showTemplatePreview\">\n <div class=\"se-head\">\n <div class=\"se-side-title\">What the template expects</div>\n <div class=\"se-sub\">One row per user, store and date. These are the rows the downloaded template will hold for the selected\n {{ picks.length === 1 ? 'audit' : 'audits' }} \u2014 edit or add rows in the file, then import it.</div>\n </div>\n <div class=\"se-sample\">\n <div class=\"se-sample-row se-sample-row--head\">\n <span>Date</span><span>User email</span><span>Assign store</span><span>Assign audit</span>\n </div>\n <lib-audit-v2-shimmer *ngIf=\"templateLoading\" [rows]=\"3\"></lib-audit-v2-shimmer>\n <ng-container *ngIf=\"!templateLoading\">\n <!-- The selected audits' assigned stores / users: the same rows Download template writes. -->\n <div class=\"se-sample-row\" *ngFor=\"let r of previewRows\">\n <span [title]=\"r.date\">{{ r.date }}</span><span [title]=\"r.email\">{{ r.email }}</span>\n <span [title]=\"r.store\">{{ r.store }}</span><span [title]=\"r.audit\">{{ r.audit }}</span>\n </div>\n <div class=\"se-sample-more\" *ngIf=\"previewMore\">+ {{ previewMore }} more {{ previewMore === 1 ? 'row' : 'rows' }} in the file</div>\n <div class=\"se-sample-more\" *ngIf=\"!previewRows.length\">Pick an audit to see its template rows.</div>\n </ng-container>\n </div>\n <span class=\"se-note se-note--warn\" *ngIf=\"!templateLoading && unassignedAudits.length\">\n {{ unassignedAudits.join(', ') }} {{ unassignedAudits.length === 1 ? 'has' : 'have' }} no store assigned yet \u2014 fill in Date, User email\n and Store name for {{ unassignedAudits.length === 1 ? 'its row' : 'their rows' }}.</span>\n <span class=\"se-note\">Visit start and Visit end (HH:mm) are optional \u2014 leave them blank to use the store's open and close time (10:00 to 22:00 when the store has none).</span>\n <span class=\"se-note\">Rows with an unknown store, email or audit are reported before anything is saved. Draft audits\n are published when the schedule is published.</span>\n </div>\n </div>\n</ng-container>\n\n<!-- ============ Rows ============ -->\n<ng-container *ngIf=\"step === 'rows' && !loadingEdit\">\n <!-- Back + crumb on one line, as on the Create step; the name and actions below, left edges aligned.\n Edit has no \"Edit schedule\" step in the crumb (QA 9 Oct): it opens on, and stays on, the rows. -->\n <div class=\"se-backbar\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm se-back\" (click)=\"back()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\n {{ backLabel }}\n </button>\n <div class=\"se-crumb\">\n <a href=\"#\" (click)=\"back($event)\">Schedule</a> \u203A\n <ng-container *ngIf=\"!scheduleId\"><a href=\"#\" (click)=\"backToCreate($event)\">Create schedule</a> \u203A</ng-container>\n Rows\n </div>\n </div>\n\n <div class=\"se-titlebar\">\n <div class=\"se-titletext\">\n <div class=\"se-name\">{{ name.trim() || 'Untitled schedule' }}</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" [disabled]=\"saving\" (click)=\"saveDraft()\">Save as draft</button>\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--sm se-publish\" [class.is-off]=\"!canPublish\" (click)=\"publish()\">\n {{ saving ? 'Saving\u2026' : (published ? 'Save & publish' : 'Publish schedule') }}\n </button>\n </div>\n\n <div class=\"se-ready\" [class.is-ok]=\"readyOk\">\n <svg *ngIf=\"readyOk\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\"></path><path d=\"M8 12.5l2.7 2.7L16 9.5\"></path></svg>\n <svg *ngIf=\"!readyOk\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 4l9 16H3z\"></path><path d=\"M12 10v4M12 17h.01\"></path></svg>\n <span>{{ readyLabel }}</span>\n </div>\n\n <div class=\"se-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of metrics\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\">{{ m.value }}</div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"se-card se-card--table\">\n <div class=\"se-tablehead\">\n <div class=\"se-titletext\">\n <div class=\"se-side-title\">Schedule rows</div>\n <div class=\"se-sub\">Every row is one user, at one store, on one date.</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" (click)=\"addRow()\">Add row</button>\n <label class=\"se-search se-search--sm\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"rowQuery\" placeholder=\"Search rows\">\n </label>\n </div>\n\n <div class=\"se-scroll\" (scroll)=\"onViewportChange()\">\n <div class=\"se-grid se-grid--head\">\n <div class=\"se-center\" (click)=\"toggleAllRows()\" title=\"Select all rows\">\n <span class=\"se-box\" [class.is-on]=\"allRowsSelected\">\n <svg *ngIf=\"allRowsSelected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n </div>\n <div>Schedule date</div><div>User email</div><div>Assigned store</div><div>Audit assigned</div><div>Visit window</div><div></div>\n </div>\n\n <div class=\"se-grid se-grid--row\" *ngFor=\"let r of shownRows; trackBy: trackByRow\" [class.is-selected]=\"r.selected\">\n <div class=\"se-center\" (click)=\"toggleRow(r)\">\n <span class=\"se-box\" [class.is-on]=\"r.selected\">\n <svg *ngIf=\"r.selected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n </div>\n\n <input type=\"date\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'date')\" [attr.title]=\"cellError(r, 'date') || null\" [attr.min]=\"today\"\n [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.date\" (ngModelChange)=\"touch(r, 'date')\">\n\n <!-- User: search by name or email -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'userEmail')\">\n <input type=\"text\" class=\"se-cell se-cell--pick\" [class.is-bad]=\"cellError(r, 'userEmail')\" [attr.title]=\"cellError(r, 'userEmail') || null\"\n placeholder=\"Search user\" autocomplete=\"off\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.userEmail\" (ngModelChange)=\"onPickerInput(r, 'userEmail')\"\n (focus)=\"openPicker(r, 'userEmail', $event)\" (click)=\"openPicker(r, 'userEmail', $event)\" (keydown)=\"onPickerKey(r, 'userEmail', $event)\">\n <div class=\"se-menu\" *ngIf=\"isOpen(r, 'userEmail')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <div class=\"se-opt\" *ngFor=\"let u of userSuggestions(r); let i = index\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"u.email === r.userEmail.trim().toLowerCase()\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"pickUser(r, u, $event)\">\n <span class=\"se-opt-avatar\">{{ initials(u.name || u.email) }}</span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ u.name || u.email }}</span>\n <span class=\"se-opt-sub\">{{ u.email }}</span>\n </span>\n <svg class=\"se-opt-check\" *ngIf=\"u.email === r.userEmail.trim().toLowerCase()\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!userSuggestions(r).length\">{{ users.length ? 'No user matches \u201C' + r.userEmail + '\u201D' : 'Loading users\u2026' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"moreLabel(userSuggestions(r).length, userMatches(r).length, 'users')\">\n {{ moreLabel(userSuggestions(r).length, userMatches(r).length, 'users') }}\n </div>\n </div>\n </div>\n\n <!-- Store: search and show by store name (or city); the store code is never shown or asked for -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'storeId')\">\n <input type=\"text\" class=\"se-cell se-cell--pick\"\n [class.is-bad]=\"cellError(r, 'storeId')\" [attr.title]=\"cellError(r, 'storeId') || null\"\n placeholder=\"Search store\" autocomplete=\"off\" [disabled]=\"isLocked(r)\" [ngModel]=\"r.storeText\" (ngModelChange)=\"onStoreTyped(r, $event)\"\n (focus)=\"openPicker(r, 'storeId', $event)\" (click)=\"openPicker(r, 'storeId', $event)\" (keydown)=\"onPickerKey(r, 'storeId', $event)\">\n <div class=\"se-menu\" *ngIf=\"isOpen(r, 'storeId')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <div class=\"se-opt\" *ngFor=\"let s of storeSuggestions(r); let i = index\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"s.storeId === r.storeId.trim()\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"pickStore(r, s, $event)\">\n <span class=\"se-opt-icon\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 9l1.5-5h15L21 9\"></path><path d=\"M4 9v11h16V9\"></path><path d=\"M9 20v-6h6v6\"></path></svg>\n </span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ s.storeName || s.storeId }}</span>\n <span class=\"se-opt-sub\" *ngIf=\"s.city\">{{ s.city }}</span>\n </span>\n <svg class=\"se-opt-check\" *ngIf=\"s.storeId === r.storeId.trim()\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!storeSuggestions(r).length\">{{ stores.length ? 'No store matches \u201C' + r.storeText + '\u201D' : 'Loading stores\u2026' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"moreLabel(storeSuggestions(r).length, storeMatches(r).length, 'stores')\">\n {{ moreLabel(storeSuggestions(r).length, storeMatches(r).length, 'stores') }}\n </div>\n </div>\n </div>\n\n <!-- Audit assigned: multi-select with search over the published audits (rowAuditOptions). Ticking another audit\n adds a row for it with the same date, user, store and window; unticking removes that row. No column when\n the schedule has one fixed audit. -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'checkListId')\">\n <button type=\"button\" class=\"se-cell se-select\" [class.is-bad]=\"cellError(r, 'checkListId')\" [attr.title]=\"cellError(r, 'checkListId') || null\"\n [disabled]=\"isLocked(r)\" (click)=\"openPicker(r, 'checkListId', $event)\" (keydown)=\"onPickerKey(r, 'checkListId', $event)\">\n <span class=\"se-ellipsis\" [class.se-placeholder]=\"!groupAuditFirst(r)\" [attr.title]=\"groupAuditLabel(r) || null\">{{ groupAuditFirst(r) || 'Select audits' }}</span>\n <span class=\"se-more\" *ngIf=\"groupAuditMore(r)\" [attr.title]=\"groupAuditLabel(r)\">+{{ groupAuditMore(r) }}</span>\n <svg class=\"se-chev\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\n </button>\n <div class=\"se-menu se-menu--multi\" *ngIf=\"isOpen(r, 'checkListId')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <label class=\"se-menu-search\" (mousedown)=\"$event.stopPropagation()\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" placeholder=\"Search audits\" autocomplete=\"off\" [(ngModel)]=\"auditQuery\" (ngModelChange)=\"activeIndex = 0\"\n (keydown)=\"onPickerKey(r, 'checkListId', $event)\">\n </label>\n <div class=\"se-opt\" *ngFor=\"let a of auditMatches(); let i = index; trackBy: trackByAudit\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"auditTicked(r, a)\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"toggleAudit(r, a, $event)\">\n <span class=\"se-box\" [class.is-on]=\"auditTicked(r, a)\">\n <svg *ngIf=\"auditTicked(r, a)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ a.name }}</span>\n <span class=\"se-opt-sub\" *ngIf=\"a.questions\">{{ a.questions }} {{ a.questions === 1 ? 'question' : 'questions' }}</span>\n </span>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!auditMatches().length\">{{ rowAuditOptions.length ? 'No audit matches \u201C' + auditQuery + '\u201D' : 'No published audits yet' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"auditTickCount(r) > 1\">{{ auditTickCount(r) }} audits on this row \u00B7 same user, store, date and window</div>\n </div>\n </div>\n\n <div class=\"se-window\" [attr.title]=\"cellError(r, 'window') || null\">\n <input type=\"time\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'window')\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.start\" (ngModelChange)=\"touch(r, 'window')\">\n <span class=\"se-dash\">\u2013</span>\n <input type=\"time\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'window')\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.end\" (ngModelChange)=\"touch(r, 'window')\">\n </div>\n\n <div class=\"se-center\">\n <span class=\"se-lock\" *ngIf=\"isLocked(r)\" title=\"Past visit: already raised, so it cannot be edited or deleted\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\"></rect><path d=\"M8 11V7a4 4 0 0 1 8 0v4\"></path></svg>\n </span>\n <a class=\"se-del\" *ngIf=\"!isLocked(r)\" title=\"Delete row\" (click)=\"deleteRow(r)\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 7h16\"></path><path d=\"M7 7l1 13h8l1-13M9 7V4h6v3\"></path></svg>\n </a>\n </div>\n\n <!-- Why the row is red, in words. -->\n <ng-container *ngIf=\"rowMessages(r) as msgs\">\n <div class=\"se-rowerr\" *ngIf=\"msgs.length\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\n <span>{{ msgs.join(' \u00B7 ') }}</span>\n <a class=\"se-invite-link\" *ngIf=\"inviteable(r)\" (click)=\"openInvite(newUserEmails(groupRows(r)))\">Invite user</a>\n </div>\n </ng-container>\n <!-- Hints: allowed (Publish is not blocked), e.g. the same visit in another schedule. -->\n <ng-container *ngIf=\"rowHints(r) as hints\">\n <div class=\"se-rowerr se-rowhint\" *ngIf=\"hints.length\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\n <span>{{ hints.join(' \u00B7 ') }}</span>\n </div>\n </ng-container>\n </div>\n\n <div *ngIf=\"!shownRows.length\" class=\"av2-empty\">\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\n <div class=\"av2-empty-text\">\n <div class=\"av2-empty-title\">No data found</div>\n <div class=\"av2-empty-sub\">{{ rows.length ? 'No rows match this search.' : 'No rows yet. Add a row or import the template.' }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"se-foot\">\n <!-- Row count + visit-window hint removed (user, 11 Oct); the count shows only while rows are selected. -->\n <span class=\"se-foot-text\" *ngIf=\"selectedCount\">{{ selectionLabel }}</span>\n <span class=\"se-foot-actions\">\n <button type=\"button\" class=\"se-bulk\" [class.is-off]=\"!selectedCount\" (click)=\"duplicateSelected()\">Duplicate</button>\n <button type=\"button\" class=\"se-bulk se-bulk--danger\" [class.is-off]=\"!selectedCount\" (click)=\"deleteSelected()\">Delete</button>\n </span>\n </div>\n </div>\n</ng-container>\n\n<!-- New User found (as the v1 checklist upload): emails with no user yet, after an import or from a row's Invite user. -->\n<ng-container *ngIf=\"inviteOpen\">\n <div class=\"se-inv-backdrop\" (click)=\"closeInvite()\"></div>\n <div class=\"se-inv\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"se-inv-title\">\n <span class=\"se-inv-icon\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.3 3.9L1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z\"></path><path d=\"M12 9v4M12 17h.01\"></path></svg>\n </span>\n <div class=\"se-inv-title\" id=\"se-inv-title\">{{ inviteEmails.length === 1 ? 'New user found' : 'New users found' }}</div>\n <div class=\"se-inv-text\">\n {{ inviteEmails.length === 1 ? 'This email is not a user yet.' : 'These emails are not users yet.' }}\n Invite them to add them as users of this client, or add them in User Management under the Manage menu.\n </div>\n\n <div class=\"se-inv-list\">\n <div class=\"se-pickrow se-pickrow--all\" *ngIf=\"inviteEmails.length > 1\" (click)=\"toggleAllInvite()\">\n <span class=\"se-box\" [class.is-on]=\"allInvitePicked\">\n <svg *ngIf=\"allInvitePicked\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickall\">Select all ({{ inviteEmails.length }})</span>\n </div>\n <div class=\"se-pickrow\" *ngFor=\"let e of inviteEmails\" [class.is-on]=\"invitePicked.has(e)\" (click)=\"toggleInvite(e)\">\n <span class=\"se-box\" [class.is-on]=\"invitePicked.has(e)\">\n <svg *ngIf=\"invitePicked.has(e)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickname\"><span class=\"se-ellipsis\">{{ e }}</span></span>\n </div>\n </div>\n\n <div class=\"se-inv-foot\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" [disabled]=\"inviting\" (click)=\"closeInvite()\">Skip</button>\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--sm\" [disabled]=\"inviting || !invitePicked.size\" (click)=\"inviteSelected()\">\n {{ inviting ? 'Inviting\u2026' : 'Invite selected' + (invitePicked.size ? ' (' + invitePicked.size + ')' : '') }}\n </button>\n </div>\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}:host{display:flex;flex-direction:column;gap:20px}.se-hidden{display:none}.se-grow{flex:1;min-width:0}.se-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-sk-crumb{width:180px;height:12px;margin:4px 0}.se-sk-name{height:22px;margin:4px 0}.se-crumb{font-size:13px;line-height:20px;color:#667085}.se-crumb a{font-weight:600;color:#00a3ff;text-decoration:none;cursor:pointer}.se-backbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.se-back{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.se-fixed-audit{display:flex;flex-direction:column;gap:4px;padding:12px 14px;border-radius:8px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0}.se-fixed-audit-name{font-size:14px;line-height:20px;font-weight:600;color:#101828}.se-create{display:flex;flex-wrap:wrap;gap:20px;max-width:1180px}.se-card{min-width:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;display:flex;flex-direction:column}.se-card--form{flex:1 1 420px;padding:28px;gap:20px}.se-card--side{flex:1 1 380px;padding:28px;gap:16px}.se-badge{width:44px;height:44px;border-radius:9999px;background:#eaf8ff;color:#00a3ff;display:flex;align-items:center;justify-content:center}.se-head{display:flex;flex-direction:column;gap:4px}.se-title{font-size:24px;line-height:32px;font-weight:700;color:#101828}.se-side-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.se-sub{font-size:14px;line-height:20px;color:#667085}.se-field{display:flex;flex-direction:column;gap:6px;margin:0}.se-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.se-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.se-count{font-size:12px;line-height:18px;color:#667085;white-space:nowrap}.se-input{height:44px;padding:0 14px;border:none;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:14px;color:#101828;outline:none}.se-input:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #ccedff}.se-search{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;margin:0;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;color:#667085}.se-search input{flex:1;min-width:0;height:38px;border:none;outline:none;background:transparent;font-size:14px;font-family:inherit;color:#101828}.se-search--sm{flex:0 1 240px;min-width:180px;height:36px}.se-search--sm input{height:34px;font-size:13px}.se-clear{display:flex;cursor:pointer;color:#98a2b3}.se-picklist{display:flex;flex-direction:column;gap:2px;max-height:220px;overflow-y:auto;padding:8px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd}.se-pickrow{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer}.se-pickrow:hover{background:#f9fafb}.se-pickrow.is-on{background:#f5fbff}.se-pickrow--all{border-bottom:1px solid #F2F4F7}.se-pickrow--fixed{cursor:default;background:#f9fafb}.se-pickrow--fixed:hover{background:#f9fafb}.se-pickall{font-size:14px;line-height:20px;font-weight:600;color:#344054}.se-pickname{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.se-pickname .se-ellipsis{font-size:14px;line-height:20px;font-weight:500;color:#101828}.se-meta{font-size:12px;line-height:18px;color:#667085}.se-empty-sm{padding:14px 10px;font-size:13px;line-height:20px;color:#667085}.se-box{width:16px;height:16px;flex-shrink:0;border-radius:4px;display:flex;align-items:center;justify-content:center;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#00a3ff}.se-box.is-on{background:#eaf8ff;box-shadow:inset 0 0 0 1px #00a3ff}.se-steps{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:8px;font-size:14px;line-height:20px;color:#344054}.se-steps a{font-weight:600;color:#00a3ff;cursor:pointer}.se-actions{display:flex;flex-direction:column;gap:12px}.se-or{text-align:center;font-size:14px;color:#98a2b3}.se-btn-lg{height:44px;border:none;border-radius:8px;font-family:inherit;font-size:15px;font-weight:600;cursor:pointer}.se-btn-lg--primary{background:#00a3ff;color:#fff}.se-btn-lg--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054}.se-btn-lg--ghost:hover{background:#f9fafb}.se-btn-lg.is-off{cursor:not-allowed}.se-btn-lg--primary.is-off{background:#f2f4f7;color:#98a2b3}.se-btn-lg--ghost.is-off{color:#98a2b3}.se-btn-lg--ghost.is-off:hover{background:#fff}.se-sample{display:flex;flex-direction:column;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;overflow:hidden}.se-sample-row{display:grid;grid-template-columns:.8fr 1.4fr 1fr 1.3fr;gap:8px;padding:10px 12px;border-top:1px solid #EAECF0;font-size:12px;line-height:18px;color:#344054}.se-sample-row span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-sample-row--head{border-top:none;background:#f9fafb;font-weight:600;color:#475467}.se-note{font-size:12px;line-height:18px;color:#667085;text-wrap:pretty}.se-note--warn{color:#b54708}.se-sample-more{padding:10px 12px;border-top:1px solid #EAECF0;font-size:12px;line-height:18px;color:#667085}.se-titlebar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.se-backbar+.se-titlebar{margin-top:-8px}.se-titletext{flex:1 1 240px;min-width:0;display:flex;flex-direction:column;gap:2px}.se-name{font-size:20px;line-height:30px;font-weight:700;color:#101828}.se-publish.is-off{background:#f2f4f7;color:#98a2b3;cursor:not-allowed;box-shadow:none}.se-ready{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:12px 20px;border-radius:8px;background:#fffcf5;box-shadow:inset 0 0 0 1px #fedf89;color:#b54708;font-size:14px;line-height:20px;font-weight:600}.se-ready svg{flex-shrink:0}.se-ready span{flex:1;min-width:0}.se-ready.is-ok{background:#f6fef9;box-shadow:inset 0 0 0 1px #a6f4c5;color:#027a48}.se-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.se-tablehead{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:20px 24px}.se-scroll{overflow-x:auto}.se-grid{min-width:1120px;display:grid;grid-template-columns:36px 1fr 1.5fr 1fr 1.5fr 1.6fr 40px;gap:12px;align-items:center;padding:10px 24px}.se-grid--head{background:#f9fafb;border-top:1px solid #EAECF0;border-bottom:1px solid #EAECF0;font-size:12px;font-weight:600;color:#475467}.se-grid--row{border-bottom:1px solid #F2F4F7}.se-grid--row.is-selected{background:#f5fbff}.se-center{display:flex;justify-content:center;cursor:pointer}.se-rowerr{grid-column:2/-1;margin-top:-4px;display:flex;align-items:flex-start;gap:6px;font-size:12px;line-height:18px;color:#d92d20}.se-rowerr svg{flex-shrink:0;margin-top:2px}.se-rowhint{color:#667085}.se-invite-link{flex-shrink:0;font-weight:600;color:#00a3ff;cursor:pointer;text-decoration:none}.se-invite-link:hover{text-decoration:underline}.se-inv-backdrop{position:fixed;inset:0;background:#34405499;z-index:1050}.se-inv{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:480px;max-width:calc(100vw - 32px);max-height:90vh;padding:24px;border-radius:8px;background:#fff;box-shadow:0 20px 40px #10182833;z-index:1051;display:flex;flex-direction:column;gap:12px}.se-inv-icon{width:48px;height:48px;border-radius:9999px;background:#fef0c7;box-shadow:0 0 0 8px #fffaeb;color:#dc6803;display:flex;align-items:center;justify-content:center;margin:4px 0 8px 4px}.se-inv-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.se-inv-text{font-size:14px;line-height:20px;color:#475467}.se-inv-list{max-height:260px;overflow-y:auto;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;padding:4px}.se-inv-foot{display:flex;justify-content:flex-end;gap:12px;margin-top:8px}.se-cell{width:100%;height:36px;min-width:0;padding:0 10px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;color:#101828;outline:none}.se-cell:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 3px #ccedff}.se-cell.is-bad{box-shadow:inset 0 0 0 1px #fda29b}.se-select{display:flex;align-items:center;justify-content:space-between;gap:6px;text-align:left;cursor:pointer}.se-select svg{flex-shrink:0;color:#667085}.se-placeholder{color:#98a2b3}.se-pick{position:relative;min-width:0}.se-cell--pick{padding-right:10px;text-overflow:ellipsis}.se-cell--tagged{padding-right:88px}.se-pick.is-open .se-cell{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 3px #ccedff}.se-pick.is-open .se-chev{transform:rotate(180deg)}.se-chev{transition:transform .15s ease}.se-tag{position:absolute;top:50%;right:8px;transform:translateY(-50%);max-width:76px;padding:2px 8px;border-radius:9999px;background:#f2f4f7;color:#344054;font-size:11px;line-height:16px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none}.se-menu{position:fixed;z-index:1060;width:max-content;max-width:380px;max-height:288px;overflow-y:auto;padding:6px;border-radius:10px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.se-opt{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer}.se-opt.is-active{background:#f9fafb}.se-opt.is-on{background:#f5fbff}.se-opt.is-on.is-active{background:#eaf8ff}.se-opt-avatar{width:28px;height:28px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.se-opt-icon{width:28px;height:28px;flex-shrink:0;border-radius:8px;background:#f2f4f7;color:#475467;display:flex;align-items:center;justify-content:center}.se-opt-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.se-opt-main{font-size:13px;line-height:18px;font-weight:500;color:#101828;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-opt-sub{font-size:12px;line-height:16px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-opt-check{flex-shrink:0;color:#00a3ff}.se-menu-empty{padding:12px 10px;font-size:13px;color:#667085}.se-menu--multi{min-width:260px}.se-menu-search{position:sticky;top:-6px;z-index:1;margin:-6px -6px 4px;padding:8px 10px;display:flex;align-items:center;gap:8px;background:#fff;border-bottom:1px solid #F2F4F7;color:#667085;cursor:text}.se-menu-search input{flex:1;min-width:0;border:0;outline:none;background:transparent;font-size:13px;line-height:18px;color:#101828}.se-menu-note{margin:4px -6px -6px;padding:8px 16px;border-top:1px solid #F2F4F7;background:#fcfcfd;font-size:12px;line-height:16px;color:#667085;position:sticky;bottom:-6px}.se-window{display:flex;align-items:center;gap:6px;min-width:0}.se-window .se-cell{flex:1;padding:0 6px}.se-dash{color:#98a2b3;font-size:13px}.se-lock{width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:#98a2b3;cursor:help}.se-del{width:28px;height:28px;border-radius:6px;display:flex;align-items:center;justify-content:center;color:#667085;cursor:pointer}.se-del:hover{background:#fffbfa;color:#d92d20}.se-empty{padding:36px 24px;text-align:center;font-size:13px;color:#667085}.se-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:16px 24px}.se-foot-text{display:flex;flex-direction:column;gap:2px;font-size:14px;line-height:20px;color:#667085}.se-foot-actions{display:flex;align-items:center;gap:8px;margin-left:auto}.se-bulk{height:36px;padding:0 14px;border:none;border-radius:8px;background:transparent;font-family:inherit;font-size:13px;font-weight:600;color:#344054;cursor:pointer}.se-bulk:hover{background:#f9fafb}.se-bulk--danger{color:#d92d20}.se-bulk--danger:hover{background:#fffbfa}.se-bulk.is-off{color:#98a2b3;cursor:not-allowed}.se-bulk.is-off:hover{background:transparent}.se-select .se-ellipsis{flex:0 1 auto;min-width:0}.se-select .se-chev{margin-left:auto}.se-more{flex-shrink:0;min-width:24px;height:20px;padding:0 7px;border-radius:9999px;background:#f2f4f7;color:#344054;font-size:12px;font-weight:600;line-height:20px;text-align:center}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: AuditV2ShimmerComponent, selector: "lib-audit-v2-shimmer", inputs: ["rows"] }] });
6650
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AuditV2ScheduleEditorComponent, selector: "lib-audit-v2-schedule-editor", inputs: { clientId: "clientId", audits: "audits", preselect: "preselect", lockAudits: "lockAudits", backLabel: "backLabel", scheduleId: "scheduleId" }, outputs: { closed: "closed" }, host: { listeners: { "window:scroll": "onViewportChange()", "window:resize": "onViewportChange()" } }, viewQueries: [{ propertyName: "csvInput", first: true, predicate: ["csvInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<input #csvInput type=\"file\" accept=\".xlsx,.csv,text/csv\" class=\"se-hidden\" (change)=\"onCsvPicked($event)\">\n\n<!-- Editing opens on the Rows step, so its skeleton mirrors that screen. -->\n<ng-container *ngIf=\"loadingEdit\">\n <div class=\"se-titlebar\">\n <div class=\"se-titletext\">\n <span class=\"av2-sk se-sk-crumb\"></span>\n <span class=\"av2-sk av2-sk--title se-sk-name\"></span>\n </div>\n </div>\n\n <div class=\"se-card se-card--table\">\n <lib-audit-v2-shimmer></lib-audit-v2-shimmer>\n </div>\n</ng-container>\n\n<!-- ============ Create schedule ============ -->\n<ng-container *ngIf=\"step === 'create' && !loadingEdit\">\n <div class=\"se-backbar\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm se-back\" (click)=\"back()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\n {{ backLabel }}\n </button>\n <div class=\"se-crumb\"><a href=\"#\" (click)=\"back($event)\">Schedule</a> \u203A {{ scheduleId ? name || 'Schedule' : 'Create schedule' }}</div>\n </div>\n\n <div class=\"se-create\">\n <div class=\"se-card se-card--form\">\n <span class=\"se-badge\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M12 8v8M8 12h8\"></path></svg>\n </span>\n <div class=\"se-head\">\n <div class=\"se-title\">{{ scheduleId ? 'Edit schedule' : 'Create schedule' }}</div>\n <div class=\"se-sub\">{{ scheduleId ? 'Rename the schedule, or add rows from the template.' : (locked ? 'Name the schedule, then add rows for this audit.' : 'Name the schedule, then add rows.') }}</div>\n </div>\n\n <!-- Opened from an audit's Configure page: that audit is the schedule's audit, named once here\n instead of an audit picker card (QA: the card is not needed when the audit is already chosen). -->\n <div class=\"se-fixed-audit\" *ngIf=\"locked\">\n <span class=\"se-label\">{{ pickedAudits.length > 1 ? 'Audits' : 'Audit' }}</span>\n <span class=\"se-fixed-audit-name\">{{ lockedAuditNames || 'Loading audit\u2026' }}</span>\n </div>\n\n <label class=\"se-field\">\n <span class=\"se-label\">Schedule name</span>\n <input type=\"text\" class=\"se-input\" [(ngModel)]=\"name\" placeholder=\"e.g. February hygiene round\">\n </label>\n\n <!-- Every audit, with the ones picked on the previous page (Not scheduled) already ticked.\n Create only: Edit schedule keeps the schedule's audits and does not ask for them (QA).\n Hidden for now on both (showAuditPicker). -->\n <div class=\"se-field\" *ngIf=\"showAuditPicker && !locked && !scheduleId\">\n <div class=\"se-row\">\n <span class=\"se-label se-grow\">Audits to schedule</span>\n <span class=\"se-count\">{{ pickCount }}</span>\n </div>\n <label class=\"se-search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"pickQuery\" placeholder=\"Search audits\">\n <a class=\"se-clear\" *ngIf=\"pickQuery.trim()\" title=\"Clear search\" (click)=\"pickQuery = ''\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\n </a>\n </label>\n <div class=\"se-picklist\">\n <div class=\"se-pickrow se-pickrow--all\" (click)=\"toggleAllPicks()\">\n <span class=\"se-box\" [class.is-on]=\"allPicked\">\n <svg *ngIf=\"allPicked\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickall\">{{ allLabel }}</span>\n </div>\n <div class=\"se-empty-sm\" *ngIf=\"!pickables.length\">No audits match that search.</div>\n <div class=\"se-pickrow\" *ngFor=\"let a of pickables; trackBy: trackByAudit\" [class.is-on]=\"isPicked(a)\" (click)=\"togglePick(a)\">\n <span class=\"se-box\" [class.is-on]=\"isPicked(a)\">\n <svg *ngIf=\"isPicked(a)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickname\">\n <span class=\"se-ellipsis\">{{ a.name }}</span>\n <span class=\"se-meta\">{{ a.meta }}{{ a.questions ? ' \u00B7 ' + a.questions + ' questions' : '' }}</span>\n </span>\n </div>\n </div>\n </div>\n\n <ol class=\"se-steps\">\n <li>Use the template to schedule multiple users at once.</li>\n <li>Download the template here \u2014 <a href=\"#\" (click)=\"downloadTemplate($event)\">{{ templateLoading || templateWaiting ? 'Preparing\u2026' : 'Download template' }}</a></li>\n <li>Add your data, then upload it below.</li>\n </ol>\n\n <div class=\"se-actions\">\n <button type=\"button\" class=\"se-btn-lg se-btn-lg--primary\" [class.is-off]=\"!ready\" [attr.aria-disabled]=\"!ready\"\n [ngbTooltip]=\"notReadyReason\" [disableTooltip]=\"ready\" placement=\"top\" (click)=\"importCsv()\">Import from CSV</button>\n <span class=\"se-or\">or</span>\n <button type=\"button\" class=\"se-btn-lg se-btn-lg--ghost\" [class.is-off]=\"!ready\" [attr.aria-disabled]=\"!ready\"\n [ngbTooltip]=\"notReadyReason\" [disableTooltip]=\"ready\" placement=\"top\" (click)=\"addSingle()\">Add a single row</button>\n </div>\n </div>\n\n <!-- Hidden for now on both Create and Edit (showTemplatePreview). -->\n <div class=\"se-card se-card--side\" *ngIf=\"showTemplatePreview\">\n <div class=\"se-head\">\n <div class=\"se-side-title\">What the template expects</div>\n <div class=\"se-sub\">One row per user, store and date. These are the rows the downloaded template will hold for the selected\n {{ picks.length === 1 ? 'audit' : 'audits' }} \u2014 edit or add rows in the file, then import it.</div>\n </div>\n <div class=\"se-sample\">\n <div class=\"se-sample-row se-sample-row--head\">\n <span>Date</span><span>User email</span><span>Assign store</span><span>Assign audit</span>\n </div>\n <lib-audit-v2-shimmer *ngIf=\"templateLoading\" [rows]=\"3\"></lib-audit-v2-shimmer>\n <ng-container *ngIf=\"!templateLoading\">\n <!-- The selected audits' assigned stores / users: the same rows Download template writes. -->\n <div class=\"se-sample-row\" *ngFor=\"let r of previewRows\">\n <span [title]=\"r.date\">{{ r.date }}</span><span [title]=\"r.email\">{{ r.email }}</span>\n <span [title]=\"r.store\">{{ r.store }}</span><span [title]=\"r.audit\">{{ r.audit }}</span>\n </div>\n <div class=\"se-sample-more\" *ngIf=\"previewMore\">+ {{ previewMore }} more {{ previewMore === 1 ? 'row' : 'rows' }} in the file</div>\n <div class=\"se-sample-more\" *ngIf=\"!previewRows.length\">Pick an audit to see its template rows.</div>\n </ng-container>\n </div>\n <span class=\"se-note se-note--warn\" *ngIf=\"!templateLoading && unassignedAudits.length\">\n {{ unassignedAudits.join(', ') }} {{ unassignedAudits.length === 1 ? 'has' : 'have' }} no store assigned yet \u2014 fill in Date, User email\n and Store name for {{ unassignedAudits.length === 1 ? 'its row' : 'their rows' }}.</span>\n <span class=\"se-note\">Visit start and Visit end (HH:mm) are optional \u2014 leave them blank to use the store's open and close time (10:00 to 22:00 when the store has none).</span>\n <span class=\"se-note\">Rows with an unknown store, email or audit are reported before anything is saved. Draft audits\n are published when the schedule is published.</span>\n </div>\n </div>\n</ng-container>\n\n<!-- ============ Rows ============ -->\n<ng-container *ngIf=\"step === 'rows' && !loadingEdit\">\n <!-- Back + crumb on one line, as on the Create step; the name and actions below, left edges aligned.\n Edit has no \"Edit schedule\" step in the crumb (QA 9 Oct): it opens on, and stays on, the rows. -->\n <div class=\"se-backbar\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm se-back\" (click)=\"back()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\n {{ backLabel }}\n </button>\n <div class=\"se-crumb\">\n <a href=\"#\" (click)=\"back($event)\">Schedule</a> \u203A\n <ng-container *ngIf=\"!scheduleId\"><a href=\"#\" (click)=\"backToCreate($event)\">Create schedule</a> \u203A</ng-container>\n Rows\n </div>\n </div>\n\n <div class=\"se-titlebar\">\n <div class=\"se-titletext\">\n <div class=\"se-name\">{{ name.trim() || 'Untitled schedule' }}</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" [disabled]=\"saving\" (click)=\"saveDraft()\">Save as draft</button>\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--sm se-publish\" [class.is-off]=\"!canPublish\" (click)=\"publish()\">\n {{ saving ? 'Saving\u2026' : (published ? 'Save & publish' : 'Publish schedule') }}\n </button>\n </div>\n\n <div class=\"se-ready\" [class.is-ok]=\"readyOk\">\n <svg *ngIf=\"readyOk\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\"></path><path d=\"M8 12.5l2.7 2.7L16 9.5\"></path></svg>\n <svg *ngIf=\"!readyOk\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 4l9 16H3z\"></path><path d=\"M12 10v4M12 17h.01\"></path></svg>\n <span>{{ readyLabel }}</span>\n </div>\n\n <div class=\"se-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of metrics\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\">{{ m.value }}</div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"se-card se-card--table\">\n <div class=\"se-tablehead\">\n <div class=\"se-titletext\">\n <div class=\"se-side-title\">Schedule rows</div>\n <div class=\"se-sub\">Every row is one user, at one store, on one date.</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" (click)=\"addRow()\">Add row</button>\n <label class=\"se-search se-search--sm\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"rowQuery\" placeholder=\"Search rows\">\n </label>\n </div>\n\n <div class=\"se-scroll\" (scroll)=\"onViewportChange()\">\n <div class=\"se-grid se-grid--head\">\n <div class=\"se-center\" (click)=\"toggleAllRows()\" title=\"Select all rows\">\n <span class=\"se-box\" [class.is-on]=\"allRowsSelected\">\n <svg *ngIf=\"allRowsSelected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n </div>\n <div>Schedule date</div><div>User email</div><div>Assigned store</div><div>Audit assigned</div><div>Visit window</div><div></div>\n </div>\n\n <div class=\"se-grid se-grid--row\" *ngFor=\"let r of shownRows; trackBy: trackByRow\" [class.is-selected]=\"r.selected\" [class.is-locked]=\"isLocked(r)\">\n <div class=\"se-center\" [class.is-off]=\"isLocked(r)\" [attr.title]=\"isLocked(r) ? 'Past visit: already raised, so it cannot be selected' : null\" (click)=\"toggleRow(r)\">\n <span class=\"se-box\" [class.is-on]=\"r.selected\">\n <svg *ngIf=\"r.selected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n </div>\n\n <input type=\"date\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'date')\" [attr.title]=\"cellError(r, 'date') || null\" [attr.min]=\"today\"\n [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.date\" (ngModelChange)=\"touch(r, 'date')\">\n\n <!-- User: search by name or email -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'userEmail')\">\n <input type=\"text\" class=\"se-cell se-cell--pick\" [class.is-bad]=\"cellError(r, 'userEmail')\" [attr.title]=\"cellError(r, 'userEmail') || null\"\n placeholder=\"Search user\" autocomplete=\"off\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.userEmail\" (ngModelChange)=\"onPickerInput(r, 'userEmail')\"\n (focus)=\"openPicker(r, 'userEmail', $event)\" (click)=\"openPicker(r, 'userEmail', $event)\" (keydown)=\"onPickerKey(r, 'userEmail', $event)\">\n <div class=\"se-menu\" *ngIf=\"isOpen(r, 'userEmail')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <div class=\"se-opt\" *ngFor=\"let u of userSuggestions(r); let i = index\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"u.email === r.userEmail.trim().toLowerCase()\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"pickUser(r, u, $event)\">\n <span class=\"se-opt-avatar\">{{ initials(u.name || u.email) }}</span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ u.name || u.email }}</span>\n <span class=\"se-opt-sub\">{{ u.email }}</span>\n </span>\n <svg class=\"se-opt-check\" *ngIf=\"u.email === r.userEmail.trim().toLowerCase()\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!userSuggestions(r).length\">{{ users.length ? 'No user matches \u201C' + r.userEmail + '\u201D' : 'Loading users\u2026' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"moreLabel(userSuggestions(r).length, userMatches(r).length, 'users')\">\n {{ moreLabel(userSuggestions(r).length, userMatches(r).length, 'users') }}\n </div>\n </div>\n </div>\n\n <!-- Store: search and show by store name (or city); the store code is never shown or asked for -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'storeId')\">\n <input type=\"text\" class=\"se-cell se-cell--pick\"\n [class.is-bad]=\"cellError(r, 'storeId')\" [attr.title]=\"cellError(r, 'storeId') || null\"\n placeholder=\"Search store\" autocomplete=\"off\" [disabled]=\"isLocked(r)\" [ngModel]=\"r.storeText\" (ngModelChange)=\"onStoreTyped(r, $event)\"\n (focus)=\"openPicker(r, 'storeId', $event)\" (click)=\"openPicker(r, 'storeId', $event)\" (keydown)=\"onPickerKey(r, 'storeId', $event)\">\n <div class=\"se-menu\" *ngIf=\"isOpen(r, 'storeId')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <div class=\"se-opt\" *ngFor=\"let s of storeSuggestions(r); let i = index\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"s.storeId === r.storeId.trim()\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"pickStore(r, s, $event)\">\n <span class=\"se-opt-icon\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 9l1.5-5h15L21 9\"></path><path d=\"M4 9v11h16V9\"></path><path d=\"M9 20v-6h6v6\"></path></svg>\n </span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ s.storeName || s.storeId }}</span>\n <span class=\"se-opt-sub\" *ngIf=\"s.city\">{{ s.city }}</span>\n </span>\n <svg class=\"se-opt-check\" *ngIf=\"s.storeId === r.storeId.trim()\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!storeSuggestions(r).length\">{{ stores.length ? 'No store matches \u201C' + r.storeText + '\u201D' : 'Loading stores\u2026' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"moreLabel(storeSuggestions(r).length, storeMatches(r).length, 'stores')\">\n {{ moreLabel(storeSuggestions(r).length, storeMatches(r).length, 'stores') }}\n </div>\n </div>\n </div>\n\n <!-- Audit assigned: multi-select with search over the published audits (rowAuditOptions). Ticking another audit\n adds a row for it with the same date, user, store and window; unticking removes that row. No column when\n the schedule has one fixed audit. -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'checkListId')\">\n <button type=\"button\" class=\"se-cell se-select\" [class.is-bad]=\"cellError(r, 'checkListId')\" [attr.title]=\"cellError(r, 'checkListId') || null\"\n [disabled]=\"isLocked(r)\" (click)=\"openPicker(r, 'checkListId', $event)\" (keydown)=\"onPickerKey(r, 'checkListId', $event)\">\n <span class=\"se-ellipsis\" [class.se-placeholder]=\"!groupAuditFirst(r)\" [attr.title]=\"groupAuditLabel(r) || null\">{{ groupAuditFirst(r) || 'Select audits' }}</span>\n <span class=\"se-more\" *ngIf=\"groupAuditMore(r)\" [attr.title]=\"groupAuditLabel(r)\">+{{ groupAuditMore(r) }}</span>\n <svg class=\"se-chev\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\n </button>\n <div class=\"se-menu se-menu--multi\" *ngIf=\"isOpen(r, 'checkListId')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <label class=\"se-menu-search\" (mousedown)=\"$event.stopPropagation()\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" placeholder=\"Search audits\" autocomplete=\"off\" [(ngModel)]=\"auditQuery\" (ngModelChange)=\"activeIndex = 0\"\n (keydown)=\"onPickerKey(r, 'checkListId', $event)\">\n </label>\n <div class=\"se-opt\" *ngFor=\"let a of auditMatches(); let i = index; trackBy: trackByAudit\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"auditTicked(r, a)\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"toggleAudit(r, a, $event)\">\n <span class=\"se-box\" [class.is-on]=\"auditTicked(r, a)\">\n <svg *ngIf=\"auditTicked(r, a)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ a.name }}</span>\n <span class=\"se-opt-sub\" *ngIf=\"a.questions\">{{ a.questions }} {{ a.questions === 1 ? 'question' : 'questions' }}</span>\n </span>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!auditMatches().length\">{{ rowAuditOptions.length ? 'No audit matches \u201C' + auditQuery + '\u201D' : 'No published audits yet' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"auditTickCount(r) > 1\">{{ auditTickCount(r) }} audits on this row \u00B7 same user, store, date and window</div>\n </div>\n </div>\n\n <div class=\"se-window\" [attr.title]=\"cellError(r, 'window') || null\">\n <input type=\"time\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'window')\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.start\" (ngModelChange)=\"touch(r, 'window')\">\n <span class=\"se-dash\">\u2013</span>\n <input type=\"time\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'window')\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.end\" (ngModelChange)=\"touch(r, 'window')\">\n </div>\n\n <div class=\"se-center\">\n <span class=\"se-lock\" *ngIf=\"isLocked(r)\" title=\"Past visit: already raised, so it cannot be edited or deleted\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\"></rect><path d=\"M8 11V7a4 4 0 0 1 8 0v4\"></path></svg>\n </span>\n <a class=\"se-del\" *ngIf=\"!isLocked(r)\" title=\"Delete row\" (click)=\"deleteRow(r)\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 7h16\"></path><path d=\"M7 7l1 13h8l1-13M9 7V4h6v3\"></path></svg>\n </a>\n </div>\n\n <!-- Why the row is red, in words. -->\n <ng-container *ngIf=\"rowMessages(r) as msgs\">\n <div class=\"se-rowerr\" *ngIf=\"msgs.length\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\n <span>{{ msgs.join(' \u00B7 ') }}</span>\n <a class=\"se-invite-link\" *ngIf=\"inviteable(r)\" (click)=\"openInvite(newUserEmails(groupRows(r)))\">Invite user</a>\n </div>\n </ng-container>\n <!-- Hints: allowed (Publish is not blocked), e.g. the same visit in another schedule. -->\n <ng-container *ngIf=\"rowHints(r) as hints\">\n <div class=\"se-rowerr se-rowhint\" *ngIf=\"hints.length\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\n <span>{{ hints.join(' \u00B7 ') }}</span>\n </div>\n </ng-container>\n </div>\n\n <div *ngIf=\"!shownRows.length\" class=\"av2-empty\">\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\n <div class=\"av2-empty-text\">\n <div class=\"av2-empty-title\">No data found</div>\n <div class=\"av2-empty-sub\">{{ rows.length ? 'No rows match this search.' : 'No rows yet. Add a row or import the template.' }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"se-foot\">\n <!-- Row count + visit-window hint removed (user, 11 Oct); the count shows only while rows are selected. -->\n <span class=\"se-foot-text\" *ngIf=\"selectedCount\">{{ selectionLabel }}</span>\n <span class=\"se-foot-actions\">\n <button type=\"button\" class=\"se-bulk\" [class.is-off]=\"!selectedCount\" (click)=\"duplicateSelected()\">Duplicate</button>\n <button type=\"button\" class=\"se-bulk se-bulk--danger\" [class.is-off]=\"!selectedCount\" (click)=\"deleteSelected()\">Delete</button>\n </span>\n </div>\n </div>\n</ng-container>\n\n<!-- New User found (as the v1 checklist upload): emails with no user yet, after an import or from a row's Invite user. -->\n<ng-container *ngIf=\"inviteOpen\">\n <div class=\"se-inv-backdrop\" (click)=\"closeInvite()\"></div>\n <div class=\"se-inv\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"se-inv-title\">\n <span class=\"se-inv-icon\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.3 3.9L1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z\"></path><path d=\"M12 9v4M12 17h.01\"></path></svg>\n </span>\n <div class=\"se-inv-title\" id=\"se-inv-title\">{{ inviteEmails.length === 1 ? 'New user found' : 'New users found' }}</div>\n <div class=\"se-inv-text\">\n {{ inviteEmails.length === 1 ? 'This email is not a user yet.' : 'These emails are not users yet.' }}\n Invite them to add them as users of this client, or add them in User Management under the Manage menu.\n </div>\n\n <div class=\"se-inv-list\">\n <div class=\"se-pickrow se-pickrow--all\" *ngIf=\"inviteEmails.length > 1\" (click)=\"toggleAllInvite()\">\n <span class=\"se-box\" [class.is-on]=\"allInvitePicked\">\n <svg *ngIf=\"allInvitePicked\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickall\">Select all ({{ inviteEmails.length }})</span>\n </div>\n <div class=\"se-pickrow\" *ngFor=\"let e of inviteEmails\" [class.is-on]=\"invitePicked.has(e)\" (click)=\"toggleInvite(e)\">\n <span class=\"se-box\" [class.is-on]=\"invitePicked.has(e)\">\n <svg *ngIf=\"invitePicked.has(e)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickname\"><span class=\"se-ellipsis\">{{ e }}</span></span>\n </div>\n </div>\n\n <div class=\"se-inv-foot\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" [disabled]=\"inviting\" (click)=\"closeInvite()\">Skip</button>\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--sm\" [disabled]=\"inviting || !invitePicked.size\" (click)=\"inviteSelected()\">\n {{ inviting ? 'Inviting\u2026' : 'Invite selected' + (invitePicked.size ? ' (' + invitePicked.size + ')' : '') }}\n </button>\n </div>\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}:host{display:flex;flex-direction:column;gap:20px}.se-hidden{display:none}.se-grow{flex:1;min-width:0}.se-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-sk-crumb{width:180px;height:12px;margin:4px 0}.se-sk-name{height:22px;margin:4px 0}.se-crumb{font-size:13px;line-height:20px;color:#667085}.se-crumb a{font-weight:600;color:#00a3ff;text-decoration:none;cursor:pointer}.se-backbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.se-back{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.se-fixed-audit{display:flex;flex-direction:column;gap:4px;padding:12px 14px;border-radius:8px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0}.se-fixed-audit-name{font-size:14px;line-height:20px;font-weight:600;color:#101828}.se-create{display:flex;flex-wrap:wrap;gap:20px;max-width:1180px}.se-card{min-width:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;display:flex;flex-direction:column}.se-card--form{flex:1 1 420px;padding:28px;gap:20px}.se-card--side{flex:1 1 380px;padding:28px;gap:16px}.se-badge{width:44px;height:44px;border-radius:9999px;background:#eaf8ff;color:#00a3ff;display:flex;align-items:center;justify-content:center}.se-head{display:flex;flex-direction:column;gap:4px}.se-title{font-size:24px;line-height:32px;font-weight:700;color:#101828}.se-side-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.se-sub{font-size:14px;line-height:20px;color:#667085}.se-field{display:flex;flex-direction:column;gap:6px;margin:0}.se-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.se-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.se-count{font-size:12px;line-height:18px;color:#667085;white-space:nowrap}.se-input{height:44px;padding:0 14px;border:none;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:14px;color:#101828;outline:none}.se-input:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #ccedff}.se-search{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;margin:0;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;color:#667085}.se-search input{flex:1;min-width:0;height:38px;border:none;outline:none;background:transparent;font-size:14px;font-family:inherit;color:#101828}.se-search--sm{flex:0 1 240px;min-width:180px;height:36px}.se-search--sm input{height:34px;font-size:13px}.se-clear{display:flex;cursor:pointer;color:#98a2b3}.se-picklist{display:flex;flex-direction:column;gap:2px;max-height:220px;overflow-y:auto;padding:8px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd}.se-pickrow{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer}.se-pickrow:hover{background:#f9fafb}.se-pickrow.is-on{background:#f5fbff}.se-pickrow--all{border-bottom:1px solid #F2F4F7}.se-pickrow--fixed{cursor:default;background:#f9fafb}.se-pickrow--fixed:hover{background:#f9fafb}.se-pickall{font-size:14px;line-height:20px;font-weight:600;color:#344054}.se-pickname{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.se-pickname .se-ellipsis{font-size:14px;line-height:20px;font-weight:500;color:#101828}.se-meta{font-size:12px;line-height:18px;color:#667085}.se-empty-sm{padding:14px 10px;font-size:13px;line-height:20px;color:#667085}.se-box{width:16px;height:16px;flex-shrink:0;border-radius:4px;display:flex;align-items:center;justify-content:center;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#00a3ff}.se-box.is-on{background:#eaf8ff;box-shadow:inset 0 0 0 1px #00a3ff}.se-steps{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:8px;font-size:14px;line-height:20px;color:#344054}.se-steps a{font-weight:600;color:#00a3ff;cursor:pointer}.se-actions{display:flex;flex-direction:column;gap:12px}.se-or{text-align:center;font-size:14px;color:#98a2b3}.se-btn-lg{height:44px;border:none;border-radius:8px;font-family:inherit;font-size:15px;font-weight:600;cursor:pointer}.se-btn-lg--primary{background:#00a3ff;color:#fff}.se-btn-lg--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054}.se-btn-lg--ghost:hover{background:#f9fafb}.se-btn-lg.is-off{cursor:not-allowed}.se-btn-lg--primary.is-off{background:#f2f4f7;color:#98a2b3}.se-btn-lg--ghost.is-off{color:#98a2b3}.se-btn-lg--ghost.is-off:hover{background:#fff}.se-sample{display:flex;flex-direction:column;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;overflow:hidden}.se-sample-row{display:grid;grid-template-columns:.8fr 1.4fr 1fr 1.3fr;gap:8px;padding:10px 12px;border-top:1px solid #EAECF0;font-size:12px;line-height:18px;color:#344054}.se-sample-row span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-sample-row--head{border-top:none;background:#f9fafb;font-weight:600;color:#475467}.se-note{font-size:12px;line-height:18px;color:#667085;text-wrap:pretty}.se-note--warn{color:#b54708}.se-sample-more{padding:10px 12px;border-top:1px solid #EAECF0;font-size:12px;line-height:18px;color:#667085}.se-titlebar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.se-backbar+.se-titlebar{margin-top:-8px}.se-titletext{flex:1 1 240px;min-width:0;display:flex;flex-direction:column;gap:2px}.se-name{font-size:20px;line-height:30px;font-weight:700;color:#101828}.se-publish.is-off{background:#f2f4f7;color:#98a2b3;cursor:not-allowed;box-shadow:none}.se-ready{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:12px 20px;border-radius:8px;background:#fffcf5;box-shadow:inset 0 0 0 1px #fedf89;color:#b54708;font-size:14px;line-height:20px;font-weight:600}.se-ready svg{flex-shrink:0}.se-ready span{flex:1;min-width:0}.se-ready.is-ok{background:#f6fef9;box-shadow:inset 0 0 0 1px #a6f4c5;color:#027a48}.se-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.se-tablehead{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:20px 24px}.se-scroll{overflow-x:auto}.se-grid{min-width:1120px;display:grid;grid-template-columns:36px 1fr 1.5fr 1fr 1.5fr 1.6fr 40px;gap:12px;align-items:center;padding:10px 24px}.se-grid--head{background:#f9fafb;border-top:1px solid #EAECF0;border-bottom:1px solid #EAECF0;font-size:12px;font-weight:600;color:#475467}.se-grid--row{border-bottom:1px solid #F2F4F7}.se-grid--row.is-selected{background:#f5fbff}.se-center{display:flex;justify-content:center;cursor:pointer}.se-grid--row.is-locked .se-cell{background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0;color:#667085;-webkit-text-fill-color:#667085;opacity:1;cursor:not-allowed}.se-grid--row.is-locked .se-chev{display:none}.se-grid--row.is-locked .se-center.is-off{cursor:not-allowed}.se-grid--row.is-locked .se-center.is-off .se-box{background:#f2f4f7;box-shadow:inset 0 0 0 1px #eaecf0}.se-rowerr{grid-column:2/-1;margin-top:-4px;display:flex;align-items:flex-start;gap:6px;font-size:12px;line-height:18px;color:#d92d20}.se-rowerr svg{flex-shrink:0;margin-top:2px}.se-rowhint{color:#667085}.se-invite-link{flex-shrink:0;font-weight:600;color:#00a3ff;cursor:pointer;text-decoration:none}.se-invite-link:hover{text-decoration:underline}.se-inv-backdrop{position:fixed;inset:0;background:#34405499;z-index:1050}.se-inv{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:480px;max-width:calc(100vw - 32px);max-height:90vh;padding:24px;border-radius:8px;background:#fff;box-shadow:0 20px 40px #10182833;z-index:1051;display:flex;flex-direction:column;gap:12px}.se-inv-icon{width:48px;height:48px;border-radius:9999px;background:#fef0c7;box-shadow:0 0 0 8px #fffaeb;color:#dc6803;display:flex;align-items:center;justify-content:center;margin:4px 0 8px 4px}.se-inv-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.se-inv-text{font-size:14px;line-height:20px;color:#475467}.se-inv-list{max-height:260px;overflow-y:auto;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;padding:4px}.se-inv-foot{display:flex;justify-content:flex-end;gap:12px;margin-top:8px}.se-cell{width:100%;height:36px;min-width:0;padding:0 10px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;color:#101828;outline:none}.se-cell:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 3px #ccedff}.se-cell.is-bad{box-shadow:inset 0 0 0 1px #fda29b}.se-select{display:flex;align-items:center;justify-content:space-between;gap:6px;text-align:left;cursor:pointer}.se-select svg{flex-shrink:0;color:#667085}.se-placeholder{color:#98a2b3}.se-pick{position:relative;min-width:0}.se-cell--pick{padding-right:10px;text-overflow:ellipsis}.se-cell--tagged{padding-right:88px}.se-pick.is-open .se-cell{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 3px #ccedff}.se-pick.is-open .se-chev{transform:rotate(180deg)}.se-chev{transition:transform .15s ease}.se-tag{position:absolute;top:50%;right:8px;transform:translateY(-50%);max-width:76px;padding:2px 8px;border-radius:9999px;background:#f2f4f7;color:#344054;font-size:11px;line-height:16px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none}.se-menu{position:fixed;z-index:1060;width:max-content;max-width:380px;max-height:288px;overflow-y:auto;padding:6px;border-radius:10px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.se-opt{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer}.se-opt.is-active{background:#f9fafb}.se-opt.is-on{background:#f5fbff}.se-opt.is-on.is-active{background:#eaf8ff}.se-opt-avatar{width:28px;height:28px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.se-opt-icon{width:28px;height:28px;flex-shrink:0;border-radius:8px;background:#f2f4f7;color:#475467;display:flex;align-items:center;justify-content:center}.se-opt-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.se-opt-main{font-size:13px;line-height:18px;font-weight:500;color:#101828;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-opt-sub{font-size:12px;line-height:16px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-opt-check{flex-shrink:0;color:#00a3ff}.se-menu-empty{padding:12px 10px;font-size:13px;color:#667085}.se-menu--multi{min-width:260px}.se-menu-search{position:sticky;top:-6px;z-index:1;margin:-6px -6px 4px;padding:8px 10px;display:flex;align-items:center;gap:8px;background:#fff;border-bottom:1px solid #F2F4F7;color:#667085;cursor:text}.se-menu-search input{flex:1;min-width:0;border:0;outline:none;background:transparent;font-size:13px;line-height:18px;color:#101828}.se-menu-note{margin:4px -6px -6px;padding:8px 16px;border-top:1px solid #F2F4F7;background:#fcfcfd;font-size:12px;line-height:16px;color:#667085;position:sticky;bottom:-6px}.se-window{display:flex;align-items:center;gap:6px;min-width:0}.se-window .se-cell{flex:1;padding:0 6px}.se-dash{color:#98a2b3;font-size:13px}.se-lock{width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:#98a2b3;cursor:help}.se-del{width:28px;height:28px;border-radius:6px;display:flex;align-items:center;justify-content:center;color:#667085;cursor:pointer}.se-del:hover{background:#fffbfa;color:#d92d20}.se-empty{padding:36px 24px;text-align:center;font-size:13px;color:#667085}.se-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:16px 24px}.se-foot-text{display:flex;flex-direction:column;gap:2px;font-size:14px;line-height:20px;color:#667085}.se-foot-actions{display:flex;align-items:center;gap:8px;margin-left:auto}.se-bulk{height:36px;padding:0 14px;border:none;border-radius:8px;background:transparent;font-family:inherit;font-size:13px;font-weight:600;color:#344054;cursor:pointer}.se-bulk:hover{background:#f9fafb}.se-bulk--danger{color:#d92d20}.se-bulk--danger:hover{background:#fffbfa}.se-bulk.is-off{color:#98a2b3;cursor:not-allowed}.se-bulk.is-off:hover{background:transparent}.se-select .se-ellipsis{flex:0 1 auto;min-width:0}.se-select .se-chev{margin-left:auto}.se-more{flex-shrink:0;min-width:24px;height:20px;padding:0 7px;border-radius:9999px;background:#f2f4f7;color:#344054;font-size:12px;font-weight:600;line-height:20px;text-align:center}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: AuditV2ShimmerComponent, selector: "lib-audit-v2-shimmer", inputs: ["rows"] }] });
6643
6651
  }
6644
6652
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuditV2ScheduleEditorComponent, decorators: [{
6645
6653
  type: Component,
6646
- args: [{ selector: 'lib-audit-v2-schedule-editor', template: "<input #csvInput type=\"file\" accept=\".xlsx,.csv,text/csv\" class=\"se-hidden\" (change)=\"onCsvPicked($event)\">\n\n<!-- Editing opens on the Rows step, so its skeleton mirrors that screen. -->\n<ng-container *ngIf=\"loadingEdit\">\n <div class=\"se-titlebar\">\n <div class=\"se-titletext\">\n <span class=\"av2-sk se-sk-crumb\"></span>\n <span class=\"av2-sk av2-sk--title se-sk-name\"></span>\n </div>\n </div>\n\n <div class=\"se-card se-card--table\">\n <lib-audit-v2-shimmer></lib-audit-v2-shimmer>\n </div>\n</ng-container>\n\n<!-- ============ Create schedule ============ -->\n<ng-container *ngIf=\"step === 'create' && !loadingEdit\">\n <div class=\"se-backbar\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm se-back\" (click)=\"back()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\n {{ backLabel }}\n </button>\n <div class=\"se-crumb\"><a href=\"#\" (click)=\"back($event)\">Schedule</a> \u203A {{ scheduleId ? name || 'Schedule' : 'Create schedule' }}</div>\n </div>\n\n <div class=\"se-create\">\n <div class=\"se-card se-card--form\">\n <span class=\"se-badge\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M12 8v8M8 12h8\"></path></svg>\n </span>\n <div class=\"se-head\">\n <div class=\"se-title\">{{ scheduleId ? 'Edit schedule' : 'Create schedule' }}</div>\n <div class=\"se-sub\">{{ scheduleId ? 'Rename the schedule, or add rows from the template.' : (locked ? 'Name the schedule, then add rows for this audit.' : 'Name the schedule, then add rows.') }}</div>\n </div>\n\n <!-- Opened from an audit's Configure page: that audit is the schedule's audit, named once here\n instead of an audit picker card (QA: the card is not needed when the audit is already chosen). -->\n <div class=\"se-fixed-audit\" *ngIf=\"locked\">\n <span class=\"se-label\">{{ pickedAudits.length > 1 ? 'Audits' : 'Audit' }}</span>\n <span class=\"se-fixed-audit-name\">{{ lockedAuditNames || 'Loading audit\u2026' }}</span>\n </div>\n\n <label class=\"se-field\">\n <span class=\"se-label\">Schedule name</span>\n <input type=\"text\" class=\"se-input\" [(ngModel)]=\"name\" placeholder=\"e.g. February hygiene round\">\n </label>\n\n <!-- Every audit, with the ones picked on the previous page (Not scheduled) already ticked.\n Create only: Edit schedule keeps the schedule's audits and does not ask for them (QA).\n Hidden for now on both (showAuditPicker). -->\n <div class=\"se-field\" *ngIf=\"showAuditPicker && !locked && !scheduleId\">\n <div class=\"se-row\">\n <span class=\"se-label se-grow\">Audits to schedule</span>\n <span class=\"se-count\">{{ pickCount }}</span>\n </div>\n <label class=\"se-search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"pickQuery\" placeholder=\"Search audits\">\n <a class=\"se-clear\" *ngIf=\"pickQuery.trim()\" title=\"Clear search\" (click)=\"pickQuery = ''\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\n </a>\n </label>\n <div class=\"se-picklist\">\n <div class=\"se-pickrow se-pickrow--all\" (click)=\"toggleAllPicks()\">\n <span class=\"se-box\" [class.is-on]=\"allPicked\">\n <svg *ngIf=\"allPicked\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickall\">{{ allLabel }}</span>\n </div>\n <div class=\"se-empty-sm\" *ngIf=\"!pickables.length\">No audits match that search.</div>\n <div class=\"se-pickrow\" *ngFor=\"let a of pickables; trackBy: trackByAudit\" [class.is-on]=\"isPicked(a)\" (click)=\"togglePick(a)\">\n <span class=\"se-box\" [class.is-on]=\"isPicked(a)\">\n <svg *ngIf=\"isPicked(a)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickname\">\n <span class=\"se-ellipsis\">{{ a.name }}</span>\n <span class=\"se-meta\">{{ a.meta }}{{ a.questions ? ' \u00B7 ' + a.questions + ' questions' : '' }}</span>\n </span>\n </div>\n </div>\n </div>\n\n <ol class=\"se-steps\">\n <li>Use the template to schedule multiple users at once.</li>\n <li>Download the template here \u2014 <a href=\"#\" (click)=\"downloadTemplate($event)\">{{ templateLoading || templateWaiting ? 'Preparing\u2026' : 'Download template' }}</a></li>\n <li>Add your data, then upload it below.</li>\n </ol>\n\n <div class=\"se-actions\">\n <button type=\"button\" class=\"se-btn-lg se-btn-lg--primary\" [class.is-off]=\"!ready\" [attr.aria-disabled]=\"!ready\"\n [ngbTooltip]=\"notReadyReason\" [disableTooltip]=\"ready\" placement=\"top\" (click)=\"importCsv()\">Import from CSV</button>\n <span class=\"se-or\">or</span>\n <button type=\"button\" class=\"se-btn-lg se-btn-lg--ghost\" [class.is-off]=\"!ready\" [attr.aria-disabled]=\"!ready\"\n [ngbTooltip]=\"notReadyReason\" [disableTooltip]=\"ready\" placement=\"top\" (click)=\"addSingle()\">Add a single row</button>\n </div>\n </div>\n\n <!-- Hidden for now on both Create and Edit (showTemplatePreview). -->\n <div class=\"se-card se-card--side\" *ngIf=\"showTemplatePreview\">\n <div class=\"se-head\">\n <div class=\"se-side-title\">What the template expects</div>\n <div class=\"se-sub\">One row per user, store and date. These are the rows the downloaded template will hold for the selected\n {{ picks.length === 1 ? 'audit' : 'audits' }} \u2014 edit or add rows in the file, then import it.</div>\n </div>\n <div class=\"se-sample\">\n <div class=\"se-sample-row se-sample-row--head\">\n <span>Date</span><span>User email</span><span>Assign store</span><span>Assign audit</span>\n </div>\n <lib-audit-v2-shimmer *ngIf=\"templateLoading\" [rows]=\"3\"></lib-audit-v2-shimmer>\n <ng-container *ngIf=\"!templateLoading\">\n <!-- The selected audits' assigned stores / users: the same rows Download template writes. -->\n <div class=\"se-sample-row\" *ngFor=\"let r of previewRows\">\n <span [title]=\"r.date\">{{ r.date }}</span><span [title]=\"r.email\">{{ r.email }}</span>\n <span [title]=\"r.store\">{{ r.store }}</span><span [title]=\"r.audit\">{{ r.audit }}</span>\n </div>\n <div class=\"se-sample-more\" *ngIf=\"previewMore\">+ {{ previewMore }} more {{ previewMore === 1 ? 'row' : 'rows' }} in the file</div>\n <div class=\"se-sample-more\" *ngIf=\"!previewRows.length\">Pick an audit to see its template rows.</div>\n </ng-container>\n </div>\n <span class=\"se-note se-note--warn\" *ngIf=\"!templateLoading && unassignedAudits.length\">\n {{ unassignedAudits.join(', ') }} {{ unassignedAudits.length === 1 ? 'has' : 'have' }} no store assigned yet \u2014 fill in Date, User email\n and Store name for {{ unassignedAudits.length === 1 ? 'its row' : 'their rows' }}.</span>\n <span class=\"se-note\">Visit start and Visit end (HH:mm) are optional \u2014 leave them blank to use the store's open and close time (10:00 to 22:00 when the store has none).</span>\n <span class=\"se-note\">Rows with an unknown store, email or audit are reported before anything is saved. Draft audits\n are published when the schedule is published.</span>\n </div>\n </div>\n</ng-container>\n\n<!-- ============ Rows ============ -->\n<ng-container *ngIf=\"step === 'rows' && !loadingEdit\">\n <!-- Back + crumb on one line, as on the Create step; the name and actions below, left edges aligned.\n Edit has no \"Edit schedule\" step in the crumb (QA 9 Oct): it opens on, and stays on, the rows. -->\n <div class=\"se-backbar\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm se-back\" (click)=\"back()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\n {{ backLabel }}\n </button>\n <div class=\"se-crumb\">\n <a href=\"#\" (click)=\"back($event)\">Schedule</a> \u203A\n <ng-container *ngIf=\"!scheduleId\"><a href=\"#\" (click)=\"backToCreate($event)\">Create schedule</a> \u203A</ng-container>\n Rows\n </div>\n </div>\n\n <div class=\"se-titlebar\">\n <div class=\"se-titletext\">\n <div class=\"se-name\">{{ name.trim() || 'Untitled schedule' }}</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" [disabled]=\"saving\" (click)=\"saveDraft()\">Save as draft</button>\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--sm se-publish\" [class.is-off]=\"!canPublish\" (click)=\"publish()\">\n {{ saving ? 'Saving\u2026' : (published ? 'Save & publish' : 'Publish schedule') }}\n </button>\n </div>\n\n <div class=\"se-ready\" [class.is-ok]=\"readyOk\">\n <svg *ngIf=\"readyOk\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\"></path><path d=\"M8 12.5l2.7 2.7L16 9.5\"></path></svg>\n <svg *ngIf=\"!readyOk\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 4l9 16H3z\"></path><path d=\"M12 10v4M12 17h.01\"></path></svg>\n <span>{{ readyLabel }}</span>\n </div>\n\n <div class=\"se-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of metrics\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\">{{ m.value }}</div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"se-card se-card--table\">\n <div class=\"se-tablehead\">\n <div class=\"se-titletext\">\n <div class=\"se-side-title\">Schedule rows</div>\n <div class=\"se-sub\">Every row is one user, at one store, on one date.</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" (click)=\"addRow()\">Add row</button>\n <label class=\"se-search se-search--sm\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"rowQuery\" placeholder=\"Search rows\">\n </label>\n </div>\n\n <div class=\"se-scroll\" (scroll)=\"onViewportChange()\">\n <div class=\"se-grid se-grid--head\">\n <div class=\"se-center\" (click)=\"toggleAllRows()\" title=\"Select all rows\">\n <span class=\"se-box\" [class.is-on]=\"allRowsSelected\">\n <svg *ngIf=\"allRowsSelected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n </div>\n <div>Schedule date</div><div>User email</div><div>Assigned store</div><div>Audit assigned</div><div>Visit window</div><div></div>\n </div>\n\n <div class=\"se-grid se-grid--row\" *ngFor=\"let r of shownRows; trackBy: trackByRow\" [class.is-selected]=\"r.selected\">\n <div class=\"se-center\" (click)=\"toggleRow(r)\">\n <span class=\"se-box\" [class.is-on]=\"r.selected\">\n <svg *ngIf=\"r.selected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n </div>\n\n <input type=\"date\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'date')\" [attr.title]=\"cellError(r, 'date') || null\" [attr.min]=\"today\"\n [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.date\" (ngModelChange)=\"touch(r, 'date')\">\n\n <!-- User: search by name or email -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'userEmail')\">\n <input type=\"text\" class=\"se-cell se-cell--pick\" [class.is-bad]=\"cellError(r, 'userEmail')\" [attr.title]=\"cellError(r, 'userEmail') || null\"\n placeholder=\"Search user\" autocomplete=\"off\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.userEmail\" (ngModelChange)=\"onPickerInput(r, 'userEmail')\"\n (focus)=\"openPicker(r, 'userEmail', $event)\" (click)=\"openPicker(r, 'userEmail', $event)\" (keydown)=\"onPickerKey(r, 'userEmail', $event)\">\n <div class=\"se-menu\" *ngIf=\"isOpen(r, 'userEmail')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <div class=\"se-opt\" *ngFor=\"let u of userSuggestions(r); let i = index\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"u.email === r.userEmail.trim().toLowerCase()\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"pickUser(r, u, $event)\">\n <span class=\"se-opt-avatar\">{{ initials(u.name || u.email) }}</span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ u.name || u.email }}</span>\n <span class=\"se-opt-sub\">{{ u.email }}</span>\n </span>\n <svg class=\"se-opt-check\" *ngIf=\"u.email === r.userEmail.trim().toLowerCase()\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!userSuggestions(r).length\">{{ users.length ? 'No user matches \u201C' + r.userEmail + '\u201D' : 'Loading users\u2026' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"moreLabel(userSuggestions(r).length, userMatches(r).length, 'users')\">\n {{ moreLabel(userSuggestions(r).length, userMatches(r).length, 'users') }}\n </div>\n </div>\n </div>\n\n <!-- Store: search and show by store name (or city); the store code is never shown or asked for -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'storeId')\">\n <input type=\"text\" class=\"se-cell se-cell--pick\"\n [class.is-bad]=\"cellError(r, 'storeId')\" [attr.title]=\"cellError(r, 'storeId') || null\"\n placeholder=\"Search store\" autocomplete=\"off\" [disabled]=\"isLocked(r)\" [ngModel]=\"r.storeText\" (ngModelChange)=\"onStoreTyped(r, $event)\"\n (focus)=\"openPicker(r, 'storeId', $event)\" (click)=\"openPicker(r, 'storeId', $event)\" (keydown)=\"onPickerKey(r, 'storeId', $event)\">\n <div class=\"se-menu\" *ngIf=\"isOpen(r, 'storeId')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <div class=\"se-opt\" *ngFor=\"let s of storeSuggestions(r); let i = index\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"s.storeId === r.storeId.trim()\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"pickStore(r, s, $event)\">\n <span class=\"se-opt-icon\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 9l1.5-5h15L21 9\"></path><path d=\"M4 9v11h16V9\"></path><path d=\"M9 20v-6h6v6\"></path></svg>\n </span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ s.storeName || s.storeId }}</span>\n <span class=\"se-opt-sub\" *ngIf=\"s.city\">{{ s.city }}</span>\n </span>\n <svg class=\"se-opt-check\" *ngIf=\"s.storeId === r.storeId.trim()\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!storeSuggestions(r).length\">{{ stores.length ? 'No store matches \u201C' + r.storeText + '\u201D' : 'Loading stores\u2026' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"moreLabel(storeSuggestions(r).length, storeMatches(r).length, 'stores')\">\n {{ moreLabel(storeSuggestions(r).length, storeMatches(r).length, 'stores') }}\n </div>\n </div>\n </div>\n\n <!-- Audit assigned: multi-select with search over the published audits (rowAuditOptions). Ticking another audit\n adds a row for it with the same date, user, store and window; unticking removes that row. No column when\n the schedule has one fixed audit. -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'checkListId')\">\n <button type=\"button\" class=\"se-cell se-select\" [class.is-bad]=\"cellError(r, 'checkListId')\" [attr.title]=\"cellError(r, 'checkListId') || null\"\n [disabled]=\"isLocked(r)\" (click)=\"openPicker(r, 'checkListId', $event)\" (keydown)=\"onPickerKey(r, 'checkListId', $event)\">\n <span class=\"se-ellipsis\" [class.se-placeholder]=\"!groupAuditFirst(r)\" [attr.title]=\"groupAuditLabel(r) || null\">{{ groupAuditFirst(r) || 'Select audits' }}</span>\n <span class=\"se-more\" *ngIf=\"groupAuditMore(r)\" [attr.title]=\"groupAuditLabel(r)\">+{{ groupAuditMore(r) }}</span>\n <svg class=\"se-chev\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\n </button>\n <div class=\"se-menu se-menu--multi\" *ngIf=\"isOpen(r, 'checkListId')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <label class=\"se-menu-search\" (mousedown)=\"$event.stopPropagation()\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" placeholder=\"Search audits\" autocomplete=\"off\" [(ngModel)]=\"auditQuery\" (ngModelChange)=\"activeIndex = 0\"\n (keydown)=\"onPickerKey(r, 'checkListId', $event)\">\n </label>\n <div class=\"se-opt\" *ngFor=\"let a of auditMatches(); let i = index; trackBy: trackByAudit\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"auditTicked(r, a)\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"toggleAudit(r, a, $event)\">\n <span class=\"se-box\" [class.is-on]=\"auditTicked(r, a)\">\n <svg *ngIf=\"auditTicked(r, a)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ a.name }}</span>\n <span class=\"se-opt-sub\" *ngIf=\"a.questions\">{{ a.questions }} {{ a.questions === 1 ? 'question' : 'questions' }}</span>\n </span>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!auditMatches().length\">{{ rowAuditOptions.length ? 'No audit matches \u201C' + auditQuery + '\u201D' : 'No published audits yet' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"auditTickCount(r) > 1\">{{ auditTickCount(r) }} audits on this row \u00B7 same user, store, date and window</div>\n </div>\n </div>\n\n <div class=\"se-window\" [attr.title]=\"cellError(r, 'window') || null\">\n <input type=\"time\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'window')\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.start\" (ngModelChange)=\"touch(r, 'window')\">\n <span class=\"se-dash\">\u2013</span>\n <input type=\"time\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'window')\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.end\" (ngModelChange)=\"touch(r, 'window')\">\n </div>\n\n <div class=\"se-center\">\n <span class=\"se-lock\" *ngIf=\"isLocked(r)\" title=\"Past visit: already raised, so it cannot be edited or deleted\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\"></rect><path d=\"M8 11V7a4 4 0 0 1 8 0v4\"></path></svg>\n </span>\n <a class=\"se-del\" *ngIf=\"!isLocked(r)\" title=\"Delete row\" (click)=\"deleteRow(r)\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 7h16\"></path><path d=\"M7 7l1 13h8l1-13M9 7V4h6v3\"></path></svg>\n </a>\n </div>\n\n <!-- Why the row is red, in words. -->\n <ng-container *ngIf=\"rowMessages(r) as msgs\">\n <div class=\"se-rowerr\" *ngIf=\"msgs.length\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\n <span>{{ msgs.join(' \u00B7 ') }}</span>\n <a class=\"se-invite-link\" *ngIf=\"inviteable(r)\" (click)=\"openInvite(newUserEmails(groupRows(r)))\">Invite user</a>\n </div>\n </ng-container>\n <!-- Hints: allowed (Publish is not blocked), e.g. the same visit in another schedule. -->\n <ng-container *ngIf=\"rowHints(r) as hints\">\n <div class=\"se-rowerr se-rowhint\" *ngIf=\"hints.length\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\n <span>{{ hints.join(' \u00B7 ') }}</span>\n </div>\n </ng-container>\n </div>\n\n <div *ngIf=\"!shownRows.length\" class=\"av2-empty\">\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\n <div class=\"av2-empty-text\">\n <div class=\"av2-empty-title\">No data found</div>\n <div class=\"av2-empty-sub\">{{ rows.length ? 'No rows match this search.' : 'No rows yet. Add a row or import the template.' }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"se-foot\">\n <!-- Row count + visit-window hint removed (user, 11 Oct); the count shows only while rows are selected. -->\n <span class=\"se-foot-text\" *ngIf=\"selectedCount\">{{ selectionLabel }}</span>\n <span class=\"se-foot-actions\">\n <button type=\"button\" class=\"se-bulk\" [class.is-off]=\"!selectedCount\" (click)=\"duplicateSelected()\">Duplicate</button>\n <button type=\"button\" class=\"se-bulk se-bulk--danger\" [class.is-off]=\"!selectedCount\" (click)=\"deleteSelected()\">Delete</button>\n </span>\n </div>\n </div>\n</ng-container>\n\n<!-- New User found (as the v1 checklist upload): emails with no user yet, after an import or from a row's Invite user. -->\n<ng-container *ngIf=\"inviteOpen\">\n <div class=\"se-inv-backdrop\" (click)=\"closeInvite()\"></div>\n <div class=\"se-inv\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"se-inv-title\">\n <span class=\"se-inv-icon\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.3 3.9L1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z\"></path><path d=\"M12 9v4M12 17h.01\"></path></svg>\n </span>\n <div class=\"se-inv-title\" id=\"se-inv-title\">{{ inviteEmails.length === 1 ? 'New user found' : 'New users found' }}</div>\n <div class=\"se-inv-text\">\n {{ inviteEmails.length === 1 ? 'This email is not a user yet.' : 'These emails are not users yet.' }}\n Invite them to add them as users of this client, or add them in User Management under the Manage menu.\n </div>\n\n <div class=\"se-inv-list\">\n <div class=\"se-pickrow se-pickrow--all\" *ngIf=\"inviteEmails.length > 1\" (click)=\"toggleAllInvite()\">\n <span class=\"se-box\" [class.is-on]=\"allInvitePicked\">\n <svg *ngIf=\"allInvitePicked\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickall\">Select all ({{ inviteEmails.length }})</span>\n </div>\n <div class=\"se-pickrow\" *ngFor=\"let e of inviteEmails\" [class.is-on]=\"invitePicked.has(e)\" (click)=\"toggleInvite(e)\">\n <span class=\"se-box\" [class.is-on]=\"invitePicked.has(e)\">\n <svg *ngIf=\"invitePicked.has(e)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickname\"><span class=\"se-ellipsis\">{{ e }}</span></span>\n </div>\n </div>\n\n <div class=\"se-inv-foot\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" [disabled]=\"inviting\" (click)=\"closeInvite()\">Skip</button>\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--sm\" [disabled]=\"inviting || !invitePicked.size\" (click)=\"inviteSelected()\">\n {{ inviting ? 'Inviting\u2026' : 'Invite selected' + (invitePicked.size ? ' (' + invitePicked.size + ')' : '') }}\n </button>\n </div>\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}:host{display:flex;flex-direction:column;gap:20px}.se-hidden{display:none}.se-grow{flex:1;min-width:0}.se-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-sk-crumb{width:180px;height:12px;margin:4px 0}.se-sk-name{height:22px;margin:4px 0}.se-crumb{font-size:13px;line-height:20px;color:#667085}.se-crumb a{font-weight:600;color:#00a3ff;text-decoration:none;cursor:pointer}.se-backbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.se-back{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.se-fixed-audit{display:flex;flex-direction:column;gap:4px;padding:12px 14px;border-radius:8px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0}.se-fixed-audit-name{font-size:14px;line-height:20px;font-weight:600;color:#101828}.se-create{display:flex;flex-wrap:wrap;gap:20px;max-width:1180px}.se-card{min-width:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;display:flex;flex-direction:column}.se-card--form{flex:1 1 420px;padding:28px;gap:20px}.se-card--side{flex:1 1 380px;padding:28px;gap:16px}.se-badge{width:44px;height:44px;border-radius:9999px;background:#eaf8ff;color:#00a3ff;display:flex;align-items:center;justify-content:center}.se-head{display:flex;flex-direction:column;gap:4px}.se-title{font-size:24px;line-height:32px;font-weight:700;color:#101828}.se-side-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.se-sub{font-size:14px;line-height:20px;color:#667085}.se-field{display:flex;flex-direction:column;gap:6px;margin:0}.se-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.se-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.se-count{font-size:12px;line-height:18px;color:#667085;white-space:nowrap}.se-input{height:44px;padding:0 14px;border:none;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:14px;color:#101828;outline:none}.se-input:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #ccedff}.se-search{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;margin:0;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;color:#667085}.se-search input{flex:1;min-width:0;height:38px;border:none;outline:none;background:transparent;font-size:14px;font-family:inherit;color:#101828}.se-search--sm{flex:0 1 240px;min-width:180px;height:36px}.se-search--sm input{height:34px;font-size:13px}.se-clear{display:flex;cursor:pointer;color:#98a2b3}.se-picklist{display:flex;flex-direction:column;gap:2px;max-height:220px;overflow-y:auto;padding:8px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd}.se-pickrow{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer}.se-pickrow:hover{background:#f9fafb}.se-pickrow.is-on{background:#f5fbff}.se-pickrow--all{border-bottom:1px solid #F2F4F7}.se-pickrow--fixed{cursor:default;background:#f9fafb}.se-pickrow--fixed:hover{background:#f9fafb}.se-pickall{font-size:14px;line-height:20px;font-weight:600;color:#344054}.se-pickname{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.se-pickname .se-ellipsis{font-size:14px;line-height:20px;font-weight:500;color:#101828}.se-meta{font-size:12px;line-height:18px;color:#667085}.se-empty-sm{padding:14px 10px;font-size:13px;line-height:20px;color:#667085}.se-box{width:16px;height:16px;flex-shrink:0;border-radius:4px;display:flex;align-items:center;justify-content:center;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#00a3ff}.se-box.is-on{background:#eaf8ff;box-shadow:inset 0 0 0 1px #00a3ff}.se-steps{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:8px;font-size:14px;line-height:20px;color:#344054}.se-steps a{font-weight:600;color:#00a3ff;cursor:pointer}.se-actions{display:flex;flex-direction:column;gap:12px}.se-or{text-align:center;font-size:14px;color:#98a2b3}.se-btn-lg{height:44px;border:none;border-radius:8px;font-family:inherit;font-size:15px;font-weight:600;cursor:pointer}.se-btn-lg--primary{background:#00a3ff;color:#fff}.se-btn-lg--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054}.se-btn-lg--ghost:hover{background:#f9fafb}.se-btn-lg.is-off{cursor:not-allowed}.se-btn-lg--primary.is-off{background:#f2f4f7;color:#98a2b3}.se-btn-lg--ghost.is-off{color:#98a2b3}.se-btn-lg--ghost.is-off:hover{background:#fff}.se-sample{display:flex;flex-direction:column;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;overflow:hidden}.se-sample-row{display:grid;grid-template-columns:.8fr 1.4fr 1fr 1.3fr;gap:8px;padding:10px 12px;border-top:1px solid #EAECF0;font-size:12px;line-height:18px;color:#344054}.se-sample-row span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-sample-row--head{border-top:none;background:#f9fafb;font-weight:600;color:#475467}.se-note{font-size:12px;line-height:18px;color:#667085;text-wrap:pretty}.se-note--warn{color:#b54708}.se-sample-more{padding:10px 12px;border-top:1px solid #EAECF0;font-size:12px;line-height:18px;color:#667085}.se-titlebar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.se-backbar+.se-titlebar{margin-top:-8px}.se-titletext{flex:1 1 240px;min-width:0;display:flex;flex-direction:column;gap:2px}.se-name{font-size:20px;line-height:30px;font-weight:700;color:#101828}.se-publish.is-off{background:#f2f4f7;color:#98a2b3;cursor:not-allowed;box-shadow:none}.se-ready{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:12px 20px;border-radius:8px;background:#fffcf5;box-shadow:inset 0 0 0 1px #fedf89;color:#b54708;font-size:14px;line-height:20px;font-weight:600}.se-ready svg{flex-shrink:0}.se-ready span{flex:1;min-width:0}.se-ready.is-ok{background:#f6fef9;box-shadow:inset 0 0 0 1px #a6f4c5;color:#027a48}.se-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.se-tablehead{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:20px 24px}.se-scroll{overflow-x:auto}.se-grid{min-width:1120px;display:grid;grid-template-columns:36px 1fr 1.5fr 1fr 1.5fr 1.6fr 40px;gap:12px;align-items:center;padding:10px 24px}.se-grid--head{background:#f9fafb;border-top:1px solid #EAECF0;border-bottom:1px solid #EAECF0;font-size:12px;font-weight:600;color:#475467}.se-grid--row{border-bottom:1px solid #F2F4F7}.se-grid--row.is-selected{background:#f5fbff}.se-center{display:flex;justify-content:center;cursor:pointer}.se-rowerr{grid-column:2/-1;margin-top:-4px;display:flex;align-items:flex-start;gap:6px;font-size:12px;line-height:18px;color:#d92d20}.se-rowerr svg{flex-shrink:0;margin-top:2px}.se-rowhint{color:#667085}.se-invite-link{flex-shrink:0;font-weight:600;color:#00a3ff;cursor:pointer;text-decoration:none}.se-invite-link:hover{text-decoration:underline}.se-inv-backdrop{position:fixed;inset:0;background:#34405499;z-index:1050}.se-inv{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:480px;max-width:calc(100vw - 32px);max-height:90vh;padding:24px;border-radius:8px;background:#fff;box-shadow:0 20px 40px #10182833;z-index:1051;display:flex;flex-direction:column;gap:12px}.se-inv-icon{width:48px;height:48px;border-radius:9999px;background:#fef0c7;box-shadow:0 0 0 8px #fffaeb;color:#dc6803;display:flex;align-items:center;justify-content:center;margin:4px 0 8px 4px}.se-inv-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.se-inv-text{font-size:14px;line-height:20px;color:#475467}.se-inv-list{max-height:260px;overflow-y:auto;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;padding:4px}.se-inv-foot{display:flex;justify-content:flex-end;gap:12px;margin-top:8px}.se-cell{width:100%;height:36px;min-width:0;padding:0 10px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;color:#101828;outline:none}.se-cell:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 3px #ccedff}.se-cell.is-bad{box-shadow:inset 0 0 0 1px #fda29b}.se-select{display:flex;align-items:center;justify-content:space-between;gap:6px;text-align:left;cursor:pointer}.se-select svg{flex-shrink:0;color:#667085}.se-placeholder{color:#98a2b3}.se-pick{position:relative;min-width:0}.se-cell--pick{padding-right:10px;text-overflow:ellipsis}.se-cell--tagged{padding-right:88px}.se-pick.is-open .se-cell{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 3px #ccedff}.se-pick.is-open .se-chev{transform:rotate(180deg)}.se-chev{transition:transform .15s ease}.se-tag{position:absolute;top:50%;right:8px;transform:translateY(-50%);max-width:76px;padding:2px 8px;border-radius:9999px;background:#f2f4f7;color:#344054;font-size:11px;line-height:16px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none}.se-menu{position:fixed;z-index:1060;width:max-content;max-width:380px;max-height:288px;overflow-y:auto;padding:6px;border-radius:10px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.se-opt{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer}.se-opt.is-active{background:#f9fafb}.se-opt.is-on{background:#f5fbff}.se-opt.is-on.is-active{background:#eaf8ff}.se-opt-avatar{width:28px;height:28px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.se-opt-icon{width:28px;height:28px;flex-shrink:0;border-radius:8px;background:#f2f4f7;color:#475467;display:flex;align-items:center;justify-content:center}.se-opt-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.se-opt-main{font-size:13px;line-height:18px;font-weight:500;color:#101828;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-opt-sub{font-size:12px;line-height:16px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-opt-check{flex-shrink:0;color:#00a3ff}.se-menu-empty{padding:12px 10px;font-size:13px;color:#667085}.se-menu--multi{min-width:260px}.se-menu-search{position:sticky;top:-6px;z-index:1;margin:-6px -6px 4px;padding:8px 10px;display:flex;align-items:center;gap:8px;background:#fff;border-bottom:1px solid #F2F4F7;color:#667085;cursor:text}.se-menu-search input{flex:1;min-width:0;border:0;outline:none;background:transparent;font-size:13px;line-height:18px;color:#101828}.se-menu-note{margin:4px -6px -6px;padding:8px 16px;border-top:1px solid #F2F4F7;background:#fcfcfd;font-size:12px;line-height:16px;color:#667085;position:sticky;bottom:-6px}.se-window{display:flex;align-items:center;gap:6px;min-width:0}.se-window .se-cell{flex:1;padding:0 6px}.se-dash{color:#98a2b3;font-size:13px}.se-lock{width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:#98a2b3;cursor:help}.se-del{width:28px;height:28px;border-radius:6px;display:flex;align-items:center;justify-content:center;color:#667085;cursor:pointer}.se-del:hover{background:#fffbfa;color:#d92d20}.se-empty{padding:36px 24px;text-align:center;font-size:13px;color:#667085}.se-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:16px 24px}.se-foot-text{display:flex;flex-direction:column;gap:2px;font-size:14px;line-height:20px;color:#667085}.se-foot-actions{display:flex;align-items:center;gap:8px;margin-left:auto}.se-bulk{height:36px;padding:0 14px;border:none;border-radius:8px;background:transparent;font-family:inherit;font-size:13px;font-weight:600;color:#344054;cursor:pointer}.se-bulk:hover{background:#f9fafb}.se-bulk--danger{color:#d92d20}.se-bulk--danger:hover{background:#fffbfa}.se-bulk.is-off{color:#98a2b3;cursor:not-allowed}.se-bulk.is-off:hover{background:transparent}.se-select .se-ellipsis{flex:0 1 auto;min-width:0}.se-select .se-chev{margin-left:auto}.se-more{flex-shrink:0;min-width:24px;height:20px;padding:0 7px;border-radius:9999px;background:#f2f4f7;color:#344054;font-size:12px;font-weight:600;line-height:20px;text-align:center}\n"] }]
6654
+ args: [{ selector: 'lib-audit-v2-schedule-editor', template: "<input #csvInput type=\"file\" accept=\".xlsx,.csv,text/csv\" class=\"se-hidden\" (change)=\"onCsvPicked($event)\">\n\n<!-- Editing opens on the Rows step, so its skeleton mirrors that screen. -->\n<ng-container *ngIf=\"loadingEdit\">\n <div class=\"se-titlebar\">\n <div class=\"se-titletext\">\n <span class=\"av2-sk se-sk-crumb\"></span>\n <span class=\"av2-sk av2-sk--title se-sk-name\"></span>\n </div>\n </div>\n\n <div class=\"se-card se-card--table\">\n <lib-audit-v2-shimmer></lib-audit-v2-shimmer>\n </div>\n</ng-container>\n\n<!-- ============ Create schedule ============ -->\n<ng-container *ngIf=\"step === 'create' && !loadingEdit\">\n <div class=\"se-backbar\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm se-back\" (click)=\"back()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\n {{ backLabel }}\n </button>\n <div class=\"se-crumb\"><a href=\"#\" (click)=\"back($event)\">Schedule</a> \u203A {{ scheduleId ? name || 'Schedule' : 'Create schedule' }}</div>\n </div>\n\n <div class=\"se-create\">\n <div class=\"se-card se-card--form\">\n <span class=\"se-badge\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M12 8v8M8 12h8\"></path></svg>\n </span>\n <div class=\"se-head\">\n <div class=\"se-title\">{{ scheduleId ? 'Edit schedule' : 'Create schedule' }}</div>\n <div class=\"se-sub\">{{ scheduleId ? 'Rename the schedule, or add rows from the template.' : (locked ? 'Name the schedule, then add rows for this audit.' : 'Name the schedule, then add rows.') }}</div>\n </div>\n\n <!-- Opened from an audit's Configure page: that audit is the schedule's audit, named once here\n instead of an audit picker card (QA: the card is not needed when the audit is already chosen). -->\n <div class=\"se-fixed-audit\" *ngIf=\"locked\">\n <span class=\"se-label\">{{ pickedAudits.length > 1 ? 'Audits' : 'Audit' }}</span>\n <span class=\"se-fixed-audit-name\">{{ lockedAuditNames || 'Loading audit\u2026' }}</span>\n </div>\n\n <label class=\"se-field\">\n <span class=\"se-label\">Schedule name</span>\n <input type=\"text\" class=\"se-input\" [(ngModel)]=\"name\" placeholder=\"e.g. February hygiene round\">\n </label>\n\n <!-- Every audit, with the ones picked on the previous page (Not scheduled) already ticked.\n Create only: Edit schedule keeps the schedule's audits and does not ask for them (QA).\n Hidden for now on both (showAuditPicker). -->\n <div class=\"se-field\" *ngIf=\"showAuditPicker && !locked && !scheduleId\">\n <div class=\"se-row\">\n <span class=\"se-label se-grow\">Audits to schedule</span>\n <span class=\"se-count\">{{ pickCount }}</span>\n </div>\n <label class=\"se-search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"pickQuery\" placeholder=\"Search audits\">\n <a class=\"se-clear\" *ngIf=\"pickQuery.trim()\" title=\"Clear search\" (click)=\"pickQuery = ''\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\n </a>\n </label>\n <div class=\"se-picklist\">\n <div class=\"se-pickrow se-pickrow--all\" (click)=\"toggleAllPicks()\">\n <span class=\"se-box\" [class.is-on]=\"allPicked\">\n <svg *ngIf=\"allPicked\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickall\">{{ allLabel }}</span>\n </div>\n <div class=\"se-empty-sm\" *ngIf=\"!pickables.length\">No audits match that search.</div>\n <div class=\"se-pickrow\" *ngFor=\"let a of pickables; trackBy: trackByAudit\" [class.is-on]=\"isPicked(a)\" (click)=\"togglePick(a)\">\n <span class=\"se-box\" [class.is-on]=\"isPicked(a)\">\n <svg *ngIf=\"isPicked(a)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickname\">\n <span class=\"se-ellipsis\">{{ a.name }}</span>\n <span class=\"se-meta\">{{ a.meta }}{{ a.questions ? ' \u00B7 ' + a.questions + ' questions' : '' }}</span>\n </span>\n </div>\n </div>\n </div>\n\n <ol class=\"se-steps\">\n <li>Use the template to schedule multiple users at once.</li>\n <li>Download the template here \u2014 <a href=\"#\" (click)=\"downloadTemplate($event)\">{{ templateLoading || templateWaiting ? 'Preparing\u2026' : 'Download template' }}</a></li>\n <li>Add your data, then upload it below.</li>\n </ol>\n\n <div class=\"se-actions\">\n <button type=\"button\" class=\"se-btn-lg se-btn-lg--primary\" [class.is-off]=\"!ready\" [attr.aria-disabled]=\"!ready\"\n [ngbTooltip]=\"notReadyReason\" [disableTooltip]=\"ready\" placement=\"top\" (click)=\"importCsv()\">Import from CSV</button>\n <span class=\"se-or\">or</span>\n <button type=\"button\" class=\"se-btn-lg se-btn-lg--ghost\" [class.is-off]=\"!ready\" [attr.aria-disabled]=\"!ready\"\n [ngbTooltip]=\"notReadyReason\" [disableTooltip]=\"ready\" placement=\"top\" (click)=\"addSingle()\">Add a single row</button>\n </div>\n </div>\n\n <!-- Hidden for now on both Create and Edit (showTemplatePreview). -->\n <div class=\"se-card se-card--side\" *ngIf=\"showTemplatePreview\">\n <div class=\"se-head\">\n <div class=\"se-side-title\">What the template expects</div>\n <div class=\"se-sub\">One row per user, store and date. These are the rows the downloaded template will hold for the selected\n {{ picks.length === 1 ? 'audit' : 'audits' }} \u2014 edit or add rows in the file, then import it.</div>\n </div>\n <div class=\"se-sample\">\n <div class=\"se-sample-row se-sample-row--head\">\n <span>Date</span><span>User email</span><span>Assign store</span><span>Assign audit</span>\n </div>\n <lib-audit-v2-shimmer *ngIf=\"templateLoading\" [rows]=\"3\"></lib-audit-v2-shimmer>\n <ng-container *ngIf=\"!templateLoading\">\n <!-- The selected audits' assigned stores / users: the same rows Download template writes. -->\n <div class=\"se-sample-row\" *ngFor=\"let r of previewRows\">\n <span [title]=\"r.date\">{{ r.date }}</span><span [title]=\"r.email\">{{ r.email }}</span>\n <span [title]=\"r.store\">{{ r.store }}</span><span [title]=\"r.audit\">{{ r.audit }}</span>\n </div>\n <div class=\"se-sample-more\" *ngIf=\"previewMore\">+ {{ previewMore }} more {{ previewMore === 1 ? 'row' : 'rows' }} in the file</div>\n <div class=\"se-sample-more\" *ngIf=\"!previewRows.length\">Pick an audit to see its template rows.</div>\n </ng-container>\n </div>\n <span class=\"se-note se-note--warn\" *ngIf=\"!templateLoading && unassignedAudits.length\">\n {{ unassignedAudits.join(', ') }} {{ unassignedAudits.length === 1 ? 'has' : 'have' }} no store assigned yet \u2014 fill in Date, User email\n and Store name for {{ unassignedAudits.length === 1 ? 'its row' : 'their rows' }}.</span>\n <span class=\"se-note\">Visit start and Visit end (HH:mm) are optional \u2014 leave them blank to use the store's open and close time (10:00 to 22:00 when the store has none).</span>\n <span class=\"se-note\">Rows with an unknown store, email or audit are reported before anything is saved. Draft audits\n are published when the schedule is published.</span>\n </div>\n </div>\n</ng-container>\n\n<!-- ============ Rows ============ -->\n<ng-container *ngIf=\"step === 'rows' && !loadingEdit\">\n <!-- Back + crumb on one line, as on the Create step; the name and actions below, left edges aligned.\n Edit has no \"Edit schedule\" step in the crumb (QA 9 Oct): it opens on, and stays on, the rows. -->\n <div class=\"se-backbar\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm se-back\" (click)=\"back()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\n {{ backLabel }}\n </button>\n <div class=\"se-crumb\">\n <a href=\"#\" (click)=\"back($event)\">Schedule</a> \u203A\n <ng-container *ngIf=\"!scheduleId\"><a href=\"#\" (click)=\"backToCreate($event)\">Create schedule</a> \u203A</ng-container>\n Rows\n </div>\n </div>\n\n <div class=\"se-titlebar\">\n <div class=\"se-titletext\">\n <div class=\"se-name\">{{ name.trim() || 'Untitled schedule' }}</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" [disabled]=\"saving\" (click)=\"saveDraft()\">Save as draft</button>\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--sm se-publish\" [class.is-off]=\"!canPublish\" (click)=\"publish()\">\n {{ saving ? 'Saving\u2026' : (published ? 'Save & publish' : 'Publish schedule') }}\n </button>\n </div>\n\n <div class=\"se-ready\" [class.is-ok]=\"readyOk\">\n <svg *ngIf=\"readyOk\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18z\"></path><path d=\"M8 12.5l2.7 2.7L16 9.5\"></path></svg>\n <svg *ngIf=\"!readyOk\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 4l9 16H3z\"></path><path d=\"M12 10v4M12 17h.01\"></path></svg>\n <span>{{ readyLabel }}</span>\n </div>\n\n <div class=\"se-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of metrics\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\">{{ m.value }}</div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"se-card se-card--table\">\n <div class=\"se-tablehead\">\n <div class=\"se-titletext\">\n <div class=\"se-side-title\">Schedule rows</div>\n <div class=\"se-sub\">Every row is one user, at one store, on one date.</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" (click)=\"addRow()\">Add row</button>\n <label class=\"se-search se-search--sm\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"rowQuery\" placeholder=\"Search rows\">\n </label>\n </div>\n\n <div class=\"se-scroll\" (scroll)=\"onViewportChange()\">\n <div class=\"se-grid se-grid--head\">\n <div class=\"se-center\" (click)=\"toggleAllRows()\" title=\"Select all rows\">\n <span class=\"se-box\" [class.is-on]=\"allRowsSelected\">\n <svg *ngIf=\"allRowsSelected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n </div>\n <div>Schedule date</div><div>User email</div><div>Assigned store</div><div>Audit assigned</div><div>Visit window</div><div></div>\n </div>\n\n <div class=\"se-grid se-grid--row\" *ngFor=\"let r of shownRows; trackBy: trackByRow\" [class.is-selected]=\"r.selected\" [class.is-locked]=\"isLocked(r)\">\n <div class=\"se-center\" [class.is-off]=\"isLocked(r)\" [attr.title]=\"isLocked(r) ? 'Past visit: already raised, so it cannot be selected' : null\" (click)=\"toggleRow(r)\">\n <span class=\"se-box\" [class.is-on]=\"r.selected\">\n <svg *ngIf=\"r.selected\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n </div>\n\n <input type=\"date\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'date')\" [attr.title]=\"cellError(r, 'date') || null\" [attr.min]=\"today\"\n [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.date\" (ngModelChange)=\"touch(r, 'date')\">\n\n <!-- User: search by name or email -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'userEmail')\">\n <input type=\"text\" class=\"se-cell se-cell--pick\" [class.is-bad]=\"cellError(r, 'userEmail')\" [attr.title]=\"cellError(r, 'userEmail') || null\"\n placeholder=\"Search user\" autocomplete=\"off\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.userEmail\" (ngModelChange)=\"onPickerInput(r, 'userEmail')\"\n (focus)=\"openPicker(r, 'userEmail', $event)\" (click)=\"openPicker(r, 'userEmail', $event)\" (keydown)=\"onPickerKey(r, 'userEmail', $event)\">\n <div class=\"se-menu\" *ngIf=\"isOpen(r, 'userEmail')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <div class=\"se-opt\" *ngFor=\"let u of userSuggestions(r); let i = index\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"u.email === r.userEmail.trim().toLowerCase()\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"pickUser(r, u, $event)\">\n <span class=\"se-opt-avatar\">{{ initials(u.name || u.email) }}</span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ u.name || u.email }}</span>\n <span class=\"se-opt-sub\">{{ u.email }}</span>\n </span>\n <svg class=\"se-opt-check\" *ngIf=\"u.email === r.userEmail.trim().toLowerCase()\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!userSuggestions(r).length\">{{ users.length ? 'No user matches \u201C' + r.userEmail + '\u201D' : 'Loading users\u2026' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"moreLabel(userSuggestions(r).length, userMatches(r).length, 'users')\">\n {{ moreLabel(userSuggestions(r).length, userMatches(r).length, 'users') }}\n </div>\n </div>\n </div>\n\n <!-- Store: search and show by store name (or city); the store code is never shown or asked for -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'storeId')\">\n <input type=\"text\" class=\"se-cell se-cell--pick\"\n [class.is-bad]=\"cellError(r, 'storeId')\" [attr.title]=\"cellError(r, 'storeId') || null\"\n placeholder=\"Search store\" autocomplete=\"off\" [disabled]=\"isLocked(r)\" [ngModel]=\"r.storeText\" (ngModelChange)=\"onStoreTyped(r, $event)\"\n (focus)=\"openPicker(r, 'storeId', $event)\" (click)=\"openPicker(r, 'storeId', $event)\" (keydown)=\"onPickerKey(r, 'storeId', $event)\">\n <div class=\"se-menu\" *ngIf=\"isOpen(r, 'storeId')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <div class=\"se-opt\" *ngFor=\"let s of storeSuggestions(r); let i = index\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"s.storeId === r.storeId.trim()\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"pickStore(r, s, $event)\">\n <span class=\"se-opt-icon\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 9l1.5-5h15L21 9\"></path><path d=\"M4 9v11h16V9\"></path><path d=\"M9 20v-6h6v6\"></path></svg>\n </span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ s.storeName || s.storeId }}</span>\n <span class=\"se-opt-sub\" *ngIf=\"s.city\">{{ s.city }}</span>\n </span>\n <svg class=\"se-opt-check\" *ngIf=\"s.storeId === r.storeId.trim()\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!storeSuggestions(r).length\">{{ stores.length ? 'No store matches \u201C' + r.storeText + '\u201D' : 'Loading stores\u2026' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"moreLabel(storeSuggestions(r).length, storeMatches(r).length, 'stores')\">\n {{ moreLabel(storeSuggestions(r).length, storeMatches(r).length, 'stores') }}\n </div>\n </div>\n </div>\n\n <!-- Audit assigned: multi-select with search over the published audits (rowAuditOptions). Ticking another audit\n adds a row for it with the same date, user, store and window; unticking removes that row. No column when\n the schedule has one fixed audit. -->\n <div class=\"se-pick\" [class.is-open]=\"isOpen(r, 'checkListId')\">\n <button type=\"button\" class=\"se-cell se-select\" [class.is-bad]=\"cellError(r, 'checkListId')\" [attr.title]=\"cellError(r, 'checkListId') || null\"\n [disabled]=\"isLocked(r)\" (click)=\"openPicker(r, 'checkListId', $event)\" (keydown)=\"onPickerKey(r, 'checkListId', $event)\">\n <span class=\"se-ellipsis\" [class.se-placeholder]=\"!groupAuditFirst(r)\" [attr.title]=\"groupAuditLabel(r) || null\">{{ groupAuditFirst(r) || 'Select audits' }}</span>\n <span class=\"se-more\" *ngIf=\"groupAuditMore(r)\" [attr.title]=\"groupAuditLabel(r)\">+{{ groupAuditMore(r) }}</span>\n <svg class=\"se-chev\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\n </button>\n <div class=\"se-menu se-menu--multi\" *ngIf=\"isOpen(r, 'checkListId')\" [style.top.px]=\"menuPos.top\" [style.bottom.px]=\"menuPos.bottom\"\n [style.left.px]=\"menuPos.left\" [style.min-width.px]=\"menuPos.width\">\n <label class=\"se-menu-search\" (mousedown)=\"$event.stopPropagation()\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" placeholder=\"Search audits\" autocomplete=\"off\" [(ngModel)]=\"auditQuery\" (ngModelChange)=\"activeIndex = 0\"\n (keydown)=\"onPickerKey(r, 'checkListId', $event)\">\n </label>\n <div class=\"se-opt\" *ngFor=\"let a of auditMatches(); let i = index; trackBy: trackByAudit\" [class.is-active]=\"i === activeIndex\"\n [class.is-on]=\"auditTicked(r, a)\" (mouseenter)=\"activeIndex = i\"\n (mousedown)=\"$event.preventDefault()\" (click)=\"toggleAudit(r, a, $event)\">\n <span class=\"se-box\" [class.is-on]=\"auditTicked(r, a)\">\n <svg *ngIf=\"auditTicked(r, a)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-opt-text\">\n <span class=\"se-opt-main\">{{ a.name }}</span>\n <span class=\"se-opt-sub\" *ngIf=\"a.questions\">{{ a.questions }} {{ a.questions === 1 ? 'question' : 'questions' }}</span>\n </span>\n </div>\n <div class=\"se-menu-empty\" *ngIf=\"!auditMatches().length\">{{ rowAuditOptions.length ? 'No audit matches \u201C' + auditQuery + '\u201D' : 'No published audits yet' }}</div>\n <div class=\"se-menu-note\" *ngIf=\"auditTickCount(r) > 1\">{{ auditTickCount(r) }} audits on this row \u00B7 same user, store, date and window</div>\n </div>\n </div>\n\n <div class=\"se-window\" [attr.title]=\"cellError(r, 'window') || null\">\n <input type=\"time\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'window')\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.start\" (ngModelChange)=\"touch(r, 'window')\">\n <span class=\"se-dash\">\u2013</span>\n <input type=\"time\" class=\"se-cell\" [class.is-bad]=\"cellError(r, 'window')\" [disabled]=\"isLocked(r)\" [(ngModel)]=\"r.end\" (ngModelChange)=\"touch(r, 'window')\">\n </div>\n\n <div class=\"se-center\">\n <span class=\"se-lock\" *ngIf=\"isLocked(r)\" title=\"Past visit: already raised, so it cannot be edited or deleted\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"5\" y=\"11\" width=\"14\" height=\"10\" rx=\"2\"></rect><path d=\"M8 11V7a4 4 0 0 1 8 0v4\"></path></svg>\n </span>\n <a class=\"se-del\" *ngIf=\"!isLocked(r)\" title=\"Delete row\" (click)=\"deleteRow(r)\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.9\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 7h16\"></path><path d=\"M7 7l1 13h8l1-13M9 7V4h6v3\"></path></svg>\n </a>\n </div>\n\n <!-- Why the row is red, in words. -->\n <ng-container *ngIf=\"rowMessages(r) as msgs\">\n <div class=\"se-rowerr\" *ngIf=\"msgs.length\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\n <span>{{ msgs.join(' \u00B7 ') }}</span>\n <a class=\"se-invite-link\" *ngIf=\"inviteable(r)\" (click)=\"openInvite(newUserEmails(groupRows(r)))\">Invite user</a>\n </div>\n </ng-container>\n <!-- Hints: allowed (Publish is not blocked), e.g. the same visit in another schedule. -->\n <ng-container *ngIf=\"rowHints(r) as hints\">\n <div class=\"se-rowerr se-rowhint\" *ngIf=\"hints.length\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\n <span>{{ hints.join(' \u00B7 ') }}</span>\n </div>\n </ng-container>\n </div>\n\n <div *ngIf=\"!shownRows.length\" class=\"av2-empty\">\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\n <div class=\"av2-empty-text\">\n <div class=\"av2-empty-title\">No data found</div>\n <div class=\"av2-empty-sub\">{{ rows.length ? 'No rows match this search.' : 'No rows yet. Add a row or import the template.' }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"se-foot\">\n <!-- Row count + visit-window hint removed (user, 11 Oct); the count shows only while rows are selected. -->\n <span class=\"se-foot-text\" *ngIf=\"selectedCount\">{{ selectionLabel }}</span>\n <span class=\"se-foot-actions\">\n <button type=\"button\" class=\"se-bulk\" [class.is-off]=\"!selectedCount\" (click)=\"duplicateSelected()\">Duplicate</button>\n <button type=\"button\" class=\"se-bulk se-bulk--danger\" [class.is-off]=\"!selectedCount\" (click)=\"deleteSelected()\">Delete</button>\n </span>\n </div>\n </div>\n</ng-container>\n\n<!-- New User found (as the v1 checklist upload): emails with no user yet, after an import or from a row's Invite user. -->\n<ng-container *ngIf=\"inviteOpen\">\n <div class=\"se-inv-backdrop\" (click)=\"closeInvite()\"></div>\n <div class=\"se-inv\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"se-inv-title\">\n <span class=\"se-inv-icon\">\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.3 3.9L1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z\"></path><path d=\"M12 9v4M12 17h.01\"></path></svg>\n </span>\n <div class=\"se-inv-title\" id=\"se-inv-title\">{{ inviteEmails.length === 1 ? 'New user found' : 'New users found' }}</div>\n <div class=\"se-inv-text\">\n {{ inviteEmails.length === 1 ? 'This email is not a user yet.' : 'These emails are not users yet.' }}\n Invite them to add them as users of this client, or add them in User Management under the Manage menu.\n </div>\n\n <div class=\"se-inv-list\">\n <div class=\"se-pickrow se-pickrow--all\" *ngIf=\"inviteEmails.length > 1\" (click)=\"toggleAllInvite()\">\n <span class=\"se-box\" [class.is-on]=\"allInvitePicked\">\n <svg *ngIf=\"allInvitePicked\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickall\">Select all ({{ inviteEmails.length }})</span>\n </div>\n <div class=\"se-pickrow\" *ngFor=\"let e of inviteEmails\" [class.is-on]=\"invitePicked.has(e)\" (click)=\"toggleInvite(e)\">\n <span class=\"se-box\" [class.is-on]=\"invitePicked.has(e)\">\n <svg *ngIf=\"invitePicked.has(e)\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\n </span>\n <span class=\"se-pickname\"><span class=\"se-ellipsis\">{{ e }}</span></span>\n </div>\n </div>\n\n <div class=\"se-inv-foot\">\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" [disabled]=\"inviting\" (click)=\"closeInvite()\">Skip</button>\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--sm\" [disabled]=\"inviting || !invitePicked.size\" (click)=\"inviteSelected()\">\n {{ inviting ? 'Inviting\u2026' : 'Invite selected' + (invitePicked.size ? ' (' + invitePicked.size + ')' : '') }}\n </button>\n </div>\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}:host{display:flex;flex-direction:column;gap:20px}.se-hidden{display:none}.se-grow{flex:1;min-width:0}.se-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-sk-crumb{width:180px;height:12px;margin:4px 0}.se-sk-name{height:22px;margin:4px 0}.se-crumb{font-size:13px;line-height:20px;color:#667085}.se-crumb a{font-weight:600;color:#00a3ff;text-decoration:none;cursor:pointer}.se-backbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.se-back{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.se-fixed-audit{display:flex;flex-direction:column;gap:4px;padding:12px 14px;border-radius:8px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0}.se-fixed-audit-name{font-size:14px;line-height:20px;font-weight:600;color:#101828}.se-create{display:flex;flex-wrap:wrap;gap:20px;max-width:1180px}.se-card{min-width:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;display:flex;flex-direction:column}.se-card--form{flex:1 1 420px;padding:28px;gap:20px}.se-card--side{flex:1 1 380px;padding:28px;gap:16px}.se-badge{width:44px;height:44px;border-radius:9999px;background:#eaf8ff;color:#00a3ff;display:flex;align-items:center;justify-content:center}.se-head{display:flex;flex-direction:column;gap:4px}.se-title{font-size:24px;line-height:32px;font-weight:700;color:#101828}.se-side-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.se-sub{font-size:14px;line-height:20px;color:#667085}.se-field{display:flex;flex-direction:column;gap:6px;margin:0}.se-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.se-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.se-count{font-size:12px;line-height:18px;color:#667085;white-space:nowrap}.se-input{height:44px;padding:0 14px;border:none;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:14px;color:#101828;outline:none}.se-input:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #ccedff}.se-search{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;margin:0;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;color:#667085}.se-search input{flex:1;min-width:0;height:38px;border:none;outline:none;background:transparent;font-size:14px;font-family:inherit;color:#101828}.se-search--sm{flex:0 1 240px;min-width:180px;height:36px}.se-search--sm input{height:34px;font-size:13px}.se-clear{display:flex;cursor:pointer;color:#98a2b3}.se-picklist{display:flex;flex-direction:column;gap:2px;max-height:220px;overflow-y:auto;padding:8px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd}.se-pickrow{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer}.se-pickrow:hover{background:#f9fafb}.se-pickrow.is-on{background:#f5fbff}.se-pickrow--all{border-bottom:1px solid #F2F4F7}.se-pickrow--fixed{cursor:default;background:#f9fafb}.se-pickrow--fixed:hover{background:#f9fafb}.se-pickall{font-size:14px;line-height:20px;font-weight:600;color:#344054}.se-pickname{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.se-pickname .se-ellipsis{font-size:14px;line-height:20px;font-weight:500;color:#101828}.se-meta{font-size:12px;line-height:18px;color:#667085}.se-empty-sm{padding:14px 10px;font-size:13px;line-height:20px;color:#667085}.se-box{width:16px;height:16px;flex-shrink:0;border-radius:4px;display:flex;align-items:center;justify-content:center;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#00a3ff}.se-box.is-on{background:#eaf8ff;box-shadow:inset 0 0 0 1px #00a3ff}.se-steps{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:8px;font-size:14px;line-height:20px;color:#344054}.se-steps a{font-weight:600;color:#00a3ff;cursor:pointer}.se-actions{display:flex;flex-direction:column;gap:12px}.se-or{text-align:center;font-size:14px;color:#98a2b3}.se-btn-lg{height:44px;border:none;border-radius:8px;font-family:inherit;font-size:15px;font-weight:600;cursor:pointer}.se-btn-lg--primary{background:#00a3ff;color:#fff}.se-btn-lg--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054}.se-btn-lg--ghost:hover{background:#f9fafb}.se-btn-lg.is-off{cursor:not-allowed}.se-btn-lg--primary.is-off{background:#f2f4f7;color:#98a2b3}.se-btn-lg--ghost.is-off{color:#98a2b3}.se-btn-lg--ghost.is-off:hover{background:#fff}.se-sample{display:flex;flex-direction:column;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;overflow:hidden}.se-sample-row{display:grid;grid-template-columns:.8fr 1.4fr 1fr 1.3fr;gap:8px;padding:10px 12px;border-top:1px solid #EAECF0;font-size:12px;line-height:18px;color:#344054}.se-sample-row span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-sample-row--head{border-top:none;background:#f9fafb;font-weight:600;color:#475467}.se-note{font-size:12px;line-height:18px;color:#667085;text-wrap:pretty}.se-note--warn{color:#b54708}.se-sample-more{padding:10px 12px;border-top:1px solid #EAECF0;font-size:12px;line-height:18px;color:#667085}.se-titlebar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.se-backbar+.se-titlebar{margin-top:-8px}.se-titletext{flex:1 1 240px;min-width:0;display:flex;flex-direction:column;gap:2px}.se-name{font-size:20px;line-height:30px;font-weight:700;color:#101828}.se-publish.is-off{background:#f2f4f7;color:#98a2b3;cursor:not-allowed;box-shadow:none}.se-ready{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:12px 20px;border-radius:8px;background:#fffcf5;box-shadow:inset 0 0 0 1px #fedf89;color:#b54708;font-size:14px;line-height:20px;font-weight:600}.se-ready svg{flex-shrink:0}.se-ready span{flex:1;min-width:0}.se-ready.is-ok{background:#f6fef9;box-shadow:inset 0 0 0 1px #a6f4c5;color:#027a48}.se-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.se-tablehead{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:20px 24px}.se-scroll{overflow-x:auto}.se-grid{min-width:1120px;display:grid;grid-template-columns:36px 1fr 1.5fr 1fr 1.5fr 1.6fr 40px;gap:12px;align-items:center;padding:10px 24px}.se-grid--head{background:#f9fafb;border-top:1px solid #EAECF0;border-bottom:1px solid #EAECF0;font-size:12px;font-weight:600;color:#475467}.se-grid--row{border-bottom:1px solid #F2F4F7}.se-grid--row.is-selected{background:#f5fbff}.se-center{display:flex;justify-content:center;cursor:pointer}.se-grid--row.is-locked .se-cell{background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0;color:#667085;-webkit-text-fill-color:#667085;opacity:1;cursor:not-allowed}.se-grid--row.is-locked .se-chev{display:none}.se-grid--row.is-locked .se-center.is-off{cursor:not-allowed}.se-grid--row.is-locked .se-center.is-off .se-box{background:#f2f4f7;box-shadow:inset 0 0 0 1px #eaecf0}.se-rowerr{grid-column:2/-1;margin-top:-4px;display:flex;align-items:flex-start;gap:6px;font-size:12px;line-height:18px;color:#d92d20}.se-rowerr svg{flex-shrink:0;margin-top:2px}.se-rowhint{color:#667085}.se-invite-link{flex-shrink:0;font-weight:600;color:#00a3ff;cursor:pointer;text-decoration:none}.se-invite-link:hover{text-decoration:underline}.se-inv-backdrop{position:fixed;inset:0;background:#34405499;z-index:1050}.se-inv{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:480px;max-width:calc(100vw - 32px);max-height:90vh;padding:24px;border-radius:8px;background:#fff;box-shadow:0 20px 40px #10182833;z-index:1051;display:flex;flex-direction:column;gap:12px}.se-inv-icon{width:48px;height:48px;border-radius:9999px;background:#fef0c7;box-shadow:0 0 0 8px #fffaeb;color:#dc6803;display:flex;align-items:center;justify-content:center;margin:4px 0 8px 4px}.se-inv-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.se-inv-text{font-size:14px;line-height:20px;color:#475467}.se-inv-list{max-height:260px;overflow-y:auto;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;padding:4px}.se-inv-foot{display:flex;justify-content:flex-end;gap:12px;margin-top:8px}.se-cell{width:100%;height:36px;min-width:0;padding:0 10px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;color:#101828;outline:none}.se-cell:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 3px #ccedff}.se-cell.is-bad{box-shadow:inset 0 0 0 1px #fda29b}.se-select{display:flex;align-items:center;justify-content:space-between;gap:6px;text-align:left;cursor:pointer}.se-select svg{flex-shrink:0;color:#667085}.se-placeholder{color:#98a2b3}.se-pick{position:relative;min-width:0}.se-cell--pick{padding-right:10px;text-overflow:ellipsis}.se-cell--tagged{padding-right:88px}.se-pick.is-open .se-cell{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 3px #ccedff}.se-pick.is-open .se-chev{transform:rotate(180deg)}.se-chev{transition:transform .15s ease}.se-tag{position:absolute;top:50%;right:8px;transform:translateY(-50%);max-width:76px;padding:2px 8px;border-radius:9999px;background:#f2f4f7;color:#344054;font-size:11px;line-height:16px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none}.se-menu{position:fixed;z-index:1060;width:max-content;max-width:380px;max-height:288px;overflow-y:auto;padding:6px;border-radius:10px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.se-opt{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;cursor:pointer}.se-opt.is-active{background:#f9fafb}.se-opt.is-on{background:#f5fbff}.se-opt.is-on.is-active{background:#eaf8ff}.se-opt-avatar{width:28px;height:28px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.se-opt-icon{width:28px;height:28px;flex-shrink:0;border-radius:8px;background:#f2f4f7;color:#475467;display:flex;align-items:center;justify-content:center}.se-opt-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.se-opt-main{font-size:13px;line-height:18px;font-weight:500;color:#101828;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-opt-sub{font-size:12px;line-height:16px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.se-opt-check{flex-shrink:0;color:#00a3ff}.se-menu-empty{padding:12px 10px;font-size:13px;color:#667085}.se-menu--multi{min-width:260px}.se-menu-search{position:sticky;top:-6px;z-index:1;margin:-6px -6px 4px;padding:8px 10px;display:flex;align-items:center;gap:8px;background:#fff;border-bottom:1px solid #F2F4F7;color:#667085;cursor:text}.se-menu-search input{flex:1;min-width:0;border:0;outline:none;background:transparent;font-size:13px;line-height:18px;color:#101828}.se-menu-note{margin:4px -6px -6px;padding:8px 16px;border-top:1px solid #F2F4F7;background:#fcfcfd;font-size:12px;line-height:16px;color:#667085;position:sticky;bottom:-6px}.se-window{display:flex;align-items:center;gap:6px;min-width:0}.se-window .se-cell{flex:1;padding:0 6px}.se-dash{color:#98a2b3;font-size:13px}.se-lock{width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:#98a2b3;cursor:help}.se-del{width:28px;height:28px;border-radius:6px;display:flex;align-items:center;justify-content:center;color:#667085;cursor:pointer}.se-del:hover{background:#fffbfa;color:#d92d20}.se-empty{padding:36px 24px;text-align:center;font-size:13px;color:#667085}.se-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:16px 24px}.se-foot-text{display:flex;flex-direction:column;gap:2px;font-size:14px;line-height:20px;color:#667085}.se-foot-actions{display:flex;align-items:center;gap:8px;margin-left:auto}.se-bulk{height:36px;padding:0 14px;border:none;border-radius:8px;background:transparent;font-family:inherit;font-size:13px;font-weight:600;color:#344054;cursor:pointer}.se-bulk:hover{background:#f9fafb}.se-bulk--danger{color:#d92d20}.se-bulk--danger:hover{background:#fffbfa}.se-bulk.is-off{color:#98a2b3;cursor:not-allowed}.se-bulk.is-off:hover{background:transparent}.se-select .se-ellipsis{flex:0 1 auto;min-width:0}.se-select .se-chev{margin-left:auto}.se-more{flex-shrink:0;min-width:24px;height:20px;padding:0 7px;border-radius:9999px;background:#f2f4f7;color:#344054;font-size:12px;font-weight:600;line-height:20px;text-align:center}\n"] }]
6647
6655
  }], ctorParameters: () => [{ type: TraxService }, { type: i3.ToastService }, { type: i0.ChangeDetectorRef }], propDecorators: { clientId: [{
6648
6656
  type: Input
6649
6657
  }], audits: [{
@@ -6848,7 +6856,8 @@ class AuditV2ScheduleDetailComponent {
6848
6856
  edit = new EventEmitter();
6849
6857
  loading = true;
6850
6858
  name = '';
6851
- audits = '';
6859
+ /** The schedule's audits by name; the summary line shows a count when there are several (names in its tooltip). */
6860
+ auditNames = [];
6852
6861
  published = false;
6853
6862
  metrics = { visits: 0, users: 0, completed: 0, pending: 0 };
6854
6863
  rows = [];
@@ -6875,7 +6884,7 @@ class AuditV2ScheduleDetailComponent {
6875
6884
  }
6876
6885
  this.name = d.schedule?.name || 'Schedule';
6877
6886
  this.published = !!d.schedule?.publish;
6878
- this.audits = (d.schedule?.checkLists || []).map((c) => c.checkListName).filter(Boolean).join(' · ');
6887
+ this.auditNames = (d.schedule?.checkLists || []).map((c) => c.checkListName).filter(Boolean);
6879
6888
  this.metrics = { ...this.metrics, ...(d.metrics || {}) };
6880
6889
  this.rows = (d.rows || []).map((r) => {
6881
6890
  const email = String(r.userEmail || '');
@@ -6971,8 +6980,13 @@ class AuditV2ScheduleDetailComponent {
6971
6980
  }
6972
6981
  get rangeLabel() {
6973
6982
  const m = this.shownMetrics;
6983
+ const n = this.auditNames.length;
6974
6984
  return m.visits + (m.visits === 1 ? ' visit' : ' visits') + ' · ' + m.users + (m.users === 1 ? ' user' : ' users')
6975
- + (this.audits ? ' · ' + this.audits : '');
6985
+ + (n === 1 ? ' · ' + this.auditNames[0] : n > 1 ? ' · ' + n + ' audits' : '');
6986
+ }
6987
+ /** Every audit name, as the summary line's tooltip when it shows only the count. */
6988
+ get auditsTip() {
6989
+ return this.auditNames.length > 1 ? this.auditNames.join(', ') : null;
6976
6990
  }
6977
6991
  /** Column sort ('' = the schedule's order); a header click toggles ascending / descending (QA 10 Oct). */
6978
6992
  sortKey = '';
@@ -7034,11 +7048,11 @@ class AuditV2ScheduleDetailComponent {
7034
7048
  fg(s) { return STATUS$1[s].fg; }
7035
7049
  dot(s) { return STATUS$1[s].dot; }
7036
7050
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuditV2ScheduleDetailComponent, deps: [{ token: TraxService }, { token: i3.ToastService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
7037
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AuditV2ScheduleDetailComponent, selector: "lib-audit-v2-schedule-detail", inputs: { clientId: "clientId", scheduleId: "scheduleId", canEdit: "canEdit", fromDate: "fromDate", toDate: "toDate" }, outputs: { back: "back", edit: "edit" }, ngImport: i0, template: "<ng-container *ngIf=\"loading\">\n <div class=\"sd-titlebar\">\n <div class=\"sd-titletext\">\n <span class=\"av2-sk sd-sk-crumb\"></span>\n <span class=\"av2-sk av2-sk--title sd-sk-name\"></span>\n </div>\n </div>\n\n <div class=\"sd-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of cards\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\"><span class=\"av2-sk av2-sk--value sd-sk-value\"></span></div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-card\">\n <lib-audit-v2-shimmer></lib-audit-v2-shimmer>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"!loading\">\n <div class=\"sd-titlebar\">\n <div class=\"sd-titletext\">\n <div class=\"sd-crumb\"><a href=\"#\" (click)=\"goBack($event)\">Schedule</a> \u203A {{ name }}</div>\n <div class=\"sd-name\">{{ name }}</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" *ngIf=\"canEdit\" (click)=\"edit.emit(scheduleId)\">Edit rows</button>\n </div>\n\n <div class=\"sd-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of cards\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\">{{ m.value }}</div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-card\">\n <div class=\"sd-tablehead\">\n <div class=\"sd-titletext\">\n <div class=\"sd-card-title\">Scheduled info</div>\n <div class=\"sd-sub\">\n {{ rangeLabel }}\n <ng-container *ngIf=\"rangeText\">\n \u00B7 {{ rangeOn ? 'Visits on ' + rangeText : 'All dates' }}\n <a class=\"sd-range-link\" (click)=\"toggleShowAll()\">{{ rangeOn ? 'Show all dates' : 'Show ' + rangeText + ' only' }}</a>\n </ng-container>\n </div>\n </div>\n <label class=\"sd-search\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"query\" (ngModelChange)=\"onQuery()\" placeholder=\"Search users or stores\">\n </label>\n </div>\n\n <div class=\"sd-scroll\">\n <div class=\"sd-grid sd-grid--head\">\n <div class=\"av2-sortable\" (click)=\"sortBy('date')\">Schedule date <lib-audit-v2-sort-icon [active]=\"sortKey === 'date'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('email')\">User email <lib-audit-v2-sort-icon [active]=\"sortKey === 'email'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('store')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'store'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('window')\">Visit window <lib-audit-v2-sort-icon [active]=\"sortKey === 'window'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('audit')\">Audit <lib-audit-v2-sort-icon [active]=\"sortKey === 'audit'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('status')\">Status <lib-audit-v2-sort-icon [active]=\"sortKey === 'status'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n </div>\n <div class=\"sd-grid sd-grid--row\" *ngFor=\"let r of paged\">\n <div>{{ r.date }}</div>\n <div class=\"sd-user\">\n <span class=\"sd-avatar\">{{ r.initials }}</span>\n <span class=\"sd-ellipsis\" [av2Tip]=\"r.email\">{{ r.email }}</span>\n </div>\n <!-- Store name (QA: the store code was shown); the id only for a row without a name. -->\n <div class=\"sd-store sd-ellipsis\" [av2Tip]=\"r.storeName || ''\">{{ r.storeName || '\u2014' }}</div>\n <div [class.sd-muted]=\"!r.hasWindow\" [class.sd-missed]=\"r.status === 'missed' && r.hasWindow\" [attr.title]=\"r.windowTip || null\">{{ r.window }}</div>\n <div class=\"sd-ellipsis\" [av2Tip]=\"r.audit\">{{ r.audit }}</div>\n <div>\n <span class=\"sd-pill\" [style.background]=\"bg(r.status)\" [style.color]=\"fg(r.status)\" [title]=\"r.note\">\n <span class=\"sd-dot\" [style.background]=\"dot(r.status)\"></span>{{ label(r.status) }}\n </span>\n </div>\n </div>\n <div *ngIf=\"!filtered.length\" class=\"av2-empty\">\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\n <div class=\"av2-empty-text\">\n <div class=\"av2-empty-title\">No data found</div>\n <div class=\"av2-empty-sub\">{{ rows.length ? 'No visits match this search.' : 'No rows yet. Use Edit rows to add users, stores and dates.' }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-foot\">\n <span>{{ countLabel }}</span>\n <lib-pagination *ngIf=\"filtered.length\" [itemsPerPage]=\"pageSize\" [pageSize]=\"pageSize\"\n [paginationSizes]=\"pageSizes\" [currentPage]=\"page\" [totalItems]=\"filtered.length\"\n (pageChange)=\"onPage($event)\" (pageSizeChange)=\"onPageSize($event)\"></lib-pagination>\n </div>\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}::ng-deep .tooltip.av2-tip{--bs-tooltip-bg: #fff;--bs-tooltip-color: #344054;--bs-tooltip-max-width: 320px;--bs-tooltip-opacity: 1}::ng-deep .tooltip.av2-tip .tooltip-inner{background-color:#fff!important;color:#344054!important;padding:8px 12px;border-radius:8px;font-size:13px;line-height:18px;font-weight:500;text-align:left;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,0 0 0 1px #eaecf0}::ng-deep .tooltip.av2-tip .tooltip-arrow:before{border-top-color:#fff;border-bottom-color:#fff}:host ::ng-deep lib-pagination{display:block}:host ::ng-deep lib-pagination .container{max-width:none;padding:0;display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;font-size:14px;color:#475467}:host ::ng-deep lib-pagination .mt-4{margin-top:0!important}:host ::ng-deep lib-pagination .container>.text-center{display:flex;align-items:center}:host ::ng-deep lib-pagination .container>.text-center>ul:not(.ngx-pagination){display:none}:host ::ng-deep lib-pagination pagination-controls{display:flex;align-items:center}:host ::ng-deep lib-pagination .sub-title{color:#475467!important;font-size:14px!important;font-weight:400!important;line-height:20px}:host ::ng-deep lib-pagination .border-val{height:40px;min-width:64px;padding:0 30px 0 12px!important;border:1px solid #D0D5DD!important;border-radius:8px!important;box-shadow:0 1px 2px #1018280d;background-color:#fff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\")!important;background-repeat:no-repeat!important;background-position:right 10px center!important;background-size:14px 14px!important;appearance:none;-webkit-appearance:none;font-size:14px;font-weight:500;color:#1d2939;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}:host ::ng-deep lib-pagination .border-val:hover{border-color:#98a2b3!important}:host ::ng-deep lib-pagination .border-val:focus{outline:none;border-color:#66c8ff!important;box-shadow:0 0 0 3px #eaf8ff}:host ::ng-deep lib-pagination .ngx-pagination{margin:0;padding:0;display:flex;align-items:center;gap:6px;color:#475467!important;font-size:14px!important;font-weight:500}:host ::ng-deep lib-pagination .ngx-pagination li{display:inline-flex;margin:0}:host ::ng-deep lib-pagination .ngx-pagination li.small-screen{display:none!important}:host ::ng-deep lib-pagination .ngx-pagination a,:host ::ng-deep lib-pagination .ngx-pagination button,:host ::ng-deep lib-pagination .ngx-pagination .current,:host ::ng-deep lib-pagination .ngx-pagination .disabled{min-width:40px!important;height:40px;padding:0 8px!important;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;line-height:20px;color:#475467}:host ::ng-deep lib-pagination .ngx-pagination a:hover,:host ::ng-deep lib-pagination .ngx-pagination button:hover{background:#f2f4f7;padding:0 8px!important}:host ::ng-deep lib-pagination .ngx-pagination .current{background:#eaf8ff!important;color:#00a3ff!important;font-weight:600;font-size:14px!important}:host ::ng-deep lib-pagination .ngx-pagination .disabled{color:#98a2b3}:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:after{margin:0}:host ::ng-deep lib-pagination .ngx-pagination .ellipsis:after{color:#98a2b3;padding:0}:host{display:flex;flex-direction:column;gap:20px}.sd-sk-crumb{width:140px;height:12px;margin:4px 0}.sd-sk-name{height:22px;margin:4px 0}.sd-sk-value{height:32px;margin:3px 0}.sd-titlebar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.sd-titletext{flex:1 1 240px;min-width:0;display:flex;flex-direction:column;gap:2px}.sd-crumb{font-size:13px;line-height:20px;color:#667085}.sd-crumb a{font-weight:600;color:#00a3ff;text-decoration:none;cursor:pointer}.sd-name{font-size:20px;line-height:30px;font-weight:700;color:#101828}.sd-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px}.sd-card{border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;display:flex;flex-direction:column}.sd-tablehead{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:20px 24px}.sd-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.sd-sub{font-size:14px;line-height:20px;color:#667085}.sd-search{flex:0 1 260px;min-width:180px;display:flex;align-items:center;gap:8px;height:36px;padding:0 12px;margin:0;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;color:#667085}.sd-search input{flex:1;min-width:0;height:34px;border:none;outline:none;background:transparent;font-size:13px;font-family:inherit;color:#101828}.sd-scroll{overflow-x:auto}.sd-grid{min-width:1180px;display:grid;grid-template-columns:1fr 1.6fr .9fr 1.1fr 1.5fr 1fr;gap:12px;align-items:center;padding:14px 24px}.sd-grid--head{padding:10px 24px;background:#f9fafb;border-top:1px solid #EAECF0;border-bottom:1px solid #EAECF0;font-size:12px;font-weight:600;color:#475467}.sd-grid--row{border-bottom:1px solid #F2F4F7;font-size:13px;color:#344054}.sd-user{display:flex;align-items:center;gap:8px;min-width:0}.sd-avatar{width:24px;height:24px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700}.sd-ellipsis{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-store{font-weight:600;color:#101828}.sd-muted{color:#98a2b3}.sd-missed{color:#d92d20}.sd-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:9999px;font-size:12px;font-weight:600}.sd-dot{width:6px;height:6px;border-radius:9999px;display:block}.sd-empty{padding:36px 24px;text-align:center;font-size:13px;color:#667085}.sd-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:16px 24px;font-size:14px;color:#667085}.sd-range-link{margin-left:6px;color:#00a3ff;font-weight:500;cursor:pointer}.sd-range-link:hover{text-decoration:underline}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: AuditV2TipDirective, selector: "[av2Tip]", inputs: ["av2Tip"] }, { kind: "component", type: AuditV2ShimmerComponent, selector: "lib-audit-v2-shimmer", inputs: ["rows"] }, { kind: "component", type: AuditV2SortIconComponent, selector: "lib-audit-v2-sort-icon", inputs: ["active", "dir"] }] });
7051
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AuditV2ScheduleDetailComponent, selector: "lib-audit-v2-schedule-detail", inputs: { clientId: "clientId", scheduleId: "scheduleId", canEdit: "canEdit", fromDate: "fromDate", toDate: "toDate" }, outputs: { back: "back", edit: "edit" }, ngImport: i0, template: "<ng-container *ngIf=\"loading\">\n <div class=\"sd-titlebar\">\n <div class=\"sd-titletext\">\n <span class=\"av2-sk sd-sk-crumb\"></span>\n <span class=\"av2-sk av2-sk--title sd-sk-name\"></span>\n </div>\n </div>\n\n <div class=\"sd-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of cards\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\"><span class=\"av2-sk av2-sk--value sd-sk-value\"></span></div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-card\">\n <lib-audit-v2-shimmer></lib-audit-v2-shimmer>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"!loading\">\n <div class=\"sd-titlebar\">\n <div class=\"sd-titletext\">\n <div class=\"sd-crumb\"><a href=\"#\" (click)=\"goBack($event)\">Schedule</a> \u203A {{ name }}</div>\n <div class=\"sd-name\">{{ name }}</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" *ngIf=\"canEdit\" (click)=\"edit.emit(scheduleId)\">Edit rows</button>\n </div>\n\n <div class=\"sd-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of cards\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\">{{ m.value }}</div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-card\">\n <div class=\"sd-tablehead\">\n <div class=\"sd-titletext\">\n <div class=\"sd-card-title\">Scheduled info</div>\n <div class=\"sd-sub\">\n <span [attr.title]=\"auditsTip\">{{ rangeLabel }}</span>\n <ng-container *ngIf=\"rangeText\">\n \u00B7 {{ rangeOn ? 'Visits on ' + rangeText : 'All dates' }}\n <a class=\"sd-range-link\" (click)=\"toggleShowAll()\">{{ rangeOn ? 'Show all dates' : 'Show ' + rangeText + ' only' }}</a>\n </ng-container>\n </div>\n </div>\n <label class=\"sd-search\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"query\" (ngModelChange)=\"onQuery()\" placeholder=\"Search users or stores\">\n </label>\n </div>\n\n <div class=\"sd-scroll\">\n <div class=\"sd-grid sd-grid--head\">\n <div class=\"av2-sortable\" (click)=\"sortBy('date')\">Schedule date <lib-audit-v2-sort-icon [active]=\"sortKey === 'date'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('email')\">User email <lib-audit-v2-sort-icon [active]=\"sortKey === 'email'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('store')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'store'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('window')\">Visit window <lib-audit-v2-sort-icon [active]=\"sortKey === 'window'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('audit')\">Audit <lib-audit-v2-sort-icon [active]=\"sortKey === 'audit'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('status')\">Status <lib-audit-v2-sort-icon [active]=\"sortKey === 'status'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n </div>\n <div class=\"sd-grid sd-grid--row\" *ngFor=\"let r of paged\">\n <div>{{ r.date }}</div>\n <div class=\"sd-user\">\n <span class=\"sd-avatar\">{{ r.initials }}</span>\n <span class=\"sd-ellipsis\" [av2Tip]=\"r.email\">{{ r.email }}</span>\n </div>\n <!-- Store name (QA: the store code was shown); the id only for a row without a name. -->\n <div class=\"sd-store sd-ellipsis\" [av2Tip]=\"r.storeName || ''\">{{ r.storeName || '\u2014' }}</div>\n <div [class.sd-muted]=\"!r.hasWindow\" [class.sd-missed]=\"r.status === 'missed' && r.hasWindow\" [attr.title]=\"r.windowTip || null\">{{ r.window }}</div>\n <div class=\"sd-ellipsis\" [av2Tip]=\"r.audit\">{{ r.audit }}</div>\n <div>\n <span class=\"sd-pill\" [style.background]=\"bg(r.status)\" [style.color]=\"fg(r.status)\" [title]=\"r.note\">\n <span class=\"sd-dot\" [style.background]=\"dot(r.status)\"></span>{{ label(r.status) }}\n </span>\n </div>\n </div>\n <div *ngIf=\"!filtered.length\" class=\"av2-empty\">\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\n <div class=\"av2-empty-text\">\n <div class=\"av2-empty-title\">No data found</div>\n <div class=\"av2-empty-sub\">{{ rows.length ? 'No visits match this search.' : 'No rows yet. Use Edit rows to add users, stores and dates.' }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-foot\">\n <span>{{ countLabel }}</span>\n <lib-pagination *ngIf=\"filtered.length\" [itemsPerPage]=\"pageSize\" [pageSize]=\"pageSize\"\n [paginationSizes]=\"pageSizes\" [currentPage]=\"page\" [totalItems]=\"filtered.length\"\n (pageChange)=\"onPage($event)\" (pageSizeChange)=\"onPageSize($event)\"></lib-pagination>\n </div>\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}::ng-deep .tooltip.av2-tip{--bs-tooltip-bg: #fff;--bs-tooltip-color: #344054;--bs-tooltip-max-width: 320px;--bs-tooltip-opacity: 1}::ng-deep .tooltip.av2-tip .tooltip-inner{background-color:#fff!important;color:#344054!important;padding:8px 12px;border-radius:8px;font-size:13px;line-height:18px;font-weight:500;text-align:left;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,0 0 0 1px #eaecf0}::ng-deep .tooltip.av2-tip .tooltip-arrow:before{border-top-color:#fff;border-bottom-color:#fff}:host ::ng-deep lib-pagination{display:block}:host ::ng-deep lib-pagination .container{max-width:none;padding:0;display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;font-size:14px;color:#475467}:host ::ng-deep lib-pagination .mt-4{margin-top:0!important}:host ::ng-deep lib-pagination .container>.text-center{display:flex;align-items:center}:host ::ng-deep lib-pagination .container>.text-center>ul:not(.ngx-pagination){display:none}:host ::ng-deep lib-pagination pagination-controls{display:flex;align-items:center}:host ::ng-deep lib-pagination .sub-title{color:#475467!important;font-size:14px!important;font-weight:400!important;line-height:20px}:host ::ng-deep lib-pagination .border-val{height:40px;min-width:64px;padding:0 30px 0 12px!important;border:1px solid #D0D5DD!important;border-radius:8px!important;box-shadow:0 1px 2px #1018280d;background-color:#fff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\")!important;background-repeat:no-repeat!important;background-position:right 10px center!important;background-size:14px 14px!important;appearance:none;-webkit-appearance:none;font-size:14px;font-weight:500;color:#1d2939;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}:host ::ng-deep lib-pagination .border-val:hover{border-color:#98a2b3!important}:host ::ng-deep lib-pagination .border-val:focus{outline:none;border-color:#66c8ff!important;box-shadow:0 0 0 3px #eaf8ff}:host ::ng-deep lib-pagination .ngx-pagination{margin:0;padding:0;display:flex;align-items:center;gap:6px;color:#475467!important;font-size:14px!important;font-weight:500}:host ::ng-deep lib-pagination .ngx-pagination li{display:inline-flex;margin:0}:host ::ng-deep lib-pagination .ngx-pagination li.small-screen{display:none!important}:host ::ng-deep lib-pagination .ngx-pagination a,:host ::ng-deep lib-pagination .ngx-pagination button,:host ::ng-deep lib-pagination .ngx-pagination .current,:host ::ng-deep lib-pagination .ngx-pagination .disabled{min-width:40px!important;height:40px;padding:0 8px!important;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;line-height:20px;color:#475467}:host ::ng-deep lib-pagination .ngx-pagination a:hover,:host ::ng-deep lib-pagination .ngx-pagination button:hover{background:#f2f4f7;padding:0 8px!important}:host ::ng-deep lib-pagination .ngx-pagination .current{background:#eaf8ff!important;color:#00a3ff!important;font-weight:600;font-size:14px!important}:host ::ng-deep lib-pagination .ngx-pagination .disabled{color:#98a2b3}:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:after{margin:0}:host ::ng-deep lib-pagination .ngx-pagination .ellipsis:after{color:#98a2b3;padding:0}:host{display:flex;flex-direction:column;gap:20px}.sd-sk-crumb{width:140px;height:12px;margin:4px 0}.sd-sk-name{height:22px;margin:4px 0}.sd-sk-value{height:32px;margin:3px 0}.sd-titlebar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.sd-titletext{flex:1 1 240px;min-width:0;display:flex;flex-direction:column;gap:2px}.sd-crumb{font-size:13px;line-height:20px;color:#667085}.sd-crumb a{font-weight:600;color:#00a3ff;text-decoration:none;cursor:pointer}.sd-name{font-size:20px;line-height:30px;font-weight:700;color:#101828}.sd-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px}.sd-card{border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;display:flex;flex-direction:column}.sd-tablehead{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:20px 24px}.sd-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.sd-sub{font-size:14px;line-height:20px;color:#667085}.sd-search{flex:0 1 260px;min-width:180px;display:flex;align-items:center;gap:8px;height:36px;padding:0 12px;margin:0;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;color:#667085}.sd-search input{flex:1;min-width:0;height:34px;border:none;outline:none;background:transparent;font-size:13px;font-family:inherit;color:#101828}.sd-scroll{overflow-x:auto}.sd-grid{min-width:1180px;display:grid;grid-template-columns:1fr 1.6fr .9fr 1.1fr 1.5fr 1fr;gap:12px;align-items:center;padding:14px 24px}.sd-grid--head{padding:10px 24px;background:#f9fafb;border-top:1px solid #EAECF0;border-bottom:1px solid #EAECF0;font-size:12px;font-weight:600;color:#475467}.sd-grid--row{border-bottom:1px solid #F2F4F7;font-size:13px;color:#344054}.sd-user{display:flex;align-items:center;gap:8px;min-width:0}.sd-avatar{width:24px;height:24px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700}.sd-ellipsis{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-store{font-weight:600;color:#101828}.sd-muted{color:#98a2b3}.sd-missed{color:#d92d20}.sd-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:9999px;font-size:12px;font-weight:600}.sd-dot{width:6px;height:6px;border-radius:9999px;display:block}.sd-empty{padding:36px 24px;text-align:center;font-size:13px;color:#667085}.sd-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:16px 24px;font-size:14px;color:#667085}.sd-range-link{margin-left:6px;color:#00a3ff;font-weight:500;cursor:pointer}.sd-range-link:hover{text-decoration:underline}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: AuditV2TipDirective, selector: "[av2Tip]", inputs: ["av2Tip"] }, { kind: "component", type: AuditV2ShimmerComponent, selector: "lib-audit-v2-shimmer", inputs: ["rows"] }, { kind: "component", type: AuditV2SortIconComponent, selector: "lib-audit-v2-sort-icon", inputs: ["active", "dir"] }] });
7038
7052
  }
7039
7053
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuditV2ScheduleDetailComponent, decorators: [{
7040
7054
  type: Component,
7041
- args: [{ selector: 'lib-audit-v2-schedule-detail', template: "<ng-container *ngIf=\"loading\">\n <div class=\"sd-titlebar\">\n <div class=\"sd-titletext\">\n <span class=\"av2-sk sd-sk-crumb\"></span>\n <span class=\"av2-sk av2-sk--title sd-sk-name\"></span>\n </div>\n </div>\n\n <div class=\"sd-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of cards\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\"><span class=\"av2-sk av2-sk--value sd-sk-value\"></span></div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-card\">\n <lib-audit-v2-shimmer></lib-audit-v2-shimmer>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"!loading\">\n <div class=\"sd-titlebar\">\n <div class=\"sd-titletext\">\n <div class=\"sd-crumb\"><a href=\"#\" (click)=\"goBack($event)\">Schedule</a> \u203A {{ name }}</div>\n <div class=\"sd-name\">{{ name }}</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" *ngIf=\"canEdit\" (click)=\"edit.emit(scheduleId)\">Edit rows</button>\n </div>\n\n <div class=\"sd-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of cards\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\">{{ m.value }}</div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-card\">\n <div class=\"sd-tablehead\">\n <div class=\"sd-titletext\">\n <div class=\"sd-card-title\">Scheduled info</div>\n <div class=\"sd-sub\">\n {{ rangeLabel }}\n <ng-container *ngIf=\"rangeText\">\n \u00B7 {{ rangeOn ? 'Visits on ' + rangeText : 'All dates' }}\n <a class=\"sd-range-link\" (click)=\"toggleShowAll()\">{{ rangeOn ? 'Show all dates' : 'Show ' + rangeText + ' only' }}</a>\n </ng-container>\n </div>\n </div>\n <label class=\"sd-search\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"query\" (ngModelChange)=\"onQuery()\" placeholder=\"Search users or stores\">\n </label>\n </div>\n\n <div class=\"sd-scroll\">\n <div class=\"sd-grid sd-grid--head\">\n <div class=\"av2-sortable\" (click)=\"sortBy('date')\">Schedule date <lib-audit-v2-sort-icon [active]=\"sortKey === 'date'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('email')\">User email <lib-audit-v2-sort-icon [active]=\"sortKey === 'email'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('store')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'store'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('window')\">Visit window <lib-audit-v2-sort-icon [active]=\"sortKey === 'window'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('audit')\">Audit <lib-audit-v2-sort-icon [active]=\"sortKey === 'audit'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('status')\">Status <lib-audit-v2-sort-icon [active]=\"sortKey === 'status'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n </div>\n <div class=\"sd-grid sd-grid--row\" *ngFor=\"let r of paged\">\n <div>{{ r.date }}</div>\n <div class=\"sd-user\">\n <span class=\"sd-avatar\">{{ r.initials }}</span>\n <span class=\"sd-ellipsis\" [av2Tip]=\"r.email\">{{ r.email }}</span>\n </div>\n <!-- Store name (QA: the store code was shown); the id only for a row without a name. -->\n <div class=\"sd-store sd-ellipsis\" [av2Tip]=\"r.storeName || ''\">{{ r.storeName || '\u2014' }}</div>\n <div [class.sd-muted]=\"!r.hasWindow\" [class.sd-missed]=\"r.status === 'missed' && r.hasWindow\" [attr.title]=\"r.windowTip || null\">{{ r.window }}</div>\n <div class=\"sd-ellipsis\" [av2Tip]=\"r.audit\">{{ r.audit }}</div>\n <div>\n <span class=\"sd-pill\" [style.background]=\"bg(r.status)\" [style.color]=\"fg(r.status)\" [title]=\"r.note\">\n <span class=\"sd-dot\" [style.background]=\"dot(r.status)\"></span>{{ label(r.status) }}\n </span>\n </div>\n </div>\n <div *ngIf=\"!filtered.length\" class=\"av2-empty\">\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\n <div class=\"av2-empty-text\">\n <div class=\"av2-empty-title\">No data found</div>\n <div class=\"av2-empty-sub\">{{ rows.length ? 'No visits match this search.' : 'No rows yet. Use Edit rows to add users, stores and dates.' }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-foot\">\n <span>{{ countLabel }}</span>\n <lib-pagination *ngIf=\"filtered.length\" [itemsPerPage]=\"pageSize\" [pageSize]=\"pageSize\"\n [paginationSizes]=\"pageSizes\" [currentPage]=\"page\" [totalItems]=\"filtered.length\"\n (pageChange)=\"onPage($event)\" (pageSizeChange)=\"onPageSize($event)\"></lib-pagination>\n </div>\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}::ng-deep .tooltip.av2-tip{--bs-tooltip-bg: #fff;--bs-tooltip-color: #344054;--bs-tooltip-max-width: 320px;--bs-tooltip-opacity: 1}::ng-deep .tooltip.av2-tip .tooltip-inner{background-color:#fff!important;color:#344054!important;padding:8px 12px;border-radius:8px;font-size:13px;line-height:18px;font-weight:500;text-align:left;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,0 0 0 1px #eaecf0}::ng-deep .tooltip.av2-tip .tooltip-arrow:before{border-top-color:#fff;border-bottom-color:#fff}:host ::ng-deep lib-pagination{display:block}:host ::ng-deep lib-pagination .container{max-width:none;padding:0;display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;font-size:14px;color:#475467}:host ::ng-deep lib-pagination .mt-4{margin-top:0!important}:host ::ng-deep lib-pagination .container>.text-center{display:flex;align-items:center}:host ::ng-deep lib-pagination .container>.text-center>ul:not(.ngx-pagination){display:none}:host ::ng-deep lib-pagination pagination-controls{display:flex;align-items:center}:host ::ng-deep lib-pagination .sub-title{color:#475467!important;font-size:14px!important;font-weight:400!important;line-height:20px}:host ::ng-deep lib-pagination .border-val{height:40px;min-width:64px;padding:0 30px 0 12px!important;border:1px solid #D0D5DD!important;border-radius:8px!important;box-shadow:0 1px 2px #1018280d;background-color:#fff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\")!important;background-repeat:no-repeat!important;background-position:right 10px center!important;background-size:14px 14px!important;appearance:none;-webkit-appearance:none;font-size:14px;font-weight:500;color:#1d2939;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}:host ::ng-deep lib-pagination .border-val:hover{border-color:#98a2b3!important}:host ::ng-deep lib-pagination .border-val:focus{outline:none;border-color:#66c8ff!important;box-shadow:0 0 0 3px #eaf8ff}:host ::ng-deep lib-pagination .ngx-pagination{margin:0;padding:0;display:flex;align-items:center;gap:6px;color:#475467!important;font-size:14px!important;font-weight:500}:host ::ng-deep lib-pagination .ngx-pagination li{display:inline-flex;margin:0}:host ::ng-deep lib-pagination .ngx-pagination li.small-screen{display:none!important}:host ::ng-deep lib-pagination .ngx-pagination a,:host ::ng-deep lib-pagination .ngx-pagination button,:host ::ng-deep lib-pagination .ngx-pagination .current,:host ::ng-deep lib-pagination .ngx-pagination .disabled{min-width:40px!important;height:40px;padding:0 8px!important;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;line-height:20px;color:#475467}:host ::ng-deep lib-pagination .ngx-pagination a:hover,:host ::ng-deep lib-pagination .ngx-pagination button:hover{background:#f2f4f7;padding:0 8px!important}:host ::ng-deep lib-pagination .ngx-pagination .current{background:#eaf8ff!important;color:#00a3ff!important;font-weight:600;font-size:14px!important}:host ::ng-deep lib-pagination .ngx-pagination .disabled{color:#98a2b3}:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:after{margin:0}:host ::ng-deep lib-pagination .ngx-pagination .ellipsis:after{color:#98a2b3;padding:0}:host{display:flex;flex-direction:column;gap:20px}.sd-sk-crumb{width:140px;height:12px;margin:4px 0}.sd-sk-name{height:22px;margin:4px 0}.sd-sk-value{height:32px;margin:3px 0}.sd-titlebar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.sd-titletext{flex:1 1 240px;min-width:0;display:flex;flex-direction:column;gap:2px}.sd-crumb{font-size:13px;line-height:20px;color:#667085}.sd-crumb a{font-weight:600;color:#00a3ff;text-decoration:none;cursor:pointer}.sd-name{font-size:20px;line-height:30px;font-weight:700;color:#101828}.sd-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px}.sd-card{border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;display:flex;flex-direction:column}.sd-tablehead{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:20px 24px}.sd-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.sd-sub{font-size:14px;line-height:20px;color:#667085}.sd-search{flex:0 1 260px;min-width:180px;display:flex;align-items:center;gap:8px;height:36px;padding:0 12px;margin:0;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;color:#667085}.sd-search input{flex:1;min-width:0;height:34px;border:none;outline:none;background:transparent;font-size:13px;font-family:inherit;color:#101828}.sd-scroll{overflow-x:auto}.sd-grid{min-width:1180px;display:grid;grid-template-columns:1fr 1.6fr .9fr 1.1fr 1.5fr 1fr;gap:12px;align-items:center;padding:14px 24px}.sd-grid--head{padding:10px 24px;background:#f9fafb;border-top:1px solid #EAECF0;border-bottom:1px solid #EAECF0;font-size:12px;font-weight:600;color:#475467}.sd-grid--row{border-bottom:1px solid #F2F4F7;font-size:13px;color:#344054}.sd-user{display:flex;align-items:center;gap:8px;min-width:0}.sd-avatar{width:24px;height:24px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700}.sd-ellipsis{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-store{font-weight:600;color:#101828}.sd-muted{color:#98a2b3}.sd-missed{color:#d92d20}.sd-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:9999px;font-size:12px;font-weight:600}.sd-dot{width:6px;height:6px;border-radius:9999px;display:block}.sd-empty{padding:36px 24px;text-align:center;font-size:13px;color:#667085}.sd-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:16px 24px;font-size:14px;color:#667085}.sd-range-link{margin-left:6px;color:#00a3ff;font-weight:500;cursor:pointer}.sd-range-link:hover{text-decoration:underline}\n"] }]
7055
+ args: [{ selector: 'lib-audit-v2-schedule-detail', template: "<ng-container *ngIf=\"loading\">\n <div class=\"sd-titlebar\">\n <div class=\"sd-titletext\">\n <span class=\"av2-sk sd-sk-crumb\"></span>\n <span class=\"av2-sk av2-sk--title sd-sk-name\"></span>\n </div>\n </div>\n\n <div class=\"sd-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of cards\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\"><span class=\"av2-sk av2-sk--value sd-sk-value\"></span></div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-card\">\n <lib-audit-v2-shimmer></lib-audit-v2-shimmer>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"!loading\">\n <div class=\"sd-titlebar\">\n <div class=\"sd-titletext\">\n <div class=\"sd-crumb\"><a href=\"#\" (click)=\"goBack($event)\">Schedule</a> \u203A {{ name }}</div>\n <div class=\"sd-name\">{{ name }}</div>\n </div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" *ngIf=\"canEdit\" (click)=\"edit.emit(scheduleId)\">Edit rows</button>\n </div>\n\n <div class=\"sd-metrics\">\n <div class=\"av2-ocard\" *ngFor=\"let m of cards\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count\">{{ m.value }}</div>\n <div class=\"av2-ocard-text\">{{ m.label }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-card\">\n <div class=\"sd-tablehead\">\n <div class=\"sd-titletext\">\n <div class=\"sd-card-title\">Scheduled info</div>\n <div class=\"sd-sub\">\n <span [attr.title]=\"auditsTip\">{{ rangeLabel }}</span>\n <ng-container *ngIf=\"rangeText\">\n \u00B7 {{ rangeOn ? 'Visits on ' + rangeText : 'All dates' }}\n <a class=\"sd-range-link\" (click)=\"toggleShowAll()\">{{ rangeOn ? 'Show all dates' : 'Show ' + rangeText + ' only' }}</a>\n </ng-container>\n </div>\n </div>\n <label class=\"sd-search\">\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" [(ngModel)]=\"query\" (ngModelChange)=\"onQuery()\" placeholder=\"Search users or stores\">\n </label>\n </div>\n\n <div class=\"sd-scroll\">\n <div class=\"sd-grid sd-grid--head\">\n <div class=\"av2-sortable\" (click)=\"sortBy('date')\">Schedule date <lib-audit-v2-sort-icon [active]=\"sortKey === 'date'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('email')\">User email <lib-audit-v2-sort-icon [active]=\"sortKey === 'email'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('store')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'store'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('window')\">Visit window <lib-audit-v2-sort-icon [active]=\"sortKey === 'window'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('audit')\">Audit <lib-audit-v2-sort-icon [active]=\"sortKey === 'audit'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n <div class=\"av2-sortable\" (click)=\"sortBy('status')\">Status <lib-audit-v2-sort-icon [active]=\"sortKey === 'status'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></div>\n </div>\n <div class=\"sd-grid sd-grid--row\" *ngFor=\"let r of paged\">\n <div>{{ r.date }}</div>\n <div class=\"sd-user\">\n <span class=\"sd-avatar\">{{ r.initials }}</span>\n <span class=\"sd-ellipsis\" [av2Tip]=\"r.email\">{{ r.email }}</span>\n </div>\n <!-- Store name (QA: the store code was shown); the id only for a row without a name. -->\n <div class=\"sd-store sd-ellipsis\" [av2Tip]=\"r.storeName || ''\">{{ r.storeName || '\u2014' }}</div>\n <div [class.sd-muted]=\"!r.hasWindow\" [class.sd-missed]=\"r.status === 'missed' && r.hasWindow\" [attr.title]=\"r.windowTip || null\">{{ r.window }}</div>\n <div class=\"sd-ellipsis\" [av2Tip]=\"r.audit\">{{ r.audit }}</div>\n <div>\n <span class=\"sd-pill\" [style.background]=\"bg(r.status)\" [style.color]=\"fg(r.status)\" [title]=\"r.note\">\n <span class=\"sd-dot\" [style.background]=\"dot(r.status)\"></span>{{ label(r.status) }}\n </span>\n </div>\n </div>\n <div *ngIf=\"!filtered.length\" class=\"av2-empty\">\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\n <div class=\"av2-empty-text\">\n <div class=\"av2-empty-title\">No data found</div>\n <div class=\"av2-empty-sub\">{{ rows.length ? 'No visits match this search.' : 'No rows yet. Use Edit rows to add users, stores and dates.' }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"sd-foot\">\n <span>{{ countLabel }}</span>\n <lib-pagination *ngIf=\"filtered.length\" [itemsPerPage]=\"pageSize\" [pageSize]=\"pageSize\"\n [paginationSizes]=\"pageSizes\" [currentPage]=\"page\" [totalItems]=\"filtered.length\"\n (pageChange)=\"onPage($event)\" (pageSizeChange)=\"onPageSize($event)\"></lib-pagination>\n </div>\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}::ng-deep .tooltip.av2-tip{--bs-tooltip-bg: #fff;--bs-tooltip-color: #344054;--bs-tooltip-max-width: 320px;--bs-tooltip-opacity: 1}::ng-deep .tooltip.av2-tip .tooltip-inner{background-color:#fff!important;color:#344054!important;padding:8px 12px;border-radius:8px;font-size:13px;line-height:18px;font-weight:500;text-align:left;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,0 0 0 1px #eaecf0}::ng-deep .tooltip.av2-tip .tooltip-arrow:before{border-top-color:#fff;border-bottom-color:#fff}:host ::ng-deep lib-pagination{display:block}:host ::ng-deep lib-pagination .container{max-width:none;padding:0;display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;font-size:14px;color:#475467}:host ::ng-deep lib-pagination .mt-4{margin-top:0!important}:host ::ng-deep lib-pagination .container>.text-center{display:flex;align-items:center}:host ::ng-deep lib-pagination .container>.text-center>ul:not(.ngx-pagination){display:none}:host ::ng-deep lib-pagination pagination-controls{display:flex;align-items:center}:host ::ng-deep lib-pagination .sub-title{color:#475467!important;font-size:14px!important;font-weight:400!important;line-height:20px}:host ::ng-deep lib-pagination .border-val{height:40px;min-width:64px;padding:0 30px 0 12px!important;border:1px solid #D0D5DD!important;border-radius:8px!important;box-shadow:0 1px 2px #1018280d;background-color:#fff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\")!important;background-repeat:no-repeat!important;background-position:right 10px center!important;background-size:14px 14px!important;appearance:none;-webkit-appearance:none;font-size:14px;font-weight:500;color:#1d2939;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}:host ::ng-deep lib-pagination .border-val:hover{border-color:#98a2b3!important}:host ::ng-deep lib-pagination .border-val:focus{outline:none;border-color:#66c8ff!important;box-shadow:0 0 0 3px #eaf8ff}:host ::ng-deep lib-pagination .ngx-pagination{margin:0;padding:0;display:flex;align-items:center;gap:6px;color:#475467!important;font-size:14px!important;font-weight:500}:host ::ng-deep lib-pagination .ngx-pagination li{display:inline-flex;margin:0}:host ::ng-deep lib-pagination .ngx-pagination li.small-screen{display:none!important}:host ::ng-deep lib-pagination .ngx-pagination a,:host ::ng-deep lib-pagination .ngx-pagination button,:host ::ng-deep lib-pagination .ngx-pagination .current,:host ::ng-deep lib-pagination .ngx-pagination .disabled{min-width:40px!important;height:40px;padding:0 8px!important;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;line-height:20px;color:#475467}:host ::ng-deep lib-pagination .ngx-pagination a:hover,:host ::ng-deep lib-pagination .ngx-pagination button:hover{background:#f2f4f7;padding:0 8px!important}:host ::ng-deep lib-pagination .ngx-pagination .current{background:#eaf8ff!important;color:#00a3ff!important;font-weight:600;font-size:14px!important}:host ::ng-deep lib-pagination .ngx-pagination .disabled{color:#98a2b3}:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:after{margin:0}:host ::ng-deep lib-pagination .ngx-pagination .ellipsis:after{color:#98a2b3;padding:0}:host{display:flex;flex-direction:column;gap:20px}.sd-sk-crumb{width:140px;height:12px;margin:4px 0}.sd-sk-name{height:22px;margin:4px 0}.sd-sk-value{height:32px;margin:3px 0}.sd-titlebar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.sd-titletext{flex:1 1 240px;min-width:0;display:flex;flex-direction:column;gap:2px}.sd-crumb{font-size:13px;line-height:20px;color:#667085}.sd-crumb a{font-weight:600;color:#00a3ff;text-decoration:none;cursor:pointer}.sd-name{font-size:20px;line-height:30px;font-weight:700;color:#101828}.sd-metrics{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px}.sd-card{border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;display:flex;flex-direction:column}.sd-tablehead{display:flex;flex-wrap:wrap;align-items:center;gap:12px;padding:20px 24px}.sd-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.sd-sub{font-size:14px;line-height:20px;color:#667085}.sd-search{flex:0 1 260px;min-width:180px;display:flex;align-items:center;gap:8px;height:36px;padding:0 12px;margin:0;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;color:#667085}.sd-search input{flex:1;min-width:0;height:34px;border:none;outline:none;background:transparent;font-size:13px;font-family:inherit;color:#101828}.sd-scroll{overflow-x:auto}.sd-grid{min-width:1180px;display:grid;grid-template-columns:1fr 1.6fr .9fr 1.1fr 1.5fr 1fr;gap:12px;align-items:center;padding:14px 24px}.sd-grid--head{padding:10px 24px;background:#f9fafb;border-top:1px solid #EAECF0;border-bottom:1px solid #EAECF0;font-size:12px;font-weight:600;color:#475467}.sd-grid--row{border-bottom:1px solid #F2F4F7;font-size:13px;color:#344054}.sd-user{display:flex;align-items:center;gap:8px;min-width:0}.sd-avatar{width:24px;height:24px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700}.sd-ellipsis{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-store{font-weight:600;color:#101828}.sd-muted{color:#98a2b3}.sd-missed{color:#d92d20}.sd-pill{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:9999px;font-size:12px;font-weight:600}.sd-dot{width:6px;height:6px;border-radius:9999px;display:block}.sd-empty{padding:36px 24px;text-align:center;font-size:13px;color:#667085}.sd-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:16px 24px;font-size:14px;color:#667085}.sd-range-link{margin-left:6px;color:#00a3ff;font-weight:500;cursor:pointer}.sd-range-link:hover{text-decoration:underline}\n"] }]
7042
7056
  }], ctorParameters: () => [{ type: TraxService }, { type: i3.ToastService }, { type: i0.ChangeDetectorRef }], propDecorators: { clientId: [{
7043
7057
  type: Input
7044
7058
  }], scheduleId: [{
@@ -8217,6 +8231,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
8217
8231
  const PASS_MARK = 75;
8218
8232
  /** Rows without a circle head in the store hierarchy are grouped under this key. */
8219
8233
  const UNASSIGNED = '__unassigned';
8234
+ /** Visits per /audit/dashboard/detail call when exporting (the API's max limit). */
8235
+ const EXPORT_PAGE = 5000;
8220
8236
  /**
8221
8237
  * Reports ("Reports — Store audit report" prototype), read from POST /trax/audit/reports: one call returns every
8222
8238
  * store of the header scope with its score, result, last audit, cluster and hierarchy line, plus the circle head /
@@ -8385,6 +8401,9 @@ class AuditV2ReportsComponent {
8385
8401
  return this.pageOf(this.storeRows);
8386
8402
  }
8387
8403
  get storeLabel() {
8404
+ if (this.storeSel && !this.storeSel.size) {
8405
+ return 'No stores selected';
8406
+ }
8388
8407
  return this.storeSel
8389
8408
  ? this.storeSel.size + (this.storeSel.size === 1 ? ' store' : ' stores') + ' selected'
8390
8409
  : 'All stores (' + this.allStores.length + ')';
@@ -8817,6 +8836,11 @@ class AuditV2ReportsComponent {
8817
8836
  /** Apply: the draft's filters become the page's; a new date range refetches. */
8818
8837
  applyFilters() {
8819
8838
  const d = this.draft;
8839
+ if (d && d.mode === 'store' && d.storeSel && !d.storeSel.size) {
8840
+ this.activeCat = 'scope';
8841
+ this.toast.getErrorToast('Select at least one store');
8842
+ return;
8843
+ }
8820
8844
  if (d) {
8821
8845
  const datesChanged = d.from !== this.from || d.to !== this.to;
8822
8846
  this.from = d.from;
@@ -8895,9 +8919,10 @@ class AuditV2ReportsComponent {
8895
8919
  const n = this.storeScope.length;
8896
8920
  return this.storeLabel + ' · ' + n + (n === 1 ? ' store' : ' stores') + ' in scope';
8897
8921
  }
8922
+ /** null = every store; an empty set = none ticked (Select All unticked), which Apply does not accept. */
8898
8923
  applyPick(ids) {
8899
8924
  const uniq = [...new Set(ids)];
8900
- this.storeSel = !uniq.length || uniq.length >= this.allStores.length ? null : new Set(uniq);
8925
+ this.storeSel = uniq.length >= this.allStores.length ? null : new Set(uniq);
8901
8926
  this.page = 1;
8902
8927
  }
8903
8928
  get pickedIds() {
@@ -9009,52 +9034,35 @@ class AuditV2ReportsComponent {
9009
9034
  }
9010
9035
  }
9011
9036
  // ---------------------------------------------------------------------------
9012
- // Export (CSV, built in the browser from the loaded report)
9037
+ // Export (QA 12 Oct): every export on this page is the Dashboard detail (Monthly Performance) "Audit Info"
9038
+ // workbook - one row per audit visit of the chosen stores in the report period - read from
9039
+ // POST /trax/audit/dashboard/detail with by 'scope' (no single audit / store / user), 5000 rows a call.
9013
9040
  // ---------------------------------------------------------------------------
9014
- storeHeader = ['Store', 'Store ID', 'Cluster', 'Circle head', 'Zone manager', 'Area manager', 'Audited', 'Score', 'Result', 'Last audit'];
9015
- storeLine(s) {
9016
- return [s.name, s.key, s.cluster, s.circle, s.zone, s.aom, s.audited ? 'Yes' : 'No', this.scoreText(s), this.resultText(s), s.lastAudit || 'No audit'];
9017
- }
9018
- /** Top Export: the whole report as filtered (every page): stores in the Store view, the current level in the User view. */
9041
+ /** True while an export is being fetched; a second click waits for it. */
9042
+ exporting = false;
9043
+ /** Top Export: the report as filtered (every page): its stores in the Store view, the stores under the current level in the User view. */
9019
9044
  exportAll() {
9020
9045
  if (this.loading) {
9021
9046
  return;
9022
9047
  }
9023
9048
  if (this.isStoreMode || this.level === 'store') {
9024
9049
  const list = this.isStoreMode ? this.storeRows : this.userStores;
9025
- if (!list.length) {
9026
- this.toast.getErrorToast('No stores to export');
9027
- return;
9028
- }
9029
- this.downloadCsv([this.storeHeader, ...list.map(s => this.storeLine(s))], this.isStoreMode ? 'store-report' : 'store-report-' + this.hierarchyTitle);
9030
- }
9031
- else {
9032
- const list = this.filteredRows;
9033
- if (!list.length) {
9034
- this.toast.getErrorToast('Nothing to export');
9035
- return;
9036
- }
9037
- const t = this.totals;
9038
- this.downloadCsv([
9039
- [this.levelLabel, 'Email', 'Total stores', 'Audited', 'Not audited', 'Coverage', 'Avg audit score', 'Failed store %'],
9040
- ...list.map(r => [r.name, r.email, r.total, r.audited, r.notAudited, r.coverage, r.avgScore, r.failedPct]),
9041
- ['Total', '', t.total, t.audited, t.total - t.audited, this.totalCoverage, this.totalAverage, this.totalFailedPct]
9042
- ], 'user-report-' + this.hierarchyTitle);
9050
+ this.exportVisits(list.map(s => s.key), this.isStoreMode ? 'Store report' : 'User report - ' + this.hierarchyTitle);
9051
+ return;
9043
9052
  }
9044
- this.toast.getSuccessToast(this.isStoreMode ? 'Store report exported' : 'User report exported');
9053
+ const stores = this.filteredRows.reduce((all, row) => all.concat(this.storesUnder(row)), []);
9054
+ this.exportVisits(stores.map(s => s.key), 'User report - ' + this.hierarchyTitle);
9045
9055
  }
9046
- /** Row Export in a store table: that store's line; a store with no audit in the period has nothing to export. */
9056
+ /** Row Export in a store table: that store's visits. */
9047
9057
  exportStore(s) {
9048
- if (!s.audited) {
9049
- this.toast.getErrorToast('No audit to export for ' + s.name);
9050
- return;
9051
- }
9052
- this.downloadCsv([this.storeHeader, this.storeLine(s)], 'audit-report-' + s.name);
9053
- this.toast.getSuccessToast('Report exported for ' + s.name);
9058
+ this.exportVisits([s.key], s.name);
9054
9059
  }
9055
- /** Row Export in the roll-up table: every store under that row. */
9060
+ /** Row Export in the roll-up table: the visits of every store under that row. */
9056
9061
  exportRow(row) {
9057
- const stores = this.allStores.filter(s => {
9062
+ this.exportVisits(this.storesUnder(row).map(s => s.key), row.name);
9063
+ }
9064
+ storesUnder(row) {
9065
+ return this.allStores.filter(s => {
9058
9066
  if (row.key === UNASSIGNED) {
9059
9067
  return !s.circleKey;
9060
9068
  }
@@ -9066,21 +9074,80 @@ class AuditV2ReportsComponent {
9066
9074
  }
9067
9075
  return s.aomKey === row.key;
9068
9076
  });
9069
- if (!stores.length) {
9070
- this.toast.getErrorToast('No stores to export for ' + row.name);
9077
+ }
9078
+ exportVisits(storeIds, title) {
9079
+ const ids = [...new Set(storeIds.filter(Boolean))];
9080
+ if (!ids.length) {
9081
+ this.toast.getErrorToast('No stores to export');
9082
+ return;
9083
+ }
9084
+ if (this.exporting) {
9071
9085
  return;
9072
9086
  }
9073
- this.downloadCsv([this.storeHeader, ...stores.map(s => this.storeLine(s))], 'audit-report-' + row.name);
9074
- this.toast.getSuccessToast('Report exported for ' + row.name);
9087
+ this.exporting = true;
9088
+ const visits = [];
9089
+ const done = (error) => {
9090
+ this.exporting = false;
9091
+ if (error) {
9092
+ this.toast.getErrorToast(error);
9093
+ }
9094
+ else if (!visits.length) {
9095
+ this.toast.getErrorToast('No audit visits to export for ' + title);
9096
+ }
9097
+ else {
9098
+ this.traxService.exportWorkbook([{ name: 'Audit Info', rows: visits.map(r => this.visitLine(r)) }], `${title} - audit info - ${this.from} to ${this.to}`);
9099
+ this.toast.getSuccessToast('Report exported for ' + title);
9100
+ }
9101
+ this.cd.detectChanges();
9102
+ };
9103
+ const fetchPage = (offset) => {
9104
+ this.traxService.auditDashboardDetail({
9105
+ clientId: this.headerData?.client,
9106
+ fromDate: this.from,
9107
+ toDate: this.to,
9108
+ storeId: ids,
9109
+ by: 'scope',
9110
+ status: 'all',
9111
+ searchValue: '',
9112
+ limit: EXPORT_PAGE,
9113
+ offset
9114
+ }).pipe(takeUntil$1(this.destroy$)).subscribe({
9115
+ next: (res) => {
9116
+ if (res?.code !== 200) {
9117
+ done('Unable to export');
9118
+ return;
9119
+ }
9120
+ const page = res.data?.rows || [];
9121
+ visits.push(...page);
9122
+ if (page.length === EXPORT_PAGE && visits.length < (res.data?.totalCount || 0)) {
9123
+ fetchPage(offset + 1);
9124
+ return;
9125
+ }
9126
+ done();
9127
+ },
9128
+ error: () => done('Unable to export')
9129
+ });
9130
+ };
9131
+ fetchPage(1);
9075
9132
  }
9076
- downloadCsv(lines, name) {
9077
- const q = (v) => '"' + String(v ?? '').replace(/"/g, '""') + '"';
9078
- const blob = new Blob(['' + lines.map(l => l.map(q).join(',')).join('\r\n')], { type: 'text/csv;charset=utf-8;' });
9079
- const a = document.createElement('a');
9080
- a.href = URL.createObjectURL(blob);
9081
- a.download = name.replace(/[^\w-]+/g, '_') + '-' + this.from + '-to-' + this.to + '.csv';
9082
- a.click();
9083
- URL.revokeObjectURL(a.href);
9133
+ /** The Dashboard detail export's columns (audit-v2-detail exportRows), one visit per row. */
9134
+ visitLine(r) {
9135
+ const status = r.status === 'submit' ? 'Submitted' : (r.status === 'inprogress' ? 'In Progress' : 'Open');
9136
+ const time = (v) => (v ? dayjs(v).format('hh:mm A, DD MMM YYYY') : '--');
9137
+ return {
9138
+ 'Date': r.date ? dayjs(r.date).format('DD MMM YYYY') : '--',
9139
+ 'Audit Name': r.checkListName,
9140
+ 'Store ID': r.storeId,
9141
+ 'Store Name': r.storeName,
9142
+ 'User Name': r.userName,
9143
+ 'Submitted By': r.userEmail,
9144
+ 'Status': status + (r.redo ? ' (Redo)' : ''),
9145
+ 'Submitted On': time(r.submittedOn),
9146
+ 'Submission Count': r.submissionCount,
9147
+ 'Flags': r.flags,
9148
+ 'Approved By': r.approvedBy || '--',
9149
+ 'Approved On': time(r.approvedOn)
9150
+ };
9084
9151
  }
9085
9152
  trackByRow(_, row) {
9086
9153
  return row.key || row.name;
@@ -9095,11 +9162,11 @@ class AuditV2ReportsComponent {
9095
9162
  return c.key;
9096
9163
  }
9097
9164
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuditV2ReportsComponent, deps: [{ token: TraxService }, { token: i2.GlobalStateService }, { token: i3.ToastService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
9098
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AuditV2ReportsComponent, selector: "lib-audit-v2-reports", ngImport: i0, template: "<div class=\"av2-page audit-reports\">\r\n\r\n <!-- Breadcrumb + title -->\r\n <div class=\"rp-head\">\r\n <div class=\"rp-crumb\">Audits \u203A <span class=\"rp-crumb-current\">Reports</span></div>\r\n <div class=\"rp-title\">Store audit report</div>\r\n </div>\r\n\r\n <!-- Filter chips, Filter button at the right end (QA 9 Oct); Export moved to the table head beside its search. -->\r\n <div class=\"rp-controls\">\r\n <button type=\"button\" class=\"rp-chip\" *ngFor=\"let c of chips; trackBy: trackByChip\" (click)=\"openFilters(c.key)\"\r\n [title]=\"c.label + ': ' + c.value\">\r\n <span class=\"rp-chip-key\">{{ c.label }}</span><span class=\"rp-chip-value\">{{ c.value }}</span>\r\n </button>\r\n <div class=\"av2-grow\"></div>\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost rp-filterbtn\" (click)=\"openFilters()\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"></polygon></svg>\r\n Filter\r\n <span class=\"rp-countpill\">{{ filterCount }}</span>\r\n </button>\r\n </div>\r\n\r\n <!-- User view: where in the hierarchy -->\r\n <div class=\"rp-drillbar\" *ngIf=\"!isStoreMode\">\r\n <ng-container *ngFor=\"let c of crumbs; let last = last; let first = first\">\r\n <div class=\"rp-drillcrumb\" [class.is-current]=\"last\" (click)=\"goToLevel(c.level)\">\r\n <span class=\"rp-drillsep\" *ngIf=\"!first\">\u203A</span>{{ c.label }}\r\n </div>\r\n </ng-container>\r\n <div class=\"av2-grow\"></div>\r\n <div class=\"rp-hint\">{{ hint }}</div>\r\n </div>\r\n\r\n <!-- Scope -->\r\n <div class=\"rp-scope\">\r\n <div class=\"rp-scope-title\">{{ scopeTitle }}</div>\r\n <div class=\"rp-scope-meta\">{{ scopeMeta }}</div>\r\n </div>\r\n\r\n <!-- KPIs -->\r\n <div class=\"rp-kpis\">\r\n <!-- Old Checklist summary card: figure + label in the gradient strip, note below. -->\r\n <div class=\"av2-ocard\" *ngFor=\"let kpi of kpis\">\r\n <div class=\"av2-ocard-head\">\r\n <div class=\"av2-ocard-count rp-kpi-value\" [class.is-good]=\"kpi.tone === 'good'\" [class.is-bad]=\"kpi.tone === 'bad'\">\r\n <span *ngIf=\"loading\" class=\"av2-sk av2-sk--value rp-sk-value\"></span>\r\n <ng-container *ngIf=\"!loading\">{{ kpi.value }}</ng-container>\r\n </div>\r\n <div class=\"av2-ocard-text\">{{ kpi.label }}</div>\r\n </div>\r\n <div class=\"av2-ocard-body\">\r\n <span *ngIf=\"loading\" class=\"av2-sk av2-sk--note\"></span>\r\n <div *ngIf=\"!loading\" class=\"av2-ocard-note\">{{ kpi.note }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Report table -->\r\n <section class=\"rp-card\">\r\n <div class=\"rp-card-head\">\r\n <div class=\"rp-card-text\">\r\n <ng-container *ngIf=\"isStoreMode\">\r\n <div class=\"rp-card-title\">Store report</div>\r\n <div class=\"rp-card-meta\">{{ storeRows.length }} {{ storeRows.length === 1 ? 'store' : 'stores' }} \u00B7 audits submitted in the period</div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!isStoreMode\">\r\n <div class=\"rp-card-title\">{{ tableTitle }}</div>\r\n <div class=\"rp-card-meta\">{{ tableMeta }}</div>\r\n </ng-container>\r\n </div>\r\n <div class=\"av2-grow\"></div>\r\n <label class=\"av2-search rp-search\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\">\r\n <circle cx=\"11\" cy=\"11\" r=\"7\"></circle>\r\n <line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line>\r\n </svg>\r\n <input type=\"text\" [placeholder]=\"isStoreMode ? 'Search store' : 'Search ' + levelLabel.toLowerCase()\"\r\n [(ngModel)]=\"search\" (ngModelChange)=\"onSearchChange()\">\r\n </label>\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost\" [disabled]=\"loading\" (click)=\"exportAll()\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 16V4\"></path><polyline points=\"7 9 12 4 17 9\"></polyline><path d=\"M4 16v4h16v-4\"></path></svg>\r\n Export\r\n </button>\r\n </div>\r\n\r\n <lib-audit-v2-shimmer *ngIf=\"loading\"></lib-audit-v2-shimmer>\r\n\r\n <!-- Store view: one row per store -->\r\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && isStoreMode && tableCount\">\r\n <table class=\"rp-table rp-table--stores\">\r\n <thead>\r\n <tr>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('cluster')\">Cluster <lib-audit-v2-sort-icon [active]=\"sortKey === 'cluster'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('aom')\">Area manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'aom'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('score')\">Score <lib-audit-v2-sort-icon [active]=\"sortKey === 'score'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('status')\">Result <lib-audit-v2-sort-icon [active]=\"sortKey === 'status'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('lastAudit')\">Last audit <lib-audit-v2-sort-icon [active]=\"sortKey === 'lastAudit'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right\">Export</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let s of storePageRows; trackBy: trackByKey\">\r\n <td class=\"is-strong rp-cell-name\" [av2Tip]=\"s.name\">{{ s.name }}</td>\r\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.cluster\">{{ s.cluster || '\u2014' }}</td>\r\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.aom\">{{ s.aom || '\u2014' }}</td>\r\n <td class=\"t-right\" [class.is-muted]=\"!s.audited\">{{ s.audited ? 'Yes' : 'No' }}</td>\r\n <td class=\"t-right is-strong\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\"\r\n [class.is-muted]=\"s.score === null\">{{ scoreText(s) }}</td>\r\n <td class=\"t-right\">\r\n <span class=\"rp-result\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\">{{ resultText(s) }}</span>\r\n </td>\r\n <td class=\"t-right\" [class.is-muted]=\"!s.lastAudit\">{{ s.lastAudit || 'No audit' }}</td>\r\n <td class=\"t-right\">\r\n <button type=\"button\" class=\"rp-export\" (click)=\"exportStore(s)\">Export</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tfoot>\r\n <tr class=\"rp-total\">\r\n <td>Total</td>\r\n <td></td>\r\n <td></td>\r\n <td class=\"t-right\">{{ totalAuditedOf }}</td>\r\n <td class=\"t-right\">{{ totalAverage }}</td>\r\n <td class=\"t-right\">{{ totals.failed }} fail</td>\r\n <td></td>\r\n <td></td>\r\n </tr>\r\n </tfoot>\r\n </table>\r\n </div>\r\n\r\n <!-- User view: circle head / zone manager / area manager roll-up -->\r\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && !isStoreMode && level !== 'store' && tableCount\">\r\n <table class=\"rp-table\">\r\n <thead>\r\n <tr>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">{{ levelLabel }} <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('total')\">Total stores <lib-audit-v2-sort-icon [active]=\"sortKey === 'total'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('notAudited')\">Not audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'notAudited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('coverage')\">Coverage <lib-audit-v2-sort-icon [active]=\"sortKey === 'coverage'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('avgScore')\">Avg audit score <lib-audit-v2-sort-icon [active]=\"sortKey === 'avgScore'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('failedPct')\">Failed store % <lib-audit-v2-sort-icon [active]=\"sortKey === 'failedPct'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right\">Report</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let row of pageRows; trackBy: trackByRow\" class=\"rp-row\" (click)=\"openRow(row)\">\r\n <td>\r\n <div class=\"rp-name\">\r\n <span class=\"rp-name-main\">{{ row.name }}</span>\r\n <span class=\"rp-name-sub\" *ngIf=\"row.email\">{{ row.email }}</span>\r\n </div>\r\n </td>\r\n <td class=\"t-right\">{{ row.total }}</td>\r\n <td class=\"t-right\">{{ row.audited }}</td>\r\n <td class=\"t-right\" [class.is-muted]=\"!row.notAudited\">{{ row.notAudited }}</td>\r\n <td class=\"t-right\">{{ row.coverage }}</td>\r\n <td class=\"t-right is-strong\">{{ row.avgScore }}</td>\r\n <td class=\"t-right is-strong\" [class.is-fail]=\"isHighFail(row)\">{{ row.failedPct }}</td>\r\n <td class=\"t-right\">\r\n <button type=\"button\" class=\"rp-export\" (click)=\"exportRow(row); $event.stopPropagation()\">Export</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tfoot>\r\n <tr class=\"rp-total\">\r\n <td>Total</td>\r\n <td class=\"t-right\">{{ totals.total }}</td>\r\n <td class=\"t-right\">{{ totals.audited }}</td>\r\n <td class=\"t-right\">{{ totals.total - totals.audited }}</td>\r\n <td class=\"t-right\">{{ totalCoverage }}</td>\r\n <td class=\"t-right\">{{ totalAverage }}</td>\r\n <td class=\"t-right\">{{ totalFailedPct }}</td>\r\n <td></td>\r\n </tr>\r\n </tfoot>\r\n </table>\r\n </div>\r\n\r\n <!-- User view, deepest level: the area manager's stores -->\r\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && !isStoreMode && level === 'store' && tableCount\">\r\n <table class=\"rp-table rp-table--userstores\">\r\n <thead>\r\n <tr>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('aom')\">Area manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'aom'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('zone')\">Zone manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'zone'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('score')\">Score <lib-audit-v2-sort-icon [active]=\"sortKey === 'score'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right\">Export</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let s of userStorePageRows; trackBy: trackByKey\">\r\n <td class=\"is-strong rp-cell-name\" [av2Tip]=\"s.name\">{{ s.name }}</td>\r\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.aom\">{{ s.aom || '\u2014' }}</td>\r\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.zone\">{{ s.zone || '\u2014' }}</td>\r\n <td class=\"t-right\" [class.is-muted]=\"!s.audited\">{{ s.audited ? 'Yes' : 'No' }}</td>\r\n <td class=\"t-right is-strong\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\"\r\n [class.is-muted]=\"s.score === null\">{{ scoreText(s) }}</td>\r\n <td class=\"t-right\">\r\n <button type=\"button\" class=\"rp-export\" (click)=\"exportStore(s)\">Export</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tfoot>\r\n <tr class=\"rp-total\">\r\n <td>Total</td>\r\n <td></td>\r\n <td></td>\r\n <td class=\"t-right\">{{ totalAuditedOf }}</td>\r\n <td class=\"t-right\">{{ totalAverage }}</td>\r\n <td></td>\r\n </tr>\r\n </tfoot>\r\n </table>\r\n </div>\r\n\r\n <div *ngIf=\"!loading && !tableCount\" class=\"av2-empty\">\r\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\r\n <div class=\"av2-empty-text\">\r\n <div class=\"av2-empty-title\">No data found</div>\r\n <div class=\"av2-empty-sub\">{{ search ? 'No rows match \"' + search + '\"' : 'No stores match the current filters' }}</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Shared pager (10 / 20 / 30), as on the other audit lists. -->\r\n <div class=\"rp-pager\" *ngIf=\"!loading && tableCount\">\r\n <lib-pagination [itemsPerPage]=\"pageSize\" [pageSize]=\"pageSize\" [paginationSizes]=\"pageSizes\" [currentPage]=\"page\"\r\n [totalItems]=\"tableCount\" (pageChange)=\"onPageChange($event)\" (pageSizeChange)=\"onPageSizeChange($event)\"></lib-pagination>\r\n </div>\r\n </section>\r\n\r\n <!-- ============ FILTER DRAWER ============ -->\r\n <div class=\"filter-backdrop\" *ngIf=\"filtersOpen\" (click)=\"closeFilters()\"></div>\r\n\r\n <!-- Every control edits the drawer's draft (dr); the page behind changes only on Apply or Reset all. -->\r\n <div class=\"filter-drawer\" *ngIf=\"filtersOpen && draft as dr\">\r\n <div class=\"drawer-head\">\r\n <span class=\"drawer-title\">Filters</span>\r\n <span class=\"rp-countpill\">{{ dr.filterCount }}</span>\r\n <div class=\"av2-grow\"></div>\r\n <button type=\"button\" class=\"closebtn\" (click)=\"closeFilters()\" title=\"Close\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"drawer-body\">\r\n <div class=\"drawer-nav\">\r\n <!-- trackBy: filterCats is rebuilt on every check, and lib-audit-v2-select's document:mousedown runs one\r\n between press and release; without it the button was replaced mid-click and the click never landed. -->\r\n <button type=\"button\" class=\"drawer-navitem\" *ngFor=\"let c of dr.filterCats; trackBy: trackByChip\" [class.navitem-active]=\"activeCat === c.key\"\r\n (click)=\"selectCat(c.key)\">\r\n <span class=\"navtext\">\r\n <span class=\"navtitle\">{{ c.label }}</span>\r\n <span class=\"navvalue\" [class.is-dirty]=\"c.dirty\">{{ c.value }}</span>\r\n </span>\r\n <span class=\"dirtydot\" *ngIf=\"c.dirty\"></span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"drawer-pane\">\r\n <div class=\"panetitle\">{{ dr.paneTitle }}</div>\r\n <div class=\"panehint\">{{ dr.paneSub }}</div>\r\n\r\n <!-- Date -->\r\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'date'\">\r\n <div class=\"av2-datepick\">\r\n <svg class=\"av2-datepick-icon\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"></rect>\r\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"></line><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"></line><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"></line></svg>\r\n <input type=\"text\" class=\"av2-datepick-input rp-daterange\" ngxDaterangepickerMd readonly autocomplete=\"off\"\r\n placeholder=\"Select date range\" [(ngModel)]=\"dr.range\" [locale]=\"pickerLocale\" [maxDate]=\"today\"\r\n [ranges]=\"ranges\" [showCustomRangeLabel]=\"true\" [alwaysShowCalendars]=\"false\"\r\n [keepCalendarOpeningWithRange]=\"true\" [autoApply]=\"true\" [showCancel]=\"false\"\r\n [drops]=\"'down'\" [opens]=\"'right'\" (datesUpdated)=\"dr.onRangePicked($event)\">\r\n </div>\r\n <div class=\"rp-presets\">\r\n <button type=\"button\" class=\"rp-preset\" *ngFor=\"let p of presets\" [class.is-on]=\"dr.preset === p\"\r\n (click)=\"dr.setPreset(p)\">{{ p }}</button>\r\n </div>\r\n </div>\r\n\r\n <!-- View by -->\r\n <div class=\"pane-options\" *ngIf=\"activeCat === 'mode'\">\r\n <div class=\"pane-option\" [class.is-on]=\"dr.isStoreMode\" (click)=\"dr.setMode('store')\">\r\n <span class=\"pane-radio\" [class.is-on]=\"dr.isStoreMode\"><span></span></span>\r\n <span class=\"pane-option-text\">\r\n <span class=\"pane-option-label\">Store</span>\r\n <span class=\"pane-option-help\">One row per store with score, result and last audit date.</span>\r\n </span>\r\n </div>\r\n <div class=\"pane-option\" [class.is-on]=\"!dr.isStoreMode\" (click)=\"dr.setMode('user')\">\r\n <span class=\"pane-radio\" [class.is-on]=\"!dr.isStoreMode\"><span></span></span>\r\n <span class=\"pane-option-text\">\r\n <span class=\"pane-option-label\">User</span>\r\n <span class=\"pane-option-help\">Rolled up by circle head, zone manager and AOM, drillable down to stores.</span>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- Stores (Store view) -->\r\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'scope' && dr.isStoreMode\">\r\n <label class=\"av2-search rp-pick-search\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\r\n <input type=\"text\" placeholder=\"Search store\" [(ngModel)]=\"dr.storeQuery\">\r\n </label>\r\n <div class=\"rp-picklist\">\r\n <ng-container *ngIf=\"dr.storePickItems.length\">\r\n <label class=\"rp-pick is-all\">\r\n <input type=\"checkbox\" [checked]=\"dr.storePickAllChecked\" (change)=\"dr.toggleStorePickAll()\">\r\n <span>Select All</span>\r\n </label>\r\n <label class=\"rp-pick\" *ngFor=\"let it of dr.storePickItems; trackBy: trackByPick\">\r\n <input type=\"checkbox\" [checked]=\"it.checked\" (change)=\"dr.toggleStorePick(it.store)\">\r\n <span class=\"rp-pick-label\">{{ it.store.name }}</span>\r\n <span class=\"rp-pick-sub\">{{ it.store.cluster || it.store.aom }}</span>\r\n </label>\r\n </ng-container>\r\n <div class=\"rp-pick-empty\" *ngIf=\"!dr.storePickItems.length\">\r\n {{ dr.storeQuery ? 'No stores match \"' + dr.storeQuery + '\"' : 'No stores in scope' }}\r\n </div>\r\n </div>\r\n <div class=\"rp-reading\">\r\n <span>Reading</span>\r\n <strong>{{ dr.storePickReading }}</strong>\r\n <span class=\"av2-grow\"></span>\r\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"dr.resetStorePick()\">Reset to all stores</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Store hierarchy (User view) -->\r\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'scope' && !dr.isStoreMode\">\r\n <div class=\"rp-field\">\r\n <div class=\"rp-field-label\">Circle Head <span>{{ dr.circleOptions.length - 1 }} users</span></div>\r\n <lib-audit-v2-select [value]=\"dr.circleKey\" [options]=\"dr.circleOptions\" placeholder=\"All circles\"\r\n ariaLabel=\"Circle Head\" (changed)=\"dr.pickCircle($event.target.value)\"></lib-audit-v2-select>\r\n </div>\r\n <div class=\"rp-field\" *ngIf=\"dr.showZonePick\">\r\n <div class=\"rp-field-label\">Zone Manager <span>{{ dr.zoneOptions.length - 1 }} {{ dr.zoneOptions.length === 2 ? 'user' : 'users' }}</span></div>\r\n <lib-audit-v2-select [value]=\"dr.zoneKey\" [options]=\"dr.zoneOptions\" placeholder=\"All zones\"\r\n ariaLabel=\"Zone Manager\" (changed)=\"dr.pickZone($event.target.value)\"></lib-audit-v2-select>\r\n </div>\r\n <div class=\"rp-field\" *ngIf=\"dr.zoneKey\">\r\n <div class=\"rp-field-label\">AOM <span>{{ dr.aomOptions.length - 1 }} {{ dr.aomOptions.length === 2 ? 'user' : 'users' }}</span></div>\r\n <lib-audit-v2-select [value]=\"dr.aomKey\" [options]=\"dr.aomOptions\" placeholder=\"All AOMs\"\r\n ariaLabel=\"AOM\" (changed)=\"dr.pickAom($event.target.value)\"></lib-audit-v2-select>\r\n </div>\r\n <div class=\"rp-field\" *ngIf=\"dr.aomKey\">\r\n <div class=\"rp-field-label\">Store <span>{{ dr.storeOptions.length - 1 }} stores</span></div>\r\n <lib-audit-v2-select [value]=\"dr.storeKey\" [options]=\"dr.storeOptions\" placeholder=\"All stores\"\r\n ariaLabel=\"Store\" (changed)=\"dr.pickStore($event.target.value)\"></lib-audit-v2-select>\r\n </div>\r\n <div class=\"rp-reading\">\r\n <span>Reading</span>\r\n <strong>{{ dr.hierarchyReading }}</strong>\r\n <span class=\"av2-grow\"></span>\r\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"dr.goToLevel('circle')\">Reset to all circles</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Result (Store view) -->\r\n <div class=\"pane-options\" *ngIf=\"activeCat === 'result' && dr.isStoreMode\">\r\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'all'\" (click)=\"dr.setResult('all')\">\r\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'all'\"><span></span></span>\r\n <span class=\"pane-option-text\">\r\n <span class=\"pane-option-label\">All</span>\r\n <span class=\"pane-option-help\">Every store in scope, audited or not.</span>\r\n </span>\r\n </div>\r\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'pass'\" (click)=\"dr.setResult('pass')\">\r\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'pass'\"><span></span></span>\r\n <span class=\"pane-option-text\">\r\n <span class=\"pane-option-label\">Pass</span>\r\n <span class=\"pane-option-help\">Only stores scoring at or above the {{ passMark }}% pass mark.</span>\r\n </span>\r\n </div>\r\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'fail'\" (click)=\"dr.setResult('fail')\">\r\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'fail'\"><span></span></span>\r\n <span class=\"pane-option-text\">\r\n <span class=\"pane-option-label\">Fail</span>\r\n <span class=\"pane-option-help\">Only stores scoring below the {{ passMark }}% pass mark.</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"drawer-foot\">\r\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"resetFilters()\">Reset all</button>\r\n <div class=\"av2-grow\"></div>\r\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--wide\" (click)=\"applyFilters()\">Apply</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}::ng-deep .tooltip.av2-tip{--bs-tooltip-bg: #fff;--bs-tooltip-color: #344054;--bs-tooltip-max-width: 320px;--bs-tooltip-opacity: 1}::ng-deep .tooltip.av2-tip .tooltip-inner{background-color:#fff!important;color:#344054!important;padding:8px 12px;border-radius:8px;font-size:13px;line-height:18px;font-weight:500;text-align:left;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,0 0 0 1px #eaecf0}::ng-deep .tooltip.av2-tip .tooltip-arrow:before{border-top-color:#fff;border-bottom-color:#fff}:host ::ng-deep lib-pagination{display:block}:host ::ng-deep lib-pagination .container{max-width:none;padding:0;display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;font-size:14px;color:#475467}:host ::ng-deep lib-pagination .mt-4{margin-top:0!important}:host ::ng-deep lib-pagination .container>.text-center{display:flex;align-items:center}:host ::ng-deep lib-pagination .container>.text-center>ul:not(.ngx-pagination){display:none}:host ::ng-deep lib-pagination pagination-controls{display:flex;align-items:center}:host ::ng-deep lib-pagination .sub-title{color:#475467!important;font-size:14px!important;font-weight:400!important;line-height:20px}:host ::ng-deep lib-pagination .border-val{height:40px;min-width:64px;padding:0 30px 0 12px!important;border:1px solid #D0D5DD!important;border-radius:8px!important;box-shadow:0 1px 2px #1018280d;background-color:#fff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\")!important;background-repeat:no-repeat!important;background-position:right 10px center!important;background-size:14px 14px!important;appearance:none;-webkit-appearance:none;font-size:14px;font-weight:500;color:#1d2939;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}:host ::ng-deep lib-pagination .border-val:hover{border-color:#98a2b3!important}:host ::ng-deep lib-pagination .border-val:focus{outline:none;border-color:#66c8ff!important;box-shadow:0 0 0 3px #eaf8ff}:host ::ng-deep lib-pagination .ngx-pagination{margin:0;padding:0;display:flex;align-items:center;gap:6px;color:#475467!important;font-size:14px!important;font-weight:500}:host ::ng-deep lib-pagination .ngx-pagination li{display:inline-flex;margin:0}:host ::ng-deep lib-pagination .ngx-pagination li.small-screen{display:none!important}:host ::ng-deep lib-pagination .ngx-pagination a,:host ::ng-deep lib-pagination .ngx-pagination button,:host ::ng-deep lib-pagination .ngx-pagination .current,:host ::ng-deep lib-pagination .ngx-pagination .disabled{min-width:40px!important;height:40px;padding:0 8px!important;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;line-height:20px;color:#475467}:host ::ng-deep lib-pagination .ngx-pagination a:hover,:host ::ng-deep lib-pagination .ngx-pagination button:hover{background:#f2f4f7;padding:0 8px!important}:host ::ng-deep lib-pagination .ngx-pagination .current{background:#eaf8ff!important;color:#00a3ff!important;font-weight:600;font-size:14px!important}:host ::ng-deep lib-pagination .ngx-pagination .disabled{color:#98a2b3}:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:after{margin:0}:host ::ng-deep lib-pagination .ngx-pagination .ellipsis:after{color:#98a2b3;padding:0}.rp-pager{padding-top:20px}.rp-head{display:flex;flex-direction:column;gap:2px}.rp-crumb{font-size:13px;line-height:20px;color:#667085}.rp-crumb-current{color:#00a3ff}.rp-title{font-size:22px;line-height:30px;font-weight:600;color:#101828}.rp-controls{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.rp-countpill{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;border-radius:9999px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:600}.rp-chip{height:32px;max-width:360px;padding:0 12px;border:none;border-radius:9999px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0;display:inline-flex;align-items:center;gap:6px;font-family:inherit;font-size:13px;line-height:20px;white-space:nowrap;cursor:pointer}.rp-chip:hover{background:#f9fafb}.rp-chip-key{font-weight:500;color:#667085}.rp-chip-value{overflow:hidden;text-overflow:ellipsis;font-weight:600;color:#101828}.av2-datepick{position:relative;display:inline-flex;align-items:center}.av2-datepick-icon{position:absolute;left:10px;color:#667085;pointer-events:none}.av2-datepick-input{height:36px;padding:0 10px 0 32px;border:none;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;background:#fff;font-family:inherit;font-size:13px;font-weight:500;color:#101828;cursor:pointer;outline:none}.av2-datepick-input:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}:host ::ng-deep .av2-datepick .md-drppicker{margin-top:4px;z-index:1060;font-family:inherit;border-radius:8px;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,inset 0 0 0 1px #eaecf0}:host ::ng-deep .av2-datepick .md-drppicker.double,:host ::ng-deep .av2-datepick .md-drppicker.show-ranges{width:max-content}:host ::ng-deep .av2-datepick .md-drppicker.ltr .ranges{float:left;margin-top:10px}:host ::ng-deep .av2-datepick .md-drppicker .ranges ul li button{width:160px;padding:12px 16px;border:none;border-radius:8px;background:none;color:#344054;font-size:14px;font-weight:400;line-height:20px;text-align:left;cursor:pointer}:host ::ng-deep .av2-datepick .md-drppicker .ranges ul li button.active{background:#eaf8ff;color:#00a3ff;font-weight:500}:host ::ng-deep .av2-datepick .md-drppicker th,:host ::ng-deep .av2-datepick .md-drppicker td{width:40px!important;height:40px!important;min-width:32px;padding:0!important;border:1px solid transparent!important;background:transparent!important;font-size:14px!important;font-weight:400!important;line-height:38px}:host ::ng-deep .av2-datepick .md-drppicker th{color:#344054!important;font-weight:500!important}:host ::ng-deep .av2-datepick .md-drppicker th.month{width:auto!important;font-size:16px!important}:host ::ng-deep .av2-datepick .md-drppicker td{color:#344054!important}:host ::ng-deep .av2-datepick .md-drppicker th.available.prev,:host ::ng-deep .av2-datepick .md-drppicker th.available.next{background:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='15 6 9 12 15 18'/%3E%3C/svg%3E\") center/18px no-repeat!important}:host ::ng-deep .av2-datepick .md-drppicker th.available:hover,:host ::ng-deep .av2-datepick .md-drppicker td.available:hover{background-color:#f2f4f7!important}:host ::ng-deep .av2-datepick .md-drppicker td.in-range{background-color:#eaf8ff!important;color:#101828!important}:host ::ng-deep .av2-datepick .md-drppicker td.active,:host ::ng-deep .av2-datepick .md-drppicker td.active:hover{background-color:#029cf4!important;border-radius:20px;color:#fff!important;font-weight:500!important}:host ::ng-deep .av2-datepick .md-drppicker td.off,:host ::ng-deep .av2-datepick .md-drppicker td.off.in-range{color:#98a2b3!important;background-color:transparent!important}:host ::ng-deep .av2-datepick .md-drppicker td.disabled{color:#98a2b3!important;background-color:transparent!important;text-decoration:line-through;pointer-events:none}:host ::ng-deep .av2-datepick--compact .md-drppicker th,:host ::ng-deep .av2-datepick--compact .md-drppicker td{width:32px!important;height:32px!important;font-size:12px!important;line-height:30px}:host ::ng-deep .av2-datepick--compact .md-drppicker th.month{font-size:14px!important}.rp-daterange{width:260px;height:44px;font-size:14px}.rp-presets{display:flex;flex-wrap:wrap;gap:8px}.rp-preset{height:36px;padding:0 14px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0;font-family:inherit;font-size:14px;font-weight:500;color:#667085;cursor:pointer}.rp-preset.is-on{background:#eaf8ff;box-shadow:inset 0 0 0 1px #99dbff;color:#101828;font-weight:600}.rp-drillbar{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:14px 18px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}.rp-drillcrumb{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;color:#00a3ff;cursor:pointer}.rp-drillcrumb.is-current{color:#101828;cursor:default}.rp-drillsep{color:#98a2b3;font-weight:400}.rp-hint{font-size:14px;color:#667085}.rp-scope{display:flex;flex-direction:column;gap:2px}.rp-scope-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.rp-scope-meta{font-size:14px;line-height:20px;color:#667085}.rp-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:16px}.rp-kpi-value.is-good{color:#027a48}.rp-kpi-value.is-bad{color:#d92d20}.rp-sk-value{height:32px;margin:3px 0}.rp-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:18px 20px 12px;display:flex;flex-direction:column;gap:14px}.rp-card-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.rp-card-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:200px}.rp-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.rp-card-meta{font-size:14px;line-height:20px;color:#667085}.rp-search{width:260px}.rp-table{width:100%;border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed}.rp-table th:nth-child(1){width:29%}.rp-table th:nth-child(2){width:9.5%}.rp-table th:nth-child(3){width:8.5%}.rp-table th:nth-child(4){width:9.5%}.rp-table th:nth-child(5){width:9.5%}.rp-table th:nth-child(6){width:12%}.rp-table th:nth-child(7){width:11%}.rp-table th:nth-child(8){width:11%}.rp-table--stores th:nth-child(1){width:14%}.rp-table--stores th:nth-child(2){width:20%}.rp-table--stores th:nth-child(3){width:16%}.rp-table--stores th:nth-child(4){width:9%}.rp-table--stores th:nth-child(5){width:9%}.rp-table--stores th:nth-child(6){width:11%}.rp-table--stores th:nth-child(7){width:12%}.rp-table--stores th:nth-child(8){width:9%}.rp-table--userstores th:nth-child(1){width:18%}.rp-table--userstores th:nth-child(2){width:25%}.rp-table--userstores th:nth-child(3){width:25%}.rp-table--userstores th:nth-child(4){width:11%}.rp-table--userstores th:nth-child(5){width:10%}.rp-table--userstores th:nth-child(6){width:11%}.rp-table thead th{padding:8px 4px;border:0;border-bottom:1px solid #EAECF0;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;white-space:nowrap}.rp-table tbody td{padding:12px 4px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;color:#344054;vertical-align:middle}.rp-table tfoot td{padding:12px 4px;border:0;font-size:14px;line-height:20px;font-weight:700;color:#101828}.rp-table thead th.t-right,.rp-table tbody td.t-right,.rp-table tfoot td.t-right{text-align:right}.rp-table .is-strong{font-weight:600}.rp-table tbody td.is-muted{color:#98a2b3}.rp-table tbody td.is-pass{color:#027a48}.rp-table tbody td.is-fail{color:#d92d20}.rp-table tbody td.rp-cell-name{color:#101828;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-result{display:inline-flex;padding:2px 10px;border-radius:9999px;background:#f2f4f7;font-size:12px;line-height:18px;font-weight:500;color:#475467;white-space:nowrap}.rp-result.is-pass{background:#ecfdf3;color:#027a48}.rp-result.is-fail{background:#fef3f2;color:#b42318}.rp-row{cursor:pointer}.rp-row:hover td{background:#fcfcfd}.rp-name{display:flex;flex-direction:column;gap:2px;min-width:0}.rp-name-main{font-weight:600;color:#00a3ff}.rp-name-sub{font-size:12px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-export{height:32px;padding:0 12px;border:none;border-radius:6px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#344054;cursor:pointer}.rp-export:hover{background:#f9fafb}.filter-backdrop{position:fixed;inset:0;background:#10182873;z-index:1050}.filter-drawer{position:fixed;top:0;right:0;bottom:0;width:860px;max-width:96vw;display:flex;flex-direction:column;background:#fff;box-shadow:-10px 0 30px #1018282e;z-index:1051;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.drawer-head{display:flex;align-items:center;gap:10px;padding:18px 20px;box-shadow:inset 0 -1px #eaecf0}.drawer-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.closebtn{width:32px;height:32px;border:none;border-radius:8px;background:transparent;color:#667085;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.closebtn:hover{background:#f2f4f7;color:#344054}.drawer-body{display:flex;flex:1;min-height:0}.drawer-nav{flex:0 0 280px;max-width:280px;background:#f9fafb;box-shadow:inset -1px 0 #eaecf0;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:4px}.drawer-navitem{display:flex;align-items:center;gap:10px;width:100%;padding:12px 14px;border:none;border-radius:8px;background:transparent;text-align:left;font-family:inherit;cursor:pointer}.drawer-navitem:hover{background:#fff}.drawer-navitem.navitem-active{background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d}.navtext{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.navtitle{font-size:14px;line-height:20px;font-weight:600;color:#101828}.navvalue{font-size:14px;line-height:20px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.navvalue.is-dirty{color:#009bf3}.dirtydot{width:8px;height:8px;border-radius:9999px;background:#00a3ff;flex-shrink:0;display:block}.drawer-pane{flex:1;min-width:0;overflow-y:auto;padding:24px 28px;display:flex;flex-direction:column;gap:6px}.panetitle{font-size:18px;line-height:28px;font-weight:600;color:#101828}.panehint{font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.pane-stack{display:flex;flex-direction:column;gap:14px;margin-top:14px;max-width:560px}.pane-options{display:flex;flex-direction:column;gap:10px;margin-top:14px;max-width:560px}.pane-option{display:flex;align-items:flex-start;gap:12px;padding:14px 16px;border-radius:8px;cursor:pointer;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0}.pane-option.is-on{background:#f5fbff;box-shadow:inset 0 0 0 1.5px #00a3ff}.pane-radio{width:18px;height:18px;flex-shrink:0;margin-top:2px;border-radius:9999px;display:flex;align-items:center;justify-content:center;box-shadow:inset 0 0 0 1px #d0d5dd}.pane-radio>span{width:8px;height:8px;border-radius:9999px;background:transparent;display:block}.pane-radio.is-on{box-shadow:inset 0 0 0 1.5px #00a3ff}.pane-radio.is-on>span{background:#00a3ff}.pane-option-text{display:flex;flex-direction:column;gap:2px}.pane-option-label{font-size:14px;line-height:20px;font-weight:600;color:#101828}.pane-option-help{font-size:14px;line-height:20px;color:#667085}.drawer-foot{display:flex;align-items:center;gap:10px;padding:14px 20px;box-shadow:inset 0 1px #eaecf0}.rp-reset{border:none;background:transparent;padding:0;font-family:inherit;font-weight:600;text-decoration:none;white-space:nowrap}.rp-pick-search{width:100%}.rp-picklist{max-height:320px;overflow-y:auto;padding:6px;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;display:flex;flex-direction:column}.rp-pick{display:flex;align-items:center;gap:12px;min-height:40px;margin:0;padding:0 10px;border-radius:6px;font-size:14px;color:#344054;cursor:pointer}.rp-pick:hover{background:#f9fafb}.rp-pick.is-all{font-weight:600}.rp-pick input{appearance:none;-webkit-appearance:none;flex-shrink:0;width:16px;height:16px;margin:0;border:1px solid #D0D5DD;border-radius:4px;background:#fff no-repeat center/12px 12px;cursor:pointer;vertical-align:middle;transition:border-color .12s ease,background-color .12s ease}.rp-pick input:hover:not(:disabled){border-color:#00a3ff}.rp-pick input:checked{border-color:#00a3ff;background-color:#eaf8ff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2300A3FF' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E\")}.rp-pick input:focus-visible{outline:none;box-shadow:0 0 0 3px #eaf8ff}.rp-pick input:disabled{cursor:not-allowed;opacity:.45}.rp-pick-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-pick-sub{max-width:45%;font-size:12px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-pick-empty{padding:20px 10px;font-size:14px;color:#667085}.rp-reading{display:flex;align-items:center;gap:12px;padding:12px 16px;border-radius:8px;background:#f9fafb;font-size:14px;color:#475467}.rp-reading strong{font-weight:600;color:#101828}.rp-field{display:flex;flex-direction:column;gap:6px;min-width:0}.rp-field-label{display:flex;align-items:baseline;gap:8px;font-size:14px;line-height:20px;font-weight:600;color:#1d2939}.rp-field-label span{font-weight:400;color:#667085}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.DaterangepickerDirective, selector: "input[ngxDaterangepickerMd]", inputs: ["minDate", "maxDate", "autoApply", "alwaysShowCalendars", "showCustomRangeLabel", "linkedCalendars", "dateLimit", "singleDatePicker", "showWeekNumbers", "showISOWeekNumbers", "showDropdowns", "isInvalidDate", "isCustomDate", "isTooltipDate", "showClearButton", "customRangeDirection", "ranges", "opens", "drops", "firstMonthDayClass", "lastMonthDayClass", "emptyWeekRowClass", "emptyWeekColumnClass", "firstDayOfNextMonthClass", "lastDayOfPreviousMonthClass", "keepCalendarOpeningWithRange", "showRangeLabelOnInput", "showCancel", "lockStartDate", "timePicker", "timePicker24Hour", "timePickerIncrement", "timePickerSeconds", "closeOnAutoApply", "endKeyHolder", "startKey", "locale", "endKey"], outputs: ["change", "rangeClicked", "datesUpdated", "startDateChanged", "endDateChanged", "clearClicked"] }, { kind: "directive", type: AuditV2TipDirective, selector: "[av2Tip]", inputs: ["av2Tip"] }, { kind: "component", type: AuditV2ShimmerComponent, selector: "lib-audit-v2-shimmer", inputs: ["rows"] }, { kind: "component", type: AuditV2SelectComponent, selector: "lib-audit-v2-select", inputs: ["options", "placeholder", "searchable", "ariaLabel", "disabled", "value"], outputs: ["changed"] }, { kind: "component", type: AuditV2SortIconComponent, selector: "lib-audit-v2-sort-icon", inputs: ["active", "dir"] }] });
9165
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AuditV2ReportsComponent, selector: "lib-audit-v2-reports", ngImport: i0, template: "<div class=\"av2-page audit-reports\">\n\n <!-- Breadcrumb + title -->\n <div class=\"rp-head\">\n <div class=\"rp-crumb\">Audits \u203A <span class=\"rp-crumb-current\">Reports</span></div>\n <div class=\"rp-title\">Store audit report</div>\n </div>\n\n <!-- Filter chips, Filter button at the right end (QA 9 Oct); Export moved to the table head beside its search. -->\n <div class=\"rp-controls\">\n <button type=\"button\" class=\"rp-chip\" *ngFor=\"let c of chips; trackBy: trackByChip\" (click)=\"openFilters(c.key)\"\n [title]=\"c.label + ': ' + c.value\">\n <span class=\"rp-chip-key\">{{ c.label }}</span><span class=\"rp-chip-value\">{{ c.value }}</span>\n </button>\n <div class=\"av2-grow\"></div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost rp-filterbtn\" (click)=\"openFilters()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"></polygon></svg>\n Filter\n <span class=\"rp-countpill\">{{ filterCount }}</span>\n </button>\n </div>\n\n <!-- User view: where in the hierarchy -->\n <div class=\"rp-drillbar\" *ngIf=\"!isStoreMode\">\n <ng-container *ngFor=\"let c of crumbs; let last = last; let first = first\">\n <div class=\"rp-drillcrumb\" [class.is-current]=\"last\" (click)=\"goToLevel(c.level)\">\n <span class=\"rp-drillsep\" *ngIf=\"!first\">\u203A</span>{{ c.label }}\n </div>\n </ng-container>\n <div class=\"av2-grow\"></div>\n <div class=\"rp-hint\">{{ hint }}</div>\n </div>\n\n <!-- Scope -->\n <div class=\"rp-scope\">\n <div class=\"rp-scope-title\">{{ scopeTitle }}</div>\n <div class=\"rp-scope-meta\">{{ scopeMeta }}</div>\n </div>\n\n <!-- KPIs -->\n <div class=\"rp-kpis\">\n <!-- Old Checklist summary card: figure + label in the gradient strip, note below. -->\n <div class=\"av2-ocard\" *ngFor=\"let kpi of kpis\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count rp-kpi-value\" [class.is-good]=\"kpi.tone === 'good'\" [class.is-bad]=\"kpi.tone === 'bad'\">\n <span *ngIf=\"loading\" class=\"av2-sk av2-sk--value rp-sk-value\"></span>\n <ng-container *ngIf=\"!loading\">{{ kpi.value }}</ng-container>\n </div>\n <div class=\"av2-ocard-text\">{{ kpi.label }}</div>\n </div>\n <div class=\"av2-ocard-body\">\n <span *ngIf=\"loading\" class=\"av2-sk av2-sk--note\"></span>\n <div *ngIf=\"!loading\" class=\"av2-ocard-note\">{{ kpi.note }}</div>\n </div>\n </div>\n </div>\n\n <!-- Report table -->\n <section class=\"rp-card\">\n <div class=\"rp-card-head\">\n <div class=\"rp-card-text\">\n <ng-container *ngIf=\"isStoreMode\">\n <div class=\"rp-card-title\">Store report</div>\n <div class=\"rp-card-meta\">{{ storeRows.length }} {{ storeRows.length === 1 ? 'store' : 'stores' }} \u00B7 audits submitted in the period</div>\n </ng-container>\n <ng-container *ngIf=\"!isStoreMode\">\n <div class=\"rp-card-title\">{{ tableTitle }}</div>\n <div class=\"rp-card-meta\">{{ tableMeta }}</div>\n </ng-container>\n </div>\n <div class=\"av2-grow\"></div>\n <label class=\"av2-search rp-search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"7\"></circle>\n <line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line>\n </svg>\n <input type=\"text\" [placeholder]=\"isStoreMode ? 'Search store' : 'Search ' + levelLabel.toLowerCase()\"\n [(ngModel)]=\"search\" (ngModelChange)=\"onSearchChange()\">\n </label>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost\" [disabled]=\"loading || exporting\" (click)=\"exportAll()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 16V4\"></path><polyline points=\"7 9 12 4 17 9\"></polyline><path d=\"M4 16v4h16v-4\"></path></svg>\n Export\n </button>\n </div>\n\n <lib-audit-v2-shimmer *ngIf=\"loading\"></lib-audit-v2-shimmer>\n\n <!-- Store view: one row per store -->\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && isStoreMode && tableCount\">\n <table class=\"rp-table rp-table--stores\">\n <thead>\n <tr>\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"av2-sortable\" (click)=\"sortBy('cluster')\">Cluster <lib-audit-v2-sort-icon [active]=\"sortKey === 'cluster'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"av2-sortable\" (click)=\"sortBy('aom')\">Area manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'aom'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('score')\">Score <lib-audit-v2-sort-icon [active]=\"sortKey === 'score'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('status')\">Result <lib-audit-v2-sort-icon [active]=\"sortKey === 'status'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('lastAudit')\">Last audit <lib-audit-v2-sort-icon [active]=\"sortKey === 'lastAudit'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right\">Export</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let s of storePageRows; trackBy: trackByKey\">\n <td class=\"is-strong rp-cell-name\" [av2Tip]=\"s.name\">{{ s.name }}</td>\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.cluster\">{{ s.cluster || '\u2014' }}</td>\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.aom\">{{ s.aom || '\u2014' }}</td>\n <td class=\"t-right\" [class.is-muted]=\"!s.audited\">{{ s.audited ? 'Yes' : 'No' }}</td>\n <td class=\"t-right is-strong\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\"\n [class.is-muted]=\"s.score === null\">{{ scoreText(s) }}</td>\n <td class=\"t-right\">\n <span class=\"rp-result\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\">{{ resultText(s) }}</span>\n </td>\n <td class=\"t-right\" [class.is-muted]=\"!s.lastAudit\">{{ s.lastAudit || 'No audit' }}</td>\n <td class=\"t-right\">\n <button type=\"button\" class=\"rp-export\" [disabled]=\"exporting\" (click)=\"exportStore(s)\">Export</button>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr class=\"rp-total\">\n <td>Total</td>\n <td></td>\n <td></td>\n <td class=\"t-right\">{{ totalAuditedOf }}</td>\n <td class=\"t-right\">{{ totalAverage }}</td>\n <td class=\"t-right\">{{ totals.failed }} fail</td>\n <td></td>\n <td></td>\n </tr>\n </tfoot>\n </table>\n </div>\n\n <!-- User view: circle head / zone manager / area manager roll-up -->\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && !isStoreMode && level !== 'store' && tableCount\">\n <table class=\"rp-table\">\n <thead>\n <tr>\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">{{ levelLabel }} <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('total')\">Total stores <lib-audit-v2-sort-icon [active]=\"sortKey === 'total'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('notAudited')\">Not audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'notAudited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('coverage')\">Coverage <lib-audit-v2-sort-icon [active]=\"sortKey === 'coverage'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('avgScore')\">Avg audit score <lib-audit-v2-sort-icon [active]=\"sortKey === 'avgScore'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('failedPct')\">Failed store % <lib-audit-v2-sort-icon [active]=\"sortKey === 'failedPct'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right\">Report</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of pageRows; trackBy: trackByRow\" class=\"rp-row\" (click)=\"openRow(row)\">\n <td>\n <div class=\"rp-name\">\n <span class=\"rp-name-main\">{{ row.name }}</span>\n <span class=\"rp-name-sub\" *ngIf=\"row.email\">{{ row.email }}</span>\n </div>\n </td>\n <td class=\"t-right\">{{ row.total }}</td>\n <td class=\"t-right\">{{ row.audited }}</td>\n <td class=\"t-right\" [class.is-muted]=\"!row.notAudited\">{{ row.notAudited }}</td>\n <td class=\"t-right\">{{ row.coverage }}</td>\n <td class=\"t-right is-strong\">{{ row.avgScore }}</td>\n <td class=\"t-right is-strong\" [class.is-fail]=\"isHighFail(row)\">{{ row.failedPct }}</td>\n <td class=\"t-right\">\n <button type=\"button\" class=\"rp-export\" [disabled]=\"exporting\" (click)=\"exportRow(row); $event.stopPropagation()\">Export</button>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr class=\"rp-total\">\n <td>Total</td>\n <td class=\"t-right\">{{ totals.total }}</td>\n <td class=\"t-right\">{{ totals.audited }}</td>\n <td class=\"t-right\">{{ totals.total - totals.audited }}</td>\n <td class=\"t-right\">{{ totalCoverage }}</td>\n <td class=\"t-right\">{{ totalAverage }}</td>\n <td class=\"t-right\">{{ totalFailedPct }}</td>\n <td></td>\n </tr>\n </tfoot>\n </table>\n </div>\n\n <!-- User view, deepest level: the area manager's stores -->\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && !isStoreMode && level === 'store' && tableCount\">\n <table class=\"rp-table rp-table--userstores\">\n <thead>\n <tr>\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"av2-sortable\" (click)=\"sortBy('aom')\">Area manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'aom'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"av2-sortable\" (click)=\"sortBy('zone')\">Zone manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'zone'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('score')\">Score <lib-audit-v2-sort-icon [active]=\"sortKey === 'score'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right\">Export</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let s of userStorePageRows; trackBy: trackByKey\">\n <td class=\"is-strong rp-cell-name\" [av2Tip]=\"s.name\">{{ s.name }}</td>\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.aom\">{{ s.aom || '\u2014' }}</td>\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.zone\">{{ s.zone || '\u2014' }}</td>\n <td class=\"t-right\" [class.is-muted]=\"!s.audited\">{{ s.audited ? 'Yes' : 'No' }}</td>\n <td class=\"t-right is-strong\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\"\n [class.is-muted]=\"s.score === null\">{{ scoreText(s) }}</td>\n <td class=\"t-right\">\n <button type=\"button\" class=\"rp-export\" [disabled]=\"exporting\" (click)=\"exportStore(s)\">Export</button>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr class=\"rp-total\">\n <td>Total</td>\n <td></td>\n <td></td>\n <td class=\"t-right\">{{ totalAuditedOf }}</td>\n <td class=\"t-right\">{{ totalAverage }}</td>\n <td></td>\n </tr>\n </tfoot>\n </table>\n </div>\n\n <div *ngIf=\"!loading && !tableCount\" class=\"av2-empty\">\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\n <div class=\"av2-empty-text\">\n <div class=\"av2-empty-title\">No data found</div>\n <div class=\"av2-empty-sub\">{{ search ? 'No rows match \"' + search + '\"' : 'No stores match the current filters' }}</div>\n </div>\n </div>\n\n <!-- Shared pager (10 / 20 / 30), as on the other audit lists. -->\n <div class=\"rp-pager\" *ngIf=\"!loading && tableCount\">\n <lib-pagination [itemsPerPage]=\"pageSize\" [pageSize]=\"pageSize\" [paginationSizes]=\"pageSizes\" [currentPage]=\"page\"\n [totalItems]=\"tableCount\" (pageChange)=\"onPageChange($event)\" (pageSizeChange)=\"onPageSizeChange($event)\"></lib-pagination>\n </div>\n </section>\n\n <!-- ============ FILTER DRAWER ============ -->\n <div class=\"filter-backdrop\" *ngIf=\"filtersOpen\" (click)=\"closeFilters()\"></div>\n\n <!-- Every control edits the drawer's draft (dr); the page behind changes only on Apply or Reset all. -->\n <div class=\"filter-drawer\" *ngIf=\"filtersOpen && draft as dr\">\n <div class=\"drawer-head\">\n <span class=\"drawer-title\">Filters</span>\n <span class=\"rp-countpill\">{{ dr.filterCount }}</span>\n <div class=\"av2-grow\"></div>\n <button type=\"button\" class=\"closebtn\" (click)=\"closeFilters()\" title=\"Close\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\n </button>\n </div>\n\n <div class=\"drawer-body\">\n <div class=\"drawer-nav\">\n <!-- trackBy: filterCats is rebuilt on every check, and lib-audit-v2-select's document:mousedown runs one\n between press and release; without it the button was replaced mid-click and the click never landed. -->\n <button type=\"button\" class=\"drawer-navitem\" *ngFor=\"let c of dr.filterCats; trackBy: trackByChip\" [class.navitem-active]=\"activeCat === c.key\"\n (click)=\"selectCat(c.key)\">\n <span class=\"navtext\">\n <span class=\"navtitle\">{{ c.label }}</span>\n <span class=\"navvalue\" [class.is-dirty]=\"c.dirty\">{{ c.value }}</span>\n </span>\n <span class=\"dirtydot\" *ngIf=\"c.dirty\"></span>\n </button>\n </div>\n\n <div class=\"drawer-pane\">\n <div class=\"panetitle\">{{ dr.paneTitle }}</div>\n <div class=\"panehint\">{{ dr.paneSub }}</div>\n\n <!-- Date -->\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'date'\">\n <div class=\"av2-datepick\">\n <svg class=\"av2-datepick-icon\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"></rect>\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"></line><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"></line><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"></line></svg>\n <input type=\"text\" class=\"av2-datepick-input rp-daterange\" ngxDaterangepickerMd readonly autocomplete=\"off\"\n placeholder=\"Select date range\" [(ngModel)]=\"dr.range\" [locale]=\"pickerLocale\" [maxDate]=\"today\"\n [ranges]=\"ranges\" [showCustomRangeLabel]=\"true\" [alwaysShowCalendars]=\"false\"\n [keepCalendarOpeningWithRange]=\"true\" [autoApply]=\"true\" [showCancel]=\"false\"\n [drops]=\"'down'\" [opens]=\"'right'\" (datesUpdated)=\"dr.onRangePicked($event)\">\n </div>\n <div class=\"rp-presets\">\n <button type=\"button\" class=\"rp-preset\" *ngFor=\"let p of presets\" [class.is-on]=\"dr.preset === p\"\n (click)=\"dr.setPreset(p)\">{{ p }}</button>\n </div>\n </div>\n\n <!-- View by -->\n <div class=\"pane-options\" *ngIf=\"activeCat === 'mode'\">\n <div class=\"pane-option\" [class.is-on]=\"dr.isStoreMode\" (click)=\"dr.setMode('store')\">\n <span class=\"pane-radio\" [class.is-on]=\"dr.isStoreMode\"><span></span></span>\n <span class=\"pane-option-text\">\n <span class=\"pane-option-label\">Store</span>\n <span class=\"pane-option-help\">One row per store with score, result and last audit date.</span>\n </span>\n </div>\n <div class=\"pane-option\" [class.is-on]=\"!dr.isStoreMode\" (click)=\"dr.setMode('user')\">\n <span class=\"pane-radio\" [class.is-on]=\"!dr.isStoreMode\"><span></span></span>\n <span class=\"pane-option-text\">\n <span class=\"pane-option-label\">User</span>\n <span class=\"pane-option-help\">Rolled up by circle head, zone manager and AOM, drillable down to stores.</span>\n </span>\n </div>\n </div>\n\n <!-- Stores (Store view) -->\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'scope' && dr.isStoreMode\">\n <label class=\"av2-search rp-pick-search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" placeholder=\"Search store\" [(ngModel)]=\"dr.storeQuery\">\n </label>\n <div class=\"rp-picklist\">\n <ng-container *ngIf=\"dr.storePickItems.length\">\n <label class=\"rp-pick is-all\">\n <input type=\"checkbox\" [checked]=\"dr.storePickAllChecked\" (change)=\"dr.toggleStorePickAll()\">\n <span>Select All</span>\n </label>\n <label class=\"rp-pick\" *ngFor=\"let it of dr.storePickItems; trackBy: trackByPick\">\n <input type=\"checkbox\" [checked]=\"it.checked\" (change)=\"dr.toggleStorePick(it.store)\">\n <span class=\"rp-pick-label\">{{ it.store.name }}</span>\n <span class=\"rp-pick-sub\">{{ it.store.cluster || it.store.aom }}</span>\n </label>\n </ng-container>\n <div class=\"rp-pick-empty\" *ngIf=\"!dr.storePickItems.length\">\n {{ dr.storeQuery ? 'No stores match \"' + dr.storeQuery + '\"' : 'No stores in scope' }}\n </div>\n </div>\n <div class=\"rp-reading\">\n <span>Reading</span>\n <strong>{{ dr.storePickReading }}</strong>\n <span class=\"av2-grow\"></span>\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"dr.resetStorePick()\">Reset to all stores</button>\n </div>\n </div>\n\n <!-- Store hierarchy (User view) -->\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'scope' && !dr.isStoreMode\">\n <div class=\"rp-field\">\n <div class=\"rp-field-label\">Circle Head <span>{{ dr.circleOptions.length - 1 }} users</span></div>\n <lib-audit-v2-select [value]=\"dr.circleKey\" [options]=\"dr.circleOptions\" placeholder=\"All circles\"\n ariaLabel=\"Circle Head\" (changed)=\"dr.pickCircle($event.target.value)\"></lib-audit-v2-select>\n </div>\n <div class=\"rp-field\" *ngIf=\"dr.showZonePick\">\n <div class=\"rp-field-label\">Zone Manager <span>{{ dr.zoneOptions.length - 1 }} {{ dr.zoneOptions.length === 2 ? 'user' : 'users' }}</span></div>\n <lib-audit-v2-select [value]=\"dr.zoneKey\" [options]=\"dr.zoneOptions\" placeholder=\"All zones\"\n ariaLabel=\"Zone Manager\" (changed)=\"dr.pickZone($event.target.value)\"></lib-audit-v2-select>\n </div>\n <div class=\"rp-field\" *ngIf=\"dr.zoneKey\">\n <div class=\"rp-field-label\">AOM <span>{{ dr.aomOptions.length - 1 }} {{ dr.aomOptions.length === 2 ? 'user' : 'users' }}</span></div>\n <lib-audit-v2-select [value]=\"dr.aomKey\" [options]=\"dr.aomOptions\" placeholder=\"All AOMs\"\n ariaLabel=\"AOM\" (changed)=\"dr.pickAom($event.target.value)\"></lib-audit-v2-select>\n </div>\n <div class=\"rp-field\" *ngIf=\"dr.aomKey\">\n <div class=\"rp-field-label\">Store <span>{{ dr.storeOptions.length - 1 }} stores</span></div>\n <lib-audit-v2-select [value]=\"dr.storeKey\" [options]=\"dr.storeOptions\" placeholder=\"All stores\"\n ariaLabel=\"Store\" (changed)=\"dr.pickStore($event.target.value)\"></lib-audit-v2-select>\n </div>\n <div class=\"rp-reading\">\n <span>Reading</span>\n <strong>{{ dr.hierarchyReading }}</strong>\n <span class=\"av2-grow\"></span>\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"dr.goToLevel('circle')\">Reset to all circles</button>\n </div>\n </div>\n\n <!-- Result (Store view) -->\n <div class=\"pane-options\" *ngIf=\"activeCat === 'result' && dr.isStoreMode\">\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'all'\" (click)=\"dr.setResult('all')\">\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'all'\"><span></span></span>\n <span class=\"pane-option-text\">\n <span class=\"pane-option-label\">All</span>\n <span class=\"pane-option-help\">Every store in scope, audited or not.</span>\n </span>\n </div>\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'pass'\" (click)=\"dr.setResult('pass')\">\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'pass'\"><span></span></span>\n <span class=\"pane-option-text\">\n <span class=\"pane-option-label\">Pass</span>\n <span class=\"pane-option-help\">Only stores scoring at or above the {{ passMark }}% pass mark.</span>\n </span>\n </div>\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'fail'\" (click)=\"dr.setResult('fail')\">\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'fail'\"><span></span></span>\n <span class=\"pane-option-text\">\n <span class=\"pane-option-label\">Fail</span>\n <span class=\"pane-option-help\">Only stores scoring below the {{ passMark }}% pass mark.</span>\n </span>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"drawer-foot\">\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"resetFilters()\">Reset all</button>\n <div class=\"av2-grow\"></div>\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--wide\" (click)=\"applyFilters()\">Apply</button>\n </div>\n </div>\n\n</div>\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}::ng-deep .tooltip.av2-tip{--bs-tooltip-bg: #fff;--bs-tooltip-color: #344054;--bs-tooltip-max-width: 320px;--bs-tooltip-opacity: 1}::ng-deep .tooltip.av2-tip .tooltip-inner{background-color:#fff!important;color:#344054!important;padding:8px 12px;border-radius:8px;font-size:13px;line-height:18px;font-weight:500;text-align:left;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,0 0 0 1px #eaecf0}::ng-deep .tooltip.av2-tip .tooltip-arrow:before{border-top-color:#fff;border-bottom-color:#fff}:host ::ng-deep lib-pagination{display:block}:host ::ng-deep lib-pagination .container{max-width:none;padding:0;display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;font-size:14px;color:#475467}:host ::ng-deep lib-pagination .mt-4{margin-top:0!important}:host ::ng-deep lib-pagination .container>.text-center{display:flex;align-items:center}:host ::ng-deep lib-pagination .container>.text-center>ul:not(.ngx-pagination){display:none}:host ::ng-deep lib-pagination pagination-controls{display:flex;align-items:center}:host ::ng-deep lib-pagination .sub-title{color:#475467!important;font-size:14px!important;font-weight:400!important;line-height:20px}:host ::ng-deep lib-pagination .border-val{height:40px;min-width:64px;padding:0 30px 0 12px!important;border:1px solid #D0D5DD!important;border-radius:8px!important;box-shadow:0 1px 2px #1018280d;background-color:#fff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\")!important;background-repeat:no-repeat!important;background-position:right 10px center!important;background-size:14px 14px!important;appearance:none;-webkit-appearance:none;font-size:14px;font-weight:500;color:#1d2939;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}:host ::ng-deep lib-pagination .border-val:hover{border-color:#98a2b3!important}:host ::ng-deep lib-pagination .border-val:focus{outline:none;border-color:#66c8ff!important;box-shadow:0 0 0 3px #eaf8ff}:host ::ng-deep lib-pagination .ngx-pagination{margin:0;padding:0;display:flex;align-items:center;gap:6px;color:#475467!important;font-size:14px!important;font-weight:500}:host ::ng-deep lib-pagination .ngx-pagination li{display:inline-flex;margin:0}:host ::ng-deep lib-pagination .ngx-pagination li.small-screen{display:none!important}:host ::ng-deep lib-pagination .ngx-pagination a,:host ::ng-deep lib-pagination .ngx-pagination button,:host ::ng-deep lib-pagination .ngx-pagination .current,:host ::ng-deep lib-pagination .ngx-pagination .disabled{min-width:40px!important;height:40px;padding:0 8px!important;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;line-height:20px;color:#475467}:host ::ng-deep lib-pagination .ngx-pagination a:hover,:host ::ng-deep lib-pagination .ngx-pagination button:hover{background:#f2f4f7;padding:0 8px!important}:host ::ng-deep lib-pagination .ngx-pagination .current{background:#eaf8ff!important;color:#00a3ff!important;font-weight:600;font-size:14px!important}:host ::ng-deep lib-pagination .ngx-pagination .disabled{color:#98a2b3}:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:after{margin:0}:host ::ng-deep lib-pagination .ngx-pagination .ellipsis:after{color:#98a2b3;padding:0}.rp-pager{padding-top:20px}.rp-head{display:flex;flex-direction:column;gap:2px}.rp-crumb{font-size:13px;line-height:20px;color:#667085}.rp-crumb-current{color:#00a3ff}.rp-title{font-size:22px;line-height:30px;font-weight:600;color:#101828}.rp-controls{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.rp-countpill{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;border-radius:9999px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:600}.rp-chip{height:32px;max-width:360px;padding:0 12px;border:none;border-radius:9999px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0;display:inline-flex;align-items:center;gap:6px;font-family:inherit;font-size:13px;line-height:20px;white-space:nowrap;cursor:pointer}.rp-chip:hover{background:#f9fafb}.rp-chip-key{font-weight:500;color:#667085}.rp-chip-value{overflow:hidden;text-overflow:ellipsis;font-weight:600;color:#101828}.av2-datepick{position:relative;display:inline-flex;align-items:center}.av2-datepick-icon{position:absolute;left:10px;color:#667085;pointer-events:none}.av2-datepick-input{height:36px;padding:0 10px 0 32px;border:none;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;background:#fff;font-family:inherit;font-size:13px;font-weight:500;color:#101828;cursor:pointer;outline:none}.av2-datepick-input:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}:host ::ng-deep .av2-datepick .md-drppicker{margin-top:4px;z-index:1060;font-family:inherit;border-radius:8px;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,inset 0 0 0 1px #eaecf0}:host ::ng-deep .av2-datepick .md-drppicker.double,:host ::ng-deep .av2-datepick .md-drppicker.show-ranges{width:max-content}:host ::ng-deep .av2-datepick .md-drppicker.ltr .ranges{float:left;margin-top:10px}:host ::ng-deep .av2-datepick .md-drppicker .ranges ul li button{width:160px;padding:12px 16px;border:none;border-radius:8px;background:none;color:#344054;font-size:14px;font-weight:400;line-height:20px;text-align:left;cursor:pointer}:host ::ng-deep .av2-datepick .md-drppicker .ranges ul li button.active{background:#eaf8ff;color:#00a3ff;font-weight:500}:host ::ng-deep .av2-datepick .md-drppicker th,:host ::ng-deep .av2-datepick .md-drppicker td{width:40px!important;height:40px!important;min-width:32px;padding:0!important;border:1px solid transparent!important;background:transparent!important;font-size:14px!important;font-weight:400!important;line-height:38px}:host ::ng-deep .av2-datepick .md-drppicker th{color:#344054!important;font-weight:500!important}:host ::ng-deep .av2-datepick .md-drppicker th.month{width:auto!important;font-size:16px!important}:host ::ng-deep .av2-datepick .md-drppicker td{color:#344054!important}:host ::ng-deep .av2-datepick .md-drppicker th.available.prev,:host ::ng-deep .av2-datepick .md-drppicker th.available.next{background:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='15 6 9 12 15 18'/%3E%3C/svg%3E\") center/18px no-repeat!important}:host ::ng-deep .av2-datepick .md-drppicker th.available:hover,:host ::ng-deep .av2-datepick .md-drppicker td.available:hover{background-color:#f2f4f7!important}:host ::ng-deep .av2-datepick .md-drppicker td.in-range{background-color:#eaf8ff!important;color:#101828!important}:host ::ng-deep .av2-datepick .md-drppicker td.active,:host ::ng-deep .av2-datepick .md-drppicker td.active:hover{background-color:#029cf4!important;border-radius:20px;color:#fff!important;font-weight:500!important}:host ::ng-deep .av2-datepick .md-drppicker td.off,:host ::ng-deep .av2-datepick .md-drppicker td.off.in-range{color:#98a2b3!important;background-color:transparent!important}:host ::ng-deep .av2-datepick .md-drppicker td.disabled{color:#98a2b3!important;background-color:transparent!important;text-decoration:line-through;pointer-events:none}:host ::ng-deep .av2-datepick--compact .md-drppicker th,:host ::ng-deep .av2-datepick--compact .md-drppicker td{width:32px!important;height:32px!important;font-size:12px!important;line-height:30px}:host ::ng-deep .av2-datepick--compact .md-drppicker th.month{font-size:14px!important}.rp-daterange{width:260px;height:44px;font-size:14px}.rp-presets{display:flex;flex-wrap:wrap;gap:8px}.rp-preset{height:36px;padding:0 14px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0;font-family:inherit;font-size:14px;font-weight:500;color:#667085;cursor:pointer}.rp-preset.is-on{background:#eaf8ff;box-shadow:inset 0 0 0 1px #99dbff;color:#101828;font-weight:600}.rp-drillbar{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:14px 18px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}.rp-drillcrumb{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;color:#00a3ff;cursor:pointer}.rp-drillcrumb.is-current{color:#101828;cursor:default}.rp-drillsep{color:#98a2b3;font-weight:400}.rp-hint{font-size:14px;color:#667085}.rp-scope{display:flex;flex-direction:column;gap:2px}.rp-scope-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.rp-scope-meta{font-size:14px;line-height:20px;color:#667085}.rp-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:16px}.rp-kpi-value.is-good{color:#027a48}.rp-kpi-value.is-bad{color:#d92d20}.rp-sk-value{height:32px;margin:3px 0}.rp-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:18px 20px 12px;display:flex;flex-direction:column;gap:14px}.rp-card-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.rp-card-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:200px}.rp-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.rp-card-meta{font-size:14px;line-height:20px;color:#667085}.rp-search{width:260px}.rp-table{width:100%;border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed}.rp-table th:nth-child(1){width:29%}.rp-table th:nth-child(2){width:9.5%}.rp-table th:nth-child(3){width:8.5%}.rp-table th:nth-child(4){width:9.5%}.rp-table th:nth-child(5){width:9.5%}.rp-table th:nth-child(6){width:12%}.rp-table th:nth-child(7){width:11%}.rp-table th:nth-child(8){width:11%}.rp-table--stores th:nth-child(1){width:14%}.rp-table--stores th:nth-child(2){width:20%}.rp-table--stores th:nth-child(3){width:16%}.rp-table--stores th:nth-child(4){width:9%}.rp-table--stores th:nth-child(5){width:9%}.rp-table--stores th:nth-child(6){width:11%}.rp-table--stores th:nth-child(7){width:12%}.rp-table--stores th:nth-child(8){width:9%}.rp-table--userstores th:nth-child(1){width:18%}.rp-table--userstores th:nth-child(2){width:25%}.rp-table--userstores th:nth-child(3){width:25%}.rp-table--userstores th:nth-child(4){width:11%}.rp-table--userstores th:nth-child(5){width:10%}.rp-table--userstores th:nth-child(6){width:11%}.rp-table thead th{padding:8px 4px;border:0;border-bottom:1px solid #EAECF0;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;white-space:nowrap}.rp-table tbody td{padding:12px 4px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;color:#344054;vertical-align:middle}.rp-table tfoot td{padding:12px 4px;border:0;font-size:14px;line-height:20px;font-weight:700;color:#101828}.rp-table thead th.t-right,.rp-table tbody td.t-right,.rp-table tfoot td.t-right{text-align:right}.rp-table .is-strong{font-weight:600}.rp-table tbody td.is-muted{color:#98a2b3}.rp-table tbody td.is-pass{color:#027a48}.rp-table tbody td.is-fail{color:#d92d20}.rp-table tbody td.rp-cell-name{color:#101828;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-result{display:inline-flex;padding:2px 10px;border-radius:9999px;background:#f2f4f7;font-size:12px;line-height:18px;font-weight:500;color:#475467;white-space:nowrap}.rp-result.is-pass{background:#ecfdf3;color:#027a48}.rp-result.is-fail{background:#fef3f2;color:#b42318}.rp-row{cursor:pointer}.rp-row:hover td{background:#fcfcfd}.rp-name{display:flex;flex-direction:column;gap:2px;min-width:0}.rp-name-main{font-weight:600;color:#00a3ff}.rp-name-sub{font-size:12px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-export{height:32px;padding:0 12px;border:none;border-radius:6px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#344054;cursor:pointer}.rp-export:hover{background:#f9fafb}.filter-backdrop{position:fixed;inset:0;background:#10182873;z-index:1050}.filter-drawer{position:fixed;top:0;right:0;bottom:0;width:860px;max-width:96vw;display:flex;flex-direction:column;background:#fff;box-shadow:-10px 0 30px #1018282e;z-index:1051;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.drawer-head{display:flex;align-items:center;gap:10px;padding:18px 20px;box-shadow:inset 0 -1px #eaecf0}.drawer-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.closebtn{width:32px;height:32px;border:none;border-radius:8px;background:transparent;color:#667085;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.closebtn:hover{background:#f2f4f7;color:#344054}.drawer-body{display:flex;flex:1;min-height:0}.drawer-nav{flex:0 0 280px;max-width:280px;background:#f9fafb;box-shadow:inset -1px 0 #eaecf0;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:4px}.drawer-navitem{display:flex;align-items:center;gap:10px;width:100%;padding:12px 14px;border:none;border-radius:8px;background:transparent;text-align:left;font-family:inherit;cursor:pointer}.drawer-navitem:hover{background:#fff}.drawer-navitem.navitem-active{background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d}.navtext{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.navtitle{font-size:14px;line-height:20px;font-weight:600;color:#101828}.navvalue{font-size:14px;line-height:20px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.navvalue.is-dirty{color:#009bf3}.dirtydot{width:8px;height:8px;border-radius:9999px;background:#00a3ff;flex-shrink:0;display:block}.drawer-pane{flex:1;min-width:0;overflow-y:auto;padding:24px 28px;display:flex;flex-direction:column;gap:6px}.panetitle{font-size:18px;line-height:28px;font-weight:600;color:#101828}.panehint{font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.pane-stack{display:flex;flex-direction:column;gap:14px;margin-top:14px;max-width:560px}.pane-options{display:flex;flex-direction:column;gap:10px;margin-top:14px;max-width:560px}.pane-option{display:flex;align-items:flex-start;gap:12px;padding:14px 16px;border-radius:8px;cursor:pointer;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0}.pane-option.is-on{background:#f5fbff;box-shadow:inset 0 0 0 1.5px #00a3ff}.pane-radio{width:18px;height:18px;flex-shrink:0;margin-top:2px;border-radius:9999px;display:flex;align-items:center;justify-content:center;box-shadow:inset 0 0 0 1px #d0d5dd}.pane-radio>span{width:8px;height:8px;border-radius:9999px;background:transparent;display:block}.pane-radio.is-on{box-shadow:inset 0 0 0 1.5px #00a3ff}.pane-radio.is-on>span{background:#00a3ff}.pane-option-text{display:flex;flex-direction:column;gap:2px}.pane-option-label{font-size:14px;line-height:20px;font-weight:600;color:#101828}.pane-option-help{font-size:14px;line-height:20px;color:#667085}.drawer-foot{display:flex;align-items:center;gap:10px;padding:14px 20px;box-shadow:inset 0 1px #eaecf0}.rp-reset{border:none;background:transparent;padding:0;font-family:inherit;font-weight:600;text-decoration:none;white-space:nowrap}.rp-pick-search{width:100%}.rp-picklist{max-height:320px;overflow-y:auto;padding:6px;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;display:flex;flex-direction:column}.rp-pick{display:flex;align-items:center;gap:12px;min-height:40px;margin:0;padding:0 10px;border-radius:6px;font-size:14px;color:#344054;cursor:pointer}.rp-pick:hover{background:#f9fafb}.rp-pick.is-all{font-weight:600}.rp-pick input{appearance:none;-webkit-appearance:none;flex-shrink:0;width:16px;height:16px;margin:0;border:1px solid #D0D5DD;border-radius:4px;background:#fff no-repeat center/12px 12px;cursor:pointer;vertical-align:middle;transition:border-color .12s ease,background-color .12s ease}.rp-pick input:hover:not(:disabled){border-color:#00a3ff}.rp-pick input:checked{border-color:#00a3ff;background-color:#eaf8ff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2300A3FF' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E\")}.rp-pick input:focus-visible{outline:none;box-shadow:0 0 0 3px #eaf8ff}.rp-pick input:disabled{cursor:not-allowed;opacity:.45}.rp-pick-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-pick-sub{max-width:45%;font-size:12px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-pick-empty{padding:20px 10px;font-size:14px;color:#667085}.rp-reading{display:flex;align-items:center;gap:12px;padding:12px 16px;border-radius:8px;background:#f9fafb;font-size:14px;color:#475467}.rp-reading strong{font-weight:600;color:#101828}.rp-field{display:flex;flex-direction:column;gap:6px;min-width:0}.rp-field-label{display:flex;align-items:baseline;gap:8px;font-size:14px;line-height:20px;font-weight:600;color:#1d2939}.rp-field-label span{font-weight:400;color:#667085}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i8.DaterangepickerDirective, selector: "input[ngxDaterangepickerMd]", inputs: ["minDate", "maxDate", "autoApply", "alwaysShowCalendars", "showCustomRangeLabel", "linkedCalendars", "dateLimit", "singleDatePicker", "showWeekNumbers", "showISOWeekNumbers", "showDropdowns", "isInvalidDate", "isCustomDate", "isTooltipDate", "showClearButton", "customRangeDirection", "ranges", "opens", "drops", "firstMonthDayClass", "lastMonthDayClass", "emptyWeekRowClass", "emptyWeekColumnClass", "firstDayOfNextMonthClass", "lastDayOfPreviousMonthClass", "keepCalendarOpeningWithRange", "showRangeLabelOnInput", "showCancel", "lockStartDate", "timePicker", "timePicker24Hour", "timePickerIncrement", "timePickerSeconds", "closeOnAutoApply", "endKeyHolder", "startKey", "locale", "endKey"], outputs: ["change", "rangeClicked", "datesUpdated", "startDateChanged", "endDateChanged", "clearClicked"] }, { kind: "directive", type: AuditV2TipDirective, selector: "[av2Tip]", inputs: ["av2Tip"] }, { kind: "component", type: AuditV2ShimmerComponent, selector: "lib-audit-v2-shimmer", inputs: ["rows"] }, { kind: "component", type: AuditV2SelectComponent, selector: "lib-audit-v2-select", inputs: ["options", "placeholder", "searchable", "ariaLabel", "disabled", "value"], outputs: ["changed"] }, { kind: "component", type: AuditV2SortIconComponent, selector: "lib-audit-v2-sort-icon", inputs: ["active", "dir"] }] });
9099
9166
  }
9100
9167
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuditV2ReportsComponent, decorators: [{
9101
9168
  type: Component,
9102
- args: [{ selector: 'lib-audit-v2-reports', template: "<div class=\"av2-page audit-reports\">\r\n\r\n <!-- Breadcrumb + title -->\r\n <div class=\"rp-head\">\r\n <div class=\"rp-crumb\">Audits \u203A <span class=\"rp-crumb-current\">Reports</span></div>\r\n <div class=\"rp-title\">Store audit report</div>\r\n </div>\r\n\r\n <!-- Filter chips, Filter button at the right end (QA 9 Oct); Export moved to the table head beside its search. -->\r\n <div class=\"rp-controls\">\r\n <button type=\"button\" class=\"rp-chip\" *ngFor=\"let c of chips; trackBy: trackByChip\" (click)=\"openFilters(c.key)\"\r\n [title]=\"c.label + ': ' + c.value\">\r\n <span class=\"rp-chip-key\">{{ c.label }}</span><span class=\"rp-chip-value\">{{ c.value }}</span>\r\n </button>\r\n <div class=\"av2-grow\"></div>\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost rp-filterbtn\" (click)=\"openFilters()\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"></polygon></svg>\r\n Filter\r\n <span class=\"rp-countpill\">{{ filterCount }}</span>\r\n </button>\r\n </div>\r\n\r\n <!-- User view: where in the hierarchy -->\r\n <div class=\"rp-drillbar\" *ngIf=\"!isStoreMode\">\r\n <ng-container *ngFor=\"let c of crumbs; let last = last; let first = first\">\r\n <div class=\"rp-drillcrumb\" [class.is-current]=\"last\" (click)=\"goToLevel(c.level)\">\r\n <span class=\"rp-drillsep\" *ngIf=\"!first\">\u203A</span>{{ c.label }}\r\n </div>\r\n </ng-container>\r\n <div class=\"av2-grow\"></div>\r\n <div class=\"rp-hint\">{{ hint }}</div>\r\n </div>\r\n\r\n <!-- Scope -->\r\n <div class=\"rp-scope\">\r\n <div class=\"rp-scope-title\">{{ scopeTitle }}</div>\r\n <div class=\"rp-scope-meta\">{{ scopeMeta }}</div>\r\n </div>\r\n\r\n <!-- KPIs -->\r\n <div class=\"rp-kpis\">\r\n <!-- Old Checklist summary card: figure + label in the gradient strip, note below. -->\r\n <div class=\"av2-ocard\" *ngFor=\"let kpi of kpis\">\r\n <div class=\"av2-ocard-head\">\r\n <div class=\"av2-ocard-count rp-kpi-value\" [class.is-good]=\"kpi.tone === 'good'\" [class.is-bad]=\"kpi.tone === 'bad'\">\r\n <span *ngIf=\"loading\" class=\"av2-sk av2-sk--value rp-sk-value\"></span>\r\n <ng-container *ngIf=\"!loading\">{{ kpi.value }}</ng-container>\r\n </div>\r\n <div class=\"av2-ocard-text\">{{ kpi.label }}</div>\r\n </div>\r\n <div class=\"av2-ocard-body\">\r\n <span *ngIf=\"loading\" class=\"av2-sk av2-sk--note\"></span>\r\n <div *ngIf=\"!loading\" class=\"av2-ocard-note\">{{ kpi.note }}</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Report table -->\r\n <section class=\"rp-card\">\r\n <div class=\"rp-card-head\">\r\n <div class=\"rp-card-text\">\r\n <ng-container *ngIf=\"isStoreMode\">\r\n <div class=\"rp-card-title\">Store report</div>\r\n <div class=\"rp-card-meta\">{{ storeRows.length }} {{ storeRows.length === 1 ? 'store' : 'stores' }} \u00B7 audits submitted in the period</div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!isStoreMode\">\r\n <div class=\"rp-card-title\">{{ tableTitle }}</div>\r\n <div class=\"rp-card-meta\">{{ tableMeta }}</div>\r\n </ng-container>\r\n </div>\r\n <div class=\"av2-grow\"></div>\r\n <label class=\"av2-search rp-search\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\">\r\n <circle cx=\"11\" cy=\"11\" r=\"7\"></circle>\r\n <line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line>\r\n </svg>\r\n <input type=\"text\" [placeholder]=\"isStoreMode ? 'Search store' : 'Search ' + levelLabel.toLowerCase()\"\r\n [(ngModel)]=\"search\" (ngModelChange)=\"onSearchChange()\">\r\n </label>\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost\" [disabled]=\"loading\" (click)=\"exportAll()\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 16V4\"></path><polyline points=\"7 9 12 4 17 9\"></polyline><path d=\"M4 16v4h16v-4\"></path></svg>\r\n Export\r\n </button>\r\n </div>\r\n\r\n <lib-audit-v2-shimmer *ngIf=\"loading\"></lib-audit-v2-shimmer>\r\n\r\n <!-- Store view: one row per store -->\r\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && isStoreMode && tableCount\">\r\n <table class=\"rp-table rp-table--stores\">\r\n <thead>\r\n <tr>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('cluster')\">Cluster <lib-audit-v2-sort-icon [active]=\"sortKey === 'cluster'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('aom')\">Area manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'aom'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('score')\">Score <lib-audit-v2-sort-icon [active]=\"sortKey === 'score'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('status')\">Result <lib-audit-v2-sort-icon [active]=\"sortKey === 'status'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('lastAudit')\">Last audit <lib-audit-v2-sort-icon [active]=\"sortKey === 'lastAudit'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right\">Export</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let s of storePageRows; trackBy: trackByKey\">\r\n <td class=\"is-strong rp-cell-name\" [av2Tip]=\"s.name\">{{ s.name }}</td>\r\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.cluster\">{{ s.cluster || '\u2014' }}</td>\r\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.aom\">{{ s.aom || '\u2014' }}</td>\r\n <td class=\"t-right\" [class.is-muted]=\"!s.audited\">{{ s.audited ? 'Yes' : 'No' }}</td>\r\n <td class=\"t-right is-strong\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\"\r\n [class.is-muted]=\"s.score === null\">{{ scoreText(s) }}</td>\r\n <td class=\"t-right\">\r\n <span class=\"rp-result\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\">{{ resultText(s) }}</span>\r\n </td>\r\n <td class=\"t-right\" [class.is-muted]=\"!s.lastAudit\">{{ s.lastAudit || 'No audit' }}</td>\r\n <td class=\"t-right\">\r\n <button type=\"button\" class=\"rp-export\" (click)=\"exportStore(s)\">Export</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tfoot>\r\n <tr class=\"rp-total\">\r\n <td>Total</td>\r\n <td></td>\r\n <td></td>\r\n <td class=\"t-right\">{{ totalAuditedOf }}</td>\r\n <td class=\"t-right\">{{ totalAverage }}</td>\r\n <td class=\"t-right\">{{ totals.failed }} fail</td>\r\n <td></td>\r\n <td></td>\r\n </tr>\r\n </tfoot>\r\n </table>\r\n </div>\r\n\r\n <!-- User view: circle head / zone manager / area manager roll-up -->\r\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && !isStoreMode && level !== 'store' && tableCount\">\r\n <table class=\"rp-table\">\r\n <thead>\r\n <tr>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">{{ levelLabel }} <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('total')\">Total stores <lib-audit-v2-sort-icon [active]=\"sortKey === 'total'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('notAudited')\">Not audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'notAudited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('coverage')\">Coverage <lib-audit-v2-sort-icon [active]=\"sortKey === 'coverage'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('avgScore')\">Avg audit score <lib-audit-v2-sort-icon [active]=\"sortKey === 'avgScore'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('failedPct')\">Failed store % <lib-audit-v2-sort-icon [active]=\"sortKey === 'failedPct'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right\">Report</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let row of pageRows; trackBy: trackByRow\" class=\"rp-row\" (click)=\"openRow(row)\">\r\n <td>\r\n <div class=\"rp-name\">\r\n <span class=\"rp-name-main\">{{ row.name }}</span>\r\n <span class=\"rp-name-sub\" *ngIf=\"row.email\">{{ row.email }}</span>\r\n </div>\r\n </td>\r\n <td class=\"t-right\">{{ row.total }}</td>\r\n <td class=\"t-right\">{{ row.audited }}</td>\r\n <td class=\"t-right\" [class.is-muted]=\"!row.notAudited\">{{ row.notAudited }}</td>\r\n <td class=\"t-right\">{{ row.coverage }}</td>\r\n <td class=\"t-right is-strong\">{{ row.avgScore }}</td>\r\n <td class=\"t-right is-strong\" [class.is-fail]=\"isHighFail(row)\">{{ row.failedPct }}</td>\r\n <td class=\"t-right\">\r\n <button type=\"button\" class=\"rp-export\" (click)=\"exportRow(row); $event.stopPropagation()\">Export</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tfoot>\r\n <tr class=\"rp-total\">\r\n <td>Total</td>\r\n <td class=\"t-right\">{{ totals.total }}</td>\r\n <td class=\"t-right\">{{ totals.audited }}</td>\r\n <td class=\"t-right\">{{ totals.total - totals.audited }}</td>\r\n <td class=\"t-right\">{{ totalCoverage }}</td>\r\n <td class=\"t-right\">{{ totalAverage }}</td>\r\n <td class=\"t-right\">{{ totalFailedPct }}</td>\r\n <td></td>\r\n </tr>\r\n </tfoot>\r\n </table>\r\n </div>\r\n\r\n <!-- User view, deepest level: the area manager's stores -->\r\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && !isStoreMode && level === 'store' && tableCount\">\r\n <table class=\"rp-table rp-table--userstores\">\r\n <thead>\r\n <tr>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('aom')\">Area manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'aom'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"av2-sortable\" (click)=\"sortBy('zone')\">Zone manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'zone'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('score')\">Score <lib-audit-v2-sort-icon [active]=\"sortKey === 'score'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\r\n <th class=\"t-right\">Export</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let s of userStorePageRows; trackBy: trackByKey\">\r\n <td class=\"is-strong rp-cell-name\" [av2Tip]=\"s.name\">{{ s.name }}</td>\r\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.aom\">{{ s.aom || '\u2014' }}</td>\r\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.zone\">{{ s.zone || '\u2014' }}</td>\r\n <td class=\"t-right\" [class.is-muted]=\"!s.audited\">{{ s.audited ? 'Yes' : 'No' }}</td>\r\n <td class=\"t-right is-strong\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\"\r\n [class.is-muted]=\"s.score === null\">{{ scoreText(s) }}</td>\r\n <td class=\"t-right\">\r\n <button type=\"button\" class=\"rp-export\" (click)=\"exportStore(s)\">Export</button>\r\n </td>\r\n </tr>\r\n </tbody>\r\n <tfoot>\r\n <tr class=\"rp-total\">\r\n <td>Total</td>\r\n <td></td>\r\n <td></td>\r\n <td class=\"t-right\">{{ totalAuditedOf }}</td>\r\n <td class=\"t-right\">{{ totalAverage }}</td>\r\n <td></td>\r\n </tr>\r\n </tfoot>\r\n </table>\r\n </div>\r\n\r\n <div *ngIf=\"!loading && !tableCount\" class=\"av2-empty\">\r\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\r\n <div class=\"av2-empty-text\">\r\n <div class=\"av2-empty-title\">No data found</div>\r\n <div class=\"av2-empty-sub\">{{ search ? 'No rows match \"' + search + '\"' : 'No stores match the current filters' }}</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Shared pager (10 / 20 / 30), as on the other audit lists. -->\r\n <div class=\"rp-pager\" *ngIf=\"!loading && tableCount\">\r\n <lib-pagination [itemsPerPage]=\"pageSize\" [pageSize]=\"pageSize\" [paginationSizes]=\"pageSizes\" [currentPage]=\"page\"\r\n [totalItems]=\"tableCount\" (pageChange)=\"onPageChange($event)\" (pageSizeChange)=\"onPageSizeChange($event)\"></lib-pagination>\r\n </div>\r\n </section>\r\n\r\n <!-- ============ FILTER DRAWER ============ -->\r\n <div class=\"filter-backdrop\" *ngIf=\"filtersOpen\" (click)=\"closeFilters()\"></div>\r\n\r\n <!-- Every control edits the drawer's draft (dr); the page behind changes only on Apply or Reset all. -->\r\n <div class=\"filter-drawer\" *ngIf=\"filtersOpen && draft as dr\">\r\n <div class=\"drawer-head\">\r\n <span class=\"drawer-title\">Filters</span>\r\n <span class=\"rp-countpill\">{{ dr.filterCount }}</span>\r\n <div class=\"av2-grow\"></div>\r\n <button type=\"button\" class=\"closebtn\" (click)=\"closeFilters()\" title=\"Close\">\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"drawer-body\">\r\n <div class=\"drawer-nav\">\r\n <!-- trackBy: filterCats is rebuilt on every check, and lib-audit-v2-select's document:mousedown runs one\r\n between press and release; without it the button was replaced mid-click and the click never landed. -->\r\n <button type=\"button\" class=\"drawer-navitem\" *ngFor=\"let c of dr.filterCats; trackBy: trackByChip\" [class.navitem-active]=\"activeCat === c.key\"\r\n (click)=\"selectCat(c.key)\">\r\n <span class=\"navtext\">\r\n <span class=\"navtitle\">{{ c.label }}</span>\r\n <span class=\"navvalue\" [class.is-dirty]=\"c.dirty\">{{ c.value }}</span>\r\n </span>\r\n <span class=\"dirtydot\" *ngIf=\"c.dirty\"></span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"drawer-pane\">\r\n <div class=\"panetitle\">{{ dr.paneTitle }}</div>\r\n <div class=\"panehint\">{{ dr.paneSub }}</div>\r\n\r\n <!-- Date -->\r\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'date'\">\r\n <div class=\"av2-datepick\">\r\n <svg class=\"av2-datepick-icon\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"></rect>\r\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"></line><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"></line><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"></line></svg>\r\n <input type=\"text\" class=\"av2-datepick-input rp-daterange\" ngxDaterangepickerMd readonly autocomplete=\"off\"\r\n placeholder=\"Select date range\" [(ngModel)]=\"dr.range\" [locale]=\"pickerLocale\" [maxDate]=\"today\"\r\n [ranges]=\"ranges\" [showCustomRangeLabel]=\"true\" [alwaysShowCalendars]=\"false\"\r\n [keepCalendarOpeningWithRange]=\"true\" [autoApply]=\"true\" [showCancel]=\"false\"\r\n [drops]=\"'down'\" [opens]=\"'right'\" (datesUpdated)=\"dr.onRangePicked($event)\">\r\n </div>\r\n <div class=\"rp-presets\">\r\n <button type=\"button\" class=\"rp-preset\" *ngFor=\"let p of presets\" [class.is-on]=\"dr.preset === p\"\r\n (click)=\"dr.setPreset(p)\">{{ p }}</button>\r\n </div>\r\n </div>\r\n\r\n <!-- View by -->\r\n <div class=\"pane-options\" *ngIf=\"activeCat === 'mode'\">\r\n <div class=\"pane-option\" [class.is-on]=\"dr.isStoreMode\" (click)=\"dr.setMode('store')\">\r\n <span class=\"pane-radio\" [class.is-on]=\"dr.isStoreMode\"><span></span></span>\r\n <span class=\"pane-option-text\">\r\n <span class=\"pane-option-label\">Store</span>\r\n <span class=\"pane-option-help\">One row per store with score, result and last audit date.</span>\r\n </span>\r\n </div>\r\n <div class=\"pane-option\" [class.is-on]=\"!dr.isStoreMode\" (click)=\"dr.setMode('user')\">\r\n <span class=\"pane-radio\" [class.is-on]=\"!dr.isStoreMode\"><span></span></span>\r\n <span class=\"pane-option-text\">\r\n <span class=\"pane-option-label\">User</span>\r\n <span class=\"pane-option-help\">Rolled up by circle head, zone manager and AOM, drillable down to stores.</span>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- Stores (Store view) -->\r\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'scope' && dr.isStoreMode\">\r\n <label class=\"av2-search rp-pick-search\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\r\n <input type=\"text\" placeholder=\"Search store\" [(ngModel)]=\"dr.storeQuery\">\r\n </label>\r\n <div class=\"rp-picklist\">\r\n <ng-container *ngIf=\"dr.storePickItems.length\">\r\n <label class=\"rp-pick is-all\">\r\n <input type=\"checkbox\" [checked]=\"dr.storePickAllChecked\" (change)=\"dr.toggleStorePickAll()\">\r\n <span>Select All</span>\r\n </label>\r\n <label class=\"rp-pick\" *ngFor=\"let it of dr.storePickItems; trackBy: trackByPick\">\r\n <input type=\"checkbox\" [checked]=\"it.checked\" (change)=\"dr.toggleStorePick(it.store)\">\r\n <span class=\"rp-pick-label\">{{ it.store.name }}</span>\r\n <span class=\"rp-pick-sub\">{{ it.store.cluster || it.store.aom }}</span>\r\n </label>\r\n </ng-container>\r\n <div class=\"rp-pick-empty\" *ngIf=\"!dr.storePickItems.length\">\r\n {{ dr.storeQuery ? 'No stores match \"' + dr.storeQuery + '\"' : 'No stores in scope' }}\r\n </div>\r\n </div>\r\n <div class=\"rp-reading\">\r\n <span>Reading</span>\r\n <strong>{{ dr.storePickReading }}</strong>\r\n <span class=\"av2-grow\"></span>\r\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"dr.resetStorePick()\">Reset to all stores</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Store hierarchy (User view) -->\r\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'scope' && !dr.isStoreMode\">\r\n <div class=\"rp-field\">\r\n <div class=\"rp-field-label\">Circle Head <span>{{ dr.circleOptions.length - 1 }} users</span></div>\r\n <lib-audit-v2-select [value]=\"dr.circleKey\" [options]=\"dr.circleOptions\" placeholder=\"All circles\"\r\n ariaLabel=\"Circle Head\" (changed)=\"dr.pickCircle($event.target.value)\"></lib-audit-v2-select>\r\n </div>\r\n <div class=\"rp-field\" *ngIf=\"dr.showZonePick\">\r\n <div class=\"rp-field-label\">Zone Manager <span>{{ dr.zoneOptions.length - 1 }} {{ dr.zoneOptions.length === 2 ? 'user' : 'users' }}</span></div>\r\n <lib-audit-v2-select [value]=\"dr.zoneKey\" [options]=\"dr.zoneOptions\" placeholder=\"All zones\"\r\n ariaLabel=\"Zone Manager\" (changed)=\"dr.pickZone($event.target.value)\"></lib-audit-v2-select>\r\n </div>\r\n <div class=\"rp-field\" *ngIf=\"dr.zoneKey\">\r\n <div class=\"rp-field-label\">AOM <span>{{ dr.aomOptions.length - 1 }} {{ dr.aomOptions.length === 2 ? 'user' : 'users' }}</span></div>\r\n <lib-audit-v2-select [value]=\"dr.aomKey\" [options]=\"dr.aomOptions\" placeholder=\"All AOMs\"\r\n ariaLabel=\"AOM\" (changed)=\"dr.pickAom($event.target.value)\"></lib-audit-v2-select>\r\n </div>\r\n <div class=\"rp-field\" *ngIf=\"dr.aomKey\">\r\n <div class=\"rp-field-label\">Store <span>{{ dr.storeOptions.length - 1 }} stores</span></div>\r\n <lib-audit-v2-select [value]=\"dr.storeKey\" [options]=\"dr.storeOptions\" placeholder=\"All stores\"\r\n ariaLabel=\"Store\" (changed)=\"dr.pickStore($event.target.value)\"></lib-audit-v2-select>\r\n </div>\r\n <div class=\"rp-reading\">\r\n <span>Reading</span>\r\n <strong>{{ dr.hierarchyReading }}</strong>\r\n <span class=\"av2-grow\"></span>\r\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"dr.goToLevel('circle')\">Reset to all circles</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Result (Store view) -->\r\n <div class=\"pane-options\" *ngIf=\"activeCat === 'result' && dr.isStoreMode\">\r\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'all'\" (click)=\"dr.setResult('all')\">\r\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'all'\"><span></span></span>\r\n <span class=\"pane-option-text\">\r\n <span class=\"pane-option-label\">All</span>\r\n <span class=\"pane-option-help\">Every store in scope, audited or not.</span>\r\n </span>\r\n </div>\r\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'pass'\" (click)=\"dr.setResult('pass')\">\r\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'pass'\"><span></span></span>\r\n <span class=\"pane-option-text\">\r\n <span class=\"pane-option-label\">Pass</span>\r\n <span class=\"pane-option-help\">Only stores scoring at or above the {{ passMark }}% pass mark.</span>\r\n </span>\r\n </div>\r\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'fail'\" (click)=\"dr.setResult('fail')\">\r\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'fail'\"><span></span></span>\r\n <span class=\"pane-option-text\">\r\n <span class=\"pane-option-label\">Fail</span>\r\n <span class=\"pane-option-help\">Only stores scoring below the {{ passMark }}% pass mark.</span>\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"drawer-foot\">\r\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"resetFilters()\">Reset all</button>\r\n <div class=\"av2-grow\"></div>\r\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--wide\" (click)=\"applyFilters()\">Apply</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}::ng-deep .tooltip.av2-tip{--bs-tooltip-bg: #fff;--bs-tooltip-color: #344054;--bs-tooltip-max-width: 320px;--bs-tooltip-opacity: 1}::ng-deep .tooltip.av2-tip .tooltip-inner{background-color:#fff!important;color:#344054!important;padding:8px 12px;border-radius:8px;font-size:13px;line-height:18px;font-weight:500;text-align:left;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,0 0 0 1px #eaecf0}::ng-deep .tooltip.av2-tip .tooltip-arrow:before{border-top-color:#fff;border-bottom-color:#fff}:host ::ng-deep lib-pagination{display:block}:host ::ng-deep lib-pagination .container{max-width:none;padding:0;display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;font-size:14px;color:#475467}:host ::ng-deep lib-pagination .mt-4{margin-top:0!important}:host ::ng-deep lib-pagination .container>.text-center{display:flex;align-items:center}:host ::ng-deep lib-pagination .container>.text-center>ul:not(.ngx-pagination){display:none}:host ::ng-deep lib-pagination pagination-controls{display:flex;align-items:center}:host ::ng-deep lib-pagination .sub-title{color:#475467!important;font-size:14px!important;font-weight:400!important;line-height:20px}:host ::ng-deep lib-pagination .border-val{height:40px;min-width:64px;padding:0 30px 0 12px!important;border:1px solid #D0D5DD!important;border-radius:8px!important;box-shadow:0 1px 2px #1018280d;background-color:#fff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\")!important;background-repeat:no-repeat!important;background-position:right 10px center!important;background-size:14px 14px!important;appearance:none;-webkit-appearance:none;font-size:14px;font-weight:500;color:#1d2939;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}:host ::ng-deep lib-pagination .border-val:hover{border-color:#98a2b3!important}:host ::ng-deep lib-pagination .border-val:focus{outline:none;border-color:#66c8ff!important;box-shadow:0 0 0 3px #eaf8ff}:host ::ng-deep lib-pagination .ngx-pagination{margin:0;padding:0;display:flex;align-items:center;gap:6px;color:#475467!important;font-size:14px!important;font-weight:500}:host ::ng-deep lib-pagination .ngx-pagination li{display:inline-flex;margin:0}:host ::ng-deep lib-pagination .ngx-pagination li.small-screen{display:none!important}:host ::ng-deep lib-pagination .ngx-pagination a,:host ::ng-deep lib-pagination .ngx-pagination button,:host ::ng-deep lib-pagination .ngx-pagination .current,:host ::ng-deep lib-pagination .ngx-pagination .disabled{min-width:40px!important;height:40px;padding:0 8px!important;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;line-height:20px;color:#475467}:host ::ng-deep lib-pagination .ngx-pagination a:hover,:host ::ng-deep lib-pagination .ngx-pagination button:hover{background:#f2f4f7;padding:0 8px!important}:host ::ng-deep lib-pagination .ngx-pagination .current{background:#eaf8ff!important;color:#00a3ff!important;font-weight:600;font-size:14px!important}:host ::ng-deep lib-pagination .ngx-pagination .disabled{color:#98a2b3}:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:after{margin:0}:host ::ng-deep lib-pagination .ngx-pagination .ellipsis:after{color:#98a2b3;padding:0}.rp-pager{padding-top:20px}.rp-head{display:flex;flex-direction:column;gap:2px}.rp-crumb{font-size:13px;line-height:20px;color:#667085}.rp-crumb-current{color:#00a3ff}.rp-title{font-size:22px;line-height:30px;font-weight:600;color:#101828}.rp-controls{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.rp-countpill{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;border-radius:9999px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:600}.rp-chip{height:32px;max-width:360px;padding:0 12px;border:none;border-radius:9999px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0;display:inline-flex;align-items:center;gap:6px;font-family:inherit;font-size:13px;line-height:20px;white-space:nowrap;cursor:pointer}.rp-chip:hover{background:#f9fafb}.rp-chip-key{font-weight:500;color:#667085}.rp-chip-value{overflow:hidden;text-overflow:ellipsis;font-weight:600;color:#101828}.av2-datepick{position:relative;display:inline-flex;align-items:center}.av2-datepick-icon{position:absolute;left:10px;color:#667085;pointer-events:none}.av2-datepick-input{height:36px;padding:0 10px 0 32px;border:none;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;background:#fff;font-family:inherit;font-size:13px;font-weight:500;color:#101828;cursor:pointer;outline:none}.av2-datepick-input:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}:host ::ng-deep .av2-datepick .md-drppicker{margin-top:4px;z-index:1060;font-family:inherit;border-radius:8px;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,inset 0 0 0 1px #eaecf0}:host ::ng-deep .av2-datepick .md-drppicker.double,:host ::ng-deep .av2-datepick .md-drppicker.show-ranges{width:max-content}:host ::ng-deep .av2-datepick .md-drppicker.ltr .ranges{float:left;margin-top:10px}:host ::ng-deep .av2-datepick .md-drppicker .ranges ul li button{width:160px;padding:12px 16px;border:none;border-radius:8px;background:none;color:#344054;font-size:14px;font-weight:400;line-height:20px;text-align:left;cursor:pointer}:host ::ng-deep .av2-datepick .md-drppicker .ranges ul li button.active{background:#eaf8ff;color:#00a3ff;font-weight:500}:host ::ng-deep .av2-datepick .md-drppicker th,:host ::ng-deep .av2-datepick .md-drppicker td{width:40px!important;height:40px!important;min-width:32px;padding:0!important;border:1px solid transparent!important;background:transparent!important;font-size:14px!important;font-weight:400!important;line-height:38px}:host ::ng-deep .av2-datepick .md-drppicker th{color:#344054!important;font-weight:500!important}:host ::ng-deep .av2-datepick .md-drppicker th.month{width:auto!important;font-size:16px!important}:host ::ng-deep .av2-datepick .md-drppicker td{color:#344054!important}:host ::ng-deep .av2-datepick .md-drppicker th.available.prev,:host ::ng-deep .av2-datepick .md-drppicker th.available.next{background:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='15 6 9 12 15 18'/%3E%3C/svg%3E\") center/18px no-repeat!important}:host ::ng-deep .av2-datepick .md-drppicker th.available:hover,:host ::ng-deep .av2-datepick .md-drppicker td.available:hover{background-color:#f2f4f7!important}:host ::ng-deep .av2-datepick .md-drppicker td.in-range{background-color:#eaf8ff!important;color:#101828!important}:host ::ng-deep .av2-datepick .md-drppicker td.active,:host ::ng-deep .av2-datepick .md-drppicker td.active:hover{background-color:#029cf4!important;border-radius:20px;color:#fff!important;font-weight:500!important}:host ::ng-deep .av2-datepick .md-drppicker td.off,:host ::ng-deep .av2-datepick .md-drppicker td.off.in-range{color:#98a2b3!important;background-color:transparent!important}:host ::ng-deep .av2-datepick .md-drppicker td.disabled{color:#98a2b3!important;background-color:transparent!important;text-decoration:line-through;pointer-events:none}:host ::ng-deep .av2-datepick--compact .md-drppicker th,:host ::ng-deep .av2-datepick--compact .md-drppicker td{width:32px!important;height:32px!important;font-size:12px!important;line-height:30px}:host ::ng-deep .av2-datepick--compact .md-drppicker th.month{font-size:14px!important}.rp-daterange{width:260px;height:44px;font-size:14px}.rp-presets{display:flex;flex-wrap:wrap;gap:8px}.rp-preset{height:36px;padding:0 14px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0;font-family:inherit;font-size:14px;font-weight:500;color:#667085;cursor:pointer}.rp-preset.is-on{background:#eaf8ff;box-shadow:inset 0 0 0 1px #99dbff;color:#101828;font-weight:600}.rp-drillbar{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:14px 18px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}.rp-drillcrumb{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;color:#00a3ff;cursor:pointer}.rp-drillcrumb.is-current{color:#101828;cursor:default}.rp-drillsep{color:#98a2b3;font-weight:400}.rp-hint{font-size:14px;color:#667085}.rp-scope{display:flex;flex-direction:column;gap:2px}.rp-scope-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.rp-scope-meta{font-size:14px;line-height:20px;color:#667085}.rp-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:16px}.rp-kpi-value.is-good{color:#027a48}.rp-kpi-value.is-bad{color:#d92d20}.rp-sk-value{height:32px;margin:3px 0}.rp-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:18px 20px 12px;display:flex;flex-direction:column;gap:14px}.rp-card-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.rp-card-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:200px}.rp-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.rp-card-meta{font-size:14px;line-height:20px;color:#667085}.rp-search{width:260px}.rp-table{width:100%;border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed}.rp-table th:nth-child(1){width:29%}.rp-table th:nth-child(2){width:9.5%}.rp-table th:nth-child(3){width:8.5%}.rp-table th:nth-child(4){width:9.5%}.rp-table th:nth-child(5){width:9.5%}.rp-table th:nth-child(6){width:12%}.rp-table th:nth-child(7){width:11%}.rp-table th:nth-child(8){width:11%}.rp-table--stores th:nth-child(1){width:14%}.rp-table--stores th:nth-child(2){width:20%}.rp-table--stores th:nth-child(3){width:16%}.rp-table--stores th:nth-child(4){width:9%}.rp-table--stores th:nth-child(5){width:9%}.rp-table--stores th:nth-child(6){width:11%}.rp-table--stores th:nth-child(7){width:12%}.rp-table--stores th:nth-child(8){width:9%}.rp-table--userstores th:nth-child(1){width:18%}.rp-table--userstores th:nth-child(2){width:25%}.rp-table--userstores th:nth-child(3){width:25%}.rp-table--userstores th:nth-child(4){width:11%}.rp-table--userstores th:nth-child(5){width:10%}.rp-table--userstores th:nth-child(6){width:11%}.rp-table thead th{padding:8px 4px;border:0;border-bottom:1px solid #EAECF0;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;white-space:nowrap}.rp-table tbody td{padding:12px 4px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;color:#344054;vertical-align:middle}.rp-table tfoot td{padding:12px 4px;border:0;font-size:14px;line-height:20px;font-weight:700;color:#101828}.rp-table thead th.t-right,.rp-table tbody td.t-right,.rp-table tfoot td.t-right{text-align:right}.rp-table .is-strong{font-weight:600}.rp-table tbody td.is-muted{color:#98a2b3}.rp-table tbody td.is-pass{color:#027a48}.rp-table tbody td.is-fail{color:#d92d20}.rp-table tbody td.rp-cell-name{color:#101828;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-result{display:inline-flex;padding:2px 10px;border-radius:9999px;background:#f2f4f7;font-size:12px;line-height:18px;font-weight:500;color:#475467;white-space:nowrap}.rp-result.is-pass{background:#ecfdf3;color:#027a48}.rp-result.is-fail{background:#fef3f2;color:#b42318}.rp-row{cursor:pointer}.rp-row:hover td{background:#fcfcfd}.rp-name{display:flex;flex-direction:column;gap:2px;min-width:0}.rp-name-main{font-weight:600;color:#00a3ff}.rp-name-sub{font-size:12px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-export{height:32px;padding:0 12px;border:none;border-radius:6px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#344054;cursor:pointer}.rp-export:hover{background:#f9fafb}.filter-backdrop{position:fixed;inset:0;background:#10182873;z-index:1050}.filter-drawer{position:fixed;top:0;right:0;bottom:0;width:860px;max-width:96vw;display:flex;flex-direction:column;background:#fff;box-shadow:-10px 0 30px #1018282e;z-index:1051;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.drawer-head{display:flex;align-items:center;gap:10px;padding:18px 20px;box-shadow:inset 0 -1px #eaecf0}.drawer-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.closebtn{width:32px;height:32px;border:none;border-radius:8px;background:transparent;color:#667085;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.closebtn:hover{background:#f2f4f7;color:#344054}.drawer-body{display:flex;flex:1;min-height:0}.drawer-nav{flex:0 0 280px;max-width:280px;background:#f9fafb;box-shadow:inset -1px 0 #eaecf0;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:4px}.drawer-navitem{display:flex;align-items:center;gap:10px;width:100%;padding:12px 14px;border:none;border-radius:8px;background:transparent;text-align:left;font-family:inherit;cursor:pointer}.drawer-navitem:hover{background:#fff}.drawer-navitem.navitem-active{background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d}.navtext{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.navtitle{font-size:14px;line-height:20px;font-weight:600;color:#101828}.navvalue{font-size:14px;line-height:20px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.navvalue.is-dirty{color:#009bf3}.dirtydot{width:8px;height:8px;border-radius:9999px;background:#00a3ff;flex-shrink:0;display:block}.drawer-pane{flex:1;min-width:0;overflow-y:auto;padding:24px 28px;display:flex;flex-direction:column;gap:6px}.panetitle{font-size:18px;line-height:28px;font-weight:600;color:#101828}.panehint{font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.pane-stack{display:flex;flex-direction:column;gap:14px;margin-top:14px;max-width:560px}.pane-options{display:flex;flex-direction:column;gap:10px;margin-top:14px;max-width:560px}.pane-option{display:flex;align-items:flex-start;gap:12px;padding:14px 16px;border-radius:8px;cursor:pointer;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0}.pane-option.is-on{background:#f5fbff;box-shadow:inset 0 0 0 1.5px #00a3ff}.pane-radio{width:18px;height:18px;flex-shrink:0;margin-top:2px;border-radius:9999px;display:flex;align-items:center;justify-content:center;box-shadow:inset 0 0 0 1px #d0d5dd}.pane-radio>span{width:8px;height:8px;border-radius:9999px;background:transparent;display:block}.pane-radio.is-on{box-shadow:inset 0 0 0 1.5px #00a3ff}.pane-radio.is-on>span{background:#00a3ff}.pane-option-text{display:flex;flex-direction:column;gap:2px}.pane-option-label{font-size:14px;line-height:20px;font-weight:600;color:#101828}.pane-option-help{font-size:14px;line-height:20px;color:#667085}.drawer-foot{display:flex;align-items:center;gap:10px;padding:14px 20px;box-shadow:inset 0 1px #eaecf0}.rp-reset{border:none;background:transparent;padding:0;font-family:inherit;font-weight:600;text-decoration:none;white-space:nowrap}.rp-pick-search{width:100%}.rp-picklist{max-height:320px;overflow-y:auto;padding:6px;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;display:flex;flex-direction:column}.rp-pick{display:flex;align-items:center;gap:12px;min-height:40px;margin:0;padding:0 10px;border-radius:6px;font-size:14px;color:#344054;cursor:pointer}.rp-pick:hover{background:#f9fafb}.rp-pick.is-all{font-weight:600}.rp-pick input{appearance:none;-webkit-appearance:none;flex-shrink:0;width:16px;height:16px;margin:0;border:1px solid #D0D5DD;border-radius:4px;background:#fff no-repeat center/12px 12px;cursor:pointer;vertical-align:middle;transition:border-color .12s ease,background-color .12s ease}.rp-pick input:hover:not(:disabled){border-color:#00a3ff}.rp-pick input:checked{border-color:#00a3ff;background-color:#eaf8ff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2300A3FF' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E\")}.rp-pick input:focus-visible{outline:none;box-shadow:0 0 0 3px #eaf8ff}.rp-pick input:disabled{cursor:not-allowed;opacity:.45}.rp-pick-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-pick-sub{max-width:45%;font-size:12px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-pick-empty{padding:20px 10px;font-size:14px;color:#667085}.rp-reading{display:flex;align-items:center;gap:12px;padding:12px 16px;border-radius:8px;background:#f9fafb;font-size:14px;color:#475467}.rp-reading strong{font-weight:600;color:#101828}.rp-field{display:flex;flex-direction:column;gap:6px;min-width:0}.rp-field-label{display:flex;align-items:baseline;gap:8px;font-size:14px;line-height:20px;font-weight:600;color:#1d2939}.rp-field-label span{font-weight:400;color:#667085}\n"] }]
9169
+ args: [{ selector: 'lib-audit-v2-reports', template: "<div class=\"av2-page audit-reports\">\n\n <!-- Breadcrumb + title -->\n <div class=\"rp-head\">\n <div class=\"rp-crumb\">Audits \u203A <span class=\"rp-crumb-current\">Reports</span></div>\n <div class=\"rp-title\">Store audit report</div>\n </div>\n\n <!-- Filter chips, Filter button at the right end (QA 9 Oct); Export moved to the table head beside its search. -->\n <div class=\"rp-controls\">\n <button type=\"button\" class=\"rp-chip\" *ngFor=\"let c of chips; trackBy: trackByChip\" (click)=\"openFilters(c.key)\"\n [title]=\"c.label + ': ' + c.value\">\n <span class=\"rp-chip-key\">{{ c.label }}</span><span class=\"rp-chip-value\">{{ c.value }}</span>\n </button>\n <div class=\"av2-grow\"></div>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost rp-filterbtn\" (click)=\"openFilters()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"></polygon></svg>\n Filter\n <span class=\"rp-countpill\">{{ filterCount }}</span>\n </button>\n </div>\n\n <!-- User view: where in the hierarchy -->\n <div class=\"rp-drillbar\" *ngIf=\"!isStoreMode\">\n <ng-container *ngFor=\"let c of crumbs; let last = last; let first = first\">\n <div class=\"rp-drillcrumb\" [class.is-current]=\"last\" (click)=\"goToLevel(c.level)\">\n <span class=\"rp-drillsep\" *ngIf=\"!first\">\u203A</span>{{ c.label }}\n </div>\n </ng-container>\n <div class=\"av2-grow\"></div>\n <div class=\"rp-hint\">{{ hint }}</div>\n </div>\n\n <!-- Scope -->\n <div class=\"rp-scope\">\n <div class=\"rp-scope-title\">{{ scopeTitle }}</div>\n <div class=\"rp-scope-meta\">{{ scopeMeta }}</div>\n </div>\n\n <!-- KPIs -->\n <div class=\"rp-kpis\">\n <!-- Old Checklist summary card: figure + label in the gradient strip, note below. -->\n <div class=\"av2-ocard\" *ngFor=\"let kpi of kpis\">\n <div class=\"av2-ocard-head\">\n <div class=\"av2-ocard-count rp-kpi-value\" [class.is-good]=\"kpi.tone === 'good'\" [class.is-bad]=\"kpi.tone === 'bad'\">\n <span *ngIf=\"loading\" class=\"av2-sk av2-sk--value rp-sk-value\"></span>\n <ng-container *ngIf=\"!loading\">{{ kpi.value }}</ng-container>\n </div>\n <div class=\"av2-ocard-text\">{{ kpi.label }}</div>\n </div>\n <div class=\"av2-ocard-body\">\n <span *ngIf=\"loading\" class=\"av2-sk av2-sk--note\"></span>\n <div *ngIf=\"!loading\" class=\"av2-ocard-note\">{{ kpi.note }}</div>\n </div>\n </div>\n </div>\n\n <!-- Report table -->\n <section class=\"rp-card\">\n <div class=\"rp-card-head\">\n <div class=\"rp-card-text\">\n <ng-container *ngIf=\"isStoreMode\">\n <div class=\"rp-card-title\">Store report</div>\n <div class=\"rp-card-meta\">{{ storeRows.length }} {{ storeRows.length === 1 ? 'store' : 'stores' }} \u00B7 audits submitted in the period</div>\n </ng-container>\n <ng-container *ngIf=\"!isStoreMode\">\n <div class=\"rp-card-title\">{{ tableTitle }}</div>\n <div class=\"rp-card-meta\">{{ tableMeta }}</div>\n </ng-container>\n </div>\n <div class=\"av2-grow\"></div>\n <label class=\"av2-search rp-search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"7\"></circle>\n <line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line>\n </svg>\n <input type=\"text\" [placeholder]=\"isStoreMode ? 'Search store' : 'Search ' + levelLabel.toLowerCase()\"\n [(ngModel)]=\"search\" (ngModelChange)=\"onSearchChange()\">\n </label>\n <button type=\"button\" class=\"av2-btn av2-btn--ghost\" [disabled]=\"loading || exporting\" (click)=\"exportAll()\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 16V4\"></path><polyline points=\"7 9 12 4 17 9\"></polyline><path d=\"M4 16v4h16v-4\"></path></svg>\n Export\n </button>\n </div>\n\n <lib-audit-v2-shimmer *ngIf=\"loading\"></lib-audit-v2-shimmer>\n\n <!-- Store view: one row per store -->\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && isStoreMode && tableCount\">\n <table class=\"rp-table rp-table--stores\">\n <thead>\n <tr>\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"av2-sortable\" (click)=\"sortBy('cluster')\">Cluster <lib-audit-v2-sort-icon [active]=\"sortKey === 'cluster'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"av2-sortable\" (click)=\"sortBy('aom')\">Area manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'aom'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('score')\">Score <lib-audit-v2-sort-icon [active]=\"sortKey === 'score'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('status')\">Result <lib-audit-v2-sort-icon [active]=\"sortKey === 'status'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('lastAudit')\">Last audit <lib-audit-v2-sort-icon [active]=\"sortKey === 'lastAudit'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right\">Export</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let s of storePageRows; trackBy: trackByKey\">\n <td class=\"is-strong rp-cell-name\" [av2Tip]=\"s.name\">{{ s.name }}</td>\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.cluster\">{{ s.cluster || '\u2014' }}</td>\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.aom\">{{ s.aom || '\u2014' }}</td>\n <td class=\"t-right\" [class.is-muted]=\"!s.audited\">{{ s.audited ? 'Yes' : 'No' }}</td>\n <td class=\"t-right is-strong\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\"\n [class.is-muted]=\"s.score === null\">{{ scoreText(s) }}</td>\n <td class=\"t-right\">\n <span class=\"rp-result\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\">{{ resultText(s) }}</span>\n </td>\n <td class=\"t-right\" [class.is-muted]=\"!s.lastAudit\">{{ s.lastAudit || 'No audit' }}</td>\n <td class=\"t-right\">\n <button type=\"button\" class=\"rp-export\" [disabled]=\"exporting\" (click)=\"exportStore(s)\">Export</button>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr class=\"rp-total\">\n <td>Total</td>\n <td></td>\n <td></td>\n <td class=\"t-right\">{{ totalAuditedOf }}</td>\n <td class=\"t-right\">{{ totalAverage }}</td>\n <td class=\"t-right\">{{ totals.failed }} fail</td>\n <td></td>\n <td></td>\n </tr>\n </tfoot>\n </table>\n </div>\n\n <!-- User view: circle head / zone manager / area manager roll-up -->\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && !isStoreMode && level !== 'store' && tableCount\">\n <table class=\"rp-table\">\n <thead>\n <tr>\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">{{ levelLabel }} <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('total')\">Total stores <lib-audit-v2-sort-icon [active]=\"sortKey === 'total'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('notAudited')\">Not audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'notAudited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('coverage')\">Coverage <lib-audit-v2-sort-icon [active]=\"sortKey === 'coverage'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('avgScore')\">Avg audit score <lib-audit-v2-sort-icon [active]=\"sortKey === 'avgScore'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('failedPct')\">Failed store % <lib-audit-v2-sort-icon [active]=\"sortKey === 'failedPct'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right\">Report</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of pageRows; trackBy: trackByRow\" class=\"rp-row\" (click)=\"openRow(row)\">\n <td>\n <div class=\"rp-name\">\n <span class=\"rp-name-main\">{{ row.name }}</span>\n <span class=\"rp-name-sub\" *ngIf=\"row.email\">{{ row.email }}</span>\n </div>\n </td>\n <td class=\"t-right\">{{ row.total }}</td>\n <td class=\"t-right\">{{ row.audited }}</td>\n <td class=\"t-right\" [class.is-muted]=\"!row.notAudited\">{{ row.notAudited }}</td>\n <td class=\"t-right\">{{ row.coverage }}</td>\n <td class=\"t-right is-strong\">{{ row.avgScore }}</td>\n <td class=\"t-right is-strong\" [class.is-fail]=\"isHighFail(row)\">{{ row.failedPct }}</td>\n <td class=\"t-right\">\n <button type=\"button\" class=\"rp-export\" [disabled]=\"exporting\" (click)=\"exportRow(row); $event.stopPropagation()\">Export</button>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr class=\"rp-total\">\n <td>Total</td>\n <td class=\"t-right\">{{ totals.total }}</td>\n <td class=\"t-right\">{{ totals.audited }}</td>\n <td class=\"t-right\">{{ totals.total - totals.audited }}</td>\n <td class=\"t-right\">{{ totalCoverage }}</td>\n <td class=\"t-right\">{{ totalAverage }}</td>\n <td class=\"t-right\">{{ totalFailedPct }}</td>\n <td></td>\n </tr>\n </tfoot>\n </table>\n </div>\n\n <!-- User view, deepest level: the area manager's stores -->\n <div class=\"av2-table-wrap\" *ngIf=\"!loading && !isStoreMode && level === 'store' && tableCount\">\n <table class=\"rp-table rp-table--userstores\">\n <thead>\n <tr>\n <th class=\"av2-sortable\" (click)=\"sortBy('name')\">Store <lib-audit-v2-sort-icon [active]=\"sortKey === 'name'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"av2-sortable\" (click)=\"sortBy('aom')\">Area manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'aom'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"av2-sortable\" (click)=\"sortBy('zone')\">Zone manager <lib-audit-v2-sort-icon [active]=\"sortKey === 'zone'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('audited')\">Audited <lib-audit-v2-sort-icon [active]=\"sortKey === 'audited'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right av2-sortable\" (click)=\"sortBy('score')\">Score <lib-audit-v2-sort-icon [active]=\"sortKey === 'score'\" [dir]=\"sortDir\"></lib-audit-v2-sort-icon></th>\n <th class=\"t-right\">Export</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let s of userStorePageRows; trackBy: trackByKey\">\n <td class=\"is-strong rp-cell-name\" [av2Tip]=\"s.name\">{{ s.name }}</td>\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.aom\">{{ s.aom || '\u2014' }}</td>\n <td class=\"av2-ellipsis\" [av2Tip]=\"s.zone\">{{ s.zone || '\u2014' }}</td>\n <td class=\"t-right\" [class.is-muted]=\"!s.audited\">{{ s.audited ? 'Yes' : 'No' }}</td>\n <td class=\"t-right is-strong\" [class.is-pass]=\"s.status === 'pass'\" [class.is-fail]=\"s.status === 'fail'\"\n [class.is-muted]=\"s.score === null\">{{ scoreText(s) }}</td>\n <td class=\"t-right\">\n <button type=\"button\" class=\"rp-export\" [disabled]=\"exporting\" (click)=\"exportStore(s)\">Export</button>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr class=\"rp-total\">\n <td>Total</td>\n <td></td>\n <td></td>\n <td class=\"t-right\">{{ totalAuditedOf }}</td>\n <td class=\"t-right\">{{ totalAverage }}</td>\n <td></td>\n </tr>\n </tfoot>\n </table>\n </div>\n\n <div *ngIf=\"!loading && !tableCount\" class=\"av2-empty\">\n <img class=\"av2-empty-img\" src=\"./assets/tango/Icons/Nodata1.svg\" alt=\"\">\n <div class=\"av2-empty-text\">\n <div class=\"av2-empty-title\">No data found</div>\n <div class=\"av2-empty-sub\">{{ search ? 'No rows match \"' + search + '\"' : 'No stores match the current filters' }}</div>\n </div>\n </div>\n\n <!-- Shared pager (10 / 20 / 30), as on the other audit lists. -->\n <div class=\"rp-pager\" *ngIf=\"!loading && tableCount\">\n <lib-pagination [itemsPerPage]=\"pageSize\" [pageSize]=\"pageSize\" [paginationSizes]=\"pageSizes\" [currentPage]=\"page\"\n [totalItems]=\"tableCount\" (pageChange)=\"onPageChange($event)\" (pageSizeChange)=\"onPageSizeChange($event)\"></lib-pagination>\n </div>\n </section>\n\n <!-- ============ FILTER DRAWER ============ -->\n <div class=\"filter-backdrop\" *ngIf=\"filtersOpen\" (click)=\"closeFilters()\"></div>\n\n <!-- Every control edits the drawer's draft (dr); the page behind changes only on Apply or Reset all. -->\n <div class=\"filter-drawer\" *ngIf=\"filtersOpen && draft as dr\">\n <div class=\"drawer-head\">\n <span class=\"drawer-title\">Filters</span>\n <span class=\"rp-countpill\">{{ dr.filterCount }}</span>\n <div class=\"av2-grow\"></div>\n <button type=\"button\" class=\"closebtn\" (click)=\"closeFilters()\" title=\"Close\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\n </button>\n </div>\n\n <div class=\"drawer-body\">\n <div class=\"drawer-nav\">\n <!-- trackBy: filterCats is rebuilt on every check, and lib-audit-v2-select's document:mousedown runs one\n between press and release; without it the button was replaced mid-click and the click never landed. -->\n <button type=\"button\" class=\"drawer-navitem\" *ngFor=\"let c of dr.filterCats; trackBy: trackByChip\" [class.navitem-active]=\"activeCat === c.key\"\n (click)=\"selectCat(c.key)\">\n <span class=\"navtext\">\n <span class=\"navtitle\">{{ c.label }}</span>\n <span class=\"navvalue\" [class.is-dirty]=\"c.dirty\">{{ c.value }}</span>\n </span>\n <span class=\"dirtydot\" *ngIf=\"c.dirty\"></span>\n </button>\n </div>\n\n <div class=\"drawer-pane\">\n <div class=\"panetitle\">{{ dr.paneTitle }}</div>\n <div class=\"panehint\">{{ dr.paneSub }}</div>\n\n <!-- Date -->\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'date'\">\n <div class=\"av2-datepick\">\n <svg class=\"av2-datepick-icon\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"></rect>\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"></line><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"></line><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"></line></svg>\n <input type=\"text\" class=\"av2-datepick-input rp-daterange\" ngxDaterangepickerMd readonly autocomplete=\"off\"\n placeholder=\"Select date range\" [(ngModel)]=\"dr.range\" [locale]=\"pickerLocale\" [maxDate]=\"today\"\n [ranges]=\"ranges\" [showCustomRangeLabel]=\"true\" [alwaysShowCalendars]=\"false\"\n [keepCalendarOpeningWithRange]=\"true\" [autoApply]=\"true\" [showCancel]=\"false\"\n [drops]=\"'down'\" [opens]=\"'right'\" (datesUpdated)=\"dr.onRangePicked($event)\">\n </div>\n <div class=\"rp-presets\">\n <button type=\"button\" class=\"rp-preset\" *ngFor=\"let p of presets\" [class.is-on]=\"dr.preset === p\"\n (click)=\"dr.setPreset(p)\">{{ p }}</button>\n </div>\n </div>\n\n <!-- View by -->\n <div class=\"pane-options\" *ngIf=\"activeCat === 'mode'\">\n <div class=\"pane-option\" [class.is-on]=\"dr.isStoreMode\" (click)=\"dr.setMode('store')\">\n <span class=\"pane-radio\" [class.is-on]=\"dr.isStoreMode\"><span></span></span>\n <span class=\"pane-option-text\">\n <span class=\"pane-option-label\">Store</span>\n <span class=\"pane-option-help\">One row per store with score, result and last audit date.</span>\n </span>\n </div>\n <div class=\"pane-option\" [class.is-on]=\"!dr.isStoreMode\" (click)=\"dr.setMode('user')\">\n <span class=\"pane-radio\" [class.is-on]=\"!dr.isStoreMode\"><span></span></span>\n <span class=\"pane-option-text\">\n <span class=\"pane-option-label\">User</span>\n <span class=\"pane-option-help\">Rolled up by circle head, zone manager and AOM, drillable down to stores.</span>\n </span>\n </div>\n </div>\n\n <!-- Stores (Store view) -->\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'scope' && dr.isStoreMode\">\n <label class=\"av2-search rp-pick-search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7\"></circle><line x1=\"16.5\" y1=\"16.5\" x2=\"21\" y2=\"21\"></line></svg>\n <input type=\"text\" placeholder=\"Search store\" [(ngModel)]=\"dr.storeQuery\">\n </label>\n <div class=\"rp-picklist\">\n <ng-container *ngIf=\"dr.storePickItems.length\">\n <label class=\"rp-pick is-all\">\n <input type=\"checkbox\" [checked]=\"dr.storePickAllChecked\" (change)=\"dr.toggleStorePickAll()\">\n <span>Select All</span>\n </label>\n <label class=\"rp-pick\" *ngFor=\"let it of dr.storePickItems; trackBy: trackByPick\">\n <input type=\"checkbox\" [checked]=\"it.checked\" (change)=\"dr.toggleStorePick(it.store)\">\n <span class=\"rp-pick-label\">{{ it.store.name }}</span>\n <span class=\"rp-pick-sub\">{{ it.store.cluster || it.store.aom }}</span>\n </label>\n </ng-container>\n <div class=\"rp-pick-empty\" *ngIf=\"!dr.storePickItems.length\">\n {{ dr.storeQuery ? 'No stores match \"' + dr.storeQuery + '\"' : 'No stores in scope' }}\n </div>\n </div>\n <div class=\"rp-reading\">\n <span>Reading</span>\n <strong>{{ dr.storePickReading }}</strong>\n <span class=\"av2-grow\"></span>\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"dr.resetStorePick()\">Reset to all stores</button>\n </div>\n </div>\n\n <!-- Store hierarchy (User view) -->\n <div class=\"pane-stack\" *ngIf=\"activeCat === 'scope' && !dr.isStoreMode\">\n <div class=\"rp-field\">\n <div class=\"rp-field-label\">Circle Head <span>{{ dr.circleOptions.length - 1 }} users</span></div>\n <lib-audit-v2-select [value]=\"dr.circleKey\" [options]=\"dr.circleOptions\" placeholder=\"All circles\"\n ariaLabel=\"Circle Head\" (changed)=\"dr.pickCircle($event.target.value)\"></lib-audit-v2-select>\n </div>\n <div class=\"rp-field\" *ngIf=\"dr.showZonePick\">\n <div class=\"rp-field-label\">Zone Manager <span>{{ dr.zoneOptions.length - 1 }} {{ dr.zoneOptions.length === 2 ? 'user' : 'users' }}</span></div>\n <lib-audit-v2-select [value]=\"dr.zoneKey\" [options]=\"dr.zoneOptions\" placeholder=\"All zones\"\n ariaLabel=\"Zone Manager\" (changed)=\"dr.pickZone($event.target.value)\"></lib-audit-v2-select>\n </div>\n <div class=\"rp-field\" *ngIf=\"dr.zoneKey\">\n <div class=\"rp-field-label\">AOM <span>{{ dr.aomOptions.length - 1 }} {{ dr.aomOptions.length === 2 ? 'user' : 'users' }}</span></div>\n <lib-audit-v2-select [value]=\"dr.aomKey\" [options]=\"dr.aomOptions\" placeholder=\"All AOMs\"\n ariaLabel=\"AOM\" (changed)=\"dr.pickAom($event.target.value)\"></lib-audit-v2-select>\n </div>\n <div class=\"rp-field\" *ngIf=\"dr.aomKey\">\n <div class=\"rp-field-label\">Store <span>{{ dr.storeOptions.length - 1 }} stores</span></div>\n <lib-audit-v2-select [value]=\"dr.storeKey\" [options]=\"dr.storeOptions\" placeholder=\"All stores\"\n ariaLabel=\"Store\" (changed)=\"dr.pickStore($event.target.value)\"></lib-audit-v2-select>\n </div>\n <div class=\"rp-reading\">\n <span>Reading</span>\n <strong>{{ dr.hierarchyReading }}</strong>\n <span class=\"av2-grow\"></span>\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"dr.goToLevel('circle')\">Reset to all circles</button>\n </div>\n </div>\n\n <!-- Result (Store view) -->\n <div class=\"pane-options\" *ngIf=\"activeCat === 'result' && dr.isStoreMode\">\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'all'\" (click)=\"dr.setResult('all')\">\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'all'\"><span></span></span>\n <span class=\"pane-option-text\">\n <span class=\"pane-option-label\">All</span>\n <span class=\"pane-option-help\">Every store in scope, audited or not.</span>\n </span>\n </div>\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'pass'\" (click)=\"dr.setResult('pass')\">\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'pass'\"><span></span></span>\n <span class=\"pane-option-text\">\n <span class=\"pane-option-label\">Pass</span>\n <span class=\"pane-option-help\">Only stores scoring at or above the {{ passMark }}% pass mark.</span>\n </span>\n </div>\n <div class=\"pane-option\" [class.is-on]=\"dr.result === 'fail'\" (click)=\"dr.setResult('fail')\">\n <span class=\"pane-radio\" [class.is-on]=\"dr.result === 'fail'\"><span></span></span>\n <span class=\"pane-option-text\">\n <span class=\"pane-option-label\">Fail</span>\n <span class=\"pane-option-help\">Only stores scoring below the {{ passMark }}% pass mark.</span>\n </span>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"drawer-foot\">\n <button type=\"button\" class=\"av2-link rp-reset\" (click)=\"resetFilters()\">Reset all</button>\n <div class=\"av2-grow\"></div>\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--wide\" (click)=\"applyFilters()\">Apply</button>\n </div>\n </div>\n\n</div>\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}::ng-deep .tooltip.av2-tip{--bs-tooltip-bg: #fff;--bs-tooltip-color: #344054;--bs-tooltip-max-width: 320px;--bs-tooltip-opacity: 1}::ng-deep .tooltip.av2-tip .tooltip-inner{background-color:#fff!important;color:#344054!important;padding:8px 12px;border-radius:8px;font-size:13px;line-height:18px;font-weight:500;text-align:left;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,0 0 0 1px #eaecf0}::ng-deep .tooltip.av2-tip .tooltip-arrow:before{border-top-color:#fff;border-bottom-color:#fff}:host ::ng-deep lib-pagination{display:block}:host ::ng-deep lib-pagination .container{max-width:none;padding:0;display:flex;align-items:center;justify-content:center;gap:16px;flex-wrap:wrap;font-size:14px;color:#475467}:host ::ng-deep lib-pagination .mt-4{margin-top:0!important}:host ::ng-deep lib-pagination .container>.text-center{display:flex;align-items:center}:host ::ng-deep lib-pagination .container>.text-center>ul:not(.ngx-pagination){display:none}:host ::ng-deep lib-pagination pagination-controls{display:flex;align-items:center}:host ::ng-deep lib-pagination .sub-title{color:#475467!important;font-size:14px!important;font-weight:400!important;line-height:20px}:host ::ng-deep lib-pagination .border-val{height:40px;min-width:64px;padding:0 30px 0 12px!important;border:1px solid #D0D5DD!important;border-radius:8px!important;box-shadow:0 1px 2px #1018280d;background-color:#fff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\")!important;background-repeat:no-repeat!important;background-position:right 10px center!important;background-size:14px 14px!important;appearance:none;-webkit-appearance:none;font-size:14px;font-weight:500;color:#1d2939;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}:host ::ng-deep lib-pagination .border-val:hover{border-color:#98a2b3!important}:host ::ng-deep lib-pagination .border-val:focus{outline:none;border-color:#66c8ff!important;box-shadow:0 0 0 3px #eaf8ff}:host ::ng-deep lib-pagination .ngx-pagination{margin:0;padding:0;display:flex;align-items:center;gap:6px;color:#475467!important;font-size:14px!important;font-weight:500}:host ::ng-deep lib-pagination .ngx-pagination li{display:inline-flex;margin:0}:host ::ng-deep lib-pagination .ngx-pagination li.small-screen{display:none!important}:host ::ng-deep lib-pagination .ngx-pagination a,:host ::ng-deep lib-pagination .ngx-pagination button,:host ::ng-deep lib-pagination .ngx-pagination .current,:host ::ng-deep lib-pagination .ngx-pagination .disabled{min-width:40px!important;height:40px;padding:0 8px!important;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;line-height:20px;color:#475467}:host ::ng-deep lib-pagination .ngx-pagination a:hover,:host ::ng-deep lib-pagination .ngx-pagination button:hover{background:#f2f4f7;padding:0 8px!important}:host ::ng-deep lib-pagination .ngx-pagination .current{background:#eaf8ff!important;color:#00a3ff!important;font-weight:600;font-size:14px!important}:host ::ng-deep lib-pagination .ngx-pagination .disabled{color:#98a2b3}:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-previous.disabled:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next a:after,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:before,:host ::ng-deep lib-pagination .ngx-pagination .pagination-next.disabled:after{margin:0}:host ::ng-deep lib-pagination .ngx-pagination .ellipsis:after{color:#98a2b3;padding:0}.rp-pager{padding-top:20px}.rp-head{display:flex;flex-direction:column;gap:2px}.rp-crumb{font-size:13px;line-height:20px;color:#667085}.rp-crumb-current{color:#00a3ff}.rp-title{font-size:22px;line-height:30px;font-weight:600;color:#101828}.rp-controls{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.rp-countpill{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;border-radius:9999px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:600}.rp-chip{height:32px;max-width:360px;padding:0 12px;border:none;border-radius:9999px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0;display:inline-flex;align-items:center;gap:6px;font-family:inherit;font-size:13px;line-height:20px;white-space:nowrap;cursor:pointer}.rp-chip:hover{background:#f9fafb}.rp-chip-key{font-weight:500;color:#667085}.rp-chip-value{overflow:hidden;text-overflow:ellipsis;font-weight:600;color:#101828}.av2-datepick{position:relative;display:inline-flex;align-items:center}.av2-datepick-icon{position:absolute;left:10px;color:#667085;pointer-events:none}.av2-datepick-input{height:36px;padding:0 10px 0 32px;border:none;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;background:#fff;font-family:inherit;font-size:13px;font-weight:500;color:#101828;cursor:pointer;outline:none}.av2-datepick-input:focus{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}:host ::ng-deep .av2-datepick .md-drppicker{margin-top:4px;z-index:1060;font-family:inherit;border-radius:8px;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808,inset 0 0 0 1px #eaecf0}:host ::ng-deep .av2-datepick .md-drppicker.double,:host ::ng-deep .av2-datepick .md-drppicker.show-ranges{width:max-content}:host ::ng-deep .av2-datepick .md-drppicker.ltr .ranges{float:left;margin-top:10px}:host ::ng-deep .av2-datepick .md-drppicker .ranges ul li button{width:160px;padding:12px 16px;border:none;border-radius:8px;background:none;color:#344054;font-size:14px;font-weight:400;line-height:20px;text-align:left;cursor:pointer}:host ::ng-deep .av2-datepick .md-drppicker .ranges ul li button.active{background:#eaf8ff;color:#00a3ff;font-weight:500}:host ::ng-deep .av2-datepick .md-drppicker th,:host ::ng-deep .av2-datepick .md-drppicker td{width:40px!important;height:40px!important;min-width:32px;padding:0!important;border:1px solid transparent!important;background:transparent!important;font-size:14px!important;font-weight:400!important;line-height:38px}:host ::ng-deep .av2-datepick .md-drppicker th{color:#344054!important;font-weight:500!important}:host ::ng-deep .av2-datepick .md-drppicker th.month{width:auto!important;font-size:16px!important}:host ::ng-deep .av2-datepick .md-drppicker td{color:#344054!important}:host ::ng-deep .av2-datepick .md-drppicker th.available.prev,:host ::ng-deep .av2-datepick .md-drppicker th.available.next{background:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='15 6 9 12 15 18'/%3E%3C/svg%3E\") center/18px no-repeat!important}:host ::ng-deep .av2-datepick .md-drppicker th.available:hover,:host ::ng-deep .av2-datepick .md-drppicker td.available:hover{background-color:#f2f4f7!important}:host ::ng-deep .av2-datepick .md-drppicker td.in-range{background-color:#eaf8ff!important;color:#101828!important}:host ::ng-deep .av2-datepick .md-drppicker td.active,:host ::ng-deep .av2-datepick .md-drppicker td.active:hover{background-color:#029cf4!important;border-radius:20px;color:#fff!important;font-weight:500!important}:host ::ng-deep .av2-datepick .md-drppicker td.off,:host ::ng-deep .av2-datepick .md-drppicker td.off.in-range{color:#98a2b3!important;background-color:transparent!important}:host ::ng-deep .av2-datepick .md-drppicker td.disabled{color:#98a2b3!important;background-color:transparent!important;text-decoration:line-through;pointer-events:none}:host ::ng-deep .av2-datepick--compact .md-drppicker th,:host ::ng-deep .av2-datepick--compact .md-drppicker td{width:32px!important;height:32px!important;font-size:12px!important;line-height:30px}:host ::ng-deep .av2-datepick--compact .md-drppicker th.month{font-size:14px!important}.rp-daterange{width:260px;height:44px;font-size:14px}.rp-presets{display:flex;flex-wrap:wrap;gap:8px}.rp-preset{height:36px;padding:0 14px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0;font-family:inherit;font-size:14px;font-weight:500;color:#667085;cursor:pointer}.rp-preset.is-on{background:#eaf8ff;box-shadow:inset 0 0 0 1px #99dbff;color:#101828;font-weight:600}.rp-drillbar{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:14px 18px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}.rp-drillcrumb{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;color:#00a3ff;cursor:pointer}.rp-drillcrumb.is-current{color:#101828;cursor:default}.rp-drillsep{color:#98a2b3;font-weight:400}.rp-hint{font-size:14px;color:#667085}.rp-scope{display:flex;flex-direction:column;gap:2px}.rp-scope-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.rp-scope-meta{font-size:14px;line-height:20px;color:#667085}.rp-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:16px}.rp-kpi-value.is-good{color:#027a48}.rp-kpi-value.is-bad{color:#d92d20}.rp-sk-value{height:32px;margin:3px 0}.rp-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:18px 20px 12px;display:flex;flex-direction:column;gap:14px}.rp-card-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.rp-card-text{display:flex;flex-direction:column;gap:2px;flex:1;min-width:200px}.rp-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828}.rp-card-meta{font-size:14px;line-height:20px;color:#667085}.rp-search{width:260px}.rp-table{width:100%;border-collapse:separate;border-spacing:0;margin:0;table-layout:fixed}.rp-table th:nth-child(1){width:29%}.rp-table th:nth-child(2){width:9.5%}.rp-table th:nth-child(3){width:8.5%}.rp-table th:nth-child(4){width:9.5%}.rp-table th:nth-child(5){width:9.5%}.rp-table th:nth-child(6){width:12%}.rp-table th:nth-child(7){width:11%}.rp-table th:nth-child(8){width:11%}.rp-table--stores th:nth-child(1){width:14%}.rp-table--stores th:nth-child(2){width:20%}.rp-table--stores th:nth-child(3){width:16%}.rp-table--stores th:nth-child(4){width:9%}.rp-table--stores th:nth-child(5){width:9%}.rp-table--stores th:nth-child(6){width:11%}.rp-table--stores th:nth-child(7){width:12%}.rp-table--stores th:nth-child(8){width:9%}.rp-table--userstores th:nth-child(1){width:18%}.rp-table--userstores th:nth-child(2){width:25%}.rp-table--userstores th:nth-child(3){width:25%}.rp-table--userstores th:nth-child(4){width:11%}.rp-table--userstores th:nth-child(5){width:10%}.rp-table--userstores th:nth-child(6){width:11%}.rp-table thead th{padding:8px 4px;border:0;border-bottom:1px solid #EAECF0;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;white-space:nowrap}.rp-table tbody td{padding:12px 4px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;color:#344054;vertical-align:middle}.rp-table tfoot td{padding:12px 4px;border:0;font-size:14px;line-height:20px;font-weight:700;color:#101828}.rp-table thead th.t-right,.rp-table tbody td.t-right,.rp-table tfoot td.t-right{text-align:right}.rp-table .is-strong{font-weight:600}.rp-table tbody td.is-muted{color:#98a2b3}.rp-table tbody td.is-pass{color:#027a48}.rp-table tbody td.is-fail{color:#d92d20}.rp-table tbody td.rp-cell-name{color:#101828;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-result{display:inline-flex;padding:2px 10px;border-radius:9999px;background:#f2f4f7;font-size:12px;line-height:18px;font-weight:500;color:#475467;white-space:nowrap}.rp-result.is-pass{background:#ecfdf3;color:#027a48}.rp-result.is-fail{background:#fef3f2;color:#b42318}.rp-row{cursor:pointer}.rp-row:hover td{background:#fcfcfd}.rp-name{display:flex;flex-direction:column;gap:2px;min-width:0}.rp-name-main{font-weight:600;color:#00a3ff}.rp-name-sub{font-size:12px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-export{height:32px;padding:0 12px;border:none;border-radius:6px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#344054;cursor:pointer}.rp-export:hover{background:#f9fafb}.filter-backdrop{position:fixed;inset:0;background:#10182873;z-index:1050}.filter-drawer{position:fixed;top:0;right:0;bottom:0;width:860px;max-width:96vw;display:flex;flex-direction:column;background:#fff;box-shadow:-10px 0 30px #1018282e;z-index:1051;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.drawer-head{display:flex;align-items:center;gap:10px;padding:18px 20px;box-shadow:inset 0 -1px #eaecf0}.drawer-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.closebtn{width:32px;height:32px;border:none;border-radius:8px;background:transparent;color:#667085;display:inline-flex;align-items:center;justify-content:center;cursor:pointer}.closebtn:hover{background:#f2f4f7;color:#344054}.drawer-body{display:flex;flex:1;min-height:0}.drawer-nav{flex:0 0 280px;max-width:280px;background:#f9fafb;box-shadow:inset -1px 0 #eaecf0;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:4px}.drawer-navitem{display:flex;align-items:center;gap:10px;width:100%;padding:12px 14px;border:none;border-radius:8px;background:transparent;text-align:left;font-family:inherit;cursor:pointer}.drawer-navitem:hover{background:#fff}.drawer-navitem.navitem-active{background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d}.navtext{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.navtitle{font-size:14px;line-height:20px;font-weight:600;color:#101828}.navvalue{font-size:14px;line-height:20px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.navvalue.is-dirty{color:#009bf3}.dirtydot{width:8px;height:8px;border-radius:9999px;background:#00a3ff;flex-shrink:0;display:block}.drawer-pane{flex:1;min-width:0;overflow-y:auto;padding:24px 28px;display:flex;flex-direction:column;gap:6px}.panetitle{font-size:18px;line-height:28px;font-weight:600;color:#101828}.panehint{font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.pane-stack{display:flex;flex-direction:column;gap:14px;margin-top:14px;max-width:560px}.pane-options{display:flex;flex-direction:column;gap:10px;margin-top:14px;max-width:560px}.pane-option{display:flex;align-items:flex-start;gap:12px;padding:14px 16px;border-radius:8px;cursor:pointer;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0}.pane-option.is-on{background:#f5fbff;box-shadow:inset 0 0 0 1.5px #00a3ff}.pane-radio{width:18px;height:18px;flex-shrink:0;margin-top:2px;border-radius:9999px;display:flex;align-items:center;justify-content:center;box-shadow:inset 0 0 0 1px #d0d5dd}.pane-radio>span{width:8px;height:8px;border-radius:9999px;background:transparent;display:block}.pane-radio.is-on{box-shadow:inset 0 0 0 1.5px #00a3ff}.pane-radio.is-on>span{background:#00a3ff}.pane-option-text{display:flex;flex-direction:column;gap:2px}.pane-option-label{font-size:14px;line-height:20px;font-weight:600;color:#101828}.pane-option-help{font-size:14px;line-height:20px;color:#667085}.drawer-foot{display:flex;align-items:center;gap:10px;padding:14px 20px;box-shadow:inset 0 1px #eaecf0}.rp-reset{border:none;background:transparent;padding:0;font-family:inherit;font-weight:600;text-decoration:none;white-space:nowrap}.rp-pick-search{width:100%}.rp-picklist{max-height:320px;overflow-y:auto;padding:6px;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;display:flex;flex-direction:column}.rp-pick{display:flex;align-items:center;gap:12px;min-height:40px;margin:0;padding:0 10px;border-radius:6px;font-size:14px;color:#344054;cursor:pointer}.rp-pick:hover{background:#f9fafb}.rp-pick.is-all{font-weight:600}.rp-pick input{appearance:none;-webkit-appearance:none;flex-shrink:0;width:16px;height:16px;margin:0;border:1px solid #D0D5DD;border-radius:4px;background:#fff no-repeat center/12px 12px;cursor:pointer;vertical-align:middle;transition:border-color .12s ease,background-color .12s ease}.rp-pick input:hover:not(:disabled){border-color:#00a3ff}.rp-pick input:checked{border-color:#00a3ff;background-color:#eaf8ff;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2300A3FF' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E\")}.rp-pick input:focus-visible{outline:none;box-shadow:0 0 0 3px #eaf8ff}.rp-pick input:disabled{cursor:not-allowed;opacity:.45}.rp-pick-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-pick-sub{max-width:45%;font-size:12px;color:#667085;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rp-pick-empty{padding:20px 10px;font-size:14px;color:#667085}.rp-reading{display:flex;align-items:center;gap:12px;padding:12px 16px;border-radius:8px;background:#f9fafb;font-size:14px;color:#475467}.rp-reading strong{font-weight:600;color:#101828}.rp-field{display:flex;flex-direction:column;gap:6px;min-width:0}.rp-field-label{display:flex;align-items:baseline;gap:8px;font-size:14px;line-height:20px;font-weight:600;color:#1d2939}.rp-field-label span{font-weight:400;color:#667085}\n"] }]
9103
9170
  }], ctorParameters: () => [{ type: TraxService }, { type: i2.GlobalStateService }, { type: i3.ToastService }, { type: i0.ChangeDetectorRef }] });
9104
9171
 
9105
9172
  /**
@@ -9368,6 +9435,10 @@ class AuditV2ConfigureComponent {
9368
9435
  dailySendApprover = true;
9369
9436
  dailySendCustom = false;
9370
9437
  dailyUsers = [];
9438
+ /** Daily Report > Custom bulk upload popup (as the Checklist Configure page's). */
9439
+ dailyBulkOpen = false;
9440
+ /** Row errors of the last upload; any error rejects the whole file, so nothing partial is applied. */
9441
+ dailyBulkErrors = [];
9371
9442
  sharePostApproval = false;
9372
9443
  exportSubmissionOn = false;
9373
9444
  redoValidFor = 7;
@@ -9463,8 +9534,9 @@ class AuditV2ConfigureComponent {
9463
9534
  this.destroy$.next();
9464
9535
  this.destroy$.complete();
9465
9536
  }
9466
- /** Escape closes the open dropdown / suggestion list. */
9537
+ /** Escape closes the open dropdown / suggestion list / bulk upload popup. */
9467
9538
  onEscape() {
9539
+ this.dailyBulkOpen = false;
9468
9540
  this.openSelect = null;
9469
9541
  this.openChips = null;
9470
9542
  }
@@ -9948,6 +10020,116 @@ class AuditV2ConfigureComponent {
9948
10020
  removeChip(list, index) {
9949
10021
  this[list] = this[list].filter((_, i) => i !== index);
9950
10022
  }
10023
+ // ---- Daily Report custom users: bulk upload ----------------------------------------------
10024
+ openDailyBulk() {
10025
+ this.dailyBulkErrors = [];
10026
+ this.dailyBulkOpen = true;
10027
+ this.openChips = null;
10028
+ this.openSelect = null;
10029
+ }
10030
+ closeDailyBulk() {
10031
+ this.dailyBulkOpen = false;
10032
+ this.dailyBulkErrors = [];
10033
+ }
10034
+ /** Username + Email template, pre-filled with the current Daily Report custom users (as the Checklist one). */
10035
+ downloadDailyTemplate() {
10036
+ const rows = this.dailyUsers.length ? this.dailyUsers.map(u => [u.n, u.e]) : [['', '']];
10037
+ const sheet = XLSX.utils.aoa_to_sheet([['Username', 'Email'], ...rows]);
10038
+ sheet['!cols'] = [{ wch: 28 }, { wch: 36 }];
10039
+ const book = XLSX.utils.book_new();
10040
+ XLSX.utils.book_append_sheet(book, sheet, 'Users');
10041
+ XLSX.writeFile(book, 'dailyReportTemplate.xlsx');
10042
+ }
10043
+ /**
10044
+ * Replaces the Daily Report custom users with the uploaded sheet, as the Checklist Configure page does:
10045
+ * only the Email column counts (the name comes from the client's user list), and every row must be an
10046
+ * existing user. Any invalid row rejects the whole file.
10047
+ */
10048
+ onDailyBulkFile(event) {
10049
+ const input = event.target;
10050
+ const file = input.files?.[0];
10051
+ input.value = '';
10052
+ if (!file) {
10053
+ return;
10054
+ }
10055
+ this.dailyBulkErrors = [];
10056
+ if (!/\.xlsx$/i.test(file.name)) {
10057
+ this.dailyBulkErrors = ['Please upload a valid .xlsx file.'];
10058
+ this.cd.detectChanges();
10059
+ return;
10060
+ }
10061
+ if (!this.users.length) {
10062
+ this.dailyBulkErrors = ['The users of this client could not be loaded. Reload the page and try again.'];
10063
+ this.cd.detectChanges();
10064
+ return;
10065
+ }
10066
+ file.arrayBuffer().then(buffer => {
10067
+ this.dailyBulkErrors = this.applyDailyBulk(buffer);
10068
+ if (!this.dailyBulkErrors.length) {
10069
+ this.dailyBulkOpen = false;
10070
+ this.toast.getSuccessToast('File uploaded successfully. ' + this.dailyUsers.length
10071
+ + (this.dailyUsers.length === 1 ? ' user' : ' users') + ' added to the daily report.');
10072
+ }
10073
+ this.cd.detectChanges();
10074
+ }).catch(() => {
10075
+ this.dailyBulkErrors = ['Could not read this file. Upload the downloaded template as .xlsx.'];
10076
+ this.cd.detectChanges();
10077
+ });
10078
+ }
10079
+ /** Applies the sheet to dailyUsers and returns [] on success, else the reasons it was rejected. */
10080
+ applyDailyBulk(buffer) {
10081
+ let rows;
10082
+ try {
10083
+ const book = XLSX.read(buffer, { type: 'array' });
10084
+ rows = XLSX.utils.sheet_to_json(book.Sheets[book.SheetNames[0]], { header: 1, defval: '', blankrows: true });
10085
+ }
10086
+ catch {
10087
+ return ['Could not read this file. Upload the downloaded template as .xlsx.'];
10088
+ }
10089
+ const emailCol = (rows[0] || []).findIndex(h => String(h ?? '').trim().toLowerCase() === 'email');
10090
+ if (emailCol < 0) {
10091
+ return ["The template must contain an 'Email' column."];
10092
+ }
10093
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
10094
+ const byEmail = new Map(this.users.map(u => [u.e, u]));
10095
+ const matched = [];
10096
+ const errors = [];
10097
+ let dataRows = 0;
10098
+ rows.slice(1).forEach((row, i) => {
10099
+ // Skip fully blank rows (any column, not just Email).
10100
+ if (!row.some(v => String(v ?? '').trim() !== '')) {
10101
+ return;
10102
+ }
10103
+ dataRows++;
10104
+ const rowNo = i + 2; // +1 header, +1 to 1-based
10105
+ const email = String(row[emailCol] ?? '').trim().toLowerCase();
10106
+ if (!email) {
10107
+ errors.push('Row ' + rowNo + ': Email is required');
10108
+ return;
10109
+ }
10110
+ if (!emailRegex.test(email)) {
10111
+ errors.push('Row ' + rowNo + ': "' + email + '" is not a valid email');
10112
+ return;
10113
+ }
10114
+ const user = byEmail.get(email);
10115
+ if (!user) {
10116
+ errors.push('Row ' + rowNo + ': "' + email + '" is not an existing user');
10117
+ return;
10118
+ }
10119
+ if (!matched.some(u => u.e === user.e)) {
10120
+ matched.push(user);
10121
+ }
10122
+ });
10123
+ if (!dataRows) {
10124
+ return ['The uploaded file has no data rows.'];
10125
+ }
10126
+ if (errors.length) {
10127
+ return errors;
10128
+ }
10129
+ this.dailyUsers = matched;
10130
+ this.dailySendCustom = true;
10131
+ return [];
10132
+ }
9951
10133
  /** What the checklist keeps as assignedUsers, exactly as the Checklist Configure page sends it. */
9952
10134
  assignedUsers() {
9953
10135
  const d = this.configData?.checkListDetails || {};
@@ -10204,11 +10386,11 @@ class AuditV2ConfigureComponent {
10204
10386
  return data;
10205
10387
  }
10206
10388
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuditV2ConfigureComponent, deps: [{ token: TraxService }, { token: i2.GlobalStateService }, { token: i1.ActivatedRoute }, { token: i1.Router }, { token: i3.ToastService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
10207
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AuditV2ConfigureComponent, selector: "lib-audit-v2-configure", host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "<div class=\"av2-page audit-configure\">\r\n\r\n <!-- Back + breadcrumb (as the schedule editor's back bar) -->\r\n <div class=\"cf-backbar\">\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm cf-back\" (click)=\"back()\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\r\n {{ backLabel }}\r\n </button>\r\n <div class=\"cf-crumb\">\r\n <a href=\"#\" (click)=\"back($event)\">Manage Audit</a> \u203A Configure\r\n </div>\r\n </div>\r\n\r\n <!-- Title + actions -->\r\n <div class=\"cf-header\">\r\n <div class=\"cf-header-text\">\r\n <span class=\"av2-sk av2-sk--title cf-sk-title\" *ngIf=\"loading\"></span>\r\n <div class=\"cf-title\" *ngIf=\"!loading\">{{ auditName || 'Audit' }}</div>\r\n <input type=\"text\" class=\"cf-desc\" placeholder=\"Enter Audit Description\" [(ngModel)]=\"description\">\r\n </div>\r\n <div class=\"av2-grow\"></div>\r\n <button type=\"button\" class=\"av2-btn av2-btn--primary cf-publish\" [disabled]=\"!canSave\" [title]=\"saveBlockedReason || publishBlockedReason\" (click)=\"publish()\">\r\n {{ saving ? 'Saving\u2026' : (published ? 'Save & Publish' : 'Publish') }}\r\n </button>\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost cf-draft\" [disabled]=\"!canSave\" [title]=\"saveBlockedReason\" (click)=\"saveDraft()\">Save as Draft</button>\r\n </div>\r\n\r\n <div class=\"cf-error cf-error--page\" *ngIf=\"loadError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ loadError }}\r\n </div>\r\n\r\n <!-- Chip picker: chips + input + suggestion list (one template, used for every user list) -->\r\n <ng-template #chipPicker let-list=\"list\" let-large=\"large\">\r\n <div class=\"cf-chipbox\" [class.cf-chipbox--lg]=\"large\" [class.is-open]=\"openChips === list\" (click)=\"focusChips(list, $event)\">\r\n <span class=\"cf-chip\" [class.cf-chip--lg]=\"large\" *ngFor=\"let u of chipsOf(list); let i = index\" [title]=\"u.e\">\r\n <span [class]=\"large ? 'cf-chip-tag' : 'cf-chip-ini'\">{{ u.i }}</span>{{ u.n }}\r\n <a class=\"cf-chip-x\" (click)=\"removeChip(list, i); $event.stopPropagation()\">\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\r\n </a>\r\n </span>\r\n <input type=\"text\" class=\"cf-chip-input\" [class.cf-chip-input--lg]=\"large\" placeholder=\"Add user...\"\r\n [ngModel]=\"draftOf(list)\" (ngModelChange)=\"setDraft(list, $event)\" (focus)=\"focusChips(list, $event)\" (keyup.enter)=\"addChip(list)\">\r\n <div class=\"cf-suggest\" *ngIf=\"openChips === list\">\r\n <div class=\"cf-suggest-item\" *ngFor=\"let u of suggestions(list)\" (click)=\"addSuggestion(list, u, $event)\">\r\n <span class=\"cf-chip-ini\">{{ u.i }}</span>\r\n <span class=\"cf-suggest-name\">{{ u.n }}</span>\r\n <span class=\"cf-suggest-mail\">{{ u.e }}</span>\r\n </div>\r\n <div class=\"cf-suggest-empty\" *ngIf=\"!suggestions(list).length\">\r\n {{ users.length ? 'No matching user' : 'No users for this client' }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Dropdown: styled like the prototype instead of the browser's native select -->\r\n <ng-template #dropdown let-key=\"key\" let-options=\"options\">\r\n <span class=\"cf-select\" [class.is-open]=\"openSelect === key\">\r\n <button type=\"button\" class=\"cf-select-btn\" (click)=\"toggleSelect(key, $event)\">\r\n {{ selectLabel(key, options) }}\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\r\n </button>\r\n <div class=\"cf-select-menu\" *ngIf=\"openSelect === key\">\r\n <div class=\"cf-select-item\" *ngFor=\"let o of options\" [class.is-on]=\"isPicked(key, o)\"\r\n (click)=\"pick(key, o, $event)\">{{ o.label }}</div>\r\n </div>\r\n </span>\r\n </ng-template>\r\n\r\n <div class=\"cf-body\" *ngIf=\"!loadError\">\r\n <!-- Section tree -->\r\n <aside class=\"cf-left\">\r\n <lib-audit-v2-shimmer *ngIf=\"loading\" [rows]=\"3\"></lib-audit-v2-shimmer>\r\n\r\n <ng-container *ngIf=\"!loading\">\r\n <div class=\"cf-left-title\">{{ auditName || 'Audit' }}</div>\r\n\r\n <div class=\"cf-hint\" *ngIf=\"!sections.length\">No questions yet</div>\r\n <ng-container *ngFor=\"let s of sections\">\r\n <div class=\"cf-section\" [class.is-open]=\"s.open\" (click)=\"toggleSection(s)\">\r\n {{ s.label }}\r\n <span class=\"cf-rule\"></span>\r\n <span class=\"cf-chev\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" [class.rotate]=\"!s.open\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"cf-items\" *ngIf=\"s.open && s.items.length\">\r\n <div *ngFor=\"let it of s.items\">{{ it }}</div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- No Schedule block (QA 10 Oct): audits have no one-time / repeat schedule here; visits come from Schedules. -->\r\n </ng-container>\r\n </aside>\r\n\r\n <!-- Configuration -->\r\n <div class=\"cf-right\">\r\n\r\n <section class=\"cf-card\" *ngIf=\"loading\">\r\n <lib-audit-v2-shimmer [rows]=\"4\"></lib-audit-v2-shimmer>\r\n </section>\r\n\r\n <ng-container *ngIf=\"!loading\">\r\n\r\n <!-- ===== Advance Configuration ===== -->\r\n <section class=\"cf-card\">\r\n <div class=\"cf-block-head\">\r\n <span class=\"cf-block-title\">Advance Configuration</span>\r\n <span class=\"cf-rule\"></span>\r\n <span class=\"cf-chev\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\r\n </span>\r\n </div>\r\n\r\n <!-- Audit Owner -->\r\n <div>\r\n <div class=\"cf-label\">Audit Owner</div>\r\n <div class=\"cf-hint\">Owners get access to manage the audit</div>\r\n </div>\r\n <div class=\"cf-row\">\r\n <span class=\"cf-field\">Can be managed by</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'owners', large: false }\"></ng-container>\r\n </div>\r\n\r\n <!-- Approver -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Approver</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"approverOn\" (click)=\"toggleApprover()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, the users will be able to approve the audit</div>\r\n <div class=\"cf-row\" *ngIf=\"approverOn\">\r\n <span class=\"cf-field\">To be approved by</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'approvers', large: false }\"></ng-container>\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"approverError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ approverError }}\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\" *ngIf=\"!approverOn && approvers.length\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Approver is off, so the {{ approvers.length }} approver{{ approvers.length === 1 ? '' : 's' }} added will be removed when you save. Turn Approver back on to keep {{ approvers.length === 1 ? 'it' : 'them' }}.\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\" *ngIf=\"!approverOn && !approvers.length\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Approver is off, so submitted audits are not sent for approval. Turn it on to add approvers or to send flags and reports to them.\r\n </div>\r\n\r\n <!-- Reminder -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Reminder</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"reminderOn\" (click)=\"toggleReminder()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, the users will be reminded in the selected interval</div>\r\n <div class=\"cf-inner\" *ngIf=\"reminderOn\">\r\n <div class=\"cf-inline\">\r\n Notify user before\r\n <span class=\"cf-reminder\" *ngFor=\"let m of reminders; let i = index\">\r\n <lib-audit-v2-select class=\"cf-reminder-select\" [value]=\"m\" [options]=\"reminderOpts[i] || []\" [searchable]=\"false\"\r\n [ariaLabel]=\"'Reminder ' + (i + 1) + ' in minutes'\" (changed)=\"setReminder(i, $event.target.value)\"></lib-audit-v2-select>\r\n <a class=\"cf-chip-x\" *ngIf=\"reminders.length > 1\" title=\"Remove reminder\" (click)=\"removeReminder(i)\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\r\n </a>\r\n </span>\r\n <button type=\"button\" class=\"cf-icon-btn\" *ngIf=\"reminders.length < maxReminders\" title=\"Add reminder\" (click)=\"addReminder()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line></svg>\r\n </button>\r\n </div>\r\n <div class=\"cf-info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Send alerts {{ reminderSummary }} mins before the audit end time\r\n </div>\r\n </div>\r\n\r\n <!-- Notify Flags -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Notify Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"notifyFlagsOn\" (click)=\"toggleNotifyFlags()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, all flags will be sent as an email</div>\r\n <ng-container *ngIf=\"notifyFlagsOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !notifySendApprover\" (click)=\"toggleSendApprover('notifySendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"notifySendApprover\">\r\n <svg *ngIf=\"notifySendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"notifySendCustom = !notifySendCustom\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"notifySendCustom\">\r\n <svg *ngIf=\"notifySendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"notifySendCustom\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'notifyUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <div class=\"cf-error\" *ngIf=\"notifyFlagsError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ notifyFlagsError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Notify on Recurring Flags -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Notify on Recurring Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"recurringFlagsOn\" (click)=\"toggleRecurringFlags()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">When enabled, emails are sent for recurring flags based on the configured threshold</div>\r\n\r\n <div class=\"cf-inner\" *ngIf=\"recurringFlagsOn\">\r\n <div class=\"cf-inline\">\r\n Send Email if the same question is flagged\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'recurringThreshold', options: thresholdOpts }\"></ng-container>\r\n times by the same store\r\n </div>\r\n <div class=\"cf-info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Once the threshold is reached and an email is sent, the flag count resets to zero\r\n </div>\r\n </div>\r\n <ng-container *ngIf=\"recurringFlagsOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !recurringSendApprover\" (click)=\"toggleSendApprover('recurringSendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSendApprover\">\r\n <svg *ngIf=\"recurringSendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"toggleRecurringCustom()\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSendCustom\">\r\n <svg *ngIf=\"recurringSendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n <label class=\"cf-check\" (click)=\"recurringSameAsNotify = !recurringSameAsNotify\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSameAsNotify\">\r\n <svg *ngIf=\"recurringSameAsNotify\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Use same users from Notify Flags\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"recurringSendCustom\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'recurringUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <div class=\"cf-info\" *ngIf=\"recurringSameAsNotify\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n {{ notifyRecipientsLabel }}\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"recurringFlagsError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ recurringFlagsError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Daily report -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Enable - Daily Report</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"dailyReportOn\" (click)=\"toggleDailyReport()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By Enabling, compliance score will be sent as an email to the above users</div>\r\n <ng-container *ngIf=\"dailyReportOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !dailySendApprover\" (click)=\"toggleSendApprover('dailySendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"dailySendApprover\">\r\n <svg *ngIf=\"dailySendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"dailySendCustom = !dailySendCustom\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"dailySendCustom\">\r\n <svg *ngIf=\"dailySendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"dailySendCustom\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'dailyUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <label class=\"cf-check\" (click)=\"sharePostApproval = !sharePostApproval\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"sharePostApproval\">\r\n <svg *ngIf=\"sharePostApproval\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Share Report Post Approval\r\n </label>\r\n <div class=\"cf-error\" *ngIf=\"dailyReportError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ dailyReportError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Export submission: Tango users only, as the v1 Configure (its stored value is kept for everyone else). -->\r\n <div class=\"cf-grid2\" *ngIf=\"access.isTango\">\r\n <div class=\"cf-stack cf-stack--tight\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Export Submission</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"exportSubmissionOn\" (click)=\"exportSubmissionOn = !exportSubmissionOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint\">Enable this to allow audit submitters to download their submission as a PDF file</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Redo validity -->\r\n <div class=\"cf-grid2\">\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-label\">Redo Validity</div>\r\n <div class=\"cf-inline\">\r\n Redo valid for\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'redoValidFor', options: redoDayOpts }\"></ng-container>\r\n Day from Redo creation\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Auto create task -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Auto Create Task for Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"autoCreateTaskOn\" (click)=\"autoCreateTaskOn = !autoCreateTaskOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, a task is automatically created for every flagged question in the audit</div>\r\n\r\n <!-- Who gets the task and how long it stays open (as the Checklist Configure page) -->\r\n <div class=\"cf-autotask\" *ngIf=\"autoCreateTaskOn\">\r\n <div class=\"cf-autotask-title\">Task Assignee</div>\r\n <div class=\"cf-hint cf-hint--tight\">Choose who the flagged task is assigned to</div>\r\n <div class=\"cf-autotask-choices\">\r\n <button type=\"button\" class=\"cf-choice\" [class.is-on]=\"taskAssignee === 'submitter'\" (click)=\"taskAssignee = 'submitter'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"taskAssignee === 'submitter'\"><span></span></span>\r\n <span class=\"cf-choice-text\">\r\n <span class=\"cf-choice-title\">Audit Submitter</span>\r\n <span class=\"cf-choice-sub\">Task is assigned to the user who filled the audit</span>\r\n </span>\r\n </button>\r\n <button type=\"button\" class=\"cf-choice\" [class.is-on]=\"taskAssignee === 'store'\" (click)=\"taskAssignee = 'store'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"taskAssignee === 'store'\"><span></span></span>\r\n <span class=\"cf-choice-text\">\r\n <span class=\"cf-choice-title\">Store User</span>\r\n <span class=\"cf-choice-sub\">Task is assigned to the user mapped to the flagged store</span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"cf-autotask-title\">Task Validity</div>\r\n <div class=\"cf-autotask-validity\">\r\n <span>Task valid for</span>\r\n <lib-audit-v2-select class=\"cf-validity-select\" [(ngModel)]=\"taskValidity\" [options]=\"taskValidityOptions\"\r\n [searchable]=\"false\" ariaLabel=\"Task validity in days\"></lib-audit-v2-select>\r\n <span>days from task creation</span>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Audit Configuration ===== -->\r\n <div class=\"cf-divider-head\">\r\n <span class=\"cf-block-title\">Audit Configuration</span>\r\n <span class=\"cf-rule\"></span>\r\n </div>\r\n\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Submission &amp; Visibility</div>\r\n\r\n <!-- cf-box--open: the dispute-window and response-delay menus must not be clipped by the box -->\r\n <div class=\"cf-box cf-box--open\">\r\n <div class=\"cf-box-row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"showResponseInApp\"\r\n (click)=\"showResponseInApp = !showResponseInApp\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Show Response in Mobile App</div>\r\n <div class=\"cf-hint\">By enabling this option, store users can view the audit response in the Mobile App.</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"cf-box-sub\" *ngIf=\"showResponseInApp\">\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label-sm\">Response Visibility</div>\r\n <div class=\"cf-hint\">Choose when the response becomes visible to store users</div>\r\n </div>\r\n\r\n <div class=\"cf-options\">\r\n <div class=\"cf-option\" [class.is-on]=\"responseVisibility === 'pre'\" (click)=\"responseVisibility = 'pre'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"responseVisibility === 'pre'\"><span></span></span>\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm\">Pre-approval</div>\r\n <div class=\"cf-hint\">The audit response will be visible to store users before it is approved.</div>\r\n <div class=\"cf-inline cf-inline--top\">\r\n Show response\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'respDelay', options: respDelayOpts }\"></ng-container>\r\n after submission\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"cf-option\" [class.is-on]=\"responseVisibility === 'post'\" (click)=\"responseVisibility = 'post'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"responseVisibility === 'post'\"><span></span></span>\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm\" [class.cf-muted]=\"responseVisibility !== 'post'\">Post-approval</div>\r\n <div class=\"cf-hint\">Once the response is approved, it will automatically be displayed in the Mobile App. Store users cannot raise a dispute.</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"cf-box-sep\">\r\n <ng-container *ngIf=\"responseVisibility === 'pre'\">\r\n <div class=\"cf-box-row cf-box-row--flush\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"disputeOn\" (click)=\"disputeOn = !disputeOn\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label-sm\">Dispute Configuration</div>\r\n <div class=\"cf-hint cf-hint--wrap\">When enabled, the store team can raise a dispute against the auditor's submission once the response becomes visible to them.</div>\r\n </div>\r\n </div>\r\n <div class=\"cf-box cf-box--nested\" *ngIf=\"disputeOn\">\r\n <div class=\"cf-inline\">\r\n Dispute window\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'disputeWindow', options: dispWindowOpts }\"></ng-container>\r\n from when the response becomes visible\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Disputes raised inside this window go to the approver. Approved disputes revise the answer and the compliance score.\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"!hasApprovers\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n No approver is set, so no one can review disputes. Turn on Approver and add an approver.\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"responseVisibility === 'post'\">\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm cf-muted\">Dispute Configuration</div>\r\n <div class=\"cf-info cf-info--wrap\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Disputes are not available when responses are shown post-approval.\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Pre-submission access -->\r\n <div class=\"cf-box cf-box--pad\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Pre-Submission Access</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"preSubmissionAccessOn\" (click)=\"preSubmissionAccessOn = !preSubmissionAccessOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--wrap\">Users added here can view Open and In Progress audits until submission. The Schedule Info tab is also visible only to these users.</div>\r\n <ng-container *ngIf=\"preSubmissionAccessOn\">\r\n <div class=\"cf-row cf-row--top\">\r\n <span class=\"cf-field\">Visible to</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'preSubmissionUsers', large: false }\"></ng-container>\r\n </div>\r\n <div class=\"cf-error cf-error--indent\" *ngIf=\"preSubmissionEmpty\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n Add at least one user\r\n </div>\r\n </ng-container>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Scoring ===== -->\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Scoring</div>\r\n <div class=\"cf-box cf-box--pad\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Pass/Fail Score Setup</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"passFailOn\" (click)=\"passFailOn = !passFailOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--wrap\">Set the compliance score an audit must reach to be marked {{ passLabel }}. Anything below it is marked {{ failLabel }}.</div>\r\n <div class=\"cf-row cf-row--wrap cf-row--top\" *ngIf=\"passFailOn\">\r\n <span class=\"cf-field\">Minimum score to {{ passLabel }}</span>\r\n <label class=\"cf-num\">\r\n <input type=\"number\" min=\"1\" max=\"100\" [(ngModel)]=\"passThreshold\">\r\n <span>%</span>\r\n </label>\r\n <span class=\"cf-pill cf-pill--pass\">{{ passLabel }} \u2265 {{ passThreshold }}%</span>\r\n <span class=\"cf-pill cf-pill--fail\">{{ failLabel }} &lt; {{ passThreshold }}%</span>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Approver Controls ===== -->\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Approver Controls</div>\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Edit Submitted Audit</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"editSubmittedOn\" (click)=\"toggleEditSubmitted()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">Allow Approvers to edit submitted Audit</div>\r\n <ng-container *ngIf=\"editSubmittedOn\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'editUsers', large: true }\"></ng-container>\r\n <div class=\"cf-error\" *ngIf=\"editSubmittedError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ editSubmittedError }}\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div class=\"cf-grid2\">\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-label\">Redo Extension</div>\r\n <div class=\"cf-inline\">\r\n Extend redo up to\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'redoExtension', options: redoExtensionOpts }\"></ng-container>\r\n Days till approval\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== User Verification ===== -->\r\n <section class=\"cf-card\">\r\n <div class=\"cf-block-title\">User Verification Configuration</div>\r\n <div class=\"cf-box cf-box--row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"requirePhoto\" (click)=\"requirePhoto = !requirePhoto\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Require Photo Capture</div>\r\n <div class=\"cf-hint\">By enabling, users must capture their photo to complete submission</div>\r\n </div>\r\n </div>\r\n <div class=\"cf-box cf-box--row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"requireAcknowledgment\" (click)=\"requireAcknowledgment = !requireAcknowledgment\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Require User Acknowledgment</div>\r\n <div class=\"cf-hint\">By enabling, users must type their name as acknowledgment to complete submission</div>\r\n </div>\r\n </div>\r\n </section>\r\n </ng-container>\r\n\r\n </div>\r\n </div>\r\n\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}.cf-backbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.cf-back{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.cf-crumb{font-size:13px;line-height:20px;color:#667085}.cf-crumb a{font-weight:600;color:#00a3ff}.cf-header{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:16px 20px;display:flex;align-items:center;gap:12px}.cf-header-text{display:flex;flex-direction:column;gap:4px;min-width:0}.cf-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.cf-sk-title{margin:3px 0}.cf-desc{border:none;outline:none;padding:0;background:transparent;font-family:inherit;font-size:13px;line-height:18px;color:#344054;min-width:320px}.cf-desc::placeholder{color:#98a2b3}.cf-publish{padding:0 20px;box-shadow:0 1px 2px #1018280d}.cf-draft{padding:0 18px;box-shadow:inset 0 0 0 1px #d0d5dd,0 1px 2px #1018280d}.cf-body{display:flex;gap:16px;align-items:flex-start}.cf-left{width:300px;flex-shrink:0;background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:16px;display:flex;flex-direction:column;gap:10px;position:sticky;top:calc(var(--bs-app-header-height, 0px) + 16px);max-height:calc(100vh - var(--bs-app-header-height, 0px) - 32px);overflow-y:auto;scrollbar-width:thin}.cf-left-title{font-size:14px;line-height:20px;font-weight:600;color:#101828}.cf-section{display:flex;align-items:center;gap:8px;padding:2px 0;font-size:13px;font-weight:500;color:#344054;cursor:pointer;white-space:nowrap}.cf-section.is-open{color:#1d2939}.cf-rule{flex:1;border-top:1px solid #EAECF0}.cf-chev{display:flex;color:#98a2b3}.cf-chev svg{transition:transform .15s cubic-bezier(.4,0,.2,1)}.cf-chev .rotate{transform:rotate(-90deg)}.cf-items{display:flex;flex-direction:column;gap:8px;padding-left:12px;font-size:13px;color:#475467}.cf-schedule-title{font-size:14px;font-weight:600;color:#101828;margin-top:6px}.cf-schedule{display:flex;flex-direction:column;gap:6px;font-size:13px;color:#475467}.cf-schedule>div{display:flex;align-items:center;gap:6px}.cf-right{flex:1;min-width:0;display:flex;flex-direction:column;gap:16px}.cf-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px;display:flex;flex-direction:column;gap:14px}.cf-card--lg{border-radius:8px}.cf-block-head{display:flex;align-items:center;gap:12px}.cf-block-title{font-size:15px;font-weight:600;color:#101828}.cf-divider-head{display:flex;align-items:center;gap:10px;margin-top:4px}.cf-label{font-size:14px;font-weight:600;color:#101828}.cf-label-sm{font-size:13px;font-weight:600;color:#101828}.cf-muted{color:#667085}.cf-hint{font-size:12px;line-height:18px;color:#667085}.cf-hint--tight{margin-top:-8px}.cf-hint--wrap{max-width:640px;text-wrap:pretty}.cf-field{font-size:13px;font-weight:500;color:#344054;min-width:150px;flex-shrink:0}.cf-row{display:flex;align-items:center;gap:12px}.cf-row--top{margin-top:6px}.cf-row--wrap{flex-wrap:wrap}.cf-stack{display:flex;flex-direction:column;gap:8px}.cf-stack--tight,.cf-stack--sm{gap:4px}.cf-stack--xs{gap:2px}.cf-grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.cf-toggle-row{display:flex;align-items:center;gap:10px}.cf-switch{width:36px;height:20px;padding:2px;border:none;border-radius:9999px;background:#eaecf0;display:flex;align-items:center;justify-content:flex-start;flex-shrink:0;cursor:pointer;transition:background .15s cubic-bezier(.4,0,.2,1)}.cf-switch>span{width:16px;height:16px;border-radius:9999px;background:#fff;box-shadow:0 1px 2px #1018280d}.cf-switch.is-on{background:#00a3ff;justify-content:flex-end}.cf-switch--top{margin-top:2px}.cf-chipbox{flex:1;min-width:0;display:flex;flex-wrap:wrap;gap:6px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;padding:8px 10px}.cf-chipbox--lg{gap:8px;padding:10px 12px}.cf-chip{display:flex;align-items:center;gap:6px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0;border-radius:9999px;padding:3px 8px;font-size:12px;color:#344054;white-space:nowrap;flex-shrink:0;max-width:100%}.cf-chip--lg{gap:8px;background:#fff;padding:5px 11px;font-size:13px;color:#1d2939}.cf-chip-ini{color:#00a3ff;font-weight:600;font-size:11px}.cf-chip-tag{display:inline-flex;align-items:center;justify-content:center;padding:1px 5px;border-radius:6px;background:#eaf8ff;color:#00a3ff;font-weight:700;font-size:11px;letter-spacing:.02em}.cf-chip-x{display:flex;cursor:pointer;color:#98a2b3}.cf-chip-x:hover{color:#344054}.cf-chip-input{flex:1;min-width:100px;border:none;outline:none;background:transparent;font-family:inherit;font-size:12px;color:#101828}.cf-chip-input::placeholder{color:#98a2b3}.cf-chip-input--lg{min-width:120px;font-size:13px}.cf-inner{border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;padding:14px 16px;display:flex;flex-direction:column;gap:8px}.cf-inline{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:13px;color:#344054}.cf-inline--top{margin-top:2px}.cf-mini{height:32px;padding:0 28px 0 10px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#101828;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 8px center;outline:none}.cf-info{display:flex;align-items:center;gap:6px;font-size:12px;line-height:18px;color:#667085}.cf-info svg{flex-shrink:0}.cf-info--wrap{align-items:flex-start;max-width:560px;text-wrap:pretty}.cf-info--wrap svg{margin-top:3px}.cf-checks{display:flex;align-items:center;gap:16px;flex-wrap:wrap;font-size:13px;color:#344054}.cf-checks-label{font-weight:500}.cf-check{display:flex;align-items:center;gap:6px;margin:0;font-size:13px;color:#344054;cursor:pointer;-webkit-user-select:none;user-select:none}.cf-check-box{width:16px;height:16px;border-radius:4px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}.cf-check-box.is-on{background:#00a3ff;box-shadow:none}.cf-box{border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;overflow:hidden;display:flex;flex-direction:column}.cf-box--pad{padding:14px 16px;gap:6px;overflow:visible}.cf-box--row{padding:14px 16px;flex-direction:row;align-items:flex-start;gap:12px}.cf-box--nested{background:#fff;padding:12px 14px;gap:8px;margin-left:46px;overflow:visible}.cf-box--open{overflow:visible}.cf-box--open>.cf-box-sub:last-child{border-radius:0 0 8px 8px}.cf-box-row{padding:14px 16px;display:flex;align-items:flex-start;gap:12px}.cf-box-row--flush{padding:0;gap:10px}.cf-box-sub{border-top:1px solid #EAECF0;background:#f9fafb;padding:16px 16px 18px 64px;display:flex;flex-direction:column;gap:12px}.cf-options{display:flex;flex-direction:column;gap:10px}.cf-option{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;cursor:pointer}.cf-option.is-on{box-shadow:inset 0 0 0 1.5px #00a3ff}.cf-box-sep{display:flex;flex-direction:column;gap:12px;padding-top:14px;border-top:1px solid #EAECF0}.cf-num{display:flex;align-items:center;gap:8px;height:36px;padding:0 6px 0 12px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;margin:0}.cf-num input{width:52px;border:none;outline:none;background:transparent;font-family:inherit;font-size:14px;font-weight:600;color:#101828}.cf-num span{font-size:13px;color:#667085;padding-right:6px}.cf-pill{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;border-radius:9999px;padding:4px 12px}.cf-pill--pass{background:#ecfdf3;color:#027a48}.cf-pill--fail{background:#fef3f2;color:#d92d20}.cf-error{display:flex;gap:6px;font-size:12px;font-weight:500;color:#d92d20;align-items:flex-start;line-height:18px;max-width:640px}.cf-error svg{flex-shrink:0;margin-top:3px}.cf-error--indent{margin-left:162px}.cf-check.is-blocked{color:#98a2b3;cursor:not-allowed}.cf-select{position:relative;display:inline-block;vertical-align:middle}.cf-select-btn{display:inline-flex;align-items:center;gap:8px;height:32px;padding:0 10px 0 12px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#101828;cursor:pointer;white-space:nowrap}.cf-select-btn svg{color:#667085;transition:transform .15s ease}.is-open .cf-select-btn{box-shadow:0 0 0 2px #99dbff,inset 0 0 0 1px #d0d5dd}.is-open .cf-select-btn svg{transform:rotate(180deg)}.cf-select-menu{position:absolute;top:calc(100% + 4px);left:0;z-index:30;min-width:100%;padding:4px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 8px 24px #1018281f}.cf-select-item{padding:8px 12px;border-radius:6px;font-size:13px;color:#344054;white-space:nowrap;cursor:pointer}.cf-select-item:hover{background:#f9fafb}.cf-select-item.is-on{background:#eaf8ff;color:#009bf3;font-weight:600}.cf-chipbox{position:relative}.cf-chipbox.is-open{box-shadow:0 0 0 2px #99dbff,inset 0 0 0 1px #d0d5dd}.cf-suggest{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:30;max-height:260px;overflow-y:auto;padding:4px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 8px 24px #1018281f}.cf-suggest-item{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:6px;cursor:pointer}.cf-suggest-item:hover{background:#f9fafb}.cf-suggest-name{font-size:13px;color:#101828}.cf-suggest-mail{font-size:12px;color:#667085;margin-left:auto}.cf-suggest-empty{padding:8px 10px;font-size:12px;color:#667085}.cf-error--page{margin:0 0 12px}.cf-autotask{margin-top:12px;padding:14px 16px;border-radius:10px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0;display:flex;flex-direction:column;gap:8px}.cf-autotask-title{font-size:14px;font-weight:600;color:#1d2939}.cf-autotask-title:not(:first-child){margin-top:6px}.cf-autotask-choices{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}@media (max-width: 720px){.cf-autotask-choices{grid-template-columns:1fr}}.cf-choice{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;text-align:left;cursor:pointer}.cf-choice.is-on{background:#f5faff;box-shadow:inset 0 0 0 1px #66c8ff}.cf-radio{width:18px;height:18px;flex-shrink:0;margin-top:1px;border-radius:9999px;box-shadow:inset 0 0 0 1px #d0d5dd;display:flex;align-items:center;justify-content:center}.cf-radio span{width:8px;height:8px;border-radius:9999px;background:transparent}.cf-radio.is-on{box-shadow:inset 0 0 0 1px #1570ef}.cf-radio.is-on span{background:#1570ef}.cf-choice-text{display:flex;flex-direction:column;gap:2px;min-width:0}.cf-choice-title{font-size:14px;font-weight:600;color:#101828}.cf-choice-sub{font-size:12px;color:#667085}.cf-autotask-validity{display:flex;align-items:center;flex-wrap:wrap;gap:10px;font-size:13px;color:#344054}.cf-validity-select{width:96px}.cf-reminder{display:inline-flex;align-items:center;gap:6px}.cf-reminder-select{width:120px}.cf-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;cursor:pointer}.cf-icon-btn:hover{background:#f9fafb}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AuditV2ShimmerComponent, selector: "lib-audit-v2-shimmer", inputs: ["rows"] }, { kind: "component", type: AuditV2SelectComponent, selector: "lib-audit-v2-select", inputs: ["options", "placeholder", "searchable", "ariaLabel", "disabled", "value"], outputs: ["changed"] }] });
10389
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AuditV2ConfigureComponent, selector: "lib-audit-v2-configure", host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "<div class=\"av2-page audit-configure\">\r\n\r\n <!-- Back + breadcrumb (as the schedule editor's back bar) -->\r\n <div class=\"cf-backbar\">\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm cf-back\" (click)=\"back()\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\r\n {{ backLabel }}\r\n </button>\r\n <div class=\"cf-crumb\">\r\n <a href=\"#\" (click)=\"back($event)\">Manage Audit</a> \u203A Configure\r\n </div>\r\n </div>\r\n\r\n <!-- Title + actions -->\r\n <div class=\"cf-header\">\r\n <div class=\"cf-header-text\">\r\n <span class=\"av2-sk av2-sk--title cf-sk-title\" *ngIf=\"loading\"></span>\r\n <div class=\"cf-title\" *ngIf=\"!loading\">{{ auditName || 'Audit' }}</div>\r\n <input type=\"text\" class=\"cf-desc\" placeholder=\"Enter Audit Description\" [(ngModel)]=\"description\">\r\n </div>\r\n <div class=\"av2-grow\"></div>\r\n <button type=\"button\" class=\"av2-btn av2-btn--primary cf-publish\" [disabled]=\"!canSave\" [title]=\"saveBlockedReason || publishBlockedReason\" (click)=\"publish()\">\r\n {{ saving ? 'Saving\u2026' : (published ? 'Save & Publish' : 'Publish') }}\r\n </button>\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost cf-draft\" [disabled]=\"!canSave\" [title]=\"saveBlockedReason\" (click)=\"saveDraft()\">Save as Draft</button>\r\n </div>\r\n\r\n <div class=\"cf-error cf-error--page\" *ngIf=\"loadError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ loadError }}\r\n </div>\r\n\r\n <!-- Chip picker: chips + input + suggestion list (one template, used for every user list) -->\r\n <ng-template #chipPicker let-list=\"list\" let-large=\"large\">\r\n <div class=\"cf-chipbox\" [class.cf-chipbox--lg]=\"large\" [class.is-open]=\"openChips === list\" (click)=\"focusChips(list, $event)\">\r\n <span class=\"cf-chip\" [class.cf-chip--lg]=\"large\" *ngFor=\"let u of chipsOf(list); let i = index\" [title]=\"u.e\">\r\n <span [class]=\"large ? 'cf-chip-tag' : 'cf-chip-ini'\">{{ u.i }}</span>{{ u.n }}\r\n <a class=\"cf-chip-x\" (click)=\"removeChip(list, i); $event.stopPropagation()\">\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\r\n </a>\r\n </span>\r\n <input type=\"text\" class=\"cf-chip-input\" [class.cf-chip-input--lg]=\"large\" placeholder=\"Add user...\"\r\n [ngModel]=\"draftOf(list)\" (ngModelChange)=\"setDraft(list, $event)\" (focus)=\"focusChips(list, $event)\" (keyup.enter)=\"addChip(list)\">\r\n <div class=\"cf-suggest\" *ngIf=\"openChips === list\">\r\n <div class=\"cf-suggest-item\" *ngFor=\"let u of suggestions(list)\" (click)=\"addSuggestion(list, u, $event)\">\r\n <span class=\"cf-chip-ini\">{{ u.i }}</span>\r\n <span class=\"cf-suggest-name\">{{ u.n }}</span>\r\n <span class=\"cf-suggest-mail\">{{ u.e }}</span>\r\n </div>\r\n <div class=\"cf-suggest-empty\" *ngIf=\"!suggestions(list).length\">\r\n {{ users.length ? 'No matching user' : 'No users for this client' }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Dropdown: styled like the prototype instead of the browser's native select -->\r\n <ng-template #dropdown let-key=\"key\" let-options=\"options\">\r\n <span class=\"cf-select\" [class.is-open]=\"openSelect === key\">\r\n <button type=\"button\" class=\"cf-select-btn\" (click)=\"toggleSelect(key, $event)\">\r\n {{ selectLabel(key, options) }}\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\r\n </button>\r\n <div class=\"cf-select-menu\" *ngIf=\"openSelect === key\">\r\n <div class=\"cf-select-item\" *ngFor=\"let o of options\" [class.is-on]=\"isPicked(key, o)\"\r\n (click)=\"pick(key, o, $event)\">{{ o.label }}</div>\r\n </div>\r\n </span>\r\n </ng-template>\r\n\r\n <div class=\"cf-body\" *ngIf=\"!loadError\">\r\n <!-- Section tree -->\r\n <aside class=\"cf-left\">\r\n <lib-audit-v2-shimmer *ngIf=\"loading\" [rows]=\"3\"></lib-audit-v2-shimmer>\r\n\r\n <ng-container *ngIf=\"!loading\">\r\n <div class=\"cf-left-title\">{{ auditName || 'Audit' }}</div>\r\n\r\n <div class=\"cf-hint\" *ngIf=\"!sections.length\">No questions yet</div>\r\n <ng-container *ngFor=\"let s of sections\">\r\n <div class=\"cf-section\" [class.is-open]=\"s.open\" (click)=\"toggleSection(s)\">\r\n {{ s.label }}\r\n <span class=\"cf-rule\"></span>\r\n <span class=\"cf-chev\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" [class.rotate]=\"!s.open\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"cf-items\" *ngIf=\"s.open && s.items.length\">\r\n <div *ngFor=\"let it of s.items\">{{ it }}</div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- No Schedule block (QA 10 Oct): audits have no one-time / repeat schedule here; visits come from Schedules. -->\r\n </ng-container>\r\n </aside>\r\n\r\n <!-- Configuration -->\r\n <div class=\"cf-right\">\r\n\r\n <section class=\"cf-card\" *ngIf=\"loading\">\r\n <lib-audit-v2-shimmer [rows]=\"4\"></lib-audit-v2-shimmer>\r\n </section>\r\n\r\n <ng-container *ngIf=\"!loading\">\r\n\r\n <!-- ===== Advance Configuration ===== -->\r\n <section class=\"cf-card\">\r\n <div class=\"cf-block-head\">\r\n <span class=\"cf-block-title\">Advance Configuration</span>\r\n <span class=\"cf-rule\"></span>\r\n <span class=\"cf-chev\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\r\n </span>\r\n </div>\r\n\r\n <!-- Audit Owner -->\r\n <div>\r\n <div class=\"cf-label\">Audit Owner</div>\r\n <div class=\"cf-hint\">Owners get access to manage the audit</div>\r\n </div>\r\n <div class=\"cf-row\">\r\n <span class=\"cf-field\">Can be managed by</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'owners', large: false }\"></ng-container>\r\n </div>\r\n\r\n <!-- Approver -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Approver</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"approverOn\" (click)=\"toggleApprover()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, the users will be able to approve the audit</div>\r\n <div class=\"cf-row\" *ngIf=\"approverOn\">\r\n <span class=\"cf-field\">To be approved by</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'approvers', large: false }\"></ng-container>\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"approverError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ approverError }}\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\" *ngIf=\"!approverOn && approvers.length\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Approver is off, so the {{ approvers.length }} approver{{ approvers.length === 1 ? '' : 's' }} added will be removed when you save. Turn Approver back on to keep {{ approvers.length === 1 ? 'it' : 'them' }}.\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\" *ngIf=\"!approverOn && !approvers.length\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Approver is off, so submitted audits are not sent for approval. Turn it on to add approvers or to send flags and reports to them.\r\n </div>\r\n\r\n <!-- Reminder -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Reminder</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"reminderOn\" (click)=\"toggleReminder()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, the users will be reminded in the selected interval</div>\r\n <div class=\"cf-inner\" *ngIf=\"reminderOn\">\r\n <div class=\"cf-inline\">\r\n Notify user before\r\n <span class=\"cf-reminder\" *ngFor=\"let m of reminders; let i = index\">\r\n <lib-audit-v2-select class=\"cf-reminder-select\" [value]=\"m\" [options]=\"reminderOpts[i] || []\" [searchable]=\"false\"\r\n [ariaLabel]=\"'Reminder ' + (i + 1) + ' in minutes'\" (changed)=\"setReminder(i, $event.target.value)\"></lib-audit-v2-select>\r\n <a class=\"cf-chip-x\" *ngIf=\"reminders.length > 1\" title=\"Remove reminder\" (click)=\"removeReminder(i)\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\r\n </a>\r\n </span>\r\n <button type=\"button\" class=\"cf-icon-btn\" *ngIf=\"reminders.length < maxReminders\" title=\"Add reminder\" (click)=\"addReminder()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line></svg>\r\n </button>\r\n </div>\r\n <div class=\"cf-info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Send alerts {{ reminderSummary }} mins before the audit end time\r\n </div>\r\n </div>\r\n\r\n <!-- Notify Flags -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Notify Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"notifyFlagsOn\" (click)=\"toggleNotifyFlags()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, all flags will be sent as an email</div>\r\n <ng-container *ngIf=\"notifyFlagsOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !notifySendApprover\" (click)=\"toggleSendApprover('notifySendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"notifySendApprover\">\r\n <svg *ngIf=\"notifySendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"notifySendCustom = !notifySendCustom\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"notifySendCustom\">\r\n <svg *ngIf=\"notifySendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"notifySendCustom\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'notifyUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <div class=\"cf-error\" *ngIf=\"notifyFlagsError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ notifyFlagsError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Notify on Recurring Flags -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Notify on Recurring Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"recurringFlagsOn\" (click)=\"toggleRecurringFlags()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">When enabled, emails are sent for recurring flags based on the configured threshold</div>\r\n\r\n <div class=\"cf-inner\" *ngIf=\"recurringFlagsOn\">\r\n <div class=\"cf-inline\">\r\n Send Email if the same question is flagged\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'recurringThreshold', options: thresholdOpts }\"></ng-container>\r\n times by the same store\r\n </div>\r\n <div class=\"cf-info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Once the threshold is reached and an email is sent, the flag count resets to zero\r\n </div>\r\n </div>\r\n <ng-container *ngIf=\"recurringFlagsOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !recurringSendApprover\" (click)=\"toggleSendApprover('recurringSendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSendApprover\">\r\n <svg *ngIf=\"recurringSendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"toggleRecurringCustom()\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSendCustom\">\r\n <svg *ngIf=\"recurringSendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n <label class=\"cf-check\" (click)=\"recurringSameAsNotify = !recurringSameAsNotify\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSameAsNotify\">\r\n <svg *ngIf=\"recurringSameAsNotify\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Use same users from Notify Flags\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"recurringSendCustom\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'recurringUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <div class=\"cf-info\" *ngIf=\"recurringSameAsNotify\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n {{ notifyRecipientsLabel }}\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"recurringFlagsError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ recurringFlagsError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Daily report -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Enable - Daily Report</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"dailyReportOn\" (click)=\"toggleDailyReport()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By Enabling, compliance score will be sent as an email to the above users</div>\r\n <ng-container *ngIf=\"dailyReportOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !dailySendApprover\" (click)=\"toggleSendApprover('dailySendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"dailySendApprover\">\r\n <svg *ngIf=\"dailySendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"dailySendCustom = !dailySendCustom\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"dailySendCustom\">\r\n <svg *ngIf=\"dailySendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"dailySendCustom\">\r\n <div class=\"cf-bulkbar\">\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" (click)=\"openDailyBulk()\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.67\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M17.5 12.5V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H4.16667C3.72464 17.5 3.30072 17.3244 2.98816 17.0118C2.67559 16.6993 2.5 16.2754 2.5 15.8333V12.5M14.1667 6.66667L10 2.5M10 2.5L5.83333 6.66667M10 2.5V12.5\"></path></svg>\r\n Bulk Upload\r\n </button>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'dailyUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <label class=\"cf-check\" (click)=\"sharePostApproval = !sharePostApproval\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"sharePostApproval\">\r\n <svg *ngIf=\"sharePostApproval\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Share Report Post Approval\r\n </label>\r\n <div class=\"cf-error\" *ngIf=\"dailyReportError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ dailyReportError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Export submission: Tango users only, as the v1 Configure (its stored value is kept for everyone else). -->\r\n <div class=\"cf-grid2\" *ngIf=\"access.isTango\">\r\n <div class=\"cf-stack cf-stack--tight\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Export Submission</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"exportSubmissionOn\" (click)=\"exportSubmissionOn = !exportSubmissionOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint\">Enable this to allow audit submitters to download their submission as a PDF file</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Redo validity -->\r\n <div class=\"cf-grid2\">\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-label\">Redo Validity</div>\r\n <div class=\"cf-inline\">\r\n Redo valid for\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'redoValidFor', options: redoDayOpts }\"></ng-container>\r\n Day from Redo creation\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Auto create task -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Auto Create Task for Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"autoCreateTaskOn\" (click)=\"autoCreateTaskOn = !autoCreateTaskOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, a task is automatically created for every flagged question in the audit</div>\r\n\r\n <!-- Who gets the task and how long it stays open (as the Checklist Configure page) -->\r\n <div class=\"cf-autotask\" *ngIf=\"autoCreateTaskOn\">\r\n <div class=\"cf-autotask-title\">Task Assignee</div>\r\n <div class=\"cf-hint cf-hint--tight\">Choose who the flagged task is assigned to</div>\r\n <div class=\"cf-autotask-choices\">\r\n <button type=\"button\" class=\"cf-choice\" [class.is-on]=\"taskAssignee === 'submitter'\" (click)=\"taskAssignee = 'submitter'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"taskAssignee === 'submitter'\"><span></span></span>\r\n <span class=\"cf-choice-text\">\r\n <span class=\"cf-choice-title\">Audit Submitter</span>\r\n <span class=\"cf-choice-sub\">Task is assigned to the user who filled the audit</span>\r\n </span>\r\n </button>\r\n <button type=\"button\" class=\"cf-choice\" [class.is-on]=\"taskAssignee === 'store'\" (click)=\"taskAssignee = 'store'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"taskAssignee === 'store'\"><span></span></span>\r\n <span class=\"cf-choice-text\">\r\n <span class=\"cf-choice-title\">Store User</span>\r\n <span class=\"cf-choice-sub\">Task is assigned to the user mapped to the flagged store</span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"cf-autotask-title\">Task Validity</div>\r\n <div class=\"cf-autotask-validity\">\r\n <span>Task valid for</span>\r\n <lib-audit-v2-select class=\"cf-validity-select\" [(ngModel)]=\"taskValidity\" [options]=\"taskValidityOptions\"\r\n [searchable]=\"false\" ariaLabel=\"Task validity in days\"></lib-audit-v2-select>\r\n <span>days from task creation</span>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Audit Configuration ===== -->\r\n <div class=\"cf-divider-head\">\r\n <span class=\"cf-block-title\">Audit Configuration</span>\r\n <span class=\"cf-rule\"></span>\r\n </div>\r\n\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Submission &amp; Visibility</div>\r\n\r\n <!-- cf-box--open: the dispute-window and response-delay menus must not be clipped by the box -->\r\n <div class=\"cf-box cf-box--open\">\r\n <div class=\"cf-box-row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"showResponseInApp\"\r\n (click)=\"showResponseInApp = !showResponseInApp\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Show Response in Mobile App</div>\r\n <div class=\"cf-hint\">By enabling this option, store users can view the audit response in the Mobile App.</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"cf-box-sub\" *ngIf=\"showResponseInApp\">\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label-sm\">Response Visibility</div>\r\n <div class=\"cf-hint\">Choose when the response becomes visible to store users</div>\r\n </div>\r\n\r\n <div class=\"cf-options\">\r\n <div class=\"cf-option\" [class.is-on]=\"responseVisibility === 'pre'\" (click)=\"responseVisibility = 'pre'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"responseVisibility === 'pre'\"><span></span></span>\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm\">Pre-approval</div>\r\n <div class=\"cf-hint\">The audit response will be visible to store users before it is approved.</div>\r\n <div class=\"cf-inline cf-inline--top\">\r\n Show response\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'respDelay', options: respDelayOpts }\"></ng-container>\r\n after submission\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"cf-option\" [class.is-on]=\"responseVisibility === 'post'\" (click)=\"responseVisibility = 'post'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"responseVisibility === 'post'\"><span></span></span>\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm\" [class.cf-muted]=\"responseVisibility !== 'post'\">Post-approval</div>\r\n <div class=\"cf-hint\">Once the response is approved, it will automatically be displayed in the Mobile App. Store users cannot raise a dispute.</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"cf-box-sep\">\r\n <ng-container *ngIf=\"responseVisibility === 'pre'\">\r\n <div class=\"cf-box-row cf-box-row--flush\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"disputeOn\" (click)=\"disputeOn = !disputeOn\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label-sm\">Dispute Configuration</div>\r\n <div class=\"cf-hint cf-hint--wrap\">When enabled, the store team can raise a dispute against the auditor's submission once the response becomes visible to them.</div>\r\n </div>\r\n </div>\r\n <div class=\"cf-box cf-box--nested\" *ngIf=\"disputeOn\">\r\n <div class=\"cf-inline\">\r\n Dispute window\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'disputeWindow', options: dispWindowOpts }\"></ng-container>\r\n from when the response becomes visible\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Disputes raised inside this window go to the approver. Approved disputes revise the answer and the compliance score.\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"!hasApprovers\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n No approver is set, so no one can review disputes. Turn on Approver and add an approver.\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"responseVisibility === 'post'\">\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm cf-muted\">Dispute Configuration</div>\r\n <div class=\"cf-info cf-info--wrap\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Disputes are not available when responses are shown post-approval.\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Pre-submission access -->\r\n <div class=\"cf-box cf-box--pad\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Pre-Submission Access</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"preSubmissionAccessOn\" (click)=\"preSubmissionAccessOn = !preSubmissionAccessOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--wrap\">Users added here can view Open and In Progress audits until submission. The Schedule Info tab is also visible only to these users.</div>\r\n <ng-container *ngIf=\"preSubmissionAccessOn\">\r\n <div class=\"cf-row cf-row--top\">\r\n <span class=\"cf-field\">Visible to</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'preSubmissionUsers', large: false }\"></ng-container>\r\n </div>\r\n <div class=\"cf-error cf-error--indent\" *ngIf=\"preSubmissionEmpty\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n Add at least one user\r\n </div>\r\n </ng-container>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Scoring ===== -->\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Scoring</div>\r\n <div class=\"cf-box cf-box--pad\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Pass/Fail Score Setup</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"passFailOn\" (click)=\"passFailOn = !passFailOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--wrap\">Set the compliance score an audit must reach to be marked {{ passLabel }}. Anything below it is marked {{ failLabel }}.</div>\r\n <div class=\"cf-row cf-row--wrap cf-row--top\" *ngIf=\"passFailOn\">\r\n <span class=\"cf-field\">Minimum score to {{ passLabel }}</span>\r\n <label class=\"cf-num\">\r\n <input type=\"number\" min=\"1\" max=\"100\" [(ngModel)]=\"passThreshold\">\r\n <span>%</span>\r\n </label>\r\n <span class=\"cf-pill cf-pill--pass\">{{ passLabel }} \u2265 {{ passThreshold }}%</span>\r\n <span class=\"cf-pill cf-pill--fail\">{{ failLabel }} &lt; {{ passThreshold }}%</span>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Approver Controls ===== -->\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Approver Controls</div>\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Edit Submitted Audit</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"editSubmittedOn\" (click)=\"toggleEditSubmitted()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">Allow Approvers to edit submitted Audit</div>\r\n <ng-container *ngIf=\"editSubmittedOn\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'editUsers', large: true }\"></ng-container>\r\n <div class=\"cf-error\" *ngIf=\"editSubmittedError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ editSubmittedError }}\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div class=\"cf-grid2\">\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-label\">Redo Extension</div>\r\n <div class=\"cf-inline\">\r\n Extend redo up to\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'redoExtension', options: redoExtensionOpts }\"></ng-container>\r\n Days till approval\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== User Verification ===== -->\r\n <section class=\"cf-card\">\r\n <div class=\"cf-block-title\">User Verification Configuration</div>\r\n <div class=\"cf-box cf-box--row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"requirePhoto\" (click)=\"requirePhoto = !requirePhoto\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Require Photo Capture</div>\r\n <div class=\"cf-hint\">By enabling, users must capture their photo to complete submission</div>\r\n </div>\r\n </div>\r\n <div class=\"cf-box cf-box--row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"requireAcknowledgment\" (click)=\"requireAcknowledgment = !requireAcknowledgment\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Require User Acknowledgment</div>\r\n <div class=\"cf-hint\">By enabling, users must type their name as acknowledgment to complete submission</div>\r\n </div>\r\n </div>\r\n </section>\r\n </ng-container>\r\n\r\n </div>\r\n </div>\r\n\r\n <!-- Daily Report > Custom: bulk upload users (as the Checklist Configure page's popup) -->\r\n <ng-container *ngIf=\"dailyBulkOpen\">\r\n <div class=\"cf-dlg-backdrop\" (click)=\"closeDailyBulk()\"></div>\r\n <div class=\"cf-dlg\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"cf-dlg-title\">\r\n <span class=\"cf-dlg-icon\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.67\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M17.5 12.5V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H4.16667C3.72464 17.5 3.30072 17.3244 2.98816 17.0118C2.67559 16.6993 2.5 16.2754 2.5 15.8333V12.5M14.1667 6.66667L10 2.5M10 2.5L5.83333 6.66667M10 2.5V12.5\"></path></svg>\r\n </span>\r\n <div class=\"cf-dlg-title\" id=\"cf-dlg-title\">Bulk Upload</div>\r\n <div class=\"cf-dlg-steps\">\r\n <div>Step 1 - <a href=\"#\" (click)=\"$event.preventDefault(); downloadDailyTemplate()\">Download the template here</a></div>\r\n <div>Step 2 - Add the Email of existing users to the template</div>\r\n <div>Step 3 - Upload it below for processing</div>\r\n </div>\r\n <div class=\"cf-dlg-note\">\r\n **Note : Only the Email column is considered - the Username is taken from the existing user list.\r\n Only existing users of this client are accepted. On upload, all the existing data will be replaced.\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"dailyBulkErrors.length\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n <div class=\"cf-dlg-errors\">\r\n <div>The file was not uploaded. Fix {{ dailyBulkErrors.length === 1 ? 'this row' : 'these rows' }} and upload again:</div>\r\n <div *ngFor=\"let e of dailyBulkErrors.slice(0, 5)\">{{ e }}</div>\r\n <div *ngIf=\"dailyBulkErrors.length > 5\">+{{ dailyBulkErrors.length - 5 }} more</div>\r\n </div>\r\n </div>\r\n <div class=\"cf-dlg-foot\">\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" (click)=\"closeDailyBulk()\">Cancel</button>\r\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--sm\" (click)=\"dailyBulkFile.click()\">Upload</button>\r\n <input #dailyBulkFile type=\"file\" accept=\".xlsx\" hidden (change)=\"onDailyBulkFile($event)\">\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}.cf-backbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.cf-back{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.cf-crumb{font-size:13px;line-height:20px;color:#667085}.cf-crumb a{font-weight:600;color:#00a3ff}.cf-header{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:16px 20px;display:flex;align-items:center;gap:12px}.cf-header-text{display:flex;flex-direction:column;gap:4px;min-width:0}.cf-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.cf-sk-title{margin:3px 0}.cf-desc{border:none;outline:none;padding:0;background:transparent;font-family:inherit;font-size:13px;line-height:18px;color:#344054;min-width:320px}.cf-desc::placeholder{color:#98a2b3}.cf-publish{padding:0 20px;box-shadow:0 1px 2px #1018280d}.cf-draft{padding:0 18px;box-shadow:inset 0 0 0 1px #d0d5dd,0 1px 2px #1018280d}.cf-body{display:flex;gap:16px;align-items:flex-start}.cf-left{width:300px;flex-shrink:0;background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:16px;display:flex;flex-direction:column;gap:10px;position:sticky;top:calc(var(--bs-app-header-height, 0px) + 16px);max-height:calc(100vh - var(--bs-app-header-height, 0px) - 32px);overflow-y:auto;scrollbar-width:thin}.cf-left-title{font-size:14px;line-height:20px;font-weight:600;color:#101828}.cf-section{display:flex;align-items:center;gap:8px;padding:2px 0;font-size:13px;font-weight:500;color:#344054;cursor:pointer;white-space:nowrap}.cf-section.is-open{color:#1d2939}.cf-rule{flex:1;border-top:1px solid #EAECF0}.cf-chev{display:flex;color:#98a2b3}.cf-chev svg{transition:transform .15s cubic-bezier(.4,0,.2,1)}.cf-chev .rotate{transform:rotate(-90deg)}.cf-items{display:flex;flex-direction:column;gap:8px;padding-left:12px;font-size:13px;color:#475467}.cf-schedule-title{font-size:14px;font-weight:600;color:#101828;margin-top:6px}.cf-schedule{display:flex;flex-direction:column;gap:6px;font-size:13px;color:#475467}.cf-schedule>div{display:flex;align-items:center;gap:6px}.cf-right{flex:1;min-width:0;display:flex;flex-direction:column;gap:16px}.cf-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px;display:flex;flex-direction:column;gap:14px}.cf-card--lg{border-radius:8px}.cf-block-head{display:flex;align-items:center;gap:12px}.cf-block-title{font-size:15px;font-weight:600;color:#101828}.cf-divider-head{display:flex;align-items:center;gap:10px;margin-top:4px}.cf-label{font-size:14px;font-weight:600;color:#101828}.cf-label-sm{font-size:13px;font-weight:600;color:#101828}.cf-muted{color:#667085}.cf-hint{font-size:12px;line-height:18px;color:#667085}.cf-hint--tight{margin-top:-8px}.cf-hint--wrap{max-width:640px;text-wrap:pretty}.cf-field{font-size:13px;font-weight:500;color:#344054;min-width:150px;flex-shrink:0}.cf-row{display:flex;align-items:center;gap:12px}.cf-row--top{margin-top:6px}.cf-row--wrap{flex-wrap:wrap}.cf-stack{display:flex;flex-direction:column;gap:8px}.cf-stack--tight,.cf-stack--sm{gap:4px}.cf-stack--xs{gap:2px}.cf-grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.cf-toggle-row{display:flex;align-items:center;gap:10px}.cf-switch{width:36px;height:20px;padding:2px;border:none;border-radius:9999px;background:#eaecf0;display:flex;align-items:center;justify-content:flex-start;flex-shrink:0;cursor:pointer;transition:background .15s cubic-bezier(.4,0,.2,1)}.cf-switch>span{width:16px;height:16px;border-radius:9999px;background:#fff;box-shadow:0 1px 2px #1018280d}.cf-switch.is-on{background:#00a3ff;justify-content:flex-end}.cf-switch--top{margin-top:2px}.cf-chipbox{flex:1;min-width:0;display:flex;flex-wrap:wrap;gap:6px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;padding:8px 10px}.cf-chipbox--lg{gap:8px;padding:10px 12px}.cf-chip{display:flex;align-items:center;gap:6px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0;border-radius:9999px;padding:3px 8px;font-size:12px;color:#344054;white-space:nowrap;flex-shrink:0;max-width:100%}.cf-chip--lg{gap:8px;background:#fff;padding:5px 11px;font-size:13px;color:#1d2939}.cf-chip-ini{color:#00a3ff;font-weight:600;font-size:11px}.cf-chip-tag{display:inline-flex;align-items:center;justify-content:center;padding:1px 5px;border-radius:6px;background:#eaf8ff;color:#00a3ff;font-weight:700;font-size:11px;letter-spacing:.02em}.cf-chip-x{display:flex;cursor:pointer;color:#98a2b3}.cf-chip-x:hover{color:#344054}.cf-chip-input{flex:1;min-width:100px;border:none;outline:none;background:transparent;font-family:inherit;font-size:12px;color:#101828}.cf-chip-input::placeholder{color:#98a2b3}.cf-chip-input--lg{min-width:120px;font-size:13px}.cf-inner{border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;padding:14px 16px;display:flex;flex-direction:column;gap:8px}.cf-inline{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:13px;color:#344054}.cf-inline--top{margin-top:2px}.cf-mini{height:32px;padding:0 28px 0 10px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#101828;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 8px center;outline:none}.cf-info{display:flex;align-items:center;gap:6px;font-size:12px;line-height:18px;color:#667085}.cf-info svg{flex-shrink:0}.cf-info--wrap{align-items:flex-start;max-width:560px;text-wrap:pretty}.cf-info--wrap svg{margin-top:3px}.cf-checks{display:flex;align-items:center;gap:16px;flex-wrap:wrap;font-size:13px;color:#344054}.cf-checks-label{font-weight:500}.cf-check{display:flex;align-items:center;gap:6px;margin:0;font-size:13px;color:#344054;cursor:pointer;-webkit-user-select:none;user-select:none}.cf-check-box{width:16px;height:16px;border-radius:4px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}.cf-check-box.is-on{background:#00a3ff;box-shadow:none}.cf-box{border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;overflow:hidden;display:flex;flex-direction:column}.cf-box--pad{padding:14px 16px;gap:6px;overflow:visible}.cf-box--row{padding:14px 16px;flex-direction:row;align-items:flex-start;gap:12px}.cf-box--nested{background:#fff;padding:12px 14px;gap:8px;margin-left:46px;overflow:visible}.cf-box--open{overflow:visible}.cf-box--open>.cf-box-sub:last-child{border-radius:0 0 8px 8px}.cf-box-row{padding:14px 16px;display:flex;align-items:flex-start;gap:12px}.cf-box-row--flush{padding:0;gap:10px}.cf-box-sub{border-top:1px solid #EAECF0;background:#f9fafb;padding:16px 16px 18px 64px;display:flex;flex-direction:column;gap:12px}.cf-options{display:flex;flex-direction:column;gap:10px}.cf-option{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;cursor:pointer}.cf-option.is-on{box-shadow:inset 0 0 0 1.5px #00a3ff}.cf-box-sep{display:flex;flex-direction:column;gap:12px;padding-top:14px;border-top:1px solid #EAECF0}.cf-num{display:flex;align-items:center;gap:8px;height:36px;padding:0 6px 0 12px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;margin:0}.cf-num input{width:52px;border:none;outline:none;background:transparent;font-family:inherit;font-size:14px;font-weight:600;color:#101828}.cf-num span{font-size:13px;color:#667085;padding-right:6px}.cf-pill{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;border-radius:9999px;padding:4px 12px}.cf-pill--pass{background:#ecfdf3;color:#027a48}.cf-pill--fail{background:#fef3f2;color:#d92d20}.cf-error{display:flex;gap:6px;font-size:12px;font-weight:500;color:#d92d20;align-items:flex-start;line-height:18px;max-width:640px}.cf-error svg{flex-shrink:0;margin-top:3px}.cf-error--indent{margin-left:162px}.cf-check.is-blocked{color:#98a2b3;cursor:not-allowed}.cf-select{position:relative;display:inline-block;vertical-align:middle}.cf-select-btn{display:inline-flex;align-items:center;gap:8px;height:32px;padding:0 10px 0 12px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#101828;cursor:pointer;white-space:nowrap}.cf-select-btn svg{color:#667085;transition:transform .15s ease}.is-open .cf-select-btn{box-shadow:0 0 0 2px #99dbff,inset 0 0 0 1px #d0d5dd}.is-open .cf-select-btn svg{transform:rotate(180deg)}.cf-select-menu{position:absolute;top:calc(100% + 4px);left:0;z-index:30;min-width:100%;padding:4px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 8px 24px #1018281f}.cf-select-item{padding:8px 12px;border-radius:6px;font-size:13px;color:#344054;white-space:nowrap;cursor:pointer}.cf-select-item:hover{background:#f9fafb}.cf-select-item.is-on{background:#eaf8ff;color:#009bf3;font-weight:600}.cf-chipbox{position:relative}.cf-chipbox.is-open{box-shadow:0 0 0 2px #99dbff,inset 0 0 0 1px #d0d5dd}.cf-suggest{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:30;max-height:260px;overflow-y:auto;padding:4px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 8px 24px #1018281f}.cf-suggest-item{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:6px;cursor:pointer}.cf-suggest-item:hover{background:#f9fafb}.cf-suggest-name{font-size:13px;color:#101828}.cf-suggest-mail{font-size:12px;color:#667085;margin-left:auto}.cf-suggest-empty{padding:8px 10px;font-size:12px;color:#667085}.cf-error--page{margin:0 0 12px}.cf-autotask{margin-top:12px;padding:14px 16px;border-radius:10px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0;display:flex;flex-direction:column;gap:8px}.cf-autotask-title{font-size:14px;font-weight:600;color:#1d2939}.cf-autotask-title:not(:first-child){margin-top:6px}.cf-autotask-choices{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}@media (max-width: 720px){.cf-autotask-choices{grid-template-columns:1fr}}.cf-choice{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;text-align:left;cursor:pointer}.cf-choice.is-on{background:#f5faff;box-shadow:inset 0 0 0 1px #66c8ff}.cf-radio{width:18px;height:18px;flex-shrink:0;margin-top:1px;border-radius:9999px;box-shadow:inset 0 0 0 1px #d0d5dd;display:flex;align-items:center;justify-content:center}.cf-radio span{width:8px;height:8px;border-radius:9999px;background:transparent}.cf-radio.is-on{box-shadow:inset 0 0 0 1px #1570ef}.cf-radio.is-on span{background:#1570ef}.cf-choice-text{display:flex;flex-direction:column;gap:2px;min-width:0}.cf-choice-title{font-size:14px;font-weight:600;color:#101828}.cf-choice-sub{font-size:12px;color:#667085}.cf-autotask-validity{display:flex;align-items:center;flex-wrap:wrap;gap:10px;font-size:13px;color:#344054}.cf-validity-select{width:96px}.cf-reminder{display:inline-flex;align-items:center;gap:6px}.cf-reminder-select{width:120px}.cf-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;cursor:pointer}.cf-icon-btn:hover{background:#f9fafb}.cf-bulkbar{display:flex;justify-content:flex-end;margin-bottom:-4px}.cf-bulkbar .av2-btn{display:inline-flex;align-items:center;gap:6px}.cf-dlg-backdrop{position:fixed;inset:0;background:#34405499;z-index:1050}.cf-dlg{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:520px;max-width:calc(100vw - 32px);max-height:90vh;overflow-y:auto;padding:24px;border-radius:8px;background:#fff;box-shadow:0 20px 40px #10182833;z-index:1051;display:flex;flex-direction:column;gap:12px}.cf-dlg-icon{width:40px;height:40px;border-radius:9999px;background:#eaf8ff;color:#00a3ff;display:flex;align-items:center;justify-content:center}.cf-dlg-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.cf-dlg-steps{display:flex;flex-direction:column;gap:8px;font-size:14px;line-height:20px;color:#344054}.cf-dlg-steps a{color:#00a3ff;text-decoration:underline;cursor:pointer}.cf-dlg-note{font-size:13px;line-height:20px;font-weight:600;color:#344054}.cf-dlg-errors{display:flex;flex-direction:column;gap:2px;min-width:0;overflow-wrap:anywhere}.cf-dlg-foot{display:flex;justify-content:flex-end;gap:12px;margin-top:4px}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AuditV2ShimmerComponent, selector: "lib-audit-v2-shimmer", inputs: ["rows"] }, { kind: "component", type: AuditV2SelectComponent, selector: "lib-audit-v2-select", inputs: ["options", "placeholder", "searchable", "ariaLabel", "disabled", "value"], outputs: ["changed"] }] });
10208
10390
  }
10209
10391
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuditV2ConfigureComponent, decorators: [{
10210
10392
  type: Component,
10211
- args: [{ selector: 'lib-audit-v2-configure', template: "<div class=\"av2-page audit-configure\">\r\n\r\n <!-- Back + breadcrumb (as the schedule editor's back bar) -->\r\n <div class=\"cf-backbar\">\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm cf-back\" (click)=\"back()\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\r\n {{ backLabel }}\r\n </button>\r\n <div class=\"cf-crumb\">\r\n <a href=\"#\" (click)=\"back($event)\">Manage Audit</a> \u203A Configure\r\n </div>\r\n </div>\r\n\r\n <!-- Title + actions -->\r\n <div class=\"cf-header\">\r\n <div class=\"cf-header-text\">\r\n <span class=\"av2-sk av2-sk--title cf-sk-title\" *ngIf=\"loading\"></span>\r\n <div class=\"cf-title\" *ngIf=\"!loading\">{{ auditName || 'Audit' }}</div>\r\n <input type=\"text\" class=\"cf-desc\" placeholder=\"Enter Audit Description\" [(ngModel)]=\"description\">\r\n </div>\r\n <div class=\"av2-grow\"></div>\r\n <button type=\"button\" class=\"av2-btn av2-btn--primary cf-publish\" [disabled]=\"!canSave\" [title]=\"saveBlockedReason || publishBlockedReason\" (click)=\"publish()\">\r\n {{ saving ? 'Saving\u2026' : (published ? 'Save & Publish' : 'Publish') }}\r\n </button>\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost cf-draft\" [disabled]=\"!canSave\" [title]=\"saveBlockedReason\" (click)=\"saveDraft()\">Save as Draft</button>\r\n </div>\r\n\r\n <div class=\"cf-error cf-error--page\" *ngIf=\"loadError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ loadError }}\r\n </div>\r\n\r\n <!-- Chip picker: chips + input + suggestion list (one template, used for every user list) -->\r\n <ng-template #chipPicker let-list=\"list\" let-large=\"large\">\r\n <div class=\"cf-chipbox\" [class.cf-chipbox--lg]=\"large\" [class.is-open]=\"openChips === list\" (click)=\"focusChips(list, $event)\">\r\n <span class=\"cf-chip\" [class.cf-chip--lg]=\"large\" *ngFor=\"let u of chipsOf(list); let i = index\" [title]=\"u.e\">\r\n <span [class]=\"large ? 'cf-chip-tag' : 'cf-chip-ini'\">{{ u.i }}</span>{{ u.n }}\r\n <a class=\"cf-chip-x\" (click)=\"removeChip(list, i); $event.stopPropagation()\">\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\r\n </a>\r\n </span>\r\n <input type=\"text\" class=\"cf-chip-input\" [class.cf-chip-input--lg]=\"large\" placeholder=\"Add user...\"\r\n [ngModel]=\"draftOf(list)\" (ngModelChange)=\"setDraft(list, $event)\" (focus)=\"focusChips(list, $event)\" (keyup.enter)=\"addChip(list)\">\r\n <div class=\"cf-suggest\" *ngIf=\"openChips === list\">\r\n <div class=\"cf-suggest-item\" *ngFor=\"let u of suggestions(list)\" (click)=\"addSuggestion(list, u, $event)\">\r\n <span class=\"cf-chip-ini\">{{ u.i }}</span>\r\n <span class=\"cf-suggest-name\">{{ u.n }}</span>\r\n <span class=\"cf-suggest-mail\">{{ u.e }}</span>\r\n </div>\r\n <div class=\"cf-suggest-empty\" *ngIf=\"!suggestions(list).length\">\r\n {{ users.length ? 'No matching user' : 'No users for this client' }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Dropdown: styled like the prototype instead of the browser's native select -->\r\n <ng-template #dropdown let-key=\"key\" let-options=\"options\">\r\n <span class=\"cf-select\" [class.is-open]=\"openSelect === key\">\r\n <button type=\"button\" class=\"cf-select-btn\" (click)=\"toggleSelect(key, $event)\">\r\n {{ selectLabel(key, options) }}\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\r\n </button>\r\n <div class=\"cf-select-menu\" *ngIf=\"openSelect === key\">\r\n <div class=\"cf-select-item\" *ngFor=\"let o of options\" [class.is-on]=\"isPicked(key, o)\"\r\n (click)=\"pick(key, o, $event)\">{{ o.label }}</div>\r\n </div>\r\n </span>\r\n </ng-template>\r\n\r\n <div class=\"cf-body\" *ngIf=\"!loadError\">\r\n <!-- Section tree -->\r\n <aside class=\"cf-left\">\r\n <lib-audit-v2-shimmer *ngIf=\"loading\" [rows]=\"3\"></lib-audit-v2-shimmer>\r\n\r\n <ng-container *ngIf=\"!loading\">\r\n <div class=\"cf-left-title\">{{ auditName || 'Audit' }}</div>\r\n\r\n <div class=\"cf-hint\" *ngIf=\"!sections.length\">No questions yet</div>\r\n <ng-container *ngFor=\"let s of sections\">\r\n <div class=\"cf-section\" [class.is-open]=\"s.open\" (click)=\"toggleSection(s)\">\r\n {{ s.label }}\r\n <span class=\"cf-rule\"></span>\r\n <span class=\"cf-chev\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" [class.rotate]=\"!s.open\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"cf-items\" *ngIf=\"s.open && s.items.length\">\r\n <div *ngFor=\"let it of s.items\">{{ it }}</div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- No Schedule block (QA 10 Oct): audits have no one-time / repeat schedule here; visits come from Schedules. -->\r\n </ng-container>\r\n </aside>\r\n\r\n <!-- Configuration -->\r\n <div class=\"cf-right\">\r\n\r\n <section class=\"cf-card\" *ngIf=\"loading\">\r\n <lib-audit-v2-shimmer [rows]=\"4\"></lib-audit-v2-shimmer>\r\n </section>\r\n\r\n <ng-container *ngIf=\"!loading\">\r\n\r\n <!-- ===== Advance Configuration ===== -->\r\n <section class=\"cf-card\">\r\n <div class=\"cf-block-head\">\r\n <span class=\"cf-block-title\">Advance Configuration</span>\r\n <span class=\"cf-rule\"></span>\r\n <span class=\"cf-chev\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\r\n </span>\r\n </div>\r\n\r\n <!-- Audit Owner -->\r\n <div>\r\n <div class=\"cf-label\">Audit Owner</div>\r\n <div class=\"cf-hint\">Owners get access to manage the audit</div>\r\n </div>\r\n <div class=\"cf-row\">\r\n <span class=\"cf-field\">Can be managed by</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'owners', large: false }\"></ng-container>\r\n </div>\r\n\r\n <!-- Approver -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Approver</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"approverOn\" (click)=\"toggleApprover()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, the users will be able to approve the audit</div>\r\n <div class=\"cf-row\" *ngIf=\"approverOn\">\r\n <span class=\"cf-field\">To be approved by</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'approvers', large: false }\"></ng-container>\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"approverError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ approverError }}\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\" *ngIf=\"!approverOn && approvers.length\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Approver is off, so the {{ approvers.length }} approver{{ approvers.length === 1 ? '' : 's' }} added will be removed when you save. Turn Approver back on to keep {{ approvers.length === 1 ? 'it' : 'them' }}.\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\" *ngIf=\"!approverOn && !approvers.length\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Approver is off, so submitted audits are not sent for approval. Turn it on to add approvers or to send flags and reports to them.\r\n </div>\r\n\r\n <!-- Reminder -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Reminder</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"reminderOn\" (click)=\"toggleReminder()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, the users will be reminded in the selected interval</div>\r\n <div class=\"cf-inner\" *ngIf=\"reminderOn\">\r\n <div class=\"cf-inline\">\r\n Notify user before\r\n <span class=\"cf-reminder\" *ngFor=\"let m of reminders; let i = index\">\r\n <lib-audit-v2-select class=\"cf-reminder-select\" [value]=\"m\" [options]=\"reminderOpts[i] || []\" [searchable]=\"false\"\r\n [ariaLabel]=\"'Reminder ' + (i + 1) + ' in minutes'\" (changed)=\"setReminder(i, $event.target.value)\"></lib-audit-v2-select>\r\n <a class=\"cf-chip-x\" *ngIf=\"reminders.length > 1\" title=\"Remove reminder\" (click)=\"removeReminder(i)\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\r\n </a>\r\n </span>\r\n <button type=\"button\" class=\"cf-icon-btn\" *ngIf=\"reminders.length < maxReminders\" title=\"Add reminder\" (click)=\"addReminder()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line></svg>\r\n </button>\r\n </div>\r\n <div class=\"cf-info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Send alerts {{ reminderSummary }} mins before the audit end time\r\n </div>\r\n </div>\r\n\r\n <!-- Notify Flags -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Notify Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"notifyFlagsOn\" (click)=\"toggleNotifyFlags()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, all flags will be sent as an email</div>\r\n <ng-container *ngIf=\"notifyFlagsOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !notifySendApprover\" (click)=\"toggleSendApprover('notifySendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"notifySendApprover\">\r\n <svg *ngIf=\"notifySendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"notifySendCustom = !notifySendCustom\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"notifySendCustom\">\r\n <svg *ngIf=\"notifySendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"notifySendCustom\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'notifyUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <div class=\"cf-error\" *ngIf=\"notifyFlagsError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ notifyFlagsError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Notify on Recurring Flags -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Notify on Recurring Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"recurringFlagsOn\" (click)=\"toggleRecurringFlags()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">When enabled, emails are sent for recurring flags based on the configured threshold</div>\r\n\r\n <div class=\"cf-inner\" *ngIf=\"recurringFlagsOn\">\r\n <div class=\"cf-inline\">\r\n Send Email if the same question is flagged\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'recurringThreshold', options: thresholdOpts }\"></ng-container>\r\n times by the same store\r\n </div>\r\n <div class=\"cf-info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Once the threshold is reached and an email is sent, the flag count resets to zero\r\n </div>\r\n </div>\r\n <ng-container *ngIf=\"recurringFlagsOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !recurringSendApprover\" (click)=\"toggleSendApprover('recurringSendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSendApprover\">\r\n <svg *ngIf=\"recurringSendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"toggleRecurringCustom()\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSendCustom\">\r\n <svg *ngIf=\"recurringSendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n <label class=\"cf-check\" (click)=\"recurringSameAsNotify = !recurringSameAsNotify\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSameAsNotify\">\r\n <svg *ngIf=\"recurringSameAsNotify\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Use same users from Notify Flags\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"recurringSendCustom\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'recurringUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <div class=\"cf-info\" *ngIf=\"recurringSameAsNotify\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n {{ notifyRecipientsLabel }}\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"recurringFlagsError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ recurringFlagsError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Daily report -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Enable - Daily Report</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"dailyReportOn\" (click)=\"toggleDailyReport()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By Enabling, compliance score will be sent as an email to the above users</div>\r\n <ng-container *ngIf=\"dailyReportOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !dailySendApprover\" (click)=\"toggleSendApprover('dailySendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"dailySendApprover\">\r\n <svg *ngIf=\"dailySendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"dailySendCustom = !dailySendCustom\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"dailySendCustom\">\r\n <svg *ngIf=\"dailySendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"dailySendCustom\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'dailyUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <label class=\"cf-check\" (click)=\"sharePostApproval = !sharePostApproval\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"sharePostApproval\">\r\n <svg *ngIf=\"sharePostApproval\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Share Report Post Approval\r\n </label>\r\n <div class=\"cf-error\" *ngIf=\"dailyReportError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ dailyReportError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Export submission: Tango users only, as the v1 Configure (its stored value is kept for everyone else). -->\r\n <div class=\"cf-grid2\" *ngIf=\"access.isTango\">\r\n <div class=\"cf-stack cf-stack--tight\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Export Submission</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"exportSubmissionOn\" (click)=\"exportSubmissionOn = !exportSubmissionOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint\">Enable this to allow audit submitters to download their submission as a PDF file</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Redo validity -->\r\n <div class=\"cf-grid2\">\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-label\">Redo Validity</div>\r\n <div class=\"cf-inline\">\r\n Redo valid for\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'redoValidFor', options: redoDayOpts }\"></ng-container>\r\n Day from Redo creation\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Auto create task -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Auto Create Task for Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"autoCreateTaskOn\" (click)=\"autoCreateTaskOn = !autoCreateTaskOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, a task is automatically created for every flagged question in the audit</div>\r\n\r\n <!-- Who gets the task and how long it stays open (as the Checklist Configure page) -->\r\n <div class=\"cf-autotask\" *ngIf=\"autoCreateTaskOn\">\r\n <div class=\"cf-autotask-title\">Task Assignee</div>\r\n <div class=\"cf-hint cf-hint--tight\">Choose who the flagged task is assigned to</div>\r\n <div class=\"cf-autotask-choices\">\r\n <button type=\"button\" class=\"cf-choice\" [class.is-on]=\"taskAssignee === 'submitter'\" (click)=\"taskAssignee = 'submitter'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"taskAssignee === 'submitter'\"><span></span></span>\r\n <span class=\"cf-choice-text\">\r\n <span class=\"cf-choice-title\">Audit Submitter</span>\r\n <span class=\"cf-choice-sub\">Task is assigned to the user who filled the audit</span>\r\n </span>\r\n </button>\r\n <button type=\"button\" class=\"cf-choice\" [class.is-on]=\"taskAssignee === 'store'\" (click)=\"taskAssignee = 'store'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"taskAssignee === 'store'\"><span></span></span>\r\n <span class=\"cf-choice-text\">\r\n <span class=\"cf-choice-title\">Store User</span>\r\n <span class=\"cf-choice-sub\">Task is assigned to the user mapped to the flagged store</span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"cf-autotask-title\">Task Validity</div>\r\n <div class=\"cf-autotask-validity\">\r\n <span>Task valid for</span>\r\n <lib-audit-v2-select class=\"cf-validity-select\" [(ngModel)]=\"taskValidity\" [options]=\"taskValidityOptions\"\r\n [searchable]=\"false\" ariaLabel=\"Task validity in days\"></lib-audit-v2-select>\r\n <span>days from task creation</span>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Audit Configuration ===== -->\r\n <div class=\"cf-divider-head\">\r\n <span class=\"cf-block-title\">Audit Configuration</span>\r\n <span class=\"cf-rule\"></span>\r\n </div>\r\n\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Submission &amp; Visibility</div>\r\n\r\n <!-- cf-box--open: the dispute-window and response-delay menus must not be clipped by the box -->\r\n <div class=\"cf-box cf-box--open\">\r\n <div class=\"cf-box-row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"showResponseInApp\"\r\n (click)=\"showResponseInApp = !showResponseInApp\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Show Response in Mobile App</div>\r\n <div class=\"cf-hint\">By enabling this option, store users can view the audit response in the Mobile App.</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"cf-box-sub\" *ngIf=\"showResponseInApp\">\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label-sm\">Response Visibility</div>\r\n <div class=\"cf-hint\">Choose when the response becomes visible to store users</div>\r\n </div>\r\n\r\n <div class=\"cf-options\">\r\n <div class=\"cf-option\" [class.is-on]=\"responseVisibility === 'pre'\" (click)=\"responseVisibility = 'pre'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"responseVisibility === 'pre'\"><span></span></span>\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm\">Pre-approval</div>\r\n <div class=\"cf-hint\">The audit response will be visible to store users before it is approved.</div>\r\n <div class=\"cf-inline cf-inline--top\">\r\n Show response\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'respDelay', options: respDelayOpts }\"></ng-container>\r\n after submission\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"cf-option\" [class.is-on]=\"responseVisibility === 'post'\" (click)=\"responseVisibility = 'post'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"responseVisibility === 'post'\"><span></span></span>\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm\" [class.cf-muted]=\"responseVisibility !== 'post'\">Post-approval</div>\r\n <div class=\"cf-hint\">Once the response is approved, it will automatically be displayed in the Mobile App. Store users cannot raise a dispute.</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"cf-box-sep\">\r\n <ng-container *ngIf=\"responseVisibility === 'pre'\">\r\n <div class=\"cf-box-row cf-box-row--flush\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"disputeOn\" (click)=\"disputeOn = !disputeOn\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label-sm\">Dispute Configuration</div>\r\n <div class=\"cf-hint cf-hint--wrap\">When enabled, the store team can raise a dispute against the auditor's submission once the response becomes visible to them.</div>\r\n </div>\r\n </div>\r\n <div class=\"cf-box cf-box--nested\" *ngIf=\"disputeOn\">\r\n <div class=\"cf-inline\">\r\n Dispute window\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'disputeWindow', options: dispWindowOpts }\"></ng-container>\r\n from when the response becomes visible\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Disputes raised inside this window go to the approver. Approved disputes revise the answer and the compliance score.\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"!hasApprovers\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n No approver is set, so no one can review disputes. Turn on Approver and add an approver.\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"responseVisibility === 'post'\">\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm cf-muted\">Dispute Configuration</div>\r\n <div class=\"cf-info cf-info--wrap\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Disputes are not available when responses are shown post-approval.\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Pre-submission access -->\r\n <div class=\"cf-box cf-box--pad\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Pre-Submission Access</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"preSubmissionAccessOn\" (click)=\"preSubmissionAccessOn = !preSubmissionAccessOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--wrap\">Users added here can view Open and In Progress audits until submission. The Schedule Info tab is also visible only to these users.</div>\r\n <ng-container *ngIf=\"preSubmissionAccessOn\">\r\n <div class=\"cf-row cf-row--top\">\r\n <span class=\"cf-field\">Visible to</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'preSubmissionUsers', large: false }\"></ng-container>\r\n </div>\r\n <div class=\"cf-error cf-error--indent\" *ngIf=\"preSubmissionEmpty\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n Add at least one user\r\n </div>\r\n </ng-container>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Scoring ===== -->\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Scoring</div>\r\n <div class=\"cf-box cf-box--pad\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Pass/Fail Score Setup</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"passFailOn\" (click)=\"passFailOn = !passFailOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--wrap\">Set the compliance score an audit must reach to be marked {{ passLabel }}. Anything below it is marked {{ failLabel }}.</div>\r\n <div class=\"cf-row cf-row--wrap cf-row--top\" *ngIf=\"passFailOn\">\r\n <span class=\"cf-field\">Minimum score to {{ passLabel }}</span>\r\n <label class=\"cf-num\">\r\n <input type=\"number\" min=\"1\" max=\"100\" [(ngModel)]=\"passThreshold\">\r\n <span>%</span>\r\n </label>\r\n <span class=\"cf-pill cf-pill--pass\">{{ passLabel }} \u2265 {{ passThreshold }}%</span>\r\n <span class=\"cf-pill cf-pill--fail\">{{ failLabel }} &lt; {{ passThreshold }}%</span>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Approver Controls ===== -->\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Approver Controls</div>\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Edit Submitted Audit</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"editSubmittedOn\" (click)=\"toggleEditSubmitted()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">Allow Approvers to edit submitted Audit</div>\r\n <ng-container *ngIf=\"editSubmittedOn\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'editUsers', large: true }\"></ng-container>\r\n <div class=\"cf-error\" *ngIf=\"editSubmittedError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ editSubmittedError }}\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div class=\"cf-grid2\">\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-label\">Redo Extension</div>\r\n <div class=\"cf-inline\">\r\n Extend redo up to\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'redoExtension', options: redoExtensionOpts }\"></ng-container>\r\n Days till approval\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== User Verification ===== -->\r\n <section class=\"cf-card\">\r\n <div class=\"cf-block-title\">User Verification Configuration</div>\r\n <div class=\"cf-box cf-box--row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"requirePhoto\" (click)=\"requirePhoto = !requirePhoto\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Require Photo Capture</div>\r\n <div class=\"cf-hint\">By enabling, users must capture their photo to complete submission</div>\r\n </div>\r\n </div>\r\n <div class=\"cf-box cf-box--row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"requireAcknowledgment\" (click)=\"requireAcknowledgment = !requireAcknowledgment\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Require User Acknowledgment</div>\r\n <div class=\"cf-hint\">By enabling, users must type their name as acknowledgment to complete submission</div>\r\n </div>\r\n </div>\r\n </section>\r\n </ng-container>\r\n\r\n </div>\r\n </div>\r\n\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}.cf-backbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.cf-back{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.cf-crumb{font-size:13px;line-height:20px;color:#667085}.cf-crumb a{font-weight:600;color:#00a3ff}.cf-header{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:16px 20px;display:flex;align-items:center;gap:12px}.cf-header-text{display:flex;flex-direction:column;gap:4px;min-width:0}.cf-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.cf-sk-title{margin:3px 0}.cf-desc{border:none;outline:none;padding:0;background:transparent;font-family:inherit;font-size:13px;line-height:18px;color:#344054;min-width:320px}.cf-desc::placeholder{color:#98a2b3}.cf-publish{padding:0 20px;box-shadow:0 1px 2px #1018280d}.cf-draft{padding:0 18px;box-shadow:inset 0 0 0 1px #d0d5dd,0 1px 2px #1018280d}.cf-body{display:flex;gap:16px;align-items:flex-start}.cf-left{width:300px;flex-shrink:0;background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:16px;display:flex;flex-direction:column;gap:10px;position:sticky;top:calc(var(--bs-app-header-height, 0px) + 16px);max-height:calc(100vh - var(--bs-app-header-height, 0px) - 32px);overflow-y:auto;scrollbar-width:thin}.cf-left-title{font-size:14px;line-height:20px;font-weight:600;color:#101828}.cf-section{display:flex;align-items:center;gap:8px;padding:2px 0;font-size:13px;font-weight:500;color:#344054;cursor:pointer;white-space:nowrap}.cf-section.is-open{color:#1d2939}.cf-rule{flex:1;border-top:1px solid #EAECF0}.cf-chev{display:flex;color:#98a2b3}.cf-chev svg{transition:transform .15s cubic-bezier(.4,0,.2,1)}.cf-chev .rotate{transform:rotate(-90deg)}.cf-items{display:flex;flex-direction:column;gap:8px;padding-left:12px;font-size:13px;color:#475467}.cf-schedule-title{font-size:14px;font-weight:600;color:#101828;margin-top:6px}.cf-schedule{display:flex;flex-direction:column;gap:6px;font-size:13px;color:#475467}.cf-schedule>div{display:flex;align-items:center;gap:6px}.cf-right{flex:1;min-width:0;display:flex;flex-direction:column;gap:16px}.cf-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px;display:flex;flex-direction:column;gap:14px}.cf-card--lg{border-radius:8px}.cf-block-head{display:flex;align-items:center;gap:12px}.cf-block-title{font-size:15px;font-weight:600;color:#101828}.cf-divider-head{display:flex;align-items:center;gap:10px;margin-top:4px}.cf-label{font-size:14px;font-weight:600;color:#101828}.cf-label-sm{font-size:13px;font-weight:600;color:#101828}.cf-muted{color:#667085}.cf-hint{font-size:12px;line-height:18px;color:#667085}.cf-hint--tight{margin-top:-8px}.cf-hint--wrap{max-width:640px;text-wrap:pretty}.cf-field{font-size:13px;font-weight:500;color:#344054;min-width:150px;flex-shrink:0}.cf-row{display:flex;align-items:center;gap:12px}.cf-row--top{margin-top:6px}.cf-row--wrap{flex-wrap:wrap}.cf-stack{display:flex;flex-direction:column;gap:8px}.cf-stack--tight,.cf-stack--sm{gap:4px}.cf-stack--xs{gap:2px}.cf-grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.cf-toggle-row{display:flex;align-items:center;gap:10px}.cf-switch{width:36px;height:20px;padding:2px;border:none;border-radius:9999px;background:#eaecf0;display:flex;align-items:center;justify-content:flex-start;flex-shrink:0;cursor:pointer;transition:background .15s cubic-bezier(.4,0,.2,1)}.cf-switch>span{width:16px;height:16px;border-radius:9999px;background:#fff;box-shadow:0 1px 2px #1018280d}.cf-switch.is-on{background:#00a3ff;justify-content:flex-end}.cf-switch--top{margin-top:2px}.cf-chipbox{flex:1;min-width:0;display:flex;flex-wrap:wrap;gap:6px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;padding:8px 10px}.cf-chipbox--lg{gap:8px;padding:10px 12px}.cf-chip{display:flex;align-items:center;gap:6px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0;border-radius:9999px;padding:3px 8px;font-size:12px;color:#344054;white-space:nowrap;flex-shrink:0;max-width:100%}.cf-chip--lg{gap:8px;background:#fff;padding:5px 11px;font-size:13px;color:#1d2939}.cf-chip-ini{color:#00a3ff;font-weight:600;font-size:11px}.cf-chip-tag{display:inline-flex;align-items:center;justify-content:center;padding:1px 5px;border-radius:6px;background:#eaf8ff;color:#00a3ff;font-weight:700;font-size:11px;letter-spacing:.02em}.cf-chip-x{display:flex;cursor:pointer;color:#98a2b3}.cf-chip-x:hover{color:#344054}.cf-chip-input{flex:1;min-width:100px;border:none;outline:none;background:transparent;font-family:inherit;font-size:12px;color:#101828}.cf-chip-input::placeholder{color:#98a2b3}.cf-chip-input--lg{min-width:120px;font-size:13px}.cf-inner{border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;padding:14px 16px;display:flex;flex-direction:column;gap:8px}.cf-inline{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:13px;color:#344054}.cf-inline--top{margin-top:2px}.cf-mini{height:32px;padding:0 28px 0 10px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#101828;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 8px center;outline:none}.cf-info{display:flex;align-items:center;gap:6px;font-size:12px;line-height:18px;color:#667085}.cf-info svg{flex-shrink:0}.cf-info--wrap{align-items:flex-start;max-width:560px;text-wrap:pretty}.cf-info--wrap svg{margin-top:3px}.cf-checks{display:flex;align-items:center;gap:16px;flex-wrap:wrap;font-size:13px;color:#344054}.cf-checks-label{font-weight:500}.cf-check{display:flex;align-items:center;gap:6px;margin:0;font-size:13px;color:#344054;cursor:pointer;-webkit-user-select:none;user-select:none}.cf-check-box{width:16px;height:16px;border-radius:4px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}.cf-check-box.is-on{background:#00a3ff;box-shadow:none}.cf-box{border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;overflow:hidden;display:flex;flex-direction:column}.cf-box--pad{padding:14px 16px;gap:6px;overflow:visible}.cf-box--row{padding:14px 16px;flex-direction:row;align-items:flex-start;gap:12px}.cf-box--nested{background:#fff;padding:12px 14px;gap:8px;margin-left:46px;overflow:visible}.cf-box--open{overflow:visible}.cf-box--open>.cf-box-sub:last-child{border-radius:0 0 8px 8px}.cf-box-row{padding:14px 16px;display:flex;align-items:flex-start;gap:12px}.cf-box-row--flush{padding:0;gap:10px}.cf-box-sub{border-top:1px solid #EAECF0;background:#f9fafb;padding:16px 16px 18px 64px;display:flex;flex-direction:column;gap:12px}.cf-options{display:flex;flex-direction:column;gap:10px}.cf-option{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;cursor:pointer}.cf-option.is-on{box-shadow:inset 0 0 0 1.5px #00a3ff}.cf-box-sep{display:flex;flex-direction:column;gap:12px;padding-top:14px;border-top:1px solid #EAECF0}.cf-num{display:flex;align-items:center;gap:8px;height:36px;padding:0 6px 0 12px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;margin:0}.cf-num input{width:52px;border:none;outline:none;background:transparent;font-family:inherit;font-size:14px;font-weight:600;color:#101828}.cf-num span{font-size:13px;color:#667085;padding-right:6px}.cf-pill{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;border-radius:9999px;padding:4px 12px}.cf-pill--pass{background:#ecfdf3;color:#027a48}.cf-pill--fail{background:#fef3f2;color:#d92d20}.cf-error{display:flex;gap:6px;font-size:12px;font-weight:500;color:#d92d20;align-items:flex-start;line-height:18px;max-width:640px}.cf-error svg{flex-shrink:0;margin-top:3px}.cf-error--indent{margin-left:162px}.cf-check.is-blocked{color:#98a2b3;cursor:not-allowed}.cf-select{position:relative;display:inline-block;vertical-align:middle}.cf-select-btn{display:inline-flex;align-items:center;gap:8px;height:32px;padding:0 10px 0 12px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#101828;cursor:pointer;white-space:nowrap}.cf-select-btn svg{color:#667085;transition:transform .15s ease}.is-open .cf-select-btn{box-shadow:0 0 0 2px #99dbff,inset 0 0 0 1px #d0d5dd}.is-open .cf-select-btn svg{transform:rotate(180deg)}.cf-select-menu{position:absolute;top:calc(100% + 4px);left:0;z-index:30;min-width:100%;padding:4px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 8px 24px #1018281f}.cf-select-item{padding:8px 12px;border-radius:6px;font-size:13px;color:#344054;white-space:nowrap;cursor:pointer}.cf-select-item:hover{background:#f9fafb}.cf-select-item.is-on{background:#eaf8ff;color:#009bf3;font-weight:600}.cf-chipbox{position:relative}.cf-chipbox.is-open{box-shadow:0 0 0 2px #99dbff,inset 0 0 0 1px #d0d5dd}.cf-suggest{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:30;max-height:260px;overflow-y:auto;padding:4px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 8px 24px #1018281f}.cf-suggest-item{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:6px;cursor:pointer}.cf-suggest-item:hover{background:#f9fafb}.cf-suggest-name{font-size:13px;color:#101828}.cf-suggest-mail{font-size:12px;color:#667085;margin-left:auto}.cf-suggest-empty{padding:8px 10px;font-size:12px;color:#667085}.cf-error--page{margin:0 0 12px}.cf-autotask{margin-top:12px;padding:14px 16px;border-radius:10px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0;display:flex;flex-direction:column;gap:8px}.cf-autotask-title{font-size:14px;font-weight:600;color:#1d2939}.cf-autotask-title:not(:first-child){margin-top:6px}.cf-autotask-choices{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}@media (max-width: 720px){.cf-autotask-choices{grid-template-columns:1fr}}.cf-choice{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;text-align:left;cursor:pointer}.cf-choice.is-on{background:#f5faff;box-shadow:inset 0 0 0 1px #66c8ff}.cf-radio{width:18px;height:18px;flex-shrink:0;margin-top:1px;border-radius:9999px;box-shadow:inset 0 0 0 1px #d0d5dd;display:flex;align-items:center;justify-content:center}.cf-radio span{width:8px;height:8px;border-radius:9999px;background:transparent}.cf-radio.is-on{box-shadow:inset 0 0 0 1px #1570ef}.cf-radio.is-on span{background:#1570ef}.cf-choice-text{display:flex;flex-direction:column;gap:2px;min-width:0}.cf-choice-title{font-size:14px;font-weight:600;color:#101828}.cf-choice-sub{font-size:12px;color:#667085}.cf-autotask-validity{display:flex;align-items:center;flex-wrap:wrap;gap:10px;font-size:13px;color:#344054}.cf-validity-select{width:96px}.cf-reminder{display:inline-flex;align-items:center;gap:6px}.cf-reminder-select{width:120px}.cf-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;cursor:pointer}.cf-icon-btn:hover{background:#f9fafb}\n"] }]
10393
+ args: [{ selector: 'lib-audit-v2-configure', template: "<div class=\"av2-page audit-configure\">\r\n\r\n <!-- Back + breadcrumb (as the schedule editor's back bar) -->\r\n <div class=\"cf-backbar\">\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm cf-back\" (click)=\"back()\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 6 9 12 15 18\"></polyline></svg>\r\n {{ backLabel }}\r\n </button>\r\n <div class=\"cf-crumb\">\r\n <a href=\"#\" (click)=\"back($event)\">Manage Audit</a> \u203A Configure\r\n </div>\r\n </div>\r\n\r\n <!-- Title + actions -->\r\n <div class=\"cf-header\">\r\n <div class=\"cf-header-text\">\r\n <span class=\"av2-sk av2-sk--title cf-sk-title\" *ngIf=\"loading\"></span>\r\n <div class=\"cf-title\" *ngIf=\"!loading\">{{ auditName || 'Audit' }}</div>\r\n <input type=\"text\" class=\"cf-desc\" placeholder=\"Enter Audit Description\" [(ngModel)]=\"description\">\r\n </div>\r\n <div class=\"av2-grow\"></div>\r\n <button type=\"button\" class=\"av2-btn av2-btn--primary cf-publish\" [disabled]=\"!canSave\" [title]=\"saveBlockedReason || publishBlockedReason\" (click)=\"publish()\">\r\n {{ saving ? 'Saving\u2026' : (published ? 'Save & Publish' : 'Publish') }}\r\n </button>\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost cf-draft\" [disabled]=\"!canSave\" [title]=\"saveBlockedReason\" (click)=\"saveDraft()\">Save as Draft</button>\r\n </div>\r\n\r\n <div class=\"cf-error cf-error--page\" *ngIf=\"loadError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ loadError }}\r\n </div>\r\n\r\n <!-- Chip picker: chips + input + suggestion list (one template, used for every user list) -->\r\n <ng-template #chipPicker let-list=\"list\" let-large=\"large\">\r\n <div class=\"cf-chipbox\" [class.cf-chipbox--lg]=\"large\" [class.is-open]=\"openChips === list\" (click)=\"focusChips(list, $event)\">\r\n <span class=\"cf-chip\" [class.cf-chip--lg]=\"large\" *ngFor=\"let u of chipsOf(list); let i = index\" [title]=\"u.e\">\r\n <span [class]=\"large ? 'cf-chip-tag' : 'cf-chip-ini'\">{{ u.i }}</span>{{ u.n }}\r\n <a class=\"cf-chip-x\" (click)=\"removeChip(list, i); $event.stopPropagation()\">\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\r\n </a>\r\n </span>\r\n <input type=\"text\" class=\"cf-chip-input\" [class.cf-chip-input--lg]=\"large\" placeholder=\"Add user...\"\r\n [ngModel]=\"draftOf(list)\" (ngModelChange)=\"setDraft(list, $event)\" (focus)=\"focusChips(list, $event)\" (keyup.enter)=\"addChip(list)\">\r\n <div class=\"cf-suggest\" *ngIf=\"openChips === list\">\r\n <div class=\"cf-suggest-item\" *ngFor=\"let u of suggestions(list)\" (click)=\"addSuggestion(list, u, $event)\">\r\n <span class=\"cf-chip-ini\">{{ u.i }}</span>\r\n <span class=\"cf-suggest-name\">{{ u.n }}</span>\r\n <span class=\"cf-suggest-mail\">{{ u.e }}</span>\r\n </div>\r\n <div class=\"cf-suggest-empty\" *ngIf=\"!suggestions(list).length\">\r\n {{ users.length ? 'No matching user' : 'No users for this client' }}\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Dropdown: styled like the prototype instead of the browser's native select -->\r\n <ng-template #dropdown let-key=\"key\" let-options=\"options\">\r\n <span class=\"cf-select\" [class.is-open]=\"openSelect === key\">\r\n <button type=\"button\" class=\"cf-select-btn\" (click)=\"toggleSelect(key, $event)\">\r\n {{ selectLabel(key, options) }}\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\r\n </button>\r\n <div class=\"cf-select-menu\" *ngIf=\"openSelect === key\">\r\n <div class=\"cf-select-item\" *ngFor=\"let o of options\" [class.is-on]=\"isPicked(key, o)\"\r\n (click)=\"pick(key, o, $event)\">{{ o.label }}</div>\r\n </div>\r\n </span>\r\n </ng-template>\r\n\r\n <div class=\"cf-body\" *ngIf=\"!loadError\">\r\n <!-- Section tree -->\r\n <aside class=\"cf-left\">\r\n <lib-audit-v2-shimmer *ngIf=\"loading\" [rows]=\"3\"></lib-audit-v2-shimmer>\r\n\r\n <ng-container *ngIf=\"!loading\">\r\n <div class=\"cf-left-title\">{{ auditName || 'Audit' }}</div>\r\n\r\n <div class=\"cf-hint\" *ngIf=\"!sections.length\">No questions yet</div>\r\n <ng-container *ngFor=\"let s of sections\">\r\n <div class=\"cf-section\" [class.is-open]=\"s.open\" (click)=\"toggleSection(s)\">\r\n {{ s.label }}\r\n <span class=\"cf-rule\"></span>\r\n <span class=\"cf-chev\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" [class.rotate]=\"!s.open\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"cf-items\" *ngIf=\"s.open && s.items.length\">\r\n <div *ngFor=\"let it of s.items\">{{ it }}</div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- No Schedule block (QA 10 Oct): audits have no one-time / repeat schedule here; visits come from Schedules. -->\r\n </ng-container>\r\n </aside>\r\n\r\n <!-- Configuration -->\r\n <div class=\"cf-right\">\r\n\r\n <section class=\"cf-card\" *ngIf=\"loading\">\r\n <lib-audit-v2-shimmer [rows]=\"4\"></lib-audit-v2-shimmer>\r\n </section>\r\n\r\n <ng-container *ngIf=\"!loading\">\r\n\r\n <!-- ===== Advance Configuration ===== -->\r\n <section class=\"cf-card\">\r\n <div class=\"cf-block-head\">\r\n <span class=\"cf-block-title\">Advance Configuration</span>\r\n <span class=\"cf-rule\"></span>\r\n <span class=\"cf-chev\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>\r\n </span>\r\n </div>\r\n\r\n <!-- Audit Owner -->\r\n <div>\r\n <div class=\"cf-label\">Audit Owner</div>\r\n <div class=\"cf-hint\">Owners get access to manage the audit</div>\r\n </div>\r\n <div class=\"cf-row\">\r\n <span class=\"cf-field\">Can be managed by</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'owners', large: false }\"></ng-container>\r\n </div>\r\n\r\n <!-- Approver -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Approver</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"approverOn\" (click)=\"toggleApprover()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, the users will be able to approve the audit</div>\r\n <div class=\"cf-row\" *ngIf=\"approverOn\">\r\n <span class=\"cf-field\">To be approved by</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'approvers', large: false }\"></ng-container>\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"approverError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ approverError }}\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\" *ngIf=\"!approverOn && approvers.length\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Approver is off, so the {{ approvers.length }} approver{{ approvers.length === 1 ? '' : 's' }} added will be removed when you save. Turn Approver back on to keep {{ approvers.length === 1 ? 'it' : 'them' }}.\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\" *ngIf=\"!approverOn && !approvers.length\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Approver is off, so submitted audits are not sent for approval. Turn it on to add approvers or to send flags and reports to them.\r\n </div>\r\n\r\n <!-- Reminder -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Reminder</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"reminderOn\" (click)=\"toggleReminder()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, the users will be reminded in the selected interval</div>\r\n <div class=\"cf-inner\" *ngIf=\"reminderOn\">\r\n <div class=\"cf-inline\">\r\n Notify user before\r\n <span class=\"cf-reminder\" *ngFor=\"let m of reminders; let i = index\">\r\n <lib-audit-v2-select class=\"cf-reminder-select\" [value]=\"m\" [options]=\"reminderOpts[i] || []\" [searchable]=\"false\"\r\n [ariaLabel]=\"'Reminder ' + (i + 1) + ' in minutes'\" (changed)=\"setReminder(i, $event.target.value)\"></lib-audit-v2-select>\r\n <a class=\"cf-chip-x\" *ngIf=\"reminders.length > 1\" title=\"Remove reminder\" (click)=\"removeReminder(i)\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line></svg>\r\n </a>\r\n </span>\r\n <button type=\"button\" class=\"cf-icon-btn\" *ngIf=\"reminders.length < maxReminders\" title=\"Add reminder\" (click)=\"addReminder()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line></svg>\r\n </button>\r\n </div>\r\n <div class=\"cf-info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Send alerts {{ reminderSummary }} mins before the audit end time\r\n </div>\r\n </div>\r\n\r\n <!-- Notify Flags -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Notify Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"notifyFlagsOn\" (click)=\"toggleNotifyFlags()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, all flags will be sent as an email</div>\r\n <ng-container *ngIf=\"notifyFlagsOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !notifySendApprover\" (click)=\"toggleSendApprover('notifySendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"notifySendApprover\">\r\n <svg *ngIf=\"notifySendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"notifySendCustom = !notifySendCustom\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"notifySendCustom\">\r\n <svg *ngIf=\"notifySendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"notifySendCustom\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'notifyUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <div class=\"cf-error\" *ngIf=\"notifyFlagsError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ notifyFlagsError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Notify on Recurring Flags -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Notify on Recurring Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"recurringFlagsOn\" (click)=\"toggleRecurringFlags()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">When enabled, emails are sent for recurring flags based on the configured threshold</div>\r\n\r\n <div class=\"cf-inner\" *ngIf=\"recurringFlagsOn\">\r\n <div class=\"cf-inline\">\r\n Send Email if the same question is flagged\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'recurringThreshold', options: thresholdOpts }\"></ng-container>\r\n times by the same store\r\n </div>\r\n <div class=\"cf-info\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Once the threshold is reached and an email is sent, the flag count resets to zero\r\n </div>\r\n </div>\r\n <ng-container *ngIf=\"recurringFlagsOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !recurringSendApprover\" (click)=\"toggleSendApprover('recurringSendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSendApprover\">\r\n <svg *ngIf=\"recurringSendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"toggleRecurringCustom()\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSendCustom\">\r\n <svg *ngIf=\"recurringSendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n <label class=\"cf-check\" (click)=\"recurringSameAsNotify = !recurringSameAsNotify\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"recurringSameAsNotify\">\r\n <svg *ngIf=\"recurringSameAsNotify\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Use same users from Notify Flags\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"recurringSendCustom\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'recurringUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <div class=\"cf-info\" *ngIf=\"recurringSameAsNotify\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n {{ notifyRecipientsLabel }}\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"recurringFlagsError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ recurringFlagsError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Daily report -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Enable - Daily Report</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"dailyReportOn\" (click)=\"toggleDailyReport()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By Enabling, compliance score will be sent as an email to the above users</div>\r\n <ng-container *ngIf=\"dailyReportOn\">\r\n <div class=\"cf-checks\">\r\n <span class=\"cf-checks-label\">Send To</span>\r\n <label class=\"cf-check\" [class.is-blocked]=\"!hasApprovers && !dailySendApprover\" (click)=\"toggleSendApprover('dailySendApprover')\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"dailySendApprover\">\r\n <svg *ngIf=\"dailySendApprover\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Approver\r\n </label>\r\n <label class=\"cf-check\" (click)=\"dailySendCustom = !dailySendCustom\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"dailySendCustom\">\r\n <svg *ngIf=\"dailySendCustom\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Custom\r\n </label>\r\n </div>\r\n <ng-container *ngIf=\"dailySendCustom\">\r\n <div class=\"cf-bulkbar\">\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" (click)=\"openDailyBulk()\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.67\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M17.5 12.5V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H4.16667C3.72464 17.5 3.30072 17.3244 2.98816 17.0118C2.67559 16.6993 2.5 16.2754 2.5 15.8333V12.5M14.1667 6.66667L10 2.5M10 2.5L5.83333 6.66667M10 2.5V12.5\"></path></svg>\r\n Bulk Upload\r\n </button>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'dailyUsers', large: false }\"></ng-container>\r\n </ng-container>\r\n <label class=\"cf-check\" (click)=\"sharePostApproval = !sharePostApproval\">\r\n <span class=\"cf-check-box\" [class.is-on]=\"sharePostApproval\">\r\n <svg *ngIf=\"sharePostApproval\" width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>\r\n </span>Share Report Post Approval\r\n </label>\r\n <div class=\"cf-error\" *ngIf=\"dailyReportError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ dailyReportError }}\r\n </div>\r\n </ng-container>\r\n\r\n <!-- Export submission: Tango users only, as the v1 Configure (its stored value is kept for everyone else). -->\r\n <div class=\"cf-grid2\" *ngIf=\"access.isTango\">\r\n <div class=\"cf-stack cf-stack--tight\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Export Submission</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"exportSubmissionOn\" (click)=\"exportSubmissionOn = !exportSubmissionOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint\">Enable this to allow audit submitters to download their submission as a PDF file</div>\r\n </div>\r\n </div>\r\n\r\n <!-- Redo validity -->\r\n <div class=\"cf-grid2\">\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-label\">Redo Validity</div>\r\n <div class=\"cf-inline\">\r\n Redo valid for\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'redoValidFor', options: redoDayOpts }\"></ng-container>\r\n Day from Redo creation\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Auto create task -->\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Auto Create Task for Flags</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"autoCreateTaskOn\" (click)=\"autoCreateTaskOn = !autoCreateTaskOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">By enabling, a task is automatically created for every flagged question in the audit</div>\r\n\r\n <!-- Who gets the task and how long it stays open (as the Checklist Configure page) -->\r\n <div class=\"cf-autotask\" *ngIf=\"autoCreateTaskOn\">\r\n <div class=\"cf-autotask-title\">Task Assignee</div>\r\n <div class=\"cf-hint cf-hint--tight\">Choose who the flagged task is assigned to</div>\r\n <div class=\"cf-autotask-choices\">\r\n <button type=\"button\" class=\"cf-choice\" [class.is-on]=\"taskAssignee === 'submitter'\" (click)=\"taskAssignee = 'submitter'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"taskAssignee === 'submitter'\"><span></span></span>\r\n <span class=\"cf-choice-text\">\r\n <span class=\"cf-choice-title\">Audit Submitter</span>\r\n <span class=\"cf-choice-sub\">Task is assigned to the user who filled the audit</span>\r\n </span>\r\n </button>\r\n <button type=\"button\" class=\"cf-choice\" [class.is-on]=\"taskAssignee === 'store'\" (click)=\"taskAssignee = 'store'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"taskAssignee === 'store'\"><span></span></span>\r\n <span class=\"cf-choice-text\">\r\n <span class=\"cf-choice-title\">Store User</span>\r\n <span class=\"cf-choice-sub\">Task is assigned to the user mapped to the flagged store</span>\r\n </span>\r\n </button>\r\n </div>\r\n <div class=\"cf-autotask-title\">Task Validity</div>\r\n <div class=\"cf-autotask-validity\">\r\n <span>Task valid for</span>\r\n <lib-audit-v2-select class=\"cf-validity-select\" [(ngModel)]=\"taskValidity\" [options]=\"taskValidityOptions\"\r\n [searchable]=\"false\" ariaLabel=\"Task validity in days\"></lib-audit-v2-select>\r\n <span>days from task creation</span>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Audit Configuration ===== -->\r\n <div class=\"cf-divider-head\">\r\n <span class=\"cf-block-title\">Audit Configuration</span>\r\n <span class=\"cf-rule\"></span>\r\n </div>\r\n\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Submission &amp; Visibility</div>\r\n\r\n <!-- cf-box--open: the dispute-window and response-delay menus must not be clipped by the box -->\r\n <div class=\"cf-box cf-box--open\">\r\n <div class=\"cf-box-row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"showResponseInApp\"\r\n (click)=\"showResponseInApp = !showResponseInApp\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Show Response in Mobile App</div>\r\n <div class=\"cf-hint\">By enabling this option, store users can view the audit response in the Mobile App.</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"cf-box-sub\" *ngIf=\"showResponseInApp\">\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label-sm\">Response Visibility</div>\r\n <div class=\"cf-hint\">Choose when the response becomes visible to store users</div>\r\n </div>\r\n\r\n <div class=\"cf-options\">\r\n <div class=\"cf-option\" [class.is-on]=\"responseVisibility === 'pre'\" (click)=\"responseVisibility = 'pre'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"responseVisibility === 'pre'\"><span></span></span>\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm\">Pre-approval</div>\r\n <div class=\"cf-hint\">The audit response will be visible to store users before it is approved.</div>\r\n <div class=\"cf-inline cf-inline--top\">\r\n Show response\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'respDelay', options: respDelayOpts }\"></ng-container>\r\n after submission\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"cf-option\" [class.is-on]=\"responseVisibility === 'post'\" (click)=\"responseVisibility = 'post'\">\r\n <span class=\"cf-radio\" [class.is-on]=\"responseVisibility === 'post'\"><span></span></span>\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm\" [class.cf-muted]=\"responseVisibility !== 'post'\">Post-approval</div>\r\n <div class=\"cf-hint\">Once the response is approved, it will automatically be displayed in the Mobile App. Store users cannot raise a dispute.</div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"cf-box-sep\">\r\n <ng-container *ngIf=\"responseVisibility === 'pre'\">\r\n <div class=\"cf-box-row cf-box-row--flush\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"disputeOn\" (click)=\"disputeOn = !disputeOn\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label-sm\">Dispute Configuration</div>\r\n <div class=\"cf-hint cf-hint--wrap\">When enabled, the store team can raise a dispute against the auditor's submission once the response becomes visible to them.</div>\r\n </div>\r\n </div>\r\n <div class=\"cf-box cf-box--nested\" *ngIf=\"disputeOn\">\r\n <div class=\"cf-inline\">\r\n Dispute window\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'disputeWindow', options: dispWindowOpts }\"></ng-container>\r\n from when the response becomes visible\r\n </div>\r\n <div class=\"cf-info cf-info--wrap\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Disputes raised inside this window go to the approver. Approved disputes revise the answer and the compliance score.\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"!hasApprovers\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n No approver is set, so no one can review disputes. Turn on Approver and add an approver.\r\n </div>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"responseVisibility === 'post'\">\r\n <div class=\"cf-stack cf-stack--sm\">\r\n <div class=\"cf-label-sm cf-muted\">Dispute Configuration</div>\r\n <div class=\"cf-info cf-info--wrap\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line></svg>\r\n Disputes are not available when responses are shown post-approval.\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Pre-submission access -->\r\n <div class=\"cf-box cf-box--pad\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Pre-Submission Access</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"preSubmissionAccessOn\" (click)=\"preSubmissionAccessOn = !preSubmissionAccessOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--wrap\">Users added here can view Open and In Progress audits until submission. The Schedule Info tab is also visible only to these users.</div>\r\n <ng-container *ngIf=\"preSubmissionAccessOn\">\r\n <div class=\"cf-row cf-row--top\">\r\n <span class=\"cf-field\">Visible to</span>\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'preSubmissionUsers', large: false }\"></ng-container>\r\n </div>\r\n <div class=\"cf-error cf-error--indent\" *ngIf=\"preSubmissionEmpty\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n Add at least one user\r\n </div>\r\n </ng-container>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Scoring ===== -->\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Scoring</div>\r\n <div class=\"cf-box cf-box--pad\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Pass/Fail Score Setup</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"passFailOn\" (click)=\"passFailOn = !passFailOn\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--wrap\">Set the compliance score an audit must reach to be marked {{ passLabel }}. Anything below it is marked {{ failLabel }}.</div>\r\n <div class=\"cf-row cf-row--wrap cf-row--top\" *ngIf=\"passFailOn\">\r\n <span class=\"cf-field\">Minimum score to {{ passLabel }}</span>\r\n <label class=\"cf-num\">\r\n <input type=\"number\" min=\"1\" max=\"100\" [(ngModel)]=\"passThreshold\">\r\n <span>%</span>\r\n </label>\r\n <span class=\"cf-pill cf-pill--pass\">{{ passLabel }} \u2265 {{ passThreshold }}%</span>\r\n <span class=\"cf-pill cf-pill--fail\">{{ failLabel }} &lt; {{ passThreshold }}%</span>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== Approver Controls ===== -->\r\n <section class=\"cf-card cf-card--lg\">\r\n <div class=\"cf-block-title\">Approver Controls</div>\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-toggle-row\">\r\n <span class=\"cf-label\">Edit Submitted Audit</span>\r\n <button type=\"button\" class=\"cf-switch\" [class.is-on]=\"editSubmittedOn\" (click)=\"toggleEditSubmitted()\"><span></span></button>\r\n </div>\r\n <div class=\"cf-hint cf-hint--tight\">Allow Approvers to edit submitted Audit</div>\r\n <ng-container *ngIf=\"editSubmittedOn\">\r\n <ng-container *ngTemplateOutlet=\"chipPicker; context: { list: 'editUsers', large: true }\"></ng-container>\r\n <div class=\"cf-error\" *ngIf=\"editSubmittedError\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n {{ editSubmittedError }}\r\n </div>\r\n </ng-container>\r\n </div>\r\n <div class=\"cf-grid2\">\r\n <div class=\"cf-stack\">\r\n <div class=\"cf-label\">Redo Extension</div>\r\n <div class=\"cf-inline\">\r\n Extend redo up to\r\n <ng-container *ngTemplateOutlet=\"dropdown; context: { key: 'redoExtension', options: redoExtensionOpts }\"></ng-container>\r\n Days till approval\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n\r\n <!-- ===== User Verification ===== -->\r\n <section class=\"cf-card\">\r\n <div class=\"cf-block-title\">User Verification Configuration</div>\r\n <div class=\"cf-box cf-box--row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"requirePhoto\" (click)=\"requirePhoto = !requirePhoto\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Require Photo Capture</div>\r\n <div class=\"cf-hint\">By enabling, users must capture their photo to complete submission</div>\r\n </div>\r\n </div>\r\n <div class=\"cf-box cf-box--row\">\r\n <button type=\"button\" class=\"cf-switch cf-switch--top\" [class.is-on]=\"requireAcknowledgment\" (click)=\"requireAcknowledgment = !requireAcknowledgment\"><span></span></button>\r\n <div class=\"cf-stack cf-stack--xs\">\r\n <div class=\"cf-label\">Require User Acknowledgment</div>\r\n <div class=\"cf-hint\">By enabling, users must type their name as acknowledgment to complete submission</div>\r\n </div>\r\n </div>\r\n </section>\r\n </ng-container>\r\n\r\n </div>\r\n </div>\r\n\r\n <!-- Daily Report > Custom: bulk upload users (as the Checklist Configure page's popup) -->\r\n <ng-container *ngIf=\"dailyBulkOpen\">\r\n <div class=\"cf-dlg-backdrop\" (click)=\"closeDailyBulk()\"></div>\r\n <div class=\"cf-dlg\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"cf-dlg-title\">\r\n <span class=\"cf-dlg-icon\">\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.67\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M17.5 12.5V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H4.16667C3.72464 17.5 3.30072 17.3244 2.98816 17.0118C2.67559 16.6993 2.5 16.2754 2.5 15.8333V12.5M14.1667 6.66667L10 2.5M10 2.5L5.83333 6.66667M10 2.5V12.5\"></path></svg>\r\n </span>\r\n <div class=\"cf-dlg-title\" id=\"cf-dlg-title\">Bulk Upload</div>\r\n <div class=\"cf-dlg-steps\">\r\n <div>Step 1 - <a href=\"#\" (click)=\"$event.preventDefault(); downloadDailyTemplate()\">Download the template here</a></div>\r\n <div>Step 2 - Add the Email of existing users to the template</div>\r\n <div>Step 3 - Upload it below for processing</div>\r\n </div>\r\n <div class=\"cf-dlg-note\">\r\n **Note : Only the Email column is considered - the Username is taken from the existing user list.\r\n Only existing users of this client are accepted. On upload, all the existing data will be replaced.\r\n </div>\r\n <div class=\"cf-error\" *ngIf=\"dailyBulkErrors.length\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg>\r\n <div class=\"cf-dlg-errors\">\r\n <div>The file was not uploaded. Fix {{ dailyBulkErrors.length === 1 ? 'this row' : 'these rows' }} and upload again:</div>\r\n <div *ngFor=\"let e of dailyBulkErrors.slice(0, 5)\">{{ e }}</div>\r\n <div *ngIf=\"dailyBulkErrors.length > 5\">+{{ dailyBulkErrors.length - 5 }} more</div>\r\n </div>\r\n </div>\r\n <div class=\"cf-dlg-foot\">\r\n <button type=\"button\" class=\"av2-btn av2-btn--ghost av2-btn--sm\" (click)=\"closeDailyBulk()\">Cancel</button>\r\n <button type=\"button\" class=\"av2-btn av2-btn--primary av2-btn--sm\" (click)=\"dailyBulkFile.click()\">Upload</button>\r\n <input #dailyBulkFile type=\"file\" accept=\".xlsx\" hidden (change)=\"onDailyBulkFile($event)\">\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.av2-page{display:flex;flex-direction:column;gap:16px;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:#101828;-webkit-font-smoothing:antialiased}.av2-page *,.av2-page *:before,.av2-page *:after{box-sizing:border-box}.av2-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.av2-card--log{padding:20px 24px 24px;gap:18px}.av2-card--table{padding:20px 24px 24px;gap:16px}.av2-card-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.av2-card-head--center{align-items:center;gap:12px}.av2-title-block{display:flex;flex-direction:column;gap:4px;flex:1;min-width:220px}.av2-card-title{font-size:20px;line-height:30px;font-weight:600;color:#101828;display:flex;align-items:center;gap:10px}.av2-card-title--grow{flex:1;min-width:180px}.av2-card-sub{font-size:14px;line-height:20px;color:#667085}.av2-grow{flex:1}.av2-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.av2-grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}.av2-grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}.av2-stat-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:10px}.av2-stat{padding:8px 16px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;align-items:center;gap:20px}.av2-stat-value{font-size:30px;line-height:38px;font-weight:600;color:#101828}.av2-stat-label{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-kpi{background:#fff;border-radius:10px;box-shadow:inset 0 0 0 1px #eaecf0,0 1px 2px #1018280d;display:flex;flex-direction:column;overflow:hidden}.av2-kpi.is-primary{box-shadow:inset 0 0 0 1px #99dbff,0 1px 2px #1018280d}.av2-kpi.is-primary .av2-kpi-head{background:#eaf8ff}.av2-kpi-head{padding:14px 18px;background:#f9fafb;font-size:16px;line-height:24px;font-weight:500;color:#101828}.av2-kpi-body{padding:16px 18px 18px;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}.av2-kpi-value{font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-kpi-delta{display:flex;align-items:center;gap:4px;font-size:12px;color:#039855}.av2-kpi-delta.is-down{color:#d92d20}.av2-kpi-note{font-size:12px;color:#667085}.av2-ocard{padding:8px;border-radius:12px;border:1px solid #D0D5DD;background:#fff;display:flex;flex-direction:column;min-width:0;height:100%}.av2-ocard-head{min-height:70px;padding:10px 14px;border-radius:6px;border-bottom:2px solid #EAECF0;background:radial-gradient(206.89% 107.47% at 16.16% 32.77%,#fff6,#45bbfe33),#f2f4f7;box-shadow:0 4px 10px #0000000d;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-width:0}.av2-ocard-head--row{flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}.av2-ocard-count{font-size:30px;line-height:38px;font-weight:600;color:#101828;white-space:nowrap}.av2-ocard-text{font-size:14px;line-height:20px;font-weight:500;color:#344054}.av2-ocard-body{flex:1;padding:12px 14px;display:flex;gap:16px;min-width:0}.av2-ocard-cell{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.av2-ocard-cell--center{align-items:center;text-align:center}.av2-ocard-sub{margin:4px 0;font-size:20px;line-height:30px;font-weight:700;color:#101828}.av2-ocard-note{font-size:14px;line-height:20px;font-weight:400;color:#667085}.av2-ocard-delta{margin-top:6px;display:inline-flex;align-items:center;gap:6px;font-size:12px;line-height:18px;font-weight:400;color:#1d2939}.av2-ocard-delta b{font-weight:600;color:#667085}.av2-ocard-delta svg{flex-shrink:0;color:#039855}.av2-ocard-delta.is-down svg{color:#d92d20}.av2-search{position:relative;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#98a2b3;font-size:14px;flex-shrink:0}.av2-search svg{flex-shrink:0}.av2-search input{flex:1;min-width:0;height:100%;border:0;outline:0;padding:0;background:transparent;font:inherit;font-size:14px;font-weight:500;color:#101828}.av2-search input::placeholder{color:#98a2b3}.av2-search:focus-within{box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-search--sm{width:300px}.av2-search--md{width:320px}.av2-search--lg{width:340px}.av2-select{height:44px;padding:0 36px 0 12px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;font-size:14px;font-weight:500;color:#344054;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23344054' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 12px center;flex-shrink:0}.av2-select:focus{outline:0;box-shadow:inset 0 0 0 1px #66c8ff,0 0 0 4px #eaf8ff}.av2-select--sm{width:180px}.av2-chip{display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-size:14px;color:#344054;white-space:nowrap;flex-shrink:0}.av2-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:44px;padding:0 16px;border:0;border-radius:8px;font-family:inherit;font-size:14px;line-height:20px;font-weight:600;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.av2-btn svg{flex-shrink:0}.av2-btn:disabled{opacity:.55;cursor:not-allowed}.av2-btn--ghost{background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;font-weight:500}.av2-btn--ghost:hover:not(:disabled){background:#f9fafb}.av2-btn--primary{background:#00a3ff;color:#fff;font-size:16px;line-height:24px}.av2-btn--primary:hover:not(:disabled){background:#009bf3}.av2-btn--sm{height:36px;padding:0 14px;font-size:13px}.av2-btn--wide{padding:0 18px}.av2-tabs{display:flex;align-items:center;gap:6px}.av2-tab{height:44px;padding:0 26px;border:0;border-radius:6px;background:transparent;display:inline-flex;align-items:center;justify-content:center;font-family:inherit;font-size:16px;font-weight:500;color:#475467;cursor:pointer}.av2-tab.is-active{background:#eaf8ff;color:#009bf3;font-weight:500}.av2-badge{display:inline-flex;align-items:center;height:22px;padding:2px 8px;border-radius:16px;background:#eaf8ff;color:#009bf3;font-size:12px;font-weight:500;line-height:18px;white-space:nowrap}.av2-badge--count{height:22px;padding:0 8px}.av2-badge--success{background:#ecfdf3;color:#027a48}.av2-badge--error{background:#fef3f2;color:#b42318}.av2-badge--warning{background:#fffaeb;color:#b54708}.av2-badge--gray{background:#f2f4f7;color:#344054}.av2-badge--purple{background:#f9f5ff;color:#5925dc}.av2-link{color:#00a3ff;font-size:14px;font-weight:500;text-decoration:underline;cursor:pointer}.av2-link:hover{color:#009bf3;text-decoration:underline}.av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.av2-muted{color:#667085}.av2-dim{color:#475467}.av2-faint{color:#98a2b3}table tbody td.av2-dim{color:#475467}table tbody td.av2-faint{color:#98a2b3}.av2-table-wrap{overflow-x:auto}.av2-table{width:100%;border-collapse:separate;border-spacing:0;margin:0}.av2-table thead th{background:#f9fafb;padding:12px;font-size:12px;line-height:18px;font-weight:500;color:#667085;text-align:left;text-transform:none;letter-spacing:0;border:0;white-space:nowrap}.av2-table thead th:first-child{border-radius:8px 0 0}.av2-table thead th:last-child{border-radius:0 8px 0 0}.av2-table tbody td{padding:16px 12px;border:0;border-bottom:1px solid #F2F4F7;font-size:14px;line-height:20px;font-weight:500;color:#101828;vertical-align:middle}.av2-table .av2-th-sort{display:inline-flex;align-items:center;gap:4px}.av2-table .av2-cell-icon{display:flex;align-items:center;gap:8px;min-width:0}.av2-table .av2-cell-icon svg{flex-shrink:0}.av2-table .av2-cell-icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-table .av2-cell-stack{display:flex;flex-direction:column;gap:2px}.av2-table .av2-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.av2-sortable{cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap}.av2-table--lined thead th{background:transparent;border-bottom:1px solid #EAECF0;border-radius:0!important}.av2-empty{display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px 16px 32px;text-align:center}.av2-empty-img{display:block;width:160px;height:120px}.av2-empty-text{display:flex;flex-direction:column;gap:4px;align-items:center}.av2-empty-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.av2-empty-sub{max-width:480px;font-size:14px;line-height:20px;color:#667085;text-wrap:pretty}.av2-col-head{border-radius:8px;background:#f9fafb;padding:14px 16px;font-size:12px;line-height:20px;font-weight:500;color:#344054;display:flex;align-items:center;gap:8px}.av2-avatar{width:32px;height:32px;flex-shrink:0;border-radius:9999px;background:#eaf8ff;color:#009bf3;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}.av2-bar{flex:1;height:5px;border-radius:9999px;background:#f2f4f7;overflow:hidden;display:block;min-width:60px}.av2-bar span{display:block;height:5px;border-radius:9999px;background:#00a3ff}@keyframes av2-shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}.av2-sk{display:block;width:100%;max-width:100%;height:12px;border-radius:4px;flex-shrink:0;background:linear-gradient(to right,#e6e6e6 5%,#ccc 25%,#e6e6e6 35%);background-size:1000px 100%;animation:av2-shimmer 3s linear infinite}.av2-sk--value{width:72px;height:28px;border-radius:6px}.av2-sk--title{width:220px;height:18px}.av2-sk--note{width:60%}.av2-sk--block{border-radius:8px}@media (prefers-reduced-motion: reduce){.av2-sk{animation:none}}.cf-backbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.cf-back{display:inline-flex;align-items:center;gap:4px;flex-shrink:0}.cf-crumb{font-size:13px;line-height:20px;color:#667085}.cf-crumb a{font-weight:600;color:#00a3ff}.cf-header{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:16px 20px;display:flex;align-items:center;gap:12px}.cf-header-text{display:flex;flex-direction:column;gap:4px;min-width:0}.cf-title{font-size:16px;line-height:24px;font-weight:600;color:#101828}.cf-sk-title{margin:3px 0}.cf-desc{border:none;outline:none;padding:0;background:transparent;font-family:inherit;font-size:13px;line-height:18px;color:#344054;min-width:320px}.cf-desc::placeholder{color:#98a2b3}.cf-publish{padding:0 20px;box-shadow:0 1px 2px #1018280d}.cf-draft{padding:0 18px;box-shadow:inset 0 0 0 1px #d0d5dd,0 1px 2px #1018280d}.cf-body{display:flex;gap:16px;align-items:flex-start}.cf-left{width:300px;flex-shrink:0;background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:16px;display:flex;flex-direction:column;gap:10px;position:sticky;top:calc(var(--bs-app-header-height, 0px) + 16px);max-height:calc(100vh - var(--bs-app-header-height, 0px) - 32px);overflow-y:auto;scrollbar-width:thin}.cf-left-title{font-size:14px;line-height:20px;font-weight:600;color:#101828}.cf-section{display:flex;align-items:center;gap:8px;padding:2px 0;font-size:13px;font-weight:500;color:#344054;cursor:pointer;white-space:nowrap}.cf-section.is-open{color:#1d2939}.cf-rule{flex:1;border-top:1px solid #EAECF0}.cf-chev{display:flex;color:#98a2b3}.cf-chev svg{transition:transform .15s cubic-bezier(.4,0,.2,1)}.cf-chev .rotate{transform:rotate(-90deg)}.cf-items{display:flex;flex-direction:column;gap:8px;padding-left:12px;font-size:13px;color:#475467}.cf-schedule-title{font-size:14px;font-weight:600;color:#101828;margin-top:6px}.cf-schedule{display:flex;flex-direction:column;gap:6px;font-size:13px;color:#475467}.cf-schedule>div{display:flex;align-items:center;gap:6px}.cf-right{flex:1;min-width:0;display:flex;flex-direction:column;gap:16px}.cf-card{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #f1f1f4,0 3px 4px #00000008;padding:20px;display:flex;flex-direction:column;gap:14px}.cf-card--lg{border-radius:8px}.cf-block-head{display:flex;align-items:center;gap:12px}.cf-block-title{font-size:15px;font-weight:600;color:#101828}.cf-divider-head{display:flex;align-items:center;gap:10px;margin-top:4px}.cf-label{font-size:14px;font-weight:600;color:#101828}.cf-label-sm{font-size:13px;font-weight:600;color:#101828}.cf-muted{color:#667085}.cf-hint{font-size:12px;line-height:18px;color:#667085}.cf-hint--tight{margin-top:-8px}.cf-hint--wrap{max-width:640px;text-wrap:pretty}.cf-field{font-size:13px;font-weight:500;color:#344054;min-width:150px;flex-shrink:0}.cf-row{display:flex;align-items:center;gap:12px}.cf-row--top{margin-top:6px}.cf-row--wrap{flex-wrap:wrap}.cf-stack{display:flex;flex-direction:column;gap:8px}.cf-stack--tight,.cf-stack--sm{gap:4px}.cf-stack--xs{gap:2px}.cf-grid2{display:grid;grid-template-columns:1fr 1fr;gap:16px}.cf-toggle-row{display:flex;align-items:center;gap:10px}.cf-switch{width:36px;height:20px;padding:2px;border:none;border-radius:9999px;background:#eaecf0;display:flex;align-items:center;justify-content:flex-start;flex-shrink:0;cursor:pointer;transition:background .15s cubic-bezier(.4,0,.2,1)}.cf-switch>span{width:16px;height:16px;border-radius:9999px;background:#fff;box-shadow:0 1px 2px #1018280d}.cf-switch.is-on{background:#00a3ff;justify-content:flex-end}.cf-switch--top{margin-top:2px}.cf-chipbox{flex:1;min-width:0;display:flex;flex-wrap:wrap;gap:6px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;padding:8px 10px}.cf-chipbox--lg{gap:8px;padding:10px 12px}.cf-chip{display:flex;align-items:center;gap:6px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0;border-radius:9999px;padding:3px 8px;font-size:12px;color:#344054;white-space:nowrap;flex-shrink:0;max-width:100%}.cf-chip--lg{gap:8px;background:#fff;padding:5px 11px;font-size:13px;color:#1d2939}.cf-chip-ini{color:#00a3ff;font-weight:600;font-size:11px}.cf-chip-tag{display:inline-flex;align-items:center;justify-content:center;padding:1px 5px;border-radius:6px;background:#eaf8ff;color:#00a3ff;font-weight:700;font-size:11px;letter-spacing:.02em}.cf-chip-x{display:flex;cursor:pointer;color:#98a2b3}.cf-chip-x:hover{color:#344054}.cf-chip-input{flex:1;min-width:100px;border:none;outline:none;background:transparent;font-family:inherit;font-size:12px;color:#101828}.cf-chip-input::placeholder{color:#98a2b3}.cf-chip-input--lg{min-width:120px;font-size:13px}.cf-inner{border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;padding:14px 16px;display:flex;flex-direction:column;gap:8px}.cf-inline{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:13px;color:#344054}.cf-inline--top{margin-top:2px}.cf-mini{height:32px;padding:0 28px 0 10px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#101828;cursor:pointer;appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>\");background-repeat:no-repeat;background-position:right 8px center;outline:none}.cf-info{display:flex;align-items:center;gap:6px;font-size:12px;line-height:18px;color:#667085}.cf-info svg{flex-shrink:0}.cf-info--wrap{align-items:flex-start;max-width:560px;text-wrap:pretty}.cf-info--wrap svg{margin-top:3px}.cf-checks{display:flex;align-items:center;gap:16px;flex-wrap:wrap;font-size:13px;color:#344054}.cf-checks-label{font-weight:500}.cf-check{display:flex;align-items:center;gap:6px;margin:0;font-size:13px;color:#344054;cursor:pointer;-webkit-user-select:none;user-select:none}.cf-check-box{width:16px;height:16px;border-radius:4px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;display:flex;align-items:center;justify-content:center;color:#fff;flex-shrink:0}.cf-check-box.is-on{background:#00a3ff;box-shadow:none}.cf-box{border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;overflow:hidden;display:flex;flex-direction:column}.cf-box--pad{padding:14px 16px;gap:6px;overflow:visible}.cf-box--row{padding:14px 16px;flex-direction:row;align-items:flex-start;gap:12px}.cf-box--nested{background:#fff;padding:12px 14px;gap:8px;margin-left:46px;overflow:visible}.cf-box--open{overflow:visible}.cf-box--open>.cf-box-sub:last-child{border-radius:0 0 8px 8px}.cf-box-row{padding:14px 16px;display:flex;align-items:flex-start;gap:12px}.cf-box-row--flush{padding:0;gap:10px}.cf-box-sub{border-top:1px solid #EAECF0;background:#f9fafb;padding:16px 16px 18px 64px;display:flex;flex-direction:column;gap:12px}.cf-options{display:flex;flex-direction:column;gap:10px}.cf-option{background:#fff;border-radius:8px;box-shadow:inset 0 0 0 1px #eaecf0;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;cursor:pointer}.cf-option.is-on{box-shadow:inset 0 0 0 1.5px #00a3ff}.cf-box-sep{display:flex;flex-direction:column;gap:12px;padding-top:14px;border-top:1px solid #EAECF0}.cf-num{display:flex;align-items:center;gap:8px;height:36px;padding:0 6px 0 12px;border-radius:8px;box-shadow:inset 0 0 0 1px #d0d5dd;margin:0}.cf-num input{width:52px;border:none;outline:none;background:transparent;font-family:inherit;font-size:14px;font-weight:600;color:#101828}.cf-num span{font-size:13px;color:#667085;padding-right:6px}.cf-pill{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;border-radius:9999px;padding:4px 12px}.cf-pill--pass{background:#ecfdf3;color:#027a48}.cf-pill--fail{background:#fef3f2;color:#d92d20}.cf-error{display:flex;gap:6px;font-size:12px;font-weight:500;color:#d92d20;align-items:flex-start;line-height:18px;max-width:640px}.cf-error svg{flex-shrink:0;margin-top:3px}.cf-error--indent{margin-left:162px}.cf-check.is-blocked{color:#98a2b3;cursor:not-allowed}.cf-select{position:relative;display:inline-block;vertical-align:middle}.cf-select-btn{display:inline-flex;align-items:center;gap:8px;height:32px;padding:0 10px 0 12px;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font-family:inherit;font-size:13px;font-weight:600;color:#101828;cursor:pointer;white-space:nowrap}.cf-select-btn svg{color:#667085;transition:transform .15s ease}.is-open .cf-select-btn{box-shadow:0 0 0 2px #99dbff,inset 0 0 0 1px #d0d5dd}.is-open .cf-select-btn svg{transform:rotate(180deg)}.cf-select-menu{position:absolute;top:calc(100% + 4px);left:0;z-index:30;min-width:100%;padding:4px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 8px 24px #1018281f}.cf-select-item{padding:8px 12px;border-radius:6px;font-size:13px;color:#344054;white-space:nowrap;cursor:pointer}.cf-select-item:hover{background:#f9fafb}.cf-select-item.is-on{background:#eaf8ff;color:#009bf3;font-weight:600}.cf-chipbox{position:relative}.cf-chipbox.is-open{box-shadow:0 0 0 2px #99dbff,inset 0 0 0 1px #d0d5dd}.cf-suggest{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:30;max-height:260px;overflow-y:auto;padding:4px;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #eaecf0,0 8px 24px #1018281f}.cf-suggest-item{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:6px;cursor:pointer}.cf-suggest-item:hover{background:#f9fafb}.cf-suggest-name{font-size:13px;color:#101828}.cf-suggest-mail{font-size:12px;color:#667085;margin-left:auto}.cf-suggest-empty{padding:8px 10px;font-size:12px;color:#667085}.cf-error--page{margin:0 0 12px}.cf-autotask{margin-top:12px;padding:14px 16px;border-radius:10px;background:#f9fafb;box-shadow:inset 0 0 0 1px #eaecf0;display:flex;flex-direction:column;gap:8px}.cf-autotask-title{font-size:14px;font-weight:600;color:#1d2939}.cf-autotask-title:not(:first-child){margin-top:6px}.cf-autotask-choices{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}@media (max-width: 720px){.cf-autotask-choices{grid-template-columns:1fr}}.cf-choice{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border:0;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;font:inherit;text-align:left;cursor:pointer}.cf-choice.is-on{background:#f5faff;box-shadow:inset 0 0 0 1px #66c8ff}.cf-radio{width:18px;height:18px;flex-shrink:0;margin-top:1px;border-radius:9999px;box-shadow:inset 0 0 0 1px #d0d5dd;display:flex;align-items:center;justify-content:center}.cf-radio span{width:8px;height:8px;border-radius:9999px;background:transparent}.cf-radio.is-on{box-shadow:inset 0 0 0 1px #1570ef}.cf-radio.is-on span{background:#1570ef}.cf-choice-text{display:flex;flex-direction:column;gap:2px;min-width:0}.cf-choice-title{font-size:14px;font-weight:600;color:#101828}.cf-choice-sub{font-size:12px;color:#667085}.cf-autotask-validity{display:flex;align-items:center;flex-wrap:wrap;gap:10px;font-size:13px;color:#344054}.cf-validity-select{width:96px}.cf-reminder{display:inline-flex;align-items:center;gap:6px}.cf-reminder-select{width:120px}.cf-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:none;border-radius:8px;background:#fff;box-shadow:inset 0 0 0 1px #d0d5dd;color:#344054;cursor:pointer}.cf-icon-btn:hover{background:#f9fafb}.cf-bulkbar{display:flex;justify-content:flex-end;margin-bottom:-4px}.cf-bulkbar .av2-btn{display:inline-flex;align-items:center;gap:6px}.cf-dlg-backdrop{position:fixed;inset:0;background:#34405499;z-index:1050}.cf-dlg{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:520px;max-width:calc(100vw - 32px);max-height:90vh;overflow-y:auto;padding:24px;border-radius:8px;background:#fff;box-shadow:0 20px 40px #10182833;z-index:1051;display:flex;flex-direction:column;gap:12px}.cf-dlg-icon{width:40px;height:40px;border-radius:9999px;background:#eaf8ff;color:#00a3ff;display:flex;align-items:center;justify-content:center}.cf-dlg-title{font-size:18px;line-height:28px;font-weight:600;color:#101828}.cf-dlg-steps{display:flex;flex-direction:column;gap:8px;font-size:14px;line-height:20px;color:#344054}.cf-dlg-steps a{color:#00a3ff;text-decoration:underline;cursor:pointer}.cf-dlg-note{font-size:13px;line-height:20px;font-weight:600;color:#344054}.cf-dlg-errors{display:flex;flex-direction:column;gap:2px;min-width:0;overflow-wrap:anywhere}.cf-dlg-foot{display:flex;justify-content:flex-end;gap:12px;margin-top:4px}\n"] }]
10212
10394
  }], ctorParameters: () => [{ type: TraxService }, { type: i2.GlobalStateService }, { type: i1.ActivatedRoute }, { type: i1.Router }, { type: i3.ToastService }, { type: i0.ChangeDetectorRef }], propDecorators: { onEscape: [{
10213
10395
  type: HostListener,
10214
10396
  args: ['document:keydown.escape']
@@ -13981,4 +14163,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
13981
14163
  }] });
13982
14164
 
13983
14165
  export { AuditV2Module };
13984
- //# sourceMappingURL=tango-app-ui-analyse-trax-audit-v2.module-D2O6kj8t.mjs.map
14166
+ //# sourceMappingURL=tango-app-ui-analyse-trax-audit-v2.module-Bpm0GYMw.mjs.map