@memberjunction/ng-explorer-settings 6.1.4 → 6.2.0-edge.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/dist/lib/account-info/account-info.component.d.ts +1 -1
- package/dist/lib/account-info/account-info.component.js +2 -2
- package/dist/lib/account-info/account-info.component.js.map +1 -1
- package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts +93 -10
- package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts.map +1 -1
- package/dist/lib/application-management/application-dialog/application-dialog.component.js +232 -80
- package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
- package/dist/lib/application-management/application-management.component.d.ts +94 -11
- package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
- package/dist/lib/application-management/application-management.component.js +231 -67
- package/dist/lib/application-management/application-management.component.js.map +1 -1
- package/dist/lib/application-settings/application-settings.component.d.ts +4 -4
- package/dist/lib/application-settings/application-settings.component.js +10 -10
- package/dist/lib/application-settings/application-settings.component.js.map +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts +88 -10
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.js +219 -63
- package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts +44 -6
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts.map +1 -1
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +117 -43
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
- package/dist/lib/notification-preferences/notification-preferences.component.d.ts +25 -3
- package/dist/lib/notification-preferences/notification-preferences.component.d.ts.map +1 -1
- package/dist/lib/notification-preferences/notification-preferences.component.js +62 -18
- package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
- package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts +32 -4
- package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts.map +1 -1
- package/dist/lib/role-management/role-dialog/role-dialog.component.js +84 -30
- package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
- package/dist/lib/role-management/role-management-agent-context.d.ts +12 -4
- package/dist/lib/role-management/role-management-agent-context.d.ts.map +1 -1
- package/dist/lib/role-management/role-management-agent-context.js +26 -10
- package/dist/lib/role-management/role-management-agent-context.js.map +1 -1
- package/dist/lib/role-management/role-management.component.d.ts +95 -11
- package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
- package/dist/lib/role-management/role-management.component.js +259 -91
- package/dist/lib/role-management/role-management.component.js.map +1 -1
- package/dist/lib/settings/settings.component.d.ts +87 -11
- package/dist/lib/settings/settings.component.d.ts.map +1 -1
- package/dist/lib/settings/settings.component.js +211 -65
- package/dist/lib/settings/settings.component.js.map +1 -1
- package/dist/lib/shared/settings-card.component.d.ts +24 -4
- package/dist/lib/shared/settings-card.component.d.ts.map +1 -1
- package/dist/lib/shared/settings-card.component.js +46 -6
- package/dist/lib/shared/settings-card.component.js.map +1 -1
- package/dist/lib/sql-logging/sql-logging.component.d.ts +172 -18
- package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -1
- package/dist/lib/sql-logging/sql-logging.component.js +320 -108
- package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
- package/dist/lib/user-app-config/user-app-config-content.component.js +3 -3
- package/dist/lib/user-app-config/user-app-config-content.component.js.map +1 -1
- package/dist/lib/user-app-config/user-app-config-reorder.d.ts +4 -0
- package/dist/lib/user-app-config/user-app-config-reorder.d.ts.map +1 -1
- package/dist/lib/user-app-config/user-app-config-reorder.js +11 -3
- package/dist/lib/user-app-config/user-app-config-reorder.js.map +1 -1
- package/dist/lib/user-management/transaction-group-refusals.d.ts +45 -0
- package/dist/lib/user-management/transaction-group-refusals.d.ts.map +1 -0
- package/dist/lib/user-management/transaction-group-refusals.js +49 -0
- package/dist/lib/user-management/transaction-group-refusals.js.map +1 -0
- package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts +44 -6
- package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-dialog/user-dialog.component.js +134 -45
- package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
- package/dist/lib/user-management/user-management-agent-context.d.ts +10 -0
- package/dist/lib/user-management/user-management-agent-context.d.ts.map +1 -1
- package/dist/lib/user-management/user-management-agent-context.js +26 -6
- package/dist/lib/user-management/user-management-agent-context.js.map +1 -1
- package/dist/lib/user-management/user-management.component.d.ts +174 -16
- package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-management.component.js +501 -177
- package/dist/lib/user-management/user-management.component.js.map +1 -1
- package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts +97 -15
- package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts.map +1 -1
- package/dist/lib/user-profile-settings/user-profile-settings.component.js +280 -116
- package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
- package/package.json +20 -20
|
@@ -248,28 +248,140 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
248
248
|
sharedService;
|
|
249
249
|
cdr;
|
|
250
250
|
ngZone;
|
|
251
|
-
|
|
252
|
-
|
|
251
|
+
CurrentUser;
|
|
252
|
+
/** @deprecated Use {@link CurrentUser}. */
|
|
253
|
+
get currentUser() {
|
|
254
|
+
return this.CurrentUser;
|
|
255
|
+
}
|
|
256
|
+
/** @deprecated Use {@link CurrentUser}. */
|
|
257
|
+
set currentUser(value) {
|
|
258
|
+
this.CurrentUser = value;
|
|
259
|
+
}
|
|
260
|
+
SelectedTab = 'url';
|
|
261
|
+
/** @deprecated Use {@link SelectedTab}. */
|
|
262
|
+
get selectedTab() {
|
|
263
|
+
return this.SelectedTab;
|
|
264
|
+
}
|
|
265
|
+
/** @deprecated Use {@link SelectedTab}. */
|
|
266
|
+
set selectedTab(value) {
|
|
267
|
+
this.SelectedTab = value;
|
|
268
|
+
}
|
|
253
269
|
// Form state
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
270
|
+
ImageUrlInput = '';
|
|
271
|
+
/** @deprecated Use {@link ImageUrlInput}. */
|
|
272
|
+
get imageUrlInput() {
|
|
273
|
+
return this.ImageUrlInput;
|
|
274
|
+
}
|
|
275
|
+
/** @deprecated Use {@link ImageUrlInput}. */
|
|
276
|
+
set imageUrlInput(value) {
|
|
277
|
+
this.ImageUrlInput = value;
|
|
278
|
+
}
|
|
279
|
+
SelectedIconClass = '';
|
|
280
|
+
/** @deprecated Use {@link SelectedIconClass}. */
|
|
281
|
+
get selectedIconClass() {
|
|
282
|
+
return this.SelectedIconClass;
|
|
283
|
+
}
|
|
284
|
+
/** @deprecated Use {@link SelectedIconClass}. */
|
|
285
|
+
set selectedIconClass(value) {
|
|
286
|
+
this.SelectedIconClass = value;
|
|
287
|
+
}
|
|
288
|
+
UploadedImageBase64 = '';
|
|
289
|
+
/** @deprecated Use {@link UploadedImageBase64}. */
|
|
290
|
+
get uploadedImageBase64() {
|
|
291
|
+
return this.UploadedImageBase64;
|
|
292
|
+
}
|
|
293
|
+
/** @deprecated Use {@link UploadedImageBase64}. */
|
|
294
|
+
set uploadedImageBase64(value) {
|
|
295
|
+
this.UploadedImageBase64 = value;
|
|
296
|
+
}
|
|
297
|
+
UploadedFileName = '';
|
|
298
|
+
/** @deprecated Use {@link UploadedFileName}. */
|
|
299
|
+
get uploadedFileName() {
|
|
300
|
+
return this.UploadedFileName;
|
|
301
|
+
}
|
|
302
|
+
/** @deprecated Use {@link UploadedFileName}. */
|
|
303
|
+
set uploadedFileName(value) {
|
|
304
|
+
this.UploadedFileName = value;
|
|
305
|
+
}
|
|
306
|
+
PreviewUrl = '';
|
|
307
|
+
/** @deprecated Use {@link PreviewUrl}. */
|
|
308
|
+
get previewUrl() {
|
|
309
|
+
return this.PreviewUrl;
|
|
310
|
+
}
|
|
311
|
+
/** @deprecated Use {@link PreviewUrl}. */
|
|
312
|
+
set previewUrl(value) {
|
|
313
|
+
this.PreviewUrl = value;
|
|
314
|
+
}
|
|
315
|
+
PreviewIconClass = '';
|
|
316
|
+
/** @deprecated Use {@link PreviewIconClass}. */
|
|
317
|
+
get previewIconClass() {
|
|
318
|
+
return this.PreviewIconClass;
|
|
319
|
+
}
|
|
320
|
+
/** @deprecated Use {@link PreviewIconClass}. */
|
|
321
|
+
set previewIconClass(value) {
|
|
322
|
+
this.PreviewIconClass = value;
|
|
323
|
+
}
|
|
260
324
|
// UI state
|
|
261
|
-
|
|
262
|
-
|
|
325
|
+
IsSaving = false;
|
|
326
|
+
/** @deprecated Use {@link IsSaving}. */
|
|
327
|
+
get isSaving() {
|
|
328
|
+
return this.IsSaving;
|
|
329
|
+
}
|
|
330
|
+
/** @deprecated Use {@link IsSaving}. */
|
|
331
|
+
set isSaving(value) {
|
|
332
|
+
this.IsSaving = value;
|
|
333
|
+
}
|
|
334
|
+
ShowSuccessMessage = false;
|
|
335
|
+
/** @deprecated Use {@link ShowSuccessMessage}. */
|
|
336
|
+
get showSuccessMessage() {
|
|
337
|
+
return this.ShowSuccessMessage;
|
|
338
|
+
}
|
|
339
|
+
/** @deprecated Use {@link ShowSuccessMessage}. */
|
|
340
|
+
set showSuccessMessage(value) {
|
|
341
|
+
this.ShowSuccessMessage = value;
|
|
342
|
+
}
|
|
263
343
|
errorMessage = '';
|
|
264
344
|
// Icon search state
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
345
|
+
IconSearchTerm = '';
|
|
346
|
+
/** @deprecated Use {@link IconSearchTerm}. */
|
|
347
|
+
get iconSearchTerm() {
|
|
348
|
+
return this.IconSearchTerm;
|
|
349
|
+
}
|
|
350
|
+
/** @deprecated Use {@link IconSearchTerm}. */
|
|
351
|
+
set iconSearchTerm(value) {
|
|
352
|
+
this.IconSearchTerm = value;
|
|
353
|
+
}
|
|
354
|
+
IconSearch$ = new BehaviorSubject('');
|
|
355
|
+
/** @deprecated Use {@link IconSearch$}. */
|
|
356
|
+
get iconSearch$() {
|
|
357
|
+
return this.IconSearch$;
|
|
358
|
+
}
|
|
359
|
+
/** @deprecated Use {@link IconSearch$}. */
|
|
360
|
+
set iconSearch$(value) {
|
|
361
|
+
this.IconSearch$ = value;
|
|
362
|
+
}
|
|
363
|
+
FilteredIconCategories = [];
|
|
364
|
+
/** @deprecated Use {@link FilteredIconCategories}. */
|
|
365
|
+
get filteredIconCategories() {
|
|
366
|
+
return this.FilteredIconCategories;
|
|
367
|
+
}
|
|
368
|
+
/** @deprecated Use {@link FilteredIconCategories}. */
|
|
369
|
+
set filteredIconCategories(value) {
|
|
370
|
+
this.FilteredIconCategories = value;
|
|
371
|
+
}
|
|
372
|
+
TotalFilteredIcons = 0;
|
|
373
|
+
/** @deprecated Use {@link TotalFilteredIcons}. */
|
|
374
|
+
get totalFilteredIcons() {
|
|
375
|
+
return this.TotalFilteredIcons;
|
|
376
|
+
}
|
|
377
|
+
/** @deprecated Use {@link TotalFilteredIcons}. */
|
|
378
|
+
set totalFilteredIcons(value) {
|
|
379
|
+
this.TotalFilteredIcons = value;
|
|
380
|
+
}
|
|
269
381
|
// Cleanup
|
|
270
382
|
destroy$ = new Subject();
|
|
271
383
|
// Icon picker data
|
|
272
|
-
|
|
384
|
+
IconCategories = [
|
|
273
385
|
{
|
|
274
386
|
name: 'Users',
|
|
275
387
|
icons: [
|
|
@@ -346,6 +458,14 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
346
458
|
]
|
|
347
459
|
}
|
|
348
460
|
];
|
|
461
|
+
/** @deprecated Use {@link IconCategories}. */
|
|
462
|
+
get iconCategories() {
|
|
463
|
+
return this.IconCategories;
|
|
464
|
+
}
|
|
465
|
+
/** @deprecated Use {@link IconCategories}. */
|
|
466
|
+
set iconCategories(value) {
|
|
467
|
+
this.IconCategories = value;
|
|
468
|
+
}
|
|
349
469
|
constructor(userAvatarService, sharedService, cdr, ngZone) {
|
|
350
470
|
super();
|
|
351
471
|
this.userAvatarService = userAvatarService;
|
|
@@ -357,11 +477,11 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
357
477
|
const md = this.ProviderToUse;
|
|
358
478
|
const currentUserInfo = md.CurrentUser;
|
|
359
479
|
// Load the full MJUserEntity to access avatar fields
|
|
360
|
-
this.
|
|
361
|
-
await this.
|
|
480
|
+
this.CurrentUser = await md.GetEntityObject('MJ: Users');
|
|
481
|
+
await this.CurrentUser.Load(currentUserInfo.ID);
|
|
362
482
|
// Initialize filtered icons
|
|
363
|
-
this.
|
|
364
|
-
this.
|
|
483
|
+
this.FilteredIconCategories = [...this.IconCategories];
|
|
484
|
+
this.TotalFilteredIcons = this.IconCategories.reduce((sum, cat) => sum + cat.icons.length, 0);
|
|
365
485
|
// Setup icon search subscription
|
|
366
486
|
this.setupIconSearchSubscription();
|
|
367
487
|
this.loadCurrentAvatar();
|
|
@@ -374,7 +494,7 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
374
494
|
* Initializes the icon search subscription with debounce
|
|
375
495
|
*/
|
|
376
496
|
setupIconSearchSubscription() {
|
|
377
|
-
this.
|
|
497
|
+
this.IconSearch$
|
|
378
498
|
.pipe(debounceTime(200), // Faster debounce for local filtering
|
|
379
499
|
distinctUntilChanged(), takeUntil(this.destroy$))
|
|
380
500
|
.subscribe((searchTerm) => {
|
|
@@ -384,10 +504,14 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
384
504
|
/**
|
|
385
505
|
* Handles icon search input changes
|
|
386
506
|
*/
|
|
387
|
-
|
|
507
|
+
OnIconSearchChange(event) {
|
|
388
508
|
const value = event.target.value;
|
|
389
|
-
this.
|
|
390
|
-
this.
|
|
509
|
+
this.IconSearchTerm = value;
|
|
510
|
+
this.IconSearch$.next(value);
|
|
511
|
+
}
|
|
512
|
+
/** @deprecated Use {@link OnIconSearchChange}. */
|
|
513
|
+
onIconSearchChange(event) {
|
|
514
|
+
return this.OnIconSearchChange(event);
|
|
391
515
|
}
|
|
392
516
|
/**
|
|
393
517
|
* Filters icons based on search term
|
|
@@ -396,25 +520,25 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
396
520
|
filterIcons(searchTerm) {
|
|
397
521
|
if (!searchTerm || searchTerm.trim() === '') {
|
|
398
522
|
// Show all icons
|
|
399
|
-
this.
|
|
400
|
-
this.
|
|
523
|
+
this.FilteredIconCategories = [...this.IconCategories];
|
|
524
|
+
this.TotalFilteredIcons = this.IconCategories.reduce((sum, cat) => sum + cat.icons.length, 0);
|
|
401
525
|
return;
|
|
402
526
|
}
|
|
403
527
|
const term = searchTerm.toLowerCase().trim();
|
|
404
|
-
this.
|
|
405
|
-
this.
|
|
406
|
-
for (const category of this.
|
|
528
|
+
this.FilteredIconCategories = [];
|
|
529
|
+
this.TotalFilteredIcons = 0;
|
|
530
|
+
for (const category of this.IconCategories) {
|
|
407
531
|
const matchingIcons = category.icons.filter((icon) => {
|
|
408
532
|
// Extract icon name from class (e.g., "fa-solid fa-user-tie" -> "user-tie")
|
|
409
|
-
const iconName = this.
|
|
533
|
+
const iconName = this.ExtractIconName(icon);
|
|
410
534
|
return iconName.includes(term);
|
|
411
535
|
});
|
|
412
536
|
if (matchingIcons.length > 0) {
|
|
413
|
-
this.
|
|
537
|
+
this.FilteredIconCategories.push({
|
|
414
538
|
name: category.name,
|
|
415
539
|
icons: matchingIcons
|
|
416
540
|
});
|
|
417
|
-
this.
|
|
541
|
+
this.TotalFilteredIcons += matchingIcons.length;
|
|
418
542
|
}
|
|
419
543
|
}
|
|
420
544
|
}
|
|
@@ -422,7 +546,7 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
422
546
|
* Extracts the icon name from a Font Awesome class string
|
|
423
547
|
* e.g., "fa-solid fa-user-tie" -> "user-tie"
|
|
424
548
|
*/
|
|
425
|
-
|
|
549
|
+
ExtractIconName(iconClass) {
|
|
426
550
|
const parts = iconClass.split(' ');
|
|
427
551
|
for (const part of parts) {
|
|
428
552
|
if (part.startsWith('fa-') && !['fa-solid', 'fa-regular', 'fa-light', 'fa-brands'].includes(part)) {
|
|
@@ -431,51 +555,63 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
431
555
|
}
|
|
432
556
|
return iconClass.toLowerCase();
|
|
433
557
|
}
|
|
558
|
+
/** @deprecated Use {@link ExtractIconName}. */
|
|
559
|
+
extractIconName(iconClass) {
|
|
560
|
+
return this.ExtractIconName(iconClass);
|
|
561
|
+
}
|
|
434
562
|
/**
|
|
435
563
|
* Clears the icon search
|
|
436
564
|
*/
|
|
565
|
+
ClearIconSearch() {
|
|
566
|
+
this.IconSearchTerm = '';
|
|
567
|
+
this.IconSearch$.next('');
|
|
568
|
+
}
|
|
569
|
+
/** @deprecated Use {@link ClearIconSearch}. */
|
|
437
570
|
clearIconSearch() {
|
|
438
|
-
this.
|
|
439
|
-
this.iconSearch$.next('');
|
|
571
|
+
return this.ClearIconSearch();
|
|
440
572
|
}
|
|
441
573
|
/**
|
|
442
574
|
* Loads the current avatar settings from the user entity
|
|
443
575
|
*/
|
|
444
576
|
loadCurrentAvatar() {
|
|
445
|
-
if (this.
|
|
446
|
-
this.
|
|
447
|
-
this.
|
|
577
|
+
if (this.CurrentUser.UserImageURL) {
|
|
578
|
+
this.ImageUrlInput = this.CurrentUser.UserImageURL;
|
|
579
|
+
this.PreviewUrl = this.CurrentUser.UserImageURL;
|
|
448
580
|
// Determine if it's a Base64 upload or URL
|
|
449
|
-
if (this.userAvatarService.isValidBase64DataUri(this.
|
|
450
|
-
this.
|
|
451
|
-
this.
|
|
452
|
-
this.
|
|
581
|
+
if (this.userAvatarService.isValidBase64DataUri(this.CurrentUser.UserImageURL)) {
|
|
582
|
+
this.SelectedTab = 'upload';
|
|
583
|
+
this.UploadedImageBase64 = this.CurrentUser.UserImageURL;
|
|
584
|
+
this.UploadedFileName = 'Current uploaded image';
|
|
453
585
|
}
|
|
454
586
|
else {
|
|
455
|
-
this.
|
|
587
|
+
this.SelectedTab = 'url';
|
|
456
588
|
}
|
|
457
589
|
}
|
|
458
|
-
else if (this.
|
|
459
|
-
this.
|
|
460
|
-
this.
|
|
461
|
-
this.
|
|
590
|
+
else if (this.CurrentUser.UserImageIconClass) {
|
|
591
|
+
this.SelectedIconClass = this.CurrentUser.UserImageIconClass;
|
|
592
|
+
this.PreviewIconClass = this.CurrentUser.UserImageIconClass;
|
|
593
|
+
this.SelectedTab = 'icon';
|
|
462
594
|
}
|
|
463
595
|
else {
|
|
464
596
|
// Default to URL tab with empty state
|
|
465
|
-
this.
|
|
597
|
+
this.SelectedTab = 'url';
|
|
466
598
|
}
|
|
467
599
|
}
|
|
468
600
|
/**
|
|
469
601
|
* Switches between tabs and updates preview
|
|
470
602
|
*/
|
|
471
|
-
|
|
472
|
-
this.
|
|
603
|
+
SelectTab(tab) {
|
|
604
|
+
this.SelectedTab = tab;
|
|
473
605
|
this.updatePreview();
|
|
474
606
|
}
|
|
607
|
+
/** @deprecated Use {@link SelectTab}. */
|
|
608
|
+
selectTab(tab) {
|
|
609
|
+
return this.SelectTab(tab);
|
|
610
|
+
}
|
|
475
611
|
/**
|
|
476
612
|
* Handles file selection from native input
|
|
477
613
|
*/
|
|
478
|
-
async
|
|
614
|
+
async OnFileSelected(event) {
|
|
479
615
|
const input = event.target;
|
|
480
616
|
const file = input.files?.[0];
|
|
481
617
|
if (!file) {
|
|
@@ -498,23 +634,27 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
498
634
|
}
|
|
499
635
|
// Convert to Base64
|
|
500
636
|
try {
|
|
501
|
-
this.
|
|
502
|
-
this.
|
|
503
|
-
this.
|
|
504
|
-
this.
|
|
637
|
+
this.UploadedImageBase64 = await this.userAvatarService.fileToBase64(file);
|
|
638
|
+
this.UploadedFileName = file.name;
|
|
639
|
+
this.PreviewUrl = this.UploadedImageBase64;
|
|
640
|
+
this.PreviewIconClass = ''; // Clear icon preview
|
|
505
641
|
}
|
|
506
642
|
catch (error) {
|
|
507
643
|
this.errorMessage = 'Failed to process image. Please try again.';
|
|
508
644
|
console.error('Error converting file to Base64:', error);
|
|
509
645
|
}
|
|
510
646
|
}
|
|
647
|
+
/** @deprecated Use {@link OnFileSelected}. */
|
|
648
|
+
async onFileSelected(event) {
|
|
649
|
+
return this.OnFileSelected(event);
|
|
650
|
+
}
|
|
511
651
|
/**
|
|
512
652
|
* Clears uploaded file
|
|
513
653
|
*/
|
|
514
|
-
|
|
515
|
-
this.
|
|
516
|
-
this.
|
|
517
|
-
this.
|
|
654
|
+
ClearUpload() {
|
|
655
|
+
this.UploadedFileName = '';
|
|
656
|
+
this.UploadedImageBase64 = '';
|
|
657
|
+
this.PreviewUrl = '';
|
|
518
658
|
this.errorMessage = '';
|
|
519
659
|
// Reset file input
|
|
520
660
|
const fileInput = document.querySelector('input[type="file"]');
|
|
@@ -522,73 +662,93 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
522
662
|
fileInput.value = '';
|
|
523
663
|
}
|
|
524
664
|
}
|
|
665
|
+
/** @deprecated Use {@link ClearUpload}. */
|
|
666
|
+
clearUpload() {
|
|
667
|
+
return this.ClearUpload();
|
|
668
|
+
}
|
|
525
669
|
/**
|
|
526
670
|
* Handles URL input changes
|
|
527
671
|
*/
|
|
528
|
-
|
|
672
|
+
OnUrlChange() {
|
|
529
673
|
this.errorMessage = '';
|
|
530
|
-
if (this.
|
|
531
|
-
if (this.userAvatarService.isValidUrl(this.
|
|
532
|
-
this.
|
|
533
|
-
this.
|
|
674
|
+
if (this.ImageUrlInput && this.ImageUrlInput.trim().length > 0) {
|
|
675
|
+
if (this.userAvatarService.isValidUrl(this.ImageUrlInput)) {
|
|
676
|
+
this.PreviewUrl = this.ImageUrlInput;
|
|
677
|
+
this.PreviewIconClass = ''; // Clear icon preview
|
|
534
678
|
}
|
|
535
679
|
else {
|
|
536
680
|
this.errorMessage = 'Please enter a valid URL';
|
|
537
|
-
this.
|
|
681
|
+
this.PreviewUrl = '';
|
|
538
682
|
}
|
|
539
683
|
}
|
|
540
684
|
else {
|
|
541
|
-
this.
|
|
685
|
+
this.PreviewUrl = '';
|
|
542
686
|
}
|
|
543
687
|
}
|
|
688
|
+
/** @deprecated Use {@link OnUrlChange}. */
|
|
689
|
+
onUrlChange() {
|
|
690
|
+
return this.OnUrlChange();
|
|
691
|
+
}
|
|
544
692
|
/**
|
|
545
693
|
* Handles icon selection
|
|
546
694
|
*/
|
|
547
|
-
|
|
548
|
-
this.
|
|
549
|
-
this.
|
|
550
|
-
this.
|
|
695
|
+
SelectIcon(iconClass) {
|
|
696
|
+
this.SelectedIconClass = iconClass;
|
|
697
|
+
this.PreviewIconClass = iconClass;
|
|
698
|
+
this.PreviewUrl = ''; // Clear image preview
|
|
551
699
|
this.errorMessage = '';
|
|
552
700
|
}
|
|
701
|
+
/** @deprecated Use {@link SelectIcon}. */
|
|
702
|
+
selectIcon(iconClass) {
|
|
703
|
+
return this.SelectIcon(iconClass);
|
|
704
|
+
}
|
|
553
705
|
/**
|
|
554
706
|
* Checks if an icon is currently selected
|
|
555
707
|
*/
|
|
708
|
+
IsIconSelected(iconClass) {
|
|
709
|
+
return this.SelectedIconClass === iconClass;
|
|
710
|
+
}
|
|
711
|
+
/** @deprecated Use {@link IsIconSelected}. */
|
|
556
712
|
isIconSelected(iconClass) {
|
|
557
|
-
return this.
|
|
713
|
+
return this.IsIconSelected(iconClass);
|
|
558
714
|
}
|
|
559
715
|
/**
|
|
560
716
|
* Syncs avatar from authentication provider
|
|
561
717
|
* NOTE: This is a placeholder - actual implementation should be done
|
|
562
718
|
* in the calling application which has access to auth services
|
|
563
719
|
*/
|
|
564
|
-
async
|
|
720
|
+
async SyncFromProvider() {
|
|
565
721
|
this.errorMessage = 'Avatar sync from provider is not yet implemented in settings. Please use the automatic sync on login or manually upload an image.';
|
|
566
722
|
// TODO: Implement auth provider integration
|
|
567
723
|
// The calling application should provide a way to get auth claims
|
|
568
724
|
// and call userAvatarService.syncFromImageUrl() with the appropriate URL and headers
|
|
569
725
|
}
|
|
726
|
+
/** @deprecated Use {@link SyncFromProvider}. */
|
|
727
|
+
async syncFromProvider() {
|
|
728
|
+
return this.SyncFromProvider();
|
|
729
|
+
}
|
|
570
730
|
/**
|
|
571
731
|
* Reverts avatar to default (clears both fields)
|
|
572
732
|
* This will trigger auto-sync from auth provider on next login
|
|
573
733
|
*/
|
|
574
|
-
async
|
|
575
|
-
this.
|
|
734
|
+
async RevertToDefault() {
|
|
735
|
+
this.IsSaving = true;
|
|
576
736
|
this.errorMessage = '';
|
|
577
|
-
this.
|
|
737
|
+
this.ShowSuccessMessage = false;
|
|
578
738
|
try {
|
|
579
739
|
// Clear both avatar fields
|
|
580
|
-
this.
|
|
581
|
-
this.
|
|
740
|
+
this.CurrentUser.UserImageURL = null;
|
|
741
|
+
this.CurrentUser.UserImageIconClass = null;
|
|
582
742
|
// Save to database
|
|
583
|
-
const saved = await this.
|
|
743
|
+
const saved = await this.CurrentUser.Save();
|
|
584
744
|
if (saved) {
|
|
585
745
|
// Clear local state
|
|
586
|
-
this.
|
|
587
|
-
this.
|
|
588
|
-
this.
|
|
589
|
-
this.
|
|
590
|
-
this.
|
|
591
|
-
this.
|
|
746
|
+
this.ImageUrlInput = '';
|
|
747
|
+
this.SelectedIconClass = '';
|
|
748
|
+
this.UploadedImageBase64 = '';
|
|
749
|
+
this.UploadedFileName = '';
|
|
750
|
+
this.PreviewUrl = '';
|
|
751
|
+
this.PreviewIconClass = '';
|
|
592
752
|
this.showSuccess('Avatar reverted to default! Your auth provider image will sync on next login.');
|
|
593
753
|
// Notify header component to update avatar display
|
|
594
754
|
MJGlobal.Instance.RaiseEvent({
|
|
@@ -614,32 +774,36 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
614
774
|
}
|
|
615
775
|
finally {
|
|
616
776
|
this.ngZone.run(() => {
|
|
617
|
-
this.
|
|
777
|
+
this.IsSaving = false;
|
|
618
778
|
this.cdr.markForCheck();
|
|
619
779
|
});
|
|
620
780
|
}
|
|
621
781
|
}
|
|
782
|
+
/** @deprecated Use {@link RevertToDefault}. */
|
|
783
|
+
async revertToDefault() {
|
|
784
|
+
return this.RevertToDefault();
|
|
785
|
+
}
|
|
622
786
|
/**
|
|
623
787
|
* Updates the preview based on current tab
|
|
624
788
|
*/
|
|
625
789
|
updatePreview() {
|
|
626
|
-
switch (this.
|
|
790
|
+
switch (this.SelectedTab) {
|
|
627
791
|
case 'upload':
|
|
628
|
-
if (this.
|
|
629
|
-
this.
|
|
630
|
-
this.
|
|
792
|
+
if (this.UploadedImageBase64) {
|
|
793
|
+
this.PreviewUrl = this.UploadedImageBase64;
|
|
794
|
+
this.PreviewIconClass = '';
|
|
631
795
|
}
|
|
632
796
|
break;
|
|
633
797
|
case 'url':
|
|
634
|
-
if (this.
|
|
635
|
-
this.
|
|
636
|
-
this.
|
|
798
|
+
if (this.ImageUrlInput && this.userAvatarService.isValidUrl(this.ImageUrlInput)) {
|
|
799
|
+
this.PreviewUrl = this.ImageUrlInput;
|
|
800
|
+
this.PreviewIconClass = '';
|
|
637
801
|
}
|
|
638
802
|
break;
|
|
639
803
|
case 'icon':
|
|
640
|
-
if (this.
|
|
641
|
-
this.
|
|
642
|
-
this.
|
|
804
|
+
if (this.SelectedIconClass) {
|
|
805
|
+
this.PreviewIconClass = this.SelectedIconClass;
|
|
806
|
+
this.PreviewUrl = '';
|
|
643
807
|
}
|
|
644
808
|
break;
|
|
645
809
|
}
|
|
@@ -648,42 +812,42 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
648
812
|
* Saves avatar settings to database
|
|
649
813
|
*/
|
|
650
814
|
async save() {
|
|
651
|
-
this.
|
|
815
|
+
this.IsSaving = true;
|
|
652
816
|
this.errorMessage = '';
|
|
653
|
-
this.
|
|
817
|
+
this.ShowSuccessMessage = false;
|
|
654
818
|
try {
|
|
655
819
|
// Update user entity based on selected tab
|
|
656
|
-
switch (this.
|
|
820
|
+
switch (this.SelectedTab) {
|
|
657
821
|
case 'upload':
|
|
658
|
-
if (!this.
|
|
822
|
+
if (!this.UploadedImageBase64) {
|
|
659
823
|
this.errorMessage = 'Please select an image to upload';
|
|
660
|
-
this.
|
|
824
|
+
this.IsSaving = false;
|
|
661
825
|
return;
|
|
662
826
|
}
|
|
663
|
-
this.
|
|
664
|
-
this.
|
|
827
|
+
this.CurrentUser.UserImageURL = this.UploadedImageBase64;
|
|
828
|
+
this.CurrentUser.UserImageIconClass = null;
|
|
665
829
|
break;
|
|
666
830
|
case 'url':
|
|
667
|
-
if (!this.
|
|
831
|
+
if (!this.ImageUrlInput || !this.userAvatarService.isValidUrl(this.ImageUrlInput)) {
|
|
668
832
|
this.errorMessage = 'Please enter a valid image URL';
|
|
669
|
-
this.
|
|
833
|
+
this.IsSaving = false;
|
|
670
834
|
return;
|
|
671
835
|
}
|
|
672
|
-
this.
|
|
673
|
-
this.
|
|
836
|
+
this.CurrentUser.UserImageURL = this.ImageUrlInput;
|
|
837
|
+
this.CurrentUser.UserImageIconClass = null;
|
|
674
838
|
break;
|
|
675
839
|
case 'icon':
|
|
676
|
-
if (!this.
|
|
840
|
+
if (!this.SelectedIconClass) {
|
|
677
841
|
this.errorMessage = 'Please select an icon';
|
|
678
|
-
this.
|
|
842
|
+
this.IsSaving = false;
|
|
679
843
|
return;
|
|
680
844
|
}
|
|
681
|
-
this.
|
|
682
|
-
this.
|
|
845
|
+
this.CurrentUser.UserImageURL = null;
|
|
846
|
+
this.CurrentUser.UserImageIconClass = this.SelectedIconClass;
|
|
683
847
|
break;
|
|
684
848
|
}
|
|
685
849
|
// Save to database
|
|
686
|
-
const saved = await this.
|
|
850
|
+
const saved = await this.CurrentUser.Save();
|
|
687
851
|
if (saved) {
|
|
688
852
|
this.showSuccess('Avatar updated successfully!');
|
|
689
853
|
// Notify header component to update avatar display
|
|
@@ -692,8 +856,8 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
692
856
|
eventCode: EventCodes.AvatarUpdated,
|
|
693
857
|
component: this,
|
|
694
858
|
args: {
|
|
695
|
-
imageUrl: this.
|
|
696
|
-
iconClass: this.
|
|
859
|
+
imageUrl: this.CurrentUser.UserImageURL,
|
|
860
|
+
iconClass: this.CurrentUser.UserImageIconClass
|
|
697
861
|
}
|
|
698
862
|
});
|
|
699
863
|
}
|
|
@@ -710,7 +874,7 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
710
874
|
}
|
|
711
875
|
finally {
|
|
712
876
|
this.ngZone.run(() => {
|
|
713
|
-
this.
|
|
877
|
+
this.IsSaving = false;
|
|
714
878
|
this.cdr.markForCheck();
|
|
715
879
|
});
|
|
716
880
|
}
|
|
@@ -721,17 +885,17 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
|
721
885
|
cancel() {
|
|
722
886
|
this.loadCurrentAvatar();
|
|
723
887
|
this.errorMessage = '';
|
|
724
|
-
this.
|
|
888
|
+
this.ShowSuccessMessage = false;
|
|
725
889
|
}
|
|
726
890
|
/**
|
|
727
891
|
* Shows success message temporarily
|
|
728
892
|
*/
|
|
729
893
|
showSuccess(message) {
|
|
730
|
-
this.
|
|
894
|
+
this.ShowSuccessMessage = true;
|
|
731
895
|
this.sharedService.CreateSimpleNotification(message, 'success', 3000);
|
|
732
896
|
// Hide success message after 3 seconds
|
|
733
897
|
setTimeout(() => {
|
|
734
|
-
this.
|
|
898
|
+
this.ShowSuccessMessage = false;
|
|
735
899
|
}, 3000);
|
|
736
900
|
}
|
|
737
901
|
static ɵfac = function UserProfileSettingsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserProfileSettingsComponent)(i0.ɵɵdirectiveInject(i1.UserAvatarService), i0.ɵɵdirectiveInject(i2.SharedService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone)); };
|