mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
migrate cloud components
This commit is contained in:
@@ -16,7 +16,17 @@
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, inject } from '@angular/core';
|
||||
import { AuthConfig, AUTH_CONFIG, OAuthErrorEvent, OAuthEvent, OAuthService, OAuthStorage, TokenResponse, LoginOptions, OAuthSuccessEvent } from 'angular-oauth2-oidc';
|
||||
import {
|
||||
AuthConfig,
|
||||
AUTH_CONFIG,
|
||||
OAuthErrorEvent,
|
||||
OAuthEvent,
|
||||
OAuthService,
|
||||
OAuthStorage,
|
||||
TokenResponse,
|
||||
LoginOptions,
|
||||
OAuthSuccessEvent
|
||||
} from 'angular-oauth2-oidc';
|
||||
import { JwksValidationHandler } from 'angular-oauth2-oidc-jwks';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { distinctUntilChanged, filter, map, shareReplay, take } from 'rxjs/operators';
|
||||
@@ -25,229 +35,230 @@ import { AUTH_MODULE_CONFIG, AuthModuleConfig } from './auth-config';
|
||||
|
||||
const isPromise = <T>(value: T | Promise<T>): value is Promise<T> => value && typeof (value as Promise<T>).then === 'function';
|
||||
|
||||
@Injectable()
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class RedirectAuthService extends AuthService {
|
||||
readonly authModuleConfig: AuthModuleConfig = inject(AUTH_MODULE_CONFIG);
|
||||
|
||||
readonly authModuleConfig: AuthModuleConfig = inject(AUTH_MODULE_CONFIG);
|
||||
onLogin: Observable<any>;
|
||||
|
||||
onLogin: Observable<any>;
|
||||
onTokenReceived: Observable<any>;
|
||||
|
||||
onTokenReceived: Observable<any>;
|
||||
private _loadDiscoveryDocumentPromise = Promise.resolve(false);
|
||||
|
||||
private _loadDiscoveryDocumentPromise = Promise.resolve(false);
|
||||
/** Subscribe to whether the user has valid Id/Access tokens. */
|
||||
authenticated$!: Observable<boolean>;
|
||||
|
||||
/** Subscribe to whether the user has valid Id/Access tokens. */
|
||||
authenticated$!: Observable<boolean>;
|
||||
/** Subscribe to errors reaching the IdP. */
|
||||
idpUnreachable$!: Observable<Error>;
|
||||
|
||||
/** Subscribe to errors reaching the IdP. */
|
||||
idpUnreachable$!: Observable<Error>;
|
||||
/**
|
||||
* Get whether the user has valid Id/Access tokens.
|
||||
*
|
||||
* @returns `true` if the user is authenticated, otherwise `false`
|
||||
*/
|
||||
get authenticated(): boolean {
|
||||
return this.oauthService.hasValidIdToken() && this.oauthService.hasValidAccessToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the user has valid Id/Access tokens.
|
||||
*
|
||||
* @returns `true` if the user is authenticated, otherwise `false`
|
||||
*/
|
||||
get authenticated(): boolean {
|
||||
return this.oauthService.hasValidIdToken() && this.oauthService.hasValidAccessToken();
|
||||
}
|
||||
private authConfig!: AuthConfig | Promise<AuthConfig>;
|
||||
|
||||
private authConfig!: AuthConfig | Promise<AuthConfig>;
|
||||
private readonly AUTH_STORAGE_ITEMS: string[] = [
|
||||
'access_token',
|
||||
'access_token_stored_at',
|
||||
'expires_at',
|
||||
'granted_scopes',
|
||||
'id_token',
|
||||
'id_token_claims_obj',
|
||||
'id_token_expires_at',
|
||||
'id_token_stored_at',
|
||||
'nonce',
|
||||
'PKCE_verifier',
|
||||
'refresh_token',
|
||||
'session_state'
|
||||
];
|
||||
|
||||
private readonly AUTH_STORAGE_ITEMS: string[] = [
|
||||
'access_token',
|
||||
'access_token_stored_at',
|
||||
'expires_at',
|
||||
'granted_scopes',
|
||||
'id_token',
|
||||
'id_token_claims_obj',
|
||||
'id_token_expires_at',
|
||||
'id_token_stored_at',
|
||||
'nonce',
|
||||
'PKCE_verifier',
|
||||
'refresh_token',
|
||||
'session_state'
|
||||
];
|
||||
constructor(private oauthService: OAuthService, private _oauthStorage: OAuthStorage, @Inject(AUTH_CONFIG) authConfig: AuthConfig) {
|
||||
super();
|
||||
this.authConfig = authConfig;
|
||||
|
||||
constructor(
|
||||
private oauthService: OAuthService,
|
||||
private _oauthStorage: OAuthStorage,
|
||||
@Inject(AUTH_CONFIG) authConfig: AuthConfig
|
||||
) {
|
||||
super();
|
||||
this.authConfig = authConfig;
|
||||
this.oauthService.clearHashAfterLogin = true;
|
||||
|
||||
this.oauthService.clearHashAfterLogin = true;
|
||||
this.authenticated$ = this.oauthService.events.pipe(
|
||||
map(() => this.authenticated),
|
||||
distinctUntilChanged(),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
this.authenticated$ = this.oauthService.events.pipe(
|
||||
map(() => this.authenticated),
|
||||
distinctUntilChanged(),
|
||||
shareReplay(1)
|
||||
);
|
||||
this.oauthService.events.pipe(take(1)).subscribe(() => {
|
||||
if (this.oauthService.getAccessToken() && !this.authenticated) {
|
||||
this.AUTH_STORAGE_ITEMS.map((item: string) => this._oauthStorage.removeItem(item));
|
||||
this.reloadPage();
|
||||
}
|
||||
});
|
||||
|
||||
this.oauthService.events.pipe(take(1)).subscribe(() => {
|
||||
if(this.oauthService.getAccessToken() && !this.authenticated){
|
||||
this.AUTH_STORAGE_ITEMS.map((item: string) => this._oauthStorage.removeItem(item));
|
||||
this.reloadPage();
|
||||
this.onLogin = this.authenticated$.pipe(
|
||||
filter((authenticated) => authenticated),
|
||||
map(() => undefined)
|
||||
);
|
||||
|
||||
this.onTokenReceived = this.oauthService.events.pipe(
|
||||
filter((event: OAuthEvent) => event.type === 'token_received'),
|
||||
map(() => undefined)
|
||||
);
|
||||
|
||||
this.idpUnreachable$ = this.oauthService.events.pipe(
|
||||
filter((event): event is OAuthErrorEvent => event.type === 'discovery_document_load_error'),
|
||||
map((event) => event.reason as Error)
|
||||
);
|
||||
}
|
||||
|
||||
init(): Promise<boolean> {
|
||||
if (isPromise(this.authConfig)) {
|
||||
return this.authConfig.then((config) => this.configureAuth(config));
|
||||
}
|
||||
});
|
||||
|
||||
this.onLogin = this.authenticated$.pipe(
|
||||
filter((authenticated) => authenticated),
|
||||
map(() => undefined)
|
||||
);
|
||||
|
||||
this.onTokenReceived = this.oauthService.events.pipe(
|
||||
filter((event: OAuthEvent) => event.type === 'token_received'),
|
||||
map(() => undefined)
|
||||
);
|
||||
|
||||
this.idpUnreachable$ = this.oauthService.events.pipe(
|
||||
filter((event): event is OAuthErrorEvent => event.type === 'discovery_document_load_error'),
|
||||
map((event) => event.reason as Error)
|
||||
);
|
||||
}
|
||||
|
||||
init(): Promise<boolean> {
|
||||
if (isPromise(this.authConfig)) {
|
||||
return this.authConfig.then((config) => this.configureAuth(config));
|
||||
return this.configureAuth(this.authConfig);
|
||||
}
|
||||
|
||||
return this.configureAuth(this.authConfig);
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.oauthService.logOut();
|
||||
}
|
||||
|
||||
ensureDiscoveryDocument(): Promise<boolean> {
|
||||
this._loadDiscoveryDocumentPromise = this._loadDiscoveryDocumentPromise
|
||||
.catch(() => false)
|
||||
.then((loaded) => {
|
||||
if (!loaded) {
|
||||
return this.oauthService.loadDiscoveryDocument().then(() => true);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return this._loadDiscoveryDocumentPromise;
|
||||
}
|
||||
|
||||
|
||||
login(currentUrl?: string): void {
|
||||
let stateKey: string | undefined;
|
||||
|
||||
if (currentUrl) {
|
||||
const randomValue = window.crypto.getRandomValues(new Uint32Array(1))[0];
|
||||
stateKey = `auth_state_${randomValue}${Date.now()}`;
|
||||
this._oauthStorage.setItem(stateKey, JSON.stringify(currentUrl || {}));
|
||||
}
|
||||
|
||||
// initLoginFlow will initialize the login flow in either code or implicit depending on the configuration
|
||||
this.ensureDiscoveryDocument().then(() => void this.oauthService.initLoginFlow(stateKey));
|
||||
}
|
||||
|
||||
baseAuthLogin(username: string, password: string): Observable<TokenResponse> {
|
||||
this.oauthService.useHttpBasicAuth = true;
|
||||
|
||||
return from(this.oauthService.fetchTokenUsingPasswordFlow(username, password)).pipe(
|
||||
map((response) => {
|
||||
const props = new Map<string, string>();
|
||||
props.set('id_token', response.id_token);
|
||||
// for backward compatibility we need to set the response in our storage
|
||||
this.oauthService['storeAccessTokenResponse'](response.access_token, response.refresh_token, response.expires_in, response.scope, props);
|
||||
return response;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async loginCallback(loginOptions?: LoginOptions): Promise<string | undefined> {
|
||||
return this.ensureDiscoveryDocument()
|
||||
.then(() => this.oauthService.tryLogin({ ...loginOptions, preventClearHashAfterLogin: this.authModuleConfig.preventClearHashAfterLogin }))
|
||||
.then(() => this._getRedirectUrl());
|
||||
}
|
||||
|
||||
private _getRedirectUrl() {
|
||||
const DEFAULT_REDIRECT = '/';
|
||||
const stateKey = this.oauthService.state;
|
||||
|
||||
if (stateKey) {
|
||||
const stateStringified = this._oauthStorage.getItem(stateKey);
|
||||
if (stateStringified) {
|
||||
// cleanup state from storage
|
||||
this._oauthStorage.removeItem(stateKey);
|
||||
return JSON.parse(stateStringified);
|
||||
}
|
||||
}
|
||||
|
||||
return DEFAULT_REDIRECT;
|
||||
}
|
||||
|
||||
private configureAuth(config: AuthConfig): Promise<boolean> {
|
||||
this.oauthService.configure(config);
|
||||
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
|
||||
|
||||
if (config.sessionChecksEnabled) {
|
||||
this.oauthService.events.pipe(filter((event) => event.type === 'session_terminated')).subscribe(() => {
|
||||
logout() {
|
||||
this.oauthService.logOut();
|
||||
});
|
||||
}
|
||||
|
||||
return this.ensureDiscoveryDocument().then(() => {
|
||||
this.oauthService.setupAutomaticSilentRefresh();
|
||||
return void this.allowRefreshTokenAndSilentRefreshOnMultipleTabs();
|
||||
}).catch(() => {
|
||||
// catch error to prevent the app from crashing when trying to access unprotected routes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix a known issue (https://github.com/manfredsteyer/angular-oauth2-oidc/issues/850)
|
||||
* where multiple tabs can cause the token refresh and the silent refresh to fail.
|
||||
* This patch is based on the solutions provided in the following comments:
|
||||
* https://github.com/manfredsteyer/angular-oauth2-oidc/issues/850#issuecomment-889921776 fix silent refresh for the implicit flow
|
||||
* https://github.com/manfredsteyer/angular-oauth2-oidc/issues/850#issuecomment-1557286966 fix refresh token for the code flow
|
||||
*/
|
||||
private allowRefreshTokenAndSilentRefreshOnMultipleTabs() {
|
||||
let lastUpdatedAccessToken: string | undefined;
|
||||
|
||||
if (this.oauthService.hasValidAccessToken()) {
|
||||
lastUpdatedAccessToken = this.oauthService.getAccessToken();
|
||||
ensureDiscoveryDocument(): Promise<boolean> {
|
||||
this._loadDiscoveryDocumentPromise = this._loadDiscoveryDocumentPromise
|
||||
.catch(() => false)
|
||||
.then((loaded) => {
|
||||
if (!loaded) {
|
||||
return this.oauthService.loadDiscoveryDocument().then(() => true);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return this._loadDiscoveryDocumentPromise;
|
||||
}
|
||||
|
||||
const originalRefreshToken = this.oauthService.refreshToken.bind(this.oauthService);
|
||||
this.oauthService.refreshToken = (): Promise<TokenResponse> =>
|
||||
navigator.locks.request(`refresh_tokens_${location.origin}`, () => {
|
||||
if (!!lastUpdatedAccessToken && lastUpdatedAccessToken !== this.oauthService.getAccessToken()) {
|
||||
(this.oauthService as any).eventsSubject.next(new OAuthSuccessEvent('token_received'));
|
||||
(this.oauthService as any).eventsSubject.next(new OAuthSuccessEvent('token_refreshed'));
|
||||
lastUpdatedAccessToken = this.oauthService.getAccessToken();
|
||||
return;
|
||||
login(currentUrl?: string): void {
|
||||
let stateKey: string | undefined;
|
||||
|
||||
if (currentUrl) {
|
||||
const randomValue = window.crypto.getRandomValues(new Uint32Array(1))[0];
|
||||
stateKey = `auth_state_${randomValue}${Date.now()}`;
|
||||
this._oauthStorage.setItem(stateKey, JSON.stringify(currentUrl || {}));
|
||||
}
|
||||
|
||||
// initLoginFlow will initialize the login flow in either code or implicit depending on the configuration
|
||||
this.ensureDiscoveryDocument().then(() => void this.oauthService.initLoginFlow(stateKey));
|
||||
}
|
||||
|
||||
baseAuthLogin(username: string, password: string): Observable<TokenResponse> {
|
||||
this.oauthService.useHttpBasicAuth = true;
|
||||
|
||||
return from(this.oauthService.fetchTokenUsingPasswordFlow(username, password)).pipe(
|
||||
map((response) => {
|
||||
const props = new Map<string, string>();
|
||||
props.set('id_token', response.id_token);
|
||||
// for backward compatibility we need to set the response in our storage
|
||||
this.oauthService['storeAccessTokenResponse'](
|
||||
response.access_token,
|
||||
response.refresh_token,
|
||||
response.expires_in,
|
||||
response.scope,
|
||||
props
|
||||
);
|
||||
return response;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async loginCallback(loginOptions?: LoginOptions): Promise<string | undefined> {
|
||||
return this.ensureDiscoveryDocument()
|
||||
.then(() => this.oauthService.tryLogin({ ...loginOptions, preventClearHashAfterLogin: this.authModuleConfig.preventClearHashAfterLogin }))
|
||||
.then(() => this._getRedirectUrl());
|
||||
}
|
||||
|
||||
private _getRedirectUrl() {
|
||||
const DEFAULT_REDIRECT = '/';
|
||||
const stateKey = this.oauthService.state;
|
||||
|
||||
if (stateKey) {
|
||||
const stateStringified = this._oauthStorage.getItem(stateKey);
|
||||
if (stateStringified) {
|
||||
// cleanup state from storage
|
||||
this._oauthStorage.removeItem(stateKey);
|
||||
return JSON.parse(stateStringified);
|
||||
}
|
||||
}
|
||||
|
||||
return originalRefreshToken().then((resp) => (lastUpdatedAccessToken = resp.access_token));
|
||||
});
|
||||
return DEFAULT_REDIRECT;
|
||||
}
|
||||
|
||||
const originalSilentRefresh = this.oauthService.silentRefresh.bind(this.oauthService);
|
||||
this.oauthService.silentRefresh = async (params: any = {}, noPrompt = true): Promise<OAuthEvent> =>
|
||||
navigator.locks.request(`silent_refresh_${location.origin}`, async (): Promise<OAuthEvent> => {
|
||||
if (lastUpdatedAccessToken !== this.oauthService.getAccessToken()) {
|
||||
(this.oauthService as any).eventsSubject.next(new OAuthSuccessEvent('token_received'));
|
||||
(this.oauthService as any).eventsSubject.next(new OAuthSuccessEvent('token_refreshed'));
|
||||
const event = new OAuthSuccessEvent('silently_refreshed');
|
||||
(this.oauthService as any).eventsSubject.next(event);
|
||||
lastUpdatedAccessToken = this.oauthService.getAccessToken();
|
||||
return event;
|
||||
} else {
|
||||
return originalSilentRefresh(params, noPrompt);
|
||||
}
|
||||
});
|
||||
}
|
||||
private configureAuth(config: AuthConfig): Promise<boolean> {
|
||||
this.oauthService.configure(config);
|
||||
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
|
||||
|
||||
updateIDPConfiguration(config: AuthConfig) {
|
||||
this.oauthService.configure(config);
|
||||
}
|
||||
if (config.sessionChecksEnabled) {
|
||||
this.oauthService.events.pipe(filter((event) => event.type === 'session_terminated')).subscribe(() => {
|
||||
this.oauthService.logOut();
|
||||
});
|
||||
}
|
||||
|
||||
reloadPage() {
|
||||
window.location.reload();
|
||||
}
|
||||
return this.ensureDiscoveryDocument()
|
||||
.then(() => {
|
||||
this.oauthService.setupAutomaticSilentRefresh();
|
||||
return void this.allowRefreshTokenAndSilentRefreshOnMultipleTabs();
|
||||
})
|
||||
.catch(() => {
|
||||
// catch error to prevent the app from crashing when trying to access unprotected routes
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix a known issue (https://github.com/manfredsteyer/angular-oauth2-oidc/issues/850)
|
||||
* where multiple tabs can cause the token refresh and the silent refresh to fail.
|
||||
* This patch is based on the solutions provided in the following comments:
|
||||
* https://github.com/manfredsteyer/angular-oauth2-oidc/issues/850#issuecomment-889921776 fix silent refresh for the implicit flow
|
||||
* https://github.com/manfredsteyer/angular-oauth2-oidc/issues/850#issuecomment-1557286966 fix refresh token for the code flow
|
||||
*/
|
||||
private allowRefreshTokenAndSilentRefreshOnMultipleTabs() {
|
||||
let lastUpdatedAccessToken: string | undefined;
|
||||
|
||||
if (this.oauthService.hasValidAccessToken()) {
|
||||
lastUpdatedAccessToken = this.oauthService.getAccessToken();
|
||||
}
|
||||
|
||||
const originalRefreshToken = this.oauthService.refreshToken.bind(this.oauthService);
|
||||
this.oauthService.refreshToken = (): Promise<TokenResponse> =>
|
||||
navigator.locks.request(`refresh_tokens_${location.origin}`, () => {
|
||||
if (!!lastUpdatedAccessToken && lastUpdatedAccessToken !== this.oauthService.getAccessToken()) {
|
||||
(this.oauthService as any).eventsSubject.next(new OAuthSuccessEvent('token_received'));
|
||||
(this.oauthService as any).eventsSubject.next(new OAuthSuccessEvent('token_refreshed'));
|
||||
lastUpdatedAccessToken = this.oauthService.getAccessToken();
|
||||
return;
|
||||
}
|
||||
|
||||
return originalRefreshToken().then((resp) => (lastUpdatedAccessToken = resp.access_token));
|
||||
});
|
||||
|
||||
const originalSilentRefresh = this.oauthService.silentRefresh.bind(this.oauthService);
|
||||
this.oauthService.silentRefresh = async (params: any = {}, noPrompt = true): Promise<OAuthEvent> =>
|
||||
navigator.locks.request(`silent_refresh_${location.origin}`, async (): Promise<OAuthEvent> => {
|
||||
if (lastUpdatedAccessToken !== this.oauthService.getAccessToken()) {
|
||||
(this.oauthService as any).eventsSubject.next(new OAuthSuccessEvent('token_received'));
|
||||
(this.oauthService as any).eventsSubject.next(new OAuthSuccessEvent('token_refreshed'));
|
||||
const event = new OAuthSuccessEvent('silently_refreshed');
|
||||
(this.oauthService as any).eventsSubject.next(event);
|
||||
lastUpdatedAccessToken = this.oauthService.getAccessToken();
|
||||
return event;
|
||||
} else {
|
||||
return originalSilentRefresh(params, noPrompt);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateIDPConfiguration(config: AuthConfig) {
|
||||
this.oauthService.configure(config);
|
||||
}
|
||||
|
||||
reloadPage() {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -19,6 +19,7 @@ import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-cloud-form-custom-outcomes',
|
||||
standalone: true,
|
||||
template: '<ng-content></ng-content>'
|
||||
})
|
||||
export class FormCustomOutcomesComponent {}
|
||||
|
||||
@@ -98,7 +98,7 @@ describe('FormCloudComponent', () => {
|
||||
const resolver = formRenderingService.getComponentTypeResolver(type);
|
||||
const widgetType = resolver(null);
|
||||
|
||||
const factoryResolver: ComponentFactoryResolver = TestBed.inject(ComponentFactoryResolver);
|
||||
const factoryResolver = TestBed.inject(ComponentFactoryResolver);
|
||||
const factory = factoryResolver.resolveComponentFactory(widgetType);
|
||||
const componentRef = factory.create(injector);
|
||||
|
||||
@@ -107,7 +107,7 @@ describe('FormCloudComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ProcessServiceCloudTestingModule],
|
||||
imports: [ProcessServiceCloudTestingModule, FormCloudComponent],
|
||||
providers: [
|
||||
{
|
||||
provide: VersionCompatibilityService,
|
||||
|
||||
@@ -44,7 +44,12 @@ import {
|
||||
ContentLinkModel,
|
||||
UploadWidgetContentLinkModel,
|
||||
FormEvent,
|
||||
ConfirmDialogComponent
|
||||
ConfirmDialogComponent,
|
||||
FormatSpacePipe,
|
||||
FormRendererComponent,
|
||||
ToolbarDividerComponent,
|
||||
ToolbarComponent,
|
||||
FormStylePipe
|
||||
} from '@alfresco/adf-core';
|
||||
import { FormCloudService } from '../services/form-cloud.service';
|
||||
import { TaskVariableCloud } from '../models/task-variable-cloud.model';
|
||||
@@ -54,9 +59,29 @@ import { v4 as uuidGeneration } from 'uuid';
|
||||
import { FormCloudDisplayMode, FormCloudDisplayModeConfiguration } from '../../services/form-fields.interfaces';
|
||||
import { FormCloudSpinnerService } from '../services/spinner/form-cloud-spinner.service';
|
||||
import { DisplayModeService } from '../services/display-mode.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { A11yModule } from '@angular/cdk/a11y';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-cloud-form',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
TranslateModule,
|
||||
FormatSpacePipe,
|
||||
MatButtonModule,
|
||||
MatCardModule,
|
||||
FormRendererComponent,
|
||||
MatIconModule,
|
||||
ToolbarDividerComponent,
|
||||
ToolbarComponent,
|
||||
A11yModule,
|
||||
FormStylePipe
|
||||
],
|
||||
templateUrl: './form-cloud.component.html',
|
||||
styleUrls: ['./form-cloud.component.scss']
|
||||
})
|
||||
|
||||
+1
-3
@@ -17,7 +17,6 @@
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { FormDefinitionSelectorCloudComponent } from './form-definition-selector-cloud.component';
|
||||
import { of } from 'rxjs';
|
||||
import { FormDefinitionSelectorCloudService } from '../services/form-definition-selector-cloud.service';
|
||||
@@ -33,8 +32,7 @@ describe('FormDefinitionCloudComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ProcessServiceCloudTestingModule],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
imports: [ProcessServiceCloudTestingModule, FormDefinitionSelectorCloudComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(FormDefinitionSelectorCloudComponent);
|
||||
service = TestBed.inject(FormDefinitionSelectorCloudService);
|
||||
|
||||
+8
-6
@@ -18,17 +18,21 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { FormDefinitionSelectorCloudService } from '../services/form-definition-selector-cloud.service';
|
||||
import { MatSelectChange } from '@angular/material/select';
|
||||
import { MatSelectChange, MatSelectModule } from '@angular/material/select';
|
||||
import { FormRepresentation } from '../../services/form-fields.interfaces';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatOptionModule } from '@angular/material/core';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-cloud-form-definition-selector',
|
||||
standalone: true,
|
||||
imports: [CommonModule, TranslateModule, MatOptionModule, MatFormFieldModule, MatSelectModule],
|
||||
templateUrl: './form-definition-selector-cloud.component.html',
|
||||
styleUrls: ['./form-definition-selector-cloud.component.scss']
|
||||
})
|
||||
|
||||
export class FormDefinitionSelectorCloudComponent implements OnInit {
|
||||
|
||||
/** Name of the application. If specified, this shows the users who have access to the app. */
|
||||
@Input()
|
||||
appName: string = '';
|
||||
@@ -39,8 +43,7 @@ export class FormDefinitionSelectorCloudComponent implements OnInit {
|
||||
|
||||
forms$: Observable<FormRepresentation[]>;
|
||||
|
||||
constructor(private formDefinitionCloudService: FormDefinitionSelectorCloudService) {
|
||||
}
|
||||
constructor(private formDefinitionCloudService: FormDefinitionSelectorCloudService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.forms$ = this.formDefinitionCloudService.getStandAloneTaskForms(this.appName);
|
||||
@@ -49,5 +52,4 @@ export class FormDefinitionSelectorCloudComponent implements OnInit {
|
||||
onSelect(event: MatSelectChange) {
|
||||
this.selectForm.emit(event.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
|
||||
import { FileViewerWidgetComponent } from './file-viewer.widget';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FormModel, FormService, FormFieldModel, NoopTranslateModule } from '@alfresco/adf-core';
|
||||
import { FormModel, FormService, FormFieldModel, NoopTranslateModule, NoopAuthModule } from '@alfresco/adf-core';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
|
||||
describe('FileViewerWidgetComponent', () => {
|
||||
@@ -43,7 +43,7 @@ describe('FileViewerWidgetComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [NoopTranslateModule, FileViewerWidgetComponent],
|
||||
imports: [NoopTranslateModule, NoopAuthModule, FileViewerWidgetComponent],
|
||||
providers: [{ provide: FormService, useValue: formServiceStub }],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
});
|
||||
|
||||
+1
-4
@@ -18,7 +18,6 @@
|
||||
import { FormFieldModel, FormFieldTypes, FormModel, IdentityUserModel } from '@alfresco/adf-core';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { PeopleCloudWidgetComponent } from './people-cloud.widget';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
|
||||
import { IdentityUserService } from '../../../../people/services/identity-user.service';
|
||||
import { mockShepherdsPie, mockYorkshirePudding } from '../../../../people/mock/people-cloud.mock';
|
||||
@@ -36,9 +35,7 @@ describe('PeopleCloudWidgetComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ProcessServiceCloudTestingModule],
|
||||
declarations: [PeopleCloudWidgetComponent],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
imports: [ProcessServiceCloudTestingModule, PeopleCloudWidgetComponent]
|
||||
});
|
||||
identityUserService = TestBed.inject(IdentityUserService);
|
||||
fixture = TestBed.createComponent(PeopleCloudWidgetComponent);
|
||||
|
||||
+8
-4
@@ -16,18 +16,23 @@
|
||||
*/
|
||||
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { WidgetComponent, FormService } from '@alfresco/adf-core';
|
||||
import { WidgetComponent, FormService, ErrorWidgetComponent } from '@alfresco/adf-core';
|
||||
import { UntypedFormControl } from '@angular/forms';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { ComponentSelectionMode } from '../../../../types';
|
||||
import { IdentityUserModel } from '../../../../people/models/identity-user.model';
|
||||
import { IdentityUserService } from '../../../../people/services/identity-user.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { PeopleCloudComponent } from '../../../../people/components/people-cloud.component';
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
@Component({
|
||||
selector: 'people-cloud-widget',
|
||||
standalone: true,
|
||||
imports: [CommonModule, TranslateModule, ErrorWidgetComponent, PeopleCloudComponent],
|
||||
templateUrl: './people-cloud.widget.html',
|
||||
host: {
|
||||
'(click)': 'event($event)',
|
||||
@@ -43,7 +48,6 @@ import { IdentityUserService } from '../../../../people/services/identity-user.s
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class PeopleCloudWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
typeId = 'PeopleCloudWidgetComponent';
|
||||
@@ -70,7 +74,7 @@ export class PeopleCloudWidgetComponent extends WidgetComponent implements OnIni
|
||||
this.validate = this.field.readOnly ? false : true;
|
||||
}
|
||||
|
||||
this.search = new UntypedFormControl({value: '', disabled: this.field.readOnly}, []);
|
||||
this.search = new UntypedFormControl({ value: '', disabled: this.field.readOnly }, []);
|
||||
|
||||
this.search.statusChanges
|
||||
.pipe(
|
||||
@@ -94,7 +98,7 @@ export class PeopleCloudWidgetComponent extends WidgetComponent implements OnIni
|
||||
|
||||
if (this.field.selectLoggedUser && !this.field.value) {
|
||||
const userInfo = this.identityUserService.getCurrentUserInfo();
|
||||
this.preSelectUsers = [ userInfo ];
|
||||
this.preSelectUsers = [userInfo];
|
||||
this.onChangedUser(this.preSelectUsers);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -16,13 +16,17 @@
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
||||
import { PresetConfig, NodesApiService } from '@alfresco/adf-content-services';
|
||||
import { PresetConfig, NodesApiService, ContentMetadataComponent } from '@alfresco/adf-content-services';
|
||||
import { Node } from '@alfresco/js-api';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
@Component({
|
||||
selector: 'adf-properties-viewer-wrapper',
|
||||
standalone: true,
|
||||
imports: [CommonModule, ContentMetadataComponent, MatProgressSpinnerModule],
|
||||
templateUrl: './properties-viewer-wrapper.component.html',
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ describe('PropertiesViewerWidgetComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ProcessServiceCloudTestingModule],
|
||||
imports: [ProcessServiceCloudTestingModule, PropertiesViewerWrapperComponent],
|
||||
providers: [NodesApiService, { provide: BasicPropertiesService, useValue: { getProperties: () => [] } }]
|
||||
});
|
||||
fixture = TestBed.createComponent(PropertiesViewerWrapperComponent);
|
||||
|
||||
+1
-2
@@ -47,8 +47,7 @@ describe('PropertiesViewerWidgetComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ProcessServiceCloudTestingModule],
|
||||
declarations: [PropertiesViewerWrapperComponent],
|
||||
imports: [ProcessServiceCloudTestingModule, PropertiesViewerWrapperComponent],
|
||||
providers: [NodesApiService, { provide: BasicPropertiesService, useValue: { getProperties: () => [] } }]
|
||||
});
|
||||
fixture = TestBed.createComponent(PropertiesViewerWidgetComponent);
|
||||
|
||||
+6
-2
@@ -16,13 +16,18 @@
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { BaseViewerWidgetComponent, FormService } from '@alfresco/adf-core';
|
||||
import { BaseViewerWidgetComponent, ErrorWidgetComponent, FormService } from '@alfresco/adf-core';
|
||||
import { Node } from '@alfresco/js-api';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { PropertiesViewerWrapperComponent } from './properties-viewer-wrapper/properties-viewer-wrapper.component';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
@Component({
|
||||
selector: 'adf-properties-viewer-widget',
|
||||
standalone: true,
|
||||
imports: [CommonModule, PropertiesViewerWrapperComponent, ErrorWidgetComponent, TranslateModule],
|
||||
templateUrl: './properties-viewer.widget.html',
|
||||
styleUrls: ['./properties-viewer.widget.scss'],
|
||||
host: {
|
||||
@@ -39,7 +44,6 @@ import { Node } from '@alfresco/js-api';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class PropertiesViewerWidgetComponent extends BaseViewerWidgetComponent {
|
||||
|
||||
@Output()
|
||||
nodeContentLoaded: EventEmitter<Node> = new EventEmitter();
|
||||
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ describe('RadioButtonsCloudWidgetComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ProcessServiceCloudTestingModule]
|
||||
imports: [ProcessServiceCloudTestingModule, RadioButtonsCloudWidgetComponent]
|
||||
});
|
||||
formCloudService = TestBed.inject(FormCloudService);
|
||||
fixture = TestBed.createComponent(RadioButtonsCloudWidgetComponent);
|
||||
|
||||
+7
-2
@@ -18,14 +18,19 @@
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { WidgetComponent, FormService, FormFieldOption, ErrorMessageModel } from '@alfresco/adf-core';
|
||||
import { WidgetComponent, FormService, FormFieldOption, ErrorMessageModel, ErrorWidgetComponent } from '@alfresco/adf-core';
|
||||
import { FormCloudService } from '../../../services/form-cloud.service';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'radio-buttons-cloud-widget',
|
||||
standalone: true,
|
||||
imports: [CommonModule, TranslateModule, ErrorWidgetComponent, MatRadioModule, FormsModule],
|
||||
templateUrl: './radio-buttons-cloud.widget.html',
|
||||
styleUrls: ['./radio-buttons-cloud.widget.scss'],
|
||||
host: {
|
||||
|
||||
@@ -32,9 +32,7 @@ import {
|
||||
import { GroupCloudWidgetComponent } from './components/widgets/group/group-cloud.widget';
|
||||
import { PeopleCloudWidgetComponent } from './components/widgets/people/people-cloud.widget';
|
||||
import { AttachFileCloudWidgetComponent } from './components/widgets/attach-file/attach-file-cloud-widget.component';
|
||||
|
||||
import { UploadCloudWidgetComponent } from './components/widgets/attach-file/upload-cloud.widget';
|
||||
import { PeopleCloudModule } from '../people/people-cloud.module';
|
||||
import { GroupCloudModule } from '../group/group-cloud.module';
|
||||
import { PropertiesViewerWidgetComponent } from './components/widgets/properties-viewer/properties-viewer.widget';
|
||||
import { PropertiesViewerWrapperComponent } from './components/widgets/properties-viewer/properties-viewer-wrapper/properties-viewer-wrapper.component';
|
||||
@@ -46,6 +44,7 @@ import { RichTextEditorModule } from '../rich-text-editor';
|
||||
import { A11yModule } from '@angular/cdk/a11y';
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
import { FormSpinnerComponent } from './components/spinner/form-spinner.component';
|
||||
import { PeopleCloudComponent } from '../people/components/people-cloud.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -56,7 +55,7 @@ import { FormSpinnerComponent } from './components/spinner/form-spinner.componen
|
||||
ReactiveFormsModule,
|
||||
CoreModule,
|
||||
ContentNodeSelectorModule,
|
||||
PeopleCloudModule,
|
||||
PeopleCloudComponent,
|
||||
GroupCloudModule,
|
||||
RichTextEditorModule,
|
||||
...TOOLBAR_DIRECTIVES,
|
||||
@@ -72,16 +71,14 @@ import { FormSpinnerComponent } from './components/spinner/form-spinner.componen
|
||||
FilePropertiesTableCloudComponent,
|
||||
DisplayRichTextWidgetComponent,
|
||||
FileViewerWidgetComponent,
|
||||
GroupCloudWidgetComponent
|
||||
],
|
||||
declarations: [
|
||||
FormCloudComponent,
|
||||
FormDefinitionSelectorCloudComponent,
|
||||
GroupCloudWidgetComponent,
|
||||
PeopleCloudWidgetComponent,
|
||||
FormCustomOutcomesComponent,
|
||||
RadioButtonsCloudWidgetComponent,
|
||||
PeopleCloudWidgetComponent,
|
||||
FormDefinitionSelectorCloudComponent,
|
||||
PropertiesViewerWrapperComponent,
|
||||
PropertiesViewerWidgetComponent
|
||||
PropertiesViewerWidgetComponent,
|
||||
FormCloudComponent
|
||||
],
|
||||
exports: [
|
||||
FormCloudComponent,
|
||||
|
||||
@@ -47,6 +47,7 @@ import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatChipsModule } from '@angular/material/chips';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { InitialGroupNamePipe } from '../pipe/group-initial.pipe';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-cloud-group',
|
||||
@@ -62,7 +63,8 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
MatChipsModule,
|
||||
MatInputModule,
|
||||
ReactiveFormsModule,
|
||||
MatButtonModule
|
||||
MatButtonModule,
|
||||
InitialGroupNamePipe
|
||||
],
|
||||
templateUrl: './group-cloud.component.html',
|
||||
styleUrls: ['./group-cloud.component.scss'],
|
||||
|
||||
@@ -83,7 +83,7 @@ describe('PeopleCloudComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule, ProcessServiceCloudTestingModule, PeopleCloudModule]
|
||||
imports: [CoreTestingModule, ProcessServiceCloudTestingModule, PeopleCloudModule, PeopleCloudComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(PeopleCloudComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { UntypedFormControl } from '@angular/forms';
|
||||
import { ReactiveFormsModule, UntypedFormControl } from '@angular/forms';
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
@@ -33,16 +33,37 @@ import {
|
||||
} from '@angular/core';
|
||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||
import { switchMap, debounceTime, distinctUntilChanged, mergeMap, tap, filter, takeUntil } from 'rxjs/operators';
|
||||
import { FullNamePipe } from '@alfresco/adf-core';
|
||||
import { FullNamePipe, InitialUsernamePipe } from '@alfresco/adf-core';
|
||||
import { trigger, state, style, transition, animate } from '@angular/animations';
|
||||
import { ComponentSelectionMode } from '../../types';
|
||||
import { IdentityUserModel } from '../models/identity-user.model';
|
||||
import { IdentityUserServiceInterface } from '../services/identity-user.service.interface';
|
||||
import { IDENTITY_USER_SERVICE_TOKEN } from '../services/identity-user-service.token';
|
||||
import { MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-field';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatChipsModule } from '@angular/material/chips';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { IdentityUserService } from '../services/identity-user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-cloud-people',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
TranslateModule,
|
||||
MatIconModule,
|
||||
MatChipsModule,
|
||||
MatInputModule,
|
||||
FullNamePipe,
|
||||
ReactiveFormsModule,
|
||||
MatAutocompleteModule,
|
||||
InitialUsernamePipe,
|
||||
MatProgressBarModule
|
||||
],
|
||||
templateUrl: './people-cloud.component.html',
|
||||
styleUrls: ['./people-cloud.component.scss'],
|
||||
animations: [
|
||||
@@ -51,7 +72,7 @@ import { MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-
|
||||
transition('void => enter', [style({ opacity: 0, transform: 'translateY(-100%)' }), animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)')])
|
||||
])
|
||||
],
|
||||
providers: [FullNamePipe],
|
||||
providers: [FullNamePipe, { provide: IDENTITY_USER_SERVICE_TOKEN, useExisting: IdentityUserService }],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class PeopleCloudComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit {
|
||||
|
||||
@@ -17,17 +17,12 @@
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { PeopleCloudComponent } from './components/people-cloud.component';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MaterialModule } from '../material.module';
|
||||
import { CoreModule, FullNamePipe, InitialUsernamePipe } from '@alfresco/adf-core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { IdentityUserService } from './services/identity-user.service';
|
||||
import { IDENTITY_USER_SERVICE_TOKEN } from './services/identity-user-service.token';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
|
||||
/** @deprecated Use `PeopleCloudComponent` instead */
|
||||
@NgModule({
|
||||
imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, CoreModule, FullNamePipe, InitialUsernamePipe, MatProgressBarModule],
|
||||
declarations: [PeopleCloudComponent],
|
||||
imports: [PeopleCloudComponent],
|
||||
exports: [PeopleCloudComponent],
|
||||
providers: [{ provide: IDENTITY_USER_SERVICE_TOKEN, useExisting: IdentityUserService }]
|
||||
})
|
||||
|
||||
@@ -31,11 +31,11 @@ import {
|
||||
PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN,
|
||||
TASK_LIST_PREFERENCES_SERVICE_TOKEN
|
||||
} from './services/public-api';
|
||||
import { PeopleCloudModule } from './people/people-cloud.module';
|
||||
import { CloudFormRenderingService } from './form/components/cloud-form-rendering.service';
|
||||
import { ApolloModule } from 'apollo-angular';
|
||||
import { RichTextEditorModule } from './rich-text-editor/rich-text-editor.module';
|
||||
import { ProcessNameCloudPipe } from './pipes/process-name-cloud.pipe';
|
||||
import { PeopleCloudComponent } from './people/components/people-cloud.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -44,7 +44,7 @@ import { ProcessNameCloudPipe } from './pipes/process-name-cloud.pipe';
|
||||
ProcessCloudModule,
|
||||
TaskCloudModule,
|
||||
GroupCloudModule,
|
||||
PeopleCloudModule,
|
||||
PeopleCloudComponent,
|
||||
FormCloudModule,
|
||||
TaskFormModule,
|
||||
ProcessNameCloudPipe,
|
||||
@@ -59,7 +59,7 @@ import { ProcessNameCloudPipe } from './pipes/process-name-cloud.pipe';
|
||||
GroupCloudModule,
|
||||
FormCloudModule,
|
||||
TaskFormModule,
|
||||
PeopleCloudModule,
|
||||
PeopleCloudComponent,
|
||||
ProcessNameCloudPipe,
|
||||
RichTextEditorModule
|
||||
]
|
||||
|
||||
@@ -23,23 +23,11 @@ import { StartTaskCloudComponent } from './components/start-task-cloud.component
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { GroupCloudModule } from '../../group/group-cloud.module';
|
||||
import { FormCloudModule } from '../../form/form-cloud.module';
|
||||
import { PeopleCloudModule } from '../../people/people-cloud.module';
|
||||
import { PeopleCloudComponent } from '../../people/components/people-cloud.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
MaterialModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
GroupCloudModule,
|
||||
CoreModule,
|
||||
FormCloudModule,
|
||||
PeopleCloudModule
|
||||
],
|
||||
imports: [CommonModule, MaterialModule, FormsModule, ReactiveFormsModule, GroupCloudModule, CoreModule, FormCloudModule, PeopleCloudComponent],
|
||||
declarations: [StartTaskCloudComponent],
|
||||
exports: [
|
||||
StartTaskCloudComponent
|
||||
]
|
||||
exports: [StartTaskCloudComponent]
|
||||
})
|
||||
export class StartTaskCloudModule {
|
||||
}
|
||||
export class StartTaskCloudModule {}
|
||||
|
||||
@@ -23,7 +23,6 @@ import { MaterialModule } from '../../material.module';
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { APP_LIST_CLOUD_DIRECTIVES } from './../../app/app-list-cloud.module';
|
||||
import { PeopleCloudModule } from '../../people/people-cloud.module';
|
||||
import { EditServiceTaskFilterCloudComponent } from './components/edit-task-filters/edit-service-task-filter-cloud.component';
|
||||
import { EditTaskFilterCloudComponent } from './components/edit-task-filters/edit-task-filter-cloud.component';
|
||||
import { TaskFilterDialogCloudComponent } from './components/task-filter-dialog/task-filter-dialog-cloud.component';
|
||||
@@ -32,6 +31,7 @@ import { TaskAssignmentFilterCloudComponent } from './components/task-assignment
|
||||
import { GroupCloudModule } from '../../group/group-cloud.module';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { DateRangeFilterComponent } from '../../common/date-range-filter/date-range-filter.component';
|
||||
import { PeopleCloudComponent } from '../../people/components/people-cloud.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -44,7 +44,7 @@ import { DateRangeFilterComponent } from '../../common/date-range-filter/date-ra
|
||||
CoreModule,
|
||||
GroupCloudModule,
|
||||
DateRangeFilterComponent,
|
||||
PeopleCloudModule,
|
||||
PeopleCloudComponent,
|
||||
MatProgressSpinnerModule
|
||||
],
|
||||
declarations: [
|
||||
|
||||
+1
-2
@@ -68,8 +68,7 @@ describe('TaskFormCloudComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ProcessServiceCloudTestingModule],
|
||||
declarations: [FormCloudComponent]
|
||||
imports: [ProcessServiceCloudTestingModule, FormCloudComponent]
|
||||
});
|
||||
taskDetails.status = TASK_ASSIGNED_STATE;
|
||||
taskDetails.permissions = [TASK_VIEW_PERMISSION];
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
import { FileViewerWidgetComponent } from './file-viewer.widget';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FormModel, FormService, FormFieldModel, RedirectAuthService, NoopTranslateModule } from '@alfresco/adf-core';
|
||||
import { FormModel, FormService, FormFieldModel, RedirectAuthService, NoopTranslateModule, NoopAuthModule } from '@alfresco/adf-core';
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { EMPTY, of } from 'rxjs';
|
||||
|
||||
@@ -44,7 +44,7 @@ describe('FileViewerWidgetComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [NoopTranslateModule, FileViewerWidgetComponent],
|
||||
imports: [NoopTranslateModule, NoopAuthModule, FileViewerWidgetComponent],
|
||||
providers: [
|
||||
{ provide: FormService, useValue: formServiceStub },
|
||||
{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } }
|
||||
|
||||
Reference in New Issue
Block a user