Files
kevisual-center-v1/src/pages/app/edit/List.tsx

226 lines
8.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useShallow } from 'zustand/react/shallow';
import { useUserAppStore } from '../store';
import { useEffect } from 'react';
import { Button, Form, Input, Space, Modal, Select, Tooltip, Switch } from 'antd';
import { CodeOutlined, DeleteOutlined, EditOutlined, LinkOutlined, PlusOutlined, UnorderedListOutlined } from '@ant-design/icons';
import { isObjectNull } from '@/utils/is-null';
import { useNewNavigate } from '@/modules';
import { marked } from 'marked';
import clsx from 'clsx';
import { message } from '@/modules/message';
const FormModal = () => {
const [form] = Form.useForm();
const containerStore = useUserAppStore(
useShallow((state) => {
return {
showEdit: state.showEdit,
setShowEdit: state.setShowEdit,
formData: state.formData,
updateData: state.updateData,
};
}),
);
useEffect(() => {
const open = containerStore.showEdit;
if (open) {
if (open) {
const isNull = isObjectNull(containerStore.formData);
if (isNull) {
form.setFieldsValue({});
} else form.setFieldsValue(containerStore.formData);
}
}
}, [containerStore.showEdit]);
const onFinish = async (values: any) => {
containerStore.updateData(values);
};
const onClose = () => {
containerStore.setShowEdit(false);
form.resetFields();
};
const isEdit = containerStore.formData.id;
return (
<Modal
title={isEdit ? 'Edit' : 'Add'}
open={containerStore.showEdit}
onClose={() => containerStore.setShowEdit(false)}
destroyOnClose
footer={false}
width={800}
onCancel={onClose}>
<Form
form={form}
onFinish={onFinish}
labelCol={{
span: 4,
}}
wrapperCol={{
span: 20,
}}>
<Form.Item name='id' hidden>
<Input />
</Form.Item>
<Form.Item name='title' label='title'>
<Input />
</Form.Item>
<Form.Item name='domain' label='domain'>
<Input />
</Form.Item>
<Form.Item name='key' label='key'>
<Input />
</Form.Item>
<Form.Item name='description' label='description'>
<Input.TextArea rows={4} />
</Form.Item>
<Form.Item name='proxy' label='proxy' tooltip='静态网站设置如果是静态网站不需要重定向到index.html的页面。'>
<Switch />
</Form.Item>
<Form.Item name='status' label='status'>
<Select
options={[
{ label: 'Running', value: 'running' },
{ label: 'Stop', value: 'stop' },
]}
/>
</Form.Item>
<Form.Item label=' ' colon={false}>
<Button type='primary' htmlType='submit'>
Submit
</Button>
<Button className='ml-2' htmlType='reset' onClick={onClose}>
Cancel
</Button>
</Form.Item>
</Form>
</Modal>
);
};
export const List = () => {
const [modal, contextHolder] = Modal.useModal();
const userAppStore = useUserAppStore(
useShallow((state) => {
return {
list: state.list,
getList: state.getList,
setShowEdit: state.setShowEdit,
formData: state.formData,
setFormData: state.setFormData,
deleteData: state.deleteData,
};
}),
);
const navicate = useNewNavigate();
useEffect(() => {
userAppStore.getList();
}, []);
return (
<div className='w-full h-full flex bg-slate-100'>
<div className='p-2 h-full bg-white flex flex-col gap-2'>
<Button
onClick={() => {
userAppStore.setShowEdit(true);
}}
icon={<PlusOutlined />}></Button>
<Tooltip title='To Container'>
<Button
onClick={() => {
navicate('/container');
}}
icon={<CodeOutlined />}></Button>
</Tooltip>
</div>
<div className='grow'>
<div className='w-full h-full p-4'>
<div className='w-full h-full bg-white rounded-lg p-2 scrollbar '>
<div className='flex flex-wrap gap-2'>
{userAppStore.list.map((item) => {
const isRunning = item.status === 'running';
const hasDescription = !!item.description;
const content = marked.parse(item.description);
return (
<div className='card border-t border-gray-200 w-[300px] ' key={item.id}>
<div className='card-title flex justify-between' onClick={() => {}}>
{item.title}
<div>
<div className={`${isRunning ? 'bg-green-500' : 'bg-red-500'} w-4 h-4 rounded-full`}></div>
</div>
</div>
<div>
<div className='text-xs'>domain: {item.domain}</div>
<div className='text-xs'>version: {item.version}</div>
<div className={clsx('text-sm border border-gray-200 p-2 max-h-[140px] scrollbar my-1', !hasDescription && 'hidden')}>
<div dangerouslySetInnerHTML={{ __html: content }}></div>
</div>
</div>
<div className='mt-2'>
<Space.Compact>
<Tooltip title={'Edit'}>
<Button
icon={<EditOutlined />}
onClick={() => {
userAppStore.setFormData(item);
userAppStore.setShowEdit(true);
}}></Button>
</Tooltip>
<Tooltip title={'App Version List'}>
<Button
icon={<UnorderedListOutlined />}
onClick={() => {
navicate(`/app/${item.key}/version/list`);
}}></Button>
</Tooltip>
<Tooltip title={'To App'}>
<Button
icon={<LinkOutlined />}
onClick={() => {
if (isRunning) {
let baseUri = location.origin;
if (item.domain) {
if (item.domain.startsWith('http://') || item.domain.startsWith('https://')) {
baseUri = item.domain;
} else {
baseUri = new URL(item.domain).origin;
}
}
if (DEV_SERVER) {
baseUri = 'http://localhost:3005';
}
const link = new URL(`/${item.user}/${item.key}`, baseUri);
window.open(link.toString(), '_blank');
} else {
message.error('The app is not running');
}
}}></Button>
</Tooltip>
<Tooltip title={'Delete'}>
<Button
icon={<DeleteOutlined />}
onClick={(e) => {
console.log('delete', item);
modal.confirm({
title: 'Delete',
content: 'Are you sure delete this data?',
onOk: () => {
userAppStore.deleteData(item.id);
},
});
e.stopPropagation();
}}></Button>
</Tooltip>
</Space.Compact>
</div>
</div>
);
})}
</div>
</div>
</div>
</div>
{contextHolder}
<FormModal />
</div>
);
};