Skip to content

Commit 92c12b3

Browse files
authored
Merge pull request #347 from samueldurantes/feat/sql
feat: allow format sql code
2 parents c1c2189 + 998ce69 commit 92c12b3

File tree

5 files changed

+139
-8
lines changed

5 files changed

+139
-8
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Menu } from '@headlessui/react'
2+
import { CodeBracketIcon } from '@heroicons/react/20/solid'
3+
import { useRef } from 'react'
4+
import { TooltipV2 } from '../Tooltips'
5+
6+
interface Props {
7+
onFormat: () => void
8+
disabled: boolean
9+
}
10+
11+
function FormatSQLButton(props: Props) {
12+
const buttonRef = useRef<HTMLButtonElement>(null)
13+
14+
return (
15+
<Menu as="div" className="inline-block">
16+
{({ open }) => {
17+
return (
18+
<>
19+
<TooltipV2<HTMLButtonElement>
20+
message="Format and structure your SQL code for better readability."
21+
referenceRef={buttonRef}
22+
active={!open}
23+
>
24+
{(ref) => (
25+
<Menu.Button
26+
ref={ref}
27+
className="rounded-sm border border-gray-200 h-6 min-w-6 flex items-center justify-center relative group hover:bg-gray-50"
28+
onClick={props.onFormat}
29+
disabled={props.disabled}
30+
>
31+
<CodeBracketIcon className="w-3 h-3 text-gray-400 group-hover:text-gray-500" />
32+
</Menu.Button>
33+
)}
34+
</TooltipV2>
35+
</>
36+
)
37+
}}
38+
</Menu>
39+
)
40+
}
41+
42+
export default FormatSQLButton

apps/web/src/components/v2Editor/customBlocks/sql/index.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
AITasks,
3434
isExecutionStatusLoading,
3535
AddBlockGroupBlock,
36+
getSQLCodeFormatted,
3637
} from '@briefer/editor'
3738
import SQLResult from './SQLResult'
3839
import type {
@@ -56,6 +57,7 @@ import LargeSpinner from '@/components/LargeSpinner'
5657
import { APIDataSources } from '@/hooks/useDatasources'
5758
import { useRouter } from 'next/router'
5859
import HiddenInPublishedButton from '../../HiddenInPublishedButton'
60+
import FormatSQLButton from '../../FormatSQLButton'
5961
import useEditorAwareness from '@/hooks/useEditorAwareness'
6062
import { useWorkspaces } from '@/hooks/useWorkspaces'
6163
import useProperties from '@/hooks/useProperties'
@@ -440,6 +442,17 @@ function SQLBlock(props: Props) {
440442
router.push(`/workspaces/${props.document.workspaceId}/data-sources`)
441443
}, [router, props.document.workspaceId])
442444

