Move file tab sidebar to separate component

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent d25ed3cd80
commit f4988efb7e

@ -46,6 +46,7 @@ import { AddRepositoryDialogComponent } from './pages/home/repositories-tab/add-
import {MatTooltipModule} from "@angular/material/tooltip";
import {MatMenuModule} from "@angular/material/menu";
import { ConfirmDialogComponent } from './components/confirm-dialog/confirm-dialog.component';
import { FilesTabSidebarComponent } from './pages/home/files-tab/files-tab-sidebar/files-tab-sidebar.component';
@NgModule({
declarations: [
@ -63,6 +64,7 @@ import { ConfirmDialogComponent } from './components/confirm-dialog/confirm-dial
ContentAwareImageComponent,
AddRepositoryDialogComponent,
ConfirmDialogComponent,
FilesTabSidebarComponent,
],
imports: [
BrowserModule,

@ -22,11 +22,7 @@ import {ErrorBrokerService} from "../../services/error-broker/error-broker.servi
templateUrl: './file-search.component.html',
styleUrls: ['./file-search.component.scss']
})
export class FileSearchComponent implements AfterViewChecked {
public ngAfterViewChecked(): void {
this.inputList.nativeElement.scrollLeft = this.inputList.nativeElement.scrollWidth;
}
export class FileSearchComponent implements AfterViewChecked, OnInit {
public sortExpression: SortKey[] = [new SortKey("FileImportedTime",
"Ascending", undefined)];
public formControl = new FormControl();
@ -47,6 +43,14 @@ export class FileSearchComponent implements AfterViewChecked {
tag) : this.validTags.slice(0, 20)));
}
public async ngOnInit() {
await this.searchForFiles();
}
public ngAfterViewChecked(): void {
this.inputList.nativeElement.scrollLeft = this.inputList.nativeElement.scrollWidth;
}
private filterSuggestionTag(tag: string) {
const negated = tag.startsWith("-");
const normalizedTag = tag.replace(/^-/, "");

@ -0,0 +1,15 @@
<div fxLayout="column" class="sidebar-inner">
<div id="file-search-input" fxFlex="220px">
<app-file-search #filesearch (searchStartEvent)="this.searchStartEvent.emit()"
(searchEndEvent)="this.searchEndEvent.emit()" [validTags]="this.getValidTagsForSearch()"></app-file-search>
</div>
<div id="file-tag-list" fxFlex fxFlexAlign="start" fxFlexFill>
<h1>Selection Tags</h1>
<mat-selection-list [multiple]="false" *ngIf="tags.length > 0"
(selectionChange)="addSearchTagFromList($event)">
<mat-list-option
*ngFor="let tag of tags"
[value]="tag.getNormalizedOutput()">{{tag.getNormalizedOutput()}}</mat-list-option>
</mat-selection-list>
</div>
</div>

@ -0,0 +1,20 @@
#file-search-input {
width: 100%;
overflow: hidden;
}
app-file-search {
display: block;
width: 100%;
}
#file-tag-list {
height: 100%;
overflow-y: auto;
}
.sidebar-inner {
height: 100%;
width: 100%;
display: block;
}

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FilesTabSidebarComponent } from './files-tab-sidebar.component';
describe('FilesTabSidebarComponent', () => {
let component: FilesTabSidebarComponent;
let fixture: ComponentFixture<FilesTabSidebarComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ FilesTabSidebarComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(FilesTabSidebarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,74 @@
import {
Component,
EventEmitter,
Input, OnChanges,
OnInit,
Output, SimpleChanges,
ViewChild
} from '@angular/core';
import {Tag} from "../../../../models/Tag";
import {TagService} from "../../../../services/tag/tag.service";
import {FileService} from "../../../../services/file/file.service";
import {File} from "../../../../models/File";
import {MatSelectionListChange} from "@angular/material/list";
import {FileSearchComponent} from "../../../../components/file-search/file-search.component";
import {RepositoryService} from "../../../../services/repository/repository.service";
@Component({
selector: 'app-files-tab-sidebar',
templateUrl: './files-tab-sidebar.component.html',
styleUrls: ['./files-tab-sidebar.component.scss']
})
export class FilesTabSidebarComponent implements OnInit, OnChanges {
@Input() selectedFiles: File[] = [];
@Output() searchStartEvent = new EventEmitter<void>();
@Output() searchEndEvent = new EventEmitter<void>();
@ViewChild('filesearch') fileSearch!: FileSearchComponent;
public tagsOfFiles: Tag[] = [];
public tags: Tag[] = [];
public files: File[] = [];
constructor(private repoService: RepositoryService, private tagService: TagService, private fileService: FileService) {
this.fileService.displayedFiles.subscribe(async files => {
this.files = files;
await this.loadTagsForDisplayedFiles();
});
this.repoService.selectedRepository.subscribe(async (repo) => repo && this.fileSearch && await this.fileSearch.searchForFiles());
}
async ngOnInit() {
this.fileSearch && await this.fileSearch.searchForFiles();
}
public async ngOnChanges(changes: SimpleChanges): Promise<void >{
if (changes["selectedFiles"]) {
const tags = await this.tagService.getTagsForFiles(this.selectedFiles.map(f => f.hash));
this.tags = tags.sort((a, b) => a.getNormalizedOutput().localeCompare(b.getNormalizedOutput()));
}
}
async loadTagsForDisplayedFiles() {
this.tagsOfFiles = await this.tagService.getTagsForFiles(this.files.map(f => f.hash));
}
async addSearchTagFromList(event: MatSelectionListChange) {
if (event.options.length > 0) {
const tag = event.options[0].value;
this.fileSearch.addSearchTag(tag);
await this.fileSearch.searchForFiles();
}
event.source.deselectAll();
}
getValidTagsForSearch(): string[] {
return this.tagsOfFiles.map(t => t.getNormalizedOutput())
}
async showFileDetails(files: File[]) {
this.tags = await this.tagService.getTagsForFiles(files.map(f => f.hash))
this.tags = this.tags.sort((a, b) => a.getNormalizedOutput().localeCompare(b.getNormalizedOutput()));
}
}

@ -1,20 +1,7 @@
<mat-drawer-container class="page">
<mat-drawer mode="side" opened disableClose>
<div fxLayout="column" class="drawer-sidebar-inner">
<div id="file-search-input" fxFlex="220px">
<app-file-search #filesearch (searchStartEvent)="contentLoading = true"
(searchEndEvent)="contentLoading = false" [validTags]="this.getValidTagsForSearch()"></app-file-search>
</div>
<div id="file-tag-list" fxFlex fxFlexAlign="start" fxFlexFill>
<h1>Selection Tags</h1>
<mat-selection-list [multiple]="false" *ngIf="tags.length > 0"
(selectionChange)="addSearchTagFromList($event)">
<mat-list-option
*ngFor="let tag of tags"
[value]="tag.getNormalizedOutput()">{{tag.getNormalizedOutput()}}</mat-list-option>
</mat-selection-list>
</div>
</div>
<app-files-tab-sidebar (searchEndEvent)="this.contentLoading = false"
(searchStartEvent)="this.contentLoading = true" [selectedFiles]="this.selectedFiles"></app-files-tab-sidebar>
</mat-drawer>
<mat-drawer-content>
<div *ngIf="contentLoading" class="spinner-overlay">

@ -1,24 +1,3 @@
.drawer-sidebar-inner {
height: 100%;
width: 100%;
display: block;
}
#file-search-input {
width: 100%;
overflow: hidden;
}
app-file-search {
display: block;
width: 100%;
}
#file-tag-list {
height: 100%;
overflow-y: auto;
}
mat-selection-list {
height: 100%;
}

@ -17,66 +17,36 @@ import {RepositoryService} from "../../../services/repository/repository.service
})
export class FilesTabComponent implements OnInit {
tagsOfFiles: Tag[] = [];
tags: Tag[] = [];
files: File[] = [];
private openingLightbox = false;
showGallery = false;
preselectedFile: File | undefined;
contentLoading = false;
@ViewChild('filesearch') fileSearch!: FileSearchComponent;
selectedFiles: File[] = [];
constructor(
private errorBroker: ErrorBrokerService,
private repoService: RepositoryService,
private fileService: FileService,
private tagService: TagService,) {
private fileService: FileService,) {
}
async ngOnInit() {
this.fileService.displayedFiles.subscribe(async (files) => {
this.files = files;
await this.loadTagsForDisplayedFiles();
});
this.repoService.selectedRepository.subscribe(async (repo) => repo && await this.loadFilesInitially());
await this.loadFilesInitially();
}
async loadFilesInitially() {
this.files = [];
this.contentLoading = true;
if (this.fileSearch) {
await this.fileSearch.searchForFiles();
} else {
await this.fileService.findFiles([], [new SortKey("FileImportedTime", "Ascending", undefined)])
}
this.contentLoading = false;
}
async onFileMultiSelect(files: File[]) {
await this.showFileDetails(files);
this.selectedFiles = files;
}
async onFileSelect(file: File | undefined) {
if (file) {
await this.showFileDetails([file]);
}
}
async showFileDetails(files: File[]) {
this.tags = await this.tagService.getTagsForFiles(files.map(f => f.hash))
this.tags = this.tags.sort((a, b) => a.getNormalizedOutput().localeCompare(b.getNormalizedOutput()));
}
async addSearchTagFromList(event: MatSelectionListChange) {
if (event.options.length > 0) {
const tag = event.options[0].value;
this.fileSearch.addSearchTag(tag);
await this.fileSearch.searchForFiles();
this.selectedFiles = [file];
} else {
this.selectedFiles = [];
}
event.source.deselectAll();
}
async openGallery(preselectedFile: File) {
@ -88,12 +58,4 @@ export class FilesTabComponent implements OnInit {
this.preselectedFile = preselectedFile;
this.showGallery = false;
}
async loadTagsForDisplayedFiles() {
this.tagsOfFiles = await this.tagService.getTagsForFiles(this.files.map(f => f.hash));
}
getValidTagsForSearch(): string[] {
return this.tagsOfFiles.map(t => t.getNormalizedOutput())
}
}

Loading…
Cancel
Save