Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/auto-merge-claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ jobs:
- run: npm ci

- run: npm run build:cdn
env:
NODE_OPTIONS: --max-old-space-size=6144

- name: Prepare site files
run: |
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/build-cdn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
actions: write

steps:
- uses: actions/checkout@v4
Expand All @@ -32,3 +33,8 @@ jobs:
git add dist-cdn/
git diff --cached --quiet || git commit -m "chore: rebuild dist-cdn [skip ci]"
git push origin main

- name: Trigger deploy
run: gh workflow run deploy.yml --ref main
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
12 changes: 5 additions & 7 deletions src/app/components/SqlDataTable.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
/**
* SqlDataTable — remplace SimpleDatatables pour les cellules sql/table.
* Utilise DataTablePaginated de @sqlrooms/data-table avec tri et pagination
* client-side. Gère les colonnes spéciales PERCENT et TREND.
*/
import { useMemo, useState } from 'react'
import DataTablePaginated from '@sqlrooms/data-table/dist/DataTablePaginated'
import { DataTablePaginated, QueryDataTableActionsMenu } from '@sqlrooms/data-table'
import { sanitizeQuery } from '@sqlrooms/duckdb'
import { rawTableDataStore as _rawTableDataStore } from '../../lib/tableDataStore'
import { parseColumnRoles, getTableColumnDisplayNames } from '../../lib/EChartSqlParser'
import { ConfigManager } from '../../lib/ConfigManager'

// Types Arrow numériques tels que retournés par String(field.type) de duckdb-wasm
const NUMERIC_ARROW_RE = /^(Int|Uint|Float|Decimal)/i

function colMeta(schemaTypes: Record<string, string>, key: string) {
Expand All @@ -23,6 +19,7 @@ export function SqlDataTable({ cell, searchable = false }: { cell: any; searchab

const rawResults = _rawTableDataStore.get(cell._id) || cell._results || []
const schemaTypes: Record<string, string> = cell._schemaTypes || {}
const cellQuery = sanitizeQuery(ConfigManager.getCellQuery(cell, 'main') || '')

const { columns, allColKeys } = useMemo(() => {
if (!rawResults?.length) return { columns: [], allColKeys: [] }
Expand Down Expand Up @@ -130,6 +127,7 @@ export function SqlDataTable({ cell, searchable = false }: { cell: any; searchab
onPaginationChange={setPagination}
onSortingChange={setSorting}
fontSize="text-xs"
footerActions={cellQuery ? <QueryDataTableActionsMenu query={cellQuery} /> : null}
/>
</div>
)
Expand Down
42 changes: 37 additions & 5 deletions src/app/room.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
/**
* Room — Composant racine utilisant RoomShell de @sqlrooms/room-shell.
*
* - RoomShell.Sidebar : sidebar (boutons panels auto-inclus) + boutons custom
* - Sidebar custom : boutons groupés (datasources en haut du groupe bas)
* - RoomShell.LayoutComposer : mosaic layout (NotebookPanel + DataSourcesPanel)
* - RoomShell.LoadingProgress : barre de progression DuckDB
* - RoomShell.CommandPalette : palette de commandes (Ctrl+K)
* - Modals globaux (portals → document.body, indépendants du layout)
*/
import { RoomShell } from '@sqlrooms/room-shell'
import { RoomShell, useBaseRoomShellStore } from '@sqlrooms/room-shell'
import { useDisclosure, ThemeSwitch } from '@sqlrooms/ui'
import { useShallow } from 'zustand/react/shallow'
import { useMemo } from 'react'
import { roomStore, useNotebookStore } from './store/notebookStore'
import { SqlEditorModal } from '@sqlrooms/sql-editor'
import { BookHeartIcon, MessageSquareCodeIcon, PaintbrushIcon, Settings2Icon, TerminalIcon } from 'lucide-react'
Expand All @@ -23,6 +24,33 @@ import { ExportModal, GistTokenModal, GistResultModal, JsonPassphraseModal } fro
import { CellConfigModal } from './components/modals/CellConfigModal'
import { LoopConfigModal, GroupSettingsModal, ChildGroupModal } from './components/modals/GroupModals'

function getMosaicLeaves(node: any): string[] {
if (!node) return []
if (typeof node === 'string') return [node]
return [...getMosaicLeaves(node.first), ...getMosaicLeaves(node.second)]
}

function DataPanelSidebarButton() {
const togglePanel = useBaseRoomShellStore(s => s.layout.togglePanel)
const layoutConfig = useBaseRoomShellStore(s => s.layout.config)
const panels = useBaseRoomShellStore(s => s.layout.panels)
const initialized = useBaseRoomShellStore(s => s.room.initialized)

const panel = panels?.['data']
const isSelected = useMemo(() => getMosaicLeaves(layoutConfig?.nodes).includes('data'), [layoutConfig])

if (!panel) return null
return (
<RoomShell.SidebarButton
title={panel.title ?? 'Sources'}
isSelected={isSelected}
isDisabled={!initialized}
icon={panel.icon}
onClick={() => togglePanel('data')}
/>
)
}

function DbEngineIcon({ className }: { className?: string }) {
const dbEngine = useNotebookStore(s => s.dbEngine)
return <span className={className} style={{ fontSize: '1.1em', lineHeight: 1 }}>{dbEngine === 'ducklings' ? '🐤' : '🦆'}</span>
Expand Down Expand Up @@ -84,6 +112,9 @@ function SidebarControls() {
{/* Ancrés en bas via spacer */}
<div className="flex-1" />

{/* Sources de données — en haut du groupe ancré */}
<DataPanelSidebarButton />

{/* Documentation (gist) */}
<RoomShell.SidebarButton
title="Documentation"
Expand Down Expand Up @@ -116,15 +147,17 @@ function SidebarControls() {
export function Room() {
const showLayout = useNotebookStore(s => s.showLayout)


return (
<>
<RoomShell roomStore={roomStore} className="h-screen w-screen">
<RoomShell.Sidebar className={showLayout ? '' : 'hidden'}>
<div className={`bg-muted/70 flex h-full w-12 flex-col items-center gap-2 px-1 py-4 ${showLayout ? '' : 'hidden'}`}>
<SidebarControls />
</RoomShell.Sidebar>
</div>
<RoomShell.LayoutComposer tileClassName="p-0" />
<RoomShell.LoadingProgress />
<RoomShell.CommandPalette />
<ChildGroupModal />
</RoomShell>

{/* Modals globaux — portals vers document.body, indépendants du layout */}
Expand All @@ -135,7 +168,6 @@ export function Room() {
<InsertCellModal />
<AddCellToGroupModal />
<CellConfigModal />
<ChildGroupModal />
<LoopConfigModal />
<GroupSettingsModal />
<DbEngineModal />
Expand Down
Loading