Rework repository form

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

@ -15,7 +15,6 @@ import {MatSnackBarModule} from "@angular/material/snack-bar";
import {MatFormFieldModule} from "@angular/material/form-field";
import {MatInputModule} from "@angular/material/input";
import {ReactiveFormsModule} from "@angular/forms";
import {RepoFormComponent} from './pages/home/repositories-tab/repo-form/repo-form.component';
import {FileGridComponent} from './components/file-grid/file-grid.component';
import {MatSidenavModule} from "@angular/material/sidenav";
import {MatGridListModule} from "@angular/material/grid-list";
@ -43,6 +42,7 @@ import {PanelModule} from "primeng/panel";
import {DragDropModule} from "@angular/cdk/drag-drop";
import { ContentAwareImageComponent } from './components/content-aware-image/content-aware-image.component';
import {MatSliderModule} from "@angular/material/slider";
import { AddRepositoryDialogComponent } from './pages/home/repositories-tab/add-repository-dialog/add-repository-dialog.component';
@NgModule({
declarations: [
@ -50,7 +50,6 @@ import {MatSliderModule} from "@angular/material/slider";
RepositoriesTabComponent,
HomeComponent,
RepositoryCardComponent,
RepoFormComponent,
FileGridComponent,
FileGridEntryComponent,
FileSearchComponent,
@ -59,6 +58,7 @@ import {MatSliderModule} from "@angular/material/slider";
FileGalleryComponent,
FileGalleryEntryComponent,
ContentAwareImageComponent,
AddRepositoryDialogComponent,
],
imports: [
BrowserModule,

@ -0,0 +1,39 @@
<h1 mat-dialog-title>Add a Repository</h1>
<div mat-dialog-content>
<form [formGroup]="formGroup">
<mat-form-field>
<mat-label>Name</mat-label>
<input matInput formControlName="name">
</mat-form-field>
<mat-form-field>
<mat-label>Type</mat-label>
<mat-select #repoTypeSelect formControlName="repositoryType"
(selectionChange)="onTypeChange(repoTypeSelect.value)">
<mat-option value="local">Local</mat-option>
<mat-option value="remote">Remote</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field *ngIf="repoTypeSelect.value === 'local'">
<button class="button-folder-select" mat-button (click)="openFolderDialog()"><mat-icon>folder</mat-icon></button>
<mat-label>Path</mat-label>
<input matInput formControlName="path">
</mat-form-field>
<mat-form-field *ngIf="repoTypeSelect.value === 'remote'">
<mat-label>Address</mat-label>
<input matInput formControlName="address">
</mat-form-field>
</form>
<div *ngIf="repoTypeSelect.value === 'remote'" class="connection-state">
<span>Status:</span>&nbsp;<span>{{this.onlineStatus}}</span>
</div>
</div>
<div class="dialog-buttons" mat-dialog-actions>
<button mat-flat-button [disabled]="!formGroup.valid" color="primary" (click)="addRepository()">Add</button>
<button mat-stroked-button color="accent" (click)="closeDialog()">Cancel</button>
<button class="check-connection-button" *ngIf="repoTypeSelect.value === 'remote'" [disabled]="!formGroup.valid"
mat-stroked-button (click)="checkRepositoryStatus()">Check Connection</button>
</div>

@ -0,0 +1,26 @@
form {
display: flex;
flex-direction: column;
}
.dialog-buttons {
display: block;
width: 100%;
button {
margin-left: 1em;
float: right
}
.check-connection-button {
justify-self: right;
margin: 0;
float: left;
}
}
.button-folder-select {
position: absolute;
top: -10px;
right: 0;
}

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

@ -0,0 +1,108 @@
import {Component, Inject, OnInit} from '@angular/core';
import {
AbstractControl,
FormControl,
FormGroup, ValidationErrors,
Validators
} from "@angular/forms";
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {RepositoryService} from "../../../../services/repository/repository.service";
import {ErrorBrokerService} from "../../../../services/error-broker/error-broker.service";
import {dialog} from "@tauri-apps/api";
@Component({
selector: 'app-add-repository-dialog',
templateUrl: './add-repository-dialog.component.html',
styleUrls: ['./add-repository-dialog.component.scss']
})
export class AddRepositoryDialogComponent {
formGroup = new FormGroup({
name: new FormControl("My Repository", [Validators.required]),
repositoryType: new FormControl("local", [Validators.required]),
path: new FormControl("", [this.validatePath]),
address: new FormControl("", [this.validateAddress])
});
onlineStatus = "Unknown";
constructor(
public repoService: RepositoryService,
public errorBroker: ErrorBrokerService,
public dialogRef: MatDialogRef<AddRepositoryDialogComponent>,
@Inject(MAT_DIALOG_DATA) data: any) {
}
public async checkRepositoryStatus() {
this.onlineStatus = "Checking...";
const address = this.formGroup.value.address;
const running = await this.repoService.checkDaemonRunning(address);
console.log(running);
this.onlineStatus = running? "Online" : "Offline";
}
public async addRepository() {
let {name, repositoryType, path, address} = this.formGroup.value;
path = repositoryType === "local"? path : undefined;
address = repositoryType === "remote"? address : undefined;
try {
await this.repoService.addRepository(name, path, address, repositoryType === "local");
this.dialogRef.close();
} catch (err) {
this.errorBroker.showError(err);
}
}
public closeDialog() {
this.dialogRef.close();
}
public async openFolderDialog() {
const path = await dialog.open({
directory: true,
multiple: false,
});
this.formGroup.get("path")?.setValue(path);
}
public async onTypeChange(type: string) {
setTimeout(() => {
const path = this.formGroup.get("path");
const address = this.formGroup.get("address");
switch (type) {
case "local":
address?.clearValidators();
address?.setErrors(null);
path?.setValidators(this.validatePath);
path?.setErrors(this.validatePath(path));
break;
case "remote":
path?.clearValidators();
path?.setErrors(null);
address?.setValidators(this.validateAddress);
address?.setErrors(this.validateAddress(address));
break;
}
}, 0);
}
validatePath(control: AbstractControl): ValidationErrors | null {
const repositoryType = control.parent?.get("repositoryType")?.value ?? "local";
if (repositoryType === "local") {
return control.value.length > 0? null : {valueRequired: control.value};
}
return null;
}
validateAddress(control: AbstractControl): ValidationErrors | null {
const repositoryType = control.parent?.get("repositoryType")?.value ?? "remote";
if (repositoryType === "remote") {
const match = /(\d+\.){3}\d+:\d+|\S+:\d+/.test(control.value)
return match? null : {invalidAddress: control.value};
}
return null;
}
}

@ -1,15 +0,0 @@
<form [formGroup]="repoForm" (ngSubmit)="addRepository()">
<mat-form-field appearance="fill">
<mat-label>Name</mat-label>
<input type="text" matInput required formControlName="name">
</mat-form-field>
<mat-form-field appearance="fill" id="path-input">
<mat-label>Path</mat-label>
<button class="button-folder-select" mat-button (click)="this.openFolderDialog($event)">
<mat-icon>folder</mat-icon>
</button>
<input type="text" matInput required formControlName="path">
</mat-form-field>
<button mat-flat-button color="primary" id="add-button" [disabled]="!repoForm.valid">Add</button>
<mat-divider></mat-divider>
</form>

@ -1,17 +0,0 @@
#add-button {
margin: 1em
}
#path-input {
width: 60%
}
mat-form-field, button {
margin: 0.2em
}
.button-folder-select {
position: absolute;
top: -24px;
right: 0;
}

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

@ -1,42 +0,0 @@
import { Component, OnInit } from '@angular/core';
import {FormControl, FormGroup, Validators} from "@angular/forms";
import {RepositoryService} from "../../../../services/repository/repository.service";
import {MatSnackBar} from "@angular/material/snack-bar";
import {ErrorBrokerService} from "../../../../services/error-broker/error-broker.service";
import {dialog} from "@tauri-apps/api";
@Component({
selector: 'app-repo-form',
templateUrl: './repo-form.component.html',
styleUrls: ['./repo-form.component.scss']
})
export class RepoFormComponent implements OnInit {
repoForm = new FormGroup({
name: new FormControl("", Validators.required),
path: new FormControl("", Validators.required),
})
constructor(private repoService: RepositoryService, private errorBroker: ErrorBrokerService) { }
ngOnInit(): void {
}
async addRepository() {
let {name, path} = this.repoForm.value;
try {
await this.repoService.addRepository(name, path, undefined, true);
} catch(err) {
this.errorBroker.showError(err);
}
}
public async openFolderDialog($event: MouseEvent): Promise<void> {
const path = await dialog.open({
directory: true,
multiple: false,
});
this.repoForm.controls.path.setValue(path);
}
}

@ -1,6 +1,6 @@
<div class="repo-page-content">
<div class="add-repo-tools">
<app-repo-form></app-repo-form>
<button mat-flat-button color="primary" (click)="openAddRepositoryDialog()">Add Repository</button>
</div>
<div class="repository-list">
<div *ngFor="let repository of repositories" class="repository-container">

@ -11,8 +11,12 @@
}
.add-repo-tools {
margin: 1em 0;
height: 5em;
display: flex;
flex-direction: row-reverse;
button {
margin: 1em;
}
}
.repository-list {

@ -1,8 +1,8 @@
import { Component, OnInit } from '@angular/core';
import {Repository} from "../../../models/Repository";
import {RepositoryService} from "../../../services/repository/repository.service";
import {MatSnackBar} from "@angular/material/snack-bar";
import {FormBuilder, FormGroup} from "@angular/forms";
import {MatDialog} from "@angular/material/dialog";
import {AddRepositoryDialogComponent} from "./add-repository-dialog/add-repository-dialog.component";
@Component({
selector: 'app-repositories-tab',
@ -15,6 +15,7 @@ export class RepositoriesTabComponent implements OnInit {
constructor(
private repoService: RepositoryService,
public dialog: MatDialog
) {
}
@ -26,7 +27,11 @@ export class RepositoriesTabComponent implements OnInit {
});
}
async addRepository() {
public openAddRepositoryDialog() {
this.dialog.open(AddRepositoryDialogComponent, {
disableClose: true,
minWidth: "30%",
minHeight: "30%",
});
}
}

Loading…
Cancel
Save