@alepha/devtools 0.16.0 → 0.19.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 (236) hide show
  1. package/README.md +1 -5
  2. package/dist/index.browser.js +224 -0
  3. package/dist/index.browser.js.map +1 -0
  4. package/dist/index.d.ts +349 -321
  5. package/dist/index.js +293 -186
  6. package/dist/index.js.map +1 -1
  7. package/package.json +30 -23
  8. package/src/assets.ts +6 -0
  9. package/src/{api/entities → entities}/logs.ts +2 -2
  10. package/src/index.browser.ts +11 -0
  11. package/src/index.shared.ts +15 -0
  12. package/src/index.ts +11 -37
  13. package/src/{api/providers → providers}/DevToolsMetadataProvider.ts +84 -47
  14. package/src/providers/DevToolsProvider.ts +280 -0
  15. package/src/{api/schemas → schemas}/DevActionMetadata.ts +8 -0
  16. package/src/{api/schemas → schemas}/DevEntityMetadata.ts +3 -0
  17. package/src/{api/schemas → schemas}/DevMetadata.ts +13 -2
  18. package/src/{api/schemas → schemas}/DevPageMetadata.ts +3 -0
  19. package/src/{api/schemas → schemas}/DevTopicMetadata.ts +1 -0
  20. package/src/ui/AppRouter.tsx +55 -59
  21. package/src/ui/components/DevLayout.tsx +104 -84
  22. package/src/ui/components/configuration/ConfigAtoms.page.tsx +5 -0
  23. package/src/ui/components/configuration/ConfigAtoms.tsx +511 -0
  24. package/src/ui/components/configuration/ConfigEnv.page.tsx +5 -0
  25. package/src/ui/components/configuration/ConfigEnv.tsx +230 -0
  26. package/src/ui/components/configuration/DevConfiguration.tsx +36 -0
  27. package/src/ui/components/configuration/index.ts +3 -0
  28. package/src/ui/components/dashboard/DevDashboard.tsx +482 -0
  29. package/src/ui/components/database/DatabaseEditor.page.tsx +23 -0
  30. package/src/ui/components/database/DatabaseEditor.tsx +399 -0
  31. package/src/ui/components/database/DatabaseErd.page.tsx +28 -0
  32. package/src/ui/components/database/DatabaseErd.tsx +107 -0
  33. package/src/ui/components/database/DevDatabase.tsx +36 -0
  34. package/src/ui/components/database/EntityNode.tsx +83 -0
  35. package/src/ui/components/explorer/DevExplorer.tsx +351 -0
  36. package/src/ui/components/explorer/ExplorerTree.tsx +178 -0
  37. package/src/ui/components/explorer/panels/DevPanelAction.tsx +499 -0
  38. package/src/ui/components/explorer/panels/DevPanelCache.tsx +73 -0
  39. package/src/ui/components/explorer/panels/DevPanelPage.tsx +96 -0
  40. package/src/ui/components/explorer/panels/DevPanelQueue.tsx +51 -0
  41. package/src/ui/components/explorer/panels/DevPanelTopic.tsx +56 -0
  42. package/src/ui/components/explorer/panels/index.ts +5 -0
  43. package/src/ui/components/graph/DevDependencyGraph.tsx +35 -60
  44. package/src/ui/components/graph/GraphControls.tsx +10 -11
  45. package/src/ui/components/graph/NodeDetails.tsx +22 -29
  46. package/src/ui/components/graph/ProviderNode.tsx +4 -4
  47. package/src/ui/components/graph/helpers.ts +1 -1
  48. package/src/ui/components/logs/DevLogs.tsx +661 -0
  49. package/src/ui/components/logs/index.ts +1 -0
  50. package/src/ui/components/shared/TreeView.tsx +189 -0
  51. package/src/ui/main.css +17 -0
  52. package/src/ui/main.ts +2 -6
  53. package/LICENSE +0 -21
  54. package/assets/devtools/actions.html +0 -21
  55. package/assets/devtools/actions.html.br +0 -0
  56. package/assets/devtools/actions.html.gz +0 -0
  57. package/assets/devtools/asset.BJSLFcNT.css +0 -1
  58. package/assets/devtools/asset.BJSLFcNT.css.br +0 -0
  59. package/assets/devtools/asset.BJSLFcNT.css.gz +0 -0
  60. package/assets/devtools/asset.BZV40eAE.css +0 -1
  61. package/assets/devtools/asset.BZV40eAE.css.br +0 -0
  62. package/assets/devtools/asset.BZV40eAE.css.gz +0 -0
  63. package/assets/devtools/atoms.html +0 -21
  64. package/assets/devtools/atoms.html.br +0 -0
  65. package/assets/devtools/atoms.html.gz +0 -0
  66. package/assets/devtools/caches.html +0 -21
  67. package/assets/devtools/caches.html.br +0 -0
  68. package/assets/devtools/caches.html.gz +0 -0
  69. package/assets/devtools/chunk.1h5GuATm.js +0 -1
  70. package/assets/devtools/chunk.1h5GuATm.js.br +0 -0
  71. package/assets/devtools/chunk.1h5GuATm.js.gz +0 -0
  72. package/assets/devtools/chunk.3PgxxOdM.js +0 -1
  73. package/assets/devtools/chunk.3PgxxOdM.js.br +0 -0
  74. package/assets/devtools/chunk.3PgxxOdM.js.gz +0 -0
  75. package/assets/devtools/chunk.A_W3H6Aa.js +0 -1
  76. package/assets/devtools/chunk.A_W3H6Aa.js.br +0 -0
  77. package/assets/devtools/chunk.A_W3H6Aa.js.gz +0 -0
  78. package/assets/devtools/chunk.B5tL0VjH.js +0 -1
  79. package/assets/devtools/chunk.B5tL0VjH.js.br +0 -0
  80. package/assets/devtools/chunk.B5tL0VjH.js.gz +0 -0
  81. package/assets/devtools/chunk.B8p_Szro.js +0 -1
  82. package/assets/devtools/chunk.B8p_Szro.js.br +0 -0
  83. package/assets/devtools/chunk.B8p_Szro.js.gz +0 -0
  84. package/assets/devtools/chunk.BANy8c2v.js +0 -1
  85. package/assets/devtools/chunk.BANy8c2v.js.br +0 -0
  86. package/assets/devtools/chunk.BANy8c2v.js.gz +0 -0
  87. package/assets/devtools/chunk.BKph0hv1.js +0 -1
  88. package/assets/devtools/chunk.BKph0hv1.js.br +0 -0
  89. package/assets/devtools/chunk.BKph0hv1.js.gz +0 -0
  90. package/assets/devtools/chunk.BUs1kuwE.js +0 -1
  91. package/assets/devtools/chunk.BUs1kuwE.js.br +0 -0
  92. package/assets/devtools/chunk.BUs1kuwE.js.gz +0 -0
  93. package/assets/devtools/chunk.BVIEr21R.js +0 -1
  94. package/assets/devtools/chunk.BVIEr21R.js.br +0 -0
  95. package/assets/devtools/chunk.BVIEr21R.js.gz +0 -0
  96. package/assets/devtools/chunk.Bb3re2d8.js +0 -1
  97. package/assets/devtools/chunk.Bb3re2d8.js.br +0 -2
  98. package/assets/devtools/chunk.Bb3re2d8.js.gz +0 -0
  99. package/assets/devtools/chunk.BjFrJKj1.js +0 -1
  100. package/assets/devtools/chunk.BjFrJKj1.js.br +0 -2
  101. package/assets/devtools/chunk.BjFrJKj1.js.gz +0 -0
  102. package/assets/devtools/chunk.BkXzz14p.js +0 -1
  103. package/assets/devtools/chunk.BkXzz14p.js.br +0 -0
  104. package/assets/devtools/chunk.BkXzz14p.js.gz +0 -0
  105. package/assets/devtools/chunk.BlqFPyLh.js +0 -1
  106. package/assets/devtools/chunk.BlqFPyLh.js.br +0 -0
  107. package/assets/devtools/chunk.BlqFPyLh.js.gz +0 -0
  108. package/assets/devtools/chunk.BymZ9jU5.js +0 -1
  109. package/assets/devtools/chunk.BymZ9jU5.js.br +0 -0
  110. package/assets/devtools/chunk.BymZ9jU5.js.gz +0 -0
  111. package/assets/devtools/chunk.C0BD3Ujz.js +0 -1
  112. package/assets/devtools/chunk.C0BD3Ujz.js.br +0 -0
  113. package/assets/devtools/chunk.C0BD3Ujz.js.gz +0 -0
  114. package/assets/devtools/chunk.C63rzhbT.js +0 -1
  115. package/assets/devtools/chunk.C63rzhbT.js.br +0 -0
  116. package/assets/devtools/chunk.C63rzhbT.js.gz +0 -0
  117. package/assets/devtools/chunk.CJrYVzjN.js +0 -9
  118. package/assets/devtools/chunk.CJrYVzjN.js.br +0 -0
  119. package/assets/devtools/chunk.CJrYVzjN.js.gz +0 -0
  120. package/assets/devtools/chunk.CPGX3Xpx.js +0 -1
  121. package/assets/devtools/chunk.CPGX3Xpx.js.br +0 -1
  122. package/assets/devtools/chunk.CPGX3Xpx.js.gz +0 -0
  123. package/assets/devtools/chunk.Cf-3skUw.js +0 -1
  124. package/assets/devtools/chunk.Cf-3skUw.js.br +0 -0
  125. package/assets/devtools/chunk.Cf-3skUw.js.gz +0 -0
  126. package/assets/devtools/chunk.D7JLxcoJ.js +0 -7
  127. package/assets/devtools/chunk.D7JLxcoJ.js.br +0 -0
  128. package/assets/devtools/chunk.D7JLxcoJ.js.gz +0 -0
  129. package/assets/devtools/chunk.D7e5mBY4.js +0 -1
  130. package/assets/devtools/chunk.D7e5mBY4.js.br +0 -0
  131. package/assets/devtools/chunk.D7e5mBY4.js.gz +0 -0
  132. package/assets/devtools/chunk.DClU9Z1_.js +0 -1
  133. package/assets/devtools/chunk.DClU9Z1_.js.br +0 -0
  134. package/assets/devtools/chunk.DClU9Z1_.js.gz +0 -0
  135. package/assets/devtools/chunk.DE_M8b3Z.js +0 -1
  136. package/assets/devtools/chunk.DE_M8b3Z.js.br +0 -0
  137. package/assets/devtools/chunk.DE_M8b3Z.js.gz +0 -0
  138. package/assets/devtools/chunk.DWASJDBE.js +0 -1
  139. package/assets/devtools/chunk.DWASJDBE.js.br +0 -0
  140. package/assets/devtools/chunk.DWASJDBE.js.gz +0 -0
  141. package/assets/devtools/chunk.DfzRLqwW.js +0 -1
  142. package/assets/devtools/chunk.DfzRLqwW.js.br +0 -0
  143. package/assets/devtools/chunk.DfzRLqwW.js.gz +0 -0
  144. package/assets/devtools/chunk.Dww1YQtc.js +0 -1
  145. package/assets/devtools/chunk.Dww1YQtc.js.br +0 -0
  146. package/assets/devtools/chunk.Dww1YQtc.js.gz +0 -0
  147. package/assets/devtools/chunk.HFLdduaf.js +0 -1
  148. package/assets/devtools/chunk.HFLdduaf.js.br +0 -0
  149. package/assets/devtools/chunk.HFLdduaf.js.gz +0 -0
  150. package/assets/devtools/chunk.J-htqECs.js +0 -1
  151. package/assets/devtools/chunk.J-htqECs.js.br +0 -2
  152. package/assets/devtools/chunk.J-htqECs.js.gz +0 -0
  153. package/assets/devtools/chunk.JjTGVewZ.js +0 -2
  154. package/assets/devtools/chunk.JjTGVewZ.js.br +0 -0
  155. package/assets/devtools/chunk.JjTGVewZ.js.gz +0 -0
  156. package/assets/devtools/chunk.OV_89czZ.js +0 -1
  157. package/assets/devtools/chunk.OV_89czZ.js.br +0 -0
  158. package/assets/devtools/chunk.OV_89czZ.js.gz +0 -0
  159. package/assets/devtools/chunk.YFkMUqFM.js +0 -1
  160. package/assets/devtools/chunk.YFkMUqFM.js.br +0 -0
  161. package/assets/devtools/chunk.YFkMUqFM.js.gz +0 -0
  162. package/assets/devtools/chunk._KdUFIrt.js +0 -1
  163. package/assets/devtools/chunk._KdUFIrt.js.br +0 -0
  164. package/assets/devtools/chunk._KdUFIrt.js.gz +0 -0
  165. package/assets/devtools/chunk.pjP6xqG8.js +0 -1
  166. package/assets/devtools/chunk.pjP6xqG8.js.br +0 -0
  167. package/assets/devtools/chunk.pjP6xqG8.js.gz +0 -0
  168. package/assets/devtools/chunk.uTFtY0ae.js +0 -2
  169. package/assets/devtools/chunk.uTFtY0ae.js.br +0 -0
  170. package/assets/devtools/chunk.uTFtY0ae.js.gz +0 -0
  171. package/assets/devtools/chunk.uyVen0u2.js +0 -1
  172. package/assets/devtools/chunk.uyVen0u2.js.br +0 -0
  173. package/assets/devtools/chunk.uyVen0u2.js.gz +0 -0
  174. package/assets/devtools/chunk.vHjNjQS8.js +0 -1
  175. package/assets/devtools/chunk.vHjNjQS8.js.br +0 -0
  176. package/assets/devtools/chunk.vHjNjQS8.js.gz +0 -0
  177. package/assets/devtools/db.html +0 -21
  178. package/assets/devtools/db.html.br +0 -0
  179. package/assets/devtools/db.html.gz +0 -0
  180. package/assets/devtools/entry.DhzNl8q_.js +0 -79
  181. package/assets/devtools/entry.DhzNl8q_.js.br +0 -0
  182. package/assets/devtools/entry.DhzNl8q_.js.gz +0 -0
  183. package/assets/devtools/env.html +0 -21
  184. package/assets/devtools/env.html.br +0 -0
  185. package/assets/devtools/env.html.gz +0 -0
  186. package/assets/devtools/graph.html +0 -22
  187. package/assets/devtools/graph.html.br +0 -0
  188. package/assets/devtools/graph.html.gz +0 -0
  189. package/assets/devtools/index.html +0 -21
  190. package/assets/devtools/index.html.br +0 -0
  191. package/assets/devtools/index.html.gz +0 -0
  192. package/assets/devtools/logs.html +0 -21
  193. package/assets/devtools/logs.html.br +0 -0
  194. package/assets/devtools/logs.html.gz +0 -0
  195. package/assets/devtools/queues.html +0 -21
  196. package/assets/devtools/queues.html.br +0 -0
  197. package/assets/devtools/queues.html.gz +0 -0
  198. package/assets/devtools/topics.html +0 -21
  199. package/assets/devtools/topics.html.br +0 -0
  200. package/assets/devtools/topics.html.gz +0 -0
  201. package/src/api/DevToolsProvider.ts +0 -157
  202. package/src/api/providers/DevToolsDatabaseProvider.ts +0 -27
  203. package/src/api/repositories/LogRepository.ts +0 -8
  204. package/src/api/schemas/DevCommandMetadata.ts +0 -9
  205. package/src/ui/components/DevAtomsViewer.tsx +0 -637
  206. package/src/ui/components/DevCacheInspector.tsx +0 -423
  207. package/src/ui/components/DevDashboard.tsx +0 -38
  208. package/src/ui/components/DevEnvExplorer.tsx +0 -462
  209. package/src/ui/components/DevLogViewer.tsx +0 -252
  210. package/src/ui/components/DevQueueMonitor.tsx +0 -51
  211. package/src/ui/components/DevTopicsViewer.tsx +0 -686
  212. package/src/ui/components/actions/ActionGroup.tsx +0 -37
  213. package/src/ui/components/actions/ActionItem.tsx +0 -138
  214. package/src/ui/components/actions/DevActionsExplorer.tsx +0 -132
  215. package/src/ui/components/actions/MethodBadge.tsx +0 -18
  216. package/src/ui/components/actions/SchemaViewer.tsx +0 -21
  217. package/src/ui/components/actions/TryItPanel.tsx +0 -140
  218. package/src/ui/components/actions/constants.ts +0 -7
  219. package/src/ui/components/actions/helpers.ts +0 -18
  220. package/src/ui/components/actions/index.ts +0 -8
  221. package/src/ui/components/db/ColumnBadge.tsx +0 -55
  222. package/src/ui/components/db/DevDbStudio.tsx +0 -485
  223. package/src/ui/components/db/constants.ts +0 -11
  224. package/src/ui/components/db/index.ts +0 -4
  225. package/src/ui/components/db/types.ts +0 -7
  226. package/src/ui/styles.css +0 -1
  227. /package/src/{api/schemas → schemas}/DevAtomMetadata.ts +0 -0
  228. /package/src/{api/schemas → schemas}/DevBucketMetadata.ts +0 -0
  229. /package/src/{api/schemas → schemas}/DevCacheMetadata.ts +0 -0
  230. /package/src/{api/schemas → schemas}/DevEnvMetadata.ts +0 -0
  231. /package/src/{api/schemas → schemas}/DevModuleMetadata.ts +0 -0
  232. /package/src/{api/schemas → schemas}/DevProviderMetadata.ts +0 -0
  233. /package/src/{api/schemas → schemas}/DevQueueMetadata.ts +0 -0
  234. /package/src/{api/schemas → schemas}/DevRealmMetadata.ts +0 -0
  235. /package/src/{api/schemas → schemas}/DevRouteMetadata.ts +0 -0
  236. /package/src/{api/schemas → schemas}/DevSchedulerMetadata.ts +0 -0
