Add overview for repository metadata

Signed-off-by: Trivernis <trivernis@protonmail.com>
pull/4/head
Trivernis 3 years ago
parent 25786f9d3c
commit 86412b7039

@ -1489,8 +1489,8 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]] [[package]]
name = "mediarepo-api" name = "mediarepo-api"
version = "0.17.0" version = "0.18.0"
source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=d81648edc0b6b03f8a0c6ab90854a9e7a3376d00#d81648edc0b6b03f8a0c6ab90854a9e7a3376d00" source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=c5f2bfa48e822e9a761191c9a7ef42e2dbf811b5#c5f2bfa48e822e9a761191c9a7ef42e2dbf811b5"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bromine", "bromine",

@ -25,7 +25,7 @@ features = [ "env-filter" ]
[dependencies.mediarepo-api] [dependencies.mediarepo-api]
git = "https://github.com/Trivernis/mediarepo-api.git" git = "https://github.com/Trivernis/mediarepo-api.git"
rev = "d81648edc0b6b03f8a0c6ab90854a9e7a3376d00" rev = "c5f2bfa48e822e9a761191c9a7ef42e2dbf811b5"
features = [ "tauri-plugin" ] features = [ "tauri-plugin" ]
[features] [features]

@ -45,6 +45,8 @@ import {
import { import {
RepositoryModule RepositoryModule
} from "../shared/repository/repository/repository.module"; } from "../shared/repository/repository/repository.module";
import {MatToolbarModule} from "@angular/material/toolbar";
import { RepositoryDetailsViewComponent } from './repositories-tab/repository-details-view/repository-details-view.component';
@NgModule({ @NgModule({
@ -57,6 +59,7 @@ import {
ImportTabSidebarComponent, ImportTabSidebarComponent,
RepositoryCardComponent, RepositoryCardComponent,
DownloadDaemonDialogComponent, DownloadDaemonDialogComponent,
RepositoryDetailsViewComponent,
], ],
exports: [ exports: [
CoreComponent, CoreComponent,
@ -88,6 +91,7 @@ import {
MatInputModule, MatInputModule,
TagModule, TagModule,
RepositoryModule, RepositoryModule,
MatToolbarModule,
] ]
}) })
export class CoreModule { export class CoreModule {

@ -1,4 +1,4 @@
<div class="repo-page-content"> <div class="repo-page-content" *ngIf="!selectedRepository">
<div class="add-repo-tools"> <div class="add-repo-tools">
<button (click)="openAddRepositoryDialog()" color="primary" mat-flat-button>Add Repository</button> <button (click)="openAddRepositoryDialog()" color="primary" mat-flat-button>Add Repository</button>
</div> </div>
@ -8,3 +8,6 @@
</div> </div>
</div> </div>
</div> </div>
<div class="repo-details" *ngIf="selectedRepository">
<app-repository-details-view [repository]="selectedRepository"></app-repository-details-view>
</div>

@ -17,7 +17,8 @@ import {
styleUrls: ["./repositories-tab.component.scss"] styleUrls: ["./repositories-tab.component.scss"]
}) })
export class RepositoriesTabComponent implements OnInit, AfterViewInit { export class RepositoriesTabComponent implements OnInit, AfterViewInit {
repositories: Repository[] = []; public repositories: Repository[] = [];
public selectedRepository?: Repository;
constructor( constructor(
private repoService: RepositoryService, private repoService: RepositoryService,
@ -31,13 +32,13 @@ export class RepositoriesTabComponent implements OnInit, AfterViewInit {
this.repositories = repos; this.repositories = repos;
} }
}); });
this.repoService.selectedRepository.subscribe(repo => this.selectedRepository = repo);
} }
public async ngAfterViewInit() { public async ngAfterViewInit() {
await this.checkAndPromptDaemonExecutable(); await this.checkAndPromptDaemonExecutable();
} }
public openAddRepositoryDialog() { public openAddRepositoryDialog() {
this.dialog.open(AddRepositoryDialogComponent, { this.dialog.open(AddRepositoryDialogComponent, {
disableClose: true, disableClose: true,

@ -0,0 +1,22 @@
<mat-toolbar>
<span class="repository-name">{{repository.name}}</span>
<button class="button-close-repository" mat-flat-button color="primary" (click)="this.closeRepository()">Close</button>
</mat-toolbar>
<div class="details-content" fxLayout="row">
<div class="repository-metadata" fxFlex="50%">
<h1>Stats</h1>
<app-metadata-entry *ngIf="repository.path" attributeName="Path" [value]="repository.path"></app-metadata-entry>
<app-metadata-entry *ngIf="repository.address" attributeName="Address" [value]="repository.address"></app-metadata-entry>
<ng-container *ngIf="metadata">
<app-metadata-entry attributeName="Daemon Version" [value]="metadata.version"></app-metadata-entry>
<app-metadata-entry attributeName="File Count" [value]="metadata.file_count.toString()"></app-metadata-entry>
<app-metadata-entry attributeName="Tag Count" [value]="metadata.tag_count.toString()"></app-metadata-entry>
<app-metadata-entry attributeName="Namespace Count" [value]="metadata.namespace_count.toString()"></app-metadata-entry>
<app-metadata-entry attributeName="Mapping Count" [value]="metadata.mapping_count.toString()"></app-metadata-entry>
<app-metadata-entry attributeName="Total Size" [value]="formatByteSize(metadata.total_size)"></app-metadata-entry>
<app-metadata-entry attributeName="File Folder Size" [value]="formatByteSize(metadata.file_size)"></app-metadata-entry>
<app-metadata-entry attributeName="Thumbnail Folder Size" [value]="formatByteSize(metadata.thumbnail_size)"></app-metadata-entry>
<app-metadata-entry attributeName="Database File Size" [value]="formatByteSize(metadata.database_size)"></app-metadata-entry>
</ng-container>
</div>
</div>

@ -0,0 +1,9 @@
.repository-name {
text-align: center;
align-self: center;
margin: auto;
}
.button-close-repository {
float: right
}

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

@ -0,0 +1,63 @@
import {
Component,
Input,
OnChanges,
OnInit,
SimpleChanges
} from "@angular/core";
import {Repository} from "../../../../models/Repository";
import {
RepositoryService
} from "../../../../services/repository/repository.service";
import {RepositoryMetadata} from "../../../../models/RepositoryMetadata";
@Component({
selector: "app-repository-details-view",
templateUrl: "./repository-details-view.component.html",
styleUrls: ["./repository-details-view.component.scss"]
})
export class RepositoryDetailsViewComponent implements OnInit, OnChanges {
@Input() repository!: Repository;
public metadata?: RepositoryMetadata;
constructor(private repoService: RepositoryService) {
}
public async ngOnInit() {
this.metadata = await this.repoService.getRepositoryMetadata();
}
public async ngOnChanges(changes: SimpleChanges) {
if (changes["repository"]) {
this.metadata = await this.repoService.getRepositoryMetadata();
}
}
public async closeRepository() {
if (this.repository?.local) {
await this.repoService.closeSelectedRepository();
} else {
await this.repoService.disconnectSelectedRepository();
}
}
public formatByteSize(size: number): string {
const kib = 1024;
const mib = kib ** 2;
const gib = kib ** 3;
const tib = kib ** 4;
if (size >= tib) {
return (size / tib).toFixed(2) + " TiB";
} else if (size >= gib) {
return (size / gib).toFixed(2) + " GiB";
} else if (size >= mib) {
return (size / mib).toFixed(2) + " MiB";
} else if (size >= kib) {
return (size / kib).toFixed(2) + " KiB";
} else {
return size + " B"
}
}
}

@ -16,6 +16,9 @@ import {
ContentAwareImageComponent ContentAwareImageComponent
} from "./content-aware-image/content-aware-image.component"; } from "./content-aware-image/content-aware-image.component";
import { InputReceiverDirective } from "./input-receiver/input-receiver.directive"; import { InputReceiverDirective } from "./input-receiver/input-receiver.directive";
import {
MetadataEntryComponent
} from "./metadata-entry/metadata-entry.component";
@NgModule({ @NgModule({
@ -25,6 +28,7 @@ import { InputReceiverDirective } from "./input-receiver/input-receiver.directiv
ContextMenuComponent, ContextMenuComponent,
ContentAwareImageComponent, ContentAwareImageComponent,
InputReceiverDirective, InputReceiverDirective,
MetadataEntryComponent,
], ],
exports: [ exports: [
ConfirmDialogComponent, ConfirmDialogComponent,
@ -32,6 +36,7 @@ import { InputReceiverDirective } from "./input-receiver/input-receiver.directiv
ContextMenuComponent, ContextMenuComponent,
ContentAwareImageComponent, ContentAwareImageComponent,
InputReceiverDirective, InputReceiverDirective,
MetadataEntryComponent,
], ],
imports: [ imports: [
CommonModule, CommonModule,

@ -44,7 +44,7 @@ import {MatMenuModule} from "@angular/material/menu";
import {FileMetadataComponent} from "./file-metadata/file-metadata.component"; import {FileMetadataComponent} from "./file-metadata/file-metadata.component";
import { import {
MetadataEntryComponent MetadataEntryComponent
} from "./file-metadata/metadata-entry/metadata-entry.component"; } from "../app-common/metadata-entry/metadata-entry.component";
import { import {
EditableMetadataEntryComponent EditableMetadataEntryComponent
} from "./file-metadata/editable-metadata-entry/editable-metadata-entry.component"; } from "./file-metadata/editable-metadata-entry/editable-metadata-entry.component";
@ -62,7 +62,6 @@ import {MatAutocompleteModule} from "@angular/material/autocomplete";
FileImportComponent, FileImportComponent,
FilesystemImportComponent, FilesystemImportComponent,
FileMetadataComponent, FileMetadataComponent,
MetadataEntryComponent,
EditableMetadataEntryComponent, EditableMetadataEntryComponent,
], ],
exports: [ exports: [

@ -0,0 +1,12 @@
export type RepositoryMetadata = {
version: string,
file_count: number,
tag_count: number,
namespace_count: number,
mapping_count: number,
hash_count: number,
total_size: number,
file_size: number,
database_size: number,
thumbnail_size: number,
};

@ -6,6 +6,7 @@ import {listen} from "@tauri-apps/api/event";
import {Info} from "../../models/Info"; import {Info} from "../../models/Info";
import {ErrorBrokerService} from "../error-broker/error-broker.service"; import {ErrorBrokerService} from "../error-broker/error-broker.service";
import {FileService} from "../file/file.service"; import {FileService} from "../file/file.service";
import {RepositoryMetadata} from "../../models/RepositoryMetadata";
@Injectable({ @Injectable({
providedIn: "root" providedIn: "root"
@ -163,6 +164,14 @@ export class RepositoryService {
await invoke("plugin:mediarepo|init_repository", {repoPath}); await invoke("plugin:mediarepo|init_repository", {repoPath});
} }
/**
* Retrieves metadata about the selected repository
* @returns {Promise<RepositoryMetadata>}
*/
public async getRepositoryMetadata(): Promise<RepositoryMetadata> {
return await invoke<RepositoryMetadata>("plugin:mediarepo|get_repo_metadata");
}
async loadSelectedRepository() { async loadSelectedRepository() {
let active_repo = await invoke<Repository | undefined>( let active_repo = await invoke<Repository | undefined>(
"plugin:mediarepo|get_active_repository"); "plugin:mediarepo|get_active_repository");

Loading…
Cancel
Save