// @flow import Tabs from '@atlaskit/tabs'; import React, { Component } from 'react'; import { translate } from '../../../i18n/functions'; import logger from '../../logger'; import StatelessDialog from './StatelessDialog'; /** * The type of the React {@code Component} props of {@link DialogWithTabs}. */ export type Props = { /** * Function that closes the dialog. */ closeDialog: Function, /** * Css class name that will be added to the dialog. */ cssClassName: string, /** * Which settings tab should be initially displayed. If not defined then * the first tab will be displayed. */ defaultTab: number, /** * Disables dismissing the dialog when the blanket is clicked. Enabled * by default. */ disableBlanketClickDismiss: boolean, /** * Callback invoked when the Save button has been pressed. */ onSubmit: Function, /** * Invoked to obtain translated strings. */ t: Function, /** * Information about the tabs that will be rendered. */ tabs: Array, /** * Key to use for showing a title. */ titleKey: string }; /** * The type of the React {@code Component} state of {@link DialogWithTabs}. */ type State = { /** * The index of the tab that should be displayed. */ selectedTab: number, /** * An array of the states of the tabs. */ tabStates: Array }; /** * A React {@code Component} for displaying a dialog with tabs. * * @extends Component */ class DialogWithTabs extends Component { /** * Initializes a new {@code DialogWithTabs} instance. * * @param {Object} props - The read-only React {@code Component} props with * which the new instance is to be initialized. */ constructor(props: Props) { super(props); this.state = { selectedTab: this.props.defaultTab || 0, tabStates: this.props.tabs.map(tab => tab.props) }; this._onSubmit = this._onSubmit.bind(this); this._onTabSelected = this._onTabSelected.bind(this); this._onTabStateChange = this._onTabStateChange.bind(this); } /** * Implements React's {@link Component#render()}. * * @inheritdoc * @returns {ReactElement} */ render() { const onCancel = this.props.closeDialog; return (
{ this._renderTabs() }
); } /** * Gets the props to pass into the tab component. * * @param {number} tabId - The index of the tab configuration within * {@link this.state.tabStates}. * @returns {Object} */ _getTabProps(tabId) { const { tabs } = this.props; const { tabStates } = this.state; const tabConfiguration = tabs[tabId]; const currentTabState = tabStates[tabId]; if (tabConfiguration.propsUpdateFunction) { return tabConfiguration.propsUpdateFunction( currentTabState, tabConfiguration.props); } return { ...currentTabState }; } _onTabSelected: (Object, number) => void; /** * Callback invoked when the desired tab to display should be changed. * * @param {Object} tab - The configuration passed into atlaskit tabs to * describe how to display the selected tab. * @param {number} tabIndex - The index of the tab within the array of * displayed tabs. * @private * @returns {void} */ _onTabSelected(tab, tabIndex) { // eslint-disable-line no-unused-vars this.setState({ selectedTab: tabIndex }); } /** * Renders the tabs from the tab information passed on props. * * @returns {void} */ _renderTabs() { const { t, tabs } = this.props; if (tabs.length === 1) { return this._renderTab({ ...tabs[0], tabId: 0 }); } if (tabs.length > 1) { return ( { return { content: this._renderTab({ component, styles, tabId: idx }), label: t(label) }; }) } />); } logger.warn('No settings tabs configured to display.'); return null; } /** * Renders a tab from the tab information passed as parameters. * * @param {Object} tabInfo - Information about the tab. * @returns {Component} - The tab. */ _renderTab({ component, styles, tabId }) { const { closeDialog } = this.props; const TabComponent = component; return (
); } _onTabStateChange: (number, Object) => void; /** * Changes the state for a tab. * * @param {number} tabId - The id of the tab which state will be changed. * @param {Object} state - The new state. * @returns {void} */ _onTabStateChange(tabId, state) { const tabStates = [ ...this.state.tabStates ]; tabStates[tabId] = state; this.setState({ tabStates }); } _onSubmit: () => void; /** * Submits the information filled in the dialog. * * @returns {void} */ _onSubmit() { const { onSubmit, tabs } = this.props; tabs.forEach(({ submit }, idx) => { submit && submit(this.state.tabStates[idx]); }); onSubmit(); } } export default translate(DialogWithTabs);