Skip to content
Snippets Groups Projects
Unverified Commit eec529f8 authored by balibabu's avatar balibabu Committed by GitHub
Browse files

feat: set width of chunk text to 100% and add Skeleton to Preview of document...

feat: set width of chunk text to 100% and add Skeleton to Preview of document and remove react-pdf (#94)

* feat: remove react-pdf

* feat: add Skeleton to Preview of document

* feat: set width of chunk text to 100%
parent 7bfaf0df
No related branches found
No related tags found
No related merge requests found
Showing
with 81 additions and 804 deletions
import path from 'path';
import { defineConfig } from 'umi';
import routes from './src/routes';
const cMapsDir = path.join(
path.dirname(require.resolve('pdfjs-dist/package.json')),
'cmaps',
);
const standardFontsDir = path.join(
path.dirname(require.resolve('pdfjs-dist/package.json')),
'standard_fonts',
);
export default defineConfig({
outputPath: 'dist',
// alias: { '@': './src' },
......@@ -38,11 +28,4 @@ export default defineConfig({
// pathRewrite: { '^/v1': '/v1' },
},
},
copy: [
{ from: cMapsDir, to: 'cmaps/' },
{ from: standardFontsDir, to: 'standard_fonts/' },
],
chainWebpack(memo, args) {
console.info(memo);
},
});
This diff is collapsed.
......@@ -27,7 +27,6 @@
"react-i18next": "^14.0.0",
"react-infinite-scroll-component": "^6.1.0",
"react-markdown": "^9.0.1",
"react-pdf": "^7.7.1",
"react-pdf-highlighter": "^6.1.0",
"react-string-replace": "^1.1.1",
"umi": "^4.0.90",
......
import { Divider, Layout, theme } from 'antd';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Outlet } from 'umi';
import '../locales/config';
import Header from './components/header';
import styles from './index.less';
const { Content } = Layout;
const App: React.FC = () => {
const { t } = useTranslation();
const {
token: { colorBgContainer, borderRadiusLG },
} = theme.useToken();
......@@ -25,6 +24,7 @@ const App: React.FC = () => {
background: colorBgContainer,
borderRadius: borderRadiusLG,
overflow: 'auto',
display: 'flex',
}}
>
<Outlet />
......
......@@ -13,6 +13,9 @@
color: red;
font-style: normal;
}
table {
width: 100%;
}
caption {
color: @blurBackground;
......
export const testHighlights = [
{
content: {
text: '实验证明,由氧氯化锆锂和高镍三元正极组成的全固态锂电池展示了极为优异的性能:在12 分钟快速充电的条件下,该电池仍然成功地在室温稳定循环2000 圈以上。',
},
position: {
boundingRect: {
x1: 219.7,
// x1: 419.7,
y1: 204.3,
// y1: 304.3,
x2: 547.0,
// x2: 747.0,
y2: 264.0,
// y2: 364.0,
},
rects: [
// {
// x1: 219.7,
// // x1: 419.7,
// y1: 204.3,
// // y1: 304.3,
// x2: 547.0,
// // x2: 747.0,
// y2: 264.0,
// // y2: 364.0,
// width: 849,
// height: 1200,
// },
],
pageNumber: 9,
},
comment: {
text: 'Flow or TypeScript?',
emoji: '🔥',
},
id: 'jsdlihdkghergjl',
},
{
content: {
text: '图2:乘联会预计6 月新能源乘用车厂商批发销量74 万辆,环比增长10%,同比增长30%。',
},
position: {
boundingRect: {
x1: 219.0,
x2: 546.0,
y1: 616.0,
y2: 674.7,
},
rects: [],
pageNumber: 6,
},
comment: {
text: 'Flow or TypeScript?',
emoji: '🔥',
},
id: 'bfdbtymkhjildbfghserrgrt',
},
{
content: {
text: '图2:乘联会预计6 月新能源乘用车厂商批发销量74 万辆,环比增长10%,同比增长30%。',
},
position: {
boundingRect: {
x1: 73.7,
x2: 391.7,
y1: 570.3,
y2: 676.3,
},
rects: [],
pageNumber: 1,
},
comment: {
text: '',
emoji: '',
},
id: 'fgnhxdvsesgmghyu',
},
].map((x) => {
const boundingRect = x.position.boundingRect;
const ret: any = {
width: 849,
height: 1200,
};
Object.entries(boundingRect).forEach(([key, value]) => {
ret[key] = value / 0.7;
});
return { ...x, position: { ...x.position, boundingRect: ret, rects: [ret] } };
});
import { useGetKnowledgeSearchParams } from '@/hooks/knowledgeHook';
import { api_host } from '@/utils/api';
import { useMemo, useState } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
import 'react-pdf/dist/esm/Page/TextLayer.css';
import { useDocumentResizeObserver, useHighlightText } from './hooks';
import { Spin } from 'antd';
import { useGetSelectedChunk } from '../../hooks';
import styles from './index.less';
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.js',
import.meta.url,
).toString();
interface IProps {
selectedChunkId: string;
}
const DocumentPreview = ({ selectedChunkId }: IProps) => {
const [numPages, setNumPages] = useState<number>();
const { documentId } = useGetKnowledgeSearchParams();
const { containerWidth, setContainerRef } = useDocumentResizeObserver();
const selectedChunk = useGetSelectedChunk(selectedChunkId);
console.info(selectedChunk?.content_with_weight);
const textRenderer = useHighlightText(selectedChunk?.content_with_weight);
function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
setNumPages(numPages);
}
const url = useMemo(() => {
return `${api_host}/document/get/${documentId}`;
}, [documentId]);
return (
<div ref={setContainerRef} className={styles.documentContainer}>
<Document
file={url}
onLoadSuccess={onDocumentLoadSuccess}
loading={<Spin></Spin>}
>
{Array.from(new Array(numPages), (el, index) => (
<Page
key={`page_${index + 1}`}
pageNumber={index + 1}
width={containerWidth}
customTextRenderer={textRenderer}
/>
))}
</Document>
</div>
);
};
export default DocumentPreview;
import { Spin } from 'antd';
import { Skeleton } from 'antd';
import { useEffect, useRef } from 'react';
import {
AreaHighlight,
Highlight,
NewHighlight,
IHighlight,
PdfHighlighter,
PdfLoader,
Popup,
Tip,
} from 'react-pdf-highlighter';
import { useGetChunkHighlights, useGetSelectedChunk } from '../../hooks';
import { useGetChunkHighlights } from '../../hooks';
import { useGetDocumentUrl } from './hooks';
import styles from './index.less';
......@@ -18,8 +17,6 @@ interface IProps {
selectedChunkId: string;
}
const getNextId = () => String(Math.random()).slice(2);
const HighlightPopup = ({
comment,
}: {
......@@ -33,70 +30,10 @@ const HighlightPopup = ({
const Preview = ({ selectedChunkId }: IProps) => {
const url = useGetDocumentUrl();
const selectedChunk = useGetSelectedChunk(selectedChunkId);
// const [state, setState] = useState<any>(testHighlights);
const state = useGetChunkHighlights(selectedChunkId);
const ref = useRef<(highlight: IHighlight) => void>(() => {});
const ref = useRef((highlight: any) => {});
const parseIdFromHash = () =>
document.location.hash.slice('#highlight-'.length);
const resetHash = () => {
document.location.hash = '';
};
const getHighlightById = (id: string) => {
const highlights = state;
return highlights.find((highlight: any) => highlight.id === id);
};
// let scrollViewerTo = (highlight: any) => {};
let scrollToHighlightFromHash = () => {
const highlight = getHighlightById(parseIdFromHash());
if (highlight) {
ref.current(highlight);
}
};
const addHighlight = (highlight: NewHighlight) => {
const highlights = state;
console.log('Saving highlight', highlight);
// setState([{ ...highlight, id: getNextId() }, ...highlights]);
};
const updateHighlight = (
highlightId: string,
position: Object,
content: Object,
) => {
console.log('Updating highlight', highlightId, position, content);
// setState(
// state.map((h: any) => {
// const {
// id,
// position: originalPosition,
// content: originalContent,
// ...rest
// } = h;
// return id === highlightId
// ? {
// id,
// position: { ...originalPosition, ...position },
// content: { ...originalContent, ...content },
// ...rest,
// }
// : h;
// }),
// );
};
const resetHash = () => {};
useEffect(() => {
if (state.length > 0) {
......@@ -106,35 +43,16 @@ const Preview = ({ selectedChunkId }: IProps) => {
return (
<div className={styles.documentContainer}>
<PdfLoader url={url} beforeLoad={<Spin />}>
<PdfLoader url={url} beforeLoad={<Skeleton active />}>
{(pdfDocument) => (
<PdfHighlighter
pdfDocument={pdfDocument}
enableAreaSelection={(event) => event.altKey}
onScrollChange={resetHash}
// pdfScaleValue="page-width"
scrollRef={(scrollTo) => {
// scrollViewerTo = scrollTo;
ref.current = scrollTo;
scrollToHighlightFromHash();
}}
onSelectionFinished={(
position,
content,
hideTipAndSelection,
transformSelection,
) => (
<Tip
onOpen={transformSelection}
onConfirm={(comment) => {
addHighlight({ content, position, comment });
hideTipAndSelection();
}}
/>
)}
onSelectionFinished={() => null}
highlightTransform={(
highlight,
index,
......@@ -158,13 +76,7 @@ const Preview = ({ selectedChunkId }: IProps) => {
<AreaHighlight
isScrolledTo={isScrolledTo}
highlight={highlight}
onChange={(boundingRect) => {
updateHighlight(
highlight.id,
{ boundingRect: viewportToScaled(boundingRect) },
{ image: screenshot(boundingRect) },
);
}}
onChange={() => {}}
/>
);
......@@ -172,7 +84,7 @@ const Preview = ({ selectedChunkId }: IProps) => {
<Popup
popupContent={<HighlightPopup {...highlight} />}
onMouseOver={(popupContent) =>
setTip(highlight, (highlight: any) => popupContent)
setTip(highlight, () => popupContent)
}
onMouseOut={hideTip}
key={index}
......
......@@ -288,7 +288,7 @@ const KnowledgeFile = () => {
dataSource={data}
loading={loading}
pagination={pagination}
scroll={{ scrollToFirstRowOnChange: true, x: true, y: 'fill' }}
scroll={{ scrollToFirstRowOnChange: true, x: 1300, y: 'fill' }}
/>
<CreateEPModal getKfList={getKfList} kb_id={knowledgeBaseId} />
<SegmentSetModal
......
.popover-content {
width: 300px;
.popoverContent {
width: 40vw;
.popoverContentItem {
display: flex;
gap: 10px;
}
.popoverContentText {
white-space: pre-line;
.popoverContentErrorLabel {
color: red;
}
}
}
.operationIcon {
......
import { ReactComponent as RefreshIcon } from '@/assets/svg/refresh.svg';
import { ReactComponent as RunIcon } from '@/assets/svg/run.svg';
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
import { Badge, DescriptionsProps, Flex, Popover, Space, Tag } from 'antd';
import { RunningStatus, RunningStatusMap } from '../constant';
import { CloseCircleOutlined } from '@ant-design/icons';
import { Badge, DescriptionsProps, Flex, Popover, Space, Tag } from 'antd';
import reactStringReplace from 'react-string-replace';
import { useDispatch } from 'umi';
import { RunningStatus, RunningStatusMap } from '../constant';
import styles from './index.less';
const iconMap = {
......@@ -35,17 +35,27 @@ const PopoverContent = ({ record }: IProps) => {
{
key: 'progress_msg',
label: 'Progress Msg',
children: record.progress_msg,
children: reactStringReplace(
record.progress_msg.trim(),
/(\[ERROR\].+\s)/g,
(match, i) => {
return (
<span key={i} className={styles.popoverContentErrorLabel}>
{match}
</span>
);
},
),
},
];
return (
<Flex vertical className={styles['popover-content']}>
{items.map((x) => {
<Flex vertical className={styles.popoverContent}>
{items.map((x, idx) => {
return (
<div key={x.key}>
<div key={x.key} className={idx < 2 ? styles.popoverContentItem : ''}>
<b>{x.label}:</b>
<p>{x.children}</p>
<div className={styles.popoverContentText}>{x.children}</div>
</div>
);
})}
......
.container {
display: flex;
height: 100%;
width: 100%;
.contentWrapper {
flex: 1;
overflow-x: auto;
......
// @import '~@/less/variable.less';
.knowledge {
padding: 48px 60px;
padding: 48px 0;
}
.topWrapper {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding-bottom: 72px;
padding: 0 60px 72px;
.title {
font-family: Inter;
......@@ -41,3 +41,7 @@
.topButton();
}
}
.knowledgeCardContainer {
padding: 0 60px;
overflow: auto;
}
import { ReactComponent as FilterIcon } from '@/assets/filter.svg';
import ModalManager from '@/components/modal-manager';
import { PlusOutlined } from '@ant-design/icons';
import { Button, Flex, Space } from 'antd';
import { Button, Empty, Flex, Space } from 'antd';
import KnowledgeCard from './knowledge-card';
import KnowledgeCreatingModal from './knowledge-creating-modal';
import { useFetchKnowledgeList } from '@/hooks/knowledgeHook';
import { useSelectUserInfo } from '@/hooks/userSettingHook';
import styles from './index.less';
const Knowledge = () => {
const data = useFetchKnowledgeList();
const list = useFetchKnowledgeList();
const userInfo = useSelectUserInfo();
return (
<div className={styles.knowledge}>
<Flex className={styles.knowledge} vertical flex={1}>
<div className={styles.topWrapper}>
<div>
<span className={styles.title}>Welcome back, Zing</span>
<span className={styles.title}>
Welcome back, {userInfo.nickname}
</span>
<p className={styles.description}>
Which database are we going to use today?
</p>
......@@ -46,12 +50,22 @@ const Knowledge = () => {
</ModalManager>
</Space>
</div>
<Flex gap="large" wrap="wrap">
{data.map((item: any) => {
return <KnowledgeCard item={item} key={item.name}></KnowledgeCard>;
})}
<Flex
gap="large"
wrap="wrap"
flex={1}
// justify="center"
className={styles.knowledgeCardContainer}
>
{list.length > 0 ? (
list.map((item: any) => {
return <KnowledgeCard item={item} key={item.name}></KnowledgeCard>;
})
) : (
<Empty></Empty>
)}
</Flex>
</div>
</Flex>
);
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment