перевод на jwt
This commit is contained in:
parent
de7a4b6d52
commit
92fd933c60
17
api/authentication.ts
Normal file
17
api/authentication.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export interface AuthenticationInterface {
|
||||||
|
key: string
|
||||||
|
token(): string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BearerAuthentication implements AuthenticationInterface {
|
||||||
|
key = 'Authorization'
|
||||||
|
_token: string
|
||||||
|
|
||||||
|
constructor(token: string) {
|
||||||
|
this._token = token
|
||||||
|
}
|
||||||
|
|
||||||
|
token(): string {
|
||||||
|
return `Bearer ${this._token}`;
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
import {AuthenticationInterface} from "./authentication";
|
||||||
|
|
||||||
export enum Method {
|
export enum Method {
|
||||||
GET = 'GET',
|
GET = 'GET',
|
||||||
POST = 'POST',
|
POST = 'POST',
|
||||||
@ -9,10 +11,6 @@ export let hasQuery = (method: Method) => {
|
|||||||
return Method.GET === method
|
return Method.GET === method
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClientOptions {
|
|
||||||
baseUrl: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SchemaInterface {
|
export interface SchemaInterface {
|
||||||
url: string,
|
url: string,
|
||||||
method: Method
|
method: Method
|
||||||
@ -25,12 +23,23 @@ export class Context {
|
|||||||
memoryKey?: string
|
memoryKey?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SchemaClientOptionsInterface {
|
||||||
|
baseUrl?: string
|
||||||
|
authentication?: AuthenticationInterface
|
||||||
|
}
|
||||||
|
|
||||||
export class SchemaClient {
|
export class SchemaClient {
|
||||||
baseUrl: string | null = null
|
baseUrl: string | null = null
|
||||||
|
authentication: AuthenticationInterface | null = null
|
||||||
context: Context | null = null
|
context: Context | null = null
|
||||||
|
|
||||||
memory: Record<string, any> = {}
|
memory: Record<string, any> = {}
|
||||||
|
|
||||||
|
constructor(options: SchemaClientOptionsInterface) {
|
||||||
|
this.baseUrl = options.baseUrl || null
|
||||||
|
this.authentication = options.authentication || null
|
||||||
|
}
|
||||||
|
|
||||||
debouncing(time: number)
|
debouncing(time: number)
|
||||||
{
|
{
|
||||||
let context = this.grabContext()
|
let context = this.grabContext()
|
||||||
@ -47,6 +56,10 @@ export class SchemaClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async send(schema: SchemaInterface, data: any) {
|
async send(schema: SchemaInterface, data: any) {
|
||||||
|
if (this.baseUrl === null) {
|
||||||
|
throw new Error('Base url not defined!');
|
||||||
|
}
|
||||||
|
|
||||||
let context = this.context
|
let context = this.context
|
||||||
this.context = null
|
this.context = null
|
||||||
|
|
||||||
@ -64,12 +77,22 @@ export class SchemaClient {
|
|||||||
preparedUrl += '?' + new URLSearchParams(preparedData)
|
preparedUrl += '?' + new URLSearchParams(preparedData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let token = ''
|
||||||
|
if (typeof localStorage !== 'undefined') {
|
||||||
|
let tokenId = localStorage.getItem('token')
|
||||||
|
token = localStorage.getItem(tokenId || '') || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
let headers: Record<string, any> = {
|
||||||
|
...(schema.contentType ? {'Content-Type': schema.contentType} : {}),
|
||||||
|
'X-Plugin-Token': 'passw0rd',
|
||||||
|
}
|
||||||
|
if (this.authentication) {
|
||||||
|
headers[this.authentication.key] = this.authentication.token();
|
||||||
|
}
|
||||||
let response = await fetch(preparedUrl, {
|
let response = await fetch(preparedUrl, {
|
||||||
method: schema.method.toString(),
|
method: schema.method.toString(),
|
||||||
headers: {
|
headers,
|
||||||
...(schema.contentType ? {'Content-Type': schema.contentType} : {}),
|
|
||||||
'X-Plugin-Token': 'passw0rd'
|
|
||||||
},
|
|
||||||
body: hasQuery(schema.method) ? null : JSON.stringify(preparedData)
|
body: hasQuery(schema.method) ? null : JSON.stringify(preparedData)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,11 +17,7 @@ import stopProcessSchema from "./schemas/stop-process";
|
|||||||
import killProcessSchema from "./schemas/kill-process";
|
import killProcessSchema from "./schemas/kill-process";
|
||||||
import commandSchema from "./schemas/command";
|
import commandSchema from "./schemas/command";
|
||||||
|
|
||||||
let baseUrl = typeof location !== 'undefined' && location.origin.includes('.wallester.') ? location.origin : 'http://fmw.sipachev.sv'
|
|
||||||
|
|
||||||
export class SMClient extends SchemaClient {
|
export class SMClient extends SchemaClient {
|
||||||
baseUrl = baseUrl
|
|
||||||
|
|
||||||
async getCommands(): Promise<ResponseInterface<CommandInterface[]>> {
|
async getCommands(): Promise<ResponseInterface<CommandInterface[]>> {
|
||||||
let { responseData, headers } = await this.send(commandsSchema, {})
|
let { responseData, headers } = await this.send(commandsSchema, {})
|
||||||
return {
|
return {
|
||||||
@ -104,6 +100,3 @@ export class SMClient extends SchemaClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export let smClient = new SMClient
|
|
||||||
export default smClient
|
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
import styles from './styles.module.css'
|
import styles from './styles.module.css'
|
||||||
import {Table, TableBody, TableCell, TableHead, TableRow, IconButton, Autocomplete, TextField} from "@mui/material";
|
import {IconButton, Autocomplete, TextField} from "@mui/material";
|
||||||
import Command from "./elements/command";
|
import Command from "./elements/command";
|
||||||
import {useContext, useEffect, useState} from "react";
|
import {useContext, useEffect, useState} from "react";
|
||||||
import PlayCircleOutline from '@mui/icons-material/PlayCircleOutline';
|
|
||||||
import ConfirmDialog from "../confirm-dialog";
|
import ConfirmDialog from "../confirm-dialog";
|
||||||
import TabContext from "../../../context/tab";
|
import TabContext from "../../../context/tab";
|
||||||
import {TabEnum} from "../../../pages";
|
import {TabEnum} from "../../../pages";
|
||||||
import smClient from "../../../api/sm/sm-client";
|
|
||||||
import Send from "@mui/icons-material/Send"
|
import Send from "@mui/icons-material/Send"
|
||||||
import {CommandInterface} from "../../../api/sm/responses/comamnds";
|
import {CommandInterface} from "../../../api/sm/responses/comamnds";
|
||||||
|
import {useApi} from "../../../hooks/use-api";
|
||||||
|
|
||||||
export default function Commands() {
|
export default function Commands() {
|
||||||
const {setTab} = useContext(TabContext)
|
const {setTab} = useContext(TabContext)
|
||||||
@ -18,9 +17,10 @@ export default function Commands() {
|
|||||||
const [argumentList, setArgumentList] = useState<Record<string, any>>({});
|
const [argumentList, setArgumentList] = useState<Record<string, any>>({});
|
||||||
const [value, setValue] = useState<string | null>('');
|
const [value, setValue] = useState<string | null>('');
|
||||||
const [open, setOpen] = useState<boolean>(false);
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
let refreshCommands = async () => {
|
let refreshCommands = async () => {
|
||||||
const { data: commands } = await smClient.useMemory().getCommands()
|
const { data: commands } = await api.useMemory().getCommands()
|
||||||
setCommands(commands)
|
setCommands(commands)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ export default function Commands() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
lock = true
|
lock = true
|
||||||
await smClient.runCommand({
|
await api.runCommand({
|
||||||
commandName: selectedCommand.name,
|
commandName: selectedCommand.name,
|
||||||
options: optionList,
|
options: optionList,
|
||||||
arguments: argumentList,
|
arguments: argumentList,
|
||||||
|
@ -25,11 +25,11 @@ import {
|
|||||||
TablePagination, Autocomplete
|
TablePagination, Autocomplete
|
||||||
} from "@mui/material"
|
} from "@mui/material"
|
||||||
import ConfirmDialog from "../confirm-dialog";
|
import ConfirmDialog from "../confirm-dialog";
|
||||||
import smClient from "../../../api/sm/sm-client";
|
|
||||||
import {ProcessInterface, Status} from "../../../api/sm/responses/processes";
|
import {ProcessInterface, Status} from "../../../api/sm/responses/processes";
|
||||||
import Command from "../commands/elements/command";
|
import Command from "../commands/elements/command";
|
||||||
import {CommandInterface} from "../../../api/sm/responses/comamnds";
|
import {CommandInterface} from "../../../api/sm/responses/comamnds";
|
||||||
import Grid from '@mui/material/Grid';
|
import Grid from '@mui/material/Grid';
|
||||||
|
import {useApi} from "../../../hooks/use-api";
|
||||||
|
|
||||||
enum Action {
|
enum Action {
|
||||||
Run,
|
Run,
|
||||||
@ -54,11 +54,12 @@ export default function Processes() {
|
|||||||
const [selectedProcess, setSelectedProcess] = useState<ProcessInterface | null>(null);
|
const [selectedProcess, setSelectedProcess] = useState<ProcessInterface | null>(null);
|
||||||
const [optionList, setOptionList] = useState<Record<string, any>>({});
|
const [optionList, setOptionList] = useState<Record<string, any>>({});
|
||||||
const [argumentList, setArgumentList] = useState<Record<string, any>>({});
|
const [argumentList, setArgumentList] = useState<Record<string, any>>({});
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
let variants = commands.map((command: CommandInterface, index: number) => command.name);
|
let variants = commands.map((command: CommandInterface, index: number) => command.name);
|
||||||
|
|
||||||
let refreshCommands = async () => {
|
let refreshCommands = async () => {
|
||||||
const { data: commands } = await smClient.useMemory().getCommands()
|
const { data: commands } = await api.useMemory().getCommands()
|
||||||
setCommands(commands)
|
setCommands(commands)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ export default function Processes() {
|
|||||||
if (!!name) {
|
if (!!name) {
|
||||||
data['name'] = name
|
data['name'] = name
|
||||||
}
|
}
|
||||||
const { data: processes, headers } = await smClient.getProcesses({
|
const { data: processes, headers } = await api.getProcesses({
|
||||||
...data,
|
...data,
|
||||||
page: page + 1,
|
page: page + 1,
|
||||||
limit: 20,
|
limit: 20,
|
||||||
@ -91,7 +92,7 @@ export default function Processes() {
|
|||||||
refreshLock = false
|
refreshLock = false
|
||||||
}
|
}
|
||||||
let output = async (process: ProcessInterface) => {
|
let output = async (process: ProcessInterface) => {
|
||||||
const { data: output } = await smClient.getProcessOutput({
|
const { data: output } = await api.getProcessOutput({
|
||||||
id: process.id
|
id: process.id
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -136,7 +137,7 @@ export default function Processes() {
|
|||||||
lock = true
|
lock = true
|
||||||
|
|
||||||
if (action === Action.Run) {
|
if (action === Action.Run) {
|
||||||
await smClient.runCommand({
|
await api.runCommand({
|
||||||
commandName: selectedProcess.name,
|
commandName: selectedProcess.name,
|
||||||
options: optionList,
|
options: optionList,
|
||||||
arguments: argumentList,
|
arguments: argumentList,
|
||||||
@ -145,7 +146,7 @@ export default function Processes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action === Action.Repeat) {
|
if (action === Action.Repeat) {
|
||||||
await smClient.repeatProcess({
|
await api.repeatProcess({
|
||||||
id: selectedProcess.id,
|
id: selectedProcess.id,
|
||||||
requestId: dialogId
|
requestId: dialogId
|
||||||
})
|
})
|
||||||
@ -278,7 +279,7 @@ export default function Processes() {
|
|||||||
modifyCallback={async () => {
|
modifyCallback={async () => {
|
||||||
setAction(Action.Run)
|
setAction(Action.Run)
|
||||||
setModalLoading(true)
|
setModalLoading(true)
|
||||||
let {data: command} = await smClient.getCommand(selectedProcess.name)
|
let {data: command} = await api.getCommand(selectedProcess.name)
|
||||||
setCommand(command)
|
setCommand(command)
|
||||||
setModalLoading(false)
|
setModalLoading(false)
|
||||||
}}
|
}}
|
||||||
@ -303,10 +304,10 @@ export default function Processes() {
|
|||||||
title={`Are you sure?`}
|
title={`Are you sure?`}
|
||||||
open={ !!action && ([Action.Play, Action.Pause, Action.Stop, Action.Kill].indexOf(action) > -1) }
|
open={ !!action && ([Action.Play, Action.Pause, Action.Stop, Action.Kill].indexOf(action) > -1) }
|
||||||
agreeCallback={async () => {
|
agreeCallback={async () => {
|
||||||
Action.Play === action && await smClient.playProcess(selectedProcess.id)
|
Action.Play === action && await api.playProcess(selectedProcess.id)
|
||||||
Action.Pause === action && await smClient.pauseProcess(selectedProcess.id)
|
Action.Pause === action && await api.pauseProcess(selectedProcess.id)
|
||||||
Action.Stop === action && await smClient.stopProcess(selectedProcess.id)
|
Action.Stop === action && await api.stopProcess(selectedProcess.id)
|
||||||
Action.Kill === action && await smClient.killProcess(selectedProcess.id)
|
Action.Kill === action && await api.killProcess(selectedProcess.id)
|
||||||
setAction(null)
|
setAction(null)
|
||||||
}}
|
}}
|
||||||
closeCallback={() => {setAction(null)}}>
|
closeCallback={() => {setAction(null)}}>
|
||||||
|
6
context/token.ts
Normal file
6
context/token.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {UseTokenInterface} from "../hooks/use-token"
|
||||||
|
|
||||||
|
const Context = React.createContext({} as UseTokenInterface)
|
||||||
|
export const Provider = Context.Provider
|
||||||
|
export default Context
|
120
functions/token.ts
Normal file
120
functions/token.ts
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export interface TokenData<T=any> {
|
||||||
|
payload: T
|
||||||
|
headers: Record<string, any>
|
||||||
|
}
|
||||||
|
|
||||||
|
const isClient = () => {
|
||||||
|
return typeof window !== 'undefined'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const storeToken = (token: string) => {
|
||||||
|
if (!isClient()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let tokenData = grabTokenData(token)
|
||||||
|
let tokenId = tokenData?.payload?.id;
|
||||||
|
if (!tokenId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tokens: string | null = window.localStorage.getItem('tokens')
|
||||||
|
let tokensData: string[] = JSON.parse(tokens || '[]');
|
||||||
|
if (!tokensData) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
window.localStorage.setItem('token', tokenId)
|
||||||
|
window.localStorage.setItem(tokenId, token)
|
||||||
|
tokensData.push(tokenId)
|
||||||
|
window.localStorage.setItem('tokens', JSON.stringify(tokensData))
|
||||||
|
}
|
||||||
|
|
||||||
|
export const cleanToken = (id: string) => {
|
||||||
|
if (!isClient()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let tokens: string | null = window.localStorage.getItem('tokens')
|
||||||
|
let tokensData: string[] = JSON.parse(tokens || '[]');
|
||||||
|
if (!tokensData) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tokensData = tokensData.filter((storedTokenId: string) => storedTokenId !== id)
|
||||||
|
window.localStorage.setItem('tokens', JSON.stringify(tokensData))
|
||||||
|
window.localStorage.removeItem(id)
|
||||||
|
|
||||||
|
// Чистим текущий токен
|
||||||
|
let activeTokenId: string | null = window.localStorage.getItem('token')
|
||||||
|
if (id === activeTokenId) {
|
||||||
|
window.localStorage.removeItem('token')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const selectToken = (id: string) => {
|
||||||
|
if (!isClient()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.localStorage.setItem('token', id)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const grabTokenData = (token: string): TokenData|null => {
|
||||||
|
if (!isClient()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const parts = token.split('.')
|
||||||
|
let payload = 3 === parts.length && parts[1] ? JSON.parse(window.atob(parts[1])) : null
|
||||||
|
let headers = 3 === parts.length && parts[0] ? JSON.parse(window.atob(parts[0])) : null
|
||||||
|
if (!payload || !headers){
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
payload,
|
||||||
|
headers,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const grabRawToken = (): string | null => {
|
||||||
|
if (!isClient()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const tokenId = window.localStorage.getItem('token')
|
||||||
|
if (!tokenId) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return window.localStorage.getItem(tokenId)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const grabToken = (): TokenData | null => {
|
||||||
|
const token = grabRawToken()
|
||||||
|
if (!token) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return grabTokenData(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const grabTokens = (): TokenData[] => {
|
||||||
|
if (!isClient()) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
const storedTokens = window.localStorage.getItem('tokens')
|
||||||
|
let tokens: string[] = JSON.parse(storedTokens || '[]');
|
||||||
|
if (!tokens) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: TokenData[] = []
|
||||||
|
|
||||||
|
tokens.forEach((tokenId) => {
|
||||||
|
let token = window.localStorage.getItem(tokenId)
|
||||||
|
if (!token) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
let tokenData = grabTokenData(token)
|
||||||
|
if (tokenData) {
|
||||||
|
result.push(tokenData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
30
hooks/use-api.ts
Normal file
30
hooks/use-api.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import {useContext, useEffect, useState} from 'react'
|
||||||
|
import {SMClient} from "../api/sm/sm-client";
|
||||||
|
import Context from "../context/token";
|
||||||
|
import {Token} from "./use-token";
|
||||||
|
import {BearerAuthentication} from "../api/authentication";
|
||||||
|
import {grabRawToken} from "../functions/token";
|
||||||
|
|
||||||
|
const grabClient = (token: Token | null, rawToken: string | null): SMClient => {
|
||||||
|
let authentication = {}
|
||||||
|
if (rawToken) {
|
||||||
|
authentication = {
|
||||||
|
authentication: new BearerAuthentication(rawToken)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SMClient({
|
||||||
|
baseUrl: 'http://' + (token?.host || 'localhost'),
|
||||||
|
...authentication
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useApi(): SMClient {
|
||||||
|
let {token} = useContext(Context)
|
||||||
|
let [client, setClient] = useState<SMClient>(grabClient(token, grabRawToken()))
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setClient(grabClient(token, grabRawToken()))
|
||||||
|
}, [token])
|
||||||
|
|
||||||
|
return client
|
||||||
|
}
|
48
hooks/use-token.ts
Normal file
48
hooks/use-token.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import {useState, useEffect} from 'react'
|
||||||
|
import {cleanToken, grabToken, grabTokens, selectToken, storeToken} from "../functions/token";
|
||||||
|
|
||||||
|
export class Token {
|
||||||
|
id!: string
|
||||||
|
host!: string
|
||||||
|
permissions!: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UseTokenInterface {
|
||||||
|
token: Token|null
|
||||||
|
tokens: Token[]
|
||||||
|
switchToken(tokenId: string): void
|
||||||
|
deleteToken(tokenId: string): void
|
||||||
|
addToken(tokenId: string): void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useToken(): UseTokenInterface {
|
||||||
|
const [token, setToken] = useState<Token|null>(null);
|
||||||
|
const [tokens, setTokens] = useState<Token[]>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
setToken(grabToken()?.payload)
|
||||||
|
|
||||||
|
let tokens = grabTokens().map((tokenData) => tokenData.payload)
|
||||||
|
setTokens(tokens)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const switchToken = (tokenId: string) => {
|
||||||
|
selectToken(tokenId)
|
||||||
|
setToken(grabToken()?.payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteToken = (tokenId: string) => {
|
||||||
|
cleanToken(tokenId)
|
||||||
|
setToken(grabToken()?.payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
const addToken = (token: string) => {
|
||||||
|
storeToken(token)
|
||||||
|
setToken(grabToken()?.payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {token, tokens, switchToken, deleteToken, addToken}
|
||||||
|
}
|
@ -1,6 +1,13 @@
|
|||||||
import '../styles/globals.css'
|
import '../styles/globals.css'
|
||||||
import type { AppProps } from 'next/app'
|
import type { AppProps } from 'next/app'
|
||||||
|
import {Provider} from "../context/token";
|
||||||
|
import {useToken} from "../hooks/use-token";
|
||||||
|
|
||||||
export default function App({ Component, pageProps }: AppProps) {
|
export default function App({ Component, pageProps }: AppProps) {
|
||||||
return <Component {...pageProps} />
|
let {token, tokens, switchToken, deleteToken, addToken} = useToken()
|
||||||
|
return (
|
||||||
|
<Provider value={{token, tokens, switchToken, deleteToken, addToken}}>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</Provider>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import styles from '../styles/Home.module.css'
|
import styles from '../styles/Home.module.css'
|
||||||
import Processes from "../components/elements/processes";
|
import Processes from "../components/elements/processes";
|
||||||
import {Tabs, Tab} from '@mui/material';
|
import {Tabs, Tab, MenuItem, Select, InputLabel, TextareaAutosize, Button} from '@mui/material';
|
||||||
import {useState} from "react";
|
import {useContext, useEffect, useState} from "react";
|
||||||
import Commands from "../components/elements/commands";
|
import Commands from "../components/elements/commands";
|
||||||
import {Provider as TabProvider} from '../context/tab'
|
import {Provider as TabProvider} from '../context/tab'
|
||||||
|
import Context from "../context/token";
|
||||||
|
|
||||||
|
|
||||||
export enum TabEnum {
|
export enum TabEnum {
|
||||||
Commands,
|
Commands,
|
||||||
@ -12,8 +14,42 @@ export enum TabEnum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
let {token, tokens, addToken} = useContext(Context)
|
||||||
const [tab, setTab] = useState<TabEnum>(TabEnum.Processes);
|
const [tab, setTab] = useState<TabEnum>(TabEnum.Processes);
|
||||||
const handleChange = (event: any, tab: number) => setTab(tab)
|
const handleChange = (event: any, tab: number) => setTab(tab)
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// const storedToken = grabToken()
|
||||||
|
// setToken(storedToken)
|
||||||
|
// const storedTokens = grabTokens()
|
||||||
|
// setTokens(storedTokens)
|
||||||
|
// }, [])
|
||||||
|
|
||||||
|
let onTokenInput = (event: any) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>System monitoring</title>
|
||||||
|
<meta name="description" content="System monitoring service"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
<link rel="icon" href="/favicon.ico"/>
|
||||||
|
</Head>
|
||||||
|
<main className={styles.main}>
|
||||||
|
<h2>Для дальнейшей работы добавьте JWT токен</h2>
|
||||||
|
<TextareaAutosize
|
||||||
|
minRows={20}
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
onInput={(event: any) => addToken(event.target.value)}
|
||||||
|
/>
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
@ -23,21 +59,46 @@ export default function Home() {
|
|||||||
<link rel="icon" href="/favicon.ico"/>
|
<link rel="icon" href="/favicon.ico"/>
|
||||||
</Head>
|
</Head>
|
||||||
<main className={styles.main}>
|
<main className={styles.main}>
|
||||||
<Tabs
|
{tokens.length > 0 && <>
|
||||||
value={tab}
|
<InputLabel id="tokens">Tokens</InputLabel>
|
||||||
onChange={handleChange}
|
<Select
|
||||||
variant="scrollable"
|
value={token}
|
||||||
scrollButtons
|
labelId="tokens"
|
||||||
allowScrollButtonsMobile
|
id="demo-simple-select-autowidth"
|
||||||
aria-label="scrollable force tabs example"
|
label="Tokens"
|
||||||
>
|
onChange={(event: any) => {
|
||||||
<Tab value={TabEnum.Commands} label="Commands" />
|
// selectToken(event.target.value)
|
||||||
<Tab value={TabEnum.Processes} label="Processes" />
|
// const storedToken = grabToken()
|
||||||
</Tabs>
|
// setToken(storedToken)
|
||||||
<TabProvider value={{tab, setTab}}>
|
// if (storedToken) {
|
||||||
{tab === TabEnum.Commands && <Commands />}
|
// smClient.baseUrl = storedToken.payload.host
|
||||||
{tab === TabEnum.Processes && <Processes />}
|
// }
|
||||||
</TabProvider>
|
}}
|
||||||
|
>
|
||||||
|
{tokens.map((token, index) => (
|
||||||
|
<MenuItem key={index} value={index}>{token.host}</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</>}
|
||||||
|
|
||||||
|
|
||||||
|
{token && <>
|
||||||
|
<Tabs
|
||||||
|
value={tab}
|
||||||
|
onChange={handleChange}
|
||||||
|
variant="scrollable"
|
||||||
|
scrollButtons
|
||||||
|
allowScrollButtonsMobile
|
||||||
|
aria-label="scrollable force tabs example"
|
||||||
|
>
|
||||||
|
<Tab value={TabEnum.Commands} label="Commands" />
|
||||||
|
<Tab value={TabEnum.Processes} label="Processes" />
|
||||||
|
</Tabs>
|
||||||
|
<TabProvider value={{tab, setTab}}>
|
||||||
|
{tab === TabEnum.Commands && <Commands />}
|
||||||
|
{tab === TabEnum.Processes && <Processes />}
|
||||||
|
</TabProvider>
|
||||||
|
</>}
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user