Skip to content

Commit

Permalink
Fix style, add notebook selector
Browse files Browse the repository at this point in the history
  • Loading branch information
gessfred committed Jan 21, 2024
1 parent 5339541 commit 8ab50ba
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 52 deletions.
19 changes: 19 additions & 0 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@codemirror/lang-sql": "^6.5.5",
"@headlessui/react": "^1.7.18",
"@heroicons/react": "^2.1.1",
"@uiw/codemirror-themes": "^4.21.21",
"@uiw/react-codemirror": "^4.21.21",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
6 changes: 5 additions & 1 deletion app/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@
.read-the-docs {
color: #888;
}
*/
*/

:root {
outline: none;
}
35 changes: 33 additions & 2 deletions app/src/components/Code.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useRef, useEffect } from 'react'
import CodeMirror from '@uiw/react-codemirror'
import { createTheme } from '@uiw/codemirror-themes'
import { sql } from '@codemirror/lang-sql'

function extractTextBetweenSemicolons(text, caretPos) {
Expand All @@ -19,6 +20,26 @@ function extractTextBetweenSemicolons(text, caretPos) {
return text.substring(startPos, endPos);
}

const mainTheme = createTheme({
theme: 'light',
settings: {
background: '#ffffff',
backgroundImage: '',
foreground: 'black',
caret: '#5d00ff',
selection: '#036dd626',
selectionMatch: '#036dd626',
lineHighlight: 'none',
gutterBackground: 'white',
gutterForeground: '#8a919966',
gutterBorder: 'white',
gutterActiveForeground: 'white',
border: 'transparent',
outline: 'white',
fontWeight: 'bold'
},
})

export function CodeEditor({code, setCode, onCtrlEnter}) {
const editor = useRef()
const handleCmdEnter = (event) => {
Expand All @@ -44,16 +65,26 @@ export function CodeEditor({code, setCode, onCtrlEnter}) {
console.log("exe", window.getSelection().baseNode.nodeValue, '->', extractTextBetweenSemicolons(code, window.getSelection().baseOffset))
setCode(code)
}}
style={{outline: 'none', border: 'none'}}
className='border-transparent'
ref={editor}
height='500px'
basicSetup={{lineNumbers: false}}
minHeight='100px'
basicSetup={{
lineNumbers: false,
highlightActiveLine: false,
foldGutter: false,
rectangularSelection: false
}}
theme={mainTheme}
extensions={[sql()]}
options={{
extraKeys: {
'Ctrl-Enter': (cm) => console.log("ctrl+enter")
}}}
onKeyDown={handleCmdEnter}
onSelect={e => console.log('SELECT', e)}
autoFocus={true}
onStatistics={(s) => console.log('statistics', s)}
/>
)
}
2 changes: 1 addition & 1 deletion app/src/components/Dropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function Dropdown({name, items, selected, setSelected}) {
<Listbox value={selected} onChange={setSelected}>
{({ open }) => (
<>
<Listbox.Label className="block text-sm font-medium leading-6 text-gray-900">{name}</Listbox.Label>
{name && <Listbox.Label className="block text-sm font-medium leading-6 text-gray-900">{name}</Listbox.Label>}
<div className="relative mt-2">
<Listbox.Button className="relative w-full cursor-default rounded-md bg-white py-1.5 pl-3 pr-10 text-left text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 sm:text-sm sm:leading-6">
<span className="flex items-center">
Expand Down
13 changes: 8 additions & 5 deletions app/src/components/Layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {

const navigation = [
{ name: 'Home', icon: HomeIcon, current: true, id: 'home' },
{ name: 'Notebooks', href: '#', icon: UsersIcon, current: false },
{ name: 'Notebooks', icon: UsersIcon, current: false, id: 'notebook' },
]
const teams = [
{ id: 1, name: 'Heroicons', href: '#', initial: 'H', current: false },
Expand Down Expand Up @@ -96,7 +96,10 @@ export default function Layout({children, setMainPage, onSecondMenuChange}) {
{navigation.map((item) => (
<li key={item.name}>
<button
onClick={() => setMainPage(item.id)}
onClick={() => {
console.log('set main page', item)
setMainPage(item.id)
}}
className={classNames(
item.current
? 'bg-gray-50 text-indigo-600'
Expand All @@ -118,7 +121,7 @@ export default function Layout({children, setMainPage, onSecondMenuChange}) {
</ul>
</li>
<li>
<div className="text-xs font-semibold leading-6 text-gray-400">Your teams</div>
<div className="text-xs font-semibold leading-6 text-gray-400">Datasource</div>
<ul role="list" className="-mx-2 mt-2 space-y-1">
{teams.map((team) => (
<li key={team.name}>
Expand Down Expand Up @@ -196,7 +199,7 @@ export default function Layout({children, setMainPage, onSecondMenuChange}) {
</ul>
</li>
<li>
<div className="text-xs font-semibold leading-6 text-gray-400">Your teams</div>
<div className="text-xs font-semibold leading-6 text-gray-400">Datasource</div>
<ul role="list" className="-mx-2 mt-2 space-y-1">
{teams.map((team) => (
<li key={team.name}>
Expand Down Expand Up @@ -261,7 +264,7 @@ export default function Layout({children, setMainPage, onSecondMenuChange}) {
</div>

<main className="py-10 lg:pl-72">
<div className="px-4 sm:px-6 lg:px-8">{children}</div>
<div className="px-4 sm:px-6 lg:px-8 px-2">{children}</div>
</main>
</div>
</>
Expand Down
4 changes: 4 additions & 0 deletions app/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
@tailwind components;
@tailwind utilities;

textarea {
outline: none;
}

/*:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
Expand Down
82 changes: 39 additions & 43 deletions app/src/pages/Notebook.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import {
LinkIcon,
MapPinIcon,
PencilIcon,
CircleStackIcon
} from '@heroicons/react/20/solid'
import { Menu, Transition } from '@headlessui/react'
import Dropdown from '../components/Dropdown'
function execSql(api, query, datasource, onSuccess, onError) {
console.log(query, datasource, {"query": query, datasource_id: datasource})
api.post('/query', {"query": query, datasource_id: datasource}, {
Expand Down Expand Up @@ -64,7 +66,7 @@ function classNames(...classes) {
return classes.filter(Boolean).join(' ')
}

export function NotebookHeader({addCell, onPublish}) {
export function NotebookHeader({datasource, datasources, addCell, onPublish}) {
return (
<div className="lg:flex lg:items-center lg:justify-between">
<div className="min-w-0 flex-1">
Expand All @@ -73,9 +75,14 @@ export function NotebookHeader({addCell, onPublish}) {
</h2>
<div className="mt-1 flex flex-col sm:mt-0 sm:flex-row sm:flex-wrap sm:space-x-6">
<div className="mt-2 flex items-center text-sm text-gray-500">
<BriefcaseIcon className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
Full-time
<CircleStackIcon className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
Datasource
</div>
<Dropdown
items={[{avatar: '', name: ''}]}
selected=''
setSelected={() => {}}
/>
<div className="mt-2 flex items-center text-sm text-gray-500">
<MapPinIcon className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
Remote
Expand Down Expand Up @@ -212,26 +219,26 @@ function DashboardSettings({cell, setStyle}) {
)
}

function NotebookCellToolbar({cell, run, isComputing, setStyle}) {

function NotebookCellStatusBar({isComputing}) {
return (
<div className='notebook-cell-status-bar'>
<div className='notebook-cell-status-bar-left'>
<Button icon='fa-play' onClick={run} isLoading={isComputing}>
Run
</Button>
<span className='notebook-cell-duration'>
{cell.result && Math.round(cell.result.duration)} s
</span>
<DashboardTypeSelector
cell={cell}
choices={['Table', 'Dashboard']}
setStyle={setStyle}
/>
<div>
{isComputing && (
<svg className={"animate-spin h-6 w-6 mr-3"} viewBox="0 0 24 24">
<path d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z" opacity=".25"/><path d="M10.72,19.9a8,8,0,0,1-6.5-9.79A7.77,7.77,0,0,1,10.4,4.16a8,8,0,0,1,9.49,6.52A1.54,1.54,0,0,0,21.38,12h.13a1.37,1.37,0,0,0,1.38-1.54,11,11,0,1,0-12.7,12.39A1.54,1.54,0,0,0,12,21.34h0A1.47,1.47,0,0,0,10.72,19.9Z" />
</svg>
)}
</div>
)
}

function CellContainer({children}) {
return (
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-4 shadow-xl rounded-lg">
{/* We've used 3xl here, but feel free to try other max-widths based on your needs */}
<div className="mx-auto max-w-7xl space-y-4">
{children}
</div>
{(cell && cell.style && cell.result) && <DashboardSettings
cell={cell}
setStyle={setStyle}
/>}
</div>
)
}
Expand All @@ -245,7 +252,7 @@ function NotebookCell({api, datasource, setQuery, setResult, setStyle, cell, onC
setState({isComputing: false})
}
return (
<div>
<CellContainer>
<CodeEditor
code={cell.query}
setCode={setQuery}
Expand All @@ -255,24 +262,15 @@ function NotebookCell({api, datasource, setQuery, setResult, setStyle, cell, onC
setState({isComputing: true})
}}
/>
{false && <NotebookCellToolbar
run={() => {
execSql(api, cell.query, datasource, onQueryResult, onQueryResult)
setState({isComputing: true})
}}
<NotebookCellStatusBar
isComputing={state.isComputing}
cell={cell}
setStyle={style => {
console.log(style)
setStyle(style)
}}
/>}
/>
{cell.result.columns && ((cell.style && cell.style.type === 'Table' )|| true) && <Table
columns={cell.result.columns}
rows={cell.result.rows}
/>}
{cell.result.error && <span>{JSON.stringify(cell?.result?.error)}</span>}
</div>
</CellContainer>
)
}
/*
Expand Down Expand Up @@ -318,15 +316,6 @@ export function Notebook({api, datasource, show, data}) {
api.userdata.notebooks.write(Object.assign({}, state, {cells: Object.values(state.cells)}))
}}
/>
{false && <NotebookToolbar
newCell={addCell}
metadata={{datasource: datasource}}
data={state}
setData={setState}
saveNotebook={() => {
api.userdata.notebooks.write(Object.assign({}, state, {cells: Object.values(state.cells)}))
}}
/>}
<div className=''>
{Object.values(state.cells).map((cell, idx) => <NotebookCell
api={api}
Expand All @@ -342,3 +331,10 @@ export function Notebook({api, datasource, show, data}) {
</div>
)
}


/*
saveNotebook={() => {
api.userdata.notebooks.write(Object.assign({}, state, {cells: Object.values(state.cells)}))
}}
*/

0 comments on commit 8ab50ba

Please sign in to comment.