Skip to content

Commit 04530cf

Browse files
committed
Add Grid Layout to Asset Selector Dialog
1 parent 02b17e3 commit 04530cf

File tree

9 files changed

+269
-127
lines changed

9 files changed

+269
-127
lines changed

src/app/features/spaces/assets/assets.component.scss

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,7 @@
1-
@use '@angular/material' as mat;
2-
31
table {
42
width: 100%;
53
}
64

7-
.digital-asset-card {
8-
max-width: 240px;
9-
min-width: 240px;
10-
img {
11-
min-width: 240px;
12-
min-height: 240px;
13-
max-width: 240px;
14-
max-height: 240px;
15-
border-top-left-radius: inherit;
16-
border-top-right-radius: inherit;
17-
border-bottom-width: var(--mdc-outlined-card-outline-width);
18-
border-bottom-color: var(--mdc-outlined-card-outline-color, var(--mat-app-outline-variant));
19-
}
20-
.progress {
21-
min-width: 240px;
22-
min-height: 240px;
23-
max-width: 240px;
24-
max-height: 240px;
25-
align-content: center;
26-
padding-left: 60px;
27-
}
28-
29-
}
30-
315

326
//mat-header-cell {
337
// &.mat-column-actions {

src/app/features/spaces/contents/shared/asset-select/asset-select.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class AssetSelectComponent implements OnInit {
5555
openAssetSelectDialog(): void {
5656
this.dialog
5757
.open<AssetsSelectDialogComponent, AssetsSelectDialogModel, Asset[] | undefined>(AssetsSelectDialogComponent, {
58-
panelClass: 'xl',
58+
panelClass: 'full-screen',
5959
data: {
6060
spaceId: this.space().id,
6161
multiple: false,

src/app/features/spaces/contents/shared/assets-select/assets-select.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export class AssetsSelectComponent implements OnInit {
6464
openAssetSelectDialog(): void {
6565
this.dialog
6666
.open<AssetsSelectDialogComponent, AssetsSelectDialogModel, AssetFile[] | undefined>(AssetsSelectDialogComponent, {
67-
panelClass: 'xl',
67+
panelClass: 'full-screen',
6868
data: {
6969
spaceId: this.space().id,
7070
multiple: true,

src/app/shared/components/assets-select-dialog/assets-select-dialog.component.html

Lines changed: 153 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,32 @@
1-
<h2 mat-dialog-title>Assets</h2>
1+
<h2 mat-dialog-title>
2+
<span>Assets</span>
3+
<div class="header-actions">
4+
<mat-button-toggle-group
5+
hideSingleSelectionIndicator="true"
6+
(change)="settingsStore.setAssetDialogLayout($event.value)"
7+
[value]="settingsStore.assetDialogLayout()">
8+
<mat-button-toggle value="list" matTooltip="List Layout">
9+
<mat-icon>view_list</mat-icon>
10+
</mat-button-toggle>
11+
<mat-button-toggle value="grid" matTooltip="Grid Layout">
12+
<mat-icon>grid_view</mat-icon>
13+
</mat-button-toggle>
14+
</mat-button-toggle-group>
15+
@if ('ASSET_CREATE' | canUserPerform | async) {
16+
<button mat-stroked-button color="primary" (click)="fileInput.click()">
17+
<mat-icon>upload_file</mat-icon>
18+
Upload Assets
19+
</button>
20+
<input hidden type="file" multiple #fileInput (change)="onFileUpload($event)" />
21+
}
22+
</div>
23+
</h2>
24+
@if (isLoading()) {
25+
<mat-progress-bar mode="query" />
26+
}
27+
@if (isLoading()) {
28+
<mat-progress-bar mode="query" />
29+
}
230
<ll-breadcrumb>
331
<span style="padding-left: 1rem">&nbsp;</span>
432
@for (pathItem of assetPath; track pathItem.fullSlug; let isFirst = $first) {
@@ -8,81 +36,134 @@ <h2 mat-dialog-title>Assets</h2>
836
}
937
</ll-breadcrumb>
1038
<mat-dialog-content>
11-
<mat-table [dataSource]="dataSource" matSort>
12-
<!-- Checkbox Column -->
13-
<ng-container matColumnDef="select">
14-
<mat-header-cell *matHeaderCellDef> #</mat-header-cell>
15-
<mat-cell *matCellDef="let row">
16-
@if (row.kind === 'FILE') {
17-
<mat-checkbox
18-
(click)="$event.stopPropagation()"
19-
(change)="$event ? selection.toggle(row) : null"
20-
[checked]="selection.isSelected(row)">
21-
</mat-checkbox>
22-
}
23-
</mat-cell>
24-
</ng-container>
25-
<ng-container matColumnDef="icon">
26-
<mat-header-cell *matHeaderCellDef> Icon</mat-header-cell>
27-
<mat-cell *matCellDef="let element">
28-
@switch (element.kind) {
29-
@case ('FILE') {
30-
<mat-icon>{{ fileIcon(element.type) }}</mat-icon>
39+
@if (settingsStore.assetDialogLayout() === 'list') {
40+
<mat-table [dataSource]="dataSource" matSort>
41+
<!-- Checkbox Column -->
42+
<ng-container matColumnDef="select">
43+
<mat-header-cell *matHeaderCellDef> #</mat-header-cell>
44+
<mat-cell *matCellDef="let row">
45+
@if (row.kind === 'FILE') {
46+
<mat-checkbox
47+
(click)="$event.stopPropagation()"
48+
(change)="$event ? selection.toggle(row) : null"
49+
[checked]="selection.isSelected(row)">
50+
</mat-checkbox>
3151
}
32-
@case ('FOLDER') {
33-
<mat-icon>folder</mat-icon>
52+
</mat-cell>
53+
</ng-container>
54+
<ng-container matColumnDef="icon">
55+
<mat-header-cell *matHeaderCellDef> Icon</mat-header-cell>
56+
<mat-cell *matCellDef="let element">
57+
@switch (element.kind) {
58+
@case ('FILE') {
59+
<mat-icon>{{ fileIcon(element.type) }}</mat-icon>
60+
}
61+
@case ('FOLDER') {
62+
<mat-icon>folder</mat-icon>
63+
}
3464
}
35-
}
36-
</mat-cell>
37-
</ng-container>
38-
<ng-container matColumnDef="preview">
39-
<mat-header-cell *matHeaderCellDef> Preview</mat-header-cell>
40-
<mat-cell *matCellDef="let element">
41-
@if (element.kind === 'FILE' && filePreview(element.type)) {
42-
<img
43-
class="border object-contain rounded bg-stripes-gray"
44-
width="200"
45-
height="200"
46-
alt="thumbnail"
47-
loading="lazy"
48-
[loaderParams]="{ thumbnail: true }"
49-
ngSrc="/api/v1/spaces/{{ data.spaceId }}/assets/{{ element.id }}" />
50-
}
51-
</mat-cell>
52-
</ng-container>
53-
<ng-container matColumnDef="name">
54-
<mat-header-cell *matHeaderCellDef> Name</mat-header-cell>
55-
<mat-cell *matCellDef="let element">
56-
<div>
57-
<div class="break-all">{{ element.name }}{{ element.extension }}</div>
58-
@if (element.metadata; as metadata) {
59-
<code class="fw-light">
60-
@if (metadata.width && metadata.height) {
61-
W{{ metadata.width }} x H{{ metadata.height }}
62-
}
63-
</code>
65+
</mat-cell>
66+
</ng-container>
67+
<ng-container matColumnDef="preview">
68+
<mat-header-cell *matHeaderCellDef> Preview</mat-header-cell>
69+
<mat-cell *matCellDef="let element">
70+
@if (element.kind === 'FILE' && filePreview(element.type)) {
71+
<img
72+
class="border object-contain rounded bg-stripes-gray"
73+
width="200"
74+
height="200"
75+
alt="thumbnail"
76+
loading="lazy"
77+
[loaderParams]="{ thumbnail: true }"
78+
ngSrc="/api/v1/spaces/{{ data.spaceId }}/assets/{{ element.id }}" />
6479
}
65-
</div>
66-
</mat-cell>
67-
</ng-container>
68-
<ng-container matColumnDef="size">
69-
<mat-header-cell *matHeaderCellDef> Size</mat-header-cell>
70-
<mat-cell *matCellDef="let element"> {{ element.size | digitalStore }}</mat-cell>
71-
</ng-container>
72-
<ng-container matColumnDef="type">
73-
<mat-header-cell *matHeaderCellDef> Type</mat-header-cell>
74-
<mat-cell *matCellDef="let element"> {{ element.type }}</mat-cell>
75-
</ng-container>
76-
<ng-container matColumnDef="updatedAt">
77-
<mat-header-cell *matHeaderCellDef> Updated At</mat-header-cell>
78-
<mat-cell *matCellDef="let element" [matTooltip]="element.updatedAt?.toDate() | date: 'medium'">
79-
{{ element.updatedAt?.toDate() | date: 'mediumDate' }}
80-
</mat-cell>
81-
</ng-container>
80+
</mat-cell>
81+
</ng-container>
82+
<ng-container matColumnDef="name">
83+
<mat-header-cell *matHeaderCellDef> Name</mat-header-cell>
84+
<mat-cell *matCellDef="let element">
85+
<div>
86+
<div class="break-all">{{ element.name }}{{ element.extension }}</div>
87+
@if (element.metadata; as metadata) {
88+
<code class="fw-light">
89+
@if (metadata.width && metadata.height) {
90+
W{{ metadata.width }} x H{{ metadata.height }}
91+
}
92+
</code>
93+
}
94+
</div>
95+
</mat-cell>
96+
</ng-container>
97+
<ng-container matColumnDef="size">
98+
<mat-header-cell *matHeaderCellDef> Size</mat-header-cell>
99+
<mat-cell *matCellDef="let element"> {{ element.size | digitalStore }}</mat-cell>
100+
</ng-container>
101+
<ng-container matColumnDef="type">
102+
<mat-header-cell *matHeaderCellDef> Type</mat-header-cell>
103+
<mat-cell *matCellDef="let element"> {{ element.type }}</mat-cell>
104+
</ng-container>
105+
<ng-container matColumnDef="updatedAt">
106+
<mat-header-cell *matHeaderCellDef> Updated At</mat-header-cell>
107+
<mat-cell *matCellDef="let element" [matTooltip]="element.updatedAt?.toDate() | date: 'medium'">
108+
{{ element.updatedAt?.toDate() | date: 'mediumDate' }}
109+
</mat-cell>
110+
</ng-container>
82111

83-
<mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
84-
<mat-row *matRowDef="let row; columns: displayedColumns" (click)="onRowSelect(row)"></mat-row>
85-
</mat-table>
112+
<mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
113+
<mat-row *matRowDef="let row; columns: displayedColumns" (click)="onAssetSelect(row)" class="cursor-pointer"></mat-row>
114+
</mat-table>
115+
} @else {
116+
<div class="flex flex-wrap gap-2 justify-start">
117+
@for (item of dataSource.connect() | async; track item.id) {
118+
<mat-card class="digital-asset-card cursor-pointer" appearance="outlined" (click)="onAssetSelect(item)">
119+
@if (item.inProgress) {
120+
<div class="progress">
121+
<mat-progress-spinner mode="indeterminate" />
122+
</div>
123+
} @else if (item.kind === 'FILE' && filePreview(item.type)) {
124+
<img
125+
class="object-contain bg-stripes-gray"
126+
width="600"
127+
height="600"
128+
loading="lazy"
129+
alt="thumbnail"
130+
[loaderParams]="{ thumbnail: true }"
131+
ngSrc="/api/v1/spaces/{{ data.spaceId }}/assets/{{ item.id }}" />
132+
} @else if (item.kind === 'FILE') {
133+
<img mat-card-image ngSrc="assets/icons/{{ fileIcon(item.type) }}.svg" alt="File" width="240" height="240" />
134+
} @else {
135+
<img mat-card-image ngSrc="assets/icons/folder.svg" alt="Folder" width="240" height="240" />
136+
}
137+
<mat-card-header>
138+
<mat-card-subtitle class="break-all">{{ item.name }}{{ item.extension }}</mat-card-subtitle>
139+
</mat-card-header>
140+
<mat-card-content>
141+
@if (item.kind === 'FILE') {
142+
@if (item.metadata; as metadata) {
143+
@if (metadata.width && metadata.height) {
144+
<code class="fw-light"> W{{ metadata.width }} x H{{ metadata.height }} </code>
145+
}
146+
}
147+
@if (item.size; as size) {
148+
<p>{{ size | digitalStore }}</p>
149+
}
150+
}
151+
<p [matTooltip]="item.updatedAt?.toDate() | date: 'medium'">
152+
{{ item.updatedAt?.toDate() | date: 'mediumDate' }}
153+
</p>
154+
</mat-card-content>
155+
<span class="spacer"></span>
156+
<mat-card-actions>
157+
<mat-checkbox
158+
(click)="$event.stopPropagation()"
159+
(change)="$event ? selection.toggle(item) : null"
160+
[checked]="selection.isSelected(item)">
161+
</mat-checkbox>
162+
</mat-card-actions>
163+
</mat-card>
164+
}
165+
</div>
166+
}
86167
</mat-dialog-content>
87168
<mat-dialog-actions align="end">
88169
<mat-paginator></mat-paginator>

src/app/shared/components/assets-select-dialog/assets-select-dialog.component.scss

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,25 @@ table {
22
width: 100%;
33
}
44

5+
.header-actions {
6+
float: right;
7+
margin-top: 6px;
8+
.mat-mdc-button-base {
9+
margin-left: 8px;
10+
margin-right: 8px;
11+
margin-top: 2px;
12+
}
13+
}
14+
515
mat-dialog-content {
616
@apply pt-0 #{!important};
717
}
818

919
mat-cell {
10-
cursor: pointer;
1120
&.mat-column-preview {
1221
img {
22+
min-width: 115px;
23+
min-height: 115px;
1324
max-width: 115px;
1425
max-height: 115px;
1526
}

0 commit comments

Comments
 (0)