react-semaphor 0.1.178 → 0.1.180

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/chunks/{dashboard-controls-00cjSeD7.js → dashboard-controls-Baw7eUyM.js} +8 -8
  2. package/dist/chunks/{dashboard-controls-C9IWIFfW.js → dashboard-controls-CS3pAVZi.js} +473 -470
  3. package/dist/chunks/{dashboard-json--ke9XK9p.js → dashboard-json-ClalWYi4.js} +1 -1
  4. package/dist/chunks/{dashboard-json-BDjl-3ej.js → dashboard-json-Cz4bNnCC.js} +1 -1
  5. package/dist/chunks/{edit-dashboard-visual-BroCdmtP.js → edit-dashboard-visual-BMElXt-n.js} +30 -35
  6. package/dist/chunks/{edit-dashboard-visual-BBsC9feJ.js → edit-dashboard-visual-DFJ5FJ7y.js} +11 -22
  7. package/dist/chunks/editor-action-buttons-DVWnnC_r.js +11 -0
  8. package/dist/chunks/{editor-action-buttons-CHoiNw7F.js → editor-action-buttons-MtNYw1Bb.js} +57 -45
  9. package/dist/chunks/index-8Crk3ROJ.js +1 -0
  10. package/dist/chunks/index-B4EhQdS9.js +1857 -0
  11. package/dist/chunks/{index-DZjcALSv.js → index-CAeKp6K8.js} +23423 -24714
  12. package/dist/chunks/index-CfPKTeUk.js +1082 -0
  13. package/dist/chunks/notification-bell-2dZI5OV0.js +21 -0
  14. package/dist/chunks/notification-bell-YZ8VqdwA.js +870 -0
  15. package/dist/chunks/{resource-management-panel-C96ElLa5.js → resource-management-panel-Buhi-kvP.js} +1 -1
  16. package/dist/chunks/{resource-management-panel-DE8DnPSl.js → resource-management-panel-pxL28GXq.js} +133 -133
  17. package/dist/chunks/{use-role-aware-display-preferences-Dovp_VmV.js → use-role-aware-display-preferences-B_i2f9tn.js} +1 -1
  18. package/dist/chunks/{use-role-aware-display-preferences-Rd1BhDG4.js → use-role-aware-display-preferences-JljRcjrP.js} +1 -1
  19. package/dist/chunks/{use-visual-utils-BkRr5LoD.js → use-visual-utils-D3HjbsKO.js} +38 -38
  20. package/dist/chunks/{use-visual-utils-Cnju2tnE.js → use-visual-utils-DPEHcmFT.js} +1 -1
  21. package/dist/dashboard/index.cjs +1 -1
  22. package/dist/dashboard/index.js +1 -1
  23. package/dist/format-utils/index.cjs +5 -0
  24. package/dist/format-utils/index.js +451 -0
  25. package/dist/index.cjs +1 -6
  26. package/dist/index.js +133 -126
  27. package/dist/style.css +1 -1
  28. package/dist/surfboard/index.cjs +1 -1
  29. package/dist/surfboard/index.js +1 -1
  30. package/dist/types/format-utils.d.ts +375 -0
  31. package/dist/types/main.d.ts +262 -0
  32. package/package.json +14 -1
  33. package/dist/chunks/editor-action-buttons-JE9t84-4.js +0 -6
  34. package/dist/chunks/index-CdfFCbJb.js +0 -1077
  35. package/dist/chunks/schedule-dashboard-BFa0Uljc.js +0 -416
  36. package/dist/chunks/schedule-dashboard-CzU0ziLB.js +0 -6
@@ -243,6 +243,26 @@ declare type Actions_3 = TableActions & ExplorerActions & DrillActions & {
243
243
  setOnClose: (onClose: () => void) => void;
244
244
  };
245
245
 
