ci/cd + any fixes
This commit is contained in:
+148
-136
@@ -3,15 +3,15 @@
|
||||
<mat-sidenav-container class="sidenav-container">
|
||||
<!-- Folder Tree Sidenav -->
|
||||
<mat-sidenav #sidenav
|
||||
mode="side"
|
||||
[opened]="showTreeView"
|
||||
class="tree-sidenav">
|
||||
mode="side"
|
||||
[opened]="showTreeView"
|
||||
class="tree-sidenav">
|
||||
|
||||
<app-file-system-tree-component
|
||||
(folderSelected)="onFolderSelected($event)"
|
||||
[baseUrl]="baseUrl"
|
||||
<app-file-system-tree-component
|
||||
(folderSelected)="onFolderSelected($event)"
|
||||
[baseUrl]="baseUrl"
|
||||
>
|
||||
</app-file-system-tree-component>
|
||||
</app-file-system-tree-component>
|
||||
</mat-sidenav>
|
||||
|
||||
<!-- Main Content -->
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
<div class="title-section">
|
||||
<button mat-icon-button (click)="toggleView()"
|
||||
[matTooltip]="showTreeView ? 'Hide Tree' : 'Show Tree'">
|
||||
[matTooltip]="showTreeView ? 'Hide Tree' : 'Show Tree'">
|
||||
<mat-icon>{{ showTreeView ? 'view_list' : 'account_tree' }}</mat-icon>
|
||||
</button>
|
||||
<!-- Breadcrumb Navigation -->
|
||||
@@ -34,29 +34,31 @@
|
||||
Root
|
||||
</button>
|
||||
</li>
|
||||
<li *ngFor="let segment of pathSegments; let i = index" class="breadcrumb-item">
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
<button mat-button (click)="navigateToPath(i)" class="path-button">
|
||||
{{ segment }}
|
||||
</button>
|
||||
</li>
|
||||
@for (segment of pathSegments; track segment; let i = $index) {
|
||||
<li class="breadcrumb-item">
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
<button mat-button (click)="navigateToPath(i)" class="path-button">
|
||||
{{ segment }}
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
</ol>
|
||||
</nav>
|
||||
<div class="header-actions">
|
||||
<!-- Search Bar -->
|
||||
<!--<div class="search-container">
|
||||
<mat-form-field appearance="outline" class="search-field">
|
||||
<mat-label>Search files...</mat-label>
|
||||
<input matInput
|
||||
[(ngModel)]="searchQuery"
|
||||
(input)="onSearchInput($event)"
|
||||
placeholder="Enter filename or extension">
|
||||
<mat-form-field appearance="outline" class="search-field">
|
||||
<mat-label>Search files...</mat-label>
|
||||
<input matInput
|
||||
[(ngModel)]="searchQuery"
|
||||
(input)="onSearchInput($event)"
|
||||
placeholder="Enter filename or extension">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<button *ngIf="searchQuery"
|
||||
mat-icon-button
|
||||
matSuffix
|
||||
(click)="clearSearch()"
|
||||
matTooltip="Clear search">
|
||||
mat-icon-button
|
||||
matSuffix
|
||||
(click)="clearSearch()"
|
||||
matTooltip="Clear search">
|
||||
<mat-icon>clear</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
@@ -64,134 +66,144 @@
|
||||
</div>-->
|
||||
|
||||
<input #fileInput type="file" multiple style="display: none"
|
||||
(change)="onFilesSelected($event)">
|
||||
<button mat-icon-button
|
||||
color="primary"
|
||||
[matTooltip]="'Upload Files'"
|
||||
(click)="fileInput.click()">
|
||||
<mat-icon>upload</mat-icon>
|
||||
(change)="onFilesSelected($event)">
|
||||
<button mat-icon-button
|
||||
color="primary"
|
||||
[matTooltip]="'Upload Files'"
|
||||
(click)="fileInput.click()">
|
||||
<mat-icon>upload</mat-icon>
|
||||
|
||||
</button>
|
||||
<button mat-icon-button
|
||||
color="accent"
|
||||
[matTooltip]="'New Folder'"
|
||||
(click)="openCreateFolderDialog()">
|
||||
<mat-icon>create_new_folder</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button
|
||||
color="accent"
|
||||
[matTooltip]="'New Folder'"
|
||||
(click)="openCreateFolderDialog()">
|
||||
<mat-icon>create_new_folder</mat-icon>
|
||||
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</mat-card-title>
|
||||
</mat-card-header>
|
||||
</mat-card-title>
|
||||
</mat-card-header>
|
||||
|
||||
<mat-card-content>
|
||||
<mat-card-content>
|
||||
|
||||
|
||||
<!-- Progress Bar -->
|
||||
<mat-progress-bar *ngIf="loading" mode="indeterminate"></mat-progress-bar>
|
||||
<!-- Progress Bar -->
|
||||
@if (loading) {
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
}
|
||||
|
||||
<!-- Upload Progress -->
|
||||
<div *ngIf="uploading" class="upload-progress">
|
||||
<mat-progress-bar mode="determinate" [value]="uploadProgress"></mat-progress-bar>
|
||||
<span class="progress-text">Uploading... {{uploadProgress}}%</span>
|
||||
</div>
|
||||
<!-- Upload Progress -->
|
||||
@if (uploading) {
|
||||
<div class="upload-progress">
|
||||
<mat-progress-bar mode="determinate" [value]="uploadProgress"></mat-progress-bar>
|
||||
<span class="progress-text">Uploading... {{uploadProgress}}%</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- File Table -->
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" class="file-table">
|
||||
<!-- Selection Column -->
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox (change)="masterToggle()"
|
||||
[checked]="selection.size > 0 && isAllSelected()"
|
||||
[indeterminate]="selection.size > 0 && !isAllSelected()">
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let file">
|
||||
<mat-checkbox (change)="toggleSelection(file)"
|
||||
[checked]="isSelected(file)">
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- File Table -->
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="dataSource" class="file-table">
|
||||
<!-- Selection Column -->
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox (change)="masterToggle()"
|
||||
[checked]="selection.size > 0 && isAllSelected()"
|
||||
[indeterminate]="selection.size > 0 && !isAllSelected()">
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let file">
|
||||
<mat-checkbox (change)="toggleSelection(file)"
|
||||
[checked]="isSelected(file)">
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Icon Column -->
|
||||
<ng-container matColumnDef="icon">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let file" class="icon-cell">
|
||||
<mat-icon [class.folder-icon]="file.type === 'directory'">
|
||||
{{ getFileIcon(file) }}
|
||||
</mat-icon>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Icon Column -->
|
||||
<ng-container matColumnDef="icon">
|
||||
<th mat-header-cell *matHeaderCellDef></th>
|
||||
<td mat-cell *matCellDef="let file" class="icon-cell">
|
||||
<mat-icon [class.folder-icon]="file.type === 'directory'">
|
||||
{{ getFileIcon(file) }}
|
||||
</mat-icon>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Name Column -->
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>Name</th>
|
||||
<td mat-cell *matCellDef="let file"
|
||||
<!-- Name Column -->
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>Name</th>
|
||||
<td mat-cell *matCellDef="let file"
|
||||
(dblclick)="onFileDoubleClick(file)"
|
||||
class="name-cell"
|
||||
[class.clickable]="file.type === 'directory'">
|
||||
{{ file.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
{{ file.name }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Size Column -->
|
||||
<ng-container matColumnDef="size">
|
||||
<th mat-header-cell *matHeaderCellDef>Size</th>
|
||||
<td mat-cell *matCellDef="let file">
|
||||
{{ file.type === 'directory' ? '-' : formatFileSize(file.size) }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Size Column -->
|
||||
<ng-container matColumnDef="size">
|
||||
<th mat-header-cell *matHeaderCellDef>Size</th>
|
||||
<td mat-cell *matCellDef="let file">
|
||||
{{ file.type === 'directory' ? '-' : formatFileSize(file.size) }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Last Modified Column -->
|
||||
<ng-container matColumnDef="lastModified">
|
||||
<th mat-header-cell *matHeaderCellDef>Last Modified</th>
|
||||
<td mat-cell *matCellDef="let file">
|
||||
{{ file.lastModified | date:'short' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Last Modified Column -->
|
||||
<ng-container matColumnDef="lastModified">
|
||||
<th mat-header-cell *matHeaderCellDef>Last Modified</th>
|
||||
<td mat-cell *matCellDef="let file">
|
||||
{{ file.lastModified | date:'short' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Actions Column -->
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<button *ngIf="selection.size > 0"
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
(click)="deleteSelected()"
|
||||
matTooltip="Delete Selected">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let file">
|
||||
<button *ngIf="file.type === 'file'"
|
||||
mat-icon-button
|
||||
(click)="downloadFile(file)"
|
||||
matTooltip="Download">
|
||||
<mat-icon>download</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button
|
||||
(click)="deleteFile(file)"
|
||||
color="warn"
|
||||
matTooltip="Delete">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Actions Column -->
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
@if (selection.size > 0) {
|
||||
<button
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
(click)="deleteSelected()"
|
||||
matTooltip="Delete Selected">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let file">
|
||||
@if (file.type === 'file') {
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="downloadFile(file)"
|
||||
matTooltip="Download">
|
||||
<mat-icon>download</mat-icon>
|
||||
</button>
|
||||
}
|
||||
<button mat-icon-button
|
||||
(click)="deleteFile(file)"
|
||||
color="warn"
|
||||
matTooltip="Delete">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
</div>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Empty State -->
|
||||
<div *ngIf="!loading && dataSource.data.length === 0" class="empty-state">
|
||||
<mat-icon>{{ searchQuery ? 'search_off' : 'folder_open' }}</mat-icon>
|
||||
<h3>{{ searchQuery ? 'No results found' : 'This folder is empty' }}</h3>
|
||||
<p>{{ searchQuery ? 'Try adjusting your search terms' : 'Upload files or create folders to get started.' }}</p>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
</div>
|
||||
<!-- Empty State -->
|
||||
@if (!loading && dataSource.data.length === 0) {
|
||||
<div class="empty-state">
|
||||
<mat-icon>{{ searchQuery ? 'search_off' : 'folder_open' }}</mat-icon>
|
||||
<h3>{{ searchQuery ? 'No results found' : 'This folder is empty' }}</h3>
|
||||
<p>{{ searchQuery ? 'Try adjusting your search terms' : 'Upload files or create folders to get started.' }}</p>
|
||||
</div>
|
||||
}
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
</div>
|
||||
|
||||
+3
-10
@@ -1,5 +1,5 @@
|
||||
import {Component, CUSTOM_ELEMENTS_SCHEMA, Input, OnInit, ViewChild} from '@angular/core';
|
||||
import {DatePipe, NgForOf, NgIf} from '@angular/common';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import {
|
||||
MatCell,
|
||||
MatCellDef, MatColumnDef,
|
||||
@@ -29,7 +29,6 @@ import {FileSystemTreeComponent} from '../file-system-tree-component/file-system
|
||||
@Component({
|
||||
selector: 'app-file-browser-with-tree-component',
|
||||
imports: [
|
||||
NgIf,
|
||||
MatIcon,
|
||||
MatHeaderRowDef,
|
||||
MatRowDef,
|
||||
@@ -45,10 +44,7 @@ import {FileSystemTreeComponent} from '../file-system-tree-component/file-system
|
||||
MatCheckbox,
|
||||
MatTable,
|
||||
MatProgressBar,
|
||||
|
||||
FormsModule,
|
||||
|
||||
NgForOf,
|
||||
MatButton,
|
||||
MatCardContent,
|
||||
MatSidenavContent,
|
||||
@@ -57,12 +53,9 @@ import {FileSystemTreeComponent} from '../file-system-tree-component/file-system
|
||||
MatCardTitle,
|
||||
MatSidenav,
|
||||
MatSidenavContainer,
|
||||
|
||||
|
||||
DatePipe,
|
||||
FileSystemTreeComponent,
|
||||
|
||||
],
|
||||
FileSystemTreeComponent
|
||||
],
|
||||
templateUrl: './file-browser-with-tree-component.html',
|
||||
styleUrl: './file-browser-with-tree-component.scss',
|
||||
schemas:[CUSTOM_ELEMENTS_SCHEMA]
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import {MatProgressBarModule} from '@angular/material/progress-bar';
|
||||
import {MatIconModule} from '@angular/material/icon';
|
||||
import {MatButtonModule} from '@angular/material/button';
|
||||
import {MatTreeModule} from '@angular/material/tree';
|
||||
import {NgIf} from '@angular/common';
|
||||
|
||||
|
||||
import {FileBrowserTreeService, FileItem} from '../../services/file-browser-tree.service';
|
||||
import {MatTooltip} from '@angular/material/tooltip';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import "~node_modules/cropperjs/dist/cropper.css";
|
||||
@import "node_modules/cropperjs/dist/cropper.css";
|
||||
|
||||
.ngx-pe-overlay-container {
|
||||
width: 100%;
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from '@angular/core';
|
||||
import {Route, Router, RouterLink, RouterLinkActive} from '@angular/router';
|
||||
import {MatListItem, MatListItemIcon, MatListItemTitle, MatNavList} from '@angular/material/list';
|
||||
import {NgForOf} from '@angular/common';
|
||||
|
||||
import {MatIconButton} from '@angular/material/button';
|
||||
import {MatTooltip} from '@angular/material/tooltip';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
@@ -36,10 +36,8 @@ export interface NavItem {
|
||||
RouterLink,
|
||||
MatListItem,
|
||||
MatNavList,
|
||||
NgForOf,
|
||||
MatIconButton,
|
||||
|
||||
],
|
||||
MatIconButton
|
||||
],
|
||||
templateUrl: './vertical-nav.component.html',
|
||||
styleUrl: './vertical-nav.component.scss',
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
|
||||
+49
-52
@@ -1,8 +1,8 @@
|
||||
<div class="json-dump-container" *ngIf="!loading; else loadingTpl">
|
||||
<h2>JSON Dump Management</h2>
|
||||
|
||||
<!-- Entity-specific Export/Import -->
|
||||
<!-- <div class="entity-actions" *ngFor="let entity of entityTypes">
|
||||
@if (!loading) {
|
||||
<div class="json-dump-container">
|
||||
<h2>JSON Dump Management</h2>
|
||||
<!-- Entity-specific Export/Import -->
|
||||
<!-- <div class="entity-actions" *ngFor="let entity of entityTypes">
|
||||
<h3>{{ entity | titlecase }}</h3>
|
||||
<button mat-raised-button color="primary" (click)="exportEntity(entity)">
|
||||
<mat-icon>download</mat-icon> Export {{ entity }}
|
||||
@@ -38,51 +38,48 @@
|
||||
accept=".json"
|
||||
(change)="onFileSelected($event, entity)"
|
||||
hidden
|
||||
/>
|
||||
</mat-toolbar-row>
|
||||
}
|
||||
</mat-toolbar>
|
||||
<!-- Files Table -->
|
||||
<h3>Available JSON Files</h3>
|
||||
<mat-table [dataSource]="files">
|
||||
<ng-container matColumnDef="fileName">
|
||||
<mat-header-cell *matHeaderCellDef> File Name </mat-header-cell>
|
||||
<mat-cell *matCellDef="let file">{{ file.fileName }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="size">
|
||||
<mat-header-cell *matHeaderCellDef> Size </mat-header-cell>
|
||||
<mat-cell *matCellDef="let file">{{ jsonDumpService.formatFileSize(file.size) }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="lastModified">
|
||||
<mat-header-cell *matHeaderCellDef> Last Modified </mat-header-cell>
|
||||
<mat-cell *matCellDef="let file">{{ jsonDumpService.formatDate(file.lastModified) }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
|
||||
<mat-cell *matCellDef="let file">
|
||||
<button mat-icon-button (click)="downloadFile(file.fileName)" matTooltip="Download">
|
||||
<mat-icon>download</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="deleteFile(file.fileName)" matTooltip="Delete">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="['fileName', 'size', 'lastModified', 'actions']"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: ['fileName', 'size', 'lastModified', 'actions']"></mat-row>
|
||||
</mat-table>
|
||||
|
||||
<!-- Archives -->
|
||||
<h3>Archives</h3>
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let archive of archives">{{ archive }}</mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
|
||||
<ng-template #loadingTpl>
|
||||
/>
|
||||
</mat-toolbar-row>
|
||||
}
|
||||
</mat-toolbar>
|
||||
<!-- Files Table -->
|
||||
<h3>Available JSON Files</h3>
|
||||
<mat-table [dataSource]="files">
|
||||
<ng-container matColumnDef="fileName">
|
||||
<mat-header-cell *matHeaderCellDef> File Name </mat-header-cell>
|
||||
<mat-cell *matCellDef="let file">{{ file.fileName }}</mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="size">
|
||||
<mat-header-cell *matHeaderCellDef> Size </mat-header-cell>
|
||||
<mat-cell *matCellDef="let file">{{ jsonDumpService.formatFileSize(file.size) }}</mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="lastModified">
|
||||
<mat-header-cell *matHeaderCellDef> Last Modified </mat-header-cell>
|
||||
<mat-cell *matCellDef="let file">{{ jsonDumpService.formatDate(file.lastModified) }}</mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions">
|
||||
<mat-header-cell *matHeaderCellDef> Actions </mat-header-cell>
|
||||
<mat-cell *matCellDef="let file">
|
||||
<button mat-icon-button (click)="downloadFile(file.fileName)" matTooltip="Download">
|
||||
<mat-icon>download</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="deleteFile(file.fileName)" matTooltip="Delete">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
<mat-header-row *matHeaderRowDef="['fileName', 'size', 'lastModified', 'actions']"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: ['fileName', 'size', 'lastModified', 'actions']"></mat-row>
|
||||
</mat-table>
|
||||
<!-- Archives -->
|
||||
<h3>Archives</h3>
|
||||
<mat-list>
|
||||
@for (archive of archives; track archive) {
|
||||
<mat-list-item>{{ archive }}</mat-list-item>
|
||||
}
|
||||
</mat-list>
|
||||
</div>
|
||||
} @else {
|
||||
<mat-spinner></mat-spinner>
|
||||
</ng-template>
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -12,7 +12,7 @@ import {
|
||||
MatRowDef, MatTable
|
||||
} from '@angular/material/table';
|
||||
import {MatIconButton} from '@angular/material/button';
|
||||
import {NgForOf, NgIf, TitleCasePipe} from '@angular/common';
|
||||
import { TitleCasePipe } from '@angular/common';
|
||||
import {MatProgressSpinner} from '@angular/material/progress-spinner';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {MatTooltip} from '@angular/material/tooltip';
|
||||
@@ -41,12 +41,10 @@ import {MatLabel} from '@angular/material/input';
|
||||
MatCellDef,
|
||||
MatTable,
|
||||
TitleCasePipe,
|
||||
NgIf,
|
||||
NgForOf,
|
||||
MatToolbar,
|
||||
MatToolbarRow,
|
||||
MatLabel
|
||||
],
|
||||
],
|
||||
styleUrls: ['./json-dump.component.scss'],
|
||||
schemas:[CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ import {Subscription} from 'rxjs';
|
||||
import {TokenStorageService} from '../../../services/token-storage.service';
|
||||
import {AuthService} from '../../../services/auth.service';
|
||||
import {EventBusService} from '../../../_shared/event-bus.service';
|
||||
import {CommonModule} from '@angular/common';
|
||||
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
import {MatMenu, MatMenuItem, MatMenuTrigger} from '@angular/material/menu';
|
||||
import {MatTooltip} from '@angular/material/tooltip';
|
||||
@@ -26,7 +26,6 @@ import {GlobalConstants} from '../../../global-constants';
|
||||
MatButton,
|
||||
RouterLink,
|
||||
RouterOutlet,
|
||||
CommonModule,
|
||||
MatIcon,
|
||||
MatMiniFabButton,
|
||||
MatMenuTrigger,
|
||||
@@ -34,7 +33,7 @@ import {GlobalConstants} from '../../../global-constants';
|
||||
MatMenuItem,
|
||||
MatTooltip,
|
||||
MatLabel
|
||||
],
|
||||
],
|
||||
schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
|
||||
templateUrl: './main.component.html',
|
||||
styleUrl: './main.component.scss'
|
||||
|
||||
+88
-81
@@ -6,33 +6,36 @@
|
||||
<h3>Running Containers</h3>
|
||||
<button (click)="refreshContainers()" class="btn btn-secondary">Refresh</button>
|
||||
|
||||
<div class="container-list" *ngIf="containers.length > 0; else noContainers">
|
||||
<div class="container-item" *ngFor="let container of containers">
|
||||
<div class="container-info">
|
||||
<strong>{{container.name}}</strong>
|
||||
<span class="image">{{container.image}}</span>
|
||||
<span class="status" [class.running]="container.status.includes('Up')">
|
||||
@if (containers.length > 0) {
|
||||
<div class="container-list">
|
||||
@for (container of containers; track container) {
|
||||
<div class="container-item">
|
||||
<div class="container-info">
|
||||
<strong>{{container.name}}</strong>
|
||||
<span class="image">{{container.image}}</span>
|
||||
<span class="status" [class.running]="container.status.includes('Up')">
|
||||
{{container.status}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="container-actions">
|
||||
<button (click)="stopContainer(container.name)"
|
||||
[disabled]="!container.status.includes('Up')"
|
||||
class="btn btn-warning">Stop</button>
|
||||
<button (click)="startContainer(container.name)"
|
||||
[disabled]="container.status.includes('Up')"
|
||||
class="btn btn-success">Start</button>
|
||||
<button (click)="removeContainer(container.name)"
|
||||
class="btn btn-danger">Remove</button>
|
||||
<button (click)="viewLogs(container.name)"
|
||||
class="btn btn-info">Logs</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-actions">
|
||||
<button (click)="stopContainer(container.name)"
|
||||
[disabled]="!container.status.includes('Up')"
|
||||
class="btn btn-warning">Stop</button>
|
||||
<button (click)="startContainer(container.name)"
|
||||
[disabled]="container.status.includes('Up')"
|
||||
class="btn btn-success">Start</button>
|
||||
<button (click)="removeContainer(container.name)"
|
||||
class="btn btn-danger">Remove</button>
|
||||
<button (click)="viewLogs(container.name)"
|
||||
class="btn btn-info">Logs</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #noContainers>
|
||||
} @else {
|
||||
<p>No containers found</p>
|
||||
</ng-template>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Run New Container -->
|
||||
@@ -42,68 +45,72 @@
|
||||
<div class="form-group">
|
||||
<label>Image Name:</label>
|
||||
<input type="text" formControlName="imageName"
|
||||
placeholder="e.g., nginx:latest" class="form-control">
|
||||
</div>
|
||||
placeholder="e.g., nginx:latest" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Container Name:</label>
|
||||
<input type="text" formControlName="containerName"
|
||||
placeholder="Optional container name" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Container Name:</label>
|
||||
<input type="text" formControlName="containerName"
|
||||
placeholder="Optional container name" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Ports:</label>
|
||||
<input type="text" formControlName="ports"
|
||||
placeholder="e.g., 8080:80" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Ports:</label>
|
||||
<input type="text" formControlName="ports"
|
||||
placeholder="e.g., 8080:80" class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Environment Variables:</label>
|
||||
<input type="text" formControlName="environmentVars"
|
||||
placeholder="e.g., -e NODE_ENV=production" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Environment Variables:</label>
|
||||
<input type="text" formControlName="environmentVars"
|
||||
placeholder="e.g., -e NODE_ENV=production" class="form-control">
|
||||
</div>
|
||||
|
||||
<button type="submit" [disabled]="runContainerForm.invalid || loading"
|
||||
class="btn btn-primary">
|
||||
{{loading ? 'Starting...' : 'Run Container'}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<button type="submit" [disabled]="runContainerForm.invalid || loading"
|
||||
class="btn btn-primary">
|
||||
{{loading ? 'Starting...' : 'Run Container'}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Execute Command -->
|
||||
<div class="execute-command-section">
|
||||
<h3>Execute Docker Command</h3>
|
||||
<form [formGroup]="commandForm" (ngSubmit)="executeCommand()">
|
||||
<div class="form-group">
|
||||
<label>Docker Command:</label>
|
||||
<input type="text" formControlName="command"
|
||||
placeholder="e.g., docker ps -a" class="form-control">
|
||||
</div>
|
||||
<button type="submit" [disabled]="commandForm.invalid || loading"
|
||||
class="btn btn-primary">Execute</button>
|
||||
</form>
|
||||
</div>
|
||||
<!-- Execute Command -->
|
||||
<div class="execute-command-section">
|
||||
<h3>Execute Docker Command</h3>
|
||||
<form [formGroup]="commandForm" (ngSubmit)="executeCommand()">
|
||||
<div class="form-group">
|
||||
<label>Docker Command:</label>
|
||||
<input type="text" formControlName="command"
|
||||
placeholder="e.g., docker ps -a" class="form-control">
|
||||
</div>
|
||||
<button type="submit" [disabled]="commandForm.invalid || loading"
|
||||
class="btn btn-primary">Execute</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Command Output -->
|
||||
<div class="output-section" *ngIf="lastCommandResult">
|
||||
<h3>Command Output</h3>
|
||||
<div class="output-box"
|
||||
[class.success]="lastCommandResult.success"
|
||||
[class.error]="!lastCommandResult.success">
|
||||
<pre>{{getOutputText(lastCommandResult.output)}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Command Output -->
|
||||
@if (lastCommandResult) {
|
||||
<div class="output-section">
|
||||
<h3>Command Output</h3>
|
||||
<div class="output-box"
|
||||
[class.success]="lastCommandResult.success"
|
||||
[class.error]="!lastCommandResult.success">
|
||||
<pre>{{getOutputText(lastCommandResult.output)}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Container Logs Modal -->
|
||||
<div class="logs-modal" *ngIf="selectedContainerLogs">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3>Container Logs: {{selectedContainer}}</h3>
|
||||
<button (click)="closeLogs()" class="close-btn">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre class="logs-content">{{selectedContainerLogs.join('\n')}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Container Logs Modal -->
|
||||
@if (selectedContainerLogs) {
|
||||
<div class="logs-modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3>Container Logs: {{selectedContainer}}</h3>
|
||||
<button (click)="closeLogs()" class="close-btn">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre class="logs-content">{{selectedContainerLogs.join('\n')}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
+3
-5
@@ -1,5 +1,5 @@
|
||||
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||
import {NgForOf, NgIf} from '@angular/common';
|
||||
|
||||
import {Subject, takeUntil} from 'rxjs';
|
||||
import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
|
||||
import {ContainerInfo, DockerResult, DockerService} from '../docker.service';
|
||||
@@ -7,10 +7,8 @@ import {ContainerInfo, DockerResult, DockerService} from '../docker.service';
|
||||
@Component({
|
||||
selector: 'app-docker-management-component',
|
||||
imports: [
|
||||
NgIf,
|
||||
ReactiveFormsModule,
|
||||
NgForOf
|
||||
],
|
||||
ReactiveFormsModule
|
||||
],
|
||||
templateUrl: './docker-management-component.html',
|
||||
styleUrl: './docker-management-component.scss'
|
||||
})
|
||||
|
||||
@@ -3,6 +3,7 @@ export const environment = {
|
||||
port: 8081,
|
||||
production: true,
|
||||
fromWeb: true,
|
||||
host_name: 'https://jambotron.run.place',
|
||||
//host_name: 'https://jambotron.run.place',
|
||||
host_name:'http://localhost',
|
||||
title: 'JAMBOTRON.RUN.PLACE'
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user