trigger screen
23
ui/.gitignore
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
18534
ui/package-lock.json
generated
Normal file
50
ui/package.json
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"name": "infinite-todo-list",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@monaco-editor/react": "^4.6.0",
|
||||
"@testing-library/jest-dom": "^5.17.0",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^16.18.46",
|
||||
"@types/react": "^18.2.21",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"formik-antd": "^2.0.4",
|
||||
"mobx": "^6.10.0",
|
||||
"mobx-react-lite": "^4.0.4",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"sass": "^1.66.1",
|
||||
"typescript": "^4.9.5",
|
||||
"uuid": "^9.0.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
BIN
ui/public/favicon.ico
Normal file
After Width: | Height: | Size: 3.8 KiB |
20
ui/public/index.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<title>Infinite Todo List</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
BIN
ui/public/logo192.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
ui/public/logo512.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
25
ui/public/manifest.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
3
ui/public/robots.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
12
ui/src/assets/icons/add.svg
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||
<svg width="64px" height="64px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||
|
||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
|
||||
<g id="SVGRepo_iconCarrier"> <path d="M12 7.75732L12 16.2426" stroke="#f46036" stroke-width="2" stroke-linecap="round"/> <path d="M7.75735 12L16.2426 12" stroke="#f46036" stroke-width="2" stroke-linecap="round"/> <rect x="3" y="3" width="18" height="18" rx="3" stroke="#f46036" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 769 B |
7
ui/src/assets/icons/check.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||
<svg width="64px" height="64px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g id="SVGRepo_iconCarrier"> <g id="Interface / Check"> <path id="Vector" d="M6 12L10.2426 16.2426L18.727 7.75732" stroke="#f8f9fa" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g> </g>
|
||||
</svg>
|
After Width: | Height: | Size: 628 B |
7
ui/src/assets/icons/chevron.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||
<svg width="64px" height="64px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g id="SVGRepo_iconCarrier"> <path d="M15.8351 11.6296L9.20467 5.1999C8.79094 4.79869 8 5.04189 8 5.5703L8 18.4297C8 18.9581 8.79094 19.2013 9.20467 18.8001L15.8351 12.3704C16.055 12.1573 16.0549 11.8427 15.8351 11.6296Z" fill="#013a63"/> </g>
|
||||
</svg>
|
After Width: | Height: | Size: 664 B |
13
ui/src/assets/icons/delete.svg
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||
<svg width="64px" height="64px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||
|
||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
|
||||
<g id="SVGRepo_iconCarrier">
|
||||
<rect width="24" height="24" fill="none"/> <path d="M7 17L16.8995 7.10051" stroke="#f55d3e" stroke-linecap="round" stroke-linejoin="round"/> <path d="M7 7.00001L16.8995 16.8995" stroke="#f46036" stroke-linecap="round" stroke-linejoin="round"/> </g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 701 B |
12
ui/src/assets/images/logo.svg
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||
<svg width="64px" height="64px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||
|
||||
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
|
||||
<g id="SVGRepo_iconCarrier"> <path fill-rule="evenodd" clip-rule="evenodd" d="M2 5.75C2 5.33579 2.33579 5 2.75 5H20.75C21.1642 5 21.5 5.33579 21.5 5.75C21.5 6.16421 21.1642 6.5 20.75 6.5H2.75C2.33579 6.5 2 6.16421 2 5.75ZM2 9.75C2 9.33579 2.33579 9 2.75 9H20.75C21.1642 9 21.5 9.33579 21.5 9.75C21.5 10.1642 21.1642 10.5 20.75 10.5H2.75C2.33579 10.5 2 10.1642 2 9.75ZM20.2113 12.6586C20.5379 12.9134 20.5961 13.3847 20.3414 13.7113L16.4414 18.7113C16.3022 18.8897 16.0899 18.9958 15.8636 18.9999C15.6373 19.004 15.4213 18.9057 15.2757 18.7324L13.1757 16.2324C12.9093 15.9152 12.9504 15.4421 13.2676 15.1757C13.5848 14.9093 14.0579 14.9504 14.3243 15.2676L15.8284 17.0582L19.1586 12.7887C19.4134 12.4621 19.8847 12.4039 20.2113 12.6586ZM2 13.75C2 13.3358 2.33579 13 2.75 13H9.75C10.1642 13 10.5 13.3358 10.5 13.75C10.5 14.1642 10.1642 14.5 9.75 14.5H2.75C2.33579 14.5 2 14.1642 2 13.75ZM2 17.75C2 17.3358 2.33579 17 2.75 17H9.75C10.1642 17 10.5 17.3358 10.5 17.75C10.5 18.1642 10.1642 18.5 9.75 18.5H2.75C2.33579 18.5 2 18.1642 2 17.75Z" fill="#f46036"/> </g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
32
ui/src/core/repository/http_repository.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
export enum HttpMethod {
|
||||
GET = 'GET',
|
||||
POST = 'POST'
|
||||
}
|
||||
|
||||
export class HttpRepository {
|
||||
|
||||
private server = 'http://localhost:3000'
|
||||
|
||||
public async jsonRequest<T>(method: HttpMethod, url: string, data?: any): Promise<T> {
|
||||
const reqInit = {
|
||||
'body': data,
|
||||
'method': method,
|
||||
'headers': { 'Content-Type': 'application/json' },
|
||||
}
|
||||
if (data !== undefined) {
|
||||
reqInit['body'] = JSON.stringify(data)
|
||||
}
|
||||
return (await fetch(this.server + url, reqInit)).json()
|
||||
}
|
||||
|
||||
public async request<T>(method: HttpMethod, url: string, data?: any): Promise<T> {
|
||||
const reqInit = {
|
||||
'body': data,
|
||||
'method': method,
|
||||
}
|
||||
if (data !== undefined) {
|
||||
reqInit['body'] = data
|
||||
}
|
||||
return (await fetch(this.server + url, reqInit)).json()
|
||||
}
|
||||
}
|
11
ui/src/features/trigger/data/trigger_repository.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import {
|
||||
HttpMethod,
|
||||
HttpRepository,
|
||||
} from "../../../core/repository/http_repository";
|
||||
import { ITriggerModel } from "../model/trigger_model";
|
||||
|
||||
export class TriggerRepository extends HttpRepository {
|
||||
public async save(model: ITriggerModel) {
|
||||
return await this.jsonRequest(HttpMethod.POST, "/trigger", model);
|
||||
}
|
||||
}
|
10
ui/src/features/trigger/model/trigger_form_view_model.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { TriggerType } from "./trigger_model";
|
||||
|
||||
export interface ITriggerViewValueModel {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface TriggerViewModel extends ITriggerViewValueModel {
|
||||
id: string;
|
||||
type: TriggerType;
|
||||
}
|
10
ui/src/features/trigger/model/trigger_model.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
export interface ITriggerModel {
|
||||
_id?: string;
|
||||
type: string;
|
||||
value: string[];
|
||||
}
|
||||
|
||||
export enum TriggerType {
|
||||
PROCESS = "PROCESS",
|
||||
FILE = "FILE",
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import * as React from "react";
|
||||
import Editor from "@monaco-editor/react";
|
||||
import { Button } from "antd";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { triggerStore } from "../logic/trigger_store";
|
||||
|
||||
export const CodeTriggerForm: React.FunctionComponent = observer(() => {
|
||||
return (
|
||||
<>
|
||||
<div style={{ width: "100%", backgroundColor: "black", height: "1px" }} />
|
||||
|
||||
<Editor
|
||||
height="40vh"
|
||||
defaultLanguage="javascript"
|
||||
value={triggerStore.codeTriggerValue}
|
||||
onChange={(v) => {
|
||||
triggerStore.writeNewTrigger(v);
|
||||
}}
|
||||
onValidate={(m) => {
|
||||
console.log(m);
|
||||
}}
|
||||
/>
|
||||
|
||||
<div style={{ width: "100%", backgroundColor: "black", height: "1px" }} />
|
||||
<div style={{ height: "10px" }}/>
|
||||
|
||||
<Button
|
||||
onClick={() => triggerStore.saveCode()}
|
||||
style={{ marginLeft: "10px", marginRight: "10px" }}
|
||||
>
|
||||
Save code
|
||||
</Button>
|
||||
|
||||
<Button onClick={() => triggerStore.clearTriggerCode()}>
|
||||
Reset code
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
});
|
|
@ -0,0 +1,55 @@
|
|||
import * as React from "react";
|
||||
import { Formik } from "formik";
|
||||
import { SubmitButton, Input, ResetButton, Form, FormItem } from "formik-antd";
|
||||
import { Row, Col } from "antd";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { triggerStore } from "../logic/trigger_store";
|
||||
import { TriggerType } from "../../model/trigger_model";
|
||||
|
||||
function validateRequired(value: string) {
|
||||
return value ? undefined : "required";
|
||||
}
|
||||
|
||||
export const FileTriggerForm: React.FunctionComponent = observer(() => {
|
||||
return (
|
||||
<>
|
||||
<div style={{ marginTop: 80 }}>
|
||||
<Formik
|
||||
initialValues={{
|
||||
value: "",
|
||||
}}
|
||||
onSubmit={(values, actions) => {
|
||||
triggerStore.pushTrigger(values.value, TriggerType.FILE);
|
||||
actions.setSubmitting(false);
|
||||
actions.resetForm();
|
||||
}}
|
||||
validate={(values) => {
|
||||
if (values.value.length === 0) {
|
||||
return false;
|
||||
}
|
||||
return {};
|
||||
}}
|
||||
render={() => (
|
||||
<Form>
|
||||
<div style={{ background: "white", flex: 1, padding: 40 }}>
|
||||
<FormItem
|
||||
name="value"
|
||||
required={true}
|
||||
validate={validateRequired}
|
||||
>
|
||||
<Input name="value" placeholder="regExp file" />
|
||||
</FormItem>
|
||||
<Row style={{ marginTop: 60 }}>
|
||||
<Col offset={8}>
|
||||
<ResetButton>Reset</ResetButton>
|
||||
<SubmitButton>Submit</SubmitButton>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
});
|
80
ui/src/features/trigger/presentation/logic/trigger_store.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
import { makeAutoObservable } from "mobx";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { TriggerType } from "../../model/trigger_model";
|
||||
import { TriggerRepository } from "../../data/trigger_repository";
|
||||
import { TriggerViewModel } from "../../model/trigger_form_view_model";
|
||||
|
||||
class TriggerStore {
|
||||
constructor(repository: TriggerRepository) {
|
||||
this.triggerType = TriggerType.FILE;
|
||||
this.repository = repository;
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
triggerType: TriggerType;
|
||||
codeTriggerValue = "";
|
||||
triggers: TriggerViewModel[] = [];
|
||||
|
||||
repository: TriggerRepository;
|
||||
|
||||
deleteItem(id: string): void {
|
||||
this.triggers = this.triggers.filter((el) => el.id !== id);
|
||||
console.log(id);
|
||||
}
|
||||
|
||||
getTriggerType = (): boolean => {
|
||||
return this.triggerType === TriggerType.FILE;
|
||||
};
|
||||
setTriggerType = (): void => {
|
||||
this.triggers = [];
|
||||
if (this.triggerType === TriggerType.FILE) {
|
||||
this.triggerType = TriggerType.PROCESS;
|
||||
return;
|
||||
}
|
||||
this.triggerType = TriggerType.FILE;
|
||||
};
|
||||
getTriggerDescription = (): string => {
|
||||
return this.triggerType === TriggerType.FILE
|
||||
? TriggerType.FILE
|
||||
: TriggerType.PROCESS;
|
||||
};
|
||||
pushTrigger = (value: string, type: TriggerType): void => {
|
||||
console.log(value);
|
||||
this.triggers.push({
|
||||
value: value,
|
||||
id: uuidv4(),
|
||||
type: type,
|
||||
});
|
||||
};
|
||||
|
||||
writeNewTrigger(v: string | undefined): void {
|
||||
if (v === undefined) {
|
||||
throw new Error("Editor Value is undefined");
|
||||
}
|
||||
this.codeTriggerValue = v;
|
||||
}
|
||||
clearTriggerCode(): void {
|
||||
this.codeTriggerValue = "";
|
||||
}
|
||||
saveCode(): void {
|
||||
if (this.codeTriggerValue !== "") {
|
||||
this.triggers.push({
|
||||
id: uuidv4(),
|
||||
value: this.codeTriggerValue,
|
||||
type: TriggerType.PROCESS,
|
||||
});
|
||||
|
||||
this.codeTriggerValue = "";
|
||||
}
|
||||
}
|
||||
async saveResult(): Promise<void> {
|
||||
await this.repository.save({
|
||||
type: this.getTriggerDescription(),
|
||||
value: this.triggers.map((el) => {
|
||||
return el.value;
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const triggerStore = new TriggerStore(new TriggerRepository());
|
|
@ -0,0 +1,66 @@
|
|||
import * as React from "react";
|
||||
import { Button, Col, Row, Switch, Typography } from "antd";
|
||||
import { CodeTriggerForm } from "./components/code_trigger_form";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { triggerStore } from "./logic/trigger_store";
|
||||
import { FileTriggerForm } from "./components/file_trigger_form";
|
||||
import { ReactComponent as DeleteIcon } from "../../../assets/icons/delete.svg";
|
||||
|
||||
const { Title } = Typography;
|
||||
|
||||
const Header = observer(() => {
|
||||
return (
|
||||
<Row style={{ justifyItems: "center", alignItems: "center" }}>
|
||||
<div style={{ height: "37px" }}>
|
||||
<Switch
|
||||
checked={triggerStore.getTriggerType()}
|
||||
onChange={() => triggerStore.setTriggerType()}
|
||||
/>
|
||||
</div>
|
||||
<Title level={2}>
|
||||
Trigger editor: {triggerStore.getTriggerDescription()}
|
||||
</Title>
|
||||
<div style={{ width: "10px" }}></div>
|
||||
<Button onClick={() => triggerStore.saveResult()}>Save result</Button>
|
||||
</Row>
|
||||
);
|
||||
});
|
||||
|
||||
const Bottom = observer(() => {
|
||||
return (
|
||||
<Col>
|
||||
{triggerStore.triggers.map((el) => {
|
||||
return (
|
||||
<Row
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
{el.value}
|
||||
<DeleteIcon onClick={() => triggerStore.deleteItem(el.id)} />
|
||||
</Row>
|
||||
);
|
||||
})}
|
||||
</Col>
|
||||
);
|
||||
});
|
||||
|
||||
export const TriggerScreen: React.FunctionComponent = observer(() => {
|
||||
return (
|
||||
<>
|
||||
<main className="test">
|
||||
<Header />,
|
||||
{triggerStore.getTriggerType() ? (
|
||||
<>
|
||||
<FileTriggerForm />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<CodeTriggerForm />
|
||||
</>
|
||||
)}
|
||||
<Bottom />
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
});
|
16
ui/src/index.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
|
||||
|
||||
import { TriggerScreen } from './features/trigger/presentation/trigger_presentation';
|
||||
import "antd/dist/antd.css";
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById('root') as HTMLElement
|
||||
);
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<TriggerScreen />
|
||||
</React.StrictMode>
|
||||
);
|
1
ui/src/react-app-env.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/// <reference types="react-scripts" />
|
27
ui/tsconfig.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
"useDefineForClassFields": true
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|