@brftech/filex-core 0.42.2 → 0.43.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 (234) hide show
  1. package/README.md +14 -2
  2. package/dist/ArchiveViewer-BqU761Wk.js +149 -0
  3. package/dist/ArchiveViewer-BqU761Wk.js.map +1 -0
  4. package/dist/CsvViewer-ByHVK5ga.js +172 -0
  5. package/dist/CsvViewer-ByHVK5ga.js.map +1 -0
  6. package/dist/{DrawioViewer-CC6rJXeP.js → DrawioViewer-Bgrj8-zG.js} +45 -44
  7. package/dist/DrawioViewer-Bgrj8-zG.js.map +1 -0
  8. package/dist/{EpubViewer-CAoTSXTO.js → EpubViewer-DJwUKlHW.js} +50 -50
  9. package/dist/EpubViewer-DJwUKlHW.js.map +1 -0
  10. package/dist/IpynbViewer-Bz0eJ4NS.js +184 -0
  11. package/dist/IpynbViewer-Bz0eJ4NS.js.map +1 -0
  12. package/dist/MermaidViewer-CEDTD_pp.js +136 -0
  13. package/dist/MermaidViewer-CEDTD_pp.js.map +1 -0
  14. package/dist/PsdViewer-CZcxUpZO.js +121 -0
  15. package/dist/PsdViewer-CZcxUpZO.js.map +1 -0
  16. package/dist/TiffViewer-BwI62CbQ.js +141 -0
  17. package/dist/TiffViewer-BwI62CbQ.js.map +1 -0
  18. package/dist/{Viewer3D-CdZeK4j4.js → Viewer3D-DoeZcuMm.js} +16 -16
  19. package/dist/Viewer3D-DoeZcuMm.js.map +1 -0
  20. package/dist/filex-core.js +475 -219
  21. package/dist/filex-core.umd.cjs +165 -108
  22. package/dist/filex-core.umd.cjs.map +1 -1
  23. package/dist/fonts/caveat-latin-ext.woff2 +0 -0
  24. package/dist/fonts/caveat-latin.woff2 +0 -0
  25. package/dist/fonts/dancing-script-latin-ext.woff2 +0 -0
  26. package/dist/fonts/dancing-script-latin.woff2 +0 -0
  27. package/dist/fonts/homemade-apple-latin.woff2 +0 -0
  28. package/dist/fonts/source-serif-4-latin-ext.woff2 +0 -0
  29. package/dist/fonts/source-serif-4-latin.woff2 +0 -0
  30. package/dist/index-DuWnGuv5.js +35901 -0
  31. package/dist/index-DuWnGuv5.js.map +1 -0
  32. package/dist/index.d.ts +5227 -553
  33. package/dist/pdf-CaPYsOUo.js +21302 -0
  34. package/dist/pdf-CaPYsOUo.js.map +1 -0
  35. package/dist/style.css +1 -1
  36. package/package.json +1 -1
  37. package/src/FileExplorer.vue +1055 -253
  38. package/src/assets/fonts/LICENSE-Apache-2.0.txt +202 -0
  39. package/src/assets/fonts/LICENSE-OFL-1.1.txt +93 -0
  40. package/src/assets/fonts/README.md +58 -0
  41. package/src/assets/fonts/caveat-latin-ext.woff2 +0 -0
  42. package/src/assets/fonts/caveat-latin.woff2 +0 -0
  43. package/src/assets/fonts/dancing-script-latin-ext.woff2 +0 -0
  44. package/src/assets/fonts/dancing-script-latin.woff2 +0 -0
  45. package/src/assets/fonts/homemade-apple-latin.woff2 +0 -0
  46. package/src/assets/fonts/source-serif-4-latin-ext.woff2 +0 -0
  47. package/src/assets/fonts/source-serif-4-latin.woff2 +0 -0
  48. package/src/components/AdvancedSearch.vue +49 -0
  49. package/src/components/Breadcrumb.vue +5 -5
  50. package/src/components/ChoiceButtons.vue +152 -0
  51. package/src/components/CommandPalette.vue +5 -5
  52. package/src/components/ConnectionGuideView.vue +1 -1
  53. package/src/components/ConnectionNotice.vue +59 -0
  54. package/src/components/ConnectionsPanel.vue +30 -568
  55. package/src/components/ContextMenu.vue +31 -5
  56. package/src/components/DataTable.vue +1331 -0
  57. package/src/components/FilePane.vue +3 -0
  58. package/src/components/FilterBar.vue +12 -5
  59. package/src/components/GalleryView.vue +50 -2
  60. package/src/components/GridView.vue +51 -3
  61. package/src/components/HomeView.vue +18 -6
  62. package/src/components/InspectorPanel.vue +134 -17
  63. package/src/components/ListView.vue +366 -900
  64. package/src/components/LogoMark.vue +57 -0
  65. package/src/components/NFSExportsPanel.vue +76 -28
  66. package/src/components/OnboardingTour.vue +19 -7
  67. package/src/components/OperationsCenter.vue +77 -1
  68. package/src/components/PendingOpsTray.vue +59 -5
  69. package/src/components/PresenceBar.vue +7 -7
  70. package/src/components/ProductVersion.vue +31 -0
  71. package/src/components/QuickLook.vue +10 -14
  72. package/src/components/RecentlyOpened.vue +31 -15
  73. package/src/components/RecoveryKeyModal.vue +1 -1
  74. package/src/components/RowActions.vue +134 -0
  75. package/src/components/S3KeysPanel.vue +98 -62
  76. package/src/components/SSHKeysPanel.vue +79 -30
  77. package/src/components/SideNav.vue +260 -96
  78. package/src/components/StarButton.vue +1 -0
  79. package/src/components/StorageFields.vue +74 -6
  80. package/src/components/StorageTags.vue +62 -0
  81. package/src/components/TabBar.vue +1 -1
  82. package/src/components/TagKindIcon.vue +56 -0
  83. package/src/components/TagPicker.vue +226 -40
  84. package/src/components/ThemePalette.vue +4 -4
  85. package/src/components/TimeZonePicker.vue +29 -10
  86. package/src/components/TokensPanel.vue +82 -31
  87. package/src/components/Toolbar.vue +28 -6
  88. package/src/components/plugin/PluginConfirmModal.vue +54 -0
  89. package/src/components/plugin/PluginInspectorSection.vue +149 -0
  90. package/src/components/plugin/PluginPageView.vue +339 -0
  91. package/src/components/plugin/PluginViewModal.vue +159 -0
  92. package/src/components/plugin/SurfaceConversation.vue +76 -0
  93. package/src/components/plugin/SurfaceFooterButtons.vue +73 -0
  94. package/src/components/plugin/SurfaceRenderer.vue +299 -0
  95. package/src/components/plugin/SurfaceSections.vue +91 -0
  96. package/src/components/plugin/nodes/PdfFieldEditor.vue +509 -0
  97. package/src/components/plugin/nodes/SurfaceFileChooser.vue +94 -0
  98. package/src/components/plugin/nodes/SurfaceForm.vue +82 -0
  99. package/src/components/plugin/nodes/SurfaceList.vue +127 -0
  100. package/src/components/plugin/nodes/SurfacePdfFields.vue +1285 -0
  101. package/src/components/plugin/nodes/SurfacePeoplePicker.vue +213 -0
  102. package/src/components/plugin/nodes/SurfacePinInput.vue +57 -0
  103. package/src/components/plugin/nodes/SurfacePreview.vue +119 -0
  104. package/src/components/plugin/nodes/SurfaceProgress.vue +48 -0
  105. package/src/components/plugin/nodes/SurfaceSignaturePad.vue +472 -0
  106. package/src/components/plugin/nodes/SurfaceSteps.vue +53 -0
  107. package/src/components/public/PublicLanguagePicker.vue +58 -0
  108. package/src/components/public/PublicLinkPage.vue +286 -0
  109. package/src/components/public/PublicLinkPreview.vue +85 -0
  110. package/src/components/public/PublicPinGate.vue +108 -0
  111. package/src/components/public/PublicRequestBody.vue +204 -0
  112. package/src/components/public/PublicShareBody.vue +188 -0
  113. package/src/components/public/PublicShell.vue +332 -0
  114. package/src/composables/useConnections.ts +8 -2
  115. package/src/composables/useFileApi.ts +183 -44
  116. package/src/composables/useLocale.ts +277 -41
  117. package/src/composables/useNFSExports.ts +8 -10
  118. package/src/composables/useOperations.ts +44 -3
  119. package/src/composables/usePendingOps.ts +59 -8
  120. package/src/composables/usePluginActions.ts +121 -0
  121. package/src/composables/usePluginSurface.ts +223 -0
  122. package/src/composables/usePublicBranding.ts +172 -0
  123. package/src/composables/usePublicLink.ts +573 -0
  124. package/src/composables/usePublicPage.ts +61 -0
  125. package/src/composables/useS3Keys.ts +17 -12
  126. package/src/composables/useSSHKeys.ts +8 -10
  127. package/src/composables/useTokens.ts +8 -12
  128. package/src/composables/useUploadChunked.ts +18 -8
  129. package/src/composables/useViewerFetch.ts +6 -3
  130. package/src/index.ts +404 -8
  131. package/src/lib/actionIcons.ts +46 -1
  132. package/src/lib/advSearch.ts +14 -7
  133. package/src/lib/appLock.ts +130 -0
  134. package/src/lib/connection.ts +110 -0
  135. package/src/lib/destinationTree.ts +19 -3
  136. package/src/lib/direction.ts +353 -0
  137. package/src/lib/dragGhost.ts +6 -0
  138. package/src/lib/dropLimits.ts +69 -0
  139. package/src/lib/errorWords.ts +394 -0
  140. package/src/lib/externalReach.ts +5 -1
  141. package/src/lib/fileFilters.ts +7 -2
  142. package/src/lib/fileIcons.ts +4 -0
  143. package/src/lib/internalPaths.ts +77 -0
  144. package/src/lib/listInput.ts +64 -0
  145. package/src/lib/listing.ts +58 -23
  146. package/src/lib/modalStack.ts +26 -0
  147. package/src/lib/nodeRow.ts +18 -3
  148. package/src/lib/pdfFieldRules.ts +126 -0
  149. package/src/lib/pdfFields.ts +589 -0
  150. package/src/lib/pdfFieldsGeom.ts +203 -0
  151. package/src/lib/pdfjsLoader.ts +51 -0
  152. package/src/lib/personName.ts +47 -0
  153. package/src/lib/pluginApplies.ts +123 -0
  154. package/src/lib/pluginLabel.ts +72 -0
  155. package/src/lib/pluginMenu.ts +253 -0
  156. package/src/lib/pluginPage.ts +58 -0
  157. package/src/lib/plural.ts +181 -0
  158. package/src/lib/popupLayer.ts +103 -0
  159. package/src/lib/prefs.ts +563 -0
  160. package/src/lib/productVersion.ts +35 -0
  161. package/src/lib/publicLayout.ts +39 -0
  162. package/src/lib/serviceGate.ts +104 -0
  163. package/src/lib/shareTtl.ts +25 -11
  164. package/src/lib/signFonts.ts +85 -0
  165. package/src/lib/signaturePad.ts +111 -0
  166. package/src/lib/sortOrder.ts +100 -38
  167. package/src/lib/star.ts +7 -1
  168. package/src/lib/surfaceCell.ts +41 -0
  169. package/src/lib/surfaceConditions.ts +156 -0
  170. package/src/lib/surfaceOpen.ts +106 -0
  171. package/src/lib/surfaceSteps.ts +68 -0
  172. package/src/lib/surfaceValues.ts +191 -0
  173. package/src/lib/symlink.ts +150 -0
  174. package/src/lib/tableColumns.ts +493 -0
  175. package/src/lib/tableEnv.ts +34 -0
  176. package/src/lib/tablePrefs.ts +84 -0
  177. package/src/lib/tags.ts +121 -12
  178. package/src/lib/themes.ts +286 -18
  179. package/src/lib/tour.ts +152 -0
  180. package/src/lib/trashEmpty.ts +111 -0
  181. package/src/lib/trashTimeLeft.ts +23 -0
  182. package/src/lib/uiLocales.ts +460 -0
  183. package/src/lib/viewPrefs.ts +696 -660
  184. package/src/lib/viewPrefsHttp.ts +78 -0
  185. package/src/locales/en.ts +515 -117
  186. package/src/locales/resolve.ts +17 -8
  187. package/src/locales/tr.ts +536 -152
  188. package/src/modals/ConvertModal.vue +62 -11
  189. package/src/modals/DestinationPickerModal.vue +59 -16
  190. package/src/modals/Modal.vue +113 -23
  191. package/src/modals/NewDocumentModal.vue +16 -6
  192. package/src/modals/NewFolderModal.vue +8 -0
  193. package/src/modals/PermissionsModal.vue +272 -163
  194. package/src/modals/PreviewModal.vue +119 -20
  195. package/src/modals/RenameModal.vue +37 -1
  196. package/src/styles/base.css +2890 -260
  197. package/src/styles/sign-fonts.css +118 -0
  198. package/src/styles/variables.css +60 -0
  199. package/src/types/Connections.ts +17 -0
  200. package/src/types/ExplorerConfig.ts +117 -1
  201. package/src/types/FileNode.ts +50 -0
  202. package/src/types/Plugins.ts +494 -0
  203. package/src/types/Public.ts +212 -0
  204. package/src/viewers/ArchiveViewer.vue +93 -48
  205. package/src/viewers/CsvViewer.vue +99 -53
  206. package/src/viewers/DrawioViewer.vue +35 -9
  207. package/src/viewers/EpubViewer.vue +7 -8
  208. package/src/viewers/IpynbViewer.vue +3 -1
  209. package/src/viewers/MermaidViewer.vue +4 -5
  210. package/src/viewers/PdfViewer.vue +8 -17
  211. package/src/viewers/PsdViewer.vue +2 -4
  212. package/src/viewers/TiffViewer.vue +4 -5
  213. package/src/viewers/Viewer3D.vue +1 -1
  214. package/LICENSE +0 -21
  215. package/dist/ArchiveViewer-BUQWLhwX.js +0 -124
  216. package/dist/ArchiveViewer-BUQWLhwX.js.map +0 -1
  217. package/dist/CsvViewer-Bg2_aqzc.js +0 -141
  218. package/dist/CsvViewer-Bg2_aqzc.js.map +0 -1
  219. package/dist/DrawioViewer-CC6rJXeP.js.map +0 -1
  220. package/dist/EpubViewer-CAoTSXTO.js.map +0 -1
  221. package/dist/IpynbViewer-D0GwGpnE.js +0 -184
  222. package/dist/IpynbViewer-D0GwGpnE.js.map +0 -1
  223. package/dist/MermaidViewer-DGwAvRZg.js +0 -137
  224. package/dist/MermaidViewer-DGwAvRZg.js.map +0 -1
  225. package/dist/PsdViewer-DhGweA0m.js +0 -122
  226. package/dist/PsdViewer-DhGweA0m.js.map +0 -1
  227. package/dist/TiffViewer-D0AurvAh.js +0 -142
  228. package/dist/TiffViewer-D0AurvAh.js.map +0 -1
  229. package/dist/Viewer3D-CdZeK4j4.js.map +0 -1
  230. package/dist/index-BArI-B1M.js +0 -26911
  231. package/dist/index-BArI-B1M.js.map +0 -1
  232. package/dist/useViewerFetch-czqbd2Lj.js +0 -25
  233. package/dist/useViewerFetch-czqbd2Lj.js.map +0 -1
  234. package/src/composables/useScrolledX.ts +0 -21
@@ -0,0 +1,118 @@
1
+ /**
2
+ * sign-fonts.css — the five faces a signature may be written in.
3
+ *
4
+ * Three handwriting (Caveat, Dancing Script, Homemade Apple) and two formal
5
+ * (the interface face, Source Serif 4): the closed set `pdf-fields` and
6
+ * `signature-pad` offer, mirrored by `lib/signFonts.ts` (which is what the
7
+ * components and the wire value read — keep the two in step).
8
+ *
9
+ * ⚠⚠ Self-hosted on purpose. A CDN `@font-face` on a signing screen tells a
10
+ * third party that somebody, at this address, is signing a document right
11
+ * now — and on an air-gapped install it silently draws the signature in the
12
+ * wrong face. The `.woff2` files live in `../assets/fonts/`; the bundler
13
+ * emits them beside `style.css`, so every host of the package gets them
14
+ * without wiring anything. See that folder's README for licences.
15
+ *
16
+ * ⚠ These rules cost nothing until they are used: a browser fetches a
17
+ * `@font-face` file only when text is actually laid out in that family, and
18
+ * `unicode-range` narrows it further to the subset the text needs.
19
+ *
20
+ * ⚠ `unicode-range` is copied from the upstream stylesheet. Without it the
21
+ * browser would download the latin-ext file for a plain ASCII name, and —
22
+ * worse — would NOT fall back to the interface face for a glyph the subset
23
+ * does not carry (Homemade Apple has no latin-ext at all: `ş ğ İ` come from
24
+ * the fallback, which is exactly the intended behaviour).
25
+ */
26
+
27
+ /* ── Caveat (OFL 1.1) ─────────────────────────────────────────────────── */
28
+ @font-face {
29
+ font-family: 'Caveat';
30
+ font-style: normal;
31
+ font-weight: 400 700;
32
+ font-display: swap;
33
+ src: url('../assets/fonts/caveat-latin-ext.woff2') format('woff2');
34
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
35
+ U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
36
+ U+2C60-2C7F, U+A720-A7FF;
37
+ }
38
+ @font-face {
39
+ font-family: 'Caveat';
40
+ font-style: normal;
41
+ font-weight: 400 700;
42
+ font-display: swap;
43
+ src: url('../assets/fonts/caveat-latin.woff2') format('woff2');
44
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
45
+ U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
46
+ }
47
+
48
+ /* ── Dancing Script (OFL 1.1) ─────────────────────────────────────────── */
49
+ @font-face {
50
+ font-family: 'Dancing Script';
51
+ font-style: normal;
52
+ font-weight: 400 700;
53
+ font-display: swap;
54
+ src: url('../assets/fonts/dancing-script-latin-ext.woff2') format('woff2');
55
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
56
+ U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
57
+ U+2C60-2C7F, U+A720-A7FF;
58
+ }
59
+ @font-face {
60
+ font-family: 'Dancing Script';
61
+ font-style: normal;
62
+ font-weight: 400 700;
63
+ font-display: swap;
64
+ src: url('../assets/fonts/dancing-script-latin.woff2') format('woff2');
65
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
66
+ U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
67
+ }
68
+
69
+ /* ── Homemade Apple (Apache 2.0) — latin only, see the folder README ──── */
70
+ @font-face {
71
+ font-family: 'Homemade Apple';
72
+ font-style: normal;
73
+ font-weight: 400;
74
+ font-display: swap;
75
+ src: url('../assets/fonts/homemade-apple-latin.woff2') format('woff2');
76
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
77
+ U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
78
+ }
79
+
80
+ /* ── Source Serif 4 (OFL 1.1) ─────────────────────────────────────────── */
81
+ @font-face {
82
+ font-family: 'Source Serif 4';
83
+ font-style: normal;
84
+ font-weight: 200 900;
85
+ font-display: swap;
86
+ src: url('../assets/fonts/source-serif-4-latin-ext.woff2') format('woff2');
87
+ unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
88
+ U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
89
+ U+2C60-2C7F, U+A720-A7FF;
90
+ }
91
+ @font-face {
92
+ font-family: 'Source Serif 4';
93
+ font-style: normal;
94
+ font-weight: 200 900;
95
+ font-display: swap;
96
+ src: url('../assets/fonts/source-serif-4-latin.woff2') format('woff2');
97
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
98
+ U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
99
+ }
100
+
101
+ /* The CSS stack each key resolves to. One definition, read by the pad, by
102
+ the pdf-fields overlay and by anything that later renders a stored value:
103
+ a second copy is how a signature drawn in Caveat comes back in Inter. */
104
+ .fe-signfont--caveat {
105
+ font-family: 'Caveat', cursive;
106
+ }
107
+ .fe-signfont--dancing-script {
108
+ font-family: 'Dancing Script', cursive;
109
+ }
110
+ .fe-signfont--homemade-apple {
111
+ font-family: 'Homemade Apple', cursive;
112
+ }
113
+ .fe-signfont--inter {
114
+ font-family: var(--fe-font);
115
+ }
116
+ .fe-signfont--source-serif {
117
+ font-family: 'Source Serif 4', Georgia, 'Times New Roman', serif;
118
+ }
@@ -64,6 +64,14 @@
64
64
  * new width in Turkish, the longer of the two catalogues — the widest row
65
65
  * label ("Paylaşılanlar") clears it, and so does the quota line. */
66
66
  --fe-sidenav-w: 192px;
67
+ /* The list view's FROZEN LEAD — how far from the pane's left edge the Name
68
+ * column's sticky offset sits, i.e. the width of the tick's track plus the
69
+ * gap after it. Declared here because it is a real default and because a
70
+ * `--fe-*` nobody declares is a name nobody can find (web/tests/api/
71
+ * themeTokens.test.ts), even though ListView writes the exact number inline:
72
+ * only the component knows the tick's track, and it recomputes it whenever
73
+ * the metrics change. */
74
+ --fe-list-lead: calc(var(--fe-h-sm) + var(--fe-gap) + var(--fe-gap-sm));
67
75
  /* Type scale. Small and tight on purpose: the shell packs a filename, a
68
76
  * size, a date and a menu into one row, and 14px with normal leading pushes
69
77
  * that to two lines at any realistic column width. */
@@ -246,3 +254,55 @@
246
254
  it changes nothing visually, it only makes the token real. */
247
255
  --fe-ok: #16a34a;
248
256
  }
257
+
258
+ /* === The outward-facing page's own ground and card =====================
259
+ * The public shell (`/s/`, `/d/`, an app's public page) does NOT paint with
260
+ * `--fe-bg` / `--fe-bg-elev`: in the app those two mean "surface" and
261
+ * "sunken strip", and a card on a page has to sit ABOVE its ground, not
262
+ * below it. Drawing the card in `--fe-bg-elev` on `--fe-bg` is exactly what
263
+ * made the v0.43.0 public page look like no page at all.
264
+ *
265
+ * The values are the Go-rendered page's own, up to v0.42.2 (`--px-bg1`,
266
+ * `--px-bg2`, `--px-card`, `--px-shadow`).
267
+ *
268
+ * ⚠ Declared HERE, in both variants, and not beside the rules that use them:
269
+ * web/tests/api/themeTokens.test.ts reads this file alone, and a `--fe-*`
270
+ * declared anywhere else is a phantom token to every other reader. */
271
+ .fe.fe-ppage {
272
+ --fe-ppage-ground-1: #f5f7fb;
273
+ --fe-ppage-ground-2: #e9edf4;
274
+ --fe-ppage-card: #ffffff;
275
+ --fe-ppage-shadow: 0 12px 40px rgba(15, 23, 42, 0.1);
276
+ --fe-ppage-ok: var(--fe-ok);
277
+ /* The card's width, set by the shell's `layout` (lib/publicLayout):
278
+ the gate's 400px here, 520 and 880 below. */
279
+ --fe-ppage-max: 400px;
280
+ }
281
+ .fe.fe-ppage.fe--theme-dark,
282
+ :root[data-theme='dark'] .fe.fe-ppage,
283
+ :root.dark .fe.fe-ppage,
284
+ .dark .fe.fe-ppage {
285
+ --fe-ppage-ground-1: #12151a;
286
+ --fe-ppage-ground-2: #191e25;
287
+ --fe-ppage-card: #1f242c;
288
+ --fe-ppage-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
289
+ --fe-ppage-ok: #22c55e;
290
+ }
291
+ @media (prefers-color-scheme: dark) {
292
+ .fe.fe-ppage:not(.fe--theme-light) {
293
+ --fe-ppage-ground-1: #12151a;
294
+ --fe-ppage-ground-2: #191e25;
295
+ --fe-ppage-card: #1f242c;
296
+ --fe-ppage-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
297
+ --fe-ppage-ok: #22c55e;
298
+ }
299
+ }
300
+ /* ⚠ `.fe.` on purpose: `.fe.fe-ppage` above is (0,2,0), so a single-class
301
+ modifier LOSES to it and every card came out at the gate's 400px —
302
+ measured on the folder and the signing page at 1440. */
303
+ .fe.fe-ppage--form {
304
+ --fe-ppage-max: 520px;
305
+ }
306
+ .fe.fe-ppage--wide {
307
+ --fe-ppage-max: 880px;
308
+ }
@@ -46,6 +46,23 @@ export interface StorageField {
46
46
  monospace?: boolean;
47
47
  multiline?: boolean;
48
48
  advanced?: boolean;
49
+ /**
50
+ * Draw the choice as BUTTONS rather than a dropdown — every option on the
51
+ * screen, readable without clicking (`components/ChoiceButtons`).
52
+ *
53
+ * ⚠ Set by the DECLARATION, not by the surface drawing it. An app
54
+ * plugin's fields always carry it (v3 §2: "no dropdowns anywhere in a
55
+ * surface", applied by `lib/surfaceValues.storageFieldOf`), and a storage
56
+ * driver may ask for it on a short choice. Branching on "am I in a
57
+ * surface?" inside the renderer would be the same control behaving two
58
+ * ways on two screens, which is the thing this package keeps un-writing.
59
+ *
60
+ * On a `bool` it means the two-button Yes/No decision; a bool without it
61
+ * stays the on/off checkbox a driver setting wants.
62
+ */
63
+ choice?: boolean;
64
+ /** A `select` that takes several of its options; the value is then a list. */
65
+ multi?: boolean;
49
66
  /** THE field that scopes the storage inside the backend (s3 prefix,
50
67
  * local path, sftp/ftp/webdav root). The backend rejects an empty or
51
68
  * "/" value with ROOT_PATH_FORBIDDEN. */
@@ -43,7 +43,14 @@ export type AuthConfig =
43
43
  | { type: 'csrf'; csrf: string };
44
44
 
45
45
  export type ThemeMode = 'light' | 'dark' | 'auto';
46
- export type LocaleCode = 'tr' | 'en';
46
+ /**
47
+ * A language code. `tr` and `en` are the two this package ships a catalogue
48
+ * for; ANY other tag may arrive too — a language pack (an app whose manifest
49
+ * carries `ui_locales`) adds languages at run time, see `lib/uiLocales`.
50
+ * `(string & {})` keeps the two named ones in autocompletion without
51
+ * pretending they are the only ones.
52
+ */
53
+ export type LocaleCode = 'tr' | 'en' | (string & {});
47
54
 
48
55
  /**
49
56
  * Resolved endpoint map. `useFileApi` derives this once on construction
@@ -84,6 +91,16 @@ export interface EndpointMap {
84
91
  /* wiring:e2 */
85
92
  e2eEscrowChallenge: string | null;
86
93
  e2eEscrowUsed: string | null;
94
+ /* App plugins (docs/APP-PLUGINS-API.md). Templates carry `{plugin}`,
95
+ * `{action}`, `{view}` and `{id}` placeholders, filled at call time. */
96
+ pluginActions: string | null;
97
+ pluginActionRun: string | null;
98
+ pluginView: string | null;
99
+ pluginViewEvent: string | null;
100
+ /** `?plugin=<name>&q=` — the people-picker's user lookup (M2). */
101
+ pluginUsers: string | null;
102
+ /** `POST` cancel of a queued/running ops row — `{id}` placeholder. */
103
+ opsCancel: string | null;
87
104
  }
