snapshot of https://github.com/dream-num/univer.git (dev, 2026-09-16; blobs > 131072B omitted)
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
Some checks failed
📦 Build / build (push) Has been cancelled
🧪 CI Test / test shard (1/4) (push) Has been cancelled
🧪 CI Test / test shard (2/4) (push) Has been cancelled
🧪 CI Test / test shard (3/4) (push) Has been cancelled
🧪 CI Test / test shard (4/4) (push) Has been cancelled
🧪 CI Test / test (push) Has been cancelled
🧪 CI Test / eslint (push) Has been cancelled
🧪 CI Test / typecheck (push) Has been cancelled
🔫 Sync to Pro / dispatch-sync (push) Has been cancelled
🔮 Sync Mirror / sync (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Workbook } from '@univerjs/core';
|
||||
import type { IThreadComment } from '@univerjs/thread-comment';
|
||||
import { ICommandService, IUniverInstanceService, UniverInstanceType, UserManagerService } from '@univerjs/core';
|
||||
import { singleReferenceToGrid } from '@univerjs/engine-formula';
|
||||
import { IMarkSelectionService } from '@univerjs/sheets-ui';
|
||||
import { deserializeThreadCommentAnchor, serializeThreadCommentAnchor, ThreadCommentAnchorKind } from '@univerjs/thread-comment';
|
||||
import { ThreadCommentDraftService, ThreadCommentPanel, ThreadCommentPanelService } from '@univerjs/thread-comment-ui';
|
||||
import { useDependency, useObservable } from '@univerjs/ui';
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import { map } from 'rxjs';
|
||||
import { ShowAddSheetCommentModalOperation } from '../commands/operations/comment.operation';
|
||||
import { SheetsThreadCommentPopupService } from '../services/sheets-thread-comment-popup.service';
|
||||
|
||||
export interface ISheetsThreadCommentPanelProps {
|
||||
ThreadCommentPanelComponent?: typeof ThreadCommentPanel;
|
||||
}
|
||||
|
||||
export const SheetsThreadCommentPanel = ({
|
||||
ThreadCommentPanelComponent = ThreadCommentPanel,
|
||||
}: ISheetsThreadCommentPanelProps = {}) => {
|
||||
const markSelectionService = useDependency(IMarkSelectionService);
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
const sheetsThreadCommentPopupService = useDependency(SheetsThreadCommentPopupService);
|
||||
const workbook = univerInstanceService.getCurrentUnitOfType<Workbook>(UniverInstanceType.UNIVER_SHEET)!;
|
||||
const unitId = workbook.getUnitId();
|
||||
const commandService = useDependency(ICommandService);
|
||||
const draftService = useDependency(ThreadCommentDraftService);
|
||||
const userManagerService = useDependency(UserManagerService);
|
||||
const draft = useObservable(draftService.draft$, draftService.draft);
|
||||
const tempDrawingComment = draft?.anchor.kind === ThreadCommentAnchorKind.SHEET_DRAWING && draft.unitId === unitId
|
||||
? {
|
||||
id: '',
|
||||
threadId: '',
|
||||
unitId: draft.unitId,
|
||||
subUnitId: draft.subUnitId,
|
||||
ref: serializeThreadCommentAnchor(draft.anchor),
|
||||
dT: '',
|
||||
personId: userManagerService.getCurrentUser().userID,
|
||||
text: { dataStream: '\r\n' },
|
||||
}
|
||||
: null;
|
||||
const subUnitId$ = useMemo(() => workbook.activeSheet$.pipe(map((i) => i?.getSheetId())), [workbook.activeSheet$]);
|
||||
const subUnitId = useObservable(subUnitId$, workbook.getActiveSheet()?.getSheetId());
|
||||
const hoverShapeId = useRef<string | null>(null);
|
||||
const panelService = useDependency(ThreadCommentPanelService);
|
||||
const activeCommentId = useObservable(panelService.activeCommentId$);
|
||||
const panelVisible = useObservable(panelService.panelVisible$, panelService.panelVisible);
|
||||
const sortComments = useCallback((comments: IThreadComment[]) => {
|
||||
const worksheets = workbook.getSheets();
|
||||
const sheetIndex: Record<string, number> = {};
|
||||
worksheets.forEach((sheet, i) => {
|
||||
sheetIndex[sheet.getSheetId()] = i;
|
||||
});
|
||||
|
||||
const sort = (comments: IThreadComment[]) => {
|
||||
return comments.map((comment) => {
|
||||
const anchor = deserializeThreadCommentAnchor(comment.ref);
|
||||
if (anchor?.kind === ThreadCommentAnchorKind.SHEET_DRAWING) {
|
||||
return { ...comment, p: [sheetIndex[comment.subUnitId] ?? 0, Number.MAX_SAFE_INTEGER, 0] };
|
||||
}
|
||||
const ref = singleReferenceToGrid(comment.ref);
|
||||
const p = [sheetIndex[comment.subUnitId] ?? 0, ref.row, ref.column];
|
||||
return { ...comment, p };
|
||||
}).sort((pre, aft) => {
|
||||
if (pre.p[0] === aft.p[0]) {
|
||||
if (pre.p[1] === aft.p[1]) {
|
||||
return pre.p[2] - aft.p[2];
|
||||
}
|
||||
return pre.p[1] - aft.p[1];
|
||||
}
|
||||
|
||||
return pre.p[0] - aft.p[0];
|
||||
});
|
||||
};
|
||||
|
||||
return [
|
||||
...sort(comments.filter((comment) => !comment.resolved)),
|
||||
...sort(comments.filter((comment) => comment.resolved)),
|
||||
];
|
||||
}, [workbook]);
|
||||
|
||||
const showShape = useCallback((comment: IThreadComment) => {
|
||||
if (deserializeThreadCommentAnchor(comment.ref)) {
|
||||
return null;
|
||||
}
|
||||
if (comment.unitId === unitId && comment.subUnitId === subUnitId && !comment.resolved) {
|
||||
const { row, column } = singleReferenceToGrid(comment.ref);
|
||||
const worksheet = workbook.getSheetBySheetId(comment.subUnitId);
|
||||
const mergeInfo = worksheet?.getMergedCell(row, column) ?? {
|
||||
startColumn: column,
|
||||
endColumn: column,
|
||||
startRow: row,
|
||||
endRow: row,
|
||||
};
|
||||
if (!Number.isNaN(row) && !Number.isNaN(column)) {
|
||||
return markSelectionService.addShape({
|
||||
range: mergeInfo,
|
||||
style: {
|
||||
// hasAutoFill: false,
|
||||
fill: 'rgb(255, 189, 55, 0.35)',
|
||||
strokeWidth: 1,
|
||||
stroke: '#FFBD37',
|
||||
widgets: {},
|
||||
},
|
||||
primary: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}, [markSelectionService, subUnitId, unitId]);
|
||||
|
||||
const getSubUnitName = (id: string) => {
|
||||
return workbook.getSheetBySheetId(id)?.getName() ?? '';
|
||||
};
|
||||
|
||||
const handleAdd = () => {
|
||||
commandService.executeCommand(ShowAddSheetCommentModalOperation.id);
|
||||
};
|
||||
|
||||
const handleHover = (comment: IThreadComment) => {
|
||||
if (hoverShapeId.current) {
|
||||
markSelectionService.removeShape(hoverShapeId.current);
|
||||
hoverShapeId.current = null;
|
||||
}
|
||||
|
||||
if (
|
||||
activeCommentId &&
|
||||
activeCommentId.unitId === comment.unitId &&
|
||||
activeCommentId.subUnitId === comment.subUnitId &&
|
||||
activeCommentId.commentId === comment.id
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
hoverShapeId.current = showShape(comment);
|
||||
};
|
||||
|
||||
const handleLeave = () => {
|
||||
if (hoverShapeId.current) {
|
||||
markSelectionService.removeShape(hoverShapeId.current);
|
||||
hoverShapeId.current = null;
|
||||
}
|
||||
};
|
||||
|
||||
const handleResolve = (id: string, resolved: boolean) => {
|
||||
if (resolved) {
|
||||
sheetsThreadCommentPopupService.hidePopup();
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!panelVisible && hoverShapeId.current) {
|
||||
markSelectionService.removeShape(hoverShapeId.current);
|
||||
hoverShapeId.current = null;
|
||||
}
|
||||
}, [markSelectionService, panelVisible]);
|
||||
|
||||
return (
|
||||
<ThreadCommentPanelComponent
|
||||
unitId={unitId}
|
||||
subUnitId$={subUnitId$}
|
||||
type={UniverInstanceType.UNIVER_SHEET}
|
||||
onAdd={handleAdd}
|
||||
getSubUnitName={getSubUnitName}
|
||||
onResolve={handleResolve}
|
||||
sortComments={sortComments}
|
||||
onItemEnter={handleHover}
|
||||
onItemLeave={handleLeave}
|
||||
onDeleteComment={() => {
|
||||
handleLeave();
|
||||
return true;
|
||||
}}
|
||||
tempComment={tempDrawingComment}
|
||||
onTempCommentClose={() => draftService.cancel()}
|
||||
formatRef={(comment) => {
|
||||
const anchor = deserializeThreadCommentAnchor(comment.ref);
|
||||
return anchor?.kind === ThreadCommentAnchorKind.SHEET_DRAWING ? `#${anchor.elementId}` : comment.ref;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user