efficient-shell 4.134.0 → 4.137.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 (171) hide show
  1. package/LICENSE +6 -17
  2. package/README.md +84 -8
  3. package/dist/Browser-ZX5OTOKK.js +43 -0
  4. package/dist/Calculator-4SQGOQFQ.js +29 -0
  5. package/dist/ConfirmDialog-NPKW2XHM.js +1 -0
  6. package/dist/CurrencyConverter-2KOM7L6V.js +21 -0
  7. package/dist/Documents-IZTIQYPG.js +52 -0
  8. package/dist/Files-B63KKXGZ.js +89 -0
  9. package/dist/Notepad-WA77V45J.js +25 -0
  10. package/dist/PdfViewer-RBRGEKWF.js +1 -0
  11. package/dist/PomodoroTimer-SDUBKXUS.js +99 -0
  12. package/dist/Preview-D4KOA4OI.js +187 -0
  13. package/dist/Sidebar-Y57LYXXI.js +23 -0
  14. package/dist/Spreadsheet-JX5E6WH6.js +37 -0
  15. package/dist/Stock-XAQ5WMUZ.js +16 -0
  16. package/dist/Weather-HLAGJ5LV.js +60 -0
  17. package/dist/WorldClock-IRI4VCTA.js +32 -0
  18. package/dist/apps/index.js +1 -151
  19. package/dist/brand.css +1 -1
  20. package/dist/chunk-3A46NCXK.js +29 -0
  21. package/dist/chunk-44UO7FYU.js +11 -0
  22. package/dist/chunk-466CM2TJ.js +1 -0
  23. package/dist/chunk-57MIENLJ.js +1 -0
  24. package/dist/chunk-5CRAF2AD.js +2 -0
  25. package/dist/chunk-A2OQLLYK.js +6 -0
  26. package/dist/chunk-B43AGQET.js +4 -0
  27. package/dist/chunk-BR22X7E5.js +1 -0
  28. package/dist/chunk-BUTSU7FO.js +1 -0
  29. package/dist/chunk-D65T4H6J.js +1 -0
  30. package/dist/chunk-ESL5TDNA.js +1 -0
  31. package/dist/chunk-FBDZGO3V.js +1 -0
  32. package/dist/chunk-FHTLC7HH.js +1 -0
  33. package/dist/chunk-FQLMX3IE.js +948 -0
  34. package/dist/chunk-H562R4GX.js +34 -0
  35. package/dist/chunk-JN4WXTWJ.js +106 -0
  36. package/dist/chunk-LVDRBRYU.js +1 -0
  37. package/dist/chunk-LWLCNQY7.js +1 -0
  38. package/dist/chunk-MAIHBBWT.js +1 -0
  39. package/dist/chunk-NPJH5MD7.js +13 -0
  40. package/dist/chunk-OCSOMMY2.js +1 -0
  41. package/dist/chunk-OQDWLHZI.js +1 -0
  42. package/dist/chunk-OWSAMA3I.js +23 -0
  43. package/dist/chunk-PH3PRIFP.js +5 -0
  44. package/dist/chunk-TAWKWSPN.js +9 -0
  45. package/dist/chunk-U4GTZPXP.js +1 -0
  46. package/dist/chunk-UB4JIOLD.js +2 -0
  47. package/dist/chunk-UZAJ5BF6.js +9 -0
  48. package/dist/chunk-VEGMDXT4.js +1 -0
  49. package/dist/chunk-VTVSMRFX.js +1 -0
  50. package/dist/chunk-VVAGSKW7.js +1 -0
  51. package/dist/chunk-XO43FJRM.js +19 -0
  52. package/dist/chunk-Y7BOLDRM.js +69 -0
  53. package/dist/file-intake/index.js +1 -4
  54. package/dist/{index-DZ7E7bCl.d.ts → index-DVI9DMSu.d.ts} +189 -18
  55. package/dist/index.d.ts +2 -2
  56. package/dist/index.js +639 -7473
  57. package/dist/map/index.js +20 -540
  58. package/dist/markdown/index.js +6 -184
  59. package/dist/markup/index.js +1 -135
  60. package/dist/page-tabs/index.js +21 -709
  61. package/dist/sounds-OMHXVVQ4.js +1 -0
  62. package/dist/ui/index.d.ts +1 -1
  63. package/dist/ui/index.js +1 -19
  64. package/dist/ui.css +78 -10
  65. package/package.json +4 -3
  66. package/dist/Browser-O3QZGUF2.js +0 -482
  67. package/dist/Browser-O3QZGUF2.js.map +0 -1
  68. package/dist/Calculator-L6N5X3KU.js +0 -192
  69. package/dist/Calculator-L6N5X3KU.js.map +0 -1
  70. package/dist/ConfirmDialog-LYSSZSUD.js +0 -4
  71. package/dist/ConfirmDialog-LYSSZSUD.js.map +0 -1
  72. package/dist/CurrencyConverter-64MKXB3D.js +0 -236
  73. package/dist/CurrencyConverter-64MKXB3D.js.map +0 -1
  74. package/dist/Documents-5WXXYCLI.js +0 -441
  75. package/dist/Documents-5WXXYCLI.js.map +0 -1
  76. package/dist/Files-AUURUUDN.js +0 -805
  77. package/dist/Files-AUURUUDN.js.map +0 -1
  78. package/dist/Notepad-GPXJVPB7.js +0 -410
  79. package/dist/Notepad-GPXJVPB7.js.map +0 -1
  80. package/dist/PdfViewer-HKO6P4SR.js +0 -5
  81. package/dist/PdfViewer-HKO6P4SR.js.map +0 -1
  82. package/dist/PomodoroTimer-4TQBWLP2.js +0 -633
  83. package/dist/PomodoroTimer-4TQBWLP2.js.map +0 -1
  84. package/dist/Preview-FOZYPKM2.js +0 -2959
  85. package/dist/Preview-FOZYPKM2.js.map +0 -1
  86. package/dist/Sidebar-BPU7RCZP.js +0 -291
  87. package/dist/Sidebar-BPU7RCZP.js.map +0 -1
  88. package/dist/Spreadsheet-3C66BBBF.js +0 -519
  89. package/dist/Spreadsheet-3C66BBBF.js.map +0 -1
  90. package/dist/Stock-IF4IHYLU.js +0 -158
  91. package/dist/Stock-IF4IHYLU.js.map +0 -1
  92. package/dist/Weather-725PFR7T.js +0 -431
  93. package/dist/Weather-725PFR7T.js.map +0 -1
  94. package/dist/WorldClock-UU4NZIQ7.js +0 -202
  95. package/dist/WorldClock-UU4NZIQ7.js.map +0 -1
  96. package/dist/apps/index.js.map +0 -1
  97. package/dist/chunk-2TPTHAKI.js +0 -316
  98. package/dist/chunk-2TPTHAKI.js.map +0 -1
  99. package/dist/chunk-4P44JXDS.js +0 -195
  100. package/dist/chunk-4P44JXDS.js.map +0 -1
  101. package/dist/chunk-5O42JXQE.js +0 -26
  102. package/dist/chunk-5O42JXQE.js.map +0 -1
  103. package/dist/chunk-72CQWN7O.js +0 -547
  104. package/dist/chunk-72CQWN7O.js.map +0 -1
  105. package/dist/chunk-7CCHEEYC.js +0 -94
  106. package/dist/chunk-7CCHEEYC.js.map +0 -1
  107. package/dist/chunk-BE7FZOFU.js +0 -17
  108. package/dist/chunk-BE7FZOFU.js.map +0 -1
  109. package/dist/chunk-D276EMXS.js +0 -57
  110. package/dist/chunk-D276EMXS.js.map +0 -1
  111. package/dist/chunk-D7PYW2QS.js +0 -265
  112. package/dist/chunk-D7PYW2QS.js.map +0 -1
  113. package/dist/chunk-DVZWYWSD.js +0 -26
  114. package/dist/chunk-DVZWYWSD.js.map +0 -1
  115. package/dist/chunk-ET6ID4LP.js +0 -102
  116. package/dist/chunk-ET6ID4LP.js.map +0 -1
  117. package/dist/chunk-GA35NEND.js +0 -56
  118. package/dist/chunk-GA35NEND.js.map +0 -1
  119. package/dist/chunk-GIGV2ZRW.js +0 -70
  120. package/dist/chunk-GIGV2ZRW.js.map +0 -1
  121. package/dist/chunk-IPXN646P.js +0 -14
  122. package/dist/chunk-IPXN646P.js.map +0 -1
  123. package/dist/chunk-IRWSRJ4K.js +0 -48
  124. package/dist/chunk-IRWSRJ4K.js.map +0 -1
  125. package/dist/chunk-IULP5BCD.js +0 -79
  126. package/dist/chunk-IULP5BCD.js.map +0 -1
  127. package/dist/chunk-MGGY74RY.js +0 -14
  128. package/dist/chunk-MGGY74RY.js.map +0 -1
  129. package/dist/chunk-OLJDJYSU.js +0 -13678
  130. package/dist/chunk-OLJDJYSU.js.map +0 -1
  131. package/dist/chunk-PIGDNN5F.js +0 -46
  132. package/dist/chunk-PIGDNN5F.js.map +0 -1
  133. package/dist/chunk-Q2MJVSJT.js +0 -7
  134. package/dist/chunk-Q2MJVSJT.js.map +0 -1
  135. package/dist/chunk-Q3LT745N.js +0 -3710
  136. package/dist/chunk-Q3LT745N.js.map +0 -1
  137. package/dist/chunk-QAGQRNKI.js +0 -145
  138. package/dist/chunk-QAGQRNKI.js.map +0 -1
  139. package/dist/chunk-QRL64J5F.js +0 -503
  140. package/dist/chunk-QRL64J5F.js.map +0 -1
  141. package/dist/chunk-QSKCQUZE.js +0 -1103
  142. package/dist/chunk-QSKCQUZE.js.map +0 -1
  143. package/dist/chunk-R4OQIQYX.js +0 -153
  144. package/dist/chunk-R4OQIQYX.js.map +0 -1
  145. package/dist/chunk-RT6DSB5Y.js +0 -143
  146. package/dist/chunk-RT6DSB5Y.js.map +0 -1
  147. package/dist/chunk-SHQM5CK3.js +0 -549
  148. package/dist/chunk-SHQM5CK3.js.map +0 -1
  149. package/dist/chunk-T4VQHMG4.js +0 -822
  150. package/dist/chunk-T4VQHMG4.js.map +0 -1
  151. package/dist/chunk-TRCWINHF.js +0 -105
  152. package/dist/chunk-TRCWINHF.js.map +0 -1
  153. package/dist/chunk-TW7LPMVR.js +0 -16
  154. package/dist/chunk-TW7LPMVR.js.map +0 -1
  155. package/dist/chunk-W622KQTD.js +0 -465
  156. package/dist/chunk-W622KQTD.js.map +0 -1
  157. package/dist/chunk-X4Q6G253.js +0 -416
  158. package/dist/chunk-X4Q6G253.js.map +0 -1
  159. package/dist/chunk-YNKK7NE3.js +0 -171
  160. package/dist/chunk-YNKK7NE3.js.map +0 -1
  161. package/dist/chunk-YPO6RDMX.js +0 -20
  162. package/dist/chunk-YPO6RDMX.js.map +0 -1
  163. package/dist/file-intake/index.js.map +0 -1
  164. package/dist/index.js.map +0 -1
  165. package/dist/map/index.js.map +0 -1
  166. package/dist/markdown/index.js.map +0 -1
  167. package/dist/markup/index.js.map +0 -1
  168. package/dist/page-tabs/index.js.map +0 -1
  169. package/dist/sounds-NT4DEZGD.js +0 -3
  170. package/dist/sounds-NT4DEZGD.js.map +0 -1
  171. package/dist/ui/index.js.map +0 -1
