diff --git a/scripts/core/interactive-article-actions-panel/actions/publish-tab.tsx b/scripts/core/interactive-article-actions-panel/actions/publish-tab.tsx index 4f590d5be8..e9ec89e24d 100644 --- a/scripts/core/interactive-article-actions-panel/actions/publish-tab.tsx +++ b/scripts/core/interactive-article-actions-panel/actions/publish-tab.tsx @@ -5,7 +5,7 @@ import {gettext} from 'core/utils'; import {PanelContent} from '../panel/panel-content'; import {PanelFooter} from '../panel/panel-footer'; import {DestinationSelect} from '../subcomponents/destination-select'; -import {IPanelError, ISendToDestination} from '../interfaces'; +import {IPanelError, IPropsHocInteractivePanelTab, ISendToDestination} from '../interfaces'; import {getCurrentDeskDestination} from '../utils/get-initial-destination'; import { IPublishingDateOptions, @@ -29,7 +29,7 @@ import {PreviewModal} from 'apps/publish-preview/previewModal'; import {notify} from 'core/notify/notify'; import {sdApi} from 'api'; -interface IProps { +interface IProps extends IPropsHocInteractivePanelTab { item: IArticle; closePublishView(): void; handleUnsavedChanges(): Promise; @@ -45,7 +45,7 @@ interface IState { subscribers: Array | null; } -export class PublishTab extends React.PureComponent { +export class WithPublishTab extends React.PureComponent { constructor(props: IProps) { super(props); @@ -153,129 +153,139 @@ export class PublishTab extends React.PureComponent { .flatMap(({activationResult}) => activationResult?.contributions?.publishingSections ?? []); const style: CSSProperties | undefined = sectionsFromExtensions.length > 0 - ? {display: 'flex', alignItems: 'start', justifyContent: 'space-between'} + ? {display: 'flex', alignItems: 'start', justifyContent: 'space-between', gap: 32} : undefined; - return ( - - -
-
- { - publishFromEnabled && ( - - { - this.setState({ - selectedDestination: value, - }); - }} - includePersonalSpace={false} + const childrenStyle: CSSProperties = { + flex: 1, // equal width for columns + }; - /** - * Changing the destination is only used - * to control which desk's output stage - * the published item appears in, thus - * choosing a stage would not have an impact - */ - hideStages={true} - /> - - ) - } + return this.props.children({ + columnCount: 1 + sectionsFromExtensions.length, + content: ( + + +
+
+ { + publishFromEnabled && ( + + { + this.setState({ + selectedDestination: value, + }); + }} + includePersonalSpace={false} - { - this.setState( - {publishingDateOptions: val}, - () => this.props.onDataChange({ - ...this.props.item, - ...getPublishingDatePatch( - this.props.item, - this.state.publishingDateOptions, - ), - }), - ); - }} - allowSettingEmbargo={appConfig.ui.publishEmbargo !== false} - /> + /** + * Changing the destination is only used + * to control which desk's output stage + * the published item appears in, thus + * choosing a stage would not have an impact + */ + hideStages={true} + /> + + ) + } + + { + this.setState( + {publishingDateOptions: val}, + () => this.props.onDataChange({ + ...this.props.item, + ...getPublishingDatePatch( + this.props.item, + this.state.publishingDateOptions, + ), + }), + ); + }} + allowSettingEmbargo={appConfig.ui.publishEmbargo !== false} + /> - { - this.setState( - {publishingTarget: val}, - () => this.props.onDataChange({ - ...this.props.item, - ...getPublishingTargetPatch(this.props.item, this.state.publishingTarget), - }), + { + this.setState( + {publishingTarget: val}, + () => this.props.onDataChange({ + ...this.props.item, + ...getPublishingTargetPatch( + this.props.item, + this.state.publishingTarget, + ), + }), + ); + }} + /> +
+ + { + sectionsFromExtensions.map((panel, i) => { + const Component = panel.component; + + return ( +
+ +
); - }} - /> + }) + }
+
+ { - sectionsFromExtensions.map((panel, i) => { - const Component = panel.component; - - return ( -
- -
- ); - }) + canPreview && ( +
- - - - { - canPreview && ( -
- - - {(() => { - if (activeTab === 'publish') { - if (items.length !== 1) { - logger.error(new Error('Publishing multiple items from authoring pane is not supported')); - - return null; - } - - const item = items[0]; - - return ( - handleUnsavedChanges([item]).then((res) => res[0]) - } - /> - ); - } if (activeTab === 'correct') { - if (items.length !== 1) { - logger.error(new Error('Correcting multiple items from authoring pane is not supported')); - - return null; + const panelHeader = ( + +
+ ({id, label: getTabLabel(id)})) } + selectedTabId={activeTab} + onChange={(tab: IArticleActionInteractive) => { + this.setState({ + activeTab: tab, + }); + }} + data-test-id="tabs" + /> + +
+
+ ); - const item = items[0]; - - return ( - handleUnsavedChanges([item]).then((res) => res[0]) - } - /> - ); - } else if (activeTab === 'send_to') { - return ( - - ); - } else if (activeTab === 'fetch_to') { - return ( - - ); - } if (activeTab === 'duplicate_to') { - return ( - - ); - } if (activeTab === 'unspike') { - return ( - - ); - } else { - return assertNever(activeTab); + function PanelWithHeader({columnCount = 1, children}: {columnCount?: number, children: React.ReactNode}) { + return ( + + {panelHeader} + {children} + + ); + } + + if (activeTab === 'publish') { + if (items.length !== 1) { + logger.error(new Error('Publishing multiple items from authoring pane is not supported')); + + return null; + } + + const item = items[0]; + + return ( + handleUnsavedChanges([item]).then((res) => res[0]) } - })()} - - ); + > + {({columnCount, content}) => ( + + {content} + + )} + + ); + } if (activeTab === 'correct') { + if (items.length !== 1) { + logger.error(new Error('Correcting multiple items from authoring pane is not supported')); + + return null; + } + + const item = items[0]; + + return ( + + handleUnsavedChanges([item]).then((res) => res[0]) + } + /> + + ); + } else if (activeTab === 'send_to') { + return ( + + + + ); + } else if (activeTab === 'fetch_to') { + return ( + + + + ); + } if (activeTab === 'duplicate_to') { + return ( + + + + ); + } if (activeTab === 'unspike') { + return ( + + + + ); + } else { + return assertNever(activeTab); + } } } diff --git a/scripts/core/interactive-article-actions-panel/interfaces.ts b/scripts/core/interactive-article-actions-panel/interfaces.ts index 728fbbafd0..369ea207a7 100644 --- a/scripts/core/interactive-article-actions-panel/interfaces.ts +++ b/scripts/core/interactive-article-actions-panel/interfaces.ts @@ -29,3 +29,12 @@ export interface ISendToDestinationPersonalSpace { } export type ISendToDestination = ISendToDestinationDesk | ISendToDestinationPersonalSpace; + +export interface IHocInteractivePanelResult { + columnCount: number; + content: React.ReactNode; +} + +export interface IPropsHocInteractivePanelTab { + children(args: IHocInteractivePanelResult): JSX.Element; +} diff --git a/scripts/core/interactive-article-actions-panel/panel/panel-footer.tsx b/scripts/core/interactive-article-actions-panel/panel/panel-footer.tsx index d37eebaee0..29d4c013ee 100644 --- a/scripts/core/interactive-article-actions-panel/panel/panel-footer.tsx +++ b/scripts/core/interactive-article-actions-panel/panel/panel-footer.tsx @@ -7,7 +7,9 @@ export class PanelFooter extends React.PureComponent { if (this.props.markupV2) { return ( - {this.props.children} +
+ {this.props.children} +
); } else { diff --git a/scripts/core/interactive-article-actions-panel/panel/panel-main.tsx b/scripts/core/interactive-article-actions-panel/panel/panel-main.tsx index d83dd1aff9..8cce6101c4 100644 --- a/scripts/core/interactive-article-actions-panel/panel/panel-main.tsx +++ b/scripts/core/interactive-article-actions-panel/panel/panel-main.tsx @@ -9,13 +9,18 @@ export interface IPropsSendToPanel { */ markupV2: boolean; 'data-test-id'?: string; + width?: React.CSSProperties['width']; } export class Panel extends React.PureComponent { render() { if (this.props.markupV2) { return ( - + {this.props.children} ); @@ -24,6 +29,7 @@ export class Panel extends React.PureComponent {
{this.props.children}