Compare commits

...
Author SHA1 Message Date
Denys Vuika 0baf221ce9 new docs for About component 2025-07-23 09:50:51 -04:00
dependabot[bot] 5e6e2b5949 build(deps): bump form-data from 3.0.1 to 3.0.4 in /tools/doc (#11043)
Bumps [form-data](https://github.com/form-data/form-data) from 3.0.1 to 3.0.4.
- [Release notes](https://github.com/form-data/form-data/releases)
- [Changelog](https://github.com/form-data/form-data/blob/v3.0.4/CHANGELOG.md)
- [Commits](https://github.com/form-data/form-data/compare/v3.0.1...v3.0.4)

---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 3.0.4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-22 08:18:42 +02:00
Denys VuikaandAnton Ramanovich 0b90affea4 ACS-8770 Update the Auth Service api docs and deprecations (#9947)
* update api docs and clean dead code

* update api docs and clean dead code

rebasing onto develop branch

* [ACS-8770] fix unit test after auth refactor

* [ACS-8770] fix sonarcube issues

* [ACS-8770] update auth service doc file

* [ACS-8770] clean up demo-shell artifacts

---------

Co-authored-by: Anton Ramanovich <Anton.Ramanovich@hyland.com>
2025-07-21 15:16:59 +02:00
Soumyajit Chakraborty 45834e20f9 AAE-36388 fixing form-field cut issue on preview (#11025) 2025-07-21 18:22:06 +05:30
dependabot[bot] f67a7d0721 build(deps): bump Alfresco/alfresco-build-tools from 8.26.0 to 8.27.0 (#11038)
---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 8.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-21 09:44:46 +02:00
dependabot[bot] 4dd8367878 build(deps): bump Alfresco/alfresco-build-tools (#11037)
Bumps [Alfresco/alfresco-build-tools](https://github.com/alfresco/alfresco-build-tools) from 8.26.0 to 8.27.0.
- [Release notes](https://github.com/alfresco/alfresco-build-tools/releases)
- [Commits](https://github.com/alfresco/alfresco-build-tools/compare/691c1d16c90c88a92d2438a001acdefc0efa7d2a...20d21f43addae05442096a7e935dc2b321361501)

---
updated-dependencies:
- dependency-name: Alfresco/alfresco-build-tools
  dependency-version: 8.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-21 09:34:29 +02:00
dependabot[bot] b2246cb148 build(deps-dev): bump eslint-plugin-prettier from 4.2.1 to 5.5.3 (#11034)
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 4.2.1 to 5.5.3.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v4.2.1...v5.5.3)

---
updated-dependencies:
- dependency-name: eslint-plugin-prettier
  dependency-version: 5.5.3
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-21 09:28:28 +02:00
dependabot[bot] fb3a9ca2c2 build(deps): bump on-headers and compression (#11030)
Bumps [on-headers](https://github.com/jshttp/on-headers) and [compression](https://github.com/expressjs/compression). These dependencies needed to be updated together.

Updates `on-headers` from 1.0.2 to 1.1.0
- [Release notes](https://github.com/jshttp/on-headers/releases)
- [Changelog](https://github.com/jshttp/on-headers/blob/master/HISTORY.md)
- [Commits](https://github.com/jshttp/on-headers/compare/v1.0.2...v1.1.0)

Updates `compression` from 1.8.0 to 1.8.1
- [Release notes](https://github.com/expressjs/compression/releases)
- [Changelog](https://github.com/expressjs/compression/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/compression/compare/1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: on-headers
  dependency-version: 1.1.0
  dependency-type: indirect
- dependency-name: compression
  dependency-version: 1.8.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-21 09:20:10 +02:00
Grzegorz Jaśkowski f15014f295 [ACS-9880] Create ADF upgrade guide from 7.0.0 to 8.0.0 (#11029)
* [ACS-9880] add ADF upgrade from 7.0.0 to 8.0.0 guide

* [ACS-9880] add missing commas and values [ci:force]
2025-07-18 14:19:06 +02:00
dominikiwanekhyland b28479b92b [AAE-32978] Move ADF "RichTextEditorComponent" to HxP monorepo (#10967) 2025-07-17 12:11:56 +02:00
AleksanderSklorz 89380f2905 [ACS-7266] checkboxes in sorting boxes are put on the right side of the text instead of the left side (#11009)
* [ACS-7266] Fix for checkboxes position

* [ACS-7266] Unit test

* [ACS-7266] Addressed comment
2025-07-16 09:13:10 +02:00
AleksanderSklorz e5fcfde2ec Post release version bump (#11021)
* Trigger Build

* Post release bump
2025-07-15 16:16:03 +02:00
Maurizio Vitale 2e10d2c5c7 AAE-36718 Expose a landing page provider for the landing-page-token (#11020)
* Expose a landing page provider for the landin-page-token

* Expose a landing page provider for the landin-page-token

* fix lint

* fix lint
2025-07-15 14:54:18 +01:00
Alfresco BuildandCrowdin Bot 96281d32a1 New Crowdin translations by GitHub Action (#11017)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-07-15 14:46:38 +01:00
52 changed files with 3200 additions and 1552 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ runs:
cache-dependency-path: package-lock.json
- name: get latest tag sha
id: tag-sha
uses: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag@691c1d16c90c88a92d2438a001acdefc0efa7d2a # v8.26.0
uses: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag@20d21f43addae05442096a7e935dc2b321361501 # v8.27.0
# CACHE
- name: Node Modules cache
id: node-modules-cache
+2 -2
View File
@@ -84,10 +84,10 @@ jobs:
fetch-depth: 0
- name: Get branch name
uses: Alfresco/alfresco-build-tools/.github/actions/get-branch-name@691c1d16c90c88a92d2438a001acdefc0efa7d2a # v8.26.0
uses: Alfresco/alfresco-build-tools/.github/actions/get-branch-name@20d21f43addae05442096a7e935dc2b321361501 # v8.27.0
- name: Save commit message
uses: Alfresco/alfresco-build-tools/.github/actions/get-commit-message@691c1d16c90c88a92d2438a001acdefc0efa7d2a # v8.26.0
uses: Alfresco/alfresco-build-tools/.github/actions/get-commit-message@20d21f43addae05442096a7e935dc2b321361501 # v8.27.0
- name: ci:force flag parser
shell: bash
+392 -15
View File
@@ -2,55 +2,432 @@
Title: About Component
Added: v3.5.0
Status: Active
Last reviewed: 2022-11-11
Last reviewed: 2025-07-23
---
# [About Component](../../../lib/core/src/lib/about/about.component.ts "Defined in about.component.ts")
# About Component
Presentational component to display About information as a set of collapsible panels.
A flexible presentational component that displays information in collapsible accordion panels. The About Component is ideal for organizing application information, settings, or any content that benefits from a collapsible interface structure.
## Overview
The About Component creates an accordion-style interface using Angular Material's expansion panels. Each panel can contain any content and can be conditionally displayed. This component is commonly used for:
- Application information and version details
- Feature lists and documentation
- Settings panels
- Help and support sections
- Plugin or extension information
## Prerequisites
Before using the About Component, ensure you have imported the necessary modules:
```typescript
import { AboutComponent } from '@alfresco/adf-core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-example',
imports: [CommonModule, AboutComponent],
template: `
<!-- Your template here -->
`
})
export class ExampleComponent {
// Component logic
}
```
## API Reference
### AboutComponent
| Property | Type | Description |
|----------|------|-------------|
| `panels` | `QueryList<AboutPanelDirective>` | Content children representing the panels to display |
### AboutPanelDirective (adf-about-panel)
| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| `label` | `string` | Yes | - | The title text displayed in the panel header |
| `automationId` | `string` | No | - | Data automation ID for testing purposes |
## Basic Usage
### Simple Panel Structure
```html
<adf-about>
<adf-about-panel [label]="'Panel 1'">
<adf-about-panel [label]="'Application Information'">
<ng-template>
<your-components></your-components>
<div class="about-content">
<h3>My Application</h3>
<p>Version: 1.0.0</p>
<p>Built with Angular and ADF</p>
</div>
</ng-template>
</adf-about-panel>
<adf-about-panel [label]="'Panel 2'">
<adf-about-panel [label]="'Features'">
<ng-template>
<your-components></your-components>
<ul>
<li>Document management</li>
<li>User authentication</li>
<li>Process workflows</li>
</ul>
</ng-template>
</adf-about-panel>
</adf-about>
```
## Conditional Display
You can wire each panel with the `*ngIf` conditions:
### Using Automation IDs for Testing
```html
<adf-about>
<adf-about-panel *ngIf="devMode" [label]="'Panel 1'">
<adf-about-panel
[label]="'System Information'"
automationId="system-info-panel">
<ng-template>
<your-components></your-components>
<your-system-info-component></your-system-info-component>
</ng-template>
</adf-about-panel>
</adf-about>
```
Where `devMode` is an example of an input property exposed by your component.
## Advanced Usage
Observables are also supported:
### Conditional Panel Display
You can control panel visibility using Angular's structural directives:
```html
<adf-about>
<adf-about-panel *ngIf="extensions$ | async as extensions" [label]="'ABOUT.PLUGINS.TITLE' | translate">
<!-- Show panel only in development mode -->
<adf-about-panel
*ngIf="isDevelopmentMode"
[label]="'Debug Information'"
automationId="debug-panel">
<ng-template>
<div class="debug-info">
<h4>Debug Tools</h4>
<button (click)="clearCache()">Clear Cache</button>
<button (click)="showLogs()">View Logs</button>
</div>
</ng-template>
</adf-about-panel>
<!-- Always visible panel -->
<adf-about-panel [label]="'General Information'">
<ng-template>
<app-general-info></app-general-info>
</ng-template>
</adf-about-panel>
</adf-about>
```
### Working with Observables and Async Data
```html
<adf-about>
<!-- Panel with async data -->
<adf-about-panel
*ngIf="extensions$ | async as extensions"
[label]="'ABOUT.PLUGINS.TITLE' | translate"
automationId="extensions-panel">
<ng-template>
<adf-about-extension-list [data]="extensions"></adf-about-extension-list>
</ng-template>
</adf-about-panel>
<!-- Panel with multiple conditions -->
<adf-about-panel
*ngIf="userPermissions$ | async as permissions; else noPermissions"
[label]="'User Permissions'"
automationId="permissions-panel">
<ng-template>
<div *ngFor="let permission of permissions" class="permission-item">
{{ permission.name }}: {{ permission.granted ? 'Granted' : 'Denied' }}
</div>
</ng-template>
</adf-about-panel>
<ng-template #noPermissions>
<adf-about-panel [label]="'Permissions'">
<ng-template>
<p>Loading permissions...</p>
</ng-template>
</adf-about-panel>
</ng-template>
</adf-about>
```
### Dynamic Panel Generation
```typescript
// Component logic
export class MyAboutComponent {
isDevelopmentMode = environment.production === false;
extensions$ = this.extensionService.getExtensions();
userPermissions$ = this.authService.getUserPermissions();
panels = [
{
label: 'System Info',
content: 'system-info',
show: true
},
{
label: 'Debug Tools',
content: 'debug-tools',
show: this.isDevelopmentMode
}
];
clearCache(): void {
// Clear cache implementation
}
showLogs(): void {
// Show logs implementation
}
}
```
```html
<!-- Template using dynamic panels -->
<adf-about>
<adf-about-panel
*ngFor="let panel of panels"
[label]="panel.label"
[automationId]="panel.content + '-panel'"
*ngIf="panel.show">
<ng-template>
<ng-container [ngSwitch]="panel.content">
<app-system-info *ngSwitchCase="'system-info'"></app-system-info>
<app-debug-tools *ngSwitchCase="'debug-tools'"></app-debug-tools>
</ng-container>
</ng-template>
</adf-about-panel>
</adf-about>
```
## Styling and Customization
### CSS Classes
The About Component uses these CSS classes that you can customize:
- `.adf-about-panel` - Main accordion container
- `.adf-about-panel-header` - Panel header styling
- `.adf-about-panel-header__title` - Panel title styling
### Custom Styling Example
```scss
// Custom panel styling
.adf-about-panel {
.mat-expansion-panel {
margin-bottom: 8px;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
&:not(.mat-expanded) {
.mat-expansion-panel-header {
background-color: #f5f5f5;
}
}
}
.adf-about-panel-header__title {
font-weight: 600;
color: #333;
}
}
// Custom content styling
.about-content {
padding: 16px 0;
h3 {
margin-top: 0;
color: #1976d2;
}
.permission-item {
padding: 4px 0;
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: none;
}
}
}
```
## Accessibility Features
The About Component inherits accessibility features from Angular Material's expansion panels:
- **Keyboard Navigation**: Use Tab to navigate between panels, Enter/Space to expand/collapse
- **Screen Reader Support**: Panels are properly labeled and state changes are announced
- **ARIA Attributes**: Proper ARIA attributes are automatically applied
- **Focus Management**: Focus is managed correctly when panels are expanded/collapsed
### Enhancing Accessibility
```html
<adf-about>
<adf-about-panel
[label]="'System Information'"
automationId="system-info-panel"
role="region"
[attr.aria-label]="'System information panel'">
<ng-template>
<div role="tabpanel" aria-live="polite">
<h3 id="system-heading">Current System Status</h3>
<p aria-describedby="system-heading">
All systems are operational.
</p>
</div>
</ng-template>
</adf-about-panel>
</adf-about>
```
## Testing
### Unit Testing Example
```typescript
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AboutComponent } from '@alfresco/adf-core';
import { DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
describe('AboutComponent', () => {
let component: AboutComponent;
let fixture: ComponentFixture<AboutComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AboutComponent]
}).compileComponents();
fixture = TestBed.createComponent(AboutComponent);
component = fixture.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should display panels with correct labels', () => {
const panels = fixture.debugElement.queryAll(
By.css('[data-automation-id="system-info-panel"]')
);
expect(panels.length).toBeGreaterThan(0);
});
});
```
### E2E Testing with Automation IDs
```typescript
// Page object example
export class AboutPage {
async expandPanel(automationId: string): Promise<void> {
const panel = element(by.css(`[data-automation-id="${automationId}"]`));
const header = panel.element(by.css('.mat-expansion-panel-header'));
await header.click();
}
async isPanelExpanded(automationId: string): Promise<boolean> {
const panel = element(by.css(`[data-automation-id="${automationId}"]`));
const classes = await panel.getAttribute('class');
return classes.includes('mat-expanded');
}
}
```
## Best Practices
### 1. Use Descriptive Labels
```html
<!-- Good: Descriptive and clear -->
<adf-about-panel [label]="'Application Version Information'">
<!-- Avoid: Vague labels -->
<adf-about-panel [label]="'Info'">
```
### 2. Provide Automation IDs for Testing
```html
<!-- Always include automation IDs for testing -->
<adf-about-panel
[label]="'User Settings'"
automationId="user-settings-panel">
```
### 3. Handle Loading States
```html
<adf-about-panel
*ngIf="data$ | async as data; else loadingPanel"
[label]="'Dynamic Content'">
<ng-template>
<div>{{ data.content }}</div>
</ng-template>
</adf-about-panel>
<ng-template #loadingPanel>
<adf-about-panel [label]="'Loading...'">
<ng-template>
<mat-spinner diameter="20"></mat-spinner>
</ng-template>
</adf-about-panel>
</ng-template>
```
### 4. Organize Related Information
Group related information into logical panels to improve user experience and information architecture.
## Common Use Cases
### Application Information Dashboard
```html
<adf-about>
<adf-about-panel [label]="'Application Details'" automationId="app-details">
<ng-template>
<div class="app-info">
<h3>{{ appName }}</h3>
<p>Version: {{ appVersion }}</p>
<p>Build: {{ buildNumber }}</p>
<p>Environment: {{ environment }}</p>
</div>
</ng-template>
</adf-about-panel>
<adf-about-panel [label]="'Dependencies'" automationId="dependencies">
<ng-template>
<ul>
<li *ngFor="let dep of dependencies">
{{ dep.name }}: {{ dep.version }}
</li>
</ul>
</ng-template>
</adf-about-panel>
</adf-about>
```
## See Also
- [Angular Material Expansion Panel](https://material.angular.io/components/expansion/overview)
- [ADF Core Components](../README.md)
- [Accessibility Guidelines](../../user-guide/accessibility.md)
+25 -71
View File
@@ -2,10 +2,10 @@
Title: Authentication Service
Added: v2.0.0
Status: Active
Last reviewed: 2019-03-19
Last reviewed: 2025-06-12
---
# [Authentication Service](../../../lib/core/src/lib/auth/services/authentication.service.ts "Defined in authentication.service.ts")
# Authentication Service
Provides authentication to ACS and APS.
@@ -13,103 +13,57 @@ Provides authentication to ACS and APS.
### Methods
- **addTokenToHeader**(headersArg?: `HttpHeaders`): [`Observable`](http://reactivex.io/documentation/observable.html)`<HttpHeaders>`<br/>
- **addTokenToHeader**(requestUrl: `string`, headersArg?: `HttpHeaders`): [`Observable`](http://reactivex.io/documentation/observable.html)`<HttpHeaders>`<br/>
Adds the auth token to an HTTP header using the 'bearer' scheme.
- _requestUrl:_ `string` - The URL of the request for which to set authentication headers.
- _headersArg:_ `HttpHeaders` - (Optional) Header that will receive the token
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<HttpHeaders>` - The new header with the token added
- **getBearerExcludedUrls**()<br/>
Gets the set of URLs that the token bearer is excluded from.
- **getBpmLoggedUser**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/UserRepresentation.md)`>`<br/>
Gets information about the user currently logged into APS.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/UserRepresentation.md)`>` - User information
- **getBpmUsername**(): `string`<br/>
Gets the BPM username
- **Returns** `string` - The BPM username
- **getEcmUsername**(): `string`<br/>
Gets the ECM username.
- **Returns** `string` - The ECM username
- **getRedirect**(): `string`<br/>
Gets the URL to redirect to after login.
- **Returns** `string` - The redirect URL
- **getTicketBpm**(): `string|null`<br/>
Gets the BPM ticket stored in the Storage.
- **Returns** `string|null` - The ticket or `null` if none was found
- **getTicketEcm**(): `string|null`<br/>
Gets the ECM ticket stored in the Storage.
- **Returns** `string|null` - The ticket or `null` if none was found
- **getTicketEcmBase64**(): `string|null`<br/>
Gets the BPM ticket from the Storage in Base 64 format.
- **Returns** `string|null` - The ticket or `null` if none was found
- **getToken**(): `string`<br/>
Gets the auth token.
- **Returns** `string` - Auth token string
- **handleError**(error: `any`): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
Prints an error message in the console browser
- _error:_ `any` - Error message
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<any>` - Object representing the error message
- **getUsername**(): `string`<br/>
Gets the username of the authenticated user.
- **Returns** `string` - Username of the authenticated user
- **getAuthHeaders**(requestUrl: `string`, headers: `HttpHeaders`): `HttpHeaders`<br/>
Gets and sets the necessary authentication headers for a given request URL.
- _requestUrl:_ `string` - The URL of the request for which to obtain authentication headers.
- _headers:_ `HttpHeaders` - The existing HTTP headers to which authentication details might be added.
- **Returns** `HttpHeaders` - The HTTP headers object, potentially updated with authentication tokens.
- **isALLProvider**(): `boolean`<br/>
Does the provider support both ECM and BPM?
- **Returns** `boolean` - True if both are supported, false otherwise
- **isAuthCodeFlow**(): `boolean`<br/>
- **Returns** `boolean` -
- **isBPMProvider**(): `boolean`<br/>
Does the provider support BPM?
- **Returns** `boolean` - True if supported, false otherwise
- **isBpmLoggedIn**(): `boolean`<br/>
Checks if the user is logged in on a BPM provider.
- **Returns** `boolean` - True if logged in, false otherwise
- **isECMProvider**(): `boolean`<br/>
Does the provider support ECM?
- **Returns** `boolean` - True if supported, false otherwise
- **isEcmLoggedIn**(): `boolean`<br/>
Checks if the user is logged in on an ECM provider.
- **Returns** `boolean` - True if logged in, false otherwise
- **isImplicitFlow**(): `boolean`<br/>
- **Returns** `boolean` -
- **isKerberosEnabled**(): `boolean`<br/>
Does kerberos enabled?
- **Returns** `boolean` - True if enabled, false otherwise
- **isLoggedIn**(): `boolean`<br/>
Checks if the user logged in.
- **Returns** `boolean` - True if logged in, false otherwise
- **isLoggedInWith**(provider: `string`): `boolean`<br/>
- _provider:_ `string` -
- **Returns** `boolean` -
- **isOauth**(): `boolean`<br/>
Does the provider support OAuth?
- **Returns** `boolean` - True if supported, false otherwise
- **isPublicUrl**(): `boolean`<br/>
- **Returns** `boolean` -
- **isRememberMeSet**(): `boolean`<br/>
Checks whether the "remember me" cookie was set or not.
- **Returns** `boolean` - True if set, false otherwise
- **login**(username: `string`, password: `string`, rememberMe: `boolean` = `false`): [`Observable`](http://reactivex.io/documentation/observable.html)`<Function>`<br/>
- **login**(username: `string`, password: `string`, rememberMe?: `boolean`): [`Observable`](http://reactivex.io/documentation/observable.html)`<{ type: string; ticket: any }>`<br/>
Logs the user in.
- _username:_ `string` - Username for the login
- _password:_ `string` - Password for the login
- _rememberMe:_ `boolean` - Stores the user's login details if true
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<Function>` - Object with auth type ("ECM", "BPM" or "ALL") and auth ticket
- **logout**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
Logs the user out.
- _rememberMe:_ `boolean` - (Optional) Stores the user's login details if true
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<{ type: string; ticket: any }>` - An Observable that emits an object containing the authentication type (`type`) and the authentication ticket (`ticket`) upon successful login.
- **logout**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/> Logs the user out.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<any>` - Response event called when logout is complete
- **reset**()<br/>
- **saveRememberMeCookie**(rememberMe: `boolean`)<br/>
Saves the "remember me" cookie as either a long-life cookie or a session cookie.
- _rememberMe:_ `boolean` - Enables a long-life cookie
- **setRedirect**(url?: [`RedirectionModel`](../../../lib/core/src/lib/auth/models/redirection.model.ts))<br/>
Sets the URL to redirect to after login.
- _url:_ [`RedirectionModel`](../../../lib/core/src/lib/auth/models/redirection.model.ts) - (Optional) URL to redirect to
- **ssoImplicitLogin**()<br/>
Logs the user in with SSO
- **reset**(): `void`<br/>Resets the authentication state of the service.
- **on**(event: `string`, listener: `Function`): `void`<br/> Adds an event listener for the specified event.
- **off**(event: `string`, listener?: `Function`): `void`<br/> Removes an event listener for the specified event.
- **once**(event: `string`, listener: `Function`): `void`<br/> Adds a one-time event listener for the specified event.
- **emit**(event: `string`, ...args: `any[]`): `void`<br/> Emits an event with optional arguments.
- **onLogin**: [`Subject`](https://reactivex.io/documentation/subject)`<any>`<br/> Emitted when the user logs in successfully.
- **onLogout**: [`Subject`](https://reactivex.io/documentation/subject)`<any>`<br/> Emitted when the user logs out.
- **onTokenReceived**: [`Subject`](https://reactivex.io/documentation/subject)`<any>`<br/> Emitted when an authentication token is received.
- **onError**: [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/> An Observable that emits an error object when an authentication-related error occurs.
## Details
+164
View File
@@ -0,0 +1,164 @@
---
Title: Upgrading from ADF v7.0 to v8.0
---
# Upgrading from ADF v7.0 to v8.0
This guide provides instructions for upgrading your v7.0.0 ADF projects to v8.0.0.
## Before you begin
Always perform upgrades on a "clean" project state. Back up your changes or create a full project backup before proceeding.
```shell
# Recommended clean up
nx reset && rm -rf .angular .nx dist node_modules nxcache tmp
```
## Libraries
Update your dependencies to the versions introduced in the 8.0.0 release:
```json
{
"dependencies": {
"@alfresco/adf-core": "8.0.0",
"@alfresco/adf-content-services": "8.0.0",
"@alfresco/adf-process-services-cloud": "8.0.0",
"@alfresco/adf-insights": "8.0.0",
"@alfresco/adf-extensions": "8.0.0",
"@alfresco/adf-cli": "8.0.0",
"@alfresco/eslint-plugin-eslint-angular": "8.0.0",
"@alfresco/adf-testing": "8.0.0",
"@alfresco/js-api": "9.0.0"
}
}
```
Currently used Node version: 22.14.0.
### Breaking changes
Major version updates have been applied to the following core libraries:
- Angular: 19.2.6
- Angular Material: 19.2.9
- Typescript: 5.8.2
> Details on Angular update can be found in *Update Guide* from Angular documentation.
### Added libraries
```json
{
"dependencies": {
"node-fetch": "^3.3.2"
},
"devDependencies": {
"resize-observer-polyfill": "^1.5.1",
"webdriver-manager": "12.1.9"
}
}
```
### Deleted libraries
```json
{
"devDependencies": {
"mini-css-extract-plugin": "X.X.X",
"css-loader": "X.X.X"
}
}
```
Reinstall your dependencies and perform an initial build:
```shell
npm i
npm run build
```
Review your applications as some styles and classes of Angular Material components might have changed.
## Deprecations
The following table lists deprecated features and modules that will be removed in upcoming releases. Consider replacing them as soon as you update ADF to minimize future technical debt.
| Name | Notes |
|-------------------------------|-----------------------------------------------------------------------------------------------|
| Custom Theme | Refer to [Custom Theme documentation](../../lib/core/custom-theme/README.md) |
| ShellModule | Refer to [Shell documentation](../../lib/core/shell/README.md) |
| FormBaseModule | Use standalone components instead. |
| CoreTestingModule | Use standalone components instead. |
| ProcessServicesCloudModule | Refer to [ProcessServicesCloudModule replacement](#processservicescloudmodule-replacement) |
### ProcessServicesCloudModule replacement
To replace this module, import the standalone components directly or use the following provider API to replicate its behavior:
```typescript
providers: [
provideTranslations('adf-process-services-cloud', 'assets/adf-process-services-cloud'),
provideCloudPreferences(),
provideCloudFormRenderer(),
{ provide: TASK_LIST_CLOUD_TOKEN, useClass: TaskListCloudService }
]
```
## New features and APIs
You can start using the new features and APIs introduced in the 8.0.0 release.
### XMLHttpRequest.withCredentials
Support for disabling the `withCredentials` property in `app.config.json` for identity providers that disallow credentials has been introduced. You can configure it as shown below:
```json
{
"auth": {
"withCredentials": false
}
}
```
### provideShell
The new provideShell API for providing the main application layout can replace the `withRoutes(routes: Routes | AppShellRoutesConfig)` method, as shown below.
```typescript
import { provideShell } from '@alfresco/adf-core/shell';
provideShell(
{
routes: [],
appService: AppService,
authGuard: AuthGuard,
navBar: {
minWidth: 0,
maxWidth: 100
}
}
)
```
### provideI18N
The new `provideI18N` API for providing translation can replace `provideTranslations('app', 'assets')` method, as shown below.
```typescript
import { provideI18N } from '@alfresco/adf-core';
provideI18N(
{
defaultLanguage: "en", // optional, defaults to "en"
assets: [['en', '/assets/i18n/en.json'], ['fr', '/assets/i18n/fr.json']]
}
)
```
## Final steps
After updating your code, thoroughly test your application to ensure everything works as expected.
If you encounter any issues during the upgrade process, refer to the Angular update guide or seek assistance from the ADF community.
+13 -19
View File
@@ -1,20 +1,20 @@
{
"name": "@alfresco/adf-cli",
"version": "8.0.0",
"version": "9.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@alfresco/adf-cli",
"version": "8.0.0",
"version": "9.0.0",
"license": "Apache-2.0",
"dependencies": {
"@alfresco/js-api": ">=8.0.0-alpha.7",
"@alfresco/js-api": ">=9.0.0",
"commander": "^6.2.1",
"ejs": "^3.1.9",
"license-checker": "^25.0.1",
"node-fetch": "^2.7.0",
"rxjs": "^6.6.6",
"rxjs": "7.8.2",
"shelljs": "^0.8.3",
"spdx-license-list": "^5.0.0"
},
@@ -30,9 +30,10 @@
}
},
"node_modules/@alfresco/js-api": {
"version": "8.0.0-alpha.7-12984503308",
"resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-8.0.0-alpha.7-12984503308.tgz",
"integrity": "sha512-ua8YgR6BHO751wKclLCQeJEByLJbLl5xmfQqEDJyRlnMvDCk+v7a5e2ibF58meQkmstR+CkIXi5ZlW9YhBKtZg==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/@alfresco/js-api/-/js-api-9.0.0.tgz",
"integrity": "sha512-tkVc3vCmbyp1cAJOtga/c5kApWmkj7lBmnJk0M+Jx/aek5mUQkXvDKlpPBoE0QR8UHKEKgB6HgwmaOMumYQVAw==",
"license": "Apache-2.0",
"dependencies": {
"event-emitter": "^0.3.5",
"superagent": "^9.0.1",
@@ -1052,21 +1053,14 @@
}
},
"node_modules/rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^1.9.0"
},
"engines": {
"npm": ">=2.0.0"
"tslib": "^2.1.0"
}
},
"node_modules/rxjs/node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-cli",
"description": "Alfresco ADF cli and utils",
"version": "8.0.0",
"version": "9.0.0",
"author": "Hyland Software, Inc. and its affiliates",
"bin": {
"adf-cli": "bin/adf-cli",
@@ -20,7 +20,7 @@
"dist": "rm -rf ../../dist/libs/cli && npm run build && cp -R ./bin ../../dist/libs/cli && cp -R ./resources ../../dist/libs/cli && cp -R ./templates ../../dist/libs/cli && cp ./package.json ../../dist/libs/cli"
},
"dependencies": {
"@alfresco/js-api": ">=8.0.0-alpha.7",
"@alfresco/js-api": ">=9.0.0",
"commander": "^6.2.1",
"ejs": "^3.1.9",
"license-checker": "^25.0.1",
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-content-services",
"description": "Alfresco ADF content services",
"version": "8.0.0",
"version": "9.0.0",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -21,9 +21,9 @@
"@angular/platform-browser": ">=14.1.3",
"@angular/platform-browser-dynamic": ">=14.1.3",
"@angular/router": ">=14.1.3",
"@alfresco/js-api": ">=9.0.0",
"@alfresco/js-api": ">=10.0.0",
"@ngx-translate/core": ">=16.0.0",
"@alfresco/adf-core": ">=8.0.0"
"@alfresco/adf-core": ">=9.0.0"
},
"keywords": [
"content-services",
@@ -156,7 +156,7 @@ describe('ContentService', () => {
});
it('should take current logged user id if userId undefined ', () => {
spyOn(authService, 'getEcmUsername').and.returnValue('user1');
spyOn(authService, 'getUsername').and.returnValue('user1');
const permissionNode = new Node({
permissions: {
inherited: [
@@ -84,7 +84,7 @@ export class ContentService {
*/
hasPermissions(node: Node, permission: PermissionsEnum | string, userId?: string): boolean {
let hasPermissions = false;
userId = userId ?? this.authService.getEcmUsername();
userId = userId ?? this.authService.getUsername();
const permissions = [...(node.permissions?.locallySet || []), ...(node.permissions?.inherited || [])].filter(
(currentPermission) => currentPermission.authorityId === userId
@@ -274,7 +274,7 @@ describe('DropdownSitesComponent', () => {
});
it('should show only sites which logged user is member of when member relation is set', async () => {
spyOn(authService, 'getEcmUsername').and.returnValue('test');
spyOn(authService, 'getUsername').and.returnValue('test');
fixture.detectChanges();
await fixture.whenStable();
@@ -295,7 +295,7 @@ describe('DropdownSitesComponent', () => {
});
it('should show all the sites if no relation is set', async () => {
spyOn(authService, 'getEcmUsername').and.returnValue('test');
spyOn(authService, 'getUsername').and.returnValue('test');
fixture.detectChanges();
await fixture.whenStable();
@@ -181,7 +181,7 @@ export class DropdownSitesComponent implements OnInit {
}
private filteredResultsByMember(sites: SitePaging): SitePaging {
const loggedUserName = this.authService.getEcmUsername();
const loggedUserName = this.authService.getUsername();
sites.list.entries = sites.list.entries.filter((site) => this.isCurrentUserMember(site, loggedUserName));
return sites;
}
@@ -646,7 +646,7 @@ describe('DocumentList', () => {
title: 'FileAction'
});
spyOn(authenticationService, 'getEcmUsername').and.returnValue('lockOwner');
spyOn(authenticationService, 'getUsername').and.returnValue('lockOwner');
documentList.actions = [documentMenu];
@@ -677,7 +677,7 @@ describe('DocumentList', () => {
title: 'FileAction'
});
spyOn(authenticationService, 'getEcmUsername').and.returnValue('jerryTheKillerCow');
spyOn(authenticationService, 'getUsername').and.returnValue('jerryTheKillerCow');
documentList.actions = [documentMenu];
@@ -137,22 +137,22 @@ describe('LockService', () => {
} as Node;
it('should return false when the user is the lock owner', () => {
spyOn(authenticationService, 'getEcmUsername').and.returnValue('lock-owner-user');
spyOn(authenticationService, 'getUsername').and.returnValue('lock-owner-user');
expect(service.isLocked(nodeOwnerAllowedLock)).toBeFalsy();
});
it('should return true when the user is not the lock owner', () => {
spyOn(authenticationService, 'getEcmUsername').and.returnValue('banana-user');
spyOn(authenticationService, 'getUsername').and.returnValue('banana-user');
expect(service.isLocked(nodeOwnerAllowedLock)).toBeTruthy();
});
it('should return false when the user is not the lock owner but the lock is expired', () => {
spyOn(authenticationService, 'getEcmUsername').and.returnValue('banana-user');
spyOn(authenticationService, 'getUsername').and.returnValue('banana-user');
expect(service.isLocked(nodeOwnerAllowedLockWithExpiredDate)).toBeFalsy();
});
it('should return true when is not the lock owner and the expiration date is valid', () => {
spyOn(authenticationService, 'getEcmUsername').and.returnValue('banana-user');
spyOn(authenticationService, 'getUsername').and.returnValue('banana-user');
expect(service.isLocked(nodeOwnerAllowedLockWithActiveExpiration)).toBeTruthy();
});
});
@@ -32,7 +32,7 @@ export class LockService {
if (this.isReadOnlyLock(node)) {
isLocked = !this.isLockExpired(node);
} else if (this.isLockOwnerAllowed(node)) {
isLocked = this.authService.getEcmUsername() !== node.properties['cm:lockOwner'].id;
isLocked = this.authService.getUsername() !== node.properties['cm:lockOwner'].id;
if (this.isLockExpired(node)) {
isLocked = false;
}
+2 -2
View File
@@ -184,8 +184,8 @@
"DUPLICATED_CATEGORY": "Kategoria została już dodana",
"CREATE_CATEGORIES": "Błąd podczas tworzenia kategorii",
"EXISTING_CATEGORIES": "Niektóre kategorie już istnieją",
"SPECIAL_CHARACTERS": "Category name cannot contain prohibited characters",
"ENDS_WITH_DOT": "Category name cannot end with a dot"
"SPECIAL_CHARACTERS": "Nazwa kategorii nie może zawierać niedozwolonych znaków",
"ENDS_WITH_DOT": "Nazwa kategorii nie może kończyć się kropką"
},
"CATEGORIES_SEARCH_PLACEHOLDER": "Kategorie wyszukiwania"
},
@@ -2,7 +2,6 @@
<mat-checkbox
*ngFor="let option of options"
[checked]="option.checked"
labelPosition="before"
(keydown.enter)="option.checked = !option.checked"
[attr.data-automation-id]="'checkbox-' + (option.name)"
[attr.aria-label]="option.name | translate"
@@ -25,11 +25,14 @@ import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
import { MatButtonHarness } from '@angular/material/button/testing';
import { ReplaySubject } from 'rxjs';
import { UnitTestingUtils } from '@alfresco/adf-core';
import { MatCheckbox } from '@angular/material/checkbox';
describe('SearchCheckListComponent', () => {
let loader: HarnessLoader;
let fixture: ComponentFixture<SearchCheckListComponent>;
let component: SearchCheckListComponent;
let unitTestingUtils: UnitTestingUtils;
beforeEach(() => {
TestBed.configureTestingModule({
@@ -38,6 +41,7 @@ describe('SearchCheckListComponent', () => {
fixture = TestBed.createComponent(SearchCheckListComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
unitTestingUtils = new UnitTestingUtils(fixture.debugElement);
component.context = {
queryFragments: {},
@@ -138,6 +142,18 @@ describe('SearchCheckListComponent', () => {
expect(component.context.filterRawParams[component.id]).toBeUndefined();
});
it('should have set labelPosition to after for checkboxes', () => {
component.options = new SearchFilterList<SearchListOption>([
{ name: 'Folder', value: `TYPE:'cm:folder'`, checked: true },
{ name: 'Document', value: `TYPE:'cm:content'`, checked: true }
]);
fixture.detectChanges();
const checkboxes = unitTestingUtils.getAllByDirective(MatCheckbox);
expect(checkboxes.length).toBe(2);
expect(checkboxes.every((checkbox) => checkbox.componentInstance.labelPosition === 'after')).toBeTrue();
});
describe('Pagination', () => {
it('should show 5 items when pageSize not defined', async () => {
component.id = 'checklist';
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-core",
"description": "Alfresco ADF core",
"version": "8.0.0",
"version": "9.0.0",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -38,8 +38,8 @@
"@angular/router": ">=16.0.0",
"@mat-datetimepicker/core": ">=12.0.1",
"@ngx-translate/core": ">=16.0.0",
"@alfresco/js-api": ">=9.0.0",
"@alfresco/adf-extensions": ">=8.0.0",
"@alfresco/js-api": ">=10.0.0",
"@alfresco/adf-extensions": ">=9.0.0",
"minimatch": ">=10.0.0",
"pdfjs-dist": ">=3.3.122",
"ts-morph": ">=20.0.0"
@@ -317,14 +317,27 @@ export class BasicAlfrescoAuthService extends BaseAuthenticationService {
return this.redirectUrl && (this.redirectUrl.provider === 'ALL' || provider === 'ALL');
}
/**
* @deprecated use `getUsername()` instead
* @returns the username of the authenticated user
*/
getBpmUsername(): string {
return this.processAuth.getUsername();
}
/**
* @deprecated use `getUsername()` instead
* @returns the username of the authenticated user
*/
getEcmUsername(): string {
return this.contentAuth.getUsername();
}
/**
* Gets the username of the authenticated user.
*
* @returns the username of the authenticated user
*/
getUsername(): string {
if (this.isBPMProvider()) {
return this.processAuth.getUsername();
@@ -94,7 +94,7 @@ describe('AuthGuardService BPM', () => {
});
it('if the alfresco js api is logged in should canActivate be true', async () => {
spyOn(authService, 'isBpmLoggedIn').and.returnValue(true);
spyOn(authService, 'isLoggedIn').and.returnValue(true);
authGuard = TestBed.runInInjectionContext(() => AuthGuardBpm(route, state)) as Promise<boolean>;
expect(await authGuard).toBeTruthy();
@@ -28,7 +28,7 @@ export const AuthGuardBpm: CanActivateFn = async (_: ActivatedRouteSnapshot, sta
return authGuardBaseService.redirectSSOSuccessURL();
}
if (authenticationService.isBpmLoggedIn() || authGuardBaseService.withCredentials) {
if (authenticationService.isLoggedIn() || authGuardBaseService.withCredentials) {
return true;
}
@@ -20,7 +20,6 @@ import ee from 'event-emitter';
import { Observable } from 'rxjs';
export interface AuthenticationServiceInterface {
onError: any;
onLogin: any;
onLogout: any;
@@ -31,30 +30,26 @@ export interface AuthenticationServiceInterface {
emit: (type: string, ...args: any[]) => void;
getToken(): string;
isLoggedIn(): boolean;
isOauth(): boolean;
logout(): any;
isEcmLoggedIn(): boolean;
isBpmLoggedIn(): boolean;
isECMProvider(): boolean;
isBPMProvider(): boolean;
isALLProvider(): boolean;
getEcmUsername(): string;
getBpmUsername(): string;
getUsername(): string;
getAuthHeaders(requestUrl: string, header: HttpHeaders): HttpHeaders;
addTokenToHeader(requestUrl: string, headersArg?: HttpHeaders): Observable<HttpHeaders>;
reset(): void;
/** @deprecated use `isLoggedIn` instead, use `isECMProvider` if you need to know the auth type */
isEcmLoggedIn(): boolean;
/** @deprecated use `isLoggedIn` instead, use `isBPMProvider` if you need to know the auth type */
isBpmLoggedIn(): boolean;
/** @deprecated use `getUsername` instead */
getEcmUsername(): string;
/** @deprecated use `getUsername` instead */
getBpmUsername(): string;
}
@@ -56,6 +56,10 @@ export class OidcAuthenticationService extends BaseAuthenticationService {
map(([authenticated, isDiscoveryDocumentLoaded]) => !authenticated && isDiscoveryDocumentLoaded)
);
/**
* @deprecated use `isLoggedIn` instead
* @returns true if the ECM provider is logged in
*/
isEcmLoggedIn(): boolean {
if (this.isECMProvider() || this.isALLProvider()) {
return this.isLoggedIn();
@@ -63,6 +67,10 @@ export class OidcAuthenticationService extends BaseAuthenticationService {
return false;
}
/**
* @deprecated use `isLoggedIn` instead
* @returns true if the BPM provider is logged in
*/
isBpmLoggedIn(): boolean {
if (this.isBPMProvider() || this.isALLProvider()) {
return this.isLoggedIn();
@@ -82,16 +90,6 @@ export class OidcAuthenticationService extends BaseAuthenticationService {
return this.oauthService.hasValidIdToken();
}
isImplicitFlow() {
const oauth2: OauthConfigModel = Object.assign({}, this.appConfig.get<OauthConfigModel>(AppConfigValues.OAUTHCONFIG, null));
return !!oauth2?.implicitFlow;
}
isAuthCodeFlow() {
const oauth2: OauthConfigModel = Object.assign({}, this.appConfig.get<OauthConfigModel>(AppConfigValues.OAUTHCONFIG, null));
return !!oauth2?.codeFlow;
}
login(username: string, password: string): Observable<{ type: string; ticket: any }> {
return this.auth.baseAuthLogin(username, password).pipe(
map((response) => {
@@ -125,12 +123,17 @@ export class OidcAuthenticationService extends BaseAuthenticationService {
});
}
/**
* Gets the username of the authenticated user.
*
* @returns the logged username
*/
getUsername() {
return this.jwtHelperService.getValueFromLocalToken<string>(JwtHelperService.USER_PREFERRED_USERNAME);
}
/**
* @deprecated
* @deprecated use `getUsername` instead
* @returns the logged username
*/
getEcmUsername(): string {
@@ -138,7 +141,7 @@ export class OidcAuthenticationService extends BaseAuthenticationService {
}
/**
* @deprecated
* @deprecated use `getUsername` instead
* @returns the logged username
*/
getBpmUsername(): string {
@@ -149,10 +152,6 @@ export class OidcAuthenticationService extends BaseAuthenticationService {
this.auth.login(redirectUrl);
}
ssoCodeFlowLogin() {
this.oauthService.initCodeFlow();
}
isRememberMeSet(): boolean {
return true;
}
@@ -116,17 +116,25 @@ export class AuthenticationService implements AuthenticationServiceInterface, ee
}
}
/**
* @deprecated use `isLoggedIn` instead
* @returns true if the ECM provider is logged in
*/
isEcmLoggedIn(): boolean {
if (this.isOauth()) {
return this.oidcAuthenticationService.isEcmLoggedIn();
return this.oidcAuthenticationService.isLoggedIn();
} else {
return this.basicAlfrescoAuthService.isEcmLoggedIn();
}
}
/**
* @deprecated use `isLoggedIn` instead
* @returns true if the BPM provider is logged in
*/
isBpmLoggedIn(): boolean {
if (this.isOauth()) {
return this.oidcAuthenticationService.isBpmLoggedIn();
return this.oidcAuthenticationService.isLoggedIn();
} else {
return this.basicAlfrescoAuthService.isBpmLoggedIn();
}
@@ -149,6 +157,8 @@ export class AuthenticationService implements AuthenticationServiceInterface, ee
}
/**
* Gets the username of the authenticated user.
*
* @returns the username of the authenticated user
*/
getUsername(): string {
@@ -160,27 +170,19 @@ export class AuthenticationService implements AuthenticationServiceInterface, ee
}
/**
* @deprecated
* @deprecated use `getUsername` instead
* @returns the logged username
*/
getEcmUsername(): string {
if (this.isOauth()) {
return this.oidcAuthenticationService.getUsername();
} else {
return this.basicAlfrescoAuthService.getEcmUsername();
}
return this.getUsername();
}
/**
* @deprecated
* @deprecated use `getUsername` instead
* @returns the logged username
*/
getBpmUsername(): string {
if (this.isOauth()) {
return this.oidcAuthenticationService.getUsername();
} else {
return this.basicAlfrescoAuthService.getBpmUsername();
}
return this.getUsername();
}
getAuthHeaders(requestUrl: string, headers: HttpHeaders): HttpHeaders {
@@ -40,21 +40,23 @@ export abstract class BaseAuthenticationService implements AuthenticationService
}
abstract getAuthHeaders(requestUrl: string, header: HttpHeaders): HttpHeaders;
abstract getToken(): string;
abstract isLoggedIn(): boolean;
abstract logout(): any;
/** @deprecated use `isLoggedIn` instead */
abstract isEcmLoggedIn(): boolean;
/** @deprecated use `isLoggedIn` instead */
abstract isBpmLoggedIn(): boolean;
abstract reset(): void;
abstract getUsername(): string;
/** @deprecated use `getUsername` instead */
abstract getEcmUsername(): string;
/** @deprecated use `getUsername` instead */
abstract getBpmUsername(): string;
/**
@@ -110,11 +112,6 @@ export abstract class BaseAuthenticationService implements AuthenticationService
return provider && provider.toUpperCase() === 'ALL';
}
isOauthConfiguration(): boolean {
const authType = this.appConfig.get('authType') as string;
return authType === 'OAUTH';
}
/**
* Prints an error message in the console browser
*
@@ -26,9 +26,9 @@
#{ms.$mat-tab-body} {
margin-bottom: 8em;
@include flex.layout-bp(lt-md) {
margin-bottom: 0em;
margin-bottom: 0;
}
}
@@ -69,7 +69,6 @@
&-item {
width: 100%;
flex-grow: 1;
box-sizing: border-box;
}
}
@@ -78,8 +77,8 @@
display: flex;
flex-direction: column;
flex: 1 1 auto;
padding-right: 1%;
padding-left: 1%;
padding-left: 5px;
padding-right: 5px;
}
&-item {
+1 -1
View File
@@ -453,7 +453,7 @@
"RESET": "Resetuj",
"THUMBNAILS": "Miniatura dokumentu",
"THUMBNAILS_PANLEL_CLOSE": "Zamknij panel miniatur",
"LOADING": "Document is loading"
"LOADING": "Wczytywanie dokumentu"
},
"PAGE_LABEL": {
"SHOWING": "Wyświetlanie",
@@ -15,12 +15,18 @@
* limitations under the License.
*/
import { NgModule } from '@angular/core';
import { RichTextEditorComponent } from './rich-text-editor.component';
import { InjectionToken, Provider, Type } from '@angular/core';
/** @deprecated use `RichTextEditorComponent` instead */
@NgModule({
imports: [RichTextEditorComponent],
exports: [RichTextEditorComponent]
})
export class RichTextEditorModule {}
export const LANDING_PAGE_TOKEN = new InjectionToken<Type<any>>('LANDING_PAGE_TOKEN');
/**
*
* @param componentClass The component class to be registered as the landing page.
* @returns A provider that registers the landing page component class.
*/
export function provideLandingPage(componentClass: Type<any>): Provider {
return {
provide: LANDING_PAGE_TOKEN,
useValue: componentClass
};
}
@@ -15,5 +15,4 @@
* limitations under the License.
*/
export * from './rich-text-editor.component';
export * from './rich-text-editor.module';
export * from './provider';
@@ -75,6 +75,10 @@ export class UnitTestingUtils {
return this.debugElement.query(By.directive(directive));
}
getAllByDirective(directive: Type<any>): DebugElement[] {
return this.debugElement.queryAll(By.directive(directive));
}
/** Perform actions */
clickByCSS(selector: string): void {
+1
View File
@@ -24,6 +24,7 @@ export * from './lib/toolbar/index';
export * from './lib/header/index';
export * from './lib/pagination/index';
export * from './lib/login/index';
export * from './lib/landing-page/index';
export * from './lib/language-menu/index';
export * from './lib/info-drawer/index';
export * from './lib/identity-user-info/index';
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@alfresco/eslint-plugin-eslint-angular",
"version": "8.0.0",
"version": "9.0.0",
"description": "Alfresco ADF eslint angular custom rules",
"main": "main.js",
"author": "Hyland Software, Inc. and its affiliates",
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-extensions",
"description": "Provides extensibility support for ADF applications.",
"version": "8.0.0",
"version": "9.0.0",
"license": "Apache-2.0",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
@@ -14,7 +14,7 @@
"peerDependencies": {
"@angular/common": ">=14.1.3",
"@angular/core": ">=14.1.3",
"@alfresco/js-api": ">=9.0.0"
"@alfresco/js-api": ">=10.0.0"
},
"keywords": [
"extensions",
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-insights",
"description": "Alfresco ADF insights",
"version": "8.0.0",
"version": "9.0.0",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -11,8 +11,8 @@
"url": "https://github.com/Alfresco/alfresco-ng2-components/issues"
},
"dependencies": {
"@alfresco/adf-core": ">=8.0.0",
"@alfresco/adf-content-services": ">=8.0.0",
"@alfresco/adf-core": ">=9.0.0",
"@alfresco/adf-content-services": ">=9.0.0",
"@ngx-translate/core": ">=14.0.0",
"chart.js": "^4.3.0",
"ng2-charts": "^4.1.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@alfresco/js-api",
"version": "9.0.0",
"version": "10.0.0",
"license": "Apache-2.0",
"description": "JavaScript client library for the Alfresco REST API",
"author": "Hyland Software, Inc. and its affiliates",
+1 -14
View File
@@ -28,19 +28,6 @@
},
"allowedNonPeerDependencies": [
"@apollo/client",
"apollo-angular",
"@editorjs/editorjs",
"@editorjs/code",
"@editorjs/header",
"@editorjs/inline-code",
"@editorjs/list",
"@editorjs/marker",
"@editorjs/paragraph",
"@editorjs/underline",
"@valano/change-font-size",
"editorjs-text-color-plugin",
"editorjs-html",
"editorjs-paragraph-with-alignment",
"editorjs-text-alignment-blocktune"
"apollo-angular"
]
}
+4 -19
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-process-services-cloud",
"description": "Alfresco ADF process services cloud",
"version": "8.0.0",
"version": "9.0.0",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -10,21 +10,6 @@
"bugs": {
"url": "https://github.com/Alfresco/alfresco-ng2-components/issues"
},
"dependencies": {
"@editorjs/code": "2.9.0",
"@editorjs/editorjs": "^2.28.2",
"@editorjs/header": "2.8.1",
"@editorjs/inline-code": "1.5.0",
"@editorjs/list": "1.9.0",
"@editorjs/marker": "1.4.0",
"@editorjs/paragraph": "^2.11.6",
"@editorjs/underline": "1.1.0",
"editorjs-html": "4.0.5",
"editorjs-paragraph-with-alignment": "3.0.0",
"editorjs-text-alignment-blocktune": "^1.0.3",
"editorjs-text-color-plugin": "1.13.1",
"@valano/change-font-size": "1.0.0"
},
"peerDependencies": {
"@angular/animations": ">=14.1.3",
"@angular/cdk": ">=14.1.2",
@@ -36,9 +21,9 @@
"@angular/platform-browser": ">=14.1.3",
"@angular/platform-browser-dynamic": ">=14.1.3",
"@angular/router": ">=14.1.3",
"@alfresco/js-api": ">=9.0.0",
"@alfresco/adf-core": ">=8.0.0",
"@alfresco/adf-content-services": ">=8.0.0",
"@alfresco/js-api": ">=10.0.0",
"@alfresco/adf-core": ">=9.0.0",
"@alfresco/adf-content-services": ">=9.0.0",
"@apollo/client": ">=3.7.2",
"@ngx-translate/core": ">=14.0.0",
"apollo-angular": ">=4.0.1"
@@ -29,11 +29,9 @@ import { RadioButtonsCloudWidgetComponent } from './components/widgets/radio-but
import { FilePropertiesTableCloudComponent } from './components/widgets/attach-file/file-properties-table/file-properties-table-cloud.component';
import { FileViewerWidgetComponent } from './components/widgets/file-viewer/file-viewer.widget';
import { DisplayRichTextWidgetComponent } from './components/widgets/display-rich-text/display-rich-text.widget';
import { RichTextEditorComponent } from '../rich-text-editor';
import { FormSpinnerComponent } from './components/spinner/form-spinner.component';
export const FORM_CLOUD_DIRECTIVES = [
RichTextEditorComponent,
FormSpinnerComponent,
PropertiesViewerWrapperComponent,
PropertiesViewerWidgetComponent,
@@ -23,7 +23,6 @@ import { ProcessCloudModule } from './process/process-cloud.module';
import { FORM_CLOUD_DIRECTIVES } from './form/form-cloud.module';
import { TASK_FORM_CLOUD_DIRECTIVES } from './task/task-form/task-form.module';
import { PreferenceCloudServiceInterface, TASK_LIST_CLOUD_TOKEN } from './services/public-api';
import { RichTextEditorComponent } from './rich-text-editor';
import { GroupCloudComponent } from './group/components/group-cloud.component';
import { PeopleCloudComponent } from './people/components/people-cloud.component';
import { provideCloudFormRenderer, provideCloudPreferences } from './providers';
@@ -33,8 +32,7 @@ export const PROCESS_SERVICES_CLOUD_DIRECTIVES = [
...APP_LIST_CLOUD_DIRECTIVES,
...FORM_CLOUD_DIRECTIVES,
...TASK_FORM_CLOUD_DIRECTIVES,
PeopleCloudComponent,
RichTextEditorComponent
PeopleCloudComponent
] as const;
/**
@@ -1,102 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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.
*/
/** Plugin import */
import CodeTool from '@editorjs/code';
import Header from '@editorjs/header';
import Paragraph from '@editorjs/paragraph';
import InlineCode from '@editorjs/inline-code';
import List from '@editorjs/list';
import Marker from '@editorjs/marker';
import Underline from '@editorjs/underline';
import ChangeFontSize from '@valano/change-font-size';
import ColorPlugin from 'editorjs-text-color-plugin';
import AlignmentTuneTool from 'editorjs-text-alignment-blocktune';
export const editorJsConfig = {
autofocus: true,
logLevel: 'ERROR',
tools: {
underline: {
class: Underline,
shortcut: 'CMD+U'
},
header: {
class: Header,
inlineToolbar: true,
tunes: ['anyTuneName']
},
paragraph: {
class: Paragraph,
inlineToolbar: true,
tunes: ['anyTuneName']
},
list: {
class: List,
inlineToolbar: true,
config: {
defaultStyle: 'unordered'
}
},
Color: {
class: ColorPlugin,
config: {
customPicker: true,
colorCollections: [
'#FF1300',
'#ffa500',
'#9C27B0',
'#673AB7',
'#3F51B5',
'#0070FF',
'#03A9F4',
'#00BCD4',
'#5f9ea0',
'#4CAF50',
'#8BC34A',
'#CDDC39',
'#FFF',
'#000',
'#c0c0c0',
'#808080',
'#800000'
],
defaultColor: '#FF1300',
type: 'text'
}
},
Marker: {
class: Marker,
shortcut: 'CMD+M'
},
'Increase/Decrease font size': {
class: ChangeFontSize,
config: {
cssClass: 'plus20pc',
buttonIcon: '<span class="material-icons">format_size</span>'
}
},
inlineCode: {
class: InlineCode,
shortcut: 'CMD+SHIFT+M'
},
anyTuneName: {
class: AlignmentTuneTool
},
code: CodeTool
}
};
@@ -1,3 +0,0 @@
<div class="adf-rich-text-editor-container">
<div class="editorjs" id="{{dynamicId}}"></div>
</div>
@@ -1,32 +0,0 @@
/* stylelint-disable selector-class-pattern */
.adf-rich-text-editor-container {
color: var(--theme-text-fg-color, rgba(0, 0, 0, 0.87));
.editorjs {
&.readonly {
.codex-editor__redactor {
/* stylelint-disable declaration-no-important */
padding-bottom: 0 !important;
}
}
}
.ce-inline-toolbar {
transform: scale(1);
.ce-popover__items {
overflow: hidden;
}
.ce-inline-tool .material-icons {
font-size: 20px;
}
}
}
xy-color-picker {
position: relative;
background-color: transparent;
margin: 0;
overflow: hidden;
}
@@ -1,105 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { RichTextEditorComponent } from './rich-text-editor.component';
describe('RichTextEditorComponent', () => {
let component: RichTextEditorComponent;
let fixture: ComponentFixture<RichTextEditorComponent>;
let debugElement: DebugElement;
const cssSelectors = {
editorContent: '.codex-editor',
editorJsElement: '.editorjs'
};
const mockEditorData = {
time: 1658154611110,
blocks: [
{
id: '1',
type: 'header',
data: {
text: 'Editor.js',
level: 2
}
}
],
version: 1
};
const whenEditorIsReady = async () => {
fixture.detectChanges();
await component.editorInstance.isReady;
await fixture.whenStable();
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RichTextEditorComponent]
});
fixture = TestBed.createComponent(RichTextEditorComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
});
it('should render rich text editor', async () => {
await whenEditorIsReady();
const editor = debugElement.query(By.css(cssSelectors.editorContent));
expect(editor).toBeTruthy();
});
it('should generate dynamic id', async () => {
await whenEditorIsReady();
expect(component.dynamicId).toContain('editorjs');
});
it('should get editorjs data by calling getEditorContent', async () => {
await whenEditorIsReady();
spyOn(component.editorInstance, 'save').and.returnValue(Promise.resolve(mockEditorData) as any);
const savedEditorData = await component.getEditorContent();
expect(savedEditorData).toEqual(mockEditorData);
});
it('should destroy editor instance on ngOnDestroy', async () => {
await whenEditorIsReady();
const destroyEditorSpy = spyOn(component.editorInstance, 'destroy');
component.ngOnDestroy();
expect(destroyEditorSpy).toHaveBeenCalledTimes(1);
expect(destroyEditorSpy).toHaveBeenCalled();
});
it('should not destroy editor instance on ngOnDestroy if editor is not ready', async () => {
await whenEditorIsReady();
const destroyEditorSpy = spyOn(component.editorInstance, 'destroy');
component.isReady = false;
component.ngOnDestroy();
expect(destroyEditorSpy).not.toHaveBeenCalled();
});
});
@@ -1,99 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { applicationConfig, Meta, moduleMetadata, StoryFn } from '@storybook/angular';
import { ProcessServicesCloudStoryModule } from '../testing/process-services-cloud-story.module';
import { RichTextEditorComponent } from './rich-text-editor.component';
import { importProvidersFrom } from '@angular/core';
export default {
component: RichTextEditorComponent,
title: 'Process Services Cloud/Rich Text Editor',
decorators: [
moduleMetadata({
imports: [RichTextEditorComponent]
}),
applicationConfig({
providers: [importProvidersFrom(ProcessServicesCloudStoryModule)]
})
],
argTypes: {
data: {
control: 'object',
description: 'Output data.',
table: {
type: { summary: 'OutputData' }
}
},
placeholder: {
control: 'text',
description: 'Placeholder text.',
table: {
type: { summary: 'string' }
}
},
autoFocus: {
control: 'boolean',
description: 'Focus on the editor when it is loaded.',
table: {
type: { summary: 'boolean' }
}
}
}
} as Meta<RichTextEditorComponent>;
const template: StoryFn<RichTextEditorComponent> = (args) => ({
props: args,
template: `
<adf-cloud-rich-text-editor [data]=data [placeholder]=placeholder [autofocus]=autofocus #editor>
</adf-cloud-rich-text-editor>
<hr/>
<h3>Output data from editor:</h3>
<pre>{{editor.outputData$ | async | json}}</pre>
`
});
export const DefaultRichTextEditor = template.bind({});
DefaultRichTextEditor.args = {
data: {
time: 1550476186479,
blocks: [
{
type: 'paragraph',
data: {
text: 'The example of text that was written in <b>one of popular</b> text editors.'
}
},
{
type: 'header',
data: {
text: 'With the header of course',
level: 2
}
},
{
type: 'paragraph',
data: {
text: 'So what do we have?'
}
}
],
version: '2.29.0'
},
placeholder: 'Type something here...',
autoFocus: true
};
@@ -1,89 +0,0 @@
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { AfterViewInit, Component, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import EditorJS, { OutputData } from '@editorjs/editorjs';
import { Subject } from 'rxjs';
import { editorJsConfig } from './editorjs-config';
@Component({
selector: 'adf-cloud-rich-text-editor',
templateUrl: './rich-text-editor.component.html',
styleUrls: ['./rich-text-editor.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class RichTextEditorComponent implements OnInit, OnDestroy, AfterViewInit {
@Input()
data: OutputData;
@Input()
placeholder = '';
@Input()
autoFocus = false;
private _outputData = new Subject<OutputData>();
outputData$ = this._outputData.asObservable();
editorInstance: EditorJS;
dynamicId: string;
isReady = false;
ngOnInit(): void {
this.dynamicId = `editorjs-${crypto.getRandomValues(new Uint32Array(1))}`;
}
ngAfterViewInit(): void {
this.editorInstance = new EditorJS({
holder: this.dynamicId,
placeholder: this.placeholder,
autofocus: this.autoFocus,
...editorJsConfig,
data: this.data,
onChange: () => {
this.sendEditorOutputData();
},
onReady: () => {
this.isReady = true;
this.sendEditorOutputData();
}
} as any);
}
private sendEditorOutputData() {
this.editorInstance
.save()
.then((outputData) => {
this._outputData.next(outputData);
})
.catch((error) => {
console.error('Saving failed: ', error);
});
}
getEditorContent() {
return this.editorInstance.save();
}
ngOnDestroy(): void {
if (this.isReady) {
this.editorInstance.destroy();
}
}
}
@@ -23,7 +23,6 @@ export * from './lib/group/public-api';
export * from './lib/people/public-api';
export * from './lib/form/public-api';
export * from './lib/services/public-api';
export * from './lib/rich-text-editor/public-api';
export * from './lib/screen/public-api';
export * from './lib/types';
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-process-services",
"description": "Alfresco ADF process services",
"version": "8.0.0",
"version": "9.0.0",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -21,9 +21,9 @@
"@angular/platform-browser": ">=14.1.3",
"@angular/platform-browser-dynamic": ">=14.1.3",
"@angular/router": ">=14.1.3",
"@alfresco/js-api": ">=9.0.0",
"@alfresco/adf-core": ">=8.0.0",
"@alfresco/adf-content-services": ">=8.0.0",
"@alfresco/js-api": ">=10.0.0",
"@alfresco/adf-core": ">=9.0.0",
"@alfresco/adf-content-services": ">=9.0.0",
"@ngx-translate/core": ">=14.0.0"
},
"keywords": [
+2293 -799
View File
File diff suppressed because it is too large Load Diff
+2 -14
View File
@@ -1,7 +1,7 @@
{
"name": "alfresco-ng2-components",
"description": "Alfresco Angular components",
"version": "8.0.0",
"version": "9.0.0",
"author": "Hyland Software, Inc. and its affiliates",
"scripts": {
"prepare": "husky install",
@@ -78,14 +78,6 @@
"@angular/cli": "19.2.14",
"@angular/compiler-cli": "19.2.6",
"@chromatic-com/storybook": "1.7.0",
"@editorjs/code": "2.9.3",
"@editorjs/editorjs": "2.30.8",
"@editorjs/header": "2.8.8",
"@editorjs/inline-code": "1.5.1",
"@editorjs/list": "2.0.4",
"@editorjs/marker": "1.4.0",
"@editorjs/paragraph": "^2.11.7",
"@editorjs/underline": "1.2.1",
"@nx/angular": "21.2.2",
"@nx/eslint-plugin": "20.8.0",
"@nx/js": "20.8.0",
@@ -116,14 +108,10 @@
"@typescript-eslint/parser": "6.21.0",
"@typescript-eslint/typescript-estree": "8.35.1",
"@typescript-eslint/utils": "^8.8.1",
"@valano/change-font-size": "^1.0.1",
"ajv": "^8.12.0",
"commander": "12.0.0",
"dotenv": "16.4.7",
"editorjs-html": "4.0.5",
"editorjs-paragraph-with-alignment": "3.0.0",
"editorjs-text-alignment-blocktune": "1.0.3",
"editorjs-text-color-plugin": "2.0.4",
"ejs": "^3.1.10",
"eslint": "^8.47.0",
"eslint-config-prettier": "10.1.2",
@@ -132,7 +120,7 @@
"eslint-plugin-jsdoc": "50.3.1",
"eslint-plugin-license-header": "0.8.0",
"eslint-plugin-prefer-arrow": "1.2.3",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-prettier": "^5.5.3",
"eslint-plugin-rxjs": "^5.0.3",
"eslint-plugin-storybook": "^9.0.7",
"eslint-plugin-unicorn": "^49.0.0",
+166 -56
View File
@@ -21,7 +21,7 @@
"mdast-zone": "3.0.4",
"remark": "^9.0.0",
"remark-frontmatter": "^1.2.0",
"rxjs": "^6.6.6",
"rxjs": "7.8.2",
"typedoc": "^0.25.7",
"typescript": "3.9.8",
"unist-util-select": "2.0.0"
@@ -44,11 +44,6 @@
"tslib": "^2.0.0"
}
},
"node_modules/@alfresco/js-api/node_modules/tslib": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz",
"integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w=="
},
"node_modules/@paperist/types-remark": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@paperist/types-remark/-/types-remark-0.1.3.tgz",
@@ -338,6 +333,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/camelcase": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
@@ -698,6 +706,20 @@
"node": ">=0.4.0"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ejs": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
@@ -725,6 +747,51 @@
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz",
"integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4="
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es5-ext": {
"version": "0.10.63",
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.63.tgz",
@@ -1000,13 +1067,16 @@
}
},
"node_modules/form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.4.tgz",
"integrity": "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.35"
},
"engines": {
"node": ">= 6"
@@ -1067,19 +1137,42 @@
}
},
"node_modules/get-intrinsic": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/get-value": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@@ -1116,6 +1209,18 @@
"is-glob": "^2.0.0"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -1129,17 +1234,6 @@
"node": ">= 10.x"
}
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dependencies": {
"function-bind": "^1.1.1"
},
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
@@ -1159,10 +1253,11 @@
"node": ">=8"
}
},
"node_modules/has-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -1170,10 +1265,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
@@ -1248,9 +1347,10 @@
}
},
"node_modules/hasown": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
"integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
@@ -1714,6 +1814,15 @@
"node": ">= 12"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/math-random": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz",
@@ -1933,19 +2042,21 @@
}
},
"node_modules/mime-db": {
"version": "1.46.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz",
"integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==",
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.29",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz",
"integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==",
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.46.0"
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
@@ -2798,14 +2909,12 @@
}
},
"node_modules/rxjs": {
"version": "6.6.6",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.6.tgz",
"integrity": "sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==",
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^1.9.0"
},
"engines": {
"npm": ">=2.0.0"
"tslib": "^2.1.0"
}
},
"node_modules/safe-buffer": {
@@ -3273,9 +3382,10 @@
}
},
"node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/type": {
"version": "1.2.0",