chore: get start from deploying
This commit is contained in:
@@ -9,11 +9,21 @@ interface HeaderPrefixProps {
|
|||||||
onSelectAll?: (e: any) => void;
|
onSelectAll?: (e: any) => void;
|
||||||
indeterminate?: boolean;
|
indeterminate?: boolean;
|
||||||
selectAll?: boolean;
|
selectAll?: boolean;
|
||||||
|
hasColumns?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const HeaderPrefix: React.FC<HeaderPrefixProps> = (props) => {
|
const HeaderPrefix: React.FC<HeaderPrefixProps> = (props) => {
|
||||||
const { expandable, enableSelection, onSelectAll, indeterminate, selectAll } =
|
const {
|
||||||
props;
|
hasColumns,
|
||||||
|
expandable,
|
||||||
|
enableSelection,
|
||||||
|
onSelectAll,
|
||||||
|
indeterminate,
|
||||||
|
selectAll
|
||||||
|
} = props;
|
||||||
|
if (!hasColumns) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (expandable && enableSelection) {
|
if (expandable && enableSelection) {
|
||||||
return (
|
return (
|
||||||
<div className="header-row-prefix-wrapper">
|
<div className="header-row-prefix-wrapper">
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ interface TableBodyProps {
|
|||||||
loadChildren?: any;
|
loadChildren?: any;
|
||||||
loadChildrenAPI?: any;
|
loadChildrenAPI?: any;
|
||||||
onCell?: any;
|
onCell?: any;
|
||||||
|
empty?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TableBody: React.FC<TableBodyProps> = ({
|
const TableBody: React.FC<TableBodyProps> = ({
|
||||||
@@ -34,12 +35,13 @@ const TableBody: React.FC<TableBodyProps> = ({
|
|||||||
loadChildren,
|
loadChildren,
|
||||||
loadChildrenAPI,
|
loadChildrenAPI,
|
||||||
columns,
|
columns,
|
||||||
onCell
|
onCell,
|
||||||
|
empty
|
||||||
}) => {
|
}) => {
|
||||||
if (!dataSource.length) {
|
if (!dataSource.length) {
|
||||||
return (
|
return (
|
||||||
<div className="empty-wrapper">
|
<div className="empty-wrapper">
|
||||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
{empty || <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = (
|
|||||||
watchChildren,
|
watchChildren,
|
||||||
rowSelection,
|
rowSelection,
|
||||||
pagination,
|
pagination,
|
||||||
|
empty,
|
||||||
renderChildren,
|
renderChildren,
|
||||||
loadChildren,
|
loadChildren,
|
||||||
loadChildrenAPI
|
loadChildrenAPI
|
||||||
@@ -116,11 +117,13 @@ const SealTable: React.FC<SealTableProps & { pagination: PaginationProps }> = (
|
|||||||
onSelectAll={handleSelectAllChange}
|
onSelectAll={handleSelectAllChange}
|
||||||
expandable={expandable}
|
expandable={expandable}
|
||||||
enableSelection={rowSelection?.enableSelection}
|
enableSelection={rowSelection?.enableSelection}
|
||||||
|
hasColumns={parsedColumns.length > 0}
|
||||||
></HeaderPrefix>
|
></HeaderPrefix>
|
||||||
<Header onSort={onSort} columns={parsedColumns}></Header>
|
<Header onSort={onSort} columns={parsedColumns}></Header>
|
||||||
</div>
|
</div>
|
||||||
<Spin spinning={loading}>
|
<Spin spinning={loading}>
|
||||||
<TableBody
|
<TableBody
|
||||||
|
empty={empty}
|
||||||
dataSource={props.dataSource}
|
dataSource={props.dataSource}
|
||||||
columns={parsedColumns}
|
columns={parsedColumns}
|
||||||
rowSelection={rowSelection}
|
rowSelection={rowSelection}
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ import {
|
|||||||
ListItem as WorkerListItem
|
ListItem as WorkerListItem
|
||||||
} from '@/pages/resources/config/types';
|
} from '@/pages/resources/config/types';
|
||||||
import { handleBatchRequest } from '@/utils';
|
import { handleBatchRequest } from '@/utils';
|
||||||
|
import {
|
||||||
|
IS_FIRST_LOGIN,
|
||||||
|
readState,
|
||||||
|
writeState
|
||||||
|
} from '@/utils/localstore/index';
|
||||||
import {
|
import {
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
DownOutlined,
|
DownOutlined,
|
||||||
@@ -28,7 +33,17 @@ import {
|
|||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
import { PageContainer } from '@ant-design/pro-components';
|
||||||
import { Access, useAccess, useIntl, useNavigate } from '@umijs/max';
|
import { Access, useAccess, useIntl, useNavigate } from '@umijs/max';
|
||||||
import { Button, Dropdown, Input, Select, Space, Tooltip, message } from 'antd';
|
import {
|
||||||
|
Button,
|
||||||
|
Dropdown,
|
||||||
|
Empty,
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
Space,
|
||||||
|
Tooltip,
|
||||||
|
Typography,
|
||||||
|
message
|
||||||
|
} from 'antd';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
@@ -45,6 +60,7 @@ import {
|
|||||||
} from '../apis';
|
} from '../apis';
|
||||||
import {
|
import {
|
||||||
InstanceRealtimeLogStatus,
|
InstanceRealtimeLogStatus,
|
||||||
|
backendOptionsMap,
|
||||||
getSourceRepoConfigValue,
|
getSourceRepoConfigValue,
|
||||||
modelCategories,
|
modelCategories,
|
||||||
modelCategoriesMap,
|
modelCategoriesMap,
|
||||||
@@ -76,6 +92,7 @@ interface ModelsProps {
|
|||||||
deleteIds?: number[];
|
deleteIds?: number[];
|
||||||
gpuDeviceList: GPUDeviceItem[];
|
gpuDeviceList: GPUDeviceItem[];
|
||||||
workerList: WorkerListItem[];
|
workerList: WorkerListItem[];
|
||||||
|
catalogList?: any[];
|
||||||
dataSource: ListItem[];
|
dataSource: ListItem[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
loadend: boolean;
|
loadend: boolean;
|
||||||
@@ -158,12 +175,15 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
dataSource,
|
dataSource,
|
||||||
gpuDeviceList,
|
gpuDeviceList,
|
||||||
workerList,
|
workerList,
|
||||||
|
catalogList,
|
||||||
queryParams,
|
queryParams,
|
||||||
loading,
|
loading,
|
||||||
loadend,
|
loadend,
|
||||||
total
|
total
|
||||||
}) => {
|
}) => {
|
||||||
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();
|
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();
|
||||||
|
const [isFirstLogin, setIsFirstLogin] = useState(false);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [expandAtom, setExpandAtom] = useAtom(modelsExpandKeysAtom);
|
const [expandAtom, setExpandAtom] = useAtom(modelsExpandKeysAtom);
|
||||||
const access = useAccess();
|
const access = useAccess();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
@@ -199,6 +219,17 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
});
|
});
|
||||||
const modalRef = useRef<any>(null);
|
const modalRef = useRef<any>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!catalogList?.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const getFirstLoginState = async () => {
|
||||||
|
const is_first_login = await readState(IS_FIRST_LOGIN);
|
||||||
|
setIsFirstLogin(is_first_login);
|
||||||
|
};
|
||||||
|
getFirstLoginState();
|
||||||
|
}, [catalogList?.length]);
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
HotKeys.NEW1.join(','),
|
HotKeys.NEW1.join(','),
|
||||||
() => {
|
() => {
|
||||||
@@ -667,8 +698,11 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns: SealColumnProps[] = useMemo(
|
const columns: SealColumnProps[] = useMemo(() => {
|
||||||
() => [
|
if (isFirstLogin) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return [
|
||||||
{
|
{
|
||||||
title: intl.formatMessage({ id: 'common.table.name' }),
|
title: intl.formatMessage({ id: 'common.table.name' }),
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@@ -744,13 +778,67 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
],
|
];
|
||||||
[sortOrder, intl]
|
}, [sortOrder, intl, isFirstLogin]);
|
||||||
);
|
|
||||||
|
const handleOnClick = async () => {
|
||||||
|
if (isLoading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = catalogList?.find(
|
||||||
|
(item) => item.backend === backendOptionsMap.llamaBox && item.size === 1.5
|
||||||
|
);
|
||||||
|
console.log('catalogList=======', data);
|
||||||
|
try {
|
||||||
|
if (data) {
|
||||||
|
setIsLoading(true);
|
||||||
|
const modelData = await createModel({
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
writeState(IS_FIRST_LOGIN, false);
|
||||||
|
setIsFirstLogin(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
updateExpandedRowKeys([modelData.id]);
|
||||||
|
}, 300);
|
||||||
|
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
||||||
|
handleSearch?.();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// ingore
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const renderEmpty = useMemo(() => {
|
||||||
|
if (dataSource.length || !isFirstLogin) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="flex-column justify-center flex-center"
|
||||||
|
style={{ height: 300 }}
|
||||||
|
>
|
||||||
|
<Empty description=""></Empty>
|
||||||
|
<Typography.Title level={4} style={{ marginBottom: 30 }}>
|
||||||
|
No Models yet!
|
||||||
|
</Typography.Title>
|
||||||
|
<div>
|
||||||
|
<Button type="primary" onClick={handleOnClick} loading={isLoading}>
|
||||||
|
<span style={{ fontSize: 13 }}>Get started with</span>
|
||||||
|
<span style={{ fontSize: 14, fontWeight: 700 }}>
|
||||||
|
DeepSeek-R1-Distill-Qwen-1.5B
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}, [dataSource.length, isFirstLogin, isLoading]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageContainer
|
<PageContainer
|
||||||
|
className="models-page-container"
|
||||||
ghost
|
ghost
|
||||||
header={{
|
header={{
|
||||||
title: intl.formatMessage({ id: 'models.title' }),
|
title: intl.formatMessage({ id: 'models.title' }),
|
||||||
@@ -760,6 +848,7 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
>
|
>
|
||||||
<PageTools
|
<PageTools
|
||||||
marginBottom={22}
|
marginBottom={22}
|
||||||
|
style={{ display: isFirstLogin ? 'none' : 'flex' }}
|
||||||
left={
|
left={
|
||||||
<Space>
|
<Space>
|
||||||
<Input
|
<Input
|
||||||
@@ -856,7 +945,9 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
></PageTools>
|
></PageTools>
|
||||||
|
|
||||||
<SealTable
|
<SealTable
|
||||||
|
empty={renderEmpty}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={dataSource}
|
dataSource={dataSource}
|
||||||
rowSelection={rowSelection}
|
rowSelection={rowSelection}
|
||||||
|
|||||||
@@ -6,12 +6,15 @@ import {
|
|||||||
GPUDeviceItem,
|
GPUDeviceItem,
|
||||||
ListItem as WokerListItem
|
ListItem as WokerListItem
|
||||||
} from '@/pages/resources/config/types';
|
} from '@/pages/resources/config/types';
|
||||||
|
import { IS_FIRST_LOGIN, readState } from '@/utils/localstore';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import qs from 'query-string';
|
import qs from 'query-string';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
MODELS_API,
|
MODELS_API,
|
||||||
MODEL_INSTANCE_API,
|
MODEL_INSTANCE_API,
|
||||||
|
queryCatalogItemSpec,
|
||||||
|
queryCatalogList,
|
||||||
queryModelsInstances,
|
queryModelsInstances,
|
||||||
queryModelsList
|
queryModelsList
|
||||||
} from './apis';
|
} from './apis';
|
||||||
@@ -37,6 +40,7 @@ const Models: React.FC = () => {
|
|||||||
total: 0
|
total: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [catalogList, setCatalogList] = useState<any[]>([]);
|
||||||
const [gpuDeviceList, setGpuDeviceList] = useState<GPUDeviceItem[]>([]);
|
const [gpuDeviceList, setGpuDeviceList] = useState<GPUDeviceItem[]>([]);
|
||||||
const [workerList, setWorkerList] = useState<WokerListItem[]>([]);
|
const [workerList, setWorkerList] = useState<WokerListItem[]>([]);
|
||||||
const chunkRequedtRef = useRef<any>();
|
const chunkRequedtRef = useRef<any>();
|
||||||
@@ -243,6 +247,33 @@ const Models: React.FC = () => {
|
|||||||
};
|
};
|
||||||
}, [queryParams]);
|
}, [queryParams]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const getCataLogList = async () => {
|
||||||
|
const isFirstLogin = readState(IS_FIRST_LOGIN);
|
||||||
|
if (!isFirstLogin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const res: any = await queryCatalogList({
|
||||||
|
search: 'DeepSeek R1',
|
||||||
|
page: 1
|
||||||
|
});
|
||||||
|
const name = _.toLower(res?.items[0]?.name).replace(/\s/g, '-') || '';
|
||||||
|
const catalogSpecs: any = await queryCatalogItemSpec({
|
||||||
|
id: res?.items[0]?.id
|
||||||
|
});
|
||||||
|
const list = catalogSpecs?.items?.map((item: any) => {
|
||||||
|
item.name = name;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
setCatalogList(list || []);
|
||||||
|
} catch (error) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
};
|
||||||
|
getCataLogList();
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
createModelsChunkRequest();
|
createModelsChunkRequest();
|
||||||
}, [createModelsChunkRequest]);
|
}, [createModelsChunkRequest]);
|
||||||
@@ -311,6 +342,7 @@ const Models: React.FC = () => {
|
|||||||
deleteIds={dataSource.deletedIds}
|
deleteIds={dataSource.deletedIds}
|
||||||
gpuDeviceList={gpuDeviceList}
|
gpuDeviceList={gpuDeviceList}
|
||||||
workerList={workerList}
|
workerList={workerList}
|
||||||
|
catalogList={catalogList}
|
||||||
></TableList>
|
></TableList>
|
||||||
</TableContext.Provider>
|
</TableContext.Provider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ import {
|
|||||||
removeRememberMe
|
removeRememberMe
|
||||||
} from '@/utils/localstore/index';
|
} from '@/utils/localstore/index';
|
||||||
import { LockOutlined, UserOutlined } from '@ant-design/icons';
|
import { LockOutlined, UserOutlined } from '@ant-design/icons';
|
||||||
import { history, useIntl, useModel } from '@umijs/max';
|
import { useIntl, useModel } from '@umijs/max';
|
||||||
import { Button, Checkbox, Form } from 'antd';
|
import { Button, Checkbox, Form } from 'antd';
|
||||||
import CryptoJS from 'crypto-js';
|
import CryptoJS from 'crypto-js';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import { memo, useEffect, useMemo } from 'react';
|
import { memo, useEffect, useMemo } from 'react';
|
||||||
import { flushSync } from 'react-dom';
|
import { flushSync } from 'react-dom';
|
||||||
import { login } from '../apis';
|
import { login } from '../apis';
|
||||||
|
import { checkDefaultPage } from '../utils';
|
||||||
|
|
||||||
const REMEMBER_ME_KEY = 'r_m';
|
const REMEMBER_ME_KEY = 'r_m';
|
||||||
const CRYPT_TEXT = 'seal';
|
const CRYPT_TEXT = 'seal';
|
||||||
@@ -50,11 +51,10 @@ const LoginForm = () => {
|
|||||||
);
|
);
|
||||||
}, [intl]);
|
}, [intl]);
|
||||||
|
|
||||||
const gotoDefaultPage = (userInfo: any) => {
|
const gotoDefaultPage = async (userInfo: any) => {
|
||||||
const pathname =
|
checkDefaultPage(userInfo, true);
|
||||||
userInfo && userInfo?.is_admin ? '/dashboard' : '/playground';
|
|
||||||
history.push(pathname);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchUserInfo = async () => {
|
const fetchUserInfo = async () => {
|
||||||
const userInfo = await initialState?.fetchUserInfo?.();
|
const userInfo = await initialState?.fetchUserInfo?.();
|
||||||
|
|
||||||
@@ -108,6 +108,7 @@ const LoginForm = () => {
|
|||||||
username: values.username,
|
username: values.username,
|
||||||
password: values.password
|
password: values.password
|
||||||
});
|
});
|
||||||
|
|
||||||
const userInfo = await fetchUserInfo();
|
const userInfo = await fetchUserInfo();
|
||||||
setUserInfo(userInfo);
|
setUserInfo(userInfo);
|
||||||
if (values.autoLogin) {
|
if (values.autoLogin) {
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ import { initialPasswordAtom, userAtom } from '@/atoms/user';
|
|||||||
import SealInput from '@/components/seal-form/seal-input';
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
import { PasswordReg } from '@/config';
|
import { PasswordReg } from '@/config';
|
||||||
import { GlobalOutlined, LockOutlined } from '@ant-design/icons';
|
import { GlobalOutlined, LockOutlined } from '@ant-design/icons';
|
||||||
import { SelectLang, history, useIntl } from '@umijs/max';
|
import { SelectLang, useIntl } from '@umijs/max';
|
||||||
import { Button, Form, message } from 'antd';
|
import { Button, Form, message } from 'antd';
|
||||||
import CryptoJS from 'crypto-js';
|
import CryptoJS from 'crypto-js';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import { updatePassword } from '../apis';
|
import { updatePassword } from '../apis';
|
||||||
|
import { checkDefaultPage } from '../utils';
|
||||||
|
|
||||||
const CRYPT_TEXT = 'seal';
|
const CRYPT_TEXT = 'seal';
|
||||||
|
|
||||||
@@ -16,10 +17,8 @@ const PasswordForm: React.FC = () => {
|
|||||||
|
|
||||||
const [userInfo, setUserInfo] = useAtom(userAtom);
|
const [userInfo, setUserInfo] = useAtom(userAtom);
|
||||||
const [initialPassword, setInitialPassword] = useAtom(initialPasswordAtom);
|
const [initialPassword, setInitialPassword] = useAtom(initialPasswordAtom);
|
||||||
const gotoDefaultPage = (userInfo: any) => {
|
const gotoDefaultPage = async (userInfo: any) => {
|
||||||
const pathname =
|
checkDefaultPage(userInfo, false);
|
||||||
userInfo && userInfo?.is_admin ? '/dashboard' : '/playground';
|
|
||||||
history.push(pathname);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const decryptPassword = (password: string) => {
|
const decryptPassword = (password: string) => {
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
import { userAtom } from '@/atoms/user';
|
import { userAtom } from '@/atoms/user';
|
||||||
import Footer from '@/components/footer';
|
import Footer from '@/components/footer';
|
||||||
import { history, useModel } from '@umijs/max';
|
import { useModel } from '@umijs/max';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import LoginForm from './components/login-form';
|
import LoginForm from './components/login-form';
|
||||||
import PasswordForm from './components/password-form';
|
import PasswordForm from './components/password-form';
|
||||||
import styles from './components/styles.less';
|
import styles from './components/styles.less';
|
||||||
|
import { checkDefaultPage } from './utils';
|
||||||
|
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
const [userInfo, setUserInfo] = useAtom(userAtom);
|
const [userInfo, setUserInfo] = useAtom(userAtom);
|
||||||
const { initialState, setInitialState } = useModel('@@initialState') || {};
|
const { initialState, setInitialState } = useModel('@@initialState') || {};
|
||||||
|
|
||||||
const gotoDefaultPage = (userInfo: any) => {
|
const gotoDefaultPage = async (userInfo: any) => {
|
||||||
if (!userInfo || userInfo?.require_password_change) {
|
if (!userInfo || userInfo?.require_password_change) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkDefaultPage(userInfo, true);
|
||||||
if (!initialState?.currentUser) {
|
if (!initialState?.currentUser) {
|
||||||
setInitialState((s: any) => ({
|
setInitialState((s: any) => ({
|
||||||
...s,
|
...s,
|
||||||
currentUser: userInfo
|
currentUser: userInfo
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
const pathname = userInfo?.is_admin ? '/dashboard' : '/playground';
|
|
||||||
|
|
||||||
history.push(pathname, { replace: true });
|
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
gotoDefaultPage(userInfo);
|
gotoDefaultPage(userInfo);
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { isOnline } from '@/utils';
|
||||||
|
import {
|
||||||
|
IS_FIRST_LOGIN,
|
||||||
|
readState,
|
||||||
|
writeState
|
||||||
|
} from '@/utils/localstore/index';
|
||||||
|
import { history } from '@umijs/max';
|
||||||
|
|
||||||
|
export const checkDefaultPage = async (userInfo: any, replace: boolean) => {
|
||||||
|
const isFirstLogin = await readState(IS_FIRST_LOGIN);
|
||||||
|
|
||||||
|
if (isFirstLogin === null && isOnline()) {
|
||||||
|
writeState(IS_FIRST_LOGIN, true);
|
||||||
|
const pathname =
|
||||||
|
userInfo && userInfo?.is_admin ? '/models/list' : '/playground';
|
||||||
|
history.push(pathname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await writeState(IS_FIRST_LOGIN, false);
|
||||||
|
|
||||||
|
const pathname = userInfo?.is_admin ? '/dashboard' : '/playground';
|
||||||
|
|
||||||
|
history.push(pathname, { replace: replace });
|
||||||
|
};
|
||||||
@@ -192,3 +192,8 @@ export const base64ToFile = (base64String: string, fileName: string) => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// check onlinestatus
|
||||||
|
export const isOnline = () => {
|
||||||
|
return window.navigator.onLine;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import localStore from './store';
|
import localStore from './store';
|
||||||
|
|
||||||
|
const IS_FIRST_LOGIN = 'is_first_login';
|
||||||
|
|
||||||
const store = localStore.createInstance({ name: '_xWXJKJ_S1Sna_' });
|
const store = localStore.createInstance({ name: '_xWXJKJ_S1Sna_' });
|
||||||
|
|
||||||
const rememberMe = (key: string, data: any) => {
|
const rememberMe = (key: string, data: any) => {
|
||||||
@@ -20,6 +22,25 @@ const removeRememberMe = (key: string) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export { getRememberMe, rememberMe, removeRememberMe };
|
const readState = (key: string) => {
|
||||||
|
if (store) {
|
||||||
|
return store.getItem(key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const writeState = (key: string, data: any) => {
|
||||||
|
if (store) {
|
||||||
|
store.setItem(key, data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
IS_FIRST_LOGIN,
|
||||||
|
getRememberMe,
|
||||||
|
readState,
|
||||||
|
rememberMe,
|
||||||
|
removeRememberMe,
|
||||||
|
writeState
|
||||||
|
};
|
||||||
|
|
||||||
export default store;
|
export default store;
|
||||||
|
|||||||
Reference in New Issue
Block a user