Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(overview): add overview and project tile components (DEV-984) #777

Merged
merged 10 commits into from Jul 27, 2022
5 changes: 5 additions & 0 deletions src/app/app-routing.module.ts
Expand Up @@ -24,6 +24,7 @@ import { SystemComponent } from './system/system.component';
import { UsersComponent } from './system/users/users.component';
// user
import { DashboardComponent } from './user/dashboard/dashboard.component';
import { OverviewComponent } from './user/overview/overview.component';
import { UserComponent } from './user/user.component';
// search results and resource viewer
import { ResourceComponent } from './workspace/resource/resource.component';
Expand All @@ -42,6 +43,10 @@ const routes: Routes = [
path: 'login',
component: LoginFormComponent
},
{
path: 'overview',
component: OverviewComponent
},
{
path: 'dashboard',
component: DashboardComponent,
Expand Down
6 changes: 5 additions & 1 deletion src/app/app.module.ts
Expand Up @@ -165,6 +165,8 @@ import { OntologyClassesComponent } from './project/beta/ontology-classes/ontolo
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';
import { SettingsComponent } from './project/beta/settings/settings.component';
import { OverviewComponent } from './user/overview/overview.component';
import { ProjectTileComponent } from './system/project-tile/project-tile.component';

// translate: AoT requires an exported function for factories
export function httpLoaderFactory(httpClient: HttpClient) {
Expand Down Expand Up @@ -316,7 +318,9 @@ export function httpLoaderFactory(httpClient: HttpClient) {
OntologyClassesComponent,
OntologyClassItemComponent,
OntologyClassInstanceComponent,
SettingsComponent
SettingsComponent,
OverviewComponent,
ProjectTileComponent,
],
imports: [
AngularSplitModule.forRoot(),
Expand Down
19 changes: 18 additions & 1 deletion src/app/main/action/login-form/login-form.component.ts
@@ -1,7 +1,7 @@
import { AfterViewInit, Component, EventEmitter, Inject, Input, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { ApiResponseData, ApiResponseError, KnoraApiConnection, LoginResponse } from '@dasch-swiss/dsp-js';
import { ApiResponseData, ApiResponseError, KnoraApiConnection, LoginResponse, UserResponse } from '@dasch-swiss/dsp-js';
import { DspApiConnectionToken } from '../../declarations/dsp-api-tokens';
import { ErrorHandlerService } from '../../services/error-handler.service';
import { AuthenticationService } from '../../services/authentication.service';
Expand Down Expand Up @@ -158,9 +158,26 @@ export class LoginFormComponent implements OnInit, AfterViewInit {
this.session = this._session.getSession();

this._componentCommsService.emit(new EmitEvent(Events.loginSuccess, true));

// if user hit a page that requires to be logged in, they will have a returnUrl in the url
this.returnUrl = this._route.snapshot.queryParams['returnUrl'];
if (this.returnUrl) {
this._router.navigate([this.returnUrl]);
} else if (this._route.snapshot.url.length && this._route.snapshot.url[0].path === 'login') { // if user is on /login
const username = this.session.user.name;
this._dspApiConnection.admin.usersEndpoint.getUserByUsername(username).subscribe(
(userResponse: ApiResponseData<UserResponse>) => {
// if user is only a member of one project, redirect them to that projects dashboard
if(userResponse.body.user.projects.length === 1) {
this._router.navigateByUrl('/refresh', { skipLocationChange: true }).then(
() => this._router.navigate(['/beta/project/' + userResponse.body.user.projects[0].shortcode])
);
} else { // if user is a member of multiple projects, redirect them to the overview
this._router.navigateByUrl('/refresh', { skipLocationChange: true }).then(
() => this._router.navigate(['/overview'])
);
}
});
} else {
window.location.reload();
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/project/project-form/project-form.component.ts
Expand Up @@ -417,8 +417,8 @@ export class ProjectFormComponent implements OnInit {
this.loading = false;
this.closeDialog.emit();
// redirect to (new) project page
this._router.navigateByUrl('/project', { skipLocationChange: true }).then(() =>
this._router.navigate(['/project/' + this.form.controls['shortcode'].value])
this._router.navigateByUrl('/beta/project', { skipLocationChange: true }).then(() =>
this._router.navigate(['/beta/project/' + this.form.controls['shortcode'].value])
);
},
(error: ApiResponseError) => {
Expand Down
19 changes: 13 additions & 6 deletions src/app/project/project.component.html
Expand Up @@ -31,7 +31,12 @@ <h1 class="mat-headline">
</mat-list-item>
<!-- Maybe we can have a project selector here (similar to the github dashboard page) -->
<mat-divider></mat-divider>

<mat-list-item>
<span class="link section-label" (click)="goToOverview()">
<p>Go to projects overview</p>
</span>
</mat-list-item>
<mat-divider></mat-divider>
<!-- Ontology Section -->
<mat-list-item class="section-title">
<span class="link section-label" (click)="open('ontology')">
Expand All @@ -50,7 +55,8 @@ <h2 class="mat-title">Data Models</h2>
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<div class="sidenav-panel-header" (click)="$event.stopPropagation();">
<mat-panel-title class="mat-subheading-2" (click)="projectAdmin ? open('ontology', onto.id) : null">
<mat-panel-title class="mat-subheading-2"
(click)="projectAdmin ? open('ontology', onto.id) : null">
{{onto.label}}
</mat-panel-title>
<mat-panel-description>
Expand All @@ -69,7 +75,8 @@ <h2 class="mat-title">Data Models</h2>
</button>
</mat-list-item> -->
<mat-list>
<app-ontology-classes [resClasses]="onto.getAllClassDefinitions()" [projectMember]="projectMember">
<app-ontology-classes [resClasses]="onto.getAllClassDefinitions()"
[projectMember]="projectMember">
</app-ontology-classes>
</mat-list>
</mat-expansion-panel>
Expand All @@ -86,7 +93,7 @@ <h2 class="mat-title">Data Models</h2>
<h2 class="mat-title">Lists</h2>
</span>
<span class="fill-remaining-space"></span>
<button mat-icon-button class="hover-only"(click)="open('add-list')">
<button mat-icon-button class="hover-only" (click)="open('add-list')">
<mat-icon>add</mat-icon>
</button>
</mat-list-item>
Expand All @@ -105,7 +112,7 @@ <h2 class="mat-title">Members</h2>

<!-- Project permissions ??? will it ever come? -->

<div class="sidenav-footer" *ngIf="projectAdmin" >
<div class="sidenav-footer" *ngIf="projectAdmin">
<mat-list-item class="section-title">
<span class="link section-label" (click)="open('settings')">
<mat-icon class="sidenav-prefix-icon">settings</mat-icon>
Expand All @@ -129,4 +136,4 @@ <h2 class="mat-title">Settings</h2>
<div class="content large middle">
<app-status *ngIf="error" [status]="404"></app-status>
</div>
</ng-template>
</ng-template>
5 changes: 5 additions & 0 deletions src/app/project/project.component.ts
Expand Up @@ -222,6 +222,11 @@ export class ProjectComponent implements OnInit {
}
}

// go to overview page
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this comment refers to the function its more common to do the "/** [...] */" comment

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true true, changed in 2832fce

goToOverview() {
this._router.navigate(['/overview'], { relativeTo: this._route });
}

/**
* checks if the shortcode is valid: hexadecimal and length = 4
*
Expand Down
34 changes: 34 additions & 0 deletions src/app/system/project-tile/project-tile.component.html
@@ -0,0 +1,34 @@
<div class="project-tile">
<div class="project-tile-content">
<div class="top-bar">
<div class="status">
<div *ngIf="project.status === true" class="status-badge active">
<span>Active</span>
</div>
<div *ngIf="project.status === false" class="status-badge deactivated">
<span>Deactivated</span>
</div>
</div>
<div *ngIf="sysAdmin" class="settings">
<button class="settings-button" mat-icon-button (click)="navigateTo(project.shortcode, 'settings')">
<mat-icon>settings</mat-icon>
</button>
</div>
</div>

<div class="icon">
<mat-icon>redeem</mat-icon>
</div>

<div class="title">
<p>{{project.longname}}</p>
</div>

<div class="dashboard-button-container">
<button class="dashboard-button" mat-flat-button [color]="'primary'"
(click)="navigateTo(project.shortcode, 'dashboard')">
Go to dashboard
</button>
</div>
</div>
</div>
97 changes: 97 additions & 0 deletions src/app/system/project-tile/project-tile.component.scss
@@ -0,0 +1,97 @@
.project-tile {
border: 1px solid #d1d5db;
border-radius: 6px;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);

.project-tile-content {
padding: 10px 5px 10px 10px;

.top-bar {
display: flex;
justify-content: space-between;
align-items: center;

.status,
.settings {
display: inline-block;
}

.status {

.status-badge {
border-radius: 10px;
padding: 2px 10px 4px 10px;

span {
font-size: 12px;
}
}

.status-badge.active {
background-color: #99F6E4;

span {
color: #0F766E;
}
}

.status-badge.deactivated {
background-color: #E5E7EB;

span {
color: #6B7280;
}
}

}

.settings {
mat-icon-button {
width: 28px;
height: 28px;
line-height: 28px;
mat-icon {
height: 28px;
width: 28px;
font-size: 28px;
line-height: 28px;
}
}

}
}

.icon {
padding-top: 23px;

mat-icon {
font-size: 40px;
}
}

.title {
font-weight: 700;
font-size: 24px;
color: #3b4856;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
line-height: 28px;
padding: 0px 20px;
height: 80px;
}

.dashboard-button-container {
margin: 14% 0%;

button {
font-size: 16px;
line-height: 24px;
font-weight: 400;
padding: 13px 21px;
}
}
}

}