Move repository form outside of add dialog

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent 1dc17f0aef
commit 579a5a43be

@ -33,6 +33,7 @@ import {MatDialogModule} from "@angular/material/dialog";
import {MatTooltipModule} from "@angular/material/tooltip"; import {MatTooltipModule} from "@angular/material/tooltip";
import {MatInputModule} from "@angular/material/input"; import {MatInputModule} from "@angular/material/input";
import {TagModule} from "../shared/tag/tag.module"; import {TagModule} from "../shared/tag/tag.module";
import { RepositoryFormComponent } from './repositories-tab/repository-form/repository-form.component';
@NgModule({ @NgModule({
@ -45,6 +46,7 @@ import {TagModule} from "../shared/tag/tag.module";
ImportTabSidebarComponent, ImportTabSidebarComponent,
RepositoryCardComponent, RepositoryCardComponent,
AddRepositoryDialogComponent, AddRepositoryDialogComponent,
RepositoryFormComponent,
], ],
exports: [ exports: [
CoreComponent, CoreComponent,

@ -1,56 +1,19 @@
<h1 mat-dialog-title>Add a Repository</h1> <h1 mat-dialog-title>Add a Repository</h1>
<div mat-dialog-content> <div mat-dialog-content>
<form [formGroup]="formGroup"> <app-repository-form #repoForm></app-repository-form>
<mat-form-field matTooltip="A unique name for the repository" matTooltipShowDelay="1000">
<mat-label>Name</mat-label>
<input (blur)="validateName()" (change)="validateName()" (input)="validateName()" formControlName="name"
matInput>
</mat-form-field>
<mat-form-field matTooltip="Type of repository if it's on the local system or somewhere else"
matTooltipShowDelay="1000">
<mat-label>Type</mat-label>
<mat-select #repoTypeSelect (selectionChange)="onTypeChange(repoTypeSelect.value)"
formControlName="repositoryType">
<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'"
matTooltip="Path where the repository is located or should be created"
matTooltipShowDelay="1000">
<button (click)="openFolderDialog()" class="button-folder-select" mat-button>
<ng-icon name="mat-folder"></ng-icon>
</button>
<mat-label>Path</mat-label>
<input (change)="this.checkLocalRepoExists()" formControlName="path" matInput>
</mat-form-field>
<mat-form-field *ngIf="repoTypeSelect.value === 'remote'"
matTooltip="IP address and port of the remote repository"
matTooltipShowDelay="1000">
<mat-label>Address</mat-label>
<input formControlName="address" matInput>
</mat-form-field>
</form>
<div *ngIf="repoTypeSelect.value === 'remote'" class="connection-state">
<span>Status:</span>&nbsp;<span>{{this.onlineStatus}}</span>
</div>
</div> </div>
<div class="dialog-buttons" mat-dialog-actions> <div class="dialog-buttons" mat-dialog-actions>
<button (click)="closeDialog()" color="accent" mat-stroked-button>Cancel</button> <button (click)="closeDialog()" color="accent" mat-stroked-button>Cancel</button>
<button (click)="addRepository()" *ngIf="repoTypeSelect.value === 'remote' || this.localRepoExists" <button (click)="addRepository()" *ngIf="repoForm.formGroup.get('repositoryType')?.value === 'remote' || repoForm.localRepoExists"
[disabled]="!formGroup.valid" color="primary" mat-flat-button [disabled]="!repoForm.formGroup.valid" color="primary" mat-flat-button
matTooltip="Add the existing repository">Add matTooltip="Add the existing repository">Add
</button> </button>
<button (click)="this.initLocalRepository()" *ngIf="repoTypeSelect.value === 'local' && !this.localRepoExists" <button (click)="this.initLocalRepository()" *ngIf="repoForm.formGroup.get('repositoryType')?.value === 'local' && !repoForm.localRepoExists"
[disabled]="!formGroup.valid" [disabled]="!repoForm.formGroup.valid"
color="accent" mat-flat-button color="accent" mat-flat-button
matTooltip="Initialize the repository in the specified path">Init matTooltip="Initialize the repository in the specified path">Init
</button> </button>
<button (click)="checkRepositoryStatus()" *ngIf="repoTypeSelect.value === 'remote'" [disabled]="!formGroup.valid" <button (click)="repoForm.checkRepositoryStatus()" *ngIf="repoForm.formGroup.get('repositoryType')?.value === 'remote'" [disabled]="!repoForm.formGroup.valid"
class="check-connection-button" mat-stroked-button>Check Connection class="check-connection-button" mat-stroked-button>Check Connection
</button> </button>
</div> </div>

@ -1,6 +1,6 @@
form { app-repository-form {
display: flex; width: 100%;
flex-direction: column; height: 100%;
} }
.dialog-buttons { .dialog-buttons {
@ -18,9 +18,3 @@ form {
float: left; float: left;
} }
} }
.button-folder-select {
position: absolute;
top: -10px;
right: 0;
}

@ -1,4 +1,4 @@
import {Component, Inject, OnInit} from "@angular/core"; import {Component, Inject, OnInit, ViewChild} from "@angular/core";
import { import {
AbstractControl, AbstractControl,
FormControl, FormControl,
@ -11,24 +11,18 @@ import {RepositoryService} from "../../../../services/repository/repository.serv
import {ErrorBrokerService} from "../../../../services/error-broker/error-broker.service"; import {ErrorBrokerService} from "../../../../services/error-broker/error-broker.service";
import {dialog} from "@tauri-apps/api"; import {dialog} from "@tauri-apps/api";
import {Repository} from "../../../../models/Repository"; import {Repository} from "../../../../models/Repository";
import {
RepositoryFormComponent
} from "../repository-form/repository-form.component";
@Component({ @Component({
selector: "app-add-repository-dialog", selector: "app-add-repository-dialog",
templateUrl: "./add-repository-dialog.component.html", templateUrl: "./add-repository-dialog.component.html",
styleUrls: ["./add-repository-dialog.component.scss"] styleUrls: ["./add-repository-dialog.component.scss"]
}) })
export class AddRepositoryDialogComponent implements OnInit { 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])
});
repositories: Repository[] = []; @ViewChild(RepositoryFormComponent) repositoryForm!: RepositoryFormComponent;
onlineStatus = "Unknown";
localRepoExists = false;
constructor( constructor(
public repoService: RepositoryService, public repoService: RepositoryService,
@ -37,26 +31,13 @@ export class AddRepositoryDialogComponent implements OnInit {
@Inject(MAT_DIALOG_DATA) data: any) { @Inject(MAT_DIALOG_DATA) data: any) {
} }
ngOnInit(): void {
this.repoService.repositories.subscribe(
repositories => this.repositories = repositories)
}
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 checkLocalRepoExists() { public async checkLocalRepoExists() {
this.localRepoExists = await this.repoService.checkLocalRepositoryExists( this.repositoryForm.localRepoExists = await this.repoService.checkLocalRepositoryExists(
this.formGroup.value.path); this.repositoryForm.formGroup.value.path);
} }
public async initLocalRepository() { public async initLocalRepository() {
const path = this.formGroup.value.path; const path = this.repositoryForm.formGroup.value.path;
try { try {
await this.repoService.initRepository(path); await this.repoService.initRepository(path);
} catch (err) { } catch (err) {
@ -66,7 +47,7 @@ export class AddRepositoryDialogComponent implements OnInit {
} }
public async addRepository() { public async addRepository() {
let {name, repositoryType, path, address} = this.formGroup.value; let {name, repositoryType, path, address} = this.repositoryForm.formGroup.value;
path = repositoryType === "local" ? path : undefined; path = repositoryType === "local" ? path : undefined;
address = repositoryType === "remote" ? address : undefined; address = repositoryType === "remote" ? address : undefined;
try { try {
@ -81,65 +62,4 @@ export class AddRepositoryDialogComponent implements OnInit {
public closeDialog() { public closeDialog() {
this.dialogRef.close(); this.dialogRef.close();
} }
public async openFolderDialog() {
const path = await dialog.open({
directory: true,
multiple: false,
});
this.formGroup.get("path")?.setValue(path);
await this.checkLocalRepoExists();
}
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);
}
validateName() {
const control = this.formGroup.get("name");
const value = control?.value;
if (this.repositories.find(r => r.name === value)) {
control?.setErrors({nameAlreadyExists: value});
}
}
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;
}
} }

@ -40,6 +40,7 @@ export class RepositoryCardComponent implements OnInit, OnDestroy {
} }
} }
public isSelectedRepository(): boolean { public isSelectedRepository(): boolean {
return this.repoService.selectedRepository.getValue()?.name === this.repository.name return this.repoService.selectedRepository.getValue()?.name === this.repository.name
} }

@ -0,0 +1,38 @@
<form [formGroup]="formGroup">
<mat-form-field matTooltip="A unique name for the repository" matTooltipShowDelay="1000">
<mat-label>Name</mat-label>
<input (blur)="validateName()" (change)="validateName()" (input)="validateName()" formControlName="name"
matInput>
</mat-form-field>
<mat-form-field matTooltip="Type of repository if it's on the local system or somewhere else"
matTooltipShowDelay="1000">
<mat-label>Type</mat-label>
<mat-select #repoTypeSelect (selectionChange)="onTypeChange(repoTypeSelect.value)"
formControlName="repositoryType">
<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'"
matTooltip="Path where the repository is located or should be created"
matTooltipShowDelay="1000">
<button (click)="openFolderDialog()" class="button-folder-select" mat-button>
<ng-icon name="mat-folder"></ng-icon>
</button>
<mat-label>Path</mat-label>
<input (change)="this.checkLocalRepoExists()" formControlName="path" matInput>
</mat-form-field>
<mat-form-field *ngIf="repoTypeSelect.value === 'remote'"
matTooltip="IP address and port of the remote repository"
matTooltipShowDelay="1000">
<mat-label>Address</mat-label>
<input formControlName="address" matInput>
</mat-form-field>
</form>
<div *ngIf="repoTypeSelect.value === 'remote'" class="connection-state">
<span>Status:</span>&nbsp;<span>{{this.onlineStatus}}</span>
</div>

@ -0,0 +1,10 @@
form {
display: flex;
flex-direction: column;
}
.button-folder-select {
position: absolute;
top: -10px;
right: 0;
}

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

@ -0,0 +1,123 @@
import {Component, Input, OnInit, Output} from "@angular/core";
import {
AbstractControl,
FormControl,
FormGroup, ValidationErrors,
Validators
} from "@angular/forms";
import {Repository} from "../../../../models/Repository";
import {
RepositoryService
} from "../../../../services/repository/repository.service";
import {dialog} from "@tauri-apps/api";
import {
ErrorBrokerService
} from "../../../../services/error-broker/error-broker.service";
@Component({
selector: "app-repository-form",
templateUrl: "./repository-form.component.html",
styleUrls: ["./repository-form.component.scss"]
})
export class RepositoryFormComponent implements OnInit {
@Input() name: string = "My Repository";
@Input() repositoryType: "local" | "remote" = "local";
@Input() path: string = "";
@Input() address: string = "";
@Output() formGroup = new FormGroup({
name: new FormControl(this.name, [Validators.required]),
repositoryType: new FormControl(this.repositoryType, [Validators.required]),
path: new FormControl(this.path, [this.validatePath]),
address: new FormControl(this.address, [this.validateAddress])
});
onlineStatus = "Unknown";
localRepoExists = false;
repositories: Repository[] = [];
constructor(public repoService: RepositoryService, private errorBroker: ErrorBrokerService) {
}
ngOnInit(): void {
this.repoService.repositories.subscribe(
repositories => this.repositories = repositories)
}
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 checkLocalRepoExists() {
this.localRepoExists = await this.repoService.checkLocalRepositoryExists(
this.formGroup.value.path);
}
public async openFolderDialog() {
const path = await dialog.open({
directory: true,
multiple: false,
});
this.formGroup.get("path")?.setValue(path);
await this.checkLocalRepoExists();
}
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);
}
validateName() {
const control = this.formGroup.get("name");
const value = control?.value;
if (this.repositories.find(r => r.name === value)) {
control?.setErrors({nameAlreadyExists: value});
}
}
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;
}
}
Loading…
Cancel
Save