@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.
- package/dist/{ArchiveViewer-D_tJxJhJ.js → ArchiveViewer-QuNXAECN.js} +2 -2
- package/dist/{ArchiveViewer-D_tJxJhJ.js.map → ArchiveViewer-QuNXAECN.js.map} +1 -1
- package/dist/{CsvViewer-B95fArq0.js → CsvViewer-niuoz1Uk.js} +2 -2
- package/dist/{CsvViewer-B95fArq0.js.map → CsvViewer-niuoz1Uk.js.map} +1 -1
- package/dist/{DrawioViewer-BAaPMTge.js → DrawioViewer-BtqMiasr.js} +2 -2
- package/dist/{DrawioViewer-BAaPMTge.js.map → DrawioViewer-BtqMiasr.js.map} +1 -1
- package/dist/{EpubViewer-B-B7bRW7.js → EpubViewer-ERm7L1WN.js} +2 -2
- package/dist/{EpubViewer-B-B7bRW7.js.map → EpubViewer-ERm7L1WN.js.map} +1 -1
- package/dist/{IpynbViewer-COOTyOcu.js → IpynbViewer-Cmz5n0VR.js} +2 -2
- package/dist/{IpynbViewer-COOTyOcu.js.map → IpynbViewer-Cmz5n0VR.js.map} +1 -1
- package/dist/{MermaidViewer-CjVCmR3s.js → MermaidViewer-BJ5uOyhc.js} +2 -2
- package/dist/{MermaidViewer-CjVCmR3s.js.map → MermaidViewer-BJ5uOyhc.js.map} +1 -1
- package/dist/{PsdViewer-xsIYL9Gu.js → PsdViewer-DYCJF2BM.js} +2 -2
- package/dist/{PsdViewer-xsIYL9Gu.js.map → PsdViewer-DYCJF2BM.js.map} +1 -1
- package/dist/{TiffViewer-CtwnTxqL.js → TiffViewer-DbJv_0El.js} +2 -2
- package/dist/{TiffViewer-CtwnTxqL.js.map → TiffViewer-DbJv_0El.js.map} +1 -1
- package/dist/{Viewer3D-xYMwndEy.js → Viewer3D-DwZfYoO3.js} +2 -2
- package/dist/{Viewer3D-xYMwndEy.js.map → Viewer3D-DwZfYoO3.js.map} +1 -1
- package/dist/filex-core.js +298 -291
- package/dist/filex-core.umd.cjs +61 -61
- package/dist/filex-core.umd.cjs.map +1 -1
- package/dist/{index-BBToAjwL.js → index-1RaeWGFO.js} +14218 -13831
- package/dist/index-1RaeWGFO.js.map +1 -0
- package/dist/index.d.ts +253 -31
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/FileExplorer.vue +265 -99
- package/src/components/AdvancedSearch.vue +3 -3
- package/src/components/CommandPalette.vue +166 -42
- package/src/components/ConnectionsPanel.vue +3 -11
- package/src/components/SideNav.vue +16 -11
- package/src/components/plugin/PluginViewModal.vue +7 -0
- package/src/components/plugin/nodes/SurfacePdfFields.vue +16 -1
- package/src/components/public/PublicLinkPage.vue +6 -5
- package/src/composables/useFileApi.ts +32 -1
- package/src/composables/usePluginSurface.ts +12 -0
- package/src/composables/useSystemDark.ts +32 -0
- package/src/index.ts +16 -0
- package/src/lib/connectionGuides.ts +11 -15
- package/src/lib/downloadSelection.ts +34 -0
- package/src/lib/dragOut.ts +0 -0
- package/src/lib/searchHit.ts +129 -0
- package/src/lib/storageLine.ts +124 -0
- package/src/lib/webdavMount.ts +120 -0
- package/src/locales/en.ts +13 -0
- package/src/locales/tr.ts +13 -0
- package/src/styles/base.css +84 -7
- package/src/types/ExplorerConfig.ts +65 -1
- package/src/types/Plugins.ts +12 -0
- package/dist/index-BBToAjwL.js.map +0 -1
package/src/styles/base.css
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
-
|
|
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
|
|
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. */
|
package/src/types/Plugins.ts
CHANGED
|
@@ -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';
|