246
+ /**
247
+ * Represents an active or recently completed export job.
248
+ */
249
+ export declare interface ActiveExport {
250
+ id: string;
251
+ status: 'pending' | 'processing' | 'chunking' | 'compacting' | 'completed' | 'failed' | 'cancelled';
252
+ progress: number;
253
+ title: string;
254
+ totalRows: number;
255
+ totalChunks: number;
256
+ completedChunks: number;
257
+ startedAt: Date;
258
+ lastUpdatedAt: Date;
259
+ completedAt?: Date;
260
+ downloadUrl?: string;
261
+ fileSize?: number;
262
+ error?: string;
263
+ expiresAt: Date;
264
+ }
265
+
246
266
  export declare function AdvancedModeToggle({ className, switchClassName, }: AdvancedModeToggleProps): JSX.Element | null;
247
267
 
248
268
  declare interface AdvancedModeToggleProps {
@@ -424,6 +444,11 @@ export declare interface CalculatedFieldFormula {
424
444
  */
425
445
  export declare type CalculatedFieldOperation = 'sum' | 'difference' | 'product' | 'ratio' | 'change' | 'percentage' | 'scale' | 'custom';
426
446
 
447
+ /**
448
+ * Cancel/delete an export job
449
+ */
450
+ export declare function cancelExport(apiServiceUrl: string, token: string, exportId: string): Promise<void>;
451
+
427
452
  export declare interface CardConfig {
428
453
  groupByColumns?: GroupByField[];
429
454
  metricColumns?: MetricField[];
@@ -483,6 +508,8 @@ export declare interface CardInteractionConfig {
483
508
 
484
509
  export declare type CardMode = 'explorer' | 'dev';
485
510
 
511
+ export declare type CardType = 'table' | 'aggregateTable' | 'pivotTable';
512
+
486
513
  declare type CardWithContent = BaseCustomCard & {
487
514
  content: React.FC<{
488
515
  card: TCard;
@@ -692,6 +719,41 @@ export declare type ContainerId = 'groupBy' | 'metrics' | 'pivotBy' | 'sortBy' |
692
719
  */
693
720
  export declare const createEmptyKpiConfig: () => CardConfig;
694
721
 
722
+ /**
723
+ * Create a new export job
724
+ */
725
+ export declare function createExport(apiServiceUrl: string, token: string, params: CreateExportRequest): Promise<CreateExportResponse>;
726
+
727
+ /** Request to create a new export job */
728
+ export declare interface CreateExportRequest {
729
+ type: 'visual' | 'card';
730
+ dashboardId: string;
731
+ visualId?: string;
732
+ cardId?: string;
733
+ title?: string;
734
+ connection_id: string;
735
+ cardType: string;
736
+ cardConfig: CardConfig;
737
+ cardDataSource: DataSource;
738
+ active_filters: TFilterValue[];
739
+ timezone?: string;
740
+ totalRows: number;
741
+ format: ExportFormat;
742
+ formatOptions?: ExportFormattingConfig;
743
+ }
744
+
745
+ /** Response from creating an export job */
746
+ export declare interface CreateExportResponse {
747
+ exportId: string;
748
+ status: ExportStatus;
749
+ totalChunks: number;
750
+ chunkSize: number;
751
+ estimatedRows: number;
752
+ wasTruncated?: boolean;
753
+ originalRows?: number;
754
+ maxRows?: number;
755
+ }
756
+
695
757
  declare interface CreateResourceRequest {
696
758
  title: string;
697
759
  description?: string;
@@ -1297,6 +1359,13 @@ declare interface ExplorerActions {
1297
1359
  reorderJoins: (cardId: string, joinIds: string[]) => void;
1298
1360
  }
1299
1361
 
1362
+ /** API error response */
1363
+ export declare interface ExportApiError {
1364
+ error: string;
1365
+ message?: string;
1366
+ details?: string;
1367
+ }
1368
+
1300
1369
  export declare type ExportDataPayload = {
1301
1370
  cardId: string;
1302
1371
  title: string;
@@ -1304,6 +1373,111 @@ export declare type ExportDataPayload = {
1304
1373
  sql: string;
1305
1374
  };
1306
1375
 
1376
+ export declare class ExportError extends Error {
1377
+ readonly status: number;
1378
+ readonly details?: ExportApiError | undefined;
1379
+ constructor(message: string, status: number, details?: ExportApiError | undefined);
1380
+ }
1381
+
1382
+ export declare type ExportFormat = 'csv';
1383
+
1384
+ /** Formatting configuration passed to the export job */
1385
+ export declare interface ExportFormattingConfig {
1386
+ useFormattedValues: boolean;
1387
+ timezone: string;
1388
+ locale: string;
1389
+ delimiter: ',' | ';' | '\t';
1390
+ includeHeaders: boolean;
1391
+ columnSettings?: Record<string, unknown>;
1392
+ visibleColumns?: string[];
1393
+ }
1394
+
1395
+ /** Export job from list endpoint */
1396
+ export declare interface ExportJobListItem {
1397
+ id: string;
1398
+ title?: string;
1399
+ status: ExportStatus;
1400
+ format: string;
1401
+ totalRows: number;
1402
+ completedChunks: number;
1403
+ totalChunks: number;
1404
+ fileSize?: number;
1405
+ error?: string;
1406
+ createdAt: string;
1407
+ completedAt?: string;
1408
+ expiresAt: string;
1409
+ dashboardId?: string;
1410
+ cardId?: string;
1411
+ }
1412
+
1413
+ /** Export job status response */
1414
+ export declare interface ExportJobStatus {
1415
+ id: string;
1416
+ status: ExportStatus;
1417
+ progress: number;
1418
+ totalRows: number;
1419
+ completedChunks: number;
1420
+ totalChunks: number;
1421
+ fileSize?: number;
1422
+ error?: string;
1423
+ createdAt: string;
1424
+ completedAt?: string;
1425
+ expiresAt: string;
1426
+ }
1427
+
1428
+ /**
1429
+ * Individual export notification item.
1430
+ *
1431
+ * Shows different UI based on export status:
1432
+ * - In Progress: Progress bar with percentage
1433
+ * - Completed: Download button with file size
1434
+ * - Failed: Error message with dismiss option
1435
+ */
1436
+ export declare function ExportNotificationItem({ export: exp, onRemove, }: ExportNotificationItemProps): JSX.Element;
1437
+
1438
+ declare interface ExportNotificationItemProps {
1439
+ /** The export data to display */
1440
+ export: ActiveExport;
1441
+ /** Called when user clicks dismiss/remove */
1442
+ onRemove?: (id: string) => void;
1443
+ }
1444
+
1445
+ /**
1446
+ * List of export notifications.
1447
+ *
1448
+ * Displays all active and recent exports with their status,
1449
+ * progress, and download options.
1450
+ */
1451
+ export declare function ExportNotificationList(): JSX.Element;
1452
+
1453
+ export declare type ExportStatus = 'pending' | 'processing' | 'chunking' | 'compacting' | 'completed' | 'failed' | 'cancelled';
1454
+
1455
+ declare type ExportStore = ExportStoreState & {
1456
+ actions: ExportStoreActions;
1457
+ };
1458
+
1459
+ declare type ExportStoreActions = {
1460
+ /** Add a new export to the store */
1461
+ addExport: (exportData: ActiveExport) => void;
1462
+ /** Update an existing export */
1463
+ updateExport: (id: string, updates: Partial<ActiveExport>) => void;
1464
+ /** Remove an export from the store */
1465
+ removeExport: (id: string) => void;
1466
+ /** Get all in-progress exports */
1467
+ getInProgressExports: () => ActiveExport[];
1468
+ /** Get all exports as an array */
1469
+ getAllExports: () => ActiveExport[];
1470
+ /** Clear all completed/failed exports */
1471
+ clearCompleted: () => void;
1472
+ /** Check if there are any in-progress exports */
1473
+ hasInProgressExports: () => boolean;
1474
+ };
1475
+
1476
+ declare type ExportStoreState = {
1477
+ /** Map of export ID to export data */
1478
+ activeExports: Map<string, ActiveExport>;
1479
+ };
1480
+
1307
1481
  export declare interface Field {
1308
1482
  /**
1309
1483
  * Unique identifier for this field instance (for joins, UI state, etc.).
@@ -1458,6 +1632,11 @@ export declare type FilterValue = string | number | boolean | Date | null | [num
1458
1632
 
1459
1633
  export declare function fmt(str: string): string;
1460
1634
 
1635
+ /**
1636
+ * Format file size in human readable format
1637
+ */
1638
+ export declare function formatFileSize(bytes?: number): string;
1639
+
1461
1640
  export declare function getColumnDataType(column: TDataColumn): string;
1462
1641
 
1463
1642
  export declare type GetDashboardResponse = {
@@ -1468,6 +1647,28 @@ export declare type GetDashboardResponse = {
1468
1647
  assistantProfileId?: string;
1469
1648
  };
1470
1649
 
1650
+ /**
1651
+ * Get download URL for a completed export
1652
+ *
1653
+ * The backend returns a presigned S3 URL in JSON response.
1654
+ */
1655
+ export declare function getDownloadUrl(apiServiceUrl: string, token: string, exportId: string): Promise<string>;
1656
+
1657
+ /**
1658
+ * Get list of user's exports
1659
+ */
1660
+ export declare function getExports(apiServiceUrl: string, token: string, options?: {
1661
+ status?: ExportStatus[];
1662
+ limit?: number;
1663
+ }): Promise<{
1664
+ exports: ExportJobListItem[];
1665
+ }>;
1666
+
1667
+ /**
1668
+ * Get status of a specific export job
1669
+ */
1670
+ export declare function getExportStatus(apiServiceUrl: string, token: string, exportId: string): Promise<ExportJobStatus>;
1671
+
1471
1672
  export declare function getFilterValueType(filter: TFilter): "string" | "number" | "date" | "boolean";
1472
1673
 
1473
1674
  export declare function getFormattedTableNameForQuery({ schemaName, tableName, modelName, connectionType, databaseName, }: {
@@ -1685,6 +1886,16 @@ export declare function isColumnInSqlGen(column: TDataColumn, sqlGen: SqlGen): b
1685
1886
 
1686
1887
  export declare function isDateDataType(dataType: string): boolean;
1687
1888
 
1889
+ /**
1890
+ * Check if an export has completed (successfully or with failure)
1891
+ */
1892
+ export declare function isExportComplete(status: ExportStatus): boolean;
1893
+
1894
+ /**
1895
+ * Check if an export is still in progress
1896
+ */
1897
+ export declare function isExportInProgress(status: ExportStatus): boolean;
1898
+
1688
1899
  export declare function isNumberDataType(dataType: string): boolean;
1689
1900
 
1690
1901
  export declare function isTextDataType(dataType: string): boolean;
@@ -1822,6 +2033,17 @@ export declare type ModelItem = DropdownItem;
1822
2033
 
1823
2034
  declare type NoneOptions = {};
1824
2035
 
2036
+ /**
2037
+ * Notification bell icon with badge.
2038
+ *
2039
+ * Shows a badge when there are:
2040
+ * - In-progress exports (shows count)
2041
+ * - Completed exports that haven't been dismissed (shows dot)
2042
+ *
2043
+ * Clicking opens a popover with the full export notification list.
2044
+ */
2045
+ export declare function NotificationBell(): JSX.Element;
2046
+
1825
2047
  export declare type NumberAxisFormat = {
1826
2048
  decimalPlaces?: number;
1827
2049
  suffix?: string;
@@ -3110,6 +3332,8 @@ export declare interface URLParameter {
3110
3332
  field?: Field;
3111
3333
  }
3112
3334
 
3335
+ export declare const useActiveExports: () => Map<string, ActiveExport>;
3336
+
3113
3337
  export declare function useCard(cardId: string): {
3114
3338
  data: any;
3115
3339
  card: TCard;
@@ -3233,6 +3457,42 @@ setState(nextStateOrUpdater: EditorStore | Partial<EditorStore> | ((state: Writa
3233
3457
  setState(nextStateOrUpdater: EditorStore | ((state: WritableDraft<EditorStore>) => void), shouldReplace: true): void;
3234
3458
  }>;
3235
3459
 
3460
+ export declare const useExportActions: () => ExportStoreActions;
3461
+
3462
+ /**
3463
+ * Hook that manages smart polling for export status updates.
3464
+ *
3465
+ * Features:
3466
+ * - Dynamic polling intervals (10s → 15s → 30s) based on export duration
3467
+ * - Page Visibility API integration (pauses when tab is hidden)
3468
+ * - Automatic download URL fetching when export completes
3469
+ * - Only polls when there are in-progress exports
3470
+ *
3471
+ * @returns Object with polling state
3472
+ */
3473
+ export declare function useExportPolling(): {
3474
+ isPolling: boolean;
3475
+ isTabVisible: boolean;
3476
+ inProgressCount: number;
3477
+ };
3478
+
3479
+ /**
3480
+ * Hook that recovers active exports when the app mounts or page refreshes.
3481
+ *
3482
+ * This ensures that:
3483
+ * - Users don't lose track of their exports after a page refresh
3484
+ * - The notification tray shows all in-progress exports
3485
+ * - Polling resumes for any ongoing exports
3486
+ *
3487
+ * Should be called once at the app root level (e.g., in dashboard-plus.tsx).
3488
+ */
3489
+ export declare function useExportRecovery(): void;
3490
+
3491
+ export declare const useExportStore: UseBoundStore<Omit<StoreApi<ExportStore>, "setState"> & {
3492
+ setState(nextStateOrUpdater: ExportStore | Partial<ExportStore> | ((state: WritableDraft<ExportStore>) => void), shouldReplace?: false): void;
3493
+ setState(nextStateOrUpdater: ExportStore | ((state: WritableDraft<ExportStore>) => void), shouldReplace: true): void;
3494
+ }>;
3495
+
3236
3496
  /**
3237
3497
  * Hook that exposes print state to the window object for Lambda/Puppeteer to access.
3238
3498
  *
@@ -3253,6 +3513,8 @@ setState(nextStateOrUpdater: EditorStore | ((state: WritableDraft<EditorStore>)
3253
3513
  */
3254
3514
  export declare function useExposePrintState(isPdfRender: boolean, printState: PrintState | null): void;
3255
3515
 
3516
+ export declare const useInProgressExportsCount: () => number;
3517
+
3256
3518
  export declare const useManagementStore: UseBoundStore<Omit<StoreApi<ManagementStore>, "setState"> & {
3257
3519
  setState(nextStateOrUpdater: ManagementStore | Partial<ManagementStore> | ((state: WritableDraft<ManagementStore>) => void), shouldReplace?: false): void;
3258
3520
  setState(nextStateOrUpdater: ManagementStore | ((state: WritableDraft<ManagementStore>) => void), shouldReplace: true): void;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "email": "support@semaphor.cloud"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "0.1.178",
8
+ "version": "0.1.180",
9
9
  "description": "Fully interactive and customizable dashboards for your apps.",
10
10
  "keywords": [
11
11
  "react",
@@ -37,6 +37,11 @@
37
37
  "import": "./dist/surfboard/index.js",
38
38
  "require": "./dist/surfboard/index.cjs"
39
39
  },
40
+ "./format-utils": {
41
+ "types": "./dist/types/format-utils.d.ts",
42
+ "import": "./dist/format-utils/index.js",
43
+ "require": "./dist/format-utils/index.cjs"
44
+ },
40
45
  "./style.css": "./dist/style.css"
41
46
  },
42
47
  "scripts": {
@@ -135,6 +140,14 @@
135
140
  "react": "^18.0.0 || ^19.0.0",
136
141
  "react-dom": "^18.0.0 || ^19.0.0"
137
142
  },
143
+ "peerDependenciesMeta": {
144
+ "react": {
145
+ "optional": true
146
+ },
147
+ "react-dom": {
148
+ "optional": true
149
+ }
150
+ },
138
151
  "overrides": {
139
152
  "react": "$react",
140
153
  "react-dom": "$react-dom"
@@ -1,6 +0,0 @@
1
- "use strict";const s=require("react/jsx-runtime"),e=require("./index-CdfFCbJb.js"),v=require("./use-visual-utils-Cnju2tnE.js"),C=require("react");/**
2
- * @license lucide-react v0.453.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const E=e.createLucideIcon("Save",[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]]);function g({className:d,variant:l="outline"}){var m;const{setCardSql:i}=e.useEditorActions();e.useEditorStore(t=>t.frame);const u=e.useEditorStore(t=>t.card);v.useRemoteChartStore(((m=u.customCardPreferences)==null?void 0:m.url)||""),e.useEditorStore(t=>t.selectedSchemaName),e.useEditorStore(t=>t.selectedDatamodelId),e.useEditorStore(t=>t.selectedDatabaseName),e.useEditorStore(t=>t.selectedTableName),e.useEditorStore(t=>t.selectedConnectionId),e.useEditorStore(t=>t.isShowingVisual),u.sql;const a=e.useEditorStore(t=>t.onSave),{getUpdatedFrame:o}=v.useVisualUtils();function c(){const t=o();a==null||a(t)}return s.jsxs(e.Button,{onClick:c,className:e.cn("h-8",d),size:"sm",variant:l,children:[s.jsx(e.Check,{className:"mr-2 size-4 font-bold"}),"Accept"]})}function b({className:d,variant:l="default"}){const i=e.useQueryClient(),[u,a]=C.useState(!1),o=e.useDashboardStore(n=>n.actions.setIsDashboardPanelOpen),{setIsVisualEditing:c}=e.useDashboardActions(),{getUpdatedFrame:m}=v.useVisualUtils(),t=e.useSelectedVisual(),r=e.useEditorStore(n=>n.frame),y=e.useUpdateVisualMutation(),h=()=>{const n=m(),p=(r==null?void 0:r.visualId)||(t==null?void 0:t.id);if(!p){e.ue.error("No visual to save");return}a(!0),y.mutate({visualId:p,data:{frameObject:n}},{onSuccess:()=>{a(!1),o(!0),e.ue.success("Visual updated successfully"),i.invalidateQueries({queryKey:["resource-by-id","visual",p],exact:!0})},onError:()=>{a(!1),e.ue.error("Failed to update visual")}})};return s.jsxs(e.Button,{onClick:h,className:e.cn("h-8",d),size:"sm",variant:l,children:[u&&s.jsxs(s.Fragment,{children:[s.jsx(e.LoaderCircle,{className:"mr-2 size-4 animate-spin font-bold"})," Saving"]}),!u&&s.jsxs(s.Fragment,{children:[s.jsx(E,{className:"mr-2 size-4 font-bold"}),"Save to Library"]})]})}function x({className:d}){const l=e.useQueryClient(),[i,u]=C.useState(!1),a=e.useSelectedVisual(),o=e.useEditorStore(n=>n.frame),c=e.useDashboardStore(n=>n.selectedSheetId),{updateFrame:m,setIsVisualEditing:t}=e.useDashboardActions(),{getUpdatedFrame:r}=v.useVisualUtils(),y=e.useUpdateVisualMutation(),h=async()=>{if(!c){e.ue.error("No sheet selected");return}const n=(o==null?void 0:o.visualId)||(a==null?void 0:a.id);if(!n){e.ue.error("No visual to update");return}u(!0);try{const p=r();await y.mutateAsync({visualId:n,data:{frameObject:p}});const f={...p,visualId:n};m(c,f),l.invalidateQueries({queryKey:["visuals"]}),l.invalidateQueries({queryKey:["visual",n]}),e.ue.success("Saved to library and applied locally"),setTimeout(()=>{t(!1)},300)}catch(p){console.error("Failed to save and apply:",p),e.ue.error("Failed to save and apply changes")}finally{u(!1)}};return s.jsx(e.Button,{onClick:h,className:e.cn("h-8",d),size:"sm",variant:"default",disabled:i,children:i?s.jsxs(s.Fragment,{children:[s.jsx(e.LoaderCircle,{className:"mr-2 size-4 animate-spin font-bold"})," Saving..."]}):s.jsxs(s.Fragment,{children:[s.jsx(E,{className:"mr-2 size-4 font-bold"}),"Save & Apply"]})})}function A({className:d}){const{getUpdatedFrame:l}=v.useVisualUtils();e.useEditorStore(t=>t.frame);const i=e.useDashboardStore(t=>t.selectedSheetId),{updateFrame:u,setIsVisualEditing:a}=e.useDashboardActions(),[o,c]=C.useState(!1),m=()=>{if(!i){e.ue.error("No sheet selected");return}c(!0);const r={...l(),visualId:void 0};u(i,r),setTimeout(()=>{c(!1),e.ue.success("Changes applied. Visual is now local to this dashboard"),a(!1)},300)};return s.jsxs(e.Button,{onClick:m,className:e.cn("h-8",d),size:"sm",variant:"outline",children:[o&&s.jsxs(s.Fragment,{children:[s.jsx(e.LoaderCircle,{className:"mr-2 size-4 animate-spin font-bold"})," Applying"]}),!o&&s.jsxs(s.Fragment,{children:[s.jsx(e.Check,{className:"mr-2 size-4 font-bold"}),"Apply Locally"]})]})}function j({className:d}){const{setTempQueryData:l,setSqlGen:i}=e.useEditorActions(),u=e.useQueryClient(),a=e.useEditorStore(r=>r.tempQueryData),o=e.useEditorStore(r=>r.onClose),c=e.useEditorStore(r=>r.card),{queryKey:m}=e.useDashboardCardQuery(c);function t(){if(a){const{queryKey:r,queryData:y}=a;r&&y&&u.setQueryData(r,y)}i({}),o==null||o()}return s.jsxs(e.Button,{onClick:t,className:e.cn("h-8",d),size:"sm",variant:"outline",children:[s.jsx(e.X,{className:"mr-2 size-4"}),"Close"]})}function D(){const{setTempQueryData:d}=e.useEditorActions(),l=e.useQueryClient();e.useEditorStore(S=>S.isDevMode);const i=e.useEditorStore(S=>S.tempQueryData),u=e.useEditorStore(S=>S.card),{queryKey:a}=e.useDashboardCardQuery(u),{setCardSql:o,setSqlGen:c,setCardPython:m,setCardCustomCfg:t,setCardPreferences:r,updateDataSource:y,clearQueryConfig:h,setCardConfig:n,setCardType:p}=e.useEditorActions();function f(){const S=l.getQueryData(a);i!=null&&i.queryData||d({queryKey:a,queryData:S}),l.setQueryData(a,null),l.removeQueries({queryKey:a,exact:!0}),o(""),c({}),h(),n(void 0),m(""),t(""),r({}),p("bar")}return s.jsxs(e.Button,{onClick:f,className:"h-8",size:"sm",variant:"secondary",children:[s.jsx(e.X,{className:"mr-2 size-3.5"}),"Clear"]})}exports.EditorAcceptButton=g;exports.EditorCancelButton=j;exports.EditorClearButton=D;exports.Save=E;exports.VisualApplyLocalButton=A;exports.VisualSaveAndApplyButton=x;exports.VisualSaveButton=b;