chore: support editing the model repoID, filename, model path

This commit is contained in:
jialin
2024-12-10 15:43:29 +08:00
parent acf99a6a9e
commit f64e696f7a
12 changed files with 122 additions and 43 deletions
@@ -66,8 +66,10 @@ const RawAudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
audioRef.current.addEventListener('loadeddata', () => { audioRef.current.addEventListener('loadeddata', () => {
initEnvents(); initEnvents();
initAudioContext(); if (!audioContext.current) {
generateVisualData(); initAudioContext();
generateVisualData();
}
props.onLoadedData?.(); props.onLoadedData?.();
}); });
@@ -107,12 +109,6 @@ const RawAudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
}); });
}; };
const handleAudioOnPlay = () => {
audioRef.current?.play();
};
const handleLoadedMetadata = () => {};
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
play: () => { play: () => {
audioRef.current?.play(); audioRef.current?.play();
@@ -124,6 +120,8 @@ const RawAudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
useEffect(() => { useEffect(() => {
if (audioRef.current) { if (audioRef.current) {
console.log('audioRef.current', audioRef.current, props.url);
initEnvents();
} }
return () => { return () => {
if (audioContext.current) { if (audioContext.current) {
@@ -150,12 +148,15 @@ const RawAudioPlayer: React.FC<AudioPlayerProps> = forwardRef((props, ref) => {
return ( return (
<audio <audio
width={props.width || 300}
height={props.height || 40}
controls controls
autoPlay={autoplay} autoPlay={autoplay}
src={props.url} src={props.url}
ref={audioRef} ref={audioRef}
style={{
position: 'absolute',
left: '-9999px',
opacity: 0
}}
preload="metadata" preload="metadata"
></audio> ></audio>
); );
@@ -0,0 +1,4 @@
.dropdown-button.middle {
height: 28px;
width: 28px;
}
+10 -2
View File
@@ -1,8 +1,10 @@
import { MoreOutlined } from '@ant-design/icons'; import { MoreOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Button, Dropdown, Tooltip, type MenuProps } from 'antd'; import { Button, Dropdown, Tooltip, type MenuProps } from 'antd';
import classNames from 'classnames';
import _ from 'lodash'; import _ from 'lodash';
import { memo } from 'react'; import { memo } from 'react';
import './index.less';
interface DropdownButtonsProps { interface DropdownButtonsProps {
items: MenuProps['items']; items: MenuProps['items'];
@@ -12,7 +14,7 @@ interface DropdownButtonsProps {
const DropdownButtons: React.FC<DropdownButtonsProps> = ({ const DropdownButtons: React.FC<DropdownButtonsProps> = ({
items, items,
size = 'small', size = 'middle',
onSelect onSelect
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
@@ -81,12 +83,18 @@ const DropdownButtons: React.FC<DropdownButtonsProps> = ({
key="leftButton" key="leftButton"
> >
<Button <Button
className={classNames('dropdown-button', size)}
onClick={handleButtonClick} onClick={handleButtonClick}
size={size} size={size}
icon={_.head(items)?.icon} icon={_.head(items)?.icon}
></Button> ></Button>
</Tooltip>, </Tooltip>,
<Button icon={<MoreOutlined />} size={size} key="menu"></Button> <Button
icon={<MoreOutlined />}
size={size}
key="menu"
className={classNames('dropdown-button', size)}
></Button>
]} ]}
></Dropdown.Button> ></Dropdown.Button>
)} )}
@@ -62,14 +62,6 @@ const TableRow: React.FC<
} }
}, [rowSelection]); }, [rowSelection]);
// useEffect(() => {
// if (expandedRowKeys?.includes(record[rowKey])) {
// setExpanded(true);
// } else {
// setExpanded(false);
// }
// }, [expandedRowKeys]);
useEffect(() => { useEffect(() => {
return () => { return () => {
if (pollTimer.current) { if (pollTimer.current) {
@@ -160,8 +152,6 @@ const TableRow: React.FC<
pollTimer.current = setInterval(() => { pollTimer.current = setInterval(() => {
handlePolling(); handlePolling();
}, 1000); }, 1000);
} else {
handleLoadChildren();
} }
}; };
@@ -179,6 +169,20 @@ const TableRow: React.FC<
} }
}; };
useEffect(() => {
if (expandedRowKeys?.includes(record[rowKey])) {
setExpanded(true);
} else {
setExpanded(false);
}
}, [expandedRowKeys]);
useEffect(() => {
if (expanded) {
handleLoadChildren();
}
}, [expanded]);
useEffect(() => { useEffect(() => {
if (!firstLoad && expanded) { if (!firstLoad && expanded) {
cacheDataListRef.current = childrenData; cacheDataListRef.current = childrenData;
+14 -1
View File
@@ -64,6 +64,7 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
}, [ref.current]); }, [ref.current]);
const handleOnAnalyse = useCallback((data: any, analyser: any) => { const handleOnAnalyse = useCallback((data: any, analyser: any) => {
console.log('data+++++++++++++++++=:', data);
setAudioChunks((pre: any) => { setAudioChunks((pre: any) => {
return { return {
data: data, data: data,
@@ -88,6 +89,7 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
const handleOnAudioprocess = useCallback( const handleOnAudioprocess = useCallback(
(current: number) => { (current: number) => {
console.log('current:', current);
throttleUpdateCurrentTime(current); throttleUpdateCurrentTime(current);
}, },
[throttleUpdateCurrentTime] [throttleUpdateCurrentTime]
@@ -119,7 +121,7 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
}; };
const handleReady = useCallback((duration: number) => { const handleReady = useCallback((duration: number) => {
console.log('duration:', duration); console.log('ready+++++++++++++++', duration);
setDuration(duration); setDuration(duration);
}, []); }, []);
@@ -159,6 +161,17 @@ const SpeechItem: React.FC<SpeechContentProps> = (props) => {
onAudioprocess={handleOnAudioprocess} onAudioprocess={handleOnAudioprocess}
ref={ref} ref={ref}
></AudioPlayer> ></AudioPlayer>
{/* <RawAudioPlayer
{...props}
url={props.audioUrl}
onReady={handleReady}
onEnded={handleOnFinish}
onPlay={handleOnPlay}
onPause={handleOnPause}
onAnalyse={handleOnAnalyse}
onAudioProcess={handleOnAudioprocess}
ref={ref}
></RawAudioPlayer> */}
{isPlay && ( {isPlay && (
<AudioAnimation <AudioAnimation
maxBarCount={100} maxBarCount={100}
+1
View File
@@ -20,6 +20,7 @@ const KeybindingsMap = {
NEW1: ['Ctrl+1', 'Meta+1'], NEW1: ['Ctrl+1', 'Meta+1'],
NEW2: ['Ctrl+2', 'Meta+2'], NEW2: ['Ctrl+2', 'Meta+2'],
NEW3: ['Ctrl+3', 'Meta+3'], NEW3: ['Ctrl+3', 'Meta+3'],
NEW4: ['Ctrl+4', 'Meta+4'],
FOCUS: ['/', '/'], FOCUS: ['/', '/'],
ADD: ['Alt+Ctrl+Enter', 'Alt+Meta+Enter'] ADD: ['Alt+Ctrl+Enter', 'Alt+Meta+Enter']
}; };
+4
View File
@@ -629,6 +629,10 @@ body {
.ant-image { .ant-image {
border-radius: var(--border-radius-base); border-radius: var(--border-radius-base);
overflow: hidden; overflow: hidden;
.ant-image-mask {
background: rgba(0, 0, 0, 25%);
}
} }
.ant-message-notice-wrapper { .ant-message-notice-wrapper {
+5
View File
@@ -15,6 +15,10 @@ export default function useExpandedRowKeys() {
); );
const updateExpandedRowKeys = (keys: React.Key[]) => { const updateExpandedRowKeys = (keys: React.Key[]) => {
setExpandedRowKeys(keys);
};
const removeExpandedRowKey = (keys: React.Key[]) => {
// remove expanded row keys that are in the deleted keys // remove expanded row keys that are in the deleted keys
const newExpandedRowKeys = expandedRowKeys.filter( const newExpandedRowKeys = expandedRowKeys.filter(
(key) => !keys.includes(key) (key) => !keys.includes(key)
@@ -30,6 +34,7 @@ export default function useExpandedRowKeys() {
expandedRowKeys, expandedRowKeys,
clearExpandedRowKeys, clearExpandedRowKeys,
updateExpandedRowKeys, updateExpandedRowKeys,
removeExpandedRowKey,
handleExpandChange handleExpandChange
}; };
} }
@@ -36,7 +36,6 @@ interface AdvanceConfigProps {
gpuOptions: Array<any>; gpuOptions: Array<any>;
action: PageActionType; action: PageActionType;
source: string; source: string;
modelTask: Record<string, any>;
} }
const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => { const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
+1 -2
View File
@@ -291,7 +291,7 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
<SealAutoComplete <SealAutoComplete
filterOption filterOption
defaultActiveFirstOption defaultActiveFirstOption
disabled={action === PageAction.EDIT} disabled={false}
options={ollamaModelOptions} options={ollamaModelOptions}
label={intl.formatMessage({ id: 'model.form.ollama.model' })} label={intl.formatMessage({ id: 'model.form.ollama.model' })}
placeholder={intl.formatMessage({ id: 'model.form.ollamaholder' })} placeholder={intl.formatMessage({ id: 'model.form.ollamaholder' })}
@@ -503,7 +503,6 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
form={form} form={form}
gpuOptions={gpuOptions} gpuOptions={gpuOptions}
isGGUF={isGGUF} isGGUF={isGGUF}
modelTask={modelTask}
action={action} action={action}
source={props.source} source={props.source}
></AdvanceConfig> ></AdvanceConfig>
+28 -6
View File
@@ -82,8 +82,12 @@ const Models: React.FC<ModelsProps> = ({
const intl = useIntl(); const intl = useIntl();
const navigate = useNavigate(); const navigate = useNavigate();
const rowSelection = useTableRowSelection(); const rowSelection = useTableRowSelection();
const { handleExpandChange, updateExpandedRowKeys, expandedRowKeys } = const {
useExpandedRowKeys(); handleExpandChange,
updateExpandedRowKeys,
removeExpandedRowKey,
expandedRowKeys
} = useExpandedRowKeys();
const { sortOrder, setSortOrder } = useTableSort({ const { sortOrder, setSortOrder } = useTableSort({
defaultSortOrder: 'descend' defaultSortOrder: 'descend'
}); });
@@ -152,6 +156,20 @@ const Models: React.FC<ModelsProps> = ({
enabled: !openAddModal && !openDeployModal.show && !openLogModal enabled: !openAddModal && !openDeployModal.show && !openLogModal
} }
); );
useHotkeys(
HotKeys.NEW4.join(','),
() => {
setOpenDeployModal({
show: true,
width: 600,
source: modelSourceMap.local_path_value
});
},
{
preventDefault: true,
enabled: !openAddModal && !openDeployModal.show && !openLogModal
}
);
const sourceOptions = [ const sourceOptions = [
{ {
@@ -299,16 +317,20 @@ const Models: React.FC<ModelsProps> = ({
const result = getSourceRepoConfigValue(openDeployModal.source, data); const result = getSourceRepoConfigValue(openDeployModal.source, data);
await createModel({ const modelData = await createModel({
data: { data: {
...result.values, ...result.values,
..._.omit(data, result.omits) ..._.omit(data, result.omits)
} }
}); });
console.log('modelData:', modelData);
setOpenDeployModal({ setOpenDeployModal({
...openDeployModal, ...openDeployModal,
show: false show: false
}); });
setTimeout(() => {
updateExpandedRowKeys([modelData.id]);
}, 300);
message.success(intl.formatMessage({ id: 'common.message.success' })); message.success(intl.formatMessage({ id: 'common.message.success' }));
} catch (error) {} } catch (error) {}
}, },
@@ -324,7 +346,7 @@ const Models: React.FC<ModelsProps> = ({
name: row.name, name: row.name,
async onOk() { async onOk() {
await deleteModel(row.id); await deleteModel(row.id);
updateExpandedRowKeys([row.id]); removeExpandedRowKey([row.id]);
rowSelection.removeSelectedKey(row.id); rowSelection.removeSelectedKey(row.id);
} }
}); });
@@ -336,7 +358,7 @@ const Models: React.FC<ModelsProps> = ({
async onOk() { async onOk() {
await handleBatchRequest(rowSelection.selectedRowKeys, deleteModel); await handleBatchRequest(rowSelection.selectedRowKeys, deleteModel);
rowSelection.clearSelections(); rowSelection.clearSelections();
updateExpandedRowKeys(rowSelection.selectedRowKeys); removeExpandedRowKey(rowSelection.selectedRowKeys);
} }
}); });
}; };
@@ -386,7 +408,7 @@ const Models: React.FC<ModelsProps> = ({
async onOk() { async onOk() {
await deleteModelInstance(row.id); await deleteModelInstance(row.id);
if (list.length === 1) { if (list.length === 1) {
updateExpandedRowKeys([row.model_id]); removeExpandedRowKey([row.model_id]);
} }
} }
}); });
+30 -11
View File
@@ -1,3 +1,4 @@
import IconFont from '@/components/icon-font';
import ModalFooter from '@/components/modal-footer'; import ModalFooter from '@/components/modal-footer';
import SealAutoComplete from '@/components/seal-form/auto-complete'; import SealAutoComplete from '@/components/seal-form/auto-complete';
import SealInput from '@/components/seal-form/seal-input'; import SealInput from '@/components/seal-form/seal-input';
@@ -5,7 +6,7 @@ import SealSelect from '@/components/seal-form/seal-select';
import { PageAction } from '@/config'; import { PageAction } from '@/config';
import { PageActionType } from '@/config/types'; import { PageActionType } from '@/config/types';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Form, Modal } from 'antd'; import { Form, Modal, Tooltip, Typography } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import React, { memo, useEffect, useMemo, useState } from 'react'; import React, { memo, useEffect, useMemo, useState } from 'react';
import SimpleBar from 'simplebar-react'; import SimpleBar from 'simplebar-react';
@@ -14,6 +15,7 @@ import { queryGPUList } from '../apis';
import { import {
backendOptionsMap, backendOptionsMap,
modelSourceMap, modelSourceMap,
ollamaModelOptions,
setSourceRepoConfigValue setSourceRepoConfigValue
} from '../config'; } from '../config';
import { FormData, GPUListItem, ListItem } from '../config/types'; import { FormData, GPUListItem, ListItem } from '../config/types';
@@ -119,7 +121,7 @@ const UpdateModal: React.FC<AddModalProps> = (props) => {
<SealInput.Input <SealInput.Input
label={intl.formatMessage({ id: 'models.form.repoid' })} label={intl.formatMessage({ id: 'models.form.repoid' })}
required required
disabled={true} disabled={false}
></SealInput.Input> ></SealInput.Input>
</Form.Item> </Form.Item>
{isGGUF && ( {isGGUF && (
@@ -137,14 +139,12 @@ const UpdateModal: React.FC<AddModalProps> = (props) => {
} }
]} ]}
> >
<SealAutoComplete <SealInput.Input
filterOption
label={intl.formatMessage({ id: 'models.form.filename' })} label={intl.formatMessage({ id: 'models.form.filename' })}
required required
options={[]}
loading={loading} loading={loading}
disabled={action === PageAction.EDIT} disabled={false}
></SealAutoComplete> ></SealInput.Input>
</Form.Item> </Form.Item>
)} )}
</> </>
@@ -196,12 +196,31 @@ const UpdateModal: React.FC<AddModalProps> = (props) => {
} }
]} ]}
> >
<SealInput.Input <SealAutoComplete
disabled={action === PageAction.EDIT} filterOption
defaultActiveFirstOption
disabled={false}
options={ollamaModelOptions}
label={intl.formatMessage({ id: 'model.form.ollama.model' })} label={intl.formatMessage({ id: 'model.form.ollama.model' })}
placeholder={intl.formatMessage({ id: 'model.form.ollamaholder' })} placeholder={intl.formatMessage({ id: 'model.form.ollamaholder' })}
addAfter={
<Typography.Link
href="https://www.ollama.com/library"
target="_blank"
>
<Tooltip
title={intl.formatMessage({ id: 'models.form.ollamalink' })}
placement="topRight"
>
<IconFont
type="icon-external-link"
className="font-size-14"
></IconFont>
</Tooltip>
</Typography.Link>
}
required required
></SealInput.Input> ></SealAutoComplete>
</Form.Item> </Form.Item>
</> </>
); );
@@ -226,7 +245,7 @@ const UpdateModal: React.FC<AddModalProps> = (props) => {
]} ]}
> >
<SealInput.Input <SealInput.Input
disabled={action === PageAction.EDIT} disabled={false}
label={intl.formatMessage({ id: 'models.form.filePath' })} label={intl.formatMessage({ id: 'models.form.filePath' })}
required required
></SealInput.Input> ></SealInput.Input>