Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Classes/Fusion/Helper/NodeInfoHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public function renderNodeWithMinimalPropertiesAndChildrenInformation(
// TODO: we should export this correctly named, but that needs changes throughout the JS code as well.
'_hidden' => $node->tags->withoutInherited()->contain(NeosSubtreeTag::disabled()),
'hiddenInMenu' => $node->getProperty('hiddenInMenu'),
'_hiddenByAncestors' => $node->tags->onlyInherited()->contain(NeosSubtreeTag::disabled()),
'_hiddenInIndex' => $node->getProperty('hiddenInMenu'),
'_hasTimeableNodeVisibility' =>
$node->getProperty('enableAfterDateTime') instanceof \DateTimeInterface
Expand Down Expand Up @@ -147,6 +148,14 @@ public function renderNodeWithPropertiesAndChildrenInformation(
$nodeInfo['properties'] = $this->nodePropertyConverterService->getPropertiesArray($node);
$nodeInfo['tags'] = $node->tags;
$nodeInfo['isFullyLoaded'] = true;
$nodeInfo['properties'] = array_merge($nodeInfo['properties'], [
// TODO: we should export this correctly named, but that needs changes throughout the JS code as well.
'_hidden' => $node->tags->withoutInherited()->contain(NeosSubtreeTag::disabled()),
'_hiddenByAncestors' => $node->tags->onlyInherited()->contain(NeosSubtreeTag::disabled()),
'_hasTimeableNodeVisibility' =>
$node->getProperty('enableAfterDateTime') instanceof \DateTimeInterface
|| $node->getProperty('disableAfterDateTime') instanceof \DateTimeInterface,
]);

if ($actionRequest !== null) {
$nodeInfo = array_merge($nodeInfo, $this->getUriInformation($node, $actionRequest));
Expand Down
7 changes: 5 additions & 2 deletions packages/neos-ui-redux-store/src/UI/PageTree/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export enum actionTypes {
REQUEST_CHILDREN = '@neos/neos-ui/UI/PageTree/REQUEST_CHILDREN',
COMMENCE_SEARCH = '@neos/neos-ui/UI/PageTree/COMMENCE_SEARCH',
SET_SEARCH_RESULT = '@neos/neos-ui/UI/PageTree/SET_SEARCH_RESULT',
COLLAPSE_ALL = '@neos/neos-ui/UI/PageTree/COLLAPSE_ALL'
COLLAPSE_ALL = '@neos/neos-ui/UI/PageTree/COLLAPSE_ALL',
RELOAD_TREE = '@neos/neos-ui/UI/PageTree/RELOAD_TREE'
}

const focus = (contextPath: NodeContextPath, _: undefined, selectionMode: SelectionModeTypes = SelectionModeTypes.SINGLE_SELECT) => createAction(actionTypes.FOCUS, {contextPath, selectionMode});
Expand All @@ -56,6 +57,7 @@ const collapseAll = (
nodeContextPaths: NodeContextPath[],
collapsedByDefaultNodeContextPaths: NodeContextPath[]
) => createAction(actionTypes.COLLAPSE_ALL, {nodeContextPaths, collapsedByDefaultNodeContextPaths});
const reloadTree = (contextPath: NodeContextPath) => createAction(actionTypes.RELOAD_TREE, {contextPath});

interface CommenceSearchOptions extends Readonly<{
query: string;
Expand All @@ -81,7 +83,8 @@ export const actions = {
requestChildren,
commenceSearch,
setSearchResult,
collapseAll
collapseAll,
reloadTree
};

export type Action = ActionType<typeof actions>;
Expand Down
2 changes: 2 additions & 0 deletions packages/neos-ui-sagas/src/CR/NodeOperations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import moveDroppedNodes from './moveDroppedNodes';
import hideNode from './hideNode';
import showNode from './showNode';
import reloadState from './reloadState';
import reloadTreesAfterVisibilityChange from './reloadTreesAfterVisibilityChange';
import {makeReloadNodes} from './reloadNodes';

export {
Expand All @@ -19,5 +20,6 @@ export {
hideNode,
showNode,
reloadState,
reloadTreesAfterVisibilityChange,
makeReloadNodes
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {takeEvery, take, put, select} from 'redux-saga/effects';

import {actionTypes, actions} from '@neos-project/neos-ui-redux-store';

export default function * reloadTreesAfterVisibilityChange({globalRegistry}) {
const nodeTypesRegistry = globalRegistry.get('@neos-project/neos-ui-contentrepository');
yield takeEvery(actionTypes.Changes.PERSIST, function * (action) {
const affectedContextPaths = action.payload.changes
.filter(change => change.type === 'Neos.Neos.Ui:Property'
&& change.payload.propertyName === '_hidden')
.map(change => change.subject);
if (affectedContextPaths.length === 0) {
return;
}

// Wait until the persist round-trip is fully finished (survives request batching in
// watchPersist, which re-triggers on FINISH_SAVING while more changes are queued).
do {
yield take(actionTypes.UI.Remote.FINISH_SAVING);
} while (yield select(state => state?.ui?.remote?.isSaving));

// A hide/show also changes `_hiddenByAncestors` for every descendant. For each affected
// document node, reload its page-tree subtree so descendant document icons update immediately.
for (const contextPath of new Set(affectedContextPaths)) {
const nodeType = yield select(state => state?.cr?.nodes?.byContextPath?.[contextPath]?.nodeType);
if (nodeType && nodeTypesRegistry.hasRole(nodeType, 'document')) {
yield put(actions.UI.PageTree.reloadTree(contextPath));
}
}

// Always refresh the current document's content tree: hiding/showing a content node changes
// its descendants' `_hiddenByAncestors`, and hiding/showing the current document (or one of its
// document ancestors) makes all of its content inherited-disabled. A single lightweight reload
// of the current document's content covers both cases.
yield put(actions.UI.ContentTree.reloadTree());
});
}
30 changes: 30 additions & 0 deletions packages/neos-ui-sagas/src/UI/PageTree/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,33 @@ export function * watchSearch() {
yield put(actions.UI.PageTree.setAsLoaded(contextPath));
});
}

export function * watchReloadTree() {
yield takeEvery(actionTypes.UI.PageTree.RELOAD_TREE, function * reloadTree(action) {
const {contextPath} = action.payload;
const {q} = backend.get();
const clipboardNodesContextPaths = yield select(selectors.CR.Nodes.clipboardNodesContextPathsSelector);
const toggledNodes = yield select(state => state?.ui?.pageTree?.toggled);

yield put(actions.UI.PageTree.setAsLoading(contextPath));
let nodes = [];
try {
nodes = yield q(contextPath).neosUiDefaultNodes(
getConfiguration(configuration => configuration.nodeTree.presets.default.baseNodeType),
getConfiguration(configuration => configuration.nodeTree.loadingDepth),
toggledNodes,
clipboardNodesContextPaths
).getForTree('PAGE_TREE');
} catch (err) {
yield put(actions.UI.PageTree.invalidate(contextPath));
showFlashMessage({id: 'reloadTreeError', severity: 'error', message: err.message});
return;
}
const nodeMap = nodes.reduce((map, node) => {
map[node?.contextPath] = node;
return map;
}, {});
yield put(actions.CR.Nodes.merge(nodeMap));
yield put(actions.UI.PageTree.setAsLoaded(contextPath));
});
}
2 changes: 2 additions & 0 deletions packages/neos-ui-sagas/src/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ manifest('main.sagas', {}, globalRegistry => {
sagasRegistry.set('neos-ui/CR/NodeOperations/showNode', {saga: crNodeOperations.showNode});
sagasRegistry.set('neos-ui/CR/NodeOperations/removeNodeIfConfirmed', {saga: crNodeOperations.removeNodeIfConfirmed});
sagasRegistry.set('neos-ui/CR/NodeOperations/reloadState', {saga: crNodeOperations.reloadState});
sagasRegistry.set('neos-ui/CR/NodeOperations/reloadTreesAfterVisibilityChange', {saga: crNodeOperations.reloadTreesAfterVisibilityChange});

sagasRegistry.set('neos-ui/CR/Policies/watchNodeInformationChanges', {saga: crPolicies.watchNodeInformationChanges});

Expand Down Expand Up @@ -79,6 +80,7 @@ manifest('main.sagas', {}, globalRegistry => {
sagasRegistry.set('neos-ui/UI/PageTree/watchRequestChildrenForContextPath', {saga: uiPageTree.watchRequestChildrenForContextPath});
sagasRegistry.set('neos-ui/UI/PageTree/watchSearch', {saga: uiPageTree.watchSearch});
sagasRegistry.set('neos-ui/UI/PageTree/watchToggle', {saga: uiPageTree.watchToggle});
sagasRegistry.set('neos-ui/UI/PageTree/watchReloadTree', {saga: uiPageTree.watchReloadTree});

sagasRegistry.set('neos-ui/UI/Hotkeys/handleHotkeys', {saga: uiHotkeys.handleHotkeys});

Expand Down
11 changes: 11 additions & 0 deletions packages/neos-ui/src/Containers/LeftSideBar/NodeTree/Node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export default class Node extends PureComponent {
const {node} = this.props;

const isDisabled = node?.properties?._hidden;
const isDisabledByAncestors = node?.properties?._hiddenByAncestors;
const hasTimeableNodeVisibility = node?.properties?._hasTimeableNodeVisibility;

if (hasTimeableNodeVisibility) {
Expand All @@ -193,6 +194,16 @@ export default class Node extends PureComponent {
);
}

if (isDisabledByAncestors) {
return (
<span className="fa-layers fa-fw">
<Icon icon={this.getIcon()} />
<Icon icon="circle" color="contrastDark" transform="shrink-3 down-6 right-4" />
<Icon icon="times" transform="shrink-7 down-6 right-4" />
</span>
);
}

return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ exports[`<Icon/> should render correctly. 1`] = `
Object {
"icon": "iconClassName",
"icon--big": "bigClassName",
"icon--color-contrastDark": "color-contrastDarkClassName",
"icon--color-error": "color-errorClassName",
"icon--color-primaryBlue": "color-primaryBlueClassName",
"icon--color-warn": "color-warnClassName",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe('<FontAwesomeIcon/>', () => {
'icon--big': 'bigClassName',
'icon--color-error': 'color-errorClassName',
'icon--color-primaryBlue': 'color-primaryBlueClassName',
'icon--color-contrastDark': 'color-contrastDarkClassName',
'icon--color-warn': 'color-warnClassName',
'icon--paddedLeft': 'paddedLeftClassName',
'icon--paddedRight': 'paddedRightClassName',
Expand Down
3 changes: 2 additions & 1 deletion packages/react-ui-components/src/Icon/fontAwesomeIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ class FontAwesomeIcon extends PureComponent<IconProps> {
[theme!['icon--paddedRight']]: padded === 'right',
[theme!['icon--color-warn']]: color === 'warn',
[theme!['icon--color-error']]: color === 'error',
[theme!['icon--color-primaryBlue']]: color === 'primaryBlue'
[theme!['icon--color-primaryBlue']]: color === 'primaryBlue',
[theme!['icon--color-contrastDark']]: color === 'contrastDark'
}
);

Expand Down
1 change: 1 addition & 0 deletions packages/react-ui-components/src/Icon/icon.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ describe('<Icon/>', () => {
'icon--big': 'bigClassName',
'icon--color-error': 'color-errorClassName',
'icon--color-primaryBlue': 'color-primaryBlueClassName',
'icon--color-contrastDark': 'color-contrastDarkClassName',
'icon--color-warn': 'color-warnClassName',
'icon--paddedLeft': 'paddedLeftClassName',
'icon--paddedRight': 'paddedRightClassName',
Expand Down
3 changes: 2 additions & 1 deletion packages/react-ui-components/src/Icon/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {defaultProps} from './iconDefaultProps';

type IconSize = 'xs' | 'sm' | 'lg' | '2x' | '3x';
type IconPadding = 'none' | 'left' | 'right';
type IconColor = 'default' | 'warn' | 'error' | 'primaryBlue';
type IconColor = 'default' | 'warn' | 'error' | 'primaryBlue' | 'contrastDark';

export interface IconTheme {
readonly icon: string;
Expand All @@ -22,6 +22,7 @@ export interface IconTheme {
readonly 'icon--color-warn': string;
readonly 'icon--color-error': string;
readonly 'icon--color-primaryBlue': string;
readonly 'icon--color-contrastDark': string;
}

export interface IconProps extends Omit<FontAwesomeIconProps, 'icon' | 'ref'> {
Expand Down
1 change: 1 addition & 0 deletions packages/react-ui-components/src/Icon/resourceIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class ResourceIcon extends PureComponent<ResourceIconProps> {
[theme!['icon--color-warn']]: color === 'warn',
[theme!['icon--color-error']]: color === 'error',
[theme!['icon--color-primaryBlue']]: color === 'primaryBlue',
[theme!['icon--color-contrastDark']]: color === 'contrastDark',
[theme!['icon--huge']]: size === '3x',
[theme!['icon--large']]: size === '2x',
[theme!['icon--big']]: size === 'lg',
Expand Down
4 changes: 4 additions & 0 deletions packages/react-ui-components/src/Icon/style.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
color: var(--colors-PrimaryBlue);
}

.icon--color-contrastDark {
color: var(--colors-ContrastDark);
}

.icon--huge {
& svg {
height: 3em;
Expand Down
Loading