Skip to content

Commit b23d1ee

Browse files
committed
💄 improve dashboard
1 parent 9abfe35 commit b23d1ee

11 files changed

Lines changed: 339 additions & 158 deletions

File tree

Lines changed: 165 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,171 @@
1-
<mat-card class="dashboard__card">
2-
<mat-card-title i18n>Backends</mat-card-title>
3-
<mat-card-content>
1+
<div class="dashboard__card-wrapper">
2+
<mat-card class="dashboard__card">
3+
<mat-card-header>
4+
<mat-card-title i18n>Backends</mat-card-title>
5+
</mat-card-header>
6+
47
<ng-container [ngSwitch]="backends?.length">
5-
<div *ngSwitchCase="undefined">...</div>
6-
<div *ngSwitchCase="null">
7-
<a
8-
mat-stroked-button
9-
color="primary"
10-
routerLink="/rclone/drive/new"
11-
i18n
12-
>
13-
Connect your first backend
14-
</a>
15-
</div>
16-
<div *ngSwitchCase="1">
17-
<a
18-
mat-stroked-button
19-
color="primary"
20-
routerLink="/rclone/explore"
21-
[queryParams]="{ drive: backends?.[0] }"
22-
i18n
23-
>
24-
Browse {{ backends?.[0] }}
25-
</a>
26-
</div>
27-
<div *ngSwitchDefault>
28-
<a mat-stroked-button color="primary" routerLink="/rclone/drive" i18n>
29-
Browse backends
30-
</a>
31-
</div>
8+
<ng-container *ngSwitchCase="undefined">
9+
<mat-card-content> ... </mat-card-content>
10+
</ng-container>
11+
<ng-container *ngSwitchCase="null">
12+
<mat-card-content i18n> Connect your first backend </mat-card-content>
13+
<mat-card-actions>
14+
<a mat-button color="primary" routerLink="/rclone/drive/new" i18n>
15+
New Backend
16+
</a>
17+
</mat-card-actions>
18+
</ng-container>
19+
<ng-container *ngSwitchCase="1">
20+
<mat-card-content i18n>
21+
Backend {{ backends?.[0] }} is connected
22+
</mat-card-content>
23+
<mat-card-actions>
24+
<a
25+
mat-button
26+
color="primary"
27+
routerLink="/rclone/explore"
28+
[queryParams]="{ drive: backends?.[0] }"
29+
i18n
30+
>
31+
Browse
32+
</a>
33+
</mat-card-actions>
34+
</ng-container>
35+
<ng-container *ngSwitchDefault>
36+
<mat-card-content i18n>
37+
{{ backends?.length }} Backends are connected
38+
</mat-card-content>
39+
<mat-card-actions>
40+
<a mat-button color="primary" routerLink="/rclone/drive" i18n>
41+
Browse
42+
</a>
43+
</mat-card-actions>
44+
</ng-container>
3245
</ng-container>
33-
</mat-card-content>
34-
</mat-card>
46+
</mat-card>
47+
</div>
48+
49+
<div class="dashboard__card-wrapper">
50+
<mat-card class="dashboard__card">
51+
<mat-card-header>
52+
<mat-card-title i18n>Go to</mat-card-title>
53+
</mat-card-header>
54+
<mat-card-content>
55+
<mat-form-field>
56+
<input
57+
matInput
58+
[(ngModel)]="goToPath"
59+
(keyup.enter)="GoToLink._elementRef.nativeElement.click()"
60+
required
61+
placeholder="path:to/dest"
62+
/>
63+
</mat-form-field>
64+
</mat-card-content>
65+
<mat-card-actions>
66+
<a
67+
mat-button
68+
color="primary"
69+
routerLink="/rclone/explore"
70+
[disabled]="!goToPath"
71+
[queryParams]="{ path: goToPath }"
72+
i18n
73+
#GoToLink
74+
>
75+
Go
76+
</a>
77+
</mat-card-actions>
78+
</mat-card>
79+
</div>
80+
81+
<div class="dashboard__card-wrapper">
82+
<mat-card class="dashboard__card">
83+
<mat-card-header>
84+
<mat-card-title i18n>Mountpoints</mat-card-title>
85+
</mat-card-header>
86+
<mat-card-content i18n> Save your mountpoints here. </mat-card-content>
87+
<mat-card-actions>
88+
<a mat-button color="primary" routerLink="/rclone/mount" i18n> Manage </a>
89+
</mat-card-actions>
90+
</mat-card>
91+
</div>
92+
93+
<div class="dashboard__card-wrapper">
94+
<mat-card class="dashboard__card">
95+
<mat-card-header>
96+
<mat-card-title i18n>Rclone</mat-card-title>
97+
</mat-card-header>
98+
<mat-card-content>
99+
<table *ngIf="version">
100+
<tr>
101+
<td i18n>Version</td>
102+
<td>
103+
{{ version.version }}
104+
<ng-container *ngIf="version.isBeta" i18n> (Beta) </ng-container>
105+
<ng-container *ngIf="version.isGit" i18n> (Git)</ng-container>
106+
</td>
107+
</tr>
108+
<tr>
109+
<td i18n>Platform</td>
110+
<td>{{ version.os }}-{{ version.arch }}</td>
111+
</tr>
112+
<tr>
113+
<td i18n>Go version</td>
114+
<td>{{ version.goVersion }}</td>
115+
</tr>
116+
</table>
117+
</mat-card-content>
118+
</mat-card>
119+
</div>
35120

