diff --git a/package-lock.json b/package-lock.json index f083a6ad95..6e8274d67a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26740,6 +26740,22 @@ "resolved": "https://registry.npmjs.org/ngraph.random/-/ngraph.random-1.1.0.tgz", "integrity": "sha512-h25UdUN/g8U7y29TzQtRm/GvGr70lK37yQPvPKXXuVfs7gCm82WipYFZcksQfeKumtOemAzBIcT7lzzyK/edLw==" }, + "ngx-clipboard": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/ngx-clipboard/-/ngx-clipboard-14.0.1.tgz", + "integrity": "sha512-y6fDrvAso1cbM+VvHgB2kJ3dcQ/EBPol33nLaqqKB1jNO/Kd3l17EHdXNW/oKY0wUKCHk7ZCuiinREgUHEYfXg==", + "requires": { + "ngx-window-token": ">=4.0.0", + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + } + } + }, "ngx-color-picker": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/ngx-color-picker/-/ngx-color-picker-10.1.0.tgz", @@ -26755,6 +26771,21 @@ } } }, + "ngx-window-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ngx-window-token/-/ngx-window-token-4.0.0.tgz", + "integrity": "sha512-z6tS3UQoKULdABWHpE57l1xtoxFFzlwLe1n+nu9+xzCZUdSvkGqhb5dSje4NOVhA6mMOqzR4SctSBZARwqPPuQ==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + } + } + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", diff --git a/package.json b/package.json index ae4914483f..02689e8fa9 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "json2typescript": "^1.0.6", "jsonld": "^1.1.0", "moment": "^2.27.0", + "ngx-clipboard": "^14.0.1", "ngx-color-picker": "^10.0.1", "openseadragon": "^2.4.0", "rxjs": "~6.5.3", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 74be1004d8..8bb08eca55 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -78,12 +78,21 @@ import { SelectOntologyComponent } from './workspace/resource/resource-instance- import { SelectResourceClassComponent } from './workspace/resource/resource-instance-form/select-resource-class/select-resource-class.component'; import { SelectPropertiesComponent } from './workspace/resource/resource-instance-form/select-properties/select-properties.component'; import { SwitchPropertiesComponent } from './workspace/resource/resource-instance-form/select-properties/switch-properties/switch-properties.component'; +import { ProjectTabViewComponent } from './project/board/project-tab-view/project-tab-view.component'; +import { DatasetTabViewComponent } from './project/board/dataset-tab-view/dataset-tab-view.component'; +import { AttributionTabViewComponent } from './project/board/attribution-tab-view/attribution-tab-view.component'; +import { TermsTabViewComponent } from './project/board/terms-tab-view/terms-tab-view.component'; +import { ContactsTabViewComponent } from './project/board/contacts-tab-view/contacts-tab-view.component'; +import { ClipboardModule } from 'ngx-clipboard'; import { AngularSplitModule } from 'angular-split'; +import { PersonTemplateComponent } from './project/board/person-template/person-template.component'; +import { AddressTemplateComponent } from './project/board/address-template/address-template.component'; +import { OrganisationTemplateComponent } from './project/board/organisation-template/organisation-template.component'; // translate: AoT requires an exported function for factories export function HttpLoaderFactory(httpClient: HttpClient) { - return new TranslateHttpLoader(httpClient, 'assets/i18n/', '.json') + return new TranslateHttpLoader(httpClient, 'assets/i18n/', '.json'); } @NgModule({ @@ -143,7 +152,15 @@ export function HttpLoaderFactory(httpClient: HttpClient) { SelectOntologyComponent, SelectResourceClassComponent, SelectPropertiesComponent, - SwitchPropertiesComponent + SwitchPropertiesComponent, + ProjectTabViewComponent, + DatasetTabViewComponent, + AttributionTabViewComponent, + TermsTabViewComponent, + ContactsTabViewComponent, + PersonTemplateComponent, + AddressTemplateComponent, + OrganisationTemplateComponent ], imports: [ AppRoutingModule, @@ -165,6 +182,7 @@ export function HttpLoaderFactory(httpClient: HttpClient) { deps: [HttpClient] } }), + ClipboardModule, AngularSplitModule.forRoot() ], providers: [ diff --git a/src/app/project/board/address-template/address-template.component.ts b/src/app/project/board/address-template/address-template.component.ts new file mode 100644 index 0000000000..2d3d3fffbc --- /dev/null +++ b/src/app/project/board/address-template/address-template.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-address-template', + template: ` +
+

Address:

+
+

{{ address['streetAddress'] }}

+ {{ address['postalCode'] }} + {{ address['addressLocality'] }} +
+
+ ` +}) +export class AddressTemplateComponent { + @Input() address: object; +} diff --git a/src/app/project/board/attribution-tab-view/attribution-tab-view.component.html b/src/app/project/board/attribution-tab-view/attribution-tab-view.component.html new file mode 100644 index 0000000000..766a08aa85 --- /dev/null +++ b/src/app/project/board/attribution-tab-view/attribution-tab-view.component.html @@ -0,0 +1,15 @@ +

Attribution

+ +

The following people are involved in the creation of the dataset:

+ +
+ + + +

{{ entry.value['role'] | titlecase }}

