Skip to content

Commit

Permalink
fix(sheets-hyper-link-ui): link redo undo (#3465)
Browse files Browse the repository at this point in the history
  • Loading branch information
weird94 committed Sep 20, 2024
1 parent 3dc6d95 commit 9ddcaf5
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,9 @@ export class DocSelectionRenderService extends RxDisposable implements IRenderMo
this.disposeWithMe(
fromEvent(this._input, 'input').subscribe((e) => {
// Prevent input when there is any rect ranges.
if ((e as InputEvent).inputType === 'historyUndo' || (e as InputEvent).inputType === 'historyRedo') {
return;
}
if (this._rectRangeList.length > 0) {
e.stopPropagation();
return e.preventDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { BuildTextUtils, CellValueType, CommandType, CustomRangeType, DataStreamTreeTokenType, generateRandomId, ICommandService, IUndoRedoService, IUniverInstanceService, sequenceExecuteAsync, TextX, UniverInstanceType } from '@univerjs/core';
import { BuildTextUtils, CellValueType, CommandType, CustomRangeType, DataStreamTreeTokenType, generateRandomId, ICommandService, IUndoRedoService, IUniverInstanceService, sequenceExecuteAsync, TextX, Tools, UniverInstanceType } from '@univerjs/core';
import { DocSelectionManagerService } from '@univerjs/docs';
import { addCustomRangeBySelectionFactory } from '@univerjs/docs-ui';
import { IRenderManagerService } from '@univerjs/engine-render';
Expand Down Expand Up @@ -63,7 +63,7 @@ export const AddHyperLinkCommand: ICommand<IAddHyperLinkCommandParams> = {
const cellData = worksheet.getCell(row, column);
const doc = skeleton.getBlankCellDocumentModel(cellData);
const snapshot = doc.documentModel!.getSnapshot();
const body = snapshot.body;
const body = Tools.deepClone(snapshot.body);
if (!body) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { CellValueType, CommandType, CustomRangeType, DataStreamTreeTokenType, generateRandomId, getBodySlice, ICommandService, IUndoRedoService, IUniverInstanceService, sequenceExecuteAsync, TextX, UniverInstanceType } from '@univerjs/core';
import { CellValueType, CommandType, CustomRangeType, DataStreamTreeTokenType, generateRandomId, getBodySlice, ICommandService, IUndoRedoService, IUniverInstanceService, sequenceExecuteAsync, TextX, Tools, UniverInstanceType } from '@univerjs/core';
import { replaceSelectionFactory } from '@univerjs/docs-ui';
import { IRenderManagerService } from '@univerjs/engine-render';
import { SetRangeValuesMutation, SetRangeValuesUndoMutationFactory } from '@univerjs/sheets';
Expand Down Expand Up @@ -104,7 +104,7 @@ export const UpdateHyperLinkCommand: ICommand<IUpdateHyperLinkCommandParams> = {
if (!replaceSelection) {
return false;
}
const newBody = TextX.apply(snapshot.body!, replaceSelection.textX.serialize());
const newBody = TextX.apply(Tools.deepClone(snapshot.body!), replaceSelection.textX.serialize());

const redo = {
id: SetRangeValuesMutation.id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { getSheetCommandTarget, type ISheetCommandSharedParams, SheetsSelections
import { IEditorBridgeService } from '@univerjs/sheets-ui';
import { SheetsHyperLinkPopupService } from '../../services/popup.service';
import { HyperLinkEditSourceType } from '../../types/enums/edit-source';
import { getShouldDisableCurrentCellLink } from '../../utils';

export interface IOpenHyperLinkEditPanelOperationParams extends ISheetCommandSharedParams {
row: number;
Expand Down Expand Up @@ -93,6 +94,9 @@ export const InsertHyperLinkToolbarOperation: ICommand = {
type: CommandType.OPERATION,
id: 'sheet.operation.insert-hyper-link-toolbar',
handler(accessor) {
if (getShouldDisableCurrentCellLink(accessor)) {
return false;
}
const commandService = accessor.get(ICommandService);
const popupService = accessor.get(SheetsHyperLinkPopupService);
if (popupService.currentEditing) {
Expand Down
78 changes: 21 additions & 57 deletions packages/sheets-hyper-link-ui/src/controllers/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@
* limitations under the License.
*/

import { BuildTextUtils, CustomRangeType, DataValidationType, DOCS_ZEN_EDITOR_UNIT_ID_KEY, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
import type { IMenuItem, IShortcutItem } from '@univerjs/ui';
import { DOCS_ZEN_EDITOR_UNIT_ID_KEY, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
import { DocSelectionManagerService } from '@univerjs/docs';
import { getSheetCommandTarget, RangeProtectionPermissionEditPoint, SheetsSelectionsService, WorkbookEditablePermission, WorksheetEditPermission, WorksheetInsertHyperlinkPermission, WorksheetSetCellValuePermission } from '@univerjs/sheets';
import { getCurrentRangeDisable$, IEditorBridgeService, whenSheetEditorFocused } from '@univerjs/sheets-ui';
import { getMenuHiddenObservable, KeyCode, MenuGroup, MenuItemType, MenuPosition, MetaKeys } from '@univerjs/ui';
import type { DocumentDataModel, IAccessor, ITextRange, Workbook } from '@univerjs/core';
import { getCurrentRangeDisable$, whenSheetEditorFocused } from '@univerjs/sheets-ui';
import { RangeProtectionPermissionEditPoint, SheetsSelectionsService, WorkbookEditablePermission, WorksheetEditPermission, WorksheetInsertHyperlinkPermission, WorksheetSetCellValuePermission } from '@univerjs/sheets';
import { map, mergeMap, Observable } from 'rxjs';
import { DocSelectionManagerService } from '@univerjs/docs';
import type { IAccessor, Workbook } from '@univerjs/core';
import type { IMenuItem, IShortcutItem } from '@univerjs/ui';
import { InsertHyperLinkOperation, InsertHyperLinkToolbarOperation } from '../commands/operations/popup.operations';
import { getShouldDisableCellLink, shouldDisableAddLink } from '../utils';

const getLinkDisable$ = (accessor: IAccessor) => {
const disableRange$ = getCurrentRangeDisable$(accessor, { workbookTypes: [WorkbookEditablePermission], worksheetTypes: [WorksheetEditPermission, WorksheetSetCellValuePermission, WorksheetInsertHyperlinkPermission], rangeTypes: [RangeProtectionPermissionEditPoint] });
Expand Down Expand Up @@ -55,63 +56,13 @@ const getLinkDisable$ = (accessor: IAccessor) => {
}
const row = selections[0].range.startRow;
const col = selections[0].range.startColumn;
const cell = sheet.getCell(row, col);
if (cell?.f || cell?.si) {
return true;
}
const disables = [
DataValidationType.CHECKBOX,
DataValidationType.LIST,
DataValidationType.LIST_MULTIPLE,
];

if (cell?.dataValidation && disables.includes(cell.dataValidation.rule.type)) {
return true;
}

return false;
return getShouldDisableCellLink(sheet, row, col);
})
);

return disableRange$.pipe(mergeMap(((disableRange) => disableCell$.pipe(map((disableCell) => disableRange || disableCell)))));
};

export const shouldDisableAddLink = (accessor: IAccessor) => {
const textSelectionService = accessor.get(DocSelectionManagerService);
const univerInstanceService = accessor.get(IUniverInstanceService);
const textRanges = textSelectionService.getDocRanges();
if (!textRanges.length || textRanges.length > 1) {
return true;
}

const activeRange = textRanges[0];
const doc = univerInstanceService.getCurrentUnitForType<DocumentDataModel>(UniverInstanceType.UNIVER_DOC);
if (!doc || !activeRange || activeRange.collapsed) {
return true;
}

const body = doc.getSelfOrHeaderFooterModel(activeRange.segmentId).getBody();
const paragraphs = body?.paragraphs;
if (!paragraphs) {
return true;
}

for (let i = 0, len = paragraphs.length; i < len; i++) {
const p = paragraphs[i];
if (activeRange.startOffset! <= p.startIndex && activeRange.endOffset! > p.startIndex) {
return true;
}

if (p.startIndex > activeRange.endOffset!) {
break;
}
}

const insertCustomRanges = BuildTextUtils.customRange.getCustomRangesInterestsWithRange(activeRange as ITextRange, body.customRanges ?? []);
// can't insert hyperlink in range contains other custom ranges
return !insertCustomRanges.every((range) => range.rangeType === CustomRangeType.HYPERLINK);
};

const getZenLinkDisable$ = (accessor: IAccessor) => {
const univerInstanceService = accessor.get(IUniverInstanceService);
return univerInstanceService.focused$.pipe(
Expand All @@ -126,6 +77,19 @@ const getZenLinkDisable$ = (accessor: IAccessor) => {
if (!selection || selection.unitId !== DOCS_ZEN_EDITOR_UNIT_ID_KEY) {
return true;
}
const editorBridgeService = accessor.get(IEditorBridgeService);
const state = editorBridgeService.getEditCellState();
if (!state) {
return true;
}
const target = getSheetCommandTarget(univerInstanceService, { unitId: state.unitId, subUnitId: state.sheetId });
if (!target?.worksheet) {
return true;
}

if (getShouldDisableCellLink(target.worksheet, state.row, state.column)) {
return true;
}

return shouldDisableAddLink(accessor);
})
Expand Down
89 changes: 89 additions & 0 deletions packages/sheets-hyper-link-ui/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* 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 { BuildTextUtils, CustomRangeType, DataValidationType, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
import { DocSelectionManagerService } from '@univerjs/docs';
import { SheetsSelectionsService } from '@univerjs/sheets';
import type { DocumentDataModel, IAccessor, ITextRange, Workbook, Worksheet } from '@univerjs/core';

export const getShouldDisableCellLink = (worksheet: Worksheet, row: number, col: number) => {
const cell = worksheet.getCell(row, col);
if (cell?.f || cell?.si) {
return true;
}
const disables = [
DataValidationType.CHECKBOX,
DataValidationType.LIST,
DataValidationType.LIST_MULTIPLE,
];

if (cell?.dataValidation && disables.includes(cell.dataValidation.rule.type)) {
return true;
}

return false;
};

export const getShouldDisableCurrentCellLink = (accessor: IAccessor) => {
const unit = accessor.get(IUniverInstanceService).getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET);
if (!unit) {
return true;
}
const worksheet = unit.getActiveSheet();
const selections = accessor.get(SheetsSelectionsService).getCurrentSelections();
if (!selections.length) {
return true;
}
const row = selections[0].range.startRow;
const col = selections[0].range.startColumn;
return getShouldDisableCellLink(worksheet, row, col);
};

export const shouldDisableAddLink = (accessor: IAccessor) => {
const textSelectionService = accessor.get(DocSelectionManagerService);
const univerInstanceService = accessor.get(IUniverInstanceService);
const textRanges = textSelectionService.getDocRanges();
if (!textRanges.length || textRanges.length > 1) {
return true;
}

const activeRange = textRanges[0];
const doc = univerInstanceService.getCurrentUnitForType<DocumentDataModel>(UniverInstanceType.UNIVER_DOC);
if (!doc || !activeRange || activeRange.collapsed) {
return true;
}

const body = doc.getSelfOrHeaderFooterModel(activeRange.segmentId).getBody();
const paragraphs = body?.paragraphs;
if (!paragraphs) {
return true;
}

for (let i = 0, len = paragraphs.length; i < len; i++) {
const p = paragraphs[i];
if (activeRange.startOffset! <= p.startIndex && activeRange.endOffset! > p.startIndex) {
return true;
}

if (p.startIndex > activeRange.endOffset!) {
break;
}
}

const insertCustomRanges = BuildTextUtils.customRange.getCustomRangesInterestsWithRange(activeRange as ITextRange, body.customRanges ?? []);
// can't insert hyperlink in range contains other custom ranges
return !insertCustomRanges.every((range) => range.rangeType === CustomRangeType.HYPERLINK);
};

0 comments on commit 9ddcaf5

Please sign in to comment.