diff --git a/Resources/Private/Translations/de/Main.xlf b/Resources/Private/Translations/de/Main.xlf index 26d95e3..40f8b5f 100644 --- a/Resources/Private/Translations/de/Main.xlf +++ b/Resources/Private/Translations/de/Main.xlf @@ -218,6 +218,14 @@ {matches} options match your query {matches} Optionen entsprechen Ihrer Abfrage + + Open preview + Vorschau öffnen + + + Open the preview for current document + Öffnen Sie die Vorschau für das aktuelle Dokument + diff --git a/Resources/Private/Translations/en/Main.xlf b/Resources/Private/Translations/en/Main.xlf index 6c607e1..a0fad2d 100644 --- a/Resources/Private/Translations/en/Main.xlf +++ b/Resources/Private/Translations/en/Main.xlf @@ -171,6 +171,12 @@ {matches} options match your query + + Open preview + + + Open the preview for current document + diff --git a/packages/commandbar/src/components/SearchBox/SearchBox.tsx b/packages/commandbar/src/components/SearchBox/SearchBox.tsx index a82f56f..3d4e950 100644 --- a/packages/commandbar/src/components/SearchBox/SearchBox.tsx +++ b/packages/commandbar/src/components/SearchBox/SearchBox.tsx @@ -56,8 +56,6 @@ const SearchBox: React.FC = () => { } }); - console.debug('SearchBox.render', state.commands.value[state.resultCommandId.value]); - return ( <> void; - hotkeyRegistry: any; - handleHotkeyAction: (action: () => any) => void; addNode: ( referenceNodeContextPath: string, referenceNodeFusionPath: string | null, preferredMode: string, nodeType?: string ) => void; + baseWorkspace: string; + commandBarOpen: boolean; + config: CommandBarConfig; + discardAction: (contextPaths: string[]) => void; + documentNode: CRNode; editPreviewMode: string; - setEditPreviewMode: (mode: string) => void; editPreviewModes: EditPreviewModes; - publishableNodes: CRNode[]; - publishableNodesInDocument: CRNode[]; + focusedNodeContextPath: string; + handleHotkeyAction: (action: () => any) => void; + hotkeyRegistry: any; + i18nRegistry: I18nRegistry; isWorkspaceReadOnly: boolean; + plugins: Record HierarchicalCommandList>; publishAction: (contextPaths: string[], baseWorkspace: string) => void; - discardAction: (contextPaths: string[]) => void; - baseWorkspace: string; + publishableNodes: CRNode[]; + publishableNodesInDocument: CRNode[]; + previewUrl: string | null; setActiveContentCanvasSrc: (uri: string) => void; - plugins: Record HierarchicalCommandList>; + setEditPreviewMode: (mode: string) => void; + siteNode: CRNode; + toggleCommandBar: () => void; }; type CommandBarUiPluginState = { @@ -58,26 +60,27 @@ const IconComponent: React.FC = ({ icon, spin = false }) => { static propTypes = { + addNode: PropTypes.func.isRequired, + baseWorkspace: PropTypes.string.isRequired, + commandBarOpen: PropTypes.bool, config: PropTypes.object.isRequired, - i18nRegistry: PropTypes.object.isRequired, - siteNode: PropTypes.object, + discardAction: PropTypes.func.isRequired, documentNode: PropTypes.object, + editPreviewMode: PropTypes.string.isRequired, + editPreviewModes: PropTypes.object.isRequired, focusedNodeContextPath: PropTypes.string, - commandBarOpen: PropTypes.bool, - toggleCommandBar: PropTypes.func.isRequired, handleHotkeyAction: PropTypes.func.isRequired, hotkeyRegistry: PropTypes.object.isRequired, - addNode: PropTypes.func.isRequired, - editPreviewMode: PropTypes.string.isRequired, - setEditPreviewMode: PropTypes.func.isRequired, - editPreviewModes: PropTypes.object.isRequired, - publishableNodes: PropTypes.array, - publishableNodesInDocument: PropTypes.array, + i18nRegistry: PropTypes.object.isRequired, isWorkspaceReadOnly: PropTypes.bool, publishAction: PropTypes.func.isRequired, - discardAction: PropTypes.func.isRequired, - baseWorkspace: PropTypes.string.isRequired, + publishableNodes: PropTypes.array, + publishableNodesInDocument: PropTypes.array, + previewUrl: PropTypes.string, setActiveContentCanvasSrc: PropTypes.func.isRequired, + setEditPreviewMode: PropTypes.func.isRequired, + siteNode: PropTypes.object, + toggleCommandBar: PropTypes.func.isRequired, }; constructor(props) { @@ -173,8 +176,25 @@ class CommandBarUiPlugin extends React.PureComponent { + if (this.props.previewUrl) { + window.open(this.props.previewUrl, '_blank', 'noopener,noreferrer')?.focus(); + } else { + logger.warn('No preview url to open'); + } + }, + closeOnExecute: true, + }, }, }; + if (props.config.features.searchNeosDocs) { this.state.commands.searchNeosDocs = { name: this.translate('CommandBarUiPlugin.command.documentation', 'Documentation'), @@ -523,12 +543,6 @@ class CommandBarUiPlugin extends React.PureComponent ({ siteNode: selectors.CR.Nodes.siteNodeSelector(state), documentNode: selectors.CR.Nodes.documentNodeSelector(state), @@ -539,6 +553,7 @@ const mapStateToProps = (state: NeosRootState) => ({ baseWorkspace: selectors.CR.Workspaces.baseWorkspaceSelector(state), commandBarOpen: commandBarSelectors.commandBarOpen(state), editPreviewMode: selectors.UI.EditPreviewMode.currentEditPreviewMode(state), + previewUrl: commandBarSelectors.previewUrl(state), }); const mapDispatchToProps = (dispatch) => ({ diff --git a/packages/ui-plugin/src/actions/index.ts b/packages/ui-plugin/src/actions/index.ts index 3f3ff5e..23f9622 100644 --- a/packages/ui-plugin/src/actions/index.ts +++ b/packages/ui-plugin/src/actions/index.ts @@ -1,9 +1,24 @@ import { createAction, handleActions } from 'redux-actions'; +import { DefaultRootState } from 'react-redux'; export const actionTypes = { TOGGLE_COMMAND_BAR: 'TOGGLE_COMMAND_BAR', }; +// Type safety helper as the Neos extensibility doesn't provide a type for the global state +export interface NeosRootState extends DefaultRootState { + ui?: { + contentCanvas?: { + previewUrl?: string; + }; + }; + plugins?: { + commandBar?: { + open?: boolean; + }; + }; +} + const toggleCommandBar = createAction(actionTypes.TOGGLE_COMMAND_BAR); export const actions = { @@ -32,5 +47,6 @@ export const reducer = handleActions( ); export const selectors = { - commandBarOpen: (state) => state.plugins?.commandBar?.open, + commandBarOpen: (state: NeosRootState) => state.plugins?.commandBar?.open, + previewUrl: (state: NeosRootState) => state.ui?.contentCanvas?.previewUrl, };