Compare commits

...
Author SHA1 Message Date
alep85 fd69f91929 [ci:force] 2025-05-28 16:36:29 +02:00
alep85 ceacb6c356 AAE-34959 Provide SecurityOptionsLoaderService in root to fix No Provider error 2025-05-28 16:35:34 +02:00
alep85 6080d7d2a7 [ci:force] 2025-05-27 13:16:35 +02:00
alep85 080feea1e0 AAE-34959 Run security options loader when alfresco-api-v2-loader.serfvice is initialized because on content app the app-config.loader is run after AlfrescoApiLoaderService.init and the callback function that should setDefaultSecurityOption is not executed 2025-05-27 13:15:06 +02:00
alep85 ff12231357 [ci:force] 2025-05-23 17:07:06 +02:00
alep85 c273fabc28 AAE-35242 Release 7.0.1 2025-05-23 16:59:47 +02:00
Eugenio RomanoandEhsan Rezaei b3894a359e AAE-34675 Fix default selection required (#10860)
* fix default selection required

* rename test

* dropdown form field return object

* dropdown form field return object

* dropdown form field return object

* fix test

* Update lib/core/src/lib/form/components/widgets/core/form-field.model.spec.ts

Co-authored-by: Ehsan Rezaei <ehsan.rezaei@hyland.com>

* Update lib/core/src/lib/form/components/widgets/core/form-field.model.ts

Co-authored-by: Ehsan Rezaei <ehsan.rezaei@hyland.com>

---------

Co-authored-by: Ehsan Rezaei <ehsan.rezaei@hyland.com>
2025-05-23 15:57:16 +02:00
Amedeo Lepore 2564999281 AAE-34959 Allow disabling withCredentials for the identity providers that disallow credentials (#10859) 2025-05-23 15:56:07 +02:00
29 changed files with 491 additions and 34 deletions
+1
View File
@@ -55,3 +55,4 @@ The pages linked below contain the licenses for all third party dependencies of
- [ADF 7.0.0-alpha.6](license-info-7.0.0-alpha.6.md)
- [ADF 7.0.0-alpha.7](license-info-7.0.0-alpha.7.md)
- [ADF 7.0.0](license-info-7.0.0.md)
- [ADF 7.0.1](license-info-7.0.1.md)
+55
View File
@@ -0,0 +1,55 @@
---
Title: License info, alfresco-ng2-components 7.0.1
---
# License information for alfresco-ng2-components 7.0.1
This page lists all third party libraries the project depends on.
## Libraries
| Name | Version | License |
| --- | --- | --- |
| [@angular/animations](https://github.com/angular/angular) | 18.2.13 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/cdk](https://github.com/angular/components) | 18.2.14 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/common](https://github.com/angular/angular) | 18.2.13 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/compiler](https://github.com/angular/angular) | 18.2.13 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/core](https://github.com/angular/angular) | 18.2.13 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/forms](https://github.com/angular/angular) | 18.2.13 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/material-date-fns-adapter](https://github.com/angular/components) | 18.2.14 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/material](https://github.com/angular/components) | 18.2.14 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular) | 18.2.13 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/platform-browser](https://github.com/angular/angular) | 18.2.13 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/router](https://github.com/angular/angular) | 18.2.13 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@apollo/client](https://github.com/apollographql/apollo-client) | 3.13.1 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@cspell/eslint-plugin](https://github.com/streetsidesoftware/cspell) | 8.16.1 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@mat-datetimepicker/core](https://github.com/kuhnroyal/mat-datetimepicker) | 14.0.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngx-translate/core](https://github.com/ngx-translate/core) | 14.0.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@nx/webpack](https://github.com/nrwl/nx) | 20.4.6 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@valano/change-font-size](https://github.com/VitoAlbano/change-font-size) | 1.0.1 | [MIT](http://www.opensource.org/licenses/MIT) |
| [angular-oauth2-oidc-jwks](https://github.com/manfredsteyer/angular-oauth2-oidc) | 17.0.2 | [MIT](http://www.opensource.org/licenses/MIT) |
| [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc) | 17.0.2 | [MIT](http://www.opensource.org/licenses/MIT) |
| [apollo-angular](https://github.com/kamilkisiela/apollo-angular) | 10.0.3 | [MIT](http://www.opensource.org/licenses/MIT) |
| [chart.js](https://github.com/chartjs/Chart.js) | 4.4.4 | [MIT](http://www.opensource.org/licenses/MIT) |
| [cropperjs](https://github.com/fengyuanchen/cropperjs) | 1.6.2 | [MIT](http://www.opensource.org/licenses/MIT) |
| [date-fns](https://github.com/date-fns/date-fns) | 2.30.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [dotenv-expand](https://github.com/motdotla/dotenv-expand) | 11.0.7 | [BSD-2-Clause](http://www.opensource.org/licenses/BSD-2-Clause) |
| dotenv-expand | 5.1.0 | [BSD-2-Clause](http://www.opensource.org/licenses/BSD-2-Clause) |
| [event-emitter](https://github.com/medikoo/event-emitter) | 0.3.5 | [MIT](http://www.opensource.org/licenses/MIT) |
| [graphql-ws](https://github.com/enisdenjo/graphql-ws) | 5.16.2 | [MIT](http://www.opensource.org/licenses/MIT) |
| [material-icons](https://github.com/marella/material-icons) | 1.13.14 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [minimatch](https://github.com/isaacs/minimatch) | 3.1.2 | [ISC](https://www.isc.org/downloads/software-support-policy/isc-license/) |
| [minimatch](https://github.com/isaacs/minimatch) | 5.1.6 | [ISC](https://www.isc.org/downloads/software-support-policy/isc-license/) |
| [minimatch](https://github.com/isaacs/minimatch) | 7.4.6 | [ISC](https://www.isc.org/downloads/software-support-policy/isc-license/) |
| [minimatch](https://github.com/isaacs/minimatch) | 9.0.3 | [ISC](https://www.isc.org/downloads/software-support-policy/isc-license/) |
| [minimatch](https://github.com/isaacs/minimatch) | 9.0.5 | [ISC](https://www.isc.org/downloads/software-support-policy/isc-license/) |
| [ng2-charts](https://github.com/valor-software/ng2-charts) | 4.1.1 | [ISC](https://www.isc.org/downloads/software-support-policy/isc-license/) |
| [pdfjs-dist](https://github.com/mozilla/pdf.js) | 5.1.91 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [raphael](https://github.com/DmitryBaranovskiy/raphael) | 2.3.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [rxjs](https://github.com/reactivex/rxjs) | 7.8.1 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [subscriptions-transport-ws](https://github.com/apollostack/subscriptions-transport-ws) | 0.11.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [superagent](https://github.com/ladjs/superagent) | 9.0.2 | [MIT](http://www.opensource.org/licenses/MIT) |
| [ts-morph](https://github.com/dsherret/ts-morph) | 20.0.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [tslib](https://github.com/Microsoft/tslib) | 2.8.1 | [0BSD](http://landley.net/toybox/license.html) |
| [zone.js](https://github.com/angular/angular) | 0.14.10 | [MIT](http://www.opensource.org/licenses/MIT) |
+1
View File
@@ -9,6 +9,7 @@ The first **General Availability** release was v2.0.0.
## General Availability
- [7.0.1](RelNote-7.0.1.md)
- [7.0.0](RelNote-7.0.0.md)
- [7.0.0-alpha.7](RelNote-7.0.0-alpha.7.md)
- [7.0.0-alpha.6](RelNote-7.0.0-alpha.6.md)
+8
View File
@@ -0,0 +1,8 @@
---
Title: Changelog for alfresco-ng2-components v7.0.1
---
# Changelog
- [051b82684f](https://github.com/Alfresco/alfresco-ng2-components/commit/051b82684f) AAE-34959 Allow disabling withCredentials for the identity providers that disallow credentials (#10859)
- [b4eee9d631](https://github.com/Alfresco/alfresco-ng2-components/commit/b4eee9d631) AAE-34675 Fix default selection required (#10860)
+1
View File
@@ -52,3 +52,4 @@ The pages linked below contain the audit for all third party dependencies of ADF
- [ADF 7.0.0-alpha.6](audit-info-7.0.0-alpha.6.md)
- [ADF 7.0.0-alpha.7](audit-info-7.0.0-alpha.7.md)
- [ADF 7.0.0](audit-info-7.0.0.md)
- [ADF 7.0.1](audit-info-7.0.1.md)
+27
View File
@@ -0,0 +1,27 @@
---
Title: Audit info, alfresco-ng2-components 7.0.1
---
# Audit information for alfresco-ng2-components 7.0.1
This page lists the security audit of the dependencies this project depends on.
## Risks
- Critical risk: 0
- High risk: 1
- Moderate risk: 2
- Low risk: 1
Dependencies analyzed:
## Libraries
| Severity | Module | Vulnerable versions |
| --- | --- | --- |
|moderate | @babel/runtime | &#34;&lt;7.26.10&#34; |
|low | formidable | &#34;3.1.1-canary.20211030 - 3.5.2&#34; |
|moderate | http-proxy-middleware | &#34;1.3.0 - 2.0.8&#34; |
|high | pdfjs-dist | &#34;&lt;=4.1.392&#34; |
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@alfresco/adf-cli",
"version": "7.0.0",
"version": "7.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@alfresco/adf-cli",
"version": "7.0.0",
"version": "7.0.1",
"license": "Apache-2.0",
"dependencies": {
"@alfresco/js-api": ">=8.0.0-alpha.7-0",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-cli",
"description": "Alfresco ADF cli and utils",
"version": "7.0.0",
"version": "7.0.1",
"author": "Hyland Software, Inc. and its affiliates",
"bin": {
"adf-cli": "bin/adf-cli",
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-content-services",
"description": "Alfresco ADF content services",
"version": "7.0.0",
"version": "7.0.1",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -23,7 +23,7 @@
"@angular/router": ">=14.1.3",
"@alfresco/js-api": ">=8.0.0",
"@ngx-translate/core": ">=14.0.0",
"@alfresco/adf-core": ">=7.0.0"
"@alfresco/adf-core": ">=7.0.1"
},
"keywords": [
"content-services",
@@ -19,6 +19,7 @@ import { AlfrescoApiConfig } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { AppConfigService, AppConfigValues, StorageService } from '@alfresco/adf-core';
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
@@ -37,11 +38,12 @@ export class AlfrescoApiLoaderService {
constructor(
private readonly appConfig: AppConfigService,
private readonly apiService: AlfrescoApiService,
private readonly securityOptionsLoaderService: SecurityOptionsLoaderService,
private storageService: StorageService
) {}
async init(): Promise<any> {
await this.appConfig.load();
await this.appConfig.load(this.securityOptionsLoaderService.load);
return this.initAngularAlfrescoApi();
}
@@ -0,0 +1,73 @@
/*!
* @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();
});
});
@@ -0,0 +1,34 @@
/*!
* @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 });
}
};
}
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-core",
"description": "Alfresco ADF core",
"version": "7.0.0",
"version": "7.0.1",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -39,7 +39,7 @@
"@mat-datetimepicker/core": ">=12.0.1",
"@ngx-translate/core": ">=14.0.0",
"@alfresco/js-api": ">=8.0.0",
"@alfresco/adf-extensions": ">=7.0.0",
"@alfresco/adf-extensions": ">=7.0.1",
"minimatch": ">=10.0.0",
"pdfjs-dist": ">=3.3.122",
"ts-morph": ">=20.0.0"
@@ -0,0 +1,123 @@
/*!
* @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,6 +37,11 @@ export function loadAppConfig(
) {
const init = () => {
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, '');
storagePrefixFactory.getPrefix().subscribe((property) => {
@@ -146,7 +146,7 @@ describe('FormFieldModel', () => {
});
expect(field.options).toEqual([{ id: 'id_one', name: 'One' }]);
expect(field.value).toEqual('id_one');
expect(field.value).toEqual({ id: 'id_one', name: 'One' });
});
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.emptyOption).toEqual({ id: 'empty', name: 'Chose one...' });
expect(field.value).toEqual('empty');
expect(field.value).toEqual({ id: 'empty', name: 'Chose one...' });
});
it('should set hasEmptyValue to true if "empty" option is present in options', () => {
@@ -272,7 +272,8 @@ describe('FormFieldModel', () => {
options: [],
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' });
});
});
});
@@ -770,7 +771,7 @@ describe('FormFieldModel', () => {
];
});
it('should update form with selected option and options from which we chose', () => {
it('should update form with selected option and options from which we chose when is a string', () => {
field.value = 'restOpt2';
field.updateForm();
@@ -1023,7 +1024,7 @@ describe('FormFieldModel', () => {
expect(field.options).toEqual(staticOptions);
});
it('should selected option appear in form values', () => {
it('should selected option appear in form values string', () => {
const field = getFieldConfig('manual', staticOptions, 'opt2');
field.updateForm();
@@ -1031,6 +1032,15 @@ describe('FormFieldModel', () => {
expect(field.value).toEqual('opt2');
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', () => {
@@ -331,13 +331,13 @@ export class FormFieldModel extends FormWidgetModel {
const isEmptyValue = !value || [this.emptyOption.id, this.emptyOption.name].includes(value);
if (isEmptyValue) {
return this.emptyOption.id;
return this.emptyOption;
}
}
if (this.isValidOption(value)) {
this.addOption({ id: value.id, name: value.name });
return value.id;
return value;
}
if (this.hasMultipleValues) {
@@ -436,6 +436,17 @@ export class FormFieldModel extends FormWidgetModel {
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;
}
case FormFieldTypes.RADIO_BUTTONS: {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@alfresco/eslint-plugin-eslint-angular",
"version": "7.0.0",
"version": "7.0.1",
"description": "Alfresco ADF eslint angular custom rules",
"main": "main.js",
"author": "Hyland Software, Inc. and its affiliates",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-extensions",
"description": "Provides extensibility support for ADF applications.",
"version": "7.0.0",
"version": "7.0.1",
"license": "Apache-2.0",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-insights",
"description": "Alfresco ADF insights",
"version": "7.0.0",
"version": "7.0.1",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -11,8 +11,8 @@
"url": "https://github.com/Alfresco/alfresco-ng2-components/issues"
},
"dependencies": {
"@alfresco/adf-core": ">=7.0.0",
"@alfresco/adf-content-services": ">=7.0.0",
"@alfresco/adf-core": ">=7.0.1",
"@alfresco/adf-content-services": ">=7.0.1",
"@ngx-translate/core": ">=14.0.0",
"chart.js": "^4.3.0",
"ng2-charts": "^4.1.1",
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-process-services-cloud",
"description": "Alfresco ADF process services cloud",
"version": "7.0.0",
"version": "7.0.1",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -37,8 +37,8 @@
"@angular/platform-browser-dynamic": ">=14.1.3",
"@angular/router": ">=14.1.3",
"@alfresco/js-api": ">=8.0.0",
"@alfresco/adf-core": ">=7.0.0",
"@alfresco/adf-content-services": ">=7.0.0",
"@alfresco/adf-core": ">=7.0.1",
"@alfresco/adf-content-services": ">=7.0.1",
"@apollo/client": ">=3.7.2",
"@ngx-translate/core": ">=14.0.0",
"apollo-angular": ">=4.0.1",
@@ -953,6 +953,34 @@ describe('DropdownCloudWidgetComponent', () => {
expect(widget.field.options.length).toEqual(0);
};
it('should set dropdownControl value without emitting events if the mapping is a string', () => {
widget.field = {
value: 'testValue',
options: [],
isVisible: true
} as any; // Mock field
spyOn(widget.dropdownControl, 'setValue').and.callThrough();
widget['setFormControlValue']();
expect(widget.dropdownControl.setValue).toHaveBeenCalledWith({ id: 'testValue', name: '' }, { emitEvent: false });
expect(widget.dropdownControl.value).toEqual({ id: 'testValue', name: '' });
});
it('should set dropdownControl value without emitting events if is an object', () => {
widget.field = {
value: { id: 'testValueObj', name: 'testValueObjName' },
options: [],
isVisible: true
} as any; // Mock field
spyOn(widget.dropdownControl, 'setValue').and.callThrough();
widget['setFormControlValue']();
expect(widget.dropdownControl.setValue).toHaveBeenCalledWith({ id: 'testValueObj', name: 'testValueObjName' }, { emitEvent: false });
expect(widget.dropdownControl.value).toEqual({ id: 'testValueObj', name: 'testValueObjName' });
});
it('should display options persisted from process variable', async () => {
widget.field = getVariableDropdownWidget(
'variables.json-variable',
@@ -195,7 +195,15 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
}
private setFormControlValue(): void {
this.dropdownControl.setValue(this.field?.value, { emitEvent: false });
if (Array.isArray(this.field.value)) {
this.dropdownControl.setValue(this.field?.value, { emitEvent: false });
} else if (this.field?.value && typeof this.field?.value === 'object') {
this.dropdownControl.setValue({ id: this.field?.value.id, name: this.field?.value.name }, { emitEvent: false });
} else if (this.field.value === null) {
this.dropdownControl.setValue(this.field?.value, { emitEvent: false });
} else {
this.dropdownControl.setValue({ id: this.field?.value, name: '' }, { emitEvent: false });
}
}
private updateFormControlState(): void {
@@ -457,7 +465,11 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
const fieldValueIds = this.field.value.map((valueOption) => valueOption.id);
return fieldValueIds.every((valueOptionId) => optionIdList.includes(valueOptionId));
} else {
return [...this.field.options].map((option) => option.id).includes(this.field.value);
if (this.field?.value && typeof this.field?.value === 'object') {
return [...this.field.options].map((option) => option.id).includes(this.field.value.id);
} else {
return [...this.field.options].map((option) => option.id).includes(this.field.value);
}
}
}
@@ -0,0 +1,62 @@
/*!
* @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 { FormFieldModel } from '@alfresco/adf-core';
import { FormControl } from '@angular/forms';
import { defaultValueValidator } from './validators';
import { DEFAULT_OPTION } from './dropdown-cloud.widget';
describe('defaultValueValidator', () => {
let mockField: FormFieldModel;
beforeEach(() => {
mockField = new FormFieldModel(null, {
options: [
{ id: DEFAULT_OPTION.id, name: DEFAULT_OPTION.name },
{ id: 'opt_1', name: 'Option 1' },
{ id: 'opt_2', name: 'Option 2' }
]
});
});
it('should return null when a valid option is selected', () => {
const validator = defaultValueValidator(mockField);
const control = new FormControl({ id: 'opt_1' });
const result = validator(control);
expect(result).toBeNull();
});
it('should return a required error when no valid option is selected', () => {
const validator = defaultValueValidator(mockField);
const control = new FormControl(null);
const result = validator(control);
expect(result).toEqual({ required: true });
});
it('should return a required error when the default "choose one" option is selected', () => {
const validator = defaultValueValidator(mockField);
const control = new FormControl(DEFAULT_OPTION.id);
const result = validator(control);
expect(result).toEqual({ required: true });
});
});
@@ -30,6 +30,7 @@ export const defaultValueValidator =
const isSomeOptionSelected = optionsWithNoDefaultValue.some((dropdownOption) => {
const isOptionSelected = dropdownOption.id === control.value?.id;
return isOptionSelected;
});
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@alfresco/adf-process-services",
"description": "Alfresco ADF process services",
"version": "7.0.0",
"version": "7.0.1",
"author": "Hyland Software, Inc. and its affiliates",
"repository": {
"type": "git",
@@ -22,8 +22,8 @@
"@angular/platform-browser-dynamic": ">=14.1.3",
"@angular/router": ">=14.1.3",
"@alfresco/js-api": ">=8.0.0",
"@alfresco/adf-core": ">=7.0.0",
"@alfresco/adf-content-services": ">=7.0.0",
"@alfresco/adf-core": ">=7.0.1",
"@alfresco/adf-content-services": ">=7.0.1",
"@ngx-translate/core": ">=14.0.0"
},
"keywords": [
@@ -941,7 +941,7 @@ describe('FormComponent', () => {
let dropdownField = formFields.find((field) => field.id === 'dropdownId');
let radioField = formFields.find((field) => field.id === 'radio');
expect(dropdownField.value).toBe('empty');
expect(dropdownField.value).toEqual({ id: 'empty', name: 'Choose one...' });
expect(radioField.value).toBeNull();
const formValues: any = {};
@@ -961,7 +961,10 @@ describe('FormComponent', () => {
dropdownField = formFields.find((field) => field.id === 'dropdownId');
radioField = formFields.find((field) => field.id === 'radio');
expect(dropdownField.value).toBe('dropdown_option_2');
expect(dropdownField.value).toEqual({
id: 'dropdown_option_2',
name: 'Dropdown option 2'
});
expect(radioField.value).toBe('radio_option_3');
});
+3 -3
View File
@@ -1,12 +1,12 @@
{
"name": "alfresco-ng2-components",
"version": "7.0.0",
"version": "7.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "alfresco-ng2-components",
"version": "7.0.0",
"version": "7.0.1",
"license": "Apache-2.0",
"dependencies": {
"@angular/animations": "17.1.3",
@@ -169,7 +169,7 @@
},
"lib/eslint-angular": {
"name": "@alfresco/eslint-plugin-eslint-angular",
"version": "7.0.0",
"version": "7.0.1",
"dev": true,
"license": "Apache-2.0"
},
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "alfresco-ng2-components",
"description": "Alfresco Angular components",
"version": "7.0.0",
"version": "7.0.1",
"author": "Hyland Software, Inc. and its affiliates",
"scripts": {
"prepare": "husky install",