mirror of
https://github.com/rowyio/rowy.git
synced 2026-02-24 04:01:17 +01:00
consolidate CodeEditor to components/CodeEditor, allow resize, use github themes
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
"@emotion/styled": "^11.3.0",
|
||||
"@hookform/resolvers": "^2.8.1",
|
||||
"@mdi/js": "^6.2.95",
|
||||
"@monaco-editor/react": "^4.1.0",
|
||||
"@monaco-editor/react": "^4.3.1",
|
||||
"@mui/icons-material": "^5.0.0",
|
||||
"@mui/lab": "^5.0.0-alpha.50",
|
||||
"@mui/material": "^5.0.0",
|
||||
|
||||
10
src/assets/icons/ResizeBottomRight.tsx
Normal file
10
src/assets/icons/ResizeBottomRight.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import SvgIcon, { SvgIconProps } from "@mui/material/SvgIcon";
|
||||
import { mdiResizeBottomRight } from "@mdi/js";
|
||||
|
||||
export default function ResizeBottomRight(props: SvgIconProps) {
|
||||
return (
|
||||
<SvgIcon {...props}>
|
||||
<path d={mdiResizeBottomRight} />
|
||||
</SvgIcon>
|
||||
);
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
import React, { useRef, useMemo, useState } from "react";
|
||||
import clsx from "clsx";
|
||||
import Editor, { useMonaco } from "@monaco-editor/react";
|
||||
|
||||
import { makeStyles, createStyles } from "@mui/styles";
|
||||
import { useTheme } from "@mui/material";
|
||||
|
||||
import { useProjectContext } from "contexts/ProjectContext";
|
||||
|
||||
const useStyles = makeStyles((theme) =>
|
||||
createStyles({
|
||||
editorWrapper: { position: "relative" },
|
||||
resizeIcon: {
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
color: theme.palette.text.disabled,
|
||||
},
|
||||
saveButton: {
|
||||
marginTop: theme.spacing(1),
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
export interface ICodeEditorProps {
|
||||
onChange: (value: string) => void;
|
||||
value: string;
|
||||
height?: number;
|
||||
wrapperProps?: Partial<React.HTMLAttributes<HTMLDivElement>>;
|
||||
disabled?: boolean;
|
||||
editorOptions?: any;
|
||||
}
|
||||
|
||||
export default function CodeEditor({
|
||||
onChange,
|
||||
value,
|
||||
height = 400,
|
||||
wrapperProps,
|
||||
disabled,
|
||||
editorOptions,
|
||||
}: ICodeEditorProps) {
|
||||
const theme = useTheme();
|
||||
const [initialEditorValue] = useState(value ?? "");
|
||||
const { tableState } = useProjectContext();
|
||||
const classes = useStyles();
|
||||
const monacoInstance = useMonaco();
|
||||
|
||||
const editorRef = useRef<any>();
|
||||
|
||||
function handleEditorDidMount(_, editor) {
|
||||
editorRef.current = editor;
|
||||
}
|
||||
|
||||
const themeTransformer = (theme: string) => {
|
||||
switch (theme) {
|
||||
case "dark":
|
||||
return "vs-dark";
|
||||
default:
|
||||
return theme;
|
||||
}
|
||||
};
|
||||
|
||||
useMemo(async () => {
|
||||
if (!monacoInstance) {
|
||||
// useMonaco returns a monaco instance but initialisation is done asynchronously
|
||||
// dont execute the logic until the instance is initialised
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
monacoInstance.languages.typescript.javascriptDefaults.setDiagnosticsOptions(
|
||||
{
|
||||
noSemanticValidation: true,
|
||||
noSyntaxValidation: false,
|
||||
}
|
||||
);
|
||||
// compiler options
|
||||
monacoInstance.languages.typescript.javascriptDefaults.setCompilerOptions(
|
||||
{
|
||||
target: monacoInstance.languages.typescript.ScriptTarget.ES5,
|
||||
allowNonTsExtensions: true,
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"An error occurred during initialization of Monaco: ",
|
||||
error
|
||||
);
|
||||
}
|
||||
}, [tableState?.columns]);
|
||||
|
||||
return (
|
||||
<div
|
||||
{...wrapperProps}
|
||||
className={clsx(classes.editorWrapper, wrapperProps?.className)}
|
||||
>
|
||||
<Editor
|
||||
theme={themeTransformer(theme.palette.mode)}
|
||||
height={height}
|
||||
onMount={handleEditorDidMount}
|
||||
language="javascript"
|
||||
value={initialEditorValue}
|
||||
options={{
|
||||
readOnly: disabled,
|
||||
fontFamily: theme.typography.fontFamilyMono,
|
||||
rulers: [80],
|
||||
minimap: { enabled: false },
|
||||
...editorOptions,
|
||||
}}
|
||||
onChange={onChange as any}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
97
src/components/CodeEditor/extensions.d.ts
vendored
Normal file
97
src/components/CodeEditor/extensions.d.ts
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
type Trigger = "create" | "update" | "delete";
|
||||
type Triggers = Trigger[];
|
||||
|
||||
// function types that defines extension body and should run
|
||||
type Condition =
|
||||
| boolean
|
||||
| ((data: ExtensionContext) => boolean | Promise<boolean>);
|
||||
|
||||
// the argument that the extension body takes in
|
||||
type ExtensionContext = {
|
||||
row: Row;
|
||||
ref: FirebaseFirestore.DocumentReference;
|
||||
storage: firebasestorage.Storage;
|
||||
db: FirebaseFirestore.Firestore;
|
||||
auth: adminauth.BaseAuth;
|
||||
change: any;
|
||||
triggerType: Triggers;
|
||||
fieldTypes: any;
|
||||
extensionConfig: {
|
||||
label: string;
|
||||
type: string;
|
||||
triggers: Trigger[];
|
||||
conditions: Condition;
|
||||
requiredFields: string[];
|
||||
extensionBody: any;
|
||||
};
|
||||
utilFns: any;
|
||||
};
|
||||
|
||||
// extension body definition
|
||||
type slackEmailBody = {
|
||||
channels?: string[];
|
||||
text?: string;
|
||||
emails: string[];
|
||||
blocks?: object[];
|
||||
attachments?: any;
|
||||
};
|
||||
|
||||
type slackChannelBody = {
|
||||
channels: string[];
|
||||
text?: string;
|
||||
emails?: string[];
|
||||
blocks?: object[];
|
||||
attachments?: any;
|
||||
};
|
||||
|
||||
type DocSyncBody = (context: ExtensionContext) => Promise<{
|
||||
fieldsToSync: Fields;
|
||||
row: Row;
|
||||
targetPath: string;
|
||||
}>;
|
||||
|
||||
type HistorySnapshotBody = (context: ExtensionContext) => Promise<{
|
||||
trackedFields: Fields;
|
||||
}>;
|
||||
|
||||
type AlgoliaIndexBody = (context: ExtensionContext) => Promise<{
|
||||
fieldsToSync: Fields;
|
||||
index: string;
|
||||
row: Row;
|
||||
objectID: string;
|
||||
}>;
|
||||
|
||||
type MeiliIndexBody = (context: ExtensionContext) => Promise<{
|
||||
fieldsToSync: Fields;
|
||||
index: string;
|
||||
row: Row;
|
||||
objectID: string;
|
||||
}>;
|
||||
|
||||
type BigqueryIndexBody = (context: ExtensionContext) => Promise<{
|
||||
fieldsToSync: Fields;
|
||||
index: string;
|
||||
row: Row;
|
||||
objectID: string;
|
||||
}>;
|
||||
|
||||
type SlackMessageBody = (
|
||||
context: ExtensionContext
|
||||
) => Promise<slackEmailBody | slackChannelBody>;
|
||||
|
||||
type SendgridEmailBody = (context: ExtensionContext) => Promise<any>;
|
||||
|
||||
type ApiCallBody = (context: ExtensionContext) => Promise<{
|
||||
body: string;
|
||||
url: string;
|
||||
method: string;
|
||||
callback: any;
|
||||
}>;
|
||||
|
||||
type TwilioMessageBody = (context: ExtensionContext) => Promise<{
|
||||
body: string;
|
||||
from: string;
|
||||
to: string;
|
||||
}>;
|
||||
|
||||
type TaskBody = (context: ExtensionContext) => Promise<any>;
|
||||
@@ -844,9 +844,9 @@ declare namespace FirebaseFirestore {
|
||||
* `exists` property will always be true and `data()` will never return
|
||||
* 'undefined'.
|
||||
*/
|
||||
export class QueryDocumentSnapshot<T = DocumentData> extends DocumentSnapshot<
|
||||
T
|
||||
> {
|
||||
export class QueryDocumentSnapshot<
|
||||
T = DocumentData
|
||||
> extends DocumentSnapshot<T> {
|
||||
private constructor();
|
||||
|
||||
/**
|
||||
535
src/components/CodeEditor/github-dark-default.json
Normal file
535
src/components/CodeEditor/github-dark-default.json
Normal file
@@ -0,0 +1,535 @@
|
||||
{
|
||||
"inherit": true,
|
||||
"base": "vs-dark",
|
||||
"colors": {
|
||||
"focusBorder": "#1f6feb",
|
||||
"foreground": "#c9d1d9",
|
||||
"descriptionForeground": "#8b949e",
|
||||
"errorForeground": "#f85149",
|
||||
"textLink.foreground": "#58a6ff",
|
||||
"textLink.activeForeground": "#58a6ff",
|
||||
"textBlockQuote.background": "#010409",
|
||||
"textBlockQuote.border": "#30363d",
|
||||
"textCodeBlock.background": "#6e768166",
|
||||
"textPreformat.foreground": "#8b949e",
|
||||
"textSeparator.foreground": "#21262d",
|
||||
"button.background": "#238636",
|
||||
"button.foreground": "#ffffff",
|
||||
"button.hoverBackground": "#2ea043",
|
||||
"button.secondaryBackground": "#282e33",
|
||||
"button.secondaryForeground": "#c9d1d9",
|
||||
"button.secondaryHoverBackground": "#30363d",
|
||||
"checkbox.background": "#161b22",
|
||||
"checkbox.border": "#30363d",
|
||||
"dropdown.background": "#161b22",
|
||||
"dropdown.border": "#30363d",
|
||||
"dropdown.foreground": "#c9d1d9",
|
||||
"dropdown.listBackground": "#161b22",
|
||||
"input.background": "#0d1117",
|
||||
"input.border": "#30363d",
|
||||
"input.foreground": "#c9d1d9",
|
||||
"input.placeholderForeground": "#484f58",
|
||||
"badge.foreground": "#f0f6fc",
|
||||
"badge.background": "#1f6feb",
|
||||
"progressBar.background": "#1f6feb",
|
||||
"titleBar.activeForeground": "#8b949e",
|
||||
"titleBar.activeBackground": "#0d1117",
|
||||
"titleBar.inactiveForeground": "#8b949e",
|
||||
"titleBar.inactiveBackground": "#010409",
|
||||
"titleBar.border": "#30363d",
|
||||
"activityBar.foreground": "#c9d1d9",
|
||||
"activityBar.inactiveForeground": "#8b949e",
|
||||
"activityBar.background": "#0d1117",
|
||||
"activityBarBadge.foreground": "#f0f6fc",
|
||||
"activityBarBadge.background": "#1f6feb",
|
||||
"activityBar.activeBorder": "#f78166",
|
||||
"activityBar.border": "#30363d",
|
||||
"sideBar.foreground": "#c9d1d9",
|
||||
"sideBar.background": "#010409",
|
||||
"sideBar.border": "#30363d",
|
||||
"sideBarTitle.foreground": "#c9d1d9",
|
||||
"sideBarSectionHeader.foreground": "#c9d1d9",
|
||||
"sideBarSectionHeader.background": "#010409",
|
||||
"sideBarSectionHeader.border": "#30363d",
|
||||
"list.hoverForeground": "#c9d1d9",
|
||||
"list.inactiveSelectionForeground": "#c9d1d9",
|
||||
"list.activeSelectionForeground": "#c9d1d9",
|
||||
"list.hoverBackground": "#6e76811a",
|
||||
"list.inactiveSelectionBackground": "#6e768166",
|
||||
"list.activeSelectionBackground": "#6e768166",
|
||||
"list.focusForeground": "#c9d1d9",
|
||||
"list.focusBackground": "#388bfd26",
|
||||
"list.inactiveFocusBackground": "#388bfd26",
|
||||
"list.highlightForeground": "#58a6ff",
|
||||
"tree.indentGuidesStroke": "#21262d",
|
||||
"notificationCenterHeader.foreground": "#8b949e",
|
||||
"notificationCenterHeader.background": "#161b22",
|
||||
"notifications.foreground": "#c9d1d9",
|
||||
"notifications.background": "#161b22",
|
||||
"notifications.border": "#30363d",
|
||||
"notificationsErrorIcon.foreground": "#f85149",
|
||||
"notificationsWarningIcon.foreground": "#d29922",
|
||||
"notificationsInfoIcon.foreground": "#58a6ff",
|
||||
"pickerGroup.border": "#30363d",
|
||||
"pickerGroup.foreground": "#8b949e",
|
||||
"quickInput.background": "#161b22",
|
||||
"quickInput.foreground": "#c9d1d9",
|
||||
"statusBar.foreground": "#8b949e",
|
||||
"statusBar.background": "#0d1117",
|
||||
"statusBar.border": "#30363d",
|
||||
"statusBar.noFolderBackground": "#0d1117",
|
||||
"statusBar.debuggingBackground": "#da3633",
|
||||
"statusBar.debuggingForeground": "#f0f6fc",
|
||||
"statusBarItem.prominentBackground": "#161b22",
|
||||
"editorGroupHeader.tabsBackground": "#010409",
|
||||
"editorGroupHeader.tabsBorder": "#30363d",
|
||||
"editorGroup.border": "#30363d",
|
||||
"tab.activeForeground": "#c9d1d9",
|
||||
"tab.inactiveForeground": "#8b949e",
|
||||
"tab.inactiveBackground": "#010409",
|
||||
"tab.activeBackground": "#0d1117",
|
||||
"tab.hoverBackground": "#0d1117",
|
||||
"tab.unfocusedHoverBackground": "#6e76811a",
|
||||
"tab.border": "#30363d",
|
||||
"tab.unfocusedActiveBorderTop": "#30363d",
|
||||
"tab.activeBorder": "#0d1117",
|
||||
"tab.unfocusedActiveBorder": "#0d1117",
|
||||
"tab.activeBorderTop": "#f78166",
|
||||
"breadcrumb.foreground": "#8b949e",
|
||||
"breadcrumb.focusForeground": "#c9d1d9",
|
||||
"breadcrumb.activeSelectionForeground": "#8b949e",
|
||||
"breadcrumbPicker.background": "#161b22",
|
||||
"editor.foreground": "#c9d1d9",
|
||||
"editor.background": "#0d1117",
|
||||
"editorWidget.background": "#161b22",
|
||||
"editor.foldBackground": "#6e76811a",
|
||||
"editor.lineHighlightBackground": "#6e76811a",
|
||||
"editorLineNumber.foreground": "#8b949e",
|
||||
"editorLineNumber.activeForeground": "#c9d1d9",
|
||||
"editorIndentGuide.background": "#21262d",
|
||||
"editorIndentGuide.activeBackground": "#30363d",
|
||||
"editorWhitespace.foreground": "#484f58",
|
||||
"editorCursor.foreground": "#58a6ff",
|
||||
"editor.findMatchBackground": "#ffd33d44",
|
||||
"editor.findMatchHighlightBackground": "#ffd33d22",
|
||||
"editor.linkedEditingBackground": "#3392FF22",
|
||||
"editor.inactiveSelectionBackground": "#3392FF22",
|
||||
"editor.selectionBackground": "#3392FF44",
|
||||
"editor.selectionHighlightBackground": "#17E5E633",
|
||||
"editor.selectionHighlightBorder": "#17E5E600",
|
||||
"editor.wordHighlightBackground": "#17E5E600",
|
||||
"editor.wordHighlightStrongBackground": "#17E5E600",
|
||||
"editor.wordHighlightBorder": "#17E5E699",
|
||||
"editor.wordHighlightStrongBorder": "#17E5E666",
|
||||
"editorBracketMatch.background": "#17E5E650",
|
||||
"editorBracketMatch.border": "#17E5E600",
|
||||
"editorGutter.modifiedBackground": "#bb800966",
|
||||
"editorGutter.addedBackground": "#2ea04366",
|
||||
"editorGutter.deletedBackground": "#f8514966",
|
||||
"diffEditor.insertedTextBackground": "#2ea04326",
|
||||
"diffEditor.removedTextBackground": "#f8514926",
|
||||
"scrollbar.shadow": "#0008",
|
||||
"scrollbarSlider.background": "#484F5833",
|
||||
"scrollbarSlider.hoverBackground": "#484F5844",
|
||||
"scrollbarSlider.activeBackground": "#484F5888",
|
||||
"editorOverviewRuler.border": "#010409",
|
||||
"panel.background": "#010409",
|
||||
"panel.border": "#30363d",
|
||||
"panelTitle.activeBorder": "#f78166",
|
||||
"panelTitle.activeForeground": "#c9d1d9",
|
||||
"panelTitle.inactiveForeground": "#8b949e",
|
||||
"panelInput.border": "#30363d",
|
||||
"terminal.foreground": "#8b949e",
|
||||
"terminal.ansiBlack": "#484f58",
|
||||
"terminal.ansiRed": "#ff7b72",
|
||||
"terminal.ansiGreen": "#3fb950",
|
||||
"terminal.ansiYellow": "#d29922",
|
||||
"terminal.ansiBlue": "#58a6ff",
|
||||
"terminal.ansiMagenta": "#bc8cff",
|
||||
"terminal.ansiCyan": "#39c5cf",
|
||||
"terminal.ansiWhite": "#b1bac4",
|
||||
"terminal.ansiBrightBlack": "#6e7681",
|
||||
"terminal.ansiBrightRed": "#ffa198",
|
||||
"terminal.ansiBrightGreen": "#56d364",
|
||||
"terminal.ansiBrightYellow": "#e3b341",
|
||||
"terminal.ansiBrightBlue": "#79c0ff",
|
||||
"terminal.ansiBrightMagenta": "#d2a8ff",
|
||||
"terminal.ansiBrightCyan": "#56d4dd",
|
||||
"terminal.ansiBrightWhite": "#f0f6fc",
|
||||
"gitDecoration.addedResourceForeground": "#3fb950",
|
||||
"gitDecoration.modifiedResourceForeground": "#d29922",
|
||||
"gitDecoration.deletedResourceForeground": "#f85149",
|
||||
"gitDecoration.untrackedResourceForeground": "#3fb950",
|
||||
"gitDecoration.ignoredResourceForeground": "#484f58",
|
||||
"gitDecoration.conflictingResourceForeground": "#db6d28",
|
||||
"gitDecoration.submoduleResourceForeground": "#8b949e",
|
||||
"debugToolBar.background": "#161b22",
|
||||
"editor.stackFrameHighlightBackground": "#D2992225",
|
||||
"editor.focusedStackFrameHighlightBackground": "#3FB95025",
|
||||
"peekViewEditor.matchHighlightBackground": "#ffd33d33",
|
||||
"peekViewResult.matchHighlightBackground": "#ffd33d33",
|
||||
"peekViewEditor.background": "#0d111788",
|
||||
"peekViewResult.background": "#0d1117",
|
||||
"settings.headerForeground": "#8b949e",
|
||||
"settings.modifiedItemIndicator": "#bb800966",
|
||||
"welcomePage.buttonBackground": "#21262d",
|
||||
"welcomePage.buttonHoverBackground": "#30363d"
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"foreground": "#8b949e",
|
||||
"token": "comment"
|
||||
},
|
||||
{
|
||||
"foreground": "#8b949e",
|
||||
"token": "punctuation.definition.comment"
|
||||
},
|
||||
{
|
||||
"foreground": "#8b949e",
|
||||
"token": "string.comment"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "constant"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "entity.name.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "variable.other.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "variable.language"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "entity"
|
||||
},
|
||||
{
|
||||
"foreground": "#ffa657",
|
||||
"token": "entity.name"
|
||||
},
|
||||
{
|
||||
"foreground": "#ffa657",
|
||||
"token": "meta.export.default"
|
||||
},
|
||||
{
|
||||
"foreground": "#ffa657",
|
||||
"token": "meta.definition.variable"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "variable.parameter.function"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "meta.jsx.children"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "meta.block"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "meta.tag.attributes"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "entity.name.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "meta.object.member"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "meta.embedded.expression"
|
||||
},
|
||||
{
|
||||
"foreground": "#d2a8ff",
|
||||
"token": "entity.name.function"
|
||||
},
|
||||
{
|
||||
"foreground": "#7ee787",
|
||||
"token": "entity.name.tag"
|
||||
},
|
||||
{
|
||||
"foreground": "#7ee787",
|
||||
"token": "support.class.component"
|
||||
},
|
||||
{
|
||||
"foreground": "#ff7b72",
|
||||
"token": "keyword"
|
||||
},
|
||||
{
|
||||
"foreground": "#ff7b72",
|
||||
"token": "storage"
|
||||
},
|
||||
{
|
||||
"foreground": "#ff7b72",
|
||||
"token": "storage.type"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "storage.modifier.package"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "storage.modifier.import"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "storage.type.java"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"token": "string"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"token": "punctuation.definition.string"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"token": "string punctuation.section.embedded source"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "support"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "meta.property-name"
|
||||
},
|
||||
{
|
||||
"foreground": "#ffa657",
|
||||
"token": "variable"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "variable.other"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#ffa198",
|
||||
"token": "invalid.broken"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#ffa198",
|
||||
"token": "invalid.deprecated"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#ffa198",
|
||||
"token": "invalid.illegal"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#ffa198",
|
||||
"token": "invalid.unimplemented"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic underline",
|
||||
"background": "#ff7b72",
|
||||
"foreground": "#0d1117",
|
||||
"content": "^M",
|
||||
"token": "carriage-return"
|
||||
},
|
||||
{
|
||||
"foreground": "#ffa198",
|
||||
"token": "message.error"
|
||||
},
|
||||
{
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "string source"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "string variable"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"token": "source.regexp"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"token": "string.regexp"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"token": "string.regexp.character-class"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"token": "string.regexp constant.character.escape"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"token": "string.regexp source.ruby.embedded"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"token": "string.regexp string.regexp.arbitrary-repitition"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#7ee787",
|
||||
"token": "string.regexp constant.character.escape"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "support.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "support.variable"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "meta.module-reference"
|
||||
},
|
||||
{
|
||||
"foreground": "#ffa657",
|
||||
"token": "punctuation.definition.list.begin.markdown"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#79c0ff",
|
||||
"token": "markup.heading"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#79c0ff",
|
||||
"token": "markup.heading entity.name"
|
||||
},
|
||||
{
|
||||
"foreground": "#7ee787",
|
||||
"token": "markup.quote"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "markup.italic"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#c9d1d9",
|
||||
"token": "markup.bold"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "markup.raw"
|
||||
},
|
||||
{
|
||||
"background": "#490202",
|
||||
"foreground": "#ffa198",
|
||||
"token": "markup.deleted"
|
||||
},
|
||||
{
|
||||
"background": "#490202",
|
||||
"foreground": "#ffa198",
|
||||
"token": "meta.diff.header.from-file"
|
||||
},
|
||||
{
|
||||
"background": "#490202",
|
||||
"foreground": "#ffa198",
|
||||
"token": "punctuation.definition.deleted"
|
||||
},
|
||||
{
|
||||
"background": "#04260f",
|
||||
"foreground": "#7ee787",
|
||||
"token": "markup.inserted"
|
||||
},
|
||||
{
|
||||
"background": "#04260f",
|
||||
"foreground": "#7ee787",
|
||||
"token": "meta.diff.header.to-file"
|
||||
},
|
||||
{
|
||||
"background": "#04260f",
|
||||
"foreground": "#7ee787",
|
||||
"token": "punctuation.definition.inserted"
|
||||
},
|
||||
{
|
||||
"background": "#5a1e02",
|
||||
"foreground": "#ffa657",
|
||||
"token": "markup.changed"
|
||||
},
|
||||
{
|
||||
"background": "#5a1e02",
|
||||
"foreground": "#ffa657",
|
||||
"token": "punctuation.definition.changed"
|
||||
},
|
||||
{
|
||||
"foreground": "#161b22",
|
||||
"background": "#79c0ff",
|
||||
"token": "markup.ignored"
|
||||
},
|
||||
{
|
||||
"foreground": "#161b22",
|
||||
"background": "#79c0ff",
|
||||
"token": "markup.untracked"
|
||||
},
|
||||
{
|
||||
"foreground": "#d2a8ff",
|
||||
"fontStyle": "bold",
|
||||
"token": "meta.diff.range"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "meta.diff.header"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#79c0ff",
|
||||
"token": "meta.separator"
|
||||
},
|
||||
{
|
||||
"foreground": "#79c0ff",
|
||||
"token": "meta.output"
|
||||
},
|
||||
{
|
||||
"foreground": "#8b949e",
|
||||
"token": "brackethighlighter.tag"
|
||||
},
|
||||
{
|
||||
"foreground": "#8b949e",
|
||||
"token": "brackethighlighter.curly"
|
||||
},
|
||||
{
|
||||
"foreground": "#8b949e",
|
||||
"token": "brackethighlighter.round"
|
||||
},
|
||||
{
|
||||
"foreground": "#8b949e",
|
||||
"token": "brackethighlighter.square"
|
||||
},
|
||||
{
|
||||
"foreground": "#8b949e",
|
||||
"token": "brackethighlighter.angle"
|
||||
},
|
||||
{
|
||||
"foreground": "#8b949e",
|
||||
"token": "brackethighlighter.quote"
|
||||
},
|
||||
{
|
||||
"foreground": "#ffa198",
|
||||
"token": "brackethighlighter.unmatched"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"fontStyle": "underline",
|
||||
"token": "constant.other.reference.link"
|
||||
},
|
||||
{
|
||||
"foreground": "#a5d6ff",
|
||||
"fontStyle": "underline",
|
||||
"token": "string.other.link"
|
||||
}
|
||||
],
|
||||
"encodedTokensColors": []
|
||||
}
|
||||
531
src/components/CodeEditor/github-light-default.json
Normal file
531
src/components/CodeEditor/github-light-default.json
Normal file
@@ -0,0 +1,531 @@
|
||||
{
|
||||
"inherit": true,
|
||||
"base": "vs",
|
||||
"colors": {
|
||||
"focusBorder": "#0969da",
|
||||
"foreground": "#24292f",
|
||||
"descriptionForeground": "#57606a",
|
||||
"errorForeground": "#cf222e",
|
||||
"textLink.foreground": "#0969da",
|
||||
"textLink.activeForeground": "#0969da",
|
||||
"textBlockQuote.background": "#f6f8fa",
|
||||
"textBlockQuote.border": "#d0d7de",
|
||||
"textCodeBlock.background": "#afb8c133",
|
||||
"textPreformat.foreground": "#57606a",
|
||||
"textSeparator.foreground": "#d8dee4",
|
||||
"button.background": "#2da44e",
|
||||
"button.foreground": "#ffffff",
|
||||
"button.hoverBackground": "#2c974b",
|
||||
"button.secondaryBackground": "#ebecf0",
|
||||
"button.secondaryForeground": "#24292f",
|
||||
"button.secondaryHoverBackground": "#f3f4f6",
|
||||
"checkbox.background": "#f6f8fa",
|
||||
"checkbox.border": "#d0d7de",
|
||||
"dropdown.background": "#ffffff",
|
||||
"dropdown.border": "#d0d7de",
|
||||
"dropdown.foreground": "#24292f",
|
||||
"dropdown.listBackground": "#ffffff",
|
||||
"input.background": "#ffffff",
|
||||
"input.border": "#d0d7de",
|
||||
"input.foreground": "#24292f",
|
||||
"input.placeholderForeground": "#6e7781",
|
||||
"badge.foreground": "#ffffff",
|
||||
"badge.background": "#0969da",
|
||||
"progressBar.background": "#0969da",
|
||||
"titleBar.activeForeground": "#57606a",
|
||||
"titleBar.activeBackground": "#ffffff",
|
||||
"titleBar.inactiveForeground": "#57606a",
|
||||
"titleBar.inactiveBackground": "#f6f8fa",
|
||||
"titleBar.border": "#d0d7de",
|
||||
"activityBar.foreground": "#24292f",
|
||||
"activityBar.inactiveForeground": "#57606a",
|
||||
"activityBar.background": "#ffffff",
|
||||
"activityBarBadge.foreground": "#ffffff",
|
||||
"activityBarBadge.background": "#0969da",
|
||||
"activityBar.activeBorder": "#fd8c73",
|
||||
"activityBar.border": "#d0d7de",
|
||||
"sideBar.foreground": "#24292f",
|
||||
"sideBar.background": "#f6f8fa",
|
||||
"sideBar.border": "#d0d7de",
|
||||
"sideBarTitle.foreground": "#24292f",
|
||||
"sideBarSectionHeader.foreground": "#24292f",
|
||||
"sideBarSectionHeader.background": "#f6f8fa",
|
||||
"sideBarSectionHeader.border": "#d0d7de",
|
||||
"list.hoverForeground": "#24292f",
|
||||
"list.inactiveSelectionForeground": "#24292f",
|
||||
"list.activeSelectionForeground": "#24292f",
|
||||
"list.hoverBackground": "#eaeef280",
|
||||
"list.inactiveSelectionBackground": "#afb8c133",
|
||||
"list.activeSelectionBackground": "#afb8c133",
|
||||
"list.focusForeground": "#24292f",
|
||||
"list.focusBackground": "#ddf4ff",
|
||||
"list.inactiveFocusBackground": "#ddf4ff",
|
||||
"list.highlightForeground": "#0969da",
|
||||
"tree.indentGuidesStroke": "#d8dee4",
|
||||
"notificationCenterHeader.foreground": "#57606a",
|
||||
"notificationCenterHeader.background": "#f6f8fa",
|
||||
"notifications.foreground": "#24292f",
|
||||
"notifications.background": "#ffffff",
|
||||
"notifications.border": "#d0d7de",
|
||||
"notificationsErrorIcon.foreground": "#cf222e",
|
||||
"notificationsWarningIcon.foreground": "#9a6700",
|
||||
"notificationsInfoIcon.foreground": "#0969da",
|
||||
"pickerGroup.border": "#d0d7de",
|
||||
"pickerGroup.foreground": "#57606a",
|
||||
"quickInput.background": "#ffffff",
|
||||
"quickInput.foreground": "#24292f",
|
||||
"statusBar.foreground": "#57606a",
|
||||
"statusBar.background": "#ffffff",
|
||||
"statusBar.border": "#d0d7de",
|
||||
"statusBar.noFolderBackground": "#ffffff",
|
||||
"statusBar.debuggingBackground": "#cf222e",
|
||||
"statusBar.debuggingForeground": "#ffffff",
|
||||
"statusBarItem.prominentBackground": "#f6f8fa",
|
||||
"editorGroupHeader.tabsBackground": "#f6f8fa",
|
||||
"editorGroupHeader.tabsBorder": "#d0d7de",
|
||||
"editorGroup.border": "#d0d7de",
|
||||
"tab.activeForeground": "#24292f",
|
||||
"tab.inactiveForeground": "#57606a",
|
||||
"tab.inactiveBackground": "#f6f8fa",
|
||||
"tab.activeBackground": "#ffffff",
|
||||
"tab.hoverBackground": "#ffffff",
|
||||
"tab.unfocusedHoverBackground": "#eaeef280",
|
||||
"tab.border": "#d0d7de",
|
||||
"tab.unfocusedActiveBorderTop": "#d0d7de",
|
||||
"tab.activeBorder": "#ffffff",
|
||||
"tab.unfocusedActiveBorder": "#ffffff",
|
||||
"tab.activeBorderTop": "#fd8c73",
|
||||
"breadcrumb.foreground": "#57606a",
|
||||
"breadcrumb.focusForeground": "#24292f",
|
||||
"breadcrumb.activeSelectionForeground": "#57606a",
|
||||
"breadcrumbPicker.background": "#ffffff",
|
||||
"editor.foreground": "#24292f",
|
||||
"editor.background": "#ffffff",
|
||||
"editorWidget.background": "#ffffff",
|
||||
"editor.foldBackground": "#6e77811a",
|
||||
"editor.lineHighlightBackground": "#eaeef280",
|
||||
"editorLineNumber.foreground": "#57606a",
|
||||
"editorLineNumber.activeForeground": "#24292f",
|
||||
"editorIndentGuide.background": "#d8dee4",
|
||||
"editorIndentGuide.activeBackground": "#d0d7de",
|
||||
"editorWhitespace.foreground": "#6e7781",
|
||||
"editorCursor.foreground": "#0969da",
|
||||
"editor.findMatchBackground": "#bf8700",
|
||||
"editor.findMatchHighlightBackground": "#ffdf5d66",
|
||||
"editor.linkedEditingBackground": "#0366d611",
|
||||
"editor.inactiveSelectionBackground": "#0366d611",
|
||||
"editor.selectionBackground": "#0366d625",
|
||||
"editor.selectionHighlightBackground": "#34d05840",
|
||||
"editor.selectionHighlightBorder": "#34d05800",
|
||||
"editor.wordHighlightBackground": "#34d05800",
|
||||
"editor.wordHighlightStrongBackground": "#34d05800",
|
||||
"editor.wordHighlightBorder": "#24943e99",
|
||||
"editor.wordHighlightStrongBorder": "#24943e50",
|
||||
"editorBracketMatch.background": "#34d05840",
|
||||
"editorBracketMatch.border": "#34d05800",
|
||||
"editorGutter.modifiedBackground": "#d4a72c66",
|
||||
"editorGutter.addedBackground": "#4ac26b66",
|
||||
"editorGutter.deletedBackground": "#ff818266",
|
||||
"diffEditor.insertedTextBackground": "#dafbe1",
|
||||
"diffEditor.removedTextBackground": "#ffebe9",
|
||||
"scrollbar.shadow": "#6a737d33",
|
||||
"scrollbarSlider.background": "#959da533",
|
||||
"scrollbarSlider.hoverBackground": "#959da544",
|
||||
"scrollbarSlider.activeBackground": "#959da588",
|
||||
"editorOverviewRuler.border": "#ffffff",
|
||||
"panel.background": "#f6f8fa",
|
||||
"panel.border": "#d0d7de",
|
||||
"panelTitle.activeBorder": "#fd8c73",
|
||||
"panelTitle.activeForeground": "#24292f",
|
||||
"panelTitle.inactiveForeground": "#57606a",
|
||||
"panelInput.border": "#d0d7de",
|
||||
"terminal.foreground": "#57606a",
|
||||
"terminal.ansiBlack": "#24292f",
|
||||
"terminal.ansiRed": "#cf222e",
|
||||
"terminal.ansiGreen": "#116329",
|
||||
"terminal.ansiYellow": "#4d2d00",
|
||||
"terminal.ansiBlue": "#0969da",
|
||||
"terminal.ansiMagenta": "#8250df",
|
||||
"terminal.ansiCyan": "#1b7c83",
|
||||
"terminal.ansiWhite": "#6e7781",
|
||||
"terminal.ansiBrightBlack": "#57606a",
|
||||
"terminal.ansiBrightRed": "#a40e26",
|
||||
"terminal.ansiBrightGreen": "#1a7f37",
|
||||
"terminal.ansiBrightYellow": "#633c01",
|
||||
"terminal.ansiBrightBlue": "#218bff",
|
||||
"terminal.ansiBrightMagenta": "#a475f9",
|
||||
"terminal.ansiBrightCyan": "#3192aa",
|
||||
"terminal.ansiBrightWhite": "#8c959f",
|
||||
"gitDecoration.addedResourceForeground": "#1a7f37",
|
||||
"gitDecoration.modifiedResourceForeground": "#9a6700",
|
||||
"gitDecoration.deletedResourceForeground": "#cf222e",
|
||||
"gitDecoration.untrackedResourceForeground": "#1a7f37",
|
||||
"gitDecoration.ignoredResourceForeground": "#6e7781",
|
||||
"gitDecoration.conflictingResourceForeground": "#bc4c00",
|
||||
"gitDecoration.submoduleResourceForeground": "#57606a",
|
||||
"debugToolBar.background": "#ffffff",
|
||||
"editor.stackFrameHighlightBackground": "#ffd33d33",
|
||||
"editor.focusedStackFrameHighlightBackground": "#28a74525",
|
||||
"settings.headerForeground": "#57606a",
|
||||
"settings.modifiedItemIndicator": "#d4a72c66",
|
||||
"welcomePage.buttonBackground": "#f6f8fa",
|
||||
"welcomePage.buttonHoverBackground": "#f3f4f6"
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"foreground": "#6e7781",
|
||||
"token": "comment"
|
||||
},
|
||||
{
|
||||
"foreground": "#6e7781",
|
||||
"token": "punctuation.definition.comment"
|
||||
},
|
||||
{
|
||||
"foreground": "#6e7781",
|
||||
"token": "string.comment"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "constant"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "entity.name.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "variable.other.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "variable.language"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "entity"
|
||||
},
|
||||
{
|
||||
"foreground": "#953800",
|
||||
"token": "entity.name"
|
||||
},
|
||||
{
|
||||
"foreground": "#953800",
|
||||
"token": "meta.export.default"
|
||||
},
|
||||
{
|
||||
"foreground": "#953800",
|
||||
"token": "meta.definition.variable"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "variable.parameter.function"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "meta.jsx.children"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "meta.block"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "meta.tag.attributes"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "entity.name.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "meta.object.member"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "meta.embedded.expression"
|
||||
},
|
||||
{
|
||||
"foreground": "#8250df",
|
||||
"token": "entity.name.function"
|
||||
},
|
||||
{
|
||||
"foreground": "#116329",
|
||||
"token": "entity.name.tag"
|
||||
},
|
||||
{
|
||||
"foreground": "#116329",
|
||||
"token": "support.class.component"
|
||||
},
|
||||
{
|
||||
"foreground": "#cf222e",
|
||||
"token": "keyword"
|
||||
},
|
||||
{
|
||||
"foreground": "#cf222e",
|
||||
"token": "storage"
|
||||
},
|
||||
{
|
||||
"foreground": "#cf222e",
|
||||
"token": "storage.type"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "storage.modifier.package"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "storage.modifier.import"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "storage.type.java"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"token": "string"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"token": "punctuation.definition.string"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"token": "string punctuation.section.embedded source"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "support"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "meta.property-name"
|
||||
},
|
||||
{
|
||||
"foreground": "#953800",
|
||||
"token": "variable"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "variable.other"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#82071e",
|
||||
"token": "invalid.broken"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#82071e",
|
||||
"token": "invalid.deprecated"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#82071e",
|
||||
"token": "invalid.illegal"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#82071e",
|
||||
"token": "invalid.unimplemented"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic underline",
|
||||
"background": "#cf222e",
|
||||
"foreground": "#f6f8fa",
|
||||
"content": "^M",
|
||||
"token": "carriage-return"
|
||||
},
|
||||
{
|
||||
"foreground": "#82071e",
|
||||
"token": "message.error"
|
||||
},
|
||||
{
|
||||
"foreground": "#24292f",
|
||||
"token": "string source"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "string variable"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"token": "source.regexp"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"token": "string.regexp"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"token": "string.regexp.character-class"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"token": "string.regexp constant.character.escape"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"token": "string.regexp source.ruby.embedded"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"token": "string.regexp string.regexp.arbitrary-repitition"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#116329",
|
||||
"token": "string.regexp constant.character.escape"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "support.constant"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "support.variable"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "meta.module-reference"
|
||||
},
|
||||
{
|
||||
"foreground": "#953800",
|
||||
"token": "punctuation.definition.list.begin.markdown"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#0550ae",
|
||||
"token": "markup.heading"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#0550ae",
|
||||
"token": "markup.heading entity.name"
|
||||
},
|
||||
{
|
||||
"foreground": "#116329",
|
||||
"token": "markup.quote"
|
||||
},
|
||||
{
|
||||
"fontStyle": "italic",
|
||||
"foreground": "#24292f",
|
||||
"token": "markup.italic"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#24292f",
|
||||
"token": "markup.bold"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "markup.raw"
|
||||
},
|
||||
{
|
||||
"background": "#FFEBE9",
|
||||
"foreground": "#82071e",
|
||||
"token": "markup.deleted"
|
||||
},
|
||||
{
|
||||
"background": "#FFEBE9",
|
||||
"foreground": "#82071e",
|
||||
"token": "meta.diff.header.from-file"
|
||||
},
|
||||
{
|
||||
"background": "#FFEBE9",
|
||||
"foreground": "#82071e",
|
||||
"token": "punctuation.definition.deleted"
|
||||
},
|
||||
{
|
||||
"background": "#dafbe1",
|
||||
"foreground": "#116329",
|
||||
"token": "markup.inserted"
|
||||
},
|
||||
{
|
||||
"background": "#dafbe1",
|
||||
"foreground": "#116329",
|
||||
"token": "meta.diff.header.to-file"
|
||||
},
|
||||
{
|
||||
"background": "#dafbe1",
|
||||
"foreground": "#116329",
|
||||
"token": "punctuation.definition.inserted"
|
||||
},
|
||||
{
|
||||
"background": "#ffd8b5",
|
||||
"foreground": "#953800",
|
||||
"token": "markup.changed"
|
||||
},
|
||||
{
|
||||
"background": "#ffd8b5",
|
||||
"foreground": "#953800",
|
||||
"token": "punctuation.definition.changed"
|
||||
},
|
||||
{
|
||||
"foreground": "#eaeef2",
|
||||
"background": "#0550ae",
|
||||
"token": "markup.ignored"
|
||||
},
|
||||
{
|
||||
"foreground": "#eaeef2",
|
||||
"background": "#0550ae",
|
||||
"token": "markup.untracked"
|
||||
},
|
||||
{
|
||||
"foreground": "#8250df",
|
||||
"fontStyle": "bold",
|
||||
"token": "meta.diff.range"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "meta.diff.header"
|
||||
},
|
||||
{
|
||||
"fontStyle": "bold",
|
||||
"foreground": "#0550ae",
|
||||
"token": "meta.separator"
|
||||
},
|
||||
{
|
||||
"foreground": "#0550ae",
|
||||
"token": "meta.output"
|
||||
},
|
||||
{
|
||||
"foreground": "#57606a",
|
||||
"token": "brackethighlighter.tag"
|
||||
},
|
||||
{
|
||||
"foreground": "#57606a",
|
||||
"token": "brackethighlighter.curly"
|
||||
},
|
||||
{
|
||||
"foreground": "#57606a",
|
||||
"token": "brackethighlighter.round"
|
||||
},
|
||||
{
|
||||
"foreground": "#57606a",
|
||||
"token": "brackethighlighter.square"
|
||||
},
|
||||
{
|
||||
"foreground": "#57606a",
|
||||
"token": "brackethighlighter.angle"
|
||||
},
|
||||
{
|
||||
"foreground": "#57606a",
|
||||
"token": "brackethighlighter.quote"
|
||||
},
|
||||
{
|
||||
"foreground": "#82071e",
|
||||
"token": "brackethighlighter.unmatched"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"fontStyle": "underline",
|
||||
"token": "constant.other.reference.link"
|
||||
},
|
||||
{
|
||||
"foreground": "#0a3069",
|
||||
"fontStyle": "underline",
|
||||
"token": "string.other.link"
|
||||
}
|
||||
],
|
||||
"encodedTokensColors": []
|
||||
}
|
||||
232
src/components/CodeEditor/index.tsx
Normal file
232
src/components/CodeEditor/index.tsx
Normal file
@@ -0,0 +1,232 @@
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
import Editor, { EditorProps, useMonaco } from "@monaco-editor/react";
|
||||
import type { languages } from "monaco-editor/esm/vs/editor/editor.api";
|
||||
import githubLightTheme from "./github-light-default.json";
|
||||
import githubDarkTheme from "./github-dark-default.json";
|
||||
|
||||
import { useTheme, Box, BoxProps } from "@mui/material";
|
||||
import CircularProgressOptical from "components/CircularProgressOptical";
|
||||
import ResizeBottomRightIcon from "assets/icons/ResizeBottomRight";
|
||||
|
||||
import { useProjectContext } from "contexts/ProjectContext";
|
||||
import { getFieldProp } from "components/fields";
|
||||
|
||||
/* eslint-disable import/no-webpack-loader-syntax */
|
||||
import firestoreDefs from "!!raw-loader!./firestore.d.ts";
|
||||
import firebaseAuthDefs from "!!raw-loader!./firebaseAuth.d.ts";
|
||||
import firebaseStorageDefs from "!!raw-loader!./firebaseStorage.d.ts";
|
||||
import utilsDefs from "!!raw-loader!./utils.d.ts";
|
||||
import extensionsDefs from "!!raw-loader!./extensions.d.ts";
|
||||
|
||||
export interface ICodeEditorProps extends Partial<EditorProps> {
|
||||
onChange: EditorProps["onChange"];
|
||||
value: string;
|
||||
minHeight?: number;
|
||||
disabled?: boolean;
|
||||
containerProps?: Partial<BoxProps>;
|
||||
|
||||
extraLibs?: string[];
|
||||
onValidate?: EditorProps["onValidate"];
|
||||
onValidStatusUpdate?: ({ isValid: boolean }) => void;
|
||||
diagnosticsOptions?: languages.typescript.DiagnosticsOptions;
|
||||
onUnmount?: () => void;
|
||||
}
|
||||
|
||||
export default function CodeEditor({
|
||||
onChange,
|
||||
value,
|
||||
minHeight = 100,
|
||||
disabled,
|
||||
containerProps,
|
||||
|
||||
extraLibs,
|
||||
onValidate,
|
||||
onValidStatusUpdate,
|
||||
diagnosticsOptions,
|
||||
onUnmount,
|
||||
|
||||
...props
|
||||
}: ICodeEditorProps) {
|
||||
const theme = useTheme();
|
||||
const { tableState } = useProjectContext();
|
||||
|
||||
const [initialEditorValue] = useState(value ?? "");
|
||||
const monaco = useMonaco();
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
onUnmount?.();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const onValidate_: EditorProps["onValidate"] = (markers) => {
|
||||
if (onValidStatusUpdate)
|
||||
onValidStatusUpdate({ isValid: markers.length <= 0 });
|
||||
else if (onValidate) onValidate(markers);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!monaco) {
|
||||
// useMonaco returns a monaco instance but initialisation is done asynchronously
|
||||
// dont execute the logic until the instance is initialised
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
try {
|
||||
monaco.editor.defineTheme("github-light", githubLightTheme as any);
|
||||
monaco.editor.defineTheme("github-dark", githubDarkTheme as any);
|
||||
monaco.editor.setTheme("github-" + theme.palette.mode);
|
||||
} catch (error) {
|
||||
console.error("Could not set Monaco theme: ", error);
|
||||
}
|
||||
});
|
||||
}, [monaco, theme.palette.mode]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!monaco) {
|
||||
// useMonaco returns a monaco instance but initialisation is done asynchronously
|
||||
// dont execute the logic until the instance is initialised
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
monaco.editor.defineTheme("github-light", githubLightTheme as any);
|
||||
monaco.editor.defineTheme("github-dark", githubDarkTheme as any);
|
||||
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(firestoreDefs);
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
firebaseAuthDefs
|
||||
);
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
firebaseStorageDefs
|
||||
);
|
||||
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions(
|
||||
diagnosticsOptions ?? {
|
||||
noSemanticValidation: true,
|
||||
noSyntaxValidation: false,
|
||||
}
|
||||
);
|
||||
// compiler options
|
||||
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||
target: monaco.languages.typescript.ScriptTarget.ES2020,
|
||||
allowNonTsExtensions: true,
|
||||
});
|
||||
if (extraLibs) {
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
extraLibs.join("\n"),
|
||||
"ts:filename/extraLibs.d.ts"
|
||||
);
|
||||
}
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
utilsDefs,
|
||||
"ts:filename/utils.d.ts"
|
||||
);
|
||||
|
||||
const rowDefinition =
|
||||
Object.keys(tableState?.columns!)
|
||||
.map((columnKey: string) => {
|
||||
const column = tableState?.columns[columnKey];
|
||||
return `static ${columnKey}: ${getFieldProp("type", column.type)}`;
|
||||
})
|
||||
.join(";\n") + ";";
|
||||
|
||||
const availableFields = Object.keys(tableState?.columns!)
|
||||
.map((columnKey: string) => `"${columnKey}"`)
|
||||
.join("|\n");
|
||||
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
[
|
||||
"/**",
|
||||
" * extensions type configuration",
|
||||
" */",
|
||||
"// basic types that are used in all places",
|
||||
`type Row = {${rowDefinition}};`,
|
||||
`type Field = ${availableFields} | string | object;`,
|
||||
`type Fields = Field[];`,
|
||||
extensionsDefs,
|
||||
].join("\n"),
|
||||
"ts:filename/extensions.d.ts"
|
||||
);
|
||||
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
[
|
||||
"declare var require: any;",
|
||||
"declare var Buffer: any;",
|
||||
"const ref: FirebaseFirestore.DocumentReference;",
|
||||
"const storage: firebasestorage.Storage;",
|
||||
"const db: FirebaseFirestore.Firestore;",
|
||||
"const auth: adminauth.BaseAuth;",
|
||||
"declare class row {",
|
||||
" /**",
|
||||
" * Returns the row fields",
|
||||
" */",
|
||||
rowDefinition,
|
||||
"}",
|
||||
].join("\n"),
|
||||
"ts:filename/rowFields.d.ts"
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"An error occurred during initialization of Monaco: ",
|
||||
error
|
||||
);
|
||||
}
|
||||
}, [tableState?.columns, monaco, diagnosticsOptions, extraLibs]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
minWidth: 400,
|
||||
minHeight,
|
||||
height: minHeight,
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: 1,
|
||||
resize: "vertical",
|
||||
overflow: "hidden",
|
||||
position: "relative",
|
||||
|
||||
"& .editor": {
|
||||
// Overwrite user-select: none that causes editor
|
||||
// to not be focusable in Safari
|
||||
userSelect: "auto",
|
||||
height: "100%",
|
||||
},
|
||||
|
||||
...containerProps?.sx,
|
||||
}}
|
||||
>
|
||||
<Editor
|
||||
language="javascript"
|
||||
value={initialEditorValue}
|
||||
onValidate={onValidate_}
|
||||
loading={<CircularProgressOptical size={20} sx={{ m: 2 }} />}
|
||||
className="editor"
|
||||
{...props}
|
||||
options={{
|
||||
readOnly: disabled,
|
||||
fontFamily: theme.typography.fontFamilyMono,
|
||||
rulers: [80],
|
||||
minimap: { enabled: false },
|
||||
lineNumbersMinChars: 4,
|
||||
lineDecorationsWidth: 0,
|
||||
automaticLayout: true,
|
||||
fixedOverflowWidgets: true,
|
||||
...props.options,
|
||||
}}
|
||||
/>
|
||||
|
||||
<ResizeBottomRightIcon
|
||||
aria-label="This code editor is resizable"
|
||||
color="action"
|
||||
sx={{
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
zIndex: 1,
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
50
src/components/CodeEditor/utils.d.ts
vendored
Normal file
50
src/components/CodeEditor/utils.d.ts
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* utility functions
|
||||
*/
|
||||
declare namespace utilFns {
|
||||
/**
|
||||
* Sends out an email through sendGrid
|
||||
*/
|
||||
function sendEmail(msg: {
|
||||
from: string;
|
||||
templateId: string;
|
||||
personalizations: { to: string; dynamic_template_data: any }[];
|
||||
}): void {}
|
||||
|
||||
/**
|
||||
* Gets the secret defined in Google Cloud Secret
|
||||
*/
|
||||
async function getSecret(name: string, v?: string): any {}
|
||||
|
||||
/**
|
||||
* Async version of forEach
|
||||
*/
|
||||
async function asyncForEach(array: any[], callback: Function): void {}
|
||||
|
||||
/**
|
||||
* Generate random ID from numbers and English characters including lowercase and uppercase
|
||||
*/
|
||||
function generateId(): string {}
|
||||
|
||||
/**
|
||||
* Add an item to an array field
|
||||
*/
|
||||
function arrayUnion(val: string): void {}
|
||||
|
||||
/**
|
||||
* Remove an item to an array field
|
||||
*/
|
||||
function arrayRemove(val: string): void {}
|
||||
|
||||
/**
|
||||
* Increment a number field
|
||||
*/
|
||||
function increment(val: number): void {}
|
||||
|
||||
function hasRequiredFields(requiredFields: string[], data: any): boolean {}
|
||||
|
||||
function hasAnyRole(
|
||||
authorizedRoles: string[],
|
||||
context: functions.https.CallableContext
|
||||
): boolean {}
|
||||
}
|
||||
@@ -1,35 +1,21 @@
|
||||
import React from "react";
|
||||
import { lazy, Suspense, createElement } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { IMenuModalProps } from "..";
|
||||
|
||||
import { makeStyles, createStyles } from "@mui/styles";
|
||||
import Checkbox from "@mui/material/Checkbox";
|
||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||
import { Typography, TextField, MenuItem, ListItemText } from "@mui/material";
|
||||
import Subheading from "../Subheading";
|
||||
|
||||
import { getFieldProp } from "components/fields";
|
||||
import CodeEditorHelper from "components/CodeEditorHelper";
|
||||
import CodeEditor from "components/Table/editors/CodeEditor";
|
||||
import FieldSkeleton from "components/SideDrawer/Form/FieldSkeleton";
|
||||
import CodeEditorHelper from "@src/components/CodeEditor/CodeEditorHelper";
|
||||
import FormAutosave from "./FormAutosave";
|
||||
import { FieldType } from "constants/fields";
|
||||
import { WIKI_LINKS } from "constants/externalLinks";
|
||||
import { name } from "@root/package.json";
|
||||
|
||||
const useStyles = makeStyles((theme) =>
|
||||
createStyles({
|
||||
typeSelect: { marginBottom: theme.spacing(1) },
|
||||
typeSelectItem: { whiteSpace: "normal" },
|
||||
|
||||
codeEditorContainer: {
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
},
|
||||
|
||||
mono: {
|
||||
fontFamily: theme.typography.fontFamilyMono,
|
||||
},
|
||||
})
|
||||
const CodeEditor = lazy(
|
||||
() => import("components/CodeEditor" /* webpackChunkName: "CodeEditor" */)
|
||||
);
|
||||
|
||||
export interface IDefaultValueInputProps extends IMenuModalProps {
|
||||
@@ -43,7 +29,6 @@ export default function DefaultValueInput({
|
||||
fieldName,
|
||||
...props
|
||||
}: IDefaultValueInputProps) {
|
||||
const classes = useStyles();
|
||||
const _type =
|
||||
type !== FieldType.derivative
|
||||
? type
|
||||
@@ -64,13 +49,17 @@ export default function DefaultValueInput({
|
||||
value={config.defaultValue?.type ?? "undefined"}
|
||||
onChange={(e) => handleChange("defaultValue.type")(e.target.value)}
|
||||
fullWidth
|
||||
className={classes.typeSelect}
|
||||
sx={{ mb: 1 }}
|
||||
SelectProps={{
|
||||
MenuProps: {
|
||||
sx: { "& .MuiListItemText-root": { whiteSpace: "normal" } },
|
||||
},
|
||||
}}
|
||||
>
|
||||
<MenuItem value="undefined">
|
||||
<ListItemText
|
||||
primary="Undefined"
|
||||
secondary="No default value. The field will not appear in the row’s corresponding Firestore document by default."
|
||||
className={classes.typeSelectItem}
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem value="null">
|
||||
@@ -78,24 +67,21 @@ export default function DefaultValueInput({
|
||||
primary="Null"
|
||||
secondary={
|
||||
<>
|
||||
Initialise as <span className={classes.mono}>null</span>.
|
||||
Initialise as <code>null</code>.
|
||||
</>
|
||||
}
|
||||
className={classes.typeSelectItem}
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem value="static">
|
||||
<ListItemText
|
||||
primary="Static"
|
||||
secondary="Set a specific default value for all cells in this column."
|
||||
className={classes.typeSelectItem}
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem value="dynamic">
|
||||
<ListItemText
|
||||
primary={`Dynamic (Requires ${name} Cloud Functions)`}
|
||||
secondary={`Write code to set the default value using this table’s ${name} Cloud Function. Setup is required.`}
|
||||
className={classes.typeSelectItem}
|
||||
/>
|
||||
</MenuItem>
|
||||
</TextField>
|
||||
@@ -135,7 +121,7 @@ export default function DefaultValueInput({
|
||||
}
|
||||
/>
|
||||
|
||||
{React.createElement(customFieldInput, {
|
||||
{createElement(customFieldInput, {
|
||||
column: { type, key: fieldName, config, ...props, ...config },
|
||||
control,
|
||||
docRef: {},
|
||||
@@ -147,18 +133,12 @@ export default function DefaultValueInput({
|
||||
{config.defaultValue?.type === "dynamic" && (
|
||||
<>
|
||||
<CodeEditorHelper docLink={WIKI_LINKS.howToDefaultValues} />
|
||||
<div className={classes.codeEditorContainer}>
|
||||
<Suspense fallback={<FieldSkeleton height={100} />}>
|
||||
<CodeEditor
|
||||
height={120}
|
||||
script={config.defaultValue?.script}
|
||||
handleChange={handleChange("defaultValue.script")}
|
||||
editorOptions={{
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
}}
|
||||
value={config.defaultValue?.script}
|
||||
onChange={handleChange("defaultValue.script")}
|
||||
/>
|
||||
</div>
|
||||
</Suspense>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -15,7 +15,7 @@ import InputLabel from "@mui/material/InputLabel";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Select from "@mui/material/Select";
|
||||
import Switch from "@mui/material/Switch";
|
||||
import CodeEditor from "../editors/CodeEditor";
|
||||
// import CodeEditor from "../editors/CodeEditor";
|
||||
import { useProjectContext } from "contexts/ProjectContext";
|
||||
import { makeId } from "../../../utils/fns";
|
||||
|
||||
@@ -144,12 +144,12 @@ export default function WebhooksDialog({ open, handleClose }) {
|
||||
<MenuItem value={WebhookTypes.custom}>Custom</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
{state.type === WebhookTypes.custom && (
|
||||
{/* {state.type === WebhookTypes.custom && (
|
||||
<CodeEditor
|
||||
script={state.customParser}
|
||||
handleChange={handleChange("customParser")}
|
||||
/>
|
||||
)}
|
||||
)} */}
|
||||
<br />
|
||||
{state.type === WebhookTypes.typeForm && (
|
||||
<>
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import { lazy, Suspense } from "react";
|
||||
import { IExtensionModalStepProps } from "./ExtensionModal";
|
||||
import useStateRef from "react-usestateref";
|
||||
|
||||
import CodeEditor from "components/Table/editors/CodeEditor";
|
||||
import CodeEditorHelper from "components/CodeEditorHelper";
|
||||
|
||||
import FieldSkeleton from "components/SideDrawer/Form/FieldSkeleton";
|
||||
import CodeEditorHelper from "@src/components/CodeEditor/CodeEditorHelper";
|
||||
import { WIKI_LINKS } from "constants/externalLinks";
|
||||
|
||||
const CodeEditor = lazy(
|
||||
() => import("components/CodeEditor" /* webpackChunkName: "CodeEditor" */)
|
||||
);
|
||||
|
||||
const additionalVariables = [
|
||||
{
|
||||
key: "change",
|
||||
@@ -38,14 +42,14 @@ export default function Step3Conditions({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<Suspense fallback={<FieldSkeleton height={200} />}>
|
||||
<CodeEditor
|
||||
script={extensionObject.conditions}
|
||||
height={200}
|
||||
handleChange={(newValue) => {
|
||||
value={extensionObject.conditions}
|
||||
minHeight={200}
|
||||
onChange={(newValue) => {
|
||||
setExtensionObject({
|
||||
...extensionObject,
|
||||
conditions: newValue,
|
||||
conditions: newValue || "",
|
||||
});
|
||||
}}
|
||||
onValidStatusUpdate={({ isValid }) => {
|
||||
@@ -60,7 +64,7 @@ export default function Step3Conditions({
|
||||
onMount={() => setConditionEditorActive(true)}
|
||||
onUnmount={() => setConditionEditorActive(false)}
|
||||
/>
|
||||
</div>
|
||||
</Suspense>
|
||||
|
||||
<CodeEditorHelper
|
||||
docLink={WIKI_LINKS.extensions}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { lazy, Suspense } from "react";
|
||||
import { IExtensionModalStepProps } from "./ExtensionModal";
|
||||
import _upperFirst from "lodash/upperFirst";
|
||||
import useStateRef from "react-usestateref";
|
||||
|
||||
import CodeEditor from "components/Table/editors/CodeEditor";
|
||||
import CodeEditorHelper from "components/CodeEditorHelper";
|
||||
import FieldSkeleton from "components/SideDrawer/Form/FieldSkeleton";
|
||||
import CodeEditorHelper from "@src/components/CodeEditor/CodeEditorHelper";
|
||||
|
||||
import { WIKI_LINKS } from "constants/externalLinks";
|
||||
|
||||
const CodeEditor = lazy(
|
||||
() => import("components/CodeEditor" /* webpackChunkName: "CodeEditor" */)
|
||||
);
|
||||
|
||||
const additionalVariables = [
|
||||
{
|
||||
key: "change",
|
||||
@@ -38,14 +43,14 @@ export default function Step4Body({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<Suspense fallback={<FieldSkeleton height={200} />}>
|
||||
<CodeEditor
|
||||
script={extensionObject.extensionBody}
|
||||
height={400}
|
||||
handleChange={(newValue) => {
|
||||
value={extensionObject.extensionBody}
|
||||
minHeight={400}
|
||||
onChange={(newValue) => {
|
||||
setExtensionObject({
|
||||
...extensionObject,
|
||||
extensionBody: newValue,
|
||||
extensionBody: newValue || "",
|
||||
});
|
||||
}}
|
||||
onValidStatusUpdate={({ isValid }) => {
|
||||
@@ -63,7 +68,7 @@ export default function Step4Body({
|
||||
onMount={() => setBodyEditorActive(true)}
|
||||
onUnmount={() => setBodyEditorActive(false)}
|
||||
/>
|
||||
</div>
|
||||
</Suspense>
|
||||
|
||||
<CodeEditorHelper
|
||||
docLink={
|
||||
|
||||
@@ -1,398 +0,0 @@
|
||||
import { useRef, useMemo, useState } from "react";
|
||||
import { makeStyles, createStyles } from "@mui/styles";
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import Editor, { useMonaco } from "@monaco-editor/react";
|
||||
import { useProjectContext } from "contexts/ProjectContext";
|
||||
import { FieldType } from "constants/fields";
|
||||
import { useEffect } from "react";
|
||||
|
||||
const useStyles = makeStyles((theme) =>
|
||||
createStyles({
|
||||
editorWrapper: {
|
||||
position: "relative",
|
||||
minWidth: 400,
|
||||
minHeight: 100,
|
||||
height: "calc(100% - 50px)",
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
overflow: "hidden",
|
||||
},
|
||||
|
||||
saveButton: {
|
||||
marginTop: theme.spacing(1),
|
||||
},
|
||||
editor: {
|
||||
// overwrite user-select: none that causes editor not focusable in Safari
|
||||
userSelect: "auto",
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
export default function CodeEditor(props: any) {
|
||||
const {
|
||||
handleChange,
|
||||
extraLibs,
|
||||
height = 400,
|
||||
script,
|
||||
onValideStatusUpdate,
|
||||
diagnosticsOptions,
|
||||
onUnmount,
|
||||
onMount,
|
||||
} = props;
|
||||
const theme = useTheme();
|
||||
const monacoInstance = useMonaco();
|
||||
|
||||
const [initialEditorValue] = useState(script ?? "");
|
||||
const { tableState } = useProjectContext();
|
||||
const classes = useStyles();
|
||||
|
||||
const editorRef = useRef<any>();
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
onUnmount?.();
|
||||
};
|
||||
}, []);
|
||||
|
||||
function handleEditorDidMount(_, editor) {
|
||||
editorRef.current = editor;
|
||||
onMount?.();
|
||||
}
|
||||
|
||||
const themeTransformer = (theme: string) => {
|
||||
switch (theme) {
|
||||
case "dark":
|
||||
return "vs-dark";
|
||||
default:
|
||||
return theme;
|
||||
}
|
||||
};
|
||||
|
||||
useMemo(async () => {
|
||||
if (!monacoInstance) {
|
||||
// useMonaco returns a monaco instance but initialisation is done asynchronously
|
||||
// dont execute the logic until the instance is initialised
|
||||
return;
|
||||
}
|
||||
|
||||
const firestoreDefsFile = await fetch(
|
||||
`${process.env.PUBLIC_URL}/firestore.d.ts`
|
||||
);
|
||||
const firebaseAuthDefsFile = await fetch(
|
||||
`${process.env.PUBLIC_URL}/auth.d.ts`
|
||||
);
|
||||
const firebaseStorageDefsFile = await fetch(
|
||||
`${process.env.PUBLIC_URL}/storage.d.ts`
|
||||
);
|
||||
const firestoreDefs = await firestoreDefsFile.text();
|
||||
const firebaseStorageDefs = await firebaseStorageDefsFile.text();
|
||||
const firebaseAuthDefs = (await firebaseAuthDefsFile.text())
|
||||
?.replace("export", "declare")
|
||||
?.replace("admin.auth", "adminauth");
|
||||
|
||||
try {
|
||||
monacoInstance.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
firestoreDefs
|
||||
);
|
||||
monacoInstance.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
firebaseAuthDefs
|
||||
);
|
||||
monacoInstance.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
firebaseStorageDefs
|
||||
);
|
||||
monacoInstance.languages.typescript.javascriptDefaults.setDiagnosticsOptions(
|
||||
diagnosticsOptions ?? {
|
||||
noSemanticValidation: true,
|
||||
noSyntaxValidation: false,
|
||||
}
|
||||
);
|
||||
// compiler options
|
||||
monacoInstance.languages.typescript.javascriptDefaults.setCompilerOptions(
|
||||
{
|
||||
target: monacoInstance.languages.typescript.ScriptTarget.ES2020,
|
||||
allowNonTsExtensions: true,
|
||||
}
|
||||
);
|
||||
if (extraLibs) {
|
||||
monacoInstance.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
extraLibs.join("\n"),
|
||||
"ts:filename/extraLibs.d.ts"
|
||||
);
|
||||
}
|
||||
monacoInstance.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
[
|
||||
" /**",
|
||||
" * utility functions",
|
||||
" */",
|
||||
`
|
||||
declare namespace utilFns {
|
||||
/**
|
||||
* Sends out an email through sendGrid
|
||||
*/
|
||||
function sendEmail(msg: {
|
||||
from: string;
|
||||
templateId: string;
|
||||
personalizations: { to: string; dynamic_template_data: any }[];
|
||||
}): void {}
|
||||
|
||||
/**
|
||||
* Gets the secret defined in Google Cloud Secret
|
||||
*/
|
||||
async function getSecret(name: string, v?: string): any {}
|
||||
|
||||
/**
|
||||
* Async version of forEach
|
||||
*/
|
||||
async function asyncForEach(array: any[], callback: Function): void {}
|
||||
|
||||
/**
|
||||
* Generate random ID from numbers and English characters including lowercase and uppercase
|
||||
*/
|
||||
function generateId(): string {}
|
||||
|
||||
/**
|
||||
* Add an item to an array field
|
||||
*/
|
||||
function arrayUnion(val: string): void {}
|
||||
|
||||
/**
|
||||
* Remove an item to an array field
|
||||
*/
|
||||
function arrayRemove(val: string): void {}
|
||||
|
||||
/**
|
||||
* Increment a number field
|
||||
*/
|
||||
function increment(val: number): void {}
|
||||
|
||||
function hasRequiredFields(requiredFields: string[], data: any): boolean {}
|
||||
|
||||
function hasAnyRole(
|
||||
authorizedRoles: string[],
|
||||
context: functions.https.CallableContext
|
||||
): boolean {}
|
||||
}
|
||||
|
||||
`,
|
||||
].join("\n"),
|
||||
"ts:filename/utils.d.ts"
|
||||
);
|
||||
|
||||
const rowDefinition = [
|
||||
...Object.keys(tableState?.columns!).map((columnKey: string) => {
|
||||
const column = tableState?.columns[columnKey];
|
||||
switch (column.type) {
|
||||
case FieldType.shortText:
|
||||
case FieldType.longText:
|
||||
case FieldType.email:
|
||||
case FieldType.phone:
|
||||
case FieldType.code:
|
||||
return `${columnKey}:string`;
|
||||
case FieldType.singleSelect:
|
||||
const typeString = [
|
||||
...(column.config?.options?.map((opt) => `"${opt}"`) ?? []),
|
||||
].join(" | ");
|
||||
return `${columnKey}:${typeString}`;
|
||||
case FieldType.multiSelect:
|
||||
return `${columnKey}:string[]`;
|
||||
case FieldType.checkbox:
|
||||
return `${columnKey}:boolean`;
|
||||
default:
|
||||
return `${columnKey}:any`;
|
||||
}
|
||||
}),
|
||||
].join(";\n");
|
||||
|
||||
const availableFields = Object.keys(tableState?.columns!)
|
||||
.map((columnKey: string) => `"${columnKey}"`)
|
||||
.join("|\n");
|
||||
|
||||
const extensionsDefinition = `
|
||||
// basic types that are used in all places
|
||||
type Row = {${rowDefinition}};
|
||||
type Field = ${availableFields} | string | object;
|
||||
type Fields = Field[];
|
||||
type Trigger = "create" | "update" | "delete";
|
||||
type Triggers = Trigger[];
|
||||
|
||||
// function types that defines extension body and should run
|
||||
type Condition = boolean | ((data: ExtensionContext) => boolean | Promise<boolean>);
|
||||
|
||||
// the argument that the extension body takes in
|
||||
type ExtensionContext = {
|
||||
row: Row;
|
||||
ref:FirebaseFirestore.DocumentReference;
|
||||
storage:firebasestorage.Storage;
|
||||
db:FirebaseFirestore.Firestore;
|
||||
auth:adminauth.BaseAuth;
|
||||
change: any;
|
||||
triggerType: Triggers;
|
||||
fieldTypes: any;
|
||||
extensionConfig: {
|
||||
label: string;
|
||||
type: string;
|
||||
triggers: Trigger[];
|
||||
conditions: Condition;
|
||||
requiredFields: string[];
|
||||
extensionBody: any;
|
||||
};
|
||||
utilFns: any;
|
||||
}
|
||||
|
||||
// extension body definition
|
||||
type slackEmailBody = {
|
||||
channels?: string[];
|
||||
text?: string;
|
||||
emails: string[];
|
||||
blocks?: object[];
|
||||
attachments?: any;
|
||||
}
|
||||
|
||||
type slackChannelBody = {
|
||||
channels: string[];
|
||||
text?: string;
|
||||
emails?: string[];
|
||||
blocks?: object[];
|
||||
attachments?: any;
|
||||
}
|
||||
|
||||
type DocSyncBody = (context: ExtensionContext) => Promise<{
|
||||
fieldsToSync: Fields;
|
||||
row: Row;
|
||||
targetPath: string;
|
||||
}>
|
||||
|
||||
type HistorySnapshotBody = (context: ExtensionContext) => Promise<{
|
||||
trackedFields: Fields;
|
||||
}>
|
||||
|
||||
type AlgoliaIndexBody = (context: ExtensionContext) => Promise<{
|
||||
fieldsToSync: Fields;
|
||||
index: string;
|
||||
row: Row;
|
||||
objectID: string;
|
||||
}>
|
||||
|
||||
type MeiliIndexBody = (context: ExtensionContext) => Promise<{
|
||||
fieldsToSync: Fields;
|
||||
index: string;
|
||||
row: Row;
|
||||
objectID: string;
|
||||
}>
|
||||
|
||||
type BigqueryIndexBody = (context: ExtensionContext) => Promise<{
|
||||
fieldsToSync: Fields;
|
||||
index: string;
|
||||
row: Row;
|
||||
objectID: string;
|
||||
}>
|
||||
|
||||
type SlackMessageBody = (context: ExtensionContext) => Promise<slackEmailBody | slackChannelBody>;
|
||||
|
||||
type SendgridEmailBody = (context: ExtensionContext) => Promise<any>;
|
||||
|
||||
type ApiCallBody = (context: ExtensionContext) => Promise<{
|
||||
body: string;
|
||||
url: string;
|
||||
method: string;
|
||||
callback: any;
|
||||
}>
|
||||
|
||||
type TwilioMessageBody = (context: ExtensionContext) => Promise<{
|
||||
body: string;
|
||||
from: string;
|
||||
to: string;
|
||||
}>
|
||||
|
||||
type TaskBody = (context: ExtensionContext) => Promise<any>
|
||||
`;
|
||||
|
||||
monacoInstance.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
[
|
||||
" /**",
|
||||
" * extensions type configuration",
|
||||
" */",
|
||||
extensionsDefinition,
|
||||
].join("\n"),
|
||||
"ts:filename/extensions.d.ts"
|
||||
);
|
||||
|
||||
monacoInstance.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
[
|
||||
" declare var require: any;",
|
||||
" declare var Buffer: any;",
|
||||
" const ref:FirebaseFirestore.DocumentReference",
|
||||
" const storage:firebasestorage.Storage",
|
||||
" const db:FirebaseFirestore.Firestore;",
|
||||
" const auth:adminauth.BaseAuth;",
|
||||
"declare class row {",
|
||||
" /**",
|
||||
" * Returns the row fields",
|
||||
" */",
|
||||
...Object.keys(tableState?.columns!).map((columnKey: string) => {
|
||||
const column = tableState?.columns[columnKey];
|
||||
switch (column.type) {
|
||||
case FieldType.shortText:
|
||||
case FieldType.longText:
|
||||
case FieldType.email:
|
||||
case FieldType.phone:
|
||||
case FieldType.code:
|
||||
return `static ${columnKey}:string`;
|
||||
case FieldType.singleSelect:
|
||||
const typeString = [
|
||||
...(column.config?.options?.map((opt) => `"${opt}"`) ?? []),
|
||||
// "string",
|
||||
].join(" | ");
|
||||
return `static ${columnKey}:${typeString}`;
|
||||
case FieldType.multiSelect:
|
||||
return `static ${columnKey}:string[]`;
|
||||
case FieldType.checkbox:
|
||||
return `static ${columnKey}:boolean`;
|
||||
default:
|
||||
return `static ${columnKey}:any`;
|
||||
}
|
||||
}),
|
||||
"}",
|
||||
].join("\n"),
|
||||
"ts:filename/rowFields.d.ts"
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"An error occurred during initialization of Monaco: ",
|
||||
error
|
||||
);
|
||||
}
|
||||
}, [tableState?.columns, monacoInstance]);
|
||||
|
||||
function handleEditorValidation(markers) {
|
||||
if (onValideStatusUpdate) {
|
||||
onValideStatusUpdate({
|
||||
isValid: markers.length <= 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={classes.editorWrapper}>
|
||||
<Editor
|
||||
theme={themeTransformer(theme.palette.mode)}
|
||||
onMount={handleEditorDidMount}
|
||||
language="javascript"
|
||||
height={height}
|
||||
value={initialEditorValue}
|
||||
onChange={handleChange}
|
||||
onValidate={handleEditorValidation}
|
||||
options={{
|
||||
// readOnly: disabled,
|
||||
fontFamily: theme.typography.fontFamilyMono,
|
||||
rulers: [80],
|
||||
minimap: { enabled: false },
|
||||
// ...editorOptions,
|
||||
}}
|
||||
className={classes.editor}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -11,10 +11,7 @@ import FieldSkeleton from "components/SideDrawer/Form/FieldSkeleton";
|
||||
import { useProjectContext } from "contexts/ProjectContext";
|
||||
|
||||
const CodeEditor = lazy(
|
||||
() =>
|
||||
import(
|
||||
"components/Table/editors/CodeEditor" /* webpackChunkName: "CodeEditor" */
|
||||
)
|
||||
() => import("components/CodeEditor" /* webpackChunkName: "CodeEditor" */)
|
||||
);
|
||||
|
||||
const Settings = ({ config, handleChange }) => {
|
||||
@@ -93,8 +90,8 @@ const Settings = ({ config, handleChange }) => {
|
||||
<Typography variant="overline">action script</Typography>
|
||||
<Suspense fallback={<FieldSkeleton height={300} />}>
|
||||
<CodeEditor
|
||||
height={300}
|
||||
script={config.script}
|
||||
minHeight={300}
|
||||
value={config.script}
|
||||
extraLibs={[
|
||||
[
|
||||
"declare class ref {",
|
||||
@@ -121,9 +118,9 @@ const Settings = ({ config, handleChange }) => {
|
||||
} else return `static ${param.name}:any`;
|
||||
}),
|
||||
"}",
|
||||
],
|
||||
].join("\n"),
|
||||
]}
|
||||
handleChange={handleChange("script")}
|
||||
onChange={handleChange("script")}
|
||||
/>
|
||||
</Suspense>
|
||||
<FormControlLabel
|
||||
@@ -175,9 +172,9 @@ const Settings = ({ config, handleChange }) => {
|
||||
<Typography variant="overline">Undo action script</Typography>
|
||||
<Suspense fallback={<FieldSkeleton height={300} />}>
|
||||
<CodeEditor
|
||||
height={300}
|
||||
script={config["undo.script"]}
|
||||
handleChange={handleChange("undo.script")}
|
||||
minHeight={300}
|
||||
value={config["undo.script"]}
|
||||
onChange={handleChange("undo.script")}
|
||||
/>
|
||||
</Suspense>
|
||||
</>
|
||||
|
||||
@@ -6,10 +6,7 @@ import { FieldType } from "constants/fields";
|
||||
import FieldsDropdown from "components/Table/ColumnMenu/FieldsDropdown";
|
||||
import { useProjectContext } from "contexts/ProjectContext";
|
||||
const CodeEditor = lazy(
|
||||
() =>
|
||||
import(
|
||||
"components/Table/editors/CodeEditor" /* webpackChunkName: "CodeEditor" */
|
||||
)
|
||||
() => import("components/CodeEditor" /* webpackChunkName: "CodeEditor" */)
|
||||
);
|
||||
|
||||
const Settings = ({ config, handleChange }) => {
|
||||
@@ -29,7 +26,7 @@ const Settings = ({ config, handleChange }) => {
|
||||
<Typography variant="overline">Aggergate script</Typography>
|
||||
<Suspense fallback={<FieldSkeleton height={200} />}>
|
||||
<CodeEditor
|
||||
script={
|
||||
value={
|
||||
config.script ??
|
||||
`//triggerType: create | update | delete\n//aggregateState: the subtable accumulator stored in the cell of this column\n//snapshot: the triggered document snapshot of the the subcollection\n//incrementor: short for firebase.firestore.FieldValue.increment(n);\n//This script needs to return the new aggregateState cell value.
|
||||
switch (triggerType){
|
||||
@@ -45,13 +42,13 @@ switch (triggerType){
|
||||
}
|
||||
extraLibs={[
|
||||
` /**
|
||||
* increaments firestore field value
|
||||
* increments firestore field value
|
||||
*/",
|
||||
function incrementor(value:number):number {
|
||||
|
||||
}`,
|
||||
]}
|
||||
handleChange={handleChange("script")}
|
||||
onChange={handleChange("script")}
|
||||
/>
|
||||
</Suspense>
|
||||
|
||||
|
||||
@@ -2,46 +2,18 @@ import { Controller } from "react-hook-form";
|
||||
import { ISideDrawerFieldProps } from "../types";
|
||||
|
||||
import CodeEditor from "components/CodeEditor";
|
||||
import { makeStyles, createStyles } from "@mui/styles";
|
||||
|
||||
const useStyles = makeStyles((theme) =>
|
||||
createStyles({
|
||||
wrapper: {
|
||||
border: "1px solid",
|
||||
borderColor:
|
||||
theme.palette.mode === "light"
|
||||
? "rgba(0, 0, 0, 0.09)"
|
||||
: "rgba(255, 255, 255, 0.09)",
|
||||
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
overflow: "hidden",
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
export default function Code({
|
||||
control,
|
||||
column,
|
||||
disabled,
|
||||
}: ISideDrawerFieldProps) {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Controller
|
||||
control={control}
|
||||
name={column.key}
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<CodeEditor
|
||||
disabled={disabled}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
wrapperProps={{ className: classes.wrapper }}
|
||||
editorOptions={{
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<CodeEditor disabled={disabled} value={value} onChange={onChange} />
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -5,15 +5,12 @@ import FieldSkeleton from "components/SideDrawer/Form/FieldSkeleton";
|
||||
import { FieldType } from "constants/fields";
|
||||
import FieldsDropdown from "components/Table/ColumnMenu/FieldsDropdown";
|
||||
import { useProjectContext } from "contexts/ProjectContext";
|
||||
import CodeEditorHelper from "components/CodeEditorHelper";
|
||||
import CodeEditorHelper from "@src/components/CodeEditor/CodeEditorHelper";
|
||||
|
||||
import { WIKI_LINKS } from "constants/externalLinks";
|
||||
|
||||
const CodeEditor = lazy(
|
||||
() =>
|
||||
import(
|
||||
"components/Table/editors/CodeEditor" /* webpackChunkName: "CodeEditor" */
|
||||
)
|
||||
() => import("components/CodeEditor" /* webpackChunkName: "CodeEditor" */)
|
||||
);
|
||||
|
||||
const Settings = ({ config, handleChange }) => {
|
||||
@@ -63,10 +60,7 @@ const Settings = ({ config, handleChange }) => {
|
||||
<InputLabel>Derivative script</InputLabel>
|
||||
<CodeEditorHelper docLink={WIKI_LINKS.fieldTypesDerivative} />
|
||||
<Suspense fallback={<FieldSkeleton height={200} />}>
|
||||
<CodeEditor
|
||||
script={config.script}
|
||||
handleChange={handleChange("script")}
|
||||
/>
|
||||
<CodeEditor value={config.script} onChange={handleChange("script")} />
|
||||
</Suspense>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -6,3 +6,7 @@ declare module "*.mp4" {
|
||||
const content: any;
|
||||
export default content;
|
||||
}
|
||||
declare module "!!raw-loader!*" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
||||
@@ -2374,7 +2374,7 @@
|
||||
dependencies:
|
||||
state-local "^1.0.6"
|
||||
|
||||
"@monaco-editor/react@^4.1.0":
|
||||
"@monaco-editor/react@^4.3.1":
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@monaco-editor/react/-/react-4.3.1.tgz#d65bcbf174c39b6d4e7fec43d0cddda82b70a12a"
|
||||
integrity sha512-f+0BK1PP/W5I50hHHmwf11+Ea92E5H1VZXs+wvKplWUWOfyMa1VVwqkJrXjRvbcqHL+XdIGYWhWNdi4McEvnZg==
|
||||
|
||||
Reference in New Issue
Block a user