@sinequa/atomic-angular 0.4.22 → 0.4.28
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/fesm2022/sinequa-atomic-angular.mjs +92 -85
- package/fesm2022/sinequa-atomic-angular.mjs.map +1 -1
- package/index.d.ts +161 -162
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { Injectable, inject, HostBinding, Component, Pipe, InjectionToken, computed, ChangeDetectorRef, DestroyRef, LOCALE_ID, Inject, Optional, input, output, signal, effect, assertInInjectionContext, runInInjectionContext, Injector, EventEmitter, Directive, viewChild, ElementRef, afterNextRender, untracked, linkedSignal, model, TemplateRef, HostListener, Renderer2, contentChildren, contentChild, booleanAttribute, resource, ViewContainerRef, viewChildren, numberAttribute, afterEveryRender } from '@angular/core';
|
|
3
3
|
import { BehaviorSubject, Subscription, catchError, EMPTY, firstValueFrom, map, Subject, of, tap, throwError, filter, shareReplay, fromEvent, debounceTime, from, switchMap } from 'rxjs';
|
|
4
4
|
import { TranslocoService, TranslocoPipe, provideTranslocoScope } from '@jsverse/transloco';
|
|
5
|
-
import { DropdownComponent, DropdownContentComponent, InputComponent, ButtonComponent, cn, EllipsisIcon, ChevronRightIcon, MenuComponent, MenuContentComponent, MenuItemComponent, BadgeComponent, DialogComponent, DialogHeaderComponent, DialogTitleComponent, DialogContentComponent, DialogFooterComponent, ListItemComponent, SwitchComponent, SelectOptionDirective, DialogService, TabsComponent, TabsListComponent, TabComponent, ChevronLeftIconComponent, ChevronsLeftIconComponent, ChevronsRightIconComponent, Separator, SheetCloseDirective, SheetService, ButtonGroup, InputGroupInput, InputGroupComponent, InputGroupAddonComponent, SearchIcon, FilterIcon, DateRangePickerDirective, LoadingCircleIconComponent, CircleCheckIconComponent, PopoverComponent,
|
|
5
|
+
import { DropdownComponent, DropdownContentComponent, InputComponent, ButtonComponent, cn, EllipsisIcon, ChevronRightIcon, MenuComponent, MenuContentComponent, MenuItemComponent, BadgeComponent, DialogComponent, DialogHeaderComponent, DialogTitleComponent, DialogContentComponent, DialogFooterComponent, ListItemComponent, SwitchComponent, SelectOptionDirective, DialogService, TabsComponent, TabsListComponent, TabComponent, ChevronLeftIconComponent, ChevronsLeftIconComponent, ChevronsRightIconComponent, Separator, SheetCloseDirective, SheetService, ButtonGroup, InputGroupInput, InputGroupComponent, InputGroupAddonComponent, SearchIcon, FilterIcon, DateRangePickerDirective, LoadingCircleIconComponent, CircleCheckIconComponent, PopoverComponent, CardComponent, CardHeaderComponent, CardContentComponent, CardFooterComponent, PopoverContentComponent, BookmarkIcon, UserIcon, TrashIcon, FolderIcon, VerticalDividerComponent, BreakpointObserverService, HorizontalDividerComponent, FlagEnglishIconComponent, FlagFrenchIconComponent, EditIcon, UndoIcon, AvatarComponent, AvatarFallbackComponent, AvatarImageComponent } from '@sinequa/ui';
|
|
6
6
|
import highlightWords from 'highlight-words';
|
|
7
7
|
import { ActivatedRoute, Router, NavigationEnd, RouterLink, RouterModule } from '@angular/router';
|
|
8
8
|
import { withDevtools } from '@angular-architects/ngrx-toolkit';
|
|
@@ -1242,6 +1242,8 @@ const initialPrincipal = {
|
|
|
1242
1242
|
fullName: "",
|
|
1243
1243
|
isAdministrator: false,
|
|
1244
1244
|
isDelegatedAdmin: false,
|
|
1245
|
+
editablePartition: undefined,
|
|
1246
|
+
passwordExpirationDate: null,
|
|
1245
1247
|
description: "",
|
|
1246
1248
|
param1: "",
|
|
1247
1249
|
param2: "",
|
|
@@ -1264,6 +1266,7 @@ const PrincipalStore = signalStore({ providedIn: 'root' }, withDevtools('Princip
|
|
|
1264
1266
|
if (!fullName)
|
|
1265
1267
|
return '';
|
|
1266
1268
|
return fullName
|
|
1269
|
+
.trim()
|
|
1267
1270
|
.split(' ')
|
|
1268
1271
|
.map(word => word[0]?.toUpperCase())
|
|
1269
1272
|
.join('');
|
|
@@ -4817,8 +4820,8 @@ class UserProfileService {
|
|
|
4817
4820
|
* @param id - The ID of the user.
|
|
4818
4821
|
* @returns An Observable that emits an the UserProfile object.
|
|
4819
4822
|
*/
|
|
4820
|
-
getUserProfile(
|
|
4821
|
-
return httpResource(() => (
|
|
4823
|
+
getUserProfile(userId) {
|
|
4824
|
+
return httpResource(() => (userId() ? `${this.API_URL}/${userId()}` : undefined), {
|
|
4822
4825
|
parse: (response) => {
|
|
4823
4826
|
return response;
|
|
4824
4827
|
}
|
|
@@ -5074,7 +5077,7 @@ class DocumentLocatorComponent {
|
|
|
5074
5077
|
|
|
5075
5078
|
<div #documentLocator class="flex grow items-center gap-2 overflow-auto">
|
|
5076
5079
|
@for (segment of visibleSegments(); track $index) {
|
|
5077
|
-
<button
|
|
5080
|
+
<button variant="link" class="text-foreground h-auto cursor-pointer whitespace-nowrap p-0" (click)="navigateToSegment($index)">
|
|
5078
5081
|
{{ segment }}
|
|
5079
5082
|
</button>
|
|
5080
5083
|
|
|
@@ -5137,7 +5140,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
5137
5140
|
|
|
5138
5141
|
<div #documentLocator class="flex grow items-center gap-2 overflow-auto">
|
|
5139
5142
|
@for (segment of visibleSegments(); track $index) {
|
|
5140
|
-
<button
|
|
5143
|
+
<button variant="link" class="text-foreground h-auto cursor-pointer whitespace-nowrap p-0" (click)="navigateToSegment($index)">
|
|
5141
5144
|
{{ segment }}
|
|
5142
5145
|
</button>
|
|
5143
5146
|
|
|
@@ -5550,11 +5553,11 @@ class CollectionsDialog {
|
|
|
5550
5553
|
}
|
|
5551
5554
|
|
|
5552
5555
|
<DialogFooter class="flex flex-col">
|
|
5553
|
-
<button
|
|
5556
|
+
<button variant="outline" #closeBtn (click)="onClose()" >
|
|
5554
5557
|
{{ 'collections.close' | transloco }}
|
|
5555
5558
|
</button>
|
|
5556
5559
|
<button
|
|
5557
|
-
[
|
|
5560
|
+
[variant]="creating() ? 'outline' : undefined"
|
|
5558
5561
|
tabindex="0"
|
|
5559
5562
|
[attr.title]="(creating() ? 'collections.cancelCreation' : 'collections.createCollection') | transloco"
|
|
5560
5563
|
(click)="onCreate()">
|
|
@@ -5634,11 +5637,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
5634
5637
|
}
|
|
5635
5638
|
|
|
5636
5639
|
<DialogFooter class="flex flex-col">
|
|
5637
|
-
<button
|
|
5640
|
+
<button variant="outline" #closeBtn (click)="onClose()" >
|
|
5638
5641
|
{{ 'collections.close' | transloco }}
|
|
5639
5642
|
</button>
|
|
5640
5643
|
<button
|
|
5641
|
-
[
|
|
5644
|
+
[variant]="creating() ? 'outline' : undefined"
|
|
5642
5645
|
tabindex="0"
|
|
5643
5646
|
[attr.title]="(creating() ? 'collections.cancelCreation' : 'collections.createCollection') | transloco"
|
|
5644
5647
|
(click)="onCreate()">
|
|
@@ -5889,7 +5892,7 @@ class ExportDialog {
|
|
|
5889
5892
|
</section>
|
|
5890
5893
|
|
|
5891
5894
|
<DialogFooter>
|
|
5892
|
-
<button
|
|
5895
|
+
<button variant="outline" (click)="dialog.close()">
|
|
5893
5896
|
{{ 'cancel' | transloco }}
|
|
5894
5897
|
</button>
|
|
5895
5898
|
<button tabindex="0" [attr.title]="'export.download' | transloco" (click)="onDownload()">
|
|
@@ -5978,7 +5981,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
5978
5981
|
</section>
|
|
5979
5982
|
|
|
5980
5983
|
<DialogFooter>
|
|
5981
|
-
<button
|
|
5984
|
+
<button variant="outline" (click)="dialog.close()">
|
|
5982
5985
|
{{ 'cancel' | transloco }}
|
|
5983
5986
|
</button>
|
|
5984
5987
|
<button tabindex="0" [attr.title]="'export.download' | transloco" (click)="onDownload()">
|
|
@@ -9535,12 +9538,12 @@ class AlertDialog {
|
|
|
9535
9538
|
@if (alert || canUpdateQuery()) {
|
|
9536
9539
|
<div class="flex w-full flex-col gap-2">
|
|
9537
9540
|
@if (alert) {
|
|
9538
|
-
<button
|
|
9541
|
+
<button variant="outline" (click)="execute()" [disabled]="!canUpdateQuery()">
|
|
9539
9542
|
{{ 'alerts.execute' | transloco }}
|
|
9540
9543
|
</button>
|
|
9541
9544
|
}
|
|
9542
9545
|
@if (canUpdateQuery()) {
|
|
9543
|
-
<button [disabled]="updateStatus() !== 'idle'"
|
|
9546
|
+
<button [disabled]="updateStatus() !== 'idle'" variant="outline" (click)="updateQuery()">
|
|
9544
9547
|
@switch (updateStatus()) {
|
|
9545
9548
|
@case ('updating') {
|
|
9546
9549
|
<LoadingCircle class="size-4 animate-spin" width="16" height="16" />
|
|
@@ -9559,7 +9562,7 @@ class AlertDialog {
|
|
|
9559
9562
|
</div>
|
|
9560
9563
|
}
|
|
9561
9564
|
<div class="ml-auto flex justify-end gap-2">
|
|
9562
|
-
<button
|
|
9565
|
+
<button variant="outline" (click)="dialog.cancel()">
|
|
9563
9566
|
{{ 'cancel' | transloco }}
|
|
9564
9567
|
</button>
|
|
9565
9568
|
<button (click)="confirm()" [disabled]="invalidForm()">
|
|
@@ -9665,12 +9668,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
9665
9668
|
@if (alert || canUpdateQuery()) {
|
|
9666
9669
|
<div class="flex w-full flex-col gap-2">
|
|
9667
9670
|
@if (alert) {
|
|
9668
|
-
<button
|
|
9671
|
+
<button variant="outline" (click)="execute()" [disabled]="!canUpdateQuery()">
|
|
9669
9672
|
{{ 'alerts.execute' | transloco }}
|
|
9670
9673
|
</button>
|
|
9671
9674
|
}
|
|
9672
9675
|
@if (canUpdateQuery()) {
|
|
9673
|
-
<button [disabled]="updateStatus() !== 'idle'"
|
|
9676
|
+
<button [disabled]="updateStatus() !== 'idle'" variant="outline" (click)="updateQuery()">
|
|
9674
9677
|
@switch (updateStatus()) {
|
|
9675
9678
|
@case ('updating') {
|
|
9676
9679
|
<LoadingCircle class="size-4 animate-spin" width="16" height="16" />
|
|
@@ -9689,7 +9692,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
9689
9692
|
</div>
|
|
9690
9693
|
}
|
|
9691
9694
|
<div class="ml-auto flex justify-end gap-2">
|
|
9692
|
-
<button
|
|
9695
|
+
<button variant="outline" (click)="dialog.cancel()">
|
|
9693
9696
|
{{ 'cancel' | transloco }}
|
|
9694
9697
|
</button>
|
|
9695
9698
|
<button (click)="confirm()" [disabled]="invalidForm()">
|
|
@@ -9745,11 +9748,11 @@ class AlertsComponent {
|
|
|
9745
9748
|
this.tmpAlerts.splice(drop.currentIndex, 0, this.tmpAlerts.splice(drop.previousIndex, 1)[0]);
|
|
9746
9749
|
}
|
|
9747
9750
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AlertsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9748
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AlertsComponent, isStandalone: true, selector: "Alerts", providers: [provideTranslocoScope('alerts')], viewQueries: [{ propertyName: "alertFormDialog", first: true, predicate: AlertDialog, descendants: true, isSignal: true }], ngImport: i0, template: "<ul\n role=\"list\"\n class=\"flex min-w-80 flex-col p-2\"\n cdkDropList\n [cdkDropListData]=\"tmpAlerts\"\n [cdkDropListDisabled]=\"!reordering()\"\n (cdkDropListDropped)=\"dropped($event)\">\n @if (floating) {\n <label class=\"text-xl font-bold\">{{
|
|
9751
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: AlertsComponent, isStandalone: true, selector: "Alerts", providers: [provideTranslocoScope('alerts')], viewQueries: [{ propertyName: "alertFormDialog", first: true, predicate: AlertDialog, descendants: true, isSignal: true }], ngImport: i0, template: "<ul\r\n role=\"list\"\r\n class=\"flex min-w-80 flex-col p-2\"\r\n cdkDropList\r\n [cdkDropListData]=\"tmpAlerts\"\r\n [cdkDropListDisabled]=\"!reordering()\"\r\n (cdkDropListDropped)=\"dropped($event)\">\r\n @if (floating) {\r\n <label class=\"text-xl font-bold\">{{ \"alerts.label\" | transloco }}</label>\r\n <Separator />\r\n }\r\n @for (alert of tmpAlerts; track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group h-10\"\r\n tabindex=\"0\"\r\n cdkDrag\r\n (click)=\"onClick($index)\"\r\n (keydown.enter)=\"onClick($index)\">\r\n <i class=\"fa-fw fas fa-bell shrink-0\" aria-hidden=\"true\"></i>\r\n <p class=\"line-clamp-1\">{{ alert.name }}</p>\r\n @if (!reordering()) {\r\n <button\r\n class=\"text-destructive hover:text-destructive invisible ms-auto transition-transform group-hover:visible hover:scale-125\"\r\n title=\"{{ 'alerts.deleteAlert' | transloco }}\"\r\n [attr.aria-label]=\"'alerts.deleteAlert' | transloco\"\r\n (click)=\"deleteAlert($event, $index)\">\r\n <i class=\"fa-fw fa-regular fa-trash-can\" aria-hidden=\"true\"></i>\r\n </button>\r\n } @else {\r\n <i class=\"fa-fw fa-regular fa-bars\"></i>\r\n }\r\n </li>\r\n } @empty {\r\n <li role=\"listitem\" class=\"py-4 text-center text-neutral-500\">\r\n {{ \"alerts.noAlerts\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n<div class=\"flex flex-col gap-2 p-2\">\r\n <button\r\n variant=\"outline\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'alerts.manageAlerts' | transloco\"\r\n [disabled]=\"!alerts().length\"\r\n (click)=\"reorder()\">\r\n {{ (reordering() ? \"save\" : \"alerts.manageAlerts\") | transloco }}\r\n </button>\r\n <button\r\n class=\"w-full\"\r\n [attr.title]=\"'alerts.createAlert' | transloco\"\r\n (click)=\"createAlert()\">\r\n {{ \"alerts.createAlert\" | transloco }}\r\n </button>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: Separator, selector: "separator, Separator", inputs: ["class", "orientation"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
9749
9752
|
}
|
|
9750
9753
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AlertsComponent, decorators: [{
|
|
9751
9754
|
type: Component,
|
|
9752
|
-
args: [{ selector: 'Alerts', standalone: true, imports: [TranslocoPipe, ButtonComponent,
|
|
9755
|
+
args: [{ selector: 'Alerts', standalone: true, imports: [TranslocoPipe, ButtonComponent, ListItemComponent, DragDropModule, Separator], providers: [provideTranslocoScope('alerts')], template: "<ul\r\n role=\"list\"\r\n class=\"flex min-w-80 flex-col p-2\"\r\n cdkDropList\r\n [cdkDropListData]=\"tmpAlerts\"\r\n [cdkDropListDisabled]=\"!reordering()\"\r\n (cdkDropListDropped)=\"dropped($event)\">\r\n @if (floating) {\r\n <label class=\"text-xl font-bold\">{{ \"alerts.label\" | transloco }}</label>\r\n <Separator />\r\n }\r\n @for (alert of tmpAlerts; track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group h-10\"\r\n tabindex=\"0\"\r\n cdkDrag\r\n (click)=\"onClick($index)\"\r\n (keydown.enter)=\"onClick($index)\">\r\n <i class=\"fa-fw fas fa-bell shrink-0\" aria-hidden=\"true\"></i>\r\n <p class=\"line-clamp-1\">{{ alert.name }}</p>\r\n @if (!reordering()) {\r\n <button\r\n class=\"text-destructive hover:text-destructive invisible ms-auto transition-transform group-hover:visible hover:scale-125\"\r\n title=\"{{ 'alerts.deleteAlert' | transloco }}\"\r\n [attr.aria-label]=\"'alerts.deleteAlert' | transloco\"\r\n (click)=\"deleteAlert($event, $index)\">\r\n <i class=\"fa-fw fa-regular fa-trash-can\" aria-hidden=\"true\"></i>\r\n </button>\r\n } @else {\r\n <i class=\"fa-fw fa-regular fa-bars\"></i>\r\n }\r\n </li>\r\n } @empty {\r\n <li role=\"listitem\" class=\"py-4 text-center text-neutral-500\">\r\n {{ \"alerts.noAlerts\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n<div class=\"flex flex-col gap-2 p-2\">\r\n <button\r\n variant=\"outline\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'alerts.manageAlerts' | transloco\"\r\n [disabled]=\"!alerts().length\"\r\n (click)=\"reorder()\">\r\n {{ (reordering() ? \"save\" : \"alerts.manageAlerts\") | transloco }}\r\n </button>\r\n <button\r\n class=\"w-full\"\r\n [attr.title]=\"'alerts.createAlert' | transloco\"\r\n (click)=\"createAlert()\">\r\n {{ \"alerts.createAlert\" | transloco }}\r\n </button>\r\n</div>\r\n" }]
|
|
9753
9756
|
}], ctorParameters: () => [], propDecorators: { alertFormDialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AlertDialog), { isSignal: true }] }] } });
|
|
9754
9757
|
|
|
9755
9758
|
class ChangePasswordComponent {
|
|
@@ -10700,7 +10703,7 @@ class BookmarksComponent {
|
|
|
10700
10703
|
this.range.set(this.range() + (this.config.itemsPerPage ?? 10));
|
|
10701
10704
|
}
|
|
10702
10705
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: BookmarksComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10703
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: BookmarksComponent, isStandalone: true, selector: "bookmarks, Bookmarks", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideTranslocoScope("bookmarks")], ngImport: i0, template: "@if (floating) {\n <div class=\"p-2\">\n <label class=\"text-xl font-bold\">{{
|
|
10706
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: BookmarksComponent, isStandalone: true, selector: "bookmarks, Bookmarks", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideTranslocoScope("bookmarks")], ngImport: i0, template: "@if (floating) {\r\n <div class=\"p-2\">\r\n <label class=\"text-xl font-bold\">{{ \"bookmarks.label\" | transloco }}</label>\r\n <Separator />\r\n </div>\r\n}\r\n\r\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\" role=\"list\">\r\n @for (bookmark of paginatedBookmarks(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group h-10\"\r\n tabindex=\"0\"\r\n (click)=\"onClick(bookmark)\"\r\n (keydown.enter)=\"onClick(bookmark)\">\r\n <BookmarkIcon solid class=\"shrink-0\" />\r\n\r\n <p class=\"line-clamp-1\">{{ bookmark.label }}</p>\r\n\r\n @if (bookmark.author) {\r\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\r\n <UserIcon class=\"size-3\" />\r\n <span class=\"line-clamp-1\">{{ bookmark.author }}</span>\r\n </Badge>\r\n }\r\n @if (bookmark.parentFolder) {\r\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\r\n <FolderIcon class=\"size-3\" />\r\n <span class=\"line-clamp-1\">{{ bookmark.parentFolder }}</span>\r\n </Badge>\r\n }\r\n\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n title=\"{{ 'bookmarks.openBookmark' | transloco }}\"\r\n class=\"text-destructive ms-auto group-hover:visible\"\r\n [attr.title]=\"'bookmarks.removeBookmark' | transloco\"\r\n [attr.aria-label]=\"'bookmarks.removeBookmark' | transloco\"\r\n (click)=\"onDelete(bookmark, $event)\">\r\n <TrashIcon />\r\n </button>\r\n </li>\r\n } @empty {\r\n <li class=\"py-4 text-center text-neutral-500\">\r\n {{ \"bookmarks.noBookmarks\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n\r\n<div class=\"flex flex-col px-2\">\r\n @if (hasMore() && config.showLoadMore) {\r\n <button\r\n variant=\"ghost\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore($event)\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n <button\r\n variant=\"link\"\r\n class=\"ml-auto\"\r\n [attr.title]=\"'seeMore' | transloco\"\r\n [routerLink]=\"[config.routerLink]\">\r\n {{ \"seeMore\" | transloco }}\r\n </button>\r\n</div>\r\n", styles: [":host ul{scrollbar-width:thin}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: Separator, selector: "separator, Separator", inputs: ["class", "orientation"] }, { kind: "component", type: BookmarkIcon, selector: "bookmark-icon, BookmarkIcon", inputs: ["class", "solid"] }, { kind: "component", type: UserIcon, selector: "user-icon, UserIcon", inputs: ["class"] }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "component", type: FolderIcon, selector: "folder-icon, FolderIcon", inputs: ["class"] }, { kind: "directive", type: BadgeComponent, selector: "badge, Badge", inputs: ["class", "variant", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
10704
10707
|
}
|
|
10705
10708
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: BookmarksComponent, decorators: [{
|
|
10706
10709
|
type: Component,
|
|
@@ -10715,7 +10718,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
10715
10718
|
TrashIcon,
|
|
10716
10719
|
FolderIcon,
|
|
10717
10720
|
BadgeComponent
|
|
10718
|
-
], providers: [provideTranslocoScope("bookmarks")], template: "@if (floating) {\n <div class=\"p-2\">\n <label class=\"text-xl font-bold\">{{
|
|
10721
|
+
], providers: [provideTranslocoScope("bookmarks")], template: "@if (floating) {\r\n <div class=\"p-2\">\r\n <label class=\"text-xl font-bold\">{{ \"bookmarks.label\" | transloco }}</label>\r\n <Separator />\r\n </div>\r\n}\r\n\r\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\" role=\"list\">\r\n @for (bookmark of paginatedBookmarks(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group h-10\"\r\n tabindex=\"0\"\r\n (click)=\"onClick(bookmark)\"\r\n (keydown.enter)=\"onClick(bookmark)\">\r\n <BookmarkIcon solid class=\"shrink-0\" />\r\n\r\n <p class=\"line-clamp-1\">{{ bookmark.label }}</p>\r\n\r\n @if (bookmark.author) {\r\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\r\n <UserIcon class=\"size-3\" />\r\n <span class=\"line-clamp-1\">{{ bookmark.author }}</span>\r\n </Badge>\r\n }\r\n @if (bookmark.parentFolder) {\r\n <Badge variant=\"ghost\" class=\"text-grey-500 text-xs\">\r\n <FolderIcon class=\"size-3\" />\r\n <span class=\"line-clamp-1\">{{ bookmark.parentFolder }}</span>\r\n </Badge>\r\n }\r\n\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n title=\"{{ 'bookmarks.openBookmark' | transloco }}\"\r\n class=\"text-destructive ms-auto group-hover:visible\"\r\n [attr.title]=\"'bookmarks.removeBookmark' | transloco\"\r\n [attr.aria-label]=\"'bookmarks.removeBookmark' | transloco\"\r\n (click)=\"onDelete(bookmark, $event)\">\r\n <TrashIcon />\r\n </button>\r\n </li>\r\n } @empty {\r\n <li class=\"py-4 text-center text-neutral-500\">\r\n {{ \"bookmarks.noBookmarks\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n\r\n<div class=\"flex flex-col px-2\">\r\n @if (hasMore() && config.showLoadMore) {\r\n <button\r\n variant=\"ghost\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore($event)\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n <button\r\n variant=\"link\"\r\n class=\"ml-auto\"\r\n [attr.title]=\"'seeMore' | transloco\"\r\n [routerLink]=\"[config.routerLink]\">\r\n {{ \"seeMore\" | transloco }}\r\n </button>\r\n</div>\r\n", styles: [":host ul{scrollbar-width:thin}\n"] }]
|
|
10719
10722
|
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }] } });
|
|
10720
10723
|
|
|
10721
10724
|
class DeleteCollectionDialog {
|
|
@@ -10748,7 +10751,7 @@ class DeleteCollectionDialog {
|
|
|
10748
10751
|
<p>{{ 'collections.confirmDelete' | transloco }} {{ collection()?.name }}?</p>
|
|
10749
10752
|
|
|
10750
10753
|
<DialogFooter>
|
|
10751
|
-
<button
|
|
10754
|
+
<button variant="outline" (click)="dialog.cancel()">
|
|
10752
10755
|
{{ 'cancel' | transloco }}
|
|
10753
10756
|
</button>
|
|
10754
10757
|
|
|
@@ -10785,7 +10788,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
10785
10788
|
<p>{{ 'collections.confirmDelete' | transloco }} {{ collection()?.name }}?</p>
|
|
10786
10789
|
|
|
10787
10790
|
<DialogFooter>
|
|
10788
|
-
<button
|
|
10791
|
+
<button variant="outline" (click)="dialog.cancel()">
|
|
10789
10792
|
{{ 'cancel' | transloco }}
|
|
10790
10793
|
</button>
|
|
10791
10794
|
|
|
@@ -10840,7 +10843,7 @@ class CollectionsComponent {
|
|
|
10840
10843
|
this.range.set(this.range() + (this.config.itemsPerPage ?? 10));
|
|
10841
10844
|
}
|
|
10842
10845
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CollectionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10843
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: CollectionsComponent, isStandalone: true, selector: "app-collections", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideTranslocoScope("collections")], viewQueries: [{ propertyName: "deleteCollectionDialog", first: true, predicate: DeleteCollectionDialog, descendants: true, isSignal: true }], ngImport: i0, template: "@if (floating) {\n <div class=\"p-2\">\n <label class=\"text-xl font-bold\">{{
|
|
10846
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: CollectionsComponent, isStandalone: true, selector: "app-collections", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideTranslocoScope("collections")], viewQueries: [{ propertyName: "deleteCollectionDialog", first: true, predicate: DeleteCollectionDialog, descendants: true, isSignal: true }], ngImport: i0, template: "@if (floating) {\r\n <div class=\"p-2\">\r\n <label class=\"text-xl font-bold\">{{\r\n \"collections.label\" | transloco\r\n }}</label>\r\n <Separator />\r\n </div>\r\n}\r\n\r\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\">\r\n @for (collection of paginatedCollections(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group grid grid-cols-[min-content_auto_min-content] items-center\"\r\n tabindex=\"0\"\r\n (click)=\"onClick(collection)\"\r\n (keydown.enter)=\"onClick(collection)\">\r\n <i class=\"fas fa-inbox ps-2\"></i>\r\n\r\n <p class=\"mx-2 line-clamp-1\">{{ collection.name }}</p>\r\n\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n class=\"text-destructive invisible group-hover:visible\"\r\n title=\"{{ 'collections.deleteCollection' | transloco }}\"\r\n [attr.aria-label]=\"'collections.deleteCollection' | transloco\"\r\n (click)=\"onDelete(collection, $index, $event)\">\r\n <TrashIcon />\r\n </button>\r\n </li>\r\n } @empty {\r\n <li class=\"list-none py-4 text-center text-neutral-500\">\r\n {{ \"collections.noCollections\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n\r\n<div class=\"flex flex-col px-2\">\r\n @if (hasMore() && config.showLoadMore) {\r\n <button\r\n variant=\"outline\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore($event)\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n <button\r\n variant=\"link\"\r\n class=\"ml-auto\"\r\n [attr.title]=\"'seeMore' | transloco\"\r\n [routerLink]=\"[config.routerLink]\">\r\n {{ \"seeMore\" | transloco }}\r\n </button>\r\n</div>\r\n\r\n<delete-collection-dialog />\r\n", dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: DeleteCollectionDialog, selector: "delete-collection-dialog" }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "directive", type: ListItemComponent, selector: "[role=\"listitem\"], [role=\"option\"]", inputs: ["class", "variant", "decoration"] }, { kind: "directive", type: Separator, selector: "separator, Separator", inputs: ["class", "orientation"] }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
10844
10847
|
}
|
|
10845
10848
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CollectionsComponent, decorators: [{
|
|
10846
10849
|
type: Component,
|
|
@@ -10852,7 +10855,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
10852
10855
|
ListItemComponent,
|
|
10853
10856
|
Separator,
|
|
10854
10857
|
TrashIcon
|
|
10855
|
-
], providers: [provideTranslocoScope("collections")], template: "@if (floating) {\n <div class=\"p-2\">\n <label class=\"text-xl font-bold\">{{
|
|
10858
|
+
], providers: [provideTranslocoScope("collections")], template: "@if (floating) {\r\n <div class=\"p-2\">\r\n <label class=\"text-xl font-bold\">{{\r\n \"collections.label\" | transloco\r\n }}</label>\r\n <Separator />\r\n </div>\r\n}\r\n\r\n<ul class=\"flex max-h-[460px] flex-col overflow-auto\">\r\n @for (collection of paginatedCollections(); track $index) {\r\n <li\r\n role=\"listitem\"\r\n class=\"group grid grid-cols-[min-content_auto_min-content] items-center\"\r\n tabindex=\"0\"\r\n (click)=\"onClick(collection)\"\r\n (keydown.enter)=\"onClick(collection)\">\r\n <i class=\"fas fa-inbox ps-2\"></i>\r\n\r\n <p class=\"mx-2 line-clamp-1\">{{ collection.name }}</p>\r\n\r\n <button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n class=\"text-destructive invisible group-hover:visible\"\r\n title=\"{{ 'collections.deleteCollection' | transloco }}\"\r\n [attr.aria-label]=\"'collections.deleteCollection' | transloco\"\r\n (click)=\"onDelete(collection, $index, $event)\">\r\n <TrashIcon />\r\n </button>\r\n </li>\r\n } @empty {\r\n <li class=\"list-none py-4 text-center text-neutral-500\">\r\n {{ \"collections.noCollections\" | transloco }}\r\n </li>\r\n }\r\n</ul>\r\n\r\n<div class=\"flex flex-col px-2\">\r\n @if (hasMore() && config.showLoadMore) {\r\n <button\r\n variant=\"outline\"\r\n class=\"w-full\"\r\n tabindex=\"0\"\r\n [attr.title]=\"'loadMore' | transloco\"\r\n (click)=\"loadMore($event)\">\r\n {{ \"loadMore\" | transloco }}\r\n </button>\r\n }\r\n <button\r\n variant=\"link\"\r\n class=\"ml-auto\"\r\n [attr.title]=\"'seeMore' | transloco\"\r\n [routerLink]=\"[config.routerLink]\">\r\n {{ \"seeMore\" | transloco }}\r\n </button>\r\n</div>\r\n\r\n<delete-collection-dialog />\r\n" }]
|
|
10856
10859
|
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], deleteCollectionDialog: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DeleteCollectionDialog), { isSignal: true }] }] } });
|
|
10857
10860
|
|
|
10858
10861
|
class OverrideUserDialogComponent {
|
|
@@ -10951,7 +10954,7 @@ class OverrideUserDialogComponent {
|
|
|
10951
10954
|
</div>
|
|
10952
10955
|
|
|
10953
10956
|
<DialogFooter>
|
|
10954
|
-
<button
|
|
10957
|
+
<button variant="outline" (click)="dialog.close()">
|
|
10955
10958
|
{{ 'cancel' | transloco }}
|
|
10956
10959
|
</button>
|
|
10957
10960
|
|
|
@@ -11016,7 +11019,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
11016
11019
|
</div>
|
|
11017
11020
|
|
|
11018
11021
|
<DialogFooter>
|
|
11019
|
-
<button
|
|
11022
|
+
<button variant="outline" (click)="dialog.close()">
|
|
11020
11023
|
{{ 'cancel' | transloco }}
|
|
11021
11024
|
</button>
|
|
11022
11025
|
|
|
@@ -11055,7 +11058,7 @@ class ResetUserSettingsDialogComponent {
|
|
|
11055
11058
|
<p>{{ 'dialogs.resetUserSettings.message' | transloco }}</p>
|
|
11056
11059
|
|
|
11057
11060
|
<DialogFooter>
|
|
11058
|
-
<button
|
|
11061
|
+
<button variant="outline" (click)="dialog.close()">
|
|
11059
11062
|
{{ 'cancel' | transloco }}
|
|
11060
11063
|
</button>
|
|
11061
11064
|
|
|
@@ -11092,7 +11095,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
11092
11095
|
<p>{{ 'dialogs.resetUserSettings.message' | transloco }}</p>
|
|
11093
11096
|
|
|
11094
11097
|
<DialogFooter>
|
|
11095
|
-
<button
|
|
11098
|
+
<button variant="outline" (click)="dialog.close()">
|
|
11096
11099
|
{{ 'cancel' | transloco }}
|
|
11097
11100
|
</button>
|
|
11098
11101
|
|
|
@@ -12471,7 +12474,7 @@ class FeedbackDialogComponent {
|
|
|
12471
12474
|
}
|
|
12472
12475
|
|
|
12473
12476
|
<DialogFooter>
|
|
12474
|
-
<button
|
|
12477
|
+
<button variant="outline" (click)="dialog.close()">
|
|
12475
12478
|
{{ 'cancel' | transloco }}
|
|
12476
12479
|
</button>
|
|
12477
12480
|
<button [disabled]="!comment()" (click)="submit()">
|
|
@@ -12516,7 +12519,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
12516
12519
|
}
|
|
12517
12520
|
|
|
12518
12521
|
<DialogFooter>
|
|
12519
|
-
<button
|
|
12522
|
+
<button variant="outline" (click)="dialog.close()">
|
|
12520
12523
|
{{ 'cancel' | transloco }}
|
|
12521
12524
|
</button>
|
|
12522
12525
|
<button [disabled]="!comment()" (click)="submit()">
|
|
@@ -12888,6 +12891,8 @@ class AggregationTreeComponent {
|
|
|
12888
12891
|
constructor() {
|
|
12889
12892
|
this.query = buildQuery();
|
|
12890
12893
|
effect(() => {
|
|
12894
|
+
// if the aggregation store changes, remove previous session storage
|
|
12895
|
+
getState(this.aggregationsStore);
|
|
12891
12896
|
sessionStorage.removeItem(`agg-${this.column()}`);
|
|
12892
12897
|
});
|
|
12893
12898
|
effect(() => {
|
|
@@ -14773,11 +14778,11 @@ class SearchFooterComponent {
|
|
|
14773
14778
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: SearchFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14774
14779
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: SearchFooterComponent, isStandalone: true, selector: "search-footer, searchfooter, SearchFooter", inputs: { hasMore: { classPropertyName: "hasMore", publicName: "hasMore", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { loadMore: "loadMore" }, ngImport: i0, template: ` <div class="flex flex-col px-2">
|
|
14775
14780
|
@if (hasMore() && config().showLoadMore) {
|
|
14776
|
-
<button
|
|
14781
|
+
<button variant="outline" class="w-full" tabindex="0" [attr.title]="'loadMore' | transloco" (click)="onLoadMore($event)">
|
|
14777
14782
|
{{ 'loadMore' | transloco }}
|
|
14778
14783
|
</button>
|
|
14779
14784
|
}
|
|
14780
|
-
<button
|
|
14785
|
+
<button variant="link" class="ml-auto" [attr.title]="'seeMore' | transloco" [routerLink]="[config().routerLink]">
|
|
14781
14786
|
{{ 'seeMore' | transloco }}
|
|
14782
14787
|
</button>
|
|
14783
14788
|
</div>`, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
@@ -14789,11 +14794,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
14789
14794
|
imports: [TranslocoPipe, RouterLink, ButtonComponent],
|
|
14790
14795
|
template: ` <div class="flex flex-col px-2">
|
|
14791
14796
|
@if (hasMore() && config().showLoadMore) {
|
|
14792
|
-
<button
|
|
14797
|
+
<button variant="outline" class="w-full" tabindex="0" [attr.title]="'loadMore' | transloco" (click)="onLoadMore($event)">
|
|
14793
14798
|
{{ 'loadMore' | transloco }}
|
|
14794
14799
|
</button>
|
|
14795
14800
|
}
|
|
14796
|
-
<button
|
|
14801
|
+
<button variant="link" class="ml-auto" [attr.title]="'seeMore' | transloco" [routerLink]="[config().routerLink]">
|
|
14797
14802
|
{{ 'seeMore' | transloco }}
|
|
14798
14803
|
</button>
|
|
14799
14804
|
</div>`
|
|
@@ -15077,7 +15082,7 @@ class SavedSearchDialog {
|
|
|
15077
15082
|
(ngModelChange)="saveName.set($event)" />
|
|
15078
15083
|
|
|
15079
15084
|
<DialogFooter>
|
|
15080
|
-
<button
|
|
15085
|
+
<button variant="outline" (click)="dialog.close()">
|
|
15081
15086
|
{{ 'cancel' | transloco }}
|
|
15082
15087
|
</button>
|
|
15083
15088
|
<button (click)="confirm()" [disabled]="!saveName()">
|
|
@@ -15122,7 +15127,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
15122
15127
|
(ngModelChange)="saveName.set($event)" />
|
|
15123
15128
|
|
|
15124
15129
|
<DialogFooter>
|
|
15125
|
-
<button
|
|
15130
|
+
<button variant="outline" (click)="dialog.close()">
|
|
15126
15131
|
{{ 'cancel' | transloco }}
|
|
15127
15132
|
</button>
|
|
15128
15133
|
<button (click)="confirm()" [disabled]="!saveName()">
|
|
@@ -15216,15 +15221,7 @@ class UserProfileFormComponent {
|
|
|
15216
15221
|
}, ...(ngDevMode ? [{ debugName: "keys" }] : []));
|
|
15217
15222
|
formKeys = computed(() => this.keys().filter(k => k !== "profilePhoto"), ...(ngDevMode ? [{ debugName: "formKeys" }] : []));
|
|
15218
15223
|
allowProfilePhoto = computed(() => this.keys().some(k => k === "profilePhoto"), ...(ngDevMode ? [{ debugName: "allowProfilePhoto" }] : []));
|
|
15219
|
-
initials = computed(() => {
|
|
15220
|
-
const fullName = this.userProfile()?.data?.fullName;
|
|
15221
|
-
if (!fullName)
|
|
15222
|
-
return undefined;
|
|
15223
|
-
return fullName
|
|
15224
|
-
.split(" ")
|
|
15225
|
-
.map((word) => word[0].toUpperCase())
|
|
15226
|
-
.join("");
|
|
15227
|
-
}, ...(ngDevMode ? [{ debugName: "initials" }] : []));
|
|
15224
|
+
initials = computed(() => this.principalStore.initials(), ...(ngDevMode ? [{ debugName: "initials" }] : []));
|
|
15228
15225
|
username = computed(() => this.principalStore.name() || this.principalStore.email() || null, ...(ngDevMode ? [{ debugName: "username" }] : []));
|
|
15229
15226
|
propertyToEdit = signal(undefined, ...(ngDevMode ? [{ debugName: "propertyToEdit" }] : []));
|
|
15230
15227
|
value = model(undefined, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
@@ -15234,17 +15231,13 @@ class UserProfileFormComponent {
|
|
|
15234
15231
|
{ code: "fr", label: "Français", icon: FlagFrenchIconComponent }
|
|
15235
15232
|
];
|
|
15236
15233
|
changingPassword = signal(false, ...(ngDevMode ? [{ debugName: "changingPassword" }] : []));
|
|
15237
|
-
|
|
15238
|
-
|
|
15239
|
-
const customData = this.appStore.general()?.features?.userProfile?.customData;
|
|
15240
|
-
const profileKeys = this.userProfile()?.customData;
|
|
15241
|
-
return (customData?.length ? customData : (profileKeys ? Object.keys(profileKeys) : []))
|
|
15242
|
-
.filter(key => !this.keys().some(k => k.toLowerCase() === key.toLowerCase())); // hide any duplicates in customData keys from data's
|
|
15243
|
-
}, ...(ngDevMode ? [{ debugName: "customData" }] : []));
|
|
15234
|
+
customData = computed(() => (this.appStore.general()?.features?.userProfile?.customData || [])
|
|
15235
|
+
.filter(key => !this.keys().some(k => k.toLowerCase() === key.toLowerCase())), ...(ngDevMode ? [{ debugName: "customData" }] : []));
|
|
15244
15236
|
allowChangePassword = computed(() => {
|
|
15245
15237
|
const { useCredentials } = globalConfig;
|
|
15246
15238
|
const { allowChangePassword = false } = this.appStore.general()?.features || {};
|
|
15247
|
-
|
|
15239
|
+
const editablePartition = this.principalStore.editablePartition?.() || false;
|
|
15240
|
+
return allowChangePassword && useCredentials && editablePartition;
|
|
15248
15241
|
}, ...(ngDevMode ? [{ debugName: "allowChangePassword" }] : []));
|
|
15249
15242
|
constructor() {
|
|
15250
15243
|
this.currentLanguage.set(this.transloco.getActiveLang());
|
|
@@ -15255,26 +15248,31 @@ class UserProfileFormComponent {
|
|
|
15255
15248
|
}
|
|
15256
15249
|
});
|
|
15257
15250
|
}
|
|
15258
|
-
userProfileResource = this.userProfileService.getUserProfile(this.
|
|
15251
|
+
userProfileResource = this.userProfileService.getUserProfile(this.principalStore.userId);
|
|
15259
15252
|
userProfile = linkedSignal(() => {
|
|
15260
15253
|
if (this.userProfileResource.hasValue()) {
|
|
15261
15254
|
return this.userProfileResource.value();
|
|
15262
15255
|
}
|
|
15263
|
-
const { userId: id, email: mail, fullName } = this.
|
|
15256
|
+
const { userId: id, email: mail, fullName } = getState(this.principalStore);
|
|
15264
15257
|
if (!id || !mail || !fullName) {
|
|
15265
15258
|
return undefined;
|
|
15266
15259
|
}
|
|
15267
15260
|
return { data: { id, mail, fullName } };
|
|
15268
15261
|
}, ...(ngDevMode ? [{ debugName: "userProfile" }] : []));
|
|
15269
15262
|
async createUserProfile() {
|
|
15270
|
-
const { userId: id, email: mail, fullName } = this.
|
|
15263
|
+
const { userId: id, email: mail, fullName } = getState(this.principalStore);
|
|
15271
15264
|
if (!id) {
|
|
15272
15265
|
return;
|
|
15273
15266
|
}
|
|
15274
|
-
|
|
15275
|
-
|
|
15276
|
-
|
|
15277
|
-
|
|
15267
|
+
try {
|
|
15268
|
+
const response = await createUserProfile({ data: { id, mail, fullName } });
|
|
15269
|
+
if (response) {
|
|
15270
|
+
info("Created user profile", response);
|
|
15271
|
+
this.userProfileResource.set(response);
|
|
15272
|
+
}
|
|
15273
|
+
}
|
|
15274
|
+
catch (err) {
|
|
15275
|
+
notify.error(err.message);
|
|
15278
15276
|
}
|
|
15279
15277
|
}
|
|
15280
15278
|
/**
|
|
@@ -15286,7 +15284,7 @@ class UserProfileFormComponent {
|
|
|
15286
15284
|
onEdit(category, propertyName) {
|
|
15287
15285
|
const data = this.userProfile()?.[category];
|
|
15288
15286
|
const value = data?.[propertyName];
|
|
15289
|
-
this.value.set(value || "");
|
|
15287
|
+
this.value.set(value?.trim() || "");
|
|
15290
15288
|
this.propertyToEdit.set(`${category}.${propertyName}`);
|
|
15291
15289
|
}
|
|
15292
15290
|
/**
|
|
@@ -15296,15 +15294,20 @@ class UserProfileFormComponent {
|
|
|
15296
15294
|
* @param propertyName property name
|
|
15297
15295
|
*/
|
|
15298
15296
|
async onDeleteData(category, propertyName) {
|
|
15299
|
-
|
|
15300
|
-
|
|
15301
|
-
|
|
15302
|
-
|
|
15303
|
-
|
|
15304
|
-
|
|
15297
|
+
try {
|
|
15298
|
+
const response = await deleteUserProfileProperty(this.userProfile(), category, propertyName);
|
|
15299
|
+
if (response) {
|
|
15300
|
+
info("Deleted user profile property", response);
|
|
15301
|
+
const userProfile = JSON.parse(JSON.stringify(this.userProfile()));
|
|
15302
|
+
userProfile[category][propertyName] = undefined;
|
|
15303
|
+
this.userProfileResource.set(userProfile);
|
|
15304
|
+
}
|
|
15305
|
+
else {
|
|
15306
|
+
info("Could not delete user profile property", response);
|
|
15307
|
+
}
|
|
15305
15308
|
}
|
|
15306
|
-
|
|
15307
|
-
|
|
15309
|
+
catch (err) {
|
|
15310
|
+
notify.error(err.message);
|
|
15308
15311
|
}
|
|
15309
15312
|
}
|
|
15310
15313
|
/**
|
|
@@ -15318,19 +15321,24 @@ class UserProfileFormComponent {
|
|
|
15318
15321
|
const userProfile = JSON.parse(JSON.stringify(this.userProfile()));
|
|
15319
15322
|
if (!userProfile[category])
|
|
15320
15323
|
userProfile[category] = {};
|
|
15321
|
-
userProfile[category][propertyName] = this.value();
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
|
|
15325
|
-
|
|
15326
|
-
|
|
15327
|
-
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15324
|
+
userProfile[category][propertyName] = this.value()?.trim() || "";
|
|
15325
|
+
try {
|
|
15326
|
+
const response = await patchUserProfile(userProfile, category, propertyName);
|
|
15327
|
+
if (response) {
|
|
15328
|
+
const newUserProfile = this.userProfile();
|
|
15329
|
+
this.userProfileResource.set({
|
|
15330
|
+
...newUserProfile,
|
|
15331
|
+
...response,
|
|
15332
|
+
data: { ...(newUserProfile?.data || {}), ...(response.data || {}) },
|
|
15333
|
+
customData: { ...(newUserProfile?.customData || {}), ...(response.customData || {}) }
|
|
15334
|
+
});
|
|
15335
|
+
}
|
|
15336
|
+
this.value.set(undefined);
|
|
15337
|
+
this.propertyToEdit.set(undefined);
|
|
15338
|
+
}
|
|
15339
|
+
catch (err) {
|
|
15340
|
+
notify.error(err.message);
|
|
15331
15341
|
}
|
|
15332
|
-
this.value.set(undefined);
|
|
15333
|
-
this.propertyToEdit.set(undefined);
|
|
15334
15342
|
}
|
|
15335
15343
|
/**
|
|
15336
15344
|
* Get the value of a data key
|
|
@@ -15374,7 +15382,7 @@ class UserProfileFormComponent {
|
|
|
15374
15382
|
}
|
|
15375
15383
|
}
|
|
15376
15384
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: UserProfileFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
15377
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: UserProfileFormComponent, isStandalone: true, selector: "user-profile-form, UserProfileForm, userprofileform", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, currentLanguage: { classPropertyName: "currentLanguage", publicName: "currentLanguage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", currentLanguage: "currentLanguageChange" }, providers: [provideTranslocoScope("user-profile", "login")], viewQueries: [{ propertyName: "createInputElement", first: true, predicate: ["avatarInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (userProfileResource.hasValue()) {\n @let profile = userProfile();\n <div class=\"flex flex-col gap-2 p-4\">\n <div class=\"mb-4 flex\">\n @if (allowProfilePhoto()) {\n <!-- AVATAR -->\n <Avatar\n class=\"bg-accent text-accent-foreground hover:bg-accent/80 hover:text-accent-foreground/80 size-14 cursor-pointer\"\n (click)=\"avatarInput.click()\">\n @if (profile?.data?.profilePhoto) {\n <AvatarImage\n [src]=\"profile?.data?.profilePhoto!\"\n width=\"44\"\n height=\"44\"\n alt=\"avatar\" />\n }\n <AvatarFallback class=\"text-lg\">\n @if (initials()) {\n <span>{{ initials() }}</span>\n } @else {\n <UserIcon class=\"size-7 p-1\" />\n }\n </AvatarFallback>\n </Avatar>\n @if (profile?.data?.profilePhoto) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', 'profilePhoto')\">\n <TrashIcon />\n </button>\n }\n }\n <div class=\"grow\"></div>\n <div class=\"flex flex-col gap-4\">\n <!-- LANGUAGE -->\n <select\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 rounded-md border px-2 hover:outline focus:outline\"\n [(ngModel)]=\"currentLanguage\"\n (change)=\"changeLanguage()\">\n @for (lang of AllLanguages; track lang.code) {\n <option [value]=\"lang.code\">\n {{ lang.label }}\n </option>\n }\n </select>\n <!-- CHANGE PASSWORD -->\n @if (allowChangePassword()) {\n <button\n [disabled]=\"changingPassword()\"\n (click)=\"changingPassword.set(true)\">\n {{ \"login.changePassword\" | transloco }}\n </button>\n }\n </div>\n </div>\n @if (changingPassword()) {\n <ChangePassword\n [username]=\"username()\"\n [redirectAfterSuccess]=\"false\"\n [redirectAfterCancel]=\"false\"\n (cancel)=\"changingPassword.set(false)\"\n (success)=\"changingPassword.set(false)\" />\n } @else {\n @for (key of formKeys(); track key) {\n <div>\n <p>{{ `userProfile.data.${key}` | transloco }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('data', key)\">\n @if (propertyToEdit() === \"data.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"data\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"data.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('data', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('data', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n @for (key of customData(); track key) {\n <div>\n <p>{{ key }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('customData', key)\">\n @if (propertyToEdit() === \"customData.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"customData\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"customData.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('customData', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('customData', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('customData', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n} @else if (userProfileResource.isLoading()) {\n <span>Loading...</span>\n} @else if (userProfileResource.error()) {\n <p>Please contact an administrator to create your user profile.</p>\n}\n\n<!-- AVATAR UPLOAD -->\n<input\n #avatarInput\n class=\"hidden\"\n type=\"file\"\n accept=\"image/*\"\n (change)=\"uploadAvatar($event)\" />\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: InputComponent, selector: "input[type=\"text\"], input[type=\"email\"], input[type=\"number\"], input[type=\"password\"], input[type=\"tel\"], input[type=\"url\"], input[type=\"time\"], input[type=\"file\"]", inputs: ["class", "variant", "decoration"] }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "component", type: EditIcon, selector: "edit-icon, EditIcon, editicon", inputs: ["class"] }, { kind: "component", type: UndoIcon, selector: "UndoIcon, undoicon, undo-icon", inputs: ["class"] }, { kind: "component", type: AvatarComponent, selector: "avatar, Avatar", inputs: ["class"] }, { kind: "component", type: AvatarFallbackComponent, selector: "avatar-fallback, avatarfallback, AvatarFallback", inputs: ["class"] }, { kind: "component", type: UserIcon, selector: "user-icon, UserIcon", inputs: ["class"] }, { kind: "component", type: AvatarImageComponent, selector: "avatar-image, AvatarImage, avatarimage", inputs: ["class", "src", "alt", "width", "height", "referrerPolicy", "crossOrigin"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: ChangePasswordComponent, selector: "change-password, ChangePassword, changepassword", inputs: ["username", "alert", "redirectAfterSuccess", "redirectAfterCancel", "currentPassword", "newPassword", "confirmPassword"], outputs: ["success", "cancel", "currentPasswordChange", "newPasswordChange", "confirmPasswordChange"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
15385
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.18", type: UserProfileFormComponent, isStandalone: true, selector: "user-profile-form, UserProfileForm, userprofileform", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, currentLanguage: { classPropertyName: "currentLanguage", publicName: "currentLanguage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", currentLanguage: "currentLanguageChange" }, providers: [provideTranslocoScope("user-profile", "login")], viewQueries: [{ propertyName: "createInputElement", first: true, predicate: ["avatarInput"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (userProfileResource.hasValue()) {\n @let profile = userProfile();\n <div class=\"flex flex-col gap-2 p-4\">\n <div class=\"mb-4 flex\">\n @if (allowProfilePhoto()) {\n <!-- AVATAR -->\n <Avatar\n class=\"bg-accent text-accent-foreground hover:bg-accent/80 hover:text-accent-foreground/80 size-14 cursor-pointer\"\n (click)=\"avatarInput.click()\">\n @if (profile?.data?.profilePhoto) {\n <AvatarImage\n [src]=\"profile?.data?.profilePhoto!\"\n width=\"44\"\n height=\"44\"\n alt=\"avatar\" />\n }\n <AvatarFallback class=\"text-lg\">\n @if (initials()) {\n <span>{{ initials() }}</span>\n } @else {\n <UserIcon class=\"size-7 p-1\" />\n }\n </AvatarFallback>\n </Avatar>\n @if (profile?.data?.profilePhoto) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive cursor-pointer\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', 'profilePhoto')\">\n <TrashIcon />\n </button>\n }\n }\n <div class=\"grow\"></div>\n <div class=\"flex flex-col gap-4\">\n <!-- LANGUAGE -->\n <select\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 rounded-md border px-2 hover:outline focus:outline\"\n [(ngModel)]=\"currentLanguage\"\n (change)=\"changeLanguage()\">\n @for (lang of AllLanguages; track lang.code) {\n <option [value]=\"lang.code\">\n {{ lang.label }}\n </option>\n }\n </select>\n <!-- CHANGE PASSWORD -->\n @if (allowChangePassword()) {\n <button\n [disabled]=\"changingPassword()\"\n (click)=\"changingPassword.set(true)\">\n {{ \"login.changePassword\" | transloco }}\n </button>\n }\n </div>\n </div>\n @if (changingPassword()) {\n <ChangePassword\n [username]=\"username()\"\n [redirectAfterSuccess]=\"false\"\n [redirectAfterCancel]=\"false\"\n (cancel)=\"changingPassword.set(false)\"\n (success)=\"changingPassword.set(false)\" />\n } @else {\n @for (key of formKeys(); track key) {\n <div>\n <p>{{ `userProfile.data.${key}` | transloco }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('data', key)\">\n @if (propertyToEdit() === \"data.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"data\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"data.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('data', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('data', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n @for (key of customData(); track key) {\n <div>\n <p>{{ key }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('customData', key)\">\n @if (propertyToEdit() === \"customData.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"customData\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"customData.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('customData', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('customData', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('customData', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n} @else if (userProfileResource.isLoading()) {\n <span>Loading...</span>\n} @else if (userProfileResource.error()) {\n <p>Please contact an administrator to create your user profile.</p>\n}\n\n<!-- AVATAR UPLOAD -->\n<input\n #avatarInput\n class=\"hidden\"\n type=\"file\"\n accept=\"image/*\"\n (change)=\"uploadAvatar($event)\" />\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: RouterModule }, { kind: "component", type: TrashIcon, selector: "trash-icon, TrashIcon", inputs: ["class"] }, { kind: "component", type: EditIcon, selector: "edit-icon, EditIcon, editicon", inputs: ["class"] }, { kind: "component", type: UndoIcon, selector: "UndoIcon, undoicon, undo-icon", inputs: ["class"] }, { kind: "component", type: AvatarComponent, selector: "avatar, Avatar", inputs: ["class"] }, { kind: "component", type: AvatarFallbackComponent, selector: "avatar-fallback, avatarfallback, AvatarFallback", inputs: ["class"] }, { kind: "component", type: UserIcon, selector: "user-icon, UserIcon", inputs: ["class"] }, { kind: "component", type: AvatarImageComponent, selector: "avatar-image, AvatarImage, avatarimage", inputs: ["class", "src", "alt", "width", "height", "referrerPolicy", "crossOrigin"] }, { kind: "directive", type: ButtonComponent, selector: "button", inputs: ["class", "variant", "decoration", "size"] }, { kind: "component", type: ChangePasswordComponent, selector: "change-password, ChangePassword, changepassword", inputs: ["username", "alert", "redirectAfterSuccess", "redirectAfterCancel", "currentPassword", "newPassword", "confirmPassword"], outputs: ["success", "cancel", "currentPasswordChange", "newPasswordChange", "confirmPasswordChange"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
|
|
15378
15386
|
}
|
|
15379
15387
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: UserProfileFormComponent, decorators: [{
|
|
15380
15388
|
type: Component,
|
|
@@ -15382,7 +15390,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
15382
15390
|
FormsModule,
|
|
15383
15391
|
RouterModule,
|
|
15384
15392
|
TranslocoPipe,
|
|
15385
|
-
InputComponent,
|
|
15386
15393
|
TrashIcon,
|
|
15387
15394
|
EditIcon,
|
|
15388
15395
|
UndoIcon,
|
|
@@ -15392,7 +15399,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
|
|
|
15392
15399
|
AvatarImageComponent,
|
|
15393
15400
|
ButtonComponent,
|
|
15394
15401
|
ChangePasswordComponent
|
|
15395
|
-
], providers: [provideTranslocoScope("user-profile", "login")], template: "@if (userProfileResource.hasValue()) {\n @let profile = userProfile();\n <div class=\"flex flex-col gap-2 p-4\">\n <div class=\"mb-4 flex\">\n @if (allowProfilePhoto()) {\n <!-- AVATAR -->\n <Avatar\n class=\"bg-accent text-accent-foreground hover:bg-accent/80 hover:text-accent-foreground/80 size-14 cursor-pointer\"\n (click)=\"avatarInput.click()\">\n @if (profile?.data?.profilePhoto) {\n <AvatarImage\n [src]=\"profile?.data?.profilePhoto!\"\n width=\"44\"\n height=\"44\"\n alt=\"avatar\" />\n }\n <AvatarFallback class=\"text-lg\">\n @if (initials()) {\n <span>{{ initials() }}</span>\n } @else {\n <UserIcon class=\"size-7 p-1\" />\n }\n </AvatarFallback>\n </Avatar>\n @if (profile?.data?.profilePhoto) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive
|
|
15402
|
+
], providers: [provideTranslocoScope("user-profile", "login")], template: "@if (userProfileResource.hasValue()) {\n @let profile = userProfile();\n <div class=\"flex flex-col gap-2 p-4\">\n <div class=\"mb-4 flex\">\n @if (allowProfilePhoto()) {\n <!-- AVATAR -->\n <Avatar\n class=\"bg-accent text-accent-foreground hover:bg-accent/80 hover:text-accent-foreground/80 size-14 cursor-pointer\"\n (click)=\"avatarInput.click()\">\n @if (profile?.data?.profilePhoto) {\n <AvatarImage\n [src]=\"profile?.data?.profilePhoto!\"\n width=\"44\"\n height=\"44\"\n alt=\"avatar\" />\n }\n <AvatarFallback class=\"text-lg\">\n @if (initials()) {\n <span>{{ initials() }}</span>\n } @else {\n <UserIcon class=\"size-7 p-1\" />\n }\n </AvatarFallback>\n </Avatar>\n @if (profile?.data?.profilePhoto) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive cursor-pointer\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', 'profilePhoto')\">\n <TrashIcon />\n </button>\n }\n }\n <div class=\"grow\"></div>\n <div class=\"flex flex-col gap-4\">\n <!-- LANGUAGE -->\n <select\n class=\"hover:outline-primary focus:outline-primary border-foreground/10 bg-background hover:bg-muted focus:bg-muted h-8 rounded-md border px-2 hover:outline focus:outline\"\n [(ngModel)]=\"currentLanguage\"\n (change)=\"changeLanguage()\">\n @for (lang of AllLanguages; track lang.code) {\n <option [value]=\"lang.code\">\n {{ lang.label }}\n </option>\n }\n </select>\n <!-- CHANGE PASSWORD -->\n @if (allowChangePassword()) {\n <button\n [disabled]=\"changingPassword()\"\n (click)=\"changingPassword.set(true)\">\n {{ \"login.changePassword\" | transloco }}\n </button>\n }\n </div>\n </div>\n @if (changingPassword()) {\n <ChangePassword\n [username]=\"username()\"\n [redirectAfterSuccess]=\"false\"\n [redirectAfterCancel]=\"false\"\n (cancel)=\"changingPassword.set(false)\"\n (success)=\"changingPassword.set(false)\" />\n } @else {\n @for (key of formKeys(); track key) {\n <div>\n <p>{{ `userProfile.data.${key}` | transloco }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('data', key)\">\n @if (propertyToEdit() === \"data.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"data\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"data.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('data', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('data', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('data', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n @for (key of customData(); track key) {\n <div>\n <p>{{ key }}</p>\n <div class=\"group flex flex-row\">\n <div\n class=\"grow whitespace-pre-line\"\n [class.text-muted-foreground]=\"!getDataValue('customData', key)\">\n @if (propertyToEdit() === \"customData.\" + key) {\n <textarea\n class=\"hover:outline-primary focus:outline-primary border-foreground/20 hover:bg-muted focus:bg-muted mt-2 w-full rounded-md border px-2 pt-1 hover:outline focus:outline\"\n id=\"user-profile-{{ key }}\"\n [(ngModel)]=\"value\"></textarea>\n } @else {\n {{\n getDataValue(\"customData\", key) ||\n (\"userProfile.notDefined\" | transloco)\n }}\n }\n </div>\n @if (propertyToEdit() === \"customData.\" + key) {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"mx-2 cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onSaveData('customData', key)\">\n <i class=\"fa-fw fas fa-save ml-2\"></i>\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"cursor-pointer\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"propertyToEdit.set(undefined)\">\n <UndoIcon />\n </button>\n } @else {\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"invisible mx-2 cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.editProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.editProperty' | transloco\"\n (click)=\"onEdit('customData', key)\">\n <EditIcon />\n </button>\n <button\n variant=\"ghost\"\n size=\"icon\"\n class=\"text-destructive invisible cursor-pointer group-hover:visible\"\n title=\"{{ 'userProfile.deleteProperty' | transloco }}\"\n [attr.aria-label]=\"'userProfile.deleteProperty' | transloco\"\n (click)=\"onDeleteData('customData', key)\">\n <TrashIcon />\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n} @else if (userProfileResource.isLoading()) {\n <span>Loading...</span>\n} @else if (userProfileResource.error()) {\n <p>Please contact an administrator to create your user profile.</p>\n}\n\n<!-- AVATAR UPLOAD -->\n<input\n #avatarInput\n class=\"hidden\"\n type=\"file\"\n accept=\"image/*\"\n (change)=\"uploadAvatar($event)\" />\n" }]
|
|
15396
15403
|
}], ctorParameters: () => [], propDecorators: { createInputElement: [{ type: i0.ViewChild, args: ["avatarInput", { isSignal: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], currentLanguage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentLanguage", required: false }] }, { type: i0.Output, args: ["currentLanguageChange"] }] } });
|
|
15397
15404
|
|
|
15398
15405
|
class UserProfileDialog {
|