Rework repository form
Signed-off-by: trivernis <trivernis@protonmail.com>pull/4/head
parent
e8bfd8b710
commit
ffced041d4
@ -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> <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);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue