diff --git a/cadio-web/src/main/webapp/src/App.js b/cadio-web/src/main/webapp/src/App.js index 1e122c5e..fa5413e0 100644 --- a/cadio-web/src/main/webapp/src/App.js +++ b/cadio-web/src/main/webapp/src/App.js @@ -14,17 +14,14 @@ import TableHome from "./pages/cluster/components/keyspace/table/table-home"; import QueryHome from "./pages/cluster/components/query-home"; import MetricsHome from "./pages/cluster/components/metrics-home"; import {useEffect} from "react"; -import useCadio from "./pages/commons/hooks/useCadio"; -import {useCadioState} from "./pages/commons/context/cadioContext"; +import useCadio from "./commons/hooks/useCadio"; +import {useCadioState} from "./commons/context/cadioContext"; import NodesHome from "./pages/cluster/components/nodes-home"; import SystemView from "./pages/system/system-view"; -import TableRow from "./pages/cluster/components/keyspace/table/table-row"; -import TableInformation from "./pages/cluster/components/keyspace/table/table-information"; -import TableImport from "./pages/cluster/components/keyspace/table/table-import"; -import TableExport from "./pages/cluster/components/keyspace/table/table-export"; import LoadingView from "./pages/loading-view"; import SystemHome from "./pages/system/components/system-home"; import SystemClusterManageHome from "./pages/system/components/cluster/system-cluster-manage-home"; +import CadioToast from "./components/cadio-toast"; function App() { const {doBootstrap} = useCadio(); @@ -69,32 +66,20 @@ function App() { element={}> }> - }> - }> - }> + }> - + }> - + }> {/* 상단에 위치하는 라우트들의 규칙을 모두 확인, 일치하는 라우트가 없는경우 처리 */} }> + ) diff --git a/cadio-web/src/main/webapp/src/pages/commons/context/cadioContext.tsx b/cadio-web/src/main/webapp/src/commons/context/cadioContext.tsx similarity index 62% rename from cadio-web/src/main/webapp/src/pages/commons/context/cadioContext.tsx rename to cadio-web/src/main/webapp/src/commons/context/cadioContext.tsx index a63d757a..99d054df 100644 --- a/cadio-web/src/main/webapp/src/pages/commons/context/cadioContext.tsx +++ b/cadio-web/src/main/webapp/src/commons/context/cadioContext.tsx @@ -3,12 +3,16 @@ import React, {createContext, Dispatch, useContext, useReducer} from "react"; type CadioState = { bootstrapLoading: boolean, systemAvailable: boolean, + toasts?: any[], }; type Action = | { type: "SET_BOOTSTRAP_LOADING"; bootstrapLoading: boolean; } | { type: "SET_SYSTEM_AVAILABLE"; systemAvailable: boolean; } + | { type: "SET_TOAST"; message: string, delay: number } + | { type: "REMOVE_TOAST_ITEM"; id: number } + type CadioDispatch = Dispatch; const CadioStateContext = createContext(null); @@ -18,6 +22,7 @@ export function CadioProvider({children}: { children: React.ReactNode }) { const [state, dispatch] = useReducer(reducer, { bootstrapLoading: false, systemAvailable: false, + toasts: undefined, }); return ( @@ -41,6 +46,38 @@ function reducer(state: CadioState, action: Action): CadioState { ...state, systemAvailable: action.systemAvailable }; + // case "SET_TOASTS": + // return { + // ...state, + // toasts: action.toasts + // }; + case "SET_TOAST": + const arr = state.toasts ? [...state.toasts] : []; + arr.push({ + id : new Date().getTime(), + message: action.message, + delay: action.delay, + }); + return { + ...state, + toasts: arr + }; + case "REMOVE_TOAST_ITEM": + const arr2 = state.toasts; + //ID 추가 해서 그거 지울 수 있게 해야함 + + if (!arr2) { + return { + ...state, + }; + } + + return { + ...state, + //양이 많을 경우 누락됨. + toasts: arr2.filter(info => info.id !== action.id) + }; + default: throw new Error("Unhandled action"); } diff --git a/cadio-web/src/main/webapp/src/commons/hooks/useCadio.js b/cadio-web/src/main/webapp/src/commons/hooks/useCadio.js new file mode 100644 index 00000000..3aade76b --- /dev/null +++ b/cadio-web/src/main/webapp/src/commons/hooks/useCadio.js @@ -0,0 +1,93 @@ +import axios from "axios"; +import {useCadioDispatch} from "../context/cadioContext"; + + +export default function useCadio() { + const cadioDispatcher = useCadioDispatch(); + + function doBootstrap() { + cadioDispatcher({ + type: "SET_BOOTSTRAP_LOADING", + bootstrapLoading: true, + }) + axios({ + method: "GET", + url: `/api/bootstrap`, + params: {} + }).then((response) => { + cadioDispatcher({ + type: "SET_SYSTEM_AVAILABLE", + systemAvailable: response.data.result.systemAvailable, + //systemAvailable: false, + }) + + }).catch((error) => { + errorCatch(error); + }).finally(() => { + cadioDispatcher({ + type: "SET_BOOTSTRAP_LOADING", + bootstrapLoading: false, + }) + }); + } + + function openToast(message) { + if (!message) { + return; + } + cadioDispatcher({ + type: "SET_TOAST", + message: message, + delay: 3000, + }) + } + + function errorCatch(error) { + if (axios.isAxiosError(error)) { + const {message} = error; + const {method, url} = error.config; + const {status, statusText} = error.response; + + console.error( + `[API] ${method?.toUpperCase()} ${url} | Error ${status} ${statusText} | ${message}` + ); + + switch (status) { + case 400: + alert(`${status} 잘못된 요청입니다.`); + break; + case 401: { + alert(`${status} 인증 실패입니다.`); + break; + } + case 403: { + alert(`${status} 권한이 없습니다.`); + break; + } + case 404: { + alert(`${status} 찾을 수 없는 페이지입니다.`); + break; + } + case 500: { + openToast(`${status} 서버 오류입니다.`); + break; + } + default: { + alert(`${status} 에러가 발생했습니다. ${error.message}`); + } + } + } else if (error instanceof Error && error.name === "TimeoutError") { + console.error(`[API] | TimeError ${error.toString()}`); + alert(`${0} 요청 시간이 초과되었습니다.`); + } else { + console.error(`[API] | Error ${error.toString()}`); + alert(`${0} 에러가 발생했습니다. ${error.toString()}`); + } + } + + return { + doBootstrap, + openToast, + errorCatch, + } +} diff --git a/cadio-web/src/main/webapp/src/components/cadio-toast.js b/cadio-web/src/main/webapp/src/components/cadio-toast.js new file mode 100644 index 00000000..2913c5f6 --- /dev/null +++ b/cadio-web/src/main/webapp/src/components/cadio-toast.js @@ -0,0 +1,71 @@ +import {Toast, ToastContainer} from "react-bootstrap"; +import {useCadioDispatch, useCadioState} from "../commons/context/cadioContext"; +import {useEffect} from "react"; +import dayjs from "dayjs"; + +export default function CadioToast(props) { + const cadioDispatcher = useCadioDispatch(); + // const { + // openToast + // } = useCadio(); + const { + toasts, + } = useCadioState(); + + const removeToast = (id) => { + cadioDispatcher({ + type: "REMOVE_TOAST_ITEM", + id: id + }) + } + + useEffect(() => { + //show component + + return () => { + //hide component + + }; + }, []); + + return ( + + { + toasts && toasts.map((toast, toastIndex) => { + if (!toast) { + return (<>) + } + + return ( + { + removeToast(toast.id); + }} + > +
+ + {/**/} + {/* Cadio*/} + {/* test*/} + {/**/} + {toast.message || '내용이 비어 있습니다.'} + +
+
+ ) + }) + } +
+ ) +} diff --git a/cadio-web/src/main/webapp/src/index.js b/cadio-web/src/main/webapp/src/index.js index 85ebbb34..cf5fb905 100644 --- a/cadio-web/src/main/webapp/src/index.js +++ b/cadio-web/src/main/webapp/src/index.js @@ -2,7 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import {ClusterProvider} from "./pages/cluster/context/clusterContext"; -import {CadioProvider} from "./pages/commons/context/cadioContext"; +import {CadioProvider} from "./commons/context/cadioContext"; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/keyspace-home.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/keyspace-home.js index 0c04e69f..c4b658af 100644 --- a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/keyspace-home.js +++ b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/keyspace-home.js @@ -4,12 +4,12 @@ import {useEffect, useState} from "react"; import axios from "axios"; import Spinner from "../../../../components/spinner"; import KeyspaceTableList from "./keyspace-table-list"; -import {axiosCatch} from "../../../../utils/axiosUtils"; +import useCadio from "../../../../commons/hooks/useCadio"; const KeyspaceHome = () => { const routeParams = useParams(); - + const {errorCatch} = useCadio(); //const {doGetKeyspaceList} = useCluster(); const { keyspaceList, @@ -47,7 +47,7 @@ const KeyspaceHome = () => { } }).catch((error) => { - axiosCatch(error) + errorCatch(error) }).finally(() => { setDetailLoading(false) }); diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/keyspace-table-list.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/keyspace-table-list.js index ce242956..8cd2bc99 100644 --- a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/keyspace-table-list.js +++ b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/keyspace-table-list.js @@ -21,17 +21,16 @@ const KeyspaceTableList = ({clusterId, keyspaceName, tableList}) => { {tableList.map((info, infoIndex) => (
  • -
    {info.table_name}
    +
    { + setTableName(info.table_name); + setShowDetail(true); + }}> + {info.table_name} +
    {info.comment}
    - Rows diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-data-manage-modal.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-data-manage-modal.js new file mode 100644 index 00000000..ba74e17d --- /dev/null +++ b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-data-manage-modal.js @@ -0,0 +1,37 @@ +import {useEffect} from "react"; +import {Modal} from "react-bootstrap"; + +const TableDataManageModal = (props) => { + + const show = props.show; + const handleClose = props.handleClose; + + useEffect(() => { + //show component + + return () => { + //hide component + + }; + }, []); + + return ( + <> + + + Table Data Manage(New or Modify) + + + 데이터 신규 추가 및 수정 + + + + + + + ) +} + +export default TableDataManageModal; diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-detail-modal.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-detail-modal.js index cab89318..a42105dc 100644 --- a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-detail-modal.js +++ b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-detail-modal.js @@ -1,7 +1,7 @@ import {useEffect, useState} from "react"; import axios from "axios"; -import {axiosCatch} from "../../../../../utils/axiosUtils"; import {Modal} from "react-bootstrap"; +import useCadio from "../../../../../commons/hooks/useCadio"; const TableDetailModal = (props) => { @@ -11,7 +11,7 @@ const TableDetailModal = (props) => { const clusterId = props.clusterId; const keyspaceName = props.keyspaceName; const tableName = props.tableName; - + const {errorCatch} = useCadio(); const [tableLoading, setTableLoading] = useState(false); const [tableInfo, setTableInfo] = useState({ table: {}, @@ -37,7 +37,7 @@ const TableDetailModal = (props) => { if (!tableName) { return; } - + setTableLoading(true); axios({ method: "GET", url: `/api/cassandra/cluster/${clusterId}/keyspace/${keyspaceName}/table/${tableName}`, @@ -53,8 +53,7 @@ const TableDetailModal = (props) => { }) }).catch((error) => { - console.log(error) - axiosCatch(error) + errorCatch(error) }).finally(() => { setTableLoading(false) }); @@ -199,7 +198,7 @@ const TableDetailModal = (props) => { diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-export-modal.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-export-modal.js new file mode 100644 index 00000000..5cd82466 --- /dev/null +++ b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-export-modal.js @@ -0,0 +1,37 @@ +import {useEffect} from "react"; +import {Modal} from "react-bootstrap"; + +const TableExportModal = (props) => { + + const show = props.show; + const handleClose = props.handleClose; + + useEffect(() => { + //show component + + return () => { + //hide component + + }; + }, []); + + return ( + <> + + + 데이터 추출 + + + Export 기능 + + + + + + + ) +} + +export default TableExportModal; diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-export.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-export.js deleted file mode 100644 index 5d9f259a..00000000 --- a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-export.js +++ /dev/null @@ -1,10 +0,0 @@ -const TableExport = () => { - - return ( - <> - Export - - ) -} - -export default TableExport; diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-home.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-home.js index 5a120752..cd8e68e3 100644 --- a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-home.js +++ b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-home.js @@ -1,22 +1,78 @@ import {Link, useParams} from "react-router-dom"; -import {useClusterState} from "../../../context/clusterContext"; -import {useEffect} from "react"; +import {useEffect, useState} from "react"; +import TableDetailModal from "./table-detail-modal"; +import axios from "axios"; +import TableDataManageModal from "./table-data-manage-modal"; +import TableExportModal from "./table-export-modal"; +import TableImportModal from "./table-import-modal"; +import useCadio from "../../../../../commons/hooks/useCadio"; const TableHome = (props) => { const routeParams = useParams(); + const [showDetail, setShowDetail] = useState(false); + const [showExport, setShowExport] = useState(false); + const [showImport, setShowImport] = useState(false); + const [showDataManage, setShowDataManage] = useState(false); + const [tableName, setTableName] = useState(''); + const {errorCatch} = useCadio(); + const initQueryResult = { + wasApplied: null, + rows: [], + columnNames: [], + }; + + const [queryLoading, setQueryLoading] = useState(false) + const [queryResult, setQueryResult] = useState(initQueryResult) + const [nextCursor, setNextCursor] = useState('') + + const getList = (cursor) => { + if (cursor === null) { + setQueryResult({ + wasApplied: null, + rows: [], + columnNames: [], + }) + } + + setQueryLoading(true); + + axios({ + method: "POST", + url: `/api/cassandra/cluster/${routeParams.clusterId}/keyspace/${routeParams.keyspaceName}/table/${routeParams.tableName}/row`, + data: { + pageSize: 50, + timeoutSeconds: 3, + cursor: cursor, + }, + }).then((response) => { + setNextCursor(response.data.result.nextCursor) + + setQueryResult({ + wasApplied: response.data.result.wasApplied, + rows: [...queryResult.rows, ...response.data.result.rows], + columnNames: response.data.result.columnNames, + }) + }).catch((error) => { + errorCatch(error); + }).finally(() => { + setQueryLoading(false); + }) + } + + const renderData = (data) => { + if (typeof data === "object") { + return JSON.stringify(data); + } + + return data; + } - //const {doGetKeyspaceList} = useCluster(); - const { - keyspaceList, - keyspaceListLoading, - } = useClusterState(); useEffect(() => { //show component - console.log("routeParams ", routeParams.clusterId) - console.log("routeParams ", routeParams.keyspaceName) - console.log("routeParams ", routeParams.tableName) + setQueryResult(initQueryResult); + getList(null) return () => { //hide component @@ -50,68 +106,150 @@ const TableHome = (props) => {
    -

    Table

    - {/*
    */} - {/*
    */} - {/* */} - {/* */} - {/*
    */} - {/* */} - {/*
    */} +

    + Table { + queryLoading && +
    + Loading... +
    + } +

    +
    + + +
    + + +
    + + +
    -
      -
    • - - Home - -
    • -
    • - - Rows - -
    • -
    • - -
        -
      • - - Export - -
      • -
      • - - Import - -
      • - {/*
      • */} - {/*
        */} - {/*
      • */} - {/*
      • Separated link
      • */} -
      -
    • - {/*
    • */} - {/* Link*/} - {/*
    • */} - {/*
    • */} - {/* Disabled*/} - {/*
    • */} -
    - - {props.children} + {/*TODO : 위치 변경*/} + + +
    + + + + + { + queryResult.columnNames.map((info, infoIndex) => { + return ( + + ) + }) + } + + + + { + queryResult.rows.length <= 0 ? <> + + + + : + queryResult.rows.map((row, rowIndex) => { + return ( + + + { + queryResult.columnNames.map((info, infoIndex) => { + return ( + + ) + }) + } + + ) + }) + } + + +
    # + {info}
    + 데이터가 없습니다. +
    +
    + + + +
    +
    + { + renderData(row[info]) + } +
    +
    + + { + nextCursor && +
    + +
    + } + + setShowDetail(false)} + /> + + setShowDataManage(false)} + /> + + setShowExport(false)} + /> + + setShowImport(false)} + /> + ) } diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-import-modal.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-import-modal.js new file mode 100644 index 00000000..4cfac267 --- /dev/null +++ b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-import-modal.js @@ -0,0 +1,37 @@ +import {useEffect} from "react"; +import {Modal} from "react-bootstrap"; + +const TableImportModal = (props) => { + + const show = props.show; + const handleClose = props.handleClose; + + useEffect(() => { + //show component + + return () => { + //hide component + + }; + }, []); + + return ( + <> + + + 데이터 추가 + + + Import 기능 + + + + + + + ) +} + +export default TableImportModal; diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-import.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-import.js deleted file mode 100644 index 31716a49..00000000 --- a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-import.js +++ /dev/null @@ -1,10 +0,0 @@ -const TableImport = () => { - - return ( - <> - Infomation - - ) -} - -export default TableImport; diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-information.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-information.js deleted file mode 100644 index 21ecb726..00000000 --- a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-information.js +++ /dev/null @@ -1,79 +0,0 @@ -import {useEffect, useState} from "react"; -import {useParams} from "react-router-dom"; -import axios from "axios"; -import {axiosCatch} from "../../../../../utils/axiosUtils"; - -const TableInformation = () => { - - const routeParams = useParams(); - - const [tableLoading, setTableLoading] = useState(false); - - const [tableInfo, setTableInfo] = useState({ - table: {}, - describe: {}, - columns: [], - }) - - const splitTableOptionList = (options) => { - if (!options || options.length <= 0) { - return []; - } - const allOptionKeys = Object.keys(options); - const half = Math.ceil(allOptionKeys.length / 2); - const result = []; - result.push(allOptionKeys.splice(0, half)) - result.push(allOptionKeys.splice(-half)); - - return result; - } - - - useEffect(() => { - //show component - - console.log("routeParams ", routeParams.clusterId) - console.log("routeParams ", routeParams.keyspaceName) - console.log("routeParams ", routeParams.tableName) - setTableLoading(true); - - axios({ - method: "GET", - url: `/api/cassandra/cluster/${routeParams.clusterId}/keyspace/${routeParams.keyspaceName}/table/${routeParams.tableName}`, - params: { - withTableDescribe: true, - } - }).then((response) => { - - setTableInfo({ - table: response.data.result.table, - describe: response.data.result.describe, - columns: response.data.result.columns, - }) - - }).catch((error) => { - console.log(error) - //TODO : error catch - axiosCatch(error) - }).finally(() => { - setTableLoading(false) - }); - - return () => { - //hide component - - }; - }, []); - - return ( -
    -
    - - - -
    -
    - ) -} - -export default TableInformation; diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-row.js b/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-row.js deleted file mode 100644 index dcf36478..00000000 --- a/cadio-web/src/main/webapp/src/pages/cluster/components/keyspace/table/table-row.js +++ /dev/null @@ -1,167 +0,0 @@ -import axios from "axios"; -import {useEffect, useState} from "react"; -import {axiosCatch} from "../../../../../utils/axiosUtils"; -import {useParams} from "react-router-dom"; - -const TableRow = () => { - const routeParams = useParams(); - - const initQueryResult = { - wasApplied: null, - rows: [], - columnNames: [], - }; - - const [queryLoading, setQueryLoading] = useState(false) - const [queryResult, setQueryResult] = useState(initQueryResult) - const [nextCursor, setNextCursor] = useState('') - - const getList = (cursor) => { - if (cursor === null) { - setQueryResult({ - wasApplied: null, - rows: [], - columnNames: [], - }) - } - - setQueryLoading(true); - - axios({ - method: "POST", - url: `/api/cassandra/cluster/${routeParams.clusterId}/keyspace/${routeParams.keyspaceName}/table/${routeParams.tableName}/row`, - data: { - pageSize: 50, - timeoutSeconds: 3, - cursor: cursor, - }, - }).then((response) => { - setNextCursor(response.data.result.nextCursor) - - setQueryResult({ - wasApplied: response.data.result.wasApplied, - rows: [...queryResult.rows, ...response.data.result.rows], - columnNames: response.data.result.columnNames, - }) - }).catch((error) => { - axiosCatch(error); - }).finally(() => { - setQueryLoading(false); - }) - } - - const renderData = (data) => { - if (typeof data === "object") { - return JSON.stringify(data); - } - - return data; - } - - useEffect(() => { - //show component - setQueryResult(initQueryResult); - getList(null) - - return () => { - //hide component - - }; - }, []); - - return ( -
    -
    -
    - Rows - - { - queryLoading && -
    - Loading... -
    - } -
    - -
    - - - - - { - queryResult.columnNames.map((info, infoIndex) => { - return ( - - ) - }) - } - - - - { - queryResult.rows.length <= 0 ? <> - - - - : - queryResult.rows.map((row, rowIndex) => { - return ( - - - { - queryResult.columnNames.map((info, infoIndex) => { - return ( - - ) - }) - } - - ) - }) - } - - -
    # - {info}
    - 데이터가 없습니다. -
    -
    - - - -
    -
    - { - renderData(row[info]) - } -
    -
    - - { - nextCursor && -
    - -
    - } -
    - -
    - ) -} - -export default TableRow; diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/nodes-home.js b/cadio-web/src/main/webapp/src/pages/cluster/components/nodes-home.js index d8291013..bb23d7fe 100644 --- a/cadio-web/src/main/webapp/src/pages/cluster/components/nodes-home.js +++ b/cadio-web/src/main/webapp/src/pages/cluster/components/nodes-home.js @@ -3,11 +3,12 @@ import {useEffect, useState} from "react"; import axios from "axios"; import {DateUtils} from "../../../utils/timeUtils"; import Spinner from "../../../components/spinner"; -import {axiosCatch} from "../../../utils/axiosUtils"; +import useCadio from "../../../commons/hooks/useCadio"; const NodesHome = () => { const routeParams = useParams(); + const {errorCatch} = useCadio(); const [nodeLoading, setNodeLoading] = useState(false); const [nodeList, setNodeList] = useState([]); @@ -48,7 +49,7 @@ const NodesHome = () => { setTotalNodeSize(nodes.length) setAvailableNodeSize(nodes.filter(node => node.nodeState === 'UP').length) }).catch((error) => { - axiosCatch(error) + errorCatch(error); }).finally(() => { setNodeLoading(false) }); diff --git a/cadio-web/src/main/webapp/src/pages/cluster/components/query-home.js b/cadio-web/src/main/webapp/src/pages/cluster/components/query-home.js index cadbda2a..1f65e8e2 100644 --- a/cadio-web/src/main/webapp/src/pages/cluster/components/query-home.js +++ b/cadio-web/src/main/webapp/src/pages/cluster/components/query-home.js @@ -3,11 +3,13 @@ import axios from "axios"; import {useEffect, useState} from "react"; import {useParams} from "react-router-dom"; import QueryResult from "./query/query-result"; -import {axiosCatch} from "../../../utils/axiosUtils"; +import useCadio from "../../../commons/hooks/useCadio"; const QueryHome = () => { const routeParams = useParams(); + const {errorCatch} = useCadio(); + const [queryParam, setQueryParam] = useState( { query: "", @@ -15,6 +17,11 @@ const QueryHome = () => { } ); + const [queryOptions, setQueryOptions] = useState({ + limit: 10, + trace: false, + }); + const initQueryResult = { wasApplied: null, rows: [], @@ -44,7 +51,8 @@ const QueryHome = () => { url: `/api/cassandra/cluster/${routeParams.clusterId}/query`, data: { query: query, - pageSize: 50, + pageSize: queryOptions.limit, + trace: queryOptions.trace, timeoutSeconds: 3, cursor: cursor, }, @@ -61,7 +69,7 @@ const QueryHome = () => { columnNames: response.data.result.columnNames, }) }).catch((error) => { - axiosCatch(error); + errorCatch(error); }).finally(() => { setLoading(false); }) @@ -97,6 +105,8 @@ const QueryHome = () => { { const [queryLoading, setQueryLoading] = useState(false) const [query, setQuery] = useState("SELECT * FROM testdb.test_table_1;") + const queryOptions = props.queryOptions; + const setQueryOptions = props.setQueryOptions; + + const [selectedQuery, setSelectedQuery] = useState(''); + const editorRef = useRef(); const queryExecute = (cursor) => { - props.queryExecute(query, cursor, setQueryLoading); + if (selectedQuery) { + props.queryExecute(selectedQuery, cursor, setQueryLoading); + } else { + props.queryExecute(query, cursor, setQueryLoading); + } + + } function onSelectionChange(value, event) { const content = editorRef.current.editor.getSelectedText(); console.log("content : ", content) // use content + setSelectedQuery(editorRef.current.editor.getSelectedText()); } + function onLoad(newValue) { console.log("load", newValue); } @@ -84,39 +97,45 @@ const QueryEditor = (props) => {
    - { + setQueryOptions(t => { + return {...t, limit: parseInt(e.target.value)} + }) + } + } value={queryOptions.limit || "10"}> + + + - +
    -
    - - -
    + {/*
    */} + {/* */} + {/* */} + {/*
    */}
    -
    - - -
    + {/*
    */} + {/* */} + {/* */} + {/*
    */}
    -
    +
    -
    diff --git a/cadio-web/src/main/webapp/src/pages/cluster/hooks/useCluster.js b/cadio-web/src/main/webapp/src/pages/cluster/hooks/useCluster.js index 78fb17cf..5f82372e 100644 --- a/cadio-web/src/main/webapp/src/pages/cluster/hooks/useCluster.js +++ b/cadio-web/src/main/webapp/src/pages/cluster/hooks/useCluster.js @@ -1,11 +1,11 @@ import axios from "axios"; import {useClusterDispatch, useClusterState} from "../context/clusterContext"; import {useParams} from "react-router-dom"; -import {axiosCatch} from "../../../utils/axiosUtils"; +import {useAxios} from "../../../utils/axiosUtils"; export default function useCluster() { const routeParams = useParams(); - + const {errorCatch} = useAxios(); const clusterDispatcher = useClusterDispatch(); const {} = useClusterState(); @@ -31,7 +31,7 @@ export default function useCluster() { keyspaceNames: response.data.result.keyspaceNameMap.SYSTEM, }) }).catch((error) => { - axiosCatch(error) + errorCatch(error) }).finally(() => { clusterDispatcher({ type: "SET_KEYSPACE_NAMES_LOADING", @@ -58,7 +58,7 @@ export default function useCluster() { keyspaceList: response.data.result.keyspaceList, }) }).catch((error) => { - axiosCatch(error) + errorCatch(error) }).finally(() => { clusterDispatcher({ type: "SET_KEYSPACE_LIST_LOADING", diff --git a/cadio-web/src/main/webapp/src/pages/commons/hooks/useCadio.js b/cadio-web/src/main/webapp/src/pages/commons/hooks/useCadio.js deleted file mode 100644 index 52e0654a..00000000 --- a/cadio-web/src/main/webapp/src/pages/commons/hooks/useCadio.js +++ /dev/null @@ -1,45 +0,0 @@ -import axios from "axios"; -import {useCadioDispatch, useCadioState} from "../context/cadioContext"; -import {axiosCatch} from "../../../utils/axiosUtils"; - - -export default function useCadio() { - const cadioDispatcher = useCadioDispatch(); - const { - bootstrapLoading, - systemAvailable - } = useCadioState(); - - function doBootstrap() { - cadioDispatcher({ - type: "SET_BOOTSTRAP_LOADING", - bootstrapLoading: true, - }) - axios({ - method: "GET", - url: `/api/bootstrap`, - params: { - - } - }).then((response) => { - cadioDispatcher({ - type: "SET_SYSTEM_AVAILABLE", - systemAvailable: response.data.result.systemAvailable, - //systemAvailable: false, - }) - - }).catch((error) => { - //TODO : error catch - axiosCatch(error); - }).finally(() => { - cadioDispatcher({ - type: "SET_BOOTSTRAP_LOADING", - bootstrapLoading: false, - }) - }); - } - - return { - doBootstrap, - } -} diff --git a/cadio-web/src/main/webapp/src/pages/home-view.js b/cadio-web/src/main/webapp/src/pages/home-view.js index 84d609f0..603e0c0b 100644 --- a/cadio-web/src/main/webapp/src/pages/home-view.js +++ b/cadio-web/src/main/webapp/src/pages/home-view.js @@ -1,14 +1,18 @@ import {Link} from "react-router-dom"; import {useEffect, useState} from "react"; import axios from "axios"; -import CadioHeader from "../components/layout/cadio-header"; import CadioSidebar from "../components/layout/cadio-sidebar"; +import useCadio from "../commons/hooks/useCadio"; const HomeView = () => { + const {openToast, errorCatch} = useCadio(); + const [clustersLoading, setClustersLoading] = useState(false); const [clusters, setClusters] = useState([]); + const [test, setTest] = useState(0); + useEffect(() => { //show component @@ -21,7 +25,7 @@ const HomeView = () => { }).then((response) => { setClusters(response.data.result.clusters) }).catch((error) => { - //TODO : error catch + errorCatch(error) }).finally(() => { setClustersLoading(false) }); @@ -118,7 +122,17 @@ const HomeView = () => {
    + + + +
    ) diff --git a/cadio-web/src/main/webapp/src/pages/initialize-view.js b/cadio-web/src/main/webapp/src/pages/initialize-view.js index b603c257..91856108 100644 --- a/cadio-web/src/main/webapp/src/pages/initialize-view.js +++ b/cadio-web/src/main/webapp/src/pages/initialize-view.js @@ -1,9 +1,9 @@ import {useEffect, useState} from "react"; import axios from "axios"; -import useCadio from "./commons/hooks/useCadio"; +import useCadio from "../commons/hooks/useCadio"; const InitializeView = (props) => { - const {doBootstrap} = useCadio(); + const {doBootstrap, errorCatch} = useCadio(); const [clusterInfo, setClusterInfo] = useState( { @@ -70,7 +70,7 @@ const InitializeView = (props) => { alert("등록되었습니다."); doBootstrap(); }).catch((error) => { - + errorCatch(error); }).finally(() => { setSaveLoading(false); }) diff --git a/cadio-web/src/main/webapp/src/utils/axiosUtils.ts b/cadio-web/src/main/webapp/src/utils/axiosUtils.ts index 0f9c91fd..5b99d9fd 100644 --- a/cadio-web/src/main/webapp/src/utils/axiosUtils.ts +++ b/cadio-web/src/main/webapp/src/utils/axiosUtils.ts @@ -1,46 +1,8 @@ -import axios, {AxiosRequestConfig, AxiosResponse} from "axios"; +export function useAxios() { -export function axiosCatch(error: any) { - console.log(error); + // const {openToast} = useCadio(); - if (axios.isAxiosError(error)) { - const {message} = error; - const {method, url} = error.config as AxiosRequestConfig; - const {status, statusText} = error.response as AxiosResponse; - console.error( - `[API] ${method?.toUpperCase()} ${url} | Error ${status} ${statusText} | ${message}` - ); - - switch (status) { - case 400: - alert(`${status} 잘못된 요청입니다.`); - break; - case 401: { - alert(`${status} 인증 실패입니다.`); - break; - } - case 403: { - alert(`${status} 권한이 없습니다.`); - break; - } - case 404: { - alert(`${status} 찾을 수 없는 페이지입니다.`); - break; - } - case 500: { - alert(`${status} 서버 오류입니다.`); - break; - } - default: { - alert(`${status} 에러가 발생했습니다. ${error.message}`); - } - } - } else if (error instanceof Error && error.name === "TimeoutError") { - console.error(`[API] | TimeError ${error.toString()}`); - alert(`${0} 요청 시간이 초과되었습니다.`); - } else { - console.error(`[API] | Error ${error.toString()}`); - alert(`${0} 에러가 발생했습니다. ${error.toString()}`); + return { } }