Update webview create-react-app framework and IDE support

feature/ssh-config
Kelvin Schoofs 4 years ago
parent c0f77bf11e
commit b071a32ed4

66
.vscode/tasks.json vendored

@ -37,30 +37,52 @@
"cwd": "./webview"
},
"group": "build",
"problemMatcher": {
"source": "react-dev-utils",
"severity": "error",
"fileLocation": "absolute",
"applyTo": "closedDocuments",
"background": {
"activeOnStart": true,
"beginsPattern": "Compiling.*?|Compilation .*?starting",
"endsPattern": "Compiled .*?successfully|Failed .*?to.*?compile.*?"
"problemMatcher": [
{
"source": "parser",
"owner": "react",
"fileLocation": "absolute",
"applyTo": "allDocuments",
"pattern": [
{
"regexp": "^SyntaxError: (.*): (.+) \\((\\d+):(\\d+)\\)$",
"file": 1,
"message": 2,
"line": 3,
"column": 4
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "^Compiling.*",
"endsPattern": "^(Compiled successfully|Failed to compile)"
}
},
"pattern": [
{
"regexp": "^(.+)$",
"file": 1
},
{
"regexp": "\\((\\d+),(\\d+)\\):\\s*(.+)",
"line": 1,
"column": 2,
"message": 3,
"loop": true
{
"source": "typescript",
"owner": "react",
"fileLocation": "absolute",
"applyTo": "allDocuments",
"pattern": [
{
"regexp": "^TypeScript error in (.*)\\((\\d+),(\\d+)\\):",
"file": 1,
"line": 2,
"column": 3
},
{
"regexp": "^(.{5,})$",
"message": 1,
"loop": true
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "^Compiling.*",
"endsPattern": "^(Compiled successfully|Failed to compile)"
}
]
},
}
],
"isBackground": true
}
]

@ -110,6 +110,6 @@ export interface FileSystemConfig extends ConnectConfig {
export function invalidConfigName(name: string) {
if (!name) return 'Missing a name for this SSH FS';
if (name.match(/^[\w_\\\/\.@\-+]+$/)) return null;
if (name.match(/^[\w_\\/.@\-+]+$/)) return null;
return `A SSH FS name can only exists of lowercase alphanumeric characters, slashes and any of these: _.+-@`;
}

@ -31,6 +31,7 @@ async function getDebugContent(): Promise<string | false> {
// Make sure the CSP meta tag also includes the React dev server (including connect-src for the socket, which uses both http:// and ws://)
body = body.replace(/\$WEBVIEW_CSPSOURCE/g, `$WEBVIEW_CSPSOURCE ${URL}`);
body = body.replace(/\$WEBVIEW_CSPEXTRA/g, `connect-src ${URL} ${URL.replace('http://', 'ws://')};`);
body = body.replace(/src="\/static\//g, `src="${URL}/static/`);
cb(null, body);
}).on('error', err => {
Logging.warning(`Error connecting to React dev server: ${err}`);

@ -0,0 +1,4 @@
WDS_SOCKET_HOST=localhost
WDS_SOCKET_PORT=3000
BROWSER=none
SKIP_PREFLIGHT_CHECK=true

@ -15,6 +15,7 @@ build
.env.development.local
.env.test.local
.env.production.local
.eslintcache
npm-debug.log*
yarn-debug.log*

@ -9,18 +9,30 @@
"redux": "^4.0.5"
},
"scripts": {
"start": "cross-env BROWSER=none react-scripts-ts start",
"build": "react-scripts-ts build",
"test": "react-scripts-ts test --env=jsdom",
"eject": "react-scripts-ts eject"
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"devDependencies": {
"@types/jest": "^25.1.4",
"@types/react": "^16.9.23",
"@types/react-dom": "^16.9.5",
"@types/react-redux": "^7.1.7",
"cross-env": "^7.0.3",
"react-scripts-ts": "^3.1.0",
"react-scripts": "^4.0.1",
"typescript": "^4.0.2"
},
"browserslist": [
"Electron >= 9.0.0"
],
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
],
"rules": {
"no-sparse-arrays": 0,
"no-sequences": 0
}
}
}
}

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src $WEBVIEW_CSPSOURCE; style-src 'unsafe-inline' $WEBVIEW_CSPSOURCE; $WEBVIEW_CSPEXTRA">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline' $WEBVIEW_CSPSOURCE; style-src 'unsafe-inline' $WEBVIEW_CSPSOURCE; $WEBVIEW_CSPEXTRA">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!--<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">-->
<!--

@ -26,7 +26,7 @@ class ConfigList extends React.Component<StateProps & DispatchProps & OwnProps>
}
public editConfigClickHandler(config: FileSystemConfig) {
const { displayName } = this.props;
const name = displayName && displayName(config) || config.label || config.name;
const name = displayName?.(config) || config.label || config.name;
const onClick = () => this.props.editConfig(config);
return <li key={config.name} onClick={onClick}>{name}</li>;
}

@ -64,7 +64,7 @@ export abstract class FieldBase<T, P = {}, S = {}> extends React.Component<Props
const error = this.getError();
const { description, label, optional } = this.props;
return <div className="Field">
<FieldGroup.Consumer>{group => (group && group.register(this), [])}</FieldGroup.Consumer>
<FieldGroup.Consumer>{group => (group?.register(this), [])}</FieldGroup.Consumer>
<div className="label">{label}</div>{optional && <div className="optional">Optional</div>}
{description && <div className="description">{description}</div>}
{error && <div className="error">{error}</div>}

@ -6,10 +6,10 @@ interface Props<T> {
displayName?(item: T): string;
displayStyle?(item: T): React.CSSProperties;
}
interface State<T> {
interface State {
open: boolean;
}
export class FieldDropdown<T> extends FieldBase<T, Props<T>, State<T>> {
export class FieldDropdown<T> extends FieldBase<T, Props<T>, State> {
public mainDivRef = React.createRef<HTMLDivElement>();
public componentDidMount() {
window.addEventListener('click', this.onGlobalClick);
@ -17,7 +17,7 @@ export class FieldDropdown<T> extends FieldBase<T, Props<T>, State<T>> {
public componentWillUnmount() {
window.removeEventListener('click', this.onGlobalClick);
}
public getInitialSubState(props: Props<T>): State<T> {
public getInitialSubState(props: Props<T>): State {
return { open: false };
}
public renderInput() {
@ -39,7 +39,7 @@ export class FieldDropdown<T> extends FieldBase<T, Props<T>, State<T>> {
</li>
};
return <ul className="list">
{this.props.optional && <li onClick={this.select.bind(this, null)} />}
{this.props.optional && <li onClick={this.select.bind(this, null as any as T)} />}
{values.map(generateItem)}
</ul>;
}

@ -44,7 +44,7 @@ export class FieldDropdownWithInput extends FieldBase<string | undefined, Props,
{values.map(generateItem)}
</ul>;
}
public select(newValue: string) {
public select(newValue: string | undefined) {
this.setState({ newValue, open: false }, () => this.props.onChange(newValue));
}
public toggle = () => this.setState({ open: !this.state.open });

@ -2,9 +2,6 @@ import * as React from 'react';
import { FieldBase } from './base';
export class FieldString extends FieldBase<string | undefined> {
constructor(props: FieldString['props']) {
super(props);
}
public getInitialSubState({ value }: FieldString['props']): FieldString['state'] {
value = value || undefined;
return { oldValue: value, newValue: value };

@ -50,6 +50,9 @@ export default connect(Startscreen)<StateProps, DispatchProps>(
dispatch => ({
add: () => dispatch(openNewConfig()),
changeGroupBy: (current: string) => dispatch(openStartScreen(current === 'group' ? 'location' : 'group')),
refresh: () => (dispatch(receivedData([], [])), API.postMessage({ type: 'requestData' })),
refresh: () => {
dispatch(receivedData([], []));
API.postMessage({ type: 'requestData' });
},
}),
);

@ -0,0 +1 @@
/// <reference types="react-scripts" />

@ -110,6 +110,6 @@ export interface FileSystemConfig extends ConnectConfig {
export function invalidConfigName(name: string) {
if (!name) return 'Missing a name for this SSH FS';
if (name.match(/^[\w_\\\/\.@\-+]+$/)) return null;
if (name.match(/^[\w_\\/.@\-+]+$/)) return null;
return `A SSH FS name can only exists of lowercase alphanumeric characters, slashes and any of these: _.+-@`;
}

@ -21,7 +21,7 @@ export function addListener<T extends Message = Message>(listener: Listener<T>,
export function addListener(listener: Listener, filter?: Filter) {
LISTENERS.push([listener, filter]);
}
export function removeListener(listener: Listener) {
export function removeListener<T extends Message = Message>(listener: Listener<T>) {
LISTENERS = LISTENERS.filter(([l]) => l !== listener);
}

@ -3,7 +3,10 @@
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"lib": [
"es6",
"dom"
],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
@ -16,19 +19,18 @@
"importHelpers": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true
"noUnusedLocals": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"noFallthroughCasesInSwitch": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
},
"include": [
"src",
"public"
],
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
]
}
}

@ -1,3 +0,0 @@
{
"extends": "./tsconfig.json"
}

@ -1,6 +0,0 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs"
}
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save