Implemented the ability to choose a folder for a library. Implemented an admin landing page that will showcase the different management items.
This commit is contained in:
parent
e06e34083c
commit
2679a52aec
20 changed files with 305 additions and 17 deletions
|
|
@ -99,7 +99,7 @@
|
||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
"src/styles.scss"
|
"src/styles.scss",
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
}
|
}
|
||||||
|
|
|
||||||
50
package-lock.json
generated
50
package-lock.json
generated
|
|
@ -353,6 +353,11 @@
|
||||||
"tslib": "^2.0.0"
|
"tslib": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@angular/elements": {
|
||||||
|
"version": "9.1.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/elements/-/elements-9.1.12.tgz",
|
||||||
|
"integrity": "sha512-0zjGlx2HxRWr4BiGfS9lY0i/MDfe2u3evn37svmTw72UmLsfaAR7XBa+5W2chgPCb5/1LyQAY/h02tsUEFlvYA=="
|
||||||
|
},
|
||||||
"@angular/forms": {
|
"@angular/forms": {
|
||||||
"version": "11.0.4",
|
"version": "11.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-11.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-11.0.4.tgz",
|
||||||
|
|
@ -1563,6 +1568,16 @@
|
||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@circlon/angular-tree-component": {
|
||||||
|
"version": "10.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@circlon/angular-tree-component/-/angular-tree-component-10.0.1.tgz",
|
||||||
|
"integrity": "sha512-yLXK01Z8TdtVnzcJbt8LVShtP2AFx8CA0Jwmj+ubHKyY5wOmO6pXebDdB1x0G9HEYYljl5wFhKoZLEZnG1tSAQ==",
|
||||||
|
"requires": {
|
||||||
|
"lodash-es": "^4.17.15",
|
||||||
|
"mobx": "~4.14.1",
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@istanbuljs/schema": {
|
"@istanbuljs/schema": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
|
||||||
|
|
@ -6562,6 +6577,31 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"jqwidgets-ng": {
|
||||||
|
"version": "11.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jqwidgets-ng/-/jqwidgets-ng-11.0.1.tgz",
|
||||||
|
"integrity": "sha512-V4iFpZps7P9bdnXX8pn55tGjPCz1Wu7a5jEXzwlN9ICdR428Du4aldLyJPR1fClDNyqIMXpHsn+EADt16lsdgg==",
|
||||||
|
"requires": {
|
||||||
|
"@angular/cdk": "^9.1.1",
|
||||||
|
"@angular/elements": "^9.0.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/cdk": {
|
||||||
|
"version": "9.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-9.2.4.tgz",
|
||||||
|
"integrity": "sha512-iw2+qHMXHYVC6K/fttHeNHIieSKiTEodVutZoOEcBu9rmRTGbLB26V/CRsfIRmA1RBk+uFYWc6UQZnMC3RdnJQ==",
|
||||||
|
"requires": {
|
||||||
|
"parse5": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parse5": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"js-tokens": {
|
"js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
|
@ -7042,6 +7082,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||||
},
|
},
|
||||||
|
"lodash-es": {
|
||||||
|
"version": "4.17.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz",
|
||||||
|
"integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ=="
|
||||||
|
},
|
||||||
"lodash.memoize": {
|
"lodash.memoize": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||||
|
|
@ -7561,6 +7606,11 @@
|
||||||
"minimist": "^1.2.5"
|
"minimist": "^1.2.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mobx": {
|
||||||
|
"version": "4.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mobx/-/mobx-4.14.1.tgz",
|
||||||
|
"integrity": "sha512-Oyg7Sr7r78b+QPYLufJyUmxTWcqeQ96S1nmtyur3QL8SeI6e0TqcKKcxbG+sVJLWANhHQkBW/mDmgG5DDC4fdw=="
|
||||||
|
},
|
||||||
"move-concurrently": {
|
"move-concurrently": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||||
|
|
|
||||||
23
src/app/_services/library.service.ts
Normal file
23
src/app/_services/library.service.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { environment } from 'src/environments/environment';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class LibraryService {
|
||||||
|
|
||||||
|
baseUrl = environment.apiUrl;
|
||||||
|
|
||||||
|
constructor(private httpClient: HttpClient) { }
|
||||||
|
|
||||||
|
listDirectories(rootPath: string) {
|
||||||
|
let query = '';
|
||||||
|
if (rootPath !== undefined && rootPath.length > 0) {
|
||||||
|
query = '?path=' + rootPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.httpClient.get<string[]>(this.baseUrl + 'library/list' + query);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { Routes, RouterModule } from '@angular/router';
|
import { Routes, RouterModule } from '@angular/router';
|
||||||
import { AdminGuard } from '../_guards/admin.guard';
|
import { AdminGuard } from '../_guards/admin.guard';
|
||||||
|
import { DashboardComponent } from './dashboard/dashboard.component';
|
||||||
import { UsersComponent } from './users/users.component';
|
import { UsersComponent } from './users/users.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{path: '**', component: UsersComponent, pathMatch: 'full'},
|
{path: '**', component: DashboardComponent, pathMatch: 'full'},
|
||||||
{
|
{
|
||||||
runGuardsAndResolvers: 'always',
|
runGuardsAndResolvers: 'always',
|
||||||
canActivate: [AdminGuard],
|
canActivate: [AdminGuard],
|
||||||
children: [
|
children: [
|
||||||
|
{path: '/dashboard', component: DashboardComponent},
|
||||||
{path: '/users', component: UsersComponent}
|
{path: '/users', component: UsersComponent}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,17 @@ import { CommonModule } from '@angular/common';
|
||||||
import { AdminRoutingModule } from './admin-routing.module';
|
import { AdminRoutingModule } from './admin-routing.module';
|
||||||
import { UsersComponent } from './users/users.component';
|
import { UsersComponent } from './users/users.component';
|
||||||
import { ToastrModule } from 'ngx-toastr';
|
import { ToastrModule } from 'ngx-toastr';
|
||||||
|
import { DashboardComponent } from './dashboard/dashboard.component';
|
||||||
|
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [UsersComponent],
|
declarations: [UsersComponent, DashboardComponent],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
AdminRoutingModule
|
AdminRoutingModule,
|
||||||
|
NgbNavModule
|
||||||
],
|
],
|
||||||
providers: []
|
providers: []
|
||||||
})
|
})
|
||||||
|
|
|
||||||
18
src/app/admin/dashboard/dashboard.component.html
Normal file
18
src/app/admin/dashboard/dashboard.component.html
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<h1>Admin Dashboard</h1>
|
||||||
|
|
||||||
|
<ul ngbNav #nav="ngbNav" [(activeId)]="active" class="nav-tabs">
|
||||||
|
<li *ngFor="let tab of tabs" [ngbNavItem]="tab">
|
||||||
|
<a ngbNavLink>{{ tab | titlecase }}</a>
|
||||||
|
<ng-template ngbNavContent>
|
||||||
|
|
||||||
|
<ng-container *ngIf="tab === 'users'">
|
||||||
|
<app-users></app-users>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="tab === 'libraries'">
|
||||||
|
Library management here
|
||||||
|
</ng-container>
|
||||||
|
</ng-template>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div [ngbNavOutlet]="nav" class="mt-2"></div>
|
||||||
0
src/app/admin/dashboard/dashboard.component.scss
Normal file
0
src/app/admin/dashboard/dashboard.component.scss
Normal file
19
src/app/admin/dashboard/dashboard.component.ts
Normal file
19
src/app/admin/dashboard/dashboard.component.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-dashboard',
|
||||||
|
templateUrl: './dashboard.component.html',
|
||||||
|
styleUrls: ['./dashboard.component.scss']
|
||||||
|
})
|
||||||
|
export class DashboardComponent implements OnInit {
|
||||||
|
|
||||||
|
tabs = ['users', 'libraries'];
|
||||||
|
counter = this.tabs.length + 1;
|
||||||
|
active = this.tabs[0];
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
|
||||||
|
<button class="btn btn-primary" (click)="addFolder('')">Add Folder</button>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2>Members:</h2>
|
<h2>Members:</h2>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
|
import { ModalDismissReasons, NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { DirectoryPickerComponent, DirectoryPickerResult } from 'src/app/directory-picker/directory-picker.component';
|
||||||
import { MemberService } from 'src/app/member.service';
|
import { MemberService } from 'src/app/member.service';
|
||||||
import { Member } from 'src/app/_models/member';
|
import { Member } from 'src/app/_models/member';
|
||||||
|
|
||||||
|
|
@ -10,8 +12,10 @@ import { Member } from 'src/app/_models/member';
|
||||||
export class UsersComponent implements OnInit {
|
export class UsersComponent implements OnInit {
|
||||||
|
|
||||||
members: Member[] = [];
|
members: Member[] = [];
|
||||||
|
closeResult = ''; // Debug code
|
||||||
|
@ViewChild('content') content: any;
|
||||||
|
|
||||||
constructor(private memberService: MemberService) { }
|
constructor(private memberService: MemberService, private modalService: NgbModal) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
console.log('User Component');
|
console.log('User Component');
|
||||||
|
|
@ -20,4 +24,16 @@ export class UsersComponent implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addFolder(library: string) {
|
||||||
|
|
||||||
|
const modalRef = this.modalService.open(DirectoryPickerComponent);
|
||||||
|
//modalRef.componentInstance.name = 'World';
|
||||||
|
modalRef.closed.subscribe((closeResult: DirectoryPickerResult) => {
|
||||||
|
console.log('Closed Result', closeResult);
|
||||||
|
if (closeResult.success) {
|
||||||
|
console.log('Add folder path to Library');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ import { UserLoginComponent } from './user-login/user-login.component';
|
||||||
import { ToastrModule } from 'ngx-toastr';
|
import { ToastrModule } from 'ngx-toastr';
|
||||||
import { ErrorInterceptor } from './_interceptors/error.interceptor';
|
import { ErrorInterceptor } from './_interceptors/error.interceptor';
|
||||||
import { LibraryComponent } from './library/library.component';
|
import { LibraryComponent } from './library/library.component';
|
||||||
|
import { DirectoryPickerComponent } from './directory-picker/directory-picker.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
|
|
@ -21,7 +24,8 @@ import { LibraryComponent } from './library/library.component';
|
||||||
HomeComponent,
|
HomeComponent,
|
||||||
NavHeaderComponent,
|
NavHeaderComponent,
|
||||||
UserLoginComponent,
|
UserLoginComponent,
|
||||||
LibraryComponent
|
LibraryComponent,
|
||||||
|
DirectoryPickerComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
|
|
@ -38,6 +42,7 @@ import { LibraryComponent } from './library/library.component';
|
||||||
{provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true},
|
{provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true},
|
||||||
{provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}
|
{provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}
|
||||||
],
|
],
|
||||||
|
entryComponents: [DirectoryPickerComponent],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
|
|
|
||||||
27
src/app/directory-picker/directory-picker.component.html
Normal file
27
src/app/directory-picker/directory-picker.component.html
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title" id="modal-basic-title">Choose a Directory</h4>
|
||||||
|
<button type="button" class="close" aria-label="Close" (click)="close()">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<!-- <nav aria-label="breadcrumb">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item {{'active' ? route === routeStack.peek() : ''}}" *ngFor="let route of routeStack.items">{{getStem(route)}}</li>
|
||||||
|
</ol>
|
||||||
|
</nav> -->
|
||||||
|
<div class="list-group">
|
||||||
|
<button *ngIf="routeStack.peek() !== undefined" (click)="goBack()" class="list-group-item list-group-item-action"><i class="fa fa-arrow-left mr-2"></i>Back</button>
|
||||||
|
<button *ngFor="let folder of folders" class="list-group-item list-group-item-action" (click)="selectNode(folder)">
|
||||||
|
<span>{{getStem(folder)}}</span>
|
||||||
|
<button class="btn btn-primary pull-right" (click)="shareFolder(folder, $event)">Share</button>
|
||||||
|
</button>
|
||||||
|
<div class="text-center" *ngIf="folders.length === 0">
|
||||||
|
There are no folders here
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" (click)="close()">Cancel</button>
|
||||||
|
</div>
|
||||||
0
src/app/directory-picker/directory-picker.component.scss
Normal file
0
src/app/directory-picker/directory-picker.component.scss
Normal file
103
src/app/directory-picker/directory-picker.component.ts
Normal file
103
src/app/directory-picker/directory-picker.component.ts
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { BehaviorSubject } from 'rxjs';
|
||||||
|
import { LibraryService } from '../_services/library.service';
|
||||||
|
|
||||||
|
class Stack {
|
||||||
|
items: any[];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.items = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmpty() {
|
||||||
|
return this.items.length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
peek() {
|
||||||
|
if (!this.isEmpty()) {
|
||||||
|
return this.items[this.items.length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pop() {
|
||||||
|
if (this.isEmpty()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return this.items.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
push(item: any) {
|
||||||
|
this.items.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DirectoryPickerResult {
|
||||||
|
success: boolean;
|
||||||
|
folderPath: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-directory-picker',
|
||||||
|
templateUrl: './directory-picker.component.html',
|
||||||
|
styleUrls: ['./directory-picker.component.scss']
|
||||||
|
})
|
||||||
|
export class DirectoryPickerComponent implements OnInit {
|
||||||
|
|
||||||
|
currentRoot = '';
|
||||||
|
folders: string[] = [];
|
||||||
|
routeStack: Stack = new Stack();
|
||||||
|
|
||||||
|
constructor(public modal: NgbActiveModal, private libraryService: LibraryService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.loadChildren(this.currentRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
selectNode(folderName: string) {
|
||||||
|
this.currentRoot = folderName;
|
||||||
|
this.routeStack.push(folderName);
|
||||||
|
this.loadChildren(folderName);
|
||||||
|
}
|
||||||
|
|
||||||
|
goBack() {
|
||||||
|
this.routeStack.pop();
|
||||||
|
this.currentRoot = this.routeStack.peek();
|
||||||
|
this.loadChildren(this.currentRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadChildren(path: string) {
|
||||||
|
this.libraryService.listDirectories(path).subscribe(folders => {
|
||||||
|
this.folders = folders;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
shareFolder(folderName: string, event: any) {
|
||||||
|
console.log(`You selected ${folderName} as your folder to share!`);
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
this.modal.close({success: true, folderPath: folderName});
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.modal.close({success: false, folderPath: undefined});
|
||||||
|
}
|
||||||
|
|
||||||
|
getStem(path: string): string {
|
||||||
|
|
||||||
|
const lastPath = this.routeStack.peek();
|
||||||
|
if (lastPath) {
|
||||||
|
let replaced = path.replace(lastPath, '');
|
||||||
|
if (replaced.startsWith('/') || replaced.startsWith('\\')) {
|
||||||
|
replaced = replaced.substr(1, replaced.length);
|
||||||
|
}
|
||||||
|
return replaced;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,6 +31,8 @@
|
||||||
<app-user-login></app-user-login>
|
<app-user-login></app-user-login>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<app-directory-picker></app-directory-picker>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { take } from 'rxjs/operators';
|
||||||
|
import { User } from '../_models/user';
|
||||||
|
import { AccountService } from '../_services/account.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-library',
|
selector: 'app-library',
|
||||||
|
|
@ -7,9 +10,14 @@ import { Component, OnInit } from '@angular/core';
|
||||||
})
|
})
|
||||||
export class LibraryComponent implements OnInit {
|
export class LibraryComponent implements OnInit {
|
||||||
|
|
||||||
constructor() { }
|
user: User | undefined;
|
||||||
|
|
||||||
|
constructor(public accountService: AccountService) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.accountService.currentUser$.pipe(take(1)).subscribe(user => {
|
||||||
|
this.user = user;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@
|
||||||
|
|
||||||
<!-- TODO: Put SignalR notification button dropdown here. -->
|
<!-- TODO: Put SignalR notification button dropdown here. -->
|
||||||
|
|
||||||
<div class=" nav-item dropdown" *ngIf="(accountService.currentUser$ | async) as user" dropdown>
|
<div ngbDropdown class=" nav-item dropdown" *ngIf="(accountService.currentUser$ | async) as user" dropdown>
|
||||||
<a dropdownToggle class="dropdown-toggle text-light ml-2">{{user.username | titlecase}}</a>
|
<button class="btn btn-outline-primary" ngbDropdownToggle>{{user.username | titlecase}}</button>
|
||||||
<div class="dropdown-menu mt-3" *dropdownMenu>
|
<div ngbDropdownMenu >
|
||||||
<a *ngIf="user.isAdmin" class="dropdown-item" routerLink="/admin/users">Logout</a>
|
<button ngbDropdownItem routerLink="/admin/users">Server Settings</button>
|
||||||
<a (click)="logout()" class="dropdown-item">Logout</a>
|
<button ngbDropdownItem *ngIf="user.isAdmin"(click)="logout()">Logout</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,10 @@
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body class="mat-typography">
|
<body class="mat-typography" theme="dark">
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -43,3 +43,5 @@
|
||||||
// background-color: darken(#cc7b19, 10%) !important;
|
// background-color: darken(#cc7b19, 10%) !important;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
html, body { height: 100%; }
|
||||||
|
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue