@brftech/filex-core 0.44.2 → 0.45.1

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 (50) hide show
  1. package/dist/{ArchiveViewer-D_tJxJhJ.js → ArchiveViewer-QuNXAECN.js} +2 -2
  2. package/dist/{ArchiveViewer-D_tJxJhJ.js.map → ArchiveViewer-QuNXAECN.js.map} +1 -1
  3. package/dist/{CsvViewer-B95fArq0.js → CsvViewer-niuoz1Uk.js} +2 -2
  4. package/dist/{CsvViewer-B95fArq0.js.map → CsvViewer-niuoz1Uk.js.map} +1 -1
  5. package/dist/{DrawioViewer-BAaPMTge.js → DrawioViewer-BtqMiasr.js} +2 -2
  6. package/dist/{DrawioViewer-BAaPMTge.js.map → DrawioViewer-BtqMiasr.js.map} +1 -1
  7. package/dist/{EpubViewer-B-B7bRW7.js → EpubViewer-ERm7L1WN.js} +2 -2
  8. package/dist/{EpubViewer-B-B7bRW7.js.map → EpubViewer-ERm7L1WN.js.map} +1 -1
  9. package/dist/{IpynbViewer-COOTyOcu.js → IpynbViewer-Cmz5n0VR.js} +2 -2
  10. package/dist/{IpynbViewer-COOTyOcu.js.map → IpynbViewer-Cmz5n0VR.js.map} +1 -1
  11. package/dist/{MermaidViewer-CjVCmR3s.js → MermaidViewer-BJ5uOyhc.js} +2 -2
  12. package/dist/{MermaidViewer-CjVCmR3s.js.map → MermaidViewer-BJ5uOyhc.js.map} +1 -1
  13. package/dist/{PsdViewer-xsIYL9Gu.js → PsdViewer-DYCJF2BM.js} +2 -2
  14. package/dist/{PsdViewer-xsIYL9Gu.js.map → PsdViewer-DYCJF2BM.js.map} +1 -1
  15. package/dist/{TiffViewer-CtwnTxqL.js → TiffViewer-DbJv_0El.js} +2 -2
  16. package/dist/{TiffViewer-CtwnTxqL.js.map → TiffViewer-DbJv_0El.js.map} +1 -1
  17. package/dist/{Viewer3D-xYMwndEy.js → Viewer3D-DwZfYoO3.js} +2 -2
  18. package/dist/{Viewer3D-xYMwndEy.js.map → Viewer3D-DwZfYoO3.js.map} +1 -1
  19. package/dist/filex-core.js +298 -291
  20. package/dist/filex-core.umd.cjs +61 -61
  21. package/dist/filex-core.umd.cjs.map +1 -1
  22. package/dist/{index-BBToAjwL.js → index-1RaeWGFO.js} +14218 -13831
  23. package/dist/index-1RaeWGFO.js.map +1 -0
  24. package/dist/index.d.ts +253 -31
  25. package/dist/style.css +1 -1
  26. package/package.json +1 -1
  27. package/src/FileExplorer.vue +265 -99
  28. package/src/components/AdvancedSearch.vue +3 -3
  29. package/src/components/CommandPalette.vue +166 -42
  30. package/src/components/ConnectionsPanel.vue +3 -11
  31. package/src/components/SideNav.vue +16 -11
  32. package/src/components/plugin/PluginViewModal.vue +7 -0
  33. package/src/components/plugin/nodes/SurfacePdfFields.vue +16 -1
  34. package/src/components/public/PublicLinkPage.vue +6 -5
  35. package/src/composables/useFileApi.ts +32 -1
  36. package/src/composables/usePluginSurface.ts +12 -0
  37. package/src/composables/useSystemDark.ts +32 -0
  38. package/src/index.ts +16 -0
  39. package/src/lib/connectionGuides.ts +11 -15
  40. package/src/lib/downloadSelection.ts +34 -0
  41. package/src/lib/dragOut.ts +0 -0
  42. package/src/lib/searchHit.ts +129 -0
  43. package/src/lib/storageLine.ts +124 -0
  44. package/src/lib/webdavMount.ts +120 -0
  45. package/src/locales/en.ts +13 -0
  46. package/src/locales/tr.ts +13 -0
  47. package/src/styles/base.css +84 -7
  48. package/src/types/ExplorerConfig.ts +65 -1
  49. package/src/types/Plugins.ts +12 -0
  50. package/dist/index-BBToAjwL.js.map +0 -1
@@ -2304,6 +2304,71 @@ filex-explorer {
2304
2304
  outline-offset: -2px;
2305
2305
  }
2306
2306
 
2307
+ /* #47 — a search hit's own verbs: a Download button on the row, the row
2308
+ itself draggable, and one badge per signed-in account above its rows. */
2309
+ .fe-cmdp__item--hit {
2310
+ user-select: none;
2311
+ }
2312
+ .fe-cmdp__hitact {
2313
+ flex: 0 0 auto;
2314
+ align-self: center;
2315
+ background: transparent;
2316
+ border: 0;
2317
+ border-radius: var(--fe-radius-sm);
2318
+ padding: 2px 6px;
2319
+ font: inherit;
2320
+ color: var(--fe-text-muted);
2321
+ cursor: pointer;
2322
+ opacity: 0.55;
2323
+ }
2324
+ .fe-cmdp__item--hit:hover .fe-cmdp__hitact,
2325
+ .fe-cmdp__item--hit.is-active .fe-cmdp__hitact {
2326
+ opacity: 1;
2327
+ }
2328
+ .fe-cmdp__hitact:hover {
2329
+ background: var(--fe-bg-elev);
2330
+ color: var(--fe-primary);
2331
+ }
2332
+ .fe-cmdp__hitact:focus-visible {
2333
+ outline: 2px solid var(--fe-primary);
2334
+ outline-offset: -2px;
2335
+ opacity: 1;
2336
+ }
2337
+ .fe-cmdp__hitact .fe-aicon {
2338
+ width: 16px;
2339
+ height: 16px;
2340
+ }
2341
+ .fe-cmdp__acct {
2342
+ display: flex;
2343
+ align-items: baseline;
2344
+ gap: 6px;
2345
+ padding: 8px 10px 2px;
2346
+ min-width: 0;
2347
+ font-size: 12px;
2348
+ color: var(--fe-text);
2349
+ }
2350
+ .fe-cmdp__acct-dot {
2351
+ flex: 0 0 auto;
2352
+ align-self: center;
2353
+ width: 8px;
2354
+ height: 8px;
2355
+ border-radius: 999px;
2356
+ background: var(--fe-primary);
2357
+ }
2358
+ .fe-cmdp__acct-label {
2359
+ font-weight: 600;
2360
+ overflow: hidden;
2361
+ text-overflow: ellipsis;
2362
+ white-space: nowrap;
2363
+ }
2364
+ .fe-cmdp__acct-detail {
2365
+ min-width: 0;
2366
+ overflow: hidden;
2367
+ text-overflow: ellipsis;
2368
+ white-space: nowrap;
2369
+ color: var(--fe-text-muted);
2370
+ }
2371
+
2307
2372
  /* List view — search-result snippet line under the filename. */
