d1s 0.2.11 → 0.2.13
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/dist/.next/.next/BUILD_ID +1 -1
- package/dist/.next/.next/app-build-manifest.json +28 -28
- package/dist/.next/.next/app-path-routes-manifest.json +1 -1
- package/dist/.next/.next/build-manifest.json +3 -3
- package/dist/.next/.next/cache/.rscinfo +1 -1
- package/dist/.next/.next/cache/.tsbuildinfo +1 -1
- package/dist/.next/.next/cache/webpack/client-production/0.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/1.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/10.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/11.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/12.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/2.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/3.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/4.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/5.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/6.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/7.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/8.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/9.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/index.pack +0 -0
- package/dist/.next/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/dist/.next/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/0.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/1.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/2.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/3.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/index.pack +0 -0
- package/dist/.next/.next/cache/webpack/server-production/index.pack.old +0 -0
- package/dist/.next/.next/next-minimal-server.js.nft.json +1 -1
- package/dist/.next/.next/next-server.js.nft.json +1 -1
- package/dist/.next/.next/prerender-manifest.json +1 -1
- package/dist/.next/.next/required-server-files.json +1 -1
- package/dist/.next/.next/server/app/_not-found/page.js +1 -1
- package/dist/.next/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/.next/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/_not-found.html +1 -1
- package/dist/.next/.next/server/app/_not-found.rsc +4 -4
- package/dist/.next/.next/server/app/api/cloudflare/route.js +1 -1
- package/dist/.next/.next/server/app/api/cloudflare/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/databases/route.js +1 -1
- package/dist/.next/.next/server/app/api/databases/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/migrations/sync/route.js +5 -5
- package/dist/.next/.next/server/app/api/migrations/sync/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/migrations/sync-files/route.js +3 -3
- package/dist/.next/.next/server/app/api/migrations/sync-files/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/pull-data/confirm/route.js +1 -1
- package/dist/.next/.next/server/app/api/pull-data/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/pull-remote/confirm/route.js +2 -2
- package/dist/.next/.next/server/app/api/pull-remote/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/pull-remote/preview/route.js +4 -4
- package/dist/.next/.next/server/app/api/pull-remote/preview/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/push-remote/confirm/route.js +5 -5
- package/dist/.next/.next/server/app/api/push-remote/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/push-remote/preview/route.js +4 -4
- package/dist/.next/.next/server/app/api/push-remote/preview/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/query/route.js +3 -3
- package/dist/.next/.next/server/app/api/query/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/tables/[name]/route.js +5 -5
- package/dist/.next/.next/server/app/api/tables/[name]/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/tables/route.js +2 -2
- package/dist/.next/.next/server/app/api/tables/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/api/update/route.js +1 -1
- package/dist/.next/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app/index.html +2 -2
- package/dist/.next/.next/server/app/index.rsc +5 -5
- package/dist/.next/.next/server/app/page.js +7 -7
- package/dist/.next/.next/server/app/page.js.nft.json +1 -1
- package/dist/.next/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/.next/.next/server/app-paths-manifest.json +1 -1
- package/dist/.next/.next/server/chunks/226.js +12 -12
- package/dist/.next/.next/server/chunks/391.js +1 -1
- package/dist/.next/.next/server/chunks/572.js +1 -0
- package/dist/.next/.next/server/chunks/992.js +3 -3
- package/dist/.next/.next/server/middleware-build-manifest.js +1 -1
- package/dist/.next/.next/server/next-font-manifest.js +1 -1
- package/dist/.next/.next/server/next-font-manifest.json +1 -1
- package/dist/.next/.next/server/pages/404.html +1 -1
- package/dist/.next/.next/server/pages/500.html +1 -1
- package/dist/.next/.next/server/server-reference-manifest.json +1 -1
- package/dist/.next/.next/static/chunks/{576-c4daf274bb6469a1.js → 576-18a2209e1ed26aad.js} +1 -1
- package/dist/.next/.next/static/chunks/{92-c4466e0f1ca8a3a8.js → 92-5f7522943fcb72a8.js} +1 -1
- package/dist/.next/.next/static/chunks/app/{layout-be6ee67cf0c92654.js → layout-40ec07d04681ba81.js} +1 -1
- package/dist/.next/.next/static/chunks/app/page-f05cd0fc436bf9bc.js +1 -0
- package/dist/.next/.next/static/chunks/app/page-f2bc307c0d8acdaa.js +1 -0
- package/dist/.next/.next/static/chunks/{main-app-fa35024de9bd9284.js → main-app-4506e88db72db4b7.js} +1 -1
- package/dist/.next/.next/static/css/{9f6c25c5400f83d3.css → 7c16f57d325d0d7d.css} +1 -1
- package/dist/.next/.next/static/ejYPqJ2kVicVp5EFWOZIC/_buildManifest.js +1 -0
- package/dist/.next/.next/static/ejYPqJ2kVicVp5EFWOZIC/_ssgManifest.js +1 -0
- package/dist/.next/.next/static/gABGrAoO8IPArDo_Ns_7g/_buildManifest.js +1 -0
- package/dist/.next/.next/static/gABGrAoO8IPArDo_Ns_7g/_ssgManifest.js +1 -0
- package/dist/.next/.next/static/gh-QfIUVo4FTTduYCVKT6/_buildManifest.js +1 -0
- package/dist/.next/.next/static/gh-QfIUVo4FTTduYCVKT6/_ssgManifest.js +1 -0
- package/dist/.next/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/.next/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/.next/.next/static/thaCy2qVeNqYYhdayr13C/_buildManifest.js +1 -0
- package/dist/.next/.next/static/thaCy2qVeNqYYhdayr13C/_ssgManifest.js +1 -0
- package/dist/.next/.next/static/ybCx6L6gHqtODbKmlhU-d/_buildManifest.js +1 -0
- package/dist/.next/.next/static/ybCx6L6gHqtODbKmlhU-d/_ssgManifest.js +1 -0
- package/dist/.next/.next/trace +3 -3
- package/dist/.next/.next/types/app/api/cloudflare/route.ts +1 -1
- package/dist/.next/.next/types/app/api/databases/route.ts +1 -1
- package/dist/.next/.next/types/app/api/migrations/sync/route.ts +1 -1
- package/dist/.next/.next/types/app/api/migrations/sync-files/route.ts +1 -1
- package/dist/.next/.next/types/app/api/pull-data/confirm/route.ts +1 -1
- package/dist/.next/.next/types/app/api/pull-remote/confirm/route.ts +1 -1
- package/dist/.next/.next/types/app/api/pull-remote/preview/route.ts +1 -1
- package/dist/.next/.next/types/app/api/push-remote/confirm/route.ts +1 -1
- package/dist/.next/.next/types/app/api/push-remote/preview/route.ts +1 -1
- package/dist/.next/.next/types/app/api/query/route.ts +1 -1
- package/dist/.next/.next/types/app/api/tables/[name]/route.ts +1 -1
- package/dist/.next/.next/types/app/api/tables/route.ts +1 -1
- package/dist/.next/.next/types/app/api/update/route.ts +1 -1
- package/dist/.next/.next/types/app/page.ts +1 -1
- package/dist/.next/BUILD_ID +1 -1
- package/dist/.next/app-build-manifest.json +28 -28
- package/dist/.next/app-path-routes-manifest.json +1 -1
- package/dist/.next/build-manifest.json +3 -3
- package/dist/.next/cache/.rscinfo +1 -1
- package/dist/.next/cache/.tsbuildinfo +1 -1
- package/dist/.next/cache/webpack/client-production/0.pack +0 -0
- package/dist/.next/cache/webpack/client-production/1.pack +0 -0
- package/dist/.next/cache/webpack/client-production/2.pack +0 -0
- package/dist/.next/cache/webpack/client-production/index.pack +0 -0
- package/dist/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/dist/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/dist/.next/cache/webpack/server-production/0.pack +0 -0
- package/dist/.next/cache/webpack/server-production/index.pack +0 -0
- package/dist/.next/next-minimal-server.js.nft.json +1 -1
- package/dist/.next/next-server.js.nft.json +1 -1
- package/dist/.next/prerender-manifest.json +1 -1
- package/dist/.next/required-server-files.json +1 -1
- package/dist/.next/server/app/_not-found/page.js +1 -1
- package/dist/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/_not-found.html +1 -1
- package/dist/.next/server/app/_not-found.rsc +4 -4
- package/dist/.next/server/app/api/cloudflare/route.js +1 -1
- package/dist/.next/server/app/api/cloudflare/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/databases/route.js +1 -1
- package/dist/.next/server/app/api/databases/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/migrations/sync/route.js +5 -5
- package/dist/.next/server/app/api/migrations/sync/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/migrations/sync-files/route.js +3 -3
- package/dist/.next/server/app/api/migrations/sync-files/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/pull-data/confirm/route.js +1 -1
- package/dist/.next/server/app/api/pull-data/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/pull-remote/confirm/route.js +2 -2
- package/dist/.next/server/app/api/pull-remote/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/pull-remote/preview/route.js +4 -4
- package/dist/.next/server/app/api/pull-remote/preview/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/push-remote/confirm/route.js +5 -5
- package/dist/.next/server/app/api/push-remote/confirm/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/push-remote/preview/route.js +4 -4
- package/dist/.next/server/app/api/push-remote/preview/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/query/route.js +3 -3
- package/dist/.next/server/app/api/query/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/tables/[name]/route.js +5 -5
- package/dist/.next/server/app/api/tables/[name]/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/tables/route.js +2 -2
- package/dist/.next/server/app/api/tables/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/update/route.js +1 -1
- package/dist/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/index.html +2 -2
- package/dist/.next/server/app/index.rsc +5 -5
- package/dist/.next/server/app/page.js +7 -7
- package/dist/.next/server/app/page.js.nft.json +1 -1
- package/dist/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app-paths-manifest.json +1 -1
- package/dist/.next/server/chunks/226.js +12 -12
- package/dist/.next/server/chunks/391.js +1 -1
- package/dist/.next/server/chunks/572.js +1 -0
- package/dist/.next/server/chunks/992.js +3 -3
- package/dist/.next/server/middleware-build-manifest.js +1 -1
- package/dist/.next/server/next-font-manifest.js +1 -1
- package/dist/.next/server/next-font-manifest.json +1 -1
- package/dist/.next/server/pages/404.html +1 -1
- package/dist/.next/server/pages/500.html +1 -1
- package/dist/.next/server/server-reference-manifest.json +1 -1
- package/dist/.next/static/IX-QLbm7scYnyqWeeimal/_buildManifest.js +1 -0
- package/dist/.next/static/IX-QLbm7scYnyqWeeimal/_ssgManifest.js +1 -0
- package/dist/.next/static/chunks/{576-c4daf274bb6469a1.js → 576-18a2209e1ed26aad.js} +1 -1
- package/dist/.next/static/chunks/{92-c4466e0f1ca8a3a8.js → 92-5f7522943fcb72a8.js} +1 -1
- package/dist/.next/static/chunks/app/{layout-be6ee67cf0c92654.js → layout-40ec07d04681ba81.js} +1 -1
- package/dist/.next/static/chunks/app/page-f05cd0fc436bf9bc.js +1 -0
- package/dist/.next/static/chunks/{main-app-fa35024de9bd9284.js → main-app-4506e88db72db4b7.js} +1 -1
- package/dist/.next/static/css/{9f6c25c5400f83d3.css → 7c16f57d325d0d7d.css} +1 -1
- package/dist/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/.next/trace +3 -14
- package/dist/.next/types/app/api/cloudflare/route.ts +1 -1
- package/dist/.next/types/app/api/databases/route.ts +1 -1
- package/dist/.next/types/app/api/migrations/sync/route.ts +1 -1
- package/dist/.next/types/app/api/migrations/sync-files/route.ts +1 -1
- package/dist/.next/types/app/api/pull-data/confirm/route.ts +1 -1
- package/dist/.next/types/app/api/pull-remote/confirm/route.ts +1 -1
- package/dist/.next/types/app/api/pull-remote/preview/route.ts +1 -1
- package/dist/.next/types/app/api/push-remote/confirm/route.ts +1 -1
- package/dist/.next/types/app/api/push-remote/preview/route.ts +1 -1
- package/dist/.next/types/app/api/query/route.ts +1 -1
- package/dist/.next/types/app/api/tables/[name]/route.ts +1 -1
- package/dist/.next/types/app/api/tables/route.ts +1 -1
- package/dist/.next/types/app/api/update/route.ts +1 -1
- package/dist/.next/types/app/page.ts +1 -1
- package/dist/app/api/tables/[name]/route.js +22 -10
- package/dist/app/globals.css +39 -0
- package/dist/d1-studio.js +2 -2
- package/dist/lib/data-type-handlers.js +426 -0
- package/dist/lib/sql-operations.js +32 -8
- package/dist/lib/sql-sanitizer.js +233 -0
- package/package.json +3 -9
- package/dist/.next/.next/server/chunks/90.js +0 -1
- package/dist/.next/.next/static/chunks/app/page-36ed30b2266617f3.js +0 -1
- package/dist/.next/server/chunks/90.js +0 -1
- package/dist/.next/static/chunks/app/page-36ed30b2266617f3.js +0 -1
- package/dist/app/app/api/cloudflare/route.js +0 -150
- package/dist/app/app/api/databases/route.js +0 -71
- package/dist/app/app/api/migrations/sync/route.js +0 -174
- package/dist/app/app/api/migrations/sync-files/route.js +0 -172
- package/dist/app/app/api/pull-data/confirm/route.js +0 -230
- package/dist/app/app/api/pull-remote/confirm/route.js +0 -278
- package/dist/app/app/api/pull-remote/preview/route.js +0 -144
- package/dist/app/app/api/push-remote/confirm/route.js +0 -196
- package/dist/app/app/api/push-remote/preview/route.js +0 -179
- package/dist/app/app/api/query/route.js +0 -168
- package/dist/app/app/api/tables/[name]/route.js +0 -174
- package/dist/app/app/api/tables/route.js +0 -178
- package/dist/app/app/api/update/route.js +0 -45
- package/dist/app/app/globals.css +0 -93
- package/dist/app/app/layout.jsx +0 -35
- package/dist/app/app/page.jsx +0 -34
- package/next.config.mjs +0 -18
- package/postcss.config.mjs +0 -8
- package/scripts/studio.js +0 -199
- package/scripts/test.js +0 -366
- package/src/app/api/cloudflare/route.js +0 -150
- package/src/app/api/databases/route.js +0 -71
- package/src/app/api/migrations/sync/route.js +0 -174
- package/src/app/api/migrations/sync-files/route.js +0 -172
- package/src/app/api/pull-data/confirm/route.js +0 -230
- package/src/app/api/pull-remote/confirm/route.js +0 -278
- package/src/app/api/pull-remote/preview/route.js +0 -144
- package/src/app/api/push-remote/confirm/route.js +0 -196
- package/src/app/api/push-remote/preview/route.js +0 -179
- package/src/app/api/query/route.js +0 -168
- package/src/app/api/tables/[name]/route.js +0 -174
- package/src/app/api/tables/route.js +0 -178
- package/src/app/api/update/route.js +0 -45
- package/src/app/globals.css +0 -93
- package/src/app/layout.jsx +0 -35
- package/src/app/page.jsx +0 -34
- package/src/components/cloudflare-credentials-modal.jsx +0 -94
- package/src/components/column-selector.jsx +0 -133
- package/src/components/column-sorting.jsx +0 -65
- package/src/components/delete-records-dialog.jsx +0 -64
- package/src/components/download-button.jsx +0 -205
- package/src/components/edit-error-alert.jsx +0 -30
- package/src/components/editable-cell.jsx +0 -163
- package/src/components/editable-row.jsx +0 -169
- package/src/components/environment-handler.jsx +0 -332
- package/src/components/environment-select.jsx +0 -62
- package/src/components/pull-preview-toast.jsx +0 -215
- package/src/components/push-error-alert.jsx +0 -72
- package/src/components/push-preview-toast.jsx +0 -183
- package/src/components/query-results.jsx +0 -112
- package/src/components/refresh-button.jsx +0 -61
- package/src/components/resize-columns.jsx +0 -101
- package/src/components/sidebar.jsx +0 -254
- package/src/components/sql-editor.jsx +0 -411
- package/src/components/sql-error-display.jsx +0 -167
- package/src/components/sync-migrations-button.jsx +0 -87
- package/src/components/table-error-dialog.jsx +0 -65
- package/src/components/table-toolbar.jsx +0 -285
- package/src/components/table-view.jsx +0 -843
- package/src/components/ui/alert.jsx +0 -47
- package/src/components/ui/button.jsx +0 -48
- package/src/components/ui/card.jsx +0 -50
- package/src/components/ui/checkbox.jsx +0 -24
- package/src/components/ui/collapsible.jsx +0 -11
- package/src/components/ui/dialog.jsx +0 -96
- package/src/components/ui/dropdown-menu.jsx +0 -158
- package/src/components/ui/input.jsx +0 -19
- package/src/components/ui/scroll-area.jsx +0 -40
- package/src/components/ui/select.jsx +0 -121
- package/src/components/ui/separator.jsx +0 -25
- package/src/components/ui/sheet.jsx +0 -109
- package/src/components/ui/sidebar.jsx +0 -620
- package/src/components/ui/skeleton.jsx +0 -14
- package/src/components/ui/table.jsx +0 -86
- package/src/components/ui/tabs.jsx +0 -43
- package/src/components/ui/toast.jsx +0 -86
- package/src/components/ui/toaster.jsx +0 -35
- package/src/components/ui/tooltip.jsx +0 -28
- package/src/components/update-banner.jsx +0 -93
- package/src/context/database-context.js +0 -510
- package/src/hooks/use-mobile.jsx +0 -19
- package/src/hooks/use-sql-error.ts +0 -23
- package/src/hooks/use-toast.js +0 -155
- package/src/lib/database-queue.js +0 -37
- package/src/lib/error.js +0 -20
- package/src/lib/find-wrangler-config.js +0 -74
- package/src/lib/license.js +0 -99
- package/src/lib/logger.js +0 -58
- package/src/lib/migrations.js +0 -415
- package/src/lib/parse-sql-error.js +0 -200
- package/src/lib/request-deduplication.js +0 -24
- package/src/lib/schema-operations.js +0 -106
- package/src/lib/sql-error-types.js +0 -14
- package/src/lib/sql-operations.js +0 -647
- package/src/lib/utils.js +0 -6
- package/src/lib/version-utils.js +0 -34
- /package/dist/.next/.next/static/{OUHnbB-64afrrZQL0Srn5 → FEsQ9jwPUQv5A3fwg6Opl}/_buildManifest.js +0 -0
- /package/dist/.next/.next/static/{OUHnbB-64afrrZQL0Srn5 → FEsQ9jwPUQv5A3fwg6Opl}/_ssgManifest.js +0 -0
- /package/dist/.next/.next/static/{ZBTCAyp1kO5FdEHMU-Dw2 → Y9mYu4WBghepP5oT_3OdR}/_buildManifest.js +0 -0
- /package/dist/.next/.next/static/{ZBTCAyp1kO5FdEHMU-Dw2 → Y9mYu4WBghepP5oT_3OdR}/_ssgManifest.js +0 -0
- /package/dist/.next/.next/static/{bHYW7fgIBDF8-Q33_WPoE → ae3gNmoSGm-R5LJC4UagI}/_buildManifest.js +0 -0
- /package/dist/.next/.next/static/{bHYW7fgIBDF8-Q33_WPoE → ae3gNmoSGm-R5LJC4UagI}/_ssgManifest.js +0 -0
- /package/dist/.next/{static/ZBTCAyp1kO5FdEHMU-Dw2 → .next/static/bKfUJeuvAQlBmR3TjrfkH}/_buildManifest.js +0 -0
- /package/dist/.next/{static/ZBTCAyp1kO5FdEHMU-Dw2 → .next/static/bKfUJeuvAQlBmR3TjrfkH}/_ssgManifest.js +0 -0
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
// components/pull-preview-toast.jsx
|
|
2
|
-
|
|
3
|
-
import React, { useEffect, useState } from "react";
|
|
4
|
-
import { Button } from "@/components/ui/button";
|
|
5
|
-
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
6
|
-
import { FileText, Loader2, X } from "lucide-react";
|
|
7
|
-
import { cn } from "@/lib/utils";
|
|
8
|
-
|
|
9
|
-
export function PullPreviewToast({
|
|
10
|
-
preview = [],
|
|
11
|
-
onConfirm,
|
|
12
|
-
onCancel,
|
|
13
|
-
onDataPull,
|
|
14
|
-
isConfirming,
|
|
15
|
-
isDataPulling,
|
|
16
|
-
error,
|
|
17
|
-
isLoading,
|
|
18
|
-
success,
|
|
19
|
-
}) {
|
|
20
|
-
console.log("PullPreviewToast rendered with:", {
|
|
21
|
-
previewLength: preview.length,
|
|
22
|
-
isConfirming,
|
|
23
|
-
error,
|
|
24
|
-
isLoading,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
console.log("PullPreviewToast mounted/updated");
|
|
29
|
-
return () => console.log("PullPreviewToast unmounted");
|
|
30
|
-
}, []);
|
|
31
|
-
|
|
32
|
-
const [isDetailsOpen, setIsDetailsOpen] = useState(false);
|
|
33
|
-
|
|
34
|
-
// Loading state
|
|
35
|
-
if (isLoading) {
|
|
36
|
-
console.log("Rendering loading state");
|
|
37
|
-
return (
|
|
38
|
-
<div className="fixed bottom-4 right-4 z-50 font-sans w-[600px]">
|
|
39
|
-
<div className="rounded-lg border p-4 shadow-lg bg-background">
|
|
40
|
-
<div className="flex items-start gap-3">
|
|
41
|
-
<Loader2 className="h-5 w-5 text-neutral-600 shrink-0 mt-0.5 animate-spin" />
|
|
42
|
-
<div className="flex-1 space-y-3">
|
|
43
|
-
<div className="space-y-1">
|
|
44
|
-
<p className="font-medium text-neutral-800">
|
|
45
|
-
Preparing Pull Migration
|
|
46
|
-
</p>
|
|
47
|
-
<p className="text-sm text-neutral-600">
|
|
48
|
-
Checking remote migrations...
|
|
49
|
-
</p>
|
|
50
|
-
</div>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (!preview?.length) {
|
|
59
|
-
console.log("No preview data available");
|
|
60
|
-
return (
|
|
61
|
-
<div className="fixed bottom-4 right-4 z-50 w-[600px]">
|
|
62
|
-
<div className="rounded-lg border bg-destructive/15 p-4">
|
|
63
|
-
<div className="flex items-center gap-2">
|
|
64
|
-
<p className="text-sm font-medium text-destructive">
|
|
65
|
-
No preview data available
|
|
66
|
-
</p>
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
</div>
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Filter migrations to only include files with a ".sql" extension
|
|
74
|
-
const sqlMigrations = preview.filter((item) => {
|
|
75
|
-
const migrationName = item.migration || item.name || "";
|
|
76
|
-
return migrationName.endsWith(".sql");
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// Count only SQL migrations for the header
|
|
80
|
-
const totalMigrations = sqlMigrations.length;
|
|
81
|
-
console.log("Migration stats:", { totalMigrations });
|
|
82
|
-
|
|
83
|
-
// Determine if sync button should be enabled
|
|
84
|
-
// Only enable if pull was successful and not currently pulling data
|
|
85
|
-
const isSyncEnabled = success && !isDataPulling && !error;
|
|
86
|
-
|
|
87
|
-
return (
|
|
88
|
-
<div className="fixed bottom-4 right-4 z-50 font-sans w-[600px]">
|
|
89
|
-
<div
|
|
90
|
-
className={cn(
|
|
91
|
-
"rounded-lg border p-4 shadow-lg",
|
|
92
|
-
error ? "bg-destructive/15" : "bg-background"
|
|
93
|
-
)}
|
|
94
|
-
>
|
|
95
|
-
<div className="flex items-start gap-x-1">
|
|
96
|
-
<div className="flex-1 space-y-3">
|
|
97
|
-
{/* Header with Close Button */}
|
|
98
|
-
<div className="space-y-1">
|
|
99
|
-
<div className="flex items-center justify-between">
|
|
100
|
-
<h5
|
|
101
|
-
className={cn(
|
|
102
|
-
"font-medium",
|
|
103
|
-
error ? "text-destructive" : "text-neutral-900"
|
|
104
|
-
)}
|
|
105
|
-
>
|
|
106
|
-
{error ? "Pull Migration Error" : "Pull Migration Preview"}
|
|
107
|
-
</h5>
|
|
108
|
-
<button
|
|
109
|
-
onClick={onCancel}
|
|
110
|
-
className="text-neutral-500 hover:text-neutral-900 p-1 rounded-md hover:bg-neutral-100"
|
|
111
|
-
>
|
|
112
|
-
<X className="h-4 w-4" />
|
|
113
|
-
</button>
|
|
114
|
-
</div>
|
|
115
|
-
<p
|
|
116
|
-
className={cn(
|
|
117
|
-
"text-sm",
|
|
118
|
-
error ? "text-destructive/80" : "text-neutral-700"
|
|
119
|
-
)}
|
|
120
|
-
>
|
|
121
|
-
{`${totalMigrations} migration(s) will be applied`}
|
|
122
|
-
</p>
|
|
123
|
-
{error && (
|
|
124
|
-
<p className="text-sm text-destructive font-medium mt-1">
|
|
125
|
-
{error.message}
|
|
126
|
-
</p>
|
|
127
|
-
)}
|
|
128
|
-
{success && (
|
|
129
|
-
<p className="text-sm text-green-700 font-medium mt-1">
|
|
130
|
-
{success}
|
|
131
|
-
</p>
|
|
132
|
-
)}
|
|
133
|
-
</div>
|
|
134
|
-
|
|
135
|
-
{/* Migration Details */}
|
|
136
|
-
<div>
|
|
137
|
-
<button
|
|
138
|
-
onClick={() => setIsDetailsOpen(!isDetailsOpen)}
|
|
139
|
-
className="text-sm font-medium hover:underline"
|
|
140
|
-
>
|
|
141
|
-
{isDetailsOpen ? "Hide Details" : "Show Details"}
|
|
142
|
-
</button>
|
|
143
|
-
|
|
144
|
-
{isDetailsOpen && (
|
|
145
|
-
<ScrollArea className="h-[480px] mt-2 rounded border border-neutral-200">
|
|
146
|
-
<div className="w-full">
|
|
147
|
-
<div className="bg-neutral-50 border-b px-4 py-2">
|
|
148
|
-
<div className="text-sm font-medium text-neutral-600">Migration</div>
|
|
149
|
-
</div>
|
|
150
|
-
<div>
|
|
151
|
-
{sqlMigrations.map((item, index) => (
|
|
152
|
-
<div
|
|
153
|
-
key={index}
|
|
154
|
-
className="px-4 py-2 border-b last:border-0"
|
|
155
|
-
>
|
|
156
|
-
<div className="font-mono text-xs">
|
|
157
|
-
{item.migration || item.name}
|
|
158
|
-
</div>
|
|
159
|
-
</div>
|
|
160
|
-
))}
|
|
161
|
-
</div>
|
|
162
|
-
</div>
|
|
163
|
-
</ScrollArea>
|
|
164
|
-
)}
|
|
165
|
-
</div>
|
|
166
|
-
|
|
167
|
-
{/* Action Buttons */}
|
|
168
|
-
<div className="flex flex-col gap-2 pt-1">
|
|
169
|
-
<div className="flex gap-2">
|
|
170
|
-
<Button
|
|
171
|
-
onClick={onConfirm}
|
|
172
|
-
disabled={isConfirming}
|
|
173
|
-
className={`flex-1 ${isConfirming ? "cursor-not-allowed opacity-50" : ""}`}
|
|
174
|
-
>
|
|
175
|
-
{isConfirming ? (
|
|
176
|
-
<>
|
|
177
|
-
<Loader2 className="h-4 w-4 animate-spin" />
|
|
178
|
-
Confirming...
|
|
179
|
-
</>
|
|
180
|
-
) : (
|
|
181
|
-
"Confirm Pull"
|
|
182
|
-
)}
|
|
183
|
-
</Button>
|
|
184
|
-
|
|
185
|
-
{/* Right column - Sync data and description */}
|
|
186
|
-
<div className="flex-1 flex flex-col gap-2">
|
|
187
|
-
<Button
|
|
188
|
-
onClick={onDataPull}
|
|
189
|
-
disabled={!isSyncEnabled}
|
|
190
|
-
variant="outline"
|
|
191
|
-
className={`w-full ${!isSyncEnabled ? "cursor-not-allowed opacity-50" : ""}`}
|
|
192
|
-
>
|
|
193
|
-
{isDataPulling ? (
|
|
194
|
-
<>
|
|
195
|
-
<Loader2 className="h-4 w-4 animate-spin" />
|
|
196
|
-
Syncing remote data...
|
|
197
|
-
</>
|
|
198
|
-
) : (
|
|
199
|
-
"Sync remote data"
|
|
200
|
-
)}
|
|
201
|
-
</Button>
|
|
202
|
-
<p className="text-xs text-neutral-500 text-center">
|
|
203
|
-
75 records per table
|
|
204
|
-
</p>
|
|
205
|
-
</div>
|
|
206
|
-
</div>
|
|
207
|
-
</div>
|
|
208
|
-
</div>
|
|
209
|
-
</div>
|
|
210
|
-
</div>
|
|
211
|
-
</div>
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
export default PullPreviewToast;
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
// components/push-error-alert.jsx
|
|
2
|
-
'use client';
|
|
3
|
-
|
|
4
|
-
import React from 'react';
|
|
5
|
-
import { AlertCircle, X, ChevronDown, ChevronUp } from 'lucide-react';
|
|
6
|
-
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
|
7
|
-
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
|
8
|
-
|
|
9
|
-
export const PushErrorAlert = ({ error, onDismiss }) => {
|
|
10
|
-
const [showSuggestions, setShowSuggestions] = React.useState(true);
|
|
11
|
-
|
|
12
|
-
if (!error) return null;
|
|
13
|
-
|
|
14
|
-
// Ensure error message is visible by scrolling to it
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
if (error) {
|
|
17
|
-
const alertElement = document.querySelector('.alert-push-error');
|
|
18
|
-
alertElement?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
19
|
-
}
|
|
20
|
-
}, [error]);
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<Alert variant="destructive" className="mt-4 mb-4 alert-push-error">
|
|
24
|
-
<AlertCircle className="h-4 w-4" />
|
|
25
|
-
<AlertTitle className="flex items-center justify-between">
|
|
26
|
-
<span>{error.message}</span>
|
|
27
|
-
{onDismiss && (
|
|
28
|
-
<button
|
|
29
|
-
onClick={onDismiss}
|
|
30
|
-
className="p-1 hover:bg-destructive/10 rounded-full"
|
|
31
|
-
>
|
|
32
|
-
<X className="h-4 w-4" />
|
|
33
|
-
</button>
|
|
34
|
-
)}
|
|
35
|
-
</AlertTitle>
|
|
36
|
-
|
|
37
|
-
<AlertDescription className="mt-2">
|
|
38
|
-
<Collapsible
|
|
39
|
-
open={showSuggestions}
|
|
40
|
-
onOpenChange={setShowSuggestions}
|
|
41
|
-
className="space-y-2"
|
|
42
|
-
>
|
|
43
|
-
<CollapsibleTrigger className="flex items-center gap-2 text-sm font-medium">
|
|
44
|
-
{showSuggestions ? (
|
|
45
|
-
<ChevronUp className="h-4 w-4" />
|
|
46
|
-
) : (
|
|
47
|
-
<ChevronDown className="h-4 w-4" />
|
|
48
|
-
)}
|
|
49
|
-
Suggested Actions
|
|
50
|
-
</CollapsibleTrigger>
|
|
51
|
-
|
|
52
|
-
<CollapsibleContent className="space-y-2">
|
|
53
|
-
{error.details?.suggestions?.map((suggestion, index) => (
|
|
54
|
-
<div
|
|
55
|
-
key={index}
|
|
56
|
-
className="text-sm text-destructive-foreground/80 pl-6"
|
|
57
|
-
>
|
|
58
|
-
• {suggestion}
|
|
59
|
-
</div>
|
|
60
|
-
))}
|
|
61
|
-
</CollapsibleContent>
|
|
62
|
-
</Collapsible>
|
|
63
|
-
|
|
64
|
-
{error.details?.error && (
|
|
65
|
-
<div className="mt-4 text-sm font-mono bg-destructive/10 p-2 rounded">
|
|
66
|
-
{error.details.error}
|
|
67
|
-
</div>
|
|
68
|
-
)}
|
|
69
|
-
</AlertDescription>
|
|
70
|
-
</Alert>
|
|
71
|
-
);
|
|
72
|
-
};
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
// components/push-preview-toast.jsx
|
|
2
|
-
'use client';
|
|
3
|
-
|
|
4
|
-
import React, { useEffect, useState } from 'react';
|
|
5
|
-
import { Button } from "@/components/ui/button";
|
|
6
|
-
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
7
|
-
import {
|
|
8
|
-
Table,
|
|
9
|
-
TableBody,
|
|
10
|
-
TableCell,
|
|
11
|
-
TableHead,
|
|
12
|
-
TableHeader,
|
|
13
|
-
TableRow,
|
|
14
|
-
} from "@/components/ui/table";
|
|
15
|
-
import { Loader2, X } from "lucide-react";
|
|
16
|
-
import { cn } from "@/lib/utils";
|
|
17
|
-
|
|
18
|
-
export function PushPreviewToast({
|
|
19
|
-
preview = [],
|
|
20
|
-
onConfirm,
|
|
21
|
-
onCancel,
|
|
22
|
-
isConfirming,
|
|
23
|
-
error,
|
|
24
|
-
isLoading,
|
|
25
|
-
success
|
|
26
|
-
}) {
|
|
27
|
-
const [isDetailsOpen, setIsDetailsOpen] = useState(true);
|
|
28
|
-
|
|
29
|
-
// Handle loading state
|
|
30
|
-
if (isLoading) {
|
|
31
|
-
return (
|
|
32
|
-
<div className="fixed bottom-4 right-4 z-50 font-sans w-[600px]">
|
|
33
|
-
<div className="rounded-lg border p-4 shadow-lg bg-background">
|
|
34
|
-
<div className="flex items-start gap-3">
|
|
35
|
-
<Loader2 className="h-5 w-5 text-neutral-600 shrink-0 mt-0.5 animate-spin" />
|
|
36
|
-
<div className="flex-1 space-y-3">
|
|
37
|
-
<div className="space-y-1">
|
|
38
|
-
<p className="font-medium text-neutral-800">
|
|
39
|
-
Preparing Push Migration
|
|
40
|
-
</p>
|
|
41
|
-
<p className="text-sm text-neutral-600">
|
|
42
|
-
Checking local migrations...
|
|
43
|
-
</p>
|
|
44
|
-
</div>
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (!preview?.length) {
|
|
53
|
-
return (
|
|
54
|
-
<div className="fixed bottom-4 right-4 z-50 w-[600px]">
|
|
55
|
-
<div className="rounded-lg border p-4">
|
|
56
|
-
<p className="text-sm font-medium">No migrations to preview</p>
|
|
57
|
-
</div>
|
|
58
|
-
</div>
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Calculate migration stats
|
|
63
|
-
const pendingCount = preview.filter(m => m.action === 'will be applied').length;
|
|
64
|
-
const skippedCount = preview.filter(m => m.action === 'skipped').length;
|
|
65
|
-
const appliedCount = preview.filter(m => m.action === 'applied').length;
|
|
66
|
-
|
|
67
|
-
// Get status style based on action
|
|
68
|
-
const getStatusEmoji = (action) => {
|
|
69
|
-
switch (action) {
|
|
70
|
-
case 'will be applied':
|
|
71
|
-
return '🕒️';
|
|
72
|
-
case 'applied':
|
|
73
|
-
case 'skipped':
|
|
74
|
-
return '✅';
|
|
75
|
-
case 'failed':
|
|
76
|
-
return '❌';
|
|
77
|
-
default:
|
|
78
|
-
return '';
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
return (
|
|
83
|
-
<div className="fixed bottom-4 right-4 z-50 font-sans w-[600px]">
|
|
84
|
-
<div className={cn(
|
|
85
|
-
"rounded-lg border p-4 shadow-lg",
|
|
86
|
-
error ? "bg-destructive/15" : "bg-background"
|
|
87
|
-
)}>
|
|
88
|
-
<div className="flex flex-col gap-3">
|
|
89
|
-
{/* Header */}
|
|
90
|
-
<div className="space-y-2">
|
|
91
|
-
<div className="flex items-center justify-between">
|
|
92
|
-
<h5 className="font-medium text-neutral-900">
|
|
93
|
-
Push Migration Preview
|
|
94
|
-
</h5>
|
|
95
|
-
<button
|
|
96
|
-
onClick={onCancel}
|
|
97
|
-
className="text-neutral-500 hover:text-neutral-900 p-1 rounded-md hover:bg-neutral-100"
|
|
98
|
-
>
|
|
99
|
-
<X className="h-4 w-4" />
|
|
100
|
-
</button>
|
|
101
|
-
</div>
|
|
102
|
-
<p className="text-sm text-neutral-700">
|
|
103
|
-
{pendingCount} migration(s) 🕒️ pending, {skippedCount} to ✅ skip
|
|
104
|
-
</p>
|
|
105
|
-
{/* Status Messages */}
|
|
106
|
-
{error ? (
|
|
107
|
-
<p className="text-sm text-destructive font-medium mt-1">
|
|
108
|
-
{error.message}
|
|
109
|
-
</p>
|
|
110
|
-
) : success && (
|
|
111
|
-
<p className="text-sm text-green-700 font-medium mt-1">
|
|
112
|
-
{success}
|
|
113
|
-
</p>
|
|
114
|
-
)}
|
|
115
|
-
</div>
|
|
116
|
-
|
|
117
|
-
{/* Migration Details */}
|
|
118
|
-
<div>
|
|
119
|
-
<button
|
|
120
|
-
onClick={() => setIsDetailsOpen(!isDetailsOpen)}
|
|
121
|
-
className="text-sm font-medium hover:underline"
|
|
122
|
-
>
|
|
123
|
-
{isDetailsOpen ? 'Hide Details' : 'Show Details'}
|
|
124
|
-
</button>
|
|
125
|
-
|
|
126
|
-
{isDetailsOpen && (
|
|
127
|
-
<ScrollArea className="h-[480px] mt-2 rounded border border-neutral-200">
|
|
128
|
-
<Table>
|
|
129
|
-
<TableHeader>
|
|
130
|
-
<TableRow>
|
|
131
|
-
<TableHead>Migration</TableHead>
|
|
132
|
-
<TableHead className="text-center w-24">Status</TableHead>
|
|
133
|
-
</TableRow>
|
|
134
|
-
</TableHeader>
|
|
135
|
-
<TableBody>
|
|
136
|
-
{preview.map((item, index) => (
|
|
137
|
-
<TableRow key={index}>
|
|
138
|
-
<TableCell className="font-mono text-xs">
|
|
139
|
-
{item.name}
|
|
140
|
-
</TableCell>
|
|
141
|
-
<TableCell className="text-center align-middle">
|
|
142
|
-
{getStatusEmoji(item.action)}
|
|
143
|
-
</TableCell>
|
|
144
|
-
</TableRow>
|
|
145
|
-
))}
|
|
146
|
-
</TableBody>
|
|
147
|
-
</Table>
|
|
148
|
-
</ScrollArea>
|
|
149
|
-
)}
|
|
150
|
-
</div>
|
|
151
|
-
|
|
152
|
-
{/* Action Buttons */}
|
|
153
|
-
<div className="flex gap-2 pt-1">
|
|
154
|
-
<Button
|
|
155
|
-
onClick={onConfirm}
|
|
156
|
-
disabled={isConfirming || pendingCount === 0}
|
|
157
|
-
className="flex-1"
|
|
158
|
-
>
|
|
159
|
-
{isConfirming ? (
|
|
160
|
-
<>
|
|
161
|
-
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
162
|
-
Confirming...
|
|
163
|
-
</>
|
|
164
|
-
) : (
|
|
165
|
-
'Confirm Push'
|
|
166
|
-
)}
|
|
167
|
-
</Button>
|
|
168
|
-
<Button
|
|
169
|
-
variant="outline"
|
|
170
|
-
onClick={onCancel}
|
|
171
|
-
disabled={isConfirming}
|
|
172
|
-
className="flex-1"
|
|
173
|
-
>
|
|
174
|
-
Cancel
|
|
175
|
-
</Button>
|
|
176
|
-
</div>
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
</div>
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export default PushPreviewToast;
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
|
5
|
-
|
|
6
|
-
function QuerySummary({ results }) {
|
|
7
|
-
if (!results || !Array.isArray(results)) return null;
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<div className="text-xs font-medium text-neutral-900 flex items-center gap-2 mb-2">
|
|
11
|
-
{results.length} {results.length === 1 ? 'row' : 'rows'} returned
|
|
12
|
-
</div>
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* SQLErrorDisplay now logs the error object received from the parent.
|
|
18
|
-
* It safely handles null/undefined errors and logs them to the console.
|
|
19
|
-
*/
|
|
20
|
-
export function SQLErrorDisplay({ error }) {
|
|
21
|
-
console.debug("SQLErrorDisplay - Received error prop:", error);
|
|
22
|
-
// Create a safe fallback error object if needed.
|
|
23
|
-
const safeError =
|
|
24
|
-
error && typeof error.message === 'string'
|
|
25
|
-
? error
|
|
26
|
-
: { message: 'An unknown error occurred', details: {} };
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<div>
|
|
30
|
-
<div className="text-neutral-700 text-sm">{safeError.message}</div>
|
|
31
|
-
{safeError.details?.stderr && (
|
|
32
|
-
<pre className="mt-2 p-2 text-xs text-red-500 whitespace-pre-wrap">
|
|
33
|
-
{safeError.details.stderr}
|
|
34
|
-
</pre>
|
|
35
|
-
)}
|
|
36
|
-
</div>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function SQLResultsView({ query, results }) {
|
|
41
|
-
if (!results?.length) {
|
|
42
|
-
return (
|
|
43
|
-
<div className="text-sm text-neutral-500">
|
|
44
|
-
No results to display.
|
|
45
|
-
</div>
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Detect if the query is a PRAGMA table_info query
|
|
50
|
-
const isSchemaQuery = query?.trim().toLowerCase().startsWith('pragma table_info');
|
|
51
|
-
|
|
52
|
-
// Define columns for schema queries
|
|
53
|
-
const schemaColumns = isSchemaQuery
|
|
54
|
-
? ['Column Name', 'Type', 'Not Null', 'Default Value', 'Primary Key']
|
|
55
|
-
: Object.keys(results[0]);
|
|
56
|
-
|
|
57
|
-
// Format schema rows if it's a schema query
|
|
58
|
-
const formattedResults = isSchemaQuery
|
|
59
|
-
? results.map((row) => ({
|
|
60
|
-
'Column Name': row.name,
|
|
61
|
-
'Type': row.type,
|
|
62
|
-
'Not Null': row.notnull === 1 ? 'YES' : 'NO',
|
|
63
|
-
'Default Value': row.dflt_value || '(null)',
|
|
64
|
-
'Primary Key': row.pk === 1 ? 'YES' : 'NO',
|
|
65
|
-
}))
|
|
66
|
-
: results;
|
|
67
|
-
|
|
68
|
-
return (
|
|
69
|
-
<div className="flex flex-col h-full">
|
|
70
|
-
<QuerySummary results={formattedResults} />
|
|
71
|
-
<div className="flex-1 overflow-auto border rounded-lg">
|
|
72
|
-
<div className="min-w-full">
|
|
73
|
-
<Table>
|
|
74
|
-
<TableHeader>
|
|
75
|
-
<TableRow className="bg-muted/50">
|
|
76
|
-
{schemaColumns.map((column) => (
|
|
77
|
-
<TableHead
|
|
78
|
-
key={column}
|
|
79
|
-
className="font-mono text-xs font-medium text-muted-foreground"
|
|
80
|
-
>
|
|
81
|
-
{column}
|
|
82
|
-
</TableHead>
|
|
83
|
-
))}
|
|
84
|
-
</TableRow>
|
|
85
|
-
</TableHeader>
|
|
86
|
-
<TableBody>
|
|
87
|
-
{formattedResults.map((row, rowIndex) => (
|
|
88
|
-
<TableRow key={rowIndex} className="hover:bg-muted/50">
|
|
89
|
-
{schemaColumns.map((column) => {
|
|
90
|
-
const value = row[column];
|
|
91
|
-
const displayValue = value === null ? '(null)' : String(value);
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
<TableCell
|
|
95
|
-
key={`${rowIndex}-${column}`}
|
|
96
|
-
className="font-monospace text-xs whitespace-nowrap"
|
|
97
|
-
>
|
|
98
|
-
{displayValue}
|
|
99
|
-
</TableCell>
|
|
100
|
-
);
|
|
101
|
-
})}
|
|
102
|
-
</TableRow>
|
|
103
|
-
))}
|
|
104
|
-
</TableBody>
|
|
105
|
-
</Table>
|
|
106
|
-
</div>
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export default SQLResultsView;
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
// components/refresh-button.jsx
|
|
2
|
-
'use client';
|
|
3
|
-
|
|
4
|
-
import React, { memo, useState } from 'react';
|
|
5
|
-
import { Button } from "@/components/ui/button";
|
|
6
|
-
import { RefreshCw, Loader2 } from 'lucide-react';
|
|
7
|
-
import {
|
|
8
|
-
Tooltip,
|
|
9
|
-
TooltipContent,
|
|
10
|
-
TooltipProvider,
|
|
11
|
-
TooltipTrigger,
|
|
12
|
-
} from "@/components/ui/tooltip";
|
|
13
|
-
|
|
14
|
-
const RefreshButton = memo(({ onRefresh, disabled }) => {
|
|
15
|
-
const [isRefreshing, setIsRefreshing] = useState(false);
|
|
16
|
-
|
|
17
|
-
const handleRefresh = async () => {
|
|
18
|
-
if (isRefreshing || disabled) return;
|
|
19
|
-
|
|
20
|
-
setIsRefreshing(true);
|
|
21
|
-
try {
|
|
22
|
-
await onRefresh();
|
|
23
|
-
} catch (error) {
|
|
24
|
-
console.error('Refresh failed:', error);
|
|
25
|
-
} finally {
|
|
26
|
-
// Add a small delay before allowing another refresh
|
|
27
|
-
setTimeout(() => {
|
|
28
|
-
setIsRefreshing(false);
|
|
29
|
-
}, 500);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
return (
|
|
34
|
-
<TooltipProvider>
|
|
35
|
-
<Tooltip>
|
|
36
|
-
<TooltipTrigger asChild>
|
|
37
|
-
<Button
|
|
38
|
-
variant="outline"
|
|
39
|
-
size="icon"
|
|
40
|
-
onClick={handleRefresh}
|
|
41
|
-
disabled={isRefreshing || disabled}
|
|
42
|
-
className="h-8"
|
|
43
|
-
>
|
|
44
|
-
{isRefreshing ? (
|
|
45
|
-
<Loader2 className="h-4 w-4 animate-spin" />
|
|
46
|
-
) : (
|
|
47
|
-
<RefreshCw className="h-4 w-4" />
|
|
48
|
-
)}
|
|
49
|
-
</Button>
|
|
50
|
-
</TooltipTrigger>
|
|
51
|
-
<TooltipContent>
|
|
52
|
-
<p>Refresh table data</p>
|
|
53
|
-
</TooltipContent>
|
|
54
|
-
</Tooltip>
|
|
55
|
-
</TooltipProvider>
|
|
56
|
-
);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
RefreshButton.displayName = 'RefreshButton';
|
|
60
|
-
|
|
61
|
-
export default RefreshButton;
|