36-
<mat-card class="dashboard__card">
37-
<mat-card-title i18n>Mountpoints</mat-card-title>
38-
<mat-card-content>
39-
<a mat-stroked-button color="primary" routerLink="/rclone/mount" i18n>
40-
Manage Mountpoints
41-
</a>
42-
</mat-card-content>
43-
</mat-card>
121+
<div class="dashboard__card-wrapper">
122+
<mat-card class="dashboard__card">
123+
<mat-card-header>
124+
<mat-card-title i18n>WebUI</mat-card-title>
125+
</mat-card-header>
44126

45-
<mat-card class="dashboard__card">
46-
<mat-card-title i18n>Rclone</mat-card-title>
47-
<mat-card-content>
48-
<table *ngIf="version">
49-
<tr>
50-
<td i18n>Version</td>
51-
<td>
52-
{{ version.version }}
53-
<ng-container *ngIf="version.isBeta" i18n> (Beta) </ng-container>
54-
<ng-container *ngIf="version.isGit" i18n> (Git)</ng-container>
55-
</td>
56-
</tr>
57-
<tr>
58-
<td i18n>Platform</td>
59-
<td>{{ version.os }}-{{ version.arch }}</td>
60-
</tr>
61-
<tr>
62-
<td i18n>Go version</td>
63-
<td>{{ version.goVersion }}</td>
64-
</tr>
65-
</table>
66-
</mat-card-content>
67-
</mat-card>
127+
<mat-card-content>
128+
<table>
129+
<tr>
130+
<td i18n>Version</td>
131+
<td>{{ webUIVersion }}</td>
132+
</tr>
133+
<tr>
134+
<td i18n>Environment</td>
135+
<td>{{ webUIEnv }}</td>
136+
</tr>
137+
</table>
138+
</mat-card-content>
139+
</mat-card>
140+
</div>
68141

69-
<mat-card class="dashboard__card">
70-
<mat-card-title i18n>WebUI</mat-card-title>
71-
<mat-card-content>
72-
<table>
73-
<tr>
74-
<td i18n>Version</td>
75-
<td>{{ webUIVersion }}</td>
76-
</tr>
77-
<tr>
78-
<td i18n>Environment</td>
79-
<td>{{ webUIEnv }}</td>
80-
</tr>
81-
</table>
82-
</mat-card-content>
83-
</mat-card>
142+
<div class="dashboard__card-wrapper">
143+
<mat-card class="dashboard__card">
144+
<mat-card-header>
145+
<mat-card-title i18n>Statistics</mat-card-title>
146+
</mat-card-header>
84147

85-
<mat-card class="dashboard__card">
86-
<mat-card-title i18n>Statistics</mat-card-title>
87-
<mat-card-content>
88-
<table *ngIf="stat$ | async as stat">
89-
<tr>
90-
<td i18n>Transferring</td>
91-
<td>
92-
{{ stat.transferring?.length ?? 0 }}
93-
</td>
94-
</tr>
95-
<tr>
96-
<td i18n>Transferred</td>
97-
<td>
98-
{{ stat.transfers }}
99-
</td>
100-
</tr>
101-
<tr>
102-
<td i18n>Speed</td>
103-
<td>
104-
{{ stat.speed }}
105-
</td>
106-
</tr>
107-
</table>
108-
</mat-card-content>
109-
</mat-card>
148+
<mat-card-content>
149+
<table *ngIf="stat$ | async as stat">
150+
<tr>
151+
<td i18n>Transferring</td>
152+
<td>
153+
{{ stat.transferring?.length ?? 0 }}
154+
</td>
155+
</tr>
156+
<tr>
157+
<td i18n>Transferred</td>
158+
<td>
159+
{{ stat.transfers }}
160+
</td>
161+
</tr>
162+
<tr>
163+
<td i18n>Speed</td>
164+
<td>
165+
{{ stat.speed }}
166+
</td>
167+
</tr>
168+
</table>
169+
</mat-card-content>
170+
</mat-card>
171+
</div>

‎src/app/features/dashboard/dashboard.component.scss‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,15 @@
55
align-items: stretch;
66
}
77

