@trismegisto/spine 3.3.2 → 3.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +15 -2
  2. package/fesm2022/trismegisto-spine-audit.mjs +6 -6
  3. package/fesm2022/trismegisto-spine-audit.mjs.map +1 -1
  4. package/fesm2022/{trismegisto-spine-auto-service-auto-service-client.component-BAfeLyTB.mjs → trismegisto-spine-auto-service-auto-service-client.component-kAXaCM5W.mjs} +8 -8
  5. package/fesm2022/{trismegisto-spine-auto-service-auto-service-client.component-BAfeLyTB.mjs.map → trismegisto-spine-auto-service-auto-service-client.component-kAXaCM5W.mjs.map} +1 -1
  6. package/fesm2022/{trismegisto-spine-auto-service-auto-service-groups.component-BYjIQ9ID.mjs → trismegisto-spine-auto-service-auto-service-groups.component-DE2QIGRH.mjs} +251 -85
  7. package/fesm2022/trismegisto-spine-auto-service-auto-service-groups.component-DE2QIGRH.mjs.map +1 -0
  8. package/fesm2022/{trismegisto-spine-auto-service-auto-service-news-page.component-CBemH4hr.mjs → trismegisto-spine-auto-service-auto-service-news-page.component-BW7BJ0oD.mjs} +2 -2
  9. package/fesm2022/{trismegisto-spine-auto-service-auto-service-news-page.component-CBemH4hr.mjs.map → trismegisto-spine-auto-service-auto-service-news-page.component-BW7BJ0oD.mjs.map} +1 -1
  10. package/fesm2022/{trismegisto-spine-auto-service-auto-service-ratings-page.component-C_THGTkw.mjs → trismegisto-spine-auto-service-auto-service-ratings-page.component-CHPU-QLJ.mjs} +2 -2
  11. package/fesm2022/{trismegisto-spine-auto-service-auto-service-ratings-page.component-C_THGTkw.mjs.map → trismegisto-spine-auto-service-auto-service-ratings-page.component-CHPU-QLJ.mjs.map} +1 -1
  12. package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-CkiCTmXD.mjs +3733 -0
  13. package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-CkiCTmXD.mjs.map +1 -0
  14. package/fesm2022/{trismegisto-spine-auto-service-auto-service.component-QsIQ61w2.mjs → trismegisto-spine-auto-service-auto-service.component-D58Ht9PH.mjs} +7 -7
  15. package/fesm2022/{trismegisto-spine-auto-service-auto-service.component-QsIQ61w2.mjs.map → trismegisto-spine-auto-service-auto-service.component-D58Ht9PH.mjs.map} +1 -1
  16. package/fesm2022/{trismegisto-spine-auto-service-groups.technical-_jQrg1Qh.mjs → trismegisto-spine-auto-service-groups.technical-CB1D3ANC.mjs} +12 -3
  17. package/fesm2022/trismegisto-spine-auto-service-groups.technical-CB1D3ANC.mjs.map +1 -0
  18. package/fesm2022/{trismegisto-spine-auto-service-groups.usage-OvWjNeeT.mjs → trismegisto-spine-auto-service-groups.usage-De2MhlE7.mjs} +7 -2
  19. package/fesm2022/{trismegisto-spine-auto-service-groups.usage-OvWjNeeT.mjs.map → trismegisto-spine-auto-service-groups.usage-De2MhlE7.mjs.map} +1 -1
  20. package/fesm2022/{trismegisto-spine-auto-service-home.component-rQ3dIGIE.mjs → trismegisto-spine-auto-service-home.component-9WvXOH3l.mjs} +7 -4
  21. package/fesm2022/trismegisto-spine-auto-service-home.component-9WvXOH3l.mjs.map +1 -0
  22. package/fesm2022/{trismegisto-spine-auto-service-suggestions.technical-BtUK6sKD.mjs → trismegisto-spine-auto-service-suggestions.technical-CGBBzAR8.mjs} +14 -1
  23. package/fesm2022/{trismegisto-spine-auto-service-suggestions.technical-BtUK6sKD.mjs.map → trismegisto-spine-auto-service-suggestions.technical-CGBBzAR8.mjs.map} +1 -1
  24. package/fesm2022/{trismegisto-spine-auto-service-suggestions.usage-BwO9Hjsx.mjs → trismegisto-spine-auto-service-suggestions.usage-DnAJS-Z0.mjs} +26 -3
  25. package/fesm2022/trismegisto-spine-auto-service-suggestions.usage-DnAJS-Z0.mjs.map +1 -0
  26. package/fesm2022/trismegisto-spine-auto-service.mjs +25 -12
  27. package/fesm2022/trismegisto-spine-auto-service.mjs.map +1 -1
  28. package/fesm2022/trismegisto-spine-graphql.mjs +3 -1
  29. package/fesm2022/trismegisto-spine-graphql.mjs.map +1 -1
  30. package/fesm2022/trismegisto-spine-layout-suggestions-page.component-CEKMqera.mjs +532 -0
  31. package/fesm2022/trismegisto-spine-layout-suggestions-page.component-CEKMqera.mjs.map +1 -0
  32. package/fesm2022/trismegisto-spine-layout-trismegisto-spine-layout-DiAfxIGP.mjs +8764 -0
  33. package/fesm2022/trismegisto-spine-layout-trismegisto-spine-layout-DiAfxIGP.mjs.map +1 -0
  34. package/fesm2022/trismegisto-spine-layout.mjs +1 -7662
  35. package/fesm2022/trismegisto-spine-layout.mjs.map +1 -1
  36. package/fesm2022/trismegisto-spine-notification.mjs +1 -1
  37. package/fesm2022/trismegisto-spine-notification.mjs.map +1 -1
  38. package/fesm2022/trismegisto-spine-routing.mjs +16 -3
  39. package/fesm2022/trismegisto-spine-routing.mjs.map +1 -1
  40. package/fesm2022/trismegisto-spine-shell.mjs +4 -2
  41. package/fesm2022/trismegisto-spine-shell.mjs.map +1 -1
  42. package/fesm2022/trismegisto-spine-side-panel.mjs +1 -1
  43. package/fesm2022/trismegisto-spine-side-panel.mjs.map +1 -1
  44. package/fesm2022/trismegisto-spine.mjs +813 -38
  45. package/fesm2022/trismegisto-spine.mjs.map +1 -1
  46. package/package.json +6 -6
  47. package/types/trismegisto-spine-auto-service.d.ts +20 -4
  48. package/types/trismegisto-spine-auto-service.d.ts.map +1 -1
  49. package/types/trismegisto-spine-layout.d.ts +1200 -74
  50. package/types/trismegisto-spine-layout.d.ts.map +1 -1
  51. package/types/trismegisto-spine-routing.d.ts.map +1 -1
  52. package/types/trismegisto-spine-shell.d.ts.map +1 -1
  53. package/types/trismegisto-spine.d.ts +350 -14
  54. package/types/trismegisto-spine.d.ts.map +1 -1
  55. package/fesm2022/trismegisto-spine-auto-service-auto-service-groups.component-BYjIQ9ID.mjs.map +0 -1
  56. package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-DIeunpQ9.mjs +0 -2123
  57. package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-DIeunpQ9.mjs.map +0 -1
  58. package/fesm2022/trismegisto-spine-auto-service-groups.technical-_jQrg1Qh.mjs.map +0 -1
  59. package/fesm2022/trismegisto-spine-auto-service-home.component-rQ3dIGIE.mjs.map +0 -1
  60. package/fesm2022/trismegisto-spine-auto-service-suggestions.usage-BwO9Hjsx.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"trismegisto-spine-auto-service-auto-service-news-page.component-CBemH4hr.mjs","sources":["../../../projects/ui/auto-service/src/tabs/auto-service-news/auto-service-news.service.ts","../../../projects/ui/auto-service/src/tabs/auto-service-news/auto-service-news.component.ts","../../../projects/ui/auto-service/src/tabs/auto-service-news/auto-service-news.component.html","../../../projects/ui/auto-service/src/pages/auto-service-news-page.component.ts"],"sourcesContent":["import { HttpClient, HttpHeaders } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { urlPath } from '@trismegisto/primitives';\nimport { AUTO_SERVICE_CONFIG } from '../../auto-service.tokens';\n\n/** Situação calculada pelo servidor (com o relógio do banco). */\nexport type AutoServiceNewsStatus = 'scheduled' | 'published' | 'expired';\n\n/**\n * Tipo de publicação: só texto (`informativo`); introdução + lista de mudanças (`implementacao`); ou introdução + antes\n * e agora (`alteracao`).\n */\nexport type AutoServiceNewsKind = 'informativo' | 'implementacao' | 'alteracao';\n\n/** Uma novidade do app (`GET /auto-service/:clientId/news`); o conteúdo (`body_html`, `items`, antes e agora) só no detalhe. */\nexport interface AutoServiceNews {\n id: string;\n /** Servidor antigo não manda: vale `informativo`. */\n kind?: AutoServiceNewsKind;\n title: string;\n summary: string;\n published_at: string;\n /** Último dia em que aparece (AAAA-MM-DD); null = não vence. */\n until: string | null;\n status: AutoServiceNewsStatus;\n /** Público restrito; vazio = todos que entram no app. */\n groups: { id: string; name: string }[];\n author: { id: string; username: string; name: string | null; picture: string | null } | null;\n created_at: string;\n updated_at: string;\n body_html?: string;\n items?: string[];\n before_html?: string;\n after_html?: string;\n}\n\nexport interface AutoServiceNewsPage { news: AutoServiceNews[]; total: number; page: number; limit: number }\n\n/**\n * Corpo de criar/editar. `published_at` null = agora; `group_ids` vazio = todos. `body_html` é o texto (informativo) ou\n * a introdução; `items` só na implementação e `before_html`/`after_html` só na alteração (nos outros tipos, vazios).\n */\nexport interface AutoServiceNewsWrite {\n kind: AutoServiceNewsKind;\n title: string;\n summary: string;\n body_html: string;\n items: string[];\n before_html: string;\n after_html: string;\n published_at: string | null;\n until: string | null;\n group_ids: string[];\n}\n\n/** Grupo que pode ser público (`GET .../news/audience`): os com acesso ao app, sem o de administração. */\nexport interface AutoServiceNewsAudienceGroup { id: string; name: string; description: string | null; enabled: boolean; member_count: number }\n\n/**\n * Novidades do app no auto-serviço (`{adminApi}/auto-service/:clientId/news*`): o servidor recorta pelo client da URL\n * e exige o grupo de administração com o crachá Administrador. Próprio da aba (o `AutoServiceService` é o das outras\n * telas).\n */\n@Injectable({ providedIn: 'root' })\nexport class AutoServiceNewsService {\n private readonly http = inject(HttpClient);\n private readonly auth = inject(AuthorizationService);\n private readonly config = inject(AUTO_SERVICE_CONFIG);\n\n private url(clientId: string, rest = ''): string {\n return `${this.config.adminApi}/auto-service${urlPath`/${clientId}`}/news${rest}`;\n }\n\n private get headers(): HttpHeaders {\n return new HttpHeaders({ 'x-access-token': this.auth.getToken() ?? '' });\n }\n\n list(clientId: string, page: number, limit: number): Promise<AutoServiceNewsPage> {\n return firstValueFrom(this.http.get<AutoServiceNewsPage>(this.url(clientId), { headers: this.headers, params: { page, limit } }));\n }\n\n get(clientId: string, newsId: string): Promise<AutoServiceNews> {\n return firstValueFrom(this.http.get<AutoServiceNews>(this.url(clientId, urlPath`/${newsId}`), { headers: this.headers }));\n }\n\n audience(clientId: string): Promise<{ groups: AutoServiceNewsAudienceGroup[] }> {\n return firstValueFrom(this.http.get<{ groups: AutoServiceNewsAudienceGroup[] }>(this.url(clientId, '/audience'), { headers: this.headers }));\n }\n\n create(clientId: string, body: AutoServiceNewsWrite): Promise<AutoServiceNews> {\n return firstValueFrom(this.http.post<AutoServiceNews>(this.url(clientId), body, { headers: this.headers }));\n }\n\n update(clientId: string, newsId: string, body: AutoServiceNewsWrite): Promise<AutoServiceNews> {\n return firstValueFrom(this.http.put<AutoServiceNews>(this.url(clientId, urlPath`/${newsId}`), body, { headers: this.headers }));\n }\n\n remove(clientId: string, newsId: string): Promise<void> {\n return firstValueFrom(this.http.delete<void>(this.url(clientId, urlPath`/${newsId}`), { headers: this.headers }));\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input, effect, signal, untracked } from '@angular/core';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport {\n AccountAvatarComponent, AlertComponent, ButtonComponent, ComboboxMultiComponent, ComboboxOption, DataGridActionTriggered,\n DataGridCellDirective, DataGridComponent, DataGridRowAction, DatePickerComponent, GridColumn, HermesDialogService, IconComponent,\n InputComponent, ListEditorComponent, type ListEditorValidator, ModalComponent, RichTextComponent, SegmentedControlComponent,\n type SegmentedOption, TagComponent, TextareaComponent, TimePickerComponent,\n} from '@trismegisto/angular';\nimport { formatMessage, type PaginationState } from '@trismegisto/primitives';\nimport { SPINE_MESSAGES, type SpineMessages } from '@trismegisto/spine';\nimport { AutoServiceDeleteFeedback } from '../../auto-service-delete';\nimport {\n AutoServiceNews, AutoServiceNewsKind, AutoServiceNewsService, AutoServiceNewsStatus, AutoServiceNewsWrite,\n} from './auto-service-news.service';\n\ntype NewsText = SpineMessages['autoServiceNews'];\n\nconst PAGE_SIZE = 20;\nconst TITLE_MAX = 140;\nconst SUMMARY_MAX = 300;\n\nlet sequence = 0;\n\n/** Teto da lista de mudanças (implementação) e de cada item -- os mesmos do servidor. */\nconst ITEMS_MAX = 30;\nconst ITEM_MAX = 300;\n\n/** Ícone de cada tipo (seletor do topo e prévia). */\nconst KIND_ICONS: Record<AutoServiceNewsKind, string> = {\n informativo: 'file-text',\n implementacao: 'rocket-diagonal',\n alteracao: 'two-way-arrows',\n};\n\n/** HTML de rich text com texto de verdade (não só tags vazias). */\nexport function newsHtmlHasText(html: string | null | undefined): boolean {\n return !!html && html.replace(/<[^>]*>/g, '').replace(/&nbsp;|&#160;/g, ' ').trim() !== '';\n}\n\nconst pad = (n: number) => String(n).padStart(2, '0');\n\n/** Data e hora LOCAIS (do navegador) de um instante ISO, no formato dos campos (`AAAA-MM-DD`, `HH:mm`). */\nexport function newsLocalParts(iso: string): { date: string | null; time: string | null } {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return { date: null, time: null };\n return { date: `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`, time: `${pad(d.getHours())}:${pad(d.getMinutes())}` };\n}\n\n/** Instante ISO (UTC) da data e hora locais dos campos; sem data = null (o servidor publica ao salvar); sem hora = 00:00. */\nexport function newsPublishedAt(date: string | null, time: string | null): string | null {\n if (!date) return null;\n const d = new Date(`${date}T${time || '00:00'}:00`);\n return Number.isNaN(d.getTime()) ? null : d.toISOString();\n}\n\n/** Código do argos-admin (`{ error }`) → texto no idioma ativo; desconhecido, o `detail` do servidor ou `fallback`. */\nexport function newsErrorText(err: unknown, text: NewsText, fallback: string): string {\n if (!(err instanceof HttpErrorResponse)) return fallback;\n const body = err.error as { error?: unknown; detail?: unknown } | null;\n const known: Record<string, string> = {\n invalid_title: text.errors.invalidTitle,\n invalid_summary: text.errors.invalidSummary,\n body_too_large: text.errors.bodyTooLarge,\n invalid_published_at: text.errors.invalidPublishedAt,\n invalid_until: text.errors.invalidUntil,\n invalid_group_ids: text.errors.invalidGroupIds,\n invalid_kind: text.errors.invalidKind,\n invalid_items: text.errors.invalidItems,\n invalid_compare: text.errors.invalidCompare,\n compare_too_large: text.errors.compareTooLarge,\n };\n const code = typeof body?.error === 'string' ? body.error : '';\n if (Object.prototype.hasOwnProperty.call(known, code)) return known[code];\n return typeof body?.detail === 'string' && body.detail ? body.detail : fallback;\n}\n\n/**\n * O editor. `body` é o texto (informativo) ou a introdução (implementação, alteração). Trocar de tipo guarda o que já\n * foi escrito nos campos dos outros tipos; só o do tipo escolhido vai para o servidor.\n */\ninterface NewsForm {\n kind: AutoServiceNewsKind;\n title: string;\n summary: string;\n body: string;\n items: string[];\n before: string;\n after: string;\n publishDate: string | null;\n publishTime: string | null;\n until: string | null;\n groupIds: string[];\n}\n\nconst emptyForm = (): NewsForm => ({\n kind: 'informativo', title: '', summary: '', body: '', items: [], before: '', after: '', publishDate: null, publishTime: null,\n until: null, groupIds: [],\n});\n\n/**\n * Aba Novidades do Cliente: o que o spine mostra em \"Novidades\" (menu do perfil, aviso da entrada, card do Início)\n * para quem entra no app. Grade paginada no servidor (agendadas e vencidas também), criar/editar num modal e excluir\n * com confirmação (no menu da linha ou no rodapé do modal, ao editar). O modal é um editor em seções numeradas\n * (título e resumo, texto em rich text, publicação, validade e público) com a prévia ao vivo do card do Início ao\n * lado. Sem rascunho: a novidade não tem esse estado (sem data, sai ao salvar). O texto é saneado pelo argos-admin ao\n * gravar; o público vazio é todo mundo que entra no app.\n */\n@Component({\n selector: 'spine-auto-service-news',\n imports: [\n AccountAvatarComponent, AlertComponent, ButtonComponent, ComboboxMultiComponent, DataGridComponent, DataGridCellDirective,\n DatePickerComponent, IconComponent, InputComponent, ListEditorComponent, ModalComponent, RichTextComponent, SegmentedControlComponent,\n TagComponent, TextareaComponent, TimePickerComponent,\n ],\n templateUrl: './auto-service-news.component.html',\n styleUrls: ['./auto-service-news.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AutoServiceNewsComponent {\n private readonly service = inject(AutoServiceNewsService);\n private readonly deletion = inject(AutoServiceDeleteFeedback);\n private readonly dialogs = inject(HermesDialogService);\n protected readonly text = inject(SPINE_MESSAGES).autoServiceNews;\n protected readonly common = inject(SPINE_MESSAGES).autoService;\n /** Rótulos do card Novidades do Início, repetidos na prévia. */\n protected readonly home = inject(SPINE_MESSAGES).home;\n protected readonly uid = `spine-as-news-${++sequence}`;\n private readonly dateFormat = new Intl.DateTimeFormat(inject(SPINE_MESSAGES).meta.locale, { dateStyle: 'short', timeStyle: 'short' });\n private readonly dayFormat = new Intl.DateTimeFormat(inject(SPINE_MESSAGES).meta.locale, { dateStyle: 'short', timeZone: 'UTC' });\n protected readonly TITLE_MAX = TITLE_MAX;\n protected readonly SUMMARY_MAX = SUMMARY_MAX;\n protected readonly ITEMS_MAX = ITEMS_MAX;\n /** Tipos do seletor do topo, com ícone. */\n protected readonly kindOptions: readonly SegmentedOption<AutoServiceNewsKind>[] = [\n { value: 'informativo', label: this.text.kindInformativo, icon: KIND_ICONS.informativo },\n { value: 'implementacao', label: this.text.kindImplementacao, icon: KIND_ICONS.implementacao },\n { value: 'alteracao', label: this.text.kindAlteracao, icon: KIND_ICONS.alteracao },\n ];\n /** Cada mudança até 300 caracteres (o vazio e o repetido o próprio hm-list-editor recusa). */\n protected readonly itemRule: ListEditorValidator<string> = (item) =>\n item.length > ITEM_MAX ? this.text.errors.invalidItems : null;\n\n readonly clientId = input('');\n\n protected readonly rows = signal<AutoServiceNews[]>([]);\n protected readonly total = signal(0);\n protected readonly pageState = signal<PaginationState>({ page: 1, size: PAGE_SIZE });\n protected readonly loading = signal(false);\n protected readonly loadError = signal('');\n protected readonly audienceOptions = signal<ComboboxOption[]>([]);\n\n protected readonly modalOpen = signal(false);\n protected readonly editingId = signal('');\n protected form: NewsForm = emptyForm();\n protected readonly saving = signal(false);\n protected readonly saveError = signal<string | null>(null);\n /** O texto da novidade em edição ainda está vindo (o editor espera). */\n protected readonly loadingBody = signal(false);\n /** Excluindo pelo rodapé do modal. */\n protected readonly removing = signal(false);\n\n readonly rowId = (n: AutoServiceNews) => n.id;\n readonly columns = computed<GridColumn<AutoServiceNews>[]>(() => [\n { key: 'title', title: this.text.colTitle, value: (n) => n.title },\n { key: 'status', title: this.text.colStatus, value: (n) => this.statusLabel(n.status) },\n { key: 'published_at', title: this.text.colPublishedAt, value: (n) => this.formatDate(n.published_at) },\n { key: 'until', title: this.text.colUntil, value: (n) => this.formatDay(n.until) },\n { key: 'groups', title: this.text.colAudience, value: (n) => n.groups.map((g) => g.name).join(', ') || this.text.audienceAll },\n { key: 'author', title: this.text.colAuthor, value: (n) => n.author?.name || n.author?.username || '' },\n ]);\n readonly rowActions = computed<DataGridRowAction<AutoServiceNews>[]>(() => [\n { id: 'edit', icon: 'pencil', label: this.common.edit },\n {\n id: 'delete', icon: 'trash', label: this.common.delete, danger: true, separatorAbove: true,\n confirm: (n) => ({ heading: this.text.confirmDeleteHeading, message: formatMessage(this.text.confirmDelete, { title: n.title }) }),\n },\n ]);\n\n /** Validade antes do dia da publicação: a novidade nunca apareceria. */\n protected get untilBeforePublish(): boolean {\n const publishDay = this.form.publishDate ?? newsLocalParts(new Date().toISOString()).date;\n return !!this.form.until && !!publishDay && this.form.until < publishDay;\n }\n\n /** Data e hora da prévia: as dos campos; sem data, \"ao salvar\". */\n protected get previewDate(): string {\n const at = newsPublishedAt(this.form.publishDate, this.form.publishTime);\n return at ? this.formatDate(at) : this.text.previewNow;\n }\n\n /** Publicação no futuro: a prévia marca \"Agendada\". */\n protected get previewScheduled(): boolean {\n const at = newsPublishedAt(this.form.publishDate, this.form.publishTime);\n return !!at && new Date(at).getTime() > Date.now();\n }\n\n protected get canSave(): boolean {\n const title = this.form.title.trim();\n return !!title && title.length <= TITLE_MAX && this.form.summary.trim().length <= SUMMARY_MAX && !this.untilBeforePublish\n && this.kindReady;\n }\n\n /** O conteúdo do tipo está completo: a implementação com ao menos uma mudança; a alteração com o antes e o agora. */\n protected get kindReady(): boolean {\n if (this.form.kind === 'implementacao') return this.form.items.length > 0 && this.form.items.length <= ITEMS_MAX;\n if (this.form.kind === 'alteracao') return newsHtmlHasText(this.form.before) && newsHtmlHasText(this.form.after);\n return true;\n }\n\n protected get kindIcon(): string {\n return KIND_ICONS[this.form.kind];\n }\n\n protected get kindLabel(): string {\n return this.kindOptions.find((o) => o.value === this.form.kind)?.label ?? '';\n }\n\n protected setKind(kind: string): void {\n if (kind === 'informativo' || kind === 'implementacao' || kind === 'alteracao') this.form = { ...this.form, kind };\n this.saveError.set(null);\n }\n\n constructor() {\n effect(() => {\n const id = this.clientId();\n untracked(() => {\n this.pageState.set({ page: 1, size: this.pageState().size });\n void this.load();\n void this.loadAudience(id);\n });\n });\n }\n\n protected statusLabel(status: AutoServiceNewsStatus): string {\n return status === 'scheduled' ? this.text.statusScheduled : status === 'expired' ? this.text.statusExpired : this.text.statusPublished;\n }\n\n protected statusColor(status: AutoServiceNewsStatus): 'info' | 'success' | 'neutral' {\n return status === 'scheduled' ? 'info' : status === 'expired' ? 'neutral' : 'success';\n }\n\n protected formatDate(iso: string): string {\n const d = new Date(iso);\n return Number.isNaN(d.getTime()) ? '' : this.dateFormat.format(d);\n }\n\n /** `until` é um dia (AAAA-MM-DD), sem fuso: formatado em UTC para não mudar de dia. */\n protected formatDay(day: string | null): string {\n if (!day) return this.text.noUntil;\n const d = new Date(`${day}T00:00:00Z`);\n return Number.isNaN(d.getTime()) ? day : this.dayFormat.format(d);\n }\n\n async load(page = this.pageState().page, size = this.pageState().size): Promise<void> {\n const clientId = this.clientId();\n if (!clientId) { this.rows.set([]); this.total.set(0); return; }\n this.loading.set(true);\n this.loadError.set('');\n try {\n const res = await this.service.list(clientId, page, size);\n this.rows.set(res.news ?? []);\n this.total.set(res.total ?? 0);\n this.pageState.set({ page, size });\n } catch (err) {\n this.rows.set([]);\n this.total.set(0);\n this.loadError.set(newsErrorText(err, this.text, this.text.loadError));\n } finally {\n this.loading.set(false);\n }\n }\n\n /** Sem a lista de público o campo fica sem opção (a novidade sai para todos). */\n private async loadAudience(clientId: string): Promise<void> {\n if (!clientId) { this.audienceOptions.set([]); return; }\n try {\n const res = await this.service.audience(clientId);\n this.audienceOptions.set((res.groups ?? []).map((g) => ({ value: g.id, label: g.name })));\n } catch {\n this.audienceOptions.set([]);\n }\n }\n\n protected onPageStateChange(state: PaginationState): void {\n void this.load(state.page, state.size);\n }\n\n protected openCreate(): void {\n this.editingId.set('');\n this.form = emptyForm();\n this.saveError.set(null);\n this.loadingBody.set(false);\n this.removing.set(false);\n this.modalOpen.set(true);\n }\n\n /** O corpo não vem na lista: busca o detalhe antes de liberar o editor. */\n protected async openEdit(row: AutoServiceNews): Promise<void> {\n const parts = newsLocalParts(row.published_at);\n this.editingId.set(row.id);\n this.form = {\n kind: row.kind ?? 'informativo', title: row.title, summary: row.summary, body: '', items: [], before: '', after: '',\n publishDate: parts.date, publishTime: parts.time, until: row.until, groupIds: row.groups.map((g) => g.id),\n };\n this.saveError.set(null);\n this.loadingBody.set(true);\n this.removing.set(false);\n this.modalOpen.set(true);\n try {\n const full = await this.service.get(this.clientId(), row.id);\n if (this.editingId() === row.id) {\n this.form = {\n ...this.form, kind: full.kind ?? this.form.kind, body: full.body_html ?? '', items: [...(full.items ?? [])],\n before: full.before_html ?? '', after: full.after_html ?? '',\n };\n }\n } catch (err) {\n this.saveError.set(newsErrorText(err, this.text, this.text.loadError));\n } finally {\n this.loadingBody.set(false);\n }\n }\n\n protected async save(): Promise<void> {\n if (!this.canSave || this.saving() || this.loadingBody()) return;\n const body: AutoServiceNewsWrite = {\n kind: this.form.kind,\n title: this.form.title.trim(),\n summary: this.form.summary.trim(),\n body_html: this.form.body,\n // Só o conteúdo do tipo escolhido; o resto vai vazio (o servidor zera também).\n items: this.form.kind === 'implementacao' ? [...this.form.items] : [],\n before_html: this.form.kind === 'alteracao' ? this.form.before : '',\n after_html: this.form.kind === 'alteracao' ? this.form.after : '',\n published_at: newsPublishedAt(this.form.publishDate, this.form.publishTime),\n until: this.form.until || null,\n group_ids: [...this.form.groupIds],\n };\n this.saving.set(true);\n this.saveError.set(null);\n try {\n if (this.editingId()) await this.service.update(this.clientId(), this.editingId(), body);\n else await this.service.create(this.clientId(), body);\n } catch (err) {\n // O modal fica aberto com o motivo no idioma ativo.\n this.saveError.set(newsErrorText(err, this.text, this.text.saveError));\n return;\n } finally {\n this.saving.set(false);\n }\n this.modalOpen.set(false);\n await this.load(this.editingId() ? this.pageState().page : 1);\n }\n\n /** \"Excluir\" no rodapé do modal (só ao editar): confirma, exclui, fecha e recarrega; falha deixa o modal aberto. */\n protected async removeFromModal(): Promise<void> {\n const id = this.editingId();\n if (!id || this.saving() || this.removing()) return;\n const title = this.form.title.trim();\n const ok = await this.dialogs.confirm({\n heading: this.text.confirmDeleteHeading, message: formatMessage(this.text.confirmDelete, { title }),\n confirmLabel: this.common.delete, danger: true,\n });\n if (!ok || this.editingId() !== id || !this.modalOpen()) return;\n this.removing.set(true);\n try {\n if (!(await this.deletion.run(() => this.service.remove(this.clientId(), id)))) return;\n } finally {\n this.removing.set(false);\n }\n this.modalOpen.set(false);\n await this.load();\n }\n\n /** Já confirmado pelo `confirm` da ação na grade. */\n private async remove(row: AutoServiceNews): Promise<void> {\n if (await this.deletion.run(() => this.service.remove(this.clientId(), row.id))) await this.load();\n }\n\n protected onAction(e: DataGridActionTriggered<AutoServiceNews>): void {\n if (e.action === 'edit') void this.openEdit(e.row);\n if (e.action === 'delete') void this.remove(e.row);\n }\n}\n","<!-- Paginação no servidor (agendadas e vencidas também); a busca/filtro local da grade fica desligada. -->\n<hm-data-grid\n [columns]=\"columns()\"\n [rows]=\"rows()\"\n [rowId]=\"rowId\"\n [caption]=\"text.caption\"\n [loading]=\"loading()\"\n [error]=\"loadError()\"\n [emptyMessage]=\"text.empty\"\n [rowActions]=\"rowActions()\"\n [filterable]=\"false\"\n [paginated]=\"false\"\n [totalItems]=\"total()\"\n [pageState]=\"pageState()\"\n (pageStateChange)=\"onPageStateChange($event)\"\n [pageSizes]=\"[10, 20, 50, 100]\"\n (actionTriggered)=\"onAction($event)\"\n>\n <hm-button dataGridActions icon=\"plus\" (clicked)=\"openCreate()\">{{ text.newNews }}</hm-button>\n <ng-template hmCell=\"title\" let-n>\n <span class=\"news-title\">\n <span>{{ n.title }}</span>\n @if (n.summary) { <span class=\"news-title__summary\">{{ n.summary }}</span> }\n </span>\n </ng-template>\n <ng-template hmCell=\"status\" let-n>\n <hm-tag [name]=\"statusLabel(n.status)\" [color]=\"statusColor(n.status)\" />\n </ng-template>\n <ng-template hmCell=\"groups\" let-n>\n @if (n.groups.length) {\n <span class=\"news-tags\">\n @for (g of n.groups; track g.id) { <hm-tag [name]=\"g.name\" color=\"info\" /> }\n </span>\n } @else {\n <span class=\"muted\">{{ text.audienceAll }}</span>\n }\n </ng-template>\n <ng-template hmCell=\"author\" let-n>\n @if (n.author; as a) {\n <span class=\"news-author\">\n <hm-account-avatar size=\"small\" [name]=\"a.name || a.username\" [imageUrl]=\"a.picture\" />\n <span>{{ a.name || a.username }}</span>\n </span>\n }\n </ng-template>\n</hm-data-grid>\n\n<!-- Modal: criar/editar novidade. O cabeçalho do hm-modal some da vista (o título segue como nome do diálogo, ver o\n .scss) e o editor desenha o seu: ícone, título e subtítulo. Pensado para caber sem rolagem num notebook: em cima,\n \"1. Informações principais\" (título) com o resumo ao lado; embaixo, o conteúdo do tipo escolhido no topo (texto;\n introdução + lista; ou introdução + antes e agora), que estica e rola por dentro, ao lado do painel com publicação,\n validade, público, dica e a prévia do Início no fim. O modal não rola; em tela estreita, tudo empilha. -->\n<hm-modal [open]=\"modalOpen()\" (openChange)=\"modalOpen.set($event)\" [heading]=\"editingId() ? text.editNews : text.newNews\" size=\"xlarge\"\n (closed)=\"modalOpen.set(false)\">\n <div class=\"ne\">\n <header class=\"ne-head\">\n <span class=\"ne-head__icon\" aria-hidden=\"true\"><hm-icon shape=\"announcement\" size=\"md\" /></span>\n <span class=\"ne-head__text\">\n <!-- O h2 do hm-modal já dá o nome ao diálogo: este é só o visual. -->\n <span class=\"ne-head__title\" aria-hidden=\"true\">{{ editingId() ? text.editNews : text.newNews }}</span>\n <span class=\"ne-head__intro\">{{ editingId() ? text.editNewsIntro : text.newNewsIntro }}</span>\n </span>\n <!-- Tipo de publicação: muda os campos do conteúdo e a prévia. -->\n <hm-segmented-control class=\"ne-kind\" [label]=\"text.kind\" [options]=\"kindOptions\" [value]=\"form.kind\" (valueChange)=\"setKind($event)\" />\n </header>\n\n <div class=\"ne-scroll\">\n @if (saveError()) { <hm-alert variant=\"error\">{{ saveError() }}</hm-alert> }\n\n <div class=\"ne-grid\">\n <!-- Linha de cima: a seção 1 ocupa as duas colunas (subgrid): título à esquerda, resumo à direita. -->\n <section class=\"ne-section ne-intro\" [attr.aria-labelledby]=\"uid + '-main'\">\n <div class=\"ne-intro__lead\">\n <div class=\"ne-section__head\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-main'\"><span class=\"ne-step\" aria-hidden=\"true\">1</span>{{ text.sectionMain }}</h3>\n <p class=\"ne-section__hint\">{{ text.sectionMainHint }}</p>\n </div>\n <hm-input [label]=\"text.title\" required [maxLength]=\"TITLE_MAX\" [(value)]=\"form.title\" (valueChange)=\"saveError.set(null)\" />\n </div>\n <hm-textarea class=\"ne-intro__summary\" [label]=\"text.summary\" [hint]=\"text.summaryHint\" [rows]=\"3\" [maxLength]=\"SUMMARY_MAX\"\n [(value)]=\"form.summary\" />\n </section>\n\n <section class=\"ne-section ne-content\" [attr.aria-labelledby]=\"uid + '-body'\">\n <div class=\"ne-section__head\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-body'\"><span class=\"ne-step\" aria-hidden=\"true\">2</span>{{ text.sectionBody }}</h3>\n <p class=\"ne-section__hint\">\n {{ form.kind === 'implementacao' ? text.sectionBodyHintImpl : form.kind === 'alteracao' ? text.sectionBodyHintAlt : text.sectionBodyHint }}\n </p>\n </div>\n <!-- Estica até o fim da linha; quem rola é o texto (ou a lista), não o modal. -->\n @switch (form.kind) {\n @case ('implementacao') {\n <hm-rich-text class=\"ne-content__intro\" [label]=\"text.intro\" [rows]=\"2\" [maxRows]=\"4\" [loading]=\"loadingBody()\"\n [(value)]=\"form.body\" />\n <div class=\"ne-content__items\">\n <hm-list-editor [label]=\"text.items\" [hint]=\"text.itemsHint\" [placeholder]=\"text.itemPlaceholder\" [emptyText]=\"text.itemsEmpty\"\n [max]=\"ITEMS_MAX\" [validate]=\"itemRule\" editable [items]=\"form.items\" (itemsChange)=\"form.items = [...$event]\" />\n </div>\n }\n @case ('alteracao') {\n <hm-rich-text class=\"ne-content__intro\" [label]=\"text.intro\" [rows]=\"2\" [maxRows]=\"4\" [loading]=\"loadingBody()\"\n [(value)]=\"form.body\" />\n <div class=\"ne-content__compare\">\n <hm-rich-text class=\"ne-content__editor ne-content__editor--labelled\" [label]=\"text.before\" required [rows]=\"4\" [maxRows]=\"16\" [loading]=\"loadingBody()\"\n [(value)]=\"form.before\" />\n <hm-rich-text class=\"ne-content__editor ne-content__editor--labelled\" [label]=\"text.after\" required [rows]=\"4\" [maxRows]=\"16\" [loading]=\"loadingBody()\"\n [(value)]=\"form.after\" />\n </div>\n }\n @default {\n <hm-rich-text class=\"ne-content__editor\" [label]=\"text.sectionBody\" labelHidden [hint]=\"text.bodyHint\" [rows]=\"6\" [maxRows]=\"24\"\n showCounter [loading]=\"loadingBody()\" [(value)]=\"form.body\" />\n }\n }\n </section>\n\n <aside class=\"ne-side\">\n <section class=\"ne-section ne-side__publish\" [attr.aria-labelledby]=\"uid + '-publish'\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-publish'\"><span class=\"ne-step\" aria-hidden=\"true\">3</span>{{ text.sectionPublish }}</h3>\n <div class=\"ne-row\">\n <hm-date-picker [label]=\"text.publishDate\" [(value)]=\"form.publishDate\" />\n <hm-time-picker [label]=\"text.publishTime\" [(value)]=\"form.publishTime\" />\n </div>\n <p class=\"ne-note\">{{ text.publishHint }}</p>\n </section>\n\n <section class=\"ne-section ne-side__until\" [attr.aria-labelledby]=\"uid + '-until'\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-until'\"><span class=\"ne-step\" aria-hidden=\"true\">4</span>{{ text.sectionUntil }}</h3>\n <hm-date-picker [label]=\"text.untilDate\" [hint]=\"text.untilHint\" [min]=\"form.publishDate\" [(value)]=\"form.until\" />\n @if (untilBeforePublish) { <hm-alert variant=\"warning\">{{ text.errors.untilBeforePublish }}</hm-alert> }\n </section>\n\n <section class=\"ne-section ne-side__audience\" [attr.aria-labelledby]=\"uid + '-audience'\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-audience'\"><span class=\"ne-step\" aria-hidden=\"true\">5</span>{{ text.sectionAudience }}</h3>\n <!-- Vazio = todos que entram no app. -->\n <hm-combobox-multi [label]=\"text.audienceGroups\" [hint]=\"text.audienceHint\" [placeholder]=\"text.audienceAll\" [options]=\"audienceOptions()\"\n [visibleChipsLimit]=\"null\" [selected]=\"form.groupIds\" (selectedChange)=\"form.groupIds = [...$event]\" />\n </section>\n\n <p class=\"ne-tip\"><hm-icon class=\"ne-tip__icon\" shape=\"lightbulb\" size=\"sm\" /><span><strong>{{ text.tipTitle }}</strong> {{ text.tipText }}</span></p>\n\n <section class=\"ne-section ne-side__preview\" [attr.aria-labelledby]=\"uid + '-preview'\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-preview'\"><hm-icon class=\"ne-section__icon\" shape=\"eye\" size=\"sm\" />{{ text.preview }}</h3>\n <!-- Mesmo desenho do card Novidades do Início; repete o que está nos campos, então fica fora da leitura. -->\n <div class=\"ne-preview\" aria-hidden=\"true\">\n <div class=\"ne-preview__head\">\n <span class=\"ne-preview__heading\">{{ home.news }}</span>\n <span class=\"ne-preview__badge\">{{ home.newsBadge }}</span>\n </div>\n <div class=\"ne-preview__item\">\n <span class=\"ne-preview__icon\"><hm-icon [shape]=\"kindIcon\" size=\"sm\" /></span>\n <span class=\"ne-preview__text\">\n <span class=\"ne-preview__title\" [class.ne-preview__placeholder]=\"!form.title.trim()\">{{ form.title.trim() || text.previewTitle }}</span>\n <span class=\"ne-preview__summary\" [class.ne-preview__placeholder]=\"!form.summary.trim()\">{{ form.summary.trim() || text.previewSummary }}</span>\n <span class=\"ne-preview__date\">\n <hm-icon shape=\"calendar\" size=\"xs\" />{{ previewDate }}\n @if (previewScheduled) { <span class=\"ne-preview__status\">{{ text.statusScheduled }}</span> }\n <span class=\"ne-preview__kind\">{{ kindLabel }}</span>\n </span>\n </span>\n <hm-icon class=\"ne-preview__chevron\" shape=\"angle-right\" size=\"sm\" />\n </div>\n </div>\n </section>\n </aside>\n </div>\n </div>\n </div>\n\n <ng-container footer>\n <!-- Sem rascunho: a novidade não tem esse estado (sem data = publica ao salvar). -->\n @if (editingId()) {\n <hm-button class=\"ne-delete\" emphasis=\"medium\" intent=\"danger\" icon=\"trash\" [disabled]=\"saving() || removing()\" [loading]=\"removing()\"\n (clicked)=\"removeFromModal()\">{{ common.delete }}</hm-button>\n }\n <hm-button emphasis=\"medium\" (clicked)=\"modalOpen.set(false)\">{{ common.cancel }}</hm-button>\n <hm-button [disabled]=\"!canSave || loadingBody() || removing()\" [loading]=\"saving()\" (clicked)=\"save()\">\n {{ editingId() ? common.save : common.create }}\n </hm-button>\n </ng-container>\n</hm-modal>\n","import { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { AutoServiceClient, AutoServiceClientPickerComponent } from '../client-picker/auto-service-client-picker.component';\nimport { AutoServiceNewsComponent } from '../tabs/auto-service-news/auto-service-news.component';\n\n/**\n * Tela \"Novidades\" do auto-serviço (router `AUTO_SERVICE_NEWS_TEMPLATE_ROUTER_ID`, na raiz do menu; migration 0036 do\n * argos): o seletor de client + o painel de novidades que era a aba Cliente › Novidades. Carregada só por\n * `AUTO_SERVICE_SCREENS.news` -- nunca exportada pelo ponto de entrada (ver `public-api.ts`).\n */\n@Component({\n selector: 'spine-auto-service-news-page',\n imports: [AutoServiceClientPickerComponent, AutoServiceNewsComponent],\n // Sem título/descrição internos: vêm da barra da página do spine (nome da rota + descrição do router AD100006).\n template: `\n <div class=\"as-stack\">\n <spine-auto-service-client-picker (clientChange)=\"client.set($event)\" />\n @if (client(); as c) {\n <spine-auto-service-news [clientId]=\"c.id\" />\n }\n </div>\n `,\n styleUrl: './auto-service-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AutoServiceNewsPageComponent {\n protected readonly client = signal<AutoServiceClient | null>(null);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trismegisto-spine-auto-service-auto-service-news-page.component-BW7BJ0oD.mjs","sources":["../../../projects/ui/auto-service/src/tabs/auto-service-news/auto-service-news.service.ts","../../../projects/ui/auto-service/src/tabs/auto-service-news/auto-service-news.component.ts","../../../projects/ui/auto-service/src/tabs/auto-service-news/auto-service-news.component.html","../../../projects/ui/auto-service/src/pages/auto-service-news-page.component.ts"],"sourcesContent":["import { HttpClient, HttpHeaders } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { urlPath } from '@trismegisto/primitives';\nimport { AUTO_SERVICE_CONFIG } from '../../auto-service.tokens';\n\n/** Situação calculada pelo servidor (com o relógio do banco). */\nexport type AutoServiceNewsStatus = 'scheduled' | 'published' | 'expired';\n\n/**\n * Tipo de publicação: só texto (`informativo`); introdução + lista de mudanças (`implementacao`); ou introdução + antes\n * e agora (`alteracao`).\n */\nexport type AutoServiceNewsKind = 'informativo' | 'implementacao' | 'alteracao';\n\n/** Uma novidade do app (`GET /auto-service/:clientId/news`); o conteúdo (`body_html`, `items`, antes e agora) só no detalhe. */\nexport interface AutoServiceNews {\n id: string;\n /** Servidor antigo não manda: vale `informativo`. */\n kind?: AutoServiceNewsKind;\n title: string;\n summary: string;\n published_at: string;\n /** Último dia em que aparece (AAAA-MM-DD); null = não vence. */\n until: string | null;\n status: AutoServiceNewsStatus;\n /** Público restrito; vazio = todos que entram no app. */\n groups: { id: string; name: string }[];\n author: { id: string; username: string; name: string | null; picture: string | null } | null;\n created_at: string;\n updated_at: string;\n body_html?: string;\n items?: string[];\n before_html?: string;\n after_html?: string;\n}\n\nexport interface AutoServiceNewsPage { news: AutoServiceNews[]; total: number; page: number; limit: number }\n\n/**\n * Corpo de criar/editar. `published_at` null = agora; `group_ids` vazio = todos. `body_html` é o texto (informativo) ou\n * a introdução; `items` só na implementação e `before_html`/`after_html` só na alteração (nos outros tipos, vazios).\n */\nexport interface AutoServiceNewsWrite {\n kind: AutoServiceNewsKind;\n title: string;\n summary: string;\n body_html: string;\n items: string[];\n before_html: string;\n after_html: string;\n published_at: string | null;\n until: string | null;\n group_ids: string[];\n}\n\n/** Grupo que pode ser público (`GET .../news/audience`): os com acesso ao app, sem o de administração. */\nexport interface AutoServiceNewsAudienceGroup { id: string; name: string; description: string | null; enabled: boolean; member_count: number }\n\n/**\n * Novidades do app no auto-serviço (`{adminApi}/auto-service/:clientId/news*`): o servidor recorta pelo client da URL\n * e exige o grupo de administração com o crachá Administrador. Próprio da aba (o `AutoServiceService` é o das outras\n * telas).\n */\n@Injectable({ providedIn: 'root' })\nexport class AutoServiceNewsService {\n private readonly http = inject(HttpClient);\n private readonly auth = inject(AuthorizationService);\n private readonly config = inject(AUTO_SERVICE_CONFIG);\n\n private url(clientId: string, rest = ''): string {\n return `${this.config.adminApi}/auto-service${urlPath`/${clientId}`}/news${rest}`;\n }\n\n private get headers(): HttpHeaders {\n return new HttpHeaders({ 'x-access-token': this.auth.getToken() ?? '' });\n }\n\n list(clientId: string, page: number, limit: number): Promise<AutoServiceNewsPage> {\n return firstValueFrom(this.http.get<AutoServiceNewsPage>(this.url(clientId), { headers: this.headers, params: { page, limit } }));\n }\n\n get(clientId: string, newsId: string): Promise<AutoServiceNews> {\n return firstValueFrom(this.http.get<AutoServiceNews>(this.url(clientId, urlPath`/${newsId}`), { headers: this.headers }));\n }\n\n audience(clientId: string): Promise<{ groups: AutoServiceNewsAudienceGroup[] }> {\n return firstValueFrom(this.http.get<{ groups: AutoServiceNewsAudienceGroup[] }>(this.url(clientId, '/audience'), { headers: this.headers }));\n }\n\n create(clientId: string, body: AutoServiceNewsWrite): Promise<AutoServiceNews> {\n return firstValueFrom(this.http.post<AutoServiceNews>(this.url(clientId), body, { headers: this.headers }));\n }\n\n update(clientId: string, newsId: string, body: AutoServiceNewsWrite): Promise<AutoServiceNews> {\n return firstValueFrom(this.http.put<AutoServiceNews>(this.url(clientId, urlPath`/${newsId}`), body, { headers: this.headers }));\n }\n\n remove(clientId: string, newsId: string): Promise<void> {\n return firstValueFrom(this.http.delete<void>(this.url(clientId, urlPath`/${newsId}`), { headers: this.headers }));\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input, effect, signal, untracked } from '@angular/core';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport {\n AccountAvatarComponent, AlertComponent, ButtonComponent, ComboboxMultiComponent, ComboboxOption, DataGridActionTriggered,\n DataGridCellDirective, DataGridComponent, DataGridRowAction, DatePickerComponent, GridColumn, HermesDialogService, IconComponent,\n InputComponent, ListEditorComponent, type ListEditorValidator, ModalComponent, RichTextComponent, SegmentedControlComponent,\n type SegmentedOption, TagComponent, TextareaComponent, TimePickerComponent,\n} from '@trismegisto/angular';\nimport { formatMessage, type PaginationState } from '@trismegisto/primitives';\nimport { SPINE_MESSAGES, type SpineMessages } from '@trismegisto/spine';\nimport { AutoServiceDeleteFeedback } from '../../auto-service-delete';\nimport {\n AutoServiceNews, AutoServiceNewsKind, AutoServiceNewsService, AutoServiceNewsStatus, AutoServiceNewsWrite,\n} from './auto-service-news.service';\n\ntype NewsText = SpineMessages['autoServiceNews'];\n\nconst PAGE_SIZE = 20;\nconst TITLE_MAX = 140;\nconst SUMMARY_MAX = 300;\n\nlet sequence = 0;\n\n/** Teto da lista de mudanças (implementação) e de cada item -- os mesmos do servidor. */\nconst ITEMS_MAX = 30;\nconst ITEM_MAX = 300;\n\n/** Ícone de cada tipo (seletor do topo e prévia). */\nconst KIND_ICONS: Record<AutoServiceNewsKind, string> = {\n informativo: 'file-text',\n implementacao: 'rocket-diagonal',\n alteracao: 'two-way-arrows',\n};\n\n/** HTML de rich text com texto de verdade (não só tags vazias). */\nexport function newsHtmlHasText(html: string | null | undefined): boolean {\n return !!html && html.replace(/<[^>]*>/g, '').replace(/&nbsp;|&#160;/g, ' ').trim() !== '';\n}\n\nconst pad = (n: number) => String(n).padStart(2, '0');\n\n/** Data e hora LOCAIS (do navegador) de um instante ISO, no formato dos campos (`AAAA-MM-DD`, `HH:mm`). */\nexport function newsLocalParts(iso: string): { date: string | null; time: string | null } {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return { date: null, time: null };\n return { date: `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`, time: `${pad(d.getHours())}:${pad(d.getMinutes())}` };\n}\n\n/** Instante ISO (UTC) da data e hora locais dos campos; sem data = null (o servidor publica ao salvar); sem hora = 00:00. */\nexport function newsPublishedAt(date: string | null, time: string | null): string | null {\n if (!date) return null;\n const d = new Date(`${date}T${time || '00:00'}:00`);\n return Number.isNaN(d.getTime()) ? null : d.toISOString();\n}\n\n/** Código do argos-admin (`{ error }`) → texto no idioma ativo; desconhecido, o `detail` do servidor ou `fallback`. */\nexport function newsErrorText(err: unknown, text: NewsText, fallback: string): string {\n if (!(err instanceof HttpErrorResponse)) return fallback;\n const body = err.error as { error?: unknown; detail?: unknown } | null;\n const known: Record<string, string> = {\n invalid_title: text.errors.invalidTitle,\n invalid_summary: text.errors.invalidSummary,\n body_too_large: text.errors.bodyTooLarge,\n invalid_published_at: text.errors.invalidPublishedAt,\n invalid_until: text.errors.invalidUntil,\n invalid_group_ids: text.errors.invalidGroupIds,\n invalid_kind: text.errors.invalidKind,\n invalid_items: text.errors.invalidItems,\n invalid_compare: text.errors.invalidCompare,\n compare_too_large: text.errors.compareTooLarge,\n };\n const code = typeof body?.error === 'string' ? body.error : '';\n if (Object.prototype.hasOwnProperty.call(known, code)) return known[code];\n return typeof body?.detail === 'string' && body.detail ? body.detail : fallback;\n}\n\n/**\n * O editor. `body` é o texto (informativo) ou a introdução (implementação, alteração). Trocar de tipo guarda o que já\n * foi escrito nos campos dos outros tipos; só o do tipo escolhido vai para o servidor.\n */\ninterface NewsForm {\n kind: AutoServiceNewsKind;\n title: string;\n summary: string;\n body: string;\n items: string[];\n before: string;\n after: string;\n publishDate: string | null;\n publishTime: string | null;\n until: string | null;\n groupIds: string[];\n}\n\nconst emptyForm = (): NewsForm => ({\n kind: 'informativo', title: '', summary: '', body: '', items: [], before: '', after: '', publishDate: null, publishTime: null,\n until: null, groupIds: [],\n});\n\n/**\n * Aba Novidades do Cliente: o que o spine mostra em \"Novidades\" (menu do perfil, aviso da entrada, card do Início)\n * para quem entra no app. Grade paginada no servidor (agendadas e vencidas também), criar/editar num modal e excluir\n * com confirmação (no menu da linha ou no rodapé do modal, ao editar). O modal é um editor em seções numeradas\n * (título e resumo, texto em rich text, publicação, validade e público) com a prévia ao vivo do card do Início ao\n * lado. Sem rascunho: a novidade não tem esse estado (sem data, sai ao salvar). O texto é saneado pelo argos-admin ao\n * gravar; o público vazio é todo mundo que entra no app.\n */\n@Component({\n selector: 'spine-auto-service-news',\n imports: [\n AccountAvatarComponent, AlertComponent, ButtonComponent, ComboboxMultiComponent, DataGridComponent, DataGridCellDirective,\n DatePickerComponent, IconComponent, InputComponent, ListEditorComponent, ModalComponent, RichTextComponent, SegmentedControlComponent,\n TagComponent, TextareaComponent, TimePickerComponent,\n ],\n templateUrl: './auto-service-news.component.html',\n styleUrls: ['./auto-service-news.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AutoServiceNewsComponent {\n private readonly service = inject(AutoServiceNewsService);\n private readonly deletion = inject(AutoServiceDeleteFeedback);\n private readonly dialogs = inject(HermesDialogService);\n protected readonly text = inject(SPINE_MESSAGES).autoServiceNews;\n protected readonly common = inject(SPINE_MESSAGES).autoService;\n /** Rótulos do card Novidades do Início, repetidos na prévia. */\n protected readonly home = inject(SPINE_MESSAGES).home;\n protected readonly uid = `spine-as-news-${++sequence}`;\n private readonly dateFormat = new Intl.DateTimeFormat(inject(SPINE_MESSAGES).meta.locale, { dateStyle: 'short', timeStyle: 'short' });\n private readonly dayFormat = new Intl.DateTimeFormat(inject(SPINE_MESSAGES).meta.locale, { dateStyle: 'short', timeZone: 'UTC' });\n protected readonly TITLE_MAX = TITLE_MAX;\n protected readonly SUMMARY_MAX = SUMMARY_MAX;\n protected readonly ITEMS_MAX = ITEMS_MAX;\n /** Tipos do seletor do topo, com ícone. */\n protected readonly kindOptions: readonly SegmentedOption<AutoServiceNewsKind>[] = [\n { value: 'informativo', label: this.text.kindInformativo, icon: KIND_ICONS.informativo },\n { value: 'implementacao', label: this.text.kindImplementacao, icon: KIND_ICONS.implementacao },\n { value: 'alteracao', label: this.text.kindAlteracao, icon: KIND_ICONS.alteracao },\n ];\n /** Cada mudança até 300 caracteres (o vazio e o repetido o próprio hm-list-editor recusa). */\n protected readonly itemRule: ListEditorValidator<string> = (item) =>\n item.length > ITEM_MAX ? this.text.errors.invalidItems : null;\n\n readonly clientId = input('');\n\n protected readonly rows = signal<AutoServiceNews[]>([]);\n protected readonly total = signal(0);\n protected readonly pageState = signal<PaginationState>({ page: 1, size: PAGE_SIZE });\n protected readonly loading = signal(false);\n protected readonly loadError = signal('');\n protected readonly audienceOptions = signal<ComboboxOption[]>([]);\n\n protected readonly modalOpen = signal(false);\n protected readonly editingId = signal('');\n protected form: NewsForm = emptyForm();\n protected readonly saving = signal(false);\n protected readonly saveError = signal<string | null>(null);\n /** O texto da novidade em edição ainda está vindo (o editor espera). */\n protected readonly loadingBody = signal(false);\n /** Excluindo pelo rodapé do modal. */\n protected readonly removing = signal(false);\n\n readonly rowId = (n: AutoServiceNews) => n.id;\n readonly columns = computed<GridColumn<AutoServiceNews>[]>(() => [\n { key: 'title', title: this.text.colTitle, value: (n) => n.title },\n { key: 'status', title: this.text.colStatus, value: (n) => this.statusLabel(n.status) },\n { key: 'published_at', title: this.text.colPublishedAt, value: (n) => this.formatDate(n.published_at) },\n { key: 'until', title: this.text.colUntil, value: (n) => this.formatDay(n.until) },\n { key: 'groups', title: this.text.colAudience, value: (n) => n.groups.map((g) => g.name).join(', ') || this.text.audienceAll },\n { key: 'author', title: this.text.colAuthor, value: (n) => n.author?.name || n.author?.username || '' },\n ]);\n readonly rowActions = computed<DataGridRowAction<AutoServiceNews>[]>(() => [\n { id: 'edit', icon: 'pencil', label: this.common.edit },\n {\n id: 'delete', icon: 'trash', label: this.common.delete, danger: true, separatorAbove: true,\n confirm: (n) => ({ heading: this.text.confirmDeleteHeading, message: formatMessage(this.text.confirmDelete, { title: n.title }) }),\n },\n ]);\n\n /** Validade antes do dia da publicação: a novidade nunca apareceria. */\n protected get untilBeforePublish(): boolean {\n const publishDay = this.form.publishDate ?? newsLocalParts(new Date().toISOString()).date;\n return !!this.form.until && !!publishDay && this.form.until < publishDay;\n }\n\n /** Data e hora da prévia: as dos campos; sem data, \"ao salvar\". */\n protected get previewDate(): string {\n const at = newsPublishedAt(this.form.publishDate, this.form.publishTime);\n return at ? this.formatDate(at) : this.text.previewNow;\n }\n\n /** Publicação no futuro: a prévia marca \"Agendada\". */\n protected get previewScheduled(): boolean {\n const at = newsPublishedAt(this.form.publishDate, this.form.publishTime);\n return !!at && new Date(at).getTime() > Date.now();\n }\n\n protected get canSave(): boolean {\n const title = this.form.title.trim();\n return !!title && title.length <= TITLE_MAX && this.form.summary.trim().length <= SUMMARY_MAX && !this.untilBeforePublish\n && this.kindReady;\n }\n\n /** O conteúdo do tipo está completo: a implementação com ao menos uma mudança; a alteração com o antes e o agora. */\n protected get kindReady(): boolean {\n if (this.form.kind === 'implementacao') return this.form.items.length > 0 && this.form.items.length <= ITEMS_MAX;\n if (this.form.kind === 'alteracao') return newsHtmlHasText(this.form.before) && newsHtmlHasText(this.form.after);\n return true;\n }\n\n protected get kindIcon(): string {\n return KIND_ICONS[this.form.kind];\n }\n\n protected get kindLabel(): string {\n return this.kindOptions.find((o) => o.value === this.form.kind)?.label ?? '';\n }\n\n protected setKind(kind: string): void {\n if (kind === 'informativo' || kind === 'implementacao' || kind === 'alteracao') this.form = { ...this.form, kind };\n this.saveError.set(null);\n }\n\n constructor() {\n effect(() => {\n const id = this.clientId();\n untracked(() => {\n this.pageState.set({ page: 1, size: this.pageState().size });\n void this.load();\n void this.loadAudience(id);\n });\n });\n }\n\n protected statusLabel(status: AutoServiceNewsStatus): string {\n return status === 'scheduled' ? this.text.statusScheduled : status === 'expired' ? this.text.statusExpired : this.text.statusPublished;\n }\n\n protected statusColor(status: AutoServiceNewsStatus): 'info' | 'success' | 'neutral' {\n return status === 'scheduled' ? 'info' : status === 'expired' ? 'neutral' : 'success';\n }\n\n protected formatDate(iso: string): string {\n const d = new Date(iso);\n return Number.isNaN(d.getTime()) ? '' : this.dateFormat.format(d);\n }\n\n /** `until` é um dia (AAAA-MM-DD), sem fuso: formatado em UTC para não mudar de dia. */\n protected formatDay(day: string | null): string {\n if (!day) return this.text.noUntil;\n const d = new Date(`${day}T00:00:00Z`);\n return Number.isNaN(d.getTime()) ? day : this.dayFormat.format(d);\n }\n\n async load(page = this.pageState().page, size = this.pageState().size): Promise<void> {\n const clientId = this.clientId();\n if (!clientId) { this.rows.set([]); this.total.set(0); return; }\n this.loading.set(true);\n this.loadError.set('');\n try {\n const res = await this.service.list(clientId, page, size);\n this.rows.set(res.news ?? []);\n this.total.set(res.total ?? 0);\n this.pageState.set({ page, size });\n } catch (err) {\n this.rows.set([]);\n this.total.set(0);\n this.loadError.set(newsErrorText(err, this.text, this.text.loadError));\n } finally {\n this.loading.set(false);\n }\n }\n\n /** Sem a lista de público o campo fica sem opção (a novidade sai para todos). */\n private async loadAudience(clientId: string): Promise<void> {\n if (!clientId) { this.audienceOptions.set([]); return; }\n try {\n const res = await this.service.audience(clientId);\n this.audienceOptions.set((res.groups ?? []).map((g) => ({ value: g.id, label: g.name })));\n } catch {\n this.audienceOptions.set([]);\n }\n }\n\n protected onPageStateChange(state: PaginationState): void {\n void this.load(state.page, state.size);\n }\n\n protected openCreate(): void {\n this.editingId.set('');\n this.form = emptyForm();\n this.saveError.set(null);\n this.loadingBody.set(false);\n this.removing.set(false);\n this.modalOpen.set(true);\n }\n\n /** O corpo não vem na lista: busca o detalhe antes de liberar o editor. */\n protected async openEdit(row: AutoServiceNews): Promise<void> {\n const parts = newsLocalParts(row.published_at);\n this.editingId.set(row.id);\n this.form = {\n kind: row.kind ?? 'informativo', title: row.title, summary: row.summary, body: '', items: [], before: '', after: '',\n publishDate: parts.date, publishTime: parts.time, until: row.until, groupIds: row.groups.map((g) => g.id),\n };\n this.saveError.set(null);\n this.loadingBody.set(true);\n this.removing.set(false);\n this.modalOpen.set(true);\n try {\n const full = await this.service.get(this.clientId(), row.id);\n if (this.editingId() === row.id) {\n this.form = {\n ...this.form, kind: full.kind ?? this.form.kind, body: full.body_html ?? '', items: [...(full.items ?? [])],\n before: full.before_html ?? '', after: full.after_html ?? '',\n };\n }\n } catch (err) {\n this.saveError.set(newsErrorText(err, this.text, this.text.loadError));\n } finally {\n this.loadingBody.set(false);\n }\n }\n\n protected async save(): Promise<void> {\n if (!this.canSave || this.saving() || this.loadingBody()) return;\n const body: AutoServiceNewsWrite = {\n kind: this.form.kind,\n title: this.form.title.trim(),\n summary: this.form.summary.trim(),\n body_html: this.form.body,\n // Só o conteúdo do tipo escolhido; o resto vai vazio (o servidor zera também).\n items: this.form.kind === 'implementacao' ? [...this.form.items] : [],\n before_html: this.form.kind === 'alteracao' ? this.form.before : '',\n after_html: this.form.kind === 'alteracao' ? this.form.after : '',\n published_at: newsPublishedAt(this.form.publishDate, this.form.publishTime),\n until: this.form.until || null,\n group_ids: [...this.form.groupIds],\n };\n this.saving.set(true);\n this.saveError.set(null);\n try {\n if (this.editingId()) await this.service.update(this.clientId(), this.editingId(), body);\n else await this.service.create(this.clientId(), body);\n } catch (err) {\n // O modal fica aberto com o motivo no idioma ativo.\n this.saveError.set(newsErrorText(err, this.text, this.text.saveError));\n return;\n } finally {\n this.saving.set(false);\n }\n this.modalOpen.set(false);\n await this.load(this.editingId() ? this.pageState().page : 1);\n }\n\n /** \"Excluir\" no rodapé do modal (só ao editar): confirma, exclui, fecha e recarrega; falha deixa o modal aberto. */\n protected async removeFromModal(): Promise<void> {\n const id = this.editingId();\n if (!id || this.saving() || this.removing()) return;\n const title = this.form.title.trim();\n const ok = await this.dialogs.confirm({\n heading: this.text.confirmDeleteHeading, message: formatMessage(this.text.confirmDelete, { title }),\n confirmLabel: this.common.delete, danger: true,\n });\n if (!ok || this.editingId() !== id || !this.modalOpen()) return;\n this.removing.set(true);\n try {\n if (!(await this.deletion.run(() => this.service.remove(this.clientId(), id)))) return;\n } finally {\n this.removing.set(false);\n }\n this.modalOpen.set(false);\n await this.load();\n }\n\n /** Já confirmado pelo `confirm` da ação na grade. */\n private async remove(row: AutoServiceNews): Promise<void> {\n if (await this.deletion.run(() => this.service.remove(this.clientId(), row.id))) await this.load();\n }\n\n protected onAction(e: DataGridActionTriggered<AutoServiceNews>): void {\n if (e.action === 'edit') void this.openEdit(e.row);\n if (e.action === 'delete') void this.remove(e.row);\n }\n}\n","<!-- Paginação no servidor (agendadas e vencidas também); a busca/filtro local da grade fica desligada. -->\n<hm-data-grid\n [columns]=\"columns()\"\n [rows]=\"rows()\"\n [rowId]=\"rowId\"\n [caption]=\"text.caption\"\n [loading]=\"loading()\"\n [error]=\"loadError()\"\n [emptyMessage]=\"text.empty\"\n [rowActions]=\"rowActions()\"\n [filterable]=\"false\"\n [paginated]=\"false\"\n [totalItems]=\"total()\"\n [pageState]=\"pageState()\"\n (pageStateChange)=\"onPageStateChange($event)\"\n [pageSizes]=\"[10, 20, 50, 100]\"\n (actionTriggered)=\"onAction($event)\"\n>\n <hm-button dataGridActions icon=\"plus\" (clicked)=\"openCreate()\">{{ text.newNews }}</hm-button>\n <ng-template hmCell=\"title\" let-n>\n <span class=\"news-title\">\n <span>{{ n.title }}</span>\n @if (n.summary) { <span class=\"news-title__summary\">{{ n.summary }}</span> }\n </span>\n </ng-template>\n <ng-template hmCell=\"status\" let-n>\n <hm-tag [name]=\"statusLabel(n.status)\" [color]=\"statusColor(n.status)\" />\n </ng-template>\n <ng-template hmCell=\"groups\" let-n>\n @if (n.groups.length) {\n <span class=\"news-tags\">\n @for (g of n.groups; track g.id) { <hm-tag [name]=\"g.name\" color=\"info\" /> }\n </span>\n } @else {\n <span class=\"muted\">{{ text.audienceAll }}</span>\n }\n </ng-template>\n <ng-template hmCell=\"author\" let-n>\n @if (n.author; as a) {\n <span class=\"news-author\">\n <hm-account-avatar size=\"small\" [name]=\"a.name || a.username\" [imageUrl]=\"a.picture\" />\n <span>{{ a.name || a.username }}</span>\n </span>\n }\n </ng-template>\n</hm-data-grid>\n\n<!-- Modal: criar/editar novidade. O cabeçalho do hm-modal some da vista (o título segue como nome do diálogo, ver o\n .scss) e o editor desenha o seu: ícone, título e subtítulo. Pensado para caber sem rolagem num notebook: em cima,\n \"1. Informações principais\" (título) com o resumo ao lado; embaixo, o conteúdo do tipo escolhido no topo (texto;\n introdução + lista; ou introdução + antes e agora), que estica e rola por dentro, ao lado do painel com publicação,\n validade, público, dica e a prévia do Início no fim. O modal não rola; em tela estreita, tudo empilha. -->\n<hm-modal [open]=\"modalOpen()\" (openChange)=\"modalOpen.set($event)\" [heading]=\"editingId() ? text.editNews : text.newNews\" size=\"xlarge\"\n (closed)=\"modalOpen.set(false)\">\n <div class=\"ne\">\n <header class=\"ne-head\">\n <span class=\"ne-head__icon\" aria-hidden=\"true\"><hm-icon shape=\"announcement\" size=\"md\" /></span>\n <span class=\"ne-head__text\">\n <!-- O h2 do hm-modal já dá o nome ao diálogo: este é só o visual. -->\n <span class=\"ne-head__title\" aria-hidden=\"true\">{{ editingId() ? text.editNews : text.newNews }}</span>\n <span class=\"ne-head__intro\">{{ editingId() ? text.editNewsIntro : text.newNewsIntro }}</span>\n </span>\n <!-- Tipo de publicação: muda os campos do conteúdo e a prévia. -->\n <hm-segmented-control class=\"ne-kind\" [label]=\"text.kind\" [options]=\"kindOptions\" [value]=\"form.kind\" (valueChange)=\"setKind($event)\" />\n </header>\n\n <div class=\"ne-scroll\">\n @if (saveError()) { <hm-alert variant=\"error\">{{ saveError() }}</hm-alert> }\n\n <div class=\"ne-grid\">\n <!-- Linha de cima: a seção 1 ocupa as duas colunas (subgrid): título à esquerda, resumo à direita. -->\n <section class=\"ne-section ne-intro\" [attr.aria-labelledby]=\"uid + '-main'\">\n <div class=\"ne-intro__lead\">\n <div class=\"ne-section__head\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-main'\"><span class=\"ne-step\" aria-hidden=\"true\">1</span>{{ text.sectionMain }}</h3>\n <p class=\"ne-section__hint\">{{ text.sectionMainHint }}</p>\n </div>\n <hm-input [label]=\"text.title\" required [maxLength]=\"TITLE_MAX\" [(value)]=\"form.title\" (valueChange)=\"saveError.set(null)\" />\n </div>\n <hm-textarea class=\"ne-intro__summary\" [label]=\"text.summary\" [hint]=\"text.summaryHint\" [rows]=\"3\" [maxLength]=\"SUMMARY_MAX\"\n [(value)]=\"form.summary\" />\n </section>\n\n <section class=\"ne-section ne-content\" [attr.aria-labelledby]=\"uid + '-body'\">\n <div class=\"ne-section__head\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-body'\"><span class=\"ne-step\" aria-hidden=\"true\">2</span>{{ text.sectionBody }}</h3>\n <p class=\"ne-section__hint\">\n {{ form.kind === 'implementacao' ? text.sectionBodyHintImpl : form.kind === 'alteracao' ? text.sectionBodyHintAlt : text.sectionBodyHint }}\n </p>\n </div>\n <!-- Estica até o fim da linha; quem rola é o texto (ou a lista), não o modal. -->\n @switch (form.kind) {\n @case ('implementacao') {\n <hm-rich-text class=\"ne-content__intro\" [label]=\"text.intro\" [rows]=\"2\" [maxRows]=\"4\" [loading]=\"loadingBody()\"\n [(value)]=\"form.body\" />\n <div class=\"ne-content__items\">\n <hm-list-editor [label]=\"text.items\" [hint]=\"text.itemsHint\" [placeholder]=\"text.itemPlaceholder\" [emptyText]=\"text.itemsEmpty\"\n [max]=\"ITEMS_MAX\" [validate]=\"itemRule\" editable [items]=\"form.items\" (itemsChange)=\"form.items = [...$event]\" />\n </div>\n }\n @case ('alteracao') {\n <hm-rich-text class=\"ne-content__intro\" [label]=\"text.intro\" [rows]=\"2\" [maxRows]=\"4\" [loading]=\"loadingBody()\"\n [(value)]=\"form.body\" />\n <div class=\"ne-content__compare\">\n <hm-rich-text class=\"ne-content__editor ne-content__editor--labelled\" [label]=\"text.before\" required [rows]=\"4\" [maxRows]=\"16\" [loading]=\"loadingBody()\"\n [(value)]=\"form.before\" />\n <hm-rich-text class=\"ne-content__editor ne-content__editor--labelled\" [label]=\"text.after\" required [rows]=\"4\" [maxRows]=\"16\" [loading]=\"loadingBody()\"\n [(value)]=\"form.after\" />\n </div>\n }\n @default {\n <hm-rich-text class=\"ne-content__editor\" [label]=\"text.sectionBody\" labelHidden [hint]=\"text.bodyHint\" [rows]=\"6\" [maxRows]=\"24\"\n showCounter [loading]=\"loadingBody()\" [(value)]=\"form.body\" />\n }\n }\n </section>\n\n <aside class=\"ne-side\">\n <section class=\"ne-section ne-side__publish\" [attr.aria-labelledby]=\"uid + '-publish'\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-publish'\"><span class=\"ne-step\" aria-hidden=\"true\">3</span>{{ text.sectionPublish }}</h3>\n <div class=\"ne-row\">\n <hm-date-picker [label]=\"text.publishDate\" [(value)]=\"form.publishDate\" />\n <hm-time-picker [label]=\"text.publishTime\" [(value)]=\"form.publishTime\" />\n </div>\n <p class=\"ne-note\">{{ text.publishHint }}</p>\n </section>\n\n <section class=\"ne-section ne-side__until\" [attr.aria-labelledby]=\"uid + '-until'\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-until'\"><span class=\"ne-step\" aria-hidden=\"true\">4</span>{{ text.sectionUntil }}</h3>\n <hm-date-picker [label]=\"text.untilDate\" [hint]=\"text.untilHint\" [min]=\"form.publishDate\" [(value)]=\"form.until\" />\n @if (untilBeforePublish) { <hm-alert variant=\"warning\">{{ text.errors.untilBeforePublish }}</hm-alert> }\n </section>\n\n <section class=\"ne-section ne-side__audience\" [attr.aria-labelledby]=\"uid + '-audience'\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-audience'\"><span class=\"ne-step\" aria-hidden=\"true\">5</span>{{ text.sectionAudience }}</h3>\n <!-- Vazio = todos que entram no app. -->\n <hm-combobox-multi [label]=\"text.audienceGroups\" [hint]=\"text.audienceHint\" [placeholder]=\"text.audienceAll\" [options]=\"audienceOptions()\"\n [visibleChipsLimit]=\"null\" [selected]=\"form.groupIds\" (selectedChange)=\"form.groupIds = [...$event]\" />\n </section>\n\n <p class=\"ne-tip\"><hm-icon class=\"ne-tip__icon\" shape=\"lightbulb\" size=\"sm\" /><span><strong>{{ text.tipTitle }}</strong> {{ text.tipText }}</span></p>\n\n <section class=\"ne-section ne-side__preview\" [attr.aria-labelledby]=\"uid + '-preview'\">\n <h3 class=\"ne-section__title\" [id]=\"uid + '-preview'\"><hm-icon class=\"ne-section__icon\" shape=\"eye\" size=\"sm\" />{{ text.preview }}</h3>\n <!-- Mesmo desenho do card Novidades do Início; repete o que está nos campos, então fica fora da leitura. -->\n <div class=\"ne-preview\" aria-hidden=\"true\">\n <div class=\"ne-preview__head\">\n <span class=\"ne-preview__heading\">{{ home.news }}</span>\n <span class=\"ne-preview__badge\">{{ home.newsBadge }}</span>\n </div>\n <div class=\"ne-preview__item\">\n <span class=\"ne-preview__icon\"><hm-icon [shape]=\"kindIcon\" size=\"sm\" /></span>\n <span class=\"ne-preview__text\">\n <span class=\"ne-preview__title\" [class.ne-preview__placeholder]=\"!form.title.trim()\">{{ form.title.trim() || text.previewTitle }}</span>\n <span class=\"ne-preview__summary\" [class.ne-preview__placeholder]=\"!form.summary.trim()\">{{ form.summary.trim() || text.previewSummary }}</span>\n <span class=\"ne-preview__date\">\n <hm-icon shape=\"calendar\" size=\"xs\" />{{ previewDate }}\n @if (previewScheduled) { <span class=\"ne-preview__status\">{{ text.statusScheduled }}</span> }\n <span class=\"ne-preview__kind\">{{ kindLabel }}</span>\n </span>\n </span>\n <hm-icon class=\"ne-preview__chevron\" shape=\"angle-right\" size=\"sm\" />\n </div>\n </div>\n </section>\n </aside>\n </div>\n </div>\n </div>\n\n <ng-container footer>\n <!-- Sem rascunho: a novidade não tem esse estado (sem data = publica ao salvar). -->\n @if (editingId()) {\n <hm-button class=\"ne-delete\" emphasis=\"medium\" intent=\"danger\" icon=\"trash\" [disabled]=\"saving() || removing()\" [loading]=\"removing()\"\n (clicked)=\"removeFromModal()\">{{ common.delete }}</hm-button>\n }\n <hm-button emphasis=\"medium\" (clicked)=\"modalOpen.set(false)\">{{ common.cancel }}</hm-button>\n <hm-button [disabled]=\"!canSave || loadingBody() || removing()\" [loading]=\"saving()\" (clicked)=\"save()\">\n {{ editingId() ? common.save : common.create }}\n </hm-button>\n </ng-container>\n</hm-modal>\n","import { ChangeDetectionStrategy, Component, signal } from '@angular/core';\nimport { AutoServiceClient, AutoServiceClientPickerComponent } from '../client-picker/auto-service-client-picker.component';\nimport { AutoServiceNewsComponent } from '../tabs/auto-service-news/auto-service-news.component';\n\n/**\n * Tela \"Novidades\" do auto-serviço (router `AUTO_SERVICE_NEWS_TEMPLATE_ROUTER_ID`, na raiz do menu; migration 0036 do\n * argos): o seletor de client + o painel de novidades que era a aba Cliente › Novidades. Carregada só por\n * `AUTO_SERVICE_SCREENS.news` -- nunca exportada pelo ponto de entrada (ver `public-api.ts`).\n */\n@Component({\n selector: 'spine-auto-service-news-page',\n imports: [AutoServiceClientPickerComponent, AutoServiceNewsComponent],\n // Sem título/descrição internos: vêm da barra da página do spine (nome da rota + descrição do router AD100006).\n template: `\n <div class=\"as-stack\">\n <spine-auto-service-client-picker (clientChange)=\"client.set($event)\" />\n @if (client(); as c) {\n <spine-auto-service-news [clientId]=\"c.id\" />\n }\n </div>\n `,\n styleUrl: './auto-service-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AutoServiceNewsPageComponent {\n protected readonly client = signal<AutoServiceClient | null>(null);\n}\n"],"names":[],"mappings":"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"}
