diff --git a/package-lock.json b/package-lock.json index ef4fdf1..106de38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@typescript-eslint/eslint-plugin": "^5.36.2", "@typescript-eslint/parser": "^5.36.2", "ajv-keywords": "5.1.0", - "arlas-wui-toolkit": "24.3.0-beta.11", + "arlas-wui-toolkit": "24.3.0-beta.14", "eslint": "^8.2.0", "js-yaml": "4.1.0", "ngx-toastr": "~14.3.0", @@ -5165,9 +5165,9 @@ } }, "node_modules/arlas-web-components": { - "version": "24.3.0-beta.7", - "resolved": "https://registry.npmjs.org/arlas-web-components/-/arlas-web-components-24.3.0-beta.7.tgz", - "integrity": "sha512-c7TryiEpfQ/s6CW3pMRp+n9R3nCMjI5dIE4tp7kLve+AU73fnxLCb2I/+liTqacbwwy4pohDRqZHvWs7a8hVBQ==", + "version": "24.3.0-beta.8", + "resolved": "https://registry.npmjs.org/arlas-web-components/-/arlas-web-components-24.3.0-beta.8.tgz", + "integrity": "sha512-Fsu14JFepLODkJuDtEfn0MYQx3m3AyOWMhTZBBj4v0U06NVMo9XbZqps4yJ8mMEid/Fe9Ym/or0j2tRlBI+T3w==", "dependencies": { "@mapbox/mapbox-gl-draw": "1.3.0", "@mapbox/mapbox-gl-draw-static-mode": "^1.0.1", @@ -5247,9 +5247,9 @@ } }, "node_modules/arlas-wui-toolkit": { - "version": "24.3.0-beta.11", - "resolved": "https://registry.npmjs.org/arlas-wui-toolkit/-/arlas-wui-toolkit-24.3.0-beta.11.tgz", - "integrity": "sha512-5uVlBBj5QVomSsgWUN5eLM+9R4uUFpg/xfxayeccgASvy0oyx+z74Gd6weEe6kcQGB+XUZGmS6WsY3QDqqwIHA==", + "version": "24.3.0-beta.14", + "resolved": "https://registry.npmjs.org/arlas-wui-toolkit/-/arlas-wui-toolkit-24.3.0-beta.14.tgz", + "integrity": "sha512-02k/QHuMuQIs+TQf/Ie1vEhiY43LNr0j+FIXOoe/pAnQm+nEa04QwBNJS4c37LD4x3OuNJXfAtTRYo9XBPlxYg==", "dependencies": { "@danielmoncada/angular-datetime-picker": "14.2.0", "@danielmoncada/angular-datetime-picker-moment-adapter": "~2.2.0", @@ -5261,7 +5261,7 @@ "arlas-permissions-api": "~24.0.0", "arlas-persistence-api": "~24.0.0", "arlas-tagger-api": "~24.0.1", - "arlas-web-components": "~24.3.0-beta.7", + "arlas-web-components": "~24.3.0-beta.8", "arlas-web-contributors": "~24.1.3", "cli-color": "^1.2.0", "fetch-intercept": "^2.3.1", @@ -21638,9 +21638,9 @@ } }, "arlas-web-components": { - "version": "24.3.0-beta.7", - "resolved": "https://registry.npmjs.org/arlas-web-components/-/arlas-web-components-24.3.0-beta.7.tgz", - "integrity": "sha512-c7TryiEpfQ/s6CW3pMRp+n9R3nCMjI5dIE4tp7kLve+AU73fnxLCb2I/+liTqacbwwy4pohDRqZHvWs7a8hVBQ==", + "version": "24.3.0-beta.8", + "resolved": "https://registry.npmjs.org/arlas-web-components/-/arlas-web-components-24.3.0-beta.8.tgz", + "integrity": "sha512-Fsu14JFepLODkJuDtEfn0MYQx3m3AyOWMhTZBBj4v0U06NVMo9XbZqps4yJ8mMEid/Fe9Ym/or0j2tRlBI+T3w==", "requires": { "@mapbox/mapbox-gl-draw": "1.3.0", "@mapbox/mapbox-gl-draw-static-mode": "^1.0.1", @@ -21701,9 +21701,9 @@ } }, "arlas-wui-toolkit": { - "version": "24.3.0-beta.11", - "resolved": "https://registry.npmjs.org/arlas-wui-toolkit/-/arlas-wui-toolkit-24.3.0-beta.11.tgz", - "integrity": "sha512-5uVlBBj5QVomSsgWUN5eLM+9R4uUFpg/xfxayeccgASvy0oyx+z74Gd6weEe6kcQGB+XUZGmS6WsY3QDqqwIHA==", + "version": "24.3.0-beta.14", + "resolved": "https://registry.npmjs.org/arlas-wui-toolkit/-/arlas-wui-toolkit-24.3.0-beta.14.tgz", + "integrity": "sha512-02k/QHuMuQIs+TQf/Ie1vEhiY43LNr0j+FIXOoe/pAnQm+nEa04QwBNJS4c37LD4x3OuNJXfAtTRYo9XBPlxYg==", "requires": { "@danielmoncada/angular-datetime-picker": "14.2.0", "@danielmoncada/angular-datetime-picker-moment-adapter": "~2.2.0", @@ -21715,7 +21715,7 @@ "arlas-permissions-api": "~24.0.0", "arlas-persistence-api": "~24.0.0", "arlas-tagger-api": "~24.0.1", - "arlas-web-components": "~24.3.0-beta.7", + "arlas-web-components": "~24.3.0-beta.8", "arlas-web-contributors": "~24.1.3", "cli-color": "^1.2.0", "fetch-intercept": "^2.3.1", diff --git a/package.json b/package.json index 2b6a0be..f8fda89 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@typescript-eslint/eslint-plugin": "^5.36.2", "@typescript-eslint/parser": "^5.36.2", "ajv-keywords": "5.1.0", - "arlas-wui-toolkit": "24.3.0-beta.11", + "arlas-wui-toolkit": "24.3.0-beta.14", "eslint": "^8.2.0", "js-yaml": "4.1.0", "patch-package": "^6.4.7", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ebd39e0..1ad85a3 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -26,9 +26,10 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; import { ArlasCollaborativesearchService, ArlasConfigurationDescriptor, ArlasIamService, + ArlasSettingsService, ArlasStartupService, ArlasToolkitSharedModule, AuthentificationService, CONFIG_UPDATER, - FETCH_OPTIONS, GET_OPTIONS, LoginModule, configUpdaterFactory, getOptionsFactory + FETCH_OPTIONS, GET_OPTIONS, LoginModule, PersistenceService, configUpdaterFactory, getOptionsFactory } from 'arlas-wui-toolkit'; import { ToastrModule } from 'ngx-toastr'; import { AppRoutingModule } from './app-routing.module'; @@ -53,6 +54,7 @@ import { UserAddComponent } from './components/user/user-add/user-add.component' import { UserFormComponent } from './components/user/user-form/user-form.component'; import { UserComponent } from './components/user/user.component'; import { IamStartupService } from './services/startup/startup.service'; +import { ArlasTranslateLoader } from '@tools/customLoader'; export function startupServiceFactory(startup: IamStartupService) { const load = () => startup.load(); @@ -63,10 +65,6 @@ export function auhtentServiceFactory(service: AuthentificationService) { return service; } -export function createTranslateLoader(http: HttpClient) { - return new TranslateHttpLoader(http, 'assets/i18n/', '.json'); -} - @NgModule({ declarations: [ AppComponent, @@ -117,8 +115,8 @@ export function createTranslateLoader(http: HttpClient) { TranslateModule.forRoot({ loader: { provide: TranslateLoader, - useFactory: (createTranslateLoader), - deps: [HttpClient] + useClass: ArlasTranslateLoader, + deps: [HttpClient, ArlasSettingsService, PersistenceService] } }), ToastrModule.forRoot({ diff --git a/src/app/components/home/home.component.html b/src/app/components/home/home.component.html index 66eb5cc..2df006f 100644 --- a/src/app/components/home/home.component.html +++ b/src/app/components/home/home.component.html @@ -1,11 +1,11 @@
{{'ARLAS IAM' | translate}}
-
+
-
+
{{'Organisation'| translate}} @@ -24,7 +24,7 @@ {{'Home' | translate}} - person @@ -32,7 +32,7 @@ {{'Users' | translate}} - group @@ -40,7 +40,7 @@ {{'Groups'| translate}} - verified_user @@ -48,7 +48,7 @@ {{'Permissions'| translate}} - rule @@ -58,20 +58,6 @@ - -
diff --git a/src/app/components/home/home.component.scss b/src/app/components/home/home.component.scss index 6c27087..9a88ee8 100644 --- a/src/app/components/home/home.component.scss +++ b/src/app/components/home/home.component.scss @@ -4,16 +4,28 @@ background-color: $primaryColor !important; padding: 0 10px !important; color: white; - .orga { - font-size: medium; - font-weight: 300; - padding-right: 15px; - - .current-orga { - width: 150px; - background-color: white; - color: black; - padding: 0 5px; + .right-menu { + display: flex; + align-items: baseline; + gap: 0 5px; + .create-org { + padding-right: 15px; + .add-org { + line-height: 32px; + vertical-align: bottom; + } + } + .orga { + font-size: medium; + font-weight: 300; + padding-right: 15px; + + .current-orga { + width: 150px; + background-color: white; + color: black; + padding: 0 5px; + } } } } @@ -45,6 +57,9 @@ } .mat-list-item { color: #28292b; + &.mat-list-item-disabled { + cursor: not-allowed !important; + } } .mat-list-item-content { margin: 15px !important; diff --git a/src/app/components/user/user-add/user-add.component.scss b/src/app/components/user/user-add/user-add.component.scss index 1296443..0096f06 100644 --- a/src/app/components/user/user-add/user-add.component.scss +++ b/src/app/components/user/user-add/user-add.component.scss @@ -5,6 +5,11 @@ display: flex; flex-direction: column; + mat-form-field { + width: fit-content; + min-width: 400px; + } + .owner{ padding: 0 0 15px 10px; } diff --git a/src/app/components/user/user-add/user-add.component.ts b/src/app/components/user/user-add/user-add.component.ts index 1a5f675..bc7aaf5 100644 --- a/src/app/components/user/user-add/user-add.component.ts +++ b/src/app/components/user/user-add/user-add.component.ts @@ -81,6 +81,9 @@ export class UserAddComponent implements OnInit, OnDestroy { if (err.status === 404) { this.toastr.error(this.translate.instant('User not found')); } + if (err.status === 400) { + this.toastr.error(this.translate.instant('User is already in organisation')); + } } }); } diff --git a/src/app/services/startup/startup.service.ts b/src/app/services/startup/startup.service.ts index a49ddfe..8e73737 100644 --- a/src/app/services/startup/startup.service.ts +++ b/src/app/services/startup/startup.service.ts @@ -87,15 +87,22 @@ export class IamStartupService { next: loginData => { if (!!loginData) { const storedArlasOrganisation = this.arlasIamService.getOrganisation(); - const org = !!storedArlasOrganisation ? storedArlasOrganisation : loginData.user?.organisations[0]?.name; + const org = !!storedArlasOrganisation ? storedArlasOrganisation + : (!!loginData.user?.organisations[0] ? loginData.user?.organisations[0].name : null); this.arlasIamService.setHeaders(org, loginData.accessToken); + const iamHeader = { + Authorization: 'Bearer ' + loginData.accessToken, + }; + // Set the org filter only if the organisation is defined + if (!!org) { + // @ts-ignore + iamHeader['arlas-org-filter'] = org; + } + this.managerService.setOptions({ - headers: { - Authorization: 'Bearer ' + loginData.accessToken, - 'arlas-org-filter': org - } + headers: iamHeader }); } return Promise.resolve(data); diff --git a/src/app/tools/customLoader.ts b/src/app/tools/customLoader.ts new file mode 100644 index 0000000..eabd429 --- /dev/null +++ b/src/app/tools/customLoader.ts @@ -0,0 +1,101 @@ +/* + * Licensed to Gisaïa under one or more contributor + * license agreements. See the NOTICE.txt file distributed with + * this work for additional information regarding copyright + * ownership. Gisaïa licenses this file to you 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 { HttpClient } from '@angular/common/http'; +import { TranslateLoader } from '@ngx-translate/core'; +import enComponents from 'arlas-web-components/assets/i18n/en.json'; +import frComponents from 'arlas-web-components/assets/i18n/fr.json'; +import { ArlasSettingsService, CONFIG_ID_QUERY_PARAM, NOT_CONFIGURED, PersistenceService } from 'arlas-wui-toolkit'; +import enToolkit from 'arlas-wui-toolkit/assets/i18n/en.json'; +import frToolkit from 'arlas-wui-toolkit/assets/i18n/fr.json'; +import { Observable, forkJoin, of } from 'rxjs'; +import { catchError } from 'rxjs/internal/operators/catchError'; +import { map } from 'rxjs/internal/operators/map'; +import { mergeMap } from 'rxjs/internal/operators/mergeMap'; + + +export class ArlasTranslateLoader implements TranslateLoader { + + public constructor( + private http: HttpClient, + private arlasSettings: ArlasSettingsService, + private persistenceService: PersistenceService + ) { } + + public getTranslation(lang: string): Observable { + const localI18nAdress = 'assets/i18n/' + lang + '.json?' + Date.now(); + const url = new URL(window.location.href); + const settings = this.arlasSettings.getSettings(); + const usePersistence = (!!settings && !!settings.persistence && !!settings.persistence.url + && settings.persistence.url !== '' && settings.persistence.url !== NOT_CONFIGURED); + const configurationId = url.searchParams.get(CONFIG_ID_QUERY_PARAM); + if (usePersistence && configurationId) { + const localI18nObs = this.http.get(localI18nAdress); + const externalI18nObs = this.persistenceService.get(configurationId) + .pipe(mergeMap(configDoc => this.persistenceService + .existByZoneKey('i18n', configDoc.doc_key.concat('_').concat(lang)) + .pipe(mergeMap(exist => exist.exists ? this.persistenceService + .getByZoneKey('i18n', configDoc.doc_key.concat('_').concat(lang)) + .pipe(map(i18nDoc => i18nDoc.doc_value)) : of('{}')), catchError(e => of('{}'))))); + return Observable.create((observer: any) => { + forkJoin([localI18nObs, externalI18nObs]).subscribe( + results => { + const localI18n = results[0]; + const externalI18n = JSON.parse(results[1] as string); + let merged = localI18n; + // Properties in externalI18n will overwrite those in localI18n and frToolkit and frComponents . + if (lang === 'fr') { + merged = { ...frComponents, ...frToolkit, ...localI18n, ...externalI18n as Object }; + } else if (lang === 'en') { + merged = { ...enComponents, ...enToolkit, ...localI18n, ...externalI18n as Object }; + } + observer.next(merged); + observer.complete(); + }, + error => { + this.mergeLocalI18n(localI18nAdress, lang, observer); + } + ); + }); + } else { + return Observable.create((observer: any) => { + this.mergeLocalI18n(localI18nAdress, lang, observer); + }); + } + } + + private mergeLocalI18n(localI18nAdress: string, lang: string, observer: any) { + this.http.get(localI18nAdress).subscribe( + res => { + let merged = res; + // Properties in res will overwrite those in frToolkit and frComponents . + if (lang === 'fr') { + merged = { ...frComponents, ...frToolkit, ...res }; + } else if (lang === 'en') { + merged = { ...enComponents, ...enToolkit, ...res }; + } + observer.next(merged); + observer.complete(); + }, + error => { + // failed to retrieve requested language file, use default + observer.complete(); // => Default language is already loaded + } + ); + } +}