removed unused components

This commit is contained in:
Dragos 2021-04-26 15:36:04 +03:00
parent f3adbfba0f
commit 2c61988074
20 changed files with 0 additions and 622 deletions

View File

@ -1,128 +0,0 @@
<div class="d-flex flex-column h-100 pb-3">
<div class="container text-center mt-1" [formGroup]="editorForm">
<div class="btn-toolbar pt-2">
<span class="d-none d-sm-block flex-grow-1"></span>
<ng-container *ngIf="images && images.length">
<div class="input-group input-group-pill flex-grow-1 flex-grow-sm-0 me-sm-3 w-sm-auto w-100">
<input type="text" class="form-control" placeholder="Search by name..." formControlName="searchTerm" appAlphaOnly="^[A-Za-z0-9_-]+$">
<button class="btn btn-outline-info" type="button" (click)="clearSearch()" [disabled]="!editorForm.get('searchTerm').value"
tooltip="Clear search" container="body" placement="top" [adaptivePosition]="false">
<fa-icon icon="times" size="sm" [fixedWidth]="true"></fa-icon>
</button>
</div>
<div class="btn-group flex-grow-1 flex-grow-sm-0 w-sm-auto w-100" dropdown placement="bottom left">
<button class="btn btn-outline-info dropdown-toggle" dropdownToggle>
Sort by
<b *ngIf="editorForm.get('sortProperty').value === 'name'">name</b>
<b *ngIf="editorForm.get('sortProperty').value === 'description'">description</b>
<b *ngIf="editorForm.get('sortProperty').value === 'os'">operating system</b>
<b *ngIf="editorForm.get('sortProperty').value === 'type'">type</b>
<b *ngIf="editorForm.get('sortProperty').value === 'state'">status</b>
</button>
<ul id="dropdown-split" *dropdownMenu class="dropdown-menu dropdown-menu-right" role="menu">
<li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'name'" (click)="setSortProperty('name')">
Name
</button>
</li>
<li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'description'" (click)="setSortProperty('description')">
Description
</button>
</li>
<li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'os'" (click)="setSortProperty('os')">
Operating system
</button>
</li>
<li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'type'" (click)="setSortProperty('type')">
Type
</button>
</li>
<li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'status'" (click)="setSortProperty('status')">
Status
</button>
</li>
</ul>
</div>
</ng-container>
</div>
<div class="spinner-border text-center text-info text-faded" role="status" *ngIf="loadingIndicator">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div class="overflow-auto">
<div class="container my-4">
<div class="table-responsive" *ngIf="!loadingIndicator">
<p *ngIf="!images.length" class="text-center text-info text-faded p-3 mb-0">
You don't have any custom images yet
</p>
<table class="table table-hover" *ngIf="images.length">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>OS</th>
<th>Type</th>
<th>Publish date</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let image of listItems">
<td>
{{ image.name }}
</td>
<td>
<div class="text-truncate">{{ image.description }}</div>
</td>
<td class="text-uppercase">
{{ image.os }}
</td>
<td class="text-uppercase">
{{ image.type }}
</td>
<td>
{{ image.published_at ? (image.published_at | timeago) : '' }}
</td>
<td>
<span class="badge" [ngClass]="image.state === 'active' ? 'bg-success' : 'bg-warning text-dark'">{{ image.state }}</span>
</td>
<td class="text-end">
<div class="btn-group btn-group-sm" dropdown placement="bottom right" container="body" [isDisabled]="image.working">
<button class="btn btn-link text-info" dropdownToggle
tooltip="More options" container="body" placement="top" [adaptivePosition]="false">
<fa-icon icon="ellipsis-v" [fixedWidth]="true" size="sm"></fa-icon>
</button>
<ul id="dropdown-split" *dropdownMenu class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="button-split">
<li role="menuitem">
<button class="dropdown-item" (click)="deleteCustomImage(image)">
<fa-icon icon="trash" [fixedWidth]="true"></fa-icon>
Delete this image
</button>
</li>
</ul>
</div>
</td>
</tr>
</tbody>
<tfoot *ngIf="!listItems.length">
<tr>
<td colspan="7" class="text-uppercase">
No images match your search criteria
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>

View File

@ -1,45 +0,0 @@
.table-responsive
{
background-color: rgba(16, 21, 39, 0.75);
box-shadow: 0 0 0 2px #0b2b51, 0 0 2px 4px #0b284b, 0 0 10px 3px #0e162a;
transition: box-shadow 0.15s ease-out;
border-radius: .25rem;
&:hover
{
box-shadow: 0 0 0 2px #0b2b51, 0 0 2px 4px rgb(18 203 240 / 40%), 0 0 10px 3px #0e162a;
}
.rule
{
text-transform: uppercase;
color: #3d5e8e;
}
.highlight
{
color: #8881ff;
}
b, .strong
{
color: #ff9c07;
font-weight: normal;
}
.text-truncate
{
max-width: 350px;
}
.inline-list-item + .inline-list-item
{
padding-left: .25rem;
&:before
{
content: attr(text);
color: #3d5e8e;
}
}
}

