@trismegisto/spine 3.3.1 → 3.3.2
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.
|
@@ -3,7 +3,7 @@ import { inject, ChangeDetectorRef, ChangeDetectionStrategy, Component, Injectio
|
|
|
3
3
|
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
4
4
|
import * as i3 from '@angular/router';
|
|
5
5
|
import { RouterLink, Router, NavigationEnd, NavigationSkipped, RouterOutlet } from '@angular/router';
|
|
6
|
-
import { firstValueFrom,
|
|
6
|
+
import { firstValueFrom, filter, Subject, take, debounceTime, distinctUntilChanged } from 'rxjs';
|
|
7
7
|
import { MenuButtonComponent, HermesThemeService, HERMES_THEME_CONFIG, HermesSidebarService, HermesToastService, IconComponent, ButtonComponent, SkeletonComponent, TextareaComponent, FloatingWindowComponent, IconButtonComponent, HermesShortcutService, HeaderComponent as HeaderComponent$1, AccountAvatarComponent, CommandPaletteComponent, createPersistedWorkspaceStore, HERMES_WORKSPACE_PERSISTENCE_CONFIG, findPanelTabs, SidebarComponent as SidebarComponent$1, SidebarNodeComponent, HermesI18nService, SegmentedControlComponent, ThemePickerComponent, AlertComponent, BreadcrumbComponent, DrawerComponent, ModalComponent, PaginatorComponent, RichTextComponent, SearchFieldComponent, ShortcutListComponent, TagComponent, CodeInputComponent, InputComponent, RadioComponent, CheckboxComponent, CodeViewerComponent, SelectComponent, AvatarGroupComponent, HERMES_SIDEBAR_CONFIG, ComboboxComponent, SettingsDialogComponent, SettingsRowComponent, SettingsSectionComponent, ToggletipComponent, TooltipDirective, EmptyComponent, LoadingSquareComponent, WorkspaceComponent, ToastStackComponent } from '@trismegisto/angular';
|
|
8
8
|
import { ModalComponent as ModalComponent$1 } from '@trismegisto/spine/modal';
|
|
9
9
|
import { SidePanelComponent } from '@trismegisto/spine/side-panel';
|
|
@@ -724,6 +724,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.24", ngImpo
|
|
|
724
724
|
args: [{ providedIn: 'root' }]
|
|
725
725
|
}] });
|
|
726
726
|
|
|
727
|
+
/**
|
|
728
|
+
* Manda uma requisição ao argos-admin com o token da sessão em `x-access-token`. Com token na mão, sai na hora (token
|
|
729
|
+
* vencido é com o interceptor do Orfeu, que troca pelo renovado). Sem token ainda — o cabeçalho, as novidades e a
|
|
730
|
+
* avaliação chamam a API assim que aparecem, às vezes antes de o Orfeu restaurar a sessão —, espera a sessão ser
|
|
731
|
+
* aplicada (`isAuth$`) em vez de sair sem token (o servidor respondia "Access token required"). Orfeu sem `isAuth$`, ou
|
|
732
|
+
* sem `AuthorizationService` (app ou teste sem Orfeu): sai com o que houver.
|
|
733
|
+
*/
|
|
734
|
+
function sendWithSession(auth, send) {
|
|
735
|
+
const now = auth?.getToken();
|
|
736
|
+
if (now || !auth)
|
|
737
|
+
return firstValueFrom(send(tokenHeaders(now)));
|
|
738
|
+
const session = auth;
|
|
739
|
+
if (!session.isAuth$ || session.authenticated !== false)
|
|
740
|
+
return firstValueFrom(send(tokenHeaders(now)));
|
|
741
|
+
return firstValueFrom(session.isAuth$.pipe(filter(Boolean))).then(() => firstValueFrom(send(tokenHeaders(auth.getToken()))));
|
|
742
|
+
}
|
|
743
|
+
function tokenHeaders(token) {
|
|
744
|
+
return new HttpHeaders({ 'x-access-token': token ?? '' });
|
|
745
|
+
}
|
|
746
|
+
|
|
727
747
|
/** Espera depois da entrada (ou do fim da configuração inicial) antes do aviso, para não emendar com ela. */
|
|
728
748
|
const ANNOUNCE_DELAY_MS = 1200;
|
|
729
749
|
/** Quantas das mais recentes a entrada lê: decidem o aviso, a contagem do menu e o card do Início. */
|
|
@@ -783,9 +803,6 @@ class SpineNewsService {
|
|
|
783
803
|
this.announcedKey = `${prefix}_news_announced`;
|
|
784
804
|
this.favoritesKey = `${prefix}_news_favorites`;
|
|
785
805
|
}
|
|
786
|
-
get headers() {
|
|
787
|
-
return new HttpHeaders({ 'x-access-token': this.auth?.getToken() ?? '' });
|
|
788
|
-
}
|
|
789
806
|
/** Relê as mais recentes; qualquer falha deixa a lista vazia (o item some em vez de mostrar um erro sem contexto). */
|
|
790
807
|
async refresh() {
|
|
791
808
|
if (!this.available)
|
|
@@ -800,14 +817,14 @@ class SpineNewsService {
|
|
|
800
817
|
}
|
|
801
818
|
/** Uma página da lista (`page` a partir de 1). Falha propaga: o painel mostra o erro com "Tentar de novo". */
|
|
802
819
|
page(page, limit) {
|
|
803
|
-
return
|
|
804
|
-
headers
|
|
820
|
+
return sendWithSession(this.auth, (headers) => this.http.get(`${this.adminApi}/me/news`, {
|
|
821
|
+
headers,
|
|
805
822
|
params: { page, limit },
|
|
806
823
|
}));
|
|
807
824
|
}
|
|
808
825
|
/** Uma novidade com o corpo. */
|
|
809
826
|
detail(id) {
|
|
810
|
-
return
|
|
827
|
+
return sendWithSession(this.auth, (headers) => this.http.get(`${this.adminApi}/me/news${urlPath `/${id}`}`, { headers }));
|
|
811
828
|
}
|
|
812
829
|
/**
|
|
813
830
|
* Chamado uma vez pelo layout na entrada: lê as mais recentes, espera a configuração inicial se decidir (e terminar,
|
|
@@ -964,9 +981,6 @@ class SpineRatingsService {
|
|
|
964
981
|
get url() {
|
|
965
982
|
return `${this.adminApi}/me/ratings`;
|
|
966
983
|
}
|
|
967
|
-
get headers() {
|
|
968
|
-
return new HttpHeaders({ 'x-access-token': this.auth?.getToken() ?? '' });
|
|
969
|
-
}
|
|
970
984
|
/** "Avaliar o {app}": abre a janela (ou troca o conteúdo dela) para a ferramenta. */
|
|
971
985
|
openApp() {
|
|
972
986
|
if (this.enabled)
|
|
@@ -1001,7 +1015,7 @@ class SpineRatingsService {
|
|
|
1001
1015
|
}
|
|
1002
1016
|
/** Média e total da ferramenta (`GET /me/ratings/summary`); quem mostra trata a falha. */
|
|
1003
1017
|
async loadAppAverage() {
|
|
1004
|
-
const res = await
|
|
1018
|
+
const res = await sendWithSession(this.auth, (headers) => this.http.get(`${this.url}/summary`, { headers }));
|
|
1005
1019
|
const out = { average: res?.average ?? null, total: res?.total ?? 0 };
|
|
1006
1020
|
this.appAverage.set(out);
|
|
1007
1021
|
return out;
|
|
@@ -1011,7 +1025,7 @@ class SpineRatingsService {
|
|
|
1011
1025
|
const params = { scope: target.scope };
|
|
1012
1026
|
if (target.scope === 'screen')
|
|
1013
1027
|
params['screen'] = target.screenPath ?? '';
|
|
1014
|
-
const res = await
|
|
1028
|
+
const res = await sendWithSession(this.auth, (headers) => this.http.get(this.url, { headers, params }));
|
|
1015
1029
|
return res?.rating ?? null;
|
|
1016
1030
|
}
|
|
1017
1031
|
/** Cria ou atualiza a avaliação (nota 0 a 10); comentário vazio vai como `null`. */
|
|
@@ -1021,7 +1035,7 @@ class SpineRatingsService {
|
|
|
1021
1035
|
body['screen_path'] = target.screenPath ?? '';
|
|
1022
1036
|
body['screen_label'] = target.screenLabel ?? null;
|
|
1023
1037
|
}
|
|
1024
|
-
const res = await
|
|
1038
|
+
const res = await sendWithSession(this.auth, (headers) => this.http.put(this.url, body, { headers }));
|
|
1025
1039
|
this.ratedNow.update((set) => new Set(set).add(keyOf(target)));
|
|
1026
1040
|
if (target.scope === 'app') {
|
|
1027
1041
|
this.appRated.set(true);
|
|
@@ -6162,21 +6176,18 @@ class SpineSuggestionsService {
|
|
|
6162
6176
|
url(strings, ...ids) {
|
|
6163
6177
|
return `${this.adminApi}/me/suggestions${urlPath(strings, ...ids)}`;
|
|
6164
6178
|
}
|
|
6165
|
-
get headers() {
|
|
6166
|
-
return new HttpHeaders({ 'x-access-token': this.auth.getToken() ?? '' });
|
|
6167
|
-
}
|
|
6168
6179
|
create(draft) {
|
|
6169
|
-
return
|
|
6180
|
+
return sendWithSession(this.auth, (headers) => this.http.post(this.url ``, draft, { headers }));
|
|
6170
6181
|
}
|
|
6171
6182
|
/** As minhas, da mais nova; `status` filtra uma coluna. */
|
|
6172
|
-
mine(opts) {
|
|
6183
|
+
async mine(opts) {
|
|
6173
6184
|
let params = new HttpParams().set('limit', opts.limit).set('offset', opts.offset);
|
|
6174
6185
|
if (opts.status)
|
|
6175
6186
|
params = params.set('status', opts.status);
|
|
6176
|
-
return
|
|
6187
|
+
return sendWithSession(this.auth, (headers) => this.http.get(this.url ``, { headers, params }));
|
|
6177
6188
|
}
|
|
6178
6189
|
/** "Sugestões do app": as de todas as pessoas no app (menos recusadas e arquivadas), com filtros e paginação. */
|
|
6179
|
-
all(query) {
|
|
6190
|
+
async all(query) {
|
|
6180
6191
|
let params = new HttpParams().set('limit', query.limit).set('offset', query.offset);
|
|
6181
6192
|
if (query.status)
|
|
6182
6193
|
params = params.set('status', query.status);
|
|
@@ -6186,24 +6197,24 @@ class SpineSuggestionsService {
|
|
|
6186
6197
|
params = params.set('screen', query.screen);
|
|
6187
6198
|
if (query.sort)
|
|
6188
6199
|
params = params.set('sort', query.sort);
|
|
6189
|
-
return
|
|
6200
|
+
return sendWithSession(this.auth, (headers) => this.http.get(this.url `/all`, { headers, params }));
|
|
6190
6201
|
}
|
|
6191
6202
|
/** Os comentários públicos de uma sugestão (o detalhe só de leitura), do mais novo. */
|
|
6192
|
-
comments(id, page) {
|
|
6203
|
+
async comments(id, page) {
|
|
6193
6204
|
const params = new HttpParams().set('limit', page.limit).set('offset', page.offset);
|
|
6194
|
-
return
|
|
6205
|
+
return sendWithSession(this.auth, (headers) => this.http.get(this.url `/${id}/comments`, { headers, params }));
|
|
6195
6206
|
}
|
|
6196
6207
|
/** As ainda abertas da tela, de qualquer pessoa: o modal oferece apoiar em vez de repetir. */
|
|
6197
6208
|
async byScreen(path) {
|
|
6198
6209
|
const params = new HttpParams().set('path', path);
|
|
6199
|
-
const res = await
|
|
6210
|
+
const res = await sendWithSession(this.auth, (headers) => this.http.get(this.url `/screen`, { headers, params }));
|
|
6200
6211
|
return res.suggestions ?? [];
|
|
6201
6212
|
}
|
|
6202
6213
|
vote(id) {
|
|
6203
|
-
return
|
|
6214
|
+
return sendWithSession(this.auth, (headers) => this.http.post(this.url `/${id}/vote`, {}, { headers }));
|
|
6204
6215
|
}
|
|
6205
6216
|
unvote(id) {
|
|
6206
|
-
return
|
|
6217
|
+
return sendWithSession(this.auth, (headers) => this.http.delete(this.url `/${id}/vote`, { headers }));
|
|
6207
6218
|
}
|
|
6208
6219
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: SpineSuggestionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
6209
6220
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.24", ngImport: i0, type: SpineSuggestionsService, providedIn: 'root' }); }
|