220 lines
8.6 KiB
TypeScript
220 lines
8.6 KiB
TypeScript
import { Button, Form, Input, message, Modal, Select } from 'antd';
|
||
import React, { useState, useEffect, useRef } from 'react';
|
||
import Styles from './styles.module.less';
|
||
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
|
||
import { EntityDict } from '@project/oak-app-domain';
|
||
import Logs from '../log';
|
||
import MdEditor from '@project/components/common/byteMD/MdEditor';
|
||
import { Image } from 'mdast';
|
||
import Crop from 'oak-general-business/es/components/extraFile/crop';
|
||
import Commit from 'oak-general-business/es/components/extraFile/commit';
|
||
|
||
export default function VditorComponent(
|
||
props: WebComponentProps<
|
||
EntityDict,
|
||
'essay',
|
||
false,
|
||
{
|
||
isCreation: boolean;
|
||
item: RowWithActions<EntityDict, 'essay'>;
|
||
}
|
||
>
|
||
) {
|
||
const { item, isCreation, oakDirty, oakFullpath, oakEntity } = props.data;
|
||
const { update, execute, navigateBack, t } = props.methods;
|
||
|
||
const [showTitleEdit, setShowTitleEdit] = useState<boolean>(false);
|
||
|
||
const handleImageUpload = (
|
||
files: File[],
|
||
callback?: (path: string) => void
|
||
) => {
|
||
// 实现图片上传的逻辑
|
||
message.warning('功能未实现');
|
||
return new Promise<Pick<Image, 'url' | 'alt' | 'title'>[]>(
|
||
(resolve) => {
|
||
resolve([]);
|
||
}
|
||
);
|
||
};
|
||
|
||
const saveDoc = () => {
|
||
if (isCreation) {
|
||
if (!item.content) {
|
||
message.error(t('error.contentCannotBeEmpty'));
|
||
return;
|
||
}
|
||
setShowTitleEdit(true);
|
||
} else {
|
||
execute();
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className={Styles.editorBody}>
|
||
{/* 切换模式 */}
|
||
<div className={Styles.topbar}>
|
||
{/* 标题编辑框 */}
|
||
{!isCreation && (
|
||
<div className={Styles.title}>
|
||
<Input
|
||
placeholder={t('title')}
|
||
className={Styles.titleInput}
|
||
size='large'
|
||
value={item?.title}
|
||
onChange={(e) =>
|
||
update({
|
||
title: e.target.value,
|
||
})
|
||
}
|
||
/>
|
||
</div>
|
||
)}
|
||
<div className={Styles.btns}>
|
||
<Logs oakPath={`${oakFullpath}.log$entity`} />
|
||
{/* 设置按钮 */}
|
||
<div className={Styles.setting}>
|
||
<Button
|
||
onClick={() => {
|
||
setShowTitleEdit(true);
|
||
}}
|
||
>
|
||
{t('setting')}
|
||
</Button>
|
||
</div>
|
||
{/* 保存按钮 */}
|
||
<div className={Styles.saveBtn}>
|
||
<Button
|
||
type='primary'
|
||
onClick={saveDoc}
|
||
disabled={!oakDirty}
|
||
>
|
||
{isCreation
|
||
? t('common::action.newAdd')
|
||
: t('common::action.save')}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<MdEditor
|
||
value={item?.content || ''}
|
||
className={Styles.editorWrap}
|
||
onChange={(value) => {
|
||
update({
|
||
content: value,
|
||
});
|
||
}}
|
||
imageUpload={handleImageUpload}
|
||
onSave={(value) => {
|
||
saveDoc();
|
||
}}
|
||
></MdEditor>
|
||
<Modal
|
||
title={t('setting')}
|
||
open={showTitleEdit}
|
||
footer={
|
||
<div className={Styles.footer}>
|
||
<Button
|
||
onClick={() => {
|
||
setShowTitleEdit(false);
|
||
}}
|
||
>
|
||
{t('common::action.cancel')}
|
||
</Button>
|
||
{/* 如果没有被commit,是没有实际记录,所以无法关联到file,就无法点击 */}
|
||
{isCreation ? (
|
||
<Button
|
||
type='primary'
|
||
onClick={() => {
|
||
if (!item.content) {
|
||
message.error(
|
||
t('error.contentCannotBeEmpty')
|
||
);
|
||
return;
|
||
}
|
||
if (!item?.title) {
|
||
message.error(
|
||
t('error.titleCannotBeEmpty')
|
||
);
|
||
return;
|
||
}
|
||
setShowTitleEdit(false);
|
||
execute();
|
||
navigateBack();
|
||
}}
|
||
>
|
||
{t('common::action.save')}
|
||
</Button>
|
||
) : (
|
||
<Commit
|
||
entity={oakEntity}
|
||
oakPath={oakFullpath}
|
||
beforeCommit={() => {
|
||
if (!item.content) {
|
||
message.error(
|
||
t('error.contentCannotBeEmpty')
|
||
);
|
||
return false;
|
||
}
|
||
if (!item?.title) {
|
||
message.error(
|
||
t('error.titleCannotBeEmpty')
|
||
);
|
||
return false;
|
||
}
|
||
return true;
|
||
}}
|
||
afterCommit={() => {
|
||
setShowTitleEdit(false);
|
||
execute();
|
||
navigateBack();
|
||
}}
|
||
executeText={t('common::action.save')}
|
||
></Commit>
|
||
)}
|
||
</div>
|
||
}
|
||
>
|
||
<Form>
|
||
<Form.Item label={t('essay:attr.title')}>
|
||
<Input
|
||
value={item?.title}
|
||
onChange={(e) =>
|
||
update({
|
||
title: e.target.value,
|
||
})
|
||
}
|
||
/>
|
||
</Form.Item>
|
||
{!isCreation && (
|
||
<Form.Item label={t('essay:attr.images')}>
|
||
{item && (
|
||
<Crop
|
||
entity={oakEntity}
|
||
entityId={item.id}
|
||
oakPath={`${oakFullpath}.extraFile$entity`}
|
||
maxNumber={1}
|
||
accept='image/*'
|
||
tag1='cover'
|
||
enableCrop
|
||
showRest
|
||
showGrid
|
||
rotationSlider
|
||
aspectSlider
|
||
aspect={16 / 9}
|
||
cropQuality={0.8}
|
||
enableCompross
|
||
maxWidth={1920}
|
||
maxHeight={1080}
|
||
minWidth={1280}
|
||
minHeight={720}
|
||
></Crop>
|
||
)}
|
||
</Form.Item>
|
||
)}
|
||
</Form>
|
||
</Modal>
|
||
</div>
|
||
);
|
||
}
|