View File

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

View File

@ -1,191 +0,0 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ColumnMode, SelectionType } from '@swimlane/ngx-datatable';
import { CatalogService } from '../helpers/catalog.service';
import { AuthService } from '../../helpers/auth.service';
import { debounceTime, distinctUntilChanged, filter, first, map, switchMap, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { ToastrService } from 'ngx-toastr';
import { CatalogImage } from '../models/image';
import { FormGroup, FormBuilder, Validators, AbstractControl, FormArray } from '@angular/forms';
import Fuse from 'fuse.js';
import { sortArray } from '../../helpers/utils.service';
import { BsModalService } from 'ngx-bootstrap/modal';
import { ConfirmationDialogComponent } from '../../components/confirmation-dialog/confirmation-dialog.component';
@Component({
selector: 'app-custom-images',
templateUrl: './custom-images.component.html',
styleUrls: ['./custom-images.component.scss']
})
export class CustomImagesComponent implements OnInit, OnDestroy
{
images: CatalogImage[] = [];
listItems: CatalogImage[] = [];
editorForm: FormGroup;
loadingIndicator = true;
private destroy$ = new Subject();
private readonly fuseJsOptions: {};
// ----------------------------------------------------------------------------------------------------------------
constructor(private readonly catalogService: CatalogService,
private readonly modalService: BsModalService,
private readonly authService: AuthService,
private readonly toastr: ToastrService,
private readonly fb: FormBuilder)
{
// Configure FuseJs
this.fuseJsOptions = {
includeScore: false,
minMatchCharLength: 2,
includeMatches: true,
shouldSort: false,
threshold: .3, // Lower value means a more exact search
keys: [
{ name: 'name', weight: .9 },
{ name: 'description', weight: .8 },
{ name: 'os', weight: .7 },
{ name: 'type', weight: .7 }
]
};
this.createForm();
}
// ----------------------------------------------------------------------------------------------------------------
private createForm()
{
this.editorForm = this.fb.group(
{
searchTerm: [''],
sortProperty: ['name']
});
this.editorForm.get('searchTerm').valueChanges
.pipe(
debounceTime(300),
distinctUntilChanged(),
takeUntil(this.destroy$)
)
.subscribe(() => this.applyFiltersAndSort());
this.editorForm.get('sortProperty').valueChanges
.pipe(
distinctUntilChanged(),
takeUntil(this.destroy$)
)
.subscribe(() => this.applyFiltersAndSort());
}
// ----------------------------------------------------------------------------------------------------------------
private applyFiltersAndSort()
{
let listItems: CatalogImage[] = null;
const searchTerm = this.editorForm.get('searchTerm').value;
if (searchTerm.length >= 2)
{
const fuse = new Fuse(this.images, this.fuseJsOptions);
const fuseResults = fuse.search(searchTerm);
listItems = fuseResults.map(x => x.item as CatalogImage);
}
if (!listItems)
listItems = [...this.images];
this.listItems = sortArray(listItems, this.editorForm.get('sortProperty').value);
}
// ----------------------------------------------------------------------------------------------------------------
setSortProperty(propertyName: string)
{
this.editorForm.get('sortProperty').setValue(propertyName);
}
// ----------------------------------------------------------------------------------------------------------------
clearSearch()
{
this.editorForm.get('searchTerm').setValue('');
}
// ----------------------------------------------------------------------------------------------------------------
private getCustomImages()
{
this.loadingIndicator = true;
this.authService.userInfoUpdated$
.pipe(
takeUntil(this.destroy$),
filter(userInfo => userInfo != null),
switchMap(userInfo => this.catalogService.getCustomImages(userInfo.id))
)
.subscribe(images =>
{
this.images = images;
this.applyFiltersAndSort();
this.loadingIndicator = false
}, err =>
{
const errorDetails = err.error?.message ? `(${err.error.message})` : '';
this.toastr.error(`Failed to retrieve the list of custom images ${errorDetails}`);
this.loadingIndicator = false;
});
}
// ----------------------------------------------------------------------------------------------------------------
deleteCustomImage(image: CatalogImage)
{
const modalConfig = {
ignoreBackdropClick: true,
keyboard: false,
animated: true,
initialState: {
prompt: `Are you sure you wish to permanently delete the "${image.name}" image?`,
confirmButtonText: 'Yes, delete this image',
declineButtonText: 'No, keep it',
confirmByDefault: false
}
};
const modalRef = this.modalService.show(ConfirmationDialogComponent, modalConfig);
modalRef.content.confirm.pipe(first()).subscribe(() =>
{
this.toastr.info(`Removing machine "${image.name}"...`);
this.catalogService.deleteImage(image.id)
.subscribe(() =>
{
const index = this.images.findIndex(i => i.id === image.id);
if (index >= 0)
this.images.splice(index, 1);
this.applyFiltersAndSort();
this.toastr.info(`The image "${image.name}" has been removed`);
},
err =>
{
this.toastr.error(`Failed to delete the "${image.name}" image ${err.error.message}`);
});
});
}
// ----------------------------------------------------------------------------------------------------------------
ngOnInit(): void
{
this.getCustomImages();
}
// ----------------------------------------------------------------------------------------------------------------
ngOnDestroy()
{
this.destroy$.next();
}
}

View File

@ -1 +0,0 @@
<p>docker-image-editor works!</p>

View File

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

View File

@ -1,15 +0,0 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-docker-image-editor',
templateUrl: './docker-image-editor.component.html',
styleUrls: ['./docker-image-editor.component.scss']
})
export class DockerImageEditorComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@ -1,57 +0,0 @@
<ngx-datatable [rows]="rows" [headerHeight]="48" [footerHeight]="46" [rowHeight]="40"
[scrollbarV]="true" [scrollbarH]="false" [selectionType]="selectionType.checkbox" [columnMode]="columnMode.flex"
[loadingIndicator]="loadingIndicator">
<ngx-datatable-column [width]="30"
[sortable]="false"
[canAutoResize]="false"
[draggable]="false"
[resizeable]="false"
[headerCheckboxable]="true"
[checkboxable]="true">
</ngx-datatable-column>
<ngx-datatable-column name="Name" [canAutoResize]="true" [flexGrow]="1"></ngx-datatable-column>
<ngx-datatable-column name="Description" [flexGrow]="2">
<ng-template let-value="value" ngx-datatable-cell-template>
<div class="text-truncate">{{ value }}</div>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="Status" prop="state" [width]="70" [canAutoResize]="false">
<ng-template let-value="value" ngx-datatable-cell-template>
<span class="badge" [ngClass]="value === 'active' ? 'bg-success' : 'bg-warning text-dark'">{{ value }}</span>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="OS" [canAutoResize]="false" [width]="100">
<ng-template let-value="value" ngx-datatable-cell-template>
<div class="os" [class.smartos]="value === 'smartos'" [class.bsd]="value === 'bsd'"
[class.windows]="value === 'windows'" [class.linux]="value === 'linux'">
<span>{{ value }}</span>
</div>
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="Type" [width]="120" [canAutoResize]="false"></ngx-datatable-column>
<ngx-datatable-column name="Publish date" prop="published_at" [width]="100" [canAutoResize]="false">
<ng-template let-value="value" ngx-datatable-cell-template>
{{ value | date | timeago }}
</ng-template>
</ngx-datatable-column>
<!--<ngx-datatable-column name="Tags">
<ng-template let-value="value" ngx-datatable-cell-template>
<ng-container *ngFor="let tag of value | keyvalue">
<span class="badge badge-dark mr-1">{{ tag.key }} <span class="text-primary">{{ tag.value }}</span></span>
</ng-container>
</ng-template>
</ngx-datatable-column>-->
<ngx-datatable-column [flexGrow]="1" cellClass="text-right" headerClass="text-right" [sortable]="false">
<ng-template let-value="value" ngx-datatable-cell-template>
<button class="btn btn-sm btn-primary m-1">Instances</button>
</ng-template>
</ngx-datatable-column>
</ngx-datatable>

