@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.
- package/README.md +15 -2
- package/fesm2022/trismegisto-spine-audit.mjs +6 -6
- package/fesm2022/trismegisto-spine-audit.mjs.map +1 -1
- package/fesm2022/{trismegisto-spine-auto-service-auto-service-client.component-BAfeLyTB.mjs → trismegisto-spine-auto-service-auto-service-client.component-kAXaCM5W.mjs} +8 -8
- 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
- package/fesm2022/{trismegisto-spine-auto-service-auto-service-groups.component-BYjIQ9ID.mjs → trismegisto-spine-auto-service-auto-service-groups.component-DE2QIGRH.mjs} +251 -85
- package/fesm2022/trismegisto-spine-auto-service-auto-service-groups.component-DE2QIGRH.mjs.map +1 -0
- 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
- 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
- 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
- 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
- package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-CkiCTmXD.mjs +3733 -0
- package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-CkiCTmXD.mjs.map +1 -0
- package/fesm2022/{trismegisto-spine-auto-service-auto-service.component-QsIQ61w2.mjs → trismegisto-spine-auto-service-auto-service.component-D58Ht9PH.mjs} +7 -7
- package/fesm2022/{trismegisto-spine-auto-service-auto-service.component-QsIQ61w2.mjs.map → trismegisto-spine-auto-service-auto-service.component-D58Ht9PH.mjs.map} +1 -1
- package/fesm2022/{trismegisto-spine-auto-service-groups.technical-_jQrg1Qh.mjs → trismegisto-spine-auto-service-groups.technical-CB1D3ANC.mjs} +12 -3
- package/fesm2022/trismegisto-spine-auto-service-groups.technical-CB1D3ANC.mjs.map +1 -0
- package/fesm2022/{trismegisto-spine-auto-service-groups.usage-OvWjNeeT.mjs → trismegisto-spine-auto-service-groups.usage-De2MhlE7.mjs} +7 -2
- package/fesm2022/{trismegisto-spine-auto-service-groups.usage-OvWjNeeT.mjs.map → trismegisto-spine-auto-service-groups.usage-De2MhlE7.mjs.map} +1 -1
- package/fesm2022/{trismegisto-spine-auto-service-home.component-rQ3dIGIE.mjs → trismegisto-spine-auto-service-home.component-9WvXOH3l.mjs} +7 -4
- package/fesm2022/trismegisto-spine-auto-service-home.component-9WvXOH3l.mjs.map +1 -0
- package/fesm2022/{trismegisto-spine-auto-service-suggestions.technical-BtUK6sKD.mjs → trismegisto-spine-auto-service-suggestions.technical-CGBBzAR8.mjs} +14 -1
- package/fesm2022/{trismegisto-spine-auto-service-suggestions.technical-BtUK6sKD.mjs.map → trismegisto-spine-auto-service-suggestions.technical-CGBBzAR8.mjs.map} +1 -1
- package/fesm2022/{trismegisto-spine-auto-service-suggestions.usage-BwO9Hjsx.mjs → trismegisto-spine-auto-service-suggestions.usage-DnAJS-Z0.mjs} +26 -3
- package/fesm2022/trismegisto-spine-auto-service-suggestions.usage-DnAJS-Z0.mjs.map +1 -0
- package/fesm2022/trismegisto-spine-auto-service.mjs +25 -12
- package/fesm2022/trismegisto-spine-auto-service.mjs.map +1 -1
- package/fesm2022/trismegisto-spine-graphql.mjs +3 -1
- package/fesm2022/trismegisto-spine-graphql.mjs.map +1 -1
- package/fesm2022/trismegisto-spine-layout-suggestions-page.component-CEKMqera.mjs +532 -0
- package/fesm2022/trismegisto-spine-layout-suggestions-page.component-CEKMqera.mjs.map +1 -0
- package/fesm2022/trismegisto-spine-layout-trismegisto-spine-layout-DiAfxIGP.mjs +8764 -0
- package/fesm2022/trismegisto-spine-layout-trismegisto-spine-layout-DiAfxIGP.mjs.map +1 -0
- package/fesm2022/trismegisto-spine-layout.mjs +1 -7662
- package/fesm2022/trismegisto-spine-layout.mjs.map +1 -1
- package/fesm2022/trismegisto-spine-notification.mjs +1 -1
- package/fesm2022/trismegisto-spine-notification.mjs.map +1 -1
- package/fesm2022/trismegisto-spine-routing.mjs +16 -3
- package/fesm2022/trismegisto-spine-routing.mjs.map +1 -1
- package/fesm2022/trismegisto-spine-shell.mjs +4 -2
- package/fesm2022/trismegisto-spine-shell.mjs.map +1 -1
- package/fesm2022/trismegisto-spine-side-panel.mjs +1 -1
- package/fesm2022/trismegisto-spine-side-panel.mjs.map +1 -1
- package/fesm2022/trismegisto-spine.mjs +813 -38
- package/fesm2022/trismegisto-spine.mjs.map +1 -1
- package/package.json +6 -6
- package/types/trismegisto-spine-auto-service.d.ts +20 -4
- package/types/trismegisto-spine-auto-service.d.ts.map +1 -1
- package/types/trismegisto-spine-layout.d.ts +1200 -74
- package/types/trismegisto-spine-layout.d.ts.map +1 -1
- package/types/trismegisto-spine-routing.d.ts.map +1 -1
- package/types/trismegisto-spine-shell.d.ts.map +1 -1
- package/types/trismegisto-spine.d.ts +350 -14
- package/types/trismegisto-spine.d.ts.map +1 -1
- package/fesm2022/trismegisto-spine-auto-service-auto-service-groups.component-BYjIQ9ID.mjs.map +0 -1
- package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-DIeunpQ9.mjs +0 -2123
- package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-DIeunpQ9.mjs.map +0 -1
- package/fesm2022/trismegisto-spine-auto-service-groups.technical-_jQrg1Qh.mjs.map +0 -1
- package/fesm2022/trismegisto-spine-auto-service-home.component-rQ3dIGIE.mjs.map +0 -1
- package/fesm2022/trismegisto-spine-auto-service-suggestions.usage-BwO9Hjsx.mjs.map +0 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { OnDestroy,
|
|
2
|
+
import { OnDestroy, InjectionToken, Signal, OnInit, Type, Provider, TemplateRef, DestroyRef, EnvironmentProviders } from '@angular/core';
|
|
3
3
|
import { Router } from '@angular/router';
|
|
4
4
|
import * as _trismegisto_spine from '@trismegisto/spine';
|
|
5
5
|
import { Route, ThemeService, ThemePresetService, DensityService, SpineConfig, SpinePreferencesService, SpineHourCyclePreference, SpineStartPagePreference, SpineNoticeType, SpineMcpServer, SpineFeatures } from '@trismegisto/spine';
|
|
6
|
-
import { Subject } from 'rxjs';
|
|
6
|
+
import { Subject, Observable } from 'rxjs';
|
|
7
7
|
import * as _trismegisto_angular from '@trismegisto/angular';
|
|
8
|
-
import { HermesShortcutItem, WorkspaceStore, TabItem, MenuItem, HermesCommand, SidebarNode, HermesThemeMode, HermesDensity, SegmentedOption, HermesSidebarService, ComboboxOption, BreadcrumbItem, TagColor } from '@trismegisto/angular';
|
|
8
|
+
import { HermesShortcutItem, WorkspaceGridLimits, WorkspaceStore, TabItem, MenuItem, HermesCommand, SidebarNode, ContextMenuDirective, HermesThemeMode, HermesDensity, SegmentedOption, HermesSidebarService, ComboboxOption, BreadcrumbItem, TagColor } from '@trismegisto/angular';
|
|
9
9
|
import * as _trismegisto_primitives from '@trismegisto/primitives';
|
|
10
|
-
import { formatMessage, ShortcutDisplay, HermesMotionPreference, Weekday, AlertVariant, PaginationState } from '@trismegisto/primitives';
|
|
10
|
+
import { WorkspaceStore as WorkspaceStore$1, formatMessage, MenuItem as MenuItem$1, ShortcutDisplay, HermesMotionPreference, Weekday, AlertVariant, PaginationState } from '@trismegisto/primitives';
|
|
11
11
|
import * as _orfeu_angular_core from '@orfeu/angular/core';
|
|
12
12
|
import { AuthorizationService, ViewService, UserProfile, AppDef, RealmAppsService } from '@orfeu/angular/core';
|
|
13
13
|
import * as _trismegisto_tokens from '@trismegisto/tokens';
|
|
@@ -190,22 +190,24 @@ declare class SpineNewsService {
|
|
|
190
190
|
interface ShortcutActions {
|
|
191
191
|
navigate?: (url: string) => void;
|
|
192
192
|
toggleTheme?: () => void;
|
|
193
|
-
toggleFullscreen?: () => void;
|
|
194
|
-
logout?: () => void;
|
|
195
193
|
openSettings?: () => void;
|
|
194
|
+
toggleSidebar?: () => void;
|
|
196
195
|
}
|
|
197
196
|
/**
|
|
198
197
|
* Atalhos de teclado globais do sistema, sobre o `HermesShortcutService` da lib (um listener só,
|
|
199
198
|
* sequência `G H`, conflito, campo editável, interruptor de tecla única da WCAG 2.1.4).
|
|
200
199
|
*
|
|
201
|
-
* `setActions` registra os atalhos do shell: `G H` (Home), `G 1`…`G 9` (favoritos), `Mod
|
|
202
|
-
*
|
|
203
|
-
*
|
|
200
|
+
* `setActions` registra os atalhos do shell: `G H` (Home), `G 1`…`G 9` (favoritos), `G T` (tema), `Mod+B` (menu
|
|
201
|
+
* lateral), `Mod+,` (configurações) e `?` (painel de atalhos, via `help$`). `Mod+,` vale também com o foco num campo;
|
|
202
|
+
* os demais, não (`Mod+B` num editor continua sendo negrito).
|
|
203
|
+
*
|
|
204
|
+
* Sem atalho de propósito: sair (um deslize perderia o que estava sendo digitado; fica no menu do perfil) e tela cheia
|
|
205
|
+
* (o navegador já tem `F11`, e o botão fica no cabeçalho).
|
|
204
206
|
*
|
|
205
207
|
* O painel (`spine-shortcuts-cheatsheet` e a seção Atalhos das configurações) usa o
|
|
206
208
|
* `hm-shortcut-list` com `panelItems()`: tudo o que está registrado no `HermesShortcutService`
|
|
207
209
|
* (inclusive o que o app liga com `[hmShortcut]`) mais o que o spine só exibe e outra peça dispara
|
|
208
|
-
* (`Mod+K` do `hm-header`,
|
|
210
|
+
* (`Mod+K` e `/` do `hm-header`, voltar/avançar do navegador, `Esc` dos diálogos).
|
|
209
211
|
*/
|
|
210
212
|
declare class ShortcutService implements OnDestroy {
|
|
211
213
|
private actions;
|
|
@@ -239,16 +241,105 @@ declare class ShortcutService implements OnDestroy {
|
|
|
239
241
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<ShortcutService>;
|
|
240
242
|
}
|
|
241
243
|
|
|
244
|
+
/** Query de uma aba, como objeto (o último valor de cada nome). */
|
|
245
|
+
type SpineTabParams = Readonly<Record<string, string>>;
|
|
246
|
+
/**
|
|
247
|
+
* A aba do workspace em que a tela está montada (`inject(SPINE_TAB)` na tela). Com o keepAlive, várias abas da MESMA
|
|
248
|
+
* tela ficam vivas ao mesmo tempo (um registro por aba); `window.location`/`ActivatedRoute` só refletem a aba do
|
|
249
|
+
* painel focado. Aqui cada tela lê e escreve a SUA.
|
|
250
|
+
*
|
|
251
|
+
* ```ts
|
|
252
|
+
* private readonly tab = inject(SPINE_TAB, { optional: true });
|
|
253
|
+
* readonly pedido = computed(() => this.tab?.params()['pedido'] ?? null);
|
|
254
|
+
* // trocar a seção: a mesma aba, sem recriar a tela (e o endereço do navegador acompanha, se a aba está à vista)
|
|
255
|
+
* this.tab?.navigate({ queryParams: { secao: 'itens' } });
|
|
256
|
+
* // o nome do registro no lugar do nome da rota
|
|
257
|
+
* this.tab?.setLabel('Pedido 123');
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
interface SpineTab {
|
|
261
|
+
/** Identidade estável da aba (o caminho, ou o caminho com os parâmetros que a identificam). */
|
|
262
|
+
readonly id: Signal<string>;
|
|
263
|
+
/** O painel em que a aba está agora. */
|
|
264
|
+
readonly panelId: Signal<string>;
|
|
265
|
+
/** O endereço atual da aba, com a query. */
|
|
266
|
+
readonly url: Signal<string>;
|
|
267
|
+
/** A query da aba. */
|
|
268
|
+
readonly params: Signal<SpineTabParams>;
|
|
269
|
+
/** A aba é a visível do painel focado (é a que o endereço do navegador mostra). */
|
|
270
|
+
readonly focused: Signal<boolean>;
|
|
271
|
+
/** Troca o nome (e, se vier, o ícone) da aba; persiste no F5 nas abas com parâmetros. */
|
|
272
|
+
setLabel(label: string, icon?: string): void;
|
|
273
|
+
/**
|
|
274
|
+
* Muda o endereço da própria aba. Com `queryParams`, mescla na query atual (`merge`, padrão) ou troca a query
|
|
275
|
+
* inteira (`merge: false`); `null`/`undefined` tira o parâmetro. Mesma tela: só a query muda, a tela não é recriada.
|
|
276
|
+
* Outra tela (um caminho diferente): é a navegação no lugar da aba, como um link dentro do painel.
|
|
277
|
+
*/
|
|
278
|
+
navigate(target: string | {
|
|
279
|
+
queryParams: Readonly<Record<string, string | number | boolean | null | undefined>>;
|
|
280
|
+
merge?: boolean;
|
|
281
|
+
}): void;
|
|
282
|
+
}
|
|
283
|
+
declare const SPINE_TAB: InjectionToken<SpineTab>;
|
|
284
|
+
|
|
285
|
+
/** Limite da grade de painéis do shell: no máximo 2 lado a lado e 2 empilhados (os quatro cantos da tela). */
|
|
286
|
+
declare const SPINE_WORKSPACE_LIMITS: WorkspaceGridLimits;
|
|
287
|
+
/** O caminho de um endereço (sem query nem fragmento). */
|
|
288
|
+
declare function spinePathOf(url: string): string;
|
|
289
|
+
/** A query de um endereço, como objeto. */
|
|
290
|
+
declare function spineParamsOf(url: string): SpineTabParams;
|
|
291
|
+
/** Caminho + query com os nomes em ordem: o mesmo endereço escrito de dois jeitos vira um só (sem o fragmento). */
|
|
292
|
+
declare function spineNormalizeUrl(url: string): string;
|
|
293
|
+
/** Como abrir uma aba pelo app (`openTab`). */
|
|
294
|
+
interface SpineOpenTabOptions {
|
|
295
|
+
/** Nome da aba (senão, o da rota). A tela pode trocar depois (`SPINE_TAB.setLabel`). */
|
|
296
|
+
label?: string;
|
|
297
|
+
icon?: string;
|
|
298
|
+
/**
|
|
299
|
+
* Os parâmetros que IDENTIFICAM a aba: com `['dispositivo']`, o mesmo dispositivo em outra seção reaproveita a aba
|
|
300
|
+
* aberta, e trocar a seção dentro dela não abre outra. Sem `match`, todos os parâmetros do endereço identificam.
|
|
301
|
+
*/
|
|
302
|
+
match?: readonly string[];
|
|
303
|
+
/**
|
|
304
|
+
* Abre num painel novo ao lado do focado (para comparar), em vez de no próprio painel focado. Só vale com a
|
|
305
|
+
* preferência "Dividir abas" ligada (`SpinePreferencesService.splitTabs`); desligada (o padrão), a aba abre no painel
|
|
306
|
+
* focado, como sem `beside`. No limite da grade (`SPINE_WORKSPACE_LIMITS`, 2 colunas), abre no painel que já está
|
|
307
|
+
* ao lado, sem dividir.
|
|
308
|
+
*/
|
|
309
|
+
beside?: boolean;
|
|
310
|
+
}
|
|
242
311
|
/**
|
|
243
312
|
* Dono do `WorkspaceStore` do shell — mesmo padrão do `WorkspaceNavService` do docs/website
|
|
244
313
|
* (`packages/hermes-ui/docs/website/src/app/workspace-nav.service.ts`), adaptado pra ler a
|
|
245
314
|
* árvore de rotas do BACKEND (`ViewService.currentView`) em vez de um `page-registry.ts`
|
|
246
315
|
* estático. Cada página visitada vira uma aba, pertencente a um painel; a navegação real do
|
|
247
316
|
* `Router` (routerLink, busca, sidebar) sempre atualiza a aba ativa do painel FOCADO.
|
|
317
|
+
*
|
|
318
|
+
* **Dois jeitos de ter aba, que convivem.** A navegação de sempre (menu, links, busca) mantém UMA aba por tela, com o
|
|
319
|
+
* caminho como `id` — como antes; a query que a tela usa fica guardada no `url` da aba e volta junto quando a pessoa
|
|
320
|
+
* retorna a ela. E o app pode abrir **abas com parâmetros** (`openTab`): a mesma tela várias vezes, uma por registro
|
|
321
|
+
* (um pedido, um dispositivo...). Nelas o `id` é a identidade (o caminho com os parâmetros que a identificam) e o `url`
|
|
322
|
+
* é o endereço atual (com a query que a tela vai mudando).
|
|
323
|
+
* O keepAlive do workspace acompanha o `id`, então mudar a query da aba não recria a tela. Uma navegação real cai
|
|
324
|
+
* numa destas, em ordem:
|
|
325
|
+
* 1. o endereço já é o da aba ativa → nada;
|
|
326
|
+
* 2. a mesma tela da aba ativa, mantendo os parâmetros que a identificam → só o `url` da aba muda (mesma aba);
|
|
327
|
+
* 3. outra aba do painel já está nesse endereço → ela é ativada;
|
|
328
|
+
* 4. senão → a aba ativa passa a ser a da tela nova (o comportamento de sempre).
|
|
329
|
+
* `openTab` abre (ou foca, em qualquer painel) a aba de um endereço com parâmetros.
|
|
330
|
+
*
|
|
331
|
+
* **Dividir abas é preferência da pessoa** (`SpinePreferencesService.splitTabs`, desligada por padrão): o shell só
|
|
332
|
+
* deixa dividir a área em painéis com ela ligada (`split`). Desligada — ao carregar ou ao desligar —, um arranjo com
|
|
333
|
+
* vários painéis (salvo no navegador ou feito antes) é fundido num painel só, sem perder aba (`mergePanels`).
|
|
248
334
|
*/
|
|
249
335
|
declare class SpineWorkspaceNavService {
|
|
250
336
|
private readonly router;
|
|
251
337
|
private readonly viewService;
|
|
338
|
+
private readonly preferences;
|
|
339
|
+
/** A pessoa pode dividir a área de abas em painéis (a preferência "Dividir abas"). */
|
|
340
|
+
readonly split: _angular_core.Signal<boolean>;
|
|
341
|
+
/** Até onde dá para dividir (o shell passa para o `hm-workspace`; `openTab` com `beside` respeita). */
|
|
342
|
+
readonly limits: WorkspaceGridLimits;
|
|
252
343
|
readonly store: WorkspaceStore;
|
|
253
344
|
private readonly state;
|
|
254
345
|
readonly root: _angular_core.Signal<_trismegisto_primitives.PanelNode>;
|
|
@@ -258,22 +349,57 @@ declare class SpineWorkspaceNavService {
|
|
|
258
349
|
* `viewService.logControl$`/`breadCrumb$` globais (que só existiam porque havia uma página
|
|
259
350
|
* "atual" só; agora cada painel tem a sua). */
|
|
260
351
|
readonly focusedChain: _angular_core.Signal<Route[] | null>;
|
|
261
|
-
|
|
352
|
+
/** O último endereço que o `Router` mostrou (normalizado, com a query): o `effect` abaixo não navega para ele de novo. */
|
|
353
|
+
private lastKnownUrl;
|
|
262
354
|
constructor();
|
|
355
|
+
private activeTab;
|
|
356
|
+
/** Uma navegação real no painel focado: as quatro regras do comentário da classe. */
|
|
357
|
+
private followNavigation;
|
|
263
358
|
/**
|
|
264
359
|
* As abas abertas passam a obedecer à view atual: aba de tela que a pessoa não pode mais abrir fecha (e o
|
|
265
360
|
* conteúdo dela é destruído junto); painel que ficaria sem aba nenhuma mostra o Início no lugar; a aba ativa
|
|
266
|
-
* de cada painel recebe o nome e o ícone da view nova
|
|
361
|
+
* de cada painel recebe o nome e o ícone da view nova (a aba com parâmetros guarda o nome que a tela deu). View
|
|
362
|
+
* vazia (ainda carregando) não fecha nada.
|
|
267
363
|
*/
|
|
268
364
|
reconcileWithView(): void;
|
|
269
365
|
/** Resolve a cadeia de rotas pra uma URL, direto na view atual — sem `Router`, sem `async`
|
|
270
366
|
* (o componente da folha só é carregado por quem for de fato desenhar o painel). Desce sozinho
|
|
271
367
|
* por nós organizacionais (com filhos, sem conteúdo próprio) — o rótulo/ícone da aba e o que a
|
|
272
|
-
* sidebar/breadcrumb mostram refletem o destino DE VERDADE, não a rota-container clicada.
|
|
368
|
+
* sidebar/breadcrumb mostram refletem o destino DE VERDADE, não a rota-container clicada. A query não
|
|
369
|
+
* conta: `ViewService.routePath` a tira. */
|
|
273
370
|
private chainFor;
|
|
371
|
+
/** A aba de uma tela pelo endereço: o `id` é o caminho; com query, o endereço vai no `url` (a mesma aba da tela). */
|
|
274
372
|
tabFor(url: string): TabItem;
|
|
373
|
+
/**
|
|
374
|
+
* Restaura uma aba salva (F5): a rota precisa continuar valendo para a pessoa. A aba com parâmetros volta com o
|
|
375
|
+
* endereço e o nome que tinha (o nome é o que a tela deu — "RT-MPLS-3046-0001" —, a rota não sabe); as outras
|
|
376
|
+
* voltam com o nome da rota (que acompanha o idioma).
|
|
377
|
+
*/
|
|
378
|
+
private restoreTab;
|
|
379
|
+
/**
|
|
380
|
+
* Junta todos os painéis no focado, sem perder aba: as abas ficam na ordem dos painéis (da esquerda para a direita,
|
|
381
|
+
* de cima para baixo), uma aba repetida em dois painéis vira uma só (vale a do focado), e a aba ativa do painel focado
|
|
382
|
+
* continua a ativa (`WorkspaceStore.mergePanels`). Com um painel só, não faz nada.
|
|
383
|
+
*/
|
|
384
|
+
mergePanels(): void;
|
|
275
385
|
/** O `+` de um painel: abre a home ali, como um navegador. */
|
|
276
386
|
openNewTab(panelId: string): void;
|
|
387
|
+
/**
|
|
388
|
+
* Abre (ou foca) a aba de um endereço com parâmetros — um registro por aba na mesma tela:
|
|
389
|
+
* `openTab('/vendas/pedidos?pedido=123&secao=itens', { label: 'Pedido 123', match: ['pedido'] })`.
|
|
390
|
+
* Se alguma aba (em qualquer painel) já tem essa identidade, ela é focada e passa a esse endereço; senão abre uma
|
|
391
|
+
* no painel focado (ou num painel novo ao lado, com `beside` e a divisão ligada). Só abre o que a view da pessoa permite (a mesma
|
|
392
|
+
* regra do menu e do `ViewGuard`); fora dela, não faz nada.
|
|
393
|
+
*/
|
|
394
|
+
openTab(url: string, options?: SpineOpenTabOptions): void;
|
|
395
|
+
/** O nome (e o ícone) de uma aba, dado pela tela (`SPINE_TAB.setLabel`). */
|
|
396
|
+
setTabLabel(panelId: string, tabId: string, label: string, icon?: string): void;
|
|
397
|
+
/**
|
|
398
|
+
* A tela muda o endereço da própria aba (`SPINE_TAB.navigate`). A mesma tela, mantendo a identidade: só o `url` da
|
|
399
|
+
* aba muda (sem recriar a tela) e, se ela é a visível do painel focado, o endereço do navegador acompanha (sem
|
|
400
|
+
* empilhar histórico). Outra tela: navegação local no painel, como um link dentro dele.
|
|
401
|
+
*/
|
|
402
|
+
navigateTab(panelId: string, tabId: string, url: string): void;
|
|
277
403
|
/** Navegação LOCAL a um painel específico (usada pelo `PanelLocalLinkDirective`) — troca o
|
|
278
404
|
* ASSUNTO da aba ativa daquele painel, não empilha uma aba nova. */
|
|
279
405
|
navigateLocally(panelId: string, href: string): void;
|
|
@@ -281,6 +407,79 @@ declare class SpineWorkspaceNavService {
|
|
|
281
407
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<SpineWorkspaceNavService>;
|
|
282
408
|
}
|
|
283
409
|
|
|
410
|
+
/**
|
|
411
|
+
* Saída da sessão pelo shell: todo botão/atalho de sair do spine passa por aqui (menu do perfil, painel de
|
|
412
|
+
* configurações, tela `/blocked`).
|
|
413
|
+
*
|
|
414
|
+
* - Assina `logoutFailed$` do `@orfeu/angular` (1.3.x) uma vez só: quando o logout no Argos falha (a lib repete uma
|
|
415
|
+
* vez e mantém a sessão), mostra o aviso de erro `session.logoutFailed` (`hm-alert` de erro, `role="alert"`). Vale
|
|
416
|
+
* também para um `logout()` chamado direto pelo app.
|
|
417
|
+
* - `logout()` aguarda o resultado: só apaga os históricos do usuário (`SpineUserStorage.clearHistory()`) quando a
|
|
418
|
+
* saída deu certo. Com falha, nada muda: a pessoa continua na tela, com a sessão e os recentes.
|
|
419
|
+
* - `pending` fica `true` enquanto a saída está em andamento e sempre volta a `false` (os botões não travam).
|
|
420
|
+
*
|
|
421
|
+
* Com `@orfeu/angular` 1.0.x (sem `logoutFailed$`, `logout()` sem retorno) a saída conta como concluída, como antes.
|
|
422
|
+
*/
|
|
423
|
+
declare class SpineLogoutService {
|
|
424
|
+
private readonly auth;
|
|
425
|
+
private readonly userStorage;
|
|
426
|
+
private readonly notifications;
|
|
427
|
+
private readonly messages;
|
|
428
|
+
/** `true` quando a lib avisa a falha por `logoutFailed$` (então o aviso sai por lá, uma vez). */
|
|
429
|
+
private readonly failureStream;
|
|
430
|
+
private inFlight;
|
|
431
|
+
/** Saída em andamento (o botão mostra "saindo…" / fica desabilitado). */
|
|
432
|
+
readonly pending: _angular_core.WritableSignal<boolean>;
|
|
433
|
+
constructor();
|
|
434
|
+
/**
|
|
435
|
+
* Sai da sessão. Resolve `true` quando saiu (o `@orfeu/angular` já navega para o `/logoff`) e `false` quando o
|
|
436
|
+
* Argos não confirmou: a sessão continua e o aviso de erro aparece. Nunca rejeita. Cliques repetidos durante a
|
|
437
|
+
* saída reaproveitam a mesma tentativa.
|
|
438
|
+
*/
|
|
439
|
+
logout(): Promise<boolean>;
|
|
440
|
+
private run;
|
|
441
|
+
private notifyFailure;
|
|
442
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SpineLogoutService, never>;
|
|
443
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<SpineLogoutService>;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Registra a verificação de alterações da tela, presa à aba do workspace em que ela está (`SPINE_TAB`):
|
|
448
|
+
* com `SpineFeatures.unsavedChanges` ligado, fechar ESSA aba (ou o painel dela, ou "fechar as outras") e
|
|
449
|
+
* trocar de tela dentro dela pergunta antes. Chame num contexto de injeção (campo da tela); a verificação
|
|
450
|
+
* sai sozinha quando a tela é destruída.
|
|
451
|
+
*
|
|
452
|
+
* ```ts
|
|
453
|
+
* readonly #unsaved = registerSpineUnsavedChanges(() => this.form.dirty);
|
|
454
|
+
* ```
|
|
455
|
+
*
|
|
456
|
+
* Sem o recurso ligado, continua registrando no `HermesUnsavedChangesService` (o `hermesUnsavedChangesGuard`
|
|
457
|
+
* de uma rota do app enxerga), mas o shell não pergunta nada.
|
|
458
|
+
*/
|
|
459
|
+
declare function registerSpineUnsavedChanges(check: () => boolean): () => void;
|
|
460
|
+
/**
|
|
461
|
+
* O lado do shell do aviso de alterações não salvas (`SpineFeatures.unsavedChanges`, desligado por padrão).
|
|
462
|
+
* Ligado: o `hm-workspace` recebe um store que pergunta antes de fechar aba com alteração; trocar de tela
|
|
463
|
+
* dentro da aba pergunta também; e o navegador avisa ao recarregar/fechar a página. Desligado: `store` é o
|
|
464
|
+
* mesmo do `SpineWorkspaceNavService` e nada muda.
|
|
465
|
+
*/
|
|
466
|
+
declare class SpineUnsavedChangesService {
|
|
467
|
+
private readonly config;
|
|
468
|
+
private readonly unsaved;
|
|
469
|
+
private readonly nav;
|
|
470
|
+
/** O recurso está ligado no app. */
|
|
471
|
+
readonly enabled: boolean;
|
|
472
|
+
/** O store que o shell passa para o `hm-workspace`. */
|
|
473
|
+
readonly store: WorkspaceStore$1;
|
|
474
|
+
/** Liga o aviso do navegador (só com o recurso ligado). Devolve a função que desliga. */
|
|
475
|
+
start(): () => void;
|
|
476
|
+
/** Pode trocar a tela da aba ativa do painel? Sem o recurso ou sem alteração nela, `true` na hora. */
|
|
477
|
+
canReplaceActive(panelId: string): boolean | Promise<boolean>;
|
|
478
|
+
private guard;
|
|
479
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SpineUnsavedChangesService, never>;
|
|
480
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<SpineUnsavedChangesService>;
|
|
481
|
+
}
|
|
482
|
+
|
|
284
483
|
/**
|
|
285
484
|
* Shell do spine — MESMA estrutura do `docs/website`'s `app.component.html`/`.scss` (decisão de
|
|
286
485
|
* 2026-09-28, ver `hefesto-migration-plan.md`): `.shell` com altura de viewport de verdade
|
|
@@ -310,13 +509,19 @@ declare class LayoutComponent implements OnInit {
|
|
|
310
509
|
private readonly preferences;
|
|
311
510
|
protected readonly workspace: SpineWorkspaceNavService;
|
|
312
511
|
private readonly settings;
|
|
512
|
+
private readonly sidebar;
|
|
313
513
|
/** Também liga, uma vez, o aviso de falha do logout (`logoutFailed$` do `@orfeu/angular`). */
|
|
314
|
-
|
|
514
|
+
protected readonly logoutNotice: SpineLogoutService;
|
|
315
515
|
/** Recursos opcionais (`SpineConfig.features`): cada serviço não faz nada com o seu recurso desligado. */
|
|
316
516
|
private readonly idle;
|
|
317
517
|
private readonly startPage;
|
|
318
518
|
private readonly accountPreferences;
|
|
319
519
|
protected readonly setup: SpineInitialSetupService;
|
|
520
|
+
/** Aviso de alterações não salvas (SpineFeatures.unsavedChanges): sem o recurso, `unsaved.store` é o próprio `workspace.store`. */
|
|
521
|
+
protected readonly unsaved: SpineUnsavedChangesService;
|
|
522
|
+
/** SpineFeatures.skipLink. */
|
|
523
|
+
protected readonly skipLink: boolean;
|
|
524
|
+
private readonly destroyRef;
|
|
320
525
|
/** Esconde sidebar e área de trabalho quando a rota ATIVA (do Router real, ver
|
|
321
526
|
* `router.events` abaixo) é a de sem-permissão — nesse caso não existe menu/página válido
|
|
322
527
|
* como contexto. Note que isto reflete só a URL do painel FOCADO (dona do Router real); um
|
|
@@ -327,8 +532,12 @@ declare class LayoutComponent implements OnInit {
|
|
|
327
532
|
constructor(router: Router, theme: ThemeService, shortcuts: ShortcutService, news: SpineNewsService);
|
|
328
533
|
private matchesNoPermission;
|
|
329
534
|
ngOnInit(): void;
|
|
535
|
+
/**
|
|
536
|
+
* `Mod+B`. Tela estreita: a gaveta. Fixo e compacto: troca um pelo outro (é a preferência da pessoa, fica gravada).
|
|
537
|
+
* Automático: a coluna abre por cima e fica até o próximo `Mod+B`, sem mudar a preferência.
|
|
538
|
+
*/
|
|
539
|
+
private toggleSidebar;
|
|
330
540
|
protected onLocalNavigate(panelId: string, href: string): void;
|
|
331
|
-
private toggleFullscreen;
|
|
332
541
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<LayoutComponent, never>;
|
|
333
542
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<LayoutComponent, "spine-layout", never, {}, {}, never, never, true, never>;
|
|
334
543
|
}
|
|
@@ -432,7 +641,7 @@ declare class HeaderComponent implements OnInit {
|
|
|
432
641
|
protected readonly searchIcons: Readonly<Record<string, string>>;
|
|
433
642
|
/** Achata a árvore de rotas em itens navegáveis (com trilha de ancestrais). */
|
|
434
643
|
private flattenRoutes;
|
|
435
|
-
/** Chamado pelo `(searchRequested)` do `hm-header` (clique no campo
|
|
644
|
+
/** Chamado pelo `(searchRequested)` do `hm-header` (clique no campo, `Ctrl K` ou `/`, já tratados por ele): abre a paleta. */
|
|
436
645
|
onSearchRequested(): void;
|
|
437
646
|
/**
|
|
438
647
|
* Comandos da paleta. Cada tela aparece uma vez: favoritos primeiro, depois os abertos há pouco que não são
|
|
@@ -556,12 +765,18 @@ declare class SidebarComponent {
|
|
|
556
765
|
modules: string;
|
|
557
766
|
moduleNavigation: string;
|
|
558
767
|
apps: string;
|
|
768
|
+
openInNewTab: string;
|
|
559
769
|
};
|
|
560
770
|
protected readonly fmt: typeof formatMessage;
|
|
561
771
|
private readonly workspace;
|
|
562
772
|
private readonly viewService;
|
|
563
773
|
private readonly authService;
|
|
564
774
|
private readonly realmApps;
|
|
775
|
+
private readonly location;
|
|
776
|
+
private readonly column;
|
|
777
|
+
protected readonly pageMenu: readonly MenuItem$1[];
|
|
778
|
+
/** Endereço da página em que o menu de contexto foi aberto. */
|
|
779
|
+
private menuPage;
|
|
565
780
|
/** Aplicações do realm (o app atual já vem excluído pelo backend) — exibidas só no mobile. */
|
|
566
781
|
protected readonly apps: _angular_core.WritableSignal<AppDef[]>;
|
|
567
782
|
private readonly currentView;
|
|
@@ -583,6 +798,11 @@ declare class SidebarComponent {
|
|
|
583
798
|
* do módulo" pra mostrar. */
|
|
584
799
|
private readonly wantsModules;
|
|
585
800
|
protected readonly viewingModules: _angular_core.Signal<boolean>;
|
|
801
|
+
/** Botão direito (ou Shift+F10/tecla Menu, que o navegador traduz em `contextmenu`) numa página do menu. Grupo e
|
|
802
|
+
* entrada de módulo não são páginas: ali o menu nativo continua valendo. */
|
|
803
|
+
protected onContextMenu(event: MouseEvent, menu: ContextMenuDirective): void;
|
|
804
|
+
protected onPageMenuClosed(): void;
|
|
805
|
+
protected openPageInNewTab(): void;
|
|
586
806
|
/** Sem teto artificial de nível de grupo — o template não enxerga o global `Infinity`, só
|
|
587
807
|
* membros da classe. Ver comentário no `.html`: o backend já limita a árvore sozinho. */
|
|
588
808
|
protected readonly maxDepth: number;
|
|
@@ -628,42 +848,6 @@ declare class SpineConnectionBannerComponent {
|
|
|
628
848
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SpineConnectionBannerComponent, "spine-connection-banner", never, {}, {}, never, never, true, never>;
|
|
629
849
|
}
|
|
630
850
|
|
|
631
|
-
/**
|
|
632
|
-
* Saída da sessão pelo shell: todo botão/atalho de sair do spine passa por aqui (menu do perfil, painel de
|
|
633
|
-
* configurações, `Mod+Shift+L`, tela `/blocked`).
|
|
634
|
-
*
|
|
635
|
-
* - Assina `logoutFailed$` do `@orfeu/angular` (1.3.x) uma vez só: quando o logout no Argos falha (a lib repete uma
|
|
636
|
-
* vez e mantém a sessão), mostra o aviso de erro `session.logoutFailed` (`hm-alert` de erro, `role="alert"`). Vale
|
|
637
|
-
* também para um `logout()` chamado direto pelo app.
|
|
638
|
-
* - `logout()` aguarda o resultado: só apaga os históricos do usuário (`SpineUserStorage.clearHistory()`) quando a
|
|
639
|
-
* saída deu certo. Com falha, nada muda: a pessoa continua na tela, com a sessão e os recentes.
|
|
640
|
-
* - `pending` fica `true` enquanto a saída está em andamento e sempre volta a `false` (os botões não travam).
|
|
641
|
-
*
|
|
642
|
-
* Com `@orfeu/angular` 1.0.x (sem `logoutFailed$`, `logout()` sem retorno) a saída conta como concluída, como antes.
|
|
643
|
-
*/
|
|
644
|
-
declare class SpineLogoutService {
|
|
645
|
-
private readonly auth;
|
|
646
|
-
private readonly userStorage;
|
|
647
|
-
private readonly notifications;
|
|
648
|
-
private readonly messages;
|
|
649
|
-
/** `true` quando a lib avisa a falha por `logoutFailed$` (então o aviso sai por lá, uma vez). */
|
|
650
|
-
private readonly failureStream;
|
|
651
|
-
private inFlight;
|
|
652
|
-
/** Saída em andamento (o botão mostra "saindo…" / fica desabilitado). */
|
|
653
|
-
readonly pending: _angular_core.WritableSignal<boolean>;
|
|
654
|
-
constructor();
|
|
655
|
-
/**
|
|
656
|
-
* Sai da sessão. Resolve `true` quando saiu (o `@orfeu/angular` já navega para o `/logoff`) e `false` quando o
|
|
657
|
-
* Argos não confirmou: a sessão continua e o aviso de erro aparece. Nunca rejeita. Cliques repetidos durante a
|
|
658
|
-
* saída reaproveitam a mesma tentativa.
|
|
659
|
-
*/
|
|
660
|
-
logout(): Promise<boolean>;
|
|
661
|
-
private run;
|
|
662
|
-
private notifyFailure;
|
|
663
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SpineLogoutService, never>;
|
|
664
|
-
static ɵprov: _angular_core.ɵɵInjectableDeclaration<SpineLogoutService>;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
851
|
/** Um cartão do essencial: o texto tem `{key}` onde entra a tecla (desenhada como `<kbd>`). */
|
|
668
852
|
interface EssentialCard {
|
|
669
853
|
readonly id: string;
|
|
@@ -733,6 +917,9 @@ declare class SpineInitialSetupComponent {
|
|
|
733
917
|
sidebarAuto: string;
|
|
734
918
|
sidebarFixed: string;
|
|
735
919
|
sidebarCompact: string;
|
|
920
|
+
splitTabs: string;
|
|
921
|
+
splitTabsDescription: string;
|
|
922
|
+
splitTabsKeywords: string;
|
|
736
923
|
region: string;
|
|
737
924
|
regionKeywords: string;
|
|
738
925
|
language: string;
|
|
@@ -932,6 +1119,7 @@ declare class ShortcutsCheatsheetComponent implements OnInit, OnDestroy {
|
|
|
932
1119
|
goFavorite: string;
|
|
933
1120
|
history: string;
|
|
934
1121
|
openSettings: string;
|
|
1122
|
+
toggleSidebar: string;
|
|
935
1123
|
toggleTheme: string;
|
|
936
1124
|
fullscreen: string;
|
|
937
1125
|
logout: string;
|
|
@@ -1034,12 +1222,14 @@ interface SpineAccountPreferencesDoc {
|
|
|
1034
1222
|
startPage?: SpineStartPagePreference;
|
|
1035
1223
|
notices?: Record<string, boolean>;
|
|
1036
1224
|
browserNotices?: boolean;
|
|
1225
|
+
/** Dividir a área de abas em painéis (`SpinePreferencesService.splitTabs`). */
|
|
1226
|
+
splitTabs?: boolean;
|
|
1037
1227
|
favorites?: unknown[];
|
|
1038
1228
|
}
|
|
1039
1229
|
/**
|
|
1040
1230
|
* Chaves que são da pessoa, não do app: com o Argos que tem `{api}/preferences/global`, vão no documento global e
|
|
1041
|
-
* valem em todos os apps (escolhidas uma vez). O resto (menu lateral, atalhos, inatividade, tela inicial,
|
|
1042
|
-
* favoritos) continua no documento do app.
|
|
1231
|
+
* valem em todos os apps (escolhidas uma vez). O resto (menu lateral, dividir abas, atalhos, inatividade, tela inicial,
|
|
1232
|
+
* avisos, favoritos) continua no documento do app.
|
|
1043
1233
|
*/
|
|
1044
1234
|
declare const SPINE_GLOBAL_PREFERENCE_KEYS: readonly ["themeMode", "family", "density", "font", "textScale", "motion", "language", "timeZone", "hourCycle", "weekStart"];
|
|
1045
1235
|
/** Documento global (`PUT {api}/preferences/global`): aparência e região, mais a configuração inicial feita. */
|
|
@@ -1052,8 +1242,8 @@ type SpineAccountPreferencesStatus = 'idle' | 'local' | 'loading' | 'saving' | '
|
|
|
1052
1242
|
/**
|
|
1053
1243
|
* Preferências na conta (`SpineFeatures.accountPreferences`): espelha no Argos (`GET/PUT {api}/preferences`, por
|
|
1054
1244
|
* usuário e aplicação) o que o painel de configurações guarda no navegador — tema, cor, densidade, fonte, menu
|
|
1055
|
-
* lateral, idioma, fuso, relógio, primeiro dia da semana, tamanho do texto, animações, atalhos de tecla
|
|
1056
|
-
* inatividade, tela inicial, tipos de aviso e favoritos. As telas Aparência, Região etc. não mudam: o
|
|
1245
|
+
* lateral, dividir abas, idioma, fuso, relógio, primeiro dia da semana, tamanho do texto, animações, atalhos de tecla
|
|
1246
|
+
* única, inatividade, tela inicial, tipos de aviso e favoritos. As telas Aparência, Região etc. não mudam: o
|
|
1057
1247
|
* armazenamento local continua sendo a fonte de cada tela, e este serviço só sincroniza.
|
|
1058
1248
|
*
|
|
1059
1249
|
* - No início da sessão (`start()`, chamado pelo layout e pelo `/callback`), lê a conta e aplica o que estiver lá
|
|
@@ -1232,6 +1422,9 @@ declare class SettingsPanelComponent {
|
|
|
1232
1422
|
sidebarAuto: string;
|
|
1233
1423
|
sidebarFixed: string;
|
|
1234
1424
|
sidebarCompact: string;
|
|
1425
|
+
splitTabs: string;
|
|
1426
|
+
splitTabsDescription: string;
|
|
1427
|
+
splitTabsKeywords: string;
|
|
1235
1428
|
region: string;
|
|
1236
1429
|
regionKeywords: string;
|
|
1237
1430
|
language: string;
|
|
@@ -1684,8 +1877,8 @@ declare class SettingsPanelComponent {
|
|
|
1684
1877
|
protected clearList(list: BrowserList): void;
|
|
1685
1878
|
/**
|
|
1686
1879
|
* Restaurar preferências (com confirmação): tema (sistema), cor principal (a padrão do app), densidade
|
|
1687
|
-
* (confortável), fonte (a padrão do app), menu lateral (o modo padrão do app),
|
|
1688
|
-
* animações (sistema), formato de hora e primeiro dia da semana (automáticos). Idioma, fuso horário e
|
|
1880
|
+
* (confortável), fonte (a padrão do app), menu lateral (o modo padrão do app), dividir abas (desligado), tamanho do
|
|
1881
|
+
* texto (100%), animações (sistema), formato de hora e primeiro dia da semana (automáticos). Idioma, fuso horário e
|
|
1689
1882
|
* atalhos de tecla única ficam: mudam como a pessoa lê e digita, e não são "aparência".
|
|
1690
1883
|
*/
|
|
1691
1884
|
protected restorePreferences(): void;
|
|
@@ -1866,12 +2059,33 @@ interface GroupMember {
|
|
|
1866
2059
|
joined_at: string | null;
|
|
1867
2060
|
added_by_username: string | null;
|
|
1868
2061
|
}
|
|
2062
|
+
/** Página e filtros da lista de membros (o servidor pagina: padrão 50, até 200 por página). */
|
|
2063
|
+
interface GroupMembersQuery {
|
|
2064
|
+
page?: number;
|
|
2065
|
+
limit?: number;
|
|
2066
|
+
/** Trecho do nome, do login ou do e-mail. */
|
|
2067
|
+
search?: string;
|
|
2068
|
+
}
|
|
2069
|
+
/** Uma página de membros, com a função de quem pede e o que ela permite (como em `ManagedGroup`). */
|
|
2070
|
+
interface GroupMembersPage {
|
|
2071
|
+
my_role: GroupRole | null;
|
|
2072
|
+
can_add: boolean;
|
|
2073
|
+
assignable_roles: GroupRole[];
|
|
2074
|
+
can_change_roles: boolean;
|
|
2075
|
+
members: GroupMember[];
|
|
2076
|
+
/** Quantos passam pela busca (sem busca, o grupo inteiro). */
|
|
2077
|
+
total: number;
|
|
2078
|
+
page: number;
|
|
2079
|
+
limit: number;
|
|
2080
|
+
}
|
|
1869
2081
|
interface RealmUser {
|
|
1870
2082
|
id: string;
|
|
1871
2083
|
username: string;
|
|
1872
2084
|
email: string | null;
|
|
1873
2085
|
name: string | null;
|
|
1874
2086
|
enabled: boolean;
|
|
2087
|
+
/** Foto (o argos-admin já manda com a busca): a pessoa incluída entra na lista com ela. */
|
|
2088
|
+
picture?: string | null;
|
|
1875
2089
|
}
|
|
1876
2090
|
/**
|
|
1877
2091
|
* Grupos de que a pessoa é membro e o que a função dela permite — `argos-admin /me/groups`. Sempre da aplicação LOGADA (o
|
|
@@ -1892,9 +2106,11 @@ declare class SpineMyGroupsService {
|
|
|
1892
2106
|
private get headers();
|
|
1893
2107
|
/** Relê os grupos; qualquer falha deixa a lista vazia (a seção some em vez de mostrar um erro sem contexto). */
|
|
1894
2108
|
refresh(): Promise<void>;
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
2109
|
+
/**
|
|
2110
|
+
* Uma página dos membros, pela ordem do login. Observable (não Promise): a tela pede as páginas até o fim e cancela a
|
|
2111
|
+
* pendente ao sair.
|
|
2112
|
+
*/
|
|
2113
|
+
members(groupId: string, query?: GroupMembersQuery): Observable<GroupMembersPage>;
|
|
1898
2114
|
searchUsers(search: string, limit?: number): Promise<{
|
|
1899
2115
|
users: RealmUser[];
|
|
1900
2116
|
}>;
|
|
@@ -2779,6 +2995,132 @@ declare class SpinePageActionsDirective implements OnDestroy {
|
|
|
2779
2995
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SpinePageActionsDirective, "ng-template[spinePageActions]", never, {}, {}, never, never, true, never>;
|
|
2780
2996
|
}
|
|
2781
2997
|
|
|
2998
|
+
/** Uma novidade na central de notificações (o sino do cabeçalho). */
|
|
2999
|
+
interface SpineInboxItem {
|
|
3000
|
+
/** Único dentro da fonte. */
|
|
3001
|
+
readonly id: string;
|
|
3002
|
+
readonly title: string;
|
|
3003
|
+
/** A novidade em uma linha ("Ana: pode mandar um exemplo?"). */
|
|
3004
|
+
readonly body?: string;
|
|
3005
|
+
/** Quando aconteceu (a novidade mais recente do item): ordena a lista e vira "há 5 min". */
|
|
3006
|
+
readonly at: string | Date;
|
|
3007
|
+
/** Quantas novidades o item junta (mostra "+N" a partir de 2). */
|
|
3008
|
+
readonly count?: number;
|
|
3009
|
+
/** Quem fez: a foto (ou as iniciais) na linha; sem pessoa, o ícone da fonte. */
|
|
3010
|
+
readonly person?: {
|
|
3011
|
+
readonly name: string;
|
|
3012
|
+
readonly picture?: string | null;
|
|
3013
|
+
} | null;
|
|
3014
|
+
}
|
|
3015
|
+
/**
|
|
3016
|
+
* Uma fonte da central de notificações: o que há de novo PARA a pessoa num recurso (sugestões, aprovações, chamados…).
|
|
3017
|
+
* Não são os toasts (`HermesToastService`/`NotificationService`), que passam: aqui fica até a pessoa ver. Registre com
|
|
3018
|
+
* `provideSpineInboxSource`; o sino só aparece com alguma fonte.
|
|
3019
|
+
*/
|
|
3020
|
+
interface SpineInboxSource {
|
|
3021
|
+
readonly id: string;
|
|
3022
|
+
/** O nome da fonte ("Sugestões"), acima dos itens dela. */
|
|
3023
|
+
readonly label: string;
|
|
3024
|
+
/** Ícone da fonte (@trismegisto/icons), nos itens sem pessoa. */
|
|
3025
|
+
readonly icon?: string;
|
|
3026
|
+
/** As novidades (as mais recentes, até umas 20) e o total de itens com novidade (o número do sino). */
|
|
3027
|
+
load(): Promise<{
|
|
3028
|
+
readonly items: readonly SpineInboxItem[];
|
|
3029
|
+
readonly total: number;
|
|
3030
|
+
}>;
|
|
3031
|
+
/** A pessoa escolheu o item: marque como visto e abra onde ele está. A central relê depois. */
|
|
3032
|
+
open(item: SpineInboxItem): void | Promise<void>;
|
|
3033
|
+
}
|
|
3034
|
+
/** As fontes registradas (multi). Uma fábrica pode devolver `null` (recurso desligado): fica de fora. */
|
|
3035
|
+
declare const SPINE_INBOX_SOURCES: InjectionToken<readonly (SpineInboxSource | null)[]>;
|
|
3036
|
+
/**
|
|
3037
|
+
* Registra uma fonte na central de notificações. A fábrica roda num contexto de injeção (`inject()` vale) e pode
|
|
3038
|
+
* devolver `null` para não registrar nada.
|
|
3039
|
+
*
|
|
3040
|
+
* ```ts
|
|
3041
|
+
* provideSpineInboxSource(() => {
|
|
3042
|
+
* const api = inject(AprovacoesApi);
|
|
3043
|
+
* const router = inject(Router);
|
|
3044
|
+
* return {
|
|
3045
|
+
* id: 'aprovacoes', label: 'Aprovações', icon: 'check-circle',
|
|
3046
|
+
* load: async () => { const r = await api.pendentes(); return { total: r.total, items: r.itens.map(toItem) }; },
|
|
3047
|
+
* open: (item) => void router.navigateByUrl(`/aprovacoes/${item.id}`),
|
|
3048
|
+
* };
|
|
3049
|
+
* })
|
|
3050
|
+
* ```
|
|
3051
|
+
*/
|
|
3052
|
+
declare function provideSpineInboxSource(factory: () => SpineInboxSource | null): Provider;
|
|
3053
|
+
|
|
3054
|
+
/** Um item na lista do sino, com a fonte dele. */
|
|
3055
|
+
interface SpineInboxEntry {
|
|
3056
|
+
/** `fonte:item`, único na lista. */
|
|
3057
|
+
readonly key: string;
|
|
3058
|
+
readonly source: SpineInboxSource;
|
|
3059
|
+
readonly item: SpineInboxItem;
|
|
3060
|
+
}
|
|
3061
|
+
/** De quanto em quanto tempo a central relê, com a aba do navegador à vista. */
|
|
3062
|
+
declare const SPINE_INBOX_POLL_MS = 60000;
|
|
3063
|
+
/**
|
|
3064
|
+
* A central de notificações (o sino do cabeçalho): junta as novidades das fontes registradas
|
|
3065
|
+
* (`provideSpineInboxSource`), a mais recente primeiro. Relê enquanto alguém acompanha (`watch`): de minuto em minuto
|
|
3066
|
+
* com a aba à vista e ao voltar para ela. Quem muda o que conta como novidade (ler uma conversa, por exemplo) chama
|
|
3067
|
+
* `refresh()`.
|
|
3068
|
+
*/
|
|
3069
|
+
declare class SpineInboxService {
|
|
3070
|
+
private readonly browser;
|
|
3071
|
+
private readonly sources;
|
|
3072
|
+
/** Alguma fonte registrada: sem nenhuma, o sino não aparece. */
|
|
3073
|
+
readonly enabled: boolean;
|
|
3074
|
+
readonly entries: _angular_core.WritableSignal<readonly SpineInboxEntry[]>;
|
|
3075
|
+
/** Itens com novidade, somando as fontes (o número do sino). */
|
|
3076
|
+
readonly total: _angular_core.WritableSignal<number>;
|
|
3077
|
+
readonly loading: _angular_core.WritableSignal<boolean>;
|
|
3078
|
+
/** Nenhuma fonte respondeu na última leitura. */
|
|
3079
|
+
readonly failed: _angular_core.WritableSignal<boolean>;
|
|
3080
|
+
private request;
|
|
3081
|
+
private watchers;
|
|
3082
|
+
private timer;
|
|
3083
|
+
private readonly onVisible;
|
|
3084
|
+
/** Relê todas as fontes. Uma fonte que falha não derruba as outras. */
|
|
3085
|
+
refresh(): Promise<void>;
|
|
3086
|
+
/** A pessoa escolheu um item: a fonte abre (e marca como visto); depois a central relê. */
|
|
3087
|
+
open(entry: SpineInboxEntry): Promise<void>;
|
|
3088
|
+
/**
|
|
3089
|
+
* Passa a reler sozinha enquanto `destroyRef` viver (o sino no cabeçalho): lê agora, de minuto em minuto com a aba à
|
|
3090
|
+
* vista e ao voltar para a aba. Vários acompanhando dividem o mesmo relógio.
|
|
3091
|
+
*/
|
|
3092
|
+
watch(destroyRef: DestroyRef): void;
|
|
3093
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SpineInboxService, never>;
|
|
3094
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<SpineInboxService>;
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
/**
|
|
3098
|
+
* O sino do cabeçalho: a central de notificações (`SpineInboxService`). O número é quantos itens têm novidade; o
|
|
3099
|
+
* painel lista as novidades das fontes, a mais recente primeiro, e escolher uma abre onde ela está. Sem fonte
|
|
3100
|
+
* registrada, não desenha nada.
|
|
3101
|
+
*/
|
|
3102
|
+
declare class SpineInboxButtonComponent {
|
|
3103
|
+
protected readonly inbox: SpineInboxService;
|
|
3104
|
+
private readonly messages;
|
|
3105
|
+
protected readonly text: {
|
|
3106
|
+
title: string;
|
|
3107
|
+
button: _trismegisto_primitives.PluralMessage;
|
|
3108
|
+
empty: string;
|
|
3109
|
+
error: string;
|
|
3110
|
+
retry: string;
|
|
3111
|
+
news: _trismegisto_primitives.PluralMessage;
|
|
3112
|
+
};
|
|
3113
|
+
protected readonly buttonLabel: _angular_core.Signal<string>;
|
|
3114
|
+
constructor();
|
|
3115
|
+
protected choose(entry: SpineInboxEntry): void;
|
|
3116
|
+
protected newsText(count: number): string;
|
|
3117
|
+
protected iso(entry: SpineInboxEntry): string;
|
|
3118
|
+
/** "há 5 min", "ontem", "há 3 dias" (Intl, no idioma do catálogo). */
|
|
3119
|
+
protected ago(entry: SpineInboxEntry): string;
|
|
3120
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SpineInboxButtonComponent, never>;
|
|
3121
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SpineInboxButtonComponent, "spine-inbox-button", never, {}, {}, never, never, true, never>;
|
|
3122
|
+
}
|
|
3123
|
+
|
|
2782
3124
|
/** Tipos de sugestão, como o Argos guarda (`web.app_suggestions.kind`). */
|
|
2783
3125
|
declare const SPINE_SUGGESTION_KINDS: readonly ["melhoria", "nova_funcionalidade", "problema", "outro"];
|
|
2784
3126
|
type SpineSuggestionKind = (typeof SPINE_SUGGESTION_KINDS)[number];
|
|
@@ -2822,10 +3164,7 @@ interface SpineSuggestion {
|
|
|
2822
3164
|
kind: SpineSuggestionKind;
|
|
2823
3165
|
title: string;
|
|
2824
3166
|
description: string;
|
|
2825
|
-
screen:
|
|
2826
|
-
path: string | null;
|
|
2827
|
-
label: string | null;
|
|
2828
|
-
};
|
|
3167
|
+
screen: SpineSuggestionScreen;
|
|
2829
3168
|
status: SpineSuggestionStatus;
|
|
2830
3169
|
position: number;
|
|
2831
3170
|
votes: number;
|
|
@@ -2838,6 +3177,9 @@ interface SpineSuggestion {
|
|
|
2838
3177
|
} | null;
|
|
2839
3178
|
/** Desde quando está no status atual (o último evento para ele; sem evento, a criação). */
|
|
2840
3179
|
status_at?: string;
|
|
3180
|
+
/** Com quem está a vez na conversa (null = em dia). */
|
|
3181
|
+
waiting_on?: SpineSuggestionWaiting | null;
|
|
3182
|
+
waiting_since?: string | null;
|
|
2841
3183
|
created_at: string;
|
|
2842
3184
|
updated_at: string;
|
|
2843
3185
|
/** Só no auto-serviço: quem pediu, com a foto (null = pessoa removida). */
|
|
@@ -2864,10 +3206,7 @@ interface SpineAppSuggestion {
|
|
|
2864
3206
|
title: string;
|
|
2865
3207
|
/** Texto puro (a descrição inteira, até 4000). */
|
|
2866
3208
|
description: string;
|
|
2867
|
-
screen:
|
|
2868
|
-
path: string | null;
|
|
2869
|
-
label: string | null;
|
|
2870
|
-
};
|
|
3209
|
+
screen: SpineSuggestionScreen;
|
|
2871
3210
|
status: SpineSuggestionStatus;
|
|
2872
3211
|
votes: number;
|
|
2873
3212
|
/** Quem consulta apoia. */
|
|
@@ -2904,17 +3243,124 @@ interface SpineAppSuggestionsQuery {
|
|
|
2904
3243
|
interface SpineSuggestionDraft {
|
|
2905
3244
|
kind: SpineSuggestionKind;
|
|
2906
3245
|
title: string;
|
|
2907
|
-
|
|
3246
|
+
/** Texto puro (o formato antigo; o servidor ainda aceita). */
|
|
3247
|
+
description?: string;
|
|
3248
|
+
/** A descrição em rich text (o editor do modal); o servidor saneia e deriva o texto puro. */
|
|
3249
|
+
description_html?: string;
|
|
3250
|
+
/** Tela do menu (`router_id` e a rota) ou `new: true` com o nome da tela que ainda não existe em `label`. */
|
|
2908
3251
|
screen: {
|
|
2909
3252
|
path: string | null;
|
|
2910
3253
|
label: string | null;
|
|
3254
|
+
router_id?: string | null;
|
|
3255
|
+
new?: boolean;
|
|
2911
3256
|
};
|
|
2912
3257
|
}
|
|
3258
|
+
/** Por que a pessoa vê a sugestão (o servidor decide; uma sugestão pode ter vários). */
|
|
3259
|
+
declare const SPINE_SUGGESTION_REASONS: readonly ["autor", "relator", "envolvido", "responsavel", "grupo"];
|
|
3260
|
+
type SpineSuggestionReason = (typeof SPINE_SUGGESTION_REASONS)[number];
|
|
3261
|
+
/** Com quem está a vez na conversa: quem pediu (a equipe respondeu) ou a equipe (quem pediu escreveu). */
|
|
3262
|
+
declare const SPINE_SUGGESTION_WAITING: readonly ["solicitante", "responsaveis"];
|
|
3263
|
+
type SpineSuggestionWaiting = (typeof SPINE_SUGGESTION_WAITING)[number];
|
|
3264
|
+
/** Cor do selo "Aguardando…": a vez de quem pede chama atenção; a da equipe, não. */
|
|
3265
|
+
declare const SPINE_SUGGESTION_WAITING_COLORS: Record<SpineSuggestionWaiting, TagColor>;
|
|
3266
|
+
declare const SPINE_SUGGESTION_VISIBLE_SORTS: readonly ["activity", "recent", "votes"];
|
|
3267
|
+
type SpineSuggestionVisibleSort = (typeof SPINE_SUGGESTION_VISIBLE_SORTS)[number];
|
|
3268
|
+
/** A tela de uma sugestão: a do menu (`router_id`, rota e o caminho legível) ou uma nova (`new`, o nome no `label`). */
|
|
3269
|
+
interface SpineSuggestionScreen {
|
|
3270
|
+
path: string | null;
|
|
3271
|
+
label: string | null;
|
|
3272
|
+
router_id?: string | null;
|
|
3273
|
+
new?: boolean;
|
|
3274
|
+
}
|
|
3275
|
+
/**
|
|
3276
|
+
* Uma sugestão que a pessoa VÊ (`/me/suggestions/visible` e o detalhe): as dela, as do grupo dela e as em que ela está
|
|
3277
|
+
* envolvida, com os motivos (`reasons`), se ela pode conversar (`can_comment`, quem tem motivo pessoal) e com quem está
|
|
3278
|
+
* a vez (`waiting_on`).
|
|
3279
|
+
*/
|
|
3280
|
+
interface SpineVisibleSuggestion {
|
|
3281
|
+
id: string;
|
|
3282
|
+
key: string;
|
|
3283
|
+
kind: SpineSuggestionKind;
|
|
3284
|
+
title: string;
|
|
3285
|
+
description: string;
|
|
3286
|
+
/** A descrição em rich text (saneada pelo servidor); vazia sem descrição. */
|
|
3287
|
+
description_html?: string;
|
|
3288
|
+
screen: SpineSuggestionScreen;
|
|
3289
|
+
status: SpineSuggestionStatus;
|
|
3290
|
+
status_at?: string;
|
|
3291
|
+
votes: number;
|
|
3292
|
+
voted: boolean;
|
|
3293
|
+
mine: boolean;
|
|
3294
|
+
reasons: SpineSuggestionReason[];
|
|
3295
|
+
can_comment: boolean;
|
|
3296
|
+
waiting_on: SpineSuggestionWaiting | null;
|
|
3297
|
+
waiting_since: string | null;
|
|
3298
|
+
comments_count: number;
|
|
3299
|
+
last_comment: {
|
|
3300
|
+
comment: string;
|
|
3301
|
+
created_at: string;
|
|
3302
|
+
} | null;
|
|
3303
|
+
/** Mensagens de outras pessoas que quem consulta ainda não leu. */
|
|
3304
|
+
unread: number;
|
|
3305
|
+
archived: boolean;
|
|
3306
|
+
merged_from: Array<{
|
|
3307
|
+
id: string;
|
|
3308
|
+
key: string;
|
|
3309
|
+
title: string;
|
|
3310
|
+
}>;
|
|
3311
|
+
groups: Array<{
|
|
3312
|
+
id: string;
|
|
3313
|
+
name: string;
|
|
3314
|
+
}>;
|
|
3315
|
+
author: SpineSuggestionPerson | null;
|
|
3316
|
+
assignees: SpineSuggestionPerson[];
|
|
3317
|
+
created_at: string;
|
|
3318
|
+
updated_at: string;
|
|
3319
|
+
last_activity_at?: string;
|
|
3320
|
+
}
|
|
3321
|
+
/** Contagens do conjunto visível inteiro (sem os filtros), para os filtros rápidos da página. */
|
|
3322
|
+
type SpineVisibleCounts = Record<SpineSuggestionReason, number> & {
|
|
3323
|
+
waiting_me: number;
|
|
3324
|
+
unread: number;
|
|
3325
|
+
};
|
|
3326
|
+
interface SpineVisibleQuery {
|
|
3327
|
+
limit: number;
|
|
3328
|
+
offset: number;
|
|
3329
|
+
reason?: SpineSuggestionReason | '';
|
|
3330
|
+
status?: SpineSuggestionStatus | '';
|
|
3331
|
+
kind?: SpineSuggestionKind | '';
|
|
3332
|
+
waiting?: SpineSuggestionWaiting | '';
|
|
3333
|
+
screen?: string;
|
|
3334
|
+
newScreen?: boolean;
|
|
3335
|
+
q?: string;
|
|
3336
|
+
sort?: SpineSuggestionVisibleSort;
|
|
3337
|
+
}
|
|
3338
|
+
/** Mensagem da conversa (comentário público): `from_requester` = escrita por quem pediu ou um envolvido. */
|
|
3339
|
+
interface SpineSuggestionMessage extends SpineSuggestionComment {
|
|
3340
|
+
from_requester?: boolean;
|
|
3341
|
+
}
|
|
2913
3342
|
/**
|
|
2914
3343
|
* Sugestões de melhoria da pessoa — `argos-admin /me/suggestions`. Sempre da aplicação LOGADA (o servidor tira o client
|
|
2915
3344
|
* do access-token da sessão) e com o token da sessão (o servidor recusa x-app-token). Sem `SPINE_ADMIN_API` não há
|
|
2916
3345
|
* para onde mandar: o botão da barra da página nem aparece (`SpineSuggestButtonComponent`).
|
|
2917
3346
|
*/
|
|
3347
|
+
/** Uma sugestão acompanhada com novidade (`/me/suggestions/updates`): a central de notificações. */
|
|
3348
|
+
interface SpineSuggestionUpdate {
|
|
3349
|
+
id: string;
|
|
3350
|
+
key: string;
|
|
3351
|
+
title: string;
|
|
3352
|
+
status: SpineSuggestionStatus;
|
|
3353
|
+
/** Quantas novidades desde a última leitura (comentários públicos e mudanças de status de outras pessoas). */
|
|
3354
|
+
count: number;
|
|
3355
|
+
/** A mais recente: o comentário (até 200) ou o status novo, e quem fez. */
|
|
3356
|
+
last: {
|
|
3357
|
+
kind: 'comment' | 'status';
|
|
3358
|
+
status: SpineSuggestionStatus | null;
|
|
3359
|
+
comment: string | null;
|
|
3360
|
+
at: string;
|
|
3361
|
+
author: SpineSuggestionPerson | null;
|
|
3362
|
+
};
|
|
3363
|
+
}
|
|
2918
3364
|
declare class SpineSuggestionsService {
|
|
2919
3365
|
private readonly http;
|
|
2920
3366
|
private readonly auth;
|
|
@@ -2935,14 +3381,36 @@ declare class SpineSuggestionsService {
|
|
|
2935
3381
|
suggestions: SpineAppSuggestion[];
|
|
2936
3382
|
total: number;
|
|
2937
3383
|
}>;
|
|
2938
|
-
/** Os comentários públicos de uma sugestão (
|
|
3384
|
+
/** Os comentários públicos de uma sugestão (a conversa), do mais novo. */
|
|
2939
3385
|
comments(id: string, page: {
|
|
2940
3386
|
limit: number;
|
|
2941
3387
|
offset: number;
|
|
2942
3388
|
}): Promise<{
|
|
2943
|
-
comments:
|
|
3389
|
+
comments: SpineSuggestionMessage[];
|
|
3390
|
+
total: number;
|
|
3391
|
+
}>;
|
|
3392
|
+
/**
|
|
3393
|
+
* As que a pessoa vê (página "Sugestões do app"): as dela, as agrupadas, as em que está envolvida e as do grupo dela,
|
|
3394
|
+
* com filtros e paginação no servidor; `counts` é do conjunto inteiro (os números dos filtros rápidos).
|
|
3395
|
+
*/
|
|
3396
|
+
visible(query: SpineVisibleQuery): Promise<{
|
|
3397
|
+
suggestions: SpineVisibleSuggestion[];
|
|
2944
3398
|
total: number;
|
|
3399
|
+
counts: SpineVisibleCounts | null;
|
|
2945
3400
|
}>;
|
|
3401
|
+
/** Uma que a pessoa vê, pelo id (404 se não vê). */
|
|
3402
|
+
get(id: string): Promise<SpineVisibleSuggestion>;
|
|
3403
|
+
/** Pela chave ("SUG-12"): o link "?sugestao=SUG-12" abre a sugestão na página. */
|
|
3404
|
+
lookup(key: string): Promise<SpineVisibleSuggestion>;
|
|
3405
|
+
/** Escreve na conversa (quem pediu ou um envolvido): a vez passa para os responsáveis. */
|
|
3406
|
+
reply(id: string, comment: string): Promise<SpineSuggestionMessage>;
|
|
3407
|
+
/** As que a pessoa acompanha com novidade, a mais recente primeiro; `total` = quantas têm novidade. */
|
|
3408
|
+
updates(limit?: number): Promise<{
|
|
3409
|
+
updates: SpineSuggestionUpdate[];
|
|
3410
|
+
total: number;
|
|
3411
|
+
}>;
|
|
3412
|
+
/** Marca a conversa como lida por quem consulta (zera o `unread`). */
|
|
3413
|
+
markRead(id: string): Promise<void>;
|
|
2946
3414
|
/** As ainda abertas da tela, de qualquer pessoa: o modal oferece apoiar em vez de repetir. */
|
|
2947
3415
|
byScreen(path: string): Promise<SpineSuggestion[]>;
|
|
2948
3416
|
vote(id: string): Promise<void>;
|
|
@@ -2951,6 +3419,664 @@ declare class SpineSuggestionsService {
|
|
|
2951
3419
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<SpineSuggestionsService>;
|
|
2952
3420
|
}
|
|
2953
3421
|
|
|
3422
|
+
/**
|
|
3423
|
+
* A página "Sugestões do app" de quem pede: uma página do PRÓPRIO spine (ver `registerSpineBuiltinPage`), em todo app
|
|
3424
|
+
* com sugestões ligadas, sem cadastro de rota por client. Abre como qualquer tela do workspace (aba, painel, F5, link).
|
|
3425
|
+
*/
|
|
3426
|
+
declare const SPINE_SUGGESTIONS_PAGE_PATH = "/sugestoes";
|
|
3427
|
+
/** Chave sintética da página no distribuidor de telas (não é UUID: não colide com router do banco). */
|
|
3428
|
+
declare const SPINE_SUGGESTIONS_PAGE_ID = "spine:sugestoes";
|
|
3429
|
+
/** "?sugestao=SUG-12": abrir a página com ela abre a sugestão no painel (o mesmo parâmetro do quadro da equipe). */
|
|
3430
|
+
declare const SPINE_SUGGESTION_PAGE_PARAM = "sugestao";
|
|
3431
|
+
/** "&aba=conversa": junto com `sugestao`, abre a gaveta na Conversa (sem ele, em Detalhes). */
|
|
3432
|
+
declare const SPINE_SUGGESTION_TAB_PARAM = "aba";
|
|
3433
|
+
declare const SPINE_SUGGESTION_TAB_CONVERSATION = "conversa";
|
|
3434
|
+
/** Sugestões ligadas: o recurso não foi desligado (`SpineFeatures.suggestions`) e há para onde mandar (`SPINE_ADMIN_API`). */
|
|
3435
|
+
declare function spineSuggestionsEnabled(): boolean;
|
|
3436
|
+
/**
|
|
3437
|
+
* Registra a página no bootstrap (antes da primeira navegação: o F5 em /sugestoes passa pelo `ViewGuard`). Vai no
|
|
3438
|
+
* `provideShell`; com as sugestões desligadas, não registra nada e o endereço cai no fallback de sempre.
|
|
3439
|
+
*/
|
|
3440
|
+
declare function provideSpineSuggestionsPage(): EnvironmentProviders;
|
|
3441
|
+
|
|
3442
|
+
/** Uma tela que dá para escolher no "Sugerir melhoria": a rota, o `router_id` e o caminho legível ("Módulo › Tela"). */
|
|
3443
|
+
interface SuggestionScreenOption {
|
|
3444
|
+
path: string;
|
|
3445
|
+
routerId: string | null;
|
|
3446
|
+
/** O nome da tela (o último nível). */
|
|
3447
|
+
name: string;
|
|
3448
|
+
/** O caminho inteiro, como a barra da página mostra ("Vendas › Pedidos › Consulta"): é o que vai para o `screen.label`. */
|
|
3449
|
+
label: string;
|
|
3450
|
+
icon: string;
|
|
3451
|
+
}
|
|
3452
|
+
/** Valor da opção "Nova tela" no seletor (não é rota: nenhuma rota começa sem "/"). */
|
|
3453
|
+
declare const NEW_SCREEN_VALUE = "nova-tela";
|
|
3454
|
+
/**
|
|
3455
|
+
* As telas que a pessoa alcança, da árvore de rotas que ela já recebe (`spineRoutesOf(view)`), na ordem do menu: cada
|
|
3456
|
+
* nó com endereço e nome, com o caminho dos ancestrais com endereço (o mesmo "Módulo › … › Tela" da barra da página).
|
|
3457
|
+
* Um endereço aparece uma vez só (o primeiro). Nó com endereço e filhos (módulo que também é página) entra.
|
|
3458
|
+
*/
|
|
3459
|
+
declare function suggestionScreens(routes: readonly Route[] | null | undefined): SuggestionScreenOption[];
|
|
3460
|
+
/** O módulo (primeiro nível) de um caminho legível: "Vendas › Pedidos" → "Vendas". */
|
|
3461
|
+
declare function screenModule(label: string | null | undefined): string;
|
|
3462
|
+
/** O nome da tela (último nível) de um caminho legível: "Vendas › Pedidos › Consulta" → "Consulta". */
|
|
3463
|
+
declare function screenName(label: string | null | undefined): string;
|
|
3464
|
+
|
|
3465
|
+
/** De que lado da conversa a tela está: a de quem pede (página) ou a da equipe (detalhe da tarefa). */
|
|
3466
|
+
type SpineChatSide = 'solicitante' | 'equipe';
|
|
3467
|
+
/** Uma mensagem da conversa de uma sugestão, do jeito que o chat desenha (a página e o detalhe convertem para isto). */
|
|
3468
|
+
interface SpineChatMessage {
|
|
3469
|
+
id: string;
|
|
3470
|
+
text: string;
|
|
3471
|
+
created_at: string;
|
|
3472
|
+
author: SpineSuggestionPerson | null;
|
|
3473
|
+
/** Escrita como quem pede (pela página); `false` = como equipe (pelo detalhe da tarefa). */
|
|
3474
|
+
from_requester: boolean;
|
|
3475
|
+
/** Comentário interno da equipe (só aparece do lado da equipe). */
|
|
3476
|
+
internal?: boolean;
|
|
3477
|
+
/** A mudança de status que o comentário acompanha. */
|
|
3478
|
+
status?: SpineSuggestionStatus | null;
|
|
3479
|
+
}
|
|
3480
|
+
/** Uma linha do chat já resolvida: lado, cabeçalho, agrupamento e o divisor de dia antes dela. */
|
|
3481
|
+
interface ChatRow {
|
|
3482
|
+
message: SpineChatMessage;
|
|
3483
|
+
mine: boolean;
|
|
3484
|
+
author: string;
|
|
3485
|
+
grouped: boolean;
|
|
3486
|
+
day: string | null;
|
|
3487
|
+
}
|
|
3488
|
+
/**
|
|
3489
|
+
* A conversa de uma sugestão como chat (`hm-message-scroller` + `hm-message` + `hm-bubble`), com o campo de resposta
|
|
3490
|
+
* embaixo. Usado nos dois lados: a página de quem pede (`side="solicitante"`) e o detalhe da tarefa da equipe
|
|
3491
|
+
* (`side="equipe"`).
|
|
3492
|
+
*
|
|
3493
|
+
* **Quem fica à direita** é quem está com a tela aberta, no papel desta tela: a mensagem é da pessoa (`me`) E foi
|
|
3494
|
+
* escrita do mesmo lado (`from_requester` casa com `side`). A mesma pessoa no outro papel (quem administra e também
|
|
3495
|
+
* pediu, por exemplo) aparece à esquerda, como qualquer outro participante, com o papel no cabeçalho — a conversa
|
|
3496
|
+
* mostra de que lado cada mensagem foi escrita, não só quem a escreveu.
|
|
3497
|
+
*
|
|
3498
|
+
* - Mensagens do mais ANTIGO ao mais novo; o histórico mais antigo carrega pelo topo (`loadHistory`) sem tirar a
|
|
3499
|
+
* pessoa do lugar. Divisor de dia ("Hoje", "Ontem", a data) antes da primeira de cada dia.
|
|
3500
|
+
* - Mensagens seguidas da mesma pessoa, no mesmo papel e em poucos minutos se agrupam (sem repetir o cabeçalho).
|
|
3501
|
+
* - Comentário interno (só a equipe vê) em balão de destaque, com um cadeado pequeno no começo (sem selo embaixo: não
|
|
3502
|
+
* gasta uma linha); a mudança de status que o comentário acompanha, com o selo do status.
|
|
3503
|
+
* - O campo, numa linha só: Enter envia, Shift+Enter quebra a linha. Conteúdo extra do campo (o "Só para a equipe" do detalhe) entra
|
|
3504
|
+
* por projeção com o atributo `spineChatComposer`. Sem `canWrite`, no lugar do campo vai o conteúdo projetado com
|
|
3505
|
+
* `spineChatReadOnly`.
|
|
3506
|
+
*/
|
|
3507
|
+
declare class SpineSuggestionChatComponent {
|
|
3508
|
+
private readonly messages;
|
|
3509
|
+
protected readonly text: {
|
|
3510
|
+
button: string;
|
|
3511
|
+
buttonHint: string;
|
|
3512
|
+
modalTitle: string;
|
|
3513
|
+
intro: string;
|
|
3514
|
+
kind: string;
|
|
3515
|
+
kinds: Record<"melhoria" | "nova_funcionalidade" | "problema" | "outro", string>;
|
|
3516
|
+
statuses: Record<"em_analise" | "planejada" | "em_desenvolvimento" | "concluida" | "recusada", string>;
|
|
3517
|
+
legacyStatuses: Record<"nova", string>;
|
|
3518
|
+
title: string;
|
|
3519
|
+
titlePlaceholder: string;
|
|
3520
|
+
titleRequired: string;
|
|
3521
|
+
description: string;
|
|
3522
|
+
descriptionHint: string;
|
|
3523
|
+
screen: string;
|
|
3524
|
+
screenHint: string;
|
|
3525
|
+
send: string;
|
|
3526
|
+
cancel: string;
|
|
3527
|
+
sent: string;
|
|
3528
|
+
sendError: string;
|
|
3529
|
+
similarHeading: string;
|
|
3530
|
+
similarHint: string;
|
|
3531
|
+
vote: string;
|
|
3532
|
+
voted: string;
|
|
3533
|
+
votes: _trismegisto_primitives.PluralMessage;
|
|
3534
|
+
voteError: string;
|
|
3535
|
+
yours: string;
|
|
3536
|
+
mine: string;
|
|
3537
|
+
mineEmpty: string;
|
|
3538
|
+
mineError: string;
|
|
3539
|
+
loadMore: string;
|
|
3540
|
+
statusFilter: string;
|
|
3541
|
+
allStatuses: string;
|
|
3542
|
+
adminReply: string;
|
|
3543
|
+
sentAt: string;
|
|
3544
|
+
boardLabel: string;
|
|
3545
|
+
search: string;
|
|
3546
|
+
kindFilter: string;
|
|
3547
|
+
allKinds: string;
|
|
3548
|
+
refresh: string;
|
|
3549
|
+
boardFiltered: string;
|
|
3550
|
+
loadError: string;
|
|
3551
|
+
moveError: string;
|
|
3552
|
+
removedAuthor: string;
|
|
3553
|
+
noScreen: string;
|
|
3554
|
+
noDescription: string;
|
|
3555
|
+
requestedBy: string;
|
|
3556
|
+
requestedAt: string;
|
|
3557
|
+
status: string;
|
|
3558
|
+
statusSaved: string;
|
|
3559
|
+
statusError: string;
|
|
3560
|
+
history: string;
|
|
3561
|
+
historyEmpty: string;
|
|
3562
|
+
eventStatus: string;
|
|
3563
|
+
eventComment: string;
|
|
3564
|
+
someone: string;
|
|
3565
|
+
comment: string;
|
|
3566
|
+
commentHint: string;
|
|
3567
|
+
commentSend: string;
|
|
3568
|
+
commentSent: string;
|
|
3569
|
+
commentError: string;
|
|
3570
|
+
commentRequired: string;
|
|
3571
|
+
viewLabel: string;
|
|
3572
|
+
viewBoard: string;
|
|
3573
|
+
viewArchive: string;
|
|
3574
|
+
kpis: string;
|
|
3575
|
+
kpiOpen: string;
|
|
3576
|
+
kpiStatusCount: string;
|
|
3577
|
+
kpiDone: string;
|
|
3578
|
+
kpiDoneToday: string;
|
|
3579
|
+
kpiDoneNoneToday: string;
|
|
3580
|
+
kpiOverdueTrend: string;
|
|
3581
|
+
kpiOverdueSteady: string;
|
|
3582
|
+
kpiSoon: string;
|
|
3583
|
+
kpiMineHint: string;
|
|
3584
|
+
kpiPriority: string;
|
|
3585
|
+
kpiPriorityNone: string;
|
|
3586
|
+
kpiPriorityPart: string;
|
|
3587
|
+
filters: string;
|
|
3588
|
+
moreFilters: string;
|
|
3589
|
+
moreFiltersActive: string;
|
|
3590
|
+
allBoardStatuses: string;
|
|
3591
|
+
newTaskIn: string;
|
|
3592
|
+
newTaskOptions: string;
|
|
3593
|
+
columnOldest: string;
|
|
3594
|
+
columnOverdue: _trismegisto_primitives.PluralMessage;
|
|
3595
|
+
columnEmpty: string;
|
|
3596
|
+
columnEmptyFiltered: string;
|
|
3597
|
+
columnEmptyHints: Record<"em_analise" | "planejada" | "em_desenvolvimento" | "concluida", string>;
|
|
3598
|
+
duration: Record<"days" | "hours" | "minutes", string>;
|
|
3599
|
+
createdOn: string;
|
|
3600
|
+
dueWithin: string;
|
|
3601
|
+
dueLateDays: _trismegisto_primitives.PluralMessage;
|
|
3602
|
+
screenFilter: string;
|
|
3603
|
+
allScreens: string;
|
|
3604
|
+
authorFilter: string;
|
|
3605
|
+
allAuthors: string;
|
|
3606
|
+
sort: string;
|
|
3607
|
+
sorts: Record<"position" | "votes" | "recent", string>;
|
|
3608
|
+
sortHint: string;
|
|
3609
|
+
clearFilters: string;
|
|
3610
|
+
topVoted: string;
|
|
3611
|
+
comments: _trismegisto_primitives.PluralMessage;
|
|
3612
|
+
statusSince: string;
|
|
3613
|
+
openScreen: string;
|
|
3614
|
+
statusChange: string;
|
|
3615
|
+
statusComment: string;
|
|
3616
|
+
statusCommentHint: string;
|
|
3617
|
+
statusApply: string;
|
|
3618
|
+
archiveLabel: string;
|
|
3619
|
+
archiveSearch: string;
|
|
3620
|
+
archiveEmpty: string;
|
|
3621
|
+
archiveEmptyHint: string;
|
|
3622
|
+
archiveCount: _trismegisto_primitives.PluralMessage;
|
|
3623
|
+
closedOn: Record<"concluida" | "recusada", string>;
|
|
3624
|
+
pagination: string;
|
|
3625
|
+
reopen: string;
|
|
3626
|
+
reopened: string;
|
|
3627
|
+
reopenError: string;
|
|
3628
|
+
newTask: string;
|
|
3629
|
+
addTaskPlaceholder: string;
|
|
3630
|
+
taskCreated: string;
|
|
3631
|
+
createError: string;
|
|
3632
|
+
saveError: string;
|
|
3633
|
+
kpiMine: string;
|
|
3634
|
+
kpiOverdue: string;
|
|
3635
|
+
assigneeFilter: string;
|
|
3636
|
+
allAssignees: string;
|
|
3637
|
+
assigneeMine: string;
|
|
3638
|
+
assigneeNone: string;
|
|
3639
|
+
labelFilter: string;
|
|
3640
|
+
allLabels: string;
|
|
3641
|
+
priorityFilter: string;
|
|
3642
|
+
allPriorities: string;
|
|
3643
|
+
dueFilter: string;
|
|
3644
|
+
dueAny: string;
|
|
3645
|
+
dueOverdueFilter: string;
|
|
3646
|
+
dueSoonFilter: string;
|
|
3647
|
+
priority: string;
|
|
3648
|
+
priorities: Record<"urgente" | "alta" | "media" | "baixa", string>;
|
|
3649
|
+
dueOn: string;
|
|
3650
|
+
dueToday: string;
|
|
3651
|
+
dueTomorrow: string;
|
|
3652
|
+
dueLate: string;
|
|
3653
|
+
checklistSpoken: string;
|
|
3654
|
+
moreAssignees: string;
|
|
3655
|
+
cardMenu: string;
|
|
3656
|
+
menuStatus: string;
|
|
3657
|
+
menuAssignMe: string;
|
|
3658
|
+
menuCopyLink: string;
|
|
3659
|
+
menuCopyKey: string;
|
|
3660
|
+
menuLabel: string;
|
|
3661
|
+
menuNoLabels: string;
|
|
3662
|
+
menuPriority: string;
|
|
3663
|
+
menuArchive: string;
|
|
3664
|
+
menuRestore: string;
|
|
3665
|
+
menuDelete: string;
|
|
3666
|
+
labelColorName: string;
|
|
3667
|
+
linkCopied: string;
|
|
3668
|
+
keyCopied: string;
|
|
3669
|
+
copyError: string;
|
|
3670
|
+
deleteHeading: string;
|
|
3671
|
+
deleteMessage: string;
|
|
3672
|
+
deleteConfirm: string;
|
|
3673
|
+
deleted: string;
|
|
3674
|
+
archivedToast: string;
|
|
3675
|
+
restoredToast: string;
|
|
3676
|
+
assignedToMe: string;
|
|
3677
|
+
archivedTag: string;
|
|
3678
|
+
taskLabel: string;
|
|
3679
|
+
close: string;
|
|
3680
|
+
editTitle: string;
|
|
3681
|
+
editDescription: string;
|
|
3682
|
+
save: string;
|
|
3683
|
+
checklist: string;
|
|
3684
|
+
checklistAdd: string;
|
|
3685
|
+
checklistPlaceholder: string;
|
|
3686
|
+
checklistOnCard: string;
|
|
3687
|
+
checklistEmpty: string;
|
|
3688
|
+
checklistRemove: string;
|
|
3689
|
+
checklistUp: string;
|
|
3690
|
+
checklistDown: string;
|
|
3691
|
+
tabComments: string;
|
|
3692
|
+
tabActivity: string;
|
|
3693
|
+
commentsEmpty: string;
|
|
3694
|
+
activityEmpty: string;
|
|
3695
|
+
commentInternal: string;
|
|
3696
|
+
internalTag: string;
|
|
3697
|
+
activity: Record<"created" | "title" | "description" | "kind" | "priority" | "start_date" | "start_date_removed" | "due_date" | "due_date_removed" | "cover" | "cover_removed" | "checklist_on_card" | "screen" | "assignee_added" | "assignee_removed" | "watcher_added" | "watcher_removed" | "label_added" | "label_removed" | "checklist_added" | "checklist_done" | "checklist_undone" | "checklist_renamed" | "checklist_removed" | "archived" | "restored" | "merged" | "merged_here" | "unmerged" | "unmerged_here" | "other", string>;
|
|
3698
|
+
assignees: string;
|
|
3699
|
+
assignMe: string;
|
|
3700
|
+
addAssignee: string;
|
|
3701
|
+
watchers: string;
|
|
3702
|
+
addWatcher: string;
|
|
3703
|
+
removePerson: string;
|
|
3704
|
+
peopleSearch: string;
|
|
3705
|
+
peopleEmpty: string;
|
|
3706
|
+
nobody: string;
|
|
3707
|
+
reporter: string;
|
|
3708
|
+
originUser: string;
|
|
3709
|
+
originTeam: string;
|
|
3710
|
+
startDate: string;
|
|
3711
|
+
dueDate: string;
|
|
3712
|
+
labels: string;
|
|
3713
|
+
addLabel: string;
|
|
3714
|
+
createLabel: string;
|
|
3715
|
+
labelColor: string;
|
|
3716
|
+
noLabels: string;
|
|
3717
|
+
screenOrigin: string;
|
|
3718
|
+
votesField: string;
|
|
3719
|
+
createdAt: string;
|
|
3720
|
+
updatedAt: string;
|
|
3721
|
+
lastChange: string;
|
|
3722
|
+
lastChangeNoActor: string;
|
|
3723
|
+
key: string;
|
|
3724
|
+
copyKey: string;
|
|
3725
|
+
newTaskHeading: string;
|
|
3726
|
+
createTask: string;
|
|
3727
|
+
draftHint: string;
|
|
3728
|
+
assignMeOnCreate: string;
|
|
3729
|
+
appSuggestions: string;
|
|
3730
|
+
listView: string;
|
|
3731
|
+
tabAll: string;
|
|
3732
|
+
tabMine: string;
|
|
3733
|
+
appSearch: string;
|
|
3734
|
+
thisScreen: string;
|
|
3735
|
+
appSorts: Record<"votes" | "recent", string>;
|
|
3736
|
+
appEmpty: string;
|
|
3737
|
+
appEmptyHint: string;
|
|
3738
|
+
appEmptyFiltered: string;
|
|
3739
|
+
appError: string;
|
|
3740
|
+
support: string;
|
|
3741
|
+
supported: string;
|
|
3742
|
+
ownSupportHint: string;
|
|
3743
|
+
publicComments: string;
|
|
3744
|
+
publicCommentsEmpty: string;
|
|
3745
|
+
commentsError: string;
|
|
3746
|
+
moreComments: string;
|
|
3747
|
+
appPagination: string;
|
|
3748
|
+
menuMerge: string;
|
|
3749
|
+
mergeHeading: string;
|
|
3750
|
+
mergeIntro: string;
|
|
3751
|
+
mergeSearch: string;
|
|
3752
|
+
mergeNone: string;
|
|
3753
|
+
mergeHasMerged: string;
|
|
3754
|
+
mergePreview: string;
|
|
3755
|
+
mergeCalculating: string;
|
|
3756
|
+
mergePreviewError: string;
|
|
3757
|
+
reportersCount: _trismegisto_primitives.PluralMessage;
|
|
3758
|
+
mergeConfirmHeading: string;
|
|
3759
|
+
mergeConfirmMessage: string;
|
|
3760
|
+
mergeConfirm: string;
|
|
3761
|
+
mergedToast: string;
|
|
3762
|
+
mergeError: string;
|
|
3763
|
+
mergedTag: string;
|
|
3764
|
+
mergedInto: string;
|
|
3765
|
+
mergedIntoHint: string;
|
|
3766
|
+
openMerged: string;
|
|
3767
|
+
unmerge: string;
|
|
3768
|
+
unmergeLabel: string;
|
|
3769
|
+
unmergedToast: string;
|
|
3770
|
+
reporters: string;
|
|
3771
|
+
reporterAuthor: string;
|
|
3772
|
+
reporterVia: string;
|
|
3773
|
+
mergedHere: string;
|
|
3774
|
+
mergedFrom: string;
|
|
3775
|
+
mergedFromHint: string;
|
|
3776
|
+
buttonMenu: string;
|
|
3777
|
+
openPage: string;
|
|
3778
|
+
screenPick: string;
|
|
3779
|
+
screenPickHint: string;
|
|
3780
|
+
screenPickPlaceholder: string;
|
|
3781
|
+
newScreenOption: string;
|
|
3782
|
+
newScreenName: string;
|
|
3783
|
+
newScreenHint: string;
|
|
3784
|
+
newScreenRequired: string;
|
|
3785
|
+
newScreenTag: string;
|
|
3786
|
+
waiting: Record<"solicitante" | "responsaveis", string>;
|
|
3787
|
+
waitingFilter: string;
|
|
3788
|
+
waitingAny: string;
|
|
3789
|
+
waitingClear: string;
|
|
3790
|
+
waitingSaved: string;
|
|
3791
|
+
menuWaiting: string;
|
|
3792
|
+
groupFilter: string;
|
|
3793
|
+
allGroups: string;
|
|
3794
|
+
requestingGroups: string;
|
|
3795
|
+
noGroups: string;
|
|
3796
|
+
unread: _trismegisto_primitives.PluralMessage;
|
|
3797
|
+
fromRequester: string;
|
|
3798
|
+
cardChecklist: _trismegisto_primitives.PluralMessage;
|
|
3799
|
+
requestedByName: string;
|
|
3800
|
+
tabSummary: string;
|
|
3801
|
+
chatAuthor: string;
|
|
3802
|
+
chatSendHint: string;
|
|
3803
|
+
inbox: {
|
|
3804
|
+
label: string;
|
|
3805
|
+
comment: string;
|
|
3806
|
+
status: string;
|
|
3807
|
+
};
|
|
3808
|
+
page: {
|
|
3809
|
+
title: string;
|
|
3810
|
+
description: string;
|
|
3811
|
+
allTitle: string;
|
|
3812
|
+
statusPart: string;
|
|
3813
|
+
reasons: Record<"autor" | "relator" | "envolvido" | "responsavel" | "grupo", string>;
|
|
3814
|
+
reasonHints: Record<"autor" | "relator" | "envolvido" | "responsavel" | "grupo", string>;
|
|
3815
|
+
reasonFilter: string;
|
|
3816
|
+
allReasons: string;
|
|
3817
|
+
needsYou: string;
|
|
3818
|
+
sorts: Record<"activity" | "recent" | "votes", string>;
|
|
3819
|
+
empty: string;
|
|
3820
|
+
emptyHint: string;
|
|
3821
|
+
emptyFiltered: string;
|
|
3822
|
+
error: string;
|
|
3823
|
+
count: _trismegisto_primitives.PluralMessage;
|
|
3824
|
+
pickOne: string;
|
|
3825
|
+
notFound: string;
|
|
3826
|
+
conversation: string;
|
|
3827
|
+
conversationEmpty: string;
|
|
3828
|
+
conversationError: string;
|
|
3829
|
+
olderMessages: string;
|
|
3830
|
+
reply: string;
|
|
3831
|
+
replyPlaceholder: string;
|
|
3832
|
+
replySend: string;
|
|
3833
|
+
replyError: string;
|
|
3834
|
+
readOnly: string;
|
|
3835
|
+
team: string;
|
|
3836
|
+
you: string;
|
|
3837
|
+
groups: string;
|
|
3838
|
+
details: string;
|
|
3839
|
+
listLabel: string;
|
|
3840
|
+
filtersLabel: string;
|
|
3841
|
+
waitingYou: string;
|
|
3842
|
+
waitingTeam: string;
|
|
3843
|
+
};
|
|
3844
|
+
planning: {
|
|
3845
|
+
viewSummary: string;
|
|
3846
|
+
viewTasks: string;
|
|
3847
|
+
viewPlanning: string;
|
|
3848
|
+
viewSchedule: string;
|
|
3849
|
+
viewRisks: string;
|
|
3850
|
+
viewWorkflow: string;
|
|
3851
|
+
loadError: string;
|
|
3852
|
+
saveError: string;
|
|
3853
|
+
retry: string;
|
|
3854
|
+
save: string;
|
|
3855
|
+
cancel: string;
|
|
3856
|
+
delete: string;
|
|
3857
|
+
edit: string;
|
|
3858
|
+
points: string;
|
|
3859
|
+
pointsValue: _trismegisto_primitives.PluralMessage;
|
|
3860
|
+
noEstimate: string;
|
|
3861
|
+
backlog: string;
|
|
3862
|
+
noSprint: string;
|
|
3863
|
+
unassigned: string;
|
|
3864
|
+
dateRange: string;
|
|
3865
|
+
summary: {
|
|
3866
|
+
activeSprint: string;
|
|
3867
|
+
sprintPoints: string;
|
|
3868
|
+
sprintCapacity: string;
|
|
3869
|
+
openTasks: string;
|
|
3870
|
+
overdue: string;
|
|
3871
|
+
mine: string;
|
|
3872
|
+
mineEmpty: string;
|
|
3873
|
+
deadlines: string;
|
|
3874
|
+
deadlinesEmpty: string;
|
|
3875
|
+
topRisks: string;
|
|
3876
|
+
topRisksEmpty: string;
|
|
3877
|
+
riskScore: string;
|
|
3878
|
+
nextMilestone: string;
|
|
3879
|
+
nextMilestoneEmpty: string;
|
|
3880
|
+
};
|
|
3881
|
+
tasks: {
|
|
3882
|
+
viewLabel: string;
|
|
3883
|
+
viewList: string;
|
|
3884
|
+
viewTable: string;
|
|
3885
|
+
listLabel: string;
|
|
3886
|
+
gridCaption: string;
|
|
3887
|
+
count: _trismegisto_primitives.PluralMessage;
|
|
3888
|
+
open: string;
|
|
3889
|
+
emptyHeading: string;
|
|
3890
|
+
emptyBody: string;
|
|
3891
|
+
key: string;
|
|
3892
|
+
title: string;
|
|
3893
|
+
status: string;
|
|
3894
|
+
priority: string;
|
|
3895
|
+
assignee: string;
|
|
3896
|
+
sprint: string;
|
|
3897
|
+
due: string;
|
|
3898
|
+
};
|
|
3899
|
+
sprints: {
|
|
3900
|
+
heading: string;
|
|
3901
|
+
hint: string;
|
|
3902
|
+
readOnlyClosed: string;
|
|
3903
|
+
new: string;
|
|
3904
|
+
start: string;
|
|
3905
|
+
close: string;
|
|
3906
|
+
state: Record<"planned" | "active" | "closed", string>;
|
|
3907
|
+
closeHeading: string;
|
|
3908
|
+
closeMessage: string;
|
|
3909
|
+
deleteHeading: string;
|
|
3910
|
+
deleteMessage: string;
|
|
3911
|
+
newHeading: string;
|
|
3912
|
+
editHeading: string;
|
|
3913
|
+
name: string;
|
|
3914
|
+
nameRequired: string;
|
|
3915
|
+
goal: string;
|
|
3916
|
+
start_date: string;
|
|
3917
|
+
end_date: string;
|
|
3918
|
+
datesRequired: string;
|
|
3919
|
+
datesOrder: string;
|
|
3920
|
+
capacity: string;
|
|
3921
|
+
activeExists: string;
|
|
3922
|
+
moved: string;
|
|
3923
|
+
progressHeading: string;
|
|
3924
|
+
done: string;
|
|
3925
|
+
committed: string;
|
|
3926
|
+
capacityUse: string;
|
|
3927
|
+
burndownCaption: string;
|
|
3928
|
+
day: string;
|
|
3929
|
+
ideal: string;
|
|
3930
|
+
remaining: string;
|
|
3931
|
+
closed: string;
|
|
3932
|
+
};
|
|
3933
|
+
schedule: {
|
|
3934
|
+
heading: string;
|
|
3935
|
+
label: string;
|
|
3936
|
+
hint: string;
|
|
3937
|
+
milestones: string;
|
|
3938
|
+
newMilestone: string;
|
|
3939
|
+
milestoneTitle: string;
|
|
3940
|
+
milestoneDate: string;
|
|
3941
|
+
milestoneRequired: string;
|
|
3942
|
+
removeMilestone: string;
|
|
3943
|
+
rescheduled: string;
|
|
3944
|
+
conflicts: string;
|
|
3945
|
+
workloadHeading: string;
|
|
3946
|
+
workloadLabel: string;
|
|
3947
|
+
workloadHint: string;
|
|
3948
|
+
week: string;
|
|
3949
|
+
noPeople: string;
|
|
3950
|
+
};
|
|
3951
|
+
risks: {
|
|
3952
|
+
heading: string;
|
|
3953
|
+
label: string;
|
|
3954
|
+
hint: string;
|
|
3955
|
+
new: string;
|
|
3956
|
+
newHeading: string;
|
|
3957
|
+
editHeading: string;
|
|
3958
|
+
title: string;
|
|
3959
|
+
titleRequired: string;
|
|
3960
|
+
owner: string;
|
|
3961
|
+
status: string;
|
|
3962
|
+
mitigation: string;
|
|
3963
|
+
deleteHeading: string;
|
|
3964
|
+
statuses: Record<"identified" | "mitigating" | "closed", string>;
|
|
3965
|
+
task: string;
|
|
3966
|
+
taskPlaceholder: string;
|
|
3967
|
+
taskRequired: string;
|
|
3968
|
+
noTask: string;
|
|
3969
|
+
level: string;
|
|
3970
|
+
levels: Record<"low" | "medium" | "high" | "critical", string>;
|
|
3971
|
+
ofTask: string;
|
|
3972
|
+
add: string;
|
|
3973
|
+
empty: string;
|
|
3974
|
+
};
|
|
3975
|
+
workflow: {
|
|
3976
|
+
heading: string;
|
|
3977
|
+
hint: string;
|
|
3978
|
+
label: string;
|
|
3979
|
+
count: _trismegisto_primitives.PluralMessage;
|
|
3980
|
+
plan: string;
|
|
3981
|
+
start: string;
|
|
3982
|
+
finish: string;
|
|
3983
|
+
refuse: string;
|
|
3984
|
+
reopen: string;
|
|
3985
|
+
};
|
|
3986
|
+
detail: {
|
|
3987
|
+
estimate: string;
|
|
3988
|
+
sprint: string;
|
|
3989
|
+
backlogOption: string;
|
|
3990
|
+
dependsOn: string;
|
|
3991
|
+
dependsOnPlaceholder: string;
|
|
3992
|
+
dependencyCycle: string;
|
|
3993
|
+
blockedBy: string;
|
|
3994
|
+
};
|
|
3995
|
+
};
|
|
3996
|
+
};
|
|
3997
|
+
private readonly preferences;
|
|
3998
|
+
private readonly scroller;
|
|
3999
|
+
/** As mensagens, do mais antigo ao mais novo. */
|
|
4000
|
+
readonly items: _angular_core.InputSignal<readonly SpineChatMessage[]>;
|
|
4001
|
+
/** O papel desta tela: as mensagens da pessoa escritas deste lado ficam à direita. */
|
|
4002
|
+
readonly side: _angular_core.InputSignal<SpineChatSide>;
|
|
4003
|
+
/** O `user_id` de quem está com a tela aberta. */
|
|
4004
|
+
readonly me: _angular_core.InputSignal<string>;
|
|
4005
|
+
readonly label: _angular_core.InputSignal<string>;
|
|
4006
|
+
readonly empty: _angular_core.InputSignal<string>;
|
|
4007
|
+
readonly hasMore: _angular_core.InputSignal<boolean>;
|
|
4008
|
+
readonly loading: _angular_core.InputSignal<boolean>;
|
|
4009
|
+
readonly canWrite: _angular_core.InputSignal<boolean>;
|
|
4010
|
+
readonly composerLabel: _angular_core.InputSignal<string>;
|
|
4011
|
+
readonly placeholder: _angular_core.InputSignal<string>;
|
|
4012
|
+
readonly sendLabel: _angular_core.InputSignal<string>;
|
|
4013
|
+
readonly sending: _angular_core.InputSignal<boolean>;
|
|
4014
|
+
readonly error: _angular_core.InputSignal<string>;
|
|
4015
|
+
/** O texto do campo (em mão dupla: quem usa limpa depois de enviar). */
|
|
4016
|
+
readonly draft: _angular_core.ModelSignal<string>;
|
|
4017
|
+
readonly loadHistory: _angular_core.OutputEmitterRef<void>;
|
|
4018
|
+
/** Enviar: o texto aparado (nunca vazio). */
|
|
4019
|
+
readonly send: _angular_core.OutputEmitterRef<string>;
|
|
4020
|
+
protected readonly statusColors: Record<"em_analise" | "planejada" | "em_desenvolvimento" | "concluida" | "recusada", _trismegisto_angular.TagColor>;
|
|
4021
|
+
protected readonly timeFormat: Intl.DateTimeFormatOptions;
|
|
4022
|
+
protected readonly rows: _angular_core.Signal<ChatRow[]>;
|
|
4023
|
+
/** Depois de enviar: a pessoa quer ver a própria mensagem, mesmo se estava lendo lá em cima. */
|
|
4024
|
+
scrollToEnd(): void;
|
|
4025
|
+
protected onKey(event: Event): void;
|
|
4026
|
+
protected submit(): void;
|
|
4027
|
+
protected statusOf(m: SpineChatMessage): SpineSuggestionStatus | null;
|
|
4028
|
+
/** "Ana Souza (Equipe)": do outro lado, o papel junto do nome — inclusive a própria pessoa no outro papel. */
|
|
4029
|
+
private authorText;
|
|
4030
|
+
private dayKey;
|
|
4031
|
+
/** "Hoje", "Ontem" ou a data por extenso (no idioma do catálogo e no fuso da pessoa). */
|
|
4032
|
+
private dayLabel;
|
|
4033
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SpineSuggestionChatComponent, never>;
|
|
4034
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SpineSuggestionChatComponent, "spine-suggestion-chat", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "side": { "alias": "side"; "required": true; "isSignal": true; }; "me": { "alias": "me"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "empty": { "alias": "empty"; "required": false; "isSignal": true; }; "hasMore": { "alias": "hasMore"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "canWrite": { "alias": "canWrite"; "required": false; "isSignal": true; }; "composerLabel": { "alias": "composerLabel"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "sendLabel": { "alias": "sendLabel"; "required": false; "isSignal": true; }; "sending": { "alias": "sending"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "draft": { "alias": "draft"; "required": false; "isSignal": true; }; }, { "draft": "draftChange"; "loadHistory": "loadHistory"; "send": "send"; }, never, ["[spineChatComposer]", "[spineChatReadOnly]"], true, never>;
|
|
4035
|
+
}
|
|
4036
|
+
|
|
4037
|
+
/** Um selo da linha: o nome e, se quiser, a cor (1..8, a paleta categórica do tema); sem cor, uma estável pelo id. */
|
|
4038
|
+
interface SpineTagRowItem {
|
|
4039
|
+
id: string;
|
|
4040
|
+
name: string;
|
|
4041
|
+
color?: number;
|
|
4042
|
+
}
|
|
4043
|
+
/** Cor categórica estável para um id (o mesmo grupo sempre na mesma cor, em qualquer tela). */
|
|
4044
|
+
declare function spineTagColor(id: string): number;
|
|
4045
|
+
/**
|
|
4046
|
+
* Selos numa linha só, no modelo dos rótulos do quadro (fundo claro da cor e o ponto na cor cheia): cabem os que cabem
|
|
4047
|
+
* na largura e o resto vira "+N", com os nomes na dica e para o leitor de tela. Mede de novo quando a largura muda
|
|
4048
|
+
* (ResizeObserver) e quando a lista muda; sem medida (servidor, teste sem layout), mostra todos.
|
|
4049
|
+
*
|
|
4050
|
+
* Os que não cabem continuam no DOM, fora do fluxo e invisíveis (`visibility: hidden`), só para a largura deles poder
|
|
4051
|
+
* ser medida; ficam `aria-hidden` — quem lê a tela ouve os nomes no "+N".
|
|
4052
|
+
*/
|
|
4053
|
+
declare class SpineTagRowComponent {
|
|
4054
|
+
private readonly text;
|
|
4055
|
+
private readonly host;
|
|
4056
|
+
private readonly browser;
|
|
4057
|
+
private readonly injector;
|
|
4058
|
+
private readonly destroyRef;
|
|
4059
|
+
readonly items: _angular_core.InputSignal<readonly SpineTagRowItem[]>;
|
|
4060
|
+
readonly label: _angular_core.InputSignal<string>;
|
|
4061
|
+
/** Texto quando não há nenhum (vazio = nada). */
|
|
4062
|
+
readonly empty: _angular_core.InputSignal<string>;
|
|
4063
|
+
protected readonly tags: _angular_core.Signal<{
|
|
4064
|
+
color: number;
|
|
4065
|
+
id: string;
|
|
4066
|
+
name: string;
|
|
4067
|
+
}[]>;
|
|
4068
|
+
/** Quantos cabem; começa com todos (sem medida, todos aparecem). */
|
|
4069
|
+
protected readonly visible: _angular_core.WritableSignal<number>;
|
|
4070
|
+
protected readonly hiddenCount: _angular_core.Signal<number>;
|
|
4071
|
+
protected readonly hiddenNames: _angular_core.Signal<string>;
|
|
4072
|
+
protected readonly moreText: _angular_core.Signal<string>;
|
|
4073
|
+
constructor();
|
|
4074
|
+
/** Quantos selos cabem na largura, reservando o "+N" quando nem todos cabem. */
|
|
4075
|
+
private measure;
|
|
4076
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SpineTagRowComponent, never>;
|
|
4077
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SpineTagRowComponent, "spine-tag-row", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "empty": { "alias": "empty"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
4078
|
+
}
|
|
4079
|
+
|
|
2954
4080
|
/**
|
|
2955
4081
|
* Modal de documentação das telas: índice (com busca) à esquerda e leitura à direita. Montado uma vez
|
|
2956
4082
|
* pelo `spine-layout`; abrir, fechar e o que se lê vêm todos do `SpineDocsService`.
|
|
@@ -2996,6 +4122,6 @@ declare const SPINE_MARKDOWN_PURIFY_CONFIG: Config;
|
|
|
2996
4122
|
/** HTML limpo pelo perfil do spine, ou `null` quando não há DOM (SSR: melhor não renderizar). */
|
|
2997
4123
|
declare function sanitizeSpineMarkdownHtml(html: string): string | null;
|
|
2998
4124
|
|
|
2999
|
-
export { AiAgentComponent, AppLauncherComponent, HeaderComponent, LayoutComponent, SPINE_BRAND, SPINE_GLOBAL_PREFERENCE_KEYS, SPINE_IDLE_WARNING_SECONDS, SPINE_MARKDOWN_PURIFY_CONFIG, SPINE_PREFERENCES_SAVE_DELAY_MS, SPINE_RATING_COMMENT_MAX, SPINE_RATING_SCORE_MAX, SPINE_SETTINGS_ALIASES, SPINE_SETTINGS_KEYS, SPINE_SETTINGS_SECTIONS, SPINE_SUGGESTION_KINDS, SPINE_SUGGESTION_KIND_COLORS, SPINE_SUGGESTION_KIND_ICONS, SPINE_SUGGESTION_LIMITS, SPINE_SUGGESTION_PUBLIC_SORTS, SPINE_SUGGESTION_PUBLIC_STATUSES, SPINE_SUGGESTION_STATUSES, SPINE_SUGGESTION_STATUS_COLORS, SPINE_SUGGESTION_STATUS_ICONS, SettingsPanelComponent, ShortcutService, ShortcutsCheatsheetComponent, SidebarComponent, SpineAccountPreferencesService, SpineAccountSecurityService, SpineAppTokensService, SpineBrandComponent, SpineConnectionBannerComponent, SpineDocsComponent, SpineDocsService, SpineIdleService, SpineIdleWarningComponent, SpineInitialSetupComponent, SpineInitialSetupService, SpineLogoutService, SpineMarkdownComponent, SpineMyGroupsService, SpineNewsComponent, SpineNewsService, SpineNoticesService, SpinePageActionsDirective, SpinePageActionsSlot, SpineRatingStarsComponent, SpineRatingsService, SpineSettingsService, SpineStartPageService, SpineSuggestionsService, accountErrorCode, argosAccountApi, buildMcpConfig, effectiveIdleMinutes, idleLimits, isInternalPath, provideSettingsSection, ratingTargetKey, resolveSettingsSection, sanitizeSpineMarkdownHtml, spineScoreBand, spineStarFills, stable };
|
|
3000
|
-
export type { AccountActivityEntry, AccountActivityPage, AccountBadges, AccountMethod, AccountOverview, AccountPreferences, AccountReauth, AccountSession, AppToken, AppTokenList, AppTokenOptions, CreatedAppToken, DocsEntry, DocsGroup, DocsView, GroupMember, GroupRole, ManagedGroup, RealmUser, ShortcutActions, SpineAccountPreferencesDoc, SpineAccountPreferencesStatus, SpineAppSuggestion, SpineAppSuggestionsQuery, SpineGlobalPreferencesDoc, SpineIdleLimits, SpineInitialSetupMode, SpineInitialSetupStep, SpineNewsAuthor, SpineNewsDetail, SpineNewsFilter, SpineNewsKind, SpineNewsPage, SpineNewsSummary, SpineNotice, SpineNoticePermission, SpineRating, SpineRatingAverage, SpineRatingScope, SpineRatingTarget, SpineScoreBand, SpineSettingsSection, SpineStarFill, SpineSuggestion, SpineSuggestionComment, SpineSuggestionDraft, SpineSuggestionKind, SpineSuggestionPerson, SpineSuggestionPublicSort, SpineSuggestionPublicStatus, SpineSuggestionStatus };
|
|
4125
|
+
export { AiAgentComponent, AppLauncherComponent, HeaderComponent, LayoutComponent, NEW_SCREEN_VALUE, SPINE_BRAND, SPINE_GLOBAL_PREFERENCE_KEYS, SPINE_IDLE_WARNING_SECONDS, SPINE_INBOX_POLL_MS, SPINE_INBOX_SOURCES, SPINE_MARKDOWN_PURIFY_CONFIG, SPINE_PREFERENCES_SAVE_DELAY_MS, SPINE_RATING_COMMENT_MAX, SPINE_RATING_SCORE_MAX, SPINE_SETTINGS_ALIASES, SPINE_SETTINGS_KEYS, SPINE_SETTINGS_SECTIONS, SPINE_SUGGESTIONS_PAGE_ID, SPINE_SUGGESTIONS_PAGE_PATH, SPINE_SUGGESTION_KINDS, SPINE_SUGGESTION_KIND_COLORS, SPINE_SUGGESTION_KIND_ICONS, SPINE_SUGGESTION_LIMITS, SPINE_SUGGESTION_PAGE_PARAM, SPINE_SUGGESTION_PUBLIC_SORTS, SPINE_SUGGESTION_PUBLIC_STATUSES, SPINE_SUGGESTION_REASONS, SPINE_SUGGESTION_STATUSES, SPINE_SUGGESTION_STATUS_COLORS, SPINE_SUGGESTION_STATUS_ICONS, SPINE_SUGGESTION_TAB_CONVERSATION, SPINE_SUGGESTION_TAB_PARAM, SPINE_SUGGESTION_VISIBLE_SORTS, SPINE_SUGGESTION_WAITING, SPINE_SUGGESTION_WAITING_COLORS, SPINE_TAB, SPINE_WORKSPACE_LIMITS, SettingsPanelComponent, ShortcutService, ShortcutsCheatsheetComponent, SidebarComponent, SpineAccountPreferencesService, SpineAccountSecurityService, SpineAppTokensService, SpineBrandComponent, SpineConnectionBannerComponent, SpineDocsComponent, SpineDocsService, SpineIdleService, SpineIdleWarningComponent, SpineInboxButtonComponent, SpineInboxService, SpineInitialSetupComponent, SpineInitialSetupService, SpineLogoutService, SpineMarkdownComponent, SpineMyGroupsService, SpineNewsComponent, SpineNewsService, SpineNoticesService, SpinePageActionsDirective, SpinePageActionsSlot, SpineRatingStarsComponent, SpineRatingsService, SpineSettingsService, SpineStartPageService, SpineSuggestionChatComponent, SpineSuggestionsService, SpineTagRowComponent, SpineUnsavedChangesService, SpineWorkspaceNavService, accountErrorCode, argosAccountApi, buildMcpConfig, effectiveIdleMinutes, idleLimits, isInternalPath, provideSettingsSection, provideSpineInboxSource, provideSpineSuggestionsPage, ratingTargetKey, registerSpineUnsavedChanges, resolveSettingsSection, sanitizeSpineMarkdownHtml, screenModule, screenName, spineNormalizeUrl, spineParamsOf, spinePathOf, spineScoreBand, spineStarFills, spineSuggestionsEnabled, spineTagColor, stable, suggestionScreens };
|
|
4126
|
+
export type { AccountActivityEntry, AccountActivityPage, AccountBadges, AccountMethod, AccountOverview, AccountPreferences, AccountReauth, AccountSession, AppToken, AppTokenList, AppTokenOptions, CreatedAppToken, DocsEntry, DocsGroup, DocsView, GroupMember, GroupMembersPage, GroupMembersQuery, GroupRole, ManagedGroup, RealmUser, ShortcutActions, SpineAccountPreferencesDoc, SpineAccountPreferencesStatus, SpineAppSuggestion, SpineAppSuggestionsQuery, SpineChatMessage, SpineChatSide, SpineGlobalPreferencesDoc, SpineIdleLimits, SpineInboxEntry, SpineInboxItem, SpineInboxSource, SpineInitialSetupMode, SpineInitialSetupStep, SpineNewsAuthor, SpineNewsDetail, SpineNewsFilter, SpineNewsKind, SpineNewsPage, SpineNewsSummary, SpineNotice, SpineNoticePermission, SpineOpenTabOptions, SpineRating, SpineRatingAverage, SpineRatingScope, SpineRatingTarget, SpineScoreBand, SpineSettingsSection, SpineStarFill, SpineSuggestion, SpineSuggestionComment, SpineSuggestionDraft, SpineSuggestionKind, SpineSuggestionMessage, SpineSuggestionPerson, SpineSuggestionPublicSort, SpineSuggestionPublicStatus, SpineSuggestionReason, SpineSuggestionScreen, SpineSuggestionStatus, SpineSuggestionUpdate, SpineSuggestionVisibleSort, SpineSuggestionWaiting, SpineTab, SpineTabParams, SpineTagRowItem, SpineVisibleCounts, SpineVisibleQuery, SpineVisibleSuggestion, SuggestionScreenOption };
|
|
3001
4127
|
//# sourceMappingURL=trismegisto-spine-layout.d.ts.map
|