Skip to content

Commit

Permalink
Closes #1187: Extend the configuration UI to be able to hide files (#…
Browse files Browse the repository at this point in the history
…1493)

* feat: Extend the configuration UI to be able to hide files

* Refactor method and field names; move the functionality to show/hide hidden files to the FileToolbar.js

* Minor refactor of toggleShowHiddenFiles

* Fix comment

* Highlight hidden files when shown (change color)

* Fix linting errors

* refactor toggle show hidden files; move functionality to fetchFiles

* change default state of showHiddenFiles

Co-authored-by: Heiko Holz <heiko.holz@novatec-gmbh.de>
  • Loading branch information
2 people authored and aaronweissler committed Sep 5, 2022
1 parent 3aac752 commit 4b4d57f
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ class ConfigurationView extends React.Component {
this.props.selectFile(filename);
};

toggleShowHiddenFiles = () => {
this.props.toggleShowHiddenFiles();
};

render() {
const {
selection,
Expand Down Expand Up @@ -217,6 +221,7 @@ class ConfigurationView extends React.Component {
showMoveDialog={this.showMoveDialog}
selectedVersionChange={this.selectedVersionChange}
showSearchDialog={this.showSearchDialog}
toggleShowHiddenFiles={this.toggleShowHiddenFiles}
/>
<FileTree
className="fileTree"
Expand Down Expand Up @@ -343,6 +348,7 @@ const mapDispatchToProps = {
toggleVisualConfigurationView: configurationActions.toggleVisualConfigurationView,
selectFile: configurationActions.selectFile,
fetchVersions: configurationActions.fetchVersions,
toggleShowHiddenFiles: configurationActions.toggleShowHiddenFiles,
};

export default connect(mapStateToProps, mapDispatchToProps)(ConfigurationView);
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { configurationActions } from '../../../redux/ducks/configuration';
import { Toolbar } from 'primereact/toolbar';
import { Button } from 'primereact/button';
Expand All @@ -18,13 +18,16 @@ const FileToolbar = ({
showMoveDialog,
showDeleteFileDialog,
showSearchDialog,
toggleShowHiddenFiles,
}) => {
const dispatch = useDispatch();

// global state variables
const loading = useSelector((state) => state.configuration.pendingRequests) > 0;
const selection = useSelector((state) => state.configuration.selection) || '';

const showHiddenFiles = useSelector((state) => state.configuration.showHiddenFiles) || '';

const reloadFiles = () => {
dispatch(configurationActions.selectVersion(null));
};
Expand Down Expand Up @@ -90,6 +93,13 @@ const FileToolbar = ({
/>
</div>
<div className="p-toolbar-group-right">
<Button
disabled={loading}
onClick={toggleShowHiddenFiles}
tooltip={showHiddenFiles ? 'Hide Files' : 'Show Hidden Files'}
icon={showHiddenFiles ? 'pi pi-eye' : 'pi pi-eye-slash'}
tooltipOptions={TOOLTIP_OPTIONS}
/>
<Button
disabled={loading}
onClick={showSearchDialog}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,11 @@ class FileTree extends React.Component {
.this :global(.cm-tree-label) {
color: #aaa;
}
.this :global(.cm-hidden-file-tree-label){
color: #aaa;
}
.this :global(.ocelot-tree-head-orange) {
background: url("${linkPrefix}/static/images/inspectit-ocelot-head_orange.svg") center no-repeat;
background-size: 1rem 1rem;
Expand Down Expand Up @@ -207,7 +211,15 @@ class FileTree extends React.Component {
}

getContextMenuModel = (filePath) => {
const { showCreateDirectoryDialog, showCreateFileDialog, showMoveDialog, showDeleteFileDialog, exportSelection } = this.props;
const {
showCreateDirectoryDialog,
showCreateFileDialog,
showMoveDialog,
showDeleteFileDialog,
exportSelection,
toggleShowHiddenFiles,
showHiddenFiles,
} = this.props;

return [
{
Expand All @@ -225,6 +237,11 @@ class FileTree extends React.Component {
icon: 'pi pi-download',
command: () => exportSelection(true, filePath),
},
{
label: showHiddenFiles ? 'Hide Files' : 'Show Hidden Files',
icon: showHiddenFiles ? 'pi pi-eye-slash' : 'pi pi-eye',
command: () => toggleShowHiddenFiles(),
},
{
label: 'Rename',
icon: 'pi pi-pencil',
Expand All @@ -242,11 +259,12 @@ class FileTree extends React.Component {
}

function mapStateToProps(state) {
const { pendingRequests, selection, defaultConfig, selectedDefaultConfigFile, selectedVersion } = state.configuration;
const { pendingRequests, selection, defaultConfig, selectedDefaultConfigFile, selectedVersion, showHiddenFiles } = state.configuration;
return {
files: configurationSelectors.getFileTree(state),
loading: pendingRequests > 0,
selection,
showHiddenFiles,
defaultConfig: defaultConfig,
defaultTree: configurationSelectors.getDefaultConfigTree(state),
selectedDefaultConfigFile,
Expand All @@ -259,6 +277,7 @@ const mapDispatchToProps = {
fetchFiles: configurationActions.fetchFiles,
selectFile: configurationActions.selectFile,
exportSelection: configurationActions.exportSelection,
toggleShowHiddenFiles: configurationActions.toggleShowHiddenFiles,
move: configurationActions.move,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,9 @@ export const TOOLTIP_OPTIONS = {
showDelay: 1000,
position: 'top',
};

/**
* Name pattern for hidden files.
* @type {string}
*/
export const HIDDEN_FILES_NAME_PATTERN = '^\\.';
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DEFAULT_CONFIG_TREE_KEY, VERSION_LIMIT } from '../../../data/constants';
import { DEFAULT_CONFIG_TREE_KEY, HIDDEN_FILES_NAME_PATTERN, VERSION_LIMIT } from '../../../data/constants';
import axios from '../../../lib/axios-api';
import { configurationUtils } from '.';
import { notificationActions } from '../notification';
Expand Down Expand Up @@ -34,7 +34,7 @@ export const fetchVersions = () => {
*/
export const fetchFiles = (newSelectionOnSuccess) => {
return (dispatch, getState) => {
const { selectedVersion } = getState().configuration;
const { selectedVersion, showHiddenFiles } = getState().configuration;

const params = {};
if (selectedVersion) {
Expand All @@ -47,6 +47,9 @@ export const fetchFiles = (newSelectionOnSuccess) => {
.then((payload) => {
const files = payload;
sortFiles(files);
if (!showHiddenFiles) {
hideFilesRecursively(files, HIDDEN_FILES_NAME_PATTERN);
}
dispatch({ type: types.FETCH_FILES_SUCCESS, payload: { files } });
if (newSelectionOnSuccess) {
dispatch(selectFile(newSelectionOnSuccess));
Expand Down Expand Up @@ -256,6 +259,34 @@ export const exportSelection = (fetchFilesOnSuccess, selectedFile = null) => {
};
};

/**
* Either removes files that start with '.' or fetches files depending on if files are hidden.
*/
export const toggleShowHiddenFiles = () => {
return (dispatch) => {
dispatch({ type: types.TOGGLE_SHOW_HIDDEN_FILES });
dispatch(fetchFiles());
};
};

/**
* Recursively removes files that match the regex
* @param {array} files - the array of files
* @param {string} regex
*/
const hideFilesRecursively = (files, regex) => {
for (let i = 0; i <= files.length; i++) {
if (!files[i]) {
continue;
}
if (files[i].name.match(regex)) {
files.splice(i--, 1);
} else if (files[i].children) {
hideFilesRecursively(files[i].children, regex);
}
}
};

/**
* Attempts to write the given contents to the given file.
*
Expand Down Expand Up @@ -378,7 +409,7 @@ export const selectedFileContentsChanged = (content) => ({
*/
export const selectVersion = (version, reloadFiles = true) => {
return (dispatch) => {
// chaning the selected version
// changing the selected version
dispatch({
type: types.SELECT_VERSION,
payload: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@ const configurationReducer = createReducer(initialState)({
currentSidebar: state.currentSidebar == SidebarTypes.CONFIGURATION_DOCS ? SidebarTypes.NONE : SidebarTypes.CONFIGURATION_DOCS,
};
},

[types.TOGGLE_SHOW_HIDDEN_FILES]: (state) => {
return {
...state,
showHiddenFiles: !state.showHiddenFiles,
};
},
});

export default configurationReducer;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createSelector } from 'reselect';
import { map, find, get } from 'lodash';
import { getFile, isDirectory } from './utils';
import { DEFAULT_CONFIG_TREE_KEY } from '../../../data/constants';
import { DEFAULT_CONFIG_TREE_KEY, HIDDEN_FILES_NAME_PATTERN } from '../../../data/constants';

const configurationSelector = (state) => state.configuration;

Expand All @@ -26,6 +26,15 @@ const resolveFileTypeToIcon = (type) => {
return 'pi pi-fw ' + get(filetypeIconMapping, type, filetypeIconMapping['_default']);
};

/**
* Resolves the className for a given file in the tree
* @param file The file to resolve the className for
* @returns {string} The className
*/
const resolveFileToClassName = (file) => {
return file.name.match(HIDDEN_FILES_NAME_PATTERN) ? 'cm-hidden-file-tree-label' : '';
};

/**
* The logic to determine whether the given version is the latest one. The front-end assumes, that
* the latest version is on index 0 in the versions array provided by the backend.
Expand Down Expand Up @@ -64,6 +73,7 @@ const _asTreeNode = (parentKey, node, unsavedFileContents, isLatest) => {
key,
label: labelValue,
icon: resolveFileTypeToIcon(type),
className: resolveFileToClassName(node),
children: map(node.children, (child) => _asTreeNode(key + '/', child, unsavedFileContents, isLatest)),
};
} else {
Expand All @@ -72,6 +82,7 @@ const _asTreeNode = (parentKey, node, unsavedFileContents, isLatest) => {
key,
label: labelValue,
icon: resolveFileTypeToIcon(type),
className: resolveFileToClassName(node),
};
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export const DELETE_SELECTION_STARTED = 'configuration/DELETE_SELECTION_STARTED'
export const DELETE_SELECTION_FAILURE = 'configuration/DELETE_SELECTION_FAILURE';
export const DELETE_SELECTION_SUCCESS = 'configuration/DELETE_SELECTION_SUCCESS';

export const TOGGLE_SHOW_HIDDEN_FILES = 'configuration/TOGGLE_SHOW_HIDDEN_FILES';

export const EXPORT_SELECTION_STARTED = 'configuration/EXPORT_SELECTION_STARTED';
export const EXPORT_SELECTION_FAILURE = 'configuration/EXPORT_SELECTION_FAILURE';
export const EXPORT_SELECTION_SUCCESS = 'configuration/EXPORT_SELECTION_SUCCESS';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const configuration = {
versions: [],
/** The existing configuration files. */
files: [],
/** Indicates if hidden files ares shown. */
showHiddenFiles: false,
/**
* The history of file-move operations which were executed successfully.
* When the files are refetched, it can occur that the selection points to a non existing file.
Expand Down

0 comments on commit 4b4d57f

Please # to comment.