View File

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

View File

@ -1,28 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { ColumnMode, SelectionType } from '@swimlane/ngx-datatable';
import { CatalogService } from '../helpers/catalog.service';
@Component({
selector: 'app-docker-images',
templateUrl: './docker-images.component.html',
styleUrls: ['./docker-images.component.scss']
})
export class DockerImagesComponent implements OnInit
{
rows: any[] = [];
loadingIndicator = true;
selectionType = SelectionType;
columnMode = ColumnMode;
// ----------------------------------------------------------------------------------------------------------------
constructor(private readonly catalogService: CatalogService)
{
}
// ----------------------------------------------------------------------------------------------------------------
ngOnInit(): void
{
}
}

View File

@ -1 +0,0 @@
<p>docker-registry-editor works!</p>

View File

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

View File

@ -1,15 +0,0 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-docker-registry-editor',
templateUrl: './docker-registry-editor.component.html',
styleUrls: ['./docker-registry-editor.component.scss']
})
export class DockerRegistryEditorComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@ -1 +0,0 @@
<p>docker-registry works!</p>

View File

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

View File

@ -1,15 +0,0 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-docker-registry',
templateUrl: './docker-registry.component.html',
styleUrls: ['./docker-registry.component.scss']
})
export class DockerRegistryComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}