Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Syntax Highlighting for SQL Input #373

Merged
merged 18 commits into from
Jun 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
d7f2042
First pass at adding sql syntax highlighting. It's somewhat close, bu…
Jun 7, 2022
30dc25f
Got the new component wired up to the form correctly. Next step is to…
Jun 8, 2022
3e8a3fe
Refactored the implementation a bit to make things a bit easier to re…
Jun 8, 2022
09d719f
Cleaning up the old implementation. I commited it in the last push ju…
Jun 8, 2022
64b8146
Fixed a type issue by renaming the 'value' prop in SqlTextArea to 'ex…
Jun 8, 2022
2fddfc8
Added the SqlTextArea component to the MetricForm, and refactored the…
Jun 8, 2022
f630805
Added the SqlTextArea component to be consumed by the EditDataSourceS…
Jun 8, 2022
a9af614
Cleaning up the prop name so it's the proper case.
Jun 8, 2022
67466e4
Forgot to remove a prop that is no longer being used from the Field c…
Jun 8, 2022
66e06c7
Cleaned up some language and casing.
Jun 8, 2022
32d0284
Renamed the component from sqlTextArea to codeTextArea and added supp…
Jun 9, 2022
113b30f
Updated EditDataSourceSettingsForm to support a Python textarea. Also…
Jun 9, 2022
c516096
Refactored so instead of the Field component rendering CodeTextArea t…
Jun 10, 2022
0f46ad1
Added back python placeholder text that I accidentally omitted. Also …
Jun 10, 2022
a7cc11e
Updated the label so it matched what was previously in production.
Jun 10, 2022
860c1d8
Addressed the first level of feedback from Jeremy. Still haven't figu…
Jun 10, 2022
20cf4cc
Updated the CodeTextArea so we only use the dynamic import once.
Jun 10, 2022
f4bd0bb
Adding placeholder back in as a destructured prop to CodeTextArea and…
Jun 10, 2022
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
36 changes: 22 additions & 14 deletions packages/front-end/components/Dimensions/DimensionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DimensionInterface } from "back-end/types/dimension";
import { useDefinitions } from "../../services/DefinitionsContext";
import Field from "../Forms/Field";
import SelectField from "../Forms/SelectField";
import CodeTextArea from "../Forms/CodeTextArea";

const DimensionForm: FC<{
close: () => void;
Expand Down Expand Up @@ -88,24 +89,31 @@ const DimensionForm: FC<{
})}
/>
)}
<Field
label={sql ? "SQL" : "Event Property"}
required
{...form.register("sql")}
textarea
minRows={3}
placeholder={
sql ? `SELECT ${userIdType}, browser as value FROM users` : "$browser"
}
helpText={
sql ? (
{sql ? (
<CodeTextArea
label="SQL"
required
language="sql"
value={form.watch("sql")}
setValue={(sql) => form.setValue("sql", sql)}
placeholder={`SELECT\n ${userIdType}, browser as value\nFROM\n users`}
helpText={
<>
Select two columns named <code>{userIdType}</code> and{" "}
<code>value</code>
</>
) : null
}
/>
}
/>
) : (
<Field
label="Event Condition"
required
{...form.register("sql")}
textarea
minRows={3}
placeholder={"$browser"}
/>
)}
<p>
<strong>Important:</strong> Please limit dimensions to at most 50 unique
values.
Expand Down
64 changes: 64 additions & 0 deletions packages/front-end/components/Forms/CodeTextArea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from "react";
import Field, { FieldProps } from "./Field";
import dynamic from "next/dynamic";
const AceEditor = dynamic(
async () => {
const reactAce = await import("react-ace");
await import("ace-builds/src-min-noconflict/ext-language_tools");
await import("ace-builds/src-noconflict/mode-sql");
await import("ace-builds/src-noconflict/mode-javascript");
await import("ace-builds/src-noconflict/mode-python");
await import("ace-builds/src-noconflict/mode-yaml");
await import("ace-builds/src-noconflict/mode-json");
await import("ace-builds/src-noconflict/theme-textmate");

return reactAce;
},
{
ssr: false, // react-ace doesn't support server side rendering as it uses the window object.
}
);