88
105
 
89
106
  export interface ExplorerConfig {
@@ -132,6 +149,59 @@ export interface ExplorerConfig {
132
149
  /** Single op show endpoint — `{id}` placeholder. */
133
150
  opsShow?: string;
134
151
 
152
+ /** Cancel a queued/running op — `{id}` placeholder (plugin jobs). */
153
+ opsCancel?: string;
154
+
155
+ /** App plugins: the actions list, the run template (`{plugin}`/`{action}`),
156
+ * the view template (`{plugin}`/`{view}`) and its `/event` sibling. */
157
+ pluginActions?: string;
158
+ pluginActionRun?: string;
159
+ pluginView?: string;
160
+ pluginViewEvent?: string;
161
+ pluginUsers?: string;
162
+
163
+ /**
164
+ * App plugins (file-menu rows drawn from WebAssembly plugins).
165
+ *
166
+ * Absent: follow the server — `capabilities.app_plugins.enabled`. `false`
167
+ * switches the feature off for this instance whatever the server says, and
168
+ * the explorer then makes no plugin request at all. `true` asks even when
169
+ * the capabilities answer is missing (a host that knows its backend).
170
+ */
171
+ plugins?: boolean;
172
+
173
+ /**
174
+ * Where this host serves the SPA, for an app plugin's `page` view
175
+ * (`${pluginPageBase}apps/{plugin}/{view}?path=…`, lib/pluginPage).
176
+ *
177
+ * ⚠ A mount BASE, not the site root: the same bundle is served from
178
+ * `/admin/` and `/drive/`, and only those prefixes fall back to index.html
179
+ * for an `apps/…` address, so a bare `/apps/…` is a 404 on the server. The
180
+ * host passes the prefix it was itself served from.
181
+ *
182
+ * Absent: a `page` action falls back to the modal — the same conversation
183
+ * in a dialog. A degraded frame, never a missing feature.
184
+ */
185
+ pluginPageBase?: string;
186
+
187
+ /**
188
+ * How this host opens a plugin page. Return `true` when the host handled
189
+ * it; anything else lets the explorer open a browser tab itself.
190
+ *
191
+ * ⚠ The hook exists for shells that have no tabs to open: the desktop app
192
+ * wants its own window (and a `window.open` there lands in the system
193
+ * browser with no session), an embed inside another product may want a
194
+ * panel. The RULE — which actions open a page, and what the address is —
195
+ * stays in the package for all of them (lib/pluginPage).
196
+ */
197
+ openPluginPage?: (target: {
198
+ plugin: string;
199
+ view: string;
200
+ path?: string;
201
+ /** The address the explorer would open, already built from `pluginPageBase`. */
202
+ url: string;
203
+ }) => boolean | void;
204
+
135
205
  /**
136
206
  * OnlyOffice config endpoint. Backend POST returns
137
207
  * `{ config, documentServerUrl }` where `config` is a JWT-signed
@@ -186,6 +256,52 @@ export interface ExplorerConfig {
186
256
  /** Show the virtual `.trash/` entry in the root listing. */
187
257
  trashVisible?: boolean;
188
258
 
259
+ /**
260
+ * paylas:m1 — show the navigation panel's **My shares** row: the public
261
+ * links THIS person handed out, directly under its mirror "Shared with me".
262
+ *
263
+ * Default: OFF, and it is the only row in that group whose default is off
264
+ * for a reason that has nothing to do with taste. Every other entry either
265
+ * opens a listing this component owns (Home, Recent, Starred, Trash, a tag,
266
+ * a storage) or a panel it draws itself ("How to connect", "API keys") —
267
+ * this one opens a page of the HOST. The explorer can announce the intent
268
+ * (`open-my-shares`) and nothing more; a host that does not listen is left
269
+ * with a row that draws, takes a click and does nothing at all. Off by
270
+ * default is therefore the honest default: `<filex-explorer>` on
271
+ * work.example.com, in the fishapp and on fm.example.com has no such page, and a dead
272
+ * row is worse than a missing one.
273
+ *
274
+ * ⚠ Opting in is a promise, not a preference: set it to `true` only if you
275
+ * handle `@open-my-shares`. The SPA does (`web/src/views/Explore.vue` pushes
276
+ * its `my-shares` route), which is why it is the one host that asks for it.
277
+ * Only the Vue component emits it: `<filex-explorer>` and the React
278
+ * `<FileManager>` do not forward `open-my-shares`, so there it cannot be
279
+ * handled and the flag must stay off.
280
+ *
281
+ * ⚠ ANDed with `callerKind`, never ORed: an app token is not a person and
282
+ * has shared nothing, so the row goes with its mirror even for a host that
283
+ * asked for it. See `callerKind`.
284
+ */
285
+ mySharesVisible?: boolean;
286
+
287
+ /**
288
+ * The host draws an app plugin's `home` view as a page of ITS OWN, in the
289
+ * same tab (the SPA's `app-home` route), and handles `@open-app-home`.
290
+ *
291
+ * ⚠⚠ The owner, 2026-09-21: the Signatures screen opened as a dialog over
292
+ * the file list, and it should be "its own page" — the way My shares is,
293
+ * with its sections in a menu, the Back button working, and a
294
+ * notification landing on the right section. The explorer cannot give a
295
+ * host a page; it can only say which one was asked for, so the navigation
296
+ * panel's "Apps" row emits `open-app-home` when this is on.
297
+ *
298
+ * Default: OFF, for the reason `mySharesVisible` is off — only the Vue
299
+ * component emits the event, and a host that does not listen would be
300
+ * left with a row that does nothing. Off, an "Apps" row keeps opening the
301
+ * view in a dialog, which is a smaller frame but a working one.
302
+ */
303
+ appHomePage?: boolean;
304
+
189
305
  /** UI dil kodu */
190
306
  locale?: LocaleCode;
191
307
 
@@ -4,6 +4,8 @@
4
4
  * Backend `?q=index` (or `GET /api/files/manager?action=index`) returns:
5
5
  * { adapter, storages, dirname, files: FileNode[] }
6
6
  */
7
+ import type { AppLock } from './Plugins';
8
+
7
9
  export interface FileNode {
8
10
  /** DB node ID — needed by the per-user meta routes (starred, tags,
9
11
  * recently-opened). Backend's projectFileNodes() emits it for every
@@ -53,6 +55,38 @@ export interface FileNode {
53
55
  /* wiring:e2 — dir rows: true when the folder is E2E-encrypted (carries a
54
56
  * `.filex-e2e.json` marker). Drives the 🔒 badge in the listings. */
55
57
  e2e?: boolean;
58
+ /** An app plugin holds this file read-only (docs/APP-PLUGINS-API.md →
59
+ * "File locks"). `perm` already arrives capped at `viewer` for everyone,
60
+ * administrators included — the flag is what the badge and the details
61
+ * panel say out loud, and what turns the server's 423 into words. */
62
+ locked?: boolean;
63
+ lock?: AppLock;
64
+ /** The state keys apps keep on this file, `<plugin>:<key>`. Read by the
65
+ * menu's state-aware rows (`applies.state` / `no_state`). */
66
+ app_state?: string[];
67
+ /** Issue #34 — this row is a symlink the SERVER WILL NOT FOLLOW. A link
68
+ * whose target is inside the storage root IS followed and arrives as that
69
+ * target (a linked directory is a `dir` and opens normally), so this flag
70
+ * always means "cannot be opened", never merely "is a link".
71
+ *
72
+ * ⚠ Additive, and `type` stays the closed `'file' | 'dir'` union it has
73
+ * always been: widening it would be a breaking change for every embedder
74
+ * of `@brftech/filex`, so the backend reports such a row as a file and
75
+ * flags it here (`handlers/manager.go`). A client that does not know the
76
+ * flag renders exactly the row it rendered before — which is precisely the
77
+ * 0-byte-file-that-will-not-open the issue was filed about, and why
78
+ * `lib/symlink` exists. */
79
+ symlink?: boolean;
80
+ /** Why it will not open — `outside_root` | `broken` | `unresolved`.
81
+ *
82
+ * ⚠⚠ Absent far more often than present: only the cold-cache driver
83
+ * listing carries it. The normal DB-backed listing sends `symlink: true`
84
+ * alone, because `model.Node` has no column for a fact that belongs to the
85
+ * link as it is RIGHT NOW rather than as it was at scan time. Read it
86
+ * through `lib/symlink.linkStateOf`, which answers `'unknown'` for that
87
+ * case — and for a state a newer server invents — instead of dropping the
88
+ * row back into silence. */
89
+ link_state?: string;
56
90
  /** Generic — any additional fields the backend wants to inline. */
57
91
  [k: string]: unknown;
58
92
  }
@@ -126,6 +160,15 @@ export interface Capabilities {
126
160
  * ExplorerConfig.callerKind. Absent on a server older than the app/user
127
161
  * token split, which is why every reader treats "missing" as a person. */
128
162
  caller_kind?: 'user' | 'app';
163
+ /** Could this caller set up a missing optional service (ONLYOFFICE,
164
+ * draw.io, the converter…)? An administrator who can reach the instance
165
+ * settings — not a tenant admin, not an API token. Decides between "greyed
166
+ * with where to fix it" and "not offered" (lib/serviceGate). Absent on an
167
+ * older server, which reads as "no". */
168
+ caller_admin?: boolean;
169
+ /** App plugins (docs/APP-PLUGINS-API.md). Absent or `enabled: false` → the
170
+ * explorer makes no plugin request at all. */
171
+ app_plugins?: { enabled: boolean };
129
172
  /** The address this deployment is reached at — only when it is real (the
130
173
  * operator configured it, or the request came in on a tenant's host).
131
174
  * Read by the connection guides; see `connectionsOrigin`. */
@@ -134,7 +177,14 @@ export interface Capabilities {
134
177
  onlyoffice?: ExternalServiceStatus;
135
178
  drawio?: ExternalServiceStatus;
136
179
  mermaid?: ExternalServiceStatus;
180
+ /** The file converter. ⚠ `convert_url` is filled whenever the service is
181
+ * ENABLED, healthy or not — the menu reads this for health. */
182
+ convert?: ExternalServiceStatus;
137
183
  };
184
+ /** Can outgoing mail be sent right now (SMTP configured AND verified)?
185
+ * Absent on an older server or one with no mailer wired — read as "yes",
186
+ * i.e. keep offering mail the way it always was. */
187
+ mail?: { ready: boolean };
138
188
  /* wiring:e2 */
139
189
  /** Whether this installation holds an escrow key for E2E-encrypted folders,
140
190
  * and the public half the browser wraps new folders' master keys to.