8-
.dashboard__card {
8+
.dashboard__card-wrapper {
99
display: inline-block;
1010
margin: 2em;
11+
}
12+
13+
.dashboard__card {
1114
min-width: 20em;
15+
height: 100%;
16+
> mat-card-content {
17+
flex: 1;
18+
}
1219
}

‎src/app/features/dashboard/dashboard.component.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { DashboardService } from './dashboard.service';
1414
})
1515
export class DashboardComponent implements OnInit {
1616
backends?: string[] | null;
17+
goToPath = '';
1718
version?: RcloneVersionInfo;
1819
webUIVersion = packageJson.version;
1920
webUIEnv = environment.environment;

‎src/app/features/dashboard/dashboard.module.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,22 @@ import { NgModule } from '@angular/core';
33

44
import { MatCardModule } from '@angular/material/card';
55

6+
import { FormsModule } from '@angular/forms';
67
import { MatButtonModule } from '@angular/material/button';
8+
import { MatFormFieldModule } from '@angular/material/form-field';
9+
import { MatInputModule } from '@angular/material/input';
710
import { DashboardRoutingModule } from './dashboard-routing.module';
811
import { DashboardComponent } from './dashboard.component';
912

1013
@NgModule({
1114
declarations: [DashboardComponent],
1215
imports: [
1316
CommonModule,
17+
FormsModule,
1418
DashboardRoutingModule,
1519
MatCardModule,
20+
MatFormFieldModule,
21+
MatInputModule,
1622
MatButtonModule,
1723
],
1824
exports: [DashboardComponent],

‎src/app/features/functions/explorer/explorer-viewer/path-splitter/path-splitter.component.html‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<ng-container *ngIf="!editMode">
2-
<button mat-button (click)="pathClicked('')">{{ backend }}:</button>
2+
<button mat-button (click)="pathClicked('')">
3+
{{ backend ? backend + ":" : "/" }}
4+
</button>
35
<ng-container *ngFor="let part of pathParts; let last = last">
46
<button mat-button (click)="pathClicked(part.fullPath)">
57
{{ part.name }}

‎src/app/features/functions/explorer/explorer-viewer/path-splitter/path-splitter.component.ts‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ export class PathSplitterComponent implements OnInit, OnChanges {
6868
}
6969

7070
pathEditClicked() {
71-
this.editingPath = this.backend + ':' + this.path;
71+
const backendIdentifier = this.backend ? this.backend + ':' : '/';
72+
this.editingPath = backendIdentifier + this.path;
7273
this.editMode = true;
7374
this.pathInput?.focus();
7475
}
@@ -89,13 +90,6 @@ export class PathSplitterComponent implements OnInit, OnChanges {
8990
// find the first slash or colons
9091
const firstSlashIndex = newPath.indexOf('/');
9192
const firstColonIndex = newPath.indexOf(':');
92-
// debug
93-
console.log(
94-
'PathSplitterComponent: firstSlashIndex',
95-
firstSlashIndex,
96-
'firstColonIndex',
97-
firstColonIndex,
98-
);
9993
if (firstSlashIndex === -1 && firstColonIndex === -1) {
10094
// no slash or colon found, treat as a relative path
10195
this.pathChange.emit(newPath);

‎src/app/features/functions/explorer/explorer.component.ts‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,40 @@ export class ExplorerComponent implements OnInit {
4848
this.fetchLocalFsList();
4949

5050
this.route.queryParams.pipe(first()).subscribe((params) => {
51+
const fullPath = params['path'];
52+
if (fullPath) {
53+
let backend, path;
54+
// If the path starts with a slash, treat it as an absolute path to the root.
55+
if (fullPath.startsWith('/')) {
56+
backend = '';
57+
path = fullPath.substring(1);
58+
} else {
59+
// if a colon is found before the first slash, treat as a backend change
60+
const firstSlashIndex = fullPath.indexOf('/');
61+
const firstColonIndex = fullPath.indexOf(':');
62+
if (
63+
firstColonIndex !== -1 &&
64+
(firstSlashIndex === -1 || firstColonIndex < firstSlashIndex)
65+
) {
66+
backend = fullPath.substring(0, firstColonIndex);
67+
path = fullPath.substring(firstColonIndex + 1);
68+
} else {
69+
// otherwise, treat as a absolute path to the root
70+
backend = '';
71+
path = fullPath;
72+
}
73+
}
74+
this.viewsGroups[0].tabs.push({
75+
backend,
76+
path,
77+
info: this.backendService
78+
.getBackendInfo(backend)
79+
.then((result) => result.orThrow()),
80+
actions: {},
81+
});
82+
return;
83+
}
84+
5185
const backend = params['drive'];
5286
if (backend) {
5387
this.viewsGroups[0].tabs.push({

0 commit comments

Comments
 (0)