{"version":3,"file":"sdcorejs-angular-components-operator.mjs","sources":["../../../projects/sdcorejs-angular/components/operator/src/operator.component.ts","../../../projects/sdcorejs-angular/components/operator/src/operator.component.html","../../../projects/sdcorejs-angular/components/operator/sdcorejs-angular-components-operator.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, booleanAttribute, computed, inject, input, model, viewChild } from '@angular/core';\nimport { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { OPERATORS } from '@sdcorejs/utils/constants';\nimport { Operator } from '@sdcorejs/utils/models';\nimport { I18nService } from '@sdcorejs/angular/i18n';\n\ninterface OperatorItem {\n  value: Operator;\n  icon: SafeHtml;\n  display: string;\n}\n\n@Component({\n  selector: 'sd-operator',\n  templateUrl: './operator.component.html',\n  styleUrl: './operator.component.scss',\n  standalone: true,\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  imports: [MatMenuModule, MatTooltipModule],\n})\nexport class SdOperator {\n  // Inner SVG markup (hình phễu) dùng khi chưa chọn operator.\n  static readonly FALLBACK_ICON = '<path d=\"M4 5h16l-6.5 7.5V19l-3 2v-8.5z\"/>';\n\n  readonly #i18n = inject(I18nService);\n  readonly #sanitizer = inject(DomSanitizer);\n\n  /** Operator hiện tại — binding hai chiều [(model)]. */\n  model = model<Operator | undefined>();\n\n  /** Danh sách operator cho phép, giữ nguyên thứ tự truyền vào. */\n  operators = input<Operator[]>([]);\n\n  /** Vô hiệu hóa trigger (không mở được menu). */\n  disabled = input(false, { transform: booleanAttribute });\n\n  /** data-autoId cho e2e selector. */\n  autoId = input<string>();\n\n  /** Allowed operators map sang { value, icon, display } theo thứ tự input. */\n  readonly items = computed<OperatorItem[]>(() => {\n    const out: OperatorItem[] = [];\n    for (const value of this.operators()) {\n      const r = this.#resolve(value);\n      if (!r) continue;\n      out.push({ value, icon: this.#svg(r.icon), display: r.display });\n    }\n    return out;\n  });\n\n  /** Icon SVG ở trigger — fallback phễu khi model chưa set / không tìm thấy. */\n  readonly currentIcon = computed<SafeHtml>(() => {\n    return this.#svg(this.#resolve(this.model())?.icon ?? SdOperator.FALLBACK_ICON);\n  });\n\n  /** Tooltip = i18n label của operator hiện tại ('' khi chưa chọn). */\n  readonly currentLabel = computed<string>(() => this.#resolve(this.model())?.display ?? '');\n\n  // Resolve một operator → { inner-svg, nhãn đã dịch } từ bảng OPERATORS dùng chung.\n  // why: OPERATORS[].display là i18n KEY ('core.operator.*.display'), KHÔNG phải text —\n  // phải dịch qua I18nService, nếu không UI hiện key thô (code) thay vì nhãn đã dịch.\n  #resolve(value: Operator | undefined): { icon: string; display: string } | undefined {\n    if (value == null) return undefined;\n    const entry = OPERATORS.find(o => o.value === value);\n    return entry ? { icon: entry.icon, display: this.#i18n.t(entry.display) } : undefined;\n  }\n\n  // why: OPERATORS.icon là inner SVG (path/line/rect). Bọc <svg> + bypass sanitizer\n  // (nguồn là hằng số nội bộ, không phải input người dùng) để Angular không strip svg con.\n  #svg(inner: string): SafeHtml {\n    return this.#sanitizer.bypassSecurityTrustHtml(\n      `<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${inner}</svg>`\n    );\n  }\n\n  private readonly trigger = viewChild(MatMenuTrigger);\n\n  /** Open the operator menu programmatically (used by the query-bar build flow). */\n  open(): void {\n    this.trigger()?.openMenu();\n  }\n\n  /** Chọn operator từ menu. */\n  select(value: Operator): void {\n    this.model.set(value);\n  }\n}\n","@let _model = model();\n\n<button\n  type=\"button\"\n  class=\"c-op-trigger\"\n  [disabled]=\"disabled()\"\n  [matMenuTriggerFor]=\"menu\"\n  [matTooltip]=\"currentLabel()\"\n  matTooltipPosition=\"above\"\n  [attr.data-autoId]=\"autoId() ?? null\">\n  <span class=\"c-op-icon\" [innerHTML]=\"currentIcon()\"></span>\n</button>\n\n<mat-menu #menu=\"matMenu\" class=\"c-op-menu\">\n  @for (item of items(); track item.value) {\n    <button\n      type=\"button\"\n      mat-menu-item\n      class=\"c-op-row\"\n      [class.c-op-active]=\"item.value === _model\"\n      (click)=\"select(item.value)\">\n      <span class=\"c-op-icon\" [innerHTML]=\"item.icon\"></span>\n      <span class=\"c-op-label\">{{ item.display }}</span>\n      <span class=\"c-op-code\">{{ item.value }}</span>\n    </button>\n  }\n</mat-menu>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}