[AAE-10766] presentational and reusable About (#7969)

This commit is contained in:
Denys Vuika 2022-11-11 16:01:02 +00:00 committed by GitHub
parent 5abe22b9c8
commit 1109a73a19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 319 additions and 192 deletions

View File

@ -1,4 +1,34 @@
<mat-slide-toggle [(ngModel)]="dev">{{'APP.ABOUT.DEVELOPMENT' | translate }}</mat-slide-toggle> <mat-slide-toggle [(ngModel)]="dev">{{'APP.ABOUT.DEVELOPMENT' | translate }}</mat-slide-toggle>
<adf-about [dev]="dev" [pkg]="pkg"> </adf-about> <adf-about>
<adf-about-panel *ngIf="dev" [label]="'ABOUT.SERVER_SETTINGS.TITLE' | translate">
<ng-template>
<adf-about-server-settings></adf-about-server-settings>
</ng-template>
</adf-about-panel>
<adf-about-panel *ngIf="dev" [label]="'ABOUT.PACKAGES.TITLE' | translate">
<ng-template>
<adf-about-package-list [dependencies]="pkg?.dependencies"></adf-about-package-list>
</ng-template>
</adf-about-panel>
<adf-about-panel [label]="'ABOUT.REPOSITORY' | translate" *ngIf="repository">
<ng-template>
<adf-about-repository-info [data]="repository"></adf-about-repository-info>
</ng-template>
</adf-about-panel>
<adf-about-panel [label]="'ABOUT.VERSIONS.TITLE' | translate">
<ng-template>
<adf-about-platform-version [repository]="repository" [process]="bpmVersion"></adf-about-platform-version>
</ng-template>
</adf-about-panel>
<adf-about-panel *ngIf="extensions$ | async as extensions" [label]="'ABOUT.PLUGINS.TITLE' | translate">
<ng-template>
<adf-about-extension-list [data]="extensions"></adf-about-extension-list>
</ng-template>
</adf-about-panel>
</adf-about>

View File

@ -1,3 +0,0 @@
.adf-extension-details-container {
padding: 4px;
}

View File

@ -15,20 +15,52 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { AppExtensionService, ExtensionRef } from '@alfresco/adf-extensions';
import { AuthenticationService, BpmProductVersionModel, DiscoveryApiService, RepositoryInfo } from '@alfresco/adf-core';
import pkg from '../../../../../package.json'; import pkg from '../../../../../package.json';
import { Observable } from 'rxjs';
@Component({ @Component({
selector: 'app-about-page', selector: 'app-about-page',
templateUrl: './about.component.html', templateUrl: './about.component.html'
styleUrls: ['./about.component.scss']
}) })
export class AboutComponent { export class AboutComponent implements OnInit {
pkg: any; pkg: any;
dev: true; dev: true;
constructor() { extensions$: Observable<ExtensionRef[]>;
repository: RepositoryInfo = null;
bpmVersion: BpmProductVersionModel = null;
constructor(
private authService: AuthenticationService,
private appExtensions: AppExtensionService,
private discovery: DiscoveryApiService
) {
this.pkg = pkg; this.pkg = pkg;
this.extensions$ = this.appExtensions.references$;
} }
ngOnInit(): void {
if (this.authService.isEcmLoggedIn()) {
this.setECMInfo();
}
if (this.authService.isBpmLoggedIn()) {
this.setBPMInfo();
}
}
setECMInfo() {
this.discovery.getEcmProductInfo().subscribe((repository) => {
this.repository = repository as RepositoryInfo;
});
}
setBPMInfo() {
this.discovery.getBpmProductInfo().subscribe((bpmVersion) => {
this.bpmVersion = bpmVersion;
});
}
} }

View File

@ -0,0 +1,56 @@
---
Title: About Component
Added: v3.5.0
Status: Active
Last reviewed: 2022-11-11
---
# About Component
Presentational component to display About information as a set of collapsible panels.
## Basic Usage
```html
<adf-about>
<adf-about-panel [label]="'Panel 1'">
<ng-template>
<your-components></your-components>
</ng-template>
</adf-about-panel>
<adf-about-panel [label]="'Panel 2'">
<ng-template>
<your-components></your-components>
</ng-template>
</adf-about-panel>
</adf-about>
```
## Conditional Display
You can wire each panel with the `*ngIf` conditions:
```html
<adf-about>
<adf-about-panel *ngIf="devMode" [label]="'Panel 1'">
<ng-template>
<your-components></your-components>
</ng-template>
</adf-about-panel>
</adf-about>
```
Where `devMode` is an example of an input property exposed by your component.
Observables are also supported:
```html
<adf-about>
<adf-about-panel *ngIf="extensions$ | async as extensions" [label]="'ABOUT.PLUGINS.TITLE' | translate">
<ng-template>
<adf-about-extension-list [data]="extensions"></adf-about-extension-list>
</ng-template>
</adf-about-panel>
</adf-about>
```

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input } from '@angular/core'; import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input, OnInit } from '@angular/core';
import { PackageInfo } from '../interfaces'; import { PackageInfo } from '../interfaces';
@Component({ @Component({
@ -24,7 +24,11 @@ import { PackageInfo } from '../interfaces';
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class PackageListComponent { export class PackageListComponent implements OnInit {
@Input()
dependencies: any;
columns = [ columns = [
{ {
columnDef: 'title', columnDef: 'title',
@ -42,4 +46,20 @@ export class PackageListComponent {
@Input() @Input()
data: Array<PackageInfo> = []; data: Array<PackageInfo> = [];
ngOnInit() {
const regexp = new RegExp('^(@alfresco)');
if (this.dependencies) {
const libs = Object.keys(this.dependencies).filter((val) => regexp.test(val));
this.data = [];
libs.forEach((val) => {
this.data.push({
name: val,
version: (this.dependencies[val])
});
});
}
}
} }

View File

@ -0,0 +1,28 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ContentChild, Directive, Input, TemplateRef } from '@angular/core';
@Directive({
selector: 'adf-about-panel'
})
export class AboutPanelDirective {
@Input() label!: string;
@ContentChild(TemplateRef)
layoutTemplate!: TemplateRef<any>;
}

View File

@ -0,0 +1,16 @@
<div>
<article *ngIf="licenseEntries">
<header>{{ 'ABOUT.LICENSE.TITLE' | translate }}</header>
<adf-about-license-list [data]="licenseEntries"></adf-about-license-list>
</article>
<article *ngIf="statusEntries">
<header>{{ 'ABOUT.STATUS.TITLE' | translate }}</header>
<adf-about-status-list [data]="statusEntries"></adf-about-status-list>
</article>
<article *ngIf="data?.modules">
<header>{{ 'ABOUT.MODULES.TITLE' | translate }}</header>
<adf-about-module-list [data]="data.modules"></adf-about-module-list>
</article>
</div>

View File

@ -0,0 +1,60 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component, Input, OnInit } from '@angular/core';
import { ObjectUtils, StringUtils } from '../../utils';
import { LicenseData, StatusData } from '../interfaces';
import { RepositoryInfo } from './repository-info.interface';
@Component({
selector: 'adf-about-repository-info',
templateUrl: './about-repository-info.component.html'
})
export class AboutRepositoryInfoComponent implements OnInit {
@Input()
data: RepositoryInfo;
statusEntries: StatusData[];
licenseEntries: LicenseData[];
ngOnInit(): void {
if (this.data) {
const repository = this.data;
this.statusEntries = Object.keys(repository.status).map((key) => ({
property: key,
value: repository.status[key]
}));
if (repository.license) {
this.licenseEntries = Object.keys(repository.license).map((key) => {
if (ObjectUtils.isObject(repository.license[key])) {
return {
property: key,
value: ObjectUtils.booleanPrettify(repository.license[key], StringUtils.prettifyBooleanEnabled)
};
};
return {
property: key,
value: repository.license[key]
};
});
}
}
}
}

View File

@ -0,0 +1,47 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export interface RepositoryInfo {
status: {
isReadOnly: boolean;
isAuditEnabled: boolean;
isQuickShareEnabled: boolean;
isThumbnailGenerationEnabled: boolean;
isDirectAccessUrlEnabled: boolean;
};
edition: string;
version: {
display: string;
};
license?: {
issuedAt: Date;
expiresAt: Date;
remainingDays: number;
holder: string;
mode: string;
entitlements?: {
maxUsers?: number;
maxDocs?: number;
isClusterEnabled?: boolean;
isCryptodocEnabled?: boolean;
};
};
modules?: Array<{
title: string;
version: string;
}>;
}

View File

@ -1,51 +1,10 @@
<mat-accordion [togglePosition]="'before'"> <mat-accordion [togglePosition]="'before'">
<mat-expansion-panel *ngIf="dev"> <ng-container *ngFor="let panel of panels">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'ABOUT.SERVER_SETTINGS.TITLE' | translate }}</mat-panel-title>
</mat-expansion-panel-header>
<adf-about-server-settings></adf-about-server-settings>
</mat-expansion-panel>
<mat-expansion-panel> <mat-expansion-panel>
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title>{{ 'ABOUT.VERSIONS.TITLE' | translate }}</mat-panel-title> <mat-panel-title>{{panel.label}}</mat-panel-title>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<adf-about-platform-version [repository]="repository" [process]="bpmVersion"></adf-about-platform-version> <ng-container *ngTemplateOutlet="panel.layoutTemplate"></ng-container>
</mat-expansion-panel>
<mat-expansion-panel *ngIf="repository">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'ABOUT.REPOSITORY' | translate }}</mat-panel-title>
</mat-expansion-panel-header>
<div>
<article *ngIf="licenseEntries">
<header>{{ 'ABOUT.LICENSE.TITLE' | translate }}</header>
<adf-about-license-list [data]="licenseEntries"></adf-about-license-list>
</article>
<article *ngIf="statusEntries">
<header>{{ 'ABOUT.STATUS.TITLE' | translate }}</header>
<adf-about-status-list [data]="statusEntries"></adf-about-status-list>
</article>
<article *ngIf="repository?.modules">
<header>{{ 'ABOUT.MODULES.TITLE' | translate }}</header>
<adf-about-module-list [data]="repository.modules"></adf-about-module-list>
</article>
</div>
</mat-expansion-panel>
<mat-expansion-panel *ngIf="dependencyEntries && dev">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'ABOUT.PACKAGES.TITLE' | translate }}</mat-panel-title>
</mat-expansion-panel-header>
<adf-about-package-list [data]="dependencyEntries"></adf-about-package-list>
</mat-expansion-panel>
<mat-expansion-panel *ngIf="extensions$ | async as extensions">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'ABOUT.PLUGINS.TITLE' | translate }}</mat-panel-title>
</mat-expansion-panel-header>
<adf-about-extension-list [data]="extensions"></adf-about-extension-list>
</mat-expansion-panel> </mat-expansion-panel>
</ng-container>
</mat-accordion> </mat-accordion>