445+
const onToggleFormatSQLCode = useCallback(() => {
446+
const sqlCodeFormatted = getSQLCodeFormatted(source)
447+
448+
if (!sqlCodeFormatted) {
449+
return
450+
}
451+
452+
// Reuse the `EditWithAIForm` component to show the formatted SQL code
453+
props.block.setAttribute('aiSuggestions', sqlCodeFormatted)
454+
}, [source, props.block])
455+
443456
const onToggleIsBlockHiddenInPublished = useCallback(() => {
444457
props.onToggleIsBlockHiddenInPublished(blockId)
445458
}, [props.onToggleIsBlockHiddenInPublished, blockId])
@@ -1136,7 +1149,6 @@ function SQLBlock(props: Props) {
11361149
</button>
11371150
)}
11381151
</TooltipV2>
1139-
11401152
{!props.dashboardMode && (
11411153
<HiddenInPublishedButton
11421154
isBlockHiddenInPublished={props.isBlockHiddenInPublished}
@@ -1159,6 +1171,14 @@ function SQLBlock(props: Props) {
11591171
/>
11601172
)}
11611173

1174+
{((result && !isResultHidden) || !isCodeHidden) &&
1175+
!props.dashboardMode && (
1176+
<FormatSQLButton
1177+
onFormat={onToggleFormatSQLCode}
1178+
disabled={!props.isEditable}
1179+
/>
1180+
)}
1181+
11621182
{((result && !isResultHidden) || !isCodeHidden) &&
11631183
dataSource?.config.type === 'athena' && (
11641184
<SQLQueryConfigurationButton

packages/editor/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@
1616
"moduleNameMapper": {
1717
"^(\\.\\.?\\/.+)\\.jsx?$": "$1"
1818
},
19-
"modulePathIgnorePatterns": ["<rootDir>/dist/"]
19+
"modulePathIgnorePatterns": [
20+
"<rootDir>/dist/"
21+
]
2022
},
2123
"dependencies": {
2224
"@briefer/types": "*",
2325
"fast-diff": "^1.3.0",
2426
"ramda": "^0.29.1",
2527
"react-grid-layout": "^1.4.4",
28+
"sql-formatter": "^15.4.11",
2629
"uuid": "^9.0.1",
2730
"yjs": "^13.6.14"
2831
},

packages/editor/src/blocks/sql.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
} from './index.js'
1616
import { ResultStatus, updateYText } from '../index.js'
1717
import { clone } from 'ramda'
18+
import { format as formatSQL } from 'sql-formatter'
1819

1920
export type DataframeName = {
2021
value: string
@@ -148,8 +149,8 @@ export function duplicateSQLBlock(
148149
source: duplicateYText(prevAttributes.source),
149150
dataframeName: clone(prevAttributes.dataframeName),
150151
dataSourceId: prevAttributes.dataSourceId
151-
? options?.datasourceMap?.get(prevAttributes.dataSourceId) ??
152-
prevAttributes.dataSourceId
152+
? (options?.datasourceMap?.get(prevAttributes.dataSourceId) ??
153+
prevAttributes.dataSourceId)
153154
: null,
154155
isFileDataSource: prevAttributes.isFileDataSource,
155156
result: options?.noState ? null : clone(prevAttributes.result),
@@ -283,7 +284,7 @@ export function closeSQLEditWithAIPrompt(
283284
block: Y.XmlElement<SQLBlock>,
284285
cleanPrompt: boolean
285286
) {
286-
const opeartion = () => {
287+
const operation = () => {
287288
const prompt = getSQLBlockEditWithAIPrompt(block)
288289
if (cleanPrompt) {
289290
prompt.delete(0, prompt.length)
@@ -293,9 +294,9 @@ export function closeSQLEditWithAIPrompt(
293294
}
294295

295296
if (block.doc) {
296-
block.doc.transact(opeartion)
297+
block.doc.transact(operation)
297298
} else {
298-
opeartion()
299+
operation()
299300
}
300301
}
301302

@@ -352,3 +353,16 @@ export function getSQLBlockErrorMessage(
352353
return null
353354
}
354355
}
356+
357+
export function getSQLCodeFormatted(source: Y.Text) {
358+
if (!source.length) {
359+
return null
360+
}
361+
362+
const formatted = formatSQL(source.toString(), {
363+
language: 'sql',
364+
tabWidth: 4,
365+
})
366+
367+
return new Y.Text(formatted)
368+
}

yarn.lock

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5982,7 +5982,7 @@ command-line-usage@^7.0.0:
59825982
table-layout "^4.1.0"
59835983
typical "^7.1.1"
59845984

5985-
commander@2, commander@^2.15.1:
5985+
commander@2, commander@^2.15.1, commander@^2.19.0:
59865986
version "2.20.3"
59875987
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
59885988
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -6811,6 +6811,11 @@ dir-glob@^3.0.1:
68116811
dependencies:
68126812
path-type "^4.0.0"
68136813

6814+
6815+
version "1.0.0"
6816+
resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
6817+
integrity sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==
6818+
68146819
dlv@^1.1.3:
68156820
version "1.1.3"
68166821
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
@@ -8294,6 +8299,11 @@ get-package-type@^0.1.0:
82948299
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
82958300
integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
82968301

8302+
get-stdin@=8.0.0:
8303+
version "8.0.0"
8304+
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53"
8305+
integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==
8306+
82978307
get-stream@^6.0.0, get-stream@^6.0.1:
82988308
version "6.0.1"
82998309
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
@@ -10751,6 +10761,11 @@ monaco-editor@^0.47.0:
1075110761
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.47.0.tgz#39865d67e0c9fb8c6b49e760bf9caf6a6650d28e"
1075210762
integrity sha512-VabVvHvQ9QmMwXu4du008ZDuyLnHs9j7ThVFsiJoXSOQk18+LF89N4ADzPbFenm0W4V2bGHnFBztIRQTgBfxzw==
1075310763

10764+
moo@^0.5.0:
10765+
version "0.5.2"
10766+
resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.2.tgz#f9fe82473bc7c184b0d32e2215d3f6e67278733c"
10767+
integrity sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==
10768+
1075410769
mouse-change@^1.4.0:
1075510770
version "1.4.0"
1075610771
resolved "https://registry.yarnpkg.com/mouse-change/-/mouse-change-1.4.0.tgz#c2b77e5bfa34a43ce1445c8157a4e4dc9895c14f"
@@ -10850,6 +10865,16 @@ natural-compare@^1.4.0:
1085010865
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
1085110866
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
1085210867

10868+
nearley@^2.20.1:
10869+
version "2.20.1"
10870+
resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.20.1.tgz#246cd33eff0d012faf197ff6774d7ac78acdd474"
10871+
integrity sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==
10872+
dependencies:
10873+
commander "^2.19.0"
10874+
moo "^0.5.0"
10875+
railroad-diagrams "^1.0.0"
10876+
randexp "0.4.6"
10877+
1085310878
needle@^2.5.2:
1085410879
version "2.9.1"
1085510880
resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684"
@@ -12351,11 +12376,24 @@ raf@^3.4.1:
1235112376
dependencies:
1235212377
performance-now "^2.1.0"
1235312378

12379+
railroad-diagrams@^1.0.0:
12380+
version "1.0.0"
12381+
resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
12382+
integrity sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==
12383+
1235412384
ramda@^0.29.1:
1235512385
version "0.29.1"
1235612386
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.29.1.tgz#408a6165b9555b7ba2fc62555804b6c5a2eca196"
1235712387
integrity sha512-OfxIeWzd4xdUNxlWhgFazxsA/nl3mS4/jGZI5n00uWOoSSFRhC1b6gl6xvmzUamgmqELraWp0J/qqVlXYPDPyA==
1235812388

12389+
12390+
version "0.4.6"
12391+
resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3"
12392+
integrity sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==
12393+
dependencies:
12394+
discontinuous-range "1.0.0"
12395+
ret "~0.1.10"
12396+
1235912397
range-parser@~1.2.1:
1236012398
version "1.2.1"
1236112399
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
@@ -12902,6 +12940,11 @@ resolve@^2.0.0-next.3, resolve@^2.0.0-next.5:
1290212940
path-parse "^1.0.7"
1290312941
supports-preserve-symlinks-flag "^1.0.0"
1290412942

12943+
ret@~0.1.10:
12944+
version "0.1.15"
12945+
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
12946+
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
12947+
1290512948
retry-request@^7.0.0:
1290612949
version "7.0.2"
1290712950
resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-7.0.2.tgz#60bf48cfb424ec01b03fca6665dee91d06dd95f3"
@@ -13370,6 +13413,15 @@ sprintf-js@~1.0.2:
1337013413
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
1337113414
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
1337213415

13416+
sql-formatter@^15.4.11:
13417+
version "15.4.11"
13418+
resolved "https://registry.yarnpkg.com/sql-formatter/-/sql-formatter-15.4.11.tgz#10a8205aa82d60507811360d4735e81d4a21c137"
13419+
integrity sha512-AfIjH0mYxv0NVzs4mbcGIAcos2Si20LeF9GMk0VmVA4A3gs1PFIixVu3rtcz34ls7ghPAjrDb+XbRly/aF6HAg==
13420+
dependencies:
13421+
argparse "^2.0.1"
13422+
get-stdin "=8.0.0"
13423+
nearley "^2.20.1"
13424+
1337313425
ssh2@^1.15.0:
1337413426
version "1.16.0"
1337513427
resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.16.0.tgz#79221d40cbf4d03d07fe881149de0a9de928c9f0"

0 commit comments

Comments
 (0)