export type Language = "sql" | "json" | "javascript" | "python" | "yml";

export type Props = Omit<
FieldProps,
"value" | "onChange" | "options" | "multi" | "initialOption"
> & {
language: Language;
value: string;
setValue: (value: string) => void;
};

export default function CodeTextArea({
language,
value,
setValue,
placeholder,
...otherProps
mknowlton89 marked this conversation as resolved.
Show resolved Hide resolved
}: Props) {
// eslint-disable-next-line
const fieldProps = otherProps as any;

return (
<Field
{...fieldProps}
render={(id) => {
return (
<div className="border rounded">
<AceEditor
name={id}
mode={language}
theme="textmate"
width="inherit"
height="140px"
value={value}
onChange={(newValue) => setValue(newValue)}
placeholder={placeholder}
/>
</div>
);
}}
/>
);
}
16 changes: 8 additions & 8 deletions packages/front-end/components/Metrics/MetricForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Field from "../Forms/Field";
import SelectField from "../Forms/SelectField";
import { getInitialMetricQuery } from "../../services/datasources";
import MultiSelectField from "../Forms/MultiSelectField";
import CodeTextArea from "../Forms/CodeTextArea";

const weekAgo = new Date();
weekAgo.setDate(weekAgo.getDate() - 7);
Expand Down Expand Up @@ -467,16 +468,15 @@ const MetricForm: FC<MetricFormProps> = ({
)}
label="Identifier Types Supported"
/>
<Field
<CodeTextArea
label="SQL"
textarea
{...form.register("sql")}
minRows={8}
maxRows={20}
placeholder="SELECT ..."
autoFocus
required
minLength={15}
language="sql"
value={form.watch("sql")}
setValue={(sql) => form.setValue("sql", sql)}
placeholder={
"SELECT\n user_id as user_id, timestamp as timestamp\nFROM\n test"
}
/>
{value.type !== "binomial" && (
<Field
Expand Down
40 changes: 24 additions & 16 deletions packages/front-end/components/Segments/SegmentForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useAuth } from "../../services/auth";
import { useDefinitions } from "../../services/DefinitionsContext";
import Field from "../Forms/Field";
import SelectField from "../Forms/SelectField";
import CodeTextArea from "../../components/Forms/CodeTextArea";

const SegmentForm: FC<{
close: () => void;
Expand Down Expand Up @@ -85,30 +86,37 @@ const SegmentForm: FC<{
})}
/>
)}
<Field
label={sql ? "SQL" : "Event Condition"}
required
textarea
{...form.register("sql")}
placeholder={
sql
? `SELECT ${userIdType}, date FROM mytable`
: "event.properties.$browser === 'Chrome'"
}
helpText={
sql ? (
{sql ? (
mknowlton89 marked this conversation as resolved.
Show resolved Hide resolved
<CodeTextArea
label="SQL"
required
language="sql"
value={form.watch("sql")}
setValue={(sql) => form.setValue("sql", sql)}
placeholder={`SELECT\n ${userIdType}, date\nFROM\n mytable`}
helpText={
<>
Select two columns named <code>{userIdType}</code> and{" "}
<code>date</code>
</>
) : (
}
/>
) : (
<Field
label="Event Condition"
required
{...form.register("sql")}
textarea
minRows={3}
placeholder={"event.properties.$browser === 'Chrome'"}
helpText={
<>
Javascript condition used to filter events. Has access to an{" "}
<code>event</code> variable.
</>
)
}
/>
}
/>
)}
</Modal>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useFieldArray, useForm } from "react-hook-form";
import StringArrayField from "../Forms/StringArrayField";
import uniqid from "uniqid";
import MultiSelectField from "../Forms/MultiSelectField";
import CodeTextArea from "../Forms/CodeTextArea";