2308
2373
  .fe-list__snippet {
2309
2374
  max-width: 100%;
@@ -4690,6 +4755,11 @@ filex-explorer {
4690
4755
  .fe-sidenav__item {
4691
4756
  display: flex;
4692
4757
  align-items: center;
4758
+ /* ⚠ Said out loud, not left to the default: the explorer is not in a shadow
4759
+ root, so a host page's own `button { justify-content: center }` reached
4760
+ these buttons — the desktop app has exactly that rule for its dialogs,
4761
+ and every sidebar entry sat in the middle of its row (#53). */
4762
+ justify-content: flex-start;
4693
4763
  gap: 10px;
4694
4764
  width: 100%;
4695
4765
  padding: 7px 10px;
@@ -11518,7 +11588,10 @@ filex-explorer {
11518
11588
  .fe-steps__item.is-active .fe-steps__marker {
11519
11589
  border-color: var(--fe-primary);
11520
11590
  background: var(--fe-primary);
11521
- color: #fff;
11591
+ /* The palette's ink for its primary, as on every primary button. White
11592
+ measured 3.16:1 on the stock dark primary and 2.3:1 on an operator's pale
11593
+ pink one (#57), where the share dialog beside it used this token. */
11594
+ color: var(--fe-text-on-primary);
11522
11595
  }
11523
11596
  .fe-steps__item.is-done .fe-steps__marker {
11524
11597
  border-color: var(--fe-primary);
@@ -11552,14 +11625,14 @@ filex-explorer {
11552
11625
  .fe-sprogress__track {
11553
11626
  position: relative;
11554
11627
  height: 6px;
11555
- border-radius: 3px;
11628
+ border-radius: 999px;
11556
11629
  background: var(--fe-border);
11557
11630
  overflow: hidden;
11558
11631
  }
11559
11632
  .fe-sprogress__bar {
11560
11633
  height: 100%;
11561
11634
  background: var(--fe-primary);
11562
- border-radius: 3px;
11635
+ border-radius: 999px;
11563
11636
  transition: width 0.2s ease;
11564
11637
  }
11565
11638
  .fe-sprogress__track.is-indeterminate .fe-sprogress__bar {
@@ -11608,7 +11681,7 @@ filex-explorer {
11608
11681
  height: 20px;
11609
11682
  border-radius: 50%;
11610
11683
  background: var(--fe-primary);
11611
- color: #fff;
11684
+ color: var(--fe-text-on-primary);
11612
11685
  font-size: 11px;
11613
11686
  font-weight: 600;
11614
11687
  flex: 0 0 auto;
@@ -12027,7 +12100,7 @@ filex-explorer {
12027
12100
  padding-block: 10px; padding-inline: 14px 12px;
12028
12101
  border: 1px solid var(--fe-border);
12029
12102
  border-inline-start: 3px solid var(--spdf-color, var(--fe-primary));
12030
- border-radius: var(--fe-radius-md, 8px);
12103
+ border-radius: var(--fe-radius-md);
12031
12104
  background: var(--fe-bg-elev);
12032
12105
  }
12033
12106
  .fe-spdf__card .fe-spdf__props {
@@ -12114,7 +12187,11 @@ filex-explorer {
12114
12187
  place-items: center;
12115
12188
  font-size: var(--fe-text-xs, 11px);
12116
12189
  font-weight: 600;
12117
- color: var(--fe-text-on-primary);
12190
+ /* ⚠ The ink is the COLOUR's, not the theme's: the ground is a signer's
12191
+ identity colour (lib/pdfFields SIGNER_PALETTE), the same in every theme,
12192
+ so `--fe-text-on-primary` — dark in dark mode — measured 3.5:1 on the
12193
+ first signer's blue. SurfacePdfFields sets --spdf-ink = inkOn(colour). */
12194
+ color: var(--spdf-ink, var(--fe-text-on-primary));
12118
12195
  background: var(--spdf-color, var(--fe-primary));
12119
12196
  }
12120
12197
  .fe-spdf__add {
@@ -12132,7 +12209,7 @@ filex-explorer {
12132
12209
  .fe-spdf__empty {
12133
12210
  padding: 14px;
12134
12211
  border: 1px dashed var(--fe-border);
12135
- border-radius: var(--fe-radius-md, 8px);
12212
+ border-radius: var(--fe-radius-md);
12136
12213
  color: var(--fe-text-muted);
12137
12214
  font-size: var(--fe-text-sm);
12138
12215
  line-height: 1.5;
@@ -18,6 +18,7 @@
18
18
  */
19
19
 
20
20
  import type { UiProfile } from '../lib/uiProfile';
21
+ import type { GlobalSearchHit, GlobalSearchScope } from '../composables/useFileApi';
21
22
 
22
23
  export type { UiProfile };
23
24
 
@@ -700,7 +701,9 @@ export interface ExplorerConfig {
700
701
  /**
701
702
  * gorunum:v3-shell — bytes this storage holds, when the host knows. Drawn
702
703
  * as the caption on the Home view's storage card; absent means the card
703
- * names the kind of thing instead.
704
+ * names the kind of thing instead. For a person without a quota the
705
+ * storage line under the navigation sums these (lib/storageLine), and a
706
+ * storage left without one is measured by the explorer itself.
704
707
  *
705
708
  * ⚠ It must be the SAME quantity for every caller who gets it (in our own
706
709
  * app: `/api/admin/storages` for an operator, the RBAC-filtered
@@ -806,6 +809,67 @@ export interface ExplorerConfig {
806
809
  * ONE subscriber (the mounted explorer) and overwrites it on remount. */
807
810
  onChange?: (cb: () => void) => void;
808
811
  };
812
+
813
+ /**
814
+ * #47 — the host holds several accounts at once (the desktop app's rail),
815
+ * and ⌘K's "Everywhere" group should search all of them.
816
+ *
817
+ * The explorer never talks to another account's server itself: it has no
818
+ * credential for one, and it must not be handed any. Every call that reaches
819
+ * another account goes through this hook, and the host answers it with the
820
+ * credential it already keeps for that account. Hits come back tagged with
821
+ * the account they belong to (`GlobalSearchHit.account`) and the palette
822
+ * draws one group per account under a badge, this mount's own first.
823
+ *
824
+ * Absent — the web admin, every embed, a desktop with one account — and the
825
+ * palette is exactly what it was: this account's hits, no badges.
826
+ */
827
+ accountSearch?: AccountSearchHook;
828
+ }
829
+
830
+ /** One signed-in account, as the palette's group badge draws it. */
831
+ export interface SearchAccount {
832
+ /** The host's own id for the account; passed back on every hook call. */
833
+ id: string;
834
+ /** Short name on the badge — the server's brand name or its host. */
835
+ label: string;
836
+ /** Second line, quieter — typically the email signed in there. */
837
+ detail?: string;
838
+ /** The account's colour on the host (the rail avatar's), for the badge dot. */
839
+ color?: string;
840
+ }
841
+
842
+ /** See `ExplorerConfig.accountSearch`. */
843
+ export interface AccountSearchHook {
844
+ /** The account THIS explorer is mounted for — heads its own group. */
845
+ self: SearchAccount;
846
+ /** Every OTHER account signed in right now. Read on each query, so an
847
+ * account added or signed out while the explorer is mounted counts. */
848
+ others: () => SearchAccount[] | Promise<SearchAccount[]>;
849
+ /** `/api/files/search` on that account's server, with its credential. */
850
+ search: (
851
+ accountId: string,
852
+ query: string,
853
+ opts: { limit: number; scope: GlobalSearchScope },
854
+ ) => Promise<GlobalSearchHit[]>;
855
+ /**
856
+ * Open another account's hit — the host switches to that account. The hit
857
+ * arrives ADDRESSED (`name://rel`, as a listing row carries it): the host
858
+ * never re-derives where a file is.
859
+ */
860
+ open: (accountId: string, item: SearchHitItem) => void | Promise<void>;
861
+ /** Download another account's hit. Absent: its rows offer no Download. */
862
+ download?: (accountId: string, item: SearchHitItem) => void | Promise<void>;
863
+ /** Drag another account's hit out to the OS. Absent: its rows do not drag. */
864
+ dragStart?: (accountId: string, items: SearchHitItem[]) => void | Promise<unknown>;
865
+ }
866
+
867
+ /** A search hit, addressed — the `{path, basename, type}` a listing row hands
868
+ * the drag-out hook, with `path` = `name://rel`. */
869
+ export interface SearchHitItem {
870
+ path: string;
871
+ basename: string;
872
+ type: 'file' | 'dir';
809
873
  }
810
874
 
811
875
  /** Component emits — the parent listens for these events. */
@@ -478,6 +478,18 @@ export type PluginRunResult =
478
478
  export interface PluginViewEventBody {
479
479
  /** Adapter-qualified wire path of the row the view was opened on. */
480
480
  path?: string;
481
+ /**
482
+ * Every row the view was opened on, adapter-qualified, in selection order.
483
+ *
484
+ * ⚠⚠ Sent on EVERY event of a screen opened on a selection, not only the
485
+ * first: the server builds the event's inputs from it (and falls back to
486
+ * `path` only when it is absent), so a conversation that echoed `path`
487
+ * alone shrank to the first file after the opening screen — the second
488
+ * screen said "a.txt" where the first said "3 files", and the job its
489
+ * submit queued ran on one file (#64). The server re-checks each path for
490
+ * the person asking; this is a report of the selection, not a grant.
491
+ */
492
+ paths?: string[];
481
493
  storage_id?: number;
482
494
  state?: Record<string, unknown>;
483
495
  event: 'open' | 'change' | 'submit' | 'action';