webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js in katello-3.11.2 vs webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js in katello-3.12.0.rc1
- old
+ new
@@ -1,20 +1,13 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import classNames from 'classnames';
-import { sprintf } from 'foremanReact/common/I18n';
import { cloneDeep, findIndex, isEqual } from 'lodash';
-import { Table } from 'patternfly-react';
import { LoadingState } from '../../../../move_to_pf/LoadingState';
-import { Table as ForemanTable, TableBody as ForemanTableBody } from '../../../../move_to_foreman/components/common/table';
-import ConfirmDialog from '../../../../move_to_foreman/components/common/ConfirmDialog';
-import Dialog from '../../../../move_to_foreman/components/common/Dialog';
import { recordsValid } from '../../SubscriptionValidations';
-import { createSubscriptionsTableSchema } from './SubscriptionsTableSchema';
-import { buildTableRows, groupSubscriptionsByProductId, buildPools } from './SubscriptionsTableHelpers';
-import { renderTaskStartedToast } from '../../../Tasks/helpers';
-import { BLOCKING_FOREMAN_TASK_TYPES } from '../../SubscriptionConstants';
+import { buildTableRows, groupSubscriptionsByProductId } from './SubscriptionsTableHelpers';
+import Table from './components/Table';
+import Dialogs from './components/Dialogs';
class SubscriptionsTable extends Component {
constructor(props) {
super(props);
@@ -47,11 +40,170 @@
}
return null;
}
- toggleSubscriptionGroup(groupId) {
+ getInlineEditController = () => ({
+ isEditing: ({ rowData }) =>
+ (this.state.editing && rowData.available >= 0 && rowData.upstream_pool_id),
+ hasChanged: ({ rowData }) => {
+ const editedValue = this.state.updatedQuantity[rowData.id];
+ return this.hasQuantityChanged(rowData, editedValue);
+ },
+ onActivate: () => {
+ this.enableEditing(true);
+ },
+ onConfirm: () => {
+ if (recordsValid(this.state.rows)) {
+ this.showUpdateConfirm(true);
+ } else {
+ this.showErrorDialog(true);
+ }
+ },
+ onCancel: () => {
+ this.showCancelConfirm(true);
+ },
+ onChange: (value, { rowData }) => {
+ const updatedQuantity = cloneDeep(this.state.updatedQuantity);
+
+ if (this.hasQuantityChanged(rowData, value)) {
+ updatedQuantity[rowData.id] = value;
+ } else {
+ delete updatedQuantity[rowData.id];
+ }
+
+ this.updateRows(updatedQuantity);
+ },
+ });
+
+ getSelectionController = () => {
+ const allSubscriptionResults = this.props.subscriptions.results;
+
+ const checkAllRowsSelected = () =>
+ allSubscriptionResults.length === this.state.selectedRows.length;
+
+ const updateDeleteButton = () => {
+ this.props.toggleDeleteButton(this.state.selectedRows.length > 0);
+ };
+ return ({
+ allRowsSelected: () => checkAllRowsSelected(),
+ selectAllRows: () => {
+ if (checkAllRowsSelected()) {
+ this.setState(
+ { selectedRows: [] },
+ updateDeleteButton,
+ );
+ } else {
+ this.setState(
+ { selectedRows: allSubscriptionResults.map(row => row.id) },
+ updateDeleteButton,
+ );
+ }
+ },
+ selectRow: ({ rowData }) => {
+ let { selectedRows } = this.state;
+ if (selectedRows.includes(rowData.id)) {
+ selectedRows = selectedRows.filter(e => e !== rowData.id);
+ } else {
+ selectedRows.push(rowData.id);
+ }
+
+ this.setState(
+ { selectedRows },
+ updateDeleteButton,
+ );
+ },
+ isSelected: ({ rowData }) => this.state.selectedRows.includes(rowData.id),
+ });
+ };
+
+ getTableProps = () => {
+ const {
+ subscriptions, emptyState, tableColumns, loadSubscriptions,
+ } = this.props;
+ const { groupedSubscriptions, rows, editing } = this.state;
+
+ return {
+ emptyState,
+ editing,
+ groupedSubscriptions,
+ loadSubscriptions,
+ rows,
+ subscriptions,
+ tableColumns,
+ inlineEditController: this.getInlineEditController(),
+ selectionController: this.getSelectionController(),
+ };
+ };
+
+ getUpdateDialogProps = () => {
+ const { showUpdateConfirmDialog: show, updatedQuantity } = this.state;
+ const {
+ updateQuantity, bulkSearch, organization, task,
+ } = this.props;
+ return {
+ bulkSearch,
+ organization,
+ show,
+ task,
+ updatedQuantity,
+ updateQuantity,
+ confirmEdit: this.confirmEdit,
+ enableEditing: this.enableEditing,
+ showUpdateConfirm: this.showUpdateConfirm,
+ };
+ };
+
+ getUnsavedChangesDialogProps = () => {
+ const { showCancelConfirmDialog: show } = this.state;
+ return {
+ show,
+ cancelEdit: this.cancelEdit,
+ showCancelConfirm: this.showCancelConfirm,
+ };
+ };
+
+ getInputsErrorsDialogProps = () => {
+ const { showErrorDialog: show } = this.state;
+ return {
+ show,
+ showErrorDialog: this.showErrorDialog,
+ };
+ };
+
+ getDeleteDialogProps = () => {
+ const {
+ subscriptionDeleteModalOpen: show,
+ onDeleteSubscriptions,
+ onSubscriptionDeleteModalClose,
+ } = this.props;
+ const { selectedRows } = this.state;
+ return {
+ show,
+ selectedRows,
+ onSubscriptionDeleteModalClose,
+ onDeleteSubscriptions,
+ };
+ };
+
+ getLoadingStateProps = () => {
+ const { subscriptions: { loading } } = this.props;
+ return {
+ loading,
+ loadingText: __('Loading'),
+ };
+ };
+
+ getDialogsProps = () => ({
+ updateDialog: this.getUpdateDialogProps(),
+ unsavedChangesDialog: this.getUnsavedChangesDialogProps(),
+ inputsErrorsDialog: this.getInputsErrorsDialogProps(),
+ deleteDialog: this.getDeleteDialogProps(),
+ });
+
+
+ toggleSubscriptionGroup = (groupId) => {
const { subscriptions } = this.props;
const { groupedSubscriptions, updatedQuantity } = this.state;
const { open } = groupedSubscriptions[groupId];
groupedSubscriptions[groupId].open = !open;
@@ -62,267 +214,70 @@
subscriptions.availableQuantities,
updatedQuantity,
);
this.setState({ rows, groupedSubscriptions });
- }
+ };
- enableEditing(editingState) {
+ enableEditing = (editingState) => {
this.setState({
updatedQuantity: {},
editing: editingState,
});
- }
+ };
- updateRows(updatedQuantity) {
+ updateRows = (updatedQuantity) => {
const { groupedSubscriptions } = this.state;
const { subscriptions } = this.props;
const rows = buildTableRows(
groupedSubscriptions,
subscriptions.availableQuantities,
updatedQuantity,
);
this.setState({ rows, updatedQuantity });
- }
+ };
- showUpdateConfirm(show) {
+ showUpdateConfirm = (show) => {
this.setState({
showUpdateConfirmDialog: show,
});
- }
+ };
- showCancelConfirm(show) {
+ showCancelConfirm = (show) => {
this.setState({
showCancelConfirmDialog: show,
});
- }
+ };
- showErrorDialog(show) {
+ showErrorDialog = (show) => {
this.setState({
showErrorDialog: show,
});
- }
+ };
- confirmEdit() {
- this.showUpdateConfirm(false);
- if (Object.keys(this.state.updatedQuantity).length > 0) {
- this.props.updateQuantity(buildPools(this.state.updatedQuantity))
- .then(() =>
- this.props.bulkSearch({
- action: `organization '${this.props.organization.owner_details.displayName}'`,
- result: 'pending',
- label: BLOCKING_FOREMAN_TASK_TYPES.join(' or '),
- }))
- .then(() => renderTaskStartedToast(this.props.task));
- }
- this.enableEditing(false);
- }
-
- cancelEdit() {
+ cancelEdit = () => {
this.showCancelConfirm(false);
this.enableEditing(false);
this.updateRows({});
- }
+ };
- hasQuantityChanged(rowData, editedValue) {
+ hasQuantityChanged = (rowData, editedValue) => {
if (editedValue !== undefined) {
const originalRows = this.props.subscriptions.results;
const index = findIndex(originalRows, row => (row.id === rowData.id));
const currentValue = originalRows[index].quantity;
return (`${editedValue}` !== `${currentValue}`);
}
return false;
- }
+ };
render() {
- const { subscriptions, emptyState, tableColumns } = this.props;
- const { groupedSubscriptions } = this.state;
- const allSubscriptionResults = subscriptions.results;
-
- const groupingController = {
- isCollapseable: ({ rowData }) =>
- // it is the first subscription in the group
- rowData.id === groupedSubscriptions[rowData.product_id].subscriptions[0].id &&
- // the group contains more then one subscription
- groupedSubscriptions[rowData.product_id].subscriptions.length > 1,
- isCollapsed: ({ rowData }) => !groupedSubscriptions[rowData.product_id].open,
- toggle: ({ rowData }) => this.toggleSubscriptionGroup(rowData.product_id),
- };
-
- const inlineEditController = {
- isEditing: ({ rowData }) =>
- (this.state.editing && rowData.available >= 0 && rowData.upstream_pool_id),
- hasChanged: ({ rowData }) => {
- const editedValue = this.state.updatedQuantity[rowData.id];
- return this.hasQuantityChanged(rowData, editedValue);
- },
- onActivate: () => {
- this.enableEditing(true);
- },
- onConfirm: () => {
- if (recordsValid(this.state.rows)) {
- this.showUpdateConfirm(true);
- } else {
- this.showErrorDialog(true);
- }
- },
- onCancel: () => {
- this.showCancelConfirm(true);
- },
- onChange: (value, { rowData }) => {
- const updatedQuantity = cloneDeep(this.state.updatedQuantity);
-
- if (this.hasQuantityChanged(rowData, value)) {
- updatedQuantity[rowData.id] = value;
- } else {
- delete updatedQuantity[rowData.id];
- }
-
- this.updateRows(updatedQuantity);
- },
- };
-
- const checkAllRowsSelected = () =>
- allSubscriptionResults.length === this.state.selectedRows.length;
-
- const updateDeleteButton = () => {
- this.props.toggleDeleteButton(this.state.selectedRows.length > 0);
- };
-
- const selectionController = {
- allRowsSelected: () => checkAllRowsSelected(),
- selectAllRows: () => {
- if (checkAllRowsSelected()) {
- this.setState(
- { selectedRows: [] },
- updateDeleteButton,
- );
- } else {
- this.setState(
- { selectedRows: allSubscriptionResults.map(row => row.id) },
- updateDeleteButton,
- );
- }
- },
- selectRow: ({ rowData }) => {
- let { selectedRows } = this.state;
- if (selectedRows.includes(rowData.id)) {
- selectedRows = selectedRows.filter(e => e !== rowData.id);
- } else {
- selectedRows.push(rowData.id);
- }
-
- this.setState(
- { selectedRows },
- updateDeleteButton,
- );
- },
- isSelected: ({ rowData }) => this.state.selectedRows.includes(rowData.id),
- };
-
- const onPaginationChange = (pagination) => {
- this.props.loadSubscriptions({
- ...pagination,
- });
- };
-
- let bodyMessage;
- if (allSubscriptionResults.length === 0 && subscriptions.searchIsActive) {
- bodyMessage = __('No subscriptions match your search criteria.');
- }
-
- const alwaysDisplayColumns = ['select'];
- const columnsDefinition = createSubscriptionsTableSchema(
- inlineEditController,
- selectionController,
- groupingController,
- ).filter(column => tableColumns.includes(column.property) ||
- alwaysDisplayColumns.includes(column.property));
-
return (
- <LoadingState loading={subscriptions.loading} loadingText={__('Loading')}>
- <ForemanTable
- columns={columnsDefinition}
- emptyState={emptyState}
- bodyMessage={bodyMessage}
- rows={this.state.rows}
- components={{
- header: {
- row: Table.TableInlineEditHeaderRow,
- },
- }}
- itemCount={subscriptions.itemCount}
- pagination={subscriptions.pagination}
- onPaginationChange={onPaginationChange}
- inlineEdit
- >
- <Table.Header
- onRow={() => ({
- role: 'row',
- isEditing: () => this.state.editing,
- onCancel: () => inlineEditController.onCancel(),
- onConfirm: () => inlineEditController.onConfirm(),
- })}
- />
- <ForemanTableBody
- columns={columnsDefinition}
- rows={this.state.rows}
- rowKey="id"
- message={bodyMessage}
- onRow={rowData => ({
- className: classNames({ 'open-grouped-row': !groupingController.isCollapsed({ rowData }) }),
- })}
- />
- </ForemanTable>
- <ConfirmDialog
- show={this.state.showUpdateConfirmDialog}
- title={__('Editing Entitlements')}
- dangerouslySetInnerHTML={{
- __html: sprintf(
- __("You're making changes to %(entitlementCount)s entitlement(s)"),
- {
- entitlementCount: `<b>${Object.keys(this.state.updatedQuantity).length}</b>`,
- },
- ),
- }}
- onConfirm={() => this.confirmEdit()}
- onCancel={() => this.showUpdateConfirm(false)}
- />
- <ConfirmDialog
- show={this.state.showCancelConfirmDialog}
- title={__('Editing Entitlements')}
- message={__('You have unsaved changes. Do you want to exit without saving your changes?')}
- confirmLabel={__('Exit')}
- onConfirm={() => this.cancelEdit()}
- onCancel={() => this.showCancelConfirm(false)}
- />
- <Dialog
- show={this.state.showErrorDialog}
- title={__('Editing Entitlements')}
- message={__('Some of your inputs contain errors. Please update them and save your changes again.')}
- onCancel={() => this.showErrorDialog(false)}
- />
- <ConfirmDialog
- show={this.props.subscriptionDeleteModalOpen}
- title={__('Confirm Deletion')}
- dangerouslySetInnerHTML={{
- __html: sprintf(
- __(`Are you sure you want to delete %(entitlementCount)s
- subscription(s)? This action will remove the subscription(s) and
- refresh your manifest. All systems using these subscription(s) will
- lose them and also may lose access to updates and Errata.`),
- {
- entitlementCount: `<b>${this.state.selectedRows.length}</b>`,
- },
- ),
- }}
-
- confirmLabel={__('Delete')}
- onConfirm={() => this.props.onDeleteSubscriptions(this.state.selectedRows)}
- onCancel={this.props.onSubscriptionDeleteModalClose}
- />
+ <LoadingState {...this.getLoadingStateProps()}>
+ <Table {...this.getTableProps()} />
+ <Dialogs {...this.getDialogsProps()} />
</LoadingState>
);
}
}