mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-06-02 17:35:08 +00:00
Compare commits
No commits in common. "develop" and "8.1.0-14755969498" have entirely different histories.
develop
...
8.1.0-1475
12
.github/actions/print-affected-libs/package-lock.json
generated
vendored
12
.github/actions/print-affected-libs/package-lock.json
generated
vendored
@ -267,9 +267,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici": {
|
"node_modules/undici": {
|
||||||
"version": "5.29.0",
|
"version": "5.28.5",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz",
|
||||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
"integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/busboy": "^2.0.0"
|
"@fastify/busboy": "^2.0.0"
|
||||||
@ -495,9 +495,9 @@
|
|||||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
||||||
},
|
},
|
||||||
"undici": {
|
"undici": {
|
||||||
"version": "5.29.0",
|
"version": "5.28.5",
|
||||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz",
|
||||||
"integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
"integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@fastify/busboy": "^2.0.0"
|
"@fastify/busboy": "^2.0.0"
|
||||||
}
|
}
|
||||||
|
2
.github/actions/setup/action.yml
vendored
2
.github/actions/setup/action.yml
vendored
@ -26,7 +26,7 @@ runs:
|
|||||||
cache-dependency-path: package-lock.json
|
cache-dependency-path: package-lock.json
|
||||||
- name: get latest tag sha
|
- name: get latest tag sha
|
||||||
id: tag-sha
|
id: tag-sha
|
||||||
uses: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag@f37c44cc085236178ebb8834eb634b0b4b550a40 # v8.23.0
|
uses: Alfresco/alfresco-build-tools/.github/actions/git-latest-tag@247f59bac145315d38078f8954c763e0db57d5f1 # v8.18.3
|
||||||
# CACHE
|
# CACHE
|
||||||
- name: Node Modules cache
|
- name: Node Modules cache
|
||||||
id: node-modules-cache
|
id: node-modules-cache
|
||||||
|
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@ -30,7 +30,7 @@ jobs:
|
|||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
uses: github/codeql-action/init@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
|
||||||
# Override language selection by uncommenting this and choosing your languages
|
# Override language selection by uncommenting this and choosing your languages
|
||||||
with:
|
with:
|
||||||
languages: javascript
|
languages: javascript
|
||||||
@ -39,7 +39,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
uses: github/codeql-action/autobuild@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@ -53,4 +53,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
|
uses: github/codeql-action/analyze@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
|
||||||
|
8
.github/workflows/pull-request.yml
vendored
8
.github/workflows/pull-request.yml
vendored
@ -64,7 +64,7 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Ensure SHA pinned actions
|
- name: Ensure SHA pinned actions
|
||||||
uses: zgosalvez/github-actions-ensure-sha-pinned-actions@fc87bb5b5a97953d987372e74478de634726b3e5 # v3.0.25
|
uses: zgosalvez/github-actions-ensure-sha-pinned-actions@4830be28ce81da52ec70d65c552a7403821d98d4 # v3.0.23
|
||||||
|
|
||||||
- name: Check package-lock.json version
|
- name: Check package-lock.json version
|
||||||
run: |
|
run: |
|
||||||
@ -84,10 +84,10 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Get branch name
|
- name: Get branch name
|
||||||
uses: Alfresco/alfresco-build-tools/.github/actions/get-branch-name@b3070acf733fdcfd2698065e99017d4969256e5b # v8.22.1
|
uses: Alfresco/alfresco-build-tools/.github/actions/get-branch-name@09293790e3d482b6376a602f607e009ef1025698 # v8.19.0
|
||||||
|
|
||||||
- name: Save commit message
|
- name: Save commit message
|
||||||
uses: Alfresco/alfresco-build-tools/.github/actions/get-commit-message@b3070acf733fdcfd2698065e99017d4969256e5b # v8.22.1
|
uses: Alfresco/alfresco-build-tools/.github/actions/get-commit-message@09293790e3d482b6376a602f607e009ef1025698 # v8.19.0
|
||||||
|
|
||||||
- name: ci:force flag parser
|
- name: ci:force flag parser
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -277,7 +277,7 @@ jobs:
|
|||||||
uses: ./.github/actions/slack-group-area
|
uses: ./.github/actions/slack-group-area
|
||||||
with:
|
with:
|
||||||
affected: ${{ steps.e2e-result.outputs.result }}
|
affected: ${{ steps.e2e-result.outputs.result }}
|
||||||
- uses: slackapi/slack-github-action@b0fa283ad8fea605de13dc3f449259339835fc52 # v2.1.0
|
- uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0
|
||||||
name: Nofify QA failure
|
name: Nofify QA failure
|
||||||
if: ${{ github.event_name == 'schedule' && contains(needs.*.result, 'failure') }}
|
if: ${{ github.event_name == 'schedule' && contains(needs.*.result, 'failure') }}
|
||||||
env:
|
env:
|
||||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -229,7 +229,7 @@ jobs:
|
|||||||
needs: [release-storybook, release-npm, npm-check-bundle]
|
needs: [release-storybook, release-npm, npm-check-bundle]
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- uses: slackapi/slack-github-action@b0fa283ad8fea605de13dc3f449259339835fc52 # v2.1.0
|
- uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0
|
||||||
name: Nofify FE eng-guild-front-end workflow failed
|
name: Nofify FE eng-guild-front-end workflow failed
|
||||||
if: ${{ contains(toJson(needs.*.result), 'failure') }}
|
if: ${{ contains(toJson(needs.*.result), 'failure') }}
|
||||||
env:
|
env:
|
||||||
|
@ -8,6 +8,6 @@
|
|||||||
"source": "/**/**/i18n/en.json",
|
"source": "/**/**/i18n/en.json",
|
||||||
"translation": "/%original_path%/%two_letters_code%.%file_extension%",
|
"translation": "/%original_path%/%two_letters_code%.%file_extension%",
|
||||||
"export_only_approved": "true",
|
"export_only_approved": "true",
|
||||||
"update_option": "update_without_changes"
|
"update_option": "update_as_unapproved"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -23,10 +23,10 @@ Manages tags in Content Services.
|
|||||||
- _nodeId:_ `string` - Id of node to which tags should be assigned.
|
- _nodeId:_ `string` - Id of node to which tags should be assigned.
|
||||||
- _tags:_ `TagBody[]` - List of tags to create and assign or just assign if they already exist.
|
- _tags:_ `TagBody[]` - List of tags to create and assign or just assign if they already exist.
|
||||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TagPaging`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/TagPaging.md)`|`[`TagEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/TagEntry.md)`>` - Just linked tags to node or single tag if linked only one tag.
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TagPaging`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/TagPaging.md)`|`[`TagEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/TagEntry.md)`>` - Just linked tags to node or single tag if linked only one tag.
|
||||||
- **createTags**(tags: `TagBody[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TagEntry`](../../../lib/js-api/src/api/content-rest-api/docs/TagsApi.md#TagEntry) `|` [`TagPaging`](../../../lib/js-api/src/api/content-rest-api/docs/TagsApi.md#TagPaging)`>`<br/>
|
- **createTags**(tags: `TagBody[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TagEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/TagEntry.md)`[]>`<br/>
|
||||||
Creates tags.
|
Creates tags.
|
||||||
- _tags:_ `TagBody[]` - list of tags to create.
|
- _tags:_ `TagBody[]` - list of tags to create.
|
||||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TagEntry`](../../../lib/js-api/src/api/content-rest-api/docs/TagsApi.md#TagEntry) `|` [`TagPaging`](../../../lib/js-api/src/api/content-rest-api/docs/TagsApi.md#TagPaging)`>` - Created tags.
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TagEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/TagEntry.md)`[]>` - Created tags.
|
||||||
- **deleteTag**(tagId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<void>`<br/>
|
- **deleteTag**(tagId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<void>`<br/>
|
||||||
Deletes a tag with tagId. This will cause the tag to be removed from all nodes. You must have admin rights to delete a tag.
|
Deletes a tag with tagId. This will cause the tag to be removed from all nodes. You must have admin rights to delete a tag.
|
||||||
- _tagId:_ `string` - of the tag to be deleted
|
- _tagId:_ `string` - of the tag to be deleted
|
||||||
|
@ -4,18 +4,16 @@ Added: v4.1.0
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Form Extensibility for APA Form Widget
|
## Form Extensibility for APA Form Widget
|
||||||
|
|
||||||
This page describes how you can customize ADF forms to your own specification.
|
This page describes how you can customize ADF forms to your own specification.
|
||||||
|
|
||||||
## Contents
|
## Contents
|
||||||
|
|
||||||
There are two ways to customize the form
|
There are two ways to customize the form
|
||||||
- [Replace default form widgets with custom components](#replace-default-form-widgets-with-apa-form-widgets)
|
- [Replace default form widgets with custom components](#replace-default-form-widgets-with-apa-form-widgets)
|
||||||
- [Replace custom form widget with custom components](#replace-custom-form-widgets-with-custom-components)
|
- [Replace custom form widget with custom components](#replace-custom-form-widgets-with-custom-components)
|
||||||
|
|
||||||
## Replace default form widgets with APA form widgets
|
## Replace default form widgets with APA form widgets
|
||||||
|
|
||||||
This is an example of replacing the standard `Text` with a custom component for all APA forms rendered within the `<adf-form>` component.
|
This is an example of replacing the standard `Text` [widget](../../lib/testing/src/lib/core/pages/form/widgets/widget.ts) with a custom component for all APA forms rendered within the `<adf-form>` component.
|
||||||
|
|
||||||
1. Create a simple form with some `Text` widgets:
|
1. Create a simple form with some `Text` widgets:
|
||||||
|
|
||||||
@ -26,10 +24,8 @@ This is an example of replacing the standard `Text` with a custom component for
|
|||||||
```ts
|
```ts
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { WidgetComponent } from '@alfresco/adf-core';
|
import { WidgetComponent } from '@alfresco/adf-core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'custom-editor',
|
selector: 'custom-editor',
|
||||||
standalone: true,
|
|
||||||
template: `
|
template: `
|
||||||
<div style="color: red">Look, I'm a APA custom editor!</div>
|
<div style="color: red">Look, I'm a APA custom editor!</div>
|
||||||
`
|
`
|
||||||
@ -37,14 +33,40 @@ This is an example of replacing the standard `Text` with a custom component for
|
|||||||
export class CustomEditorComponent extends WidgetComponent {}
|
export class CustomEditorComponent extends WidgetComponent {}
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Import the [`FormRenderingService`](../core/services/form-rendering.service.md) in the feature module, or application module (recommended: `ProcessServicesExtensionModule`), and override the default mapping:
|
2. Add it to the application module or any custom module that is imported into the application one:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
import { CustomEditorComponent } from './custom-editor.component';
|
import { CustomEditorComponent } from './custom-editor.component';
|
||||||
import { FormRenderingService } from '@alfresco/adf-core';
|
@NgModule({
|
||||||
|
declarations: [ CustomEditorComponent ],
|
||||||
|
exports: [ CustomEditorComponent ]
|
||||||
|
})
|
||||||
|
export class CustomEditorsModule {}
|
||||||
|
```
|
||||||
|
|
||||||
@NgModule({...})
|
3. Every custom widget component should be added into the the collections `declarations` and `exports`. If you decided to store custom widgets in a separate dedicated module (and optionally as a separate re-distributable library) don't forget to import it into the main application:
|
||||||
export class ProcessServicesExtensionModule {
|
|
||||||
|
```ts
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
// ...
|
||||||
|
CustomEditorsModule
|
||||||
|
// ...
|
||||||
|
],
|
||||||
|
providers: [],
|
||||||
|
bootstrap: [ AppComponent ]
|
||||||
|
})
|
||||||
|
export class AppModule {}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Import the [`FormRenderingService`](../core/services/form-rendering.service.md) into any of your Views and override the default mapping, for example:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { CustomEditorComponent } from './custom-editor.component';
|
||||||
|
@Component({...})
|
||||||
|
export class MyView {
|
||||||
constructor(formRenderingService: FormRenderingService) {
|
constructor(formRenderingService: FormRenderingService) {
|
||||||
this.formRenderingService.register({
|
this.formRenderingService.register({
|
||||||
'text': () => CustomEditorComponent
|
'text': () => CustomEditorComponent
|
||||||
@ -53,12 +75,10 @@ This is an example of replacing the standard `Text` with a custom component for
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!IMPORTANT]
|
5. At runtime the form should look similar to the following:
|
||||||
> The widget should be registered outside the custom widget component, otherwise the widget will not be registered correctly.
|
|
||||||
|
|
||||||
At runtime the form should look similar to the following:
|

|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Replace custom form widgets with custom components
|
## Replace custom form widgets with custom components
|
||||||
|
|
||||||
@ -85,30 +105,54 @@ When displayed in a task, the field will look similar to the following:
|
|||||||
|
|
||||||
To render the missing content:
|
To render the missing content:
|
||||||
|
|
||||||
1. Create a standalone Angular component:
|
1. Create an Angular component:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { WidgetComponent } from '@alfresco/adf-core';
|
import { WidgetComponent } from '@alfresco/adf-core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-demo-widget',
|
selector: 'app-demo-widget',
|
||||||
standalone: true,
|
|
||||||
template: `<div style="color: green">ADF version of custom form widget</div>`
|
template: `<div style="color: green">ADF version of custom form widget</div>`
|
||||||
})
|
})
|
||||||
export class DemoWidgetComponent extends WidgetComponent {}
|
export class DemoWidgetComponent extends WidgetComponent {}
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Import the [`FormRenderingService`](../core/services/form-rendering.service.md) in the feature module, or application module (recommended: `ProcessServicesExtensionModule`), and override the default mapping:
|
2. Place it inside the custom module:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
import { DemoWidgetComponent } from './demo-widget.component';
|
import { DemoWidgetComponent } from './demo-widget.component';
|
||||||
import { FormRenderingService } from '@alfresco/adf-core';
|
@NgModule({
|
||||||
|
declarations: [ DemoWidgetComponent ],
|
||||||
|
exports: [ DemoWidgetComponent ]
|
||||||
|
})
|
||||||
|
export class CustomWidgetsModule {}
|
||||||
|
```
|
||||||
|
|
||||||
@NgModule({/*...*/})
|
3. Import it into your Application Module:
|
||||||
export class ProcessServicesExtensionModule {
|
|
||||||
|
```ts
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
// ...
|
||||||
|
CustomWidgetsModule
|
||||||
|
// ...
|
||||||
|
],
|
||||||
|
providers: [],
|
||||||
|
bootstrap: [ AppComponent ]
|
||||||
|
})
|
||||||
|
export class AppModule {}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Import the [`FormRenderingService`](../core/services/form-rendering.service.md) in any of your Views and provide the new mapping:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { DemoWidgetComponent } from './demo-widget.component';
|
||||||
|
@Component({...})
|
||||||
|
export class MyView {
|
||||||
constructor(formRenderingService: FormRenderingService) {
|
constructor(formRenderingService: FormRenderingService) {
|
||||||
formRenderingService.register({
|
this.formRenderingService.register({
|
||||||
'custom-editor': () => DemoWidgetComponent
|
'custom-editor': () => DemoWidgetComponent
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -119,9 +163,6 @@ At runtime you should now see your custom Angular component rendered in place of
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
> [!IMPORTANT]
|
|
||||||
> The widget should be registered outside the custom widget component, otherwise the widget will not be registered correctly.
|
|
||||||
|
|
||||||
## See Also
|
## See Also
|
||||||
|
|
||||||
- [Extensibility](./extensibility.md)
|
- [Extensibility](./extensibility.md)
|
||||||
|
Binary file not shown.
43
lib/cli/package-lock.json
generated
43
lib/cli/package-lock.json
generated
@ -9,7 +9,7 @@
|
|||||||
"version": "8.0.0",
|
"version": "8.0.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alfresco/js-api": ">=8.0.0-alpha.7",
|
"@alfresco/js-api": ">=8.0.0-alpha.7-0",
|
||||||
"commander": "^6.2.1",
|
"commander": "^6.2.1",
|
||||||
"ejs": "^3.1.9",
|
"ejs": "^3.1.9",
|
||||||
"license-checker": "^25.0.1",
|
"license-checker": "^25.0.1",
|
||||||
@ -39,27 +39,6 @@
|
|||||||
"tslib": "^2.6.1"
|
"tslib": "^2.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@noble/hashes": {
|
|
||||||
"version": "1.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
|
||||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": "^14.21.3 || >=16"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@paralleldrive/cuid2": {
|
|
||||||
"version": "2.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz",
|
|
||||||
"integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@noble/hashes": "^1.1.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/ejs": {
|
"node_modules/@types/ejs": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.2.tgz",
|
||||||
@ -456,18 +435,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/formidable": {
|
"node_modules/formidable": {
|
||||||
"version": "3.5.4",
|
"version": "3.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.1.tgz",
|
||||||
"integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==",
|
"integrity": "sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@paralleldrive/cuid2": "^2.2.2",
|
|
||||||
"dezalgo": "^1.0.4",
|
"dezalgo": "^1.0.4",
|
||||||
|
"hexoid": "^1.0.0",
|
||||||
"once": "^1.4.0"
|
"once": "^1.4.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
|
||||||
"node": ">=14.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://ko-fi.com/tunnckoCore/commissions"
|
"url": "https://ko-fi.com/tunnckoCore/commissions"
|
||||||
}
|
}
|
||||||
@ -601,6 +576,14 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hexoid": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/hosted-git-info": {
|
"node_modules/hosted-git-info": {
|
||||||
"version": "2.8.9",
|
"version": "2.8.9",
|
||||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||||
|
@ -19,7 +19,6 @@ import { AlfrescoApiConfig } from '@alfresco/js-api';
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { AppConfigService, AppConfigValues, StorageService } from '@alfresco/adf-core';
|
import { AppConfigService, AppConfigValues, StorageService } from '@alfresco/adf-core';
|
||||||
import { AlfrescoApiService } from '../services/alfresco-api.service';
|
import { AlfrescoApiService } from '../services/alfresco-api.service';
|
||||||
import { SecurityOptionsLoaderService } from '../security-options-loader/security-options-loader.service';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a factory to resolve an api service instance
|
* Create a factory to resolve an api service instance
|
||||||
@ -38,12 +37,11 @@ export class AlfrescoApiLoaderService {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly appConfig: AppConfigService,
|
private readonly appConfig: AppConfigService,
|
||||||
private readonly apiService: AlfrescoApiService,
|
private readonly apiService: AlfrescoApiService,
|
||||||
private readonly securityOptionsLoaderService: SecurityOptionsLoaderService,
|
|
||||||
private storageService: StorageService
|
private storageService: StorageService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async init(): Promise<any> {
|
async init(): Promise<any> {
|
||||||
await this.appConfig.load(this.securityOptionsLoaderService.load);
|
await this.appConfig.load();
|
||||||
return this.initAngularAlfrescoApi();
|
return this.initAngularAlfrescoApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,19 +92,4 @@ describe('LibraryRoleColumnComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(value).toBe('LIBRARY.ROLE.NONE');
|
expect(value).toBe('LIBRARY.ROLE.NONE');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should take role from obj when node entry role is not provided', () => {
|
|
||||||
component.context = {
|
|
||||||
row: {
|
|
||||||
node: { entry: {} },
|
|
||||||
obj: { role: 'SiteManager' }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let value = '';
|
|
||||||
component.displayText$.subscribe((val) => (value = val));
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(value).toBe('LIBRARY.ROLE.MANAGER');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
import { ChangeDetectionStrategy, Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation } from '@angular/core';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
import { Site } from '@alfresco/js-api';
|
import { Site, SiteEntry } from '@alfresco/js-api';
|
||||||
import { ShareDataRow } from '../../data/share-data-row.model';
|
import { ShareDataRow } from '../../data/share-data-row.model';
|
||||||
import { NodesApiService } from '../../../common/services/nodes-api.service';
|
import { NodesApiService } from '../../../common/services/nodes-api.service';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
@ -64,23 +64,26 @@ export class LibraryRoleColumnComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected updateValue() {
|
protected updateValue() {
|
||||||
const role = this.context.row.node?.entry.role ?? this.context.row.obj.role;
|
const node: SiteEntry = this.context.row.node;
|
||||||
switch (role) {
|
if (node?.entry) {
|
||||||
case Site.RoleEnum.SiteManager:
|
const role: string = node.entry.role;
|
||||||
this.displayText$.next('LIBRARY.ROLE.MANAGER');
|
switch (role) {
|
||||||
break;
|
case Site.RoleEnum.SiteManager:
|
||||||
case Site.RoleEnum.SiteCollaborator:
|
this.displayText$.next('LIBRARY.ROLE.MANAGER');
|
||||||
this.displayText$.next('LIBRARY.ROLE.COLLABORATOR');
|
break;
|
||||||
break;
|
case Site.RoleEnum.SiteCollaborator:
|
||||||
case Site.RoleEnum.SiteContributor:
|
this.displayText$.next('LIBRARY.ROLE.COLLABORATOR');
|
||||||
this.displayText$.next('LIBRARY.ROLE.CONTRIBUTOR');
|
break;
|
||||||
break;
|
case Site.RoleEnum.SiteContributor:
|
||||||
case Site.RoleEnum.SiteConsumer:
|
this.displayText$.next('LIBRARY.ROLE.CONTRIBUTOR');
|
||||||
this.displayText$.next('LIBRARY.ROLE.CONSUMER');
|
break;
|
||||||
break;
|
case Site.RoleEnum.SiteConsumer:
|
||||||
default:
|
this.displayText$.next('LIBRARY.ROLE.CONSUMER');
|
||||||
this.displayText$.next('LIBRARY.ROLE.NONE');
|
break;
|
||||||
break;
|
default:
|
||||||
|
this.displayText$.next('LIBRARY.ROLE.NONE');
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,54 +16,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { LibraryStatusColumnComponent } from './library-status-column.component';
|
import { LibraryStatusColumnComponent } from './library-status-column.component';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
|
||||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
||||||
import { Site } from '@alfresco/js-api';
|
|
||||||
|
|
||||||
describe('LibraryStatusColumnComponent', () => {
|
describe('LibraryStatusColumnComponent', () => {
|
||||||
let fixture: ComponentFixture<LibraryStatusColumnComponent>;
|
it('should be defined', () => {
|
||||||
let component: LibraryStatusColumnComponent;
|
expect(LibraryStatusColumnComponent).toBeDefined();
|
||||||
|
});
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
imports: [ContentTestingModule, LibraryStatusColumnComponent],
|
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
|
||||||
});
|
|
||||||
fixture = TestBed.createComponent(LibraryStatusColumnComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(LibraryStatusColumnComponent).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should take default visibility from node entry', () => {
|
|
||||||
component.context = {
|
|
||||||
row: {
|
|
||||||
node: { entry: { visibility: Site.VisibilityEnum.PUBLIC } }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let value = '';
|
|
||||||
component.displayText$.subscribe((val) => (value = val));
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(value).toBe('LIBRARY.VISIBILITY.PUBLIC');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should take visibility from obj when node entry visibility is not provided', () => {
|
|
||||||
component.context = {
|
|
||||||
row: {
|
|
||||||
node: { entry: {} },
|
|
||||||
obj: { visibility: Site.VisibilityEnum.PUBLIC }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let value = '';
|
|
||||||
component.displayText$.subscribe((val) => (value = val));
|
|
||||||
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(value).toBe('LIBRARY.VISIBILITY.PUBLIC');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
import { Component, DestroyRef, inject, Input, OnInit } from '@angular/core';
|
import { Component, DestroyRef, inject, Input, OnInit } from '@angular/core';
|
||||||
import { NodesApiService } from '../../../common/services/nodes-api.service';
|
import { NodesApiService } from '../../../common/services/nodes-api.service';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
import { Site } from '@alfresco/js-api';
|
import { Site, SiteEntry } from '@alfresco/js-api';
|
||||||
import { ShareDataRow } from '../../data/share-data-row.model';
|
import { ShareDataRow } from '../../data/share-data-row.model';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
@ -62,21 +62,24 @@ export class LibraryStatusColumnComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected updateValue() {
|
protected updateValue() {
|
||||||
const visibility = this.context.row.node?.entry.visibility ?? this.context.row.obj.visibility;
|
const node: SiteEntry = this.context.row.node;
|
||||||
|
if (node?.entry) {
|
||||||
|
const visibility: string = node.entry.visibility;
|
||||||
|
|
||||||
switch (visibility) {
|
switch (visibility) {
|
||||||
case Site.VisibilityEnum.PUBLIC:
|
case Site.VisibilityEnum.PUBLIC:
|
||||||
this.displayText$.next('LIBRARY.VISIBILITY.PUBLIC');
|
this.displayText$.next('LIBRARY.VISIBILITY.PUBLIC');
|
||||||
break;
|
break;
|
||||||
case Site.VisibilityEnum.PRIVATE:
|
case Site.VisibilityEnum.PRIVATE:
|
||||||
this.displayText$.next('LIBRARY.VISIBILITY.PRIVATE');
|
this.displayText$.next('LIBRARY.VISIBILITY.PRIVATE');
|
||||||
break;
|
break;
|
||||||
case Site.VisibilityEnum.MODERATED:
|
case Site.VisibilityEnum.MODERATED:
|
||||||
this.displayText$.next('LIBRARY.VISIBILITY.MODERATED');
|
this.displayText$.next('LIBRARY.VISIBILITY.MODERATED');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.displayText$.next('UNKNOWN');
|
this.displayText$.next('UNKNOWN');
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -711,10 +711,10 @@
|
|||||||
},
|
},
|
||||||
"NODE_FAVORITE_DIRECTIVE": {
|
"NODE_FAVORITE_DIRECTIVE": {
|
||||||
"MESSAGES": {
|
"MESSAGES": {
|
||||||
"NODE_ADDED": "Añadido {{ name }} a favoritos",
|
"NODE_ADDED": "Added {{ name }} to favorites",
|
||||||
"NODES_ADDED": "Añadidos {{ number }} elementos a favoritos",
|
"NODES_ADDED": "Added {{ number }} items to favorites",
|
||||||
"NODE_REMOVED": "Eliminado {{ name }} de favoritos",
|
"NODE_REMOVED": "Removed {{ name }} from favorites",
|
||||||
"NODES_REMOVED": "Eliminado {{ number }} elementos de favoritos"
|
"NODES_REMOVED": "Removed {{ number }} items from favorites"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -711,10 +711,10 @@
|
|||||||
},
|
},
|
||||||
"NODE_FAVORITE_DIRECTIVE": {
|
"NODE_FAVORITE_DIRECTIVE": {
|
||||||
"MESSAGES": {
|
"MESSAGES": {
|
||||||
"NODE_ADDED": "Ajout de {{ name }} aux favoris",
|
"NODE_ADDED": "Added {{ name }} to favorites",
|
||||||
"NODES_ADDED": "Ajout des éléments {{ number }} aux favoris",
|
"NODES_ADDED": "Added {{ number }} items to favorites",
|
||||||
"NODE_REMOVED": "Suppression de {{ name }} des favoris",
|
"NODE_REMOVED": "Removed {{ name }} from favorites",
|
||||||
"NODES_REMOVED": "Les éléments {{ number }} supprimés des favoris"
|
"NODES_REMOVED": "Removed {{ number }} items from favorites"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -711,10 +711,10 @@
|
|||||||
},
|
},
|
||||||
"NODE_FAVORITE_DIRECTIVE": {
|
"NODE_FAVORITE_DIRECTIVE": {
|
||||||
"MESSAGES": {
|
"MESSAGES": {
|
||||||
"NODE_ADDED": "Aggiunto {{ name }} ai preferiti",
|
"NODE_ADDED": "Added {{ name }} to favorites",
|
||||||
"NODES_ADDED": "Aggiunti {{ number }} elementi ai preferiti",
|
"NODES_ADDED": "Added {{ number }} items to favorites",
|
||||||
"NODE_REMOVED": "Rimosso {{ name }} dai preferiti",
|
"NODE_REMOVED": "Removed {{ name }} from favorites",
|
||||||
"NODES_REMOVED": "Rimosso {{ number }} elementi dai preferiti"
|
"NODES_REMOVED": "Removed {{ number }} items from favorites"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -711,10 +711,10 @@
|
|||||||
},
|
},
|
||||||
"NODE_FAVORITE_DIRECTIVE": {
|
"NODE_FAVORITE_DIRECTIVE": {
|
||||||
"MESSAGES": {
|
"MESSAGES": {
|
||||||
"NODE_ADDED": "Dodano {{ name }} do ulubionych",
|
"NODE_ADDED": "Added {{ name }} to favorites",
|
||||||
"NODES_ADDED": "Dodano {{ number }} elementy do ulubionych",
|
"NODES_ADDED": "Added {{ number }} items to favorites",
|
||||||
"NODE_REMOVED": "Usunięto {{ name }} z ulubionych",
|
"NODE_REMOVED": "Removed {{ name }} from favorites",
|
||||||
"NODES_REMOVED": "Usunięto {{ number }} elementy z ulubionych"
|
"NODES_REMOVED": "Removed {{ number }} items from favorites"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -711,10 +711,10 @@
|
|||||||
},
|
},
|
||||||
"NODE_FAVORITE_DIRECTIVE": {
|
"NODE_FAVORITE_DIRECTIVE": {
|
||||||
"MESSAGES": {
|
"MESSAGES": {
|
||||||
"NODE_ADDED": "Adicionado {{ name }} aos favoritos",
|
"NODE_ADDED": "Added {{ name }} to favorites",
|
||||||
"NODES_ADDED": "Adicionados {{ number }} itens aos favoritos",
|
"NODES_ADDED": "Added {{ number }} items to favorites",
|
||||||
"NODE_REMOVED": "Removido {{ name }} dos favoritos",
|
"NODE_REMOVED": "Removed {{ name }} from favorites",
|
||||||
"NODES_REMOVED": "Removido {{ number }} itens dos favoritos"
|
"NODES_REMOVED": "Removed {{ number }} items from favorites"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,6 @@ export abstract class InfiniteScrollDatasource<T> extends DataSource<T> {
|
|||||||
|
|
||||||
reset(): void {
|
reset(): void {
|
||||||
this.isLoading$.next(true);
|
this.isLoading$.next(true);
|
||||||
this.dataStream.next([]);
|
|
||||||
this.getNextBatch({ skipCount: 0, maxItems: this.batchSize })
|
this.getNextBatch({ skipCount: 0, maxItems: this.batchSize })
|
||||||
.pipe(take(1))
|
.pipe(take(1))
|
||||||
.subscribe((firstBatch) => {
|
.subscribe((firstBatch) => {
|
||||||
|
@ -1,73 +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 { SecurityOptionsLoaderService } from './security-options-loader.service';
|
|
||||||
import { AppConfigService, AppConfigValues } from '@alfresco/adf-core';
|
|
||||||
import { AdfHttpClient } from '@alfresco/adf-core/api';
|
|
||||||
|
|
||||||
describe('SecurityOptionsLoaderService', () => {
|
|
||||||
let service: SecurityOptionsLoaderService;
|
|
||||||
let appConfigServiceSpy: jasmine.SpyObj<AppConfigService>;
|
|
||||||
let adfHttpClientSpy: jasmine.SpyObj<AdfHttpClient>;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
appConfigServiceSpy = jasmine.createSpyObj('AppConfigService', ['get']);
|
|
||||||
adfHttpClientSpy = jasmine.createSpyObj('AdfHttpClient', ['setDefaultSecurityOption']);
|
|
||||||
|
|
||||||
service = new SecurityOptionsLoaderService(appConfigServiceSpy, adfHttpClientSpy);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set withCredentials when value is true', () => {
|
|
||||||
appConfigServiceSpy.get.and.callFake((key: string): any => {
|
|
||||||
if (key === AppConfigValues.AUTH_WITH_CREDENTIALS) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
service.load();
|
|
||||||
|
|
||||||
expect(adfHttpClientSpy.setDefaultSecurityOption).toHaveBeenCalledWith({ withCredentials: true });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set withCredentials when value is false', () => {
|
|
||||||
appConfigServiceSpy.get.and.callFake((key: string): any => {
|
|
||||||
if (key === AppConfigValues.AUTH_WITH_CREDENTIALS) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
service.load();
|
|
||||||
|
|
||||||
expect(adfHttpClientSpy.setDefaultSecurityOption).toHaveBeenCalledWith({ withCredentials: false });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not call setDefaultSecurityOption when value is undefined', () => {
|
|
||||||
appConfigServiceSpy.get.and.returnValue(undefined);
|
|
||||||
|
|
||||||
service.load();
|
|
||||||
|
|
||||||
expect(adfHttpClientSpy.setDefaultSecurityOption).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not call setDefaultSecurityOption when value is null', () => {
|
|
||||||
appConfigServiceSpy.get.and.returnValue(null);
|
|
||||||
|
|
||||||
service.load();
|
|
||||||
|
|
||||||
expect(adfHttpClientSpy.setDefaultSecurityOption).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,34 +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 { AppConfigService, AppConfigValues } from '@alfresco/adf-core';
|
|
||||||
import { AdfHttpClient } from '@alfresco/adf-core/api';
|
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class SecurityOptionsLoaderService {
|
|
||||||
constructor(private appConfigService: AppConfigService, private adfHttpClient: AdfHttpClient) {}
|
|
||||||
|
|
||||||
load = () => {
|
|
||||||
const withCredentials = this.appConfigService.get<boolean>(AppConfigValues.AUTH_WITH_CREDENTIALS);
|
|
||||||
if (withCredentials !== undefined && withCredentials !== null) {
|
|
||||||
this.adfHttpClient.setDefaultSecurityOption({ withCredentials });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -89,7 +89,7 @@ describe('TagService', () => {
|
|||||||
|
|
||||||
describe('createTags', () => {
|
describe('createTags', () => {
|
||||||
it('should call createTags on tagsApi', () => {
|
it('should call createTags on tagsApi', () => {
|
||||||
spyOn(service.tagsApi, 'createTags').and.returnValue(Promise.resolve({}));
|
spyOn(service.tagsApi, 'createTags').and.returnValue(Promise.resolve([]));
|
||||||
const tag1 = new TagBody();
|
const tag1 = new TagBody();
|
||||||
tag1.tag = 'Some tag 1';
|
tag1.tag = 'Some tag 1';
|
||||||
const tag2 = new TagBody();
|
const tag2 = new TagBody();
|
||||||
@ -101,17 +101,19 @@ describe('TagService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should emit refresh when tags creation is success', async () => {
|
it('should emit refresh when tags creation is success', async () => {
|
||||||
const tag: TagEntry = {
|
const tags: TagEntry[] = [
|
||||||
entry: {
|
{
|
||||||
id: 'Some id 1',
|
entry: {
|
||||||
tag: 'Some tag 1'
|
id: 'Some id 1',
|
||||||
|
tag: 'Some tag 1'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
];
|
||||||
spyOn(service.refresh, 'emit');
|
spyOn(service.refresh, 'emit');
|
||||||
spyOn(service.tagsApi, 'createTags').and.returnValue(Promise.resolve(tag));
|
spyOn(service.tagsApi, 'createTags').and.returnValue(Promise.resolve(tags));
|
||||||
|
|
||||||
await service.createTags([]).toPromise();
|
await service.createTags([]).toPromise();
|
||||||
expect(service.refresh.emit).toHaveBeenCalledWith(tag);
|
expect(service.refresh.emit).toHaveBeenCalledWith(tags);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ export class TagService {
|
|||||||
* @param tags list of tags to create.
|
* @param tags list of tags to create.
|
||||||
* @returns Created tags.
|
* @returns Created tags.
|
||||||
*/
|
*/
|
||||||
createTags(tags: TagBody[]): Observable<TagEntry | TagPaging> {
|
createTags(tags: TagBody[]): Observable<TagEntry[]> {
|
||||||
return from(this.tagsApi.createTags(tags)).pipe(tap((tagEntries) => this.refresh.emit(tagEntries)));
|
return from(this.tagsApi.createTags(tags)).pipe(tap((tagEntries) => this.refresh.emit(tagEntries)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ export class AuthenticationInterceptor implements HttpInterceptor {
|
|||||||
if (req.context.get(SHOULD_ADD_AUTH_TOKEN)) {
|
if (req.context.get(SHOULD_ADD_AUTH_TOKEN)) {
|
||||||
return this.authService.addTokenToHeader(req.url, req.headers).pipe(
|
return this.authService.addTokenToHeader(req.url, req.headers).pipe(
|
||||||
mergeMap((headersWithBearer) => {
|
mergeMap((headersWithBearer) => {
|
||||||
const headerWithContentType = this.appendJsonContentType(headersWithBearer, req.body);
|
const headerWithContentType = this.appendJsonContentType(headersWithBearer);
|
||||||
const kcReq = req.clone({ headers: headerWithContentType });
|
const kcReq = req.clone({ headers: headerWithContentType });
|
||||||
return next.handle(kcReq).pipe(catchError((error) => observableThrowError(error)));
|
return next.handle(kcReq).pipe(catchError((error) => observableThrowError(error)));
|
||||||
})
|
})
|
||||||
@ -55,7 +55,7 @@ export class AuthenticationInterceptor implements HttpInterceptor {
|
|||||||
return next.handle(req).pipe(catchError((error) => observableThrowError(error)));
|
return next.handle(req).pipe(catchError((error) => observableThrowError(error)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private appendJsonContentType(headers: HttpHeaders, reqBody: any): HttpHeaders {
|
private appendJsonContentType(headers: HttpHeaders): HttpHeaders {
|
||||||
// prevent adding any content type, to properly handle formData with boundary browser generated value,
|
// prevent adding any content type, to properly handle formData with boundary browser generated value,
|
||||||
// as adding any Content-Type its going to break the upload functionality
|
// as adding any Content-Type its going to break the upload functionality
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ export class AuthenticationInterceptor implements HttpInterceptor {
|
|||||||
return headers.delete('Content-Type');
|
return headers.delete('Content-Type');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!headers.get('Content-Type') && !(reqBody instanceof FormData)) {
|
if (!headers.get('Content-Type')) {
|
||||||
return headers.set('Content-Type', 'application/json;charset=UTF-8');
|
return headers.set('Content-Type', 'application/json;charset=UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
@use '@angular/material' as mat;
|
@use '@angular/material' as mat;
|
||||||
|
|
||||||
@mixin adf-breadcrumb-theme($theme) {
|
@mixin adf-breadcrumb-theme($theme) {
|
||||||
$config: mat.m2-get-color-config($theme);
|
$config: mat.get-color-config($theme);
|
||||||
$foreground-palette: map.get($config, foreground);
|
$foreground-palette: map.get($config, foreground);
|
||||||
$primary-palette: map.get($config, primary);
|
$primary-palette: map.get($config, primary);
|
||||||
$text-color: mat.m2-get-color-from-palette($foreground-palette, text);
|
$text-color: mat.get-color-from-palette($foreground-palette, text);
|
||||||
$primary: mat.m2-get-color-from-palette($primary-palette, text);
|
$primary: mat.get-color-from-palette($primary-palette, text);
|
||||||
|
|
||||||
adf-breadcrumb {
|
adf-breadcrumb {
|
||||||
.adf-breadcrumb__show-all-button-icon--rotate {
|
.adf-breadcrumb__show-all-button-icon--rotate {
|
||||||
color: mat.m2-get-color-from-palette($primary-palette, 500);
|
color: mat.get-color-from-palette($primary-palette, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
.adf-breadcrumb__item-wrapper {
|
.adf-breadcrumb__item-wrapper {
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
# DEPRECATION WARNING
|
|
||||||
|
|
||||||
The custom theme is deprecated and will be removed in the future. To generate a custom theme, please refer to the Angular Material [Custom Theme section](https://v18.material.angular.dev/guide/theming#custom-theme).
|
|
@ -2,19 +2,22 @@
|
|||||||
@use '@angular/material' as mat;
|
@use '@angular/material' as mat;
|
||||||
@import './theme/theme-data';
|
@import './theme/theme-data';
|
||||||
|
|
||||||
$custom-theme: mat.m2-define-light-theme(
|
$custom-theme: mat.define-light-theme(
|
||||||
(
|
(
|
||||||
color: (
|
color: (
|
||||||
primary: map.get($palettes, primary),
|
primary: map.get($palettes, primary),
|
||||||
accent: map.get($palettes, accent),
|
accent: map.get($palettes, accent),
|
||||||
warn: map.get($palettes, warning)
|
warn: map.get($palettes, warning),
|
||||||
),
|
),
|
||||||
typography: $app-typography
|
typography: $app-typography,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@if $background-color {
|
@if $background-color {
|
||||||
$custom-theme: get-custom-background-color($background-color, $custom-theme);
|
$custom-theme: get-custom-background-color(
|
||||||
|
$background-color,
|
||||||
|
$custom-theme
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@if $text-color {
|
@if $text-color {
|
||||||
|
@ -1,27 +1,31 @@
|
|||||||
@use '@angular/material' as mat;
|
@use '@angular/material' as mat;
|
||||||
@import './default-colors';
|
@import './default-colors.scss';
|
||||||
@import './custom-palette-creator';
|
@import './custom-palette-creator.scss';
|
||||||
|
|
||||||
@function get-mat-palettes($primary-color, $accent-color) {
|
@function get-mat-palettes($primary-color, $accent-color) {
|
||||||
$mat-primary-palette: null;
|
$mat-primary-palette: null;
|
||||||
|
|
||||||
@if ($primary-color) {
|
@if ($primary-color) {
|
||||||
$custom-theme-primary-palette: create-color-palette($primary-color, 'primary');
|
$custom-theme-primary-palette: create-color-palette($primary-color, 'primary');
|
||||||
$mat-primary-palette: mat.m2-define-palette($custom-theme-primary-palette, 500);
|
$mat-primary-palette: mat.define-palette($custom-theme-primary-palette, 500);
|
||||||
} @else {
|
} @else {
|
||||||
$mat-primary-palette: mat.m2-define-palette($default-primary, A100);
|
$mat-primary-palette: mat.define-palette($default-primary, A100);
|
||||||
}
|
}
|
||||||
|
|
||||||
$mat-accent-palette: null;
|
$mat-accent-palette: null;
|
||||||
|
|
||||||
@if ($accent-color) {
|
@if ($accent-color) {
|
||||||
$custom-theme-accent-palette: create-color-palette($accent-color, 'accent');
|
$custom-theme-accent-palette: create-color-palette($accent-color, 'accent');
|
||||||
$mat-accent-palette: mat.m2-define-palette($custom-theme-accent-palette, 500);
|
$mat-accent-palette: mat.define-palette($custom-theme-accent-palette, 500);
|
||||||
} @else {
|
} @else {
|
||||||
$mat-accent-palette: mat.m2-define-palette($default-accent);
|
$mat-accent-palette: mat.define-palette($default-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
$mat-warn-palette: mat.m2-define-palette($default-warn, A100);
|
$mat-warn-palette: mat.define-palette($default-warn, A100);
|
||||||
|
|
||||||
@return (primary: $mat-primary-palette, accent: $mat-accent-palette, warning: $mat-warn-palette);
|
@return (
|
||||||
|
primary: $mat-primary-palette,
|
||||||
|
accent: $mat-accent-palette,
|
||||||
|
warning: $mat-warn-palette,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,37 +3,37 @@
|
|||||||
@import '../variables/font-family';
|
@import '../variables/font-family';
|
||||||
|
|
||||||
@function get-mat-typography($base-font-size, $font-family) {
|
@function get-mat-typography($base-font-size, $font-family) {
|
||||||
$custom-typography: mat.m2-define-typography-config(
|
$custom-typography: mat.define-typography-config(
|
||||||
$font-family: 'Muli, Roboto, "Helvetica Neue", sans-serif',
|
$font-family: 'Muli, Roboto, "Helvetica Neue", sans-serif',
|
||||||
$headline-1: mat.m2-define-typography-level(112px, 112px, 300),
|
$headline-1: mat.define-typography-level(112px, 112px, 300),
|
||||||
$headline-2: mat.m2-define-typography-level(56px, 56px, 400),
|
$headline-2: mat.define-typography-level(56px, 56px, 400),
|
||||||
$headline-3: mat.m2-define-typography-level(45px, 48px, 400),
|
$headline-3: mat.define-typography-level(45px, 48px, 400),
|
||||||
$headline-4: mat.m2-define-typography-level(34px, 40px, 400),
|
$headline-4: mat.define-typography-level(34px, 40px, 400),
|
||||||
$headline-5: mat.m2-define-typography-level(24px, 32px, 400),
|
$headline-5: mat.define-typography-level(24px, 32px, 400),
|
||||||
$headline-6: mat.m2-define-typography-level(20px, 32px, 500),
|
$headline-6: mat.define-typography-level(20px, 32px, 500),
|
||||||
$subtitle-1: mat.m2-define-typography-level(16px, 28px, 400),
|
$subtitle-1: mat.define-typography-level(16px, 28px, 400),
|
||||||
$body-1: mat.m2-define-typography-level(15px, 24px, 400),
|
$body-1: mat.define-typography-level(15px, 24px, 400),
|
||||||
$subtitle-2: mat.m2-define-typography-level(14px, 24px, 500),
|
$subtitle-2: mat.define-typography-level(14px, 24px, 500),
|
||||||
$body-2: mat.m2-define-typography-level(14px, 20px, 400),
|
$body-2: mat.define-typography-level(14px, 20px, 400),
|
||||||
$caption: mat.m2-define-typography-level(12px, 20px, 400),
|
$caption: mat.define-typography-level(12px, 20px, 400),
|
||||||
$button: mat.m2-define-typography-level(14px, 14px, 500),
|
$button: mat.define-typography-level(14px, 14px, 500),
|
||||||
// Line-height must be unit-less fraction of the font-size.
|
// Line-height must be unit-less fraction of the font-size.
|
||||||
);
|
);
|
||||||
|
|
||||||
@if $base-font-size {
|
@if $base-font-size {
|
||||||
$custom-typography: mat.m2-define-typography-config(
|
$custom-typography: mat.define-typography-config(
|
||||||
$headline-1: mat.m2-define-typography-level(8rem, 8rem, 300),
|
$headline-1: mat.define-typography-level(8rem, 8rem, 300),
|
||||||
$headline-2: mat.m2-define-typography-level(4rem, 4rem, 400),
|
$headline-2: mat.define-typography-level(4rem, 4rem, 400),
|
||||||
$headline-3: mat.m2-define-typography-level(3.21rem, 3.21rem, 400),
|
$headline-3: mat.define-typography-level(3.21rem, 3.21rem, 400),
|
||||||
$headline-4: mat.m2-define-typography-level(2.42rem, 2.85rem, 400),
|
$headline-4: mat.define-typography-level(2.42rem, 2.85rem, 400),
|
||||||
$headline-5: mat.m2-define-typography-level(1.71rem, 2.28rem, 400),
|
$headline-5: mat.define-typography-level(1.71rem, 2.28rem, 400),
|
||||||
$headline-6: mat.m2-define-typography-level(1.42rem, 2.28rem, 500),
|
$headline-6: mat.define-typography-level(1.42rem, 2.28rem, 500),
|
||||||
$subtitle-1: mat.m2-define-typography-level(1.14rem, 2rem, 400),
|
$subtitle-1: mat.define-typography-level(1.14rem, 2rem, 400),
|
||||||
$body-1: mat.m2-define-typography-level(1.07rem, 1.71rem, 400),
|
$body-1: mat.define-typography-level(1.07rem, 1.71rem, 400),
|
||||||
$subtitle-2: mat.m2-define-typography-level(1rem, 1.71rem, 500),
|
$subtitle-2: mat.define-typography-level(1rem, 1.71rem, 500),
|
||||||
$body-2: mat.m2-define-typography-level(1rem, 1.42rem, 400),
|
$body-2: mat.define-typography-level(1rem, 1.42rem, 400),
|
||||||
$caption: mat.m2-define-typography-level(0.86rem, 1.42rem, 400),
|
$caption: mat.define-typography-level(0.86rem, 1.42rem, 400),
|
||||||
$button: mat.m2-define-typography-level(1rem, 1rem, 500),
|
$button: mat.define-typography-level(1rem, 1rem, 500),
|
||||||
$font-family: $default-font-family
|
$font-family: $default-font-family
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -17,37 +17,37 @@
|
|||||||
|
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { DebugFeaturesService } from './debug-features.service';
|
import { DebugFeaturesService } from './debug-features.service';
|
||||||
import { OverridableFeaturesServiceToken, WritableFeaturesServiceConfigToken, WritableFeaturesServiceToken } from '../interfaces/features.interface';
|
import { StorageService } from '../../../../src/lib/common/services/storage.service';
|
||||||
|
import { OverridableFeaturesServiceToken, WritableFeaturesServiceToken } from '../interfaces/features.interface';
|
||||||
import { DummyFeaturesService } from './dummy-features.service';
|
import { DummyFeaturesService } from './dummy-features.service';
|
||||||
import { StorageFeaturesService } from './storage-features.service';
|
import { StorageFeaturesService } from './storage-features.service';
|
||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
|
|
||||||
describe('DebugFeaturesService', () => {
|
describe('DebugFeaturesService', () => {
|
||||||
let service: DebugFeaturesService;
|
let service: DebugFeaturesService;
|
||||||
let mockStorageKey: string;
|
const mockStorage = {
|
||||||
let mockStorage;
|
getItem: () =>
|
||||||
|
JSON.stringify({
|
||||||
|
feature1: {
|
||||||
|
current: true
|
||||||
|
},
|
||||||
|
feature2: {
|
||||||
|
current: false,
|
||||||
|
fictive: true
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
setItem: () => {}
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockStorageKey = 'storage-key-test';
|
|
||||||
mockStorage = { [mockStorageKey]: true };
|
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
DebugFeaturesService,
|
DebugFeaturesService,
|
||||||
{
|
{ provide: StorageService, useValue: mockStorage },
|
||||||
provide: WritableFeaturesServiceConfigToken,
|
|
||||||
useValue: { storageKey: mockStorageKey }
|
|
||||||
},
|
|
||||||
{ provide: WritableFeaturesServiceToken, useClass: StorageFeaturesService },
|
{ provide: WritableFeaturesServiceToken, useClass: StorageFeaturesService },
|
||||||
{ provide: OverridableFeaturesServiceToken, useClass: DummyFeaturesService }
|
{ provide: OverridableFeaturesServiceToken, useClass: DummyFeaturesService }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
spyOn(sessionStorage, 'getItem').and.callFake((key) => JSON.stringify(mockStorage[key]));
|
|
||||||
spyOn(sessionStorage, 'setItem').and.callFake((key, value) => {
|
|
||||||
mockStorage[key] = value;
|
|
||||||
});
|
|
||||||
|
|
||||||
service = TestBed.inject(DebugFeaturesService);
|
service = TestBed.inject(DebugFeaturesService);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Inject, Injectable, Optional } from '@angular/core';
|
import { Inject, Injectable, Optional } from '@angular/core';
|
||||||
import { BehaviorSubject, Observable, combineLatest } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { filter, switchMap } from 'rxjs/operators';
|
import { skip, switchMap } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
IDebugFeaturesService,
|
IDebugFeaturesService,
|
||||||
IFeaturesService,
|
IFeaturesService,
|
||||||
@ -29,12 +29,12 @@ import {
|
|||||||
FlagSet,
|
FlagSet,
|
||||||
IWritableFeaturesService
|
IWritableFeaturesService
|
||||||
} from '../interfaces/features.interface';
|
} from '../interfaces/features.interface';
|
||||||
|
import { StorageService } from '@alfresco/adf-core';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DebugFeaturesService implements IDebugFeaturesService {
|
export class DebugFeaturesService implements IDebugFeaturesService {
|
||||||
private readonly isInDebugModeSubject = new BehaviorSubject<boolean>(false);
|
private isInDebugMode: BehaviorSubject<boolean>;
|
||||||
private readonly isInDebugMode$ = this.isInDebugModeSubject.asObservable();
|
private isInDebugMode$: Observable<boolean>;
|
||||||
private readonly initSubject = new BehaviorSubject<boolean>(false);
|
|
||||||
|
|
||||||
get storageKey(): string {
|
get storageKey(): string {
|
||||||
return `${this.config?.storageKey || 'feature-flags'}-override`;
|
return `${this.config?.storageKey || 'feature-flags'}-override`;
|
||||||
@ -43,15 +43,14 @@ export class DebugFeaturesService implements IDebugFeaturesService {
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(OverridableFeaturesServiceToken) private overriddenFeaturesService: IFeaturesService,
|
@Inject(OverridableFeaturesServiceToken) private overriddenFeaturesService: IFeaturesService,
|
||||||
@Inject(WritableFeaturesServiceToken) private writableFeaturesService: IFeaturesService & IWritableFeaturesService,
|
@Inject(WritableFeaturesServiceToken) private writableFeaturesService: IFeaturesService & IWritableFeaturesService,
|
||||||
|
private storageService: StorageService,
|
||||||
@Optional() @Inject(WritableFeaturesServiceConfigToken) private config?: WritableFeaturesServiceConfig
|
@Optional() @Inject(WritableFeaturesServiceConfigToken) private config?: WritableFeaturesServiceConfig
|
||||||
) {
|
) {
|
||||||
this.init();
|
this.isInDebugMode = new BehaviorSubject<boolean>(JSON.parse(this.storageService.getItem(this.storageKey) || 'false'));
|
||||||
|
this.isInDebugMode$ = this.isInDebugMode.asObservable();
|
||||||
|
|
||||||
combineLatest({
|
this.isInDebugMode.pipe(skip(1)).subscribe((debugMode) => {
|
||||||
debugMode: this.isInDebugModeSubject,
|
this.storageService.setItem(this.storageKey, JSON.stringify(debugMode));
|
||||||
init: this.waitForInitializationToFinish()
|
|
||||||
}).subscribe(({ debugMode }) => {
|
|
||||||
sessionStorage.setItem(this.storageKey, JSON.stringify(debugMode));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,20 +87,10 @@ export class DebugFeaturesService implements IDebugFeaturesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enable(on: boolean): void {
|
enable(on: boolean): void {
|
||||||
this.isInDebugModeSubject.next(on);
|
this.isInDebugMode.next(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
isEnabled$(): Observable<boolean> {
|
isEnabled$(): Observable<boolean> {
|
||||||
return this.isInDebugMode$;
|
return this.isInDebugMode$;
|
||||||
}
|
}
|
||||||
|
|
||||||
private init() {
|
|
||||||
const storedOverride = JSON.parse(sessionStorage.getItem(this.storageKey) || 'false');
|
|
||||||
this.isInDebugModeSubject.next(storedOverride);
|
|
||||||
this.initSubject.next(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private waitForInitializationToFinish(): Observable<boolean> {
|
|
||||||
return this.initSubject.pipe(filter((initialized) => !!initialized));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,20 +17,17 @@
|
|||||||
|
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { StorageFeaturesService } from './storage-features.service';
|
import { StorageFeaturesService } from './storage-features.service';
|
||||||
|
import { StorageService } from '../../../../src/public-api';
|
||||||
import { FlagSet, WritableFeaturesServiceConfigToken } from '../interfaces/features.interface';
|
import { FlagSet, WritableFeaturesServiceConfigToken } from '../interfaces/features.interface';
|
||||||
import { skip, take } from 'rxjs/operators';
|
import { skip, take } from 'rxjs/operators';
|
||||||
|
|
||||||
describe('StorageFeaturesService', () => {
|
describe('StorageFeaturesService', () => {
|
||||||
let storageFeaturesService: StorageFeaturesService;
|
let storageFeaturesService: StorageFeaturesService;
|
||||||
|
|
||||||
describe('if flags are present in sessionStorage', () => {
|
describe('if flags are present in LocalStorage', () => {
|
||||||
let mockStorageKey: string;
|
const mockStorage = {
|
||||||
let mockStorage;
|
getItem: () =>
|
||||||
|
JSON.stringify({
|
||||||
beforeEach(() => {
|
|
||||||
mockStorageKey = 'storage-key-test';
|
|
||||||
mockStorage = {
|
|
||||||
[mockStorageKey]: {
|
|
||||||
feature1: {
|
feature1: {
|
||||||
current: true
|
current: true
|
||||||
},
|
},
|
||||||
@ -38,23 +35,23 @@ describe('StorageFeaturesService', () => {
|
|||||||
current: false,
|
current: false,
|
||||||
fictive: true
|
fictive: true
|
||||||
}
|
}
|
||||||
}
|
}),
|
||||||
};
|
setItem: () => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
|
{ provide: StorageService, useValue: mockStorage },
|
||||||
{
|
{
|
||||||
provide: WritableFeaturesServiceConfigToken,
|
provide: WritableFeaturesServiceConfigToken,
|
||||||
useValue: { storageKey: mockStorageKey }
|
useValue: {
|
||||||
|
storageKey: 'storage-key-test'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
spyOn(sessionStorage, 'getItem').and.callFake((key) => JSON.stringify(mockStorage[key]));
|
|
||||||
spyOn(sessionStorage, 'setItem').and.callFake((key, value) => {
|
|
||||||
mockStorage[key] = value;
|
|
||||||
});
|
|
||||||
|
|
||||||
storageFeaturesService = TestBed.inject(StorageFeaturesService);
|
storageFeaturesService = TestBed.inject(StorageFeaturesService);
|
||||||
storageFeaturesService.init();
|
storageFeaturesService.init();
|
||||||
});
|
});
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Inject, Injectable, Optional } from '@angular/core';
|
import { Inject, Injectable, Optional } from '@angular/core';
|
||||||
import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs';
|
import { BehaviorSubject, Observable, of } from 'rxjs';
|
||||||
import { filter, map } from 'rxjs/operators';
|
import { map, skip } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
FlagChangeset,
|
FlagChangeset,
|
||||||
IFeaturesService,
|
IFeaturesService,
|
||||||
@ -28,21 +28,21 @@ import {
|
|||||||
WritableFeaturesServiceConfig
|
WritableFeaturesServiceConfig
|
||||||
} from '../interfaces/features.interface';
|
} from '../interfaces/features.interface';
|
||||||
import { FlagSetParser } from './flagset.parser';
|
import { FlagSetParser } from './flagset.parser';
|
||||||
|
import { StorageService } from '@alfresco/adf-core';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class StorageFeaturesService implements IFeaturesService, IWritableFeaturesService {
|
export class StorageFeaturesService implements IFeaturesService, IWritableFeaturesService {
|
||||||
private currentFlagState: WritableFlagChangeset = {};
|
private currentFlagState: WritableFlagChangeset = {};
|
||||||
private readonly flags = new BehaviorSubject<WritableFlagChangeset>({});
|
private flags = new BehaviorSubject<WritableFlagChangeset>({});
|
||||||
private readonly flags$ = this.flags.asObservable();
|
private flags$ = this.flags.asObservable();
|
||||||
private readonly initSubject = new BehaviorSubject<boolean>(false);
|
|
||||||
|
|
||||||
constructor(@Optional() @Inject(WritableFeaturesServiceConfigToken) private config?: WritableFeaturesServiceConfig) {
|
constructor(
|
||||||
combineLatest({
|
private storageService: StorageService,
|
||||||
flags: this.flags,
|
@Optional() @Inject(WritableFeaturesServiceConfigToken) private config?: WritableFeaturesServiceConfig
|
||||||
init: this.waitForInitializationToFinish()
|
) {
|
||||||
}).subscribe(({ flags }) => {
|
this.flags.pipe(skip(1)).subscribe((flags) => {
|
||||||
this.currentFlagState = flags;
|
this.currentFlagState = flags;
|
||||||
sessionStorage.setItem(this.storageKey, JSON.stringify(FlagSetParser.serialize(flags)));
|
this.storageService.setItem(this.storageKey, JSON.stringify(FlagSetParser.serialize(flags)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,10 +51,9 @@ export class StorageFeaturesService implements IFeaturesService, IWritableFeatur
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(): Observable<WritableFlagChangeset> {
|
init(): Observable<WritableFlagChangeset> {
|
||||||
const storedFlags = JSON.parse(sessionStorage.getItem(this.storageKey) || '{}');
|
const storedFlags = JSON.parse(this.storageService.getItem(this.storageKey) || '{}');
|
||||||
const initialFlagChangeSet = FlagSetParser.deserialize(storedFlags);
|
const initialFlagChangeSet = FlagSetParser.deserialize(storedFlags);
|
||||||
this.flags.next(initialFlagChangeSet);
|
this.flags.next(initialFlagChangeSet);
|
||||||
this.initSubject.next(true);
|
|
||||||
return of(initialFlagChangeSet);
|
return of(initialFlagChangeSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,8 +133,4 @@ export class StorageFeaturesService implements IFeaturesService, IWritableFeatur
|
|||||||
|
|
||||||
this.flags.next(mergedFlags);
|
this.flags.next(mergedFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
private waitForInitializationToFinish(): Observable<boolean> {
|
|
||||||
return this.initSubject.pipe(filter((initialized) => !!initialized));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,123 +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 { AdfHttpClient } from '@alfresco/adf-core/api';
|
|
||||||
import { StorageService } from '../common';
|
|
||||||
import { StoragePrefixFactory } from './app-config-storage-prefix.factory';
|
|
||||||
import { loadAppConfig } from './app-config.loader';
|
|
||||||
import { AppConfigService, AppConfigValues } from './app-config.service';
|
|
||||||
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
|
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
|
||||||
import { of } from 'rxjs';
|
|
||||||
|
|
||||||
describe('loadAppConfig', () => {
|
|
||||||
let appConfigServiceSpy: jasmine.SpyObj<AppConfigService>;
|
|
||||||
let storageServiceSpy: jasmine.SpyObj<StorageService>;
|
|
||||||
let adfHttpClientSpy: jasmine.SpyObj<AdfHttpClient>;
|
|
||||||
let storagePrefixFactorySpy: jasmine.SpyObj<StoragePrefixFactory>;
|
|
||||||
|
|
||||||
let appConfigGetSpy: jasmine.Spy;
|
|
||||||
let appConfigLoadSpy: jasmine.Spy;
|
|
||||||
|
|
||||||
let factoryFunction: () => void;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
adfHttpClientSpy = jasmine.createSpyObj('AdfHttpClient', ['setDefaultSecurityOption']);
|
|
||||||
storagePrefixFactorySpy = jasmine.createSpyObj('StoragePrefixFactory', ['getPrefix']);
|
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
imports: [HttpClientModule],
|
|
||||||
providers: [
|
|
||||||
{ provide: AppConfigService },
|
|
||||||
{ provide: StorageService },
|
|
||||||
{
|
|
||||||
provide: AdfHttpClient,
|
|
||||||
useValue: adfHttpClientSpy
|
|
||||||
},
|
|
||||||
{ provide: StoragePrefixFactory, useValue: storagePrefixFactorySpy }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
appConfigServiceSpy = TestBed.inject(AppConfigService) as jasmine.SpyObj<AppConfigService>;
|
|
||||||
appConfigGetSpy = spyOn(appConfigServiceSpy, 'get');
|
|
||||||
appConfigLoadSpy = spyOn(appConfigServiceSpy, 'load');
|
|
||||||
appConfigLoadSpy.and.callFake((callback: () => void) => {
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
|
|
||||||
storageServiceSpy = TestBed.inject(StorageService) as jasmine.SpyObj<StorageService>;
|
|
||||||
spyOnProperty(storageServiceSpy, 'prefix', 'get').and.callThrough();
|
|
||||||
|
|
||||||
storagePrefixFactorySpy.getPrefix.and.returnValue({ subscribe: () => {} } as any);
|
|
||||||
|
|
||||||
factoryFunction = loadAppConfig(appConfigServiceSpy, storageServiceSpy, adfHttpClientSpy, storagePrefixFactorySpy);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should disable CSRF based on app config', () => {
|
|
||||||
appConfigGetSpy.and.callFake((key: string): any => {
|
|
||||||
if (key === AppConfigValues.DISABLECSRF) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
factoryFunction();
|
|
||||||
|
|
||||||
expect(appConfigServiceSpy.get).toHaveBeenCalledWith('disableCSRF', true);
|
|
||||||
expect(adfHttpClientSpy.disableCsrf).toBeTrue();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set default security option when auth.withCredentials is defined', () => {
|
|
||||||
appConfigServiceSpy.get.and.callFake((key: string): any => {
|
|
||||||
if (key === AppConfigValues.AUTH_WITH_CREDENTIALS) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
factoryFunction();
|
|
||||||
|
|
||||||
expect(adfHttpClientSpy.setDefaultSecurityOption).toHaveBeenCalledWith({ withCredentials: true });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set storage prefix from app config', () => {
|
|
||||||
appConfigServiceSpy.get.and.callFake((key: string, _default): any => {
|
|
||||||
if (key === AppConfigValues.STORAGE_PREFIX) {
|
|
||||||
return 'test-prefix';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
factoryFunction();
|
|
||||||
|
|
||||||
expect(appConfigServiceSpy.get).toHaveBeenCalledWith(AppConfigValues.STORAGE_PREFIX, '');
|
|
||||||
expect(storageServiceSpy.prefix).toEqual('test-prefix_');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update storage prefix from storagePrefixFactory', fakeAsync(() => {
|
|
||||||
storagePrefixFactorySpy.getPrefix.and.returnValue(of('new-amazing-prefix'));
|
|
||||||
|
|
||||||
factoryFunction();
|
|
||||||
tick();
|
|
||||||
|
|
||||||
expect(storagePrefixFactorySpy.getPrefix).toHaveBeenCalled();
|
|
||||||
expect(storageServiceSpy.prefix).toEqual('new-amazing-prefix_');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should call appConfigService.load with the init function', () => {
|
|
||||||
factoryFunction();
|
|
||||||
|
|
||||||
expect(appConfigLoadSpy).toHaveBeenCalledWith(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
});
|
|
@ -37,11 +37,6 @@ export function loadAppConfig(
|
|||||||
) {
|
) {
|
||||||
const init = () => {
|
const init = () => {
|
||||||
adfHttpClient.disableCsrf = appConfigService.get<boolean>(AppConfigValues.DISABLECSRF, true);
|
adfHttpClient.disableCsrf = appConfigService.get<boolean>(AppConfigValues.DISABLECSRF, true);
|
||||||
const withCredentials = appConfigService.get<boolean>(AppConfigValues.AUTH_WITH_CREDENTIALS);
|
|
||||||
if (withCredentials !== undefined && withCredentials !== null) {
|
|
||||||
adfHttpClient.setDefaultSecurityOption({ withCredentials });
|
|
||||||
}
|
|
||||||
|
|
||||||
storageService.prefix = appConfigService.get<string>(AppConfigValues.STORAGE_PREFIX, '');
|
storageService.prefix = appConfigService.get<string>(AppConfigValues.STORAGE_PREFIX, '');
|
||||||
|
|
||||||
storagePrefixFactory.getPrefix().subscribe((property) => {
|
storagePrefixFactory.getPrefix().subscribe((property) => {
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
import { Directive, EventEmitter, Input, Output } from '@angular/core';
|
import { Directive, EventEmitter, Input, Output } from '@angular/core';
|
||||||
import { ThemePalette } from '@angular/material/core';
|
import { ThemePalette } from '@angular/material/core';
|
||||||
import { FormFieldModel, FormFieldValidator, FormModel, FormOutcomeEvent, FormOutcomeModel } from './widgets';
|
import { FormFieldModel, FormFieldValidator, FormModel, FormOutcomeEvent, FormOutcomeModel } from './widgets';
|
||||||
import { isOutcomeButtonVisible } from './helpers/buttons-visibility';
|
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
standalone: true
|
standalone: true
|
||||||
@ -104,6 +103,10 @@ export abstract class FormBaseComponent {
|
|||||||
*/
|
*/
|
||||||
formStyle: string = '';
|
formStyle: string = '';
|
||||||
|
|
||||||
|
get hasVisibleOutcomes(): boolean {
|
||||||
|
return this.form?.outcomes?.some((outcome) => this.isOutcomeButtonVisible(outcome, this.form.readOnly));
|
||||||
|
}
|
||||||
|
|
||||||
get form(): FormModel {
|
get form(): FormModel {
|
||||||
return this._form;
|
return this._form;
|
||||||
}
|
}
|
||||||
@ -166,7 +169,22 @@ export abstract class FormBaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isOutcomeButtonVisible(outcome: FormOutcomeModel, isFormReadOnly: boolean): boolean {
|
isOutcomeButtonVisible(outcome: FormOutcomeModel, isFormReadOnly: boolean): boolean {
|
||||||
return isOutcomeButtonVisible(outcome, { isFormReadOnly, showCompleteButton: this.showCompleteButton, showSaveButton: this.showSaveButton });
|
if (outcome?.name) {
|
||||||
|
if (outcome.name === FormOutcomeModel.COMPLETE_ACTION) {
|
||||||
|
return this.showCompleteButton;
|
||||||
|
}
|
||||||
|
if (isFormReadOnly) {
|
||||||
|
return outcome.isSelected;
|
||||||
|
}
|
||||||
|
if (outcome.name === FormOutcomeModel.SAVE_ACTION) {
|
||||||
|
return this.showSaveButton;
|
||||||
|
}
|
||||||
|
if (outcome.name === FormOutcomeModel.START_PROCESS_ACTION) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +73,6 @@ export class FormFieldComponent implements OnInit, OnDestroy {
|
|||||||
if (w.adf === undefined) {
|
if (w.adf === undefined) {
|
||||||
w.adf = {};
|
w.adf = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const originalField = this.getField();
|
const originalField = this.getField();
|
||||||
if (originalField) {
|
if (originalField) {
|
||||||
const customTemplate = this.field.form.customFieldTemplates[originalField.type];
|
const customTemplate = this.field.form.customFieldTemplates[originalField.type];
|
||||||
|
@ -3,12 +3,8 @@
|
|||||||
<div *ngIf="formDefinition.hasTabs()">
|
<div *ngIf="formDefinition.hasTabs()">
|
||||||
<div *ngIf="hasTabs()" class="alfresco-tabs-widget">
|
<div *ngIf="hasTabs()" class="alfresco-tabs-widget">
|
||||||
<mat-tab-group>
|
<mat-tab-group>
|
||||||
<mat-tab *ngFor="let tab of visibleTabs()" [label]="tab.title | translate ">
|
<mat-tab *ngFor="let tab of visibleTabs()" [label]="tab.title | translate ">
|
||||||
<ng-template matTabContent>
|
<ng-template *ngTemplateOutlet="render; context: { fieldToRender: tab.fields }" />
|
||||||
<div class="adf-form-tab-content">
|
|
||||||
<ng-template *ngTemplateOutlet="render; context: { fieldToRender: tab.fields }" />
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
</mat-tab-group>
|
</mat-tab-group>
|
||||||
</div>
|
</div>
|
||||||
@ -42,8 +38,7 @@
|
|||||||
<section class="adf-grid-list-column-view" *ngIf="currentRootElement?.isExpanded">
|
<section class="adf-grid-list-column-view" *ngIf="currentRootElement?.isExpanded">
|
||||||
<div class="adf-grid-list-single-column"
|
<div class="adf-grid-list-single-column"
|
||||||
*ngFor="let column of currentRootElement?.columns"
|
*ngFor="let column of currentRootElement?.columns"
|
||||||
[style.width.%]="getColumnWidth(currentRootElement)"
|
[style.width.%]="getColumnWidth(currentRootElement)">
|
||||||
>
|
|
||||||
<ng-container *ngFor="let field of column?.fields">
|
<ng-container *ngFor="let field of column?.fields">
|
||||||
<ng-container *ngIf="field.type === 'section'; else formField">
|
<ng-container *ngIf="field.type === 'section'; else formField">
|
||||||
<adf-form-section [field]="field"/>
|
<adf-form-section [field]="field"/>
|
||||||
@ -64,11 +59,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="currentRootElement.type === 'dynamic-table'" class="adf-container-widget">
|
<div *ngIf="currentRootElement.type === 'dynamic-table'" class="adf-container-widget">
|
||||||
<adf-form-field [field]="currentRootElement" />
|
<adf-form-field [field]="currentRootElement" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="adf-container-widget"
|
<div class="adf-container-widget"
|
||||||
*ngIf="currentRootElement.type === 'readonly' && currentRootElement.field.params.field.type === 'dynamic-table'">
|
*ngIf="currentRootElement.type === 'readonly' && currentRootElement.field.params.field.type === 'dynamic-table'">
|
||||||
<adf-form-field [field]="currentRootElement.field"/>
|
<adf-form-field [field]="currentRootElement.field"/>
|
||||||
|
@ -13,43 +13,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alfresco-tabs-widget {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.adf-form-tab-content {
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.adf-form-tab-group {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#{ms.$mat-tab-body} {
|
|
||||||
margin-bottom: 8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#{ms.$mat-tab-header} {
|
|
||||||
z-index: 10;
|
|
||||||
margin: 0;
|
|
||||||
background-color: white;
|
|
||||||
position: absolute;
|
|
||||||
width: 96%;
|
|
||||||
/* stylelint-disable-next-line declaration-no-important */
|
|
||||||
margin-left: 0 !important;
|
|
||||||
/* stylelint-disable-next-line declaration-no-important */
|
|
||||||
margin-right: 10px !important;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#{ms.$mat-tab-body-wrapper} {
|
|
||||||
padding-top: 5%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mat-mdc-card-content:first-child {
|
|
||||||
padding-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.adf-container-widget {
|
.adf-container-widget {
|
||||||
.adf-grid-list {
|
.adf-grid-list {
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -61,7 +24,6 @@
|
|||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-right: -1%;
|
margin-right: -1%;
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
&-item {
|
&-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -153,18 +115,12 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
& #{ms.$mat-tab-header} {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
& #{ms.$mat-card-header-text} {
|
& #{ms.$mat-card-header-text} {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
& #{ms.$mat-tab-body-content} {
|
& #{ms.$mat-tab-body-content} {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding-top: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
& #{mat-tab-label-text} {
|
& #{mat-tab-label-text} {
|
||||||
|
@ -1,45 +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 { FormOutcomeModel } from '../widgets';
|
|
||||||
|
|
||||||
interface IsOutcomeButtonVisibleProps {
|
|
||||||
isFormReadOnly: boolean;
|
|
||||||
showCompleteButton: boolean;
|
|
||||||
showSaveButton: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const isOutcomeButtonVisible = (outcome: FormOutcomeModel, props: IsOutcomeButtonVisibleProps): boolean => {
|
|
||||||
const { isFormReadOnly, showCompleteButton, showSaveButton } = props;
|
|
||||||
|
|
||||||
if (outcome?.name) {
|
|
||||||
if (outcome.name === FormOutcomeModel.COMPLETE_ACTION) {
|
|
||||||
return showCompleteButton;
|
|
||||||
}
|
|
||||||
if (isFormReadOnly) {
|
|
||||||
return outcome.isSelected;
|
|
||||||
}
|
|
||||||
if (outcome.name === FormOutcomeModel.SAVE_ACTION) {
|
|
||||||
return showSaveButton;
|
|
||||||
}
|
|
||||||
if (outcome.name === FormOutcomeModel.START_PROCESS_ACTION) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
@ -10,9 +10,9 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<mat-form-field class="adf-amount-widget__input" [hideRequiredMarker]="true" [floatLabel]="placeholder ? 'always' : 'auto'">
|
<mat-form-field class="adf-amount-widget__input" [hideRequiredMarker]="true">
|
||||||
<mat-label class="adf-label" *ngIf="!field.leftLabels" [attr.for]="field.id"
|
<label class="adf-label" *ngIf="!field.leftLabels" [attr.for]="field.id"
|
||||||
>{{field.name | translate }}<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span></mat-label
|
>{{field.name | translate }}<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span></label
|
||||||
>
|
>
|
||||||
<span matTextPrefix class="adf-amount-widget__prefix-spacing">{{ currency }} </span>
|
<span matTextPrefix class="adf-amount-widget__prefix-spacing">{{ currency }} </span>
|
||||||
<input
|
<input
|
||||||
|
@ -24,10 +24,6 @@
|
|||||||
align-self: flex-end;
|
align-self: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.adf-input {
|
|
||||||
margin-top: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(#{ms.$mat-focused}):not(#{ms.$mat-form-field-invalid}) {
|
&:not(#{ms.$mat-focused}):not(#{ms.$mat-form-field-invalid}) {
|
||||||
.adf-amount-widget__prefix-spacing {
|
.adf-amount-widget__prefix-spacing {
|
||||||
color: var(--adf-theme-foreground-secondary-text-color);
|
color: var(--adf-theme-foreground-secondary-text-color);
|
||||||
|
@ -192,7 +192,7 @@ describe('AmountWidgetComponent - rendering', () => {
|
|||||||
expect(inputField).toBeTruthy();
|
expect(inputField).toBeTruthy();
|
||||||
expect(await field.getPrefixText()).toBe('$');
|
expect(await field.getPrefixText()).toBe('$');
|
||||||
|
|
||||||
const widgetLabel = testingUtils.getByCSS('.adf-label').nativeElement;
|
const widgetLabel = testingUtils.getByCSS('label.adf-label').nativeElement;
|
||||||
expect(widgetLabel.textContent.trim()).toBe('Test Amount*');
|
expect(widgetLabel.textContent.trim()).toBe('Test Amount*');
|
||||||
expect(widget.field.isValid).toBe(false);
|
expect(widget.field.isValid).toBe(false);
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ describe('AmountWidgetComponent - rendering', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
await fixture.whenStable();
|
await fixture.whenStable();
|
||||||
|
|
||||||
const widgetLabel = testingUtils.getByCSS('.adf-label').nativeElement;
|
const widgetLabel = testingUtils.getByCSS('label.adf-label').nativeElement;
|
||||||
expect(widgetLabel.textContent.trim()).toBe('Test Amount*');
|
expect(widgetLabel.textContent.trim()).toBe('Test Amount*');
|
||||||
|
|
||||||
const field = await testingUtils.getMatFormField();
|
const field = await testingUtils.getMatFormField();
|
||||||
|
@ -146,7 +146,7 @@ describe('FormFieldModel', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(field.options).toEqual([{ id: 'id_one', name: 'One' }]);
|
expect(field.options).toEqual([{ id: 'id_one', name: 'One' }]);
|
||||||
expect(field.value).toEqual({ id: 'id_one', name: 'One' });
|
expect(field.value).toEqual('id_one');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add value (selected options) to field options if NOT present (multiple selection)', () => {
|
it('should add value (selected options) to field options if NOT present (multiple selection)', () => {
|
||||||
@ -176,7 +176,7 @@ describe('FormFieldModel', () => {
|
|||||||
|
|
||||||
expect(field.hasEmptyValue).toBe(true);
|
expect(field.hasEmptyValue).toBe(true);
|
||||||
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Chose one...' });
|
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Chose one...' });
|
||||||
expect(field.value).toEqual({ id: 'empty', name: 'Chose one...' });
|
expect(field.value).toEqual('empty');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set hasEmptyValue to true if "empty" option is present in options', () => {
|
it('should set hasEmptyValue to true if "empty" option is present in options', () => {
|
||||||
@ -272,8 +272,7 @@ describe('FormFieldModel', () => {
|
|||||||
options: [],
|
options: [],
|
||||||
value: { id: 'delayed-option-id', name: 'Delayed option' }
|
value: { id: 'delayed-option-id', name: 'Delayed option' }
|
||||||
});
|
});
|
||||||
|
expect(field.value).toBe('delayed-option-id');
|
||||||
expect(field.value).toEqual({ id: 'delayed-option-id', name: 'Delayed option' });
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -771,7 +770,7 @@ describe('FormFieldModel', () => {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update form with selected option and options from which we chose when is a string', () => {
|
it('should update form with selected option and options from which we chose', () => {
|
||||||
field.value = 'restOpt2';
|
field.value = 'restOpt2';
|
||||||
field.updateForm();
|
field.updateForm();
|
||||||
|
|
||||||
@ -1024,7 +1023,7 @@ describe('FormFieldModel', () => {
|
|||||||
expect(field.options).toEqual(staticOptions);
|
expect(field.options).toEqual(staticOptions);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should selected option appear in form values string', () => {
|
it('should selected option appear in form values', () => {
|
||||||
const field = getFieldConfig('manual', staticOptions, 'opt2');
|
const field = getFieldConfig('manual', staticOptions, 'opt2');
|
||||||
|
|
||||||
field.updateForm();
|
field.updateForm();
|
||||||
@ -1032,15 +1031,6 @@ describe('FormFieldModel', () => {
|
|||||||
expect(field.value).toEqual('opt2');
|
expect(field.value).toEqual('opt2');
|
||||||
expect(field.form.values['dropdown_field']).toEqual({ id: 'opt2', name: 'Option 2' });
|
expect(field.form.values['dropdown_field']).toEqual({ id: 'opt2', name: 'Option 2' });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should selected option appear in form values obj', () => {
|
|
||||||
const field = getFieldConfig('manual', staticOptions, { id: 'opt3', name: 'opt3' });
|
|
||||||
|
|
||||||
field.updateForm();
|
|
||||||
|
|
||||||
expect(field.value).toEqual({ id: 'opt3', name: 'opt3' });
|
|
||||||
expect(field.form.values['dropdown_field']).toEqual({ id: 'opt3', name: 'opt3' });
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('radio buttons field', () => {
|
describe('radio buttons field', () => {
|
||||||
|
@ -331,13 +331,13 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
|
|
||||||
const isEmptyValue = !value || [this.emptyOption.id, this.emptyOption.name].includes(value);
|
const isEmptyValue = !value || [this.emptyOption.id, this.emptyOption.name].includes(value);
|
||||||
if (isEmptyValue) {
|
if (isEmptyValue) {
|
||||||
return this.emptyOption;
|
return this.emptyOption.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isValidOption(value)) {
|
if (this.isValidOption(value)) {
|
||||||
this.addOption({ id: value.id, name: value.name });
|
this.addOption({ id: value.id, name: value.name });
|
||||||
return value;
|
return value.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.hasMultipleValues) {
|
if (this.hasMultipleValues) {
|
||||||
@ -436,17 +436,6 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
|
|
||||||
this.form.values[this.id] = matchingOption || null;
|
this.form.values[this.id] = matchingOption || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof this.value === 'object') {
|
|
||||||
if (this.value.id === 'empty' || this.value.id === '') {
|
|
||||||
this.form.values[this.id] = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const matchingOption: FormFieldOption = this.options.find((opt) => opt.id === this.value.id);
|
|
||||||
|
|
||||||
this.form.values[this.id] = matchingOption;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FormFieldTypes.RADIO_BUTTONS: {
|
case FormFieldTypes.RADIO_BUTTONS: {
|
||||||
|
@ -358,7 +358,7 @@ export class FormModel implements ProcessFormModel {
|
|||||||
this.handleSectionField(field, formFieldModel);
|
this.handleSectionField(field, formFieldModel);
|
||||||
} else if (this.isContainerField(field)) {
|
} else if (this.isContainerField(field)) {
|
||||||
this.handleContainerField(field, formFieldModel);
|
this.handleContainerField(field, formFieldModel);
|
||||||
} else if (this.isFormField(field)) {
|
} else {
|
||||||
this.handleSingleField(field, formFieldModel);
|
this.handleSingleField(field, formFieldModel);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -368,10 +368,6 @@ export class FormModel implements ProcessFormModel {
|
|||||||
return field instanceof ContainerModel;
|
return field instanceof ContainerModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isFormField(field: ContainerModel | FormFieldModel): field is FormFieldModel {
|
|
||||||
return field instanceof FormFieldModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private isSectionField(field: ContainerModel | FormFieldModel): field is FormFieldModel {
|
private isSectionField(field: ContainerModel | FormFieldModel): field is FormFieldModel {
|
||||||
return field.type === FormFieldTypes.SECTION;
|
return field.type === FormFieldTypes.SECTION;
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
<mat-form-field class="adf-date-time-widget"
|
<mat-form-field class="adf-date-time-widget"
|
||||||
[class.adf-left-label-input-datepicker]="field.leftLabels"
|
[class.adf-left-label-input-datepicker]="field.leftLabels"
|
||||||
[hideRequiredMarker]="true">
|
[hideRequiredMarker]="true">
|
||||||
<mat-label class="adf-label" *ngIf="!field.leftLabels" [attr.for]="field.id">
|
<label class="adf-label" *ngIf="!field.leftLabels" [attr.for]="field.id">
|
||||||
{{ field.name | translate }} ({{ field.dateDisplayFormat }})<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span>
|
{{ field.name | translate }} ({{ field.dateDisplayFormat }})<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span>
|
||||||
</mat-label>
|
</label>
|
||||||
<input matInput
|
<input matInput
|
||||||
[matDatetimepicker]="datetimePicker"
|
[matDatetimepicker]="datetimePicker"
|
||||||
[id]="field.id"
|
[id]="field.id"
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<mat-form-field [hideRequiredMarker]="true">
|
<mat-form-field [hideRequiredMarker]="true">
|
||||||
<mat-label class="adf-label" *ngIf="!field.leftLabels" [attr.for]="field.id">
|
<label class="adf-label" *ngIf="!field.leftLabels" [attr.for]="field.id">
|
||||||
{{ field.name | translate }}<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span>
|
{{ field.name | translate }}<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span>
|
||||||
</mat-label>
|
</label>
|
||||||
|
|
||||||
<input matInput
|
<input matInput
|
||||||
class="adf-input"
|
class="adf-input"
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
[class.adf-invalid]="!field.isValid && isTouched()"
|
[class.adf-invalid]="!field.isValid && isTouched()"
|
||||||
[class.adf-readonly]="field.readOnly">
|
[class.adf-readonly]="field.readOnly">
|
||||||
<mat-form-field floatPlaceholder="never" [hideRequiredMarker]="true">
|
<mat-form-field floatPlaceholder="never" [hideRequiredMarker]="true">
|
||||||
<mat-label class="adf-label" [attr.for]="field.id">
|
<label class="adf-label" [attr.for]="field.id">
|
||||||
{{ field.name | translate }}<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span>
|
{{ field.name | translate }}<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span>
|
||||||
</mat-label>
|
</label>
|
||||||
<textarea matInput
|
<textarea matInput
|
||||||
class="adf-input"
|
class="adf-input"
|
||||||
[cdkTextareaAutosize]="true"
|
[cdkTextareaAutosize]="true"
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<mat-form-field [hideRequiredMarker]="true">
|
<mat-form-field [hideRequiredMarker]="true">
|
||||||
<mat-label class="adf-label" *ngIf="!field.leftLabels" [attr.for]="field.id">
|
<label class="adf-label" *ngIf="!field.leftLabels" [attr.for]="field.id">
|
||||||
{{ field.name | translate }}<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span>
|
{{ field.name | translate }}<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span>
|
||||||
</mat-label>
|
</label>
|
||||||
<input matInput
|
<input matInput
|
||||||
class="adf-input"
|
class="adf-input"
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<mat-form-field [hideRequiredMarker]="true">
|
<mat-form-field [hideRequiredMarker]="true">
|
||||||
<mat-label *ngIf="!field.leftLabels" class="adf-label" [attr.for]="field.id">
|
<label *ngIf="!field.leftLabels" class="adf-label" [attr.for]="field.id">
|
||||||
{{ field.name | translate }}<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span>
|
{{ field.name | translate }}<span class="adf-asterisk" [style.visibility]="isRequired() ? 'visible' : 'hidden'">*</span>
|
||||||
</mat-label>
|
</label>
|
||||||
<input matInput
|
<input matInput
|
||||||
class="adf-input"
|
class="adf-input"
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -23,7 +23,6 @@ export * from './components/form-renderer.component';
|
|||||||
export * from './components/widgets';
|
export * from './components/widgets';
|
||||||
export * from './components/middlewares/middleware';
|
export * from './components/middlewares/middleware';
|
||||||
export * from './components/middlewares/decimal-middleware.service';
|
export * from './components/middlewares/decimal-middleware.service';
|
||||||
export * from './components/helpers/buttons-visibility';
|
|
||||||
|
|
||||||
export * from './services/form-rendering.service';
|
export * from './services/form-rendering.service';
|
||||||
export * from './services/form.service';
|
export * from './services/form.service';
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
"COMPLETE": "Abschließen",
|
"COMPLETE": "Abschließen",
|
||||||
"CANCEL": "Abbrechen",
|
"CANCEL": "Abbrechen",
|
||||||
"CLAIM": "Beanspruchen",
|
"CLAIM": "Beanspruchen",
|
||||||
"UNCLAIM": "FREIGEBEN",
|
"UNCLAIM": "Anspruch aufheben",
|
||||||
"START PROCESS": "Prozess starten",
|
"START PROCESS": "Prozess starten",
|
||||||
"DATA_LOADING": "Daten werden geladen",
|
"DATA_LOADING": "Daten werden geladen",
|
||||||
"CLOSE": "Schließen",
|
"CLOSE": "Schließen",
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
"REST_API_FAILED": "No se puede acceder al servidor '{{ hostname }}'",
|
"REST_API_FAILED": "No se puede acceder al servidor '{{ hostname }}'",
|
||||||
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "Ha habido un problema al cargar elementos desplegables. Contacte con el administrador.",
|
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "Ha habido un problema al cargar elementos desplegables. Contacte con el administrador.",
|
||||||
"DATA_TABLE_LOAD_FAILED": "Ha habido un problema al cargar elementos de tabla. Contacte con el administrador.",
|
"DATA_TABLE_LOAD_FAILED": "Ha habido un problema al cargar elementos de tabla. Contacte con el administrador.",
|
||||||
"DATA_TABLE_EMPTY_CONTENT": "No se encontraron datos",
|
"DATA_TABLE_EMPTY_CONTENT": "No data found",
|
||||||
"EXTERNAL_PROPERTY_LOAD_FAILED": "Ha habido un problema al cargar una propiedad externa. Contacte con el administrador.",
|
"EXTERNAL_PROPERTY_LOAD_FAILED": "Ha habido un problema al cargar una propiedad externa. Contacte con el administrador.",
|
||||||
"FILE_NAME": "Nombre del fichero",
|
"FILE_NAME": "Nombre del fichero",
|
||||||
"TITLE": "Título",
|
"TITLE": "Título",
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
"REST_API_FAILED": "Le serveur '{{ hostname }}' n'est pas accessible",
|
"REST_API_FAILED": "Le serveur '{{ hostname }}' n'est pas accessible",
|
||||||
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "Un problème est survenu lors du chargement des éléments de la liste déroulante. Veuillez contacter un administrateur.",
|
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "Un problème est survenu lors du chargement des éléments de la liste déroulante. Veuillez contacter un administrateur.",
|
||||||
"DATA_TABLE_LOAD_FAILED": "Un problème est survenu lors du chargement des éléments du tableau. Veuillez contacter un administrateur.",
|
"DATA_TABLE_LOAD_FAILED": "Un problème est survenu lors du chargement des éléments du tableau. Veuillez contacter un administrateur.",
|
||||||
"DATA_TABLE_EMPTY_CONTENT": "Données introuvables",
|
"DATA_TABLE_EMPTY_CONTENT": "No data found",
|
||||||
"EXTERNAL_PROPERTY_LOAD_FAILED": "Un problème est survenu lors du chargement de la propriété externe. Veuillez contacter un administrateur.",
|
"EXTERNAL_PROPERTY_LOAD_FAILED": "Un problème est survenu lors du chargement de la propriété externe. Veuillez contacter un administrateur.",
|
||||||
"FILE_NAME": "Nom de fichier",
|
"FILE_NAME": "Nom de fichier",
|
||||||
"TITLE": "Titre",
|
"TITLE": "Titre",
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
"REST_API_FAILED": "Il server '{{ hostname }}' non è raggiungibile",
|
"REST_API_FAILED": "Il server '{{ hostname }}' non è raggiungibile",
|
||||||
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "Si è verificato un problema durante il caricamento degli elementi a discesa. Si prega di contattare l’amministratore.",
|
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "Si è verificato un problema durante il caricamento degli elementi a discesa. Si prega di contattare l’amministratore.",
|
||||||
"DATA_TABLE_LOAD_FAILED": "Si è verificato un problema durante il caricamento degli elementi della tabella. Si prega di contattare l’amministratore.",
|
"DATA_TABLE_LOAD_FAILED": "Si è verificato un problema durante il caricamento degli elementi della tabella. Si prega di contattare l’amministratore.",
|
||||||
"DATA_TABLE_EMPTY_CONTENT": "Nessun dato trovato",
|
"DATA_TABLE_EMPTY_CONTENT": "No data found",
|
||||||
"EXTERNAL_PROPERTY_LOAD_FAILED": "Si è verificato un problema durante il caricamento delle proprietà esterne. Si prega di contattare l’amministratore.",
|
"EXTERNAL_PROPERTY_LOAD_FAILED": "Si è verificato un problema durante il caricamento delle proprietà esterne. Si prega di contattare l’amministratore.",
|
||||||
"FILE_NAME": "Nome file",
|
"FILE_NAME": "Nome file",
|
||||||
"TITLE": "Titolo",
|
"TITLE": "Titolo",
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
"REST_API_FAILED": "Serwer '{{ hostname }}' jest nieosiągalny",
|
"REST_API_FAILED": "Serwer '{{ hostname }}' jest nieosiągalny",
|
||||||
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "Wystąpił problem podczas ładowania elementów rozwijania. Skontaktuj się z administratorem.",
|
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "Wystąpił problem podczas ładowania elementów rozwijania. Skontaktuj się z administratorem.",
|
||||||
"DATA_TABLE_LOAD_FAILED": "Wystąpił problem podczas ładowania elementów tabeli. Skontaktuj się z administratorem.",
|
"DATA_TABLE_LOAD_FAILED": "Wystąpił problem podczas ładowania elementów tabeli. Skontaktuj się z administratorem.",
|
||||||
"DATA_TABLE_EMPTY_CONTENT": "Brak danych",
|
"DATA_TABLE_EMPTY_CONTENT": "No data found",
|
||||||
"EXTERNAL_PROPERTY_LOAD_FAILED": "Wystąpił problem podczas ładowania właściwości zewnętrznej. Skontaktuj się z administratorem.",
|
"EXTERNAL_PROPERTY_LOAD_FAILED": "Wystąpił problem podczas ładowania właściwości zewnętrznej. Skontaktuj się z administratorem.",
|
||||||
"FILE_NAME": "Nazwa pliku",
|
"FILE_NAME": "Nazwa pliku",
|
||||||
"TITLE": "Tytuł",
|
"TITLE": "Tytuł",
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
"REST_API_FAILED": "O servidor `{{ hostname }}` não pode ser acedido",
|
"REST_API_FAILED": "O servidor `{{ hostname }}` não pode ser acedido",
|
||||||
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "Problema ao carregar elementos suspensos. Entre em contacto com o administrador.",
|
"VARIABLE_DROPDOWN_OPTIONS_FAILED": "Problema ao carregar elementos suspensos. Entre em contacto com o administrador.",
|
||||||
"DATA_TABLE_LOAD_FAILED": "Problema ao carregar os elementos da tabela. Entre em contacto com o administrador.",
|
"DATA_TABLE_LOAD_FAILED": "Problema ao carregar os elementos da tabela. Entre em contacto com o administrador.",
|
||||||
"DATA_TABLE_EMPTY_CONTENT": "Não foram encontrados dados",
|
"DATA_TABLE_EMPTY_CONTENT": "No data found",
|
||||||
"EXTERNAL_PROPERTY_LOAD_FAILED": "Houve um problema ao carregar a propriedade externa. Entre em contacto com o administrador.",
|
"EXTERNAL_PROPERTY_LOAD_FAILED": "Houve um problema ao carregar a propriedade externa. Entre em contacto com o administrador.",
|
||||||
"FILE_NAME": "Nome do ficheiro",
|
"FILE_NAME": "Nome do ficheiro",
|
||||||
"TITLE": "Título",
|
"TITLE": "Título",
|
||||||
|
@ -26,70 +26,70 @@
|
|||||||
// map SCSS variables to expose as CSS variables
|
// map SCSS variables to expose as CSS variables
|
||||||
$defaults: (
|
$defaults: (
|
||||||
// theme colors
|
// theme colors
|
||||||
--theme-primary-color: mat.m2-get-color-from-palette($primary),
|
--theme-primary-color: mat.get-color-from-palette($primary),
|
||||||
--theme-primary-color-default-contrast: mat.m2-get-color-from-palette($primary, default-contrast),
|
--theme-primary-color-default-contrast: mat.get-color-from-palette($primary, default-contrast),
|
||||||
--theme-header-text-color: mat.m2-get-color-from-palette($primary, default-contrast),
|
--theme-header-text-color: mat.get-color-from-palette($primary, default-contrast),
|
||||||
--adf-theme-primary-50: mat.m2-get-color-from-palette($primary, 50),
|
--adf-theme-primary-50: mat.get-color-from-palette($primary, 50),
|
||||||
--adf-theme-primary-100: mat.m2-get-color-from-palette($primary, 100),
|
--adf-theme-primary-100: mat.get-color-from-palette($primary, 100),
|
||||||
--adf-theme-primary-300: mat.m2-get-color-from-palette($primary, 300),
|
--adf-theme-primary-300: mat.get-color-from-palette($primary, 300),
|
||||||
--adf-theme-primary-900: mat.m2-get-color-from-palette($primary, 900),
|
--adf-theme-primary-900: mat.get-color-from-palette($primary, 900),
|
||||||
--theme-warn-color: mat.m2-get-color-from-palette($warn),
|
--theme-warn-color: mat.get-color-from-palette($warn),
|
||||||
--theme-warn-color-a700: mat.m2-get-color-from-palette($warn, A700),
|
--theme-warn-color-a700: mat.get-color-from-palette($warn, A700),
|
||||||
--theme-warn-color-default-contrast: mat.m2-get-color-from-palette($warn, default-contrast),
|
--theme-warn-color-default-contrast: mat.get-color-from-palette($warn, default-contrast),
|
||||||
--theme-accent-color: mat.m2-get-color-from-palette($accent),
|
--theme-accent-color: mat.get-color-from-palette($accent),
|
||||||
--theme-accent-color-a200: mat.m2-get-color-from-palette($accent, A200),
|
--theme-accent-color-a200: mat.get-color-from-palette($accent, A200),
|
||||||
--theme-accent-color-default-contrast: mat.m2-get-color-from-palette($accent, default-contrast),
|
--theme-accent-color-default-contrast: mat.get-color-from-palette($accent, default-contrast),
|
||||||
--theme-accent-500: mat.m2-get-color-from-palette($accent, 500),
|
--theme-accent-500: mat.get-color-from-palette($accent, 500),
|
||||||
--adf-theme-foreground-base-color: mat.m2-get-color-from-palette($foreground, base),
|
--adf-theme-foreground-base-color: mat.get-color-from-palette($foreground, base),
|
||||||
--adf-theme-foreground-base-color-065: mat.m2-get-color-from-palette($foreground, base, 0.65),
|
--adf-theme-foreground-base-color-065: mat.get-color-from-palette($foreground, base, 0.65),
|
||||||
--adf-theme-foreground-base-color-045: mat.m2-get-color-from-palette($foreground, base, 0.45),
|
--adf-theme-foreground-base-color-045: mat.get-color-from-palette($foreground, base, 0.45),
|
||||||
--adf-theme-foreground-disabled-text-color: mat.m2-get-color-from-palette($foreground, disabled-text),
|
--adf-theme-foreground-disabled-text-color: mat.get-color-from-palette($foreground, disabled-text),
|
||||||
--adf-theme-foreground-divider-color: mat.m2-get-color-from-palette($foreground, divider),
|
--adf-theme-foreground-divider-color: mat.get-color-from-palette($foreground, divider),
|
||||||
--adf-theme-foreground-icon-color: mat.m2-get-color-from-palette($foreground, icon),
|
--adf-theme-foreground-icon-color: mat.get-color-from-palette($foreground, icon),
|
||||||
--adf-theme-foreground-icon-color-054: mat.m2-get-color-from-palette($foreground, icon, 0.54),
|
--adf-theme-foreground-icon-color-054: mat.get-color-from-palette($foreground, icon, 0.54),
|
||||||
--adf-theme-foreground-secondary-text-color: mat.m2-get-color-from-palette($foreground, secondary-text),
|
--adf-theme-foreground-secondary-text-color: mat.get-color-from-palette($foreground, secondary-text),
|
||||||
--adf-theme-foreground-text-color: mat.m2-get-color-from-palette($foreground, text),
|
--adf-theme-foreground-text-color: mat.get-color-from-palette($foreground, text),
|
||||||
--adf-theme-foreground-text-color-087: mat.m2-get-color-from-palette($foreground, text, 0.87),
|
--adf-theme-foreground-text-color-087: mat.get-color-from-palette($foreground, text, 0.87),
|
||||||
--adf-theme-foreground-text-color-075: mat.m2-get-color-from-palette($foreground, text, 0.75),
|
--adf-theme-foreground-text-color-075: mat.get-color-from-palette($foreground, text, 0.75),
|
||||||
--adf-theme-foreground-text-color-064: mat.m2-get-color-from-palette($foreground, text, 0.64),
|
--adf-theme-foreground-text-color-064: mat.get-color-from-palette($foreground, text, 0.64),
|
||||||
--adf-theme-foreground-text-color-054: mat.m2-get-color-from-palette($foreground, text, 0.54),
|
--adf-theme-foreground-text-color-054: mat.get-color-from-palette($foreground, text, 0.54),
|
||||||
--adf-theme-foreground-text-color-040: mat.m2-get-color-from-palette($foreground, text, 0.4),
|
--adf-theme-foreground-text-color-040: mat.get-color-from-palette($foreground, text, 0.4),
|
||||||
--adf-theme-foreground-text-color-027: mat.m2-get-color-from-palette($foreground, text, 0.27),
|
--adf-theme-foreground-text-color-027: mat.get-color-from-palette($foreground, text, 0.27),
|
||||||
--adf-theme-foreground-text-color-025: mat.m2-get-color-from-palette($foreground, text, 0.25),
|
--adf-theme-foreground-text-color-025: mat.get-color-from-palette($foreground, text, 0.25),
|
||||||
--adf-theme-foreground-text-color-014: mat.m2-get-color-from-palette($foreground, text, 0.14),
|
--adf-theme-foreground-text-color-014: mat.get-color-from-palette($foreground, text, 0.14),
|
||||||
--adf-theme-foreground-text-color-007: mat.m2-get-color-from-palette($foreground, text, 0.07),
|
--adf-theme-foreground-text-color-007: mat.get-color-from-palette($foreground, text, 0.07),
|
||||||
--adf-theme-background-card-color: mat.m2-get-color-from-palette($background, card),
|
--adf-theme-background-card-color: mat.get-color-from-palette($background, card),
|
||||||
--adf-theme-background-card-color-087: mat.m2-get-color-from-palette($background, card, 0.87),
|
--adf-theme-background-card-color-087: mat.get-color-from-palette($background, card, 0.87),
|
||||||
--theme-background-color: mat.m2-get-color-from-palette($background, background),
|
--theme-background-color: mat.get-color-from-palette($background, background),
|
||||||
--adf-theme-background-dialog-color: mat.m2-get-color-from-palette($background, dialog),
|
--adf-theme-background-dialog-color: mat.get-color-from-palette($background, dialog),
|
||||||
--adf-theme-background-hover-color: mat.m2-get-color-from-palette($background, hover),
|
--adf-theme-background-hover-color: mat.get-color-from-palette($background, hover),
|
||||||
--adf-theme-background-selected-button-color: mat.m2-get-color-from-palette($background, selected-button),
|
--adf-theme-background-selected-button-color: mat.get-color-from-palette($background, selected-button),
|
||||||
--adf-theme-background-status-bar-color: mat.m2-get-color-from-palette($background, status-bar),
|
--adf-theme-background-status-bar-color: mat.get-color-from-palette($background, status-bar),
|
||||||
--adf-theme-background-unselected-chip-color: mat.m2-get-color-from-palette($background, unselected-chip),
|
--adf-theme-background-unselected-chip-color: mat.get-color-from-palette($background, unselected-chip),
|
||||||
// typography
|
// typography
|
||||||
--theme-font-family: mat.m2-font-family($typography),
|
--theme-font-family: mat.font-family($typography),
|
||||||
--theme-font-weight: normal,
|
--theme-font-weight: normal,
|
||||||
--theme-body-1-font-size: mat.m2-font-size($typography, body-2),
|
--theme-body-1-font-size: mat.font-size($typography, body-2),
|
||||||
--theme-body-2-font-size: mat.m2-font-size($typography, subtitle-2),
|
--theme-body-2-font-size: mat.font-size($typography, subtitle-2),
|
||||||
--theme-body-1-line-height: mat.m2-line-height($typography, body-2),
|
--theme-body-1-line-height: mat.line-height($typography, body-2),
|
||||||
--theme-display-1-font-size: mat.m2-font-size($typography, headline-4),
|
--theme-display-1-font-size: mat.font-size($typography, headline-4),
|
||||||
--theme-display-3-font-size: mat.m2-font-size($typography, headline-2),
|
--theme-display-3-font-size: mat.font-size($typography, headline-2),
|
||||||
--theme-display-4-font-size: mat.m2-font-size($typography, headline-1),
|
--theme-display-4-font-size: mat.font-size($typography, headline-1),
|
||||||
--theme-caption-font-size: mat.m2-font-size($typography, caption),
|
--theme-caption-font-size: mat.font-size($typography, caption),
|
||||||
--theme-title-font-size: mat.m2-font-size($typography, headline-6),
|
--theme-title-font-size: mat.font-size($typography, headline-6),
|
||||||
--theme-subheading-1-font-size: mat.m2-font-size($typography, body-1),
|
--theme-subheading-1-font-size: mat.font-size($typography, body-1),
|
||||||
--theme-subheading-2-font-size: mat.m2-font-size($typography, subtitle-1),
|
--theme-subheading-2-font-size: mat.font-size($typography, subtitle-1),
|
||||||
--theme-button-font-size: mat.m2-font-size($typography, button),
|
--theme-button-font-size: mat.font-size($typography, button),
|
||||||
--theme-headline-font-size: mat.m2-font-size($typography, headline-5),
|
--theme-headline-font-size: mat.font-size($typography, headline-5),
|
||||||
--theme-headline-line-height: mat.m2-line-height($typography, headline-5),
|
--theme-headline-line-height: mat.line-height($typography, headline-5),
|
||||||
--theme-adf-icon-1-font-size: map-get($custom-css-variables, 'theme-adf-icon-1-font-size'),
|
--theme-adf-icon-1-font-size: map-get($custom-css-variables, 'theme-adf-icon-1-font-size'),
|
||||||
--theme-adf-picture-1-font-size: map-get($custom-css-variables, 'theme-adf-picture-1-font-size'),
|
--theme-adf-picture-1-font-size: map-get($custom-css-variables, 'theme-adf-picture-1-font-size'),
|
||||||
--theme-adf-task-footer-font-size: map-get($custom-css-variables, 'theme-adf-task-footer-font-size'),
|
--theme-adf-task-footer-font-size: map-get($custom-css-variables, 'theme-adf-task-footer-font-size'),
|
||||||
--theme-adf-task-title-font-size: map-get($custom-css-variables, 'theme-adf-task-title-font-size'),
|
--theme-adf-task-title-font-size: map-get($custom-css-variables, 'theme-adf-task-title-font-size'),
|
||||||
// specific colors
|
// specific colors
|
||||||
--adf-theme-mat-grey-color-a200: mat.m2-get-color-from-palette(mat.$m2-grey-palette, 'A200'),
|
--adf-theme-mat-grey-color-a200: mat.get-color-from-palette(mat.$grey-palette, A200),
|
||||||
--adf-theme-mat-grey-color-a400: mat.m2-get-color-from-palette(mat.$m2-grey-palette, 'A400'),
|
--adf-theme-mat-grey-color-a400: mat.get-color-from-palette(mat.$grey-palette, A400),
|
||||||
--adf-theme-mat-grey-color-50: mat.m2-get-color-from-palette(mat.$m2-grey-palette, 50),
|
--adf-theme-mat-grey-color-50: mat.get-color-from-palette(mat.$grey-palette, 50),
|
||||||
// spacing
|
// spacing
|
||||||
--adf-theme-spacing: map-get($custom-css-variables, 'theme-adf-spacing'),
|
--adf-theme-spacing: map-get($custom-css-variables, 'theme-adf-spacing'),
|
||||||
// components
|
// components
|
||||||
|
@ -6,11 +6,8 @@ $mat-tab-label-active: '.mdc-tab--active';
|
|||||||
$mat-tab-label-container: '.mat-mdc-tab-label-container';
|
$mat-tab-label-container: '.mat-mdc-tab-label-container';
|
||||||
$mat-tab-label-text: '.mdc-tab__text-label';
|
$mat-tab-label-text: '.mdc-tab__text-label';
|
||||||
$mat-tab-body: '.mat-mdc-tab-body';
|
$mat-tab-body: '.mat-mdc-tab-body';
|
||||||
$mat-tab-header: '.mat-mdc-tab-header';
|
|
||||||
$mat-tab-body-content: '.mat-mdc-tab-body-content';
|
$mat-tab-body-content: '.mat-mdc-tab-body-content';
|
||||||
$mat-tab-ink-bar: '.mdc-tab-indicator';
|
$mat-tab-ink-bar: '.mdc-tab-indicator';
|
||||||
$mat-tab-body-wrapper: '.mat-mdc-tab-body-wrapper';
|
|
||||||
$mat-tab-body-content: '.mat-mdc-card-content';
|
|
||||||
$mat-chip: '.mat-mdc-chip';
|
$mat-chip: '.mat-mdc-chip';
|
||||||
$mat-chip-list: '.mat-mdc-chip-list';
|
$mat-chip-list: '.mat-mdc-chip-list';
|
||||||
$mat-checkbox: '.mat-mdc-checkbox';
|
$mat-checkbox: '.mat-mdc-checkbox';
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
@use '@angular/material' as mat;
|
@use '@angular/material' as mat;
|
||||||
|
|
||||||
$alfresco-typography: mat.m2-define-typography-config(
|
$alfresco-typography: mat.define-typography-config(
|
||||||
$font-family: 'Roboto, "Helvetica Neue", sans-serif',
|
$font-family: 'Roboto, "Helvetica Neue", sans-serif',
|
||||||
$headline-1: mat.m2-define-typography-level(112px, 112px, 300),
|
$headline-1: mat.define-typography-level(112px, 112px, 300),
|
||||||
$headline-2: mat.m2-define-typography-level(56px, 56px, 400),
|
$headline-2: mat.define-typography-level(56px, 56px, 400),
|
||||||
$headline-3: mat.m2-define-typography-level(45px, 48px, 400),
|
$headline-3: mat.define-typography-level(45px, 48px, 400),
|
||||||
$headline-4: mat.m2-define-typography-level(34px, 40px, 400),
|
$headline-4: mat.define-typography-level(34px, 40px, 400),
|
||||||
$headline-5: mat.m2-define-typography-level(24px, 32px, 400),
|
$headline-5: mat.define-typography-level(24px, 32px, 400),
|
||||||
$headline-6: mat.m2-define-typography-level(20px, 32px, 500),
|
$headline-6: mat.define-typography-level(20px, 32px, 500),
|
||||||
$subtitle-1: mat.m2-define-typography-level(16px, 28px, 400),
|
$subtitle-1: mat.define-typography-level(16px, 28px, 400),
|
||||||
$body-1: mat.m2-define-typography-level(15px, 24px, 400),
|
$body-1: mat.define-typography-level(15px, 24px, 400),
|
||||||
$subtitle-2: mat.m2-define-typography-level(14px, 24px, 500),
|
$subtitle-2: mat.define-typography-level(14px, 24px, 500),
|
||||||
$body-2: mat.m2-define-typography-level(14px, 20px, 400),
|
$body-2: mat.define-typography-level(14px, 20px, 400),
|
||||||
$caption: mat.m2-define-typography-level(12px, 20px, 400),
|
$caption: mat.define-typography-level(12px, 20px, 400),
|
||||||
$button: mat.m2-define-typography-level(14px, 14px, 500),
|
$button: mat.define-typography-level(14px, 14px, 500),
|
||||||
// Line-height must be unit-less fraction of the font-size.
|
// Line-height must be unit-less fraction of the font-size.
|
||||||
);
|
);
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
class="adf-viewer-pdf-viewer"
|
class="adf-viewer-pdf-viewer"
|
||||||
(window:resize)="onResize()">
|
(window:resize)="onResize()">
|
||||||
<div [id]="randomPdfId + '-viewer-viewerPdf'"
|
<div [id]="randomPdfId + '-viewer-viewerPdf'"
|
||||||
class="adf-pdfViewer pdfViewer"
|
class="adf-pdfViewer"
|
||||||
role="document"
|
role="document"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
aria-expanded="true">
|
aria-expanded="true">
|
||||||
|
@ -114,7 +114,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
|
|||||||
displayPage: number;
|
displayPage: number;
|
||||||
totalPages: number;
|
totalPages: number;
|
||||||
loadingPercent: number;
|
loadingPercent: number;
|
||||||
pdfViewer: PDFViewer;
|
pdfViewer: any;
|
||||||
pdfJsWorkerUrl: string;
|
pdfJsWorkerUrl: string;
|
||||||
pdfJsWorkerInstance: Worker;
|
pdfJsWorkerInstance: Worker;
|
||||||
currentScaleMode: PdfScaleMode = 'init';
|
currentScaleMode: PdfScaleMode = 'init';
|
||||||
@ -132,12 +132,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
|
|||||||
documentOverflow = false;
|
documentOverflow = false;
|
||||||
|
|
||||||
get currentScaleText(): string {
|
get currentScaleText(): string {
|
||||||
const currentScaleValueStr = this.pdfViewer?.currentScaleValue;
|
return this.pdfViewer?.currentScaleValue ? Math.round(this.pdfViewer.currentScaleValue * 100) + '%' : '';
|
||||||
const scaleNumber = Number(currentScaleValueStr);
|
|
||||||
|
|
||||||
const currentScaleText = scaleNumber ? `${Math.round(scaleNumber * 100)}%` : '';
|
|
||||||
|
|
||||||
return currentScaleText;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private pdfjsLib = inject(PDFJS_MODULE);
|
private pdfjsLib = inject(PDFJS_MODULE);
|
||||||
@ -457,9 +452,10 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
setScaleUpdatePages(newScale: number) {
|
setScaleUpdatePages(newScale: number) {
|
||||||
if (this.pdfViewer) {
|
if (this.pdfViewer) {
|
||||||
if (!this.isSameScale(this.pdfViewer.currentScaleValue, newScale.toString())) {
|
if (!this.isSameScale(this.pdfViewer.currentScaleValue, newScale)) {
|
||||||
this.pdfViewer.currentScaleValue = newScale.toString();
|
this.pdfViewer.currentScaleValue = newScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pdfViewer.update();
|
this.pdfViewer.update();
|
||||||
}
|
}
|
||||||
this.setDocumentOverflow();
|
this.setDocumentOverflow();
|
||||||
@ -472,7 +468,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
|
|||||||
* @param newScale - new scale page
|
* @param newScale - new scale page
|
||||||
* @returns `true` if the scale is the same, otherwise `false`
|
* @returns `true` if the scale is the same, otherwise `false`
|
||||||
*/
|
*/
|
||||||
isSameScale(oldScale: string, newScale: string): boolean {
|
isSameScale(oldScale: number, newScale: number): boolean {
|
||||||
return newScale === oldScale;
|
return newScale === oldScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,105 +1,95 @@
|
|||||||
<div *ngIf="isLoading$ | async" class="adf-viewer-render-main-loader">
|
<div *ngIf="(viewerType === 'media' || viewerType === 'pdf' || viewerType === 'image') ? isLoading || !isContentReady : isLoading"
|
||||||
|
class="adf-viewer-render-main-loader">
|
||||||
<div class="adf-viewer-render-layout-content adf-viewer__fullscreen-container">
|
<div class="adf-viewer-render-layout-content adf-viewer__fullscreen-container">
|
||||||
<div class="adf-viewer-render-content-container">
|
<div class="adf-viewer-render-content-container">
|
||||||
<div class="adf-viewer-render__loading-screen">
|
<div class="adf-viewer-render__loading-screen ">
|
||||||
<h2>{{ 'ADF_VIEWER.LOADING' | translate }}</h2>
|
<h2>{{ 'ADF_VIEWER.LOADING' | translate }}</h2>
|
||||||
<div>
|
<div>
|
||||||
<mat-spinner class="adf-viewer-render__loading-screen__spinner" />
|
<mat-spinner class="adf-viewer-render__loading-screen__spinner"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-container *ngIf="urlFile || blobFile">
|
<div *ngIf="!isLoading"
|
||||||
<div [hidden]="isLoading$ | async" class="adf-viewer-render-main">
|
class="adf-viewer-render-main">
|
||||||
<div class="adf-viewer-render-layout-content adf-viewer__fullscreen-container">
|
<div class="adf-viewer-render-layout-content adf-viewer__fullscreen-container">
|
||||||
<div class="adf-viewer-render-content-container" [ngSwitch]="viewerType">
|
<div class="adf-viewer-render-content-container" [ngSwitch]="viewerType">
|
||||||
<ng-container *ngSwitchCase="'external'">
|
<ng-container *ngSwitchCase="'external'">
|
||||||
<adf-preview-extension
|
<adf-preview-extension *ngIf="!!externalViewer"
|
||||||
*ngIf="!!externalViewer"
|
[id]="externalViewer.component"
|
||||||
[id]="externalViewer.component"
|
[url]="urlFile"
|
||||||
[url]="urlFile"
|
[extension]="externalViewer.fileExtension"
|
||||||
[extension]="externalViewer.fileExtension"
|
[nodeId]="nodeId"
|
||||||
[nodeId]="nodeId"
|
[attr.data-automation-id]="externalViewer.component" />
|
||||||
[attr.data-automation-id]="externalViewer.component"
|
</ng-container>
|
||||||
/>
|
|
||||||
|
<ng-container *ngSwitchCase="'pdf'">
|
||||||
|
<adf-pdf-viewer [thumbnailsTemplate]="thumbnailsTemplate"
|
||||||
|
[allowThumbnails]="allowThumbnails"
|
||||||
|
[blobFile]="blobFile"
|
||||||
|
[urlFile]="urlFile"
|
||||||
|
[fileName]="internalFileName"
|
||||||
|
[cacheType]="cacheTypeForContent"
|
||||||
|
(pagesLoaded)="isContentReady = true"
|
||||||
|
(close)="onClose()"
|
||||||
|
(error)="onUnsupportedFile()" />
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngSwitchCase="'image'">
|
||||||
|
<adf-img-viewer [urlFile]="urlFile"
|
||||||
|
[readOnly]="readOnly"
|
||||||
|
[fileName]="internalFileName"
|
||||||
|
[allowedEditActions]="allowedEditActions"
|
||||||
|
[blobFile]="blobFile"
|
||||||
|
(error)="onUnsupportedFile()"
|
||||||
|
(submit)="onSubmitFile($event)"
|
||||||
|
(imageLoaded)="isContentReady = true"
|
||||||
|
(isSaving)="isSaving.emit($event)"
|
||||||
|
/>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngSwitchCase="'media'">
|
||||||
|
<adf-media-player id="adf-mdedia-player"
|
||||||
|
[urlFile]="urlFile"
|
||||||
|
[tracks]="tracks"
|
||||||
|
[mimeType]="mimeType"
|
||||||
|
[blobFile]="blobFile"
|
||||||
|
[fileName]="internalFileName"
|
||||||
|
(error)="onUnsupportedFile()"
|
||||||
|
(canPlay)="isContentReady = true"/>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngSwitchCase="'text'">
|
||||||
|
<adf-txt-viewer [urlFile]="urlFile"
|
||||||
|
[blobFile]="blobFile" />
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngSwitchCase="'custom'">
|
||||||
|
<ng-container *ngFor="let ext of viewerExtensions">
|
||||||
|
<adf-preview-extension *ngIf="checkExtensions(ext.fileExtension)"
|
||||||
|
[id]="ext.component"
|
||||||
|
[url]="urlFile"
|
||||||
|
[extension]="extension"
|
||||||
|
[nodeId]="nodeId"
|
||||||
|
[attr.data-automation-id]="ext.component" />
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngSwitchCase="'pdf'">
|
<ng-container *ngFor="let extensionTemplate of extensionTemplates">
|
||||||
<adf-pdf-viewer
|
<span *ngIf="extensionTemplate.isVisible" class="adf-viewer-render-custom-content">
|
||||||
[thumbnailsTemplate]="thumbnailsTemplate"
|
<ng-template [ngTemplateOutlet]="extensionTemplate.template"
|
||||||
[allowThumbnails]="allowThumbnails"
|
[ngTemplateOutletContext]="{ urlFile: urlFile, extension: extension }" />
|
||||||
[blobFile]="blobFile"
|
</span>
|
||||||
[urlFile]="urlFile"
|
|
||||||
[fileName]="internalFileName"
|
|
||||||
[cacheType]="cacheTypeForContent"
|
|
||||||
(pagesLoaded)="markAsLoaded()"
|
|
||||||
(close)="onClose()"
|
|
||||||
(error)="onUnsupportedFile()"
|
|
||||||
/>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngSwitchCase="'image'">
|
<ng-container *ngSwitchDefault>
|
||||||
<adf-img-viewer
|
<adf-viewer-unknown-format [customError]="customError"/>
|
||||||
[urlFile]="urlFile"
|
</ng-container>
|
||||||
[readOnly]="readOnly"
|
|
||||||
[fileName]="internalFileName"
|
|
||||||
[allowedEditActions]="allowedEditActions"
|
|
||||||
[blobFile]="blobFile"
|
|
||||||
(error)="onUnsupportedFile()"
|
|
||||||
(submit)="onSubmitFile($event)"
|
|
||||||
(imageLoaded)="markAsLoaded()"
|
|
||||||
(isSaving)="isSaving.emit($event)"
|
|
||||||
/>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container *ngSwitchCase="'media'">
|
|
||||||
<adf-media-player
|
|
||||||
id="adf-mdedia-player"
|
|
||||||
[urlFile]="urlFile"
|
|
||||||
[tracks]="tracks"
|
|
||||||
[mimeType]="mimeType"
|
|
||||||
[blobFile]="blobFile"
|
|
||||||
[fileName]="internalFileName"
|
|
||||||
(error)="onUnsupportedFile()"
|
|
||||||
(canPlay)="markAsLoaded()"
|
|
||||||
/>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container *ngSwitchCase="'text'">
|
|
||||||
<adf-txt-viewer [urlFile]="urlFile" [blobFile]="blobFile" />
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container *ngSwitchCase="'custom'">
|
|
||||||
<ng-container *ngFor="let ext of viewerExtensions">
|
|
||||||
<adf-preview-extension
|
|
||||||
*ngIf="checkExtensions(ext.fileExtension)"
|
|
||||||
[id]="ext.component"
|
|
||||||
[url]="urlFile"
|
|
||||||
[extension]="extension"
|
|
||||||
[nodeId]="nodeId"
|
|
||||||
[attr.data-automation-id]="ext.component"
|
|
||||||
/>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container *ngFor="let extensionTemplate of extensionTemplates">
|
|
||||||
<span *ngIf="extensionTemplate.isVisible" class="adf-viewer-render-custom-content">
|
|
||||||
<ng-template
|
|
||||||
[ngTemplateOutlet]="extensionTemplate.template"
|
|
||||||
[ngTemplateOutletContext]="{ urlFile: urlFile, extension: extension }"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</ng-container>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container *ngSwitchDefault>
|
|
||||||
<adf-viewer-unknown-format [customError]="customError" />
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</div>
|
||||||
<ng-container *ngIf="viewerTemplateExtensions">
|
<ng-container *ngIf="viewerTemplateExtensions">
|
||||||
<ng-template [ngTemplateOutlet]="viewerTemplateExtensions" [ngTemplateOutletInjector]="injector" />
|
<ng-template [ngTemplateOutlet]="viewerTemplateExtensions" [ngTemplateOutletInjector]="injector" />
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -24,7 +24,7 @@ import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
|||||||
import { NoopTranslateModule, UnitTestingUtils } from '../../../testing';
|
import { NoopTranslateModule, UnitTestingUtils } from '../../../testing';
|
||||||
import { RenderingQueueServices } from '../../services/rendering-queue.services';
|
import { RenderingQueueServices } from '../../services/rendering-queue.services';
|
||||||
import { ViewerRenderComponent } from './viewer-render.component';
|
import { ViewerRenderComponent } from './viewer-render.component';
|
||||||
import { ImgViewerComponent, MediaPlayerComponent, PdfViewerComponent, ViewerExtensionDirective } from '@alfresco/adf-core';
|
import { ImgViewerComponent, MediaPlayerComponent, ViewerExtensionDirective } from '@alfresco/adf-core';
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -483,16 +483,14 @@ describe('ViewerComponent', () => {
|
|||||||
describe('Spinner', () => {
|
describe('Spinner', () => {
|
||||||
const getMainLoader = (): DebugElement => testingUtils.getByCSS('.adf-viewer-render-main-loader');
|
const getMainLoader = (): DebugElement => testingUtils.getByCSS('.adf-viewer-render-main-loader');
|
||||||
|
|
||||||
it('should not show spinner by default', (done) => {
|
it('should show spinner when isLoading is true', () => {
|
||||||
component.isLoading$.subscribe((isLoading) => {
|
component.isLoading = true;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(isLoading).toBeFalse();
|
expect(getMainLoader()).not.toBeNull();
|
||||||
expect(getMainLoader()).toBeNull();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display spinner when viewerType is media', () => {
|
it('should show spinner until content is ready when viewerType is media', () => {
|
||||||
|
component.isLoading = false;
|
||||||
component.urlFile = 'some-file.mp4';
|
component.urlFile = 'some-file.mp4';
|
||||||
|
|
||||||
component.ngOnChanges();
|
component.ngOnChanges();
|
||||||
@ -508,21 +506,24 @@ describe('ViewerComponent', () => {
|
|||||||
expect(component.viewerType).toBe('media');
|
expect(component.viewerType).toBe('media');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display spinner when viewerType is pdf', () => {
|
// eslint-disable-next-line ban/ban
|
||||||
|
xit('should show spinner until content is ready when viewerType is pdf', () => {
|
||||||
|
component.isLoading = false;
|
||||||
component.urlFile = 'some-url.pdf';
|
component.urlFile = 'some-url.pdf';
|
||||||
expect(getMainLoader()).toBeNull();
|
|
||||||
|
|
||||||
component.ngOnChanges();
|
component.ngOnChanges();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const imgViewer = testingUtils.getByDirective(PdfViewerComponent);
|
expect(getMainLoader()).not.toBeNull();
|
||||||
imgViewer.triggerEventHandler('pagesLoaded', null);
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getMainLoader()).toBeNull();
|
||||||
expect(component.viewerType).toBe('pdf');
|
expect(component.viewerType).toBe('pdf');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display spinner when viewerType is image', () => {
|
it('should show spinner until content is ready when viewerType is image', () => {
|
||||||
|
component.isLoading = false;
|
||||||
component.urlFile = 'some-url.png';
|
component.urlFile = 'some-url.png';
|
||||||
|
|
||||||
component.ngOnChanges();
|
component.ngOnChanges();
|
||||||
@ -536,5 +537,16 @@ describe('ViewerComponent', () => {
|
|||||||
expect(getMainLoader()).toBeNull();
|
expect(getMainLoader()).toBeNull();
|
||||||
expect(component.viewerType).toBe('image');
|
expect(component.viewerType).toBe('image');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not show spinner when isLoading = false and isContentReady = false for other viewer types', () => {
|
||||||
|
component.isLoading = false;
|
||||||
|
component.urlFile = 'some-url.txt';
|
||||||
|
|
||||||
|
component.ngOnChanges();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getMainLoader()).toBeNull();
|
||||||
|
expect(component.isContentReady).toBeFalse();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { AppExtensionService, ExtensionsModule, ViewerExtensionRef } from '@alfresco/adf-extensions';
|
import { AppExtensionService, ExtensionsModule, ViewerExtensionRef } from '@alfresco/adf-extensions';
|
||||||
import { AsyncPipe, NgForOf, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet } from '@angular/common';
|
import { NgForOf, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet } from '@angular/common';
|
||||||
import { Component, EventEmitter, Injector, Input, OnChanges, OnInit, Output, TemplateRef, ViewEncapsulation } from '@angular/core';
|
import { Component, EventEmitter, Injector, Input, OnChanges, OnInit, Output, TemplateRef, ViewEncapsulation } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
@ -28,9 +28,6 @@ import { MediaPlayerComponent } from '../media-player/media-player.component';
|
|||||||
import { PdfViewerComponent } from '../pdf-viewer/pdf-viewer.component';
|
import { PdfViewerComponent } from '../pdf-viewer/pdf-viewer.component';
|
||||||
import { TxtViewerComponent } from '../txt-viewer/txt-viewer.component';
|
import { TxtViewerComponent } from '../txt-viewer/txt-viewer.component';
|
||||||
import { UnknownFormatComponent } from '../unknown-format/unknown-format.component';
|
import { UnknownFormatComponent } from '../unknown-format/unknown-format.component';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
|
||||||
|
|
||||||
type ViewerType = 'media' | 'image' | 'pdf' | 'external' | 'text' | 'custom' | 'unknown';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-viewer-render',
|
selector: 'adf-viewer-render',
|
||||||
@ -53,8 +50,7 @@ type ViewerType = 'media' | 'image' | 'pdf' | 'external' | 'text' | 'custom' | '
|
|||||||
UnknownFormatComponent,
|
UnknownFormatComponent,
|
||||||
ExtensionsModule,
|
ExtensionsModule,
|
||||||
NgForOf,
|
NgForOf,
|
||||||
NgSwitchDefault,
|
NgSwitchDefault
|
||||||
AsyncPipe
|
|
||||||
],
|
],
|
||||||
providers: [ViewUtilService]
|
providers: [ViewUtilService]
|
||||||
})
|
})
|
||||||
@ -90,6 +86,10 @@ export class ViewerRenderComponent implements OnChanges, OnInit {
|
|||||||
@Input()
|
@Input()
|
||||||
fileName: string;
|
fileName: string;
|
||||||
|
|
||||||
|
/** Override loading status */
|
||||||
|
@Input()
|
||||||
|
isLoading = false;
|
||||||
|
|
||||||
/** Enable when where is possible the editing functionalities */
|
/** Enable when where is possible the editing functionalities */
|
||||||
@Input()
|
@Input()
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
@ -141,8 +141,8 @@ export class ViewerRenderComponent implements OnChanges, OnInit {
|
|||||||
extensionsSupportedByTemplates: string[] = [];
|
extensionsSupportedByTemplates: string[] = [];
|
||||||
extension: string;
|
extension: string;
|
||||||
internalFileName: string;
|
internalFileName: string;
|
||||||
viewerType: ViewerType = 'unknown';
|
viewerType: string = 'unknown';
|
||||||
readonly isLoading$ = new BehaviorSubject(false);
|
isContentReady = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of the active Viewer content extensions.
|
* Returns a list of the active Viewer content extensions.
|
||||||
@ -182,10 +182,12 @@ export class ViewerRenderComponent implements OnChanges, OnInit {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.cacheTypeForContent = 'no-cache';
|
this.cacheTypeForContent = 'no-cache';
|
||||||
this.setDefaultLoadingState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
|
this.isContentReady = false;
|
||||||
|
this.isLoading = !this.blobFile && !this.urlFile;
|
||||||
|
|
||||||
if (this.blobFile) {
|
if (this.blobFile) {
|
||||||
this.setUpBlobData();
|
this.setUpBlobData();
|
||||||
} else if (this.urlFile) {
|
} else if (this.urlFile) {
|
||||||
@ -193,13 +195,9 @@ export class ViewerRenderComponent implements OnChanges, OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
markAsLoaded() {
|
|
||||||
this.isLoading$.next(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private setUpBlobData() {
|
private setUpBlobData() {
|
||||||
this.internalFileName = this.fileName;
|
this.internalFileName = this.fileName;
|
||||||
this.viewerType = this.viewUtilService.getViewerTypeByMimeType(this.blobFile.type) as ViewerType;
|
this.viewerType = this.viewUtilService.getViewerTypeByMimeType(this.blobFile.type);
|
||||||
|
|
||||||
this.extensionChange.emit(this.blobFile.type);
|
this.extensionChange.emit(this.blobFile.type);
|
||||||
this.scrollTop();
|
this.scrollTop();
|
||||||
@ -208,7 +206,7 @@ export class ViewerRenderComponent implements OnChanges, OnInit {
|
|||||||
private setUpUrlFile() {
|
private setUpUrlFile() {
|
||||||
this.internalFileName = this.fileName ? this.fileName : this.viewUtilService.getFilenameFromUrl(this.urlFile);
|
this.internalFileName = this.fileName ? this.fileName : this.viewUtilService.getFilenameFromUrl(this.urlFile);
|
||||||
this.extension = this.viewUtilService.getFileExtension(this.internalFileName);
|
this.extension = this.viewUtilService.getFileExtension(this.internalFileName);
|
||||||
this.viewerType = this.viewUtilService.getViewerType(this.extension, this.mimeType, this.extensionsSupportedByTemplates) as ViewerType;
|
this.viewerType = this.viewUtilService.getViewerType(this.extension, this.mimeType, this.extensionsSupportedByTemplates);
|
||||||
|
|
||||||
this.extensionChange.emit(this.extension);
|
this.extensionChange.emit(this.extension);
|
||||||
this.scrollTop();
|
this.scrollTop();
|
||||||
@ -237,14 +235,4 @@ export class ViewerRenderComponent implements OnChanges, OnInit {
|
|||||||
onClose() {
|
onClose() {
|
||||||
this.close.next(true);
|
this.close.next(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private canBePreviewed(): boolean {
|
|
||||||
return this.viewerType === 'media' || this.viewerType === 'pdf' || this.viewerType === 'image';
|
|
||||||
}
|
|
||||||
|
|
||||||
private setDefaultLoadingState() {
|
|
||||||
if (this.canBePreviewed()) {
|
|
||||||
this.isLoading$.next(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,8 @@
|
|||||||
<div class="adf-viewer__display-name"
|
<div class="adf-viewer__display-name"
|
||||||
id="adf-viewer-display-name"
|
id="adf-viewer-display-name"
|
||||||
[title]="fileName">
|
[title]="fileName">
|
||||||
<span>{{ displayName }}</span>
|
<span class="adf-viewer__display-name-without-extension">{{ fileNameWithoutExtension }}</span>
|
||||||
|
<span class="adf-viewer__display-name-extension">{{ fileExtension }}</span>
|
||||||
</div>
|
</div>
|
||||||
<button *ngIf="allowNavigate && canNavigateNext"
|
<button *ngIf="allowNavigate && canNavigateNext"
|
||||||
data-automation-id="adf-toolbar-next-file"
|
data-automation-id="adf-toolbar-next-file"
|
||||||
|
@ -55,10 +55,23 @@
|
|||||||
|
|
||||||
&__display-name {
|
&__display-name {
|
||||||
font-size: var(--theme-subheading-2-font-size);
|
font-size: var(--theme-subheading-2-font-size);
|
||||||
|
opacity: 0.87;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
letter-spacing: -0.4px;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-stretch: normal;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
color: var(--adf-theme-foreground-text-color);
|
color: var(--adf-theme-foreground-text-color);
|
||||||
white-space: nowrap;
|
|
||||||
|
&-without-extension {
|
||||||
|
display: inline-block;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 400px;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-container {
|
&-container {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, SimpleChanges } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { ComponentFixture, discardPeriodicTasks, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
|
import { ComponentFixture, discardPeriodicTasks, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
@ -143,61 +143,36 @@ describe('ViewerComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('File Name Display Tests', () => {
|
describe('File Name Test', () => {
|
||||||
describe('displayFileName method', () => {
|
const getFileNameWithoutExtension = (): string =>
|
||||||
it('should return full filename when total length is 80 characters or less', () => {
|
testingUtils.getByCSS('.adf-viewer__display-name-without-extension').nativeElement.textContent;
|
||||||
const fileShortName = 'shortname.txt';
|
const getExtension = (): string => testingUtils.getByCSS('.adf-viewer__display-name-extension').nativeElement.textContent;
|
||||||
component.fileName = fileShortName;
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(component.getDisplayFileName()).toBe(fileShortName);
|
it('should fileName be set by urlFile input if the fileName is not provided as Input', () => {
|
||||||
expect(getFileName()).toBe(fileShortName);
|
component.fileName = '';
|
||||||
});
|
spyOn(viewUtilService, 'getFilenameFromUrl').and.returnValue('fakeFileName.jpeg');
|
||||||
|
const mockSimpleChanges: any = { urlFile: { currentValue: 'https://fakefile.url/fakeFileName.jpeg' } };
|
||||||
|
|
||||||
it('should truncate filename when total length exceeds 80 characters', () => {
|
component.ngOnChanges(mockSimpleChanges);
|
||||||
const longName =
|
fixture.detectChanges();
|
||||||
'verylongfilenamethatexceedsmaximumlengthallowedverylongfilenamethatexceedsmaximumlengthallowed.verylongextensionnamethatistoolongverylongextensionnamethatistoolong';
|
|
||||||
|
|
||||||
component.fileName = longName;
|
expect(getFileName()).toEqual('fakeFileName.jpeg');
|
||||||
fixture.detectChanges();
|
expect(getFileNameWithoutExtension()).toBe('fakeFileName.');
|
||||||
|
expect(getExtension()).toBe('jpeg');
|
||||||
const result = component.getDisplayFileName();
|
|
||||||
|
|
||||||
expect(result).toContain('.....');
|
|
||||||
expect(result.length).toBe(50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle empty filename', () => {
|
|
||||||
component.fileName = '';
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(component.getDisplayFileName()).toBe('');
|
|
||||||
expect(getFileName()).toBe('');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fileName setter integration', () => {
|
it('should set fileName providing fileName input', () => {
|
||||||
it('should fileName be set by urlFile input if the fileName is not provided as Input', () => {
|
component.fileName = 'testFileName.jpg';
|
||||||
component.fileName = '';
|
spyOn(viewUtilService, 'getFilenameFromUrl').and.returnValue('fakeFileName.jpeg');
|
||||||
spyOn(viewUtilService, 'getFilenameFromUrl').and.returnValue('fakeFileName.jpeg');
|
const mockSimpleChanges: any = { urlFile: { currentValue: 'https://fakefile.url/fakeFileName.jpeg' } };
|
||||||
const mockSimpleChanges = { urlFile: { currentValue: 'https://fakefile.url/fakeFileName.jpeg' } } as unknown as SimpleChanges;
|
|
||||||
|
|
||||||
component.ngOnChanges(mockSimpleChanges);
|
component.ngOnChanges(mockSimpleChanges);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(getFileName()).toEqual('fakeFileName.jpeg');
|
expect(getFileName()).toEqual('testFileName.jpg');
|
||||||
});
|
expect(getFileNameWithoutExtension()).toBe('testFileName.');
|
||||||
|
expect(getExtension()).toBe('jpg');
|
||||||
it('should set fileName providing fileName input', () => {
|
|
||||||
component.fileName = 'testFileName.jpg';
|
|
||||||
spyOn(viewUtilService, 'getFilenameFromUrl').and.returnValue('fakeFileName.jpeg');
|
|
||||||
const mockSimpleChanges = { urlFile: { currentValue: 'https://fakefile.url/fakeFileName.jpeg' } } as unknown as SimpleChanges;
|
|
||||||
|
|
||||||
component.ngOnChanges(mockSimpleChanges);
|
|
||||||
fixture.detectChanges();
|
|
||||||
|
|
||||||
expect(getFileName()).toEqual('testFileName.jpg');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -297,7 +297,6 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
|||||||
private _fileNameWithoutExtension: string;
|
private _fileNameWithoutExtension: string;
|
||||||
private _fileExtension: string;
|
private _fileExtension: string;
|
||||||
|
|
||||||
public displayName: string;
|
|
||||||
public downloadPromptTimer: number;
|
public downloadPromptTimer: number;
|
||||||
public downloadPromptReminderTimer: number;
|
public downloadPromptReminderTimer: number;
|
||||||
public mimeTypeIconUrl: string;
|
public mimeTypeIconUrl: string;
|
||||||
@ -310,7 +309,6 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
|||||||
this._fileName = fileName;
|
this._fileName = fileName;
|
||||||
this._fileExtension = this.viewUtilsService.getFileExtension(this.fileName);
|
this._fileExtension = this.viewUtilsService.getFileExtension(this.fileName);
|
||||||
this._fileNameWithoutExtension = this.fileName?.replace(new RegExp(`${this.fileExtension}$`), '') || '';
|
this._fileNameWithoutExtension = this.fileName?.replace(new RegExp(`${this.fileExtension}$`), '') || '';
|
||||||
this.displayName = this.getDisplayFileName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get fileName(): string {
|
get fileName(): string {
|
||||||
@ -464,24 +462,6 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
|||||||
this.clearDownloadPromptTimeouts();
|
this.clearDownloadPromptTimeouts();
|
||||||
}
|
}
|
||||||
|
|
||||||
getDisplayFileName(): string {
|
|
||||||
const fullName = (this.fileNameWithoutExtension || '') + (this.fileExtension || '');
|
|
||||||
const maxLength = 50;
|
|
||||||
|
|
||||||
if (fullName.length <= maxLength) {
|
|
||||||
return fullName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const amountOfTruncateDots = 5;
|
|
||||||
const availableSpace = maxLength - amountOfTruncateDots;
|
|
||||||
const endLength = 8;
|
|
||||||
const startLength = availableSpace - endLength;
|
|
||||||
|
|
||||||
const start = fullName.substring(0, startLength);
|
|
||||||
const end = fullName.substring(fullName.length - endLength);
|
|
||||||
return start + '.....' + end;
|
|
||||||
}
|
|
||||||
|
|
||||||
private configureAndInitDownloadPrompt() {
|
private configureAndInitDownloadPrompt() {
|
||||||
this.configureDownloadPromptProperties();
|
this.configureDownloadPromptProperties();
|
||||||
if (this.enableDownloadPrompt) {
|
if (this.enableDownloadPrompt) {
|
||||||
|
@ -5,9 +5,6 @@ export default {
|
|||||||
testEnvironment: 'jsdom',
|
testEnvironment: 'jsdom',
|
||||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||||
coverageDirectory: '../../../coverage/libs/js-api',
|
coverageDirectory: '../../../coverage/libs/js-api',
|
||||||
moduleMNameMapper: {
|
|
||||||
'^pdfjs-dist$': 'pdfjs-dist/legacy/build/pdf'
|
|
||||||
},
|
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.(ts|mjs|js|html)$': [
|
'^.+\\.(ts|mjs|js|html)$': [
|
||||||
'jest-preset-angular',
|
'jest-preset-angular',
|
||||||
|
@ -209,9 +209,9 @@ export class TagsApi extends BaseApi {
|
|||||||
/**
|
/**
|
||||||
* Create specified by **tags** list of tags.
|
* Create specified by **tags** list of tags.
|
||||||
* @param tags List of tags to create.
|
* @param tags List of tags to create.
|
||||||
* @returns Promise<TagEntry | TagPaging>
|
* @returns Promise<TagEntry[]>
|
||||||
*/
|
*/
|
||||||
createTags(tags: TagBody[]): Promise<TagEntry | TagPaging> {
|
createTags(tags: TagBody[]): Promise<TagEntry[]> {
|
||||||
throwIfNotDefined(tags, 'tags');
|
throwIfNotDefined(tags, 'tags');
|
||||||
|
|
||||||
return this.post({
|
return this.post({
|
||||||
|
@ -240,7 +240,7 @@ Create specified by **tags** list of tags.
|
|||||||
|----------|-----------------------|-------------------------|
|
|----------|-----------------------|-------------------------|
|
||||||
| **tags** | [TagBody[]](#TagBody) | List of tags to create. |
|
| **tags** | [TagBody[]](#TagBody) | List of tags to create. |
|
||||||
|
|
||||||
**Return type**: [TagEntry](#TagEntry) | [TagPaging](#TagPaging)
|
**Return type**: [TagEntry[]](#TagEntry)
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ import { BaseApi } from './base.api';
|
|||||||
import { buildCollectionParam } from '../../../alfrescoApiClient';
|
import { buildCollectionParam } from '../../../alfrescoApiClient';
|
||||||
import { throwIfNotDefined } from '../../../assert';
|
import { throwIfNotDefined } from '../../../assert';
|
||||||
import { RecordsIncludeQuery, RecordsPagingQuery, RecordsSourceQuery } from './types';
|
import { RecordsIncludeQuery, RecordsPagingQuery, RecordsSourceQuery } from './types';
|
||||||
import { FilePlanRolePaging, FilePlanRoleParameters } from '../model';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FilePlansApi service.
|
* FilePlansApi service.
|
||||||
@ -159,26 +158,4 @@ export class FilePlansApi extends BaseApi {
|
|||||||
returnType: FilePlanEntry
|
returnType: FilePlanEntry
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of roles for the specified file plan.
|
|
||||||
* @param filePlanId The identifier of a file plan. You can also use the -filePlan- alias.
|
|
||||||
* @param parameters Optional parameters
|
|
||||||
* @returns Promise<FilePlanEntry>
|
|
||||||
*/
|
|
||||||
getFilePlanRoles(filePlanId: string, parameters?: FilePlanRoleParameters): Promise<FilePlanRolePaging> {
|
|
||||||
throwIfNotDefined(filePlanId, 'filePlanId');
|
|
||||||
|
|
||||||
return this.get({
|
|
||||||
path: '/file-plans/{filePlanId}/roles',
|
|
||||||
pathParams: {
|
|
||||||
filePlanId
|
|
||||||
},
|
|
||||||
queryParams: {
|
|
||||||
where: parameters?.where?.capabilityNames
|
|
||||||
? `(capabilityName in (${parameters.where.capabilityNames.map((value) => "'" + value + "'").join(', ')}))`
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
# FilePlanRole
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
| Name | Type |
|
|
||||||
|--------------------|-----------------------------------------------------------|
|
|
||||||
| **displayLabel** | string |
|
|
||||||
| **groupShortName** | string |
|
|
||||||
| **name** | string |
|
|
||||||
| **roleGroupName** | string |
|
|
||||||
| **capabilities** | [**FilePlanRoleCapability[]**](FilePlanRoleCapability.md) |
|
|
||||||
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
# FilePLanRoleCapability
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
| Name | Type |
|
|
||||||
|-----------|-------------------------------------------------------------------|
|
|
||||||
| **group** | [**FilePlanRoleCapabilityGroup**](FilePlanRoleCapabilityGroup.md) |
|
|
||||||
| **index** | number |
|
|
||||||
| **name** | string |
|
|
||||||
| **title** | string |
|
|
||||||
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
# FilePlanRoleCapabilityGroup
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
| Name | Type |
|
|
||||||
|-----------|--------|
|
|
||||||
| **id** | string |
|
|
||||||
| **title** | string |
|
|
||||||
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
# FilePlanRoleEntry
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
| Name | Type |
|
|
||||||
|-----------|-------------------------------------|
|
|
||||||
| **entry** | [**FilePlanRole**](FilePlanRole.md) |
|
|
||||||
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
# FilePLanRolePaging
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
| Name | Type |
|
|
||||||
|----------|---------------------------------------------------------|
|
|
||||||
| **list** | [**FilePlanRolePagingList**](FilePlanRolePagingList.md) |
|
|
||||||
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
# FilePLanRolePagingList
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
| Name | Type |
|
|
||||||
|----------------|-------------------------------------------------------------|
|
|
||||||
| **entries** | [**FilePlanRoleEntry[]**](FilePlanRoleEntry.md) |
|
|
||||||
| **pagination** | [**Pagination**](../../content-rest-api/docs/Pagination.md) |
|
|
||||||
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
# FilePlanRoleParameters
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
| Name | Type |
|
|
||||||
|-----------|-------------------------------------------------------------------|
|
|
||||||
| **where** | [**FilePlanRoleParametersWhere**](FilePlanRoleParametersWhere.md) |
|
|
||||||
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
# FilePlanRoleParametersWhere
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
| Name | Type |
|
|
||||||
|---------------------|----------|
|
|
||||||
| **capabilityNames** | string[] |
|
|
||||||
|
|
||||||
|
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
All URIs are relative to *https://localhost/alfresco/api/-default-/public/gs/versions/1*
|
All URIs are relative to *https://localhost/alfresco/api/-default-/public/gs/versions/1*
|
||||||
|
|
||||||
| Method | HTTP request | Description |
|
Method | HTTP request | Description
|
||||||
|--------------------------------------------------------------------------|----------------------------------------------|---------------------------------------------------|
|
------------- | ------------- | -------------
|
||||||
| [**createFilePlanCategories**](FilePlansApi.md#createFilePlanCategories) | **POST** /file-plans/{filePlanId}/categories | Create record categories for a file plan |
|
[**createFilePlanCategories**](FilePlansApi.md#createFilePlanCategories) | **POST** /file-plans/{filePlanId}/categories | Create record categories for a file plan
|
||||||
| [**getFilePlan**](FilePlansApi.md#getFilePlan) | **GET** /file-plans/{filePlanId} | Get a file plan |
|
[**getFilePlan**](FilePlansApi.md#getFilePlan) | **GET** /file-plans/{filePlanId} | Get a file plan
|
||||||
| [**getFilePlanCategories**](FilePlansApi.md#getFilePlanCategories) | **GET** /file-plans/{filePlanId}/categories | List file plans's children |
|
[**getFilePlanCategories**](FilePlansApi.md#getFilePlanCategories) | **GET** /file-plans/{filePlanId}/categories | List file plans's children
|
||||||
| [**updateFilePlan**](FilePlansApi.md#updateFilePlan) | **PUT** /file-plans/{filePlanId} | Update a file plan |
|
[**updateFilePlan**](FilePlansApi.md#updateFilePlan) | **PUT** /file-plans/{filePlanId} | Update a file plan
|
||||||
| [**getFilePlanRoles**](FilePlansApi.md#getFilePlanRoles) | **GET** /file-plans/{filePlanId}/roles | Gets a list of roles for the specified file plan. |
|
|
||||||
|
|
||||||
<a name="createFilePlanCategories"></a>
|
<a name="createFilePlanCategories"></a>
|
||||||
# **createFilePlanCategories**
|
# **createFilePlanCategories**
|
||||||
@ -402,39 +402,3 @@ parameter are returned in addition to those specified in the **fields** paramete
|
|||||||
|
|
||||||
[**FilePlanEntry**](FilePlanEntry.md)
|
[**FilePlanEntry**](FilePlanEntry.md)
|
||||||
|
|
||||||
<a name="getFilePlanRoles"></a>
|
|
||||||
# **getFilePlanRoles**
|
|
||||||
> FilePlanEntry getFilePlanRoles(filePlanId, parameters)
|
|
||||||
|
|
||||||
Gets a list of roles for the specified file plan.
|
|
||||||
|
|
||||||
### Example
|
|
||||||
```javascript
|
|
||||||
import FilePlansApi from 'FilePlansApi';
|
|
||||||
import { AlfrescoApi } from '@alfresco/js-api';
|
|
||||||
|
|
||||||
this.alfrescoApi = new AlfrescoApi();
|
|
||||||
this.alfrescoApi.setConfig({
|
|
||||||
hostEcm: 'http://127.0.0.1:8080'
|
|
||||||
});
|
|
||||||
|
|
||||||
let fileplansApi = new FilePlansApi(this.alfrescoApi);
|
|
||||||
const filePlanId = 'some id';
|
|
||||||
fileplansApi.updateFilePlan(filePlanId, {
|
|
||||||
where: {
|
|
||||||
capabilityNames: ['ViewRecords']
|
|
||||||
}
|
|
||||||
}).then((data) => console.log('API called successfully. Returned data: ' + data))
|
|
||||||
.catch((error) => console.log(error));
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
| Name | Type | Description |
|
|
||||||
|----------------|---------------------------------------------------------|-----------------------------------------------------------------------|
|
|
||||||
| **filePlanId** | **string** | The identifier of a file plan. You can also use the -filePlan- alias. |
|
|
||||||
| **parameters** | [**FilePlanRoleParameters**](FilePlanRoleParameters.md) | Optional parameters. |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**FilePlanRolePaging**](FilePlanRolePaging.md)
|
|
||||||
|
@ -1,33 +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 { FilePlanRoleCapability } from './filePlanRoleCapability';
|
|
||||||
|
|
||||||
export class FilePlanRole {
|
|
||||||
displayLabel: string;
|
|
||||||
groupShortName: string;
|
|
||||||
name: string;
|
|
||||||
roleGroupName: string;
|
|
||||||
capabilities: FilePlanRoleCapability[];
|
|
||||||
|
|
||||||
constructor(input?: Partial<FilePlanRole>) {
|
|
||||||
if (input) {
|
|
||||||
Object.assign(this, input);
|
|
||||||
this.capabilities = input.capabilities?.map((capability) => new FilePlanRoleCapability(capability));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +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 { FilePlanRoleCapabilityGroup } from './filePlanRoleCapabilityGroup';
|
|
||||||
|
|
||||||
export class FilePlanRoleCapability {
|
|
||||||
group: FilePlanRoleCapabilityGroup;
|
|
||||||
index: number;
|
|
||||||
name: string;
|
|
||||||
title: string;
|
|
||||||
|
|
||||||
constructor(input?: Partial<FilePlanRoleCapability>) {
|
|
||||||
if (input) {
|
|
||||||
Object.assign(this, input);
|
|
||||||
this.group = input.group ? new FilePlanRoleCapabilityGroup(input.group) : undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export class FilePlanRoleCapabilityGroup {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
|
|
||||||
constructor(input?: Partial<FilePlanRoleCapabilityGroup>) {
|
|
||||||
if (input) {
|
|
||||||
Object.assign(this, input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +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 { FilePlanRole } from './filePlanRole';
|
|
||||||
|
|
||||||
export class FilePlanRoleEntry {
|
|
||||||
entry: FilePlanRole;
|
|
||||||
|
|
||||||
constructor(input?: Partial<FilePlanRoleEntry>) {
|
|
||||||
if (input) {
|
|
||||||
Object.assign(this, input);
|
|
||||||
this.entry = input.entry ? new FilePlanRole(input.entry) : undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +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 { FilePlanRolePagingList } from './filePlanRolePagingList';
|
|
||||||
|
|
||||||
export class FilePlanRolePaging {
|
|
||||||
list: FilePlanRolePagingList;
|
|
||||||
|
|
||||||
constructor(input: Partial<FilePlanRolePaging>) {
|
|
||||||
if (input) {
|
|
||||||
Object.assign(this, input);
|
|
||||||
this.list = input.list ? new FilePlanRolePagingList(input.list) : undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +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 { Pagination } from '../../content-rest-api';
|
|
||||||
import { FilePlanRoleEntry } from './filePlanRoleEntry';
|
|
||||||
|
|
||||||
export class FilePlanRolePagingList {
|
|
||||||
entries: FilePlanRoleEntry[];
|
|
||||||
pagination: Pagination;
|
|
||||||
|
|
||||||
constructor(input: Partial<FilePlanRolePagingList>) {
|
|
||||||
if (input) {
|
|
||||||
Object.assign(this, input);
|
|
||||||
this.pagination = input.pagination ? new Pagination(input.pagination) : undefined;
|
|
||||||
this.entries = input?.entries.map((entry) => new FilePlanRoleEntry(entry));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +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 { FilePlanRoleParametersWhere } from './filePlanRoleParametersWhere';
|
|
||||||
|
|
||||||
export interface FilePlanRoleParameters {
|
|
||||||
where?: FilePlanRoleParametersWhere;
|
|
||||||
}
|
|
@ -1,20 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface FilePlanRoleParametersWhere {
|
|
||||||
capabilityNames?: string[];
|
|
||||||
}
|
|
@ -19,14 +19,6 @@ export * from './filePlan';
|
|||||||
export * from './filePlanBodyUpdate';
|
export * from './filePlanBodyUpdate';
|
||||||
export * from './filePlanComponentBodyUpdate';
|
export * from './filePlanComponentBodyUpdate';
|
||||||
export * from './filePlanEntry';
|
export * from './filePlanEntry';
|
||||||
export * from './filePlanRole';
|
|
||||||
export * from './filePlanRoleCapability';
|
|
||||||
export * from './filePlanRoleCapabilityGroup';
|
|
||||||
export * from './filePlanRoleEntry';
|
|
||||||
export * from './filePlanRolePaging';
|
|
||||||
export * from './filePlanRolePagingList';
|
|
||||||
export * from './filePlanRoleParameters';
|
|
||||||
export * from './filePlanRoleParametersWhere';
|
|
||||||
export * from './rMNodeBodyCreate';
|
export * from './rMNodeBodyCreate';
|
||||||
export * from './rMNodeBodyCreateWithRelativePath';
|
export * from './rMNodeBodyCreateWithRelativePath';
|
||||||
export * from './rMSite';
|
export * from './rMSite';
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import { AlfrescoApi, TagBody, TagEntry, TagPaging, TagsApi } from '../../src';
|
import { AlfrescoApi, TagBody, TagEntry, TagsApi } from '../../src';
|
||||||
import { EcmAuthMock, TagMock } from '../mockObjects';
|
import { EcmAuthMock, TagMock } from '../mockObjects';
|
||||||
|
|
||||||
describe('Tags', () => {
|
describe('Tags', () => {
|
||||||
@ -105,10 +105,10 @@ describe('Tags', () => {
|
|||||||
describe('createTags', () => {
|
describe('createTags', () => {
|
||||||
it('should return created tags', (done) => {
|
it('should return created tags', (done) => {
|
||||||
tagMock.createTags201Response();
|
tagMock.createTags201Response();
|
||||||
tagsApi.createTags([new TagBody(), new TagBody()]).then((tags: TagPaging) => {
|
tagsApi.createTags([new TagBody(), new TagBody()]).then((tags) => {
|
||||||
assert.equal(tags.list.entries.length, 2);
|
assert.equal(tags.length, 2);
|
||||||
assert.equal(tags.list.entries[0].entry.tag, 'tag-test-1');
|
assert.equal(tags[0].entry.tag, 'tag-test-1');
|
||||||
assert.equal(tags.list.entries[1].entry.tag, 'tag-test-2');
|
assert.equal(tags[1].entry.tag, 'tag-test-2');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,129 +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 { EcmAuthMock, FilePlansMock } from '../mockObjects';
|
|
||||||
import { AlfrescoApi, FilePlanRolePaging, FilePlansApi } from '../../src';
|
|
||||||
|
|
||||||
describe('FilePlansApi', () => {
|
|
||||||
let filePlansApiMock: FilePlansMock;
|
|
||||||
let filePlansApi: FilePlansApi;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
const hostEcm = 'https://127.0.0.1:8080';
|
|
||||||
const authResponseMock = new EcmAuthMock(hostEcm);
|
|
||||||
authResponseMock.get201Response();
|
|
||||||
filePlansApiMock = new FilePlansMock(hostEcm);
|
|
||||||
const alfrescoApi = new AlfrescoApi({
|
|
||||||
hostEcm
|
|
||||||
});
|
|
||||||
filePlansApi = new FilePlansApi(alfrescoApi);
|
|
||||||
await alfrescoApi.login('admin', 'admin');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getFilePlanRoles', () => {
|
|
||||||
let expectedRolePaging: FilePlanRolePaging;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
expectedRolePaging = {
|
|
||||||
list: {
|
|
||||||
pagination: {
|
|
||||||
count: 2,
|
|
||||||
hasMoreItems: false,
|
|
||||||
totalItems: 2,
|
|
||||||
skipCount: 0,
|
|
||||||
maxItems: 100
|
|
||||||
},
|
|
||||||
entries: [
|
|
||||||
{
|
|
||||||
entry: {
|
|
||||||
displayLabel: 'Role One',
|
|
||||||
groupShortName: 'group short name 1',
|
|
||||||
name: 'role1',
|
|
||||||
roleGroupName: 'role group name 1',
|
|
||||||
capabilities: [
|
|
||||||
{
|
|
||||||
index: 0,
|
|
||||||
name: 'capability1',
|
|
||||||
title: 'Capability One',
|
|
||||||
group: {
|
|
||||||
id: 'group1',
|
|
||||||
title: 'Group One'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 1,
|
|
||||||
name: 'capability2',
|
|
||||||
title: 'Capability Two',
|
|
||||||
group: {
|
|
||||||
id: 'group2',
|
|
||||||
title: 'Group Two'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
entry: {
|
|
||||||
displayLabel: 'Role Two',
|
|
||||||
groupShortName: 'group short name 2',
|
|
||||||
name: 'role2',
|
|
||||||
roleGroupName: 'role group name 2',
|
|
||||||
capabilities: [
|
|
||||||
{
|
|
||||||
index: 0,
|
|
||||||
name: 'capability3',
|
|
||||||
title: 'Capability Three',
|
|
||||||
group: {
|
|
||||||
id: 'group3',
|
|
||||||
title: 'Group Three'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get file plan roles', (done) => {
|
|
||||||
const filePlanId = 'filePlanId123';
|
|
||||||
filePlansApiMock.get200FilePlanRoles(filePlanId);
|
|
||||||
|
|
||||||
filePlansApi.getFilePlanRoles(filePlanId).then((rolePaging) => {
|
|
||||||
expect(rolePaging).toEqual(expectedRolePaging);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get file plan roles with filtering by capability names', (done) => {
|
|
||||||
const filePlanId = 'filePlanId123';
|
|
||||||
filePlansApiMock.get200FilePlanRolesWithFilteringByCapabilityNames(filePlanId);
|
|
||||||
|
|
||||||
filePlansApi
|
|
||||||
.getFilePlanRoles(filePlanId, {
|
|
||||||
where: {
|
|
||||||
capabilityNames: ['capability1', 'capability2']
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((rolePaging) => {
|
|
||||||
expect(rolePaging).toEqual(expectedRolePaging);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -65,7 +65,7 @@ export class TagMock extends BaseMock {
|
|||||||
createTags201Response(): void {
|
createTags201Response(): void {
|
||||||
nock(this.host, { encodedQueryParams: true })
|
nock(this.host, { encodedQueryParams: true })
|
||||||
.post('/alfresco/api/-default-/public/alfresco/versions/1/tags')
|
.post('/alfresco/api/-default-/public/alfresco/versions/1/tags')
|
||||||
.reply(201, this.getPaginatedListOfTags());
|
.reply(201, [this.mockTagEntry(), this.mockTagEntry('tag-test-2', 'd79bdbd0-9f55-45bb-9521-811e15bf48f6')]);
|
||||||
}
|
}
|
||||||
|
|
||||||
get201ResponseForAssigningTagsToNode(body: TagBody[]): void {
|
get201ResponseForAssigningTagsToNode(body: TagBody[]): void {
|
||||||
|
@ -1,101 +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 { BaseMock } from '../base.mock';
|
|
||||||
import nock from 'nock';
|
|
||||||
import { FilePlanRolePaging } from '@alfresco/js-api';
|
|
||||||
|
|
||||||
export class FilePlansMock extends BaseMock {
|
|
||||||
get200FilePlanRoles(filePlanId: string): void {
|
|
||||||
nock(this.host, { encodedQueryParams: true })
|
|
||||||
.get(`/alfresco/api/-default-/public/gs/versions/1/file-plans/${filePlanId}/roles`)
|
|
||||||
.query({})
|
|
||||||
.reply(200, this.mockFilePlanRolePaging());
|
|
||||||
}
|
|
||||||
|
|
||||||
get200FilePlanRolesWithFilteringByCapabilityNames(filePlanId: string): void {
|
|
||||||
nock(this.host, { encodedQueryParams: true })
|
|
||||||
.get(`/alfresco/api/-default-/public/gs/versions/1/file-plans/${filePlanId}/roles`)
|
|
||||||
.query({
|
|
||||||
where: "(capabilityName in ('capability1', 'capability2'))"
|
|
||||||
})
|
|
||||||
.reply(200, this.mockFilePlanRolePaging());
|
|
||||||
}
|
|
||||||
|
|
||||||
private mockFilePlanRolePaging(): FilePlanRolePaging {
|
|
||||||
return {
|
|
||||||
list: {
|
|
||||||
pagination: {
|
|
||||||
count: 2,
|
|
||||||
hasMoreItems: false,
|
|
||||||
totalItems: 2,
|
|
||||||
skipCount: 0,
|
|
||||||
maxItems: 100
|
|
||||||
},
|
|
||||||
entries: [
|
|
||||||
{
|
|
||||||
entry: {
|
|
||||||
displayLabel: 'Role One',
|
|
||||||
groupShortName: 'group short name 1',
|
|
||||||
name: 'role1',
|
|
||||||
roleGroupName: 'role group name 1',
|
|
||||||
capabilities: [
|
|
||||||
{
|
|
||||||
index: 0,
|
|
||||||
name: 'capability1',
|
|
||||||
title: 'Capability One',
|
|
||||||
group: {
|
|
||||||
id: 'group1',
|
|
||||||
title: 'Group One'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: 1,
|
|
||||||
name: 'capability2',
|
|
||||||
title: 'Capability Two',
|
|
||||||
group: {
|
|
||||||
id: 'group2',
|
|
||||||
title: 'Group Two'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
entry: {
|
|
||||||
displayLabel: 'Role Two',
|
|
||||||
groupShortName: 'group short name 2',
|
|
||||||
name: 'role2',
|
|
||||||
roleGroupName: 'role group name 2',
|
|
||||||
capabilities: [
|
|
||||||
{
|
|
||||||
index: 0,
|
|
||||||
name: 'capability3',
|
|
||||||
title: 'Capability Three',
|
|
||||||
group: {
|
|
||||||
id: 'group3',
|
|
||||||
title: 'Group Three'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -34,7 +34,6 @@ export * from './content-services/version.mock';
|
|||||||
export * from './content-services/webscript.mock';
|
export * from './content-services/webscript.mock';
|
||||||
|
|
||||||
export * from './goverance-services/authority-clearance.mock';
|
export * from './goverance-services/authority-clearance.mock';
|
||||||
export * from './goverance-services/file-plans.mock';
|
|
||||||
export * from './goverance-services/gs-sites.mock';
|
export * from './goverance-services/gs-sites.mock';
|
||||||
export * from './goverance-services/node-security-marks.mock';
|
export * from './goverance-services/node-security-marks.mock';
|
||||||
export * from './goverance-services/security-groups.mock';
|
export * from './goverance-services/security-groups.mock';
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user