@@ -1,291 +0,0 @@
1
- import { useAuth } from './chunk-YPO6RDMX.js';
2
- import { startMenuCategories, navVisible, navSections, isSection, isReachable, navIcons, sectionIcons, visibleChildren } from './chunk-GA35NEND.js';
3
- import { BrandMark } from './chunk-TRCWINHF.js';
4
- import { glassStyle, GLASS_INPUT_BG } from './chunk-D276EMXS.js';
5
- import './chunk-IPXN646P.js';
6
- import { useState, useRef, useMemo, useEffect, isValidElement, cloneElement } from 'react';
7
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
-
9
- function Sidebar({
10
- width,
11
- openPage,
12
- profile,
13
- user,
14
- onLogout,
15
- onNavigate,
16
- navSections: navSections2 = navSections,
17
- navIcons: navIcons2 = navIcons,
18
- sectionIcons: sectionIcons2 = sectionIcons,
19
- categories = startMenuCategories,
20
- productName,
21
- productIcon,
22
- adaptiveLogo = false,
23
- logoHasAlpha = null,
24
- logoIsLight = null
25
- }) {
26
- const { hasAnyPerm } = useAuth();
27
- const erpLabels = new Set(categories.erp);
28
- const systemLabels = new Set(categories.system);
29
- const footerLabels = new Set(categories.footer ?? []);
30
- const footerItems = (categories.footerItems ?? []).filter((it) => navVisible(it, hasAnyPerm));
31
- const virtualSections = categories.virtual ?? [];
32
- const [search, setSearch] = useState("");
33
- const [expanded, setExpanded] = useState(/* @__PURE__ */ new Set());
34
- const searchRef = useRef(null);
35
- const toggleExpanded = (label) => {
36
- setExpanded((prev) => {
37
- const next = new Set(prev);
38
- if (next.has(label)) next.delete(label);
39
- else next.add(label);
40
- return next;
41
- });
42
- };
43
- const topItems = navSections2.filter((item) => !isSection(item)).filter((item) => navVisible(item, hasAnyPerm) && isReachable(item, hasAnyPerm));
44
- const erpSections = navSections2.filter((item) => isSection(item) && erpLabels.has(item.label));
45
- const systemSections = navSections2.filter((item) => isSection(item) && systemLabels.has(item.label));
46
- const footerSections = navSections2.filter((item) => isSection(item) && footerLabels.has(item.label));
47
- const getVisibleItems = (section) => {
48
- if (!navVisible(section, hasAnyPerm)) return [];
49
- return section.items.filter((it) => navVisible(it, hasAnyPerm)).filter((it) => isReachable(it, hasAnyPerm));
50
- };
51
- const matchTree = (it, q) => {
52
- if (!navVisible(it, hasAnyPerm)) return [];
53
- if (!isReachable(it, hasAnyPerm)) return [];
54
- const hits = [];
55
- if (it.label.toLowerCase().includes(q)) hits.push(it);
56
- for (const c of visibleChildren(it, hasAnyPerm)) hits.push(...matchTree(c, q));
57
- return hits;
58
- };
59
- const searchResults = useMemo(() => {
60
- if (search.length < 2) return [];
61
- const q = search.toLowerCase();
62
- return [
63
- ...navSections2.flatMap((entry) => {
64
- if (isSection(entry)) {
65
- return getVisibleItems(entry).flatMap((it) => matchTree(it, q));
66
- }
67
- return matchTree(entry, q);
68
- }),
69
- ...footerItems.flatMap((it) => matchTree(it, q))
70
- ];
71
- }, [search, navSections2, footerItems, hasAnyPerm]);
72
- useEffect(() => {
73
- const onKey = (e) => {
74
- if (e.key === "Escape") {
75
- setExpanded(/* @__PURE__ */ new Set());
76
- setSearch("");
77
- } else if (e.key === "/" && document.activeElement?.tagName !== "INPUT" && document.activeElement?.tagName !== "TEXTAREA") {
78
- e.preventDefault();
79
- searchRef.current?.focus();
80
- }
81
- };
82
- window.addEventListener("keydown", onKey);
83
- return () => window.removeEventListener("keydown", onKey);
84
- }, []);
85
- const handleClick = (path) => {
86
- onNavigate(path);
87
- onPageOpenedReset();
88
- };
89
- const select = (item) => {
90
- if (item.onSelect) {
91
- item.onSelect();
92
- onPageOpenedReset();
93
- return;
94
- }
95
- handleClick(item.to);
96
- };
97
- const onPageOpenedReset = () => {
98
- setSearch("");
99
- };
100
- const itemCls = "w-full flex items-center gap-2 rounded-lg px-3 py-2 text-sm";
101
- const menuGlass = glassStyle();
102
- const iconEl = (to) => {
103
- const icon = navIcons2[to];
104
- if (icon && isValidElement(icon)) {
105
- return cloneElement(icon, {
106
- className: "h-4 w-4 shrink-0 text-gray-500"
107
- });
108
- }
109
- return /* @__PURE__ */ jsx("span", { className: "h-4 w-4 shrink-0" });
110
- };
111
- const secIcon = (label) => {
112
- const icon = sectionIcons2[label];
113
- if (icon && isValidElement(icon)) {
114
- return cloneElement(icon, {
115
- className: "h-4 w-4 shrink-0 text-gray-500"
116
- });
117
- }
118
- return /* @__PURE__ */ jsx("span", { className: "h-4 w-4 shrink-0" });
119
- };
120
- const renderItem = (item) => /* @__PURE__ */ jsxs("div", { children: [
121
- /* @__PURE__ */ jsxs(
122
- "button",
123
- {
124
- onClick: () => select(item),
125
- className: `${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`,
126
- children: [
127
- iconEl(item.to),
128
- /* @__PURE__ */ jsx("span", { className: "truncate", children: item.label })
129
- ]
130
- }
131
- ),
132
- item.dividerAfter && /* @__PURE__ */ jsx("div", { className: "border-t border-white/20 my-1.5 mx-2" })
133
- ] }, item.to);
134
- const renderNestedItem = (item) => {
135
- const kids = visibleChildren(item, hasAnyPerm).filter((k) => isReachable(k, hasAnyPerm));
136
- if (kids.length === 0) return renderItem(item);
137
- const key = `child:${item.to}`;
138
- const isOpen = expanded.has(key);
139
- return /* @__PURE__ */ jsxs("div", { children: [
140
- /* @__PURE__ */ jsxs(
141
- "button",
142
- {
143
- onClick: () => toggleExpanded(key),
144
- "aria-expanded": isOpen,
145
- className: `${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`,
146
- children: [
147
- iconEl(item.to),
148
- /* @__PURE__ */ jsx("span", { className: "truncate", children: item.label }),
149
- /* @__PURE__ */ jsx(
150
- "svg",
151
- {
152
- className: `h-3.5 w-3.5 ml-auto text-gray-500 transition-transform ${isOpen ? "rotate-90" : ""}`,
153
- fill: "none",
154
- viewBox: "0 0 24 24",
155
- stroke: "currentColor",
156
- strokeWidth: 2,
157
- children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8.25 4.5l7.5 7.5-7.5 7.5" })
158
- }
159
- )
160
- ]
161
- }
162
- ),
163
- isOpen && /* @__PURE__ */ jsx("div", { className: "pl-4 mt-0.5 mb-1 space-y-0.5", children: kids.map((c) => renderNestedItem(c)) }),
164
- item.dividerAfter && /* @__PURE__ */ jsx("div", { className: "border-t border-white/20 my-1.5 mx-2" })
165
- ] }, item.to);
166
- };
167
- const renderSectionAccordion = (section, isErp, isVirtual = false) => {
168
- const items = isVirtual ? section.items : getVisibleItems(section);
169
- if (items.length === 0) return null;
170
- const isOpen = expanded.has(section.label);
171
- return /* @__PURE__ */ jsxs("div", { children: [
172
- /* @__PURE__ */ jsxs(
173
- "button",
174
- {
175
- onClick: () => toggleExpanded(section.label),
176
- "aria-expanded": isOpen,
177
- className: `${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`,
178
- children: [
179
- "icon" in section && section.icon ? section.icon : secIcon(section.label),
180
- /* @__PURE__ */ jsx("span", { className: `truncate ${isErp ? "font-medium" : ""}`, children: section.label }),
181
- /* @__PURE__ */ jsx(
182
- "svg",
183
- {
184
- className: `h-3.5 w-3.5 ml-auto text-gray-500 transition-transform ${isOpen ? "rotate-90" : ""}`,
185
- fill: "none",
186
- viewBox: "0 0 24 24",
187
- stroke: "currentColor",
188
- strokeWidth: 2,
189
- children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8.25 4.5l7.5 7.5-7.5 7.5" })
190
- }
191
- )
192
- ]
193
- }
194
- ),
195
- isOpen && /* @__PURE__ */ jsx("div", { className: "pl-4 mt-0.5 mb-1 space-y-0.5", children: items.map((it) => renderNestedItem(it)) }),
196
- "dividerAfter" in section && section.dividerAfter && /* @__PURE__ */ jsx("div", { className: "border-t border-white/20 my-1.5 mx-2" })
197
- ] }, section.label);
198
- };
199
- return /* @__PURE__ */ jsxs(
200
- "div",
201
- {
202
- className: "fixed top-0 left-0 bottom-0 z-[260] flex flex-col rounded-r-2xl overflow-hidden",
203
- style: { width, ...menuGlass },
204
- children: [
205
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-3 border-b border-white/15 shrink-0", children: [
206
- productIcon && /* @__PURE__ */ jsx(
207
- BrandMark,
208
- {
209
- src: productIcon,
210
- alt: "",
211
- slot: "compact",
212
- surface: "light",
213
- adaptive: adaptiveLogo,
214
- hasAlpha: logoHasAlpha,
215
- isLight: logoIsLight,
216
- size: 20,
217
- decorative: true,
218
- className: "opacity-80"
219
- }
220
- ),
221
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-gray-800 truncate", children: productName ?? "Apps" })
222
- ] }),
223
- /* @__PURE__ */ jsx("div", { className: "px-3 pt-3 pb-2 shrink-0", children: /* @__PURE__ */ jsxs("div", { className: `flex items-center gap-2 ${GLASS_INPUT_BG} rounded-lg px-2.5 py-1.5`, children: [
224
- /* @__PURE__ */ jsx("svg", { className: "h-3.5 w-3.5 text-gray-400 shrink-0", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" }) }),
225
- /* @__PURE__ */ jsx(
226
- "input",
227
- {
228
- ref: searchRef,
229
- value: search,
230
- onChange: (e) => setSearch(e.target.value),
231
- placeholder: "Search...",
232
- className: "flex-1 bg-transparent text-xs outline-none placeholder-gray-400"
233
- }
234
- ),
235
- search && /* @__PURE__ */ jsx("button", { onClick: () => setSearch(""), className: "text-gray-400 hover:text-gray-600 text-xs", children: "\xD7" })
236
- ] }) }),
237
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto px-1 pb-1", children: search.length >= 2 ? (
238
- // Search results take over the body.
239
- /* @__PURE__ */ jsx("div", { children: searchResults.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-6 text-center text-xs text-gray-400", children: "No matches" }) : searchResults.map((r) => /* @__PURE__ */ jsxs(
240
- "button",
241
- {
242
- onClick: () => select(r),
243
- className: `${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`,
244
- children: [
245
- iconEl(r.to),
246
- /* @__PURE__ */ jsx("span", { className: "truncate", children: r.label })
247
- ]
248
- },
249
- r.to
250
- )) })
251
- ) : /* @__PURE__ */ jsxs(Fragment, { children: [
252
- topItems.map(renderItem),
253
- topItems.length > 0 && (erpSections.length > 0 || systemSections.length > 0 || virtualSections.length > 0) && /* @__PURE__ */ jsx("div", { className: "border-t border-white/15 my-1.5 mx-2" }),
254
- erpSections.map((s) => renderSectionAccordion(s, true)),
255
- systemSections.map((s) => renderSectionAccordion(s, false)),
256
- virtualSections.map((v) => renderSectionAccordion(v, false, true)),
257
- (footerSections.length > 0 || footerItems.length > 0) && /* @__PURE__ */ jsx("div", { className: "border-t border-white/15 my-1.5 mx-2" }),
258
- footerSections.map((s) => renderSectionAccordion(s, false)),
259
- footerItems.map(renderItem)
260
- ] }) }),
261
- /* @__PURE__ */ jsx("div", { className: "border-t border-white/15 p-1 shrink-0", children: /* @__PURE__ */ jsxs(
262
- "div",
263
- {
264
- onClick: () => handleClick("/profile"),
265
- className: "rounded-lg px-2 py-1.5 flex items-center gap-2.5 hover:bg-blue-50 hover:text-blue-700 transition-colors cursor-pointer",
266
- children: [
267
- profile?.avatar_url ? /* @__PURE__ */ jsx("img", { src: profile.avatar_url, alt: "", className: "h-8 w-8 rounded-full object-cover border border-white/20 shrink-0" }) : /* @__PURE__ */ jsx("div", { className: "h-8 w-8 rounded-full bg-blue-100 flex items-center justify-center text-sm font-bold text-blue-700 shrink-0", children: (profile?.first_name?.charAt(0) || user?.email?.charAt(0) || "?").toUpperCase() }),
268
- /* @__PURE__ */ jsx("p", { className: "flex-1 min-w-0 text-sm font-medium text-gray-900 truncate", children: profile?.first_name ? `${profile.first_name} ${profile.last_name || ""}`.trim() : user?.email }),
269
- /* @__PURE__ */ jsx(
270
- "button",
271
- {
272
- onClick: (e) => {
273
- e.stopPropagation();
274
- onLogout();
275
- },
276
- title: "Sign Out",
277
- className: "shrink-0 p-1.5 rounded-md text-gray-500 hover:text-red-600 hover:bg-red-50 transition-colors",
278
- children: /* @__PURE__ */ jsx("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15m3 0l3-3m0 0l-3-3m3 3H9" }) })
279
- }
280
- )
281
- ]
282
- }
283
- ) })
284
- ]
285
- }
286
- );
287
- }
288
-
289
- export { Sidebar as default };
290
- //# sourceMappingURL=Sidebar-BPU7RCZP.js.map
291
- //# sourceMappingURL=Sidebar-BPU7RCZP.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/shell/Sidebar.tsx"],"names":["navSections","navIcons","sectionIcons"],"mappings":"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","file":"Sidebar-BPU7RCZP.js","sourcesContent":["/**\n * Sidebar — persistent left strip used when `prefs.layout_mode === 'sidebar'`.\n *\n * Same configuration surface as <StartMenu> (navSections, navIcons,\n * sectionIcons, categories) but rendered inline:\n * - No flyouts. Sections expand/collapse accordion-style below their\n * header, indented one step.\n * - No taskbar-anchored positioning — fixed full-height left strip,\n * width pulled from `--sidebar-width`.\n * - Right edge `rounded-r-2xl` so it matches windowed cards on the\n * right (which use `rounded-2xl`).\n *\n * Designed for small-screen layouts where flyouts would clip and where\n * keeping the menu always-visible saves a tap to switch apps.\n */\n\nimport { useEffect, useMemo, useRef, useState, isValidElement, cloneElement, type ReactElement, type ReactNode } from 'react';\nimport {\n navSections as defaultNavSections,\n navIcons as defaultNavIcons,\n sectionIcons as defaultSectionIcons,\n startMenuCategories as defaultCategories,\n isSection,\n type NavSection,\n type NavItem,\n type StartMenuCategories,\n type VirtualSection,\n} from '../shell-config/nav';\nimport { visibleChildren, isReachable, navVisible } from './nav-types';\nimport { useAuth } from '../contexts/AuthContext';\nimport { glassStyle, GLASS_INPUT_BG } from '../utils/glass';\nimport BrandMark from '../forms/BrandMark';\n\ninterface SidebarProps {\n width: number;\n openPage: (path: string) => void;\n profile: any;\n user: any;\n onLogout: () => void;\n onNavigate: (path: string) => void;\n navSections?: (NavSection | NavItem)[];\n navIcons?: Record<string, ReactNode>;\n sectionIcons?: Record<string, ReactNode>;\n categories?: StartMenuCategories;\n productName?: string;\n productIcon?: string;\n adaptiveLogo?: boolean;\n logoHasAlpha?: boolean | null;\n logoIsLight?: boolean | null;\n}\n\nexport default function Sidebar({\n width,\n openPage,\n profile,\n user,\n onLogout,\n onNavigate,\n navSections = defaultNavSections,\n navIcons = defaultNavIcons,\n sectionIcons = defaultSectionIcons,\n categories = defaultCategories,\n productName,\n productIcon,\n adaptiveLogo = false,\n logoHasAlpha = null,\n logoIsLight = null,\n}: SidebarProps) {\n const { hasAnyPerm } = useAuth();\n const erpLabels = new Set(categories.erp);\n const systemLabels = new Set(categories.system);\n const footerLabels = new Set(categories.footer ?? []);\n // Flat rows pinned to the footer (next to the profile) — rendered inline,\n // not as an accordion section. Mirrors StartMenu's `footerItems`.\n const footerItems = (categories.footerItems ?? []).filter(it => navVisible(it, hasAnyPerm));\n const virtualSections = categories.virtual ?? [];\n\n const [search, setSearch] = useState('');\n const [expanded, setExpanded] = useState<Set<string>>(new Set());\n const searchRef = useRef<HTMLInputElement>(null);\n\n const toggleExpanded = (label: string) => {\n setExpanded(prev => {\n const next = new Set(prev);\n if (next.has(label)) next.delete(label);\n else next.add(label);\n return next;\n });\n };\n\n // Top-level items vs sections, mirroring StartMenu's split — and its\n // permission + reachability filter on the top-level rows, which the divider\n // below is derived from.\n const topItems = (navSections.filter(item => !isSection(item)) as NavItem[])\n .filter(item => navVisible(item, hasAnyPerm) && isReachable(item, hasAnyPerm));\n const erpSections = navSections.filter(item => isSection(item) && erpLabels.has((item as NavSection).label)) as NavSection[];\n const systemSections = navSections.filter(item => isSection(item) && systemLabels.has((item as NavSection).label)) as NavSection[];\n const footerSections = navSections.filter(item => isSection(item) && footerLabels.has((item as NavSection).label)) as NavSection[];\n\n const getVisibleItems = (section: { items: NavItem[]; perms?: string[]; allPerms?: string[] }) => {\n if (!navVisible(section, hasAnyPerm)) return [];\n return section.items\n .filter(it => navVisible(it, hasAnyPerm))\n // Same rule as <StartMenu>: a group whose children are all\n // permission-hidden has nothing to expand, and its `to` is a synthetic\n // key that never navigates — so drop it rather than leave an inert row.\n .filter(it => isReachable(it, hasAnyPerm));\n };\n\n // Search across all items + sections (same flat list StartMenu uses).\n // Walks 3rd-level children too so nested entries are still discoverable.\n const matchTree = (it: NavItem, q: string): NavItem[] => {\n if (!navVisible(it, hasAnyPerm)) return [];\n if (!isReachable(it, hasAnyPerm)) return [];\n const hits: NavItem[] = [];\n if (it.label.toLowerCase().includes(q)) hits.push(it);\n for (const c of visibleChildren(it, hasAnyPerm)) hits.push(...matchTree(c, q));\n return hits;\n };\n const searchResults = useMemo(() => {\n if (search.length < 2) return [] as NavItem[];\n const q = search.toLowerCase();\n return [\n ...navSections.flatMap((entry) => {\n if (isSection(entry)) {\n return getVisibleItems(entry).flatMap(it => matchTree(it, q));\n }\n return matchTree(entry as NavItem, q);\n }),\n ...footerItems.flatMap(it => matchTree(it, q)),\n ];\n }, [search, navSections, footerItems, hasAnyPerm]);\n\n // Esc collapses any expanded section + clears search; '/' focuses search.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setExpanded(new Set());\n setSearch('');\n } else if (e.key === '/' && document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') {\n e.preventDefault();\n searchRef.current?.focus();\n }\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n const handleClick = (path: string) => {\n onNavigate(path);\n onPageOpenedReset();\n };\n // A row is a destination (`to`) unless it carries an action of its own.\n const select = (item: NavItem) => {\n if (item.onSelect) {\n item.onSelect();\n onPageOpenedReset();\n return;\n }\n handleClick(item.to);\n };\n\n // Reset search after navigating so the next visit starts clean.\n const onPageOpenedReset = () => {\n setSearch('');\n };\n\n const itemCls = 'w-full flex items-center gap-2 rounded-lg px-3 py-2 text-sm';\n const menuGlass = glassStyle();\n\n // Helper that returns the (possibly recolored) per-route icon.\n const iconEl = (to: string) => {\n const icon = navIcons[to];\n if (icon && isValidElement(icon)) {\n return cloneElement(icon as ReactElement<{ className?: string }>, {\n className: 'h-4 w-4 shrink-0 text-gray-500',\n });\n }\n return <span className=\"h-4 w-4 shrink-0\" />;\n };\n\n const secIcon = (label: string) => {\n const icon = sectionIcons[label];\n if (icon && isValidElement(icon)) {\n return cloneElement(icon as ReactElement<{ className?: string }>, {\n className: 'h-4 w-4 shrink-0 text-gray-500',\n });\n }\n return <span className=\"h-4 w-4 shrink-0\" />;\n };\n\n const renderItem = (item: NavItem) => (\n <div key={item.to}>\n <button\n onClick={() => select(item)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}\n >\n {iconEl(item.to)}\n <span className=\"truncate\">{item.label}</span>\n </button>\n {item.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n );\n\n // A NavItem with children becomes its own mini-accordion, indented one step\n // further — and so does one of ITS children, for as many levels as the nav\n // data has. Recursion rather than a hand-written level: the version that\n // rendered the children of a child as plain rows silently dropped everything\n // below the third level, the same cap <StartMenu>'s flyouts used to have.\n // Expansion key is `child:<to>` so it doesn't clash with the section labels\n // in `expanded`.\n const renderNestedItem = (item: NavItem): ReactNode => {\n const kids = visibleChildren(item, hasAnyPerm).filter(k => isReachable(k, hasAnyPerm));\n if (kids.length === 0) return renderItem(item);\n const key = `child:${item.to}`;\n const isOpen = expanded.has(key);\n return (\n <div key={item.to}>\n <button\n onClick={() => toggleExpanded(key)}\n aria-expanded={isOpen}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}\n >\n {iconEl(item.to)}\n <span className=\"truncate\">{item.label}</span>\n <svg\n className={`h-3.5 w-3.5 ml-auto text-gray-500 transition-transform ${isOpen ? 'rotate-90' : ''}`}\n fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8.25 4.5l7.5 7.5-7.5 7.5\" />\n </svg>\n </button>\n {isOpen && (\n <div className=\"pl-4 mt-0.5 mb-1 space-y-0.5\">\n {kids.map(c => renderNestedItem(c))}\n </div>\n )}\n {item.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n );\n };\n\n // `isVirtual` is passed, not sniffed: this used to test `'perms' in section`,\n // which is false for a real section that sets no `perms` of its own, so every\n // row inside one skipped the permission filter.\n const renderSectionAccordion = (section: NavSection | VirtualSection, isErp: boolean, isVirtual = false) => {\n const items = isVirtual\n ? section.items\n : getVisibleItems(section as NavSection);\n if (items.length === 0) return null;\n const isOpen = expanded.has(section.label);\n return (\n <div key={section.label}>\n <button\n onClick={() => toggleExpanded(section.label)}\n aria-expanded={isOpen}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}\n >\n {'icon' in section && section.icon\n ? section.icon\n : secIcon(section.label)}\n <span className={`truncate ${isErp ? 'font-medium' : ''}`}>{section.label}</span>\n <svg\n className={`h-3.5 w-3.5 ml-auto text-gray-500 transition-transform ${isOpen ? 'rotate-90' : ''}`}\n fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8.25 4.5l7.5 7.5-7.5 7.5\" />\n </svg>\n </button>\n {isOpen && (\n <div className=\"pl-4 mt-0.5 mb-1 space-y-0.5\">\n {items.map(it => renderNestedItem(it))}\n </div>\n )}\n {'dividerAfter' in section && section.dividerAfter && <div className=\"border-t border-white/20 my-1.5 mx-2\" />}\n </div>\n );\n };\n\n return (\n <div\n className=\"fixed top-0 left-0 bottom-0 z-[260] flex flex-col rounded-r-2xl overflow-hidden\"\n style={{ width, ...menuGlass }}\n >\n {/* Brand */}\n <div className=\"flex items-center gap-2 px-4 py-3 border-b border-white/15 shrink-0\">\n {productIcon && (\n <BrandMark\n src={productIcon}\n alt=\"\"\n slot=\"compact\"\n surface=\"light\"\n adaptive={adaptiveLogo}\n hasAlpha={logoHasAlpha}\n isLight={logoIsLight}\n size={20}\n decorative\n className=\"opacity-80\"\n />\n )}\n <span className=\"text-sm font-semibold text-gray-800 truncate\">{productName ?? 'Apps'}</span>\n </div>\n\n {/* Search */}\n <div className=\"px-3 pt-3 pb-2 shrink-0\">\n <div className={`flex items-center gap-2 ${GLASS_INPUT_BG} rounded-lg px-2.5 py-1.5`}>\n <svg className=\"h-3.5 w-3.5 text-gray-400 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z\" />\n </svg>\n <input\n ref={searchRef}\n value={search}\n onChange={e => setSearch(e.target.value)}\n placeholder=\"Search...\"\n className=\"flex-1 bg-transparent text-xs outline-none placeholder-gray-400\"\n />\n {search && (\n <button onClick={() => setSearch('')} className=\"text-gray-400 hover:text-gray-600 text-xs\">×</button>\n )}\n </div>\n </div>\n\n {/* Body */}\n <div className=\"flex-1 overflow-y-auto px-1 pb-1\">\n {search.length >= 2 ? (\n // Search results take over the body.\n <div>\n {searchResults.length === 0 ? (\n <div className=\"px-3 py-6 text-center text-xs text-gray-400\">No matches</div>\n ) : (\n searchResults.map(r => (\n <button\n key={r.to}\n onClick={() => select(r)}\n className={`${itemCls} text-gray-700 hover:bg-blue-50 hover:text-blue-700 transition-colors`}\n >\n {iconEl(r.to)}\n <span className=\"truncate\">{r.label}</span>\n </button>\n ))\n )}\n </div>\n ) : (\n <>\n {/* Top-level apps */}\n {topItems.map(renderItem)}\n\n {/* Divider only when both sides have content — with every top-group\n entry moved into the footer group the top group can be empty, and\n an unconditional rule would collapse against the search box\n (mirrors StartMenu's hasAppsGroup condition). */}\n {topItems.length > 0 && (erpSections.length > 0 || systemSections.length > 0 || virtualSections.length > 0) && (\n <div className=\"border-t border-white/15 my-1.5 mx-2\" />\n )}\n\n {/* ERP sections then system sections — same order as StartMenu's vertical layout. */}\n {erpSections.map(s => renderSectionAccordion(s, true))}\n {systemSections.map(s => renderSectionAccordion(s, false))}\n {virtualSections.map(v => renderSectionAccordion(v, false, true))}\n {/* Footer items + sections: pinned just above the profile, divided from the rest. */}\n {(footerSections.length > 0 || footerItems.length > 0) && <div className=\"border-t border-white/15 my-1.5 mx-2\" />}\n {footerSections.map(s => renderSectionAccordion(s, false))}\n {footerItems.map(renderItem)}\n </>\n )}\n </div>\n\n {/* Profile + Sign out at the bottom — mirrors StartMenu's user row. */}\n <div className=\"border-t border-white/15 p-1 shrink-0\">\n <div\n onClick={() => handleClick('/profile')}\n className=\"rounded-lg px-2 py-1.5 flex items-center gap-2.5 hover:bg-blue-50 hover:text-blue-700 transition-colors cursor-pointer\"\n >\n {profile?.avatar_url ? (\n <img src={profile.avatar_url} alt=\"\" className=\"h-8 w-8 rounded-full object-cover border border-white/20 shrink-0\" />\n ) : (\n <div className=\"h-8 w-8 rounded-full bg-blue-100 flex items-center justify-center text-sm font-bold text-blue-700 shrink-0\">\n {(profile?.first_name?.charAt(0) || user?.email?.charAt(0) || '?').toUpperCase()}\n </div>\n )}\n <p className=\"flex-1 min-w-0 text-sm font-medium text-gray-900 truncate\">\n {profile?.first_name ? `${profile.first_name} ${profile.last_name || ''}`.trim() : user?.email}\n </p>\n <button\n onClick={e => { e.stopPropagation(); onLogout(); }}\n title=\"Sign Out\"\n className=\"shrink-0 p-1.5 rounded-md text-gray-500 hover:text-red-600 hover:bg-red-50 transition-colors\"\n >\n <svg className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.5}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15m3 0l3-3m0 0l-3-3m3 3H9\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n );\n}\n"]}