oip-common 0.10.0 → 0.11.1
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 +0 -1
- package/fesm2022/oip-common.mjs +220 -58
- package/fesm2022/oip-common.mjs.map +1 -1
- package/index.d.ts +48 -13
- package/package.json +1 -1
package/fesm2022/oip-common.mjs
CHANGED
|
@@ -411,6 +411,7 @@ class LayoutService {
|
|
|
411
411
|
return ngDateFormat;
|
|
412
412
|
}, ...(ngDevMode ? [{ debugName: "monthFormat" }] : []));
|
|
413
413
|
this.timeZone = computed(() => this.layoutConfig().timeZone, ...(ngDevMode ? [{ debugName: "timeZone" }] : []));
|
|
414
|
+
this.firstDayOfWeek = computed(() => this.layoutConfig().firstDayOfWeek ?? 1, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : []));
|
|
414
415
|
this.adminMode = computed(() => this.layoutConfig().adminMode ?? false, ...(ngDevMode ? [{ debugName: "adminMode" }] : []));
|
|
415
416
|
this.transitionComplete = signal(false, ...(ngDevMode ? [{ debugName: "transitionComplete" }] : []));
|
|
416
417
|
/**
|
|
@@ -443,6 +444,7 @@ class LayoutService {
|
|
|
443
444
|
if (appConfigUiString != null) {
|
|
444
445
|
const config = JSON.parse(appConfigUiString);
|
|
445
446
|
config.timeZone ??= Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
447
|
+
config.firstDayOfWeek ??= 1;
|
|
446
448
|
return config;
|
|
447
449
|
}
|
|
448
450
|
return {
|
|
@@ -456,6 +458,7 @@ class LayoutService {
|
|
|
456
458
|
timeFormat: 'HH:mm:ss',
|
|
457
459
|
dateTimeFormat: 'yyyy-MM-dd HH:mm:ss',
|
|
458
460
|
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
461
|
+
firstDayOfWeek: 1,
|
|
459
462
|
adminMode: false
|
|
460
463
|
};
|
|
461
464
|
}
|
|
@@ -810,6 +813,8 @@ class L10nService {
|
|
|
810
813
|
// Global dictionaries are available before the first `use()` call, so TranslateHttpLoader is never asked for them.
|
|
811
814
|
L10nService.registerTranslations(globalTranslations);
|
|
812
815
|
Object.entries(globalTranslations).forEach(([lang, translations]) => this.mergeTranslation(lang, translations));
|
|
816
|
+
// The first day of the week is a user setting, it overrides the value of the language dictionary.
|
|
817
|
+
effect(() => this.primeNg.setTranslation({ firstDayOfWeek: this.layoutService.firstDayOfWeek() }));
|
|
813
818
|
// Static translations are merged once per language, so they have to be re-merged on every language change.
|
|
814
819
|
this.translateService.onLangChange.subscribe((event) => {
|
|
815
820
|
L10nService.staticTranslations.forEach((byLang) => {
|
|
@@ -904,7 +909,7 @@ class L10nService {
|
|
|
904
909
|
if (key) {
|
|
905
910
|
this.get(key);
|
|
906
911
|
}
|
|
907
|
-
this.translateService.use(selectedLanguage);
|
|
912
|
+
this.translateService.use(selectedLanguage).subscribe(() => this.applyPrimeNgTranslation());
|
|
908
913
|
}
|
|
909
914
|
init(languages) {
|
|
910
915
|
this.availableLanguages = languages;
|
|
@@ -913,9 +918,17 @@ class L10nService {
|
|
|
913
918
|
this.translateService.setDefaultLang(lang);
|
|
914
919
|
this.translateService.use(lang).subscribe(() => {
|
|
915
920
|
this.loadComponentTranslations('app-info');
|
|
916
|
-
this.
|
|
921
|
+
this.applyPrimeNgTranslation();
|
|
917
922
|
});
|
|
918
923
|
}
|
|
924
|
+
/**
|
|
925
|
+
* Passes the PrimeNG dictionary of the current language to PrimeNG, keeping the user's first day of the week
|
|
926
|
+
*/
|
|
927
|
+
applyPrimeNgTranslation() {
|
|
928
|
+
this.translateService
|
|
929
|
+
.get('primeng')
|
|
930
|
+
.subscribe((res) => this.primeNg.setTranslation({ ...res, firstDayOfWeek: this.layoutService.firstDayOfWeek() }));
|
|
931
|
+
}
|
|
919
932
|
instant(key, interpolateParams) {
|
|
920
933
|
return this.translateService.instant(key, interpolateParams);
|
|
921
934
|
}
|
|
@@ -1001,7 +1014,9 @@ class BffSecurityService {
|
|
|
1001
1014
|
authorize(returnUrl) {
|
|
1002
1015
|
const normalizedReturnUrl = this.normalizeReturnUrl(returnUrl);
|
|
1003
1016
|
this.replaceWithUnauthorizedUrl(normalizedReturnUrl);
|
|
1004
|
-
|
|
1017
|
+
// The return url travels with the request: when a guard rejects the initial navigation, the router
|
|
1018
|
+
// resets the address after this call, so the page address sent as Referer no longer carries it.
|
|
1019
|
+
const form = this.createPostForm(this.buildUrl(`api/security/create-auth-session?returnUrl=${encodeURIComponent(normalizedReturnUrl)}`));
|
|
1005
1020
|
document.body.appendChild(form);
|
|
1006
1021
|
form.submit();
|
|
1007
1022
|
}
|
|
@@ -1891,9 +1906,10 @@ class SecurityApi extends HttpClient {
|
|
|
1891
1906
|
format: "json",
|
|
1892
1907
|
...params,
|
|
1893
1908
|
});
|
|
1894
|
-
this.createAuthSession = (params = {}) => this.request({
|
|
1909
|
+
this.createAuthSession = (query, params = {}) => this.request({
|
|
1895
1910
|
path: `/api/security/create-auth-session`,
|
|
1896
1911
|
method: "POST",
|
|
1912
|
+
query: query,
|
|
1897
1913
|
secure: true,
|
|
1898
1914
|
...params,
|
|
1899
1915
|
});
|
|
@@ -2043,14 +2059,14 @@ class SecurityComponent {
|
|
|
2043
2059
|
<div class="font-semibold text-xl">
|
|
2044
2060
|
{{ 'securityComponent.security' | translate }}
|
|
2045
2061
|
</div>
|
|
2046
|
-
@for (item of securityData; track item.
|
|
2062
|
+
@for (item of securityData; track item.code) {
|
|
2047
2063
|
<div class="flex flex-col gap-2">
|
|
2048
|
-
<label htmlFor="oip-security-multiselect-{{ item.
|
|
2064
|
+
<label htmlFor="oip-security-multiselect-{{ item.code }}">
|
|
2049
2065
|
{{ item.name }}
|
|
2050
2066
|
<span class="pi pi-question-circle" pTooltip="{{ item.description }}" tooltipPosition="right"></span>
|
|
2051
2067
|
</label>
|
|
2052
2068
|
<p-multiSelect
|
|
2053
|
-
id="oip-security-multiselect-{{ item.
|
|
2069
|
+
id="oip-security-multiselect-{{ item.code }}"
|
|
2054
2070
|
placeholder="{{ 'securityComponent.selectRoles' | translate }}"
|
|
2055
2071
|
[maxSelectedLabels]="10"
|
|
2056
2072
|
[options]="roles"
|
|
@@ -2081,14 +2097,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
2081
2097
|
<div class="font-semibold text-xl">
|
|
2082
2098
|
{{ 'securityComponent.security' | translate }}
|
|
2083
2099
|
</div>
|
|
2084
|
-
@for (item of securityData; track item.
|
|
2100
|
+
@for (item of securityData; track item.code) {
|
|
2085
2101
|
<div class="flex flex-col gap-2">
|
|
2086
|
-
<label htmlFor="oip-security-multiselect-{{ item.
|
|
2102
|
+
<label htmlFor="oip-security-multiselect-{{ item.code }}">
|
|
2087
2103
|
{{ item.name }}
|
|
2088
2104
|
<span class="pi pi-question-circle" pTooltip="{{ item.description }}" tooltipPosition="right"></span>
|
|
2089
2105
|
</label>
|
|
2090
2106
|
<p-multiSelect
|
|
2091
|
-
id="oip-security-multiselect-{{ item.
|
|
2107
|
+
id="oip-security-multiselect-{{ item.code }}"
|
|
2092
2108
|
placeholder="{{ 'securityComponent.selectRoles' | translate }}"
|
|
2093
2109
|
[maxSelectedLabels]="10"
|
|
2094
2110
|
[options]="roles"
|
|
@@ -2905,11 +2921,18 @@ class UserService {
|
|
|
2905
2921
|
}
|
|
2906
2922
|
this.requestedPhotoKey = photoKey;
|
|
2907
2923
|
this.userProfileApi.getUserPhoto().then((data) => {
|
|
2908
|
-
|
|
2924
|
+
// 204 No Content comes back as an empty blob: the user hasn't uploaded a photo yet,
|
|
2925
|
+
// so the avatar falls back to initials.
|
|
2926
|
+
const photo = data;
|
|
2927
|
+
if (!photo?.size) {
|
|
2928
|
+
this.photo = null;
|
|
2929
|
+
this.photoLoaded = false;
|
|
2930
|
+
return;
|
|
2931
|
+
}
|
|
2932
|
+
this.createImageFromBlob(photo);
|
|
2909
2933
|
this.photoLoaded = true;
|
|
2910
2934
|
}, (error) => {
|
|
2911
|
-
//
|
|
2912
|
-
// that's an expected state, not a failure, so fall back to initials silently.
|
|
2935
|
+
// Older backends answer 404 when there is no photo — that's an expected state, not a failure.
|
|
2913
2936
|
if (error?.status !== 404) {
|
|
2914
2937
|
this.msgService.errorFromException(error, this.translateService.instant('userService.failedToLoadPhoto'));
|
|
2915
2938
|
}
|
|
@@ -3115,6 +3138,15 @@ class NotificationApi extends HttpClient {
|
|
|
3115
3138
|
format: "json",
|
|
3116
3139
|
...params,
|
|
3117
3140
|
});
|
|
3141
|
+
this.createTestNotification = (data, params = {}) => this.request({
|
|
3142
|
+
path: `/api/notification/create-test-notification`,
|
|
3143
|
+
method: "POST",
|
|
3144
|
+
body: data,
|
|
3145
|
+
secure: true,
|
|
3146
|
+
type: ContentType.Json,
|
|
3147
|
+
format: "json",
|
|
3148
|
+
...params,
|
|
3149
|
+
});
|
|
3118
3150
|
}
|
|
3119
3151
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationApi, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3120
3152
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationApi }); }
|
|
@@ -3325,10 +3357,10 @@ class UserNotificationsComponent {
|
|
|
3325
3357
|
} @else {
|
|
3326
3358
|
<div class="flex flex-col gap-3 max-h-[26rem] overflow-y-auto pr-1">
|
|
3327
3359
|
@for (notification of notifications; track notification.notificationUserId) {
|
|
3328
|
-
<div class="border border-surface-200 dark:border-surface-700 rounded-md p-3">
|
|
3360
|
+
<div class="border border-surface-200 dark:border-surface-700 rounded-md p-3" qa-id="oip-user-notifications-item">
|
|
3329
3361
|
<div class="flex items-start justify-between gap-3">
|
|
3330
3362
|
<div class="min-w-0">
|
|
3331
|
-
<div class="font-medium leading-snug break-words">
|
|
3363
|
+
<div class="font-medium leading-snug break-words" qa-id="oip-user-notifications-subject">
|
|
3332
3364
|
{{ notification.subject }}
|
|
3333
3365
|
</div>
|
|
3334
3366
|
<div class="text-xs text-surface-500 mt-1">
|
|
@@ -3350,6 +3382,7 @@ class UserNotificationsComponent {
|
|
|
3350
3382
|
<div class="flex justify-end mt-3">
|
|
3351
3383
|
<p-button
|
|
3352
3384
|
icon="pi pi-check"
|
|
3385
|
+
qa-id="oip-user-notifications-mark-as-read"
|
|
3353
3386
|
size="small"
|
|
3354
3387
|
[label]="'userNotifications.markAsRead' | translate"
|
|
3355
3388
|
[loading]="readingNotificationId === notification.notificationUserId"
|
|
@@ -3361,6 +3394,7 @@ class UserNotificationsComponent {
|
|
|
3361
3394
|
|
|
3362
3395
|
<p-paginator
|
|
3363
3396
|
class="mt-3"
|
|
3397
|
+
qa-id="oip-user-notifications-paginator"
|
|
3364
3398
|
[first]="skip"
|
|
3365
3399
|
[rows]="take"
|
|
3366
3400
|
[rowsPerPageOptions]="[5, 10, 20]"
|
|
@@ -3430,10 +3464,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
3430
3464
|
} @else {
|
|
3431
3465
|
<div class="flex flex-col gap-3 max-h-[26rem] overflow-y-auto pr-1">
|
|
3432
3466
|
@for (notification of notifications; track notification.notificationUserId) {
|
|
3433
|
-
<div class="border border-surface-200 dark:border-surface-700 rounded-md p-3">
|
|
3467
|
+
<div class="border border-surface-200 dark:border-surface-700 rounded-md p-3" qa-id="oip-user-notifications-item">
|
|
3434
3468
|
<div class="flex items-start justify-between gap-3">
|
|
3435
3469
|
<div class="min-w-0">
|
|
3436
|
-
<div class="font-medium leading-snug break-words">
|
|
3470
|
+
<div class="font-medium leading-snug break-words" qa-id="oip-user-notifications-subject">
|
|
3437
3471
|
{{ notification.subject }}
|
|
3438
3472
|
</div>
|
|
3439
3473
|
<div class="text-xs text-surface-500 mt-1">
|
|
@@ -3455,6 +3489,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
3455
3489
|
<div class="flex justify-end mt-3">
|
|
3456
3490
|
<p-button
|
|
3457
3491
|
icon="pi pi-check"
|
|
3492
|
+
qa-id="oip-user-notifications-mark-as-read"
|
|
3458
3493
|
size="small"
|
|
3459
3494
|
[label]="'userNotifications.markAsRead' | translate"
|
|
3460
3495
|
[loading]="readingNotificationId === notification.notificationUserId"
|
|
@@ -3466,6 +3501,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
3466
3501
|
|
|
3467
3502
|
<p-paginator
|
|
3468
3503
|
class="mt-3"
|
|
3504
|
+
qa-id="oip-user-notifications-paginator"
|
|
3469
3505
|
[first]="skip"
|
|
3470
3506
|
[rows]="take"
|
|
3471
3507
|
[rowsPerPageOptions]="[5, 10, 20]"
|
|
@@ -3493,6 +3529,13 @@ class ApplicationsApi extends HttpClient {
|
|
|
3493
3529
|
format: "json",
|
|
3494
3530
|
...params,
|
|
3495
3531
|
});
|
|
3532
|
+
this.getAllApplicationRegistryItems = (params = {}) => this.request({
|
|
3533
|
+
path: `/api/applications/get-all-application-registry-items`,
|
|
3534
|
+
method: "GET",
|
|
3535
|
+
secure: true,
|
|
3536
|
+
format: "json",
|
|
3537
|
+
...params,
|
|
3538
|
+
});
|
|
3496
3539
|
this.getApplicationRegistryItemByCode = ({ code, ...query }, params = {}) => this.request({
|
|
3497
3540
|
path: `/api/applications/get-application-registry-item-by-code/${code}`,
|
|
3498
3541
|
method: "GET",
|
|
@@ -4037,6 +4080,13 @@ class MenuApi extends HttpClient {
|
|
|
4037
4080
|
secure: true,
|
|
4038
4081
|
...params,
|
|
4039
4082
|
});
|
|
4083
|
+
this.copyModuleInstance = ({ id, ...query }, params = {}) => this.request({
|
|
4084
|
+
path: `/api/menu/copy-module-instance/${id}`,
|
|
4085
|
+
method: "POST",
|
|
4086
|
+
secure: true,
|
|
4087
|
+
format: "json",
|
|
4088
|
+
...params,
|
|
4089
|
+
});
|
|
4040
4090
|
this.changeOrder = (query, params = {}) => this.request({
|
|
4041
4091
|
path: `/api/menu/change-order`,
|
|
4042
4092
|
method: "POST",
|
|
@@ -4191,9 +4241,9 @@ class StartPageService {
|
|
|
4191
4241
|
if (item.separator) {
|
|
4192
4242
|
continue;
|
|
4193
4243
|
}
|
|
4194
|
-
if (item.items?.length) {
|
|
4244
|
+
if (item.isFolder || item.items?.length) {
|
|
4195
4245
|
// A folder is never a landing page itself, its children are.
|
|
4196
|
-
result.push(...this.collectNavigableLeaves(item.items));
|
|
4246
|
+
result.push(...this.collectNavigableLeaves(item.items ?? []));
|
|
4197
4247
|
continue;
|
|
4198
4248
|
}
|
|
4199
4249
|
// A module without a real route would resolve back to the empty path and loop.
|
|
@@ -4318,13 +4368,22 @@ class MenuItemComponent {
|
|
|
4318
4368
|
{
|
|
4319
4369
|
label: this.localization.new,
|
|
4320
4370
|
icon: PrimeIcons.PLUS,
|
|
4321
|
-
command: (event) => this.newClick(event)
|
|
4371
|
+
command: (event) => this.newClick(event),
|
|
4372
|
+
// Only a folder can have child items.
|
|
4373
|
+
visible: !!item.isFolder
|
|
4322
4374
|
},
|
|
4323
4375
|
{
|
|
4324
4376
|
label: this.localization.edit,
|
|
4325
4377
|
icon: PrimeIcons.FILE_EDIT,
|
|
4326
4378
|
command: (event) => this.editClick(event)
|
|
4327
4379
|
},
|
|
4380
|
+
{
|
|
4381
|
+
label: this.localization.copy,
|
|
4382
|
+
icon: PrimeIcons.COPY,
|
|
4383
|
+
command: () => this.copyItem(item),
|
|
4384
|
+
// Only a leaf instance can be copied, folders with children are not supported.
|
|
4385
|
+
visible: !item.items?.length
|
|
4386
|
+
},
|
|
4328
4387
|
{ separator: true },
|
|
4329
4388
|
{
|
|
4330
4389
|
label: this.localization.delete,
|
|
@@ -4356,10 +4415,10 @@ class MenuItemComponent {
|
|
|
4356
4415
|
this.contextMenu.show($event);
|
|
4357
4416
|
}
|
|
4358
4417
|
/**
|
|
4359
|
-
* Builds the start page entries of the context menu. Only a navigable
|
|
4418
|
+
* Builds the start page entries of the context menu. Only a navigable non-folder item can be a start page.
|
|
4360
4419
|
*/
|
|
4361
4420
|
getStartModuleItems(item) {
|
|
4362
|
-
if (!item?.routerLink || item.items?.length) {
|
|
4421
|
+
if (!item?.routerLink || item.isFolder || item.items?.length) {
|
|
4363
4422
|
return [];
|
|
4364
4423
|
}
|
|
4365
4424
|
return item.isStart
|
|
@@ -4388,6 +4447,11 @@ class MenuItemComponent {
|
|
|
4388
4447
|
this.msgService.success(this.localization.unsetStartModuleSuccessMessage);
|
|
4389
4448
|
await this.menuService.loadMenu();
|
|
4390
4449
|
}
|
|
4450
|
+
async copyItem(item) {
|
|
4451
|
+
await this.menuDataService.copyModuleInstance({ id: item.moduleInstanceId });
|
|
4452
|
+
this.msgService.success(this.localization.copyItemSuccessMessage);
|
|
4453
|
+
await this.menuService.loadMenu();
|
|
4454
|
+
}
|
|
4391
4455
|
deleteItem(event) {
|
|
4392
4456
|
this.confirmationService.confirm({
|
|
4393
4457
|
header: this.localization.deleteItemConfirmHeader,
|
|
@@ -4677,6 +4741,7 @@ class MenuItemCreateDialogComponent {
|
|
|
4677
4741
|
this.msgService = inject(MsgService);
|
|
4678
4742
|
this.visibleChange = new EventEmitter();
|
|
4679
4743
|
this.modules = [];
|
|
4744
|
+
this.moduleOptions = [];
|
|
4680
4745
|
this.iconOptions = Object.values(PrimeIcons)
|
|
4681
4746
|
.filter((icon) => typeof icon === 'string')
|
|
4682
4747
|
.map((icon) => ({
|
|
@@ -4684,14 +4749,35 @@ class MenuItemCreateDialogComponent {
|
|
|
4684
4749
|
value: icon
|
|
4685
4750
|
}))
|
|
4686
4751
|
.sort((left, right) => left.label.localeCompare(right.label));
|
|
4687
|
-
this.selectIcon =
|
|
4752
|
+
this.selectIcon = MenuItemCreateDialogComponent.defaultIcon;
|
|
4688
4753
|
this.saving = false;
|
|
4689
4754
|
}
|
|
4755
|
+
static { this.defaultIcon = 'pi pi-box'; }
|
|
4690
4756
|
get canSave() {
|
|
4691
4757
|
return !this.saving && !!this.selectModule;
|
|
4692
4758
|
}
|
|
4693
4759
|
async ngOnInit() {
|
|
4694
4760
|
this.modules = await this.menu.getModules();
|
|
4761
|
+
this.updateModuleOptions();
|
|
4762
|
+
}
|
|
4763
|
+
/**
|
|
4764
|
+
* Restricts the module list to the folder when the item is created at the menu root,
|
|
4765
|
+
* since only a folder can be placed there.
|
|
4766
|
+
*/
|
|
4767
|
+
updateModuleOptions() {
|
|
4768
|
+
const isRoot = !this.menuService.contextMenuItem;
|
|
4769
|
+
this.moduleOptions = isRoot ? this.modules.filter((module) => module.isFolder) : this.modules;
|
|
4770
|
+
if (isRoot && this.moduleOptions.length === 1) {
|
|
4771
|
+
this.selectModule = this.moduleOptions[0].key;
|
|
4772
|
+
this.onModuleChange(this.selectModule);
|
|
4773
|
+
}
|
|
4774
|
+
else if (!this.moduleOptions.some((module) => module.key === this.selectModule)) {
|
|
4775
|
+
this.selectModule = undefined;
|
|
4776
|
+
}
|
|
4777
|
+
}
|
|
4778
|
+
onModuleChange(moduleId) {
|
|
4779
|
+
const module = this.modules.find((item) => item.key === moduleId);
|
|
4780
|
+
this.selectIcon = module?.icon || MenuItemCreateDialogComponent.defaultIcon;
|
|
4695
4781
|
}
|
|
4696
4782
|
changeVisible() {
|
|
4697
4783
|
this.visible = !this.visible;
|
|
@@ -4728,6 +4814,7 @@ class MenuItemCreateDialogComponent {
|
|
|
4728
4814
|
this.visibleChange.emit(this.visible);
|
|
4729
4815
|
}
|
|
4730
4816
|
showDialog() {
|
|
4817
|
+
this.updateModuleOptions();
|
|
4731
4818
|
this.visible = true;
|
|
4732
4819
|
this.visibleChange.emit(this.visible);
|
|
4733
4820
|
}
|
|
@@ -4774,8 +4861,9 @@ class MenuItemCreateDialogComponent {
|
|
|
4774
4861
|
placeholder="{{ 'menuItemCreateDialogComponent.selectModule' | translate }}"
|
|
4775
4862
|
scrollHeight="18rem"
|
|
4776
4863
|
[filter]="true"
|
|
4777
|
-
[options]="
|
|
4778
|
-
[(ngModel)]="selectModule"
|
|
4864
|
+
[options]="moduleOptions"
|
|
4865
|
+
[(ngModel)]="selectModule"
|
|
4866
|
+
(ngModelChange)="onModuleChange($event)" />
|
|
4779
4867
|
</div>
|
|
4780
4868
|
<div class="flex items-center gap-4 mb-4">
|
|
4781
4869
|
<label class="font-semibold w-1/3" for="oip-menu-item-create-dialog-icon">
|
|
@@ -4871,8 +4959,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
4871
4959
|
placeholder="{{ 'menuItemCreateDialogComponent.selectModule' | translate }}"
|
|
4872
4960
|
scrollHeight="18rem"
|
|
4873
4961
|
[filter]="true"
|
|
4874
|
-
[options]="
|
|
4875
|
-
[(ngModel)]="selectModule"
|
|
4962
|
+
[options]="moduleOptions"
|
|
4963
|
+
[(ngModel)]="selectModule"
|
|
4964
|
+
(ngModelChange)="onModuleChange($event)" />
|
|
4876
4965
|
</div>
|
|
4877
4966
|
<div class="flex items-center gap-4 mb-4">
|
|
4878
4967
|
<label class="font-semibold w-1/3" for="oip-menu-item-create-dialog-icon">
|
|
@@ -5197,6 +5286,8 @@ var menuComponent$1 = {
|
|
|
5197
5286
|
var menuItemComponent$1 = {
|
|
5198
5287
|
"new": "Add",
|
|
5199
5288
|
edit: "Edit",
|
|
5289
|
+
copy: "Copy",
|
|
5290
|
+
copyItemSuccessMessage: "Copied successfully",
|
|
5200
5291
|
"delete": "Delete",
|
|
5201
5292
|
deleteItemConfirmHeader: "Delete",
|
|
5202
5293
|
deleteItemConfirmMessage: "Are you sure you want to delete the item?",
|
|
@@ -5246,6 +5337,8 @@ var menuComponent = {
|
|
|
5246
5337
|
var menuItemComponent = {
|
|
5247
5338
|
"new": "Добавить",
|
|
5248
5339
|
edit: "Редактировать",
|
|
5340
|
+
copy: "Копировать",
|
|
5341
|
+
copyItemSuccessMessage: "Успешно скопировано",
|
|
5249
5342
|
"delete": "Удалить",
|
|
5250
5343
|
deleteItemConfirmHeader: "Удаление",
|
|
5251
5344
|
deleteItemConfirmMessage: "Вы уверены что хотите удалить элемент?",
|
|
@@ -6534,16 +6627,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6534
6627
|
}]
|
|
6535
6628
|
}] });
|
|
6536
6629
|
|
|
6537
|
-
var userProfile_component = /*#__PURE__*/Object.freeze({
|
|
6538
|
-
__proto__: null,
|
|
6539
|
-
UserProfileComponent: UserProfileComponent
|
|
6540
|
-
});
|
|
6541
|
-
|
|
6542
6630
|
var config$1 = {
|
|
6543
6631
|
all: "All",
|
|
6544
6632
|
applicationManagement: "Application management",
|
|
6545
6633
|
dateFormat: "Date format",
|
|
6546
6634
|
dateTimeFormat: "Date and time format:",
|
|
6635
|
+
firstDayOfWeek: "First day of the week",
|
|
6547
6636
|
goTo: "Go to",
|
|
6548
6637
|
localization: "Localization",
|
|
6549
6638
|
menu: "Menu",
|
|
@@ -6565,6 +6654,7 @@ var config = {
|
|
|
6565
6654
|
applicationManagement: "Управление приложениями",
|
|
6566
6655
|
dateFormat: "Формат даты",
|
|
6567
6656
|
dateTimeFormat: "Формат даты и времени:",
|
|
6657
|
+
firstDayOfWeek: "Первый день недели",
|
|
6568
6658
|
goTo: "Перейти",
|
|
6569
6659
|
localization: "Локализация",
|
|
6570
6660
|
menu: "Меню",
|
|
@@ -6593,10 +6683,20 @@ class ConfigComponent {
|
|
|
6593
6683
|
this.timeFormats = ['HH:mm:ss', 'HH:mm'];
|
|
6594
6684
|
// @ts-ignore
|
|
6595
6685
|
this.allTimeZones = Intl.supportedValuesOf('timeZone');
|
|
6686
|
+
/** Days of the week starting from Monday, named in the current language. */
|
|
6687
|
+
this.weekDays = computed(() => {
|
|
6688
|
+
const format = new Intl.DateTimeFormat(this.layoutService.language() ?? 'en', { weekday: 'long' });
|
|
6689
|
+
// 1 January 2024 is a Monday, so day N of that week falls on N January (Sunday - on 7 January).
|
|
6690
|
+
return [1, 2, 3, 4, 5, 6, 0].map((day) => {
|
|
6691
|
+
const name = format.format(new Date(2024, 0, day || 7));
|
|
6692
|
+
return { value: day, label: name.charAt(0).toUpperCase() + name.slice(1) };
|
|
6693
|
+
});
|
|
6694
|
+
}, ...(ngDevMode ? [{ debugName: "weekDays" }] : []));
|
|
6596
6695
|
this.selectedLanguage = this.layoutService.language();
|
|
6597
6696
|
this.selectedDateFormat = this.layoutService.dateFormat();
|
|
6598
6697
|
this.selectedTimeFormat = this.layoutService.timeFormat();
|
|
6599
6698
|
this.selectedTimeZone = this.layoutService.timeZone();
|
|
6699
|
+
this.selectedFirstDayOfWeek = this.layoutService.firstDayOfWeek();
|
|
6600
6700
|
}
|
|
6601
6701
|
changeLanguage() {
|
|
6602
6702
|
this.layoutService.layoutConfig.update((config) => ({
|
|
@@ -6611,6 +6711,9 @@ class ConfigComponent {
|
|
|
6611
6711
|
changeTimeFormat() {
|
|
6612
6712
|
this.layoutService.layoutConfig.update((config) => ({ ...config, timeFormat: this.selectedTimeFormat }));
|
|
6613
6713
|
}
|
|
6714
|
+
changeFirstDayOfWeek() {
|
|
6715
|
+
this.layoutService.layoutConfig.update((config) => ({ ...config, firstDayOfWeek: this.selectedFirstDayOfWeek }));
|
|
6716
|
+
}
|
|
6614
6717
|
changeTimeZone() {
|
|
6615
6718
|
this.layoutService.layoutConfig.update((config) => ({ ...config, timeZone: this.selectedTimeZone }));
|
|
6616
6719
|
}
|
|
@@ -6681,6 +6784,16 @@ class ConfigComponent {
|
|
|
6681
6784
|
[placeholder]="'config.timeFormat' | translate"
|
|
6682
6785
|
[(ngModel)]="selectedTimeFormat"
|
|
6683
6786
|
(onChange)="changeTimeFormat()" />
|
|
6787
|
+
<div class="mt-5">{{ 'config.firstDayOfWeek' | translate }}</div>
|
|
6788
|
+
<p-select
|
|
6789
|
+
class="w-full md:w-56"
|
|
6790
|
+
optionLabel="label"
|
|
6791
|
+
optionValue="value"
|
|
6792
|
+
qa-id="oip-app-config-first-day-of-week-select"
|
|
6793
|
+
[options]="weekDays()"
|
|
6794
|
+
[placeholder]="'config.firstDayOfWeek' | translate"
|
|
6795
|
+
[(ngModel)]="selectedFirstDayOfWeek"
|
|
6796
|
+
(onChange)="changeFirstDayOfWeek()" />
|
|
6684
6797
|
<div class="mt-5">{{ 'config.timeZone' | translate }}</div>
|
|
6685
6798
|
<p-select
|
|
6686
6799
|
class="w-full md:w-56"
|
|
@@ -6799,6 +6912,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6799
6912
|
[placeholder]="'config.timeFormat' | translate"
|
|
6800
6913
|
[(ngModel)]="selectedTimeFormat"
|
|
6801
6914
|
(onChange)="changeTimeFormat()" />
|
|
6915
|
+
<div class="mt-5">{{ 'config.firstDayOfWeek' | translate }}</div>
|
|
6916
|
+
<p-select
|
|
6917
|
+
class="w-full md:w-56"
|
|
6918
|
+
optionLabel="label"
|
|
6919
|
+
optionValue="value"
|
|
6920
|
+
qa-id="oip-app-config-first-day-of-week-select"
|
|
6921
|
+
[options]="weekDays()"
|
|
6922
|
+
[placeholder]="'config.firstDayOfWeek' | translate"
|
|
6923
|
+
[(ngModel)]="selectedFirstDayOfWeek"
|
|
6924
|
+
(onChange)="changeFirstDayOfWeek()" />
|
|
6802
6925
|
<div class="mt-5">{{ 'config.timeZone' | translate }}</div>
|
|
6803
6926
|
<p-select
|
|
6804
6927
|
class="w-full md:w-56"
|
|
@@ -8379,7 +8502,7 @@ var applications$1 = {
|
|
|
8379
8502
|
"delete": "Delete"
|
|
8380
8503
|
},
|
|
8381
8504
|
messages: {
|
|
8382
|
-
requiredFields: "Fill code, name and Base URL",
|
|
8505
|
+
requiredFields: "Fill code, name, Base URL and Internal Base URL",
|
|
8383
8506
|
createSuccess: "Application created",
|
|
8384
8507
|
updateSuccess: "Application updated",
|
|
8385
8508
|
deleteSuccess: "Application deleted"
|
|
@@ -8425,7 +8548,7 @@ var applications = {
|
|
|
8425
8548
|
"delete": "Удалить"
|
|
8426
8549
|
},
|
|
8427
8550
|
messages: {
|
|
8428
|
-
requiredFields: "Заполните код,
|
|
8551
|
+
requiredFields: "Заполните код, название, Base URL и Internal Base URL",
|
|
8429
8552
|
createSuccess: "Приложение создано",
|
|
8430
8553
|
updateSuccess: "Приложение обновлено",
|
|
8431
8554
|
deleteSuccess: "Приложение удалено"
|
|
@@ -8473,7 +8596,7 @@ class ApplicationsComponent {
|
|
|
8473
8596
|
this.loading = true;
|
|
8474
8597
|
this.cancelAllEdits();
|
|
8475
8598
|
try {
|
|
8476
|
-
this.applications = (await this.applicationsApi.
|
|
8599
|
+
this.applications = (await this.applicationsApi.getAllApplicationRegistryItems()).map((application) => ({ ...application }));
|
|
8477
8600
|
this.syncVisibleApplications();
|
|
8478
8601
|
}
|
|
8479
8602
|
catch (error) {
|
|
@@ -8533,7 +8656,7 @@ class ApplicationsComponent {
|
|
|
8533
8656
|
return;
|
|
8534
8657
|
}
|
|
8535
8658
|
const request = this.normalizeEditModel(editModel);
|
|
8536
|
-
if (!request.code || !request.displayName || !request.baseUrl) {
|
|
8659
|
+
if (!request.code || !request.displayName || !request.baseUrl || !request.internalBaseUrl) {
|
|
8537
8660
|
this.msgService.error(this.t('applications.messages.requiredFields'));
|
|
8538
8661
|
return;
|
|
8539
8662
|
}
|
|
@@ -9783,6 +9906,7 @@ class DiscussionComponent {
|
|
|
9783
9906
|
<textarea
|
|
9784
9907
|
class="min-h-28 w-full"
|
|
9785
9908
|
pTextarea
|
|
9909
|
+
qa-id="oip-discussion-new-comment"
|
|
9786
9910
|
rows="5"
|
|
9787
9911
|
[autoResize]="true"
|
|
9788
9912
|
[placeholder]="'discussionComponent.writeCommentPlaceholder' | translate"
|
|
@@ -9806,6 +9930,7 @@ class DiscussionComponent {
|
|
|
9806
9930
|
<div class="flex flex-col gap-3">
|
|
9807
9931
|
@for (candidate of mentionSuggestions; track candidate.userId) {
|
|
9808
9932
|
<button
|
|
9933
|
+
qa-id="oip-discussion-mention-suggestion"
|
|
9809
9934
|
class="flex w-full items-center justify-between gap-4 rounded-xl border border-transparent px-3 py-3 text-left transition hover:border-primary-200 hover:bg-primary-50 dark:hover:border-primary-800 dark:hover:bg-primary-950/30"
|
|
9810
9935
|
type="button"
|
|
9811
9936
|
(click)="insertMention(candidate)">
|
|
@@ -9824,7 +9949,8 @@ class DiscussionComponent {
|
|
|
9824
9949
|
<div class="flex flex-col gap-3">
|
|
9825
9950
|
@for (file of pendingFiles; track file.name + file.size) {
|
|
9826
9951
|
<div
|
|
9827
|
-
class="flex flex-col gap-3 rounded-2xl border border-surface-200 px-4 py-3 sm:flex-row sm:items-center sm:justify-between dark:border-surface-700"
|
|
9952
|
+
class="flex flex-col gap-3 rounded-2xl border border-surface-200 px-4 py-3 sm:flex-row sm:items-center sm:justify-between dark:border-surface-700"
|
|
9953
|
+
qa-id="oip-discussion-pending-file">
|
|
9828
9954
|
<div class="inline-flex items-center gap-2">
|
|
9829
9955
|
<i class="pi pi-file"></i>
|
|
9830
9956
|
<span class="break-all">{{ file.name }}</span>
|
|
@@ -9857,10 +9983,11 @@ class DiscussionComponent {
|
|
|
9857
9983
|
severity="secondary"
|
|
9858
9984
|
[label]="'discussionComponent.attachFiles' | translate"
|
|
9859
9985
|
[text]="true" />
|
|
9860
|
-
<input multiple type="file" (change)="onFilesSelected($event)" />
|
|
9986
|
+
<input multiple qa-id="oip-discussion-attach-input" type="file" (change)="onFilesSelected($event)" />
|
|
9861
9987
|
</label>
|
|
9862
9988
|
<p-button
|
|
9863
9989
|
icon="pi pi-send"
|
|
9990
|
+
qa-id="oip-discussion-send"
|
|
9864
9991
|
[disabled]="submitting || !newComment.trim()"
|
|
9865
9992
|
[label]="'discussionComponent.send' | translate"
|
|
9866
9993
|
[loading]="submitting"
|
|
@@ -9884,7 +10011,7 @@ class DiscussionComponent {
|
|
|
9884
10011
|
} @else {
|
|
9885
10012
|
<div class="flex flex-col gap-4">
|
|
9886
10013
|
@for (comment of comments; track comment.commentId) {
|
|
9887
|
-
<p-card class="block">
|
|
10014
|
+
<p-card class="block" qa-id="oip-discussion-comment">
|
|
9888
10015
|
<ng-template pTemplate="content">
|
|
9889
10016
|
<div class="grid gap-4 md:grid-cols-[3.2rem_minmax(0,1fr)]">
|
|
9890
10017
|
<div>
|
|
@@ -9905,6 +10032,7 @@ class DiscussionComponent {
|
|
|
9905
10032
|
@if (comment.isEdited) {
|
|
9906
10033
|
<p-tag
|
|
9907
10034
|
icon="pi pi-pencil"
|
|
10035
|
+
qa-id="oip-discussion-comment-edited"
|
|
9908
10036
|
severity="warn"
|
|
9909
10037
|
[value]="'discussionComponent.edited' | translate" />
|
|
9910
10038
|
}
|
|
@@ -9912,6 +10040,7 @@ class DiscussionComponent {
|
|
|
9912
10040
|
@if (comment.canEdit) {
|
|
9913
10041
|
<p-button
|
|
9914
10042
|
icon="pi pi-pencil"
|
|
10043
|
+
qa-id="oip-discussion-comment-edit"
|
|
9915
10044
|
severity="secondary"
|
|
9916
10045
|
[rounded]="true"
|
|
9917
10046
|
[text]="true"
|
|
@@ -9920,6 +10049,7 @@ class DiscussionComponent {
|
|
|
9920
10049
|
@if (comment.historyCount > 0) {
|
|
9921
10050
|
<p-button
|
|
9922
10051
|
icon="pi pi-history"
|
|
10052
|
+
qa-id="oip-discussion-comment-history"
|
|
9923
10053
|
severity="secondary"
|
|
9924
10054
|
[rounded]="true"
|
|
9925
10055
|
[text]="true"
|
|
@@ -9928,6 +10058,7 @@ class DiscussionComponent {
|
|
|
9928
10058
|
@if (comment.canDelete) {
|
|
9929
10059
|
<p-button
|
|
9930
10060
|
icon="pi pi-trash"
|
|
10061
|
+
qa-id="oip-discussion-comment-delete"
|
|
9931
10062
|
severity="danger"
|
|
9932
10063
|
[rounded]="true"
|
|
9933
10064
|
[text]="true"
|
|
@@ -9940,6 +10071,7 @@ class DiscussionComponent {
|
|
|
9940
10071
|
<textarea
|
|
9941
10072
|
class="min-h-24 w-full"
|
|
9942
10073
|
pTextarea
|
|
10074
|
+
qa-id="oip-discussion-edit-content"
|
|
9943
10075
|
rows="4"
|
|
9944
10076
|
[autoResize]="true"
|
|
9945
10077
|
[placeholder]="'discussionComponent.editCommentPlaceholder' | translate"
|
|
@@ -9958,6 +10090,7 @@ class DiscussionComponent {
|
|
|
9958
10090
|
|
|
9959
10091
|
<p-button
|
|
9960
10092
|
icon="pi pi-check"
|
|
10093
|
+
qa-id="oip-discussion-edit-save"
|
|
9961
10094
|
[disabled]="!editContent.trim()"
|
|
9962
10095
|
[label]="'discussionComponent.save' | translate"
|
|
9963
10096
|
(onClick)="saveEdit(comment)" />
|
|
@@ -9970,17 +10103,23 @@ class DiscussionComponent {
|
|
|
9970
10103
|
</div>
|
|
9971
10104
|
</div>
|
|
9972
10105
|
} @else {
|
|
9973
|
-
<div
|
|
10106
|
+
<div
|
|
10107
|
+
class="markdown-preview"
|
|
10108
|
+
qa-id="oip-discussion-comment-content"
|
|
10109
|
+
[innerHTML]="renderMarkdown(comment.content)"></div>
|
|
9974
10110
|
}
|
|
9975
10111
|
|
|
9976
10112
|
@if (comment.attachments.length > 0) {
|
|
9977
10113
|
<div class="flex flex-col gap-3">
|
|
9978
10114
|
<div class="flex flex-col gap-3">
|
|
9979
10115
|
@for (attachment of comment.attachments; track attachment.attachmentId) {
|
|
9980
|
-
<div
|
|
10116
|
+
<div
|
|
10117
|
+
class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end"
|
|
10118
|
+
qa-id="oip-discussion-attachment">
|
|
9981
10119
|
<div class="inline-flex items-center gap-2">
|
|
9982
10120
|
<i class="pi pi-file"></i>
|
|
9983
10121
|
<button
|
|
10122
|
+
qa-id="oip-discussion-attachment-name"
|
|
9984
10123
|
class="break-all bg-transparent p-0 text-left font-semibold text-primary-600 transition hover:text-primary-500"
|
|
9985
10124
|
type="button"
|
|
9986
10125
|
(click)="downloadAttachment(attachment)">
|
|
@@ -9992,6 +10131,7 @@ class DiscussionComponent {
|
|
|
9992
10131
|
@if (comment.canEdit) {
|
|
9993
10132
|
<p-button
|
|
9994
10133
|
icon="pi pi-times"
|
|
10134
|
+
qa-id="oip-discussion-attachment-delete"
|
|
9995
10135
|
severity="danger"
|
|
9996
10136
|
[rounded]="true"
|
|
9997
10137
|
[text]="true"
|
|
@@ -10006,6 +10146,7 @@ class DiscussionComponent {
|
|
|
10006
10146
|
<div class="flex flex-wrap items-center gap-2">
|
|
10007
10147
|
@for (reaction of getReactions(comment); track reaction.emojiCode) {
|
|
10008
10148
|
<p-button
|
|
10149
|
+
qa-id="oip-discussion-reaction"
|
|
10009
10150
|
severity="secondary"
|
|
10010
10151
|
[label]="reaction.emojiCode + ' ' + reaction.count"
|
|
10011
10152
|
[outlined]="false"
|
|
@@ -10015,6 +10156,7 @@ class DiscussionComponent {
|
|
|
10015
10156
|
@if (!hasUserReaction(comment)) {
|
|
10016
10157
|
<p-button
|
|
10017
10158
|
icon="pi pi-face-smile"
|
|
10159
|
+
qa-id="oip-discussion-add-reaction"
|
|
10018
10160
|
severity="secondary"
|
|
10019
10161
|
[rounded]="true"
|
|
10020
10162
|
[text]="true"
|
|
@@ -10024,6 +10166,7 @@ class DiscussionComponent {
|
|
|
10024
10166
|
@for (emoji of emojiPalette; track emoji) {
|
|
10025
10167
|
<button
|
|
10026
10168
|
class="emoji-option"
|
|
10169
|
+
qa-id="oip-discussion-emoji"
|
|
10027
10170
|
type="button"
|
|
10028
10171
|
(click)="reactWithEmoji(comment, emoji, reactionPopover)">
|
|
10029
10172
|
{{ emoji }}
|
|
@@ -10054,7 +10197,9 @@ class DiscussionComponent {
|
|
|
10054
10197
|
item of historyByComment[comment.commentId]?.items ?? [];
|
|
10055
10198
|
track item.commentEditHistoryId
|
|
10056
10199
|
) {
|
|
10057
|
-
<div
|
|
10200
|
+
<div
|
|
10201
|
+
class="rounded-2xl border border-surface-200 px-4 py-4 dark:border-surface-700"
|
|
10202
|
+
qa-id="oip-discussion-history-item">
|
|
10058
10203
|
<div class="mb-3 inline-flex items-center gap-2 text-sm font-semibold">
|
|
10059
10204
|
<i class="pi pi-clock"></i>
|
|
10060
10205
|
<span>{{ item.editedByDisplayName }} · {{ item.editedAt | date: 'short' }}</span>
|
|
@@ -10064,12 +10209,14 @@ class DiscussionComponent {
|
|
|
10064
10209
|
<p-tag severity="secondary" [value]="'discussionComponent.before' | translate" />
|
|
10065
10210
|
<div
|
|
10066
10211
|
class="history-markdown rounded-2xl bg-surface-50 px-4 py-3 leading-7 dark:bg-surface-900/40"
|
|
10212
|
+
qa-id="oip-discussion-history-old"
|
|
10067
10213
|
[innerHTML]="renderMarkdown(item.oldContent)"></div>
|
|
10068
10214
|
</div>
|
|
10069
10215
|
<div class="flex flex-col gap-2">
|
|
10070
10216
|
<p-tag severity="success" [value]="'discussionComponent.after' | translate" />
|
|
10071
10217
|
<div
|
|
10072
10218
|
class="history-markdown rounded-2xl bg-surface-50 px-4 py-3 leading-7 dark:bg-surface-900/40"
|
|
10219
|
+
qa-id="oip-discussion-history-new"
|
|
10073
10220
|
[innerHTML]="renderMarkdown(item.newContent)"></div>
|
|
10074
10221
|
</div>
|
|
10075
10222
|
</div>
|
|
@@ -10116,6 +10263,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10116
10263
|
<textarea
|
|
10117
10264
|
class="min-h-28 w-full"
|
|
10118
10265
|
pTextarea
|
|
10266
|
+
qa-id="oip-discussion-new-comment"
|
|
10119
10267
|
rows="5"
|
|
10120
10268
|
[autoResize]="true"
|
|
10121
10269
|
[placeholder]="'discussionComponent.writeCommentPlaceholder' | translate"
|
|
@@ -10139,6 +10287,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10139
10287
|
<div class="flex flex-col gap-3">
|
|
10140
10288
|
@for (candidate of mentionSuggestions; track candidate.userId) {
|
|
10141
10289
|
<button
|
|
10290
|
+
qa-id="oip-discussion-mention-suggestion"
|
|
10142
10291
|
class="flex w-full items-center justify-between gap-4 rounded-xl border border-transparent px-3 py-3 text-left transition hover:border-primary-200 hover:bg-primary-50 dark:hover:border-primary-800 dark:hover:bg-primary-950/30"
|
|
10143
10292
|
type="button"
|
|
10144
10293
|
(click)="insertMention(candidate)">
|
|
@@ -10157,7 +10306,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10157
10306
|
<div class="flex flex-col gap-3">
|
|
10158
10307
|
@for (file of pendingFiles; track file.name + file.size) {
|
|
10159
10308
|
<div
|
|
10160
|
-
class="flex flex-col gap-3 rounded-2xl border border-surface-200 px-4 py-3 sm:flex-row sm:items-center sm:justify-between dark:border-surface-700"
|
|
10309
|
+
class="flex flex-col gap-3 rounded-2xl border border-surface-200 px-4 py-3 sm:flex-row sm:items-center sm:justify-between dark:border-surface-700"
|
|
10310
|
+
qa-id="oip-discussion-pending-file">
|
|
10161
10311
|
<div class="inline-flex items-center gap-2">
|
|
10162
10312
|
<i class="pi pi-file"></i>
|
|
10163
10313
|
<span class="break-all">{{ file.name }}</span>
|
|
@@ -10190,10 +10340,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10190
10340
|
severity="secondary"
|
|
10191
10341
|
[label]="'discussionComponent.attachFiles' | translate"
|
|
10192
10342
|
[text]="true" />
|
|
10193
|
-
<input multiple type="file" (change)="onFilesSelected($event)" />
|
|
10343
|
+
<input multiple qa-id="oip-discussion-attach-input" type="file" (change)="onFilesSelected($event)" />
|
|
10194
10344
|
</label>
|
|
10195
10345
|
<p-button
|
|
10196
10346
|
icon="pi pi-send"
|
|
10347
|
+
qa-id="oip-discussion-send"
|
|
10197
10348
|
[disabled]="submitting || !newComment.trim()"
|
|
10198
10349
|
[label]="'discussionComponent.send' | translate"
|
|
10199
10350
|
[loading]="submitting"
|
|
@@ -10217,7 +10368,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10217
10368
|
} @else {
|
|
10218
10369
|
<div class="flex flex-col gap-4">
|
|
10219
10370
|
@for (comment of comments; track comment.commentId) {
|
|
10220
|
-
<p-card class="block">
|
|
10371
|
+
<p-card class="block" qa-id="oip-discussion-comment">
|
|
10221
10372
|
<ng-template pTemplate="content">
|
|
10222
10373
|
<div class="grid gap-4 md:grid-cols-[3.2rem_minmax(0,1fr)]">
|
|
10223
10374
|
<div>
|
|
@@ -10238,6 +10389,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10238
10389
|
@if (comment.isEdited) {
|
|
10239
10390
|
<p-tag
|
|
10240
10391
|
icon="pi pi-pencil"
|
|
10392
|
+
qa-id="oip-discussion-comment-edited"
|
|
10241
10393
|
severity="warn"
|
|
10242
10394
|
[value]="'discussionComponent.edited' | translate" />
|
|
10243
10395
|
}
|
|
@@ -10245,6 +10397,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10245
10397
|
@if (comment.canEdit) {
|
|
10246
10398
|
<p-button
|
|
10247
10399
|
icon="pi pi-pencil"
|
|
10400
|
+
qa-id="oip-discussion-comment-edit"
|
|
10248
10401
|
severity="secondary"
|
|
10249
10402
|
[rounded]="true"
|
|
10250
10403
|
[text]="true"
|
|
@@ -10253,6 +10406,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10253
10406
|
@if (comment.historyCount > 0) {
|
|
10254
10407
|
<p-button
|
|
10255
10408
|
icon="pi pi-history"
|
|
10409
|
+
qa-id="oip-discussion-comment-history"
|
|
10256
10410
|
severity="secondary"
|
|
10257
10411
|
[rounded]="true"
|
|
10258
10412
|
[text]="true"
|
|
@@ -10261,6 +10415,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10261
10415
|
@if (comment.canDelete) {
|
|
10262
10416
|
<p-button
|
|
10263
10417
|
icon="pi pi-trash"
|
|
10418
|
+
qa-id="oip-discussion-comment-delete"
|
|
10264
10419
|
severity="danger"
|
|
10265
10420
|
[rounded]="true"
|
|
10266
10421
|
[text]="true"
|
|
@@ -10273,6 +10428,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10273
10428
|
<textarea
|
|
10274
10429
|
class="min-h-24 w-full"
|
|
10275
10430
|
pTextarea
|
|
10431
|
+
qa-id="oip-discussion-edit-content"
|
|
10276
10432
|
rows="4"
|
|
10277
10433
|
[autoResize]="true"
|
|
10278
10434
|
[placeholder]="'discussionComponent.editCommentPlaceholder' | translate"
|
|
@@ -10291,6 +10447,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10291
10447
|
|
|
10292
10448
|
<p-button
|
|
10293
10449
|
icon="pi pi-check"
|
|
10450
|
+
qa-id="oip-discussion-edit-save"
|
|
10294
10451
|
[disabled]="!editContent.trim()"
|
|
10295
10452
|
[label]="'discussionComponent.save' | translate"
|
|
10296
10453
|
(onClick)="saveEdit(comment)" />
|
|
@@ -10303,17 +10460,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10303
10460
|
</div>
|
|
10304
10461
|
</div>
|
|
10305
10462
|
} @else {
|
|
10306
|
-
<div
|
|
10463
|
+
<div
|
|
10464
|
+
class="markdown-preview"
|
|
10465
|
+
qa-id="oip-discussion-comment-content"
|
|
10466
|
+
[innerHTML]="renderMarkdown(comment.content)"></div>
|
|
10307
10467
|
}
|
|
10308
10468
|
|
|
10309
10469
|
@if (comment.attachments.length > 0) {
|
|
10310
10470
|
<div class="flex flex-col gap-3">
|
|
10311
10471
|
<div class="flex flex-col gap-3">
|
|
10312
10472
|
@for (attachment of comment.attachments; track attachment.attachmentId) {
|
|
10313
|
-
<div
|
|
10473
|
+
<div
|
|
10474
|
+
class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-end"
|
|
10475
|
+
qa-id="oip-discussion-attachment">
|
|
10314
10476
|
<div class="inline-flex items-center gap-2">
|
|
10315
10477
|
<i class="pi pi-file"></i>
|
|
10316
10478
|
<button
|
|
10479
|
+
qa-id="oip-discussion-attachment-name"
|
|
10317
10480
|
class="break-all bg-transparent p-0 text-left font-semibold text-primary-600 transition hover:text-primary-500"
|
|
10318
10481
|
type="button"
|
|
10319
10482
|
(click)="downloadAttachment(attachment)">
|
|
@@ -10325,6 +10488,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10325
10488
|
@if (comment.canEdit) {
|
|
10326
10489
|
<p-button
|
|
10327
10490
|
icon="pi pi-times"
|
|
10491
|
+
qa-id="oip-discussion-attachment-delete"
|
|
10328
10492
|
severity="danger"
|
|
10329
10493
|
[rounded]="true"
|
|
10330
10494
|
[text]="true"
|
|
@@ -10339,6 +10503,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10339
10503
|
<div class="flex flex-wrap items-center gap-2">
|
|
10340
10504
|
@for (reaction of getReactions(comment); track reaction.emojiCode) {
|
|
10341
10505
|
<p-button
|
|
10506
|
+
qa-id="oip-discussion-reaction"
|
|
10342
10507
|
severity="secondary"
|
|
10343
10508
|
[label]="reaction.emojiCode + ' ' + reaction.count"
|
|
10344
10509
|
[outlined]="false"
|
|
@@ -10348,6 +10513,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10348
10513
|
@if (!hasUserReaction(comment)) {
|
|
10349
10514
|
<p-button
|
|
10350
10515
|
icon="pi pi-face-smile"
|
|
10516
|
+
qa-id="oip-discussion-add-reaction"
|
|
10351
10517
|
severity="secondary"
|
|
10352
10518
|
[rounded]="true"
|
|
10353
10519
|
[text]="true"
|
|
@@ -10357,6 +10523,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10357
10523
|
@for (emoji of emojiPalette; track emoji) {
|
|
10358
10524
|
<button
|
|
10359
10525
|
class="emoji-option"
|
|
10526
|
+
qa-id="oip-discussion-emoji"
|
|
10360
10527
|
type="button"
|
|
10361
10528
|
(click)="reactWithEmoji(comment, emoji, reactionPopover)">
|
|
10362
10529
|
{{ emoji }}
|
|
@@ -10387,7 +10554,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10387
10554
|
item of historyByComment[comment.commentId]?.items ?? [];
|
|
10388
10555
|
track item.commentEditHistoryId
|
|
10389
10556
|
) {
|
|
10390
|
-
<div
|
|
10557
|
+
<div
|
|
10558
|
+
class="rounded-2xl border border-surface-200 px-4 py-4 dark:border-surface-700"
|
|
10559
|
+
qa-id="oip-discussion-history-item">
|
|
10391
10560
|
<div class="mb-3 inline-flex items-center gap-2 text-sm font-semibold">
|
|
10392
10561
|
<i class="pi pi-clock"></i>
|
|
10393
10562
|
<span>{{ item.editedByDisplayName }} · {{ item.editedAt | date: 'short' }}</span>
|
|
@@ -10397,12 +10566,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
10397
10566
|
<p-tag severity="secondary" [value]="'discussionComponent.before' | translate" />
|
|
10398
10567
|
<div
|
|
10399
10568
|
class="history-markdown rounded-2xl bg-surface-50 px-4 py-3 leading-7 dark:bg-surface-900/40"
|
|
10569
|
+
qa-id="oip-discussion-history-old"
|
|
10400
10570
|
[innerHTML]="renderMarkdown(item.oldContent)"></div>
|
|
10401
10571
|
</div>
|
|
10402
10572
|
<div class="flex flex-col gap-2">
|
|
10403
10573
|
<p-tag severity="success" [value]="'discussionComponent.after' | translate" />
|
|
10404
10574
|
<div
|
|
10405
10575
|
class="history-markdown rounded-2xl bg-surface-50 px-4 py-3 leading-7 dark:bg-surface-900/40"
|
|
10576
|
+
qa-id="oip-discussion-history-new"
|
|
10406
10577
|
[innerHTML]="renderMarkdown(item.newContent)"></div>
|
|
10407
10578
|
</div>
|
|
10408
10579
|
</div>
|
|
@@ -11640,14 +11811,6 @@ function oipErrorRoute(path = 'error') {
|
|
|
11640
11811
|
loadComponent: () => Promise.resolve().then(function () { return error_component; }).then((m) => m.ErrorComponent)
|
|
11641
11812
|
};
|
|
11642
11813
|
}
|
|
11643
|
-
/** Current user profile. */
|
|
11644
|
-
function oipProfileRoute(path = 'profile') {
|
|
11645
|
-
return {
|
|
11646
|
-
path,
|
|
11647
|
-
loadComponent: () => Promise.resolve().then(function () { return userProfile_component; }).then((m) => m.UserProfileComponent),
|
|
11648
|
-
canActivate: [oipAuthGuard]
|
|
11649
|
-
};
|
|
11650
|
-
}
|
|
11651
11814
|
/** Application configuration. */
|
|
11652
11815
|
function oipConfigRoute(path = 'config') {
|
|
11653
11816
|
return {
|
|
@@ -11746,7 +11909,6 @@ function provideOipRoutes(options = {}) {
|
|
|
11746
11909
|
const children = [...(options.children ?? [])];
|
|
11747
11910
|
builtInRoute(features.access, oipAccessRoute, children);
|
|
11748
11911
|
builtInRoute(features.error, oipErrorRoute, children);
|
|
11749
|
-
builtInRoute(features.profile, oipProfileRoute, children);
|
|
11750
11912
|
builtInRoute(features.config, oipConfigRoute, children);
|
|
11751
11913
|
builtInRoute(features.applications, oipApplicationsRoute, children);
|
|
11752
11914
|
builtInRoute(features.modules, oipModulesRoute, children);
|
|
@@ -11790,5 +11952,5 @@ function provideOipRoutes(options = {}) {
|
|
|
11790
11952
|
* Generated bundle index. Do not edit.
|
|
11791
11953
|
*/
|
|
11792
11954
|
|
|
11793
|
-
export { APP_INFO_TOKEN, APP_THEME_PRESETS, APP_THEME_PRESETS_MERGE_MODE, AccessComponent, AppConfiguratorComponent, AppFloatingConfiguratorComponent, AppInfoService, AppLayoutComponent, AppModulesComponent, AppTopbar, AppTopbarApplicationSwitcherComponent, ApplicationRegistryService, ApplicationsApi, ApplicationsComponent, AuthGuardService, AuthSessionsApi, AuthSessionsComponent, BaseModuleComponent, BffSecurityService, BlockLoaderComponent, ConfigComponent, ContentType, CustomElementExtensionModuleHostComponent, DbMigrationComponent, DefaultSecretsBannerComponent, DiscussionComponent, ErrorComponent, ExtensionLoaderService, ExtensionModuleHostComponent, FolderModuleApi, FooterComponent, HttpClient, IframeModuleApi, IframeModuleComponent, L10nService, LOGO_COMPONENT_TOKEN, LayoutService, LogoComponent, LogoService, MenuComponent, MenuService, ModuleInstanceRightsService, ModuleLoadingService, MsgService, NoModulesComponent, NotfoundComponent, NotificationApi, NotificationService, OIP_EXTENSION_EVENTS, SecurityApi, SecurityComponent, SecurityService, SidebarComponent, StartPageService, TableFilterService, TopBarService, UnauthorizedComponent, UserNotificationsComponent, UserProfileApi, UserProfileComponent, UserService, convertToPrimeNgDateFormat, defaultTheme, emitOipContextChange, emitOipError, emitOipNavigate, emitOipNotify, emitOipSettingsChange, emitOipTitleChange, langIntercept, mergeWithDefaults, moduleAccessGuard, oipAccessRoute, oipApplicationsRoute, oipAuthGuard, oipConfigRoute, oipDbMigrationRoute, oipDiscussionRoute, oipErrorRoute, oipExtensionsRoute, oipIframeModuleRoute, oipModulesRoute, oipNoModulesRoute,
|
|
11955
|
+
export { APP_INFO_TOKEN, APP_THEME_PRESETS, APP_THEME_PRESETS_MERGE_MODE, AccessComponent, AppConfiguratorComponent, AppFloatingConfiguratorComponent, AppInfoService, AppLayoutComponent, AppModulesComponent, AppTopbar, AppTopbarApplicationSwitcherComponent, ApplicationRegistryService, ApplicationsApi, ApplicationsComponent, AuthGuardService, AuthSessionsApi, AuthSessionsComponent, BaseModuleComponent, BffSecurityService, BlockLoaderComponent, ConfigComponent, ContentType, CustomElementExtensionModuleHostComponent, DbMigrationComponent, DefaultSecretsBannerComponent, DiscussionComponent, ErrorComponent, ExtensionLoaderService, ExtensionModuleHostComponent, FolderModuleApi, FooterComponent, HttpClient, IframeModuleApi, IframeModuleComponent, L10nService, LOGO_COMPONENT_TOKEN, LayoutService, LogoComponent, LogoService, MenuComponent, MenuService, ModuleInstanceRightsService, ModuleLoadingService, MsgService, NoModulesComponent, NotfoundComponent, NotificationApi, NotificationService, OIP_EXTENSION_EVENTS, SecurityApi, SecurityComponent, SecurityService, SidebarComponent, StartPageService, TableFilterService, TopBarService, UnauthorizedComponent, UserNotificationsComponent, UserProfileApi, UserProfileComponent, UserService, convertToPrimeNgDateFormat, defaultTheme, emitOipContextChange, emitOipError, emitOipNavigate, emitOipNotify, emitOipSettingsChange, emitOipTitleChange, langIntercept, mergeWithDefaults, moduleAccessGuard, oipAccessRoute, oipApplicationsRoute, oipAuthGuard, oipConfigRoute, oipDbMigrationRoute, oipDiscussionRoute, oipErrorRoute, oipExtensionsRoute, oipIframeModuleRoute, oipModulesRoute, oipNoModulesRoute, oipSessionsRoute, oipStartRedirectGuard, oipStartRoute, provideAppInfo, provideAppThemes, provideLogoComponent, provideOip, provideOipRoutes, provideTranslations, replaceDefaults };
|
|
11794
11956
|
//# sourceMappingURL=oip-common.mjs.map
|