diff --git a/angular.json b/angular.json index 6ea4efe0..1d65967b 100644 --- a/angular.json +++ b/angular.json @@ -50,7 +50,6 @@ "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, - "optimization": true, "budgets": [ { "type": "initial", diff --git a/projects/sonar/src/app/app-routing.module.ts b/projects/sonar/src/app/app-routing.module.ts index f15b40cb..b21bf9aa 100644 --- a/projects/sonar/src/app/app-routing.module.ts +++ b/projects/sonar/src/app/app-routing.module.ts @@ -41,8 +41,6 @@ import { OrganisationComponent } from './record/organisation/organisation.compon import { BriefViewComponent as ProjectBriefViewComponent } from './record/project/brief-view/brief-view.component'; import { DetailComponent as ProjectDetailComponent } from './record/project/detail/detail.component'; import { BriefViewComponent as SubdivisionBriefViewComponent } from './record/subdivision/brief-view/brief-view.component'; -import { DetailComponent as SubdivisionDetailComponent } from './record/subdivision/detail/detail.component'; -import { DetailComponent as UserDetailComponent } from './record/user/detail/detail.component'; import { UserComponent } from './record/user/user.component'; import { UserService } from './user.service'; @@ -298,11 +296,8 @@ export class AppRoutingModule { { type: 'users', briefView: UserComponent, - detailView: UserDetailComponent, aggregationsOrder: ['subdivision'], - editorSettings: { - longMode: true, - }, + redirectUrl: (record: any) => of(`/records/users?q=pid:${record.metadata.pid}`), sortOptions: [ { label: _('Relevance'), @@ -362,12 +357,12 @@ export class AppRoutingModule { label: 'Research projects', briefView: ProjectBriefViewComponent, detailView: projectDetail$, - editorSettings: { - longMode: true, - }, recordResource: true, aggregationsExpand: ['organisation', 'user'], aggregationsOrder: ['organisation', 'user', 'status'], + editorSettings: { + longMode: true, + }, exportFormats: [ { label: 'CSV', @@ -401,9 +396,6 @@ export class AppRoutingModule { briefView: CollectionBriefViewComponent, detailView: CollectionDetailComponent, files: fileConfig, - editorSettings: { - longMode: true, - }, sortOptions: [ { label: _('Relevance'), @@ -421,10 +413,7 @@ export class AppRoutingModule { type: 'subdivisions', label: 'Subdivisions', briefView: SubdivisionBriefViewComponent, - detailView: SubdivisionDetailComponent, - editorSettings: { - longMode: true, - }, + redirectUrl: (record: any) => of(`/records/subdivisions?q=pid:${record.metadata.pid}`), sortOptions: [ { label: _('Relevance'), @@ -449,12 +438,11 @@ export class AppRoutingModule { } recordsRoutesConfiguration.forEach((config: any) => { - const route = { + const route: any = { matcher: (url: any) => this._routeMatcher(url, config.type), canActivate: mapToCanActivate([RoleGuard]), children: [ { path: '', component: RecordSearchPageComponent }, - { path: 'detail/:pid', component: DetailComponent }, { path: 'edit/:pid', component: EditorComponent }, { path: 'new', component: EditorComponent, canActivate: mapToCanActivate([CanAddGuard]) } ], @@ -466,7 +454,8 @@ export class AppRoutingModule { key: config.type, label: config.label || config.type.charAt(0).toUpperCase() + config.type.slice(1), component: config.briefView || null, - editorSettings: config.editorSettings || false, + editorSettings: config.editorSettings || {}, + redirectUrl: config.redirectUrl || null, detailComponent: config.detailView || null, aggregations: config.aggregations || null, aggregationsExpand: config.aggregationsExpand || [], @@ -485,7 +474,9 @@ export class AppRoutingModule { ] } }; - + if (config.detailView) { + route.children.push({ path: 'detail/:pid', component: DetailComponent }); + } this._router.config[0].children.push(route); }); } diff --git a/projects/sonar/src/app/app.module.ts b/projects/sonar/src/app/app.module.ts index 0d032f51..a3f7f1df 100644 --- a/projects/sonar/src/app/app.module.ts +++ b/projects/sonar/src/app/app.module.ts @@ -30,8 +30,8 @@ import { TabsModule } from 'ngx-bootstrap/tabs'; import { TooltipModule } from 'ngx-bootstrap/tooltip'; import { NgxDropzoneModule } from 'ngx-dropzone'; import { ToastrModule } from 'ngx-toastr'; -import { DividerModule } from 'primeng/divider'; import { CarouselModule } from 'primeng/carousel'; +import { DividerModule } from 'primeng/divider'; import { DropdownModule } from 'primeng/dropdown'; import { FileUploadModule } from 'primeng/fileupload'; import { InputTextModule } from 'primeng/inputtext'; @@ -44,6 +44,7 @@ import { AppInitializerService } from './app-initializer.service'; import { AppRoutingModule } from './app-routing.module'; import { AppTranslateLoader } from './app-translate-loader'; import { AppComponent } from './app.component'; +import { FieldDescriptionComponent } from './core/field-description/field-description.component'; import { FileLinkPipe } from './core/file-link.pipe'; import { FileSizePipe } from './core/filesize.pipe'; import { HighlightJsonPipe } from './core/highlight-json.pipe'; @@ -57,6 +58,7 @@ import { ReviewComponent } from './deposit/review/review.component'; import { UploadComponent } from './deposit/upload/upload.component'; import { HttpInterceptor } from './interceptor/http.interceptor'; import { ContributorsPipe } from './pipe/contributors.pipe'; +import { FaIconClassPipe } from './pipe/fa-icon-class.pipe'; import { LanguageValuePipe } from './pipe/language-value.pipe'; import { BriefViewComponent as CollectionBriefViewComponent } from './record/collection/brief-view/brief-view.component'; import { DetailComponent as CollectionDetailComponent } from './record/collection/detail/detail.component'; @@ -67,6 +69,8 @@ import { DocumentComponent } from './record/document/document.component'; import { FileComponent } from './record/document/file/file.component'; import { PublicationPipe } from './record/document/publication.pipe'; import { FileItemComponent } from './record/files/file-item/file-item.component'; +import { OtherFilesComponent } from './record/files/other-files/other-files.component'; +import { StatsFilesComponent } from './record/files/stats-files/stats-files.component'; import { UploadFilesComponent } from './record/files/upload-files/upload-files.component'; import { DetailComponent as HepvsProjectDetailComponent } from './record/hepvs/project/detail/detail.component'; import { IdentifierComponent } from './record/identifier/identifier.component'; @@ -75,14 +79,9 @@ import { OrganisationComponent } from './record/organisation/organisation.compon import { BriefViewComponent as ProjectBriefViewComponent } from './record/project/brief-view/brief-view.component'; import { DetailComponent as ProjectDetailComponent } from './record/project/detail/detail.component'; import { BriefViewComponent as SubdivisionBriefViewComponent } from './record/subdivision/brief-view/brief-view.component'; -import { DetailComponent as SubdivisionDetailComponent } from './record/subdivision/detail/detail.component'; -import { DetailComponent as UserDetailComponent } from './record/user/detail/detail.component'; import { UserComponent } from './record/user/user.component'; import { ValidationComponent } from './record/validation/validation.component'; import { UserService } from './user.service'; -import { OtherFilesComponent } from './record/files/other-files/other-files.component'; -import { FaIconClassPipe } from './pipe/fa-icon-class.pipe'; -import { StatsFilesComponent } from './record/files/stats-files/stats-files.component'; export function appInitializerFactory(appInitializerService: AppInitializerService): () => Promise { return () => appInitializerService.initialize().toPromise(); @@ -100,7 +99,6 @@ export function minElementError(err: any, field: FormlyFieldConfig) { UserComponent, DocumentDetailComponent, OrganisationDetailComponent, - UserDetailComponent, JoinPipe, LanguageValuePipe, DashboardComponent, @@ -124,7 +122,6 @@ export function minElementError(err: any, field: FormlyFieldConfig) { CollectionBriefViewComponent, CollectionDetailComponent, SubdivisionBriefViewComponent, - SubdivisionDetailComponent, ContributorsPipe, ContributionsComponent, ContributionComponent, @@ -132,7 +129,8 @@ export function minElementError(err: any, field: FormlyFieldConfig) { FileItemComponent, OtherFilesComponent, FaIconClassPipe, - StatsFilesComponent + StatsFilesComponent, + FieldDescriptionComponent ], imports: [ BrowserModule, diff --git a/projects/sonar/src/app/core/field-description/field-description.component.html b/projects/sonar/src/app/core/field-description/field-description.component.html new file mode 100644 index 00000000..44b92e78 --- /dev/null +++ b/projects/sonar/src/app/core/field-description/field-description.component.html @@ -0,0 +1,30 @@ + +@if (field()) { +
+
{{ label() }}
+
+ @if(type() === 'array') { +
    + @for (value of field(); track value; let last=$last; let index=$index) { +
  • + @if (template) { + + } @else { + {{ value }} + } +
  • + } +
+ } + @else { + @if (template) { + + } @else { + {{ field() }} + } + } +
+
+} diff --git a/projects/sonar/src/app/core/field-description/field-description.component.ts b/projects/sonar/src/app/core/field-description/field-description.component.ts new file mode 100644 index 00000000..87df4943 --- /dev/null +++ b/projects/sonar/src/app/core/field-description/field-description.component.ts @@ -0,0 +1,33 @@ +import { AfterContentInit, Component, ContentChildren, QueryList, TemplateRef, computed, input } from '@angular/core'; +import { PrimeTemplate } from 'primeng/api'; +import { Nullable } from 'primeng/ts-helpers'; + +@Component({ + selector: 'sonar-field-description', + templateUrl: './field-description.component.html' +}) +export class FieldDescriptionComponent implements AfterContentInit { + label = input(); + field = input(); + type = computed(() => this.getType()); + template: Nullable>; + + @ContentChildren(PrimeTemplate) templates: QueryList | null; + + ngAfterContentInit() { + (this.templates as QueryList).forEach((item) => { + switch (item.getType()) { + case 'template': + this.template = item.template; + break; + } + }); + } + getType() { + const field = this.field(); + if (Array.isArray(field)) { + return 'array'; + } + return typeof field; + } +} diff --git a/projects/sonar/src/app/deposit/upload/upload.component.spec.ts b/projects/sonar/src/app/deposit/upload/upload.component.spec.ts deleted file mode 100644 index 41c41c74..00000000 --- a/projects/sonar/src/app/deposit/upload/upload.component.spec.ts +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SONAR User Interface - * Copyright (C) 2021 RERO - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -import { HttpClient, HttpClientModule } from '@angular/common/http'; -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; -import { TranslateLoader as BaseTranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { CoreConfigService, RecordModule, TranslateLoader } from '@rero/ng-core'; -import { TabsModule } from 'ngx-bootstrap/tabs'; -import { NgxDropzoneModule } from 'ngx-dropzone'; -import { of } from 'rxjs'; -import { FileSizePipe } from '../../core/filesize.pipe'; -import { StepComponent } from '../../core/step/step.component'; -import { ReviewComponent } from '../review/review.component'; -import { UploadComponent } from './upload.component'; - -describe('UploadComponent', () => { - let component: UploadComponent; - let fixture: ComponentFixture; - - const route = { - params: of({ - id: '0' - }) - }; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [UploadComponent, StepComponent, ReviewComponent, FileSizePipe], - imports: [ - RecordModule, - ReactiveFormsModule, - NgxDropzoneModule, - TabsModule.forRoot(), - HttpClientModule, - RouterTestingModule, - TranslateModule.forRoot({ - loader: { - provide: BaseTranslateLoader, - useClass: TranslateLoader, - deps: [CoreConfigService, HttpClient] - } - }) - ], - providers: [{ provide: ActivatedRoute, useValue: route }] - }).compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(UploadComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - afterEach(() => { - TestBed.resetTestingModule(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/sonar/src/app/record/collection/detail/detail.component.html b/projects/sonar/src/app/record/collection/detail/detail.component.html index fa9e028b..77e27a42 100644 --- a/projects/sonar/src/app/record/collection/detail/detail.component.html +++ b/projects/sonar/src/app/record/collection/detail/detail.component.html @@ -1,25 +1,27 @@

{{ record.metadata.name | languageValue | async }}

-
- -
Description
-
-
-
+ @if(record.metadata.description) { +

Description

+

+ } +
diff --git a/projects/sonar/src/app/record/document/detail/contributions/contributions.component.html b/projects/sonar/src/app/record/document/detail/contributions/contributions.component.html index 92aee6a0..99a38b67 100644 --- a/projects/sonar/src/app/record/document/detail/contributions/contributions.component.html +++ b/projects/sonar/src/app/record/document/detail/contributions/contributions.component.html @@ -17,7 +17,7 @@
-
    +
    • @@ -29,11 +29,11 @@
-
-
Conference
-
-
    -
  • +
    +
    Conference
    +
    +
      +
    diff --git a/projects/sonar/src/app/record/document/detail/detail.component.html b/projects/sonar/src/app/record/document/detail/detail.component.html index 74e03692..29898b8d 100644 --- a/projects/sonar/src/app/record/document/detail/detail.component.html +++ b/projects/sonar/src/app/record/document/detail/detail.component.html @@ -14,7 +14,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - +@if(record) {
    @@ -27,54 +27,57 @@
    -
    - {{ 'document_type_' + record.documentType | translate }} -
    + @if(record.documentType){ +
    + {{ 'document_type_' + record.documentType | translate }} +
    + }

    - + @if(record.masked && record.masked !== 'not_masked') { + + } - + @if(record.title[0].subtitle) {  : {{ record.title[0].subtitle | languageValue | async - }} + }} + }

    - + @if(record.organisation) { {{ organisation.name }} - - + } + @if(record.subdivisions) { {{ subdivision.name | languageValue | async }} - + }

    @@ -83,57 +86,61 @@

    > -
      - - -
    • - {{ item.value }} -
    • -
      - -
    • {{ statement.text }}
    • -
      -
      -
    + @if(record.provisionActivity && record.provisionActivity.length > 0) { +
      + @for(statement of record.provisionActivity; track statement) { + @if(statement.text && statement.text.default) { + @for(item of statement.text | keyvalue; track item) { +
    • + {{ item.value }} +
    • + } + } @else { +
    • {{ statement.text }}
    • + } + } +
    + } -

    - {{ record.extent }} - - ; - - {{ - record.formats | join : ', ' - }} -

    + @if(record.extent || record.formats) { +

    + @if(record.extent) { + {{ record.extent }} + } + @if(record.extent && record.formats) { ; } + @if(record.formats) { + {{ + record.formats | join : ', ' + }} + } +

    + } -

    - {{ record.editionStatement.editionDesignation.value }} - - / {{ record.editionStatement.responsibility.value }} - -

    + @if(record.editionStatement) { +

    + {{ record.editionStatement.editionDesignation.value }} + @if(record.editionStatement.responsibility) { + / {{ record.editionStatement.responsibility.value }} + } +

    + } -

    - {{ record.dissertation.text }} -

    + @if(record.dissertation) { +

    + {{ record.dissertation.text }} +

    + } + + @if (record.partOf && record.partOf.length > 0) {
    @@ -146,168 +153,132 @@

    }}:

    -
    +
      -
    • - {{ partOf.text }} -
    • + @for (partOf of record.partOf; track partOf) { +
    • + {{ partOf.text }} +
    • + }
    + } - + } -
    - - {{ abstract.language | translateLanguage }} - - - - 0) { +
    + @for (abstract of record.abstracts; track abstract) { + - {{ abstract.value | slice : 0 : 400 }} - - {{ 'Show more' | translate }}… - - - - - - - -
    + {{ abstract.language | translateLanguage }} + + } + @for (abstract of record.abstracts; track abstract) { + @if (abstract.show) { + @if (!abstract.full && abstract.value.length > 400) { + + {{ abstract.value | slice : 0 : 400 }} + + {{ 'Show more' | translate }}… + + + } @else { + + } + } + } +
    + } -
    +
    - -
    Research projects
    -
    - -
    -
    + + + + {{ project.name }} + + {{ get_funding_organisations(project) }} + + - -
    Collections
    -
    - -
    -
    - + + + + {{ collection.name | languageValue | async }} + + + - - -
    - {{ 'Custom field ' + i | translate }} -
    -
    - {{ record['customField' + i].join(', ') }} -
    -
    -
    + @for (i of [1, 2, 3]; track i) { + + } - -
    Language
    -
    -
      -
    • - {{ language.value | translateLanguage }} -
    • -
    -
    -
    + + + {{ language.value | translateLanguage }} + + - + - -
    Content
    -
    -
      -
    • - {{ note }} -
    • -
    -
    -
    + - -
    Classification
    -
    - + + >{{ 'classification_' + classification.classificationPortion | translate - }} ;  - -
    -
    + }} + + +
    + - -
    Other electronic version
    -
    -

    + + - {{ otherEdition.publicNote }} + -

    -
    -
    + +
    - -
    Related to
    -
    -

    + + - {{ relatedTo.publicNote }} + -

    -
    -
    + + - -
    Series statement
    -
    -
      -
    • - {{ serie.name }} - ; {{ serie.number }} -
    • -
    -
    -
    - - - -
    Notes
    -
    -
      -
    • - {{ note }} -
    • -
    -
    -
    + + + {{ serie.name }} + @if (serie.number) { + ; {{ serie.number }} + } + + - -
    Other material characteristics
    -
    - {{ record.otherMaterialCharacteristics }} -
    -
    + - -
    Accompanying material
    -
    - {{ record.additionalMaterials }} -
    -
    + - -
    License
    -
    - {{ record.usageAndAccessPolicy.license | translate }} - -
    {{ record.usageAndAccessPolicy.label }} -
    -
    -
    + + + {{ usageAndAccessPolicy.license | translate }} + @if(usageAndAccessPolicy.label) { +
    {{ usageAndAccessPolicy.label }} + } +
    +
    - -
    Open Access status
    -
    - {{ record.oa_status }} -
    -
    + - -
    Identifiers
    -
    -

    + + -

    -
    -
    + /> + +
    -
    Permalink
    -
    - {{ record.permalink }} -
    + + + {{ permalink }} + +

    @@ -443,16 +373,17 @@
    - - @if (filteredFiles.length > 1) { - Other files - - @if (tabOther.active) { -
    - -
    - } } -
    + @if (filteredFiles.length > 1) { + + Other files + + @if (tabOther.active) { +
    + +
    + } +
    + } Statistics @@ -478,4 +409,4 @@
    } - +} diff --git a/projects/sonar/src/app/record/document/detail/detail.component.ts b/projects/sonar/src/app/record/document/detail/detail.component.ts index e746adc8..db6823b3 100644 --- a/projects/sonar/src/app/record/document/detail/detail.component.ts +++ b/projects/sonar/src/app/record/document/detail/detail.component.ts @@ -159,7 +159,7 @@ export class DetailComponent implements OnDestroy, OnInit { * * @returns List of UDC classifications. */ - get UDCclassifiations(): Array { + get UDCclassifications(): Array { if (!this.record.classification) { return []; } diff --git a/projects/sonar/src/app/record/files/other-files/other-files.component.spec.ts b/projects/sonar/src/app/record/files/other-files/other-files.component.spec.ts deleted file mode 100644 index 0ad4e2b2..00000000 --- a/projects/sonar/src/app/record/files/other-files/other-files.component.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SONAR User Interface - * Copyright (C) 2019-2024 RERO - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { OtherFilesComponent } from './other-files.component'; - -describe('OtherFilesComponent', () => { - let component: OtherFilesComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [OtherFilesComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(OtherFilesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/sonar/src/app/record/files/stats-files/stats-files.component.spec.ts b/projects/sonar/src/app/record/files/stats-files/stats-files.component.spec.ts deleted file mode 100644 index f72dbd80..00000000 --- a/projects/sonar/src/app/record/files/stats-files/stats-files.component.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* - * SONAR User Interface - * Copyright (C) 2019-2024 RERO - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { StatsFilesComponent } from './stats-files.component'; - -describe('StatsFilesComponent', () => { - let component: StatsFilesComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [StatsFilesComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(StatsFilesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/projects/sonar/src/app/record/files/upload-files/upload-files.component.ts b/projects/sonar/src/app/record/files/upload-files/upload-files.component.ts index f3cc2edd..730c4237 100644 --- a/projects/sonar/src/app/record/files/upload-files/upload-files.component.ts +++ b/projects/sonar/src/app/record/files/upload-files/upload-files.component.ts @@ -16,7 +16,14 @@ */ import { HttpClient } from '@angular/common/http'; -import { Component, ViewChild, effect, inject, input, output } from '@angular/core'; +import { + Component, + ViewChild, + effect, + inject, + input, + output, +} from '@angular/core'; import { toObservable, toSignal } from '@angular/core/rxjs-interop'; import { TranslateService } from '@ngx-translate/core'; import { DialogService, RecordService } from '@rero/ng-core'; @@ -147,7 +154,7 @@ export class UploadFilesComponent { ); if (indexToUpdate >= 0) { this.fileService - .put(`/api/documents/${this.pid()}`, this.record) + .put(`/api/${this.recordType()}/${this.pid()}`, this.record) .subscribe((record: any) => { // update the current record this.record = record.metadata; @@ -212,7 +219,10 @@ export class UploadFilesComponent { let fileUpload: File = event.fileUpload; this.spinner.show('file-upload'); this.fileService - .put(`/api/documents/${this.pid()}/files/${file.key}`, fileUpload) + .put( + `/api/${this.recordType()}/${this.pid()}/files/${file.key}`, + fileUpload + ) .pipe( catchError((e: any) => { let msg = this.translateService.instant('Server error'); @@ -261,7 +271,10 @@ export class UploadFilesComponent { private generateCreateRequests(event): Observable { return from(event.files).pipe( concatMap((f: any) => - this.fileService.put(`/api/documents/${this.pid()}/files/${f.name}`, f) + this.fileService.put( + `/api/${this.recordType()}/${this.pid()}/files/${f.name}`, + f + ) ), map((file: any) => { this.nUploadedFiles += 1; @@ -335,7 +348,9 @@ export class UploadFilesComponent { if (confirm === true) { // remove the file return this.fileService - .delete(`/api/documents/${this.pid()}/files/${file.key}`) + .delete( + `/api/${this.recordType()}/${this.pid()}/files/${file.key}` + ) .pipe( map((res) => { this.files = this.files.filter((f) => f.key !== file.key); @@ -368,7 +383,7 @@ export class UploadFilesComponent { */ private getFiles(record): Observable { return this.fileService - .get(`/api/documents/${record.pid}/files?versions`) + .get(`/api/${this.recordType()}/${record.pid}/files?versions`) .pipe( map((record: any) => { if (record?.contents) { @@ -405,7 +420,10 @@ export class UploadFilesComponent { // get old versions let versions = {}; files.map((file) => { - if (file?.metadata?.type === 'file' && file.is_head === false) { + if (file?.metadata?.type && file.metadata.type !== 'file') { + return; + } + if (file.is_head === false) { if (!(file.key in versions)) versions[file.key] = []; versions[file.key].push(file); } @@ -413,7 +431,10 @@ export class UploadFilesComponent { // get head files only let headFiles = []; files.map((file) => { - if (file?.metadata?.type === 'file' && file.is_head) { + if (file?.metadata?.type && file.metadata.type !== 'file') { + return; + } + if (file.is_head) { // add versions if exists if (versions[file.key]) { let fileVersions = versions[file.key]; @@ -436,7 +457,7 @@ export class UploadFilesComponent { recordFile.order = index + 1; }); this.fileService - .put(`/api/documents/${this.pid()}`, this.record) + .put(`/api/${this.recordType()}/${this.pid()}`, this.record) .subscribe((record: any) => { this.record = record.metadata; this.files.map((file) => { diff --git a/projects/sonar/src/app/record/hepvs/project/detail/detail.component.html b/projects/sonar/src/app/record/hepvs/project/detail/detail.component.html index fd42dc67..8101f472 100644 --- a/projects/sonar/src/app/record/hepvs/project/detail/detail.component.html +++ b/projects/sonar/src/app/record/hepvs/project/detail/detail.component.html @@ -1,20 +1,20 @@ - +@if (record$ | async; as record) {

    {{ record.metadata.name }}

    @@ -34,187 +34,158 @@

    {{ record.metadata.projectSponsor }} ({{ 'Project sponsor' | translate }}, {{ record.metadata.statusHep }})

    -
    +
    - -
    Internal research associates
    -
    {{ record.metadata.innerSearcher | join:', ' }}
    -
    + - -
    Main team
    -
    - {{ record.metadata.mainTeam }} -
    -
    + - -
    Secondary team
    -
    - {{ record.metadata.secondaryTeam }} -
    -
    + - -
    External partners
    -
    - + @if (record.metadata.externalPartners.choice) { + + + @for (partner of record.metadata.externalPartners.list; track partner; let last=$last) { {{ partner.searcherName }} {{ partner.institution }} - , - -
    -
    + @if (!last) { + ,  + } + } + +
    + } - -
    Project summary
    -
    - -
    -
    + + + + + - -
    Date of approval by the Team Leader
    -
    - {{ record.metadata.approvalDate | dateTranslate: 'dd.MM.yyyy' }} -
    -
    + + - -
    Realization framework
    -
    - {{ record.metadata.realizationFramework | join:', ' }} -
    -
    + - -
    Funding
    -
    - + @if (record.metadata.funding.choice) { + + + @if (funding?.funder?.number) { - {{ record.metadata.funding.funder.number }} + {{ funding.funder.number }} - - - {{ record.metadata.funding.funder.name }} - + } + @if (funding?.funder?.name) { + {{ funding.funder.name }} + } + @if (funding.funder.type != 'Other (free field)') { + {{ record.metadata.funding.funder.type }} - - - {{ record.metadata.funding.funder.type }} - + } + @if (['​Swiss National Science Foundation', 'Swissuniversities'].includes(funding.funder.type)) { + {{ funding.funder.type }} + } -
    -
    + [ngClass]="{ 'fa-check text-success': funding.fundingReceived, 'fa-remove text-danger': !funding.fundingReceived }"> + +
    + } - -
    Actors involved
    -
    - - {{ actor.choice !== 'Other' ? actor.choice : actor.other }} ({{ actor.count }}), - - -
    -
    + + + {{ actor.choice !== 'Other' ? actor.choice : actor.other }} ({{ actor.count }}) + @if (!last) { + ,  + } + + - -
    What are the benefits and quality improvements in the research in this - project? -
    -
    - -
    -
    + + + + + - -
    What are the impacts of training research?
    -
    - -
    -
    + + + + + - -
    What is the impact of the research on the professional environment?
    -
    - -
    -
    + + + + + - -
    What is the impact of research on public action or on internal or external - governance?
    -
    - -
    -
    + + + + + - -
    Why this project promote pedagogical or technological innovation?
    -
    - {{ record.metadata.promoteInnovation.reason }} -
    -
    + @if (record.metadata.promoteInnovation?.choice) { + + } - -
    Mandate
    -
    - {{ record.metadata.relatedToMandate.mandate }} - - {{ record.metadata.relatedToMandate.name }} - -
    - -
    Brief description of the mandate
    -
    - -
    -
    + @if (record.metadata.relatedToMandate?.choice) { + + + {{ relatedToMandate.mandate }} + @if (relatedToMandate.name) { + {{ relatedToMandate.name }} + } + + + + + + + + + } - -
    Brief description of the report
    -
    - -
    -
    + @if (record.metadata.educationalDocument?.choice) { + + + + + + } - -
    How are research results used in training?
    -
    - -
    -
    + + + + +
    - - -

    Linked documents

    - + } +} diff --git a/projects/sonar/src/app/record/organisation/detail/detail.component.html b/projects/sonar/src/app/record/organisation/detail/detail.component.html index 6888304c..82f3aae3 100644 --- a/projects/sonar/src/app/record/organisation/detail/detail.component.html +++ b/projects/sonar/src/app/record/organisation/detail/detail.component.html @@ -16,111 +16,87 @@ -->

    {{ record.metadata.name }}

    -
    -
    Code
    -
    {{ record.metadata.code }}
    +
    + -
    Is shared
    -
    - -
    + + + + + -
    Is dedicated
    -
    - -
    + + + + + - -
    Server name (without http)
    -
    {{ record.metadata.serverName }}
    -
    + - -
    Platform name
    -
    -
    + + + + + - -
    Ark Name Assigning Authority Number (NAAN)
    -
    {{ record.metadata.arkNAAN }}
    -
    + - -
    Allowed IP addresses
    -
    -
    + + + + + - -
    Description
    -
    - - {{ 'lang_' + desc.language | translate | ucfirst }} - - -
    -
    + + + {{ 'lang_' + description.language | translate | ucfirst }} + + + - -
    Footer
    -
    - - {{ 'lang_' + foot.language | translate | ucfirst }} - - -
    -
    + + + {{ 'lang_' + footer.language | translate | ucfirst }} + + + - - - -
    {{ 'Custom field' | translate }} {{ i }}
    -
    - - {{ 'Label' | translate }}: {{ record.metadata['documentsCustomField' + i].label | languageValue | async }} + @for (i of [1, 2, 3]; track i) { + + + @if (customField.label) { + {{ 'Label' | translate }}: {{ customField.label | languageValue | async }}
    -
    - + } + {{ 'Include in facets' | translate }} -
    -
    -
    + +
    + } - -
    {{ 'Visible facets in the public interface for documents' | translate }}
    -
    -
      -
    • - - {{ facet | translate | ucfirst }} -
    • -
    -
    -
    -
    + + + + {{ publicDocumentFacet | translate | ucfirst }} + + - + + + {{ subdivision.metadata.name | languageValue | async }} + + + + + + + {{ collection.metadata.name | languageValue | async }} + + + +
    +
    diff --git a/projects/sonar/src/app/record/organisation/detail/detail.component.ts b/projects/sonar/src/app/record/organisation/detail/detail.component.ts index 6d8771e8..8a89f78c 100644 --- a/projects/sonar/src/app/record/organisation/detail/detail.component.ts +++ b/projects/sonar/src/app/record/organisation/detail/detail.component.ts @@ -14,10 +14,10 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { RecordService } from '@rero/ng-core'; import { combineLatest, Observable } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; +import { map, switchMap } from 'rxjs/operators'; @Component({ templateUrl: './detail.component.html', @@ -29,6 +29,8 @@ export class DetailComponent implements OnInit { /** Organisation record. */ record: any; + recordService = inject(RecordService); + /** Subdivisions list. */ subdivisions: Array = []; @@ -40,7 +42,7 @@ export class DetailComponent implements OnInit { * * @param _recordService: Record service. */ - constructor(private _recordService: RecordService) {} + constructor() {} /** * Component init. @@ -53,11 +55,11 @@ export class DetailComponent implements OnInit { switchMap((record: any) => { this.record = record; return combineLatest([ - this._recordService.getRecords( + this.recordService.getRecords( 'subdivisions', `organisation.pid:${record.id}` ), - this._recordService.getRecords( + this.recordService.getRecords( 'collections', `organisation.pid:${record.id}` ), @@ -69,4 +71,10 @@ export class DetailComponent implements OnInit { this.collections = result[1].hits.hits; }); } + + updateFiles(files) { + this.recordService.getRecord('organisations', this.record.id, 1).pipe( + map(doc => this.record._files = doc.metadata._files) + ).subscribe(); + } } diff --git a/projects/sonar/src/app/record/project/detail/detail.component.html b/projects/sonar/src/app/record/project/detail/detail.component.html index 56ce94bc..1f9a2ca2 100644 --- a/projects/sonar/src/app/record/project/detail/detail.component.html +++ b/projects/sonar/src/app/record/project/detail/detail.component.html @@ -16,77 +16,63 @@ -->

    {{ record.metadata.name }}

    -
    - -
    Description
    -
    -
    +
    + + + + + -
    Period
    -
    {{ record.metadata.startDate | dateTranslate: 'd/M/yyyy' }} - - {{ record.metadata.endDate | dateTranslate: 'd/M/yyyy' }}
    + + - -
    End date
    -
    {{ record.metadata.endDate | dateTranslate: 'longDate' }}
    -
    + + - -
    Identifier
    -
    - -
    -
    + + + + + - -
    Investigators
    -
    - -

    - {{ investigator.agent.preferred_name }} ({{ role | translate }} - ,  - ) + + + {{ investigator.agent.preferred_name }} + (@for (role of investigator.role; track role; let last=$last) { + {{ role | translate }}@if (!last) { + ,  + } + }) - - + @if (investigator.affiliation) { + {{ investigator.affiliation }} - - - {{ investigator.affiliation }} - - - -

    - -
    -
    + } + + - -
    Funding organisations
    -
    -

    - {{ funding_organisation.agent.preferred_name }} + + + {{ funding_organisation.agent.preferred_name }} -

    -
    -
    + + +
    - - -

    Linked documents

    -
      -
    • + @if (user$ | async; as user && record.metadata.documents && record.metadata.documents.length > 0 && user.is_moderator) { +

      Linked documents

      + - - - + } +
    + } diff --git a/projects/sonar/src/app/record/subdivision/brief-view/brief-view.component.html b/projects/sonar/src/app/record/subdivision/brief-view/brief-view.component.html index e18973b2..7c1064eb 100644 --- a/projects/sonar/src/app/record/subdivision/brief-view/brief-view.component.html +++ b/projects/sonar/src/app/record/subdivision/brief-view/brief-view.component.html @@ -1,20 +1,18 @@ -

    - {{ record.metadata.name | languageValue | async }} -

    +

    {{ record.metadata.name | languageValue | async }}

    diff --git a/projects/sonar/src/app/record/subdivision/detail/detail.component.html b/projects/sonar/src/app/record/subdivision/detail/detail.component.html deleted file mode 100644 index e08edb1f..00000000 --- a/projects/sonar/src/app/record/subdivision/detail/detail.component.html +++ /dev/null @@ -1,19 +0,0 @@ - - -

    {{ record.metadata.name | languageValue | async }}

    -
    diff --git a/projects/sonar/src/app/record/subdivision/detail/detail.component.ts b/projects/sonar/src/app/record/subdivision/detail/detail.component.ts deleted file mode 100644 index d8a17831..00000000 --- a/projects/sonar/src/app/record/subdivision/detail/detail.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SONAR User Interface - * Copyright (C) 2021 RERO - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -import { Component } from '@angular/core'; -import { Observable } from 'rxjs'; - -@Component({ - templateUrl: './detail.component.html' -}) -export class DetailComponent { - /** Observable resolving record data */ - record$: Observable; -} diff --git a/projects/sonar/src/app/record/user/detail/detail.component.html b/projects/sonar/src/app/record/user/detail/detail.component.html deleted file mode 100644 index bf8b2e63..00000000 --- a/projects/sonar/src/app/record/user/detail/detail.component.html +++ /dev/null @@ -1,58 +0,0 @@ - - -

    {{ record.metadata.first_name }} {{ record.metadata.last_name }}

    -
    - -
    Organisation
    -
    {{ record.metadata.organisation.name }}
    -
    - -
    Role
    -
    {{ ('role_' + record.metadata.role) | translate }}
    - - -
    Subdivision
    -
    {{ record.metadata.subdivision.name | languageValue | async }}
    -
    - -
    Email address
    -
    {{ record.metadata.email }}
    - - -
    Birthdate
    -
    {{ record.metadata.birth_date | date }}
    -
    - - -
    Phone
    -
    {{ record.metadata.phone }}
    -
    - - -
    Address
    -
    -

    - {{ record.metadata.street }} -

    -

    - {{ record.metadata.postal_code }} {{ record.metadata.city }} -

    -
    -
    -
    -
    diff --git a/projects/sonar/src/app/record/user/detail/detail.component.ts b/projects/sonar/src/app/record/user/detail/detail.component.ts deleted file mode 100644 index d8a17831..00000000 --- a/projects/sonar/src/app/record/user/detail/detail.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SONAR User Interface - * Copyright (C) 2021 RERO - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -import { Component } from '@angular/core'; -import { Observable } from 'rxjs'; - -@Component({ - templateUrl: './detail.component.html' -}) -export class DetailComponent { - /** Observable resolving record data */ - record$: Observable; -}