View File

@ -15,142 +15,15 @@
* limitations under the License. * limitations under the License.
*/ */
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; import { Component, ContentChildren, QueryList, ViewEncapsulation } from '@angular/core';
import { AppExtensionService, ExtensionRef } from '@alfresco/adf-extensions'; import { AboutPanelDirective } from './about-panel.directive';
import { Observable } from 'rxjs';
import { AppConfigService } from '../app-config/app-config.service';
import { BpmProductVersionModel } from '../models/product-version.model';
import { AuthenticationService } from '../services/authentication.service';
import { DiscoveryApiService } from '../services/discovery-api.service';
import { LicenseData, PackageInfo, StatusData } from './interfaces';
import { ObjectUtils } from '../utils/object-utils';
import { StringUtils } from '../utils/string-utils';
interface RepositoryInfo {
status: {
isReadOnly: boolean;
isAuditEnabled: boolean;
isQuickShareEnabled: boolean;
isThumbnailGenerationEnabled: boolean;
isDirectAccessUrlEnabled: boolean;
};
edition: string;
version: {
display: string;
};
license?: {
issuedAt: Date;
expiresAt: Date;
remainingDays: number;
holder: string;
mode: string;
entitlements?: {
maxUsers?: number;
maxDocs?: number;
isClusterEnabled?: boolean;
isCryptodocEnabled?: boolean;
};
};
modules?: Array<{
title: string;
version: string;
}>;
}
@Component({ @Component({
selector: 'adf-about', selector: 'adf-about',
templateUrl: './about.component.html', templateUrl: './about.component.html',
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class AboutComponent implements OnInit { export class AboutComponent {
@ContentChildren(AboutPanelDirective)
repository: RepositoryInfo = null; panels: QueryList<AboutPanelDirective>;
bpmVersion: BpmProductVersionModel = null;
statusEntries: StatusData[];
licenseEntries: LicenseData[];
dependencyEntries: PackageInfo[] = [];
version: string;
dependencies: string;
application: string;
/** If active show more information about the app and the platform useful in debug. */
@Input() dev: boolean = false;
/** pkg json. */
@Input() pkg: any;
/** Regular expression for filtering dependencies packages. */
@Input() regexp = '^(@alfresco)';
extensions$: Observable<ExtensionRef[]>;
constructor(private authService: AuthenticationService,
private discovery: DiscoveryApiService,
private appExtensions: AppExtensionService,
private appConfigService: AppConfigService) {
this.extensions$ = this.appExtensions.references$;
this.application = this.appConfigService.get<string>(
'application.name'
);
}
ngOnInit() {
this.version = this.pkg?.version;
this.dependencies = this.pkg?.dependencies;
if (this.dependencies) {
const alfrescoPackages = Object.keys(this.dependencies).filter((val) => new RegExp(this.regexp).test(val));
alfrescoPackages.forEach((val) => {
this.dependencyEntries.push({
name: val,
version: (this.dependencies[val])
});
});
}
if (this.authService.isEcmLoggedIn()) {
this.setECMInfo();
}
if (this.authService.isBpmLoggedIn()) {
this.setBPMInfo();
}
}
setECMInfo() {
this.discovery.getEcmProductInfo().subscribe((repository) => {
this.repository = repository as RepositoryInfo;
this.statusEntries = Object.keys(repository.status).map((key) => ({
property: key,
value: repository.status[key]
}));
if (repository.license) {
this.licenseEntries = Object.keys(repository.license).map((key) => {
if (ObjectUtils.isObject(repository.license[key])) {
return {
property: key,
value: ObjectUtils.booleanPrettify(repository.license[key], StringUtils.prettifyBooleanEnabled)
};
};
return {
property: key,
value: repository.license[key]
};
});
}
});
}
setBPMInfo() {
this.discovery.getBpmProductInfo().subscribe((bpmVersion) => {
this.bpmVersion = bpmVersion;
});
}
} }

View File

@ -30,6 +30,8 @@ import { ModuleListComponent } from './about-module-list/module-list.component';
import { AboutPlatformVersionComponent } from './about-platform-version/about-platform-version.component'; import { AboutPlatformVersionComponent } from './about-platform-version/about-platform-version.component';
import { AboutComponent } from './about.component'; import { AboutComponent } from './about.component';
import { MatExpansionModule } from '@angular/material/expansion'; import { MatExpansionModule } from '@angular/material/expansion';
import { AboutPanelDirective } from './about-panel.directive';
import { AboutRepositoryInfoComponent } from './about-repository-info/about-repository-info.component';
@NgModule({ @NgModule({
imports: [ imports: [
@ -40,6 +42,8 @@ import { MatExpansionModule } from '@angular/material/expansion';
], ],
declarations: [ declarations: [
AboutComponent, AboutComponent,
AboutPanelDirective,
AboutRepositoryInfoComponent,
AboutPlatformVersionComponent, AboutPlatformVersionComponent,
AboutGithubLinkComponent, AboutGithubLinkComponent,
AboutServerSettingsComponent, AboutServerSettingsComponent,
@ -51,6 +55,8 @@ import { MatExpansionModule } from '@angular/material/expansion';
], ],
exports: [ exports: [
AboutComponent, AboutComponent,
AboutPanelDirective,
AboutRepositoryInfoComponent,
AboutPlatformVersionComponent, AboutPlatformVersionComponent,
AboutGithubLinkComponent, AboutGithubLinkComponent,
AboutServerSettingsComponent, AboutServerSettingsComponent,

View File

@ -24,5 +24,8 @@ export * from './about-platform-version/about-platform-version.component';
export * from './about-server-settings/about-server-settings.component'; export * from './about-server-settings/about-server-settings.component';
export * from './about-status-list/about-status-list.component'; export * from './about-status-list/about-status-list.component';
export * from './about.component'; export * from './about.component';
export * from './about-panel.directive';
export * from './about-repository-info/about-repository-info.component';
export * from './about-repository-info/repository-info.interface';
export * from './about.module'; export * from './about.module';