@@ -722,7 +722,7 @@ class AutoServiceRatingsComponent {
722
722
  return err instanceof HttpErrorResponse && err.status === 403 ? this.text.forbidden : this.text.loadError;
723
723
  }
724
724
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: AutoServiceRatingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
725
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: AutoServiceRatingsComponent, isStandalone: true, selector: "spine-auto-service-ratings", inputs: { clientId: { classPropertyName: "clientId", publicName: "clientId", isSignal: true, isRequired: true, transformFunction: null } }, providers: [AutoServiceRatingsService], viewQueries: [{ propertyName: "tabsCard", first: true, predicate: ["tabsCard"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Na barra da p\u00E1gina do painel (fora de um painel, aqui mesmo): quando foi lido, o per\u00EDodo e Atualizar. -->\n<ng-template spinePageActions>\n <div class=\"ratings__page-actions\">\n @if (updatedAt(); as at) {\n <span class=\"ratings__updated\">{{ updatedText(at) }}</span>\n }\n <hm-segmented-control\n [label]=\"text.period\"\n [options]=\"periodOptions()\"\n [value]=\"period()\"\n (valueChange)=\"setPeriod($event)\"\n size=\"small\"\n emphasis=\"action\"\n />\n <hm-button emphasis=\"medium\" size=\"small\" icon=\"refresh\" [loading]=\"summaryLoading() || recentLoading()\" (clicked)=\"reload()\">\n {{ text.refresh }}\n </hm-button>\n </div>\n</ng-template>\n\n<div class=\"ratings\" [attr.aria-busy]=\"summaryLoading() || recentLoading()\">\n @if (error(); as message) {\n <hm-alert variant=\"error\" [closable]=\"true\" (closed)=\"error.set(null)\">{{ message }}</hm-alert>\n }\n\n @if (!summary() && summaryLoading()) {\n <hm-skeleton shape=\"cards\" [count]=\"2\" [label]=\"text.refresh\" />\n } @else if (empty()) {\n <hm-state-screen situation=\"empty\" [heading]=\"text.noRatings\" />\n } @else if (summary()) {\n <!-- KPIs baixos: m\u00E9dia em destaque, estrelas e totais \u00E0 esquerda; o histograma das 11 notas \u00E0 direita. -->\n <div class=\"ratings__kpis\">\n @for (card of overview(); track card.id) {\n <hm-card class=\"ratings__kpi\">\n <section class=\"ratings__kpi-body\" [attr.aria-labelledby]=\"card.headingId\">\n <header class=\"ratings__head\">\n <span class=\"ratings__badge ratings__badge--{{ card.tone }}\" aria-hidden=\"true\"><hm-icon [shape]=\"card.icon\" /></span>\n <span class=\"ratings__titles\">\n <h3 class=\"ratings__title\" [id]=\"card.headingId\">{{ card.title }}</h3>\n <span class=\"ratings__subtitle\">{{ card.hint }}</span>\n </span>\n <hm-button class=\"ratings__details\" emphasis=\"minimal\" size=\"small\" iconEnd=\"arrow-right\" (clicked)=\"details(card)\">\n {{ text.details }}<span class=\"ratings__sr\"> {{ detailsLabel(card) }}</span>\n </hm-button>\n </header>\n\n <div class=\"ratings__kpi-main\">\n <div class=\"ratings__figure\">\n <span class=\"ratings__average\" aria-hidden=\"true\">\n <span class=\"ratings__average-value\">{{ averageFigure(card.data) }}</span><span class=\"ratings__average-max\">{{ text.scoreMax }}</span>\n </span>\n @if (card.data.total) {\n <spine-rating-stars class=\"ratings__stars\" [readonly]=\"true\" [showValue]=\"false\" [value]=\"card.data.average\" />\n }\n <span class=\"ratings__totals\">{{ totals(card.data) }}</span>\n </div>\n\n <ul class=\"ratings__hist\" [attr.aria-label]=\"text.distribution\">\n @for (col of card.columns; track col.score) {\n <li class=\"ratings__hist-col\" [attr.aria-label]=\"col.label\" [hmTooltip]=\"col.tip\">\n <span class=\"ratings__hist-track\" aria-hidden=\"true\">\n <span class=\"ratings__hist-bar ratings__fill--{{ col.tone }}\" [style.height.%]=\"col.height\"></span>\n </span>\n <span class=\"ratings__hist-score\" aria-hidden=\"true\">{{ col.score }}</span>\n </li>\n }\n </ul>\n </div>\n </section>\n </hm-card>\n }\n </div>\n\n <!-- Duas colunas: as telas (abas) e as recentes, lado a lado. -->\n <div class=\"ratings__columns\">\n <div class=\"ratings__main\" #tabsCard>\n <hm-card class=\"ratings__tabs-card\">\n <hm-tabs [label]=\"text.ranking\" [active]=\"tab()\" (activeChange)=\"setTab($event)\">\n <hm-tab id=\"screens\" [label]=\"text.tabScreens\" [count]=\"screenRows().length\">\n <spine-ratings-table *hmTabContent mode=\"screens\" [rows]=\"screenRows()\" [(area)]=\"tableArea\" [selected]=\"allOpen() ? screen() : null\" (picked)=\"pickScreen($event)\" />\n </hm-tab>\n <hm-tab id=\"areas\" [label]=\"text.tabAreas\" [count]=\"areaRows().length\">\n <spine-ratings-table *hmTabContent mode=\"areas\" [rows]=\"areaRows()\" (picked)=\"pickArea($event)\" />\n </hm-tab>\n <hm-tab id=\"trends\" [label]=\"text.tabTrends\">\n <spine-ratings-trend *hmTabContent [series]=\"trendSeries()\" />\n </hm-tab>\n </hm-tabs>\n </hm-card>\n </div>\n\n <hm-card class=\"ratings__recent-card\">\n <section class=\"ratings__recent\" [attr.aria-labelledby]=\"uid + '-recent'\">\n <header class=\"ratings__head\">\n <span class=\"ratings__badge ratings__badge--warning\" aria-hidden=\"true\"><hm-icon shape=\"comment-message\" /></span>\n <span class=\"ratings__titles\">\n <h3 class=\"ratings__title\" [id]=\"uid + '-recent'\">{{ text.recent }}</h3>\n <span class=\"ratings__subtitle\">{{ text.recentHint }}</span>\n </span>\n </header>\n\n @if (!recent().length && recentLoading()) {\n <hm-skeleton shape=\"list\" [count]=\"3\" [label]=\"text.refresh\" />\n } @else if (!recent().length) {\n <p class=\"ratings__empty\">{{ text.emptyList }}</p>\n } @else {\n <ul class=\"ratings__feed\">\n @for (item of recent(); track item.id) {\n <li class=\"ratings__feed-item\">\n <hm-account-avatar class=\"ratings__feed-avatar\" size=\"small\" [name]=\"author(item)\" [imageUrl]=\"item.user_picture\" />\n <div class=\"ratings__feed-body\">\n <div class=\"ratings__feed-head\">\n <span class=\"ratings__author\">{{ author(item) }}</span>\n <span class=\"ratings__when\" [attr.title]=\"date(item.updated_at)\">{{ when(item.updated_at) }}</span>\n </div>\n <div class=\"ratings__feed-meta\">\n <spine-rating-stars class=\"ratings__stars\" size=\"small\" [readonly]=\"true\" [showValue]=\"false\" [value]=\"item.score\" />\n <span class=\"ratings__item-value\" aria-hidden=\"true\">{{ scoreShort(item.score) }}</span>\n <hm-tag class=\"ratings__chip\" [color]=\"item.scope === 'app' ? 'primary' : 'info'\" [name]=\"target(item)\" />\n </div>\n @if (item.comment) {\n <p class=\"ratings__feed-comment\">{{ item.comment }}</p>\n }\n </div>\n </li>\n }\n </ul>\n }\n <hm-button class=\"ratings__all\" emphasis=\"minimal\" size=\"small\" iconEnd=\"arrow-right\" (clicked)=\"openAll()\">\n {{ viewAllLabel() }}\n </hm-button>\n </section>\n </hm-card>\n </div>\n }\n</div>\n\n<!-- Todas as avalia\u00E7\u00F5es: a lista completa, com filtros e pagina\u00E7\u00E3o no servidor. -->\n<hm-drawer [heading]=\"text.allHeading\" size=\"large\" [(open)]=\"allOpen\">\n @if (allOpen()) {\n <div class=\"ratings__all-body\" [attr.aria-busy]=\"listLoading()\">\n <div class=\"ratings__filters\">\n <hm-combobox class=\"ratings__filter\" size=\"small\" [label]=\"text.filterScope\" [options]=\"scopeOptions()\" [value]=\"scope()\" (valueChange)=\"setScope($event)\" />\n <hm-combobox class=\"ratings__filter ratings__filter--wide\" size=\"small\" [label]=\"text.filterScreen\" [options]=\"screenOptions()\" [value]=\"screen()\" (valueChange)=\"setScreen($event)\" />\n <hm-combobox class=\"ratings__filter\" size=\"small\" [label]=\"text.filterScore\" [options]=\"scoreOptions()\" [value]=\"score()\" (valueChange)=\"setScore($event)\" />\n <hm-switch class=\"ratings__switch\" [label]=\"text.withComment\" [value]=\"withComment()\" (valueChange)=\"setWithComment($event)\" />\n @if (hasFilters()) {\n <hm-button emphasis=\"minimal\" size=\"small\" (clicked)=\"clearFilters()\">{{ text.clearFilters }}</hm-button>\n }\n </div>\n\n @if (!items().length && listLoading()) {\n <hm-skeleton shape=\"list\" [count]=\"3\" [label]=\"text.refresh\" />\n } @else if (!items().length) {\n <p class=\"ratings__empty\">{{ text.emptyList }}</p>\n } @else {\n <ul class=\"ratings__list\" [class.ratings__list--busy]=\"listLoading()\">\n @for (row of rows(); track row.item.id) {\n <li class=\"ratings__item\">\n <hm-account-avatar class=\"ratings__item-avatar\" size=\"small\" [name]=\"author(row.item)\" [imageUrl]=\"row.item.user_picture\" />\n <span class=\"ratings__author ratings__item-who\">{{ author(row.item) }}</span>\n <span class=\"ratings__item-score\">\n <spine-rating-stars class=\"ratings__stars\" size=\"small\" [readonly]=\"true\" [showValue]=\"false\" [value]=\"row.item.score\" />\n <span class=\"ratings__item-value\" aria-hidden=\"true\">{{ scoreShort(row.item.score) }}</span>\n </span>\n <span class=\"ratings__target\">\n <hm-tag class=\"ratings__chip\" [color]=\"row.item.scope === 'app' ? 'primary' : 'info'\" [name]=\"target(row.item)\" />\n @if (row.item.scope === 'screen' && row.item.screen_label && row.item.screen_path) {\n <span class=\"ratings__route\">{{ row.item.screen_path }}</span>\n }\n </span>\n @if (row.item.comment) {\n <p class=\"ratings__comment\">{{ row.item.comment }}</p>\n } @else {\n <p class=\"ratings__comment ratings__comment--none\">{{ text.noComment }}</p>\n }\n <span class=\"ratings__date\">{{ date(row.item.updated_at) }}</span>\n <span class=\"ratings__item-menu\">\n @if (row.menu.length) {\n <hm-menu-button\n size=\"small\"\n icon=\"ellipsis-vertical\"\n align=\"end\"\n [showArrow]=\"false\"\n [label]=\"text.itemActions\"\n [items]=\"row.menu\"\n (chosen)=\"onItemAction(row.item, $event)\"\n />\n }\n </span>\n </li>\n }\n </ul>\n @if (total() > pageState().size) {\n <hm-paginator\n class=\"ratings__pager\"\n variant=\"simple\"\n [label]=\"text.pagination\"\n [state]=\"pageState()\"\n [totalItems]=\"total()\"\n [sizes]=\"[10, 25, 50]\"\n (stateChanged)=\"onPage($event)\"\n />\n }\n }\n </div>\n }\n</hm-drawer>\n", styles: [".as-stack{display:flex;flex-direction:column;gap:var(--hm-space-md);min-inline-size:0}.as-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--hm-space-xs)}.as-field-row{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--hm-space-sm)}.as-field-row>hm-combobox{flex:1 1 16rem;min-inline-size:0}.as-summary{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hm-space-sm)}.as-summary__info{display:flex;flex:1 1 16rem;flex-direction:column;gap:var(--hm-space-micro);min-inline-size:0}.as-summary__title{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hm-space-xs);margin:0;color:var(--hm-text);font-size:var(--hm-font-size-md);font-weight:var(--hm-font-weight-semibold)}.as-summary__detail{margin:0;color:var(--hm-muted);font-size:var(--hm-font-size-sm)}.muted{color:var(--hm-muted)}.as-empty{margin:var(--hm-space-xs) 0 0;font-size:var(--hm-font-size-sm)}.as-secret{display:grid;gap:var(--hm-space-micro)}.as-secret__label{color:var(--hm-muted);font-size:var(--hm-font-size-xs)}.as-secret__row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hm-space-xs)}.as-secret__value{flex:1 1 240px;min-width:0;border:var(--hm-border-hairline) solid var(--hm-divider);border-radius:var(--hm-radius-control);padding:var(--hm-space-xs) var(--hm-space-sm);background:var(--hm-surface-muted);color:var(--hm-text);font-family:var(--hm-font-mono);font-size:var(--hm-font-size-sm);overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}:host{display:block;min-inline-size:0;container-type:inline-size}.ratings{display:flex;flex-direction:column;gap:var(--hm-space-md);min-inline-size:0}.ratings__sr{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.ratings__page-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--hm-space-xs) var(--hm-space-sm);min-inline-size:0}.ratings__updated{color:var(--hm-muted);font-size:var(--hm-font-size-xs);white-space:nowrap}.ratings__head{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hm-space-sm);min-inline-size:0}.ratings__titles{display:flex;flex:1 1 8rem;flex-direction:column;gap:var(--hm-space-nano);min-inline-size:0}.ratings__title{margin:0;color:var(--hm-text);font-size:var(--hm-font-size-md);font-weight:var(--hm-font-weight-semibold);line-height:var(--hm-line-height-tight)}.ratings__subtitle{color:var(--hm-muted);font-size:var(--hm-font-size-xs)}.ratings__details{flex:none;margin-inline-start:auto}.ratings__badge{display:inline-flex;flex:none;align-items:center;justify-content:center;inline-size:2.25rem;block-size:2.25rem;border-radius:var(--hm-radius);font-size:var(--hm-icon-md)}.ratings__badge--accent{background:var(--hm-accent-subtle);color:var(--hm-accent-strong)}.ratings__badge--info{background:var(--hm-info-bg);color:var(--hm-info)}.ratings__badge--warning{background:var(--hm-warning-bg);color:var(--hm-warning)}.ratings__kpis{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--hm-space-md)}@container (max-width: 56rem){.ratings__kpis{grid-template-columns:minmax(0,1fr)}}.ratings__kpi-body{display:flex;flex-direction:column;gap:var(--hm-space-sm);min-inline-size:0}.ratings__kpi-main{display:flex;align-items:flex-end;gap:var(--hm-space-lg);min-inline-size:0}.ratings__figure{display:flex;flex:none;flex-direction:column;gap:var(--hm-space-micro);min-inline-size:0}.ratings__average{display:inline-flex;align-items:baseline;gap:var(--hm-space-nano);color:var(--hm-text);font-variant-numeric:tabular-nums;line-height:1}.ratings__average-value{font-size:calc(var(--hm-font-size-xxl) * 1.4);font-weight:var(--hm-font-weight-bold);letter-spacing:-.02em}.ratings__average-max{color:var(--hm-muted);font-size:var(--hm-font-size-md);font-weight:var(--hm-font-weight-medium)}.ratings__totals{color:var(--hm-muted);font-size:var(--hm-font-size-xs);white-space:nowrap}.ratings__stars{flex:none}.ratings__hist{display:grid;flex:1 1 auto;grid-template-columns:repeat(11,minmax(0,1fr));gap:var(--hm-space-micro);min-inline-size:0;margin:0;padding:0;list-style:none}.ratings__hist-col{display:flex;flex-direction:column;align-items:center;gap:var(--hm-space-nano);min-inline-size:0;font-size:var(--hm-font-size-xs);font-variant-numeric:tabular-nums;cursor:default}.ratings__hist-col:hover .ratings__hist-track{box-shadow:0 0 0 2px var(--hm-divider)}.ratings__hist-track{display:flex;align-items:flex-end;inline-size:100%;max-inline-size:1.75rem;block-size:3.75rem;border-radius:var(--hm-radius-micro);background:var(--hm-surface-muted);overflow:hidden}.ratings__hist-bar{display:block;inline-size:100%;border-radius:var(--hm-radius-micro) var(--hm-radius-micro) 0 0;transition:height .16s ease}.ratings__hist-score{color:var(--hm-muted)}@container (max-width: 30rem){.ratings__kpi-main{flex-direction:column;align-items:stretch;gap:var(--hm-space-sm)}.ratings__figure{flex-flow:row wrap;align-items:center;gap:var(--hm-space-xs) var(--hm-space-sm)}}.ratings__fill--success{background:var(--hm-success)}.ratings__fill--warning{background:var(--hm-warning)}.ratings__fill--danger{background:var(--hm-danger)}.ratings__fill--neutral{background:transparent}.ratings__columns{display:grid;grid-template-columns:minmax(0,2fr) minmax(18rem,1fr);align-items:start;gap:var(--hm-space-md)}@container (max-width: 64rem){.ratings__columns{grid-template-columns:minmax(0,1fr)}}.ratings__main{min-inline-size:0;scroll-margin-block-start:var(--hm-space-md)}.ratings__recent{display:flex;flex-direction:column;gap:var(--hm-space-sm);min-inline-size:0}.ratings__empty{margin:0;padding:var(--hm-space-md);border-radius:var(--hm-radius-control);background:var(--hm-surface-muted);color:var(--hm-muted);text-align:center}.ratings__feed{display:flex;flex-direction:column;gap:var(--hm-space-micro);margin:0;padding:0;list-style:none}.ratings__feed-item{display:flex;align-items:flex-start;gap:var(--hm-space-sm);padding:var(--hm-space-xs) var(--hm-space-sm);border-radius:var(--hm-radius-control);background:var(--hm-surface-muted);font-size:var(--hm-font-size-sm)}.ratings__feed-avatar{flex:none}.ratings__feed-body{display:flex;flex:1 1 auto;flex-direction:column;gap:var(--hm-space-nano);min-inline-size:0}.ratings__feed-head{display:flex;align-items:baseline;gap:var(--hm-space-xs);min-inline-size:0}.ratings__author{overflow:hidden;color:var(--hm-text);font-weight:var(--hm-font-weight-semibold);text-overflow:ellipsis;white-space:nowrap}.ratings__when{flex:none;margin-inline-start:auto;color:var(--hm-muted);font-size:var(--hm-font-size-xs);white-space:nowrap}.ratings__feed-meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hm-space-xs);min-inline-size:0}.ratings__feed-meta>hm-tag{max-inline-size:100%}.ratings__item-value{color:var(--hm-text);font-variant-numeric:tabular-nums;font-weight:var(--hm-font-weight-semibold)}.ratings__feed-comment{display:-webkit-box;margin:0;overflow:hidden;color:var(--hm-text);overflow-wrap:anywhere;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.ratings__all{align-self:flex-end}.ratings__all-body{display:flex;flex-direction:column;gap:var(--hm-space-sm);min-inline-size:0;container-type:inline-size}.ratings__filters{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--hm-space-xs) var(--hm-space-sm)}.ratings__filter{flex:1 1 9rem;min-inline-size:0}.ratings__filter--wide{flex-basis:13rem}.ratings__switch{flex:none;padding-block-end:var(--hm-space-xs)}.ratings__list{display:flex;flex-direction:column;gap:var(--hm-space-micro);margin:0;padding:0;list-style:none;transition:opacity .12s ease}.ratings__list--busy{opacity:.55}.ratings__item{display:grid;grid-template-areas:\"avatar who score date menu\" \"avatar target target target target\" \"avatar comment comment comment comment\";grid-template-columns:auto minmax(0,1fr) auto auto 2rem;align-items:center;gap:var(--hm-space-nano) var(--hm-space-sm);padding:var(--hm-space-xs) var(--hm-space-sm);border-radius:var(--hm-radius-control);background:var(--hm-surface-muted);font-size:var(--hm-font-size-sm)}.ratings__item-avatar{grid-area:avatar;align-self:start}.ratings__item-who{grid-area:who}.ratings__item-score{display:inline-flex;grid-area:score;align-items:center;gap:var(--hm-space-xs);white-space:nowrap}.ratings__target{display:flex;flex-wrap:wrap;grid-area:target;align-items:center;gap:var(--hm-space-xs);min-inline-size:0}.ratings__target>hm-tag{max-inline-size:100%}.ratings__route{overflow:hidden;color:var(--hm-muted);font-family:var(--hm-font-mono);font-size:var(--hm-font-size-xs);text-overflow:ellipsis;white-space:nowrap}.ratings__comment{grid-area:comment;margin:0;color:var(--hm-text);white-space:pre-line;overflow-wrap:anywhere}.ratings__comment--none{color:var(--hm-muted);font-style:italic}.ratings__date{grid-area:date;color:var(--hm-muted);font-size:var(--hm-font-size-xs);font-variant-numeric:tabular-nums;white-space:nowrap}.ratings__item-menu{display:inline-flex;grid-area:menu;justify-content:flex-end}@container (max-width: 28rem){.ratings__item{grid-template-areas:\"avatar who menu\" \"avatar score date\" \"avatar target target\" \"avatar comment comment\";grid-template-columns:auto minmax(0,1fr) auto}}.ratings__pager{margin-block-start:var(--hm-space-xs)}@media(prefers-reduced-motion:reduce){.ratings__hist-bar,.ratings__list{transition:none}}:host-context([data-motion=reduce]) .ratings__hist-bar,:host-context([data-motion=reduce]) .ratings__list{transition:none}\n"], dependencies: [{ kind: "component", type: AccountAvatarComponent, selector: "hm-account-avatar", inputs: ["name", "imageUrl", "size", "loading"] }, { kind: "component", type: AlertComponent, selector: "hm-alert", inputs: ["variant", "appearance", "heading", "closable", "size", "showIcon", "link", "linkLabel", "linkTarget", "dismissKey", "duration"], outputs: ["closed"] }, { kind: "component", type: ButtonComponent, selector: "hm-button", inputs: ["emphasis", "intent", "size", "type", "icon", "iconDirection", "iconEnd", "disabled", "loading", "loadingState", "block", "link", "newTab", "caret", "inMenu", "toggle", "pressed"], outputs: ["loadingStateChange", "pressedChange", "clicked"] }, { kind: "component", type: CardComponent, selector: "hm-card", inputs: ["heading", "icon", "selected", "fill", "media", "mediaAlt", "mediaDecorative", "mediaPosition"] }, { kind: "component", type: ComboboxComponent, selector: "hm-combobox", inputs: ["label", "options", "value", "placeholder", "icon", "hint", "size", "labelHidden", "clearable", "loading", "allowCustomValue"], outputs: ["valueChange"] }, { kind: "component", type: DrawerComponent, selector: "hm-drawer", inputs: ["open", "heading", "size", "position", "pinned", "closeLabel", "closable", "beforeClose"], outputs: ["openChange", "closed"] }, { kind: "component", type: IconComponent, selector: "hm-icon", inputs: ["shape", "direction", "size", "solid", "badge", "status", "flip", "inverse", "label"] }, { kind: "component", type: MenuButtonComponent, selector: "hm-menu-button", inputs: ["label", "icon", "items", "showArrow", "align", "side", "size", "shape", "layer", "closeOnCheck", "disabled"], outputs: ["chosen", "checkedChange"] }, { kind: "component", type: PaginatorComponent, selector: "hm-paginator", inputs: ["state", "totalItems", "variant", "label", "showPage", "hasNext", "hasPrevious", "sizes", "maxNumbers"], outputs: ["stateChanged", "nextPage", "previousPage"] }, { kind: "component", type: SegmentedControlComponent, selector: "hm-segmented-control", inputs: ["options", "value", "label", "size", "emphasis"], outputs: ["valueChange"] }, { kind: "component", type: SkeletonComponent, selector: "hm-skeleton", inputs: ["shape", "count", "label"] }, { kind: "component", type: StateScreenComponent, selector: "hm-state-screen", inputs: ["heading", "description", "situation", "action", "actionIcon"], outputs: ["actionTriggered"] }, { kind: "component", type: SwitchComponent, selector: "hm-switch", inputs: ["value", "label", "hint", "labelPosition", "loading"], outputs: ["valueChange"] }, { kind: "component", type: TabComponent, selector: "hm-tab", inputs: ["id", "label", "disabled", "count", "route", "exact", "destroyOnHide"] }, { kind: "directive", type: TabContentDirective, selector: "ng-template[hmTabContent]" }, { kind: "component", type: TabsComponent, selector: "hm-tabs", inputs: ["label", "active", "orientation", "mode", "overflow", "fillHeight", "noPanelGap"], outputs: ["activeChange"] }, { kind: "component", type: TagComponent, selector: "hm-tag", inputs: ["name", "color", "compact"] }, { kind: "directive", type: TooltipDirective, selector: "[hmTooltip]", inputs: ["hmTooltip", "hmTooltipSide", "hmTooltipDisabled", "hmTooltipShowDelay", "hmTooltipHideDelay"] }, { kind: "directive", type: SpinePageActionsDirective, selector: "ng-template[spinePageActions]" }, { kind: "component", type: SpineRatingStarsComponent, selector: "spine-rating-stars", inputs: ["value", "readonly", "showValue", "showName", "size", "label", "labelledBy", "describedBy", "invalid"], outputs: ["valueChange"] }, { kind: "component", type: RatingsTableComponent, selector: "spine-ratings-table", inputs: ["mode", "rows", "area", "selected"], outputs: ["areaChange", "picked"] }, { kind: "component", type: RatingsTrendComponent, selector: "spine-ratings-trend", inputs: ["series"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
725
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: AutoServiceRatingsComponent, isStandalone: true, selector: "spine-auto-service-ratings", inputs: { clientId: { classPropertyName: "clientId", publicName: "clientId", isSignal: true, isRequired: true, transformFunction: null } }, providers: [AutoServiceRatingsService], viewQueries: [{ propertyName: "tabsCard", first: true, predicate: ["tabsCard"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Na barra da p\u00E1gina do painel (fora de um painel, aqui mesmo): quando foi lido, o per\u00EDodo e Atualizar. -->\n<ng-template spinePageActions>\n <div class=\"ratings__page-actions\">\n @if (updatedAt(); as at) {\n <span class=\"ratings__updated\">{{ updatedText(at) }}</span>\n }\n <hm-segmented-control\n [label]=\"text.period\"\n [options]=\"periodOptions()\"\n [value]=\"period()\"\n (valueChange)=\"setPeriod($event)\"\n size=\"small\"\n emphasis=\"action\"\n />\n <hm-button emphasis=\"medium\" size=\"small\" icon=\"refresh\" [loading]=\"summaryLoading() || recentLoading()\" (clicked)=\"reload()\">\n {{ text.refresh }}\n </hm-button>\n </div>\n</ng-template>\n\n<div class=\"ratings\" [attr.aria-busy]=\"summaryLoading() || recentLoading()\">\n @if (error(); as message) {\n <hm-alert variant=\"error\" [closable]=\"true\" (closed)=\"error.set(null)\">{{ message }}</hm-alert>\n }\n\n @if (!summary() && summaryLoading()) {\n <hm-skeleton shape=\"cards\" [count]=\"2\" [label]=\"text.refresh\" />\n } @else if (empty()) {\n <hm-state-screen situation=\"empty\" [heading]=\"text.noRatings\" />\n } @else if (summary()) {\n <!-- KPIs baixos: m\u00E9dia em destaque, estrelas e totais \u00E0 esquerda; o histograma das 11 notas \u00E0 direita. -->\n <div class=\"ratings__kpis\">\n @for (card of overview(); track card.id) {\n <hm-card class=\"ratings__kpi\">\n <section class=\"ratings__kpi-body\" [attr.aria-labelledby]=\"card.headingId\">\n <header class=\"ratings__head\">\n <span class=\"ratings__badge ratings__badge--{{ card.tone }}\" aria-hidden=\"true\"><hm-icon [shape]=\"card.icon\" /></span>\n <span class=\"ratings__titles\">\n <h3 class=\"ratings__title\" [id]=\"card.headingId\">{{ card.title }}</h3>\n <span class=\"ratings__subtitle\">{{ card.hint }}</span>\n </span>\n <hm-button class=\"ratings__details\" emphasis=\"minimal\" size=\"small\" iconEnd=\"arrow-right\" (clicked)=\"details(card)\">\n {{ text.details }}<span class=\"ratings__sr\"> {{ detailsLabel(card) }}</span>\n </hm-button>\n </header>\n\n <div class=\"ratings__kpi-main\">\n <div class=\"ratings__figure\">\n <span class=\"ratings__average\" aria-hidden=\"true\">\n <span class=\"ratings__average-value\">{{ averageFigure(card.data) }}</span><span class=\"ratings__average-max\">{{ text.scoreMax }}</span>\n </span>\n @if (card.data.total) {\n <spine-rating-stars class=\"ratings__stars\" [readonly]=\"true\" [showValue]=\"false\" [value]=\"card.data.average\" />\n }\n <span class=\"ratings__totals\">{{ totals(card.data) }}</span>\n </div>\n\n <ul class=\"ratings__hist\" [attr.aria-label]=\"text.distribution\">\n @for (col of card.columns; track col.score) {\n <li class=\"ratings__hist-col\" [attr.aria-label]=\"col.label\" [hmTooltip]=\"col.tip\">\n <span class=\"ratings__hist-track\" aria-hidden=\"true\">\n <span class=\"ratings__hist-bar ratings__fill--{{ col.tone }}\" [style.height.%]=\"col.height\"></span>\n </span>\n <span class=\"ratings__hist-score\" aria-hidden=\"true\">{{ col.score }}</span>\n </li>\n }\n </ul>\n </div>\n </section>\n </hm-card>\n }\n </div>\n\n <!-- Duas colunas: as telas (abas) e as recentes, lado a lado. -->\n <div class=\"ratings__columns\">\n <div class=\"ratings__main\" #tabsCard>\n <hm-card class=\"ratings__tabs-card\">\n <hm-tabs [label]=\"text.ranking\" [active]=\"tab()\" (activeChange)=\"setTab($event)\">\n <hm-tab id=\"screens\" [label]=\"text.tabScreens\" [count]=\"screenRows().length\">\n <spine-ratings-table *hmTabContent mode=\"screens\" [rows]=\"screenRows()\" [(area)]=\"tableArea\" [selected]=\"allOpen() ? screen() : null\" (picked)=\"pickScreen($event)\" />\n </hm-tab>\n <hm-tab id=\"areas\" [label]=\"text.tabAreas\" [count]=\"areaRows().length\">\n <spine-ratings-table *hmTabContent mode=\"areas\" [rows]=\"areaRows()\" (picked)=\"pickArea($event)\" />\n </hm-tab>\n <hm-tab id=\"trends\" [label]=\"text.tabTrends\">\n <spine-ratings-trend *hmTabContent [series]=\"trendSeries()\" />\n </hm-tab>\n </hm-tabs>\n </hm-card>\n </div>\n\n <hm-card class=\"ratings__recent-card\">\n <section class=\"ratings__recent\" [attr.aria-labelledby]=\"uid + '-recent'\">\n <header class=\"ratings__head\">\n <span class=\"ratings__badge ratings__badge--warning\" aria-hidden=\"true\"><hm-icon shape=\"comment-message\" /></span>\n <span class=\"ratings__titles\">\n <h3 class=\"ratings__title\" [id]=\"uid + '-recent'\">{{ text.recent }}</h3>\n <span class=\"ratings__subtitle\">{{ text.recentHint }}</span>\n </span>\n </header>\n\n @if (!recent().length && recentLoading()) {\n <hm-skeleton shape=\"list\" [count]=\"3\" [label]=\"text.refresh\" />\n } @else if (!recent().length) {\n <p class=\"ratings__empty\">{{ text.emptyList }}</p>\n } @else {\n <ul class=\"ratings__feed\">\n @for (item of recent(); track item.id) {\n <li class=\"ratings__feed-item\">\n <hm-account-avatar class=\"ratings__feed-avatar\" size=\"small\" [name]=\"author(item)\" [imageUrl]=\"item.user_picture\" />\n <div class=\"ratings__feed-body\">\n <div class=\"ratings__feed-head\">\n <span class=\"ratings__author\">{{ author(item) }}</span>\n <span class=\"ratings__when\" [attr.title]=\"date(item.updated_at)\">{{ when(item.updated_at) }}</span>\n </div>\n <div class=\"ratings__feed-meta\">\n <spine-rating-stars class=\"ratings__stars\" size=\"small\" [readonly]=\"true\" [showValue]=\"false\" [value]=\"item.score\" />\n <span class=\"ratings__item-value\" aria-hidden=\"true\">{{ scoreShort(item.score) }}</span>\n <hm-tag class=\"ratings__chip\" [color]=\"item.scope === 'app' ? 'primary' : 'info'\" [name]=\"target(item)\" />\n </div>\n @if (item.comment) {\n <p class=\"ratings__feed-comment\">{{ item.comment }}</p>\n }\n </div>\n </li>\n }\n </ul>\n }\n <hm-button class=\"ratings__all\" emphasis=\"minimal\" size=\"small\" iconEnd=\"arrow-right\" (clicked)=\"openAll()\">\n {{ viewAllLabel() }}\n </hm-button>\n </section>\n </hm-card>\n </div>\n }\n</div>\n\n<!-- Todas as avalia\u00E7\u00F5es: a lista completa, com filtros e pagina\u00E7\u00E3o no servidor. -->\n<hm-drawer [heading]=\"text.allHeading\" size=\"large\" [(open)]=\"allOpen\">\n @if (allOpen()) {\n <div class=\"ratings__all-body\" [attr.aria-busy]=\"listLoading()\">\n <div class=\"ratings__filters\">\n <hm-combobox class=\"ratings__filter\" size=\"small\" [label]=\"text.filterScope\" [options]=\"scopeOptions()\" [value]=\"scope()\" (valueChange)=\"setScope($event)\" />\n <hm-combobox class=\"ratings__filter ratings__filter--wide\" size=\"small\" [label]=\"text.filterScreen\" [options]=\"screenOptions()\" [value]=\"screen()\" (valueChange)=\"setScreen($event)\" />\n <hm-combobox class=\"ratings__filter\" size=\"small\" [label]=\"text.filterScore\" [options]=\"scoreOptions()\" [value]=\"score()\" (valueChange)=\"setScore($event)\" />\n <hm-switch class=\"ratings__switch\" [label]=\"text.withComment\" [value]=\"withComment()\" (valueChange)=\"setWithComment($event)\" />\n @if (hasFilters()) {\n <hm-button emphasis=\"minimal\" size=\"small\" (clicked)=\"clearFilters()\">{{ text.clearFilters }}</hm-button>\n }\n </div>\n\n @if (!items().length && listLoading()) {\n <hm-skeleton shape=\"list\" [count]=\"3\" [label]=\"text.refresh\" />\n } @else if (!items().length) {\n <p class=\"ratings__empty\">{{ text.emptyList }}</p>\n } @else {\n <ul class=\"ratings__list\" [class.ratings__list--busy]=\"listLoading()\">\n @for (row of rows(); track row.item.id) {\n <li class=\"ratings__item\">\n <hm-account-avatar class=\"ratings__item-avatar\" size=\"small\" [name]=\"author(row.item)\" [imageUrl]=\"row.item.user_picture\" />\n <span class=\"ratings__author ratings__item-who\">{{ author(row.item) }}</span>\n <span class=\"ratings__item-score\">\n <spine-rating-stars class=\"ratings__stars\" size=\"small\" [readonly]=\"true\" [showValue]=\"false\" [value]=\"row.item.score\" />\n <span class=\"ratings__item-value\" aria-hidden=\"true\">{{ scoreShort(row.item.score) }}</span>\n </span>\n <span class=\"ratings__target\">\n <hm-tag class=\"ratings__chip\" [color]=\"row.item.scope === 'app' ? 'primary' : 'info'\" [name]=\"target(row.item)\" />\n @if (row.item.scope === 'screen' && row.item.screen_label && row.item.screen_path) {\n <span class=\"ratings__route\">{{ row.item.screen_path }}</span>\n }\n </span>\n @if (row.item.comment) {\n <p class=\"ratings__comment\">{{ row.item.comment }}</p>\n } @else {\n <p class=\"ratings__comment ratings__comment--none\">{{ text.noComment }}</p>\n }\n <span class=\"ratings__date\">{{ date(row.item.updated_at) }}</span>\n <span class=\"ratings__item-menu\">\n @if (row.menu.length) {\n <hm-menu-button\n size=\"small\"\n icon=\"ellipsis-vertical\"\n align=\"end\"\n [showArrow]=\"false\"\n [label]=\"text.itemActions\"\n [items]=\"row.menu\"\n (chosen)=\"onItemAction(row.item, $event)\"\n />\n }\n </span>\n </li>\n }\n </ul>\n @if (total() > pageState().size) {\n <hm-paginator\n class=\"ratings__pager\"\n variant=\"simple\"\n [label]=\"text.pagination\"\n [state]=\"pageState()\"\n [totalItems]=\"total()\"\n [sizes]=\"[10, 25, 50]\"\n (stateChanged)=\"onPage($event)\"\n />\n }\n }\n </div>\n }\n</hm-drawer>\n", styles: [".as-stack{display:flex;flex-direction:column;gap:var(--hm-space-md);min-inline-size:0}.as-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--hm-space-xs)}.as-field-row{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--hm-space-sm)}.as-field-row>hm-combobox{flex:1 1 16rem;min-inline-size:0}.as-summary{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hm-space-sm)}.as-summary__info{display:flex;flex:1 1 16rem;flex-direction:column;gap:var(--hm-space-micro);min-inline-size:0}.as-summary__title{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hm-space-xs);margin:0;color:var(--hm-text);font-size:var(--hm-font-size-md);font-weight:var(--hm-font-weight-semibold)}.as-summary__detail{margin:0;color:var(--hm-muted);font-size:var(--hm-font-size-sm)}.muted{color:var(--hm-muted)}.as-empty{margin:var(--hm-space-xs) 0 0;font-size:var(--hm-font-size-sm)}.as-secret{display:grid;gap:var(--hm-space-micro)}.as-secret__label{color:var(--hm-muted);font-size:var(--hm-font-size-xs)}.as-secret__row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hm-space-xs)}.as-secret__value{flex:1 1 240px;min-width:0;border:var(--hm-border-hairline) solid var(--hm-divider);border-radius:var(--hm-radius-control);padding:var(--hm-space-xs) var(--hm-space-sm);background:var(--hm-surface-muted);color:var(--hm-text);font-family:var(--hm-font-mono);font-size:var(--hm-font-size-sm);overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}:host{display:block;min-inline-size:0;container-type:inline-size}.ratings{display:flex;flex-direction:column;gap:var(--hm-space-md);min-inline-size:0}.ratings__sr{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.ratings__page-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--hm-space-xs) var(--hm-space-sm);min-inline-size:0}.ratings__updated{color:var(--hm-muted);font-size:var(--hm-font-size-xs);white-space:nowrap}.ratings__head{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hm-space-sm);min-inline-size:0}.ratings__titles{display:flex;flex:1 1 8rem;flex-direction:column;gap:var(--hm-space-nano);min-inline-size:0}.ratings__title{margin:0;color:var(--hm-text);font-size:var(--hm-font-size-md);font-weight:var(--hm-font-weight-semibold);line-height:var(--hm-line-height-tight)}.ratings__subtitle{color:var(--hm-muted);font-size:var(--hm-font-size-xs)}.ratings__details{flex:none;margin-inline-start:auto}.ratings__badge{display:inline-flex;flex:none;align-items:center;justify-content:center;inline-size:2.25rem;block-size:2.25rem;border-radius:var(--hm-radius);font-size:var(--hm-icon-md)}.ratings__badge--accent{background:var(--hm-accent-subtle);color:var(--hm-accent-strong)}.ratings__badge--info{background:var(--hm-info-bg);color:var(--hm-info)}.ratings__badge--warning{background:var(--hm-warning-bg);color:var(--hm-warning)}.ratings__kpis{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--hm-space-md)}@container (max-width: 56rem){.ratings__kpis{grid-template-columns:minmax(0,1fr)}}.ratings__kpi-body{display:flex;flex-direction:column;gap:var(--hm-space-sm);min-inline-size:0}.ratings__kpi-main{display:flex;align-items:flex-end;gap:var(--hm-space-lg);min-inline-size:0}.ratings__figure{display:flex;flex:none;flex-direction:column;gap:var(--hm-space-micro);min-inline-size:0}.ratings__average{display:inline-flex;align-items:baseline;gap:var(--hm-space-nano);color:var(--hm-text);font-variant-numeric:tabular-nums;line-height:1}.ratings__average-value{font-size:calc(var(--hm-font-size-xxl) * 1.4);font-weight:var(--hm-font-weight-bold);letter-spacing:-.02em}.ratings__average-max{color:var(--hm-muted);font-size:var(--hm-font-size-md);font-weight:var(--hm-font-weight-medium)}.ratings__totals{color:var(--hm-muted);font-size:var(--hm-font-size-xs);white-space:nowrap}.ratings__stars{flex:none}.ratings__hist{display:grid;flex:1 1 auto;grid-template-columns:repeat(11,minmax(0,1fr));gap:var(--hm-space-micro);min-inline-size:0;margin:0;padding:0;list-style:none}.ratings__hist-col{display:flex;flex-direction:column;align-items:center;gap:var(--hm-space-nano);min-inline-size:0;font-size:var(--hm-font-size-xs);font-variant-numeric:tabular-nums;cursor:default}.ratings__hist-col:hover .ratings__hist-track{box-shadow:0 0 0 2px var(--hm-divider)}.ratings__hist-track{display:flex;align-items:flex-end;inline-size:100%;max-inline-size:1.75rem;block-size:3.75rem;border-radius:var(--hm-radius-micro);background:var(--hm-surface-muted);overflow:hidden}.ratings__hist-bar{display:block;inline-size:100%;border-radius:var(--hm-radius-micro) var(--hm-radius-micro) 0 0;transition:height .16s ease}.ratings__hist-score{color:var(--hm-muted)}@container (max-width: 30rem){.ratings__kpi-main{flex-direction:column;align-items:stretch;gap:var(--hm-space-sm)}.ratings__figure{flex-flow:row wrap;align-items:center;gap:var(--hm-space-xs) var(--hm-space-sm)}}.ratings__fill--success{background:var(--hm-success)}.ratings__fill--warning{background:var(--hm-warning)}.ratings__fill--danger{background:var(--hm-danger)}.ratings__fill--neutral{background:transparent}.ratings__columns{display:grid;grid-template-columns:minmax(0,2fr) minmax(18rem,1fr);align-items:start;gap:var(--hm-space-md)}@container (max-width: 64rem){.ratings__columns{grid-template-columns:minmax(0,1fr)}}.ratings__main{min-inline-size:0;scroll-margin-block-start:var(--hm-space-md)}.ratings__recent{display:flex;flex-direction:column;gap:var(--hm-space-sm);min-inline-size:0}.ratings__empty{margin:0;padding:var(--hm-space-md);border-radius:var(--hm-radius-control);background:var(--hm-surface-muted);color:var(--hm-muted);text-align:center}.ratings__feed{display:flex;flex-direction:column;gap:var(--hm-space-micro);margin:0;padding:0;list-style:none}.ratings__feed-item{display:flex;align-items:flex-start;gap:var(--hm-space-sm);padding:var(--hm-space-xs) var(--hm-space-sm);border-radius:var(--hm-radius-control);background:var(--hm-surface-muted);font-size:var(--hm-font-size-sm)}.ratings__feed-avatar{flex:none}.ratings__feed-body{display:flex;flex:1 1 auto;flex-direction:column;gap:var(--hm-space-nano);min-inline-size:0}.ratings__feed-head{display:flex;align-items:baseline;gap:var(--hm-space-xs);min-inline-size:0}.ratings__author{overflow:hidden;color:var(--hm-text);font-weight:var(--hm-font-weight-semibold);text-overflow:ellipsis;white-space:nowrap}.ratings__when{flex:none;margin-inline-start:auto;color:var(--hm-muted);font-size:var(--hm-font-size-xs);white-space:nowrap}.ratings__feed-meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hm-space-xs);min-inline-size:0}.ratings__feed-meta>hm-tag{max-inline-size:100%}.ratings__item-value{color:var(--hm-text);font-variant-numeric:tabular-nums;font-weight:var(--hm-font-weight-semibold)}.ratings__feed-comment{display:-webkit-box;margin:0;overflow:hidden;color:var(--hm-text);overflow-wrap:anywhere;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.ratings__all{align-self:flex-end}.ratings__all-body{display:flex;flex-direction:column;gap:var(--hm-space-sm);min-inline-size:0;container-type:inline-size}.ratings__filters{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--hm-space-xs) var(--hm-space-sm)}.ratings__filter{flex:1 1 9rem;min-inline-size:0}.ratings__filter--wide{flex-basis:13rem}.ratings__switch{flex:none;padding-block-end:var(--hm-space-xs)}.ratings__list{display:flex;flex-direction:column;gap:var(--hm-space-micro);margin:0;padding:0;list-style:none;transition:opacity .12s ease}.ratings__list--busy{opacity:.55}.ratings__item{display:grid;grid-template-areas:\"avatar who score date menu\" \"avatar target target target target\" \"avatar comment comment comment comment\";grid-template-columns:auto minmax(0,1fr) auto auto 2rem;align-items:center;gap:var(--hm-space-nano) var(--hm-space-sm);padding:var(--hm-space-xs) var(--hm-space-sm);border-radius:var(--hm-radius-control);background:var(--hm-surface-muted);font-size:var(--hm-font-size-sm)}.ratings__item-avatar{grid-area:avatar;align-self:start}.ratings__item-who{grid-area:who}.ratings__item-score{display:inline-flex;grid-area:score;align-items:center;gap:var(--hm-space-xs);white-space:nowrap}.ratings__target{display:flex;flex-wrap:wrap;grid-area:target;align-items:center;gap:var(--hm-space-xs);min-inline-size:0}.ratings__target>hm-tag{max-inline-size:100%}.ratings__route{overflow:hidden;color:var(--hm-muted);font-family:var(--hm-font-mono);font-size:var(--hm-font-size-xs);text-overflow:ellipsis;white-space:nowrap}.ratings__comment{grid-area:comment;margin:0;color:var(--hm-text);white-space:pre-line;overflow-wrap:anywhere}.ratings__comment--none{color:var(--hm-muted);font-style:italic}.ratings__date{grid-area:date;color:var(--hm-muted);font-size:var(--hm-font-size-xs);font-variant-numeric:tabular-nums;white-space:nowrap}.ratings__item-menu{display:inline-flex;grid-area:menu;justify-content:flex-end}@container (max-width: 28rem){.ratings__item{grid-template-areas:\"avatar who menu\" \"avatar score date\" \"avatar target target\" \"avatar comment comment\";grid-template-columns:auto minmax(0,1fr) auto}}.ratings__pager{margin-block-start:var(--hm-space-xs)}@media(prefers-reduced-motion:reduce){.ratings__hist-bar,.ratings__list{transition:none}}:host-context([data-motion=reduce]) .ratings__hist-bar,:host-context([data-motion=reduce]) .ratings__list{transition:none}\n"], dependencies: [{ kind: "component", type: AccountAvatarComponent, selector: "hm-account-avatar", inputs: ["name", "imageUrl", "size", "loading", "presence", "texts"] }, { kind: "component", type: AlertComponent, selector: "hm-alert", inputs: ["variant", "appearance", "heading", "closable", "size", "showIcon", "link", "linkLabel", "linkTarget", "dismissKey", "duration"], outputs: ["closed"] }, { kind: "component", type: ButtonComponent, selector: "hm-button", inputs: ["emphasis", "intent", "size", "type", "icon", "iconDirection", "iconEnd", "disabled", "loading", "loadingState", "block", "link", "newTab", "caret", "inMenu", "toggle", "pressed"], outputs: ["loadingStateChange", "pressedChange", "clicked"] }, { kind: "component", type: CardComponent, selector: "hm-card", inputs: ["heading", "icon", "selected", "fill", "media", "mediaAlt", "mediaDecorative", "mediaPosition"] }, { kind: "component", type: ComboboxComponent, selector: "hm-combobox", inputs: ["label", "options", "value", "placeholder", "icon", "hint", "size", "labelHidden", "clearable", "loading", "allowCustomValue"], outputs: ["valueChange"] }, { kind: "component", type: DrawerComponent, selector: "hm-drawer", inputs: ["open", "heading", "size", "position", "pinned", "closeLabel", "closable", "closeOnBackdrop", "beforeClose"], outputs: ["openChange", "closed"] }, { kind: "component", type: IconComponent, selector: "hm-icon", inputs: ["shape", "direction", "size", "solid", "badge", "status", "flip", "inverse", "label"] }, { kind: "component", type: MenuButtonComponent, selector: "hm-menu-button", inputs: ["label", "icon", "items", "showArrow", "align", "side", "size", "shape", "layer", "closeOnCheck", "disabled"], outputs: ["chosen", "checkedChange"] }, { kind: "component", type: PaginatorComponent, selector: "hm-paginator", inputs: ["state", "totalItems", "variant", "label", "showPage", "hasNext", "hasPrevious", "sizes", "maxNumbers"], outputs: ["stateChanged", "nextPage", "previousPage"] }, { kind: "component", type: SegmentedControlComponent, selector: "hm-segmented-control", inputs: ["options", "value", "label", "size", "emphasis"], outputs: ["valueChange"] }, { kind: "component", type: SkeletonComponent, selector: "hm-skeleton", inputs: ["shape", "count", "label"] }, { kind: "component", type: StateScreenComponent, selector: "hm-state-screen", inputs: ["heading", "description", "situation", "action", "actionIcon"], outputs: ["actionTriggered"] }, { kind: "component", type: SwitchComponent, selector: "hm-switch", inputs: ["value", "label", "hint", "labelPosition", "loading"], outputs: ["valueChange"] }, { kind: "component", type: TabComponent, selector: "hm-tab", inputs: ["id", "label", "disabled", "count", "route", "exact", "destroyOnHide"] }, { kind: "directive", type: TabContentDirective, selector: "ng-template[hmTabContent]" }, { kind: "component", type: TabsComponent, selector: "hm-tabs", inputs: ["label", "active", "orientation", "mode", "overflow", "fillHeight", "noPanelGap"], outputs: ["activeChange"] }, { kind: "component", type: TagComponent, selector: "hm-tag", inputs: ["name", "color", "compact"] }, { kind: "directive", type: TooltipDirective, selector: "[hmTooltip]", inputs: ["hmTooltip", "hmTooltipSide", "hmTooltipDisabled", "hmTooltipShowDelay", "hmTooltipHideDelay"] }, { kind: "directive", type: SpinePageActionsDirective, selector: "ng-template[spinePageActions]" }, { kind: "component", type: SpineRatingStarsComponent, selector: "spine-rating-stars", inputs: ["value", "readonly", "showValue", "showName", "size", "label", "labelledBy", "describedBy", "invalid"], outputs: ["valueChange"] }, { kind: "component", type: RatingsTableComponent, selector: "spine-ratings-table", inputs: ["mode", "rows", "area", "selected"], outputs: ["areaChange", "picked"] }, { kind: "component", type: RatingsTrendComponent, selector: "spine-ratings-trend", inputs: ["series"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
726
726
  }
727
727
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: AutoServiceRatingsComponent, decorators: [{
728
728
  type: Component,
@@ -766,4 +766,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImpo
766
766
  }] });
767
767
 
768
768
  export { AutoServiceRatingsPageComponent };
769
- //# sourceMappingURL=trismegisto-spine-auto-service-auto-service-ratings-page.component-C_THGTkw.mjs.map
769
+ //# sourceMappingURL=trismegisto-spine-auto-service-auto-service-ratings-page.component-CHPU-QLJ.mjs.map