mirror of
https://github.com/lencx/ChatGPT.git
synced 2026-02-06 14:26:49 +00:00
chore: export
This commit is contained in:
parent
a2fcfa3b89
commit
ae2c56805c
@ -207,8 +207,8 @@ pub fn download_list(pathname: &str, filename: Option<String>, id: Option<String
|
||||
info!("download_list: {}", pathname);
|
||||
let data = get_download_list(pathname);
|
||||
let mut list = vec![];
|
||||
let mut my_hashmap = HashMap::new();
|
||||
utils::vec_to_hashmap(data.0.into_iter(), "id", &mut my_hashmap);
|
||||
let mut idmap = HashMap::new();
|
||||
utils::vec_to_hashmap(data.0.into_iter(), "id", &mut idmap);
|
||||
|
||||
for entry in WalkDir::new(utils::chat_root().join("download"))
|
||||
.into_iter()
|
||||
@ -229,7 +229,19 @@ pub fn download_list(pathname: &str, filename: Option<String>, id: Option<String
|
||||
ext: fext.to_string(),
|
||||
created: fs_extra::system_time_to_ms(metadata.created()),
|
||||
};
|
||||
if my_hashmap.get(fid).is_some() && filename.is_some() && id.is_some() {
|
||||
|
||||
if idmap.get(fid).is_some() {
|
||||
let name = idmap.get(fid).unwrap().get("name").unwrap().clone();
|
||||
match name {
|
||||
serde_json::Value::String(v) => {
|
||||
file_data.name = v.clone();
|
||||
v
|
||||
}
|
||||
_ => "".to_string(),
|
||||
};
|
||||
}
|
||||
|
||||
if filename.is_some() && id.is_some() {
|
||||
if let Some(ref v) = id {
|
||||
if fid == v {
|
||||
if let Some(ref v2) = filename {
|
||||
|
||||
25
src-tauri/src/scripts/export.js
vendored
25
src-tauri/src/scripts/export.js
vendored
@ -52,11 +52,13 @@ function shouldAddButtons(actionsArea) {
|
||||
return !/download-/.test(button.id);
|
||||
});
|
||||
|
||||
if (/Stop generating/ig.test(buttons[0].innerText)) {
|
||||
const stopBtn = buttons?.[0]?.innerText;
|
||||
|
||||
if (/Stop generating/ig.test(stopBtn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buttons.length === 2 && (/Regenerate response/ig.test(buttons[0].innerText) || buttons[1].innerText === '')) {
|
||||
if (buttons.length === 2 && (/Regenerate response/ig.test(stopBtn) || buttons[1].innerText === '')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -132,7 +134,7 @@ function addActionsButtons(actionsArea, TryAgainButton) {
|
||||
|
||||
async function exportMarkdown() {
|
||||
const data = ExportMD.turndown(document.querySelector("main div>div>div").innerHTML);
|
||||
await invoke('save_file', { name: `notes/${Date.now().toString(36)}.md`, content: data });
|
||||
await invoke('save_file', { name: `notes/${uid().toString(36)}.md`, content: data });
|
||||
}
|
||||
|
||||
function downloadThread({ as = Format.PNG } = {}) {
|
||||
@ -164,8 +166,9 @@ async function handleImg(imgData) {
|
||||
for (let i = 0; i < binaryData.length; i++) {
|
||||
data.push(binaryData.charCodeAt(i));
|
||||
}
|
||||
await invoke('download', { name: `download/img/${Date.now().toString(36)}.png`, blob: data });
|
||||
await invoke('download_list');
|
||||
const { pathname, id, filename } = getName();
|
||||
await invoke('download', { name: `download/img/${id}.png`, blob: data });
|
||||
await invoke('download_list', { pathname, filename, id });
|
||||
}
|
||||
|
||||
async function handlePdf(imgData, canvas, pixelRatio) {
|
||||
@ -178,10 +181,16 @@ async function handlePdf(imgData, canvas, pixelRatio) {
|
||||
var pdfWidth = pdf.internal.pageSize.getWidth();
|
||||
var pdfHeight = pdf.internal.pageSize.getHeight();
|
||||
pdf.addImage(imgData, "PNG", 0, 0, pdfWidth, pdfHeight, '', 'FAST');
|
||||
|
||||
const { pathname, id, filename } = getName();
|
||||
const data = pdf.__private__.getArrayBuffer(pdf.__private__.buildDocument());
|
||||
await invoke('download', { name: `download/pdf/${Date.now().toString(36)}.pdf`, blob: Array.from(new Uint8Array(data)) });
|
||||
await invoke('download_list');
|
||||
await invoke('download', { name: `download/pdf/${id}.pdf`, blob: Array.from(new Uint8Array(data)) });
|
||||
await invoke('download_list', { pathname, filename, id });
|
||||
}
|
||||
|
||||
function getName() {
|
||||
const id = uid().toString(36);
|
||||
const name = document.querySelector('nav .overflow-y-auto a.hover\\:bg-gray-800')?.innerText?.trim() || '';
|
||||
return { filename: name ? name : id, id, pathname: 'chat.download.json' };
|
||||
}
|
||||
|
||||
class Elements {
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { FC, useState, useCallback } from 'react';
|
||||
import { Input } from 'antd';
|
||||
|
||||
import { DISABLE_AUTO_COMPLETE } from '@/utils';
|
||||
|
||||
export default function useColumns(columns: any[] = []) {
|
||||
const [opType, setOpType] = useState('');
|
||||
@ -41,4 +44,40 @@ export default function useColumns(columns: any[] = []) {
|
||||
setExtra,
|
||||
opExtra,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface EditRowProps {
|
||||
rowKey: string;
|
||||
row: Record<string, any>;
|
||||
actions: any;
|
||||
}
|
||||
export const EditRow: FC<EditRowProps> = ({ rowKey, row, actions }) => {
|
||||
const [isEdit, setEdit] = useState(false);
|
||||
const [val, setVal] = useState(row[rowKey]);
|
||||
const handleEdit = () => {
|
||||
setEdit(true);
|
||||
};
|
||||
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setVal(e.target.value)
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
setEdit(false);
|
||||
row[rowKey] = val;
|
||||
actions?.setRecord(row, 'rowedit')
|
||||
};
|
||||
|
||||
return isEdit
|
||||
? (
|
||||
<Input.TextArea
|
||||
value={val}
|
||||
rows={1}
|
||||
onChange={handleChange}
|
||||
{...DISABLE_AUTO_COMPLETE}
|
||||
onPressEnter={handleSave}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<div className='rowedit' onClick={handleEdit}>{val}</div>
|
||||
);
|
||||
};
|
||||
9
src/hooks/useJson.ts
vendored
9
src/hooks/useJson.ts
vendored
@ -1,6 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { readJSON } from '@/utils';
|
||||
import { readJSON, writeJSON } from '@/utils';
|
||||
import useInit from '@/hooks/useInit';
|
||||
|
||||
export default function useJson<T>(file: string) {
|
||||
@ -11,7 +11,12 @@ export default function useJson<T>(file: string) {
|
||||
setData(data);
|
||||
};
|
||||
|
||||
const updateJson = async (data: any) => {
|
||||
await writeJSON(file, data);
|
||||
await refreshJson();
|
||||
};
|
||||
|
||||
useInit(refreshJson);
|
||||
|
||||
return { json, refreshJson };
|
||||
return { json, refreshJson, updateJson };
|
||||
}
|
||||
|
||||
33
src/hooks/useTable.tsx
vendored
33
src/hooks/useTable.tsx
vendored
@ -4,14 +4,35 @@ import type { TableRowSelection } from 'antd/es/table/interface';
|
||||
|
||||
import { safeKey } from '@/hooks/useData';
|
||||
|
||||
export default function useTableRowSelection() {
|
||||
type rowSelectionOptions = {
|
||||
key: 'id' | string;
|
||||
rowType: 'id' | 'row' | 'all';
|
||||
}
|
||||
export function useTableRowSelection(options: Partial<rowSelectionOptions> = {}) {
|
||||
const { key = 'id', rowType = 'id' } = options;
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||||
const [selectedRowIDs, setSelectedRowIDs] = useState<string[]>([]);
|
||||
const [selectedRows, setSelectedRows] = useState<Record<string|symbol, any>[]>([]);
|
||||
|
||||
const onSelectChange = (newSelectedRowKeys: React.Key[], selectedRows: Record<string|symbol, any>) => {
|
||||
const keys = selectedRows.map((i: any) => i[safeKey]);
|
||||
setSelectedRowIDs(keys);
|
||||
const onSelectChange = (newSelectedRowKeys: React.Key[], newSelectedRows: Record<string|symbol, any>[]) => {
|
||||
const keys = newSelectedRows.map((i: any) => i[safeKey] || i[key]);
|
||||
setSelectedRowKeys(newSelectedRowKeys);
|
||||
if (rowType === 'id') {
|
||||
setSelectedRowIDs(keys);
|
||||
}
|
||||
if (rowType === 'row') {
|
||||
setSelectedRows(newSelectedRows);
|
||||
}
|
||||
if (rowType === 'all') {
|
||||
setSelectedRowIDs(keys);
|
||||
setSelectedRows(newSelectedRows);
|
||||
}
|
||||
};
|
||||
|
||||
const rowReset = () => {
|
||||
setSelectedRowKeys([]);
|
||||
setSelectedRowIDs([]);
|
||||
setSelectedRows([]);
|
||||
};
|
||||
|
||||
const rowSelection: TableRowSelection<Record<string, any>> = {
|
||||
@ -24,14 +45,14 @@ export default function useTableRowSelection() {
|
||||
],
|
||||
};
|
||||
|
||||
return { rowSelection, selectedRowIDs };
|
||||
return { rowSelection, selectedRowIDs, selectedRows, rowReset };
|
||||
}
|
||||
|
||||
export const TABLE_PAGINATION = {
|
||||
hideOnSinglePage: true,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
defaultPageSize: 5,
|
||||
defaultPageSize: 10,
|
||||
pageSizeOptions: [5, 10, 15, 20],
|
||||
showTotal: (total: number) => <span>Total {total} items</span>,
|
||||
};
|
||||
19
src/main.scss
vendored
19
src/main.scss
vendored
@ -31,10 +31,27 @@ html, body {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.ellipsis-line {
|
||||
display: inline-block;
|
||||
width: 180px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.rowedit {
|
||||
padding: 2px 5px;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0 2px rgba(237, 122, 60, 0.8);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-add-btn {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
44
src/view/download/config.tsx
vendored
44
src/view/download/config.tsx
vendored
@ -1,37 +1,57 @@
|
||||
import { useState } from 'react';
|
||||
import { Tag, Space, Popconfirm } from 'antd';
|
||||
import { path, shell } from '@tauri-apps/api';
|
||||
|
||||
import { fmtDate } from '@/utils';
|
||||
import { EditRow } from '@/hooks/useColumns';
|
||||
|
||||
import useInit from '@/hooks/useInit';
|
||||
import { fmtDate, chatRoot } from '@/utils';
|
||||
|
||||
const colorMap: any = {
|
||||
pdf: 'blue',
|
||||
png: 'orange',
|
||||
}
|
||||
|
||||
export const syncColumns = () => [
|
||||
export const downloadColumns = () => [
|
||||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
fixed: 'left',
|
||||
key: 'name',
|
||||
width: 240,
|
||||
render: (_: string, row: any, actions: any) => (
|
||||
<EditRow rowKey="name" row={row} actions={actions} />
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Extension',
|
||||
dataIndex: 'ext',
|
||||
key: 'ext',
|
||||
width: 120,
|
||||
render: (v: string) => <Tag color={colorMap[v]}>{v}</Tag>,
|
||||
},
|
||||
{
|
||||
title: 'Path',
|
||||
dataIndex: 'path',
|
||||
key: 'path',
|
||||
width: 200,
|
||||
render: (_: string, row: any) => <RenderPath row={row} />,
|
||||
},
|
||||
{
|
||||
title: 'Created',
|
||||
dataIndex: 'created',
|
||||
key: 'created',
|
||||
width: 150,
|
||||
render: fmtDate,
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
fixed: 'right',
|
||||
width: 150,
|
||||
render: (_: any, row: any, actions: any) => {
|
||||
return (
|
||||
<Space>
|
||||
<a onClick={() => actions.setRecord(row, 'view')}>View</a>
|
||||
<a onClick={() => actions.setRecord(row, 'preview')}>Preview</a>
|
||||
<Popconfirm
|
||||
title="Are you sure to delete this file?"
|
||||
onConfirm={() => actions.setRecord(row, 'delete')}
|
||||
@ -46,9 +66,15 @@ export const syncColumns = () => [
|
||||
}
|
||||
];
|
||||
|
||||
// {
|
||||
// id: '',
|
||||
// name: '',
|
||||
// type: '.png',
|
||||
// created: '2022.01.01',
|
||||
// }
|
||||
const RenderPath = ({ row }: any) => {
|
||||
const [filePath, setFilePath] = useState('');
|
||||
useInit(async () => {
|
||||
setFilePath(await getPath(row));
|
||||
})
|
||||
return <a onClick={() => shell.open(filePath)}>{filePath}</a>;
|
||||
};
|
||||
|
||||
export const getPath = async (row: any) => {
|
||||
const isImg = ['png'].includes(row?.ext);
|
||||
return await path.join(await chatRoot(), 'download', isImg ? 'img' : row.ext, row.id) + `.${row.ext}`;
|
||||
}
|
||||
|
||||
12
src/view/download/index.scss
vendored
12
src/view/download/index.scss
vendored
@ -1,12 +0,0 @@
|
||||
.chat-table-tip, .chat-table-btns {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.chat-table-btns {
|
||||
margin-bottom: 5px;
|
||||
|
||||
.num {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
100
src/view/download/index.tsx
vendored
100
src/view/download/index.tsx
vendored
@ -1,14 +1,14 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Table, Modal } from 'antd';
|
||||
import { path, shell, fs } from '@tauri-apps/api';
|
||||
import { Table, Modal, Popconfirm, Button, message } from 'antd';
|
||||
import { invoke, path, shell, fs } from '@tauri-apps/api';
|
||||
|
||||
import useInit from '@/hooks/useInit';
|
||||
import useJson from '@/hooks/useJson';
|
||||
import useData from '@/hooks/useData';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import useTable, { TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { useTableRowSelection, TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { chatRoot, CHAT_DOWNLOAD_JSON } from '@/utils';
|
||||
import { syncColumns } from './config';
|
||||
import './index.scss';
|
||||
import { downloadColumns } from './config';
|
||||
|
||||
function renderFile(buff: Uint8Array, type: string) {
|
||||
const renderType = {
|
||||
@ -19,52 +19,124 @@ function renderFile(buff: Uint8Array, type: string) {
|
||||
}
|
||||
|
||||
export default function SyncPrompts() {
|
||||
const { rowSelection, selectedRowIDs } = useTable();
|
||||
const { columns, ...opInfo } = useColumns(syncColumns());
|
||||
const [downloadPath, setDownloadPath] = useState('');
|
||||
const { json } = useJson<any[]>(CHAT_DOWNLOAD_JSON);
|
||||
const [source, setSource] = useState('');
|
||||
const [isVisible, setVisible] = useState(false);
|
||||
const { opData, opInit, opReplace, opSafeKey } = useData([]);
|
||||
const { columns, ...opInfo } = useColumns(downloadColumns());
|
||||
const { rowSelection, selectedRows, rowReset } = useTableRowSelection({ rowType: 'row' });
|
||||
const { json, refreshJson, updateJson } = useJson<any[]>(CHAT_DOWNLOAD_JSON);
|
||||
const selectedItems = rowSelection.selectedRowKeys || [];
|
||||
|
||||
useInit(async () => {
|
||||
const file = await path.join(await chatRoot(), 'chat.download.json');
|
||||
const file = await path.join(await chatRoot(), CHAT_DOWNLOAD_JSON);
|
||||
setDownloadPath(file);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!json || json.length <= 0) return;
|
||||
opInit(json);
|
||||
}, [json?.length]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!opInfo.opType) return;
|
||||
(async () => {
|
||||
const record = opInfo?.opRecord;
|
||||
const isImg = ['png'].includes(record?.ext);
|
||||
const file = await path.join(await chatRoot(), 'download', isImg ? 'img' : record?.ext, `${record?.id}.${record?.ext}`);
|
||||
if (opInfo.opType === 'view') {
|
||||
if (opInfo.opType === 'preview') {
|
||||
const data = await fs.readBinaryFile(file);
|
||||
const sourceData = renderFile(data, record?.ext);
|
||||
setSource(sourceData);
|
||||
setVisible(true);
|
||||
return;
|
||||
}
|
||||
if (opInfo.opType === 'file') {
|
||||
await shell.open(file);
|
||||
}
|
||||
if (opInfo.opType === 'delete') {
|
||||
await fs.removeFile(file);
|
||||
await handleRefresh();
|
||||
}
|
||||
if (opInfo.opType === 'rowedit') {
|
||||
const data = opReplace(opInfo?.opRecord?.[opSafeKey], opInfo?.opRecord);
|
||||
await updateJson(data);
|
||||
message.success('Name has been changed!');
|
||||
}
|
||||
opInfo.resetRecord();
|
||||
})()
|
||||
}, [opInfo.opType])
|
||||
|
||||
const handleDelete = async () => {
|
||||
if (opData?.length === selectedRows.length) {
|
||||
const downloadDir = await path.join(await chatRoot(), 'download');
|
||||
await fs.removeDir(downloadDir, { recursive: true });
|
||||
await handleRefresh();
|
||||
rowReset();
|
||||
message.success('All files have been cleared!');
|
||||
return;
|
||||
}
|
||||
|
||||
const rows = selectedRows.map(async (i) => {
|
||||
const isImg = ['png'].includes(i?.ext);
|
||||
const file = await path.join(await chatRoot(), 'download', isImg ? 'img' : i?.ext, `${i?.id}.${i?.ext}`);
|
||||
await fs.removeFile(file);
|
||||
return file;
|
||||
})
|
||||
Promise.all(rows).then(async () => {
|
||||
await handleRefresh();
|
||||
message.success('All files selected are cleared!');
|
||||
});
|
||||
};
|
||||
|
||||
const handleRefresh = async () => {
|
||||
await invoke('download_list', { pathname: CHAT_DOWNLOAD_JSON });
|
||||
refreshJson();
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
setVisible(false);
|
||||
opInfo.resetRecord();
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="chat-table-btns">
|
||||
<div>
|
||||
{selectedItems.length > 0 && (
|
||||
<>
|
||||
<Popconfirm
|
||||
overlayStyle={{ width: 250 }}
|
||||
title="Sync will overwrite the previous data, confirm to sync?"
|
||||
placement="topLeft"
|
||||
onConfirm={handleDelete}
|
||||
okText="Yes"
|
||||
cancelText="No"
|
||||
>
|
||||
<Button>Batch delete</Button>
|
||||
</Popconfirm>
|
||||
<span className="num">Selected {selectedItems.length} items</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="chat-table-tip">
|
||||
<div className="chat-file-path">
|
||||
<div>PATH: <a onClick={() => shell.open(downloadPath)} title={downloadPath}>{downloadPath}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<Table
|
||||
rowKey="name"
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
scroll={{ x: 'auto' }}
|
||||
dataSource={json}
|
||||
scroll={{ x: 800 }}
|
||||
dataSource={opData}
|
||||
rowSelection={rowSelection}
|
||||
pagination={TABLE_PAGINATION}
|
||||
/>
|
||||
<Modal
|
||||
open={isVisible}
|
||||
onCancel={() => setVisible(false)}
|
||||
title={<div>{opInfo?.opRecord?.name || ''}</div>}
|
||||
onCancel={handleCancel}
|
||||
footer={false}
|
||||
destroyOnClose
|
||||
>
|
||||
|
||||
5
src/view/model/SyncPrompts/config.tsx
vendored
5
src/view/model/SyncPrompts/config.tsx
vendored
@ -1,4 +1,4 @@
|
||||
import { Switch, Tag, Tooltip } from 'antd';
|
||||
import { Table, Switch, Tag } from 'antd';
|
||||
|
||||
import { genCmd } from '@/utils';
|
||||
|
||||
@ -35,13 +35,14 @@ export const syncColumns = () => [
|
||||
<Switch checked={v} onChange={(v) => action.setRecord({ ...row, enable: v }, 'enable')} />
|
||||
),
|
||||
},
|
||||
Table.EXPAND_COLUMN,
|
||||
{
|
||||
title: 'Prompt',
|
||||
dataIndex: 'prompt',
|
||||
key: 'prompt',
|
||||
// width: 300,
|
||||
render: (v: string) => (
|
||||
<Tooltip overlayInnerStyle={{ width: 350 }} title={v}><span className="chat-prompts-val">{v}</span></Tooltip>
|
||||
<span className="chat-prompts-val">{v}</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
5
src/view/model/SyncPrompts/index.tsx
vendored
5
src/view/model/SyncPrompts/index.tsx
vendored
@ -6,7 +6,7 @@ import useInit from '@/hooks/useInit';
|
||||
import useData from '@/hooks/useData';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import useChatModel, { useCacheModel } from '@/hooks/useChatModel';
|
||||
import useTable, { TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { useTableRowSelection, TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { fmtDate, chatRoot } from '@/utils';
|
||||
import { syncColumns } from './config';
|
||||
import './index.scss';
|
||||
@ -14,7 +14,7 @@ import './index.scss';
|
||||
const promptsURL = 'https://github.com/f/awesome-chatgpt-prompts/blob/main/prompts.csv';
|
||||
|
||||
export default function SyncPrompts() {
|
||||
const { rowSelection, selectedRowIDs } = useTable();
|
||||
const { rowSelection, selectedRowIDs } = useTableRowSelection();
|
||||
const [jsonPath, setJsonPath] = useState('');
|
||||
const { modelJson, modelSet } = useChatModel('sync_prompts');
|
||||
const { modelCacheJson, modelCacheSet } = useCacheModel(jsonPath);
|
||||
@ -93,6 +93,7 @@ export default function SyncPrompts() {
|
||||
dataSource={opData}
|
||||
rowSelection={rowSelection}
|
||||
pagination={TABLE_PAGINATION}
|
||||
expandable={{expandedRowRender: (record) => <div style={{ padding: 10 }}>{record.prompt}</div>}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
5
src/view/model/SyncRecord/config.tsx
vendored
5
src/view/model/SyncRecord/config.tsx
vendored
@ -1,4 +1,4 @@
|
||||
import { Switch, Tag, Tooltip } from 'antd';
|
||||
import { Switch, Tag, Table } from 'antd';
|
||||
|
||||
import { genCmd } from '@/utils';
|
||||
|
||||
@ -37,13 +37,14 @@ export const syncColumns = () => [
|
||||
<Switch checked={v} onChange={(v) => action.setRecord({ ...row, enable: v }, 'enable')} />
|
||||
),
|
||||
},
|
||||
Table.EXPAND_COLUMN,
|
||||
{
|
||||
title: 'Prompt',
|
||||
dataIndex: 'prompt',
|
||||
key: 'prompt',
|
||||
// width: 300,
|
||||
render: (v: string) => (
|
||||
<Tooltip overlayInnerStyle={{ width: 350 }} title={v}><span className="chat-prompts-val">{v}</span></Tooltip>
|
||||
<span className="chat-prompts-val">{v}</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
5
src/view/model/SyncRecord/index.tsx
vendored
5
src/view/model/SyncRecord/index.tsx
vendored
@ -7,7 +7,7 @@ import { shell, path } from '@tauri-apps/api';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import useData from '@/hooks/useData';
|
||||
import { useCacheModel } from '@/hooks/useChatModel';
|
||||
import useTable, { TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { useTableRowSelection, TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { fmtDate, chatRoot } from '@/utils';
|
||||
import { getPath } from '@/view/model/SyncCustom/config';
|
||||
import { syncColumns } from './config';
|
||||
@ -19,7 +19,7 @@ export default function SyncRecord() {
|
||||
const [jsonPath, setJsonPath] = useState('');
|
||||
const state = location?.state;
|
||||
|
||||
const { rowSelection, selectedRowIDs } = useTable();
|
||||
const { rowSelection, selectedRowIDs } = useTableRowSelection();
|
||||
const { modelCacheJson, modelCacheSet } = useCacheModel(jsonPath);
|
||||
const { opData, opInit, opReplace, opReplaceItems, opSafeKey } = useData([]);
|
||||
const { columns, ...opInfo } = useColumns(syncColumns());
|
||||
@ -79,6 +79,7 @@ export default function SyncRecord() {
|
||||
dataSource={opData}
|
||||
rowSelection={rowSelection}
|
||||
pagination={TABLE_PAGINATION}
|
||||
expandable={{expandedRowRender: (record) => <div style={{ padding: 10 }}>{record.prompt}</div>}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
5
src/view/model/UserCustom/config.tsx
vendored
5
src/view/model/UserCustom/config.tsx
vendored
@ -1,4 +1,4 @@
|
||||
import { Tag, Switch, Tooltip, Space, Popconfirm } from 'antd';
|
||||
import { Tag, Switch, Space, Popconfirm, Table } from 'antd';
|
||||
|
||||
export const modelColumns = () => [
|
||||
{
|
||||
@ -33,13 +33,14 @@ export const modelColumns = () => [
|
||||
<Switch checked={v} onChange={(v) => action.setRecord({ ...row, enable: v }, 'enable')} />
|
||||
),
|
||||
},
|
||||
Table.EXPAND_COLUMN,
|
||||
{
|
||||
title: 'Prompt',
|
||||
dataIndex: 'prompt',
|
||||
key: 'prompt',
|
||||
width: 300,
|
||||
render: (v: string) => (
|
||||
<Tooltip overlayInnerStyle={{ width: 350 }} title={v}><span className="chat-prompts-val">{v}</span></Tooltip>
|
||||
<span className="chat-prompts-val">{v}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
||||
5
src/view/model/UserCustom/index.tsx
vendored
5
src/view/model/UserCustom/index.tsx
vendored
@ -6,13 +6,13 @@ import useInit from '@/hooks/useInit';
|
||||
import useData from '@/hooks/useData';
|
||||
import useChatModel, { useCacheModel } from '@/hooks/useChatModel';
|
||||
import useColumns from '@/hooks/useColumns';
|
||||
import useTable, { TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { useTableRowSelection, TABLE_PAGINATION } from '@/hooks/useTable';
|
||||
import { chatRoot, fmtDate } from '@/utils';
|
||||
import { modelColumns } from './config';
|
||||
import UserCustomForm from './Form';
|
||||
|
||||
export default function LanguageModel() {
|
||||
const { rowSelection, selectedRowIDs } = useTable();
|
||||
const { rowSelection, selectedRowIDs } = useTableRowSelection();
|
||||
const [isVisible, setVisible] = useState(false);
|
||||
const [jsonPath, setJsonPath] = useState('');
|
||||
const { modelJson, modelSet } = useChatModel('user_custom');
|
||||
@ -123,6 +123,7 @@ export default function LanguageModel() {
|
||||
dataSource={opData}
|
||||
rowSelection={rowSelection}
|
||||
pagination={TABLE_PAGINATION}
|
||||
expandable={{expandedRowRender: (record) => <div style={{ padding: 10 }}>{record.prompt}</div>}}
|
||||
/>
|
||||
<Modal
|
||||
open={isVisible}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user