const EditDataSourceSettingsForm: FC<{
data: Partial<DataSourceInterfaceWithParams>;
Expand Down Expand Up @@ -254,17 +255,20 @@ const EditDataSourceSettingsForm: FC<{
</div>
<div className="row">
<div className="col">
<Field
<CodeTextArea
label="SQL Query"
textarea
minRows={10}
maxRows={20}
required
{...form.register(
language="sql"
value={form.watch(
`settings.queries.exposure.${i}.query`
)}
setValue={(sql) =>
form.setValue(
`settings.queries.exposure.${i}.query`,
sql
)
}
/>

<StringArrayField
label="Dimension Columns"
value={form.watch(
Expand Down Expand Up @@ -389,15 +393,18 @@ const EditDataSourceSettingsForm: FC<{
</div>
<div className="row">
<div className="col">
<Field
<CodeTextArea
label="SQL Query"
textarea
minRows={10}
maxRows={20}
required
{...form.register(
language="sql"
value={form.watch(
`settings.queries.identityJoins.${i}.query`
)}
setValue={(sql) =>
form.setValue(
`settings.queries.identityJoins.${i}.query`,
sql
)
}
/>
</div>
<div className="col-md-5 col-lg-4">
Expand Down Expand Up @@ -444,13 +451,14 @@ const EditDataSourceSettingsForm: FC<{
<div className="bg-light border my-2 p-3 ml-3">
<div className="row mb-3">
<div className="col">
<Field
<CodeTextArea
label="Python runQuery definition"
language="python"
placeholder="def runQuery(sql):"
{...form.register("settings.notebookRunQuery")}
textarea
minRows={5}
maxRows={20}
value={form.watch(`settings.notebookRunQuery`)}
setValue={(python) =>
form.setValue(`settings.notebookRunQuery`, python)
}
helpText="Used when exporting experiment results to a Jupyter notebook"
/>
</div>
Expand Down
2 changes: 2 additions & 0 deletions packages/front-end/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@visx/stats": "^2.1.0",
"@visx/tooltip": "^2.1.0",
"@webscopeio/react-textarea-autocomplete": "^4.7.3",
"ace-builds": "^1.5.3",
"back-end": "0.0.1",
"bootstrap": "^4.5.0",
"clsx": "^1.1.1",
Expand All @@ -43,6 +44,7 @@
"md5": "^2.3.0",
"next": "^10.2.0",
"react": "^17.0.1",
"react-ace": "^10.1.0",
"react-beautiful-dnd": "^13.1.0",
"react-bootstrap-typeahead": "^5.0.0-rc.3",
"react-colorful": "^5.3.0",
Expand Down
31 changes: 31 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3291,6 +3291,11 @@ accepts@~1.3.5, accepts@~1.3.7:
mime-types "~2.1.24"
negotiator "0.6.2"

ace-builds@^1.4.14, ace-builds@^1.5.3:
version "1.5.3"
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.5.3.tgz#05f81d3464a9ea19696e5e6fd0f924d37dab442f"
integrity sha512-WN5BKR2aTSuBmisO8jo3Fytk6sOmJGki82v/Boeic81IgYN8pFHNkXq2anDF0XkmfDWMqLbRoW9sjc/GtKzQbQ==

acorn-globals@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45"
Expand Down Expand Up @@ -5350,6 +5355,11 @@ didyoumean@^1.2.1:
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff"
integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8=

diff-match-patch@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37"
integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==

diff-sequences@^27.0.6:
version "27.0.6"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723"
Expand Down Expand Up @@ -8539,6 +8549,11 @@ lodash.debounce@^4.0.8:
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=

lodash.get@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==

lodash.includes@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
Expand All @@ -8549,6 +8564,11 @@ lodash.isboolean@^3.0.3:
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=

lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==

lodash.isinteger@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
Expand Down Expand Up @@ -10756,6 +10776,17 @@ [email protected]:
iconv-lite "0.4.24"
unpipe "1.0.0"

react-ace@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-10.1.0.tgz#d348eac2b16475231779070b6cd16768deed565f"
integrity sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==
dependencies:
ace-builds "^1.4.14"
diff-match-patch "^1.0.5"
lodash.get "^4.4.2"
lodash.isequal "^4.5.0"
prop-types "^15.7.2"

react-beautiful-dnd@^13.1.0:
version "13.1.0"
resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.0.tgz#ec97c81093593526454b0de69852ae433783844d"
Expand Down