fontastic 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -19
- package/app/enums/StorageType.js +2 -0
- package/app/enums/StorageType.ts +2 -0
- package/app/package.json +1 -1
- package/package.json +2 -2
- package/src/app/core/services/database/database.service.ts +51 -4
- package/src/app/shared/components/datagrid/datagrid.component.html +25 -7
- package/src/app/shared/components/datagrid/datagrid.component.ts +10 -0
package/README.md
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
# Fontastic
|
|
2
2
|
|
|
3
|
-
](https://angular.dev)
|
|
4
|
+
[](https://electronjs.org)
|
|
5
|
+
[](https://www.typescriptlang.org)
|
|
6
|
+
[](LICENSE.md)
|
|
7
|
+
[](http://makeapullrequest.com)
|
|
6
8
|
|
|
7
9
|
[![Linux Build][linux-build-badge]][linux-build]
|
|
8
10
|
[![MacOS Build][macos-build-badge]][macos-build]
|
|
9
11
|
[![Windows Build][windows-build-badge]][windows-build]
|
|
10
12
|
|
|
11
|
-
[![
|
|
12
|
-
[![
|
|
13
|
-
[![Tweet][twitter-badge]][twitter]
|
|
13
|
+
[](https://github.com/tomshaw/fontastic/stargazers)
|
|
14
|
+
[](https://github.com/tomshaw/fontastic/watchers)
|
|
14
15
|
|
|
15
|
-
Fontastic is
|
|
16
|
+
Fontastic is an Electron-based font management and cataloging application built for organizing, browsing, and inspecting font libraries.
|
|
16
17
|
|
|
17
18
|
## Features
|
|
18
19
|
|
|
@@ -83,12 +84,6 @@ Fontastic is open-sourced software licensed under the [MIT license](https://open
|
|
|
83
84
|
|
|
84
85
|
[repo]: https://github.com/tomshaw/fontastic
|
|
85
86
|
|
|
86
|
-
[maintained-badge]: https://img.shields.io/badge/maintained-yes-brightgreen
|
|
87
|
-
[license-badge]: https://img.shields.io/badge/license-MIT-blue.svg
|
|
88
|
-
[license]: https://github.com/tomshaw/fontastic/blob/main/LICENSE.md
|
|
89
|
-
[prs-badge]: https://img.shields.io/badge/PRs-welcome-red.svg
|
|
90
|
-
[prs]: http://makeapullrequest.com
|
|
91
|
-
|
|
92
87
|
[linux-build-badge]: https://github.com/tomshaw/fontastic/workflows/Linux%20Build/badge.svg
|
|
93
88
|
[linux-build]: https://github.com/tomshaw/fontastic/actions?query=workflow%3A%22Linux+Build%22
|
|
94
89
|
[macos-build-badge]: https://github.com/tomshaw/fontastic/workflows/MacOS%20Build/badge.svg
|
|
@@ -96,9 +91,3 @@ Fontastic is open-sourced software licensed under the [MIT license](https://open
|
|
|
96
91
|
[windows-build-badge]: https://github.com/tomshaw/fontastic/workflows/Windows%20Build/badge.svg
|
|
97
92
|
[windows-build]: https://github.com/tomshaw/fontastic/actions?query=workflow%3A%22Windows+Build%22
|
|
98
93
|
|
|
99
|
-
[github-watch-badge]: https://img.shields.io/github/watchers/tomshaw/fontastic.svg?style=social
|
|
100
|
-
[github-watch]: https://github.com/tomshaw/fontastic/watchers
|
|
101
|
-
[github-star-badge]: https://img.shields.io/github/stars/tomshaw/fontastic.svg?style=social
|
|
102
|
-
[github-star]: https://github.com/tomshaw/fontastic/stargazers
|
|
103
|
-
[twitter]: https://twitter.com/intent/tweet?text=Check%20out%20fontastic!%20https://github.com/tomshaw/fontastic%20%F0%9F%91%8D
|
|
104
|
-
[twitter-badge]: https://img.shields.io/twitter/url/https/github.com/tomshaw/fontastic.svg?style=social
|
package/app/enums/StorageType.js
CHANGED
|
@@ -17,5 +17,7 @@ var StorageType;
|
|
|
17
17
|
StorageType["LayoutTheme"] = "layout.theme";
|
|
18
18
|
StorageType["AiKeys"] = "ai.keys";
|
|
19
19
|
StorageType["NavigationExpanded"] = "navigation.expanded";
|
|
20
|
+
StorageType["SortColumn"] = "datagrid.sort.column";
|
|
21
|
+
StorageType["SortDirection"] = "datagrid.sort.direction";
|
|
20
22
|
})(StorageType || (exports.StorageType = StorageType = {}));
|
|
21
23
|
//# sourceMappingURL=StorageType.js.map
|
package/app/enums/StorageType.ts
CHANGED
package/app/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fontastic",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Fontastic is an Electron-based font management and cataloging application built for organizing, browsing, and inspecting font libraries.",
|
|
5
5
|
"homepage": "https://github.com/tomshaw/fontastic",
|
|
6
6
|
"private": false,
|
|
7
7
|
"author": {
|
|
@@ -137,24 +137,26 @@ export class DatabaseService {
|
|
|
137
137
|
private fetchCurrentPage(extraOptions: any = {}) {
|
|
138
138
|
const skip = (this.currentPage() - 1) * this.pageSize();
|
|
139
139
|
const take = this.pageSize();
|
|
140
|
+
const sortOrder = this.getSortOrder();
|
|
140
141
|
|
|
141
142
|
const smartCollectionId = this.activeSmartCollectionId();
|
|
142
143
|
if (smartCollectionId) {
|
|
143
|
-
this.smartCollectionEvaluate(smartCollectionId, { skip, take });
|
|
144
|
+
this.smartCollectionEvaluate(smartCollectionId, { skip, take, ...(sortOrder ? { order: sortOrder } : {}) });
|
|
144
145
|
return;
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
const searchWhere = this.activeSearchWhere();
|
|
148
149
|
if (searchWhere) {
|
|
149
150
|
const searchOrder = this.activeSearchOrder();
|
|
150
|
-
|
|
151
|
+
const order = sortOrder ?? searchOrder;
|
|
152
|
+
this.storeSearch({ where: searchWhere, skip, take, ...(order ? { order } : {}) });
|
|
151
153
|
return;
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
const collectionId = this.collectionId();
|
|
155
157
|
const filter = this.activeFilter();
|
|
156
158
|
|
|
157
|
-
const options: any = { skip, take, ...extraOptions };
|
|
159
|
+
const options: any = { skip, take, ...extraOptions, ...(sortOrder ? { order: sortOrder } : {}) };
|
|
158
160
|
|
|
159
161
|
if (collectionId) {
|
|
160
162
|
options.collectionId = collectionId;
|
|
@@ -172,17 +174,24 @@ export class DatabaseService {
|
|
|
172
174
|
|
|
173
175
|
constructor() {
|
|
174
176
|
this.electron.ready.then(async () => {
|
|
175
|
-
const [collections, smartCollections, savedCollectionId, savedStoreId] = await Promise.all([
|
|
177
|
+
const [collections, smartCollections, savedCollectionId, savedStoreId, savedSortColumn, savedSortDirection] = await Promise.all([
|
|
176
178
|
this.message.collectionFetch({}),
|
|
177
179
|
this.message.smartCollectionFind(),
|
|
178
180
|
this.message.get(StorageType.CollectionId, null),
|
|
179
181
|
this.message.get(StorageType.StoreId, null),
|
|
182
|
+
this.message.get(StorageType.SortColumn, null),
|
|
183
|
+
this.message.get(StorageType.SortDirection, null),
|
|
180
184
|
]);
|
|
181
185
|
|
|
182
186
|
this.collections.set(collections);
|
|
183
187
|
this.smartCollections.set(smartCollections);
|
|
184
188
|
console.log('System Boot:', collections);
|
|
185
189
|
|
|
190
|
+
if (savedSortColumn) {
|
|
191
|
+
this.sortColumn.set(savedSortColumn);
|
|
192
|
+
this.sortDirection.set(savedSortDirection === 'DESC' ? 'DESC' : 'ASC');
|
|
193
|
+
}
|
|
194
|
+
|
|
186
195
|
if (savedCollectionId) {
|
|
187
196
|
this.collectionId.set(savedCollectionId);
|
|
188
197
|
}
|
|
@@ -398,6 +407,44 @@ export class DatabaseService {
|
|
|
398
407
|
|
|
399
408
|
readonly activeSearchOrder = signal<{ column: string; direction: string } | null>(null);
|
|
400
409
|
|
|
410
|
+
// Datagrid sort (persisted)
|
|
411
|
+
readonly sortColumn = signal<string | null>(null);
|
|
412
|
+
readonly sortDirection = signal<'ASC' | 'DESC'>('ASC');
|
|
413
|
+
|
|
414
|
+
toggleSort(column: string) {
|
|
415
|
+
const current = this.sortColumn();
|
|
416
|
+
if (current === column) {
|
|
417
|
+
if (this.sortDirection() === 'ASC') {
|
|
418
|
+
this.sortDirection.set('DESC');
|
|
419
|
+
} else {
|
|
420
|
+
// Clear sort
|
|
421
|
+
this.sortColumn.set(null);
|
|
422
|
+
this.sortDirection.set('ASC');
|
|
423
|
+
}
|
|
424
|
+
} else {
|
|
425
|
+
this.sortColumn.set(column);
|
|
426
|
+
this.sortDirection.set('ASC');
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Persist
|
|
430
|
+
const col = this.sortColumn();
|
|
431
|
+
if (col) {
|
|
432
|
+
this.message.set(StorageType.SortColumn, col);
|
|
433
|
+
this.message.set(StorageType.SortDirection, this.sortDirection());
|
|
434
|
+
} else {
|
|
435
|
+
this.message.set(StorageType.SortColumn, null);
|
|
436
|
+
this.message.set(StorageType.SortDirection, null);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
this.currentPage.set(1);
|
|
440
|
+
this.fetchCurrentPage();
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
private getSortOrder(): { column: string; direction: string } | null {
|
|
444
|
+
const col = this.sortColumn();
|
|
445
|
+
return col ? { column: col, direction: this.sortDirection() } : null;
|
|
446
|
+
}
|
|
447
|
+
|
|
401
448
|
selectSearch(where: { key: string; value: any }[], order?: { column: string; direction: string }) {
|
|
402
449
|
this.parentId.set(null);
|
|
403
450
|
this.collectionId.set(null);
|
|
@@ -8,13 +8,31 @@
|
|
|
8
8
|
>
|
|
9
9
|
<tr class="text-left text-[11px] uppercase tracking-wide" [style.color]="'var(--text-muted)'">
|
|
10
10
|
<th class="w-10 px-2 py-2 text-center font-medium"></th>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
@for (col of sortableColumns; track col.field) {
|
|
12
|
+
<th
|
|
13
|
+
class="px-4 py-2 font-medium cursor-pointer select-none transition-colors hover:brightness-125"
|
|
14
|
+
[class.max-w-48]="col.field === 'designer'"
|
|
15
|
+
(click)="db.toggleSort(col.field)"
|
|
16
|
+
>
|
|
17
|
+
<div class="flex items-center justify-between gap-1">
|
|
18
|
+
<span>{{ col.label }}</span>
|
|
19
|
+
@if (db.sortColumn() === col.field) {
|
|
20
|
+
<span
|
|
21
|
+
class="material-symbols-outlined"
|
|
22
|
+
style="
|
|
23
|
+
font-size: 14px;
|
|
24
|
+
font-variation-settings:
|
|
25
|
+
'opsz' 20,
|
|
26
|
+
'wght' 300;
|
|
27
|
+
"
|
|
28
|
+
[style.color]="'var(--accent)'"
|
|
29
|
+
>
|
|
30
|
+
{{ db.sortDirection() === 'ASC' ? 'arrow_upward' : 'arrow_downward' }}
|
|
31
|
+
</span>
|
|
32
|
+
}
|
|
33
|
+
</div>
|
|
34
|
+
</th>
|
|
35
|
+
}
|
|
18
36
|
<th class="w-10 px-2 py-2 text-center font-medium"></th>
|
|
19
37
|
<th class="w-10 px-2 py-2 text-center font-medium"></th>
|
|
20
38
|
<th class="w-10 px-2 py-2 text-center font-medium"></th>
|
|
@@ -11,6 +11,16 @@ export class DatagridComponent {
|
|
|
11
11
|
private messageService = inject(MessageService);
|
|
12
12
|
private el = inject(ElementRef);
|
|
13
13
|
|
|
14
|
+
readonly sortableColumns = [
|
|
15
|
+
{ field: 'full_name', label: 'Name' },
|
|
16
|
+
{ field: 'font_family', label: 'Family' },
|
|
17
|
+
{ field: 'font_subfamily', label: 'Style' },
|
|
18
|
+
{ field: 'file_type', label: 'Type' },
|
|
19
|
+
{ field: 'file_size', label: 'Size' },
|
|
20
|
+
{ field: 'version', label: 'Version' },
|
|
21
|
+
{ field: 'designer', label: 'Designer' },
|
|
22
|
+
];
|
|
23
|
+
|
|
14
24
|
constructor() {
|
|
15
25
|
effect(() => {
|
|
16
26
|
this.db.currentPage();
|