@@ -0,0 +1,230 @@
1
+ import type { DevEnvMetadata } from "@alepha/devtools";
2
+ import { devMetadataSchema } from "@alepha/devtools";
3
+ import { Flex, ui } from "@alepha/ui";
4
+ import {
5
+ Badge,
6
+ Code,
7
+ CopyButton,
8
+ ScrollArea,
9
+ Text,
10
+ TextInput,
11
+ Tooltip,
12
+ } from "@mantine/core";
13
+ import {
14
+ IconCheck,
15
+ IconCopy,
16
+ IconSearch,
17
+ IconVariable,
18
+ } from "@tabler/icons-react";
19
+ import { useInject } from "alepha/react";
20
+ import { HttpClient } from "alepha/server";
21
+ import { useEffect, useMemo, useState } from "react";
22
+
23
+ interface EnvVariable {
24
+ name: string;
25
+ value: any;
26
+ type: string;
27
+ description?: string;
28
+ format?: string;
29
+ }
30
+
31
+ const SENSITIVE_PATTERNS = ["secret", "password", "key", "token", "api_key"];
32
+
33
+ const isSensitive = (name: string): boolean => {
34
+ const lower = name.toLowerCase();
35
+ return SENSITIVE_PATTERNS.some((p) => lower.includes(p));
36
+ };
37
+
38
+ const parseEnvVariables = (envs: DevEnvMetadata[]): EnvVariable[] => {
39
+ const variableMap = new Map<string, EnvVariable>();
40
+
41
+ for (const env of envs) {
42
+ const schema = env.schema;
43
+ if (!schema?.properties) continue;
44
+
45
+ for (const [name, propSchema] of Object.entries(schema.properties)) {
46
+ if (variableMap.has(name)) continue;
47
+
48
+ const prop = propSchema as any;
49
+ const value = env.values[name];
50
+
51
+ let type = prop.type ?? "unknown";
52
+ let format = prop.format;
53
+
54
+ if (prop.anyOf) {
55
+ const nonNull = prop.anyOf.find((t: any) => t.type !== "null");
56
+ if (nonNull) {
57
+ type = nonNull.type ?? "unknown";
58
+ format = nonNull.format;
59
+ }
60
+ }
61
+
62
+ variableMap.set(name, {
63
+ name,
64
+ value,
65
+ type,
66
+ description: prop.description,
67
+ format,
68
+ });
69
+ }
70
+ }
71
+
72
+ return Array.from(variableMap.values()).sort((a, b) =>
73
+ a.name.localeCompare(b.name),
74
+ );
75
+ };
76
+
77
+ const EnvLine = ({ variable }: { variable: EnvVariable }) => {
78
+ const hasValue = variable.value !== undefined && variable.value !== "";
79
+ const displayValue = hasValue ? String(variable.value) : "";
80
+ const sensitive = isSensitive(variable.name);
81
+
82
+ return (
83
+ <Flex>
84
+ {/* Description as comment */}
85
+ {variable.description?.split("\n").map((line, i) => (
86
+ <Text key={i} fz={11} ff="monospace" c="dimmed" fs="italic" lh={1.6}>
87
+ # {line}
88
+ </Text>
89
+ ))}
90
+ <Flex align="center" gap={0} style={{ lineHeight: 1.6 }}>
91
+ <Text fz={12} ff="monospace" fw={600} c="teal.5" component="span">
92
+ {variable.name}
93
+ </Text>
94
+ <Text fz={12} ff="monospace" c="dimmed" component="span">
95
+ =
96
+ </Text>
97
+ {hasValue ? (
98
+ <Text
99
+ fz={12}
100
+ ff="monospace"
101
+ component="span"
102
+ style={{
103
+ filter: sensitive ? "blur(4px)" : undefined,
104
+ transition: "filter 150ms",
105
+ cursor: sensitive ? "pointer" : undefined,
106
+ }}
107
+ onMouseEnter={(e) => {
108
+ if (sensitive) e.currentTarget.style.filter = "none";
109
+ }}
110
+ onMouseLeave={(e) => {
111
+ if (sensitive) e.currentTarget.style.filter = "blur(4px)";
112
+ }}
113
+ >
114
+ {displayValue}
115
+ </Text>
116
+ ) : (
117
+ <Text fz={12} ff="monospace" c="dimmed" fs="italic" component="span">
118
+ (not set)
119
+ </Text>
120
+ )}
121
+ <Badge
122
+ size="xs"
123
+ variant="dot"
124
+ color="gray"
125
+ ml="sm"
126
+ style={{ flexShrink: 0 }}
127
+ >
128
+ {variable.format || variable.type}
129
+ </Badge>
130
+ {hasValue && (
131
+ <CopyButton value={String(variable.value)}>
132
+ {({ copied, copy }) => (
133
+ <Tooltip label={copied ? "Copied!" : "Copy"} withArrow>
134
+ <Flex
135
+ ml={6}
136
+ onClick={copy}
137
+ style={{ cursor: "pointer", flexShrink: 0 }}
138
+ c={copied ? "teal" : "dimmed"}
139
+ >
140
+ {copied ? <IconCheck size={12} /> : <IconCopy size={12} />}
141
+ </Flex>
142
+ </Tooltip>
143
+ )}
144
+ </CopyButton>
145
+ )}
146
+ </Flex>
147
+ </Flex>
148
+ );
149
+ };
150
+
151
+ export const ConfigEnv = () => {
152
+ const http = useInject(HttpClient);
153
+ const [envs, setEnvs] = useState<DevEnvMetadata[]>([]);
154
+ const [search, setSearch] = useState("");
155
+
156
+ useEffect(() => {
157
+ http
158
+ .fetch("/__devtools/api/metadata", {
159
+ schema: { response: devMetadataSchema },
160
+ })
161
+ .then((res) => setEnvs(res.data.envs))
162
+ .catch(() => {});
163
+ }, [http]);
164
+
165
+ const variables = useMemo(() => parseEnvVariables(envs), [envs]);
166
+
167
+ const filtered = useMemo(() => {
168
+ if (!search) return variables;
169
+ const s = search.toLowerCase();
170
+ return variables.filter(
171
+ (v) =>
172
+ v.name.toLowerCase().includes(s) ||
173
+ v.description?.toLowerCase().includes(s),
174
+ );
175
+ }, [variables, search]);
176
+
177
+ if (variables.length === 0) {
178
+ return (
179
+ <Flex align="center" justify="center" style={{ flex: 1 }} c="dimmed">
180
+ <Flex direction="column" align="center" gap="xs">
181
+ <IconVariable size={40} opacity={0.3} />
182
+ <Text fz="sm">No environment variables found</Text>
183
+ <Text fz="xs" c="dimmed">
184
+ Use $env primitive to define expected environment variables
185
+ </Text>
186
+ </Flex>
187
+ </Flex>
188
+ );
189
+ }
190
+
191
+ return (
192
+ <Flex direction="column" style={{ flex: 1 }}>
193
+ <Flex
194
+ p="sm"
195
+ style={{ borderBottom: `1px solid ${ui.colors.border}`, flexShrink: 0 }}
196
+ >
197
+ <Flex gap="sm" align="center">
198
+ <TextInput
199
+ placeholder="Search variables..."
200
+ leftSection={<IconSearch size={14} />}
201
+ size="xs"
202
+ value={search}
203
+ onChange={(e) => setSearch(e.currentTarget.value)}
204
+ style={{ flex: 1, maxWidth: 340 }}
205
+ />
206
+ <Badge variant="light" color="gray" size="sm">
207
+ {filtered.length} / {variables.length}
208
+ </Badge>
209
+ </Flex>
210
+ </Flex>
211
+ <ScrollArea style={{ flex: 1 }} p="md">
212
+ <Code
213
+ block
214
+ style={{
215
+ background: ui.colors.surface,
216
+ border: `1px solid ${ui.colors.border}`,
217
+ borderRadius: 8,
218
+ padding: 16,
219
+ }}
220
+ >
221
+ <Flex direction="column" gap={8}>
222
+ {filtered.map((v) => (
223
+ <EnvLine key={v.name} variable={v} />
224
+ ))}
225
+ </Flex>
226
+ </Code>
227
+ </ScrollArea>
228
+ </Flex>
229
+ );
230
+ };
@@ -0,0 +1,36 @@
1
+ import { Flex, ui } from "@alepha/ui";
2
+ import { SegmentedControl } from "@mantine/core";
3
+ import { NestedView, useRouter, useRouterState } from "alepha/react/router";
4
+
5
+ export const DevConfiguration = () => {
6
+ const router = useRouter();
7
+ const state = useRouterState();
8
+ const tab = state.url.pathname.endsWith("/atoms") ? "atoms" : "env";
9
+
10
+ const handleTabChange = (value: string) => {
11
+ router.push(value === "atoms" ? "/conf/atoms" : "/conf/env");
12
+ };
13
+
14
+ return (
15
+ <Flex direction="column" style={{ flex: 1 }}>
16
+ <Flex
17
+ px="md"
18
+ py="xs"
19
+ style={{ borderBottom: `1px solid ${ui.colors.border}` }}
20
+ >
21
+ <SegmentedControl
22
+ size="xs"
23
+ value={tab}
24
+ onChange={handleTabChange}
25
+ data={[
26
+ { label: "Environment", value: "env" },
27
+ { label: "Atoms", value: "atoms" },
28
+ ]}
29
+ />
30
+ </Flex>
31
+ <NestedView />
32
+ </Flex>
33
+ );
34
+ };
35
+
36
+ export default DevConfiguration;
@@ -0,0 +1,3 @@
1
+ export { ConfigAtoms } from "./ConfigAtoms.tsx";
2
+ export { ConfigEnv } from "./ConfigEnv.tsx";
3
+ export { DevConfiguration } from "./DevConfiguration.tsx";