From 459498cfc2f167caef51834d2e1259c795df8cea Mon Sep 17 00:00:00 2001 From: Kirill Shumilov Date: Mon, 19 Mar 2018 20:07:49 +0300 Subject: [PATCH] feat(xod-client): show/hide deprecated patches in the ProjectBrowser by toggling filter option --- .../core/styles/components/PanelToolbar.scss | 52 ------------------ .../core/styles/components/SidebarPanel.scss | 3 ++ packages/xod-client/src/core/styles/main.scss | 1 - .../src/projectBrowser/actionTypes.js | 2 + .../xod-client/src/projectBrowser/actions.js | 5 ++ .../src/projectBrowser/constants.js | 1 + .../containers/ProjectBrowser.jsx | 53 ++++++++++++++++--- .../xod-client/src/projectBrowser/reducer.js | 12 +++++ .../src/projectBrowser/selectors.js | 26 ++++++--- .../xod-client/src/projectBrowser/state.js | 3 ++ 10 files changed, 93 insertions(+), 65 deletions(-) delete mode 100644 packages/xod-client/src/core/styles/components/PanelToolbar.scss diff --git a/packages/xod-client/src/core/styles/components/PanelToolbar.scss b/packages/xod-client/src/core/styles/components/PanelToolbar.scss deleted file mode 100644 index c54955f6..00000000 --- a/packages/xod-client/src/core/styles/components/PanelToolbar.scss +++ /dev/null @@ -1,52 +0,0 @@ -.PanelToolbar { - display: block; - height: 24px; - overflow: hidden; - box-sizing: border-box; - background-color: $chrome-title-bg; - - button { - display: inline-block; - box-sizing: border-box; - width: 24px; - height: 24px; - padding: 0; - - text-align: center; - vertical-align: middle; - line-height: 1; - - background: none; - border: none; - outline: none; - - cursor: pointer; - - color: $sidebar-color-text; - - &:hover, &:focus { - color: $sidebar-color-text-hover; - } - - &.addlib{ - @extend .icon-addlib; - } - &.newpatch{ - @extend .icon-newpatch; - } - &.contextmenu { - @extend .icon-contextmenu; - } - } - - &-title { - font-size: $font-size-m; - color: $light-grey-bright; - float: left; - line-height: 18px; - padding: 3px; - } - &-buttons { - float: right; - } -} diff --git a/packages/xod-client/src/core/styles/components/SidebarPanel.scss b/packages/xod-client/src/core/styles/components/SidebarPanel.scss index f4127c42..675677d6 100644 --- a/packages/xod-client/src/core/styles/components/SidebarPanel.scss +++ b/packages/xod-client/src/core/styles/components/SidebarPanel.scss @@ -50,6 +50,9 @@ &.newpatch{ @extend .icon-newpatch; } + &.filter { + @extend .icon-filter; + } &.contextmenu { @extend .icon-contextmenu; opacity: 0.7; diff --git a/packages/xod-client/src/core/styles/main.scss b/packages/xod-client/src/core/styles/main.scss index cf5b3d67..1ef77676 100644 --- a/packages/xod-client/src/core/styles/main.scss +++ b/packages/xod-client/src/core/styles/main.scss @@ -36,7 +36,6 @@ 'components/Modals', 'components/Node', 'components/NoPatch', - 'components/PanelToolbar', 'components/PatchDocs', 'components/PatchGroup', 'components/PatchGroupItem', diff --git a/packages/xod-client/src/projectBrowser/actionTypes.js b/packages/xod-client/src/projectBrowser/actionTypes.js index b16c4392..99fafd0d 100644 --- a/packages/xod-client/src/projectBrowser/actionTypes.js +++ b/packages/xod-client/src/projectBrowser/actionTypes.js @@ -4,3 +4,5 @@ export const PATCH_DELETE_REQUESTED = 'PATCH_DELETE_REQUESTED'; export const SET_SELECTION = 'SET_SELECTION'; export const REMOVE_SELECTION = 'REMOVE_SELECTION'; + +export const TOGGLE_DEPRECATED_FILTER = 'TOGGLE_DEPRECATED_FILTER'; diff --git a/packages/xod-client/src/projectBrowser/actions.js b/packages/xod-client/src/projectBrowser/actions.js index a141daa9..c483cf4f 100644 --- a/packages/xod-client/src/projectBrowser/actions.js +++ b/packages/xod-client/src/projectBrowser/actions.js @@ -6,6 +6,7 @@ import { PATCH_DELETE_REQUESTED, SET_SELECTION, REMOVE_SELECTION, + TOGGLE_DEPRECATED_FILTER, } from './actionTypes'; import { getSelectedPatchPath } from './selectors'; @@ -49,3 +50,7 @@ export const setSelection = selectedPatchPath => ({ export const removeSelection = () => ({ type: REMOVE_SELECTION, }); + +export const toggleDeprecatedFilter = () => ({ + type: TOGGLE_DEPRECATED_FILTER, +}); diff --git a/packages/xod-client/src/projectBrowser/constants.js b/packages/xod-client/src/projectBrowser/constants.js index 59738dd0..0ab67314 100644 --- a/packages/xod-client/src/projectBrowser/constants.js +++ b/packages/xod-client/src/projectBrowser/constants.js @@ -1,3 +1,4 @@ // Id of context menu to show it // eslint-disable-next-line import/prefer-default-export export const PATCH_GROUP_CONTEXT_MENU_ID = 'PATCH_GROUP_CONTEXT_MENU_ID'; +export const FILTER_CONTEXT_MENU_ID = 'FILTER_CONTEXT_MENU_ID'; diff --git a/packages/xod-client/src/projectBrowser/containers/ProjectBrowser.jsx b/packages/xod-client/src/projectBrowser/containers/ProjectBrowser.jsx index e2325670..609d336f 100644 --- a/packages/xod-client/src/projectBrowser/containers/ProjectBrowser.jsx +++ b/packages/xod-client/src/projectBrowser/containers/ProjectBrowser.jsx @@ -5,7 +5,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { Icon } from 'react-fa'; import { HotKeys } from 'react-hotkeys'; -import { ContextMenuTrigger } from 'react-contextmenu'; +import { ContextMenuTrigger, ContextMenu, MenuItem } from 'react-contextmenu'; import $ from 'sanctuary-def'; import { @@ -14,6 +14,7 @@ import { isPathLocal, getBaseName, PatchPath, + isDeprecatedPatch, } from 'xod-project'; import { isAmong, notEquals, $Maybe, foldMaybe } from 'xod-func-tools'; @@ -36,16 +37,23 @@ import PatchGroupItem from '../components/PatchGroupItem'; import ProjectBrowserPopups from '../components/ProjectBrowserPopups'; import PatchGroupItemContextMenu from '../components/PatchGroupItemContextMenu'; -import { PATCH_GROUP_CONTEXT_MENU_ID } from '../constants'; +import { + PATCH_GROUP_CONTEXT_MENU_ID, + FILTER_CONTEXT_MENU_ID, +} from '../constants'; import { PANEL_IDS, SIDEBAR_IDS } from '../../editor/constants'; import { triggerUpdateHelpboxPositionViaProjectBrowser } from '../../editor/utils'; -const pickPatchPartsForComparsion = R.map(R.pick(['dead', 'path'])); +const pickPatchPartsForComparsion = R.map( + R.pick(['deprecated', 'dead', 'path']) +); + +const checkmark = active => (active ? : null); const pickPropsForComparsion = R.compose( R.evolve({ localPatches: pickPatchPartsForComparsion, - libs: pickPatchPartsForComparsion, + libs: R.map(pickPatchPartsForComparsion), }), R.omit(['actions']) ); @@ -178,9 +186,11 @@ class ProjectBrowser extends React.Component { const collectPropsFn = this.getCollectPropsFn(path); + const key = `${path}${deprecated ? '_deprecated' : ''}`; + return ( { LibName: [Patch] } + const rejectDeprecatedPatches = R.unless( + () => this.props.showDeprecated, + R.map(R.reject(isDeprecatedPatch)) + ); + const libComponents = R.compose( R.reject(R.compose(isAmong(installingLibNames), R.prop('name'))), R.map(([libName, libPatches]) => ({ @@ -250,7 +268,8 @@ class ProjectBrowser extends React.Component { ), })), - R.toPairs + R.toPairs, + rejectDeprecatedPatches )(libs); return R.compose( @@ -283,6 +302,17 @@ class ProjectBrowser extends React.Component { title="Add library" onClick={this.onClickAddLibrary} />, + + + , ]; } @@ -323,6 +353,12 @@ class ProjectBrowser extends React.Component { onPatchRename={this.props.actions.requestRename} onPatchHelp={this.onPatchHelpClicked} /> + + + {checkmark(this.props.showDeprecated)} + Deprecated nodes + + ); } @@ -342,6 +378,7 @@ ProjectBrowser.propTypes = { defaultNodePosition: PropTypes.object.isRequired, sidebarId: PropTypes.oneOf(R.values(SIDEBAR_IDS)).isRequired, autohide: PropTypes.bool.isRequired, + showDeprecated: PropTypes.bool.isRequired, actions: PropTypes.shape({ addNode: PropTypes.func.isRequired, switchPatch: PropTypes.func.isRequired, @@ -357,6 +394,7 @@ ProjectBrowser.propTypes = { closeAllPopups: PropTypes.func.isRequired, showLibSuggester: PropTypes.func.isRequired, showHelpbox: PropTypes.func.isRequired, + toggleDeprecatedFilter: PropTypes.func.isRequired, }), }; @@ -370,6 +408,7 @@ const mapStateToProps = R.applySpec({ libs: ProjectBrowserSelectors.getLibs, installingLibs: ProjectBrowserSelectors.getInstallingLibraries, defaultNodePosition: EditorSelectors.getDefaultNodePlacePosition, + showDeprecated: ProjectBrowserSelectors.shouldShowDeprecatedPatches, }); const mapDispatchToProps = dispatch => ({ @@ -395,6 +434,8 @@ const mapDispatchToProps = dispatch => ({ addNotification: MessagesActions.addNotification, showLibSuggester: EditorActions.showLibSuggester, showHelpbox: EditorActions.showHelpbox, + + toggleDeprecatedFilter: ProjectBrowserActions.toggleDeprecatedFilter, }, dispatch ), diff --git a/packages/xod-client/src/projectBrowser/reducer.js b/packages/xod-client/src/projectBrowser/reducer.js index 5fb1e803..cb9207c3 100644 --- a/packages/xod-client/src/projectBrowser/reducer.js +++ b/packages/xod-client/src/projectBrowser/reducer.js @@ -7,6 +7,7 @@ import { PATCH_DELETE_REQUESTED, SET_SELECTION, REMOVE_SELECTION, + TOGGLE_DEPRECATED_FILTER, } from './actionTypes'; import { PATCH_DELETE, PATCH_RENAME } from '../project/actionTypes'; @@ -17,6 +18,7 @@ import { INSTALL_LIBRARIES_FAILED, } from '../editor/actionTypes'; +// Reducers const selectionReducer = (state, action) => { switch (action.type) { case SET_SELECTION: @@ -52,9 +54,19 @@ const installingLibrariesReducer = (state, action) => { } }; +const filtersReducer = (state, action) => { + switch (action.type) { + case TOGGLE_DEPRECATED_FILTER: + return R.over(R.lensProp('deprecated'), R.not, state); + default: + return state; + } +}; + export default (state = initialState, action) => R.merge(state, { selectedPatchPath: selectionReducer(state.selectedPatchPath, action), + filters: filtersReducer(state.filters, action), installingLibraries: installingLibrariesReducer( state.installingLibraries, action diff --git a/packages/xod-client/src/projectBrowser/selectors.js b/packages/xod-client/src/projectBrowser/selectors.js index 8a885c8d..3472195b 100644 --- a/packages/xod-client/src/projectBrowser/selectors.js +++ b/packages/xod-client/src/projectBrowser/selectors.js @@ -10,6 +10,11 @@ import { isPatchDeadTerminal } from '../project/utils'; export const getProjectBrowser = R.prop('projectBrowser'); +export const shouldShowDeprecatedPatches = createSelector( + getProjectBrowser, + R.path(['filters', 'deprecated']) +); + export const getSelectedPatchPath = createSelector( getProjectBrowser, R.prop('selectedPatchPath') @@ -29,14 +34,23 @@ const markDeadPatches = R.curry((project, patch) => )(patch, project) ); -export const getLocalPatches = createSelector( +// :: Patch -> Patch +const markDeprecatedPatches = patch => + R.assoc('deprecated', XP.isDeprecatedPatch(patch), patch); + +const getLocalPatchesList = createSelector( ProjectSelectors.getProject, - project => + XP.listLocalPatches +); + +export const getLocalPatches = createMemoizedSelector( + [getLocalPatchesList, ProjectSelectors.getProject], + [R.equals], + (patches, project) => R.compose( R.sortBy(XP.getPatchPath), - R.map(markDeadPatches(project)), - XP.listLocalPatches - )(project) + R.map(R.compose(markDeprecatedPatches, markDeadPatches(project))) + )(patches) ); // TODO: this is not actually label anymore @@ -63,7 +77,7 @@ export const getLibs = createMemoizedSelector( R.map(R.sort(R.ascend(XP.getPatchPath))), R.groupBy(R.pipe(XP.getPatchPath, XP.getLibraryName)), R.reject(isPatchDeadTerminal), - R.map(markDeadPatches(project)) + R.map(R.compose(markDeprecatedPatches, markDeadPatches(project))) )(patches) ); diff --git a/packages/xod-client/src/projectBrowser/state.js b/packages/xod-client/src/projectBrowser/state.js index a164d303..cfa86d85 100644 --- a/packages/xod-client/src/projectBrowser/state.js +++ b/packages/xod-client/src/projectBrowser/state.js @@ -1,4 +1,7 @@ export default { selectedPatchPath: null, + filters: { + deprecated: false, + }, installingLibraries: [], };