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

Update CI and ESLint configuration #241

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
69e336a
Reformat eslintrc
RichDom2185 Sep 10, 2023
8ff8d5e
Add type annotation
RichDom2185 Sep 10, 2023
d03c8e7
Replace magic numbers with their meaning
RichDom2185 Sep 10, 2023
7fe3199
Add type annotation for rules
RichDom2185 Sep 10, 2023
ec1f240
Enable typecheck
RichDom2185 Sep 10, 2023
6a0074a
Fix type annotation
RichDom2185 Sep 10, 2023
364f8c5
Remove some commented configurations
RichDom2185 Sep 10, 2023
b7576ff
Typecheck base ESLint config
RichDom2185 Sep 10, 2023
be62ed5
Remove duplicate property
RichDom2185 Sep 10, 2023
2b37b1f
Typecheck base rules
RichDom2185 Sep 10, 2023
dca4e28
Clean up some code
RichDom2185 Sep 10, 2023
84a3c32
Replace magic numbers with their meaning
RichDom2185 Sep 10, 2023
21869fe
Remove rules that are already default
RichDom2185 Sep 10, 2023
90d6178
Set base ESLint env to es2022
RichDom2185 Sep 10, 2023
321e7b4
Fix incorrect magic number replacement
RichDom2185 Sep 10, 2023
7593bd2
Add explanatory comment
RichDom2185 Sep 10, 2023
727c318
Bump ESLint versions
RichDom2185 Sep 10, 2023
1c4d018
Remove more options that are already default
RichDom2185 Sep 10, 2023
4e919ff
Merge branch 'master' of https://github.com/source-academy/modules in…
RichDom2185 Feb 17, 2024
0e03d6f
Update lockfile post-merge
RichDom2185 Feb 17, 2024
0d86bbd
Revert "Update lockfile post-merge"
RichDom2185 Feb 17, 2024
5d526dc
Fix lockfile post-merge
RichDom2185 Feb 17, 2024
bff4431
Set up prettier config
RichDom2185 Feb 17, 2024
eca5f71
Reformat base ESLint config file
RichDom2185 Feb 17, 2024
81a085d
Reformat other ESLint config files
RichDom2185 Feb 18, 2024
f237379
Update some ESLint configs
RichDom2185 Feb 18, 2024
cb1a8ac
Autofix some ESLint errors
RichDom2185 Feb 18, 2024
aee8463
Autofix more ESLint errors
RichDom2185 Feb 18, 2024
18bdaa2
Simplify base ESLint config
RichDom2185 Feb 18, 2024
67152b5
Remove AirBnB config
RichDom2185 Feb 18, 2024
477c8eb
Reformat some files using Prettier
RichDom2185 Feb 18, 2024
4ac3ff7
Revert trailing comma config to 'none'
RichDom2185 Feb 18, 2024
9d80c1d
Simplify ESLint config
RichDom2185 Feb 18, 2024
5e81f49
Reformat tabs with prettier
RichDom2185 Feb 18, 2024
87afbf7
Add ignore for bugfix
RichDom2185 Feb 18, 2024
3abc31c
Reformat more files
RichDom2185 Feb 18, 2024
423fb9a
Reformat some bundle files with prettier
RichDom2185 Feb 18, 2024
103e37c
Reformat some more files
RichDom2185 Feb 18, 2024
f4cc696
Fix ESLint configs
RichDom2185 Feb 18, 2024
c730009
Reformat more bundles using Prettier
RichDom2185 Feb 18, 2024
a6b77f9
Fix ESLint errors in bundles and tabs
RichDom2185 Feb 18, 2024
e60b603
Update devserver lint config
RichDom2185 Feb 18, 2024
0f58149
Fix lint in devserver
RichDom2185 Feb 18, 2024
236a757
Reformat devserver
RichDom2185 Feb 18, 2024
bcedbcf
Merge branches 'update-ci' and 'master' of https://github.com/source-…
RichDom2185 Feb 23, 2024
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
463 changes: 116 additions & 347 deletions .eslintrc.base.cjs

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": true,
"singleQuote": true,
"printWidth": 100,
"arrowParens": "always",
"trailingComma": "none"
}
18 changes: 10 additions & 8 deletions devserver/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
{
"root": true,
"env": { "browser": true, "es2020": true },
"extends": [ "../.eslintrc.base.cjs" ],
"extends": ["../.eslintrc.base.cjs"],
"ignorePatterns": ["dist", ".eslintrc.cjs"],
"parser": "@typescript-eslint/parser",
"plugins": ["react", "@typescript-eslint"],
"rules": {
"func-style": 0,
"no-empty-function": 0,

"@typescript-eslint/no-explicit-any": "off",
"no-unused-vars": "off", // disable base rule, as it can report incorrect errors
"@typescript-eslint/no-unused-vars": [
1, // Was 2
"error",
{
// vars: "all",
// args: "after-used",
// ignoreRestSiblings: false,
"argsIgnorePattern": "^_",
"caughtErrors": "all", // Was "none"
"caughtErrorsIgnorePattern": "^_"
"vars": "all",
"args": "none",
"ignoreRestSiblings": false,
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_"
}
]
}
Expand Down
74 changes: 37 additions & 37 deletions devserver/src/components/ControlButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AnchorButton, Button, Icon, type IconName, Intent } from "@blueprintjs/core";
import React from "react";
import { AnchorButton, Button, Icon, Intent, type IconName } from '@blueprintjs/core';
import React from 'react';

type ButtonOptions = {
className: string;
Expand All @@ -8,7 +8,7 @@ type ButtonOptions = {
iconOnRight: boolean;
intent: Intent;
minimal: boolean;
type?: "submit" | "reset" | "button";
type?: 'submit' | 'reset' | 'button';
};

type ControlButtonProps = {
Expand All @@ -20,45 +20,45 @@ type ControlButtonProps = {
};

const defaultOptions = {
className: "",
fullWidth: false,
iconOnRight: false,
intent: Intent.NONE,
minimal: true
className: '',
fullWidth: false,
iconOnRight: false,
intent: Intent.NONE,
minimal: true
};

const ControlButton: React.FC<ControlButtonProps> = ({
label = "",
icon,
onClick,
options = {},
isDisabled = false
label = '',
icon,
onClick,
options = {},
isDisabled = false
}) => {
const buttonOptions: ButtonOptions = {
...defaultOptions,
...options
};
const iconElement = icon && <Icon icon={icon} color={buttonOptions.iconColor} />;
// Refer to #2417 and #2422 for why we conditionally
// set the button component. See also:
// https://blueprintjs.com/docs/#core/components/button
const ButtonComponent = isDisabled ? AnchorButton : Button;
const buttonOptions: ButtonOptions = {
...defaultOptions,
...options
};
const iconElement = icon && <Icon icon={icon} color={buttonOptions.iconColor} />;
// Refer to #2417 and #2422 for why we conditionally
// set the button component. See also:
// https://blueprintjs.com/docs/#core/components/button
const ButtonComponent = isDisabled ? AnchorButton : Button;

return (
<ButtonComponent
disabled={isDisabled}
fill={buttonOptions.fullWidth}
intent={buttonOptions.intent}
minimal={buttonOptions.minimal}
className={buttonOptions.className}
type={buttonOptions.type}
onClick={onClick}
icon={!buttonOptions.iconOnRight && iconElement}
rightIcon={buttonOptions.iconOnRight && iconElement}
>
{label}
</ButtonComponent>
);
return (
<ButtonComponent
disabled={isDisabled}
fill={buttonOptions.fullWidth}
intent={buttonOptions.intent}
minimal={buttonOptions.minimal}
className={buttonOptions.className}
type={buttonOptions.type}
onClick={onClick}
icon={!buttonOptions.iconOnRight && iconElement}
rightIcon={buttonOptions.iconOnRight && iconElement}
>
{label}
</ButtonComponent>
);
};

export default ControlButton;
2 changes: 1 addition & 1 deletion devserver/src/components/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
return tempContext;
};

const Playground: React.FC<{}> = () => {
const Playground: React.FC = () => {
const [dynamicTabs, setDynamicTabs] = React.useState<SideContentTab[]>([]);
const [selectedTabId, setSelectedTab] = React.useState(testTabContent.id);
const [codeContext, setCodeContext] = React.useState<Context>(createContextHelper());
Expand Down Expand Up @@ -124,7 +124,7 @@
.then(() => showToast(evalSuccessToast));
}

// TODO: Add support for console.log?

Check warning on line 127 in devserver/src/components/Playground.tsx

View workflow job for this annotation

GitHub Actions / Verify all tests pass and build success

Unexpected 'TODO' comment: 'TODO: Add support for console.log?'
if (result.status === "finished") {
setReplOutput({
type: "result",
Expand Down
199 changes: 98 additions & 101 deletions devserver/src/components/Workspace.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { FocusStyleManager } from "@blueprintjs/core";
import { type Enable, Resizable, type ResizeCallback } from "re-resizable";
import React from "react";
import { FocusStyleManager } from '@blueprintjs/core';
import { Resizable, type Enable, type ResizeCallback } from 're-resizable';
import React from 'react';

import ControlBar, { type ControlBarProps } from "./controlBar/ControlBar";
import Editor from "./editor/Editor";
import Repl, { type ReplProps } from "./repl/Repl";
import SideContent, { type SideContentProps } from "./sideContent/SideContent";
import { useDimensions } from "./utils/Hooks";
import ControlBar, { type ControlBarProps } from './controlBar/ControlBar';
import Editor from './editor/Editor';
import Repl, { type ReplProps } from './repl/Repl';
import SideContent, { type SideContentProps } from './sideContent/SideContent';
import { useDimensions } from './utils/Hooks';

type DispatchProps = {
handleEditorEval: () => void;
handleEditorValueChange: (newValue: string) => void
handlePromptAutocomplete: (row: number, col: number, callback: any) => void
handleEditorValueChange: (newValue: string) => void;
handlePromptAutocomplete: (row: number, col: number, callback: any) => void;
};

type StateProps = {
Expand All @@ -21,9 +21,9 @@ type StateProps = {
replProps: ReplProps;
sideContentHeight?: number;
sideContentIsResizeable?: boolean;
editorValue: string
editorValue: string;

sideContentProps: SideContentProps
sideContentProps: SideContentProps;
};

const rightResizeOnly: Enable = { right: true };
Expand All @@ -32,113 +32,110 @@ const bottomResizeOnly: Enable = { bottom: true };
export type WorkspaceProps = DispatchProps & StateProps;

const Workspace: React.FC<WorkspaceProps> = (props) => {
const contentContainerDiv = React.useRef<HTMLDivElement | null>(null);
const editorDividerDiv = React.useRef<HTMLDivElement | null>(null);
const leftParentResizable = React.useRef<Resizable | null>(null);
const maxDividerHeight = React.useRef<number | null>(null);
const sideDividerDiv = React.useRef<HTMLDivElement | null>(null);
const contentContainerDiv = React.useRef<HTMLDivElement | null>(null);
const editorDividerDiv = React.useRef<HTMLDivElement | null>(null);
const leftParentResizable = React.useRef<Resizable | null>(null);
const maxDividerHeight = React.useRef<number | null>(null);
const sideDividerDiv = React.useRef<HTMLDivElement | null>(null);

const [contentContainerWidth] = useDimensions(contentContainerDiv);
const [contentContainerWidth] = useDimensions(contentContainerDiv);

const [sideContentHeight, setSideContentHeight] = React.useState<number | undefined>(undefined);
const [sideContentHeight, setSideContentHeight] = React.useState<number | undefined>(undefined);

FocusStyleManager.onlyShowFocusOnTabs();
FocusStyleManager.onlyShowFocusOnTabs();

React.useEffect(() => {
if (props.sideContentIsResizeable && maxDividerHeight.current === null) {
maxDividerHeight.current = sideDividerDiv.current!.clientHeight;
}
});
React.useEffect(() => {
if (props.sideContentIsResizeable && maxDividerHeight.current === null) {
maxDividerHeight.current = sideDividerDiv.current!.clientHeight;
}
});

/**
/**
* Snaps the left-parent resizable to 100% or 0% when percentage width goes
* above 95% or below 5% respectively. Also changes the editor divider width
* in the case of < 5%.
*/
const toggleEditorDividerDisplay: ResizeCallback = (_a, _b, ref) => {
const leftThreshold = 5;
const rightThreshold = 95;
const editorWidthPercentage
= ((ref as HTMLDivElement).clientWidth / contentContainerWidth) * 100;
// update resizable size
if (editorWidthPercentage > rightThreshold) {
const toggleEditorDividerDisplay: ResizeCallback = (_a, _b, ref) => {
const leftThreshold = 5;
const rightThreshold = 95;
const editorWidthPercentage =
((ref as HTMLDivElement).clientWidth / contentContainerWidth) * 100;
// update resizable size
if (editorWidthPercentage > rightThreshold) {
leftParentResizable.current!.updateSize({
width: "100%",
height: "100%"
width: '100%',
height: '100%'
});
} else if (editorWidthPercentage < leftThreshold) {
} else if (editorWidthPercentage < leftThreshold) {
leftParentResizable.current!.updateSize({
width: "0%",
height: "100%"
width: '0%',
height: '100%'
});
}
};
}
};

/**
/**
* Hides the side-content-divider div when side-content is resized downwards
* so that it's bottom border snaps flush with editor's bottom border
*/
const toggleDividerDisplay: ResizeCallback = (_a, _b, ref) => {
maxDividerHeight.current
= sideDividerDiv.current!.clientHeight > maxDividerHeight.current!
? sideDividerDiv.current!.clientHeight
: maxDividerHeight.current;
const resizableHeight = (ref as HTMLDivElement).clientHeight;
const rightParentHeight = (ref.parentNode as HTMLDivElement).clientHeight;
if (resizableHeight + maxDividerHeight.current! + 2 > rightParentHeight) {
sideDividerDiv.current!.style.display = "none";
} else {
sideDividerDiv.current!.style.display = "initial";
}
};
const toggleDividerDisplay: ResizeCallback = (_a, _b, ref) => {
maxDividerHeight.current =
sideDividerDiv.current!.clientHeight > maxDividerHeight.current!
? sideDividerDiv.current!.clientHeight
: maxDividerHeight.current;
const resizableHeight = (ref as HTMLDivElement).clientHeight;
const rightParentHeight = (ref.parentNode as HTMLDivElement).clientHeight;
if (resizableHeight + maxDividerHeight.current! + 2 > rightParentHeight) {
sideDividerDiv.current!.style.display = 'none';
} else {
sideDividerDiv.current!.style.display = 'initial';
}
};

return (
<div className="workspace">
<ControlBar {...props.controlBarProps} />
<div className="workspace-parent">
<div className="row content-parent" ref={contentContainerDiv}>
<div className="editor-divider" ref={editorDividerDiv} />
<Resizable
className="resize-editor left-parent"
enable={rightResizeOnly}
minWidth={0}
onResize={toggleEditorDividerDisplay}
ref={leftParentResizable}
defaultSize={{
width: "50%",
height: "100%"
}}
as={undefined as any} // re-resizable bug - wrong typedef
>
<Editor
handleEditorValueChange={props.handleEditorValueChange}
handleEditorEval={props.handleEditorEval}
handleDeclarationNavigate={() => {}}
handlePromptAutocomplete={props.handlePromptAutocomplete}
handleSendReplInputToOutput={() => {}}
editorValue={props.editorValue}
/>
</Resizable>
<div className="right-parent">
<Resizable
bounds="parent"
className="resize-side-content"
enable={bottomResizeOnly}
onResize={toggleDividerDisplay}
onResizeStop={(_a, _b, ref) => setSideContentHeight(ref.clientHeight)}
>
<SideContent
sideContentHeight={sideContentHeight}
{...props.sideContentProps}
/>
<div className="side-content-divider" ref={sideDividerDiv} />
</Resizable>
<Repl {...props.replProps} />
</div>
</div>
</div>
</div>
);
return (
<div className="workspace">
<ControlBar {...props.controlBarProps} />
<div className="workspace-parent">
<div className="row content-parent" ref={contentContainerDiv}>
<div className="editor-divider" ref={editorDividerDiv} />
<Resizable
className="resize-editor left-parent"
enable={rightResizeOnly}
minWidth={0}
onResize={toggleEditorDividerDisplay}
ref={leftParentResizable}
defaultSize={{
width: '50%',
height: '100%'
}}
as={undefined as any} // re-resizable bug - wrong typedef
>
<Editor
handleEditorValueChange={props.handleEditorValueChange}
handleEditorEval={props.handleEditorEval}
handleDeclarationNavigate={() => {}}
handlePromptAutocomplete={props.handlePromptAutocomplete}
handleSendReplInputToOutput={() => {}}
editorValue={props.editorValue}
/>
</Resizable>
<div className="right-parent">
<Resizable
bounds="parent"
className="resize-side-content"
enable={bottomResizeOnly}
onResize={toggleDividerDisplay}
onResizeStop={(_a, _b, ref) => setSideContentHeight(ref.clientHeight)}
>
<SideContent sideContentHeight={sideContentHeight} {...props.sideContentProps} />
<div className="side-content-divider" ref={sideDividerDiv} />
</Resizable>
<Repl {...props.replProps} />
</div>
</div>
</div>
</div>
);
};

export default Workspace;
Loading
Loading