Skip to content

Commit

Permalink
fix: selections & editor content on file changes
Browse files Browse the repository at this point in the history
  • Loading branch information
devcatalin committed Dec 3, 2021
1 parent 0c58d9c commit 4758884
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 35 deletions.
23 changes: 22 additions & 1 deletion src/components/molecules/Monaco/Monaco.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {useSelector} from 'react-redux';
import {useMeasure} from 'react-use';

import fs from 'fs';
import log from 'loglevel';
import 'monaco-editor';
// @ts-ignore
import {languages} from 'monaco-editor/esm/vs/editor/editor.api';
Expand All @@ -25,7 +26,7 @@ import {ResourceRef} from '@models/k8sresource';
import {NewResourceWizardInput} from '@models/ui';

import {useAppDispatch, useAppSelector} from '@redux/hooks';
import {extendResourceFilter, selectFile, selectK8sResource} from '@redux/reducers/main';
import {editorHasReloadedSelectedPath, extendResourceFilter, selectFile, selectK8sResource} from '@redux/reducers/main';
import {openNewResourceWizard} from '@redux/reducers/ui';
import {isInPreviewModeSelector} from '@redux/selectors';

Expand Down Expand Up @@ -74,6 +75,7 @@ const Monaco = (props: {editorHeight: string; diffSelectedResource: () => void;
const previewValuesFileId = useAppSelector(state => state.main.previewValuesFileId);
const resourceMap = useAppSelector(state => state.main.resourceMap);
const previewType = useAppSelector(state => state.main.previewType);
const shouldEditorReloadSelectedPath = useAppSelector(state => state.main.shouldEditorReloadSelectedPath);
const isInPreviewMode = useSelector(isInPreviewModeSelector);

const [containerRef, {width: containerWidth, height: containerHeight}] = useMeasure<HTMLDivElement>();
Expand Down Expand Up @@ -227,6 +229,25 @@ const Monaco = (props: {editorHeight: string; diffSelectedResource: () => void;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedPath, selectedResourceId]);

useEffect(() => {
if (!selectedPath || !shouldEditorReloadSelectedPath) {
return;
}
log.info('[Monaco]: selected file was updated outside Monokle - reading file...');
const filePath = path.join(fileMap[ROOT_FILE_ENTRY].filePath, selectedPath);
const fileStats = getFileStats(filePath);
if (fileStats && fileStats.isFile()) {
const newCode = fs.readFileSync(filePath, 'utf8');
setCode(newCode);
setOrgCode(newCode);
setDirty(false);
dispatch(editorHasReloadedSelectedPath());
} else {
log.warn('[Monaco]: selected file was updated outside Monokle - unable to read file');
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [shouldEditorReloadSelectedPath]);

useEffect(() => {
if (selectedResource && selectedResource.text !== code) {
setCode(selectedResource.text);
Expand Down
2 changes: 2 additions & 0 deletions src/models/appstate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ interface AppState {
selectedMatches: string[];
};
notifications: AlertType[];
/** whether or not the editor should read the selectedPath file again - used when the file is updated externally */
shouldEditorReloadSelectedPath: boolean;
}

export type {
Expand Down
1 change: 1 addition & 0 deletions src/redux/initialState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const initialAppState: AppState = {
selectedMatches: [],
},
notifications: [],
shouldEditorReloadSelectedPath: false,
};

const initialAppConfigState: AppConfig = {
Expand Down
35 changes: 6 additions & 29 deletions src/redux/reducers/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ import initialState from '../initialState';
import {
addPath,
createFileEntry,
getAllFileEntriesForPath,
getFileEntryForAbsolutePath,
getResourcesForPath,
reloadFile,
removePath,
selectFilePath,
} from '../services/fileEntry';
import {
extractK8sResources,
Expand All @@ -63,7 +63,7 @@ import {
reprocessResources,
saveResource,
} from '../services/resource';
import {clearResourceSelections, highlightChildrenResources, updateSelectionAndHighlights} from '../services/selection';
import {clearResourceSelections, updateSelectionAndHighlights} from '../services/selection';
import {setAlert} from './alert';
import {closeClusterDiff} from './ui';

Expand Down Expand Up @@ -535,6 +535,9 @@ export const mainSlice = createSlice({
state.currentSelectionHistoryIndex = action.payload.nextSelectionHistoryIndex;
state.selectionHistory = action.payload.newSelectionHistory;
},
editorHasReloadedSelectedPath: (state: Draft<AppState>) => {
state.shouldEditorReloadSelectedPath = false;
},
},
extraReducers: builder => {
builder.addCase(setAlert, (state, action) => {
Expand Down Expand Up @@ -930,33 +933,6 @@ function setPreviewData<State>(payload: SetPreviewDataPayload, state: AppState)
}
}

/**
* Selects the specified filePath - used by several reducers
*/

function selectFilePath(filePath: string, state: AppState) {
const entries = getAllFileEntriesForPath(filePath, state.fileMap);
clearResourceSelections(state.resourceMap);

if (entries.length > 0) {
const parent = entries[entries.length - 1];
getResourcesForPath(parent.filePath, state.resourceMap).forEach(r => {
r.isHighlighted = true;
});

if (parent.children) {
highlightChildrenResources(parent, state.resourceMap, state.fileMap);
}

Object.values(state.helmValuesMap).forEach(valuesFile => {
valuesFile.isSelected = valuesFile.filePath === filePath;
});
}

state.selectedResourceId = undefined;
state.selectedPath = filePath;
}

export const {
setAppRehydrating,
addResource,
Expand Down Expand Up @@ -987,5 +963,6 @@ export const {
reloadClusterDiff,
setSelectionHistory,
reprocessNewResource,
editorHasReloadedSelectedPath,
} = mainSlice.actions;
export default mainSlice.reducer;
55 changes: 50 additions & 5 deletions src/redux/services/fileEntry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import {FileEntry} from '@models/fileentry';
import {HelmChart, HelmValuesFile} from '@models/helm';
import {K8sResource} from '@models/k8sresource';

import {clearResourceSelections, updateSelectionAndHighlights} from '@redux/services/selection';
import {
clearResourceSelections,
highlightChildrenResources,
updateSelectionAndHighlights,
} from '@redux/services/selection';

import {getFileStats, getFileTimestamp} from '@utils/files';

Expand Down Expand Up @@ -329,19 +333,22 @@ export function reloadFile(absolutePath: string, fileEntry: FileEntry, state: Ap
if (!fileEntry.timestamp || (absolutePathTimestamp && absolutePathTimestamp > fileEntry.timestamp)) {
fileEntry.timestamp = absolutePathTimestamp;

let wasFileSelected = state.selectedPath === fileEntry.filePath;

const resourcesInFile = getResourcesForPath(fileEntry.filePath, state.resourceMap);
let wasSelected = false;
let wasAnyResourceSelected = false;

resourcesInFile.forEach(resource => {
if (state.selectedResourceId === resource.id) {
updateSelectionAndHighlights(state, resource);
wasSelected = true;
wasAnyResourceSelected = true;
}
delete state.resourceMap[resource.id];
});

if (state.selectedPath === fileEntry.filePath) {
state.selectedPath = undefined;
state.selectedResourceId = undefined;
clearResourceSelections(state.resourceMap);
}

Expand All @@ -357,8 +364,19 @@ export function reloadFile(absolutePath: string, fileEntry: FileEntry, state: Ap
state.resourceRefsProcessingOptions
);

if (resourcesInFile.length === 1 && resourcesFromFile.length === 1 && wasSelected) {
updateSelectionAndHighlights(state, resourcesFromFile[0]);
if (wasAnyResourceSelected) {
if (resourcesInFile.length === 1 && resourcesFromFile.length === 1) {
updateSelectionAndHighlights(state, resourcesFromFile[0]);
} else {
state.selectedPath = undefined;
state.selectedResourceId = undefined;
clearResourceSelections(state.resourceMap);
}
}

if (wasFileSelected) {
selectFilePath(fileEntry.filePath, state);
state.shouldEditorReloadSelectedPath = true;
}
} else {
log.info(`ignoring changed file ${absolutePath} because of timestamp`);
Expand Down Expand Up @@ -524,3 +542,30 @@ export function removePath(absolutePath: string, state: AppState, fileEntry: Fil
}
);
}

/**
* Selects the specified filePath - used by several reducers
*/

export function selectFilePath(filePath: string, state: AppState) {
const entries = getAllFileEntriesForPath(filePath, state.fileMap);
clearResourceSelections(state.resourceMap);

if (entries.length > 0) {
const parent = entries[entries.length - 1];
getResourcesForPath(parent.filePath, state.resourceMap).forEach(r => {
r.isHighlighted = true;
});

if (parent.children) {
highlightChildrenResources(parent, state.resourceMap, state.fileMap);
}

Object.values(state.helmValuesMap).forEach(valuesFile => {
valuesFile.isSelected = valuesFile.filePath === filePath;
});
}

state.selectedResourceId = undefined;
state.selectedPath = filePath;
}

0 comments on commit 4758884

Please sign in to comment.