fontastic 0.1.3 → 0.2.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.
Files changed (452) hide show
  1. package/.editorconfig +16 -16
  2. package/.github/FUNDING.yml +3 -12
  3. package/.github/ISSUE_TEMPLATE/bug_report.yml +41 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.yml +29 -0
  5. package/.github/dependabot.yml +6 -6
  6. package/.github/pull_request_template.md +21 -21
  7. package/.github/workflows/claude-code-review.yml +45 -0
  8. package/.github/workflows/claude.yml +46 -0
  9. package/.github/workflows/macos.yml +77 -58
  10. package/.github/workflows/release.yml +165 -0
  11. package/.github/workflows/ubuntu.yml +87 -70
  12. package/.github/workflows/windows.yml +81 -64
  13. package/.husky/pre-commit +1 -0
  14. package/.lintstagedrc.json +6 -0
  15. package/.node-version +1 -1
  16. package/.postcssrc.json +5 -0
  17. package/.prettierignore +8 -0
  18. package/.prettierrc +18 -0
  19. package/.vscode/launch.json +42 -45
  20. package/.vscode/tasks.json +48 -48
  21. package/CODE_OF_CONDUCT.md +128 -45
  22. package/HOW_TO.md +39 -0
  23. package/LICENSE.md +7 -0
  24. package/README.md +103 -111
  25. package/angular.json +166 -194
  26. package/app/Application.js +39 -39
  27. package/app/Application.ts +38 -38
  28. package/app/config/alert.ts +31 -31
  29. package/app/config/database.js +194 -202
  30. package/app/config/database.ts +194 -202
  31. package/app/config/index.js +19 -19
  32. package/app/config/index.ts +2 -2
  33. package/app/config/mimes.js +48 -48
  34. package/app/config/mimes.ts +53 -53
  35. package/app/config/system.js +578 -496
  36. package/app/config/system.ts +580 -498
  37. package/app/config/themes.ts +38 -38
  38. package/app/core/AppLogger.js +30 -30
  39. package/app/core/AppLogger.ts +37 -37
  40. package/app/core/ConfigManager.js +129 -113
  41. package/app/core/ConfigManager.ts +150 -137
  42. package/app/core/ConnectionManager.js +93 -82
  43. package/app/core/ConnectionManager.ts +107 -95
  44. package/app/core/FontCatalog.js +32 -50
  45. package/app/core/FontCatalog.ts +20 -42
  46. package/app/core/FontFinder.js +72 -85
  47. package/app/core/FontFinder.ts +75 -96
  48. package/app/core/FontManager.js +128 -164
  49. package/app/core/FontManager.ts +136 -172
  50. package/app/core/FontObject.js +53 -53
  51. package/app/core/FontObject.ts +62 -62
  52. package/app/core/MessageHandler.js +270 -271
  53. package/app/core/MessageHandler.ts +330 -337
  54. package/app/core/SystemManager.js +132 -139
  55. package/app/core/SystemManager.ts +160 -171
  56. package/app/core/menu/Example.ts +279 -279
  57. package/app/core/menu/MenuBuilder.js +43 -44
  58. package/app/core/menu/MenuBuilder.ts +51 -53
  59. package/app/core/menu/templates/DarwinTemplate.js +124 -126
  60. package/app/core/menu/templates/DarwinTemplate.ts +144 -142
  61. package/app/core/menu/templates/SystemTemplate.js +121 -123
  62. package/app/core/menu/templates/SystemTemplate.ts +136 -139
  63. package/app/database/entity/Collection.schema.js +98 -98
  64. package/app/database/entity/Collection.schema.ts +68 -68
  65. package/app/database/entity/Logger.schema.js +49 -49
  66. package/app/database/entity/Logger.schema.ts +26 -26
  67. package/app/database/entity/Store.schema.js +159 -164
  68. package/app/database/entity/Store.schema.ts +110 -116
  69. package/app/database/entity/index.js +19 -19
  70. package/app/database/entity/index.ts +2 -2
  71. package/app/database/repository/Collection.repository.js +277 -180
  72. package/app/database/repository/Collection.repository.ts +291 -190
  73. package/app/database/repository/Logger.repository.js +24 -24
  74. package/app/database/repository/Logger.repository.ts +10 -10
  75. package/app/database/repository/Store.repository.js +324 -327
  76. package/app/database/repository/Store.repository.ts +349 -358
  77. package/app/database/repository/User.repository.js +11 -11
  78. package/app/database/repository/User.repository.ts +8 -8
  79. package/app/database/repository/index.js +19 -19
  80. package/app/database/repository/index.ts +2 -2
  81. package/app/enums/ChannelType.js +62 -61
  82. package/app/enums/ChannelType.ts +67 -65
  83. package/app/enums/StorageType.js +19 -18
  84. package/app/enums/{storageType.ts → StorageType.ts} +15 -14
  85. package/app/enums/index.js +18 -18
  86. package/app/enums/index.ts +2 -2
  87. package/app/helpers/command.js +27 -27
  88. package/app/helpers/command.ts +19 -19
  89. package/app/helpers/random.js +15 -15
  90. package/app/helpers/random.ts +12 -12
  91. package/app/main.js +97 -81
  92. package/app/main.ts +114 -94
  93. package/app/package-lock.json +2240 -2649
  94. package/app/package.json +23 -35
  95. package/app/types/AppAlert.js +2 -2
  96. package/app/types/AppAlert.ts +8 -8
  97. package/app/types/AuthUser.js +6 -6
  98. package/app/types/AuthUser.ts +5 -5
  99. package/app/types/Breadcrumb.js +2 -2
  100. package/app/types/Breadcrumb.ts +4 -4
  101. package/app/types/FontMetrics.ts +7 -0
  102. package/app/types/ImportOptions.js +6 -6
  103. package/app/types/ImportOptions.ts +3 -3
  104. package/app/types/QueryOptions.js +2 -2
  105. package/app/types/QueryOptions.ts +12 -12
  106. package/app/types/SystemConfig.js +2 -2
  107. package/app/types/SystemConfig.ts +127 -132
  108. package/app/types/SystemStats.js +2 -2
  109. package/app/types/SystemStats.ts +6 -7
  110. package/app/types/SystemTheme.js +2 -2
  111. package/app/types/SystemTheme.ts +5 -5
  112. package/app/types/index.js +24 -24
  113. package/app/types/index.ts +9 -8
  114. package/commitlint.config.mjs +3 -0
  115. package/e2e/main.spec.ts +57 -59
  116. package/e2e/playwright.config.ts +20 -19
  117. package/e2e/tsconfig.e2e.json +13 -13
  118. package/electron-builder.json +34 -71
  119. package/eslint.config.mjs +111 -0
  120. package/package.json +122 -121
  121. package/src/app/app.component.html +1 -1
  122. package/src/app/app.component.spec.ts +21 -0
  123. package/src/app/app.component.ts +40 -37
  124. package/src/app/core/core.module.ts +8 -11
  125. package/src/app/core/services/database/database.service.ts +410 -286
  126. package/src/app/core/services/electron/electron.service.spec.ts +12 -12
  127. package/src/app/core/services/electron/electron.service.ts +62 -62
  128. package/src/app/core/services/index.ts +5 -14
  129. package/src/app/core/services/message/message.service.ts +291 -289
  130. package/src/app/core/services/news/news.service.ts +52 -94
  131. package/src/app/core/services/presentation/presentation.service.ts +253 -341
  132. package/src/app/home/home.component.html +7 -0
  133. package/src/app/home/home.component.spec.ts +31 -0
  134. package/src/app/home/home.component.ts +15 -0
  135. package/src/app/layout/aside/aside.component.html +35 -9
  136. package/src/app/layout/aside/aside.component.ts +60 -26
  137. package/src/app/layout/footer/footer.component.html +5 -11
  138. package/src/app/layout/footer/footer.component.ts +13 -32
  139. package/src/app/layout/header/header.component.html +118 -35
  140. package/src/app/layout/header/header.component.ts +52 -229
  141. package/src/app/layout/layout.component.html +32 -14
  142. package/src/app/layout/layout.component.ts +19 -23
  143. package/src/app/layout/main/main.component.html +46 -0
  144. package/src/app/layout/main/main.component.ts +20 -0
  145. package/src/app/layout/navigation/library/library.component.ts +51 -0
  146. package/src/app/layout/navigation/navigation.component.html +126 -142
  147. package/src/app/layout/navigation/navigation.component.ts +372 -302
  148. package/src/app/layout/navigation/stats/stats.component.ts +56 -0
  149. package/src/app/settings/ai-keys/ai-keys.component.html +56 -0
  150. package/src/app/settings/ai-keys/ai-keys.component.ts +44 -0
  151. package/src/app/settings/danger-zone/danger-zone.component.html +22 -0
  152. package/src/app/settings/danger-zone/danger-zone.component.ts +37 -0
  153. package/src/app/settings/logs/logs.component.html +41 -0
  154. package/src/app/settings/logs/logs.component.ts +43 -0
  155. package/src/app/settings/news-api/news-api.component.html +40 -0
  156. package/src/app/settings/news-api/news-api.component.ts +57 -0
  157. package/src/app/settings/pages/general/general.component.html +7 -0
  158. package/src/app/settings/pages/general/general.component.ts +20 -0
  159. package/src/app/settings/pages/logs/logs.component.html +1 -0
  160. package/src/app/settings/pages/logs/logs.component.ts +10 -0
  161. package/src/app/settings/pages/system/system.component.html +1 -0
  162. package/src/app/settings/pages/system/system.component.ts +10 -0
  163. package/src/app/settings/quick-actions/quick-actions.component.html +49 -0
  164. package/src/app/settings/quick-actions/quick-actions.component.ts +40 -0
  165. package/src/app/settings/settings.component.html +47 -0
  166. package/src/app/settings/settings.component.ts +10 -0
  167. package/src/app/settings/system-info/system-info.component.html +21 -0
  168. package/src/app/settings/system-info/system-info.component.ts +42 -0
  169. package/src/app/settings/theme/theme.component.html +15 -0
  170. package/src/app/settings/theme/theme.component.ts +22 -0
  171. package/src/app/shared/components/collapsible-panel/collapsible-panel.component.ts +43 -0
  172. package/src/app/shared/components/context-menu/context-menu.component.ts +67 -0
  173. package/src/app/shared/components/datagrid/datagrid.component.html +96 -0
  174. package/src/app/shared/components/datagrid/datagrid.component.ts +49 -0
  175. package/src/app/shared/components/index.ts +11 -16
  176. package/src/app/shared/components/inspector/inspector.component.html +140 -0
  177. package/src/app/shared/components/inspector/inspector.component.ts +41 -0
  178. package/src/app/shared/components/page-not-found/page-not-found.component.html +1 -3
  179. package/src/app/shared/components/page-not-found/page-not-found.component.spec.ts +22 -0
  180. package/src/app/shared/components/page-not-found/page-not-found.component.ts +14 -12
  181. package/src/app/shared/components/panel/panel.component.html +5 -0
  182. package/src/app/shared/components/panel/panel.component.ts +8 -0
  183. package/src/app/shared/components/preview/preview.component.html +36 -0
  184. package/src/app/shared/components/preview/preview.component.ts +68 -0
  185. package/src/app/shared/components/prompt-dialog/prompt-dialog.component.html +36 -0
  186. package/src/app/shared/components/prompt-dialog/prompt-dialog.component.ts +39 -0
  187. package/src/app/shared/components/search/search.component.html +329 -54
  188. package/src/app/shared/components/search/search.component.ts +221 -77
  189. package/src/app/shared/components/spinner/spinner.component.ts +10 -26
  190. package/src/app/shared/components/toolbar/toolbar.component.html +207 -0
  191. package/src/app/shared/components/toolbar/toolbar.component.ts +99 -0
  192. package/src/app/shared/components/waterfall/waterfall.component.html +119 -0
  193. package/src/app/shared/components/waterfall/waterfall.component.ts +119 -0
  194. package/src/app/shared/directives/autofocus/autofocus.directive.ts +14 -0
  195. package/src/app/shared/directives/index.ts +2 -2
  196. package/src/app/shared/directives/webview/webview.directive.spec.ts +8 -0
  197. package/src/app/shared/directives/webview/webview.directive.ts +9 -8
  198. package/src/app/shared/shared.module.ts +13 -92
  199. package/src/assets/background.jpg +0 -0
  200. package/src/assets/fonts/md/MaterialIcons-Regular.woff2 +0 -0
  201. package/src/assets/fonts/md/MaterialSymbolsOutlined.woff2 +0 -0
  202. package/src/assets/i18n/en.json +12 -12
  203. package/src/assets/icons/electron.bmp +0 -0
  204. package/src/assets/icons/favicon.256x256.png +0 -0
  205. package/src/assets/icons/favicon.512x512.png +0 -0
  206. package/src/assets/icons/favicon.icns +0 -0
  207. package/src/assets/icons/favicon.ico +0 -0
  208. package/src/assets/icons/favicon.png +0 -0
  209. package/src/environments/environment.dev.ts +4 -4
  210. package/src/environments/environment.prod.ts +4 -4
  211. package/src/environments/environment.ts +4 -4
  212. package/src/favicon.ico +0 -0
  213. package/src/index.html +19 -55
  214. package/src/main.ts +65 -15
  215. package/src/styles/base/reset.css +41 -0
  216. package/src/styles/base/variables.css +356 -0
  217. package/src/styles/components/buttons.css +108 -0
  218. package/src/styles/components/cards.css +60 -0
  219. package/src/styles/components/forms.css +70 -0
  220. package/src/styles/components/navigation.css +24 -0
  221. package/src/styles/components/scrollbox.css +50 -0
  222. package/src/styles/components/spinner.css +7 -0
  223. package/src/styles/components/splash.css +47 -0
  224. package/src/styles/components/toolbar.css +92 -0
  225. package/src/styles/fonts/md.css +39 -0
  226. package/src/styles/themes/dashboard.scss +293 -294
  227. package/src/styles/themes/euphoria.scss +284 -283
  228. package/src/styles/themes/mellow.scss +281 -280
  229. package/src/styles/themes/midnight.scss +284 -283
  230. package/src/styles/themes/passion.scss +281 -280
  231. package/src/styles/themes/swiss.scss +284 -283
  232. package/src/styles.css +17 -0
  233. package/src/tsconfig.app.json +11 -20
  234. package/src/tsconfig.spec.json +10 -23
  235. package/src/typings.d.ts +9 -9
  236. package/src/vitest.d.ts +1 -0
  237. package/tsconfig.json +38 -42
  238. package/tsconfig.serve.json +27 -27
  239. package/.eslintrc.json +0 -54
  240. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -29
  241. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  242. package/.github/stale.yml +0 -17
  243. package/CONTRIBUTING.md +0 -72
  244. package/LICENSE +0 -21
  245. package/angular.webpack.js +0 -32
  246. package/app/core/FontInstaller.js +0 -67
  247. package/app/core/FontInstaller.ts +0 -63
  248. package/docs/logo.png +0 -0
  249. package/docs/screenshots/readme.md +0 -7
  250. package/docs/screenshots/screen-grab1.png +0 -0
  251. package/docs/screenshots/screen-grab2.png +0 -0
  252. package/docs/screenshots/screen-grab3.png +0 -0
  253. package/src/app/app-routing.module.ts +0 -15
  254. package/src/app/app.component.scss +0 -0
  255. package/src/app/app.component.spec.ts.dist +0 -33
  256. package/src/app/app.module.ts +0 -63
  257. package/src/app/core/model/AuthUserModel.ts +0 -7
  258. package/src/app/core/model/CustomThemeModel.ts +0 -7
  259. package/src/app/core/model/DbConnectionModel.ts +0 -16
  260. package/src/app/core/model/ImportOptionsModel.ts +0 -5
  261. package/src/app/core/model/LatestNewsModel.ts +0 -7
  262. package/src/app/core/model/SearchFormModel.ts +0 -10
  263. package/src/app/core/model/index.ts +0 -6
  264. package/src/app/core/services/alert/alert.service.spec.ts +0 -22
  265. package/src/app/core/services/alert/alert.service.ts +0 -71
  266. package/src/app/core/services/auth/auth.service.ts +0 -30
  267. package/src/app/core/services/boot/boot.service.ts +0 -33
  268. package/src/app/core/services/breadcrumb/breadcrumb.service.spec.ts +0 -22
  269. package/src/app/core/services/breadcrumb/breadcrumb.service.ts +0 -30
  270. package/src/app/core/services/config/config.service.ts +0 -63
  271. package/src/app/core/services/font/font.service.ts +0 -79
  272. package/src/app/core/services/gravatar/gravatar.service.spec.ts +0 -16
  273. package/src/app/core/services/gravatar/gravatar.service.ts +0 -18
  274. package/src/app/core/services/modal/modal.service.spec.ts +0 -16
  275. package/src/app/core/services/modal/modal.service.ts +0 -34
  276. package/src/app/core/services/utils/utils.service.spec.ts +0 -12
  277. package/src/app/core/services/utils/utils.service.ts +0 -144
  278. package/src/app/layout/aside/aside.component.scss +0 -1
  279. package/src/app/layout/footer/footer.component.scss +0 -27
  280. package/src/app/layout/header/header.component.scss +0 -60
  281. package/src/app/layout/layout.component.scss +0 -119
  282. package/src/app/layout/layout.module.ts +0 -32
  283. package/src/app/layout/layout.service.ts +0 -13
  284. package/src/app/layout/navigation/navigation.component.scss +0 -0
  285. package/src/app/pages/main/grid/grid.component.html +0 -160
  286. package/src/app/pages/main/grid/grid.component.scss +0 -3
  287. package/src/app/pages/main/grid/grid.component.ts +0 -98
  288. package/src/app/pages/main/inspect/inspect.component.html +0 -7
  289. package/src/app/pages/main/inspect/inspect.component.scss +0 -3
  290. package/src/app/pages/main/inspect/inspect.component.ts +0 -66
  291. package/src/app/pages/main/main-routing.module.ts +0 -30
  292. package/src/app/pages/main/main.component.html +0 -6
  293. package/src/app/pages/main/main.component.scss +0 -191
  294. package/src/app/pages/main/main.component.ts +0 -35
  295. package/src/app/pages/main/main.module.ts +0 -28
  296. package/src/app/pages/main/preview/preview.component.html +0 -46
  297. package/src/app/pages/main/preview/preview.component.scss +0 -0
  298. package/src/app/pages/main/preview/preview.component.ts +0 -239
  299. package/src/app/pages/main/toolbar/toolbar.component.html +0 -78
  300. package/src/app/pages/main/toolbar/toolbar.component.scss +0 -3
  301. package/src/app/pages/main/toolbar/toolbar.component.ts +0 -132
  302. package/src/app/shared/components/alert/alert.component.html +0 -9
  303. package/src/app/shared/components/alert/alert.component.scss +0 -0
  304. package/src/app/shared/components/alert/alert.component.ts +0 -37
  305. package/src/app/shared/components/breadcrumbs/breadcrumbs.component.html +0 -14
  306. package/src/app/shared/components/breadcrumbs/breadcrumbs.component.scss +0 -0
  307. package/src/app/shared/components/breadcrumbs/breadcrumbs.component.ts +0 -36
  308. package/src/app/shared/components/button/button.component.html +0 -3
  309. package/src/app/shared/components/button/button.component.scss +0 -2
  310. package/src/app/shared/components/button/button.component.ts +0 -22
  311. package/src/app/shared/components/collection/create-collection/create-collection.component.html +0 -41
  312. package/src/app/shared/components/collection/create-collection/create-collection.component.scss +0 -0
  313. package/src/app/shared/components/collection/create-collection/create-collection.component.ts +0 -68
  314. package/src/app/shared/components/collection/form-collection/form-collection.component.html +0 -1
  315. package/src/app/shared/components/collection/form-collection/form-collection.component.scss +0 -0
  316. package/src/app/shared/components/collection/form-collection/form-collection.component.ts +0 -15
  317. package/src/app/shared/components/collection/update-collection/update-collection.component.html +0 -40
  318. package/src/app/shared/components/collection/update-collection/update-collection.component.scss +0 -0
  319. package/src/app/shared/components/collection/update-collection/update-collection.component.ts +0 -71
  320. package/src/app/shared/components/glyph-list/glyph-list.component.html +0 -40
  321. package/src/app/shared/components/glyph-list/glyph-list.component.scss +0 -1
  322. package/src/app/shared/components/glyph-list/glyph-list.component.ts +0 -165
  323. package/src/app/shared/components/glyph-view/glyph-view.component.html +0 -23
  324. package/src/app/shared/components/glyph-view/glyph-view.component.scss +0 -0
  325. package/src/app/shared/components/glyph-view/glyph-view.component.ts +0 -228
  326. package/src/app/shared/components/loading/loading.component.html +0 -1
  327. package/src/app/shared/components/loading/loading.component.scss +0 -0
  328. package/src/app/shared/components/loading/loading.component.ts +0 -26
  329. package/src/app/shared/components/modal/modal.component.html +0 -31
  330. package/src/app/shared/components/modal/modal.component.scss +0 -0
  331. package/src/app/shared/components/modal/modal.component.ts +0 -51
  332. package/src/app/shared/components/page-not-found/page-not-found.component.scss +0 -0
  333. package/src/app/shared/components/paginator/paginator.component.html +0 -21
  334. package/src/app/shared/components/paginator/paginator.component.scss +0 -3
  335. package/src/app/shared/components/paginator/paginator.component.ts +0 -133
  336. package/src/app/shared/components/pairing/pairing.component.html +0 -20
  337. package/src/app/shared/components/pairing/pairing.component.scss +0 -0
  338. package/src/app/shared/components/pairing/pairing.component.ts +0 -33
  339. package/src/app/shared/components/search/search.component.scss +0 -10
  340. package/src/app/shared/components/settings/database/database.component.html +0 -151
  341. package/src/app/shared/components/settings/database/database.component.scss +0 -0
  342. package/src/app/shared/components/settings/database/database.component.ts +0 -145
  343. package/src/app/shared/components/settings/general/general.component.html +0 -170
  344. package/src/app/shared/components/settings/general/general.component.scss +0 -0
  345. package/src/app/shared/components/settings/general/general.component.ts +0 -150
  346. package/src/app/shared/components/settings/logs/logs.component.html +0 -44
  347. package/src/app/shared/components/settings/logs/logs.component.scss +0 -0
  348. package/src/app/shared/components/settings/logs/logs.component.ts +0 -37
  349. package/src/app/shared/components/settings/news/news.component.html +0 -41
  350. package/src/app/shared/components/settings/news/news.component.scss +0 -0
  351. package/src/app/shared/components/settings/news/news.component.ts +0 -52
  352. package/src/app/shared/components/settings/settings.component.html +0 -46
  353. package/src/app/shared/components/settings/settings.component.scss +0 -0
  354. package/src/app/shared/components/settings/settings.component.ts +0 -23
  355. package/src/app/shared/components/settings/system/system.component.html +0 -30
  356. package/src/app/shared/components/settings/system/system.component.scss +0 -0
  357. package/src/app/shared/components/settings/system/system.component.ts +0 -43
  358. package/src/app/shared/components/settings/theme/theme.component.html +0 -22
  359. package/src/app/shared/components/settings/theme/theme.component.scss +0 -0
  360. package/src/app/shared/components/settings/theme/theme.component.ts +0 -50
  361. package/src/app/shared/components/spinner/spinner.component.html +0 -1
  362. package/src/app/shared/components/spinner/spinner.component.scss +0 -0
  363. package/src/app/shared/components/store/store.component.html +0 -22
  364. package/src/app/shared/components/store/store.component.scss +0 -10
  365. package/src/app/shared/components/store/store.component.ts +0 -58
  366. package/src/app/shared/components/tables/tables.component.html +0 -47
  367. package/src/app/shared/components/tables/tables.component.scss +0 -10
  368. package/src/app/shared/components/tables/tables.component.ts +0 -81
  369. package/src/app/shared/components/typescale/typescale.component.html +0 -53
  370. package/src/app/shared/components/typescale/typescale.component.scss +0 -0
  371. package/src/app/shared/components/typescale/typescale.component.ts +0 -168
  372. package/src/app/shared/directives/gravatar/gravatar.directive.ts +0 -29
  373. package/src/app/shared/pipes/installable.pipe.ts +0 -10
  374. package/src/app/shared/pipes/prettybytes.pipe.ts +0 -10
  375. package/src/app/shared/pipes/safehtml.pipe.ts +0 -10
  376. package/src/assets/fonts/fa/fa-brands-400.eot +0 -0
  377. package/src/assets/fonts/fa/fa-brands-400.svg +0 -3535
  378. package/src/assets/fonts/fa/fa-brands-400.ttf +0 -0
  379. package/src/assets/fonts/fa/fa-brands-400.woff +0 -0
  380. package/src/assets/fonts/fa/fa-brands-400.woff2 +0 -0
  381. package/src/assets/fonts/fa/fa-regular-400.eot +0 -0
  382. package/src/assets/fonts/fa/fa-regular-400.svg +0 -803
  383. package/src/assets/fonts/fa/fa-regular-400.ttf +0 -0
  384. package/src/assets/fonts/fa/fa-regular-400.woff +0 -0
  385. package/src/assets/fonts/fa/fa-regular-400.woff2 +0 -0
  386. package/src/assets/fonts/fa/fa-solid-900.eot +0 -0
  387. package/src/assets/fonts/fa/fa-solid-900.svg +0 -4700
  388. package/src/assets/fonts/fa/fa-solid-900.ttf +0 -0
  389. package/src/assets/fonts/fa/fa-solid-900.woff +0 -0
  390. package/src/assets/fonts/fa/fa-solid-900.woff2 +0 -0
  391. package/src/assets/fonts/md/MaterialIcons-Regular.eot +0 -0
  392. package/src/assets/fonts/md/MaterialIcons-Regular.ijmap +0 -1
  393. package/src/assets/fonts/md/MaterialIcons-Regular.svg +0 -2373
  394. package/src/assets/fonts/md/MaterialIcons-Regular.ttf +0 -0
  395. package/src/assets/fonts/md/MaterialIcons-Regular.woff +0 -0
  396. package/src/assets/fonts/md/README.md +0 -9
  397. package/src/assets/fonts/md/codepoints +0 -932
  398. package/src/assets/fonts/md/material-icons.css +0 -36
  399. package/src/assets/fonts/octicon/octicon.eot +0 -0
  400. package/src/assets/fonts/octicon/octicon.svg +0 -378
  401. package/src/assets/fonts/octicon/octicon.ttf +0 -0
  402. package/src/assets/fonts/octicon/octicon.woff +0 -0
  403. package/src/assets/fonts/octicon/octicon.woff2 +0 -0
  404. package/src/assets/fonts/roboto/Roboto-Bold-webfont.eot +0 -0
  405. package/src/assets/fonts/roboto/Roboto-Bold-webfont.svg +0 -607
  406. package/src/assets/fonts/roboto/Roboto-Bold-webfont.ttf +0 -0
  407. package/src/assets/fonts/roboto/Roboto-Bold-webfont.woff +0 -0
  408. package/src/assets/fonts/roboto/Roboto-Medium-webfont.eot +0 -0
  409. package/src/assets/fonts/roboto/Roboto-Medium-webfont.svg +0 -607
  410. package/src/assets/fonts/roboto/Roboto-Medium-webfont.ttf +0 -0
  411. package/src/assets/fonts/roboto/Roboto-Medium-webfont.woff +0 -0
  412. package/src/assets/fonts/roboto/Roboto-Regular-webfont.eot +0 -0
  413. package/src/assets/fonts/roboto/Roboto-Regular-webfont.svg +0 -635
  414. package/src/assets/fonts/roboto/Roboto-Regular-webfont.ttf +0 -0
  415. package/src/assets/fonts/roboto/Roboto-Regular-webfont.woff +0 -0
  416. package/src/assets/icons/android-chrome-192x192.png +0 -0
  417. package/src/assets/icons/android-chrome-512x512.png +0 -0
  418. package/src/assets/icons/apple-touch-icon.png +0 -0
  419. package/src/assets/icons/favicon-16x16.png +0 -0
  420. package/src/assets/icons/favicon-32x32.png +0 -0
  421. package/src/assets/icons/site.webmanifest +0 -1
  422. package/src/assets/images/electron.bmp +0 -0
  423. package/src/bin/activator +0 -0
  424. package/src/bin/activator.exe +0 -0
  425. package/src/environments/environment.web.prod.ts +0 -4
  426. package/src/environments/environment.web.ts +0 -4
  427. package/src/karma.conf.js +0 -50
  428. package/src/polyfills-test.ts +0 -1
  429. package/src/polyfills.ts +0 -53
  430. package/src/styles/base/loading.scss +0 -87
  431. package/src/styles/base/reset.scss +0 -408
  432. package/src/styles/components/alert.scss +0 -54
  433. package/src/styles/components/buttons.scss +0 -93
  434. package/src/styles/components/forms.scss +0 -96
  435. package/src/styles/components/inputs.scss +0 -113
  436. package/src/styles/components/modal.scss +0 -52
  437. package/src/styles/components/paginator.scss +0 -108
  438. package/src/styles/components/scrollbox.scss +0 -71
  439. package/src/styles/components/spinner.scss +0 -11
  440. package/src/styles/components/tables.scss +0 -42
  441. package/src/styles/components/tabs.scss +0 -44
  442. package/src/styles/components/toolbar.scss +0 -130
  443. package/src/styles/fonts/md.scss +0 -54
  444. package/src/styles/fonts/octicons.scss +0 -1351
  445. package/src/styles/fonts/roboto.scss +0 -32
  446. package/src/styles/tools/_functions.scss +0 -5
  447. package/src/styles/tools/_mixins.scss +0 -159
  448. package/src/styles/tools/_placeholders.scss +0 -17
  449. package/src/styles/tools/_variables.scss +0 -67
  450. package/src/styles.scss +0 -37
  451. package/src/test.ts +0 -22
  452. package/tailwind.config.js +0 -67
