| @@ -10,6 +10,7 @@ import { addAutoMLReq, getDatasetInfoReq, updateAutoMLReq } from '@/services/aut | |||||
| import { parseJsonText, trimCharacter } from '@/utils'; | import { parseJsonText, trimCharacter } from '@/utils'; | ||||
| import { safeInvoke } from '@/utils/functional'; | import { safeInvoke } from '@/utils/functional'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import SessionStorage from '@/utils/sessionStorage'; | |||||
| import { useNavigate, useParams } from '@umijs/max'; | import { useNavigate, useParams } from '@umijs/max'; | ||||
| import { App, Button, Form } from 'antd'; | import { App, Button, Form } from 'antd'; | ||||
| import { omit } from 'lodash'; | import { omit } from 'lodash'; | ||||
| @@ -29,13 +30,25 @@ function CreateAutoML() { | |||||
| const id = safeInvoke(Number)(params.id); | const id = safeInvoke(Number)(params.id); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (id) { | |||||
| getAutoMLInfo(); | |||||
| // 复制和新建 | |||||
| const recordId = SessionStorage.getItem(SessionStorage.autoMLRecordIDKey); | |||||
| if (recordId && !Number.isNaN(Number(recordId))) { | |||||
| getAutoMLInfo(Number(recordId), true); | |||||
| } | |||||
| return () => { | |||||
| SessionStorage.removeItem(SessionStorage.autoMLRecordIDKey); | |||||
| }; | |||||
| }, []); | |||||
| useEffect(() => { | |||||
| // 编辑 | |||||
| if (id && !Number.isNaN(id)) { | |||||
| getAutoMLInfo(id, false); | |||||
| } | } | ||||
| }, [id]); | }, [id]); | ||||
| // 获取服务详情 | // 获取服务详情 | ||||
| const getAutoMLInfo = async () => { | |||||
| const getAutoMLInfo = async (id: number, isCopy = false) => { | |||||
| const [res] = await to(getDatasetInfoReq({ id })); | const [res] = await to(getDatasetInfoReq({ id })); | ||||
| if (res && res.data) { | if (res && res.data) { | ||||
| const autoMLInfo: AutoMLData = res.data; | const autoMLInfo: AutoMLData = res.data; | ||||
| @@ -47,6 +60,8 @@ function CreateAutoML() { | |||||
| exclude_feature_preprocessor: exclude_feature_preprocessor_str, | exclude_feature_preprocessor: exclude_feature_preprocessor_str, | ||||
| exclude_regressor: exclude_regressor_str, | exclude_regressor: exclude_regressor_str, | ||||
| metrics: metrics_str, | metrics: metrics_str, | ||||
| ml_name: ml_name_str, | |||||
| ...rest | |||||
| } = autoMLInfo; | } = autoMLInfo; | ||||
| const include_classifier = include_classifier_str?.split(',').filter(Boolean); | const include_classifier = include_classifier_str?.split(',').filter(Boolean); | ||||
| const include_feature_preprocessor = include_feature_preprocessor_str | const include_feature_preprocessor = include_feature_preprocessor_str | ||||
| @@ -63,9 +78,10 @@ function CreateAutoML() { | |||||
| name: key, | name: key, | ||||
| value, | value, | ||||
| })); | })); | ||||
| const ml_name = isCopy ? `${ml_name_str}-copy` : ml_name_str; | |||||
| const formData = { | const formData = { | ||||
| ...autoMLInfo, | |||||
| ...rest, | |||||
| include_classifier, | include_classifier, | ||||
| include_feature_preprocessor, | include_feature_preprocessor, | ||||
| include_regressor, | include_regressor, | ||||
| @@ -73,6 +89,7 @@ function CreateAutoML() { | |||||
| exclude_feature_preprocessor, | exclude_feature_preprocessor, | ||||
| exclude_regressor, | exclude_regressor, | ||||
| metrics, | metrics, | ||||
| ml_name, | |||||
| }; | }; | ||||
| form.setFieldsValue(formData); | form.setFieldsValue(formData); | ||||
| @@ -135,7 +152,7 @@ function CreateAutoML() { | |||||
| let buttonText = '新建'; | let buttonText = '新建'; | ||||
| let title = '新增实验'; | let title = '新增实验'; | ||||
| if (id) { | if (id) { | ||||
| title = '更新实验'; | |||||
| title = '编辑实验'; | |||||
| buttonText = '更新'; | buttonText = '更新'; | ||||
| } | } | ||||
| @@ -9,6 +9,7 @@ import { useCacheState } from '@/hooks/pageCacheState'; | |||||
| import { deleteAutoMLReq, getAutoMLListReq } from '@/services/autoML'; | import { deleteAutoMLReq, getAutoMLListReq } from '@/services/autoML'; | ||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import SessionStorage from '@/utils/sessionStorage'; | |||||
| import tableCellRender, { TableCellValueType } from '@/utils/table'; | import tableCellRender, { TableCellValueType } from '@/utils/table'; | ||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useNavigate } from '@umijs/max'; | import { useNavigate } from '@umijs/max'; | ||||
| @@ -90,7 +91,7 @@ function AutoMLList() { | |||||
| // 处理删除 | // 处理删除 | ||||
| const handleAutoMLDelete = (record: AutoMLData) => { | const handleAutoMLDelete = (record: AutoMLData) => { | ||||
| modalConfirm({ | modalConfirm({ | ||||
| title: '删除后,该服务将不可恢复', | |||||
| title: '删除后,该实验将不可恢复', | |||||
| content: '是否确认删除?', | content: '是否确认删除?', | ||||
| onOk: () => { | onOk: () => { | ||||
| deleteService(record); | deleteService(record); | ||||
| @@ -99,15 +100,21 @@ function AutoMLList() { | |||||
| }; | }; | ||||
| // 创建、编辑 | // 创建、编辑 | ||||
| const createService = (record?: AutoMLData) => { | |||||
| const createService = (record?: AutoMLData, isCopy: boolean = false) => { | |||||
| setCacheState({ | setCacheState({ | ||||
| pagination, | pagination, | ||||
| searchText, | searchText, | ||||
| }); | }); | ||||
| if (record) { | if (record) { | ||||
| navigate(`/pipeline/autoML/edit/${record.id}`); | |||||
| if (isCopy) { | |||||
| SessionStorage.setItem(SessionStorage.autoMLRecordIDKey, record.id, false); | |||||
| navigate(`/pipeline/autoML/create`); | |||||
| } else { | |||||
| navigate(`/pipeline/autoML/edit/${record.id}`); | |||||
| } | |||||
| } else { | } else { | ||||
| SessionStorage.setItem(SessionStorage.autoMLRecordIDKey, '', false); | |||||
| navigate(`/pipeline/autoML/create`); | navigate(`/pipeline/autoML/create`); | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -139,7 +146,7 @@ function AutoMLList() { | |||||
| title: '序号', | title: '序号', | ||||
| dataIndex: 'index', | dataIndex: 'index', | ||||
| key: 'index', | key: 'index', | ||||
| width: '20%', | |||||
| width: 80, | |||||
| render: tableCellRender(false, TableCellValueType.Index, { | render: tableCellRender(false, TableCellValueType.Index, { | ||||
| page: pagination.current! - 1, | page: pagination.current! - 1, | ||||
| pageSize: pagination.pageSize!, | pageSize: pagination.pageSize!, | ||||
| @@ -166,7 +173,7 @@ function AutoMLList() { | |||||
| title: '状态', | title: '状态', | ||||
| dataIndex: 'run_state', | dataIndex: 'run_state', | ||||
| key: 'run_state', | key: 'run_state', | ||||
| width: '20%', | |||||
| width: 100, | |||||
| render: RunStatusCell, | render: RunStatusCell, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -207,7 +214,7 @@ function AutoMLList() { | |||||
| size="small" | size="small" | ||||
| key="edit" | key="edit" | ||||
| icon={<KFIcon type="icon-bianji" />} | icon={<KFIcon type="icon-bianji" />} | ||||
| onClick={() => createService(record)} | |||||
| onClick={() => createService(record, false)} | |||||
| > | > | ||||
| 编辑 | 编辑 | ||||
| </Button> | </Button> | ||||
| @@ -216,17 +223,11 @@ function AutoMLList() { | |||||
| size="small" | size="small" | ||||
| key="copy" | key="copy" | ||||
| icon={<KFIcon type="icon-fuzhi" />} | icon={<KFIcon type="icon-fuzhi" />} | ||||
| onClick={() => toDetail(record)} | |||||
| onClick={() => createService(record, true)} | |||||
| > | > | ||||
| 复制 | 复制 | ||||
| </Button> | </Button> | ||||
| <Button | |||||
| type="link" | |||||
| size="small" | |||||
| key="stop" | |||||
| icon={<KFIcon type="icon-tingzhi" />} | |||||
| onClick={() => toDetail(record)} | |||||
| > | |||||
| <Button type="link" size="small" key="stop" icon={<KFIcon type="icon-tingzhi" />}> | |||||
| 停止 | 停止 | ||||
| </Button> | </Button> | ||||
| <ConfigProvider | <ConfigProvider | ||||
| @@ -120,7 +120,7 @@ function ExecuteConfig() { | |||||
| name="task_type" | name="task_type" | ||||
| rules={[{ required: true, message: '请选择任务类型' }]} | rules={[{ required: true, message: '请选择任务类型' }]} | ||||
| > | > | ||||
| <Radio.Group> | |||||
| <Radio.Group onChange={() => form.resetFields(['metrics'])}> | |||||
| <Radio value={AutoMLTaskType.Classification}>分类</Radio> | <Radio value={AutoMLTaskType.Classification}>分类</Radio> | ||||
| <Radio value={AutoMLTaskType.Regression}>回归</Radio> | <Radio value={AutoMLTaskType.Regression}>回归</Radio> | ||||
| </Radio.Group> | </Radio.Group> | ||||
| @@ -8,6 +8,14 @@ import styles from './index.less'; | |||||
| function TrialConfig() { | function TrialConfig() { | ||||
| const form = Form.useFormInstance(); | const form = Form.useFormInstance(); | ||||
| const task_type = Form.useWatch('task_type', form); | const task_type = Form.useWatch('task_type', form); | ||||
| const metrics = Form.useWatch('metrics', form) || []; | |||||
| const selectedMetrics = metrics | |||||
| .map((item: { name: string; value: number }) => item?.name) | |||||
| .filter(Boolean); | |||||
| const allMetricsOptions = | |||||
| task_type === AutoMLTaskType.Classification ? classificationMetrics : regressionMetrics; | |||||
| const metricsOptions = allMetricsOptions.filter((item) => !selectedMetrics.includes(item.label)); | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <SubAreaTitle | <SubAreaTitle | ||||
| @@ -22,7 +30,6 @@ function TrialConfig() { | |||||
| </Form.Item> | </Form.Item> | ||||
| </Col> | </Col> | ||||
| </Row> | </Row> | ||||
| <Row gutter={8}> | <Row gutter={8}> | ||||
| <Col span={10}> | <Col span={10}> | ||||
| <Form.Item label="指标权重" tooltip="用户可自定义优化指标的组合"> | <Form.Item label="指标权重" tooltip="用户可自定义优化指标的组合"> | ||||
| @@ -30,9 +37,9 @@ function TrialConfig() { | |||||
| {(fields, { add, remove }) => ( | {(fields, { add, remove }) => ( | ||||
| <> | <> | ||||
| {fields.map(({ key, name, ...restField }, index) => ( | {fields.map(({ key, name, ...restField }, index) => ( | ||||
| <Flex key={key} align="center" className={styles['advanced-config']}> | |||||
| <Flex key={key} align="flex-start" className={styles['advanced-config']}> | |||||
| <Form.Item | <Form.Item | ||||
| style={{ flex: 1, marginBottom: 0 }} | |||||
| style={{ flex: 1, marginBottom: 0, minWidth: 0 }} | |||||
| {...restField} | {...restField} | ||||
| name={[name, 'name']} | name={[name, 'name']} | ||||
| rules={[{ required: true, message: '请选择指标' }]} | rules={[{ required: true, message: '请选择指标' }]} | ||||
| @@ -41,31 +48,29 @@ function TrialConfig() { | |||||
| allowClear | allowClear | ||||
| placeholder="请选择指标" | placeholder="请选择指标" | ||||
| popupMatchSelectWidth={false} | popupMatchSelectWidth={false} | ||||
| options={ | |||||
| task_type === AutoMLTaskType.Classification | |||||
| ? classificationMetrics | |||||
| : regressionMetrics | |||||
| } | |||||
| options={metricsOptions} | |||||
| showSearch | showSearch | ||||
| /> | /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <span style={{ margin: '0 8px' }}>:</span> | |||||
| <span style={{ margin: '0 8px', lineHeight: '46px' }}>:</span> | |||||
| <Form.Item | <Form.Item | ||||
| style={{ flex: 1, marginBottom: 0 }} | |||||
| style={{ flex: 1, marginBottom: 0, minWidth: 0 }} | |||||
| {...restField} | {...restField} | ||||
| name={[name, 'value']} | name={[name, 'value']} | ||||
| rules={[{ required: true, message: '请输入指标权重' }]} | rules={[{ required: true, message: '请输入指标权重' }]} | ||||
| > | > | ||||
| <InputNumber placeholder="请输入指标权重" min={0} precision={0} /> | <InputNumber placeholder="请输入指标权重" min={0} precision={0} /> | ||||
| </Form.Item> | </Form.Item> | ||||
| <div style={{ width: '76px', marginLeft: '18px' }}> | |||||
| <Flex | |||||
| style={{ width: '76px', marginLeft: '18px', height: '46px' }} | |||||
| align="center" | |||||
| > | |||||
| <Button | <Button | ||||
| style={{ | style={{ | ||||
| marginRight: '3px', | marginRight: '3px', | ||||
| }} | }} | ||||
| shape="circle" | shape="circle" | ||||
| size="middle" | size="middle" | ||||
| // disabled={fields.length === 1} | |||||
| type="text" | type="text" | ||||
| onClick={() => remove(name)} | onClick={() => remove(name)} | ||||
| icon={<MinusCircleOutlined />} | icon={<MinusCircleOutlined />} | ||||
| @@ -79,7 +84,7 @@ function TrialConfig() { | |||||
| icon={<PlusCircleOutlined />} | icon={<PlusCircleOutlined />} | ||||
| ></Button> | ></Button> | ||||
| )} | )} | ||||
| </div> | |||||
| </Flex> | |||||
| </Flex> | </Flex> | ||||
| ))} | ))} | ||||
| {fields.length === 0 && ( | {fields.length === 0 && ( | ||||
| @@ -6,136 +6,136 @@ | |||||
| } | } | ||||
| } | } | ||||
| .command { | |||||
| width: 83.33%; | |||||
| margin-bottom: 20px; | |||||
| border: 1px solid rgba(234, 234, 234, 0.8); | |||||
| border-radius: 4px; | |||||
| &__header { | |||||
| height: 50px; | |||||
| padding-left: 8px; | |||||
| color: @text-color; | |||||
| font-size: @font-size; | |||||
| background: #f8f8f9; | |||||
| border-radius: 4px 4px 0px 0px; | |||||
| &__name { | |||||
| flex: none; | |||||
| width: 100px; | |||||
| } | |||||
| &__command { | |||||
| flex: 1; | |||||
| margin-right: 15px; | |||||
| } | |||||
| &__operation { | |||||
| flex: none; | |||||
| width: 100px; | |||||
| } | |||||
| } | |||||
| &__body { | |||||
| padding: 8px; | |||||
| border-bottom: 1px solid rgba(234, 234, 234, 0.8); | |||||
| &:last-child { | |||||
| border-bottom: none; | |||||
| } | |||||
| &__name { | |||||
| flex: none; | |||||
| width: 100px; | |||||
| } | |||||
| &__command { | |||||
| flex: 1; | |||||
| margin-right: 15px; | |||||
| margin-bottom: 0 !important; | |||||
| } | |||||
| &__operation { | |||||
| flex: none; | |||||
| width: 100px; | |||||
| } | |||||
| } | |||||
| &__add { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| padding: 15px 0; | |||||
| } | |||||
| } | |||||
| .hyper-parameter { | |||||
| width: 83.33%; | |||||
| margin-bottom: 20px; | |||||
| border: 1px solid rgba(234, 234, 234, 0.8); | |||||
| border-radius: 4px; | |||||
| &__header { | |||||
| height: 50px; | |||||
| padding-left: 8px; | |||||
| color: @text-color; | |||||
| font-size: @font-size; | |||||
| background: #f8f8f9; | |||||
| border-radius: 4px 4px 0px 0px; | |||||
| &__name, | |||||
| &__type, | |||||
| &__space { | |||||
| flex: 1; | |||||
| margin-right: 15px; | |||||
| } | |||||
| &__operation { | |||||
| flex: none; | |||||
| width: 100px; | |||||
| } | |||||
| } | |||||
| &__body { | |||||
| padding: 8px; | |||||
| border-bottom: 1px solid rgba(234, 234, 234, 0.8); | |||||
| &:last-child { | |||||
| border-bottom: none; | |||||
| } | |||||
| &__name, | |||||
| &__type, | |||||
| &__space { | |||||
| flex: 1; | |||||
| margin-right: 15px; | |||||
| margin-bottom: 0 !important; | |||||
| } | |||||
| &__operation { | |||||
| flex: none; | |||||
| width: 100px; | |||||
| } | |||||
| } | |||||
| &__add { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| padding: 15px 0; | |||||
| } | |||||
| } | |||||
| .trial-metrics { | |||||
| width: calc(41.67% - 6px); | |||||
| margin-bottom: 20px; | |||||
| padding: 0 20px; | |||||
| border: 1px dashed #e0e0e0; | |||||
| border-radius: 8px; | |||||
| } | |||||
| .upload-tip { | |||||
| margin-top: 5px; | |||||
| color: @text-color-secondary; | |||||
| font-size: 14px; | |||||
| } | |||||
| .upload-button { | |||||
| height: 46px; | |||||
| font-size: 15px; | |||||
| } | |||||
| // .command { | |||||
| // width: 83.33%; | |||||
| // margin-bottom: 20px; | |||||
| // border: 1px solid rgba(234, 234, 234, 0.8); | |||||
| // border-radius: 4px; | |||||
| // &__header { | |||||
| // height: 50px; | |||||
| // padding-left: 8px; | |||||
| // color: @text-color; | |||||
| // font-size: @font-size; | |||||
| // background: #f8f8f9; | |||||
| // border-radius: 4px 4px 0px 0px; | |||||
| // &__name { | |||||
| // flex: none; | |||||
| // width: 100px; | |||||
| // } | |||||
| // &__command { | |||||
| // flex: 1; | |||||
| // margin-right: 15px; | |||||
| // } | |||||
| // &__operation { | |||||
| // flex: none; | |||||
| // width: 100px; | |||||
| // } | |||||
| // } | |||||
| // &__body { | |||||
| // padding: 8px; | |||||
| // border-bottom: 1px solid rgba(234, 234, 234, 0.8); | |||||
| // &:last-child { | |||||
| // border-bottom: none; | |||||
| // } | |||||
| // &__name { | |||||
| // flex: none; | |||||
| // width: 100px; | |||||
| // } | |||||
| // &__command { | |||||
| // flex: 1; | |||||
| // margin-right: 15px; | |||||
| // margin-bottom: 0 !important; | |||||
| // } | |||||
| // &__operation { | |||||
| // flex: none; | |||||
| // width: 100px; | |||||
| // } | |||||
| // } | |||||
| // &__add { | |||||
| // display: flex; | |||||
| // align-items: center; | |||||
| // justify-content: center; | |||||
| // padding: 15px 0; | |||||
| // } | |||||
| // } | |||||
| // .hyper-parameter { | |||||
| // width: 83.33%; | |||||
| // margin-bottom: 20px; | |||||
| // border: 1px solid rgba(234, 234, 234, 0.8); | |||||
| // border-radius: 4px; | |||||
| // &__header { | |||||
| // height: 50px; | |||||
| // padding-left: 8px; | |||||
| // color: @text-color; | |||||
| // font-size: @font-size; | |||||
| // background: #f8f8f9; | |||||
| // border-radius: 4px 4px 0px 0px; | |||||
| // &__name, | |||||
| // &__type, | |||||
| // &__space { | |||||
| // flex: 1; | |||||
| // margin-right: 15px; | |||||
| // } | |||||
| // &__operation { | |||||
| // flex: none; | |||||
| // width: 100px; | |||||
| // } | |||||
| // } | |||||
| // &__body { | |||||
| // padding: 8px; | |||||
| // border-bottom: 1px solid rgba(234, 234, 234, 0.8); | |||||
| // &:last-child { | |||||
| // border-bottom: none; | |||||
| // } | |||||
| // &__name, | |||||
| // &__type, | |||||
| // &__space { | |||||
| // flex: 1; | |||||
| // margin-right: 15px; | |||||
| // margin-bottom: 0 !important; | |||||
| // } | |||||
| // &__operation { | |||||
| // flex: none; | |||||
| // width: 100px; | |||||
| // } | |||||
| // } | |||||
| // &__add { | |||||
| // display: flex; | |||||
| // align-items: center; | |||||
| // justify-content: center; | |||||
| // padding: 15px 0; | |||||
| // } | |||||
| // } | |||||
| // .trial-metrics { | |||||
| // width: calc(41.67% - 6px); | |||||
| // margin-bottom: 20px; | |||||
| // padding: 0 20px; | |||||
| // border: 1px dashed #e0e0e0; | |||||
| // border-radius: 8px; | |||||
| // } | |||||
| // .upload-tip { | |||||
| // margin-top: 5px; | |||||
| // color: @text-color-secondary; | |||||
| // font-size: 14px; | |||||
| // } | |||||
| // .upload-button { | |||||
| // height: 46px; | |||||
| // font-size: 15px; | |||||
| // } | |||||
| @@ -6,18 +6,19 @@ | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| function ExecuteScheduleCell(status?: any) { | |||||
| function ExecuteScheduleCell(progress?: number) { | |||||
| const width = (progress || 0) * 100 + '%'; | |||||
| return ( | return ( | ||||
| <div className={styles['execute-schedule-cell']}> | <div className={styles['execute-schedule-cell']}> | ||||
| <div className={styles['execute-schedule-cell__progress']}> | <div className={styles['execute-schedule-cell__progress']}> | ||||
| <div | <div | ||||
| className={styles['execute-schedule-cell__progress__bar']} | className={styles['execute-schedule-cell__progress__bar']} | ||||
| style={{ width: '80%' }} | |||||
| style={{ width: width }} | |||||
| ></div> | ></div> | ||||
| </div> | </div> | ||||
| <span className={styles['execute-schedule-cell__text']}> | |||||
| {/* <span className={styles['execute-schedule-cell__text']}> | |||||
| 1/<strong>2</strong> | 1/<strong>2</strong> | ||||
| </span> | |||||
| </span> */} | |||||
| </div> | </div> | ||||
| ); | ); | ||||
| } | } | ||||
| @@ -51,4 +51,7 @@ export type AutoMLData = { | |||||
| exclude_feature_preprocessor?: string; | exclude_feature_preprocessor?: string; | ||||
| exclude_regressor?: string; | exclude_regressor?: string; | ||||
| dataset?: string; | dataset?: string; | ||||
| }; | |||||
| } & Omit< | |||||
| FormData, | |||||
| 'metrics|dataset|include_classifier|include_feature_preprocessor|include_regressor|exclude_classifier|exclude_feature_preprocessor|exclude_regressor' | |||||
| >; | |||||
| @@ -11,6 +11,8 @@ export default class SessionStorage { | |||||
| static readonly editorUrlKey = 'editor-url'; | static readonly editorUrlKey = 'editor-url'; | ||||
| // 客户端信息 | // 客户端信息 | ||||
| static readonly clientInfoKey = 'client-info'; | static readonly clientInfoKey = 'client-info'; | ||||
| // 自动机器学习记录ID | |||||
| static readonly autoMLRecordIDKey = 'auto-ml-record-id'; | |||||
| static getItem(key: string, isObject: boolean = false) { | static getItem(key: string, isObject: boolean = false) { | ||||
| const jsonStr = sessionStorage.getItem(key); | const jsonStr = sessionStorage.getItem(key); | ||||