commit
5c6f479332
@ -1,5 +1,5 @@
|
||||
<ng-content></ng-content>
|
||||
<div *ngIf="this.busy" [class.blur]="this.blurBackground" [class.darken]="this.darkenBackground"
|
||||
class="busy-indicator-overlay">
|
||||
<mat-progress-spinner [mode]="mode" [value]="value" color="primary"></mat-progress-spinner>
|
||||
<mat-progress-spinner *ngIf="this.busy" [mode]="mode" [value]="value" color="primary"></mat-progress-spinner>
|
||||
</div>
|
||||
|
@ -0,0 +1,8 @@
|
||||
import { HasPropertyPipe } from './has-property.pipe';
|
||||
|
||||
describe('HasPropertyPipe', () => {
|
||||
it('create an instance', () => {
|
||||
const pipe = new HasPropertyPipe();
|
||||
expect(pipe).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,11 @@
|
||||
import {Pipe, PipeTransform} from "@angular/core";
|
||||
|
||||
@Pipe({
|
||||
name: "hasProperty"
|
||||
})
|
||||
export class HasPropertyPipe implements PipeTransform {
|
||||
|
||||
transform(value: any, propertyName: string): unknown {
|
||||
return propertyName in value;
|
||||
}
|
||||
}
|
@ -1,8 +1,11 @@
|
||||
<mat-card #card (click)="clickEvent.emit(this)" (dblclick)="dblClickEvent.emit(this)"
|
||||
[ngClass]="{'selected': entry.selected}">
|
||||
[class.selected]="this.entry.selected | async">
|
||||
<mat-card-content>
|
||||
<app-busy-indicator [busy]="this.loading">
|
||||
<app-file-thumbnail *ngIf="!loading" [file]="this.entry.data" class=".entry-image"></app-file-thumbnail>
|
||||
<app-file-thumbnail *ngIf="!loading"
|
||||
[fileChanged]="this.fileChanged"
|
||||
[file]="this.entry.data"
|
||||
class=".entry-image"></app-file-thumbnail>
|
||||
</app-busy-indicator>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
@ -1,48 +1,45 @@
|
||||
import {
|
||||
Component,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
SimpleChanges
|
||||
} from "@angular/core";
|
||||
import {ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from "@angular/core";
|
||||
import {File} from "../../../../../api/models/File";
|
||||
import {FileService} from "../../../../services/file/file.service";
|
||||
import {FileMetadata} from "../../../../../api/api-types/files";
|
||||
import {BusyIndicatorComponent} from "../../app-common/busy-indicator/busy-indicator.component";
|
||||
|
||||
@Component({
|
||||
selector: "app-file-metadata",
|
||||
templateUrl: "./file-metadata.component.html",
|
||||
styleUrls: ["./file-metadata.component.scss"]
|
||||
styleUrls: ["./file-metadata.component.scss"],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class FileMetadataComponent implements OnInit, OnChanges {
|
||||
|
||||
@Input() file!: File;
|
||||
public fileMetadata: FileMetadata | undefined;
|
||||
public loading = false;
|
||||
|
||||
@ViewChild(BusyIndicatorComponent) busyIndicator!: BusyIndicatorComponent;
|
||||
|
||||
constructor(private fileService: FileService) {
|
||||
}
|
||||
|
||||
public async ngOnInit() {
|
||||
this.loading = true;
|
||||
await this.busyIndicator.wrapAsyncOperation(async () => {
|
||||
this.fileMetadata = await this.fileService.getFileMetadata(this.file.id);
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
public async ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes["file"] && (!this.fileMetadata || this.fileMetadata.file_id != this.file.id)) {
|
||||
this.loading = true;
|
||||
await this.busyIndicator.wrapAsyncOperation(async () => {
|
||||
this.fileMetadata = await this.fileService.getFileMetadata(this.file.id);
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async saveFileName(name: string) {
|
||||
this.loading = true;
|
||||
await this.busyIndicator.wrapAsyncOperation(async () => {
|
||||
const newFile = await this.fileService.updateFileName(this.file.id, name);
|
||||
if (this.fileMetadata) {
|
||||
this.fileMetadata.name = newFile.name;
|
||||
}
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
<span *ngIf="is('OrExpression')" class="or-expression">
|
||||
<ng-container *ngFor="let query of this.orExpression().OrExpression">
|
||||
<app-property-query-item *ngIf="this.queryIs(query, 'Property')"
|
||||
[propertyQuery]="this.propertyQuery(query).Property"></app-property-query-item>
|
||||
<app-tag-query-item *ngIf="this.queryIs(query, 'Tag')"
|
||||
[tagQuery]="this.tagQuery(query).Tag"></app-tag-query-item>
|
||||
<span *ngIf="this.orExpression" class="or-expression">
|
||||
<ng-container *ngFor="let query of this.orExpression">
|
||||
<app-property-query-item *ngIf="query | hasProperty: 'Property'"
|
||||
[propertyQuery]="query | getPropertyQuery"></app-property-query-item>
|
||||
<app-tag-query-item *ngIf="query | hasProperty: 'Tag'"
|
||||
[tagQuery]="query | getTagQuery"></app-tag-query-item>
|
||||
<span class="or-combinator"> OR </span>
|
||||
</ng-container>
|
||||
</span>
|
||||
<span *ngIf="is('Query')" class="query">
|
||||
<app-property-query-item *ngIf="this.queryIs(this.query().Query, 'Property')"
|
||||
[propertyQuery]="this.propertyQuery(this.query().Query).Property"></app-property-query-item>
|
||||
<app-tag-query-item *ngIf="this.queryIs(this.query().Query, 'Tag')"
|
||||
[tagQuery]="this.tagQuery(this.query().Query).Tag"></app-tag-query-item>
|
||||
<span *ngIf="this.query" class="query">
|
||||
<app-property-query-item *ngIf="this.query | hasProperty: 'Property'"
|
||||
[propertyQuery]="this.query | getPropertyQuery"></app-property-query-item>
|
||||
<app-tag-query-item *ngIf="this.query | hasProperty: 'Tag'"
|
||||
[tagQuery]="this.query | getTagQuery"></app-tag-query-item>
|
||||
</span>
|
||||
|
@ -1,47 +1,35 @@
|
||||
import {Component, Input} from "@angular/core";
|
||||
import {
|
||||
FilterExpression,
|
||||
FilterExpressionOrExpression,
|
||||
FilterExpressionQuery,
|
||||
FilterQuery,
|
||||
FilterQueryProperty,
|
||||
FilterQueryTag
|
||||
} from "../../../../../../api/api-types/files";
|
||||
import {ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges} from "@angular/core";
|
||||
import {FilterExpression, FilterQuery} from "../../../../../../api/api-types/files";
|
||||
|
||||
@Component({
|
||||
selector: "app-filter-expression-item",
|
||||
templateUrl: "./filter-expression-item.component.html",
|
||||
styleUrls: ["./filter-expression-item.component.scss"]
|
||||
styleUrls: ["./filter-expression-item.component.scss"],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class FilterExpressionItemComponent {
|
||||
|
||||
|
||||
export class FilterExpressionItemComponent implements OnInit, OnChanges {
|
||||
@Input() filter!: FilterExpression;
|
||||
public orExpression?: FilterQuery[];
|
||||
public query?: FilterQuery;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public is(key: "OrExpression" | "Query"): boolean {
|
||||
return key in this.filter;
|
||||
}
|
||||
|
||||
public orExpression(): FilterExpressionOrExpression {
|
||||
return this.filter as FilterExpressionOrExpression;
|
||||
public ngOnInit(): void {
|
||||
this.parseQuery();
|
||||
}
|
||||
|
||||
public query(): FilterExpressionQuery {
|
||||
return this.filter as FilterExpressionQuery;
|
||||
public ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes["filter"]) {
|
||||
this.parseQuery();
|
||||
}
|
||||
|
||||
public queryIs(query: FilterQuery, key: "Property" | "Tag"): boolean {
|
||||
return key in query;
|
||||
}
|
||||
|
||||
public propertyQuery(query: FilterQuery): FilterQueryProperty {
|
||||
return query as FilterQueryProperty;
|
||||
private parseQuery() {
|
||||
if ("Query" in this.filter) {
|
||||
this.query = this.filter.Query;
|
||||
} else {
|
||||
this.orExpression = this.filter.OrExpression;
|
||||
}
|
||||
|
||||
public tagQuery(query: FilterQuery): FilterQueryTag {
|
||||
return query as FilterQueryTag;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
import { GetPropertyQueryPipe } from './get-property-query.pipe';
|
||||
|
||||
describe('GetPropertyQueryPipe', () => {
|
||||
it('create an instance', () => {
|
||||
const pipe = new GetPropertyQueryPipe();
|
||||
expect(pipe).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,13 @@
|
||||
import {Pipe, PipeTransform} from "@angular/core";
|
||||
import {FilterQuery, FilterQueryProperty, PropertyQuery} from "../../../../../../api/api-types/files";
|
||||
|
||||
@Pipe({
|
||||
name: "getPropertyQuery"
|
||||
})
|
||||
export class GetPropertyQueryPipe implements PipeTransform {
|
||||
|
||||
transform(value: FilterQuery): PropertyQuery {
|
||||
return (value as FilterQueryProperty).Property;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
import { GetTagQueryPipe } from './get-tag-query.pipe';
|
||||
|
||||
describe('GetTagQueryPipe', () => {
|
||||
it('create an instance', () => {
|
||||
const pipe = new GetTagQueryPipe();
|
||||
expect(pipe).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
import {Pipe, PipeTransform} from "@angular/core";
|
||||
import {FilterQuery, FilterQueryTag, TagQuery} from "../../../../../../api/api-types/files";
|
||||
|
||||
@Pipe({
|
||||
name: "getTagQuery"
|
||||
})
|
||||
export class GetTagQueryPipe implements PipeTransform {
|
||||
|
||||
transform(value: FilterQuery): TagQuery {
|
||||
return (value as FilterQueryTag).Tag;
|
||||
}
|
||||
}
|
@ -1,12 +1,18 @@
|
||||
import {BehaviorSubject} from "rxjs";
|
||||
|
||||
export class Selectable<T> {
|
||||
constructor(public data: T, public selected: boolean) {
|
||||
|
||||
public selected: BehaviorSubject<boolean>;
|
||||
|
||||
constructor(public data: T, selected: boolean) {
|
||||
this.selected = new BehaviorSubject<boolean>(selected);
|
||||
}
|
||||
|
||||
public select() {
|
||||
this.selected = true;
|
||||
this.selected.next(true);
|
||||
}
|
||||
|
||||
public unselect() {
|
||||
this.selected = false;
|
||||
this.selected.next(false);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue