commit ff1420271b3130b3fdfcae5194c6733cd1af1a76 Author: Rinsvent Date: Sat Jan 7 15:30:38 2023 +0700 first commit diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..55d3e94 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +.idea + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/README.md b/README.md new file mode 100644 index 0000000..c87e042 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file. + +[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`. + +The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/components/argument/index.tsx b/components/argument/index.tsx new file mode 100644 index 0000000..14285b5 --- /dev/null +++ b/components/argument/index.tsx @@ -0,0 +1,33 @@ +import styles from './styles.module.css' +import {useContext, useEffect, useState} from "react"; +import Context, {ContextInterface} from "../command/context"; + +export interface ArgumentInterface { + name: string, + description: string|null, + default: any, + isArray: boolean, + isRequired: boolean, +} + +export default function Argument(argument: ArgumentInterface) { + let {argumentList, setArgumentList} = useContext(Context) + let [value, setValue] = useState('') + + useEffect(() => { + let temp = { + ...argumentList, + } + temp[argument.name] = value + setArgumentList(temp) + }, [value]) + + let onInput = (event: any) => { + setValue(event.target.value) + } + return ( + +   + + ) +} diff --git a/components/argument/styles.module.css b/components/argument/styles.module.css new file mode 100644 index 0000000..e69de29 diff --git a/components/arguments/index.tsx b/components/arguments/index.tsx new file mode 100644 index 0000000..19c13c6 --- /dev/null +++ b/components/arguments/index.tsx @@ -0,0 +1,39 @@ +import styles from './styles.module.css' +import {useContext, useEffect, useState} from "react"; +import Argument, {ArgumentInterface} from "../argument"; +import Context, {ContextInterface} from "../command/context"; + +interface ArgumentsInterface { + argumentList: ArgumentInterface[] +} + +export default function Arguments({argumentList}: ArgumentsInterface) { + let {argumentList: al} = useContext(Context) + let [availableArguments, setAvailableArguments] = useState(argumentList); + + useEffect(() => { + let result: ArgumentInterface[] = []; + for (let argument of argumentList) { + result.push(argument) + if (!al[argument.name]) { + break + } + } + setAvailableArguments(result) + }, [al]); + + if (!argumentList.length) { + return <> + } + + return ( + <> + --  + {availableArguments.map((argument: ArgumentInterface, index: number) => { + return ( + + ) + })} + + ) +} diff --git a/components/arguments/styles.module.css b/components/arguments/styles.module.css new file mode 100644 index 0000000..e69de29 diff --git a/components/command/context.ts b/components/command/context.ts new file mode 100644 index 0000000..5fc101c --- /dev/null +++ b/components/command/context.ts @@ -0,0 +1,20 @@ +import React from 'react' + +interface SetOptionListInterface { + (optionList: Record): any +} + +interface SetArgumentListInterface { + (argumentList: Record): any +} + +export interface ContextInterface { + optionList: Record, + setOptionList: SetOptionListInterface + argumentList: Record, + setArgumentList: SetArgumentListInterface, +} + +const Context = React.createContext({} as ContextInterface) +export const Provider = Context.Provider +export default Context diff --git a/components/command/index.tsx b/components/command/index.tsx new file mode 100644 index 0000000..5060ef0 --- /dev/null +++ b/components/command/index.tsx @@ -0,0 +1,53 @@ +import styles from './styles.module.css' +import Options from "../options"; +import Arguments from "../arguments"; +import {OptionInterface} from "../option"; +import {ArgumentInterface} from "../argument"; +import {Provider} from "./context"; +import {useState} from "react"; + +export interface CommandInterface { + class: string, + name: string, + description: string, + options: OptionInterface[], + arguments: ArgumentInterface[], +} + +export default function Command(command: CommandInterface) { + const [optionList, setOptionList] = useState>({}); + const [argumentList, setArgumentList] = useState>({}); + + let onClick = async (event: any) => { + let url = `http://fmw.sipachev.sv/system-monitoring/commands/${command.name}/run` + let data = { + options: optionList, + arguments: argumentList, + } + console.log('data', data) + let response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json;charset=utf-8', + 'X-Plugin-Token': 'passw0rd' + }, + body: JSON.stringify(data) + }); + let result = await response.json(); + console.log('result', result) + } + return ( + +
+
+ {command.name}  + + +
+
+ +
+
+
+ ) +} diff --git a/components/command/styles.module.css b/components/command/styles.module.css new file mode 100644 index 0000000..84f4151 --- /dev/null +++ b/components/command/styles.module.css @@ -0,0 +1,4 @@ +.task { + display: grid; + grid-template-columns: 11fr 1fr; +} \ No newline at end of file diff --git a/components/option/index.tsx b/components/option/index.tsx new file mode 100644 index 0000000..9482095 --- /dev/null +++ b/components/option/index.tsx @@ -0,0 +1,33 @@ +import styles from './styles.module.css' +import {useContext} from "react"; +import Context, {ContextInterface} from "../command/context"; + +export interface OptionInterface { + name: string, + description: string | null, + default: any, + value: any, + shortcut: string | null, + isArray: boolean, + isNegatable: boolean, + isValueOptional: boolean, + isValueRequired: boolean + acceptValue: boolean +} + +export default function Option(option: OptionInterface) { + let {optionList: ol, setOptionList} = useContext(Context) + + let onInput = (event: any) => { + let temp = { + ...ol + } + temp[option.name] = event.target.value + setOptionList(temp) + } + return ( + + {option.shortcut ? '-' : '--'}{option.shortcut || option.name} {option.acceptValue && }  + + ) +} diff --git a/components/option/styles.module.css b/components/option/styles.module.css new file mode 100644 index 0000000..e69de29 diff --git a/components/options/index.tsx b/components/options/index.tsx new file mode 100644 index 0000000..6a6ea84 --- /dev/null +++ b/components/options/index.tsx @@ -0,0 +1,56 @@ +import styles from './styles.module.css' +import Option, {OptionInterface} from '../option' +import {useContext, useEffect, useState} from "react"; +import Context, {ContextInterface} from "../command/context"; + +interface OptionsInterface { + optionList: OptionInterface[] +} + +export default function Options({optionList}: OptionsInterface) { + let {optionList: ol, setOptionList} = useContext(Context) + let [availableOptions, setAvailableOptions] = useState(optionList); + let [values, setValues] = useState([]); + + useEffect(() => { + let result: OptionInterface[] = []; + optionList.forEach((value, index, array) => { + let check = values.find(item => item === value) + !check && result.push(value) + }) + setAvailableOptions(result) + }, [values]); + + if (!optionList.length) { + return <> + } + + let onChange = (event: any) => { + let selectedValue = event.target.value + let selectedOption = availableOptions.find(item => item.name === selectedValue) + selectedOption && values.push(selectedOption) + setValues([ ...values ]) + event.target.value = ''; + + let temp = { + ...ol + } + if (selectedOption) { + temp[selectedOption.name] = ''; + } + setOptionList(temp) + } + return ( + <> + {availableOptions.length > 0 && <> } + {values.map((option: OptionInterface, index: number) => ( +