@@ -0,0 +1,68 @@
1
+ import { Component, inject, effect, ElementRef } from '@angular/core';
2
+ import { DatabaseService, MessageService, PresentationService } from '../../../core/services';
3
+
4
+ @Component({
5
+ selector: 'app-preview',
6
+ standalone: true,
7
+ templateUrl: './preview.component.html',
8
+ })
9
+ export class PreviewComponent {
10
+ readonly db = inject(DatabaseService);
11
+ readonly presentation = inject(PresentationService);
12
+ private el = inject(ElementRef);
13
+ private messageService = inject(MessageService);
14
+
15
+ private registeredFonts = new Set<string>();
16
+
17
+ constructor() {
18
+ effect(() => {
19
+ const stores = this.db.stores();
20
+ if (stores) {
21
+ stores.forEach((store) => this.registerFont(store));
22
+ }
23
+ });
24
+
25
+ effect(() => {
26
+ this.db.currentPage();
27
+ const scrollable = this.el.nativeElement.querySelector('.scrollbox-y');
28
+ scrollable?.scrollTo(0, 0);
29
+ });
30
+ }
31
+
32
+ selectStore(id: number) {
33
+ this.db.storeId.set(id);
34
+ document.getElementById('grid-store-' + id)?.scrollIntoView({ behavior: 'smooth', block: 'center' });
35
+ }
36
+
37
+ openFileLocation(event: Event, store: any) {
38
+ event.stopPropagation();
39
+ if (store?.file_path) {
40
+ this.messageService.showItemInFolder(store.file_path);
41
+ }
42
+ }
43
+
44
+ openFileViewer(event: Event, store: any) {
45
+ event.stopPropagation();
46
+ if (store?.file_path) {
47
+ this.messageService.openPath(store.file_path);
48
+ }
49
+ }
50
+
51
+ private registerFont(store: any) {
52
+ const key = `${store.id}-${store.file_path}`;
53
+ if (this.registeredFonts.has(key)) return;
54
+
55
+ const url = `font://${store.file_path}`;
56
+ const fontFace = new FontFace(store.full_name || store.font_family, `url('${url}')`);
57
+
58
+ fontFace
59
+ .load()
60
+ .then((loaded) => {
61
+ (document as any).fonts.add(loaded);
62
+ this.registeredFonts.add(key);
63
+ })
64
+ .catch((err) => {
65
+ console.warn(`Failed to load font: ${store.file_name}`, err);
66
+ });
67
+ }
68
+ }
@@ -0,0 +1,36 @@
1
+ <div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm" (click)="cancel()">
2
+ <div class="card mb-0 w-[480px]" style="box-shadow: var(--context-shadow)" (click)="$event.stopPropagation()">
3
+ <div class="card-header">
4
+ <div class="card-title">
5
+ <h3>{{ title }}</h3>
6
+ </div>
7
+ <div class="card-tools"></div>
8
+ </div>
9
+ <div class="card-body">
10
+ <div class="mb-4">
11
+ <label class="form-label" for="promptInput">Name</label>
12
+ <input
13
+ #promptInput
14
+ type="text"
15
+ class="form-input w-full"
16
+ id="promptInput"
17
+ [placeholder]="placeholder"
18
+ [(ngModel)]="value"
19
+ (keyup.enter)="confirm()"
20
+ (keyup.escape)="cancel()"
21
+ />
22
+ </div>
23
+ </div>
24
+ <div class="card-footer">
25
+ <div></div>
26
+ <div class="card-tools">
27
+ <button class="btn btn-sm btn-default" (click)="cancel()">
28
+ {{ cancelText }}
29
+ </button>
30
+ <button class="btn btn-sm btn-theme" (click)="confirm()">
31
+ {{ confirmText }}
32
+ </button>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
@@ -0,0 +1,39 @@
1
+ import { Component, Input, Output, EventEmitter, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
2
+ import { FormsModule } from '@angular/forms';
3
+
4
+ @Component({
5
+ selector: 'app-prompt-dialog',
6
+ standalone: true,
7
+ imports: [FormsModule],
8
+ templateUrl: './prompt-dialog.component.html',
9
+ })
10
+ export class PromptDialogComponent implements AfterViewInit {
11
+ @Input() title = 'Prompt';
12
+ @Input() placeholder = '';
13
+ @Input() confirmText = 'Confirm';
14
+ @Input() cancelText = 'Cancel';
15
+
16
+ @Output() confirmed = new EventEmitter<string>();
17
+ @Output() cancelled = new EventEmitter<void>();
18
+
19
+ @ViewChild('promptInput') promptInput!: ElementRef<HTMLInputElement>;
20
+
21
+ value = '';
22
+
23
+ ngAfterViewInit(): void {
24
+ this.promptInput.nativeElement.focus();
25
+ }
26
+
27
+ confirm(): void {
28
+ const trimmed = this.value.trim();
29
+ if (trimmed) {
30
+ this.confirmed.emit(trimmed);
31
+ this.value = '';
32
+ }
33
+ }
34
+
35
+ cancel(): void {
36
+ this.value = '';
37
+ this.cancelled.emit();
38
+ }
39
+ }
@@ -1,54 +1,329 @@
1
- <figure class="border-bottom">
2
- <figcaption>
3
- <span class="material-icons">arrow_drop_down</span>
4
- <span class="grow whitespace-nowrap">Font Search</span>
5
- <span class="flex items-center justify-end material-icons-rounded">
6
- <span title="Collapse" class="material-icons" (click)="onComponentSwitch();">more_horiz</span>
7
- </span>
8
- </figcaption>
9
- </figure>
10
-
11
- <div class="hover-scrollbox-y overflow-x-hidden">
12
-
13
- <form class="p-5" (ngSubmit)="onSubmit()" #form="ngForm">
14
-
15
- <div class="form-group">
16
- <label form="term">Search term</label>
17
- <input type="text" class="form-control" [(ngModel)]="model.term" #term="ngModel" name="term" id="term" />
18
- <span class="form-text text-muted">Please enter a search term.</span>
19
- </div>
20
-
21
- <div class="form-group">
22
- <label for="mimes">Mime types</label>
23
- <select class="form-control" [(ngModel)]="model.mimes" #mimes="ngModel" name="mimes" id="mimes" multiple>
24
- <option *ngFor="let item of fontTypes;" [value]="item.type">{{item.name}}</option>
25
- </select>
26
- <span class="form-text text-muted">Please select mime type.</span>
27
- </div>
28
-
29
- <div class="form-group">
30
- <label for="sort">Sort by</label>
31
- <select class="form-control" [(ngModel)]="model.sort" #sort="ngModel" name="sort" id="sort">
32
- <option *ngFor="let item of dbColumns; let i = index;" [value]="item.name">{{item.name}}</option>
33
- </select>
34
- <span class="form-text text-muted">Select column sort.</span>
35
- </div>
36
-
37
- <div class="form-group">
38
- <label for="order">Order by</label>
39
- <select class="form-control" [(ngModel)]="model.order" #order="ngModel" name="order" id="order">
40
- <option *ngFor="let item of orderBy; let i = index;" [value]="item">{{item}}</option>
41
- </select>
42
- <span class="form-text text-muted">Select orer by.</span>
43
- </div>
44
-
45
- <div class="form__actions">
46
- <app-button [type]="'submit'" [title]="'Submit'"
47
- [ngClass]="'app-button__xl app-button__rounded'">Submit</app-button>
48
- <app-button [type]="'reset'" [title]="'Submit'" [ngClass]="'app-button__xl app-button__rounded'"
49
- (click)="onReset();">Reset</app-button>
50
- </div>
51
-
52
- </form>
53
-
54
- </div>
1
+ <div class="h-full flex flex-col">
2
+ <div
3
+ class="flex items-center justify-between px-2.5 shrink-0 h-[34px]"
4
+ [style.border-top]="'1px solid var(--border-subtle)'"
5
+ [style.border-bottom]="'1px solid var(--border-subtle)'"
6
+ [style.background-color]="'var(--surface-2)'"
7
+ >
8
+ <div class="flex items-center text-[10px] font-semibold uppercase tracking-widest" [style.color]="'var(--text-muted)'">
9
+ <span
10
+ class="material-symbols-outlined icon-sm mr-1"
11
+ style="
12
+ font-variation-settings:
13
+ 'opsz' 20,
14
+ 'wght' 500;
15
+ "
16
+ >search</span
17
+ >
18
+ @if (hasSearched()) {
19
+ {{ db.storeCount() }} results found
20
+ } @else {
21
+ Search fonts
22
+ }
23
+ </div>
24
+ <div class="flex items-center gap-1">
25
+ @if (hasSearched()) {
26
+ <button
27
+ class="px-2 py-0.5 rounded cursor-pointer text-[10px] transition-colors"
28
+ [style.color]="'var(--text-secondary)'"
29
+ [style.background-color]="'transparent'"
30
+ (mouseenter)="$any($event.currentTarget).style.backgroundColor = 'var(--hover-bg)'"
31
+ (mouseleave)="$any($event.currentTarget).style.backgroundColor = 'transparent'"
32
+ (click)="onReset()"
33
+ >
34
+ Clear
35
+ </button>
36
+ }
37
+ </div>
38
+ </div>
39
+
40
+ <div class="flex-1 overflow-auto">
41
+ <div class="w-full max-w-4xl mx-auto px-6 py-10">
42
+ <!-- Search Term (full width) -->
43
+ <div class="flex flex-col gap-1.5 mb-5">
44
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">Search Term</label>
45
+ <input
46
+ type="text"
47
+ class="w-full px-2.5 py-1.5 rounded text-xs outline-none transition-colors"
48
+ [style.background-color]="'var(--surface-2)'"
49
+ [style.border]="'1px solid var(--border-default)'"
50
+ [style.color]="'var(--text-primary)'"
51
+ placeholder="Font name, family, designer..."
52
+ [(ngModel)]="searchTerm"
53
+ (keydown)="onKeydown($event)"
54
+ />
55
+ </div>
56
+
57
+ <div class="grid grid-cols-2 gap-x-8 gap-y-5">
58
+ <!-- Search Fields -->
59
+ <div class="flex flex-col gap-1.5">
60
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">Search In</label>
61
+ <span class="text-[10px]" [style.color]="'var(--text-muted)'">Leave empty to search all fields</span>
62
+ <div class="grid grid-cols-2 gap-1">
63
+ @for (sf of searchFields; track sf.value) {
64
+ <label
65
+ class="flex items-center gap-2 px-2 py-1 rounded cursor-pointer text-[11px] transition-colors"
66
+ [style.color]="'var(--text-secondary)'"
67
+ [style.background-color]="isSearchFieldSelected(sf.value) ? 'var(--selected-bg)' : 'transparent'"
68
+ (mouseenter)="
69
+ $any($event.currentTarget).style.backgroundColor = isSearchFieldSelected(sf.value)
70
+ ? 'var(--selected-bg)'
71
+ : 'var(--hover-bg)'
72
+ "
73
+ (mouseleave)="
74
+ $any($event.currentTarget).style.backgroundColor = isSearchFieldSelected(sf.value) ? 'var(--selected-bg)' : 'transparent'
75
+ "
76
+ >
77
+ <input
78
+ type="checkbox"
79
+ class="accent-current"
80
+ [checked]="isSearchFieldSelected(sf.value)"
81
+ (change)="toggleSearchField(sf.value)"
82
+ />
83
+ {{ sf.label }}
84
+ </label>
85
+ }
86
+ </div>
87
+ </div>
88
+
89
+ <!-- File Type + Status (stacked in right column) -->
90
+ <div class="flex flex-col gap-5">
91
+ <!-- File Type -->
92
+ <div class="flex flex-col gap-1.5">
93
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">File Type</label>
94
+ <div class="grid grid-cols-2 gap-1">
95
+ @for (ft of fileTypes; track ft.value) {
96
+ <label
97
+ class="flex items-center gap-2 px-2 py-1 rounded cursor-pointer text-[11px] transition-colors"
98
+ [style.color]="'var(--text-secondary)'"
99
+ [style.background-color]="isFileTypeSelected(ft.value) ? 'var(--selected-bg)' : 'transparent'"
100
+ (mouseenter)="
101
+ $any($event.currentTarget).style.backgroundColor = isFileTypeSelected(ft.value)
102
+ ? 'var(--selected-bg)'
103
+ : 'var(--hover-bg)'
104
+ "
105
+ (mouseleave)="
106
+ $any($event.currentTarget).style.backgroundColor = isFileTypeSelected(ft.value) ? 'var(--selected-bg)' : 'transparent'
107
+ "
108
+ >
109
+ <input
110
+ type="checkbox"
111
+ class="accent-current"
112
+ [checked]="isFileTypeSelected(ft.value)"
113
+ (change)="toggleFileType(ft.value)"
114
+ />
115
+ {{ ft.label }}
116
+ </label>
117
+ }
118
+ </div>
119
+ </div>
120
+
121
+ <!-- Status Filters -->
122
+ <div class="flex flex-col gap-1.5">
123
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">Status</label>
124
+ <div class="flex flex-col gap-1">
125
+ <label
126
+ class="flex items-center gap-2 px-2 py-1 rounded cursor-pointer text-[11px] transition-colors"
127
+ [style.color]="'var(--text-secondary)'"
128
+ [style.background-color]="favoritesOnly ? 'var(--selected-bg)' : 'transparent'"
129
+ (mouseenter)="$any($event.currentTarget).style.backgroundColor = favoritesOnly ? 'var(--selected-bg)' : 'var(--hover-bg)'"
130
+ (mouseleave)="$any($event.currentTarget).style.backgroundColor = favoritesOnly ? 'var(--selected-bg)' : 'transparent'"
131
+ >
132
+ <input type="checkbox" class="accent-current" [(ngModel)]="favoritesOnly" />
133
+ Favorites Only
134
+ </label>
135
+ <label
136
+ class="flex items-center gap-2 px-2 py-1 rounded cursor-pointer text-[11px] transition-colors"
137
+ [style.color]="'var(--text-secondary)'"
138
+ [style.background-color]="systemOnly ? 'var(--selected-bg)' : 'transparent'"
139
+ (mouseenter)="$any($event.currentTarget).style.backgroundColor = systemOnly ? 'var(--selected-bg)' : 'var(--hover-bg)'"
140
+ (mouseleave)="$any($event.currentTarget).style.backgroundColor = systemOnly ? 'var(--selected-bg)' : 'transparent'"
141
+ >
142
+ <input type="checkbox" class="accent-current" [(ngModel)]="systemOnly" />
143
+ System Fonts Only
144
+ </label>
145
+ <label
146
+ class="flex items-center gap-2 px-2 py-1 rounded cursor-pointer text-[11px] transition-colors"
147
+ [style.color]="'var(--text-secondary)'"
148
+ [style.background-color]="installedOnly ? 'var(--selected-bg)' : 'transparent'"
149
+ (mouseenter)="$any($event.currentTarget).style.backgroundColor = installedOnly ? 'var(--selected-bg)' : 'var(--hover-bg)'"
150
+ (mouseleave)="$any($event.currentTarget).style.backgroundColor = installedOnly ? 'var(--selected-bg)' : 'transparent'"
151
+ >
152
+ <input type="checkbox" class="accent-current" [(ngModel)]="installedOnly" />
153
+ Installed Only
154
+ </label>
155
+ </div>
156
+ </div>
157
+ </div>
158
+
159
+ <!-- Collection Filter -->
160
+ <div class="flex flex-col gap-1.5">
161
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">Collection</label>
162
+ <select
163
+ class="w-full px-2.5 py-1.5 rounded text-xs outline-none transition-colors"
164
+ [style.background-color]="'var(--surface-2)'"
165
+ [style.border]="'1px solid var(--border-default)'"
166
+ [style.color]="'var(--text-primary)'"
167
+ [(ngModel)]="selectedCollectionId"
168
+ >
169
+ <option [ngValue]="null">All Collections</option>
170
+ @for (col of collections; track col.id) {
171
+ <option [ngValue]="col.id">{{ col.title }}</option>
172
+ }
173
+ </select>
174
+ </div>
175
+
176
+ <!-- Sort By -->
177
+ <div class="flex flex-col gap-1.5">
178
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">Sort By</label>
179
+ <select
180
+ class="w-full px-2.5 py-1.5 rounded text-xs outline-none transition-colors"
181
+ [style.background-color]="'var(--surface-2)'"
182
+ [style.border]="'1px solid var(--border-default)'"
183
+ [style.color]="'var(--text-primary)'"
184
+ [(ngModel)]="selectedSortIndex"
185
+ >
186
+ <option [ngValue]="null">Default</option>
187
+ @for (opt of sortOptions; track $index) {
188
+ <option [ngValue]="$index">{{ opt.label }}</option>
189
+ }
190
+ </select>
191
+ </div>
192
+
193
+ <!-- Designer Filter -->
194
+ <div class="flex flex-col gap-1.5">
195
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">Designer</label>
196
+ <input
197
+ type="text"
198
+ class="w-full px-2.5 py-1.5 rounded text-xs outline-none transition-colors"
199
+ [style.background-color]="'var(--surface-2)'"
200
+ [style.border]="'1px solid var(--border-default)'"
201
+ [style.color]="'var(--text-primary)'"
202
+ placeholder="Filter by designer name..."
203
+ [(ngModel)]="designerFilter"
204
+ (keydown)="onKeydown($event)"
205
+ />
206
+ </div>
207
+
208
+ <!-- Manufacturer Filter -->
209
+ <div class="flex flex-col gap-1.5">
210
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">Manufacturer</label>
211
+ <input
212
+ type="text"
213
+ class="w-full px-2.5 py-1.5 rounded text-xs outline-none transition-colors"
214
+ [style.background-color]="'var(--surface-2)'"
215
+ [style.border]="'1px solid var(--border-default)'"
216
+ [style.color]="'var(--text-primary)'"
217
+ placeholder="Filter by manufacturer..."
218
+ [(ngModel)]="manufacturerFilter"
219
+ (keydown)="onKeydown($event)"
220
+ />
221
+ </div>
222
+
223
+ <!-- Font Subfamily Filter -->
224
+ <div class="flex flex-col gap-1.5">
225
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">Font Style</label>
226
+ <input
227
+ type="text"
228
+ class="w-full px-2.5 py-1.5 rounded text-xs outline-none transition-colors"
229
+ [style.background-color]="'var(--surface-2)'"
230
+ [style.border]="'1px solid var(--border-default)'"
231
+ [style.color]="'var(--text-primary)'"
232
+ placeholder="e.g. Bold, Italic, Regular..."
233
+ [(ngModel)]="subfamilyFilter"
234
+ (keydown)="onKeydown($event)"
235
+ />
236
+ </div>
237
+
238
+ <!-- File Size Range -->
239
+ <div class="flex flex-col gap-1.5">
240
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">File Size (KB)</label>
241
+ <div class="flex gap-2 items-center">
242
+ <input
243
+ type="number"
244
+ class="flex-1 px-2.5 py-1.5 rounded text-xs outline-none transition-colors"
245
+ [style.background-color]="'var(--surface-2)'"
246
+ [style.border]="'1px solid var(--border-default)'"
247
+ [style.color]="'var(--text-primary)'"
248
+ placeholder="Min"
249
+ [(ngModel)]="fileSizeMin"
250
+ min="0"
251
+ />
252
+ <span class="text-[10px]" [style.color]="'var(--text-muted)'">to</span>
253
+ <input
254
+ type="number"
255
+ class="flex-1 px-2.5 py-1.5 rounded text-xs outline-none transition-colors"
256
+ [style.background-color]="'var(--surface-2)'"
257
+ [style.border]="'1px solid var(--border-default)'"
258
+ [style.color]="'var(--text-primary)'"
259
+ placeholder="Max"
260
+ [(ngModel)]="fileSizeMax"
261
+ min="0"
262
+ />
263
+ </div>
264
+ </div>
265
+
266
+ <!-- Date Range -->
267
+ <div class="flex flex-col gap-1.5">
268
+ <label class="text-[11px] font-semibold" [style.color]="'var(--text-primary)'">Date Added</label>
269
+ <div class="flex gap-2 items-center">
270
+ <input
271
+ type="date"
272
+ class="flex-1 px-2.5 py-1.5 rounded text-xs outline-none transition-colors"
273
+ [style.background-color]="'var(--surface-2)'"
274
+ [style.border]="'1px solid var(--border-default)'"
275
+ [style.color]="'var(--text-primary)'"
276
+ [(ngModel)]="dateFrom"
277
+ />
278
+ <span class="text-[10px]" [style.color]="'var(--text-muted)'">to</span>
279
+ <input
280
+ type="date"
281
+ class="flex-1 px-2.5 py-1.5 rounded text-xs outline-none transition-colors"
282
+ [style.background-color]="'var(--surface-2)'"
283
+ [style.border]="'1px solid var(--border-default)'"
284
+ [style.color]="'var(--text-primary)'"
285
+ [(ngModel)]="dateTo"
286
+ />
287
+ </div>
288
+ </div>
289
+ </div>
290
+
291
+ <!-- Action Buttons -->
292
+ <div class="flex gap-2 pt-5">
293
+ <button
294
+ class="flex-1 px-3 py-1.5 rounded text-[11px] font-medium cursor-pointer transition-colors"
295
+ [style.background-color]="'var(--selected-bg)'"
296
+ [style.color]="'var(--text-primary)'"
297
+ [style.border]="'1px solid var(--border-default)'"
298
+ (mouseenter)="$any($event.currentTarget).style.backgroundColor = 'var(--hover-bg)'"
299
+ (mouseleave)="$any($event.currentTarget).style.backgroundColor = 'var(--selected-bg)'"
300
+ (click)="onSearch()"
301
+ >
302
+ <span class="flex items-center justify-center gap-1">
303
+ <i
304
+ class="material-symbols-outlined text-sm"
305
+ style="
306
+ font-variation-settings:
307
+ 'opsz' 20,
308
+ 'wght' 300;
309
+ "
310
+ >search</i
311
+ >
312
+ Search
313
+ </span>
314
+ </button>
315
+ <button
316
+ class="px-3 py-1.5 rounded text-[11px] cursor-pointer transition-colors"
317
+ [style.color]="'var(--text-muted)'"
318
+ [style.border]="'1px solid var(--border-subtle)'"
319
+ [style.background-color]="'transparent'"
320
+ (mouseenter)="$any($event.currentTarget).style.backgroundColor = 'var(--hover-bg)'"
321
+ (mouseleave)="$any($event.currentTarget).style.backgroundColor = 'transparent'"
322
+ (click)="onReset()"
323
+ >
324
+ Reset
325
+ </button>
326
+ </div>
327
+ </div>
328
+ </div>
329
+ </div>