Skip to content

Commit

Permalink
feat(project): proof of new project workflow concept (DEV-985) (#760)
Browse files Browse the repository at this point in the history
* feat(workflow): new project concept

* feat(workflow): new project concept

* feat(workflow): new project concept

* feat(workflow): new project concept

* feat(workflow): new project concept

* feat(workflow): new project concept

* test: start to fix unit tests

* test(list): refactor tests and list route

* test: refactor and resolve unit tests

* chore(beta): avoid 404 when old route is active

* refactor: clean up code
  • Loading branch information
kilchenmann committed Jun 10, 2022
1 parent 5884f51 commit 2391f2a
Show file tree
Hide file tree
Showing 45 changed files with 1,246 additions and 147 deletions.
90 changes: 78 additions & 12 deletions src/app/app-routing.module.ts
@@ -1,34 +1,31 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { AuthGuard } from './main/guard/auth.guard';
import { HintComponent } from './main/action/hint/hint.component';
import { LoginFormComponent } from './main/action/login-form/login-form.component';
import { CookiePolicyComponent } from './main/cookie-policy/cookie-policy.component';
import { StatusComponent } from './main/status/status.component';
import { AuthGuard } from './main/guard/auth.guard';
import { HelpComponent } from './main/help/help.component';
import { LoginFormComponent } from './main/action/login-form/login-form.component';
import { MainComponent } from './main/main.component';

import { StatusComponent } from './main/status/status.component';
import { OntologyClassInstanceComponent } from './project/beta/ontology-classes/ontology-class-instance/ontology-class-instance.component';
// project
import { BoardComponent } from './project/board/board.component';
import { CollaborationComponent } from './project/collaboration/collaboration.component';
import { ListComponent } from './project/list/list.component';
import { OntologyComponent } from './project/ontology/ontology.component';
import { PermissionComponent } from './project/permission/permission.component';
import { ProjectComponent } from './project/project.component';

import { ProjectsComponent } from './system/projects/projects.component';
// system
import { SystemComponent } from './system/system.component';
import { UsersComponent } from './system/users/users.component';
// user
import { DashboardComponent } from './user/dashboard/dashboard.component';
import { UserComponent } from './user/user.component';

// search results and resource viewer
import { ResourceComponent } from './workspace/resource/resource.component';
import { ResultsComponent } from './workspace/results/results.component';

// system
import { SystemComponent } from './system/system.component';
import { ProjectsComponent } from './system/projects/projects.component';
import { UsersComponent } from './system/users/users.component';

const routes: Routes = [
{
path: '',
Expand Down Expand Up @@ -102,6 +99,75 @@ const routes: Routes = [
}
]
},
{
path: 'beta/project/:shortcode',
component: ProjectComponent,
children: [
{
path: '',
component: BoardComponent
},
{
path: 'info', // old path setup to avoid 404 when typing beta in front of project
redirectTo: ''
},
{
path: 'ontology',
component: HintComponent,
data: { topic: 'ontology' }
},
{
path: 'ontology/:onto',
component: OntologyComponent,
canActivate: [AuthGuard]
},
{
path: 'ontology/:onto/:class',
component: OntologyClassInstanceComponent,
},
{
path: 'ontology/:onto/:class/conf',
component: StatusComponent,
data: { status: 501, comment: 'Here you will be able to configure the resource class.' },
canActivate: [AuthGuard]
},
{
path: 'ontology/:onto/:class/:instance',
component: OntologyClassInstanceComponent,
},
{
path: 'list',
component: HintComponent,
data: { topic: 'list' }
},
{
path: 'list/:list',
component: ListComponent,
canActivate: [AuthGuard]
},
{
path: 'settings',
component: StatusComponent,
data: { status: 501, comment: 'Here you will be able to configure the project: e.g. setup collaboration and permissions.' },
canActivate: [AuthGuard]
},
{
path: 'settings/collaboration',
component: CollaborationComponent,
canActivate: [AuthGuard]
},
{
path: 'settings/permissions',
component: PermissionComponent,
canActivate: [AuthGuard]
},
{
path: '**',
component: StatusComponent,
data: { status: 404 }
}
]
},
/*
{
path: 'user/:name',
Expand Down
8 changes: 7 additions & 1 deletion src/app/app.module.ts
Expand Up @@ -161,6 +161,9 @@ import { FulltextSearchComponent } from './workspace/search/fulltext-search/full
import { SearchPanelComponent } from './workspace/search/search-panel/search-panel.component';
import { HintComponent } from './main/action/hint/hint.component';
import { TextComponent } from './workspace/resource/representation/text/text.component';
import { OntologyClassesComponent } from './project/beta/ontology-classes/ontology-classes.component';
import { OntologyClassItemComponent } from './project/beta/ontology-classes/ontology-class-item/ontology-class-item.component';
import { OntologyClassInstanceComponent } from './project/beta/ontology-classes/ontology-class-instance/ontology-class-instance.component';

// translate: AoT requires an exported function for factories
export function httpLoaderFactory(httpClient: HttpClient) {
Expand Down Expand Up @@ -308,7 +311,10 @@ export function httpLoaderFactory(httpClient: HttpClient) {
VideoComponent,
VideoPreviewComponent,
HintComponent,
TextComponent
TextComponent,
OntologyClassesComponent,
OntologyClassItemComponent,
OntologyClassInstanceComponent
],
imports: [
AngularSplitModule.forRoot(),
Expand Down
5 changes: 5 additions & 0 deletions src/app/main/action/hint/hint.component.scss
@@ -1,3 +1,8 @@
:host {
padding: 16px;
display: block;
}

a {
margin: 16px auto;

Expand Down
4 changes: 3 additions & 1 deletion src/app/main/action/hint/hint.component.spec.ts
@@ -1,5 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatIconModule } from '@angular/material/icon';
import { RouterTestingModule } from '@angular/router/testing';

import { HintComponent } from './hint.component';

Expand All @@ -13,7 +14,8 @@ describe('HintComponent', () => {
HintComponent
],
imports: [
MatIconModule
MatIconModule,
RouterTestingModule
]
})
.compileComponents();
Expand Down
31 changes: 30 additions & 1 deletion src/app/main/action/hint/hint.component.ts
@@ -1,4 +1,5 @@
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
selector: 'app-hint',
Expand All @@ -13,9 +14,18 @@ export class HintComponent implements OnInit {

documentation: string;

constructor() { }
constructor(
private _route: ActivatedRoute
) { }

ngOnInit(): void {
if (!this.topic) {
// but status is defined in app.routing
this._route.data.subscribe(data => {
this.topic = data.topic;
});
}

this.content = this._getHint(this.topic);
}

Expand Down Expand Up @@ -43,6 +53,25 @@ export class HintComponent implements OnInit {
</li>
</ul>`;
break;
case 'ontology':
this.documentation = 'https://docs.dasch.swiss/DSP-APP/user-guide/project/#data-model';
return `<p>Data Model</p>
<p>
The definition of the data model (ontology) is the most important step.
The data model is indispensable for structuring your data. Our platform
provides a tool for an easy creation of one or more project data models.
First, you have to know which data and sources you want to work with.
The data model can be flexible and customizable.
</p>`;
break;
case 'list':
this.documentation = '';
return `<p>List Data</p>
<p>
Lists are very useful if you want to use controlled vocabulary to describe something.
Typical examples are keywords.
</p>`;
break;

default:
return `There's no hint implemented for the topic <strong>${topic}<strong>.`;
Expand Down
2 changes: 2 additions & 0 deletions src/app/main/status/status.component.ts
Expand Up @@ -98,6 +98,8 @@ export class StatusComponent implements OnInit {
// but status is defined in app.routing
this._route.data.subscribe(data => {
this.status = data.status;
this.comment = data.comment;
this.url = data.url;
});
}

Expand Down
@@ -0,0 +1,37 @@
<!-- display all resource instances if instance id does not exist -->
<!-- In case if results present -->
<div class="multiple-instances" *ngIf="searchParams">
<as-split direction="horizontal" (dragEnd)="splitSizeChanged = $event">
<as-split-area [size]="40">
<app-list-view [search]="searchParams" [displayViewSwitch]="true" [withMultipleSelection]="true"
(selectedResources)="openSelectedResources($event)">
</app-list-view>
</as-split-area>
<as-split-area [size]="60" *ngIf="selectedResources?.count > 0" cdkScrollable>
<div [ngSwitch]="viewMode">
<!-- single resource view -->
<app-resource *ngSwitchCase="'single'" [resourceIri]="selectedResources.resInfo[0].id" [splitSizeChanged]="splitSizeChanged"></app-resource>

<!-- intermediate view -->
<app-intermediate *ngSwitchCase="'intermediate'" [resources]="selectedResources" (action)="viewMode=$event"></app-intermediate>

<!-- multiple resources view / comparison viewer -->
<app-comparison *ngSwitchCase="'compare'" [noOfResources]="selectedResources.count"
[resources]="selectedResources.resInfo" [splitSizeChanged]="splitSizeChanged">
</app-comparison>
</div>
</as-split-area>
</as-split>
</div>


<!-- add new resource instance if instance id is called "add" -->
<div class="single-instance-form" *ngIf="instanceId && instanceId === 'add'">
<h3>Create new {{classId}} instance</h3>
<app-resource-instance-form
[selectedResourceClassIri]="classId"
[selectedProject]="projectId">
</app-resource-instance-form>
</div>

<!-- display single resource instance if instance id exists and is not called "add" -->
@@ -0,0 +1,12 @@
@import "../../../../../assets/style/config";

.multiple-instances {
height: calc(100vh - #{$header-height});
}


.single-instance-form {
max-width: 720px;
display: block;
padding: 16px;
}
@@ -0,0 +1,74 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatDialogModule } from '@angular/material/dialog';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { ActivatedRoute } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { KnoraApiConnection } from '@dasch-swiss/dsp-js';
import { of } from 'rxjs';
import { AppInitService } from 'src/app/app-init.service';
import { DspApiConfigToken, DspApiConnectionToken } from 'src/app/main/declarations/dsp-api-tokens';
import { TestConfig } from 'test.config';
import { OntologyClassInstanceComponent } from './ontology-class-instance.component';


describe('OntologyClassInstanceComponent', () => {
let component: OntologyClassInstanceComponent;
let fixture: ComponentFixture<OntologyClassInstanceComponent>;

const appInitSpy = {
dspAppConfig: {
iriBase: 'http://rdfh.ch'
}
};

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [OntologyClassInstanceComponent],
imports: [
MatSnackBarModule,
MatDialogModule,
RouterTestingModule
],
providers: [
{
provide: AppInitService,
useValue: appInitSpy
},
{
provide: DspApiConfigToken,
useValue: TestConfig.ApiConfig
},
{
provide: DspApiConnectionToken,
useValue: new KnoraApiConnection(TestConfig.ApiConfig)
},
{
provide: ActivatedRoute,
useValue: {
params: of({
onto: 'anything',
class: 'BlueThing',
}),
parent: {
snapshot: {
params: { shortcode: '0001' }
}
}
}
}

]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(OntologyClassInstanceComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

0 comments on commit 2391f2a

Please sign in to comment.