diff --git a/droidlet/tools/hitl/dashboard_app/README.MD b/droidlet/tools/hitl/dashboard_app/README.MD index 286977ce52..bc8462302a 100644 --- a/droidlet/tools/hitl/dashboard_app/README.MD +++ b/droidlet/tools/hitl/dashboard_app/README.MD @@ -1,9 +1,17 @@ # Dashboard App for HITL -Updated July 22 by Chuxi. +Updated July 29 by Chuxi. This is a Dashboard app prototype for the HITL system. ## Update Note +- July 29: + - Extend components / backend APIs to be able to display different pipeline. + - Added traceback list component. + - Demo: + - View different pipeline + - ![demo_different_pipeline_extension](https://user-images.githubusercontent.com/51009396/181843461-f27f9fe8-b575-440c-b14d-12f57f1807b2.gif) + - View traceback list + - ![demo_traceback_list](https://user-images.githubusercontent.com/51009396/181843326-3c367e8d-999f-497b-8011-956d885db886.gif) - July 22: - Updated frontend component to show the model line graph of loss and accuracy vs epoch. - Demo: @@ -37,7 +45,8 @@ This is a Dashboard app prototype for the HITL system. - Added view session Log feature. - Demo: - ![demo_view_sesion_log](https://user-images.githubusercontent.com/51009396/178044751-8d099829-cc2f-4353-8bfd-e81e9a23b63e.gif) -- July 6: ![demo_change_dataset_ver](https://user-images.githubusercontent.com/51009396/178807740-b90ada63-573d-47ba-845e-8ab84033d184.gif) + +- July 6: - Added detail page to show detail infomation of a pipeline run (specified by the batch_id) - Added a get all sessions related to a batch id backend API. - Demo: @@ -57,6 +66,12 @@ This is a Dashboard app prototype for the HITL system. - Frontend: a react based frontend - including navigation and NLU pipeline overview page. Default run on localhost:3000. Please note this dashboard app is currently only in development build and is not optimized. +## Dependency +- Dependency required for backend server (in addition to the droidelet setting, please make sure you have the updated version as below): +Flask==2.1.2 +Flask-SocketIO==5.2.0 +- Dependency for frontend is specified in the `fairo/droidlet/tools/hitl/dashboard_app/dashboard_frontend/package.json` file. + ## How to run - Set up environment variables ``` @@ -80,10 +95,10 @@ npm start ## Supported APIs APIs are based on socket event, the following APIs are supported currently: -- get_job_list: - - get a list of jobs stored on AWS that has been run in the past. - - input: no parameter input. - - output: a list of batch ids of the jobs. +- get_run_list: + - get a list of jobs stored on AWS that has been run in the past. + - input: pipeline name in lowercase (nlu, tao, vision etc.) + - output: a list of batch ids of the jobs of the pipeline. - get_traceback_by_id: - get traceback record by id. - input: a batch id. diff --git a/droidlet/tools/hitl/dashboard_app/backend/dashboard_aws_helper.py b/droidlet/tools/hitl/dashboard_app/backend/dashboard_aws_helper.py index c1e1a196c4..288318d6c7 100644 --- a/droidlet/tools/hitl/dashboard_app/backend/dashboard_aws_helper.py +++ b/droidlet/tools/hitl/dashboard_app/backend/dashboard_aws_helper.py @@ -6,20 +6,20 @@ and preparing proper response for APIs the server provides. """ +import ast import json import tarfile import boto3 import botocore import os import re +import pandas as pd from droidlet.tools.hitl.dashboard_app.backend.dashboard_model_utils import load_model from droidlet.tools.hitl.utils.read_model_log import read_model_log_to_list -PIPELINE_DATASET_MAPPING = { - "NLU": "nsp_data", -} +PIPELINE_DATASET_MAPPING = {"NLU": "nsp_data", "TAO": "nsp_data"} S3_BUCKET_NAME = "droidlet-hitl" S3_ROOT = "s3://droidlet-hitl" @@ -70,22 +70,20 @@ def _read_file(fname: str): return content -def get_job_list(): +def get_run_list(pipeline: str): """ - helper method for preparing get_job_list api's response + helper method for preparing get_run_list api's response """ - job_list = [] - # list object from s3 bucket - res = s3.meta.client.get_paginator("list_objects").paginate( - Bucket=S3_BUCKET_NAME, Delimiter="/" - ) - # pattern of YYYYMMDDHHMMSS (batch id pattern) - pattern = r"([0-9]{4})(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])(2[0-3]|[01][0-9])([0-5][0-9])([0-5][0-9])" + # download run list file + local_fname = _download_file(f"{pipeline}_run_list") + if local_fname is None: + return f"cannot find run list for pipeline {pipeline}", 404 - for prefix in res.search("CommonPrefixes"): - if re.match(pattern, prefix.get("Prefix")): - job_list.append(int(prefix.get("Prefix")[:-1])) - return job_list + run_list = _read_file(local_fname).split("\n") + run_list = list(filter(lambda line: len(line), run_list)) # filter out empty strings if there + run_list = [int(bid) for bid in run_list] + + return run_list, None def get_traceback_by_id(batch_id: int): @@ -95,7 +93,26 @@ def get_traceback_by_id(batch_id: int): local_fname = _download_file(f"{batch_id}/log_traceback.csv") if local_fname is None: return f"cannot find traceback with id {batch_id}", 404 - return _read_file(local_fname), None + traceback_df = pd.read_csv(local_fname) + traceback_df.chat_content = traceback_df.chat_content.map( + lambda x: ast.literal_eval(x) + ) # parsse array + + def _get_freq(x): + freq_dict = {} + for o in x: + if o not in freq_dict: + freq_dict[o] = 0 + freq_dict[o] += 1 + return freq_dict + + traceback_df.chat_content = traceback_df.chat_content.map( + lambda ls: [o for o in ls if len(o)] + ) # filter out empty ones + traceback_df.chat_content = traceback_df.chat_content.map( + lambda x: _get_freq(x) + ) # get frequency + return traceback_df.to_json(orient="records"), None def get_run_info_by_id(batch_id: int): diff --git a/droidlet/tools/hitl/dashboard_app/backend/dashboard_server.py b/droidlet/tools/hitl/dashboard_app/backend/dashboard_server.py index 0fc95d6d8c..e18ffd656d 100644 --- a/droidlet/tools/hitl/dashboard_app/backend/dashboard_server.py +++ b/droidlet/tools/hitl/dashboard_app/backend/dashboard_server.py @@ -15,8 +15,8 @@ get_dataset_version_list_by_pipeline, get_interaction_session_log_by_id, get_interaction_sessions_by_id, - get_job_list, get_model_by_id, + get_run_list, get_run_info_by_id, get_traceback_by_id, ) @@ -38,7 +38,7 @@ class DASHBOARD_EVENT(Enum): server supported event types, i.e. API types """ - GET_RUNS = "get_job_list" + GET_RUNS = "get_run_list" GET_TRACEBACK = "get_traceback_by_id" GET_RUN_INFO = "get_run_info_by_id" GET_INTERACTION_SESSIONS = "get_interaction_sessions_by_id" @@ -57,16 +57,20 @@ class DASHBOARD_EVENT(Enum): @socketio.on(DASHBOARD_EVENT.GET_RUNS.value) -def get_jobs(): +def get_runs(pipeline: str): """ get a list of jobs stored on AWS that has been run in the past. - - input: no parameter input. + - input: pipeline name in lowercase (nlu, tao, vision etc.) - output: a list of batch ids of the jobs. """ - print(f"Request received: {DASHBOARD_EVENT.GET_RUNS.value}") - job_list = get_job_list() - print(f"Job list reterived from aws, sending job list (length:{len(job_list)}) to client") - emit(DASHBOARD_EVENT.GET_RUNS.value, job_list) + print(f"Request received: {DASHBOARD_EVENT.GET_RUNS.value}, pipeline = {pipeline}") + job_list, error_code = get_run_list(pipeline) + if error_code: + print(job_list) + emit(DASHBOARD_EVENT.GET_RUNS.value, error_code) + else: + print(f"Job list reterived from aws, sending job list (length:{len(job_list)}) to client") + emit(DASHBOARD_EVENT.GET_RUNS.value, job_list) @socketio.on(DASHBOARD_EVENT.GET_TRACEBACK.value) diff --git a/droidlet/tools/hitl/dashboard_app/backend/tests/dashboard_aws_helper_test.py b/droidlet/tools/hitl/dashboard_app/backend/tests/dashboard_aws_helper_test.py index c7f927d530..177906b981 100644 --- a/droidlet/tools/hitl/dashboard_app/backend/tests/dashboard_aws_helper_test.py +++ b/droidlet/tools/hitl/dashboard_app/backend/tests/dashboard_aws_helper_test.py @@ -4,7 +4,7 @@ import json from droidlet.tools.hitl.dashboard_app.backend.dashboard_aws_helper import ( - get_job_list, + get_run_list, get_run_info_by_id, get_traceback_by_id, ) @@ -41,8 +41,8 @@ def setUp(self): s3.Object(S3_BUCKET_NAME, self._info_fname).put(Body=json_content) s3.Object(S3_BUCKET_NAME, self._traceback_fname).put(Body="1, 2 \n1, 2") - def test_get_job_list(self): - res = get_job_list() + def test_get_run_list(self): + res = get_run_list() self.assertGreater(len(res), 0) def test_get_traceback_by_id_valid(self): @@ -55,12 +55,12 @@ def test_get_traceback_by_id_invalid(self): self.assertEqual(res, f"cannot find traceback with id {INVALID_ID}") def test_get_run_info_by_id_valid(self): - res = get_run_info_by_id(VALID_ID) + res, _ = get_run_info_by_id(VALID_ID) self.assertIsNotNone(res) self.assertNotEqual(res, f"cannot find run info with id {VALID_ID}") def test_get_run_info_by_id_inalid(self): - res = get_run_info_by_id(INVALID_ID) + res, _ = get_run_info_by_id(INVALID_ID) self.assertEqual(res, f"cannot find run info with id {INVALID_ID}") def tearDown(self): @@ -70,7 +70,6 @@ def tearDown(self): # remove from local temp directory as well local_info_fname = os.path.join(HITL_TMP_DIR, self._info_fname) local_traceback_fname = os.path.join(HITL_TMP_DIR, self._traceback_fname) - if os.path.exists(local_info_fname): os.remove(local_info_fname) if os.path.exists(local_traceback_fname): diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/package-lock.json b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/package-lock.json index 3aff193f8e..808dcd88a9 100644 --- a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/package-lock.json +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/package-lock.json @@ -17,6 +17,7 @@ "@testing-library/user-event": "^13.5.0", "antd": "^4.21.3", "moment": "^2.29.3", + "papaparse": "^5.3.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.3.0", @@ -13598,6 +13599,11 @@ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, + "node_modules/papaparse": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.2.tgz", + "integrity": "sha512-6dNZu0Ki+gyV0eBsFKJhYr+MdQYAzFUGlBMNj3GNrmHxmz1lfRa24CjFObPXtjcetlOv5Ad299MhIK0znp3afw==" + }, "node_modules/parallel-transform": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", @@ -32992,6 +32998,11 @@ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, + "papaparse": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.2.tgz", + "integrity": "sha512-6dNZu0Ki+gyV0eBsFKJhYr+MdQYAzFUGlBMNj3GNrmHxmz1lfRa24CjFObPXtjcetlOv5Ad299MhIK0znp3afw==" + }, "parallel-transform": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/package.json b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/package.json index 6a6eeb8922..e630e97775 100644 --- a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/package.json +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/package.json @@ -12,6 +12,7 @@ "@testing-library/user-event": "^13.5.0", "antd": "^4.21.3", "moment": "^2.29.3", + "papaparse": "^5.3.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.3.0", diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/App.js b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/App.js index 70ef97738d..235271471a 100644 --- a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/App.js +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/App.js @@ -13,8 +13,8 @@ import { SocketContext, socket } from './context/socket'; import Main from './component/main'; import { Routes, Route, BrowserRouter } from "react-router-dom"; import NavBar from './component/navbar'; -import { SUBPATHS } from './constants/subpaths'; -import { BackTop, Layout, Typography } from 'antd'; +import { PIPELINES, SUBPATHS } from './constants/subpaths'; +import { BackTop, Layout } from 'antd'; import PipelinePanel from './component/pipeline/panel'; import DetailPage from './component/pipeline/detail/detailPage'; import JobInfoCard from './component/pipeline/detail/job/jobInfoCard'; @@ -36,15 +36,17 @@ function App() { {/* Routes for different pipeline */} - Welcome to Droidlet HiTL Dashboard} /> - }> - }> - } /> + } /> + {PIPELINES.map((pipeline) => + }> + }> + } /> + - - }> + )} + }> } /> - + } /> diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/main.js b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/main.js index 6cd3d0b5da..e43d1d4a12 100644 --- a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/main.js +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/main.js @@ -20,7 +20,7 @@ const Main = () => { }, []); const getJobList = () => { - socket.emit("get_job_list"); + socket.emit("get_run_list"); setLoading(true); } @@ -43,7 +43,7 @@ const Main = () => { } useEffect(() => { - socket.on("get_job_list", (data) => handleReceivedJobList(data)); + socket.on("get_run_list", (data) => handleReceivedJobList(data)); socket.on("get_traceback_by_id", (data) => handleReciveTraceback(data)); socket.on("get_run_info_by_id", (data) => handleReciveInfo(data)); }, [socket, handleReceivedJobList, handleReciveTraceback, handleReciveInfo]); diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/asset/modelCard.js b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/asset/modelCard.js index 93bb6e571d..4b78d01389 100644 --- a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/asset/modelCard.js +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/asset/modelCard.js @@ -130,10 +130,6 @@ const ModelCard = (props) => { setAttrModalOpen(true); } - const handleViewModelLossAndAcc = (lossAccType) => { - alert(lossAccData[lossAccType].map((o) => (`loss: ${o.loss}, acc: ${o.acc}`))); - } - return (
diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/detailPage.js b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/detailPage.js index 98db005b26..e364fcfed4 100644 --- a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/detailPage.js +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/detailPage.js @@ -24,6 +24,7 @@ import { SocketContext } from '../../../context/socket'; import { JOB_TYPES } from "../../../constants/runContants"; import ModelCard from "./asset/modelCard"; import DatasetCard from "./asset/datasetCard"; +import TracebackList from "./tao/tracebackList"; const { Title } = Typography; const { Panel } = Collapse; @@ -31,6 +32,7 @@ const { Panel } = Collapse; const DetailPage = (props) => { const socket = useContext(SocketContext); const pipelineType = props.pipelineType; + const batch_id = useParams().batch_id; const [runInfo, setRunInfo] = useState(null); const [jobs, setJobs] = useState(null); @@ -102,13 +104,14 @@ const DetailPage = (props) => { > -
+
+
@@ -124,9 +127,15 @@ const DetailPage = (props) => {
+ { + pipelineType === "TAO" && <> + + + + }
diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/tao/tracebackList.js b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/tao/tracebackList.js new file mode 100644 index 0000000000..a968c549c2 --- /dev/null +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/detail/tao/tracebackList.js @@ -0,0 +1,137 @@ +/* +Copyright (c) Facebook, Inc. and its affiliates. + +Traceback List for displaying traceback. + +Usage: + +*/ + +import React, { useContext, useEffect, useState } from "react"; +import { SocketContext } from "../../../../context/socket"; +import { Table, Tag, Tooltip, Typography } from "antd"; +import { MinusSquareTwoTone, PlusSquareTwoTone } from "@ant-design/icons"; + +const innerListCols = [ + // columns for list of each of the row in the traceback list + { + title: "Cause Command", + dataIndex: "command", + sorter: (one, other) => (one.command.localeCompare(other.command)), + render: (_, row) => ( + {row.command} + ) + }, { + title: "Frequency", + dataIndex: "freq", + sorter: (one, other) => (one.freq === other.freq ? 0 : (one.freq < other.freq ? 1 : -1)), + render: (_, row) => (), + } +] + +const tracebackListCols = [ + { + title: "Traceback Content", + dataIndex: "content", + sorter: (one, other) => (one.content.localeCompare(other.content)), + render: (_, row) => ( + + {row.content} + ) + }, + { + title: "Frequency", + dataIndex: "freq", + width: "10%", + sorter: (one, other) => (one.freq === other.freq ? 0 : (one.freq < other.freq ? 1 : -1)), + render: (_, row) => (), + }, + { + title: "Causes Count", + dataIndex: "chat_content", + width: "10%", + render: (_, row) => (), + sorter: (one, other) => (one.chat_content.length === other.chat_content.length ? + 0 : + (one.chat_content.length < other.chat_content.length ? 1 : -1) + ) + }, + Table.EXPAND_COLUMN +] + +const HeatColoredNum = (props) => { + const num = props.num; + const colorList = ["magenta", "red", "volcano", "orange", "gold", "lime", "green", "cyan", "blue", "geekblue"]; // for color gradient for the tag + + return 100 ? 0 : Math.trunc(10 - num / 10)]}>{num} +} + +const TracebackList = (props) => { + const socket = useContext(SocketContext); + const batchId = props.batchId; + const [listData, setListData] = useState([]); + const [loading, setLoading] = useState(true); + + const handleReceivedTraceback = (data) => { + if (data !== 404) { + console.log(JSON.parse(data).map( + (o) => ({ + content: o.content, + freq: o.freq, + chat_content: + Object.keys(o.chat_content).map((k) => ({ command: k, freq: o.chat_content[k] })) + }) + )) + setListData(JSON.parse(data).map( + (o) => ({ + content: o.content, + freq: o.freq, + chat_content: + Object.keys(o.chat_content).map((k) => ({ command: k, freq: o.chat_content[k] })) + }) + )); + } + setLoading(false); + + } + + useEffect(() => { + socket.emit("get_traceback_by_id", batchId); + }, []); + + useEffect(() => { + socket.on("get_traceback_by_id", (data) => handleReceivedTraceback(data)); + }, [socket, handleReceivedTraceback]); + + return
+ Tracebacks} + columns={tracebackListCols} + dataSource={listData} + scroll={{ y: "80vh" }} + expandable={{ + // inner list, shows the command that causing the traceback + expandedRowRender: (row) => +
10} + />, + expandRowByClick: true, + indentSize: 0, + expandIcon: ({ expanded, onExpand, record }) => + expanded ? ( + onExpand(record, e)} /> + ) : ( + onExpand(record, e)} /> + ) + }} + loading={loading} + /> + ; +} + +export default TracebackList; \ No newline at end of file diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/metaInfo/runList.js b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/metaInfo/runList.js index 68930dd5e2..f23feeb321 100644 --- a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/metaInfo/runList.js +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/component/pipeline/metaInfo/runList.js @@ -9,14 +9,14 @@ To use this component: */ import { Badge, DatePicker, Input, Select, Skeleton, Table, Typography } from 'antd'; import React, { useContext, useState, useEffect, useCallback } from 'react'; -import { Link } from 'react-router-dom'; +import { Link, useLocation, useNavigate } from 'react-router-dom'; import { SocketContext } from '../../../context/socket'; import moment from 'moment'; const { Title } = Typography; const { Search } = Input; -const {Option} = Select; -const {RangePicker} = DatePicker; +const { Option } = Select; +const { RangePicker } = DatePicker; const timeComp = (one, other) => { // get datetime object @@ -98,8 +98,9 @@ const runListCols = [ const RunList = (props) => { const socket = useContext(SocketContext); - - const pipelineType = props.pipelineType; // to do get runs by pipelineType + const [pipelineType,] = useState(props.pipelineType); // to do get runs by pipelineType + let pipelineLocation = useLocation(); + const navigate = useNavigate(); const [runListData, setRunListData] = useState([]); const [displayData, setDisplayData] = useState([]); @@ -108,32 +109,44 @@ const RunList = (props) => { const [filterType, setFilterType] = useState("start"); const handleReceivedRunList = useCallback((data) => { - data = data.map((o) => ( - // TODO: update backend api for get job list, - // right now using fake name, descrioption infomation, and status - { - name: `name${o}`, - batch_id: o, - description: 'some description here', - status: o % 2 === 0 ? 'done' : 'running', - start_time: `${o.toString().substring(0, 4)}-${o.toString().substring(4, 6)}-${o.toString().substring(6, 8)} 12:00:${o.toString().substring(12)}`, - end_time: `${o.toString().substring(0, 4)}-${o.toString().substring(4, 6)}-${o.toString().substring(6, 8)} 18:30:${o.toString().substring(12)}` - } - )); + if (data === 404) { + navigate("/notfound"); + return; + } + if (data.length > 0) { + data = data.map((o) => ( + // TODO: update backend api for get job list, + // right now using fake name, descrioption infomation, and status + { + name: `name${o}`, + batch_id: o, + description: 'some description here', + status: o % 2 === 0 ? 'done' : 'running', + start_time: `${o.toString().substring(0, 4)}-${o.toString().substring(4, 6)}-${o.toString().substring(6, 8)} 12:00:${o.toString().substring(12)}`, + end_time: `${o.toString().substring(0, 4)}-${o.toString().substring(4, 6)}-${o.toString().substring(6, 8)} 18:30:${o.toString().substring(12)}` + } + )); + } setRunListData(data); setDisplayData(data); setLoading(false); }, []); const getRunList = () => { - socket.emit("get_job_list"); + setRunListData([]); + setDisplayData([]); + setLoading(true); + setRangeValue([]); + setFilterType("start"); + socket.emit("get_run_list", pipelineLocation.pathname.substring(1)); setLoading(true); } useEffect(() => getRunList(), []); // load job list when init the component (didMount) + useEffect(() => getRunList(), [pipelineLocation]); // load job list when location changed useEffect(() => { - socket.on("get_job_list", (data) => handleReceivedRunList(data)); + socket.on("get_run_list", (data) => handleReceivedRunList(data)); }, [socket, handleReceivedRunList]); const onSearch = (searchBoxValue) => { @@ -170,13 +183,13 @@ const RunList = (props) => { setFilterType(filterTypeValue); setRangeValue([]); // reset RangePicker value setDisplayData(runListData); - } + } return ( <>
- View All {pipelineType.label} Runs + View All {pipelineLocation.pathname.substring(1).toUpperCase()} Runs
diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/constants/subpaths.js b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/constants/subpaths.js index 2ae146f1f3..5f3c110be2 100644 --- a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/constants/subpaths.js +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/constants/subpaths.js @@ -28,4 +28,6 @@ export const SUBPATHS = { label: 'Dataset', key: '/dataset' } -} \ No newline at end of file +} + +export const PIPELINES = [SUBPATHS.NLU, SUBPATHS.TAO, SUBPATHS.VIS] \ No newline at end of file diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/context/socket.js b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/context/socket.js index ccf1a42d97..ee4dff379d 100644 --- a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/context/socket.js +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/context/socket.js @@ -1,7 +1,9 @@ import React from 'react'; import io from 'socket.io-client'; -export const socket = io.connect("http://127.0.0.1:5000", {cors: { +export const socket = io.connect("http://127.0.0.1:5000", { + withCredentials: true, + cors: { origin: "*" },transports: ['polling']}); export const SocketContext = React.createContext(); \ No newline at end of file diff --git a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/index.css b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/index.css index 4304b43fd7..4e5daedb3a 100644 --- a/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/index.css +++ b/droidlet/tools/hitl/dashboard_app/dashboard_frontend/src/index.css @@ -23,4 +23,4 @@ code { .ant-row-rtl .logo { float: right; margin: 16px 0 16px 24px; -} \ No newline at end of file +}