+ + + +
+ +
diff --git a/src/app/project/board/attribution-tab-view/attribution-tab-view.component.scss b/src/app/project/board/attribution-tab-view/attribution-tab-view.component.scss new file mode 100644 index 0000000000..ca0ffce2bf --- /dev/null +++ b/src/app/project/board/attribution-tab-view/attribution-tab-view.component.scss @@ -0,0 +1,7 @@ +.attribution-entry { + margin-top: 25px; + + .color-for-role { + color: brown; + } +} diff --git a/src/app/project/board/attribution-tab-view/attribution-tab-view.component.spec.ts b/src/app/project/board/attribution-tab-view/attribution-tab-view.component.spec.ts new file mode 100644 index 0000000000..e99ea303ae --- /dev/null +++ b/src/app/project/board/attribution-tab-view/attribution-tab-view.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AttributionTabViewComponent } from './attribution-tab-view.component'; + +describe('AttributionTabViewComponent', () => { + let component: AttributionTabViewComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AttributionTabViewComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AttributionTabViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/project/board/attribution-tab-view/attribution-tab-view.component.ts b/src/app/project/board/attribution-tab-view/attribution-tab-view.component.ts new file mode 100644 index 0000000000..17a9981f5b --- /dev/null +++ b/src/app/project/board/attribution-tab-view/attribution-tab-view.component.ts @@ -0,0 +1,82 @@ +import { Component, Input, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-attribution-tab-view', + templateUrl: './attribution-tab-view.component.html', + styleUrls: ['./attribution-tab-view.component.scss'] +}) +export class AttributionTabViewComponent implements OnInit{ + + // attribution input + @Input() attribution: object; + + // hard-coded data to complete the functionality + people = [{ + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'benjamin.jones@test.ch', + 'familyName': 'Jones', + 'givenName': 'Benjamin', + 'jobTitle': 'Dr. des.', + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': 'info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': 'http://www.utoronto.ca/' + } + }, { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'james.coleman@dasch.swiss', + 'familyName': 'Coleman', + 'givenName': 'James', + 'jobTitle': 'Dr. des.', + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': 'info@universityoftoronto.ca', + 'name': 'University of Toronto', + } + }, { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'lauren.berry@unibas.ch', + 'familyName': 'Berry', + 'givenName': 'Lauren', + 'jobTitle': 'Dr.', + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': 'info@universityoftoronto.ca', + 'name': 'University of Toronto', + } + }, { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'leonhard.hart@test.ch', + 'familyName': 'Hart', + 'givenName': 'Leonhard', + 'jobTitle': 'Prof.', + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': 'info@universityoftoronto.ca', + 'name': 'University of Toronto', + } + },{ + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'lauren.berry@unibas.ch', + 'familyName': 'Berry', + 'givenName': 'Lauren', + 'jobTitle': 'Dr.', + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': 'info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': 'http://www.utoronto.ca/' + } + }]; + + ngOnInit(): void { + // reformat data + for (let idx = 0; idx < this.people.length; idx++) { + if (this.people[idx]['sameAs']) { + this.people[idx]['sameAs'] = this.people[idx]['sameAs']['value']; + } + } + } + +} diff --git a/src/app/project/board/board.component.html b/src/app/project/board/board.component.html index d82de7dd88..f67b31332d 100644 --- a/src/app/project/board/board.component.html +++ b/src/app/project/board/board.component.html @@ -1,9 +1,9 @@ -
- - -
+
+
+ +
Active @@ -13,54 +13,175 @@ -
+
- -
-
-

- Project {{project.shortcode}} | {{project.shortname | uppercase}} -

- - - - Active - Deactivated + +
+
+

+ Project {{ project.shortcode }} | {{ project.shortname | uppercase }} +

+ + + + Active + Deactivated + - -
-
-

- {{project.longname}} -

- - - - +
+
+

+ {{ project.longname }} +

+ + + + +
- -
-
-
+
- +
+ +
+

Description

+
+
- -
- - {{k}} - -
+
+ + + + perm_data_setting + Project + + + + + + collections + Dataset + + + + + + + assignment + Attribution + + + + + + + receipt + Terms & conditions + + + + + + + portrait + Contact + + + + +
+
+
+ + + + + + + + +
+ +
diff --git a/src/app/project/board/board.component.scss b/src/app/project/board/board.component.scss index 178c18acf5..00d5eae078 100644 --- a/src/app/project/board/board.component.scss +++ b/src/app/project/board/board.component.scss @@ -1,4 +1,5 @@ @import "../../../assets/style/responsive"; +@import "../../../assets/style/config"; section { margin: 24px auto; @@ -6,7 +7,7 @@ section { // phone devices @media (max-width: map-get($grid-breakpoints, phone)) { - + .fill-remaining-space { display: none; } @@ -40,8 +41,180 @@ section { // desktop and tablet devices @media (min-width: map-get($grid-breakpoints, phone)) { - + + .more-space-bottom { + margin-bottom: 15px !important; + } + .app-toolbar-mobile { display: none; } } + +.project-info-container { + width: 98vw; + max-width: 1280px; + position: relative; + margin: 0 auto 60px auto; + + .left-info { + flex: 70%; + } + + .right-info { + flex: 30%; + max-width: 400px; + } + + .column { + padding: 15px; + } + + .metadata-box { + padding: 19px; + margin-bottom: 20px; + background-color: whitesmoke; + border: 1px solid $primary_100; + border-radius: $border-radius; + box-shadow: inset 0 1px 1px rgba(0,0,0,.05); + } + + .tab-contents { + margin-top: 20px; + } + + .display-inline-block { + display: inline-block; + } + + .copy-to-clipboard { + display: inline-block; + float: right; + + button { + cursor: pointer; + border: none; + } + } + + .mat-radio-button { + margin-bottom: 5px; + display: block; + } + + /* + .mat-radio-container{ + height: 15px; + width: 15px; + } + .mat-radio-outer-circle{ + height: 15px; + width: 15px; + } + .mat-radio-inner-circle{ + height: 15px; + width: 15px; + } + .mat-radio-button .mat-radio-ripple{ + height: 15px; + width: 15px; + left: calc(50% - 15px); + top: calc(50% - 15px); + } + */ + + .download-metadata { + margin-right: 10px; + } + + .sidenav-prop-text { + text-align: left; + overflow-wrap: break-word; + font-weight: inherit; + color: #434242; + } + + .sidenav-properties-container { + + .property { + + .property-label { + font-weight: bold; + font-size: 16px; + margin-bottom: 8px; + text-align: left; + overflow-wrap: break-word; + } + + .property-value { + margin-left: 20px; + } + } + + .property:not(:last-child) { + margin-bottom: 13px; + } + } + + // grid + ::ng-deep .properties-container { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 16px; + + .properties { + grid-column: 1 / span 6; + margin-top: 16px; + + .property { + grid-row: 1 / 1; + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 16px; + margin-top: 5px; + + .property-label, + .property-value { + overflow-wrap: break-word; + } + + .property-label { + grid-column: 1 / span 1; + padding: 2px; + + .label { + text-align: right; + color: rgba(0,0,0,.54); + } + } + + .property-value { + grid-column: 2 / span 3; + padding: 5px 2px 8px; + } + } + } + } + + ::ng-deep .person { + + h4 { + margin-bottom: 6px; + margin-top: 6px; + display: inline-block; + } + + p { + margin-top: 0px; + margin-bottom: 8px; + } + + .sub-details { + margin-top: 10px; + .contents { + margin-left: 35px; + } + } + } + +} diff --git a/src/app/project/board/board.component.spec.ts b/src/app/project/board/board.component.spec.ts index e3b7d67f8f..d0be5e4144 100644 --- a/src/app/project/board/board.component.spec.ts +++ b/src/app/project/board/board.component.spec.ts @@ -6,16 +6,15 @@ import { MatIconModule } from '@angular/material/icon'; import { ActivatedRoute } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { KnoraApiConnection } from '@dasch-swiss/dsp-js'; -import { - AppInitService, - DspActionModule, - DspApiConfigToken, - DspApiConnectionToken, - DspCoreModule -} from '@dasch-swiss/dsp-ui'; +import { AppInitService, DspActionModule, DspApiConfigToken, DspApiConnectionToken, DspCoreModule } from '@dasch-swiss/dsp-ui'; import { of } from 'rxjs'; import { TestConfig } from 'test.config'; import { BoardComponent } from './board.component'; +import { AttributionTabViewComponent } from './attribution-tab-view/attribution-tab-view.component'; +import { ContactsTabViewComponent } from './contacts-tab-view/contacts-tab-view.component'; +import { DatasetTabViewComponent } from './dataset-tab-view/dataset-tab-view.component'; +import { ProjectTabViewComponent } from './project-tab-view/project-tab-view.component'; +import { TermsTabViewComponent } from './terms-tab-view/terms-tab-view.component'; describe('BoardComponent', () => { let component: BoardComponent; @@ -23,7 +22,14 @@ describe('BoardComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [BoardComponent], + declarations: [ + BoardComponent, + AttributionTabViewComponent, + ContactsTabViewComponent, + DatasetTabViewComponent, + ProjectTabViewComponent, + TermsTabViewComponent + ], imports: [ DspActionModule, DspCoreModule, diff --git a/src/app/project/board/board.component.ts b/src/app/project/board/board.component.ts index 39aef68226..4fe406ca00 100644 --- a/src/app/project/board/board.component.ts +++ b/src/app/project/board/board.component.ts @@ -2,10 +2,12 @@ import { Component, Inject, OnInit } from '@angular/core'; import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; import { Title } from '@angular/platform-browser'; import { ActivatedRoute, Params } from '@angular/router'; -import { ApiResponseData, ApiResponseError, KnoraApiConnection, ProjectResponse, ReadProject, ReadUser } from '@dasch-swiss/dsp-js'; +import { ApiResponseData, ApiResponseError, KnoraApiConnection, ProjectResponse, ReadProject } from '@dasch-swiss/dsp-js'; import { DspApiConnectionToken, Session, SessionService } from '@dasch-swiss/dsp-ui'; import { DialogComponent } from 'src/app/main/dialog/dialog.component'; import { CacheService } from '../../main/cache/cache.service'; +import { MatRadioChange } from '@angular/material/radio'; +import { ClipboardService } from 'ngx-clipboard'; @Component({ selector: 'app-board', @@ -14,7 +16,7 @@ import { CacheService } from '../../main/cache/cache.service'; }) export class BoardComponent implements OnInit { - // loading for progess indicator + // loading for progress indicator loading: boolean; // permissions of logged-in user @@ -28,23 +30,26 @@ export class BoardComponent implements OnInit { // project data project: ReadProject; - projectMembers: ReadUser[] = []; - - // i18n setup - itemPluralMapping = { - member: { - '=1': '1 User', - other: '# Users' - }, - ontology: { - '=1': '1 Ontology', - other: '# Ontologies' - }, - keyword: { - '=1': '1 Keyword', - other: '# Keywords' - } - }; + color: string = 'primary'; + + // variables to store metadata information + metadata: object; + datasetMetadata: object; + projectMetadata: object; + attribution: object; + conditionsOfAccess: string; + license: object; + contactDetails: object; + projectDescription: string; + datasetOptions: object[]; + howToCite: string; + datasetIdentifier: string; + publicationDate: string; + keywords: object; + selectedDataset: string; + + // different metadata download formats + metadataDownloadFormats = ['XML', 'JSON', 'JSON-LD', 'Triplestore']; constructor( @Inject(DspApiConnectionToken) private _dspApiConnection: KnoraApiConnection, @@ -52,7 +57,8 @@ export class BoardComponent implements OnInit { private _session: SessionService, private _dialog: MatDialog, private _route: ActivatedRoute, - private _titleService: Title + private _titleService: Title, + private _clipboardService: ClipboardService ) { // get the shortcode of the current project this._route.parent.paramMap.subscribe((params: Params) => { @@ -73,7 +79,11 @@ export class BoardComponent implements OnInit { this.sysAdmin = this.session.user.sysAdmin; } + // get project info from backend this.getProject(); + + // get project and dataset metadata from backend + this.getProjectMetadata(); } getProject() { @@ -90,6 +100,8 @@ export class BoardComponent implements OnInit { this.projectAdmin = this.sysAdmin ? this.sysAdmin : this.session.user.projectAdmin.some(e => e === this.project.id); } + this.datasetIdentifier = this.project['id']; + this.loading = false; }, (error: ApiResponseError) => { @@ -100,13 +112,174 @@ export class BoardComponent implements OnInit { this.loading = false; } + getProjectMetadata() { + // get project metadata from backend + // note: for now to complete functionality we have used hard-coded metadata. + // in next iteration, it will be replace with ajax request to get + // metadata from backend + this.metadata = { + 'projectsMetadata': [{ + 'abstract': 'Dies ist ein Testprojekt.', + 'alternativeTitle': 'test', + 'conditionsOfAccess': 'Open Access', + 'dateCreated': '2001-09-26', + 'dateModified': '2020-04-26', + 'datePublished': '2002-09-24', + 'distribution': {'type': 'https://schema.org/DataDownload', 'value': 'https://test.dasch.swiss'}, + 'documentation': 'Work in progress', + 'howToCite': 'Testprojekt (test), 2002, https://test.dasch.swiss', + 'language': ['EN', 'DE', 'FR'], + 'license': {'type': 'https://schema.org/URL', 'value': 'https://creativecommons.org/licenses/by/3.0'}, + 'qualifiedAttribution': [{'role': 'contributor', 'agent': 'http://ns.dasch.swiss/test-berry'}, {'role': 'contributor', 'agent': 'http://ns.dasch.swiss/test-hart'}, { + 'role': 'editor', + 'agent': 'http://ns.dasch.swiss/test-abraham' + }, {'role': 'editor', 'agent': 'http://ns.dasch.swiss/test-coleman'}, {'role': 'editor', 'agent': 'http://ns.dasch.swiss/test-jones'}], + 'status': 'ongoing', + 'title': 'Testprojekt', + 'typeOfData': ['image', 'text'], + 'project': { + 'alternateName': 'test', + 'contactPoint': { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'stewart.abraham@test.ch', + 'familyName': 'Abraham', + 'givenName': 'Stewart', + 'jobTitle': 'Dr.', + 'memberOf': 'http://ns.dasch.swiss/test-dasch', + 'sameAs': {'type': 'https://schema.org/URL', 'value': 'https://orcid.org/0000-0002-1825-0097'}, + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': '/info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': {'type': 'https://schema.org/URL', 'value': 'http://www.utoronto.ca/'} + } + }, + 'dataManagementPlan': {'url': {'type': 'https://schema.org/URL', 'value': 'https://snf.ch'}, 'isAvailable': true}, + 'description': 'Dies ist ein Testprojekt...alle Properties wurden verwendet, um diese zu testen', + 'discipline': {'name': 'SKOS UNESCO Nomenclature', 'url': 'http://skos.um.es/unesco6/11'}, + 'endDate': '2001-01-26', + 'funder': 'http://ns.dasch.swiss/test-funder', + 'grant': { + 'funder': [ + { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': '/info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': {'type': 'https://schema.org/URL', 'value': 'http://www.utoronto.ca/'} + }, + { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'lauren.berry@unibas.ch', + 'familyName': 'Berry', + 'givenName': 'Lauren', + 'jobTitle': 'Dr.', + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': 'info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': 'http://www.utoronto.ca/' + } + }], 'name': 'Test Grant Name', 'number': '0123456789', 'url': {'type': 'https://schema.org/URL', 'value': 'http://p3.snf.ch/testproject'} + }, + 'keywords': ['science', 'mathematics', 'history of science', 'history of mathematics'], + 'name': 'Testprojektname (test)', + 'publication': 'testpublication', + 'shortcode': '0000', + 'spatialCoverage': [ + {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/2017370/russian-federation.html'}}, { + 'place': { + 'name': 'Geonames', + 'url': 'https://www.geonames.org/2658434/switzerland.html' + } + }, {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/3175395/italian-republic.html'}}, { + 'place': { + 'name': 'Geonames', + 'url': 'https://www.geonames.org/2921044/federal-republic-of-germany.html' + } + }, {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/3017382/republic-of-france.html'}}, { + 'place': { + 'name': 'Geonames', + 'url': 'https://www.geonames.org/6269131/england.html' + } + }, {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/6255148/europe.html'}}], + 'startDate': '2000-07-26', + 'temporalCoverage': {'name': 'Chronontology Dainst', 'url': 'http://chronontology.dainst.org/period/Ef9SyESSafJ1'}, + 'url': {'type': 'https://schema.org/URL', 'value': 'https://test.dasch.swiss/'} + }, + 'sameAs': {'type': 'https://schema.org/URL', 'value': 'https://test.dasch.swiss/'} + }, { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': '/benjamin.jones@test.ch', + 'familyName': 'Jones', + 'givenName': 'Benjamin', + 'jobTitle': 'Dr. des.', + 'memberOf': 'http://ns.dasch.swiss/test-dasch' + }, { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': '/james.coleman@dasch.swiss', + 'familyName': 'Coleman', + 'givenName': 'James', + 'jobTitle': 'Dr. des.', + 'memberOf': 'http://ns.dasch.swiss/test-dasch' + }, { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': '/lauren.berry@unibas.ch', + 'familyName': 'Berry', + 'givenName': 'Lauren', + 'jobTitle': 'Dr.', + 'memberOf': 'http://ns.dasch.swiss/test-dasch' + }, { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': '/leonhard.hart@test.ch', + 'familyName': 'Hart', + 'givenName': 'Leonhard', + 'jobTitle': 'Prof.', + 'memberOf': 'http://ns.dasch.swiss/test-dasch' + }] + }; + + this.datasetMetadata = this.metadata['projectsMetadata'][0]; + + // dataset options to display radio buttons for selection in right column + this.datasetOptions = [ + {'name': this.datasetMetadata['title'], 'id': 0, 'checked': true} + ]; + + // initialise metadata + this.initialiseMetadataVariables(); + } + + // initialise metadata variables required to display in template + initialiseMetadataVariables() { + this.projectMetadata = this.datasetMetadata['project']; + this.attribution = this.datasetMetadata['qualifiedAttribution']; + this.conditionsOfAccess = this.datasetMetadata['conditionsOfAccess']; + this.license = this.datasetMetadata['license']; + this.contactDetails = this.projectMetadata['contactPoint']; + this.projectDescription = this.projectMetadata['description']; + this.howToCite = this.datasetMetadata['howToCite']; + this.publicationDate = this.datasetMetadata['datePublished']; + this.keywords = this.projectMetadata['keywords']; + } + + updateDataset(event: MatRadioChange) { + this.datasetMetadata = this.metadata['projectsMetadata'][event.value]; + + // initialise metadata variables again + this.initialiseMetadataVariables(); + } + + copyHowToCiteToClipboard() { + this._clipboardService.copyFromContent(this.howToCite); + } + openDialog(mode: string, name: string, id?: string): void { const dialogConfig: MatDialogConfig = { width: '560px', position: { top: '112px' }, - data: { mode: mode, title: name, project: id } + data: {mode: mode, title: name, project: id} }; const dialogRef = this._dialog.open(DialogComponent, dialogConfig); diff --git a/src/app/project/board/contacts-tab-view/contacts-tab-view.component.html b/src/app/project/board/contacts-tab-view/contacts-tab-view.component.html new file mode 100644 index 0000000000..e2a6a19b98 --- /dev/null +++ b/src/app/project/board/contacts-tab-view/contacts-tab-view.component.html @@ -0,0 +1,5 @@ +

Contact

+ +
+ +
diff --git a/src/app/project/board/contacts-tab-view/contacts-tab-view.component.scss b/src/app/project/board/contacts-tab-view/contacts-tab-view.component.scss new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/app/project/board/contacts-tab-view/contacts-tab-view.component.scss @@ -0,0 +1 @@ + diff --git a/src/app/project/board/contacts-tab-view/contacts-tab-view.component.spec.ts b/src/app/project/board/contacts-tab-view/contacts-tab-view.component.spec.ts new file mode 100644 index 0000000000..cdc11b081c --- /dev/null +++ b/src/app/project/board/contacts-tab-view/contacts-tab-view.component.spec.ts @@ -0,0 +1,51 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ContactsTabViewComponent } from './contacts-tab-view.component'; +import { Component, ViewChild } from '@angular/core'; + +/** + * Test host component to simulate parent component. + */ +@Component({ + selector: 'app-board-host-component', + template: '' +}) +class TestHostBoardComponent { + + @ViewChild('contactsTabView') contactsTabView: ContactsTabViewComponent; + + // input parameters + contactDetails = { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'stewart.abraham@test.ch', + 'familyName': 'Abraham', + 'givenName': 'Stewart', + 'jobTitle': 'Dr.', + 'memberOf': 'http://ns.dasch.swiss/test-dasch', + 'sameAs': {'type': 'https://schema.org/URL', 'value': 'https://orcid.org/0000-0002-1825-0097'} + }; +} + +describe('ContactsTabViewComponent', () => { + let testHostComponent: TestHostBoardComponent; + let testHostFixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + TestHostBoardComponent, + ContactsTabViewComponent + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + testHostFixture = TestBed.createComponent(TestHostBoardComponent); + testHostComponent = testHostFixture.componentInstance; + testHostFixture.detectChanges(); + }); + + it('should create', () => { + expect(testHostComponent).toBeTruthy(); + }); +}); diff --git a/src/app/project/board/contacts-tab-view/contacts-tab-view.component.ts b/src/app/project/board/contacts-tab-view/contacts-tab-view.component.ts new file mode 100644 index 0000000000..78b45cd77a --- /dev/null +++ b/src/app/project/board/contacts-tab-view/contacts-tab-view.component.ts @@ -0,0 +1,26 @@ +import { Component, Input, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-contacts-tab-view', + templateUrl: './contacts-tab-view.component.html', + styleUrls: ['./contacts-tab-view.component.scss'] +}) +export class ContactsTabViewComponent implements OnInit { + + // contact details + @Input() contactDetails: object; + + ngOnInit(): void { + // reformat data + if (this.contactDetails['sameAs']) { + this.contactDetails['sameAs'] = this.contactDetails['sameAs']['value']; + } + + if (this.contactDetails['organisation']) { + if (this.contactDetails['organisation']['url']) { + this.contactDetails['organisation']['url'] = this.contactDetails['organisation']['url']['value']; + } + } + } + +} diff --git a/src/app/project/board/dataset-tab-view/dataset-tab-view.component.html b/src/app/project/board/dataset-tab-view/dataset-tab-view.component.html new file mode 100644 index 0000000000..00aedc1abb --- /dev/null +++ b/src/app/project/board/dataset-tab-view/dataset-tab-view.component.html @@ -0,0 +1,35 @@ +
+

Selected dataset: {{ metadata['title'] }}

+

Click on the radio button in the right side panel to change the dataset.

+
+ +
+

Default dataset is displayed, to change it click on the radio button in the right side panel.

+
+ + + +
+
+
+
+
+

+ {{ prop.key }} +

+
+
+ {{ prop.value }} +
+
+ +
+ {{ prop.value | date:'MMMM d, yyyy' }} +
+
+
+
+
+
diff --git a/src/app/project/board/dataset-tab-view/dataset-tab-view.component.scss b/src/app/project/board/dataset-tab-view/dataset-tab-view.component.scss new file mode 100644 index 0000000000..e5780ee921 --- /dev/null +++ b/src/app/project/board/dataset-tab-view/dataset-tab-view.component.scss @@ -0,0 +1,7 @@ +@import "../../../../assets/style/config"; + +.note { + font-style: italic; + color: $warn; + padding-left: 0px; +} diff --git a/src/app/project/board/dataset-tab-view/dataset-tab-view.component.spec.ts b/src/app/project/board/dataset-tab-view/dataset-tab-view.component.spec.ts new file mode 100644 index 0000000000..e3ea70e03c --- /dev/null +++ b/src/app/project/board/dataset-tab-view/dataset-tab-view.component.spec.ts @@ -0,0 +1,133 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { DatasetTabViewComponent } from './dataset-tab-view.component'; +import { Component, ViewChild } from '@angular/core'; + + +/** + * Test host component to simulate parent component. + */ +@Component({ + selector: 'app-board-host-component', + template: '' +}) +class TestHostBoardComponent { + + @ViewChild('datasetTabView') datasetTabView: DatasetTabViewComponent; + + // metadata object + datasetMetadata = { + 'abstract': 'Dies ist ein Testprojekt.', + 'alternativeTitle': 'test', + 'conditionsOfAccess': 'Open Access', + 'dateCreated': '2001-09-26', + 'dateModified': '2020-04-26', + 'datePublished': '2002-09-24', + 'distribution': {'type': 'https://schema.org/DataDownload', 'value': 'https://test.dasch.swiss'}, + 'documentation': 'Work in progress', + 'howToCite': 'Testprojekt (test), 2002, https://test.dasch.swiss', + 'language': ['EN', 'DE', 'FR'], + 'license': {'type': 'https://schema.org/URL', 'value': 'https://creativecommons.org/licenses/by/3.0'}, + 'qualifiedAttribution': [{'role': 'contributor', 'agent': 'http://ns.dasch.swiss/test-berry'}, {'role': 'contributor', 'agent': 'http://ns.dasch.swiss/test-hart'}, { + 'role': 'editor', + 'agent': 'http://ns.dasch.swiss/test-abraham' + }, {'role': 'editor', 'agent': 'http://ns.dasch.swiss/test-coleman'}, {'role': 'editor', 'agent': 'http://ns.dasch.swiss/test-jones'}], + 'status': 'ongoing', + 'title': 'Testprojekt', + 'typeOfData': ['image', 'text'], + 'project': { + 'alternateName': 'test', + 'contactPoint': { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'stewart.abraham@test.ch', + 'familyName': 'Abraham', + 'givenName': 'Stewart', + 'jobTitle': 'Dr.', + 'memberOf': 'http://ns.dasch.swiss/test-dasch', + 'sameAs': {'type': 'https://schema.org/URL', 'value': 'https://orcid.org/0000-0002-1825-0097'}, + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': '/info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': {'type': 'https://schema.org/URL', 'value': 'http://www.utoronto.ca/'} + } + }, + 'dataManagementPlan': {'url': {'type': 'https://schema.org/URL', 'value': 'https://snf.ch'}, 'isAvailable': false}, + 'description': 'Dies ist ein Testprojekt...alle Properties wurden verwendet, um diese zu testen', + 'discipline': {'name': 'SKOS UNESCO Nomenclature', 'url': 'http://skos.um.es/unesco6/11'}, + 'endDate': '2001-01-26', + 'funder': 'http://ns.dasch.swiss/test-funder', + 'grant': { + 'funder': [ + { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': '/info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': {'type': 'https://schema.org/URL', 'value': 'http://www.utoronto.ca/'} + }, + { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'lauren.berry@unibas.ch', + 'familyName': 'Berry', + 'givenName': 'Lauren', + 'jobTitle': 'Dr.', + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': 'info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': 'http://www.utoronto.ca/' + } + }], 'name': 'Test Grant Name', 'number': '0123456789', 'url': {'type': 'https://schema.org/URL', 'value': 'http://p3.snf.ch/testproject'} + }, + 'keywords': ['science', 'mathematics', 'history of science', 'history of mathematics'], + 'name': 'Testprojektname (test)', + 'publication': 'testpublication', + 'shortcode': '0000', + 'spatialCoverage': [ + {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/2017370/russian-federation.html'}}, { + 'place': { + 'name': 'Geonames', + 'url': 'https://www.geonames.org/2658434/switzerland.html' + } + }, {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/3175395/italian-republic.html'}}, { + 'place': { + 'name': 'Geonames', + 'url': 'https://www.geonames.org/2921044/federal-republic-of-germany.html' + } + }, {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/3017382/republic-of-france.html'}}, { + 'place': { + 'name': 'Geonames', + 'url': 'https://www.geonames.org/6269131/england.html' + } + }, {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/6255148/europe.html'}}], + 'startDate': '2000-07-26', + 'temporalCoverage': {'name': 'Chronontology Dainst', 'url': 'http://chronontology.dainst.org/period/Ef9SyESSafJ1'}, + 'url': {'type': 'https://schema.org/URL', 'value': 'https://test.dasch.swiss/'} + }, + 'sameAs': {'type': 'https://schema.org/URL', 'value': 'https://test.dasch.swiss/'} + }; +} + +describe('DatasetTabViewComponent', () => { + let testHostComponent: TestHostBoardComponent; + let testHostFixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + TestHostBoardComponent, + DatasetTabViewComponent + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + testHostFixture = TestBed.createComponent(TestHostBoardComponent); + testHostComponent = testHostFixture.componentInstance; + testHostFixture.detectChanges(); + }); + + it('should create', () => { + expect(testHostComponent).toBeTruthy(); + }); +}); diff --git a/src/app/project/board/dataset-tab-view/dataset-tab-view.component.ts b/src/app/project/board/dataset-tab-view/dataset-tab-view.component.ts new file mode 100644 index 0000000000..cbc12020d0 --- /dev/null +++ b/src/app/project/board/dataset-tab-view/dataset-tab-view.component.ts @@ -0,0 +1,25 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-dataset-tab-view', + templateUrl: './dataset-tab-view.component.html', + styleUrls: ['./dataset-tab-view.component.scss'] +}) +export class DatasetTabViewComponent { + + // metadata input object + @Input() metadata: object; + + // number of datasets available for this project + @Input() noOfDatasets: number; + + // metadata keys that we do not want to display + excludeKeys = ['project', 'qualifiedAttribution']; + + // metadata keys that require specific format to display + templateKeys = ['distribution', 'license', 'sameAs', 'dateCreated', 'dateModified', 'datePublished']; + + // date keys from metadata object for formatting + dateKeys = ['dateCreated', 'dateModified', 'datePublished']; + +} diff --git a/src/app/project/board/organisation-template/organisation-template.component.ts b/src/app/project/board/organisation-template/organisation-template.component.ts new file mode 100644 index 0000000000..05d9cffe4a --- /dev/null +++ b/src/app/project/board/organisation-template/organisation-template.component.ts @@ -0,0 +1,32 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-organisation-template', + template: ` + +
+
+ + {{ organisation['name'] }} +
+ + + + + + +
+ `, + styles: ['.metadata-title { font-size: 95%; }'] +}) +export class OrganisationTemplateComponent { + + // input parameter + @Input() organisation: object; +} diff --git a/src/app/project/board/person-template/person-template.component.html b/src/app/project/board/person-template/person-template.component.html new file mode 100644 index 0000000000..1c38f1342c --- /dev/null +++ b/src/app/project/board/person-template/person-template.component.html @@ -0,0 +1,28 @@ +
+

{{ person['givenName'] }} {{person['familyName'] }}

+ +
+

Job title:

+ {{ person['jobTitle'] }} +
+ + + + + + + +
+

Member of:

+
+ +
+
+ +
diff --git a/src/app/project/board/person-template/person-template.component.scss b/src/app/project/board/person-template/person-template.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/project/board/person-template/person-template.component.spec.ts b/src/app/project/board/person-template/person-template.component.spec.ts new file mode 100644 index 0000000000..ddfcdaaad7 --- /dev/null +++ b/src/app/project/board/person-template/person-template.component.spec.ts @@ -0,0 +1,52 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { PersonTemplateComponent } from './person-template.component'; +import { Component, ViewChild } from '@angular/core'; + + +/** + * Test host component to simulate parent component. + */ +@Component({ + selector: 'app-contact-host-component', + template: '' +}) +class TestHostContactComponent { + + @ViewChild('personView') personView: PersonTemplateComponent; + + // input parameters + contactDetails = { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'stewart.abraham@test.ch', + 'familyName': 'Abraham', + 'givenName': 'Stewart', + 'jobTitle': 'Dr.', + 'memberOf': 'http://ns.dasch.swiss/test-dasch', + 'sameAs': 'https://orcid.org/0000-0002-1825-0097' + }; +} + +describe('PersonTemplateComponent', () => { + let testHostComponent: TestHostContactComponent; + let testHostFixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + TestHostContactComponent, + PersonTemplateComponent + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + testHostFixture = TestBed.createComponent(TestHostContactComponent); + testHostComponent = testHostFixture.componentInstance; + testHostFixture.detectChanges(); + }); + + it('should create', () => { + expect(testHostComponent).toBeTruthy(); + }); +}); diff --git a/src/app/project/board/person-template/person-template.component.ts b/src/app/project/board/person-template/person-template.component.ts new file mode 100644 index 0000000000..f250e5e372 --- /dev/null +++ b/src/app/project/board/person-template/person-template.component.ts @@ -0,0 +1,25 @@ +import {Component, Input} from '@angular/core'; + +@Component({ + selector: 'app-person-template', + templateUrl: './person-template.component.html', + styleUrls: ['./person-template.component.scss'] +}) +export class PersonTemplateComponent { + + /* + Format for person object: + person = { + jobTitle: '', + givenName: '', + familyName: '', + email: ''. + sameAs: '', + address: '
', + organisation: '' + } + */ + // input parameter + @Input() person: object; + +} diff --git a/src/app/project/board/project-tab-view/project-tab-view.component.html b/src/app/project/board/project-tab-view/project-tab-view.component.html new file mode 100644 index 0000000000..1715b03af0 --- /dev/null +++ b/src/app/project/board/project-tab-view/project-tab-view.component.html @@ -0,0 +1,94 @@ +

Metadata for selected project is listed below.

+ +
+
+
+
+
+

+ {{ prop.key }} +

+
+
+ + + + + + + + + + + +
+ + {{ k }} + +
+ + +
+

{{ metadata['dataManagementPlan']['isAvailable']? 'Available' : 'Unavailable' }}

+

+ URL: {{ metadata['dataManagementPlan']['url']['value'] }} +

+
+ + +
+ +
+

{{ metadata['grant']['name'] }}

+ + + + +
+

Funder(s):

+ +
+ +
+
+ +
+
+
+
+ +
+ + +
+
+ {{ coverage.value['place']['name'] }} ( {{ coverage.value['place']['url'] }} ) +
+
+ + +
+
+ {{ prop.value }} +
+
+ {{ prop.value | date:'MMMM d, yyyy' }} +
+
+
+
+
+
+
diff --git a/src/app/project/board/project-tab-view/project-tab-view.component.scss b/src/app/project/board/project-tab-view/project-tab-view.component.scss new file mode 100644 index 0000000000..74bc5dadf0 --- /dev/null +++ b/src/app/project/board/project-tab-view/project-tab-view.component.scss @@ -0,0 +1,17 @@ +.mat-icon-text { + display: flex; + align-items: center; + + .mat-icon { + margin-right: 8px; + } +} + +.funder-entry { + margin-bottom: 15px; + margin-left: 35px; +} + +.remove-top-margin { + margin-top: 0px; +} diff --git a/src/app/project/board/project-tab-view/project-tab-view.component.spec.ts b/src/app/project/board/project-tab-view/project-tab-view.component.spec.ts new file mode 100644 index 0000000000..0434d3504d --- /dev/null +++ b/src/app/project/board/project-tab-view/project-tab-view.component.spec.ts @@ -0,0 +1,112 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ProjectTabViewComponent } from './project-tab-view.component'; +import { Component, ViewChild } from '@angular/core'; + +/** + * Test host component to simulate parent component. + */ +@Component({ + selector: 'app-board-host-component', + template: '' +}) +class TestHostBoardComponent { + + @ViewChild('projectTabView') projectTabView: ProjectTabViewComponent; + + // input parameters + projectMetadata = { + 'alternateName': 'test', + 'contactPoint': { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'stewart.abraham@test.ch', + 'familyName': 'Abraham', + 'givenName': 'Stewart', + 'jobTitle': 'Dr.', + 'memberOf': 'http://ns.dasch.swiss/test-dasch', + 'sameAs': {'type': 'https://schema.org/URL', 'value': 'https://orcid.org/0000-0002-1825-0097'}, + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': '/info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': {'type': 'https://schema.org/URL', 'value': 'http://www.utoronto.ca/'} + } + }, + 'dataManagementPlan': {'url': {'type': 'https://schema.org/URL', 'value': 'https://snf.ch'}, 'isAvailable': false}, + 'description': 'Dies ist ein Testprojekt...alle Properties wurden verwendet, um diese zu testen', + 'discipline': {'name': 'SKOS UNESCO Nomenclature', 'url': 'http://skos.um.es/unesco6/11'}, + 'endDate': '2001-01-26', + 'funder': 'http://ns.dasch.swiss/test-funder', + 'grant': { + 'funder': [ + { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': '/info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': {'type': 'https://schema.org/URL', 'value': 'http://www.utoronto.ca/'} + }, + { + 'address': {'addressLocality': 'Basel', 'postalCode': '4000', 'streetAddress': 'Teststrasse'}, + 'email': 'lauren.berry@unibas.ch', + 'familyName': 'Berry', + 'givenName': 'Lauren', + 'jobTitle': 'Dr.', + 'organisation': { + 'address': {'addressLocality': 'Toronto', 'postalCode': '40000', 'streetAddress': 'University of Toronto Street'}, + 'email': 'info@universityoftoronto.ca', + 'name': 'University of Toronto', + 'url': 'http://www.utoronto.ca/' + } + }], 'name': 'Test Grant Name', 'number': '0123456789', 'url': {'type': 'https://schema.org/URL', 'value': 'http://p3.snf.ch/testproject'} + }, + 'keywords': ['science', 'mathematics', 'history of science', 'history of mathematics'], + 'name': 'Testprojektname (test)', + 'publication': 'testpublication', + 'shortcode': '0000', + 'spatialCoverage': [ + {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/2017370/russian-federation.html'}}, { + 'place': { + 'name': 'Geonames', + 'url': 'https://www.geonames.org/2658434/switzerland.html' + } + }, {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/3175395/italian-republic.html'}}, { + 'place': { + 'name': 'Geonames', + 'url': 'https://www.geonames.org/2921044/federal-republic-of-germany.html' + } + }, {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/3017382/republic-of-france.html'}}, { + 'place': { + 'name': 'Geonames', + 'url': 'https://www.geonames.org/6269131/england.html' + } + }, {'place': {'name': 'Geonames', 'url': 'https://www.geonames.org/6255148/europe.html'}}], + 'startDate': '2000-07-26', + 'temporalCoverage': {'name': 'Chronontology Dainst', 'url': 'http://chronontology.dainst.org/period/Ef9SyESSafJ1'}, + 'url': {'type': 'https://schema.org/URL', 'value': 'https://test.dasch.swiss/'} + }; + +} + +describe('ProjectTabViewComponent', () => { + let testHostComponent: TestHostBoardComponent; + let testHostFixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + TestHostBoardComponent, + ProjectTabViewComponent + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + testHostFixture = TestBed.createComponent(TestHostBoardComponent); + testHostComponent = testHostFixture.componentInstance; + testHostFixture.detectChanges(); + }); + + it('should create', () => { + expect(testHostComponent).toBeTruthy(); + }); +}); diff --git a/src/app/project/board/project-tab-view/project-tab-view.component.ts b/src/app/project/board/project-tab-view/project-tab-view.component.ts new file mode 100644 index 0000000000..874aeea674 --- /dev/null +++ b/src/app/project/board/project-tab-view/project-tab-view.component.ts @@ -0,0 +1,20 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-project-tab-view', + templateUrl: './project-tab-view.component.html', + styleUrls: ['./project-tab-view.component.scss'] +}) +export class ProjectTabViewComponent { + + // metadata object + @Input() metadata: object; + + // metadata keys that we do not want to display in template + excludeKeys = ['contactPoint']; + + // list of date keys from metadata object + // used for formatting + dateKeys = ['startDate', 'endDate']; + +} diff --git a/src/app/project/board/terms-tab-view/terms-tab-view.component.html b/src/app/project/board/terms-tab-view/terms-tab-view.component.html new file mode 100644 index 0000000000..4079e2cdf5 --- /dev/null +++ b/src/app/project/board/terms-tab-view/terms-tab-view.component.html @@ -0,0 +1,15 @@ +

Terms & Conditions

+ +
+ +
+

Conditions of access:

+

{{ conditions }}

+
+ +
+

License:

+ + {{ license['value'] }} +
+
diff --git a/src/app/project/board/terms-tab-view/terms-tab-view.component.scss b/src/app/project/board/terms-tab-view/terms-tab-view.component.scss new file mode 100644 index 0000000000..149aa78f30 --- /dev/null +++ b/src/app/project/board/terms-tab-view/terms-tab-view.component.scss @@ -0,0 +1,14 @@ +.license-image { + max-width: 200px; + object-fit: contain; + margin: 24px 0px; + display: block; +} + +.display-inline-block { + display: inline-block; +} + +.add-left-margin { + margin-left: 8px; +} diff --git a/src/app/project/board/terms-tab-view/terms-tab-view.component.spec.ts b/src/app/project/board/terms-tab-view/terms-tab-view.component.spec.ts new file mode 100644 index 0000000000..7783c273a5 --- /dev/null +++ b/src/app/project/board/terms-tab-view/terms-tab-view.component.spec.ts @@ -0,0 +1,45 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { TermsTabViewComponent } from './terms-tab-view.component'; +import { Component, ViewChild } from '@angular/core'; + +/** + * Test host component to simulate parent component. + */ +@Component({ + selector: 'app-board-host-component', + template: '' +}) +class TestHostBoardComponent { + + @ViewChild('termsTabView') termsTabView: TermsTabViewComponent; + + // input parameters + conditionsOfAccess = 'Open Access'; + license = {'type': 'https://schema.org/URL', 'value': 'https://creativecommons.org/licenses/by/3.0'}; +} + +describe('TermsTabViewComponent', () => { + let testHostComponent: TestHostBoardComponent; + let testHostFixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + TestHostBoardComponent, + TermsTabViewComponent + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + testHostFixture = TestBed.createComponent(TestHostBoardComponent); + testHostComponent = testHostFixture.componentInstance; + testHostFixture.detectChanges(); + }); + + it('should create', () => { + expect(testHostComponent).toBeTruthy(); + }); +}); + diff --git a/src/app/project/board/terms-tab-view/terms-tab-view.component.ts b/src/app/project/board/terms-tab-view/terms-tab-view.component.ts new file mode 100644 index 0000000000..cf9ea8661a --- /dev/null +++ b/src/app/project/board/terms-tab-view/terms-tab-view.component.ts @@ -0,0 +1,16 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-terms-tab-view', + templateUrl: './terms-tab-view.component.html', + styleUrls: ['./terms-tab-view.component.scss'] +}) +export class TermsTabViewComponent { + + // conditions input from parent component to display it in template + @Input() conditions: string; + + // license from parent component to display it in template + @Input() license: object; + +} diff --git a/src/assets/images/cc-license.png b/src/assets/images/cc-license.png new file mode 100644 index 0000000000..5c71d21fff Binary files /dev/null and b/src/assets/images/cc-license.png differ diff --git a/src/assets/style/_config.scss b/src/assets/style/_config.scss index 3cd5a4b4b9..29afb876ce 100644 --- a/src/assets/style/_config.scss +++ b/src/assets/style/_config.scss @@ -1,6 +1,6 @@ $primary_50: #eceff1; $primary_100: #cfd8dc; -$primary_200: #b0bec5; +$primary_200: #d4d3d3; $primary_300: #90a4ae; $primary_400: #78909c; $primary_500: #607d8b;