Skip to content
Open
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: 1 addition & 1 deletion e2e/questdb
Submodule questdb updated 5076 files
1 change: 1 addition & 0 deletions src/components/CopyButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { copyToClipboard } from "../../utils/copyToClipboard"

const StyledButton = styled(Button)`
padding: 1.2rem 0.6rem;
position: relative;
`

const StyledCheckboxCircle = styled(CheckboxCircle)`
Expand Down
15 changes: 11 additions & 4 deletions src/components/LiteEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { editor } from "monaco-editor"
import { QuestDBLanguageName } from "../../scenes/Editor/Monaco/utils"
import styled, { useTheme } from "styled-components"
import { Button } from "../Button"
import { CornersOutIcon } from "@phosphor-icons/react"
import { FileCopy } from "@styled-icons/remix-line"
import { CheckboxCircle } from "@styled-icons/remix-fill"
import { copyToClipboard } from "../../utils/copyToClipboard"
Expand Down Expand Up @@ -39,6 +40,10 @@ const EditorWrapper = styled.div<{ $noBorder?: boolean }>`
pointer-events: none;
}

.view-overlays > * {
overflow-x: hidden;
}

.current-line {
background: transparent !important;
border: 0 !important;
Expand Down Expand Up @@ -141,14 +146,17 @@ const LiteEditorToolbar = ({
onOpenInEditor,
onCopy,
copied,
diffEditor,
compact = false,
}: {
diffEditor: boolean
onOpenInEditor: () => void
onCopy: () => void
copied: boolean
compact?: boolean
}) => {
const appTheme = useTheme()
const Icon = diffEditor ? SquareSplitHorizontalIcon : CornersOutIcon
return (
<ButtonsContainer>
<OpenInEditorButton
Expand All @@ -158,10 +166,7 @@ const LiteEditorToolbar = ({
data-hook="ai-open-in-editor-button"
>
{!compact && "Open in editor"}
<SquareSplitHorizontalIcon
size="1.8rem"
color={appTheme.color.offWhite}
/>
<Icon size="1.8rem" color={appTheme.color.offWhite} />
</OpenInEditorButton>
{!compact && (
<CopyButtonBase
Expand Down Expand Up @@ -393,6 +398,7 @@ export const LiteEditor: React.FC<LiteEditorProps> = ({
}}
>
<LiteEditorToolbar
diffEditor
onOpenInEditor={props.onOpenInEditor}
onCopy={() => handleCopy(props.modified)}
copied={copied}
Expand All @@ -415,6 +421,7 @@ export const LiteEditor: React.FC<LiteEditorProps> = ({
<EditorWrapper style={{ height: effectiveHeight }}>
{showToolbarForRegularEditor || compactToolbar ? (
<LiteEditorToolbar
diffEditor={false}
onOpenInEditor={props.onOpenInEditor}
onCopy={() => handleCopy(props.value ?? "")}
copied={copied}
Expand Down
23 changes: 23 additions & 0 deletions src/components/LiteEditor/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
import type { Column } from "../../utils/questdb/types"

export const truncateLongDDL = (
ddl: string,
maxLines: number = 10,
): { text: string; grayedOutLines: [number, number] | null } => {
const lines = ddl.split("\n")
if (lines.length <= maxLines) {
return { text: ddl, grayedOutLines: null }
}

const keepTop = 5
const keepBottom = 3
const topLines = lines.slice(0, keepTop)
const bottomLines = lines.slice(-keepBottom)

const indent = lines[keepTop]?.match(/^\s*/)?.[0] ?? " "
const text = [...topLines, indent + "...", ...bottomLines].join("\n")

const grayStartLine = keepTop - 1
const grayEndLine = keepTop + 1

return { text, grayedOutLines: [grayStartLine, grayEndLine] }
}

export const hideColumnsFromTableDDL = (
ddl: string,
columns: Column[],
Expand Down
8 changes: 5 additions & 3 deletions src/components/TopBar/toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const EnvIconWrapper = styled.div<{ $background?: string }>`
`

const Root = styled(Box).attrs({ align: "center" })`
gap: 1.5rem;
gap: 0.8rem;
padding-left: 1.5rem;
white-space: nowrap;
display: flex;
Expand Down Expand Up @@ -554,7 +554,9 @@ export const Toolbar = () => {
return (
<Root>
<Box gap="0.5rem">
<Text color="foreground">Web Console</Text>
<Text color="foreground" margin="0 1rem 0 0">
Web Console
</Text>
{settings["release.type"] === "EE" && (
<IconWithTooltip
icon={<EnterpriseBadge>EE</EnterpriseBadge>}
Expand Down Expand Up @@ -631,7 +633,7 @@ export const Toolbar = () => {
)}
</Badge>
)}
<Box gap="0.5rem">
<Box gap="0.8rem">
{settings["acl.enabled"] && currentUser && (
<User>
<UserIcon size="18px" />
Expand Down
46 changes: 37 additions & 9 deletions src/js/console/grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ const hashString = (str) => {
return new Uint32Array([hash])[0].toString(36)
}

const COPY_ICON_SVG =
'<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">' +
'<path d="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1.001 1.001 0 0 1 3 21l.003-14c0-.552.45-1 1.007-1H7zM5.003 8 5 20h10V8H5.003zM9 6h8v10h2V4H9v2z"></path>' +
"</svg>"

const CHECK_ICON_SVG =
'<svg width="10" height="10" viewBox="0 0 24 24" fill="#50fa7b" xmlns="http://www.w3.org/2000/svg" style="position:absolute;top:0;right:0;transform:translate(25%,-25%)">' +
'<path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-.997-6 7.07-7.071-1.414-1.414-5.656 5.657-2.829-2.829-1.414 1.414L11.003 16z"></path>' +
"</svg>"

export function grid(rootElement, _paginationFn, id) {
const defaults = {
gridID: "qdb-grid",
Expand Down Expand Up @@ -519,13 +529,18 @@ export function grid(rootElement, _paginationFn, id) {
}
}

function triggerHeaderClick(e) {
// avoid broadcasting fat finger clicks
if (colResizeColIndex === undefined) {
triggerEvent("header.click", {
columnName: e.currentTarget.getAttribute("data-column-name"),
})
}
function headerCopyClick(e) {
e.stopPropagation()
const copyBtn = e.currentTarget
const headerEl = copyBtn.closest(".qg-header")
const columnName = headerEl.getAttribute("data-column-name")
copyToClipboard(columnName).then(undefined)
copyBtn.innerHTML = COPY_ICON_SVG + CHECK_ICON_SVG
addClass(copyBtn, "qg-header-copy-active")
setTimeout(() => {
copyBtn.innerHTML = COPY_ICON_SVG
removeClass(copyBtn, "qg-header-copy-active")
}, 2000)
}

function colResizeClearTimer() {
Expand Down Expand Up @@ -984,9 +999,19 @@ export function grid(rootElement, _paginationFn, id) {

const hBorderSpan = document.createElement("span")
addClass(hBorderSpan, "qg-header-border")

const copyBtn = document.createElement("div")
addClass(copyBtn, "qg-header-copy")
copyBtn.innerHTML = COPY_ICON_SVG
copyBtn.onclick = headerCopyClick

const hNameRow = document.createElement("div")
addClass(hNameRow, "qg-header-name-row")
hNameRow.append(hName, copyBtn)

h.append(hysteresis, hBorderSpan)
h.append(hName, hType)
h.onclick = triggerHeaderClick
h.append(hNameRow, hType)

header.append(h)
}

Expand Down Expand Up @@ -1093,6 +1118,7 @@ export function grid(rootElement, _paginationFn, id) {
focusedCell = cell
focusedColumnIndex = cell.columnIndex
renderFocusedCell()
triggerEvent("selection.change", { hasSelection: true })
}
}

Expand Down Expand Up @@ -2230,6 +2256,7 @@ export function grid(rootElement, _paginationFn, id) {

function setData(_data) {
initialFocusSkipped = false
triggerEvent("selection.change", { hasSelection: false })
setTimeout(() => {
setDataPart1(_data)
// This part of the update sequence requires layoutStore access.
Expand Down Expand Up @@ -2287,6 +2314,7 @@ export function grid(rootElement, _paginationFn, id) {
setBothRowsInactive()
focusedRowIndex = -1
focusedColumnIndex = -1
triggerEvent("selection.change", { hasSelection: false })
}
})

Expand Down
1 change: 0 additions & 1 deletion src/modules/EventBus/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export enum EventType {
MSG_ACTIVE_SIDEBAR = "active.panel",
MSG_EDITOR_FOCUS = "editor.focus",
MSG_EDITOR_INSERT_COLUMN = "editor.insert.column",
GRID_FOCUS = "grid.focus",
MSG_CHART_DRAW = "chart.draw",
MSG_QUERY_CANCEL = "query.in.cancel",
Expand Down
4 changes: 2 additions & 2 deletions src/scenes/Editor/ButtonBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ const ButtonBarWrapper = styled.div<{
${({ $searchWidgetType }) => css`
position: absolute;
top: ${$searchWidgetType === "replace"
? "8.2rem"
? "calc(8.2rem + 8px)"
: $searchWidgetType === "find"
? "5.3rem"
? "calc(5.3rem + 8px)"
: "1rem"};
right: 2.4rem;
z-index: 1;
Expand Down
15 changes: 15 additions & 0 deletions src/scenes/Editor/Monaco/editor-addons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,21 @@ export const registerEditorActions = ({
}

export const registerLanguageAddons = (monaco: Monaco) => {
monaco.editor.addKeybindingRules([
{ keybinding: 0, command: "-editor.action.formatDocument" },
{ keybinding: 0, command: "-editor.action.formatSelection" },
{
keybinding: monaco.KeyMod.Alt | monaco.KeyMod.Shift | monaco.KeyCode.KeyF,
command: "editor.action.formatDocument",
when: "editorTextFocus",
},
{
keybinding: monaco.KeyMod.Alt | monaco.KeyCode.KeyF,
command: "editor.action.formatSelection",
when: "editorTextFocus",
},
])

monaco.languages.register({ id: QuestDBLanguageName })

monaco.languages.setMonarchTokensProvider(
Expand Down
38 changes: 36 additions & 2 deletions src/scenes/Editor/Monaco/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ const MonacoEditor = ({ hidden = false }: { hidden?: boolean }) => {
setTabsDisabled,
editorRef,
monacoRef,
insertTextAtCursor,
activeBuffer,
updateBuffer,
editorReadyTrigger,
Expand Down Expand Up @@ -854,7 +853,6 @@ const MonacoEditor = ({ hidden = false }: { hidden?: boolean }) => {
cleanupActionsRef.current.push(
registerLegacyEventBusEvents({
editor,
insertTextAtCursor,
toggleRunning,
}),
)
Expand All @@ -877,6 +875,42 @@ const MonacoEditor = ({ hidden = false }: { hidden?: boolean }) => {
}),
)

// Prevent context menu from being clipped
const containerDomNode = editor.getContainerDomNode()
const contextMenuObserver = new MutationObserver((mutations) => {
for (const mutation of mutations) {
for (const node of Array.from(mutation.addedNodes)) {
if (
node instanceof HTMLElement &&
node.classList.contains("context-view") &&
node.classList.contains("monaco-menu-container")
) {
const rect = node.getBoundingClientRect()
node.style.position = "fixed"
node.style.left = `${rect.left}px`
node.style.top = `${rect.top}px`

// Monaco reuses the node on subsequent opens, resetting styles.
const styleObserver = new MutationObserver(() => {
if (node.style.position !== "fixed") {
const rect = node.getBoundingClientRect()
node.style.position = "fixed"
node.style.left = `${rect.left}px`
node.style.top = `${rect.top}px`
}
})
styleObserver.observe(node, {
attributes: true,
attributeFilter: ["style"],
})
cleanupActionsRef.current.push(() => styleObserver.disconnect())
}
}
}
})
contextMenuObserver.observe(containerDomNode, { childList: true })
cleanupActionsRef.current.push(() => contextMenuObserver.disconnect())

editor.onDidChangeCursorPosition((e) => {
// To ensure the fixed position of the "run query" glyph we adjust the width of the line count element.
// This width is represented in char numbers.
Expand Down
9 changes: 0 additions & 9 deletions src/scenes/Editor/Monaco/legacy-event-bus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,11 @@ import { RunningType } from "../../../store/Query/types"

export const registerLegacyEventBusEvents = ({
editor,
insertTextAtCursor,
toggleRunning,
}: {
editor: editor.IStandaloneCodeEditor
insertTextAtCursor: (text: string) => void
toggleRunning: (runningType?: RunningType) => void
}) => {
eventBus.subscribe<string>(EventType.MSG_EDITOR_INSERT_COLUMN, (column) => {
if (column) {
insertTextAtCursor(column)
}
})

eventBus.subscribe<{ query: string; options?: AppendQueryOptions }>(
EventType.MSG_QUERY_FIND_N_EXEC,
(payload) => {
Expand Down Expand Up @@ -69,7 +61,6 @@ export const registerLegacyEventBusEvents = ({
})

return () => {
eventBus.unsubscribe(EventType.MSG_EDITOR_INSERT_COLUMN)
eventBus.unsubscribe(EventType.MSG_QUERY_FIND_N_EXEC)
eventBus.unsubscribe(EventType.MSG_QUERY_EXEC)
eventBus.unsubscribe(EventType.MSG_EDITOR_FOCUS)
Expand Down
Loading
Loading