Skip to content

Commit

Permalink
fix: editor next selection on recreate model
Browse files Browse the repository at this point in the history
  • Loading branch information
devcatalin committed Apr 27, 2023
1 parent bbc5686 commit 73ca808
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React, {useCallback, useMemo} from 'react';
import {setActiveDashboardMenu, setDashboardSelectedResourceId} from '@redux/dashboard/slice';
import {useAppDispatch, useAppSelector} from '@redux/hooks';
import {selectFile, selectResource, setActiveEditorTab} from '@redux/reducers/main';
import {setMonacoEditor} from '@redux/reducers/ui';
import {
activeResourceStorageSelector,
useActiveResourceMetaMap,
Expand All @@ -15,9 +14,9 @@ import {getRefRange} from '@utils/refs';

import GraphIcon from '@assets/GraphIcon.svg';

import {editorSetNextSelection, editorSetSelection} from '@editor/editor.slice';
import {ResourceRef, ResourceRefType, areRefPosEqual} from '@monokle/validation';
import {ResourceMeta, ResourceMetaMap} from '@shared/models/k8sResource';
import {MonacoRange} from '@shared/models/ui';
import {trackEvent} from '@shared/utils/telemetry';

import RefLink from './RefLink';
Expand Down Expand Up @@ -128,46 +127,30 @@ const RefsPopoverContent = (props: {
}
};

const makeMonacoSelection = (type: 'resource' | 'file', target: string, range: MonacoRange) => {
const newMonacoSelection =
type === 'resource'
? {
type,
resourceId: target,
range,
}
: {type, filePath: target, range};
dispatch(
setMonacoEditor({
selection: newMonacoSelection,
})
);
};

const onLinkClick = (ref: ResourceRef) => {
trackEvent('explore/navigate_resource_link', {type: ref.type});

const refRange = getRefRange(ref);

if (ref.type !== ResourceRefType.Incoming) {
if (
!selection ||
selection?.type !== 'resource' ||
(selection?.type === 'resource' && selection.resourceIdentifier.id !== resource.id)
) {
triggerSelectResource(resource.id);
if (refRange) {
dispatch(editorSetNextSelection({range: refRange}));
}
} else if (refRange) {
dispatch(editorSetSelection({range: refRange}));
}

const refRange = getRefRange(ref);

if (refRange) {
setImmediate(() => {
makeMonacoSelection('resource', resource.id, refRange);
});
}

return;
}

if (ref.target?.type === 'resource') {
let changedSelection = false;

if (!ref.target.resourceId) {
return;
}
Expand All @@ -178,6 +161,7 @@ const RefsPopoverContent = (props: {

if (selection?.type === 'resource' && selection.resourceIdentifier.id !== targetResourceMeta.id) {
triggerSelectResource(targetResourceMeta.id);
changedSelection = true;
}

const targetOutgoingRef = targetResourceMeta.refs?.find(
Expand All @@ -190,7 +174,11 @@ const RefsPopoverContent = (props: {

const targetOutgoingRefRange = getRefRange(targetOutgoingRef);
if (targetOutgoingRefRange) {
makeMonacoSelection('resource', targetResourceMeta.id, targetOutgoingRefRange);
if (changedSelection) {
dispatch(editorSetNextSelection({range: targetOutgoingRefRange}));
} else {
dispatch(editorSetSelection({range: targetOutgoingRefRange}));
}
}
}
if (ref.target?.type === 'file') {
Expand Down
27 changes: 27 additions & 0 deletions src/editor/editor.instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ let editorHovers: EditorHover[] = [];
let editorLinks: EditorLink[] = [];
let editorCommands: EditorCommand[] = [];
let editorDecorationsCollection: monaco.editor.IEditorDecorationsCollection | undefined;
let nextSelection: monaco.IRange | undefined;
let isRecreatingModel = false;

const modelContentChangeListeners: ((e: monaco.editor.IModelContentChangedEvent) => any)[] = [];

Expand All @@ -23,6 +25,11 @@ export const mountEditor = (domElement: HTMLElement) => {
EDITOR.onDidChangeModelContent(e => {
modelContentChangeListeners.forEach(listener => listener(e));
});
EDITOR.onDidChangeCursorPosition(() => {
if (!isRecreatingModel) {
consumeNextSelection();
}
});
};

export const unmountEditor = () => {
Expand All @@ -37,10 +44,29 @@ export const resetEditor = () => {
clearEditorDecorations();
};

const consumeNextSelection = () => {
if (!nextSelection) {
return;
}
const copy = structuredClone(nextSelection);
nextSelection = undefined;
return copy;
};

export const setEditorNextSelection = (range: monaco.IRange) => {
nextSelection = range;
};

export function recreateEditorModel(editor: monaco.editor.ICodeEditor, text: string, language: string = 'yaml') {
isRecreatingModel = true;
resetEditor();
editor.getModel()?.dispose();
editor.setModel(monaco.editor.createModel(text, language));
const selection = consumeNextSelection();
if (selection) {
setEditorSelection(selection);
}
isRecreatingModel = false;
}

export const getEditor = () => EDITOR;
Expand Down Expand Up @@ -96,6 +122,7 @@ export const setEditorDecorations = (decorations: monaco.editor.IModelDeltaDecor

export const setEditorSelection = (selectionRange: monaco.IRange) => {
EDITOR?.setSelection(selectionRange);
EDITOR?.revealLineInCenter(selectionRange.startLineNumber);
};

export const clearEditorDecorations = () => {
Expand Down
14 changes: 12 additions & 2 deletions src/editor/editor.slice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import {createSlice} from '@reduxjs/toolkit';
import {PayloadAction, createSlice} from '@reduxjs/toolkit';

import * as monaco from 'monaco-editor';

import {setEditorNextSelection, setEditorSelection} from './editor.instance';

export const editorSlice = createSlice({
name: 'editor',
Expand All @@ -7,7 +11,13 @@ export const editorSlice = createSlice({
// this action is dispatched by the editor component when it mounts
// then, it's used by the editor redux listener to rehydrate the editor state based on the current selection
editorMounted: () => {},
editorSetSelection: (_, action: PayloadAction<{range: monaco.IRange}>) => {
setEditorSelection(action.payload.range);
},
editorSetNextSelection: (_, action: PayloadAction<{range: monaco.IRange}>) => {
setEditorNextSelection(action.payload.range);
},
},
});

export const {editorMounted} = editorSlice.actions;
export const {editorMounted, editorSetSelection, editorSetNextSelection} = editorSlice.actions;

0 comments on commit 73ca808

Please sign in to comment.