@lunora/studio 1.0.0-alpha.4 → 1.0.0-alpha.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +6 -0
- package/__assets__/package-og.svg +1 -1
- package/dist/index.d.ts +33 -18
- package/dist/index.js +29 -29
- package/dist/mount.d.ts +1 -1
- package/dist/mount.js +3 -2
- package/dist/{packem_shared/ApiTab-W3no0KOj.js → packem_chunks/ApiTab.js} +5 -5
- package/dist/{packem_shared/AuditPanel-Bq4o_IqT.js → packem_chunks/AuditPanel.js} +29 -41
- package/dist/{packem_shared/ExportImportPanel-dxY56TDF.js → packem_chunks/ExportImportPanel.js} +16 -11
- package/dist/{packem_shared/FileBrowser-Dhy4zES8.js → packem_chunks/FileBrowser.js} +15 -15
- package/dist/{packem_shared/FunctionRunner--fQJRPAD.js → packem_chunks/FunctionRunner.js} +10 -10
- package/dist/{packem_shared/FunctionStatsPanel-BjRUA_G3.js → packem_chunks/FunctionStatsPanel.js} +153 -208
- package/dist/{packem_shared/HealthPanel-PxclMWmA.js → packem_chunks/HealthPanel.js} +37 -29
- package/dist/{packem_shared/InsightsPanel-CWS_C-xW.js → packem_chunks/InsightsPanel.js} +108 -69
- package/dist/{packem_shared/LogsPanel-CTW8CFcM.js → packem_chunks/LogsPanel.js} +46 -58
- package/dist/{packem_shared/MailPanel-BwkvfIHF.js → packem_chunks/MailPanel.js} +45 -139
- package/dist/{packem_shared/MetricsPanel-BLuOhZQ4.js → packem_chunks/MetricsPanel.js} +41 -322
- package/dist/{packem_shared/MigrationsPanel-DT3lnwHF.js → packem_chunks/MigrationsPanel.js} +44 -51
- package/dist/{packem_shared/PitrPanel-CdErL7EJ.js → packem_chunks/PitrPanel.js} +9 -9
- package/dist/{packem_shared/SchemaViewer-LJDcmNIO.js → packem_chunks/SchemaViewer.js} +17 -16
- package/dist/{packem_shared/SecurityAdvisorPanel-C_ETsPih.js → packem_chunks/SecurityAdvisorPanel.js} +47 -31
- package/dist/packem_chunks/SettingsPanel.js +391 -0
- package/dist/{packem_shared/sql-editor-panel-BFRpzj6r.js → packem_chunks/SqlEditorPanel.js} +158 -387
- package/dist/{packem_shared/TableEditor-ChfUOZec.js → packem_chunks/TableEditor.js} +10 -68
- package/dist/packem_chunks/analytics-panel.js +261 -0
- package/dist/packem_chunks/auth-config-panel.js +365 -0
- package/dist/packem_chunks/auth-sessions-panel.js +175 -0
- package/dist/packem_chunks/containers-panel.js +247 -0
- package/dist/packem_chunks/dashboards-panel.js +780 -0
- package/dist/packem_chunks/fanout-panel.js +482 -0
- package/dist/packem_chunks/flags-panel.js +176 -0
- package/dist/packem_chunks/kv-browser.js +1896 -0
- package/dist/packem_chunks/log-drains-panel.js +273 -0
- package/dist/packem_chunks/organizations-panel.js +3178 -0
- package/dist/packem_chunks/payments-panel.js +186 -0
- package/dist/packem_chunks/permissions-panel.js +805 -0
- package/dist/packem_chunks/queues-panel.js +1075 -0
- package/dist/packem_chunks/rls-panel.js +315 -0
- package/dist/packem_chunks/schedule-panel.js +831 -0
- package/dist/packem_chunks/sparkline.js +79 -0
- package/dist/packem_chunks/storage-rules-panel.js +140 -0
- package/dist/packem_chunks/subscriptions-panel.js +238 -0
- package/dist/packem_chunks/users-panel.js +1731 -0
- package/dist/packem_chunks/vector-browser.js +281 -0
- package/dist/packem_chunks/workflows-panel.js +562 -0
- package/dist/packem_shared/{ADMIN_FUNCTIONS-DmBqMZ-z.js → ADMIN_FUNCTIONS-BHHJi3Gb.js} +7 -0
- package/dist/packem_shared/{ApiDocsPanel-C5-yJ1p7.js → ApiDocsPanel-CBma-lnp.js} +2 -2
- package/dist/packem_shared/{ApiReferencePanel-1vubqG5s.js → ApiReferencePanel-CQM3pPN7.js} +2 -1
- package/dist/packem_shared/{CommandPalette-BtgkBzZI.js → CommandPalette-X2tkbyHk.js} +1 -1
- package/dist/packem_shared/{DataBrowser-CtBe1So9.js → DataBrowser-D2ywrdId.js} +198 -247
- package/dist/packem_shared/{GlobalDataBrowser-BTEmGrph.js → GlobalDataBrowser-BkTPLzAY.js} +37 -66
- package/dist/packem_shared/HomePanel-D1Q9LZgK.js +14 -0
- package/dist/packem_shared/{OpenRpcReferencePanel-vbcYbv3V.js → OpenRpcReferencePanel-Dno-hfDb.js} +2 -1
- package/dist/packem_shared/{ScheduledJobs-CabfKbyM.js → ScheduledJobs-Ctw4jYtU.js} +163 -60
- package/dist/packem_shared/Studio-lJhzDAze.js +16 -0
- package/dist/packem_shared/{StudioApp-CHOZA-z-.js → StudioApp-DiMkupvZ.js} +276 -11
- package/dist/packem_shared/{advisor-view-CGcfMiPq.js → advisor-view-BX8OhG0w.js} +6 -6
- package/dist/packem_shared/alert-CdAET2K_.js +68 -0
- package/dist/packem_shared/{app.d-CCmwDEVs.d.ts → app.d-CNLRTrWw.d.ts} +1 -1
- package/dist/packem_shared/{bar-chart-CzJAgqkp.js → bar-chart-DSwcWIRy.js} +5 -4
- package/dist/packem_shared/browser-storage-BTrX4y3B.js +215 -0
- package/dist/packem_shared/{cf-links-2cktDedA.js → cf-links-BZfRdxSE.js} +1 -1
- package/dist/packem_shared/{data-grid-B5CaV3wS.js → data-grid-CdXztApG.js} +1 -1
- package/dist/packem_shared/data-view-params-Cd6yRVbv.js +96 -0
- package/dist/packem_shared/error-alert-CXjqyGw9.js +114 -0
- package/dist/packem_shared/{grid-features-CzUfqgsM.js → grid-features-BF-KBDFz.js} +131 -163
- package/dist/packem_shared/home-panel-TFcRf9Ui.js +1889 -0
- package/dist/packem_shared/{internal-rXJEAhXS.js → internal-CYcbqMjX.js} +44 -3
- package/dist/packem_shared/modal-shell-hyaJvIJ6.js +100 -0
- package/dist/packem_shared/{reference-view-B4E49Lip.js → reference-view-DUiJcILV.js} +6 -45
- package/dist/packem_shared/scroll-area-DLhcy-ml.js +93 -0
- package/dist/packem_shared/select-UkNYCT3s.js +273 -0
- package/dist/packem_shared/skeleton-CGhL0p20.js +45 -0
- package/dist/packem_shared/{sparkline-10dG-_f0.js → sparkline-BnA1kC9X.js} +1 -1
- package/dist/packem_shared/studio-Dh9UlaF_.js +4015 -0
- package/dist/packem_shared/{table-_RzNvy3R.js → table-DsCa9Qp9.js} +1 -1
- package/dist/packem_shared/{table-list-sidebar-Bg7uzbvC.js → table-list-sidebar-UVIXQJdU.js} +1 -1
- package/dist/packem_shared/use-admin-query-CfHYWx5n.js +106 -0
- package/dist/packem_shared/use-async-submit-DJQiPc-_.js +91 -0
- package/dist/standalone/chunk-25AYY4H7.js +2 -0
- package/dist/standalone/chunk-2ANAF4ZM.js +1 -0
- package/dist/standalone/chunk-2K47A3P6.js +1 -0
- package/dist/standalone/chunk-2NGUNNGW.js +1 -0
- package/dist/standalone/chunk-3CJW6NWG.js +4 -0
- package/dist/standalone/chunk-3OA7PECS.js +6 -0
- package/dist/standalone/chunk-3OIHOXVV.js +1 -0
- package/dist/standalone/chunk-447TAUFD.js +1 -0
- package/dist/standalone/chunk-4QHKBC77.js +1 -0
- package/dist/standalone/chunk-5C4TSNE6.js +1 -0
- package/dist/standalone/chunk-5OIBXYZM.js +1 -0
- package/dist/standalone/chunk-6HSHEMZV.js +76 -0
- package/dist/standalone/chunk-6JIZ34MB.js +3 -0
- package/dist/standalone/chunk-6VO23MMW.js +4 -0
- package/dist/standalone/chunk-7MVSQS7B.js +1 -0
- package/dist/standalone/chunk-7TJJXVSE.js +1 -0
- package/dist/standalone/chunk-7YXOPTWI.js +1 -0
- package/dist/standalone/chunk-AHILM3ZP.js +1 -0
- package/dist/standalone/chunk-BGXOXASQ.js +1 -0
- package/dist/standalone/chunk-BJGBHGK3.js +1 -0
- package/dist/standalone/chunk-BOXSWNXZ.js +1 -0
- package/dist/standalone/chunk-BX5MKYOC.js +1 -0
- package/dist/standalone/chunk-CKSHCYGC.js +2 -0
- package/dist/standalone/chunk-DWDILV2E.js +1 -0
- package/dist/standalone/chunk-E75ANNWX.js +19 -0
- package/dist/standalone/chunk-EQZQOTJY.js +1 -0
- package/dist/standalone/chunk-GTLEWM5Y.js +1 -0
- package/dist/standalone/chunk-GTM65MVX.js +1 -0
- package/dist/standalone/chunk-GUI5GFFI.js +1 -0
- package/dist/standalone/chunk-HN6KJXYQ.js +1 -0
- package/dist/standalone/chunk-HV7G6DFP.js +5 -0
- package/dist/standalone/chunk-HYDJNCGW.js +1 -0
- package/dist/standalone/chunk-HZK5RQHG.js +1 -0
- package/dist/standalone/chunk-IN2SYVJB.js +1 -0
- package/dist/standalone/chunk-IOANPSJN.js +1 -0
- package/dist/standalone/chunk-ISDZPW3V.js +1 -0
- package/dist/standalone/chunk-IXDH4GL5.js +1 -0
- package/dist/standalone/chunk-J6J54MBP.js +1 -0
- package/dist/standalone/chunk-J73VHFCL.js +1 -0
- package/dist/standalone/chunk-JHKMUTIF.js +13 -0
- package/dist/standalone/chunk-JPRH6DPK.js +1 -0
- package/dist/standalone/chunk-JSEXCW5Q.js +1 -0
- package/dist/standalone/chunk-KA5YB3VP.js +1 -0
- package/dist/standalone/chunk-KBB75WNT.js +1 -0
- package/dist/standalone/chunk-KEGAWN6Y.js +1 -0
- package/dist/standalone/chunk-KJJ3WM6H.js +4 -0
- package/dist/standalone/chunk-KQV4NGH3.js +1 -0
- package/dist/standalone/chunk-KSKXW5PX.js +1 -0
- package/dist/standalone/chunk-KUH4P5F5.js +1 -0
- package/dist/standalone/chunk-KYJPPVGB.js +1 -0
- package/dist/standalone/chunk-KZ6INM5M.js +1 -0
- package/dist/standalone/chunk-L2TJVSDQ.js +1 -0
- package/dist/standalone/chunk-L7SK4ZZD.js +1 -0
- package/dist/standalone/chunk-LAK5VSPI.js +1 -0
- package/dist/standalone/chunk-LBN7LPVK.js +1 -0
- package/dist/standalone/chunk-LNZIB2MD.js +1 -0
- package/dist/standalone/chunk-MJWVMKQ4.js +6 -0
- package/dist/standalone/chunk-MLZYX5CQ.js +1 -0
- package/dist/standalone/chunk-N2X2OO4V.js +1 -0
- package/dist/standalone/chunk-NGKITPQP.js +13 -0
- package/dist/standalone/chunk-O3NAGRTR.js +1 -0
- package/dist/standalone/chunk-OZACQNKG.js +1 -0
- package/dist/standalone/chunk-PNDNXS5Z.js +1 -0
- package/dist/standalone/chunk-Q7DMUTUE.js +1 -0
- package/dist/standalone/chunk-QAFAJBAW.js +1 -0
- package/dist/standalone/chunk-QBAT52GB.js +1 -0
- package/dist/standalone/chunk-RHZ4M2NZ.js +1 -0
- package/dist/standalone/chunk-RRCPZMC2.js +22 -0
- package/dist/standalone/chunk-SEU5V7I6.js +1 -0
- package/dist/standalone/chunk-TAD43CG5.js +1 -0
- package/dist/standalone/chunk-TBMYIZIO.js +1 -0
- package/dist/standalone/chunk-TDZ44E5I.js +4 -0
- package/dist/standalone/chunk-THNBTMUF.js +1 -0
- package/dist/standalone/chunk-TIQISBGK.js +1 -0
- package/dist/standalone/chunk-TMYVNQ66.js +1 -0
- package/dist/standalone/chunk-TQ36RWOP.js +1 -0
- package/dist/standalone/chunk-UGUEC6BC.js +1 -0
- package/dist/standalone/chunk-UJB2LEI4.js +4 -0
- package/dist/standalone/chunk-UK64ZSUW.js +1 -0
- package/dist/standalone/chunk-UKDJ4H7I.js +1 -0
- package/dist/standalone/chunk-VLXV72QE.js +1 -0
- package/dist/standalone/chunk-VON7JUPG.js +1 -0
- package/dist/standalone/chunk-W3JK4YWR.js +1 -0
- package/dist/standalone/chunk-W3SHEIAL.js +3 -0
- package/dist/standalone/chunk-WI7GWFEG.js +1 -0
- package/dist/standalone/chunk-WIHXMNUY.js +1 -0
- package/dist/standalone/chunk-WLDVXVI2.js +1 -0
- package/dist/standalone/chunk-XLXNLJ4N.js +1 -0
- package/dist/standalone/chunk-XNJNSCLM.js +1 -0
- package/dist/standalone/chunk-YAECF5LW.js +1 -0
- package/dist/standalone/chunk-YBGC4PPD.js +1 -0
- package/dist/standalone/chunk-YJAPWSDC.js +4 -0
- package/dist/standalone/chunk-ZEJB6DXU.js +8 -0
- package/dist/standalone/chunk-ZFNBPAIZ.js +1 -0
- package/dist/standalone/chunk-ZHVTQ37P.js +1 -0
- package/dist/standalone/chunk-ZIGWVHCS.js +1 -0
- package/dist/standalone/chunk-ZPP2KOR4.js +1 -0
- package/dist/standalone/chunk-ZPUO7FNI.js +1 -0
- package/dist/standalone/studio.js +104 -246
- package/dist/styles.css +2 -2
- package/package.json +15 -13
- package/dist/packem_shared/HomePanel-Cw16stjq.js +0 -1273
- package/dist/packem_shared/SettingsPanel-C0uLRf5P.js +0 -176
- package/dist/packem_shared/SqlEditorPanel-CguV7otm.js +0 -13
- package/dist/packem_shared/Studio-DFWAlcuf.js +0 -33
- package/dist/packem_shared/studio-Bj8psK1c.js +0 -10303
- package/dist/packem_shared/use-live-admin-Dq6g3daN.js +0 -73
- package/dist/packem_shared/use-live-shard-seed-Cuk3dnH0.js +0 -76
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { c } from 'react/compiler-runtime';
|
|
2
2
|
import { useLunora } from '@lunora/react';
|
|
3
3
|
import { useNavigate } from '@tanstack/react-router';
|
|
4
|
-
import { useState, useEffect, useMemo } from 'react';
|
|
5
|
-
import { ShardInput } from '
|
|
6
|
-
import { B as Button } from '
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
4
|
+
import { useState, useRef, useCallback, useEffect, useMemo } from 'react';
|
|
5
|
+
import { ShardInput } from '../packem_shared/ShardInput-gx_DZXXn.js';
|
|
6
|
+
import { B as Button } from '../packem_shared/button-BhsN2uZH.js';
|
|
7
|
+
import { u as useAdminQuery } from '../packem_shared/use-admin-query-CfHYWx5n.js';
|
|
8
|
+
import useDebounced from '../packem_shared/useDebounced-Dxncpg6z.js';
|
|
9
|
+
import { useT } from '../packem_shared/DEFAULT_LOCALE-CiX4W7Kr.js';
|
|
10
|
+
import { ADMIN_FUNCTIONS } from '../packem_shared/ADMIN_FUNCTIONS-BHHJi3Gb.js';
|
|
11
|
+
import { f as fireAndForget, c as callOptions, a as adminRef } from '../packem_shared/internal-CYcbqMjX.js';
|
|
12
|
+
import { r as recordShard } from '../packem_shared/shard-history-DyebH1R5.js';
|
|
13
|
+
import { a as advisoryRow, A as AdvisorView } from '../packem_shared/advisor-view-BX8OhG0w.js';
|
|
14
|
+
import { ConfirmButton } from '../packem_shared/ConfirmButton-C2eVi2Qv.js';
|
|
14
15
|
import { jsxDEV } from 'react/jsx-dev-runtime';
|
|
15
|
-
import { deriveInsights } from '
|
|
16
|
+
import { deriveInsights } from '../packem_shared/DEFAULT_INSIGHT_THRESHOLDS-DjF0h-gA.js';
|
|
16
17
|
import { runAdvisor, RUNTIME_LINTS } from '@lunora/advisor';
|
|
17
18
|
|
|
18
19
|
const hasIndexMetadata = (metadata) => {
|
|
@@ -185,9 +186,6 @@ const deriveRuntimeAdvisories = (inputs) => {
|
|
|
185
186
|
return visible.map((finding) => advisoryRow(finding));
|
|
186
187
|
};
|
|
187
188
|
|
|
188
|
-
const GET_ADVISORIES = adminRef(ADMIN_FUNCTIONS.getAdvisories);
|
|
189
|
-
const GET_FUNCTION_STATS = adminRef(ADMIN_FUNCTIONS.getFunctionStats);
|
|
190
|
-
const GET_METRICS = adminRef(ADMIN_FUNCTIONS.getMetrics);
|
|
191
189
|
const LIST_TABLES = adminRef(ADMIN_FUNCTIONS.listTables);
|
|
192
190
|
const LIST_TABLE_INDEXES = adminRef(ADMIN_FUNCTIONS.listTableIndexes);
|
|
193
191
|
const percent = (rate) => `${(rate * 100).toFixed(1)}%`;
|
|
@@ -286,46 +284,41 @@ const InsightsPanel = ({
|
|
|
286
284
|
const navigate = useNavigate();
|
|
287
285
|
const t = useT();
|
|
288
286
|
const [shardKey, setShardKey] = useState(initialShardKey ?? "");
|
|
289
|
-
const [metrics, setMetrics] = useState(null);
|
|
290
|
-
const [functions, setFunctions] = useState(null);
|
|
291
|
-
const [advisories, setAdvisories] = useState(null);
|
|
292
|
-
const [indexHits, setIndexHits] = useState(null);
|
|
293
287
|
const [declaredIndexes, setDeclaredIndexes] = useState(null);
|
|
294
288
|
const [shardTraffic, setShardTraffic] = useState(null);
|
|
295
|
-
const
|
|
289
|
+
const debouncedShard = useDebounced(shardKey.trim(), 400);
|
|
290
|
+
const latestEnumeratedShard = useRef("");
|
|
291
|
+
const metricsQuery = useAdminQuery(ADMIN_FUNCTIONS.getMetrics, {}, {
|
|
292
|
+
live: true,
|
|
293
|
+
shardKey: debouncedShard
|
|
294
|
+
});
|
|
295
|
+
const functionsQuery = useAdminQuery(ADMIN_FUNCTIONS.getFunctionStats, {}, {
|
|
296
|
+
live: true,
|
|
297
|
+
shardKey: debouncedShard
|
|
298
|
+
});
|
|
299
|
+
const advisoriesQuery = useAdminQuery(ADMIN_FUNCTIONS.getAdvisories, {}, {
|
|
300
|
+
live: true,
|
|
301
|
+
shardKey: debouncedShard
|
|
302
|
+
});
|
|
303
|
+
const metrics = metricsQuery.data ?? null;
|
|
304
|
+
const functions = functionsQuery.data?.functions ?? null;
|
|
305
|
+
const advisories = advisoriesQuery.data?.advisories ?? null;
|
|
306
|
+
const indexHits = metricsQuery.data?.indexHits ?? null;
|
|
307
|
+
const error = metricsQuery.error !== null && functionsQuery.error !== null ? metricsQuery.error : null;
|
|
296
308
|
const fanShardTraffic = loadShardTraffic ?? ((table) => client.shardTraffic(table));
|
|
297
|
-
const
|
|
298
|
-
const
|
|
299
|
-
if (
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
setError(null);
|
|
303
|
-
recordShard(shard);
|
|
304
|
-
}
|
|
305
|
-
setMetrics(snapshot.status === "fulfilled" ? snapshot.value : null);
|
|
306
|
-
setFunctions(stats.status === "fulfilled" ? stats.value.functions : null);
|
|
307
|
-
setAdvisories(advisorySnapshot.status === "fulfilled" ? advisorySnapshot.value.advisories : null);
|
|
308
|
-
setIndexHits(snapshot.status === "fulfilled" ? snapshot.value.indexHits ?? null : null);
|
|
309
|
-
let tableNames = [];
|
|
310
|
-
try {
|
|
311
|
-
const tables = await client.query(LIST_TABLES, {}, callOptions(shard));
|
|
312
|
-
tableNames = tables.map((table_0) => table_0.name);
|
|
313
|
-
const indexResults = await Promise.allSettled(tables.map(async (table_1) => [table_1.name, await client.query(LIST_TABLE_INDEXES, {
|
|
314
|
-
table: table_1.name
|
|
315
|
-
}, callOptions(shard))]));
|
|
316
|
-
const declared = [];
|
|
317
|
-
for (const result of indexResults) {
|
|
318
|
-
if (result.status === "fulfilled") {
|
|
319
|
-
const [name, payload] = result.value;
|
|
320
|
-
declared.push(...declaredIndexesFor(name, payload.indexes));
|
|
321
|
-
}
|
|
309
|
+
const loadShardTrafficFeed = async (tableNames, shard) => {
|
|
310
|
+
const seedTable = tableNames[0];
|
|
311
|
+
if (seedTable === void 0 || seedTable === "") {
|
|
312
|
+
if (latestEnumeratedShard.current === shard) {
|
|
313
|
+
setShardTraffic(null);
|
|
322
314
|
}
|
|
323
|
-
|
|
324
|
-
} catch {
|
|
325
|
-
setDeclaredIndexes(null);
|
|
315
|
+
return;
|
|
326
316
|
}
|
|
327
317
|
try {
|
|
328
|
-
const traffic = await fanShardTraffic(
|
|
318
|
+
const traffic = await fanShardTraffic(seedTable);
|
|
319
|
+
if (latestEnumeratedShard.current !== shard) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
329
322
|
const byShard = /* @__PURE__ */ new Map();
|
|
330
323
|
for (const entry of traffic.shards) {
|
|
331
324
|
if (!byShard.has(entry.shardKey)) {
|
|
@@ -337,31 +330,76 @@ const InsightsPanel = ({
|
|
|
337
330
|
}
|
|
338
331
|
setShardTraffic([...byShard.values()]);
|
|
339
332
|
} catch {
|
|
340
|
-
|
|
333
|
+
if (latestEnumeratedShard.current === shard) {
|
|
334
|
+
setShardTraffic(null);
|
|
335
|
+
}
|
|
341
336
|
}
|
|
342
337
|
};
|
|
343
|
-
|
|
338
|
+
const enumerateShard = useCallback(
|
|
339
|
+
async (shard) => {
|
|
340
|
+
latestEnumeratedShard.current = shard;
|
|
341
|
+
let tableNames = [];
|
|
342
|
+
try {
|
|
343
|
+
const tables = await client.query(LIST_TABLES, {}, callOptions(shard));
|
|
344
|
+
if (latestEnumeratedShard.current !== shard) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
recordShard(shard);
|
|
348
|
+
tableNames = tables.map((table) => table.name);
|
|
349
|
+
const indexResults = await Promise.allSettled(tables.map(async (table) => [table.name, await client.query(LIST_TABLE_INDEXES, {
|
|
350
|
+
table: table.name
|
|
351
|
+
}, callOptions(shard))]));
|
|
352
|
+
if (latestEnumeratedShard.current !== shard) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const declared = [];
|
|
356
|
+
for (const result of indexResults) {
|
|
357
|
+
if (result.status === "fulfilled") {
|
|
358
|
+
const [name, payload] = result.value;
|
|
359
|
+
declared.push(...declaredIndexesFor(name, payload.indexes));
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
setDeclaredIndexes(declared);
|
|
363
|
+
} catch {
|
|
364
|
+
if (latestEnumeratedShard.current === shard) {
|
|
365
|
+
setDeclaredIndexes(null);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
await loadShardTrafficFeed(tableNames, shard);
|
|
369
|
+
},
|
|
370
|
+
// `fanShardTraffic`/`loadShardTrafficFeed` are render-fresh closures; the
|
|
371
|
+
// enumeration only needs to re-run on a shard change (or a manual visibility
|
|
372
|
+
// refresh), so they're intentionally excluded from the cache key.
|
|
373
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
374
|
+
[client]
|
|
375
|
+
);
|
|
376
|
+
useEffect(() => {
|
|
377
|
+
fireAndForget(enumerateShard(debouncedShard));
|
|
378
|
+
}, [debouncedShard, enumerateShard]);
|
|
344
379
|
useEffect(() => {
|
|
345
380
|
const onVisible = () => {
|
|
346
381
|
if (document.visibilityState === "visible") {
|
|
347
|
-
|
|
382
|
+
metricsQuery.refetch();
|
|
383
|
+
functionsQuery.refetch();
|
|
384
|
+
advisoriesQuery.refetch();
|
|
385
|
+
fireAndForget(enumerateShard(debouncedShard));
|
|
348
386
|
}
|
|
349
387
|
};
|
|
350
388
|
document.addEventListener("visibilitychange", onVisible);
|
|
351
389
|
return () => {
|
|
352
390
|
document.removeEventListener("visibilitychange", onVisible);
|
|
353
391
|
};
|
|
354
|
-
}, [
|
|
355
|
-
const jumpToSchemaIndex = (
|
|
392
|
+
}, [advisoriesQuery, debouncedShard, enumerateShard, functionsQuery, metricsQuery]);
|
|
393
|
+
const jumpToSchemaIndex = useCallback((table) => {
|
|
356
394
|
fireAndForget(navigate({
|
|
357
395
|
search: {
|
|
358
|
-
table
|
|
396
|
+
table
|
|
359
397
|
},
|
|
360
398
|
to: "/schema"
|
|
361
399
|
}));
|
|
362
|
-
};
|
|
400
|
+
}, [navigate]);
|
|
363
401
|
const insights = deriveInsights(metrics, functions);
|
|
364
|
-
const missingIndexTables = new Set(insights.filter((insight) => insight.kind === "missing-index").flatMap((
|
|
402
|
+
const missingIndexTables = new Set(insights.filter((insight) => insight.kind === "missing-index").flatMap((insight) => insight.tables ?? []));
|
|
365
403
|
const runtimeRows = deriveRuntimeAdvisories({
|
|
366
404
|
declaredIndexes: declaredIndexes ?? [],
|
|
367
405
|
functions,
|
|
@@ -370,18 +408,18 @@ const InsightsPanel = ({
|
|
|
370
408
|
suppressHotScanTables: missingIndexTables
|
|
371
409
|
});
|
|
372
410
|
const rows = useMemo(() => {
|
|
373
|
-
const insightRows = insights.map((
|
|
374
|
-
const
|
|
411
|
+
const insightRows = insights.map((insight) => {
|
|
412
|
+
const tables = insight.kind === "missing-index" ? insight.tables ?? [] : [];
|
|
375
413
|
return {
|
|
376
|
-
action:
|
|
414
|
+
action: tables.length > 0 ? tables.map((table) => /* @__PURE__ */ jsxDEV(AddIndexButton, {
|
|
377
415
|
onJump: jumpToSchemaIndex,
|
|
378
|
-
table
|
|
379
|
-
},
|
|
380
|
-
description:
|
|
381
|
-
entity:
|
|
382
|
-
issueType: insightTitle(t,
|
|
383
|
-
key: `${
|
|
384
|
-
level:
|
|
416
|
+
table
|
|
417
|
+
}, table, false)) : void 0,
|
|
418
|
+
description: insight.message === void 0 ? insightDetail(t, insight) : `${insightDetail(t, insight)} — ${insight.message}`,
|
|
419
|
+
entity: insight.fn,
|
|
420
|
+
issueType: insightTitle(t, insight),
|
|
421
|
+
key: `${insight.kind}:${insight.fn ?? ""}`,
|
|
422
|
+
level: insight.severity
|
|
385
423
|
};
|
|
386
424
|
});
|
|
387
425
|
const indexAdvisoryLints = /* @__PURE__ */ new Set(["unindexed_foreign_key", "unindexed_relation_target"]);
|
|
@@ -389,16 +427,16 @@ const InsightsPanel = ({
|
|
|
389
427
|
const base = advisoryRow(finding);
|
|
390
428
|
if (indexAdvisoryLints.has(finding.name) && hasIndexMetadata(finding.metadata)) {
|
|
391
429
|
const {
|
|
392
|
-
table
|
|
430
|
+
table,
|
|
393
431
|
suggestedIndex
|
|
394
432
|
} = finding.metadata;
|
|
395
|
-
const testId = `in-apply-index-${
|
|
433
|
+
const testId = `in-apply-index-${table}-${suggestedIndex.name}`;
|
|
396
434
|
return {
|
|
397
435
|
...base,
|
|
398
436
|
action: /* @__PURE__ */ jsxDEV(ApplyIndexButton, {
|
|
399
437
|
fields: suggestedIndex.fields,
|
|
400
438
|
indexName: suggestedIndex.name,
|
|
401
|
-
table
|
|
439
|
+
table,
|
|
402
440
|
testId
|
|
403
441
|
}, void 0, false)
|
|
404
442
|
};
|
|
@@ -414,6 +452,7 @@ const InsightsPanel = ({
|
|
|
414
452
|
}, void 0, false);
|
|
415
453
|
return /* @__PURE__ */ jsxDEV(AdvisorView, {
|
|
416
454
|
error,
|
|
455
|
+
errorSource: error === null ? void 0 : metricsQuery.errorSource,
|
|
417
456
|
rows,
|
|
418
457
|
testId: "lunora-insights",
|
|
419
458
|
toolbar
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { c } from 'react/compiler-runtime';
|
|
2
|
-
import { useLunora } from '@lunora/react';
|
|
3
2
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
4
|
-
import { useState, useMemo, useRef } from 'react';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
3
|
+
import { useState, useEffect, useMemo, useRef } from 'react';
|
|
4
|
+
import { E as ErrorAlert } from '../packem_shared/error-alert-CXjqyGw9.js';
|
|
5
|
+
import { L as LiveError } from '../packem_shared/live-status-FZ0psC1z.js';
|
|
6
|
+
import { ShardInput } from '../packem_shared/ShardInput-gx_DZXXn.js';
|
|
7
|
+
import { B as Badge } from '../packem_shared/badge-B2PKA1-5.js';
|
|
8
|
+
import { E as EmptyState } from '../packem_shared/empty-state-DY_oe0k6.js';
|
|
9
|
+
import { I as Input } from '../packem_shared/input-XH4r1Pt1.js';
|
|
10
|
+
import { u as useAdminQuery } from '../packem_shared/use-admin-query-CfHYWx5n.js';
|
|
11
|
+
import useDebounced from '../packem_shared/useDebounced-Dxncpg6z.js';
|
|
12
|
+
import { useT } from '../packem_shared/DEFAULT_LOCALE-CiX4W7Kr.js';
|
|
13
|
+
import { ADMIN_FUNCTIONS } from '../packem_shared/ADMIN_FUNCTIONS-BHHJi3Gb.js';
|
|
14
|
+
import { a as CLOUDFLARE_OBSERVABILITY_URL } from '../packem_shared/cf-links-BZfRdxSE.js';
|
|
15
|
+
import { r as recordShard } from '../packem_shared/shard-history-DyebH1R5.js';
|
|
16
|
+
import { c as cn } from '../packem_shared/utils-B05Dmz_H.js';
|
|
17
|
+
import { f as flooredRectObserver } from '../packem_shared/virtual-rect-CVMUskSm.js';
|
|
19
18
|
import { jsxDEV } from 'react/jsx-dev-runtime';
|
|
20
19
|
|
|
21
20
|
const SCROLL_HEIGHT = 400;
|
|
@@ -316,8 +315,6 @@ const RequestRow = (t0) => {
|
|
|
316
315
|
}
|
|
317
316
|
return t17;
|
|
318
317
|
};
|
|
319
|
-
const GET_LOGS = adminRef(ADMIN_FUNCTIONS.getLogs);
|
|
320
|
-
const GET_REQUEST_LOG = adminRef(ADMIN_FUNCTIONS.getRequestLog);
|
|
321
318
|
const entriesOf = (result) => {
|
|
322
319
|
const {
|
|
323
320
|
entries
|
|
@@ -488,13 +485,9 @@ const SummaryBucketRow = (t0) => {
|
|
|
488
485
|
const LogsPanel = ({
|
|
489
486
|
initialShardKey
|
|
490
487
|
}) => {
|
|
491
|
-
const client = useLunora();
|
|
492
488
|
const t = useT();
|
|
493
489
|
const [view, setView] = useState("requests");
|
|
494
490
|
const [shardKey, setShardKey] = useState(initialShardKey ?? "");
|
|
495
|
-
const [entries, setEntries] = useState([]);
|
|
496
|
-
const [requests, setRequests] = useState([]);
|
|
497
|
-
const [error, setError] = useState(null);
|
|
498
491
|
const [search, setSearch] = useState("");
|
|
499
492
|
const [levelFilter, setLevelFilter] = useState(() => /* @__PURE__ */ new Set());
|
|
500
493
|
const [pathFilter, setPathFilter] = useState("");
|
|
@@ -504,43 +497,37 @@ const LogsPanel = ({
|
|
|
504
497
|
const [userIdFilter, setUserIdFilter] = useState("");
|
|
505
498
|
const [tableFilter, setTableFilter] = useState("");
|
|
506
499
|
const [outcomeFilter, setOutcomeFilter] = useState("all");
|
|
507
|
-
const
|
|
500
|
+
const debouncedShard = useDebounced(shardKey.trim(), 400);
|
|
508
501
|
const requestQuery = buildRequestQuery({
|
|
509
502
|
functionPathPrefix: pathPrefix,
|
|
510
503
|
outcome: outcomeFilter,
|
|
511
504
|
tableTouched: tableFilter,
|
|
512
505
|
userId: userIdFilter
|
|
513
506
|
});
|
|
514
|
-
const
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
507
|
+
const requestsQuery = useAdminQuery(ADMIN_FUNCTIONS.getRequestLog, requestQuery, {
|
|
508
|
+
enabled: view === "requests",
|
|
509
|
+
live: true,
|
|
510
|
+
shardKey: debouncedShard
|
|
511
|
+
});
|
|
512
|
+
const errorsQuery = useAdminQuery(ADMIN_FUNCTIONS.getLogs, {}, {
|
|
513
|
+
enabled: view === "errors",
|
|
514
|
+
live: true,
|
|
515
|
+
shardKey: debouncedShard
|
|
516
|
+
});
|
|
517
|
+
const activeQuery = view === "requests" ? requestsQuery : errorsQuery;
|
|
518
|
+
const {
|
|
519
|
+
error,
|
|
520
|
+
errorSource,
|
|
521
|
+
isLoading: activeLoading,
|
|
522
|
+
liveError
|
|
523
|
+
} = activeQuery;
|
|
524
|
+
const entries = entriesOf(errorsQuery.data);
|
|
525
|
+
const requests = entriesOf(requestsQuery.data);
|
|
526
|
+
useEffect(() => {
|
|
527
|
+
if (activeQuery.data !== void 0) {
|
|
528
|
+
recordShard(debouncedShard);
|
|
531
529
|
}
|
|
532
|
-
};
|
|
533
|
-
const committedShard = useLiveShardSeed(shardKey, refresh, [view, requestQuery]);
|
|
534
|
-
useLiveAdmin(ADMIN_FUNCTIONS.getRequestLog, requestQuery, committedShard ?? "", (result_1) => {
|
|
535
|
-
setError(null);
|
|
536
|
-
setLiveError(void 0);
|
|
537
|
-
setRequests(entriesOf(result_1));
|
|
538
|
-
}, view === "requests" && committedShard !== void 0, setLiveError);
|
|
539
|
-
useLiveAdmin(ADMIN_FUNCTIONS.getLogs, {}, committedShard ?? "", (result_2) => {
|
|
540
|
-
setError(null);
|
|
541
|
-
setLiveError(void 0);
|
|
542
|
-
setEntries(entriesOf(result_2));
|
|
543
|
-
}, view === "errors" && committedShard !== void 0, setLiveError);
|
|
530
|
+
}, [activeQuery.data, debouncedShard]);
|
|
544
531
|
const filtered = filterLogs(entries, {
|
|
545
532
|
levels: levelFilter,
|
|
546
533
|
now: Date.now(),
|
|
@@ -556,10 +543,13 @@ const LogsPanel = ({
|
|
|
556
543
|
return "error";
|
|
557
544
|
}
|
|
558
545
|
if (activeCount === 0) {
|
|
546
|
+
if (activeLoading) {
|
|
547
|
+
return summaryVisible ? "summary" : "list";
|
|
548
|
+
}
|
|
559
549
|
return "empty";
|
|
560
550
|
}
|
|
561
551
|
return summaryVisible ? "summary" : "list";
|
|
562
|
-
}, [activeCount, error, summaryVisible]);
|
|
552
|
+
}, [activeCount, activeLoading, error, summaryVisible]);
|
|
563
553
|
const scrollRef = useRef(null);
|
|
564
554
|
const virtualizer = useVirtualizer({
|
|
565
555
|
count: activeCount,
|
|
@@ -755,11 +745,9 @@ const LogsPanel = ({
|
|
|
755
745
|
children: t("error")
|
|
756
746
|
}, void 0, false)]
|
|
757
747
|
}, void 0, true)]
|
|
758
|
-
}, void 0, true), readout === "error" && /* @__PURE__ */ jsxDEV(
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
role: "alert",
|
|
762
|
-
children: error
|
|
748
|
+
}, void 0, true), readout === "error" && /* @__PURE__ */ jsxDEV(ErrorAlert, {
|
|
749
|
+
error: errorSource,
|
|
750
|
+
testId: "lg-error"
|
|
763
751
|
}, void 0, false), readout === "empty" && /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
764
752
|
description: t("Function and request logs for this shard show up here as your app handles traffic."),
|
|
765
753
|
icon: /* @__PURE__ */ jsxDEV("svg", {
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
'use client';
|
|
2
1
|
import { useLunora } from '@lunora/react';
|
|
3
|
-
import { useState,
|
|
4
|
-
import {
|
|
5
|
-
import { B as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { c as cn } from './utils-B05Dmz_H.js';
|
|
11
|
-
import { jsxDEV, Fragment } from 'react/jsx-dev-runtime';
|
|
2
|
+
import { useState, useMemo } from 'react';
|
|
3
|
+
import { E as ErrorAlert } from '../packem_shared/error-alert-CXjqyGw9.js';
|
|
4
|
+
import { B as Badge } from '../packem_shared/badge-B2PKA1-5.js';
|
|
5
|
+
import { B as Button } from '../packem_shared/button-BhsN2uZH.js';
|
|
6
|
+
import { E as EmptyState } from '../packem_shared/empty-state-DY_oe0k6.js';
|
|
7
|
+
import { I as Input } from '../packem_shared/input-XH4r1Pt1.js';
|
|
8
|
+
import { S as ScrollArea } from '../packem_shared/scroll-area-DLhcy-ml.js';
|
|
12
9
|
import { Separator as Separator$1 } from '@base-ui/react/separator';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
10
|
+
import { c as cn } from '../packem_shared/utils-B05Dmz_H.js';
|
|
11
|
+
import { jsxDEV, Fragment } from 'react/jsx-dev-runtime';
|
|
12
|
+
import { u as useAdminQuery } from '../packem_shared/use-admin-query-CfHYWx5n.js';
|
|
13
|
+
import { useAutoRefresh } from '../packem_shared/DEFAULT_AUTO_REFRESH_MS-Vxwaxx51.js';
|
|
14
|
+
import { useT } from '../packem_shared/DEFAULT_LOCALE-CiX4W7Kr.js';
|
|
15
|
+
import { ADMIN_FUNCTIONS } from '../packem_shared/ADMIN_FUNCTIONS-BHHJi3Gb.js';
|
|
16
|
+
import { i as formatTimestamp, f as fireAndForget, g as copyToClipboard, c as callOptions, e as errorMessage, a as adminRef } from '../packem_shared/internal-CYcbqMjX.js';
|
|
17
17
|
|
|
18
18
|
function Separator({
|
|
19
19
|
className,
|
|
@@ -28,93 +28,6 @@ function Separator({
|
|
|
28
28
|
}, void 0, false);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
function ScrollArea(t0) {
|
|
32
|
-
const $ = c(14);
|
|
33
|
-
let children;
|
|
34
|
-
let className;
|
|
35
|
-
let props;
|
|
36
|
-
if ($[0] !== t0) {
|
|
37
|
-
({
|
|
38
|
-
className,
|
|
39
|
-
children,
|
|
40
|
-
...props
|
|
41
|
-
} = t0);
|
|
42
|
-
$[0] = t0;
|
|
43
|
-
$[1] = children;
|
|
44
|
-
$[2] = className;
|
|
45
|
-
$[3] = props;
|
|
46
|
-
} else {
|
|
47
|
-
children = $[1];
|
|
48
|
-
className = $[2];
|
|
49
|
-
props = $[3];
|
|
50
|
-
}
|
|
51
|
-
let t1;
|
|
52
|
-
if ($[4] !== className) {
|
|
53
|
-
t1 = cn("relative", className);
|
|
54
|
-
$[4] = className;
|
|
55
|
-
$[5] = t1;
|
|
56
|
-
} else {
|
|
57
|
-
t1 = $[5];
|
|
58
|
-
}
|
|
59
|
-
let t2;
|
|
60
|
-
if ($[6] !== children) {
|
|
61
|
-
t2 = /* @__PURE__ */ jsxDEV(ScrollArea$1.Viewport, {
|
|
62
|
-
"data-slot": "scroll-area-viewport",
|
|
63
|
-
className: "size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1",
|
|
64
|
-
children
|
|
65
|
-
}, void 0, false);
|
|
66
|
-
$[6] = children;
|
|
67
|
-
$[7] = t2;
|
|
68
|
-
} else {
|
|
69
|
-
t2 = $[7];
|
|
70
|
-
}
|
|
71
|
-
let t3;
|
|
72
|
-
let t4;
|
|
73
|
-
if ($[8] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
|
|
74
|
-
t3 = /* @__PURE__ */ jsxDEV(ScrollBar, {}, void 0, false);
|
|
75
|
-
t4 = /* @__PURE__ */ jsxDEV(ScrollArea$1.Corner, {}, void 0, false);
|
|
76
|
-
$[8] = t3;
|
|
77
|
-
$[9] = t4;
|
|
78
|
-
} else {
|
|
79
|
-
t3 = $[8];
|
|
80
|
-
t4 = $[9];
|
|
81
|
-
}
|
|
82
|
-
let t5;
|
|
83
|
-
if ($[10] !== props || $[11] !== t1 || $[12] !== t2) {
|
|
84
|
-
t5 = /* @__PURE__ */ jsxDEV(ScrollArea$1.Root, {
|
|
85
|
-
"data-slot": "scroll-area",
|
|
86
|
-
className: t1,
|
|
87
|
-
...props,
|
|
88
|
-
children: [t2, t3, t4]
|
|
89
|
-
}, void 0, true);
|
|
90
|
-
$[10] = props;
|
|
91
|
-
$[11] = t1;
|
|
92
|
-
$[12] = t2;
|
|
93
|
-
$[13] = t5;
|
|
94
|
-
} else {
|
|
95
|
-
t5 = $[13];
|
|
96
|
-
}
|
|
97
|
-
return t5;
|
|
98
|
-
}
|
|
99
|
-
function ScrollBar({
|
|
100
|
-
className,
|
|
101
|
-
orientation = "vertical",
|
|
102
|
-
...props
|
|
103
|
-
}) {
|
|
104
|
-
return /* @__PURE__ */ jsxDEV(ScrollArea$1.Scrollbar, {
|
|
105
|
-
"data-slot": "scroll-area-scrollbar",
|
|
106
|
-
"data-orientation": orientation,
|
|
107
|
-
orientation,
|
|
108
|
-
className: cn("flex touch-none p-px transition-colors select-none data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-s data-vertical:border-s-transparent", className),
|
|
109
|
-
...props,
|
|
110
|
-
children: /* @__PURE__ */ jsxDEV(ScrollArea$1.Thumb, {
|
|
111
|
-
"data-slot": "scroll-area-thumb",
|
|
112
|
-
className: "relative flex-1 rounded-md bg-border"
|
|
113
|
-
}, void 0, false)
|
|
114
|
-
}, void 0, false);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const GET_CAPTURED_MAIL = adminRef(ADMIN_FUNCTIONS.getCapturedMail);
|
|
118
31
|
const CLEAR_CAPTURED_MAIL = adminRef(ADMIN_FUNCTIONS.clearCapturedMail);
|
|
119
32
|
const SEND_TEST_MAIL = adminRef(ADMIN_FUNCTIONS.sendTestMail);
|
|
120
33
|
const LINK_PATTERN = /https?:\/\/[^\s"'<>)]+/i;
|
|
@@ -144,49 +57,44 @@ const MailPanel = ({
|
|
|
144
57
|
}) => {
|
|
145
58
|
const client = useLunora();
|
|
146
59
|
const t = useT();
|
|
147
|
-
const
|
|
148
|
-
|
|
60
|
+
const {
|
|
61
|
+
data,
|
|
62
|
+
error: readError,
|
|
63
|
+
errorSource: readErrorSource,
|
|
64
|
+
isLoading,
|
|
65
|
+
refetch
|
|
66
|
+
} = useAdminQuery(ADMIN_FUNCTIONS.getCapturedMail, {
|
|
67
|
+
limit
|
|
68
|
+
});
|
|
69
|
+
const [actionError, setActionError] = useState(null);
|
|
149
70
|
const [selectedId, setSelectedId] = useState(null);
|
|
150
71
|
const [tab, setTab] = useState("html");
|
|
151
72
|
const [filter, setFilter] = useState("");
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const next = await client.query(GET_CAPTURED_MAIL, {
|
|
156
|
-
limit
|
|
157
|
-
}, callOptions(""));
|
|
158
|
-
setEntries(next.entries);
|
|
159
|
-
} catch (error_) {
|
|
160
|
-
setEntries([]);
|
|
161
|
-
setError(errorMessage(error_));
|
|
162
|
-
}
|
|
163
|
-
};
|
|
73
|
+
const entries = useMemo(() => data?.entries ?? [], [data]);
|
|
74
|
+
const error = readError ?? actionError;
|
|
75
|
+
const errorSource = readError === null ? actionError : readErrorSource;
|
|
164
76
|
const clearInbox = async () => {
|
|
165
|
-
|
|
77
|
+
setActionError(null);
|
|
166
78
|
try {
|
|
167
79
|
await client.query(CLEAR_CAPTURED_MAIL, {}, callOptions(""));
|
|
168
80
|
setSelectedId(null);
|
|
169
|
-
|
|
170
|
-
} catch (
|
|
171
|
-
|
|
81
|
+
refetch();
|
|
82
|
+
} catch (error_) {
|
|
83
|
+
setActionError(errorMessage(error_));
|
|
172
84
|
}
|
|
173
85
|
};
|
|
174
86
|
const sendTest = async () => {
|
|
175
|
-
|
|
87
|
+
setActionError(null);
|
|
176
88
|
try {
|
|
177
89
|
await client.query(SEND_TEST_MAIL, {}, callOptions(""));
|
|
178
|
-
|
|
179
|
-
} catch (
|
|
180
|
-
|
|
90
|
+
refetch();
|
|
91
|
+
} catch (error__0) {
|
|
92
|
+
setActionError(errorMessage(error__0));
|
|
181
93
|
}
|
|
182
94
|
};
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
},
|
|
186
|
-
const reload = () => {
|
|
187
|
-
fireAndForget(refresh());
|
|
188
|
-
};
|
|
189
|
-
useAutoRefresh(reload, true);
|
|
95
|
+
useAutoRefresh(() => {
|
|
96
|
+
refetch();
|
|
97
|
+
}, true);
|
|
190
98
|
const onClear = () => {
|
|
191
99
|
fireAndForget(clearInbox());
|
|
192
100
|
};
|
|
@@ -205,9 +113,9 @@ const MailPanel = ({
|
|
|
205
113
|
}
|
|
206
114
|
};
|
|
207
115
|
const onSelectTab = (event_1) => {
|
|
208
|
-
const
|
|
209
|
-
if (
|
|
210
|
-
setTab(
|
|
116
|
+
const next = event_1.currentTarget.dataset["tab"];
|
|
117
|
+
if (next === "headers" || next === "html" || next === "text") {
|
|
118
|
+
setTab(next);
|
|
211
119
|
}
|
|
212
120
|
};
|
|
213
121
|
const tabTitle = (value) => {
|
|
@@ -271,12 +179,10 @@ const MailPanel = ({
|
|
|
271
179
|
count: entries.length
|
|
272
180
|
})
|
|
273
181
|
}, void 0, false)]
|
|
274
|
-
}, void 0, true), error !== null && /* @__PURE__ */ jsxDEV(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
children: error
|
|
279
|
-
}, void 0, false), error === null && entries.length === 0 && /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
182
|
+
}, void 0, true), error !== null && /* @__PURE__ */ jsxDEV(ErrorAlert, {
|
|
183
|
+
error: errorSource,
|
|
184
|
+
testId: "mail-error"
|
|
185
|
+
}, void 0, false), error === null && !isLoading && entries.length === 0 && /* @__PURE__ */ jsxDEV(EmptyState, {
|
|
280
186
|
description: t("Email your app sends in dev is captured here — nothing is delivered."),
|
|
281
187
|
icon: /* @__PURE__ */ jsxDEV("svg", {
|
|
282
188
|
"aria-hidden": "true",
|