@trismegisto/spine 3.3.5 → 3.3.7

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 (72) hide show
  1. package/README.md +4 -2
  2. package/fesm2022/trismegisto-spine-audit.mjs +20 -2
  3. package/fesm2022/trismegisto-spine-audit.mjs.map +1 -1
  4. package/fesm2022/{trismegisto-spine-auto-service-auto-service-audit.component-D8HUpZtA.mjs → trismegisto-spine-auto-service-auto-service-audit.component-CszXNvSs.mjs} +2 -2
  5. package/fesm2022/{trismegisto-spine-auto-service-auto-service-audit.component-D8HUpZtA.mjs.map → trismegisto-spine-auto-service-auto-service-audit.component-CszXNvSs.mjs.map} +1 -1
  6. package/fesm2022/{trismegisto-spine-auto-service-auto-service-client-picker.component-NawbfdLW.mjs → trismegisto-spine-auto-service-auto-service-client-picker.component-CknHYd_P.mjs} +7 -3
  7. package/fesm2022/trismegisto-spine-auto-service-auto-service-client-picker.component-CknHYd_P.mjs.map +1 -0
  8. package/fesm2022/{trismegisto-spine-auto-service-auto-service-client.component-kAXaCM5W.mjs → trismegisto-spine-auto-service-auto-service-client.component-Dg3mJrpz.mjs} +24 -5
  9. package/fesm2022/trismegisto-spine-auto-service-auto-service-client.component-Dg3mJrpz.mjs.map +1 -0
  10. package/fesm2022/{trismegisto-spine-auto-service-auto-service-delete-CV_t9vxm.mjs → trismegisto-spine-auto-service-auto-service-delete-BWY5G-xe.mjs} +2 -2
  11. package/fesm2022/trismegisto-spine-auto-service-auto-service-delete-BWY5G-xe.mjs.map +1 -0
  12. package/fesm2022/{trismegisto-spine-auto-service-auto-service-groups.component-DE2QIGRH.mjs → trismegisto-spine-auto-service-auto-service-groups.component-DQqzfq0M.mjs} +21 -5
  13. package/fesm2022/trismegisto-spine-auto-service-auto-service-groups.component-DQqzfq0M.mjs.map +1 -0
  14. package/fesm2022/{trismegisto-spine-auto-service-auto-service-login-attempts.component-DoyhkSYc.mjs → trismegisto-spine-auto-service-auto-service-login-attempts.component-CjxKYv-y.mjs} +2 -2
  15. package/fesm2022/{trismegisto-spine-auto-service-auto-service-login-attempts.component-DoyhkSYc.mjs.map → trismegisto-spine-auto-service-auto-service-login-attempts.component-CjxKYv-y.mjs.map} +1 -1
  16. package/fesm2022/{trismegisto-spine-auto-service-auto-service-news-page.component-BW7BJ0oD.mjs → trismegisto-spine-auto-service-auto-service-news-page.component-Cbaszx4F.mjs} +21 -5
  17. package/fesm2022/trismegisto-spine-auto-service-auto-service-news-page.component-Cbaszx4F.mjs.map +1 -0
  18. package/fesm2022/{trismegisto-spine-auto-service-auto-service-ratings-page.component-CHPU-QLJ.mjs → trismegisto-spine-auto-service-auto-service-ratings-page.component-CJRIDWXi.mjs} +22 -4
  19. package/fesm2022/trismegisto-spine-auto-service-auto-service-ratings-page.component-CJRIDWXi.mjs.map +1 -0
  20. package/fesm2022/{trismegisto-spine-auto-service-auto-service-suggestions-page.component-CkiCTmXD.mjs → trismegisto-spine-auto-service-auto-service-suggestions-page.component-Bu8YX554.mjs} +46 -4
  21. package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-Bu8YX554.mjs.map +1 -0
  22. package/fesm2022/{trismegisto-spine-auto-service-auto-service.component-D58Ht9PH.mjs → trismegisto-spine-auto-service-auto-service.component-BLkLHp6J.mjs} +23 -5
  23. package/fesm2022/trismegisto-spine-auto-service-auto-service.component-BLkLHp6J.mjs.map +1 -0
  24. package/fesm2022/{trismegisto-spine-auto-service-home.component-9WvXOH3l.mjs → trismegisto-spine-auto-service-home.component-BYMiTZp6.mjs} +6 -3
  25. package/fesm2022/trismegisto-spine-auto-service-home.component-BYMiTZp6.mjs.map +1 -0
  26. package/fesm2022/trismegisto-spine-auto-service.mjs +10 -10
  27. package/fesm2022/trismegisto-spine-auto-service.mjs.map +1 -1
  28. package/fesm2022/trismegisto-spine-layout-ai-agent-chat.component-LlxtxNA5.mjs +294 -0
  29. package/fesm2022/trismegisto-spine-layout-ai-agent-chat.component-LlxtxNA5.mjs.map +1 -0
  30. package/fesm2022/trismegisto-spine-layout-ai-agent-transcript-BNcgbrV_.mjs +438 -0
  31. package/fesm2022/trismegisto-spine-layout-ai-agent-transcript-BNcgbrV_.mjs.map +1 -0
  32. package/fesm2022/{trismegisto-spine-layout-suggestions-page.component-CEKMqera.mjs → trismegisto-spine-layout-suggestions-page.component-BEGFNlvw.mjs} +18 -4
  33. package/fesm2022/trismegisto-spine-layout-suggestions-page.component-BEGFNlvw.mjs.map +1 -0
  34. package/fesm2022/{trismegisto-spine-layout-trismegisto-spine-layout-DiAfxIGP.mjs → trismegisto-spine-layout-trismegisto-spine-layout-D3vetDC_.mjs} +1075 -57
  35. package/fesm2022/trismegisto-spine-layout-trismegisto-spine-layout-D3vetDC_.mjs.map +1 -0
  36. package/fesm2022/trismegisto-spine-layout.mjs +1 -1
  37. package/fesm2022/trismegisto-spine-modal.mjs +4 -1
  38. package/fesm2022/trismegisto-spine-modal.mjs.map +1 -1
  39. package/fesm2022/trismegisto-spine-notification.mjs +1 -1
  40. package/fesm2022/trismegisto-spine-notification.mjs.map +1 -1
  41. package/fesm2022/trismegisto-spine-routing.mjs +2 -2
  42. package/fesm2022/trismegisto-spine-routing.mjs.map +1 -1
  43. package/fesm2022/trismegisto-spine-shell.mjs +2 -1
  44. package/fesm2022/trismegisto-spine-shell.mjs.map +1 -1
  45. package/fesm2022/trismegisto-spine-side-panel.mjs +4 -1
  46. package/fesm2022/trismegisto-spine-side-panel.mjs.map +1 -1
  47. package/fesm2022/trismegisto-spine.mjs +218 -69
  48. package/fesm2022/trismegisto-spine.mjs.map +1 -1
  49. package/package.json +6 -6
  50. package/types/trismegisto-spine-audit.d.ts +11 -4
  51. package/types/trismegisto-spine-audit.d.ts.map +1 -1
  52. package/types/trismegisto-spine-auto-service.d.ts.map +1 -1
  53. package/types/trismegisto-spine-layout.d.ts +124 -105
  54. package/types/trismegisto-spine-layout.d.ts.map +1 -1
  55. package/types/trismegisto-spine-modal.d.ts +2 -1
  56. package/types/trismegisto-spine-modal.d.ts.map +1 -1
  57. package/types/trismegisto-spine-shell.d.ts.map +1 -1
  58. package/types/trismegisto-spine-side-panel.d.ts +2 -1
  59. package/types/trismegisto-spine-side-panel.d.ts.map +1 -1
  60. package/types/trismegisto-spine.d.ts +110 -28
  61. package/types/trismegisto-spine.d.ts.map +1 -1
  62. package/fesm2022/trismegisto-spine-auto-service-auto-service-client-picker.component-NawbfdLW.mjs.map +0 -1
  63. package/fesm2022/trismegisto-spine-auto-service-auto-service-client.component-kAXaCM5W.mjs.map +0 -1
  64. package/fesm2022/trismegisto-spine-auto-service-auto-service-delete-CV_t9vxm.mjs.map +0 -1
  65. package/fesm2022/trismegisto-spine-auto-service-auto-service-groups.component-DE2QIGRH.mjs.map +0 -1
  66. package/fesm2022/trismegisto-spine-auto-service-auto-service-news-page.component-BW7BJ0oD.mjs.map +0 -1
  67. package/fesm2022/trismegisto-spine-auto-service-auto-service-ratings-page.component-CHPU-QLJ.mjs.map +0 -1
  68. package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-CkiCTmXD.mjs.map +0 -1
  69. package/fesm2022/trismegisto-spine-auto-service-auto-service.component-D58Ht9PH.mjs.map +0 -1
  70. package/fesm2022/trismegisto-spine-auto-service-home.component-9WvXOH3l.mjs.map +0 -1
  71. package/fesm2022/trismegisto-spine-layout-suggestions-page.component-CEKMqera.mjs.map +0 -1
  72. package/fesm2022/trismegisto-spine-layout-trismegisto-spine-layout-DiAfxIGP.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"trismegisto-spine-auto-service.mjs","sources":["../../../projects/ui/auto-service/src/auto-service.tokens.ts","../../../projects/ui/auto-service/src/provide-auto-service.ts","../../../projects/ui/auto-service/src/auto-service.service.ts","../../../projects/ui/auto-service/src/public-api.ts","../../../projects/ui/auto-service/src/trismegisto-spine-auto-service.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport interface AutoServiceConfig {\n // Base URL do argos-admin-server (o mesmo backend central que atende\n // /admin/*) -- /auto-service/* já existe lá, escopado por client_id, servindo\n // qualquer aplicação que instale este pacote, não só o argos-admin.\n adminApi: string;\n}\n\nexport const AUTO_SERVICE_CONFIG = new InjectionToken<AutoServiceConfig>('AUTO_SERVICE_CONFIG');\n\n// router_id dos roteadores (páginas) do template \"auto-service\" (web.template_router,\n// ver apps/argos/database/argos/seed/web/04-template_router.sql) -- valores literais e\n// estáveis (mesma convenção do resto do seed: UUID fixo, nunca gerado em runtime). É\n// contra ISSO que o ComponentDistributorService casa via source_template_router_id\n// (não o router_id materializado de cada client, que varia): qualquer client\n// vinculado ao template \"auto-service\" resolve todos automaticamente, sem precisar\n// declarar nada no próprio features.routes.ts. Grupos, Aplicações e Cliente ficam no grupo\n// \"Administração\" do template e Ações e Tentativas de login no grupo \"Auditoria\"; Início,\n// Novidades, Sugestões e Avaliações são páginas soltas na raiz. Os grupos nunca precisam de\n// componente (nunca são page_id de router).\nexport const AUTO_SERVICE_GROUPS_TEMPLATE_ROUTER_ID = 'ad100001-0000-4000-8000-000000000001';\nexport const AUTO_SERVICE_APPS_TEMPLATE_ROUTER_ID = 'ad100002-0000-4000-8000-000000000001';\nexport const AUTO_SERVICE_CLIENT_TEMPLATE_ROUTER_ID = 'ad100003-0000-4000-8000-000000000001';\n// Menu \"Auditoria\" (rota AD000006, dentro de \"Administração\", migration 0012 do argos): duas páginas.\n// Ações (a leitura da auditoria, `audit.events`) -- o nome da constante ficou do tempo em que era a página \"Auditoria\".\nexport const AUTO_SERVICE_AUDIT_TEMPLATE_ROUTER_ID = 'ad100004-0000-4000-8000-000000000001';\n// Tentativas de login (`auth.auth_attempts` com o client do app).\nexport const AUTO_SERVICE_LOGIN_ATTEMPTS_TEMPLATE_ROUTER_ID = 'ad100005-0000-4000-8000-000000000001';\n// Novidades, Sugestões e Avaliações (migration 0036 do argos): páginas na raiz, fora de \"Administração\" -- eram abas\n// da tela Cliente. Cada uma é o seletor de client + o painel que ficava na aba.\nexport const AUTO_SERVICE_NEWS_TEMPLATE_ROUTER_ID = 'ad100006-0000-4000-8000-000000000001';\nexport const AUTO_SERVICE_SUGGESTIONS_TEMPLATE_ROUTER_ID = 'ad100007-0000-4000-8000-000000000001';\nexport const AUTO_SERVICE_RATINGS_TEMPLATE_ROUTER_ID = 'ad100008-0000-4000-8000-000000000001';\n// Início (\"home\", página de topo e pública do mesmo template). Todo client clonado do\n// template ganha a própria linha em web.router com source_template_router_id apontando pra cá.\nexport const AUTO_SERVICE_HOME_TEMPLATE_ROUTER_ID = '6a9a13db-f31b-494e-b51c-79af0ac28b60';\n","import { EnvironmentProviders, Type, makeEnvironmentProviders } from '@angular/core';\nimport { COMPONENT_ROUTES, ComponentRoute, RouteDocument } from '@trismegisto/spine/routing';\nimport { SPINE_ADMIN_API } from '@trismegisto/spine';\nimport {\n AUTO_SERVICE_CONFIG, AutoServiceConfig,\n AUTO_SERVICE_GROUPS_TEMPLATE_ROUTER_ID, AUTO_SERVICE_APPS_TEMPLATE_ROUTER_ID, AUTO_SERVICE_CLIENT_TEMPLATE_ROUTER_ID,\n AUTO_SERVICE_HOME_TEMPLATE_ROUTER_ID, AUTO_SERVICE_AUDIT_TEMPLATE_ROUTER_ID, AUTO_SERVICE_LOGIN_ATTEMPTS_TEMPLATE_ROUTER_ID,\n AUTO_SERVICE_NEWS_TEMPLATE_ROUTER_ID, AUTO_SERVICE_SUGGESTIONS_TEMPLATE_ROUTER_ID, AUTO_SERVICE_RATINGS_TEMPLATE_ROUTER_ID,\n} from './auto-service.tokens';\n\n/**\n * As 9 telas do auto-serviço, carregadas sob demanda. Cada `import()` relativo vira um chunk próprio no\n * FESM publicado (`trismegisto-spine-auto-service-<tela>-<hash>.mjs`), que o bundler do app mantém fora\n * do carregamento inicial. Não exporte as telas no `public-api.ts` (ver o comentário lá).\n */\nexport const AUTO_SERVICE_SCREENS: Readonly<Record<\n 'home' | 'groups' | 'apps' | 'client' | 'audit' | 'loginAttempts' | 'news' | 'suggestions' | 'ratings',\n () => Promise<Type<unknown>>\n>> = {\n home: () => import('./home/home.component').then(m => m.HomeComponent),\n groups: () => import('./groups/auto-service-groups.component').then(m => m.AutoServiceGroupsComponent),\n apps: () => import('./auto-service.component').then(m => m.AutoServiceComponent),\n client: () => import('./auto-service-client.component').then(m => m.AutoServiceClientComponent),\n audit: () => import('./audit/auto-service-audit.component').then(m => m.AutoServiceAuditComponent),\n loginAttempts: () => import('./audit/auto-service-login-attempts.component').then(m => m.AutoServiceLoginAttemptsComponent),\n news: () => import('./pages/auto-service-news-page.component').then(m => m.AutoServiceNewsPageComponent),\n suggestions: () => import('./pages/auto-service-suggestions-page.component').then(m => m.AutoServiceSuggestionsPageComponent),\n ratings: () => import('./pages/auto-service-ratings-page.component').then(m => m.AutoServiceRatingsPageComponent),\n};\n\n/**\n * Documentação das 9 telas (botão de documentação da barra da página e índice \"Documentação do sistema\"): o manual\n * de uso (`load`) e a especificação técnica (`loadTechnical`, só com `SpineConfig.technicalDocs`). O Markdown fica em\n * módulos `.ts` próprios em `./docs/` (o ng-packagr não carrega `.md` como texto), cada um atrás de um `import()`\n * relativo: vira um chunk à parte no FESM e só é baixado quando alguém abre o documento. Sem `title`/`group`: o\n * índice usa o nome da rota e o módulo da árvore do client. O `SpineDocsService` casa estas entradas pelo\n * `source_template_router_id`, como o `ComponentDistributorService` faz com as telas.\n */\nexport const AUTO_SERVICE_DOCUMENTS: Readonly<Record<keyof typeof AUTO_SERVICE_SCREENS, RouteDocument>> = {\n home: {\n load: () => import('./docs/home.usage').then(m => m.default),\n loadTechnical: () => import('./docs/home.technical').then(m => m.default),\n },\n groups: {\n load: () => import('./docs/groups.usage').then(m => m.default),\n loadTechnical: () => import('./docs/groups.technical').then(m => m.default),\n },\n apps: {\n load: () => import('./docs/apps.usage').then(m => m.default),\n loadTechnical: () => import('./docs/apps.technical').then(m => m.default),\n },\n client: {\n load: () => import('./docs/client.usage').then(m => m.default),\n loadTechnical: () => import('./docs/client.technical').then(m => m.default),\n },\n audit: {\n load: () => import('./docs/audit.usage').then(m => m.default),\n loadTechnical: () => import('./docs/audit.technical').then(m => m.default),\n },\n loginAttempts: {\n load: () => import('./docs/login-attempts.usage').then(m => m.default),\n loadTechnical: () => import('./docs/login-attempts.technical').then(m => m.default),\n },\n news: {\n load: () => import('./docs/news.usage').then(m => m.default),\n loadTechnical: () => import('./docs/news.technical').then(m => m.default),\n },\n suggestions: {\n load: () => import('./docs/suggestions.usage').then(m => m.default),\n loadTechnical: () => import('./docs/suggestions.technical').then(m => m.default),\n },\n ratings: {\n load: () => import('./docs/ratings.usage').then(m => m.default),\n loadTechnical: () => import('./docs/ratings.technical').then(m => m.default),\n },\n};\n\n// Cada app consumidora chama isso uma vez no bootstrap (mesmo padrão do\n// provideAuth do @orfeu/angular) informando só a URL do argos-admin-server --\n// o resto vem pronto: rotas/serviço (@trismegisto/spine/auto-service) E a própria\n// ligação com os itens de menu, registrada aqui via source_template_router_id (não\n// route_id -- esse varia por client, ver ComponentDistributorService). O app não\n// precisa (e não deve) declarar nada em features.routes.ts pra isso funcionar; basta\n// o client dele estar vinculado ao template \"auto-service\" (auth.clients.template_id).\n// 9 páginas (Início, Novidades, Sugestões e Avaliações na raiz + Grupos/Aplicações/Cliente em Administração +\n// Ações/Tentativas de login em Auditoria) -- o ComponentDistributorService\n// já suporta N entradas, cada uma casando pelo seu próprio source_template_router_id.\nexport function provideAutoService(config: AutoServiceConfig): EnvironmentProviders {\n const componentRoutes: ComponentRoute[] = [\n { source_template_router_id: AUTO_SERVICE_HOME_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.home, document: AUTO_SERVICE_DOCUMENTS.home },\n { source_template_router_id: AUTO_SERVICE_GROUPS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.groups, document: AUTO_SERVICE_DOCUMENTS.groups },\n { source_template_router_id: AUTO_SERVICE_APPS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.apps, document: AUTO_SERVICE_DOCUMENTS.apps },\n { source_template_router_id: AUTO_SERVICE_CLIENT_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.client, document: AUTO_SERVICE_DOCUMENTS.client },\n { source_template_router_id: AUTO_SERVICE_AUDIT_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.audit, document: AUTO_SERVICE_DOCUMENTS.audit },\n { source_template_router_id: AUTO_SERVICE_LOGIN_ATTEMPTS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.loginAttempts, document: AUTO_SERVICE_DOCUMENTS.loginAttempts },\n { source_template_router_id: AUTO_SERVICE_NEWS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.news, document: AUTO_SERVICE_DOCUMENTS.news },\n { source_template_router_id: AUTO_SERVICE_SUGGESTIONS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.suggestions, document: AUTO_SERVICE_DOCUMENTS.suggestions },\n { source_template_router_id: AUTO_SERVICE_RATINGS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.ratings, document: AUTO_SERVICE_DOCUMENTS.ratings },\n ];\n\n return makeEnvironmentProviders([\n { provide: AUTO_SERVICE_CONFIG, useValue: config },\n // Mesma URL, exposta também para o painel de configurações (tokens de aplicação em /me).\n { provide: SPINE_ADMIN_API, useValue: config.adminApi },\n { provide: COMPONENT_ROUTES, useValue: componentRoutes, multi: true },\n ]);\n}\n","import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';\nimport { Inject, Injectable } from '@angular/core';\nimport { Observable, firstValueFrom } from 'rxjs';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { urlPath } from '@trismegisto/primitives';\nimport { AUTO_SERVICE_CONFIG, AutoServiceConfig } from './auto-service.tokens';\n\n/** Nível de um nó na árvore do menu (`GET /routers/tree`). */\nexport type RouterOrderType = 'header' | 'navigation' | 'menu' | 'item' | 'submenu' | 'page';\n\n/** Nó da árvore do menu: uma rota num nível, com todos os routers que passam por ela. */\nexport interface RouterOrderNode {\n route_type: RouterOrderType;\n routed_id: string;\n route_name: string;\n route_display_name: string | null;\n route_icon: string | null;\n order: number;\n router_ids: string[];\n children: RouterOrderNode[];\n}\n\n/** Um item da ordem nova de um nível (`PATCH /routers/reorder`). */\nexport interface RouterOrderGroup { type: RouterOrderType; router_ids: string[] }\n\n/**\n * Grupo do projeto do client (`GET /groups`). O grupo de administração do projeto (`is_admin`) é gerido só no painel\n * central e o servidor não o devolve aqui; servidor antigo ainda devolve com `is_admin: true` e as telas descartam.\n */\nexport interface AutoServiceGroup {\n id: string;\n name: string;\n description: string | null;\n enabled: boolean;\n is_admin?: boolean;\n type: { id: string; name: string; level: number } | null;\n}\n\n/** Página e filtros de `GET /groups/:groupId/members`. */\nexport interface AutoServiceMembersQuery {\n page?: number;\n limit?: number;\n search?: string;\n}\n\n/** Uma página de membros: `total` conta quem passa pela busca. */\nexport interface AutoServiceMembersPage {\n members: any[];\n total: number;\n page: number;\n limit: number;\n}\n\n/** Sugestão de membro (`GET /groups/:groupId/member-suggestions`): está em outros grupos do sistema (`groups`). */\nexport interface AutoServiceMemberSuggestion {\n id: string;\n username: string;\n email: string | null;\n name: string | null;\n picture: string | null;\n group_count: number;\n groups: string[];\n}\n\n/** Tipo de grupo (crachá) do realm (`GET /group-types`). */\nexport interface AutoServiceGroupType { id: string; name: string; level: number; assignable: boolean }\n\n/** Corpo de `POST /groups` (o projeto é sempre o do client). */\nexport interface AutoServiceGroupCreate { group_id?: string; name: string; type_id: string; description?: string }\n\n/** Corpo de `PUT /groups/:groupId`; do grupo de administração só `description`. `null` apaga a descrição. */\nexport interface AutoServiceGroupUpdate { name?: string; type_id?: string; description?: string | null; enabled?: boolean }\n\n/** Aplicação (client_credentials) do projeto do client (`GET /apps`). */\nexport interface AutoServiceApp {\n id: string;\n name: string;\n enabled: boolean;\n allowed_grants?: string[] | null;\n [key: string]: unknown;\n}\n\n/**\n * Token de API (`x-api-token`) de uma aplicação (`GET /apps/:appId/tokens`). O valor só vem na criação; aqui fica o\n * começo dele (`token_prefix`) para reconhecer. Cada token é também um consumer (`consumer_id`) com as permissões dele.\n */\nexport interface AutoServiceAppToken {\n id: string;\n consumer_id: string;\n name: string;\n description: string | null;\n token_prefix: string;\n expires_at: string;\n revoked_at: string | null;\n created_at: string;\n last_used_at: string | null;\n}\n\n/** Corpo de `POST /apps/:appId/tokens`: validade ISO (até 365 dias) e as operações protected liberadas ao token. */\nexport interface AutoServiceAppTokenCreate { name: string; description?: string; expires_at: string; operation_ids?: string[] }\n\n/** Resposta de `POST /apps/:appId/tokens`: `token` é o valor cru, devolvido uma única vez. */\nexport interface AutoServiceAppTokenCreated { id: string; consumer_id: string; name: string; token: string }\n\n@Injectable({ providedIn: 'root' })\nexport class AutoServiceService {\n\n private get baseUrl() {\n return `${this.config.adminApi}/auto-service`;\n }\n\n /** `baseUrl` + caminho com cada id interpolado codificado (`urlPath`): um id com `/`, `?`, `#` ou `..` não muda o recurso. */\n private url(strings: TemplateStringsArray, ...ids: readonly string[]): string {\n return this.baseUrl + urlPath(strings, ...ids);\n }\n\n private get headers(): HttpHeaders {\n const token = this.auth.getToken();\n return new HttpHeaders({ 'x-access-token': token ?? '' });\n }\n\n constructor(\n private http: HttpClient,\n private auth: AuthorizationService,\n @Inject(AUTO_SERVICE_CONFIG) private config: AutoServiceConfig,\n ) {}\n\n // Descoberta\n getMyClients() { return firstValueFrom(this.http.get<{ clients: any[] }>(this.baseUrl, { headers: this.headers })); }\n\n // Routes\n getWebRoutes(clientId: string) { return firstValueFrom(this.http.get<{ routes: any[] }>(this.url`/${clientId}/routes`, { headers: this.headers })); }\n createWebRoute(clientId: string, body: any) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/routes`, body, { headers: this.headers })); }\n updateWebRoute(clientId: string, id: string, body: any) { return firstValueFrom(this.http.put<any>(this.url`/${clientId}/routes/${id}`, body, { headers: this.headers })); }\n deleteWebRoute(clientId: string, id: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/routes/${id}`, { headers: this.headers })); }\n\n // Routers\n getRouters(clientId: string) { return firstValueFrom(this.http.get<{ routers: any[] }>(this.url`/${clientId}/routers`, { headers: this.headers })); }\n createRouter(clientId: string, body: any) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/routers`, body, { headers: this.headers })); }\n updateRouter(clientId: string, id: string, body: any) { return firstValueFrom(this.http.put<any>(this.url`/${clientId}/routers/${id}`, body, { headers: this.headers })); }\n deleteRouter(clientId: string, id: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/routers/${id}`, { headers: this.headers })); }\n /** Árvore do menu (header → … → página) com os router_ids de cada nó, já na ordem gravada. */\n getRouterTree(clientId: string) { return firstValueFrom(this.http.get<{ tree: RouterOrderNode[] }>(this.url`/${clientId}/routers/tree`, { headers: this.headers })); }\n /**\n * Grava a ordem de UM nível (irmãos): o índice do grupo é a ordem; cada grupo escreve `${type}_order`\n * em todos os seus routers. Vale também para routers de template (ordem é do client).\n */\n reorderRouters(clientId: string, groups: RouterOrderGroup[]) { return firstValueFrom(this.http.patch<any>(this.url`/${clientId}/routers/reorder`, { groups }, { headers: this.headers })); }\n\n // Groups (do projeto do client, sem o grupo de administração: editar/excluir/membros dele respondem 404)\n getGroups(clientId: string) { return firstValueFrom(this.http.get<{ groups: AutoServiceGroup[] }>(this.url`/${clientId}/groups`, { headers: this.headers })); }\n /** Tipos (crachás) do realm; `assignable: false` no Administrador, que é só do grupo de administração (painel central). */\n getGroupTypes(clientId: string) { return firstValueFrom(this.http.get<{ group_types: AutoServiceGroupType[] }>(this.url`/${clientId}/group-types`, { headers: this.headers })); }\n createGroup(clientId: string, body: AutoServiceGroupCreate) { return firstValueFrom(this.http.post<AutoServiceGroup>(this.url`/${clientId}/groups`, body, { headers: this.headers })); }\n updateGroup(clientId: string, groupId: string, body: AutoServiceGroupUpdate) { return firstValueFrom(this.http.put<AutoServiceGroup>(this.url`/${clientId}/groups/${groupId}`, body, { headers: this.headers })); }\n deleteGroup(clientId: string, groupId: string) { return firstValueFrom(this.http.delete<void>(this.url`/${clientId}/groups/${groupId}`, { headers: this.headers })); }\n /**\n * Uma página dos membros (o servidor pagina: padrão 50, até 200 por página), pela ordem do login, com busca por nome,\n * login ou e-mail. Observable (não Promise): as telas pedem as páginas até o fim e cancelam a pendente ao fechar.\n */\n getGroupMembers(clientId: string, groupId: string, query: AutoServiceMembersQuery = {}): Observable<AutoServiceMembersPage> {\n let params = new HttpParams();\n if (query.page) params = params.set('page', String(query.page));\n if (query.limit) params = params.set('limit', String(query.limit));\n if (query.search?.trim()) params = params.set('search', query.search.trim());\n return this.http.get<AutoServiceMembersPage>(this.url`/${clientId}/groups/${groupId}/members`, { headers: this.headers, params });\n }\n /** Sugestões para adicionar ao grupo: quem já está em outro grupo deste sistema e ainda não neste, com foto e os grupos. */\n getMemberSuggestions(clientId: string, groupId: string, limit = 8) {\n const params = new HttpParams().set('limit', String(limit));\n return firstValueFrom(this.http.get<{ users: AutoServiceMemberSuggestion[] }>(this.url`/${clientId}/groups/${groupId}/member-suggestions`, { headers: this.headers, params }));\n }\n addGroupMember(clientId: string, groupId: string, userId: string, role: string | null) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/groups/${groupId}/members`, { user_id: userId, role }, { headers: this.headers })); }\n updateGroupMemberRole(clientId: string, groupId: string, userId: string, role: string | null) { return firstValueFrom(this.http.put<any>(this.url`/${clientId}/groups/${groupId}/members/${userId}`, { role }, { headers: this.headers })); }\n removeGroupMember(clientId: string, groupId: string, userId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/groups/${groupId}/members/${userId}`, { headers: this.headers })); }\n\n // Users (só leitura -- popular a busca de \"adicionar membro\" na aba Grupos, escopada pelo realm do próprio client)\n searchUsers(clientId: string, opts: { search?: string; limit?: number } = {}) {\n let params = new HttpParams();\n if (opts.search) params = params.set('search', opts.search);\n if (opts.limit) params = params.set('limit', String(opts.limit));\n return firstValueFrom(this.http.get<{ users: any[] }>(this.url`/${clientId}/users`, { headers: this.headers, params }));\n }\n\n // Access\n getAccess(clientId: string) { return firstValueFrom(this.http.get<{ access: any[] }>(this.url`/${clientId}/access`, { headers: this.headers })); }\n createAccess(clientId: string, groupId: string) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/access`, { group_id: groupId }, { headers: this.headers })); }\n deleteAccess(clientId: string, accessId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/access/${accessId}`, { headers: this.headers })); }\n getGuards(clientId: string, accessId: string) { return firstValueFrom(this.http.get<{ guards: any[] }>(this.url`/${clientId}/access/${accessId}/guards`, { headers: this.headers })); }\n addGuard(clientId: string, accessId: string, routerId: string) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/access/${accessId}/guards`, { router_id: routerId }, { headers: this.headers })); }\n removeGuard(clientId: string, accessId: string, guardId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/access/${accessId}/guards/${guardId}`, { headers: this.headers })); }\n\n // Apps (aplicações client_credentials no Project deste client)\n getApps(clientId: string) { return firstValueFrom(this.http.get<{ apps: AutoServiceApp[] }>(this.url`/${clientId}/apps`, { headers: this.headers })); }\n createApp(clientId: string, body: { name: string; allowed_grants?: string[] }) { return firstValueFrom(this.http.post<{ id: string; name: string; secret: string }>(this.url`/${clientId}/apps`, body, { headers: this.headers })); }\n updateApp(clientId: string, appId: string, body: any) { return firstValueFrom(this.http.put<any>(this.url`/${clientId}/apps/${appId}`, body, { headers: this.headers })); }\n /** Gera um segredo novo para a aplicação (o anterior para de valer na hora). A resposta traz o segredo uma única vez. */\n rotateAppSecret(clientId: string, appId: string) { return firstValueFrom(this.http.post<{ id: string; secret: string }>(this.url`/${clientId}/apps/${appId}/secret`, {}, { headers: this.headers })); }\n deleteApp(clientId: string, appId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/apps/${appId}`, { headers: this.headers })); }\n getAppOperations(clientId: string, appId: string) { return firstValueFrom(this.http.get<{ operations: any[] }>(this.url`/${clientId}/apps/${appId}/operations`, { headers: this.headers })); }\n\n // Tokens de API da aplicação (x-api-token)\n getAppTokens(clientId: string, appId: string) { return firstValueFrom(this.http.get<{ tokens: AutoServiceAppToken[] }>(this.url`/${clientId}/apps/${appId}/tokens`, { headers: this.headers })); }\n /** Cria o token (e o consumer dele, com as permissões escolhidas). A resposta traz o valor uma única vez. */\n createAppToken(clientId: string, appId: string, body: AutoServiceAppTokenCreate) { return firstValueFrom(this.http.post<AutoServiceAppTokenCreated>(this.url`/${clientId}/apps/${appId}/tokens`, body, { headers: this.headers })); }\n /** Revoga: o token para de valer na hora e continua na lista como revogado. */\n revokeAppToken(clientId: string, appId: string, tokenId: string) { return firstValueFrom(this.http.delete<void>(this.url`/${clientId}/apps/${appId}/tokens/${tokenId}`, { headers: this.headers })); }\n\n // Consumers (grupo ↔ aplicação), sem o do grupo de administração: o servidor não o lista e o :consumerId dele é 404\n // (servidor antigo ainda devolve com `group_is_admin: true` e a aba Acessos descarta)\n getAppConsumers(clientId: string, appId: string) { return firstValueFrom(this.http.get<{ consumers: any[] }>(this.url`/${clientId}/apps/${appId}/consumers`, { headers: this.headers })); }\n createAppConsumer(clientId: string, appId: string, groupId: string) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/apps/${appId}/consumers`, { group_id: groupId }, { headers: this.headers })); }\n deleteAppConsumer(clientId: string, consumerId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/apps/consumers/${consumerId}`, { headers: this.headers })); }\n\n // Permissions (consumer ↔ operação)\n getAppPermissions(clientId: string, consumerId: string) { return firstValueFrom(this.http.get<{ permissions: any[] }>(this.url`/${clientId}/apps/consumers/${consumerId}/permissions`, { headers: this.headers })); }\n addAppPermission(clientId: string, consumerId: string, operationId: string) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/apps/consumers/${consumerId}/permissions`, { operation_id: operationId }, { headers: this.headers })); }\n removeAppPermission(clientId: string, consumerId: string, permissionId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/apps/consumers/${consumerId}/permissions/${permissionId}`, { headers: this.headers })); }\n // Auditoria: ver `SpineAuditService` (`@trismegisto/spine/audit`), o mesmo nos escopos admin e client.\n}\n","export * from './auto-service.tokens';\nexport * from './provide-auto-service';\nexport * from './auto-service.service';\nexport type { AutoServiceClient } from './client-picker/auto-service-client-picker.component';\n// A auditoria (tipos, serviço e a tela) mora em `@trismegisto/spine/audit` — NÃO reexporte daqui: um\n// `export` estático puxaria a tela para o arquivo deste ponto de entrada (ver abaixo e check-lazy).\n// As telas (Início, Grupos, Aplicações, Cliente) e as peças delas NÃO são exportadas daqui de propósito:\n// ficam só atrás dos `import()` de `AUTO_SERVICE_SCREENS`. Qualquer `export` estático de um componente\n// delas faz o rollup do ng-packagr juntar a tela no FESM do ponto de entrada e trocar o `import()` por\n// `Promise.resolve()` — e a tela (data-grid, combobox, drawer...) vai para o bundle inicial de todo app\n// (bug da 0.9.9). `scripts/check-lazy.mjs` (no `npm run build`) falha se isso voltar.\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trismegisto-spine-auto-service.mjs","sources":["../../../projects/ui/auto-service/src/auto-service.tokens.ts","../../../projects/ui/auto-service/src/provide-auto-service.ts","../../../projects/ui/auto-service/src/auto-service.service.ts","../../../projects/ui/auto-service/src/public-api.ts","../../../projects/ui/auto-service/src/trismegisto-spine-auto-service.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport interface AutoServiceConfig {\n // Base URL do argos-admin-server (o mesmo backend central que atende\n // /admin/*) -- /auto-service/* já existe lá, escopado por client_id, servindo\n // qualquer aplicação que instale este pacote, não só o argos-admin.\n adminApi: string;\n}\n\nexport const AUTO_SERVICE_CONFIG = new InjectionToken<AutoServiceConfig>('AUTO_SERVICE_CONFIG');\n\n// router_id dos roteadores (páginas) do template \"auto-service\" (web.template_router,\n// ver apps/argos/database/argos/seed/web/04-template_router.sql) -- valores literais e\n// estáveis (mesma convenção do resto do seed: UUID fixo, nunca gerado em runtime). É\n// contra ISSO que o ComponentDistributorService casa via source_template_router_id\n// (não o router_id materializado de cada client, que varia): qualquer client\n// vinculado ao template \"auto-service\" resolve todos automaticamente, sem precisar\n// declarar nada no próprio features.routes.ts. Grupos, Aplicações e Cliente ficam no grupo\n// \"Administração\" do template e Ações e Tentativas de login no grupo \"Auditoria\"; Início,\n// Novidades, Sugestões e Avaliações são páginas soltas na raiz. Os grupos nunca precisam de\n// componente (nunca são page_id de router).\nexport const AUTO_SERVICE_GROUPS_TEMPLATE_ROUTER_ID = 'ad100001-0000-4000-8000-000000000001';\nexport const AUTO_SERVICE_APPS_TEMPLATE_ROUTER_ID = 'ad100002-0000-4000-8000-000000000001';\nexport const AUTO_SERVICE_CLIENT_TEMPLATE_ROUTER_ID = 'ad100003-0000-4000-8000-000000000001';\n// Menu \"Auditoria\" (rota AD000006, dentro de \"Administração\", migration 0012 do argos): duas páginas.\n// Ações (a leitura da auditoria, `audit.events`) -- o nome da constante ficou do tempo em que era a página \"Auditoria\".\nexport const AUTO_SERVICE_AUDIT_TEMPLATE_ROUTER_ID = 'ad100004-0000-4000-8000-000000000001';\n// Tentativas de login (`auth.auth_attempts` com o client do app).\nexport const AUTO_SERVICE_LOGIN_ATTEMPTS_TEMPLATE_ROUTER_ID = 'ad100005-0000-4000-8000-000000000001';\n// Novidades, Sugestões e Avaliações (migration 0036 do argos): páginas na raiz, fora de \"Administração\" -- eram abas\n// da tela Cliente. Cada uma é o seletor de client + o painel que ficava na aba.\nexport const AUTO_SERVICE_NEWS_TEMPLATE_ROUTER_ID = 'ad100006-0000-4000-8000-000000000001';\nexport const AUTO_SERVICE_SUGGESTIONS_TEMPLATE_ROUTER_ID = 'ad100007-0000-4000-8000-000000000001';\nexport const AUTO_SERVICE_RATINGS_TEMPLATE_ROUTER_ID = 'ad100008-0000-4000-8000-000000000001';\n// Início (\"home\", página de topo e pública do mesmo template). Todo client clonado do\n// template ganha a própria linha em web.router com source_template_router_id apontando pra cá.\nexport const AUTO_SERVICE_HOME_TEMPLATE_ROUTER_ID = '6a9a13db-f31b-494e-b51c-79af0ac28b60';\n","import { EnvironmentProviders, Type, makeEnvironmentProviders } from '@angular/core';\nimport { COMPONENT_ROUTES, ComponentRoute, RouteDocument } from '@trismegisto/spine/routing';\nimport { SPINE_ADMIN_API } from '@trismegisto/spine';\nimport {\n AUTO_SERVICE_CONFIG, AutoServiceConfig,\n AUTO_SERVICE_GROUPS_TEMPLATE_ROUTER_ID, AUTO_SERVICE_APPS_TEMPLATE_ROUTER_ID, AUTO_SERVICE_CLIENT_TEMPLATE_ROUTER_ID,\n AUTO_SERVICE_HOME_TEMPLATE_ROUTER_ID, AUTO_SERVICE_AUDIT_TEMPLATE_ROUTER_ID, AUTO_SERVICE_LOGIN_ATTEMPTS_TEMPLATE_ROUTER_ID,\n AUTO_SERVICE_NEWS_TEMPLATE_ROUTER_ID, AUTO_SERVICE_SUGGESTIONS_TEMPLATE_ROUTER_ID, AUTO_SERVICE_RATINGS_TEMPLATE_ROUTER_ID,\n} from './auto-service.tokens';\n\n/**\n * As 9 telas do auto-serviço, carregadas sob demanda. Cada `import()` relativo vira um chunk próprio no\n * FESM publicado (`trismegisto-spine-auto-service-<tela>-<hash>.mjs`), que o bundler do app mantém fora\n * do carregamento inicial. Não exporte as telas no `public-api.ts` (ver o comentário lá).\n */\nexport const AUTO_SERVICE_SCREENS: Readonly<Record<\n 'home' | 'groups' | 'apps' | 'client' | 'audit' | 'loginAttempts' | 'news' | 'suggestions' | 'ratings',\n () => Promise<Type<unknown>>\n>> = {\n home: () => import('./home/home.component').then(m => m.HomeComponent),\n groups: () => import('./groups/auto-service-groups.component').then(m => m.AutoServiceGroupsComponent),\n apps: () => import('./auto-service.component').then(m => m.AutoServiceComponent),\n client: () => import('./auto-service-client.component').then(m => m.AutoServiceClientComponent),\n audit: () => import('./audit/auto-service-audit.component').then(m => m.AutoServiceAuditComponent),\n loginAttempts: () => import('./audit/auto-service-login-attempts.component').then(m => m.AutoServiceLoginAttemptsComponent),\n news: () => import('./pages/auto-service-news-page.component').then(m => m.AutoServiceNewsPageComponent),\n suggestions: () => import('./pages/auto-service-suggestions-page.component').then(m => m.AutoServiceSuggestionsPageComponent),\n ratings: () => import('./pages/auto-service-ratings-page.component').then(m => m.AutoServiceRatingsPageComponent),\n};\n\n/**\n * Documentação das 9 telas (botão de documentação da barra da página e índice \"Documentação do sistema\"): o manual\n * de uso (`load`) e a especificação técnica (`loadTechnical`, só com `SpineConfig.technicalDocs`). O Markdown fica em\n * módulos `.ts` próprios em `./docs/` (o ng-packagr não carrega `.md` como texto), cada um atrás de um `import()`\n * relativo: vira um chunk à parte no FESM e só é baixado quando alguém abre o documento. Sem `title`/`group`: o\n * índice usa o nome da rota e o módulo da árvore do client. O `SpineDocsService` casa estas entradas pelo\n * `source_template_router_id`, como o `ComponentDistributorService` faz com as telas.\n */\nexport const AUTO_SERVICE_DOCUMENTS: Readonly<Record<keyof typeof AUTO_SERVICE_SCREENS, RouteDocument>> = {\n home: {\n load: () => import('./docs/home.usage').then(m => m.default),\n loadTechnical: () => import('./docs/home.technical').then(m => m.default),\n },\n groups: {\n load: () => import('./docs/groups.usage').then(m => m.default),\n loadTechnical: () => import('./docs/groups.technical').then(m => m.default),\n },\n apps: {\n load: () => import('./docs/apps.usage').then(m => m.default),\n loadTechnical: () => import('./docs/apps.technical').then(m => m.default),\n },\n client: {\n load: () => import('./docs/client.usage').then(m => m.default),\n loadTechnical: () => import('./docs/client.technical').then(m => m.default),\n },\n audit: {\n load: () => import('./docs/audit.usage').then(m => m.default),\n loadTechnical: () => import('./docs/audit.technical').then(m => m.default),\n },\n loginAttempts: {\n load: () => import('./docs/login-attempts.usage').then(m => m.default),\n loadTechnical: () => import('./docs/login-attempts.technical').then(m => m.default),\n },\n news: {\n load: () => import('./docs/news.usage').then(m => m.default),\n loadTechnical: () => import('./docs/news.technical').then(m => m.default),\n },\n suggestions: {\n load: () => import('./docs/suggestions.usage').then(m => m.default),\n loadTechnical: () => import('./docs/suggestions.technical').then(m => m.default),\n },\n ratings: {\n load: () => import('./docs/ratings.usage').then(m => m.default),\n loadTechnical: () => import('./docs/ratings.technical').then(m => m.default),\n },\n};\n\n// Cada app consumidora chama isso uma vez no bootstrap (mesmo padrão do\n// provideAuth do @orfeu/angular) informando só a URL do argos-admin-server --\n// o resto vem pronto: rotas/serviço (@trismegisto/spine/auto-service) E a própria\n// ligação com os itens de menu, registrada aqui via source_template_router_id (não\n// route_id -- esse varia por client, ver ComponentDistributorService). O app não\n// precisa (e não deve) declarar nada em features.routes.ts pra isso funcionar; basta\n// o client dele estar vinculado ao template \"auto-service\" (auth.clients.template_id).\n// 9 páginas (Início, Novidades, Sugestões e Avaliações na raiz + Grupos/Aplicações/Cliente em Administração +\n// Ações/Tentativas de login em Auditoria) -- o ComponentDistributorService\n// já suporta N entradas, cada uma casando pelo seu próprio source_template_router_id.\nexport function provideAutoService(config: AutoServiceConfig): EnvironmentProviders {\n const componentRoutes: ComponentRoute[] = [\n { source_template_router_id: AUTO_SERVICE_HOME_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.home, document: AUTO_SERVICE_DOCUMENTS.home },\n { source_template_router_id: AUTO_SERVICE_GROUPS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.groups, document: AUTO_SERVICE_DOCUMENTS.groups },\n { source_template_router_id: AUTO_SERVICE_APPS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.apps, document: AUTO_SERVICE_DOCUMENTS.apps },\n { source_template_router_id: AUTO_SERVICE_CLIENT_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.client, document: AUTO_SERVICE_DOCUMENTS.client },\n { source_template_router_id: AUTO_SERVICE_AUDIT_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.audit, document: AUTO_SERVICE_DOCUMENTS.audit },\n { source_template_router_id: AUTO_SERVICE_LOGIN_ATTEMPTS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.loginAttempts, document: AUTO_SERVICE_DOCUMENTS.loginAttempts },\n { source_template_router_id: AUTO_SERVICE_NEWS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.news, document: AUTO_SERVICE_DOCUMENTS.news },\n { source_template_router_id: AUTO_SERVICE_SUGGESTIONS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.suggestions, document: AUTO_SERVICE_DOCUMENTS.suggestions },\n { source_template_router_id: AUTO_SERVICE_RATINGS_TEMPLATE_ROUTER_ID, load: AUTO_SERVICE_SCREENS.ratings, document: AUTO_SERVICE_DOCUMENTS.ratings },\n ];\n\n return makeEnvironmentProviders([\n { provide: AUTO_SERVICE_CONFIG, useValue: config },\n // Mesma URL, exposta também para o painel de configurações (tokens de aplicação em /me).\n { provide: SPINE_ADMIN_API, useValue: config.adminApi },\n { provide: COMPONENT_ROUTES, useValue: componentRoutes, multi: true },\n ]);\n}\n","import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';\nimport { Inject, Injectable } from '@angular/core';\nimport { Observable, firstValueFrom } from 'rxjs';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { urlPath } from '@trismegisto/primitives/html';\nimport { AUTO_SERVICE_CONFIG, AutoServiceConfig } from './auto-service.tokens';\n\n/** Nível de um nó na árvore do menu (`GET /routers/tree`). */\nexport type RouterOrderType = 'header' | 'navigation' | 'menu' | 'item' | 'submenu' | 'page';\n\n/** Nó da árvore do menu: uma rota num nível, com todos os routers que passam por ela. */\nexport interface RouterOrderNode {\n route_type: RouterOrderType;\n routed_id: string;\n route_name: string;\n route_display_name: string | null;\n route_icon: string | null;\n order: number;\n router_ids: string[];\n children: RouterOrderNode[];\n}\n\n/** Um item da ordem nova de um nível (`PATCH /routers/reorder`). */\nexport interface RouterOrderGroup { type: RouterOrderType; router_ids: string[] }\n\n/**\n * Grupo do projeto do client (`GET /groups`). O grupo de administração do projeto (`is_admin`) é gerido só no painel\n * central e o servidor não o devolve aqui; servidor antigo ainda devolve com `is_admin: true` e as telas descartam.\n */\nexport interface AutoServiceGroup {\n id: string;\n name: string;\n description: string | null;\n enabled: boolean;\n is_admin?: boolean;\n type: { id: string; name: string; level: number } | null;\n}\n\n/** Página e filtros de `GET /groups/:groupId/members`. */\nexport interface AutoServiceMembersQuery {\n page?: number;\n limit?: number;\n search?: string;\n}\n\n/** Uma página de membros: `total` conta quem passa pela busca. */\nexport interface AutoServiceMembersPage {\n members: any[];\n total: number;\n page: number;\n limit: number;\n}\n\n/** Sugestão de membro (`GET /groups/:groupId/member-suggestions`): está em outros grupos do sistema (`groups`). */\nexport interface AutoServiceMemberSuggestion {\n id: string;\n username: string;\n email: string | null;\n name: string | null;\n picture: string | null;\n group_count: number;\n groups: string[];\n}\n\n/** Tipo de grupo (crachá) do realm (`GET /group-types`). */\nexport interface AutoServiceGroupType { id: string; name: string; level: number; assignable: boolean }\n\n/** Corpo de `POST /groups` (o projeto é sempre o do client). */\nexport interface AutoServiceGroupCreate { group_id?: string; name: string; type_id: string; description?: string }\n\n/** Corpo de `PUT /groups/:groupId`; do grupo de administração só `description`. `null` apaga a descrição. */\nexport interface AutoServiceGroupUpdate { name?: string; type_id?: string; description?: string | null; enabled?: boolean }\n\n/** Aplicação (client_credentials) do projeto do client (`GET /apps`). */\nexport interface AutoServiceApp {\n id: string;\n name: string;\n enabled: boolean;\n allowed_grants?: string[] | null;\n [key: string]: unknown;\n}\n\n/**\n * Token de API (`x-api-token`) de uma aplicação (`GET /apps/:appId/tokens`). O valor só vem na criação; aqui fica o\n * começo dele (`token_prefix`) para reconhecer. Cada token é também um consumer (`consumer_id`) com as permissões dele.\n */\nexport interface AutoServiceAppToken {\n id: string;\n consumer_id: string;\n name: string;\n description: string | null;\n token_prefix: string;\n expires_at: string;\n revoked_at: string | null;\n created_at: string;\n last_used_at: string | null;\n}\n\n/** Corpo de `POST /apps/:appId/tokens`: validade ISO (até 365 dias) e as operações protected liberadas ao token. */\nexport interface AutoServiceAppTokenCreate { name: string; description?: string; expires_at: string; operation_ids?: string[] }\n\n/** Resposta de `POST /apps/:appId/tokens`: `token` é o valor cru, devolvido uma única vez. */\nexport interface AutoServiceAppTokenCreated { id: string; consumer_id: string; name: string; token: string }\n\n@Injectable({ providedIn: 'root' })\nexport class AutoServiceService {\n\n private get baseUrl() {\n return `${this.config.adminApi}/auto-service`;\n }\n\n /** `baseUrl` + caminho com cada id interpolado codificado (`urlPath`): um id com `/`, `?`, `#` ou `..` não muda o recurso. */\n private url(strings: TemplateStringsArray, ...ids: readonly string[]): string {\n return this.baseUrl + urlPath(strings, ...ids);\n }\n\n private get headers(): HttpHeaders {\n const token = this.auth.getToken();\n return new HttpHeaders({ 'x-access-token': token ?? '' });\n }\n\n constructor(\n private http: HttpClient,\n private auth: AuthorizationService,\n @Inject(AUTO_SERVICE_CONFIG) private config: AutoServiceConfig,\n ) {}\n\n // Descoberta\n getMyClients() { return firstValueFrom(this.http.get<{ clients: any[] }>(this.baseUrl, { headers: this.headers })); }\n\n // Routes\n getWebRoutes(clientId: string) { return firstValueFrom(this.http.get<{ routes: any[] }>(this.url`/${clientId}/routes`, { headers: this.headers })); }\n createWebRoute(clientId: string, body: any) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/routes`, body, { headers: this.headers })); }\n updateWebRoute(clientId: string, id: string, body: any) { return firstValueFrom(this.http.put<any>(this.url`/${clientId}/routes/${id}`, body, { headers: this.headers })); }\n deleteWebRoute(clientId: string, id: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/routes/${id}`, { headers: this.headers })); }\n\n // Routers\n getRouters(clientId: string) { return firstValueFrom(this.http.get<{ routers: any[] }>(this.url`/${clientId}/routers`, { headers: this.headers })); }\n createRouter(clientId: string, body: any) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/routers`, body, { headers: this.headers })); }\n updateRouter(clientId: string, id: string, body: any) { return firstValueFrom(this.http.put<any>(this.url`/${clientId}/routers/${id}`, body, { headers: this.headers })); }\n deleteRouter(clientId: string, id: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/routers/${id}`, { headers: this.headers })); }\n /** Árvore do menu (header → … → página) com os router_ids de cada nó, já na ordem gravada. */\n getRouterTree(clientId: string) { return firstValueFrom(this.http.get<{ tree: RouterOrderNode[] }>(this.url`/${clientId}/routers/tree`, { headers: this.headers })); }\n /**\n * Grava a ordem de UM nível (irmãos): o índice do grupo é a ordem; cada grupo escreve `${type}_order`\n * em todos os seus routers. Vale também para routers de template (ordem é do client).\n */\n reorderRouters(clientId: string, groups: RouterOrderGroup[]) { return firstValueFrom(this.http.patch<any>(this.url`/${clientId}/routers/reorder`, { groups }, { headers: this.headers })); }\n\n // Groups (do projeto do client, sem o grupo de administração: editar/excluir/membros dele respondem 404)\n getGroups(clientId: string) { return firstValueFrom(this.http.get<{ groups: AutoServiceGroup[] }>(this.url`/${clientId}/groups`, { headers: this.headers })); }\n /** Tipos (crachás) do realm; `assignable: false` no Administrador, que é só do grupo de administração (painel central). */\n getGroupTypes(clientId: string) { return firstValueFrom(this.http.get<{ group_types: AutoServiceGroupType[] }>(this.url`/${clientId}/group-types`, { headers: this.headers })); }\n createGroup(clientId: string, body: AutoServiceGroupCreate) { return firstValueFrom(this.http.post<AutoServiceGroup>(this.url`/${clientId}/groups`, body, { headers: this.headers })); }\n updateGroup(clientId: string, groupId: string, body: AutoServiceGroupUpdate) { return firstValueFrom(this.http.put<AutoServiceGroup>(this.url`/${clientId}/groups/${groupId}`, body, { headers: this.headers })); }\n deleteGroup(clientId: string, groupId: string) { return firstValueFrom(this.http.delete<void>(this.url`/${clientId}/groups/${groupId}`, { headers: this.headers })); }\n /**\n * Uma página dos membros (o servidor pagina: padrão 50, até 200 por página), pela ordem do login, com busca por nome,\n * login ou e-mail. Observable (não Promise): as telas pedem as páginas até o fim e cancelam a pendente ao fechar.\n */\n getGroupMembers(clientId: string, groupId: string, query: AutoServiceMembersQuery = {}): Observable<AutoServiceMembersPage> {\n let params = new HttpParams();\n if (query.page) params = params.set('page', String(query.page));\n if (query.limit) params = params.set('limit', String(query.limit));\n if (query.search?.trim()) params = params.set('search', query.search.trim());\n return this.http.get<AutoServiceMembersPage>(this.url`/${clientId}/groups/${groupId}/members`, { headers: this.headers, params });\n }\n /** Sugestões para adicionar ao grupo: quem já está em outro grupo deste sistema e ainda não neste, com foto e os grupos. */\n getMemberSuggestions(clientId: string, groupId: string, limit = 8) {\n const params = new HttpParams().set('limit', String(limit));\n return firstValueFrom(this.http.get<{ users: AutoServiceMemberSuggestion[] }>(this.url`/${clientId}/groups/${groupId}/member-suggestions`, { headers: this.headers, params }));\n }\n addGroupMember(clientId: string, groupId: string, userId: string, role: string | null) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/groups/${groupId}/members`, { user_id: userId, role }, { headers: this.headers })); }\n updateGroupMemberRole(clientId: string, groupId: string, userId: string, role: string | null) { return firstValueFrom(this.http.put<any>(this.url`/${clientId}/groups/${groupId}/members/${userId}`, { role }, { headers: this.headers })); }\n removeGroupMember(clientId: string, groupId: string, userId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/groups/${groupId}/members/${userId}`, { headers: this.headers })); }\n\n // Users (só leitura -- popular a busca de \"adicionar membro\" na aba Grupos, escopada pelo realm do próprio client)\n searchUsers(clientId: string, opts: { search?: string; limit?: number } = {}) {\n let params = new HttpParams();\n if (opts.search) params = params.set('search', opts.search);\n if (opts.limit) params = params.set('limit', String(opts.limit));\n return firstValueFrom(this.http.get<{ users: any[] }>(this.url`/${clientId}/users`, { headers: this.headers, params }));\n }\n\n // Access\n getAccess(clientId: string) { return firstValueFrom(this.http.get<{ access: any[] }>(this.url`/${clientId}/access`, { headers: this.headers })); }\n createAccess(clientId: string, groupId: string) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/access`, { group_id: groupId }, { headers: this.headers })); }\n deleteAccess(clientId: string, accessId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/access/${accessId}`, { headers: this.headers })); }\n getGuards(clientId: string, accessId: string) { return firstValueFrom(this.http.get<{ guards: any[] }>(this.url`/${clientId}/access/${accessId}/guards`, { headers: this.headers })); }\n addGuard(clientId: string, accessId: string, routerId: string) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/access/${accessId}/guards`, { router_id: routerId }, { headers: this.headers })); }\n removeGuard(clientId: string, accessId: string, guardId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/access/${accessId}/guards/${guardId}`, { headers: this.headers })); }\n\n // Apps (aplicações client_credentials no Project deste client)\n getApps(clientId: string) { return firstValueFrom(this.http.get<{ apps: AutoServiceApp[] }>(this.url`/${clientId}/apps`, { headers: this.headers })); }\n createApp(clientId: string, body: { name: string; allowed_grants?: string[] }) { return firstValueFrom(this.http.post<{ id: string; name: string; secret: string }>(this.url`/${clientId}/apps`, body, { headers: this.headers })); }\n updateApp(clientId: string, appId: string, body: any) { return firstValueFrom(this.http.put<any>(this.url`/${clientId}/apps/${appId}`, body, { headers: this.headers })); }\n /** Gera um segredo novo para a aplicação (o anterior para de valer na hora). A resposta traz o segredo uma única vez. */\n rotateAppSecret(clientId: string, appId: string) { return firstValueFrom(this.http.post<{ id: string; secret: string }>(this.url`/${clientId}/apps/${appId}/secret`, {}, { headers: this.headers })); }\n deleteApp(clientId: string, appId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/apps/${appId}`, { headers: this.headers })); }\n getAppOperations(clientId: string, appId: string) { return firstValueFrom(this.http.get<{ operations: any[] }>(this.url`/${clientId}/apps/${appId}/operations`, { headers: this.headers })); }\n\n // Tokens de API da aplicação (x-api-token)\n getAppTokens(clientId: string, appId: string) { return firstValueFrom(this.http.get<{ tokens: AutoServiceAppToken[] }>(this.url`/${clientId}/apps/${appId}/tokens`, { headers: this.headers })); }\n /** Cria o token (e o consumer dele, com as permissões escolhidas). A resposta traz o valor uma única vez. */\n createAppToken(clientId: string, appId: string, body: AutoServiceAppTokenCreate) { return firstValueFrom(this.http.post<AutoServiceAppTokenCreated>(this.url`/${clientId}/apps/${appId}/tokens`, body, { headers: this.headers })); }\n /** Revoga: o token para de valer na hora e continua na lista como revogado. */\n revokeAppToken(clientId: string, appId: string, tokenId: string) { return firstValueFrom(this.http.delete<void>(this.url`/${clientId}/apps/${appId}/tokens/${tokenId}`, { headers: this.headers })); }\n\n // Consumers (grupo ↔ aplicação), sem o do grupo de administração: o servidor não o lista e o :consumerId dele é 404\n // (servidor antigo ainda devolve com `group_is_admin: true` e a aba Acessos descarta)\n getAppConsumers(clientId: string, appId: string) { return firstValueFrom(this.http.get<{ consumers: any[] }>(this.url`/${clientId}/apps/${appId}/consumers`, { headers: this.headers })); }\n createAppConsumer(clientId: string, appId: string, groupId: string) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/apps/${appId}/consumers`, { group_id: groupId }, { headers: this.headers })); }\n deleteAppConsumer(clientId: string, consumerId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/apps/consumers/${consumerId}`, { headers: this.headers })); }\n\n // Permissions (consumer ↔ operação)\n getAppPermissions(clientId: string, consumerId: string) { return firstValueFrom(this.http.get<{ permissions: any[] }>(this.url`/${clientId}/apps/consumers/${consumerId}/permissions`, { headers: this.headers })); }\n addAppPermission(clientId: string, consumerId: string, operationId: string) { return firstValueFrom(this.http.post<any>(this.url`/${clientId}/apps/consumers/${consumerId}/permissions`, { operation_id: operationId }, { headers: this.headers })); }\n removeAppPermission(clientId: string, consumerId: string, permissionId: string) { return firstValueFrom(this.http.delete<any>(this.url`/${clientId}/apps/consumers/${consumerId}/permissions/${permissionId}`, { headers: this.headers })); }\n // Auditoria: ver `SpineAuditService` (`@trismegisto/spine/audit`), o mesmo nos escopos admin e client.\n}\n","export * from './auto-service.tokens';\nexport * from './provide-auto-service';\nexport * from './auto-service.service';\nexport type { AutoServiceClient } from './client-picker/auto-service-client-picker.component';\n// A auditoria (tipos, serviço e a tela) mora em `@trismegisto/spine/audit` — NÃO reexporte daqui: um\n// `export` estático puxaria a tela para o arquivo deste ponto de entrada (ver abaixo e check-lazy).\n// As telas (Início, Grupos, Aplicações, Cliente) e as peças delas NÃO são exportadas daqui de propósito:\n// ficam só atrás dos `import()` de `AUTO_SERVICE_SCREENS`. Qualquer `export` estático de um componente\n// delas faz o rollup do ng-packagr juntar a tela no FESM do ponto de entrada e trocar o `import()` por\n// `Promise.resolve()` — e a tela (data-grid, combobox, drawer...) vai para o bundle inicial de todo app\n// (bug da 0.9.9). `scripts/check-lazy.mjs` (no `npm run build`) falha se isso voltar.\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,294 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, viewChild, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import * as i1 from '@angular/forms';
4
+ import { FormControl, ReactiveFormsModule } from '@angular/forms';
5
+ import { AuthorizationService } from '@orfeu/angular/core';
6
+ import { BubbleComponent } from '@trismegisto/angular/bubble';
7
+ import { ButtonComponent } from '@trismegisto/angular/button';
8
+ import { IconButtonComponent } from '@trismegisto/angular/icon-button';
9
+ import { MessageComponent } from '@trismegisto/angular/message';
10
+ import { MessageScrollerComponent } from '@trismegisto/angular/message-scroller';
11
+ import { PromptSuggestionsComponent } from '@trismegisto/angular/prompt-suggestions';
12
+ import { TextareaAddonDirective, TextareaComponent } from '@trismegisto/angular/textarea';
13
+ import { HermesToastService } from '@trismegisto/angular/toast';
14
+ import { TraceComponent, TraceItemComponent } from '@trismegisto/angular/trace';
15
+ import { SPINE_MESSAGES } from '@trismegisto/spine';
16
+ import { v as SpineAiAgentService, w as SpineMarkdownComponent } from './trismegisto-spine-layout-trismegisto-spine-layout-D3vetDC_.mjs';
17
+
18
+ /** A conversa com o agente do app, dentro do painel flutuante. O estado fica no `SpineAiAgentService`. */
19
+ class SpineAiAgentChatComponent {
20
+ constructor() {
21
+ this.agent = inject(SpineAiAgentService);
22
+ this.text = inject(SPINE_MESSAGES).aiAgentChat;
23
+ this.draft = new FormControl('', { nonNullable: true });
24
+ this.correction = new FormControl('', { nonNullable: true });
25
+ /** A resposta que a pessoa está corrigindo. */
26
+ this.correcting = signal(null, ...(ngDevMode ? [{ debugName: "correcting" }] : /* istanbul ignore next */ []));
27
+ this.picture = inject(AuthorizationService).profile?.picture ?? null;
28
+ this.scroller = viewChild(MessageScrollerComponent, ...(ngDevMode ? [{ debugName: "scroller" }] : /* istanbul ignore next */ []));
29
+ this.toast = inject(HermesToastService);
30
+ }
31
+ send() {
32
+ const value = this.draft.value;
33
+ if (!value.trim() || this.agent.running())
34
+ return;
35
+ this.draft.setValue('');
36
+ this.ask(value);
37
+ }
38
+ choose(suggestion) {
39
+ this.ask(suggestion);
40
+ }
41
+ async copy(entry) {
42
+ try {
43
+ await navigator.clipboard.writeText(entry.text);
44
+ this.toast.success(this.text.copied);
45
+ }
46
+ catch {
47
+ this.toast.error(this.text.copyError);
48
+ }
49
+ }
50
+ async rateUp(entry) {
51
+ this.correcting.set(null);
52
+ if (!(await this.agent.rate(entry.id, 'up')))
53
+ this.toast.error(this.text.rateError);
54
+ }
55
+ async sendCorrection(entry) {
56
+ const sent = await this.agent.rate(entry.id, 'down', this.correction.value.trim());
57
+ if (!sent) {
58
+ this.toast.error(this.text.rateError);
59
+ return;
60
+ }
61
+ this.correcting.set(null);
62
+ this.correction.setValue('');
63
+ this.toast.success(this.text.rateThanks);
64
+ }
65
+ ask(text) {
66
+ this.agent.send(text);
67
+ queueMicrotask(() => this.scroller()?.scrollToEnd());
68
+ }
69
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: SpineAiAgentChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
70
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.24", type: SpineAiAgentChatComponent, isStandalone: true, selector: "spine-ai-agent-chat", viewQueries: [{ propertyName: "scroller", first: true, predicate: MessageScrollerComponent, descendants: true, isSignal: true }], ngImport: i0, template: `
71
+ <div class="spine-agent">
72
+ @if (agent.entries().length) {
73
+ <hm-message-scroller class="spine-agent__messages" [label]="text.conversation">
74
+ @for (entry of agent.entries(); track entry.id; let last = $last) {
75
+ <hm-message
76
+ [author]="entry.role === 'person' ? text.you : agent.title"
77
+ [align]="entry.role === 'person' ? 'end' : 'start'"
78
+ [avatarUrl]="entry.role === 'person' ? picture : last ? agent.avatarNow() : agent.avatar()"
79
+ >
80
+ @if (entry.role === 'person') {
81
+ <hm-bubble variant="received"><span class="spine-agent__plain">{{ entry.text }}</span></hm-bubble>
82
+ } @else {
83
+ <div class="spine-agent__answer">
84
+ @if (entry.steps.length) {
85
+ <hm-trace class="spine-agent__steps" [label]="text.steps">
86
+ @for (step of entry.steps; track step.id) {
87
+ <hm-trace-item [heading]="step.title" [status]="step.status" [detail]="step.detail ?? ''" />
88
+ }
89
+ </hm-trace>
90
+ }
91
+ @if (entry.error) {
92
+ <p class="spine-agent__error" role="alert">{{ entry.text }}</p>
93
+ @if (last && !agent.running()) {
94
+ <hm-button size="small" emphasis="medium" icon="refresh" (clicked)="agent.retry()">{{ text.retry }}</hm-button>
95
+ }
96
+ } @else if (entry.text) {
97
+ <hm-bubble class="spine-agent__bubble" variant="emphasis"><spine-markdown [content]="entry.text" /></hm-bubble>
98
+ @if (!(last && agent.running())) {
99
+ <div class="spine-agent__actions">
100
+ <hm-icon-button emphasis="subtle" size="small" icon="copy" [label]="text.copy" (clicked)="copy(entry)" />
101
+ <hm-icon-button
102
+ emphasis="subtle"
103
+ size="small"
104
+ icon="thumbs-up"
105
+ [solid]="entry.rating === 'up'"
106
+ [label]="text.rateUp"
107
+ (clicked)="rateUp(entry)"
108
+ />
109
+ <hm-icon-button
110
+ emphasis="subtle"
111
+ size="small"
112
+ icon="thumbs-down"
113
+ [solid]="entry.rating === 'down'"
114
+ [label]="text.rateDown"
115
+ (clicked)="correcting.set(entry.id)"
116
+ />
117
+ </div>
118
+ @if (correcting() === entry.id) {
119
+ <form class="spine-agent__correction" (submit)="$event.preventDefault(); sendCorrection(entry)">
120
+ <hm-textarea
121
+ [label]="text.correctionLabel"
122
+ [placeholder]="text.correctionPlaceholder"
123
+ [rows]="2"
124
+ [formControl]="correction"
125
+ />
126
+ <div class="spine-agent__correction-actions">
127
+ <hm-button size="small" emphasis="minimal" (clicked)="correcting.set(null)">{{ text.correctionCancel }}</hm-button>
128
+ <hm-button size="small" emphasis="medium" (clicked)="sendCorrection(entry)">{{ text.correctionSend }}</hm-button>
129
+ </div>
130
+ </form>
131
+ }
132
+ }
133
+ } @else if (!entry.steps.length) {
134
+ <hm-bubble [typing]="true" />
135
+ }
136
+ </div>
137
+ }
138
+ </hm-message>
139
+ }
140
+ </hm-message-scroller>
141
+ } @else {
142
+ <div class="spine-agent__empty">
143
+ @if (agent.image() ?? agent.avatar(); as image) {
144
+ <img class="spine-agent__portrait" [src]="image" alt="" (error)="agent.imageFailed(image)" />
145
+ }
146
+ <p class="spine-agent__intro">{{ text.empty }}</p>
147
+ <hm-prompt-suggestions [suggestions]="agent.suggestions()" (chosen)="choose($event)" />
148
+ </div>
149
+ }
150
+
151
+ <hm-textarea
152
+ class="spine-agent__input"
153
+ [label]="text.placeholder"
154
+ [labelHidden]="true"
155
+ [placeholder]="text.placeholder"
156
+ [rows]="2"
157
+ [maxRows]="6"
158
+ [autoGrow]="true"
159
+ submitKey="enter"
160
+ [formControl]="draft"
161
+ (submitted)="send()"
162
+ >
163
+ <hm-icon-button
164
+ hmTextareaActionsEnd
165
+ class="spine-agent__send"
166
+ emphasis="filled"
167
+ size="medium"
168
+ icon="send-arrow"
169
+ [label]="text.send"
170
+ [disabled]="agent.running()"
171
+ (clicked)="send()"
172
+ />
173
+ </hm-textarea>
174
+ <p class="spine-agent__note">{{ text.note }}</p>
175
+ </div>
176
+ `, isInline: true, styles: [":host{display:block;height:100%}.spine-agent{display:flex;flex-direction:column;gap:var(--hm-space-sm);height:100%;min-height:0}.spine-agent__messages{flex:1;min-height:0}.spine-agent__empty{flex:1;display:flex;flex-direction:column;justify-content:flex-end;gap:var(--hm-space-sm);min-height:0;overflow-y:auto}.spine-agent__intro{margin:0;color:var(--hm-muted)}.spine-agent__portrait{align-self:center;flex:0 1 auto;min-block-size:0;max-inline-size:60%;max-block-size:calc(var(--hm-space-3xl) * 5);object-fit:contain}.spine-agent__plain{white-space:pre-wrap;overflow-wrap:anywhere}.spine-agent__answer{display:flex;flex-direction:column;align-items:flex-start;gap:var(--hm-space-xs);min-width:0;width:100%}.spine-agent__steps{width:100%}.spine-agent__bubble{inline-size:100%;max-inline-size:100%}.spine-agent__answer spine-markdown{display:block;max-inline-size:100%;overflow-x:auto}:host ::ng-deep .spine-agent__messages .hm-message__header{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}:host ::ng-deep .spine-agent__bubble .spine-md th{background:color-mix(in srgb,var(--hm-text) 8%,transparent)}:host ::ng-deep .spine-agent__bubble .spine-md :is(th,td){border-color:color-mix(in srgb,var(--hm-text) 18%,transparent)}.spine-agent__input{--hm-radius-control: calc(var(--hm-radius) * 3)}.spine-agent__send{--hm-radius-control: var(--hm-radius-pill)}.spine-agent__error{margin:0;color:var(--hm-danger)}.spine-agent__actions{display:flex;gap:var(--hm-space-micro)}.spine-agent__correction{display:flex;flex-direction:column;gap:var(--hm-space-xs);inline-size:100%}.spine-agent__correction-actions{display:flex;justify-content:flex-end;gap:var(--hm-space-xs)}.spine-agent__note{margin:0;color:var(--hm-muted);font-size:var(--hm-font-size-xs)}\n"], dependencies: [{ kind: "component", type: BubbleComponent, selector: "hm-bubble", inputs: ["variant", "reactions", "typing"], outputs: ["reactionToggle"] }, { 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: IconButtonComponent, selector: "hm-icon-button", inputs: ["label", "icon", "solid", "iconDirection", "emphasis", "intent", "size", "disabled", "toggle", "pressed", "keyShortcuts"], outputs: ["pressedChange", "clicked"] }, { kind: "component", type: MessageComponent, selector: "hm-message", inputs: ["author", "avatarUrl", "time", "timeFormat", "align", "grouped", "showAvatar", "status", "announce", "reactions", "reactionChoices", "texts"], outputs: ["retry", "reactionToggle"] }, { kind: "component", type: MessageScrollerComponent, selector: "hm-message-scroller", inputs: ["label", "hasMoreHistory", "loadingHistory", "autoLoadHistory", "live", "itemSelector", "threshold"], outputs: ["loadHistory", "atEndChange"] }, { kind: "component", type: PromptSuggestionsComponent, selector: "hm-prompt-suggestions", inputs: ["suggestions", "label", "disabled"], outputs: ["chosen"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: SpineMarkdownComponent, selector: "spine-markdown", inputs: ["content"] }, { kind: "directive", type: TextareaAddonDirective, selector: "[hmTextareaPrefix], [hmTextareaSuffix], [hmTextareaActions], [hmTextareaActionsEnd]" }, { kind: "component", type: TextareaComponent, selector: "hm-textarea", inputs: ["value", "label", "hint", "placeholder", "maxLength", "rows", "autoGrow", "labelHidden", "loading", "maxRows", "submitKey", "mentionCandidates", "mentionTrigger", "texts"], outputs: ["valueChange", "submitted", "mentioned"] }, { kind: "component", type: TraceComponent, selector: "hm-trace", inputs: ["label"] }, { kind: "component", type: TraceItemComponent, selector: "hm-trace-item", inputs: ["heading", "detail", "status", "expandable", "texts"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
177
+ }
178
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: SpineAiAgentChatComponent, decorators: [{
179
+ type: Component,
180
+ args: [{ selector: 'spine-ai-agent-chat', imports: [
181
+ BubbleComponent, ButtonComponent, IconButtonComponent, MessageComponent, MessageScrollerComponent,
182
+ PromptSuggestionsComponent, ReactiveFormsModule, SpineMarkdownComponent, TextareaAddonDirective, TextareaComponent,
183
+ TraceComponent, TraceItemComponent,
184
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: `
185
+ <div class="spine-agent">
186
+ @if (agent.entries().length) {
187
+ <hm-message-scroller class="spine-agent__messages" [label]="text.conversation">
188
+ @for (entry of agent.entries(); track entry.id; let last = $last) {
189
+ <hm-message
190
+ [author]="entry.role === 'person' ? text.you : agent.title"
191
+ [align]="entry.role === 'person' ? 'end' : 'start'"
192
+ [avatarUrl]="entry.role === 'person' ? picture : last ? agent.avatarNow() : agent.avatar()"
193
+ >
194
+ @if (entry.role === 'person') {
195
+ <hm-bubble variant="received"><span class="spine-agent__plain">{{ entry.text }}</span></hm-bubble>
196
+ } @else {
197
+ <div class="spine-agent__answer">
198
+ @if (entry.steps.length) {
199
+ <hm-trace class="spine-agent__steps" [label]="text.steps">
200
+ @for (step of entry.steps; track step.id) {
201
+ <hm-trace-item [heading]="step.title" [status]="step.status" [detail]="step.detail ?? ''" />
202
+ }
203
+ </hm-trace>
204
+ }
205
+ @if (entry.error) {
206
+ <p class="spine-agent__error" role="alert">{{ entry.text }}</p>
207
+ @if (last && !agent.running()) {
208
+ <hm-button size="small" emphasis="medium" icon="refresh" (clicked)="agent.retry()">{{ text.retry }}</hm-button>
209
+ }
210
+ } @else if (entry.text) {
211
+ <hm-bubble class="spine-agent__bubble" variant="emphasis"><spine-markdown [content]="entry.text" /></hm-bubble>
212
+ @if (!(last && agent.running())) {
213
+ <div class="spine-agent__actions">
214
+ <hm-icon-button emphasis="subtle" size="small" icon="copy" [label]="text.copy" (clicked)="copy(entry)" />
215
+ <hm-icon-button
216
+ emphasis="subtle"
217
+ size="small"
218
+ icon="thumbs-up"
219
+ [solid]="entry.rating === 'up'"
220
+ [label]="text.rateUp"
221
+ (clicked)="rateUp(entry)"
222
+ />
223
+ <hm-icon-button
224
+ emphasis="subtle"
225
+ size="small"
226
+ icon="thumbs-down"
227
+ [solid]="entry.rating === 'down'"
228
+ [label]="text.rateDown"
229
+ (clicked)="correcting.set(entry.id)"
230
+ />
231
+ </div>
232
+ @if (correcting() === entry.id) {
233
+ <form class="spine-agent__correction" (submit)="$event.preventDefault(); sendCorrection(entry)">
234
+ <hm-textarea
235
+ [label]="text.correctionLabel"
236
+ [placeholder]="text.correctionPlaceholder"
237
+ [rows]="2"
238
+ [formControl]="correction"
239
+ />
240
+ <div class="spine-agent__correction-actions">
241
+ <hm-button size="small" emphasis="minimal" (clicked)="correcting.set(null)">{{ text.correctionCancel }}</hm-button>
242
+ <hm-button size="small" emphasis="medium" (clicked)="sendCorrection(entry)">{{ text.correctionSend }}</hm-button>
243
+ </div>
244
+ </form>
245
+ }
246
+ }
247
+ } @else if (!entry.steps.length) {
248
+ <hm-bubble [typing]="true" />
249
+ }
250
+ </div>
251
+ }
252
+ </hm-message>
253
+ }
254
+ </hm-message-scroller>
255
+ } @else {
256
+ <div class="spine-agent__empty">
257
+ @if (agent.image() ?? agent.avatar(); as image) {
258
+ <img class="spine-agent__portrait" [src]="image" alt="" (error)="agent.imageFailed(image)" />
259
+ }
260
+ <p class="spine-agent__intro">{{ text.empty }}</p>
261
+ <hm-prompt-suggestions [suggestions]="agent.suggestions()" (chosen)="choose($event)" />
262
+ </div>
263
+ }
264
+
265
+ <hm-textarea
266
+ class="spine-agent__input"
267
+ [label]="text.placeholder"
268
+ [labelHidden]="true"
269
+ [placeholder]="text.placeholder"
270
+ [rows]="2"
271
+ [maxRows]="6"
272
+ [autoGrow]="true"
273
+ submitKey="enter"
274
+ [formControl]="draft"
275
+ (submitted)="send()"
276
+ >
277
+ <hm-icon-button
278
+ hmTextareaActionsEnd
279
+ class="spine-agent__send"
280
+ emphasis="filled"
281
+ size="medium"
282
+ icon="send-arrow"
283
+ [label]="text.send"
284
+ [disabled]="agent.running()"
285
+ (clicked)="send()"
286
+ />
287
+ </hm-textarea>
288
+ <p class="spine-agent__note">{{ text.note }}</p>
289
+ </div>
290
+ `, styles: [":host{display:block;height:100%}.spine-agent{display:flex;flex-direction:column;gap:var(--hm-space-sm);height:100%;min-height:0}.spine-agent__messages{flex:1;min-height:0}.spine-agent__empty{flex:1;display:flex;flex-direction:column;justify-content:flex-end;gap:var(--hm-space-sm);min-height:0;overflow-y:auto}.spine-agent__intro{margin:0;color:var(--hm-muted)}.spine-agent__portrait{align-self:center;flex:0 1 auto;min-block-size:0;max-inline-size:60%;max-block-size:calc(var(--hm-space-3xl) * 5);object-fit:contain}.spine-agent__plain{white-space:pre-wrap;overflow-wrap:anywhere}.spine-agent__answer{display:flex;flex-direction:column;align-items:flex-start;gap:var(--hm-space-xs);min-width:0;width:100%}.spine-agent__steps{width:100%}.spine-agent__bubble{inline-size:100%;max-inline-size:100%}.spine-agent__answer spine-markdown{display:block;max-inline-size:100%;overflow-x:auto}:host ::ng-deep .spine-agent__messages .hm-message__header{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}:host ::ng-deep .spine-agent__bubble .spine-md th{background:color-mix(in srgb,var(--hm-text) 8%,transparent)}:host ::ng-deep .spine-agent__bubble .spine-md :is(th,td){border-color:color-mix(in srgb,var(--hm-text) 18%,transparent)}.spine-agent__input{--hm-radius-control: calc(var(--hm-radius) * 3)}.spine-agent__send{--hm-radius-control: var(--hm-radius-pill)}.spine-agent__error{margin:0;color:var(--hm-danger)}.spine-agent__actions{display:flex;gap:var(--hm-space-micro)}.spine-agent__correction{display:flex;flex-direction:column;gap:var(--hm-space-xs);inline-size:100%}.spine-agent__correction-actions{display:flex;justify-content:flex-end;gap:var(--hm-space-xs)}.spine-agent__note{margin:0;color:var(--hm-muted);font-size:var(--hm-font-size-xs)}\n"] }]
291
+ }], propDecorators: { scroller: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MessageScrollerComponent), { isSignal: true }] }] } });
292
+
293
+ export { SpineAiAgentChatComponent };
294
+ //# sourceMappingURL=trismegisto-spine-layout-ai-agent-chat.component-LlxtxNA5.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trismegisto-spine-layout-ai-agent-chat.component-LlxtxNA5.mjs","sources":["../../../projects/ui/layout/src/ai-agent/ai-agent-chat.component.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, inject, signal, viewChild } from '@angular/core';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { BubbleComponent } from '@trismegisto/angular/bubble';\nimport { ButtonComponent } from '@trismegisto/angular/button';\nimport { IconButtonComponent } from '@trismegisto/angular/icon-button';\nimport { MessageComponent } from '@trismegisto/angular/message';\nimport { MessageScrollerComponent } from '@trismegisto/angular/message-scroller';\nimport { PromptSuggestionsComponent } from '@trismegisto/angular/prompt-suggestions';\nimport { TextareaAddonDirective, TextareaComponent } from '@trismegisto/angular/textarea';\nimport { HermesToastService } from '@trismegisto/angular/toast';\nimport { TraceComponent, TraceItemComponent } from '@trismegisto/angular/trace';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineMarkdownComponent } from '../docs/markdown.component';\nimport { SpineAgentEntry, SpineAiAgentService } from './ai-agent.service';\n\n/** A conversa com o agente do app, dentro do painel flutuante. O estado fica no `SpineAiAgentService`. */\n@Component({\n selector: 'spine-ai-agent-chat',\n imports: [\n BubbleComponent, ButtonComponent, IconButtonComponent, MessageComponent, MessageScrollerComponent,\n PromptSuggestionsComponent, ReactiveFormsModule, SpineMarkdownComponent, TextareaAddonDirective, TextareaComponent,\n TraceComponent, TraceItemComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"spine-agent\">\n @if (agent.entries().length) {\n <hm-message-scroller class=\"spine-agent__messages\" [label]=\"text.conversation\">\n @for (entry of agent.entries(); track entry.id; let last = $last) {\n <hm-message\n [author]=\"entry.role === 'person' ? text.you : agent.title\"\n [align]=\"entry.role === 'person' ? 'end' : 'start'\"\n [avatarUrl]=\"entry.role === 'person' ? picture : last ? agent.avatarNow() : agent.avatar()\"\n >\n @if (entry.role === 'person') {\n <hm-bubble variant=\"received\"><span class=\"spine-agent__plain\">{{ entry.text }}</span></hm-bubble>\n } @else {\n <div class=\"spine-agent__answer\">\n @if (entry.steps.length) {\n <hm-trace class=\"spine-agent__steps\" [label]=\"text.steps\">\n @for (step of entry.steps; track step.id) {\n <hm-trace-item [heading]=\"step.title\" [status]=\"step.status\" [detail]=\"step.detail ?? ''\" />\n }\n </hm-trace>\n }\n @if (entry.error) {\n <p class=\"spine-agent__error\" role=\"alert\">{{ entry.text }}</p>\n @if (last && !agent.running()) {\n <hm-button size=\"small\" emphasis=\"medium\" icon=\"refresh\" (clicked)=\"agent.retry()\">{{ text.retry }}</hm-button>\n }\n } @else if (entry.text) {\n <hm-bubble class=\"spine-agent__bubble\" variant=\"emphasis\"><spine-markdown [content]=\"entry.text\" /></hm-bubble>\n @if (!(last && agent.running())) {\n <div class=\"spine-agent__actions\">\n <hm-icon-button emphasis=\"subtle\" size=\"small\" icon=\"copy\" [label]=\"text.copy\" (clicked)=\"copy(entry)\" />\n <hm-icon-button\n emphasis=\"subtle\"\n size=\"small\"\n icon=\"thumbs-up\"\n [solid]=\"entry.rating === 'up'\"\n [label]=\"text.rateUp\"\n (clicked)=\"rateUp(entry)\"\n />\n <hm-icon-button\n emphasis=\"subtle\"\n size=\"small\"\n icon=\"thumbs-down\"\n [solid]=\"entry.rating === 'down'\"\n [label]=\"text.rateDown\"\n (clicked)=\"correcting.set(entry.id)\"\n />\n </div>\n @if (correcting() === entry.id) {\n <form class=\"spine-agent__correction\" (submit)=\"$event.preventDefault(); sendCorrection(entry)\">\n <hm-textarea\n [label]=\"text.correctionLabel\"\n [placeholder]=\"text.correctionPlaceholder\"\n [rows]=\"2\"\n [formControl]=\"correction\"\n />\n <div class=\"spine-agent__correction-actions\">\n <hm-button size=\"small\" emphasis=\"minimal\" (clicked)=\"correcting.set(null)\">{{ text.correctionCancel }}</hm-button>\n <hm-button size=\"small\" emphasis=\"medium\" (clicked)=\"sendCorrection(entry)\">{{ text.correctionSend }}</hm-button>\n </div>\n </form>\n }\n }\n } @else if (!entry.steps.length) {\n <hm-bubble [typing]=\"true\" />\n }\n </div>\n }\n </hm-message>\n }\n </hm-message-scroller>\n } @else {\n <div class=\"spine-agent__empty\">\n @if (agent.image() ?? agent.avatar(); as image) {\n <img class=\"spine-agent__portrait\" [src]=\"image\" alt=\"\" (error)=\"agent.imageFailed(image)\" />\n }\n <p class=\"spine-agent__intro\">{{ text.empty }}</p>\n <hm-prompt-suggestions [suggestions]=\"agent.suggestions()\" (chosen)=\"choose($event)\" />\n </div>\n }\n\n <hm-textarea\n class=\"spine-agent__input\"\n [label]=\"text.placeholder\"\n [labelHidden]=\"true\"\n [placeholder]=\"text.placeholder\"\n [rows]=\"2\"\n [maxRows]=\"6\"\n [autoGrow]=\"true\"\n submitKey=\"enter\"\n [formControl]=\"draft\"\n (submitted)=\"send()\"\n >\n <hm-icon-button\n hmTextareaActionsEnd\n class=\"spine-agent__send\"\n emphasis=\"filled\"\n size=\"medium\"\n icon=\"send-arrow\"\n [label]=\"text.send\"\n [disabled]=\"agent.running()\"\n (clicked)=\"send()\"\n />\n </hm-textarea>\n <p class=\"spine-agent__note\">{{ text.note }}</p>\n </div>\n `,\n styles: [`\n :host { display: block; height: 100%; }\n .spine-agent { display: flex; flex-direction: column; gap: var(--hm-space-sm); height: 100%; min-height: 0; }\n .spine-agent__messages { flex: 1; min-height: 0; }\n .spine-agent__empty {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n gap: var(--hm-space-sm);\n min-height: 0;\n overflow-y: auto;\n }\n .spine-agent__intro { margin: 0; color: var(--hm-muted); }\n .spine-agent__portrait {\n align-self: center;\n /* Em painel baixo, é a imagem que cede: o texto e as sugestões continuam à vista. */\n flex: 0 1 auto;\n min-block-size: 0;\n max-inline-size: 60%;\n max-block-size: calc(var(--hm-space-3xl) * 5);\n object-fit: contain;\n }\n .spine-agent__plain { white-space: pre-wrap; overflow-wrap: anywhere; }\n .spine-agent__answer { display: flex; flex-direction: column; align-items: flex-start; gap: var(--hm-space-xs); min-width: 0; width: 100%; }\n .spine-agent__steps { width: 100%; }\n /* O balão acompanha o texto até a largura toda; a tabela maior que isso rola dentro dele. */\n .spine-agent__bubble { inline-size: 100%; max-inline-size: 100%; }\n .spine-agent__answer spine-markdown { display: block; max-inline-size: 100%; overflow-x: auto; }\n /* O avatar já diz de quem é a mensagem. O nome sai só da tela: leitor de tela continua lendo. */\n :host ::ng-deep .spine-agent__messages .hm-message__header {\n position: absolute;\n inline-size: 1px;\n block-size: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n }\n /* A tabela herda o tom do balão: só o título ganha um véu do texto, que funciona nos dois temas. */\n :host ::ng-deep .spine-agent__bubble .spine-md th { background: color-mix(in srgb, var(--hm-text) 8%, transparent); }\n :host ::ng-deep .spine-agent__bubble .spine-md :is(th, td) { border-color: color-mix(in srgb, var(--hm-text) 18%, transparent); }\n .spine-agent__input { --hm-radius-control: calc(var(--hm-radius) * 3); }\n .spine-agent__send { --hm-radius-control: var(--hm-radius-pill); }\n .spine-agent__error { margin: 0; color: var(--hm-danger); }\n .spine-agent__actions { display: flex; gap: var(--hm-space-micro); }\n .spine-agent__correction { display: flex; flex-direction: column; gap: var(--hm-space-xs); inline-size: 100%; }\n .spine-agent__correction-actions { display: flex; justify-content: flex-end; gap: var(--hm-space-xs); }\n .spine-agent__note { margin: 0; color: var(--hm-muted); font-size: var(--hm-font-size-xs); }\n `],\n})\nexport class SpineAiAgentChatComponent {\n protected readonly agent = inject(SpineAiAgentService);\n protected readonly text = inject(SPINE_MESSAGES).aiAgentChat;\n protected readonly draft = new FormControl('', { nonNullable: true });\n protected readonly correction = new FormControl('', { nonNullable: true });\n /** A resposta que a pessoa está corrigindo. */\n protected readonly correcting = signal<number | null>(null);\n protected readonly picture = inject(AuthorizationService).profile?.picture ?? null;\n private readonly scroller = viewChild(MessageScrollerComponent);\n private readonly toast = inject(HermesToastService);\n\n protected send(): void {\n const value = this.draft.value;\n if (!value.trim() || this.agent.running()) return;\n this.draft.setValue('');\n this.ask(value);\n }\n\n protected choose(suggestion: string): void {\n this.ask(suggestion);\n }\n\n protected async copy(entry: SpineAgentEntry): Promise<void> {\n try {\n await navigator.clipboard.writeText(entry.text);\n this.toast.success(this.text.copied);\n } catch {\n this.toast.error(this.text.copyError);\n }\n }\n\n protected async rateUp(entry: SpineAgentEntry): Promise<void> {\n this.correcting.set(null);\n if (!(await this.agent.rate(entry.id, 'up'))) this.toast.error(this.text.rateError);\n }\n\n protected async sendCorrection(entry: SpineAgentEntry): Promise<void> {\n const sent = await this.agent.rate(entry.id, 'down', this.correction.value.trim());\n if (!sent) {\n this.toast.error(this.text.rateError);\n return;\n }\n this.correcting.set(null);\n this.correction.setValue('');\n this.toast.success(this.text.rateThanks);\n }\n\n private ask(text: string): void {\n this.agent.send(text);\n queueMicrotask(() => this.scroller()?.scrollToEnd());\n }\n}\n"],"names":[],"mappings":"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"}