@rebasepro/studio 0.19.1 → 0.19.2-canary.g09316f6

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 (36) hide show
  1. package/dist/{ApiExplorer-9iwGvNnt.js → ApiExplorer-CND5O4Z5.js} +11 -11
  2. package/dist/ApiExplorer-CND5O4Z5.js.map +1 -0
  3. package/dist/{ApiKeysView-EIvegrUk.js → ApiKeysView-OfJLH2x7.js} +14 -14
  4. package/dist/ApiKeysView-OfJLH2x7.js.map +1 -0
  5. package/dist/{AuthSimulationSelector-Bougd521.js → AuthSimulationSelector-BewmhMBw.js} +2 -2
  6. package/dist/{AuthSimulationSelector-Bougd521.js.map → AuthSimulationSelector-BewmhMBw.js.map} +1 -1
  7. package/dist/{BackupsView-DVkKzaPR.js → BackupsView-D0ZDqTEn.js} +6 -6
  8. package/dist/{BackupsView-DVkKzaPR.js.map → BackupsView-D0ZDqTEn.js.map} +1 -1
  9. package/dist/{BranchesView-Df8hQ8wE.js → BranchesView-D6Sz1a5f.js} +11 -11
  10. package/dist/BranchesView-D6Sz1a5f.js.map +1 -0
  11. package/dist/{CronJobsView-CLOGjb-L.js → CronJobsView-JwRjQCde.js} +12 -12
  12. package/dist/CronJobsView-JwRjQCde.js.map +1 -0
  13. package/dist/{JSEditor-75FTeu6P.js → JSEditor-qiuwmcvk.js} +21 -21
  14. package/dist/JSEditor-qiuwmcvk.js.map +1 -0
  15. package/dist/{LogsExplorer-DI8SVpya.js → LogsExplorer-Xq8K4oo6.js} +3 -3
  16. package/dist/{LogsExplorer-DI8SVpya.js.map → LogsExplorer-Xq8K4oo6.js.map} +1 -1
  17. package/dist/{RLSEditor-Sa1D34ny.js → RLSEditor-C958zVWW.js} +34 -34
  18. package/dist/RLSEditor-C958zVWW.js.map +1 -0
  19. package/dist/{SQLEditor-BfNA8xM3.js → SQLEditor-sdtoZv5F.js} +37 -37
  20. package/dist/SQLEditor-sdtoZv5F.js.map +1 -0
  21. package/dist/{SchemaVisualizer-DTDMYL6o.js → SchemaVisualizer-DtDzIUNy.js} +30 -27
  22. package/dist/SchemaVisualizer-DtDzIUNy.js.map +1 -0
  23. package/dist/{StorageView-Ed9Q_VlB.js → StorageView-C52dSZNf.js} +16 -16
  24. package/dist/StorageView-C52dSZNf.js.map +1 -0
  25. package/dist/index.es.js +19 -19
  26. package/dist/index.es.js.map +1 -1
  27. package/package.json +9 -9
  28. package/dist/ApiExplorer-9iwGvNnt.js.map +0 -1
  29. package/dist/ApiKeysView-EIvegrUk.js.map +0 -1
  30. package/dist/BranchesView-Df8hQ8wE.js.map +0 -1
  31. package/dist/CronJobsView-CLOGjb-L.js.map +0 -1
  32. package/dist/JSEditor-75FTeu6P.js.map +0 -1
  33. package/dist/RLSEditor-Sa1D34ny.js.map +0 -1
  34. package/dist/SQLEditor-BfNA8xM3.js.map +0 -1
  35. package/dist/SchemaVisualizer-DTDMYL6o.js.map +0 -1
  36. package/dist/StorageView-Ed9Q_VlB.js.map +0 -1
@@ -221,11 +221,11 @@ function CronJobsView() {
221
221
  ]
222
222
  });
223
223
  return /* @__PURE__ */ jsxs("div", {
224
- className: "flex h-full w-full overflow-hidden bg-white dark:bg-surface-950",
224
+ className: "flex h-full w-full overflow-hidden bg-surface-card",
225
225
  children: [/* @__PURE__ */ jsxs("div", {
226
226
  className: cls("flex flex-col w-[340px] min-w-[280px] border-r h-full", defaultBorderMixin),
227
227
  children: [/* @__PURE__ */ jsxs("div", {
228
- className: cls("flex items-center justify-between px-4 py-2.5 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin),
228
+ className: cls("flex items-center justify-between px-4 py-2.5 border-b bg-surface-sheet min-h-[48px]", defaultBorderMixin),
229
229
  children: [/* @__PURE__ */ jsxs("div", {
230
230
  className: "flex items-center gap-2",
231
231
  children: [
@@ -240,7 +240,7 @@ function CronJobsView() {
240
240
  }),
241
241
  /* @__PURE__ */ jsx(Chip, {
242
242
  size: "smallest",
243
- className: "bg-surface-200 dark:bg-surface-700 text-surface-600 dark:text-surface-300",
243
+ className: "bg-surface-raised text-surface-600 dark:text-surface-300",
244
244
  children: jobs.length
245
245
  })
246
246
  ]
@@ -254,7 +254,7 @@ function CronJobsView() {
254
254
  className: "flex-1 overflow-y-auto p-2 space-y-1",
255
255
  children: jobs.map((job) => /* @__PURE__ */ jsxs("div", {
256
256
  onClick: () => setSelectedId(job.id),
257
- className: cls("flex items-center gap-3 px-3 py-2.5 rounded-lg cursor-pointer transition-all", selectedId === job.id ? "bg-primary/10 dark:bg-primary/15 ring-1 ring-primary/30" : "hover:bg-surface-100 dark:hover:bg-surface-950"),
257
+ className: cls("flex items-center gap-3 px-3 py-2.5 rounded-lg cursor-pointer transition-all", selectedId === job.id ? "bg-primary/10 dark:bg-primary/15 ring-1 ring-primary/30" : "hover:bg-surface-hover"),
258
258
  children: [
259
259
  /* @__PURE__ */ jsx("div", { className: cls("w-2 h-2 rounded-full shrink-0", stateColors[job.state] || "bg-surface-400") }),
260
260
  /* @__PURE__ */ jsxs("div", {
@@ -285,7 +285,7 @@ function CronJobsView() {
285
285
  })
286
286
  }) : /* @__PURE__ */ jsxs(Fragment, { children: [
287
287
  /* @__PURE__ */ jsxs("div", {
288
- className: cls("flex items-center justify-between px-5 py-3 border-b bg-white dark:bg-surface-950 min-h-[56px]", defaultBorderMixin),
288
+ className: cls("flex items-center justify-between px-5 py-3 border-b bg-surface-card min-h-[56px]", defaultBorderMixin),
289
289
  children: [/* @__PURE__ */ jsxs("div", {
290
290
  className: "flex items-center gap-3 min-w-0",
291
291
  children: [/* @__PURE__ */ jsx("div", { className: cls("w-2.5 h-2.5 rounded-full", stateColors[selectedJob.state]) }), /* @__PURE__ */ jsxs("div", {
@@ -319,7 +319,7 @@ function CronJobsView() {
319
319
  })]
320
320
  }),
321
321
  /* @__PURE__ */ jsxs("div", {
322
- className: "px-5 py-4 bg-surface-50 dark:bg-surface-900/50",
322
+ className: "px-5 py-4 bg-surface-sheet",
323
323
  children: [
324
324
  /* @__PURE__ */ jsxs("div", {
325
325
  className: "grid grid-cols-2 md:grid-cols-4 gap-3",
@@ -383,7 +383,7 @@ function CronJobsView() {
383
383
  ]
384
384
  }),
385
385
  /* @__PURE__ */ jsxs("div", {
386
- className: cls("flex items-center justify-between px-5 py-2 border-y bg-white dark:bg-surface-950", defaultBorderMixin),
386
+ className: cls("flex items-center justify-between px-5 py-2 border-y bg-surface-card", defaultBorderMixin),
387
387
  children: [/* @__PURE__ */ jsxs("div", {
388
388
  className: "flex items-center gap-2",
389
389
  children: [/* @__PURE__ */ jsx(HistoryIcon, {
@@ -424,7 +424,7 @@ function CronJobsView() {
424
424
  }
425
425
  function StatCard({ label, value, mono, chipColor, highlight }) {
426
426
  return /* @__PURE__ */ jsxs("div", {
427
- className: cls("px-3 py-2 rounded-lg border bg-white dark:bg-surface-900", defaultBorderMixin),
427
+ className: cls("px-3 py-2 rounded-lg border bg-surface-card", defaultBorderMixin),
428
428
  children: [/* @__PURE__ */ jsx(Typography, {
429
429
  variant: "caption",
430
430
  color: "secondary",
@@ -440,7 +440,7 @@ function StatCard({ label, value, mono, chipColor, highlight }) {
440
440
  function LogRow({ log }) {
441
441
  const [expanded, setExpanded] = useState(false);
442
442
  return /* @__PURE__ */ jsxs("div", {
443
- className: "px-5 py-2.5 hover:bg-surface-50 dark:hover:bg-surface-950/50 transition-colors",
443
+ className: "px-5 py-2.5 hover:bg-surface-hover transition-colors",
444
444
  children: [/* @__PURE__ */ jsxs("div", {
445
445
  className: "flex items-center gap-3 cursor-pointer",
446
446
  onClick: () => setExpanded(!expanded),
@@ -494,14 +494,14 @@ function LogRow({ log }) {
494
494
  })
495
495
  }),
496
496
  log.logs.length > 0 && /* @__PURE__ */ jsx("div", {
497
- className: "p-2 rounded bg-surface-50 dark:bg-surface-900 border border-surface-200 dark:border-surface-700 max-h-40 overflow-auto",
497
+ className: "p-2 rounded bg-surface-sheet border border-hairline-strong max-h-40 overflow-auto",
498
498
  children: log.logs.map((line, i) => /* @__PURE__ */ jsx("div", {
499
499
  className: "font-mono text-[11px] text-surface-600 dark:text-surface-400 leading-relaxed",
500
500
  children: line
501
501
  }, i))
502
502
  }),
503
503
  log.result !== void 0 && /* @__PURE__ */ jsxs("div", {
504
- className: "p-2 rounded bg-surface-50 dark:bg-surface-900 border border-surface-200 dark:border-surface-700",
504
+ className: "p-2 rounded bg-surface-sheet border border-hairline-strong",
505
505
  children: [/* @__PURE__ */ jsx(Typography, {
506
506
  variant: "caption",
507
507
  className: "text-[10px] uppercase tracking-wider text-surface-400 mb-1 block",
@@ -518,4 +518,4 @@ function LogRow({ log }) {
518
518
  //#endregion
519
519
  export { CronJobsView };
520
520
 
521
- //# sourceMappingURL=CronJobsView-CLOGjb-L.js.map
521
+ //# sourceMappingURL=CronJobsView-JwRjQCde.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CronJobsView-JwRjQCde.js","names":[],"sources":["../src/components/CronJobs/CronJobsView.tsx"],"sourcesContent":["\nimport React, { useState, useEffect, useRef } from \"react\";\nimport {\n AlertCircleIcon,\n Button,\n CalendarIcon,\n Card,\n CheckCircleIcon,\n Chip,\n CircularProgress,\n cls,\n defaultBorderMixin,\n HistoryIcon,\n IconButton,\n iconSize,\n Paper,\n PauseIcon,\n PlayIcon,\n RefreshCwIcon,\n Typography\n} from \"@rebasepro/ui\";\nimport { useRebaseClient, useSnackbarController, useTranslation } from \"@rebasepro/app\";\nimport type { CronJobStatus, CronJobLogEntry } from \"@rebasepro/types\";\nimport type { RebaseClient } from \"@rebasepro/types\";\n\nimport { classifyLoadFailure, type LoadFailure } from \"../load-failure\";\nimport { LoadFailureView } from \"../load-failure-view\";\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n}\n\nfunction formatRelative(iso: string | undefined): string {\n if (!iso) return \"—\";\n const d = new Date(iso);\n const now = Date.now();\n const diff = d.getTime() - now;\n const abs = Math.abs(diff);\n if (abs < 60000) return diff > 0 ? \"in <1m\" : \"<1m ago\";\n if (abs < 3600000) { const m = Math.round(abs / 60000); return diff > 0 ? `in ${m}m` : `${m}m ago`; }\n if (abs < 86400000) { const h = Math.round(abs / 3600000); return diff > 0 ? `in ${h}h` : `${h}h ago`; }\n return d.toLocaleString();\n}\n\nconst stateColors: Record<string, string> = {\n idle: \"bg-emerald-500\",\nrunning: \"bg-blue-500\",\nsuccess: \"bg-emerald-500\",\n error: \"bg-red-500\",\ndisabled: \"bg-surface-400\"\n};\n\nexport function CronJobsView() {\n const client = useRebaseClient<RebaseClient>();\n const snackbar = useSnackbarController();\n const { t } = useTranslation();\n const [jobs, setJobs] = useState<CronJobStatus[]>([]);\n const [loading, setLoading] = useState(true);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [logs, setLogs] = useState<CronJobLogEntry[]>([]);\n const [logsLoading, setLogsLoading] = useState(false);\n const [triggering, setTriggering] = useState<string | null>(null);\n /** Why the job listing failed, classified — see `load-failure.ts`. */\n const [failure, setFailure] = useState<LoadFailure | null>(null);\n\n // Refs so effects never re-fire due to identity changes\n const clientRef = useRef(client);\n clientRef.current = client;\n const snackbarRef = useRef(snackbar);\n snackbarRef.current = snackbar;\n\n // ── Fetch jobs on mount + poll every 15s ──\n useEffect(() => {\n let cancelled = false;\n\n async function load() {\n const c = clientRef.current;\n if (!c?.cron) {\n setLoading(false);\n return;\n }\n try {\n const res = await c.cron.listJobs();\n if (!cancelled) {\n setJobs(res.jobs);\n setFailure(null);\n }\n } catch (e: unknown) {\n // A snackbar over an empty list said \"No Cron Jobs Registered\"\n // about a project whose crons the caller may not read. This\n // view polls every 15s, so the toast is also gone long before\n // anyone looks.\n if (!cancelled) setFailure(classifyLoadFailure(e));\n } finally {\n if (!cancelled) setLoading(false);\n }\n }\n\n load();\n\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const scheduleNext = () => {\n if (cancelled) return;\n timeoutId = setTimeout(async () => {\n if (document.visibilityState === \"visible\") {\n await load();\n }\n scheduleNext();\n }, 15_000);\n };\n\n scheduleNext();\n\n const handleVisibility = () => {\n if (document.visibilityState === \"visible\") {\n load();\n }\n };\n document.addEventListener(\"visibilitychange\", handleVisibility);\n\n return () => {\n cancelled = true;\n if (timeoutId) clearTimeout(timeoutId);\n document.removeEventListener(\"visibilitychange\", handleVisibility);\n };\n }, []); // runs once\n\n // ── Fetch logs when selection changes ──\n useEffect(() => {\n if (!selectedId) {\n setLogs([]);\n return;\n }\n let cancelled = false;\n const c = clientRef.current;\n if (!c?.cron) return;\n\n setLogsLoading(true);\n c.cron.getJobLogs(selectedId, { limit: 25 })\n .then(res => { if (!cancelled) setLogs(res.logs); })\n .catch((e: unknown) => {\n if (cancelled) return;\n // Same reasoning as `refreshLogs`: an empty log list is a claim.\n setLogs([]);\n snackbarRef.current.open({\n type: \"error\",\n message: e instanceof Error ? e.message : String(e)\n });\n })\n .finally(() => { if (!cancelled) setLogsLoading(false); });\n\n return () => { cancelled = true; };\n }, [selectedId]);\n\n // ── Imperative helpers (not in any dep array) ──\n async function refreshJobs() {\n const c = clientRef.current;\n if (!c?.cron) return;\n try {\n const res = await c.cron.listJobs();\n setJobs(res.jobs);\n setFailure(null);\n } catch (e: unknown) {\n // Swallowed before, which left the list showing whatever it last\n // held — or nothing — after a failed refresh. \"No cron jobs\" and\n // \"could not read the cron jobs\" are not the same statement, so the\n // reason stays on screen rather than passing through a snackbar.\n setFailure(classifyLoadFailure(e));\n }\n }\n\n async function refreshLogs(id: string) {\n const c = clientRef.current;\n if (!c?.cron) return;\n setLogsLoading(true);\n try {\n const res = await c.cron.getJobLogs(id, { limit: 25 });\n setLogs(res.logs);\n } catch (e: unknown) {\n // Clearing the list silently reads as \"this job has never run\".\n setLogs([]);\n snackbarRef.current.open({\n type: \"error\",\n message: e instanceof Error ? e.message : String(e)\n });\n }\n finally { setLogsLoading(false); }\n }\n\n const handleTrigger = async (id: string) => {\n const c = clientRef.current;\n if (!c?.cron) return;\n setTriggering(id);\n try {\n await c.cron.triggerJob(id);\n snackbarRef.current.open({ type: \"success\",\nmessage: \"Job triggered\" });\n await refreshJobs();\n if (selectedId === id) refreshLogs(id);\n } catch (e: unknown) {\n snackbarRef.current.open({ type: \"error\",\nmessage: e instanceof Error ? e.message : String(e) });\n } finally { setTriggering(null); }\n };\n\n const handleToggle = async (id: string, enabled: boolean) => {\n const c = clientRef.current;\n if (!c?.cron) return;\n try {\n await c.cron.toggleJob(id, enabled);\n snackbarRef.current.open({ type: \"success\",\nmessage: enabled ? \"Job enabled\" : \"Job paused\" });\n await refreshJobs();\n } catch (e: unknown) {\n snackbarRef.current.open({ type: \"error\",\nmessage: e instanceof Error ? e.message : String(e) });\n }\n };\n\n const selectedJob = jobs.find(j => j.id === selectedId);\n\n if (loading) return <div className=\"flex items-center justify-center h-full\"><CircularProgress/></div>;\n\n if (failure) return (\n <LoadFailureView\n failure={failure}\n title={t(\"studio_cron_read_failed\")}\n deniedTitle={t(\"studio_cron_denied_title\")}\n deniedHint={t(\"studio_cron_denied_hint\")}\n onRetry={refreshJobs}\n />\n );\n\n if (jobs.length === 0) return (\n <div className=\"flex flex-col items-center justify-center h-full gap-4 text-center p-8\">\n <CalendarIcon size={iconSize.medium} className=\"text-surface-300 dark:text-surface-600\"/>\n <Typography variant=\"h6\" color=\"secondary\">{t(\"studio_cron_empty_title\")}</Typography>\n <Typography variant=\"body2\" color=\"disabled\" className=\"max-w-md\">\n {t(\"studio_cron_empty_body\")}\n </Typography>\n <a\n href=\"https://rebase.pro/docs/backend/cron-jobs\"\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-primary text-sm underline\"\n >\n {t(\"studio_read_the_docs\")}\n </a>\n </div>\n );\n\n return (\n <div className=\"flex h-full w-full overflow-hidden bg-surface-card\">\n {/* ── Job List ── */}\n <div className={cls(\"flex flex-col w-[340px] min-w-[280px] border-r h-full\", defaultBorderMixin)}>\n <div className={cls(\"flex items-center justify-between px-4 py-2.5 border-b bg-surface-sheet min-h-[48px]\", defaultBorderMixin)}>\n <div className=\"flex items-center gap-2\">\n <CalendarIcon size={iconSize.smallest} className=\"text-primary\"/>\n <Typography variant=\"subtitle2\" className=\"font-semibold\">{t(\"studio_tool_cron\")}</Typography>\n <Chip size=\"smallest\" className=\"bg-surface-raised text-surface-600 dark:text-surface-300\">{jobs.length}</Chip>\n </div>\n <IconButton size=\"small\" onClick={refreshJobs} title=\"Refresh\"><RefreshCwIcon size={iconSize.smallest}/></IconButton>\n </div>\n <div className=\"flex-1 overflow-y-auto p-2 space-y-1\">\n {jobs.map(job => (\n <div\n key={job.id}\n onClick={() => setSelectedId(job.id)}\n className={cls(\n \"flex items-center gap-3 px-3 py-2.5 rounded-lg cursor-pointer transition-all\",\n selectedId === job.id\n ? \"bg-primary/10 dark:bg-primary/15 ring-1 ring-primary/30\"\n : \"hover:bg-surface-hover\"\n )}\n >\n <div className={cls(\"w-2 h-2 rounded-full shrink-0\", stateColors[job.state] || \"bg-surface-400\")}/>\n <div className=\"flex-1 min-w-0\">\n <Typography variant=\"body2\" className=\"truncate font-medium text-[13px]\">{job.name}</Typography>\n <Typography variant=\"caption\" color=\"secondary\" className=\"truncate text-[11px] font-mono\">{job.schedule}</Typography>\n </div>\n {job.state === \"running\" && <CircularProgress size=\"smallest\"/>}\n </div>\n ))}\n </div>\n </div>\n\n {/* ── Detail Panel ── */}\n <div className=\"flex-1 flex flex-col min-w-0 h-full overflow-hidden\">\n {!selectedJob ? (\n <div className=\"flex items-center justify-center h-full\">\n <Typography variant=\"body2\" color=\"disabled\">Select a cron job to view details</Typography>\n </div>\n ) : (\n <>\n {/* Header */}\n <div className={cls(\"flex items-center justify-between px-5 py-3 border-b bg-surface-card min-h-[56px]\", defaultBorderMixin)}>\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className={cls(\"w-2.5 h-2.5 rounded-full\", stateColors[selectedJob.state])}/>\n <div className=\"min-w-0\">\n <Typography variant=\"subtitle1\" className=\"font-semibold truncate\">{selectedJob.name}</Typography>\n {selectedJob.description && <Typography variant=\"caption\" color=\"secondary\" className=\"truncate\">{selectedJob.description}</Typography>}\n </div>\n </div>\n <div className=\"flex items-center gap-2 shrink-0\">\n <IconButton title={selectedJob.enabled ? \"Pause job\" : \"Enable job\"} size=\"small\" onClick={() => handleToggle(selectedJob.id, !selectedJob.enabled)}>\n {selectedJob.enabled ? <PauseIcon size={iconSize.small}/> : <PlayIcon size={iconSize.smallest}/>}\n </IconButton>\n <Button\n size=\"small\"\n color=\"primary\"\n onClick={() => handleTrigger(selectedJob.id)}\n disabled={triggering === selectedJob.id}\n startIcon={triggering === selectedJob.id ? <CircularProgress size=\"smallest\"/> : <PlayIcon size={iconSize.smallest}/>}\n >\n Run Now\n </Button>\n </div>\n </div>\n\n {/* Stats Cards */}\n <div className=\"px-5 py-4 bg-surface-sheet\">\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-3\">\n <StatCard label=\"Schedule\" value={selectedJob.schedule} mono/>\n <StatCard label=\"Last Run\" value={formatRelative(selectedJob.lastRunAt)}/>\n <StatCard label=\"Next Run\" value={selectedJob.enabled ? formatRelative(selectedJob.nextRunAt) : \"Paused\"}/>\n <StatCard label=\"Duration\" value={selectedJob.lastDurationMs !== undefined ? formatDuration(selectedJob.lastDurationMs) : \"—\"}/>\n </div>\n <div className=\"grid grid-cols-3 gap-3 mt-3\">\n <StatCard label=\"Status\" value={selectedJob.state.toUpperCase()} chipColor={selectedJob.state === \"error\" ? \"red\" : selectedJob.state === \"disabled\" ? \"gray\" : \"green\"}/>\n <StatCard label=\"Total Runs\" value={String(selectedJob.totalRuns)}/>\n <StatCard label=\"Failures\" value={String(selectedJob.totalFailures)} highlight={selectedJob.totalFailures > 0}/>\n </div>\n {selectedJob.lastError && (\n <div className=\"mt-3 p-3 rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800/50\">\n <div className=\"flex items-center gap-2 mb-1\">\n <AlertCircleIcon size={iconSize.smallest} className=\"text-red-500\"/>\n <Typography variant=\"caption\" className=\"font-semibold text-red-700 dark:text-red-400\">Last Error</Typography>\n </div>\n <Typography variant=\"caption\" className=\"font-mono text-red-600 dark:text-red-300 text-[11px] break-all\">{selectedJob.lastError}</Typography>\n </div>\n )}\n </div>\n\n {/* Logs Section */}\n <div className={cls(\"flex items-center justify-between px-5 py-2 border-y bg-surface-card\", defaultBorderMixin)}>\n <div className=\"flex items-center gap-2\">\n <HistoryIcon size={iconSize.smallest} className=\"text-surface-400\"/>\n <Typography variant=\"subtitle2\" className=\"font-semibold text-[13px]\">Execution History</Typography>\n </div>\n <IconButton size=\"small\" onClick={() => refreshLogs(selectedJob.id)} title=\"Refresh logs\"><RefreshCwIcon size={iconSize.smallest}/></IconButton>\n </div>\n <div className=\"flex-1 overflow-y-auto\">\n {logsLoading ? (\n <div className=\"flex justify-center p-8\"><CircularProgress size=\"small\"/></div>\n ) : logs.length === 0 ? (\n <div className=\"flex items-center justify-center h-32\">\n <Typography variant=\"body2\" color=\"disabled\">No executions yet</Typography>\n </div>\n ) : (\n <div className=\"divide-y divide-surface-100 dark:divide-surface-950\">\n {logs.map((log, idx) => (\n <LogRow key={idx} log={log}/>\n ))}\n </div>\n )}\n </div>\n </>\n )}\n </div>\n </div>\n );\n}\n\nfunction StatCard({ label, value, mono, chipColor, highlight }: {\n label: string; value: string; mono?: boolean; chipColor?: string; highlight?: boolean;\n}) {\n return (\n <div className={cls(\"px-3 py-2 rounded-lg border bg-surface-card\", defaultBorderMixin)}>\n <Typography variant=\"caption\" color=\"secondary\" className=\"text-[10px] uppercase tracking-wider font-medium\">{label}</Typography>\n <Typography variant=\"body2\" className={cls(\n \"mt-0.5 font-semibold text-[13px]\",\n mono && \"font-mono\",\n highlight && \"text-red-500 dark:text-red-400\",\n chipColor === \"red\" && \"text-red-500\",\n chipColor === \"green\" && \"text-emerald-500\",\n chipColor === \"gray\" && \"text-surface-400\"\n )}>{value}</Typography>\n </div>\n );\n}\n\nfunction LogRow({ log }: { log: CronJobLogEntry }) {\n const [expanded, setExpanded] = useState(false);\n return (\n <div className=\"px-5 py-2.5 hover:bg-surface-hover transition-colors\">\n <div className=\"flex items-center gap-3 cursor-pointer\" onClick={() => setExpanded(!expanded)}>\n {log.success\n ? <CheckCircleIcon size={iconSize.smallest} className=\"text-emerald-500 shrink-0\"/>\n : <AlertCircleIcon size={iconSize.smallest} className=\"text-red-500 shrink-0\"/>}\n <div className=\"flex-1 min-w-0\">\n <Typography variant=\"caption\" className=\"font-mono text-[11px] text-surface-500\">{new Date(log.startedAt).toLocaleString()}</Typography>\n </div>\n <div className=\"flex items-center gap-2 shrink-0\">\n {log.manual && <Chip size=\"smallest\" className=\"bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300\">manual</Chip>}\n <Typography variant=\"caption\" className=\"font-mono text-[11px]\">{formatDuration(log.durationMs)}</Typography>\n <svg className={cls(\"w-3 h-3 transition-transform text-surface-400\", expanded && \"rotate-180\")} fill=\"currentColor\" viewBox=\"0 0 20 20\"><path d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\"/></svg>\n </div>\n </div>\n {expanded && (\n <div className=\"mt-2 ml-6 space-y-2\">\n {log.error && (\n <div className=\"p-2 rounded bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800/50\">\n <Typography variant=\"caption\" className=\"font-mono text-[11px] text-red-600 dark:text-red-300 break-all\">{log.error}</Typography>\n </div>\n )}\n {log.logs.length > 0 && (\n <div className=\"p-2 rounded bg-surface-sheet border border-hairline-strong max-h-40 overflow-auto\">\n {log.logs.map((line, i) => (\n <div key={i} className=\"font-mono text-[11px] text-surface-600 dark:text-surface-400 leading-relaxed\">{line}</div>\n ))}\n </div>\n )}\n {log.result !== undefined && (\n <div className=\"p-2 rounded bg-surface-sheet border border-hairline-strong\">\n <Typography variant=\"caption\" className=\"text-[10px] uppercase tracking-wider text-surface-400 mb-1 block\">Result</Typography>\n <pre className=\"font-mono text-[11px] text-surface-600 dark:text-surface-400 whitespace-pre-wrap break-all\">{JSON.stringify(log.result, null, 2)}</pre>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { t as AuthSimulationSelector } from "./AuthSimulationSelector-Bougd521.js";
1
+ import { t as AuthSimulationSelector } from "./AuthSimulationSelector-BewmhMBw.js";
2
2
  import { ErrorView, IconForView, useApiConfig, useModeController, useRebaseClient, useRebaseContext, useSnackbarController, useStudioCollectionRegistry, useStudioSidePanelController, useTranslation } from "@rebasepro/app";
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
4
  import { Button, Chip, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, DownloadIcon, IconButton, Menu, MenuItem, MoreVerticalIcon, PencilIcon, PlayIcon, PlusIcon, ResizablePanels, SaveIcon, Tab, Tabs, TerminalIcon, TextField, Tooltip, Trash2Icon, Typography, VirtualTable, XIcon, cls, defaultBorderMixin, iconSize } from "@rebasepro/ui";
@@ -378,12 +378,12 @@ var QUICK_REFERENCE = [
378
378
  var JSEditorSidebar = ({ collections, snippets, history, onSelectSnippet, onDeleteSnippet, onInsertCode }) => {
379
379
  const [activeTab, setActiveTab] = useState("collections");
380
380
  return /* @__PURE__ */ jsxs("div", {
381
- className: cls("flex flex-col h-full w-full bg-white dark:bg-surface-950 border-r", defaultBorderMixin),
381
+ className: cls("flex flex-col h-full w-full bg-surface-card border-r", defaultBorderMixin),
382
382
  children: [/* @__PURE__ */ jsxs(Tabs, {
383
383
  value: activeTab,
384
384
  onValueChange: (v) => setActiveTab(v),
385
385
  variant: "boxy",
386
- className: "border-b border-surface-200 dark:border-surface-950",
386
+ className: "border-b border-hairline",
387
387
  children: [
388
388
  /* @__PURE__ */ jsx(Tab, {
389
389
  value: "collections",
@@ -426,7 +426,7 @@ var JSEditorSidebar = ({ collections, snippets, history, onSelectSnippet, onDele
426
426
  activeTab === "collections" && /* @__PURE__ */ jsxs("div", {
427
427
  className: "flex flex-col h-full",
428
428
  children: [/* @__PURE__ */ jsx("div", {
429
- className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin),
429
+ className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-sheet min-h-[48px]", defaultBorderMixin),
430
430
  children: /* @__PURE__ */ jsx(Typography, {
431
431
  variant: "caption",
432
432
  className: "font-semibold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark",
@@ -450,7 +450,7 @@ var JSEditorSidebar = ({ collections, snippets, history, onSelectSnippet, onDele
450
450
  activeTab === "reference" && /* @__PURE__ */ jsxs("div", {
451
451
  className: "flex flex-col h-full",
452
452
  children: [/* @__PURE__ */ jsx("div", {
453
- className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin),
453
+ className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-sheet min-h-[48px]", defaultBorderMixin),
454
454
  children: /* @__PURE__ */ jsx(Typography, {
455
455
  variant: "caption",
456
456
  className: "font-semibold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark",
@@ -459,7 +459,7 @@ var JSEditorSidebar = ({ collections, snippets, history, onSelectSnippet, onDele
459
459
  }), /* @__PURE__ */ jsx("div", {
460
460
  className: "flex-grow overflow-y-auto p-2 space-y-2 no-scrollbar",
461
461
  children: QUICK_REFERENCE.map((ref, i) => /* @__PURE__ */ jsxs("div", {
462
- className: cls("group p-2.5 rounded-lg border hover:border-primary/40 dark:hover:border-primary/40", "bg-white dark:bg-surface-900 transition-all cursor-pointer", defaultBorderMixin),
462
+ className: cls("group p-2.5 rounded-lg border hover:border-primary/40 dark:hover:border-primary/40", "bg-surface-card transition-all cursor-pointer", defaultBorderMixin),
463
463
  onClick: () => onInsertCode(ref.code),
464
464
  children: [/* @__PURE__ */ jsxs("div", {
465
465
  className: "flex items-center justify-between mb-1",
@@ -493,7 +493,7 @@ var JSEditorSidebar = ({ collections, snippets, history, onSelectSnippet, onDele
493
493
  return /* @__PURE__ */ jsxs("div", {
494
494
  className: "flex flex-col h-full",
495
495
  children: [/* @__PURE__ */ jsx("div", {
496
- className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin),
496
+ className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-sheet min-h-[48px]", defaultBorderMixin),
497
497
  children: /* @__PURE__ */ jsx(Typography, {
498
498
  variant: "caption",
499
499
  className: "font-semibold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark",
@@ -545,7 +545,7 @@ var JSEditorSidebar = ({ collections, snippets, history, onSelectSnippet, onDele
545
545
  activeTab === "history" && /* @__PURE__ */ jsxs("div", {
546
546
  className: "flex flex-col h-full",
547
547
  children: [/* @__PURE__ */ jsx("div", {
548
- className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-50 dark:bg-surface-900 min-h-[48px]", defaultBorderMixin),
548
+ className: cls("flex items-center justify-between px-3 py-2 border-b bg-surface-sheet min-h-[48px]", defaultBorderMixin),
549
549
  children: /* @__PURE__ */ jsx(Typography, {
550
550
  variant: "caption",
551
551
  className: "font-semibold uppercase tracking-wider text-text-disabled dark:text-text-disabled-dark",
@@ -561,7 +561,7 @@ var JSEditorSidebar = ({ collections, snippets, history, onSelectSnippet, onDele
561
561
  children: "No execution history yet"
562
562
  })
563
563
  }) : [...history].reverse().map((code, i) => /* @__PURE__ */ jsxs("div", {
564
- className: "p-2 py-1.5 rounded hover:bg-surface-100 dark:hover:bg-surface-900 cursor-pointer group transition-colors flex items-start",
564
+ className: "p-2 py-1.5 rounded hover:bg-surface-hover cursor-pointer group transition-colors flex items-start",
565
565
  onClick: () => onSelectSnippet(code),
566
566
  children: [/* @__PURE__ */ jsx("svg", {
567
567
  className: "w-3 h-3 mt-1 mr-2 text-text-disabled dark:text-text-disabled-dark group-hover:text-primary transition-colors flex-shrink-0",
@@ -589,7 +589,7 @@ var JSEditorSidebar = ({ collections, snippets, history, onSelectSnippet, onDele
589
589
  function CollectionItem({ collection, onInsertCode }) {
590
590
  const [expanded, setExpanded] = useState(false);
591
591
  return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("div", {
592
- className: "flex items-center p-1 cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-900 rounded transition-colors group relative",
592
+ className: "flex items-center p-1 cursor-pointer hover:bg-surface-hover rounded transition-colors group relative",
593
593
  onClick: () => setExpanded(!expanded),
594
594
  children: [
595
595
  /* @__PURE__ */ jsx("svg", {
@@ -631,7 +631,7 @@ function CollectionItem({ collection, onInsertCode }) {
631
631
  }), expanded && collection.properties.length > 0 && /* @__PURE__ */ jsx("div", {
632
632
  className: cls("ml-5 mt-1 space-y-0.5 border-l", defaultBorderMixin),
633
633
  children: collection.properties.map((prop) => /* @__PURE__ */ jsxs("div", {
634
- className: "flex items-center p-1 pl-2 hover:bg-surface-50 dark:hover:bg-surface-900 rounded-r cursor-pointer transition-colors group/prop relative min-h-[28px]",
634
+ className: "flex items-center p-1 pl-2 hover:bg-surface-hover rounded-r cursor-pointer transition-colors group/prop relative min-h-[28px]",
635
635
  onClick: () => onInsertCode(`"${prop}"`),
636
636
  children: [/* @__PURE__ */ jsx("svg", {
637
637
  className: "w-3 h-3 mr-1.5 text-text-disabled dark:text-text-disabled-dark shrink-0",
@@ -654,7 +654,7 @@ function CollectionItem({ collection, onInsertCode }) {
654
654
  }
655
655
  function SnippetItem({ snippet, onSelect, onDelete }) {
656
656
  return /* @__PURE__ */ jsxs("div", {
657
- className: cls("group p-2 rounded border hover:border-surface-400 dark:hover:border-surface-600 bg-white dark:bg-surface-900 transition-all cursor-pointer relative", defaultBorderMixin),
657
+ className: cls("group p-2 rounded border hover:border-hairline-strong bg-surface-card transition-all cursor-pointer relative", defaultBorderMixin),
658
658
  onClick: () => onSelect(snippet.code),
659
659
  children: [
660
660
  /* @__PURE__ */ jsx(Typography, {
@@ -1169,7 +1169,7 @@ function JSEditor() {
1169
1169
  secondPanel: /* @__PURE__ */ jsxs("div", {
1170
1170
  className: "flex flex-col h-full overflow-hidden",
1171
1171
  children: [/* @__PURE__ */ jsxs("div", {
1172
- className: cls("flex items-center justify-between pr-2 border-b bg-white dark:bg-surface-950", defaultBorderMixin),
1172
+ className: cls("flex items-center justify-between pr-2 border-b bg-surface-card", defaultBorderMixin),
1173
1173
  children: [/* @__PURE__ */ jsx("div", {
1174
1174
  className: "flex items-center flex-grow overflow-hidden mr-4",
1175
1175
  children: /* @__PURE__ */ jsxs("div", {
@@ -1179,7 +1179,7 @@ function JSEditor() {
1179
1179
  onValueChange: setActiveTabId,
1180
1180
  variant: "boxy",
1181
1181
  className: "w-[unset] flex-shrink-0",
1182
- innerClassName: "bg-white dark:bg-surface-950",
1182
+ innerClassName: "bg-surface-card",
1183
1183
  children: tabs.map((tab) => /* @__PURE__ */ jsxs(Tab, {
1184
1184
  value: tab.id,
1185
1185
  className: "flex items-center justify-between group max-w-[200px]",
@@ -1258,7 +1258,7 @@ function JSEditor() {
1258
1258
  firstPanel: /* @__PURE__ */ jsxs("div", {
1259
1259
  className: "h-full w-full overflow-hidden flex flex-col",
1260
1260
  children: [/* @__PURE__ */ jsx("div", {
1261
- className: "p-2 px-3 border-b border-surface-200 dark:border-surface-950 bg-surface-50 dark:bg-surface-900 flex items-center shrink-0",
1261
+ className: "p-2 px-3 border-b border-hairline bg-surface-sheet flex items-center shrink-0",
1262
1262
  children: /* @__PURE__ */ jsx(AuthSimulationSelector, {
1263
1263
  authMode,
1264
1264
  setAuthMode,
@@ -1281,10 +1281,10 @@ function JSEditor() {
1281
1281
  })]
1282
1282
  }),
1283
1283
  secondPanel: /* @__PURE__ */ jsxs("div", {
1284
- className: "h-full w-full flex flex-col bg-surface-50 dark:bg-surface-950 overflow-hidden min-h-0",
1284
+ className: "h-full w-full flex flex-col bg-surface-well overflow-hidden min-h-0",
1285
1285
  children: [
1286
1286
  /* @__PURE__ */ jsxs("div", {
1287
- className: cls("p-2 px-4 bg-surface-100 dark:bg-surface-900 border-b shrink-0 flex items-center", defaultBorderMixin),
1287
+ className: cls("p-2 px-4 bg-surface-raised border-b shrink-0 flex items-center", defaultBorderMixin),
1288
1288
  children: [/* @__PURE__ */ jsx(Typography, {
1289
1289
  variant: "caption",
1290
1290
  className: "font-semibold text-text-disabled dark:text-text-disabled-dark uppercase tracking-widest text-[10px]",
@@ -1356,7 +1356,7 @@ function JSEditor() {
1356
1356
  children: [
1357
1357
  "Write JavaScript and press ",
1358
1358
  /* @__PURE__ */ jsx("kbd", {
1359
- className: "px-1.5 py-0.5 rounded bg-surface-200 dark:bg-surface-700 text-[11px] font-mono",
1359
+ className: "px-1.5 py-0.5 rounded bg-surface-raised text-[11px] font-mono",
1360
1360
  children: "⌘ Enter"
1361
1361
  }),
1362
1362
  " to run"
@@ -1381,7 +1381,7 @@ function JSEditor() {
1381
1381
  !isRunning && result && !result.error && resultView === "table" && tableData.data.length > 0 && /* @__PURE__ */ jsxs("div", {
1382
1382
  className: "flex-grow flex flex-col overflow-hidden min-h-0",
1383
1383
  children: [matchedCollections.length > 0 && /* @__PURE__ */ jsxs("div", {
1384
- className: cls("px-4 py-1.5 border-b flex items-center gap-2 shrink-0 bg-surface-50 dark:bg-surface-900", defaultBorderMixin),
1384
+ className: cls("px-4 py-1.5 border-b flex items-center gap-2 shrink-0 bg-surface-sheet", defaultBorderMixin),
1385
1385
  children: [/* @__PURE__ */ jsx(Tooltip, {
1386
1386
  title: t("studio_sql_admin_collections_tooltip"),
1387
1387
  children: /* @__PURE__ */ jsx(Typography, {
@@ -1520,7 +1520,7 @@ function JSEditor() {
1520
1520
  ]
1521
1521
  }),
1522
1522
  !isRunning && result && !result.error && resultView === "table" && tableData.data.length > 0 && /* @__PURE__ */ jsxs("div", {
1523
- className: cls("p-2 px-4 border-t bg-surface-50 dark:bg-surface-900 flex justify-between items-center shrink-0", defaultBorderMixin),
1523
+ className: cls("p-2 px-4 border-t bg-surface-sheet flex justify-between items-center shrink-0", defaultBorderMixin),
1524
1524
  children: [/* @__PURE__ */ jsxs("div", {
1525
1525
  className: "flex space-x-4",
1526
1526
  children: [/* @__PURE__ */ jsxs("div", {
@@ -1627,4 +1627,4 @@ function JSONHighlight({ value }) {
1627
1627
  //#endregion
1628
1628
  export { JSEditor };
1629
1629
 
1630
- //# sourceMappingURL=JSEditor-75FTeu6P.js.map
1630
+ //# sourceMappingURL=JSEditor-qiuwmcvk.js.map