mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2026-09-09 18:02:54 +00:00
[ACS-9980] Add the option to provide custom user profile sections (#4859)
* [ACS-9980] Add the option to provide custom user profile sections * [ACS-9980] Cr fixes * [ACS-9980] Formatting fix
This commit is contained in:
@@ -743,6 +743,20 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"userProfileSection": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "title"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "Unique identifier.",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"component": {
|
||||||
|
"description": "Custom component id to display inside the section",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1013,6 +1027,12 @@
|
|||||||
"items": { "$ref": "#/definitions/badge" },
|
"items": { "$ref": "#/definitions/badge" },
|
||||||
"minItems": 1
|
"minItems": 1
|
||||||
},
|
},
|
||||||
|
"userProfileSections": {
|
||||||
|
"description": "List of custom sections to display in the user profile component",
|
||||||
|
"type": "array",
|
||||||
|
"items": { "$ref": "#/definitions/userProfileSection" },
|
||||||
|
"minItems": 1
|
||||||
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"description": "aca search extension",
|
"description": "aca search extension",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
|
|||||||
@@ -463,7 +463,12 @@
|
|||||||
"COLLAPSE_NAVIGATION": "Collapse navigation menu",
|
"COLLAPSE_NAVIGATION": "Collapse navigation menu",
|
||||||
"OPTIONS_SETTINGS": "Options and settings",
|
"OPTIONS_SETTINGS": "Options and settings",
|
||||||
"MY_PROFILE": "My profile",
|
"MY_PROFILE": "My profile",
|
||||||
"EXPAND_NAVIGATION": "Expand navigation menu"
|
"EXPAND_NAVIGATION": "Expand navigation menu",
|
||||||
|
"EXPAND_SECTION": "Expand section",
|
||||||
|
"COLLAPSE_SECTION": "Collapse section",
|
||||||
|
"EDIT": "Edit",
|
||||||
|
"CANCEL": "Cancel",
|
||||||
|
"SAVE": "Save"
|
||||||
},
|
},
|
||||||
"FOLDER_INFO": {
|
"FOLDER_INFO": {
|
||||||
"ICON": "Folder Icon",
|
"ICON": "Folder Icon",
|
||||||
|
|||||||
@@ -166,7 +166,8 @@ import { SaveSearchSidenavComponent } from './components/search/search-save/side
|
|||||||
'app.canShowLogout': rules.canShowLogout,
|
'app.canShowLogout': rules.canShowLogout,
|
||||||
'app.isContentServiceEnabled': rules.isContentServiceEnabled,
|
'app.isContentServiceEnabled': rules.isContentServiceEnabled,
|
||||||
'app.areTagsEnabled': rules.areTagsEnabled,
|
'app.areTagsEnabled': rules.areTagsEnabled,
|
||||||
'app.areCategoriesEnabled': rules.areCategoriesEnabled
|
'app.areCategoriesEnabled': rules.areCategoriesEnabled,
|
||||||
|
'app.isSSOEnabled': rules.isSSOEnabled
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
<div class="app-profile-container">
|
<div class="app-profile-container">
|
||||||
<div class="app-profile-row">
|
<div class="app-profile-row">
|
||||||
<div class="app-profile-title">
|
<div class="app-profile-title">
|
||||||
<button *ngIf="(appNavNarMode$ | async) === 'collapsed'" mat-icon-button (click)="toggleClick()"
|
@if ((appNavNarMode$ | async) === 'collapsed') {
|
||||||
title="{{'APP.TOOLTIPS.EXPAND_NAVIGATION' | translate}}">
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
(click)="toggleNavigationMenu()"
|
||||||
|
[attr.title]="'APP.TOOLTIPS.EXPAND_NAVIGATION' | translate"
|
||||||
|
[attr.aria-label]="'APP.TOOLTIPS.EXPAND_NAVIGATION' | translate">
|
||||||
<mat-icon>menu</mat-icon>
|
<mat-icon>menu</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
}
|
||||||
<button
|
<button
|
||||||
class="app-profile-icon"
|
class="app-profile-icon"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
@@ -16,26 +21,49 @@
|
|||||||
<h3 class="app-profile">{{'APP.EDIT_PROFILE.MY_PROFILE' | translate}}</h3>
|
<h3 class="app-profile">{{'APP.EDIT_PROFILE.MY_PROFILE' | translate}}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-profile-general-row" [formGroup]="profileForm">
|
<div class="app-profile-general-row" [formGroup]="profileForm" id="general-dropdown">
|
||||||
<div class="app-profile-general">
|
<div class="app-profile-general">
|
||||||
<div class="app-profile-general-section">
|
<div class="app-profile-general-section">
|
||||||
<mat-icon class="app-profile-general-icon" (click)="toggleGeneralDropdown()" id="toggle-general-dropdown">
|
<button
|
||||||
{{ generalSectionDropdown ? 'expand_more' : 'chevron_right'}}</mat-icon>
|
mat-icon-button
|
||||||
|
(click)="toggleGeneralDropdown()"
|
||||||
|
[attr.title]="`APP.TOOLTIPS.${generalSectionDropdown ? 'COLLAPSE' : 'EXPAND'}_SECTION` | translate"
|
||||||
|
[attr.aria-label]="`APP.TOOLTIPS.${generalSectionDropdown ? 'COLLAPSE' : 'EXPAND'}_SECTION` | translate">
|
||||||
|
<mat-icon>{{ generalSectionDropdown ? 'expand_more' : 'chevron_right'}}</mat-icon>
|
||||||
|
</button>
|
||||||
<h4 class="app-general-title">{{'APP.EDIT_PROFILE.GENERAL' | translate}}</h4>
|
<h4 class="app-general-title">{{'APP.EDIT_PROFILE.GENERAL' | translate}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-general-edit-btn" *ngIf="generalSectionButtonsToggle">
|
@if (generalSectionButtonsToggle) {
|
||||||
<button mat-raised-button (click)="toggleGeneralButtons()" id="general-edit-button"
|
<button
|
||||||
class="app-general-edit">{{'APP.EDIT_PROFILE.EDIT' | translate}}</button>
|
mat-icon-button
|
||||||
|
(click)="toggleGeneralButtons()"
|
||||||
|
class="app-general-edit"
|
||||||
|
[attr.title]="'APP.TOOLTIPS.EDIT' | translate"
|
||||||
|
[attr.aria-label]="'APP.TOOLTIPS.EDIT' | translate">
|
||||||
|
<mat-icon>edit</mat-icon>
|
||||||
|
</button>
|
||||||
|
} @else {
|
||||||
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
class="app-general-cancel-btn"
|
||||||
|
[attr.title]="'APP.TOOLTIPS.CANCEL' | translate"
|
||||||
|
[attr.aria-label]="'APP.TOOLTIPS.CANCEL' | translate"
|
||||||
|
(click)="toggleGeneralButtons()">
|
||||||
|
<mat-icon>close</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
color="primary"
|
||||||
|
[attr.title]="'APP.TOOLTIPS.SAVE' | translate"
|
||||||
|
[attr.aria-label]="'APP.TOOLTIPS.SAVE' | translate"
|
||||||
|
[disabled]="profileForm.invalid"
|
||||||
|
(click)="onSaveGeneralData(profileForm)">
|
||||||
|
<mat-icon>check</mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="app-general-edit-btn" *ngIf="!generalSectionButtonsToggle">
|
@if (generalSectionDropdown) {
|
||||||
<button mat-raised-button class="app-general-cancel-btn" id="general-cancel-button"
|
<mat-divider class="app-divider" />
|
||||||
(click)="toggleGeneralButtons()">{{'APP.EDIT_PROFILE.CANCEL' | translate}}</button>
|
|
||||||
<button mat-raised-button class="app-general-save-btn" id="general-save-button" [disabled]="profileForm.invalid"
|
|
||||||
(click)="onSaveGeneralData(profileForm)">{{'APP.EDIT_PROFILE.SAVE' | translate}}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<mat-divider class="app-divider" *ngIf="generalSectionDropdown" />
|
|
||||||
<div *ngIf="generalSectionDropdown">
|
|
||||||
<div class="app-general-dropdown">
|
<div class="app-general-dropdown">
|
||||||
<div class="app-general-dropdown-details">
|
<div class="app-general-dropdown-details">
|
||||||
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.FIRST_NAME' | translate}}</h4>
|
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.FIRST_NAME' | translate}}</h4>
|
||||||
@@ -49,106 +77,176 @@
|
|||||||
<mat-divider class="app-general-dropdown-divider" />
|
<mat-divider class="app-general-dropdown-divider" />
|
||||||
<div class="app-general-dropdown-details">
|
<div class="app-general-dropdown-details">
|
||||||
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.JOB_TITLE' | translate}}</h4>
|
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.JOB_TITLE' | translate}}</h4>
|
||||||
<p class="app-profile-general-dropdown-details" *ngIf="generalSectionButtonsToggle">{{personDetails?.jobTitle}}</p>
|
@if (generalSectionButtonsToggle) {
|
||||||
<input type="text" value="" formControlName="jobTitle" *ngIf="!generalSectionButtonsToggle"
|
<p class="app-profile-general-dropdown-details">{{personDetails?.jobTitle}}</p>
|
||||||
class="app-profile-general-dropdown-input-details app-selected">
|
} @else {
|
||||||
|
<input type="text" value="" formControlName="jobTitle" class="app-profile-general-dropdown-input-details app-selected">
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<mat-divider class="app-general-dropdown-divider" />
|
<mat-divider class="app-general-dropdown-divider" />
|
||||||
<div class="app-general-dropdown-details">
|
<div class="app-general-dropdown-details">
|
||||||
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.LOCATION' | translate}}</h4>
|
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.LOCATION' | translate}}</h4>
|
||||||
<p class="app-profile-general-dropdown-details" *ngIf="generalSectionButtonsToggle">{{personDetails?.location}}</p>
|
@if (generalSectionButtonsToggle) {
|
||||||
<input type="text" value="" formControlName="location" *ngIf="!generalSectionButtonsToggle"
|
<p class="app-profile-general-dropdown-details">{{personDetails?.location}}</p>
|
||||||
class="app-profile-general-dropdown-input-details app-selected">
|
} @else {
|
||||||
|
<input type="text" value="" formControlName="location" class="app-profile-general-dropdown-input-details app-selected">
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<mat-divider class="app-general-dropdown-divider" />
|
<mat-divider class="app-general-dropdown-divider" />
|
||||||
<div class="app-general-dropdown-details">
|
<div class="app-general-dropdown-details">
|
||||||
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.TELEPHONE' | translate}}</h4>
|
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.TELEPHONE' | translate}}</h4>
|
||||||
<p class="app-profile-general-dropdown-details" *ngIf="generalSectionButtonsToggle">{{personDetails?.telephone}}</p>
|
@if (generalSectionButtonsToggle) {
|
||||||
<input type="tel" name="Telephone" value="" formControlName="telephone" *ngIf="!generalSectionButtonsToggle"
|
<p class="app-profile-general-dropdown-details">{{personDetails?.telephone}}</p>
|
||||||
class="app-profile-general-dropdown-input-details app-selected" aria-describedby="app-view-profile-phone-error-message">
|
} @else {
|
||||||
<mat-error class="app-error-message" *ngIf="profileForm.get('telephone').invalid" role="alert" id="app-view-profile-phone-error-message">
|
<input
|
||||||
|
type="tel"
|
||||||
|
name="Telephone"
|
||||||
|
value=""
|
||||||
|
formControlName="telephone"
|
||||||
|
class="app-profile-general-dropdown-input-details app-selected"
|
||||||
|
aria-describedby="app-view-profile-phone-error-message">
|
||||||
|
}
|
||||||
|
@if (profileForm.controls['telephone'].errors) {
|
||||||
|
<mat-error class="app-error-message" role="alert" id="app-view-profile-phone-error-message">
|
||||||
{{ 'APP.EDIT_PROFILE.INVALID_INPUT' | translate }}
|
{{ 'APP.EDIT_PROFILE.INVALID_INPUT' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<mat-divider class="app-general-dropdown-divider" />
|
<mat-divider class="app-general-dropdown-divider" />
|
||||||
<div class="app-general-dropdown-details">
|
<div class="app-general-dropdown-details">
|
||||||
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.MOBILE' | translate}}</h4>
|
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.MOBILE' | translate}}</h4>
|
||||||
<p class="app-profile-general-dropdown-details" *ngIf="generalSectionButtonsToggle">{{personDetails?.mobile}}</p>
|
@if (generalSectionButtonsToggle) {
|
||||||
<input type="tel" value="" formControlName="mobile" *ngIf="!generalSectionButtonsToggle"
|
<p class="app-profile-general-dropdown-details">{{personDetails?.mobile}}</p>
|
||||||
class="app-profile-general-dropdown-input-details app-selected" aria-describedby="app-view-profile-mobile-error-message">
|
} @else {
|
||||||
<mat-error class="app-error-message" *ngIf="profileForm.get('mobile').invalid" role="alert" id="app-view-profile-mobile-error-message">
|
<input
|
||||||
|
type="tel"
|
||||||
|
value=""
|
||||||
|
formControlName="mobile"
|
||||||
|
class="app-profile-general-dropdown-input-details app-selected"
|
||||||
|
aria-describedby="app-view-profile-mobile-error-message">
|
||||||
|
}
|
||||||
|
@if (profileForm.controls['mobile'].errors) {
|
||||||
|
<mat-error class="app-error-message" role="alert" id="app-view-profile-mobile-error-message">
|
||||||
{{ 'APP.EDIT_PROFILE.INVALID_INPUT' | translate }}
|
{{ 'APP.EDIT_PROFILE.INVALID_INPUT' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="app-profile-contact-row" [formGroup]="profileForm">
|
<div class="app-profile-contact-row" [formGroup]="profileForm" id="contact-dropdown">
|
||||||
<div class="app-profile-general profile-general-bottom-radius">
|
<div class="app-profile-general profile-general-bottom-radius">
|
||||||
<div class="app-profile-general-section">
|
<div class="app-profile-general-section">
|
||||||
<mat-icon class="app-profile-general-icon" (click)="toggleContactDropdown()" id="toggle-contact-dropdown">
|
<button
|
||||||
{{ contactSectionDropdown ? 'expand_more' : 'chevron_right'}}</mat-icon>
|
mat-icon-button
|
||||||
|
(click)="toggleContactDropdown()"
|
||||||
|
[attr.title]="`APP.TOOLTIPS.${contactSectionDropdown ? 'COLLAPSE' : 'EXPAND'}_SECTION` | translate"
|
||||||
|
[attr.aria-label]="`APP.TOOLTIPS.${contactSectionDropdown ? 'COLLAPSE' : 'EXPAND'}_SECTION` | translate">
|
||||||
|
<mat-icon>{{ contactSectionDropdown ? 'expand_more' : 'chevron_right'}}</mat-icon>
|
||||||
|
</button>
|
||||||
<h4 class="app-general-title">{{'APP.EDIT_PROFILE.COMPANY_DETAILS' | translate}}</h4>
|
<h4 class="app-general-title">{{'APP.EDIT_PROFILE.COMPANY_DETAILS' | translate}}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
@if (contactSectionButtonsToggle) {
|
||||||
<div class="app-general-edit-btn" *ngIf="contactSectionButtonsToggle">
|
<button
|
||||||
<button mat-raised-button class="app-general-edit" id="contact-edit-button"
|
mat-icon-button
|
||||||
(click)="toggleContactButtons()">{{'APP.EDIT_PROFILE.EDIT' | translate}}</button>
|
(click)="toggleContactButtons()"
|
||||||
|
class="app-general-edit"
|
||||||
|
[attr.title]="'APP.TOOLTIPS.EDIT' | translate"
|
||||||
|
[attr.aria-label]="'APP.TOOLTIPS.EDIT' | translate">
|
||||||
|
<mat-icon>edit</mat-icon>
|
||||||
|
</button>
|
||||||
|
} @else {
|
||||||
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
class="app-general-cancel-btn"
|
||||||
|
[attr.title]="'APP.TOOLTIPS.CANCEL' | translate"
|
||||||
|
[attr.aria-label]="'APP.TOOLTIPS.CANCEL' | translate"
|
||||||
|
(click)="toggleContactButtons()">
|
||||||
|
<mat-icon>close</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
color="primary"
|
||||||
|
[attr.title]="'APP.TOOLTIPS.SAVE' | translate"
|
||||||
|
[attr.aria-label]="'APP.TOOLTIPS.SAVE' | translate"
|
||||||
|
[disabled]="profileForm.invalid"
|
||||||
|
(click)="onSaveCompanyData(profileForm)">
|
||||||
|
<mat-icon>check</mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="app-general-edit-btn" *ngIf="!contactSectionButtonsToggle">
|
@if (contactSectionDropdown) {
|
||||||
<button mat-raised-button class="app-general-cancel-btn" id="contact-cancel-button"
|
<mat-divider class="app-divider" />
|
||||||
(click)="toggleContactButtons()">{{'APP.EDIT_PROFILE.CANCEL' | translate}}</button>
|
|
||||||
<button mat-raised-button class="app-general-save-btn" id="contact-save-button" [disabled]="profileForm.invalid"
|
|
||||||
(click)="onSaveCompanyData(profileForm)">{{'APP.EDIT_PROFILE.SAVE' | translate}}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<mat-divider class="app-divider" *ngIf="contactSectionDropdown" />
|
|
||||||
<div *ngIf="contactSectionDropdown">
|
|
||||||
<div class="app-general-dropdown">
|
<div class="app-general-dropdown">
|
||||||
<div class="app-general-dropdown-details">
|
<div class="app-general-dropdown-details">
|
||||||
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.NAME' | translate}}</h4>
|
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.NAME' | translate}}</h4>
|
||||||
<p class="app-profile-general-dropdown-details" *ngIf="contactSectionButtonsToggle">{{personDetails?.company?.organization}}</p>
|
@if (contactSectionButtonsToggle) {
|
||||||
<input type="text" value="" *ngIf="!contactSectionButtonsToggle" formControlName="companyName"
|
<p class="app-profile-general-dropdown-details">{{personDetails?.company?.organization}}</p>
|
||||||
class="app-profile-general-dropdown-input-details app-selected">
|
} @else {
|
||||||
|
<input type="text" value="" formControlName="companyName" class="app-profile-general-dropdown-input-details app-selected">
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<mat-divider class="app-general-dropdown-divider" />
|
<mat-divider class="app-general-dropdown-divider" />
|
||||||
<div class="app-general-dropdown-details">
|
<div class="app-general-dropdown-details">
|
||||||
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.ADDRESS' | translate}}</h4>
|
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.ADDRESS' | translate}}</h4>
|
||||||
<p class="app-profile-general-dropdown-details" *ngIf="contactSectionButtonsToggle">{{personDetails?.company?.address1}}</p>
|
@if (contactSectionButtonsToggle) {
|
||||||
<input type="text" value="" *ngIf="!contactSectionButtonsToggle" formControlName="companyAddress"
|
<p class="app-profile-general-dropdown-details">{{personDetails?.company?.address1}}</p>
|
||||||
class="app-profile-general-dropdown-input-details app-selected">
|
} @else {
|
||||||
|
<input type="text" value="" formControlName="companyAddress" class="app-profile-general-dropdown-input-details app-selected">
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<mat-divider class="app-general-dropdown-divider" />
|
<mat-divider class="app-general-dropdown-divider" />
|
||||||
<div class="app-general-dropdown-details">
|
<div class="app-general-dropdown-details">
|
||||||
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.POSTCODE' | translate}}</h4>
|
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.POSTCODE' | translate}}</h4>
|
||||||
<p class="app-profile-general-dropdown-details" *ngIf="contactSectionButtonsToggle">{{personDetails?.company?.postcode}}</p>
|
@if (contactSectionButtonsToggle) {
|
||||||
<input type="text" value="" *ngIf="!contactSectionButtonsToggle" formControlName="companyPostCode"
|
<p class="app-profile-general-dropdown-details">{{personDetails?.company?.postcode}}</p>
|
||||||
class="app-profile-general-dropdown-input-details app-selected">
|
} @else {
|
||||||
|
<input type="text" value="" formControlName="companyPostCode" class="app-profile-general-dropdown-input-details app-selected">
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<mat-divider class="app-general-dropdown-divider" />
|
<mat-divider class="app-general-dropdown-divider" />
|
||||||
<div class="app-general-dropdown-details">
|
<div class="app-general-dropdown-details">
|
||||||
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.TELEPHONE' | translate}}</h4>
|
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.TELEPHONE' | translate}}</h4>
|
||||||
<p class="app-profile-general-dropdown-details" *ngIf="contactSectionButtonsToggle">{{personDetails?.company?.telephone}}</p>
|
@if (contactSectionButtonsToggle) {
|
||||||
<input type="tel" value="" *ngIf="!contactSectionButtonsToggle" formControlName="companyTelephone"
|
<p class="app-profile-general-dropdown-details">{{personDetails?.company?.telephone}}</p>
|
||||||
class="app-profile-general-dropdown-input-details app-selected" aria-describedby="app-view-profile-company-phone-error-message">
|
} @else {
|
||||||
<mat-error class="app-error-message" *ngIf="profileForm.get('companyTelephone').invalid" role="alert"
|
<input
|
||||||
id="app-view-profile-company-phone-error-message">
|
type="tel"
|
||||||
|
value=""
|
||||||
|
formControlName="companyTelephone"
|
||||||
|
class="app-profile-general-dropdown-input-details app-selected"
|
||||||
|
aria-describedby="app-view-profile-company-phone-error-message">
|
||||||
|
}
|
||||||
|
@if (profileForm.controls['companyTelephone'].errors) {
|
||||||
|
<mat-error class="app-error-message" role="alert" id="app-view-profile-company-phone-error-message">
|
||||||
{{ 'APP.EDIT_PROFILE.INVALID_INPUT' | translate }}
|
{{ 'APP.EDIT_PROFILE.INVALID_INPUT' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<mat-divider class="app-general-dropdown-divider" />
|
<mat-divider class="app-general-dropdown-divider" />
|
||||||
<div class="app-general-dropdown-details">
|
<div class="app-general-dropdown-details">
|
||||||
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.EMAIL' | translate}}</h4>
|
<h4 class="app-profile-general-dropdown-heading">{{'APP.EDIT_PROFILE.EMAIL' | translate}}</h4>
|
||||||
<p class="app-profile-general-dropdown-details" *ngIf="contactSectionButtonsToggle">{{personDetails?.company?.email}}</p>
|
@if (contactSectionButtonsToggle) {
|
||||||
<input type="text" value="" *ngIf="!contactSectionButtonsToggle" formControlName="companyEmail"
|
<p class="app-profile-general-dropdown-details">{{personDetails?.company?.email}}</p>
|
||||||
class="app-profile-general-dropdown-input-details app-selected" aria-describedby="app-view-profile-company-email-error-message">
|
} @else {
|
||||||
<mat-error class="app-error-message" *ngIf="profileForm.get('companyEmail').invalid" role="alert"
|
<input
|
||||||
id="app-view-profile-company-email-error-message">
|
type="text"
|
||||||
|
value=""
|
||||||
|
formControlName="companyEmail"
|
||||||
|
class="app-profile-general-dropdown-input-details app-selected"
|
||||||
|
aria-describedby="app-view-profile-company-email-error-message">
|
||||||
|
}
|
||||||
|
@if (profileForm.controls['companyEmail'].errors) {
|
||||||
|
<mat-error class="app-error-message" role="alert" id="app-view-profile-company-email-error-message">
|
||||||
{{ 'APP.EDIT_PROFILE.INVALID_INPUT' | translate }}
|
{{ 'APP.EDIT_PROFILE.INVALID_INPUT' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@for (section of sections; track $index) {
|
||||||
|
<adf-dynamic-component [id]="section.component"/>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ app-view-profile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.app-profile-general-icon {
|
.app-profile-general-icon {
|
||||||
|
padding: 0 0.5rem 0 1rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +53,16 @@ app-view-profile {
|
|||||||
|
|
||||||
.app-profile-general {
|
.app-profile-general {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-left: 1rem;
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.app-general-edit {
|
||||||
|
color: var(--adf-theme-foreground-text-color-054);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-general-cancel-btn {
|
||||||
|
color: var(--adf-metadata-action-button-clear-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-profile-general-bottom-radius {
|
.app-profile-general-bottom-radius {
|
||||||
@@ -62,48 +72,12 @@ app-view-profile {
|
|||||||
|
|
||||||
.app-profile-general-section {
|
.app-profile-general-section {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 60%;
|
align-items: center;
|
||||||
padding-top: 1rem;
|
width: 100%;
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-general-title {
|
|
||||||
margin-left: 0.6rem;
|
|
||||||
margin-top: 4px;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-general-edit-btn {
|
|
||||||
width: 60%;
|
|
||||||
text-align: end;
|
|
||||||
|
|
||||||
.app-general-edit {
|
|
||||||
background: var(--theme-grey-text-background-color);
|
|
||||||
height: 30px;
|
|
||||||
margin: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-general-cancel-btn {
|
|
||||||
height: 30px;
|
|
||||||
margin: 1rem;
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
background-color: var(--theme-grey-text-background-color);
|
|
||||||
padding-top: 0.25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-general-save-btn {
|
|
||||||
width: 75px;
|
|
||||||
height: 30px;
|
|
||||||
margin: 1rem;
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
color: var(--theme-white-background);
|
|
||||||
background-color: var(--theme-blue-button-color);
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-divider {
|
.app-divider {
|
||||||
border-top-width: 2px;
|
border-top-width: 1px;
|
||||||
border-top-color: var(--theme-grey-background-color);
|
border-top-color: var(--theme-grey-background-color);
|
||||||
padding-left: -1px;
|
padding-left: -1px;
|
||||||
padding-right: 1px;
|
padding-right: 1px;
|
||||||
@@ -116,10 +90,6 @@ app-view-profile {
|
|||||||
box-shadow: 0 0 2px var(--theme-blue-button-color);
|
box-shadow: 0 0 2px var(--theme-blue-button-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-general-edit:hover {
|
|
||||||
background: var(--theme-grey-hover-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-general-dropdown-divider {
|
.app-general-dropdown-divider {
|
||||||
border-top-color: var(--theme-grey-divider-color);
|
border-top-color: var(--theme-grey-divider-color);
|
||||||
}
|
}
|
||||||
@@ -183,7 +153,7 @@ app-view-profile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.app-profile-contact-row {
|
.app-profile-contact-row {
|
||||||
margin: 2rem 0 5rem 2rem;
|
margin: 2rem 0 0 2rem;
|
||||||
width: 70%;
|
width: 70%;
|
||||||
border: 1px solid var(--theme-grey-background-color);
|
border: 1px solid var(--theme-grey-background-color);
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
|
|||||||
+20
-16
@@ -25,13 +25,13 @@
|
|||||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||||
import { ViewProfileComponent } from './view-profile.component';
|
import { ViewProfileComponent } from './view-profile.component';
|
||||||
import { AppTestingModule } from '../../testing/app-testing.module';
|
import { AppTestingModule } from '../../testing/app-testing.module';
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { BehaviorSubject, Subject } from 'rxjs';
|
import { BehaviorSubject, of, Subject } from 'rxjs';
|
||||||
import { AppService } from '@alfresco/aca-shared';
|
import { AppExtensionService, AppService } from '@alfresco/aca-shared';
|
||||||
import { UnitTestingUtils } from '@alfresco/adf-core';
|
import { UnitTestingUtils } from '@alfresco/adf-core';
|
||||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||||
import { HarnessLoader } from '@angular/cdk/testing';
|
import { HarnessLoader } from '@angular/cdk/testing';
|
||||||
|
import { DynamicExtensionComponent } from '@alfresco/adf-extensions';
|
||||||
|
|
||||||
describe('ViewProfileComponent', () => {
|
describe('ViewProfileComponent', () => {
|
||||||
let fixture: ComponentFixture<ViewProfileComponent>;
|
let fixture: ComponentFixture<ViewProfileComponent>;
|
||||||
@@ -39,6 +39,7 @@ describe('ViewProfileComponent', () => {
|
|||||||
let router: Router;
|
let router: Router;
|
||||||
let unitTestingUtils: UnitTestingUtils;
|
let unitTestingUtils: UnitTestingUtils;
|
||||||
let loader: HarnessLoader;
|
let loader: HarnessLoader;
|
||||||
|
let appExtensionService: AppExtensionService;
|
||||||
|
|
||||||
const appServiceMock = {
|
const appServiceMock = {
|
||||||
toggleAppNavBar$: new Subject(),
|
toggleAppNavBar$: new Subject(),
|
||||||
@@ -61,6 +62,7 @@ describe('ViewProfileComponent', () => {
|
|||||||
router = TestBed.inject(Router);
|
router = TestBed.inject(Router);
|
||||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||||
unitTestingUtils = new UnitTestingUtils(fixture.debugElement, loader);
|
unitTestingUtils = new UnitTestingUtils(fixture.debugElement, loader);
|
||||||
|
appExtensionService = TestBed.inject(AppExtensionService);
|
||||||
router.initialNavigation();
|
router.initialNavigation();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -71,7 +73,7 @@ describe('ViewProfileComponent', () => {
|
|||||||
|
|
||||||
it('should toggle the appService toggleAppNavBar$ Subject', () => {
|
it('should toggle the appService toggleAppNavBar$ Subject', () => {
|
||||||
spyOn(appServiceMock.toggleAppNavBar$, 'next');
|
spyOn(appServiceMock.toggleAppNavBar$, 'next');
|
||||||
component.toggleClick();
|
component.toggleNavigationMenu();
|
||||||
expect(appServiceMock.toggleAppNavBar$.next).toHaveBeenCalled();
|
expect(appServiceMock.toggleAppNavBar$.next).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -156,8 +158,7 @@ describe('ViewProfileComponent', () => {
|
|||||||
component.generalSectionDropdown = false;
|
component.generalSectionDropdown = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const generalToggleIcon = fixture.debugElement.query(By.css('#toggle-general-dropdown'));
|
unitTestingUtils.clickByCSS('#general-dropdown button');
|
||||||
generalToggleIcon.triggerEventHandler('click', null);
|
|
||||||
|
|
||||||
expect(component.toggleGeneralDropdown).toHaveBeenCalled();
|
expect(component.toggleGeneralDropdown).toHaveBeenCalled();
|
||||||
expect(component.generalSectionButtonsToggle).toBe(true);
|
expect(component.generalSectionButtonsToggle).toBe(true);
|
||||||
@@ -168,8 +169,7 @@ describe('ViewProfileComponent', () => {
|
|||||||
component.contactSectionDropdown = false;
|
component.contactSectionDropdown = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const contactToggleIcon = fixture.debugElement.query(By.css('#toggle-contact-dropdown'));
|
unitTestingUtils.clickByCSS('#contact-dropdown button');
|
||||||
contactToggleIcon.triggerEventHandler('click', null);
|
|
||||||
|
|
||||||
expect(component.toggleContactDropdown).toHaveBeenCalled();
|
expect(component.toggleContactDropdown).toHaveBeenCalled();
|
||||||
expect(component.contactSectionButtonsToggle).toBe(true);
|
expect(component.contactSectionButtonsToggle).toBe(true);
|
||||||
@@ -179,12 +179,10 @@ describe('ViewProfileComponent', () => {
|
|||||||
spyOn(component, 'toggleGeneralButtons').and.callThrough();
|
spyOn(component, 'toggleGeneralButtons').and.callThrough();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const generalEditButton = fixture.debugElement.query(By.css('#general-edit-button'));
|
unitTestingUtils.clickByCSS('#general-dropdown .app-general-edit');
|
||||||
generalEditButton.triggerEventHandler('click', null);
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const generalCancelButton = fixture.debugElement.query(By.css('#general-cancel-button'));
|
unitTestingUtils.clickByCSS('#general-dropdown .app-general-cancel-btn');
|
||||||
generalCancelButton.triggerEventHandler('click', null);
|
|
||||||
|
|
||||||
expect(component.toggleGeneralButtons).toHaveBeenCalledTimes(2);
|
expect(component.toggleGeneralButtons).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
@@ -193,12 +191,10 @@ describe('ViewProfileComponent', () => {
|
|||||||
spyOn(component, 'toggleContactButtons').and.callThrough();
|
spyOn(component, 'toggleContactButtons').and.callThrough();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const contactEditButton = fixture.debugElement.query(By.css('#contact-edit-button'));
|
unitTestingUtils.clickByCSS('#contact-dropdown .app-general-edit');
|
||||||
contactEditButton.triggerEventHandler('click', null);
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const contactCancelButton = fixture.debugElement.query(By.css('#contact-cancel-button'));
|
unitTestingUtils.clickByCSS('#contact-dropdown .app-general-cancel-btn');
|
||||||
contactCancelButton.triggerEventHandler('click', null);
|
|
||||||
|
|
||||||
expect(component.toggleContactButtons).toHaveBeenCalledTimes(2);
|
expect(component.toggleContactButtons).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
@@ -209,4 +205,12 @@ describe('ViewProfileComponent', () => {
|
|||||||
|
|
||||||
expect(router.navigate).toHaveBeenCalledWith(['/personal-files'], { replaceUrl: true });
|
expect(router.navigate).toHaveBeenCalledWith(['/personal-files'], { replaceUrl: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should render additional user profile sections if provided', () => {
|
||||||
|
spyOn(appExtensionService, 'getUserProfileSections').and.returnValue(of([{ id: 'test-section' }]));
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.sections.length).toBe(1);
|
||||||
|
expect(unitTestingUtils.getByDirective(DynamicExtensionComponent)).toBeDefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ import { PeopleApi, Person } from '@alfresco/js-api';
|
|||||||
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||||
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Observable, throwError } from 'rxjs';
|
import { Observable, take, throwError } from 'rxjs';
|
||||||
import { AppService } from '@alfresco/aca-shared';
|
import { AppExtensionService, AppService, UserProfileSection } from '@alfresco/aca-shared';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
@@ -36,9 +36,19 @@ import { TranslatePipe } from '@ngx-translate/core';
|
|||||||
import { MatDividerModule } from '@angular/material/divider';
|
import { MatDividerModule } from '@angular/material/divider';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
|
import { DynamicExtensionComponent } from '@alfresco/adf-extensions';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
imports: [CommonModule, TranslatePipe, ReactiveFormsModule, MatButtonModule, MatIconModule, MatDividerModule, MatFormFieldModule],
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
TranslatePipe,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
MatButtonModule,
|
||||||
|
MatIconModule,
|
||||||
|
MatDividerModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
DynamicExtensionComponent
|
||||||
|
],
|
||||||
selector: 'app-view-profile',
|
selector: 'app-view-profile',
|
||||||
templateUrl: './view-profile.component.html',
|
templateUrl: './view-profile.component.html',
|
||||||
styleUrls: ['./view-profile.component.scss'],
|
styleUrls: ['./view-profile.component.scss'],
|
||||||
@@ -60,13 +70,15 @@ export class ViewProfileComponent implements OnInit {
|
|||||||
contactSectionDropdown = false;
|
contactSectionDropdown = false;
|
||||||
contactSectionButtonsToggle = true;
|
contactSectionButtonsToggle = true;
|
||||||
appNavNarMode$: Observable<'collapsed' | 'expanded'>;
|
appNavNarMode$: Observable<'collapsed' | 'expanded'>;
|
||||||
|
sections: UserProfileSection[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
apiService: AlfrescoApiService,
|
private readonly apiService: AlfrescoApiService,
|
||||||
private appService: AppService
|
private readonly appService: AppService,
|
||||||
|
private readonly extensionService: AppExtensionService
|
||||||
) {
|
) {
|
||||||
this.peopleApi = new PeopleApi(apiService.getInstance());
|
this.peopleApi = new PeopleApi(this.apiService.getInstance());
|
||||||
this.appNavNarMode$ = appService.appNavNarMode$.pipe(takeUntilDestroyed());
|
this.appNavNarMode$ = appService.appNavNarMode$.pipe(takeUntilDestroyed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,9 +93,14 @@ export class ViewProfileComponent implements OnInit {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
throwError(error);
|
throwError(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.extensionService
|
||||||
|
.getUserProfileSections()
|
||||||
|
.pipe(take(1))
|
||||||
|
.subscribe((sections) => (this.sections = sections));
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleClick() {
|
toggleNavigationMenu() {
|
||||||
this.appService.toggleAppNavBar$.next();
|
this.appService.toggleAppNavBar$.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,10 +129,6 @@ export class ViewProfileComponent implements OnInit {
|
|||||||
|
|
||||||
toggleGeneralDropdown() {
|
toggleGeneralDropdown() {
|
||||||
this.generalSectionDropdown = !this.generalSectionDropdown;
|
this.generalSectionDropdown = !this.generalSectionDropdown;
|
||||||
|
|
||||||
if (!this.generalSectionDropdown) {
|
|
||||||
this.generalSectionButtonsToggle = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleGeneralButtons() {
|
toggleGeneralButtons() {
|
||||||
@@ -143,10 +156,6 @@ export class ViewProfileComponent implements OnInit {
|
|||||||
|
|
||||||
toggleLoginDropdown() {
|
toggleLoginDropdown() {
|
||||||
this.loginSectionDropdown = !this.loginSectionDropdown;
|
this.loginSectionDropdown = !this.loginSectionDropdown;
|
||||||
|
|
||||||
if (!this.loginSectionDropdown) {
|
|
||||||
this.loginSectionButtonsToggle = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleLoginButtons() {
|
toggleLoginButtons() {
|
||||||
@@ -161,10 +170,6 @@ export class ViewProfileComponent implements OnInit {
|
|||||||
|
|
||||||
toggleContactDropdown() {
|
toggleContactDropdown() {
|
||||||
this.contactSectionDropdown = !this.contactSectionDropdown;
|
this.contactSectionDropdown = !this.contactSectionDropdown;
|
||||||
|
|
||||||
if (!this.contactSectionDropdown) {
|
|
||||||
this.contactSectionButtonsToggle = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleContactButtons() {
|
toggleContactButtons() {
|
||||||
|
|||||||
@@ -1196,6 +1196,18 @@ describe('app.evaluators', () => {
|
|||||||
expect(app.isSmartFolder(context)).toBeTrue();
|
expect(app.isSmartFolder(context)).toBeTrue();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isSSOEnabled', () => {
|
||||||
|
it('should return true if sso is enabled', () => {
|
||||||
|
context.appConfig = { get: () => 'OAUTH' } as any;
|
||||||
|
expect(app.isSSOEnabled(context)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false if sso is not enabled', () => {
|
||||||
|
context.appConfig = { get: () => 'basic' } as any;
|
||||||
|
expect(app.isSSOEnabled(context)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Versions compatibility', () => {
|
describe('Versions compatibility', () => {
|
||||||
|
|||||||
@@ -560,3 +560,5 @@ export const canDisplayKnowledgeRetrievalButton = (context: AcaRuleContext): boo
|
|||||||
navigation.isRecentFiles(context) ||
|
navigation.isRecentFiles(context) ||
|
||||||
navigation.isFavorites(context) ||
|
navigation.isFavorites(context) ||
|
||||||
((navigation.isSearchResults(context) || navigation.isLibraryContent(context)) && !navigation.isLibraries(context)));
|
((navigation.isSearchResults(context) || navigation.isLibraryContent(context)) && !navigation.isLibraries(context)));
|
||||||
|
|
||||||
|
export const isSSOEnabled = (context: AcaRuleContext): boolean => context.appConfig.get('authType') === 'OAUTH';
|
||||||
|
|||||||
@@ -34,3 +34,7 @@ export interface Badge extends Partial<Pick<ContentActionRef, 'component' | 'act
|
|||||||
icon: string;
|
icon: string;
|
||||||
tooltip: string;
|
tooltip: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UserProfileSection extends Partial<Pick<ContentActionRef, 'component' | 'rules'>> {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1682,6 +1682,41 @@ describe('AppExtensionService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should get custom user profile sections from config', (done) => {
|
||||||
|
extensions.setEvaluators({
|
||||||
|
'action.enabled': () => true
|
||||||
|
});
|
||||||
|
|
||||||
|
applyConfig({
|
||||||
|
...defaultConfigMock,
|
||||||
|
features: {
|
||||||
|
userProfileSections: [
|
||||||
|
{
|
||||||
|
id: 'section1-id',
|
||||||
|
component: 'testComponent1',
|
||||||
|
rules: {
|
||||||
|
visible: 'action.enabled'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'section2-id',
|
||||||
|
component: 'testComponent2',
|
||||||
|
rules: {
|
||||||
|
visible: 'action.enabled'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
service.getUserProfileSections().subscribe((sections) => {
|
||||||
|
expect(sections.length).toBe(2);
|
||||||
|
expect(sections[0].id).toEqual('section1-id');
|
||||||
|
expect(sections[1].id).toEqual('section2-id');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should update sidebar actions correctly', () => {
|
it('should update sidebar actions correctly', () => {
|
||||||
spyOn(loader, 'getContentActions').and.callThrough();
|
spyOn(loader, 'getContentActions').and.callThrough();
|
||||||
service.updateSidebarActions();
|
service.updateSidebarActions();
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import { AppConfigService, AuthenticationService, LogService } from '@alfresco/a
|
|||||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||||
import { NodeEntry, RepositoryInfo } from '@alfresco/js-api';
|
import { NodeEntry, RepositoryInfo } from '@alfresco/js-api';
|
||||||
import { ViewerRules } from '../models/viewer.rules';
|
import { ViewerRules } from '../models/viewer.rules';
|
||||||
import { Badge } from '../models/types';
|
import { Badge, UserProfileSection } from '../models/types';
|
||||||
import { NodePermissionService } from '../services/node-permission.service';
|
import { NodePermissionService } from '../services/node-permission.service';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { SearchCategory } from '@alfresco/adf-content-services';
|
import { SearchCategory } from '@alfresco/adf-content-services';
|
||||||
@@ -92,6 +92,7 @@ export class AppExtensionService implements RuleContext {
|
|||||||
private _filesDocumentListPreset = new BehaviorSubject<Array<DocumentListPresetRef>>([]);
|
private _filesDocumentListPreset = new BehaviorSubject<Array<DocumentListPresetRef>>([]);
|
||||||
private _customMetadataPanels = new BehaviorSubject<Array<ContentActionRef>>([]);
|
private _customMetadataPanels = new BehaviorSubject<Array<ContentActionRef>>([]);
|
||||||
private _bulkActions = new BehaviorSubject<Array<ContentActionRef>>([]);
|
private _bulkActions = new BehaviorSubject<Array<ContentActionRef>>([]);
|
||||||
|
private readonly _userProfileSections = new BehaviorSubject<Array<UserProfileSection>>([]);
|
||||||
|
|
||||||
documentListPresets: {
|
documentListPresets: {
|
||||||
libraries: Array<DocumentListPresetRef>;
|
libraries: Array<DocumentListPresetRef>;
|
||||||
@@ -169,6 +170,7 @@ export class AppExtensionService implements RuleContext {
|
|||||||
this._openWithActions.next(this.loader.getContentActions(config, 'features.viewer.openWith'));
|
this._openWithActions.next(this.loader.getContentActions(config, 'features.viewer.openWith'));
|
||||||
this._createActions.next(this.loader.getElements<ContentActionRef>(config, 'features.create'));
|
this._createActions.next(this.loader.getElements<ContentActionRef>(config, 'features.create'));
|
||||||
this._badges.next(this.loader.getElements<Badge>(config, 'features.badges'));
|
this._badges.next(this.loader.getElements<Badge>(config, 'features.badges'));
|
||||||
|
this._userProfileSections.next(this.loader.getElements<UserProfileSection>(config, 'features.userProfileSections'));
|
||||||
this._filesDocumentListPreset.next(this.getDocumentListPreset(config, 'files'));
|
this._filesDocumentListPreset.next(this.getDocumentListPreset(config, 'files'));
|
||||||
this._customMetadataPanels.next(this.loader.getElements<ContentActionRef>(config, 'features.customMetadataPanels'));
|
this._customMetadataPanels.next(this.loader.getElements<ContentActionRef>(config, 'features.customMetadataPanels'));
|
||||||
this._bulkActions.next(this.loader.getElements<ContentActionRef>(config, 'features.bulk-actions'));
|
this._bulkActions.next(this.loader.getElements<ContentActionRef>(config, 'features.bulk-actions'));
|
||||||
@@ -384,6 +386,10 @@ export class AppExtensionService implements RuleContext {
|
|||||||
return this._badges.pipe(map((badges) => badges.filter((badge) => this.evaluateRule(badge.rules.visible, node))));
|
return this._badges.pipe(map((badges) => badges.filter((badge) => this.evaluateRule(badge.rules.visible, node))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getUserProfileSections(): Observable<Array<UserProfileSection>> {
|
||||||
|
return this._userProfileSections.pipe(map((sections) => sections.filter((section) => this.evaluateRule(section.rules.visible))));
|
||||||
|
}
|
||||||
|
|
||||||
getCustomMetadataPanels(node: NodeEntry): Observable<Array<ContentActionRef>> {
|
getCustomMetadataPanels(node: NodeEntry): Observable<Array<ContentActionRef>> {
|
||||||
return this._customMetadataPanels.pipe(map((panels) => panels.filter((panel) => this.evaluateRule(panel.rules.visible, node))));
|
return this._customMetadataPanels.pipe(map((panels) => panels.filter((panel) => this.evaluateRule(panel.rules.visible, node))));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user