@ui5/webcomponents-react
Version:
React Wrapper for UI5 Web Components and additional components
259 lines (256 loc) • 10.1 kB
JavaScript
import BarDesign from '@ui5/webcomponents/dist/types/BarDesign.js';
import ButtonDesign from '@ui5/webcomponents/dist/types/ButtonDesign.js';
import TableOverflowMode from '@ui5/webcomponents/dist/types/TableOverflowMode.js';
import { isPhone as getIsPhone } from '@ui5/webcomponents-base/dist/Device.js';
import NoEntriesIllu from '@ui5/webcomponents-fiori/dist/illustrations/NoEntries.js';
import searchIcon from '@ui5/webcomponents-icons/dist/search.js';
import { enrichEventWithDetails, useI18nBundle, useStylesheet } from '@ui5/webcomponents-react-base';
import { Children, isValidElement, useEffect, useId, useRef, useState, createElement as _createElement } from 'react';
import { FlexBoxAlignItems } from '../../enums/FlexBoxAlignItems.js';
import { FlexBoxDirection } from '../../enums/FlexBoxDirection.js';
import { APPLY_AUTOMATICALLY, CANCEL, CREATED_BY, DEFAULT, NO_VIEWS_DEFINED_TITLE, NO_VIEWS_DEFINED_SUBTITLE, MANAGE_VIEWS, SAVE, SEARCH, SHARING, VIEW } from '../../i18n/i18n-defaults.js';
import { Bar } from '../../webComponents/Bar/index.js';
import { Button } from '../../webComponents/Button/index.js';
import { Dialog } from '../../webComponents/Dialog/index.js';
import { Icon } from '../../webComponents/Icon/index.js';
import { IllustratedMessage } from '../../webComponents/IllustratedMessage/index.js';
import { Input } from '../../webComponents/Input/index.js';
import { Table } from '../../webComponents/Table/index.js';
import { TableHeaderCell } from '../../webComponents/TableHeaderCell/index.js';
import { TableHeaderRow } from '../../webComponents/TableHeaderRow/index.js';
import { Title } from '../../webComponents/Title/index.js';
import { FlexBox } from '../FlexBox/index.js';
import { classNames, styleData } from './ManageViewsDialog.module.css.js';
import { ManageViewsTableRows } from './ManageViewsTableRows.js';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
const isPhone = getIsPhone();
export const ManageViewsDialog = props => {
const {
children,
onAfterClose,
handleSaveManageViews,
showShare,
showApplyAutomatically,
showSetAsDefault,
showCreatedBy,
variantNames,
showOnlyFavorites,
onManageViewsCancel
} = props;
const uniqueId = useId();
const i18nBundle = useI18nBundle('@ui5/webcomponents-react');
const tableRef = useRef(null);
const cancelBtnRef = useRef(null);
const cancelText = i18nBundle.getText(CANCEL);
const saveText = i18nBundle.getText(SAVE);
const viewHeaderText = i18nBundle.getText(VIEW);
const sharingHeaderText = i18nBundle.getText(SHARING);
const defaultHeaderText = i18nBundle.getText(DEFAULT);
const applyAutomaticallyHeaderText = i18nBundle.getText(APPLY_AUTOMATICALLY);
const createdByHeaderText = i18nBundle.getText(CREATED_BY);
const manageViewsText = i18nBundle.getText(MANAGE_VIEWS);
const searchText = i18nBundle.getText(SEARCH);
const [changedVariantNames, setChangedVariantNames] = useState(new Map());
const [invalidVariants, setInvalidVariants] = useState({});
const [hasApplyAutomaticallyText, setHasApplyAutomaticallyText] = useState(false);
useStylesheet(styleData, 'ManageViewsDialog');
const headerRow = /*#__PURE__*/_jsxs(TableHeaderRow, {
sticky: true,
children: [showOnlyFavorites && /*#__PURE__*/_jsx(TableHeaderCell, {}, "favorite-variant-item"), /*#__PURE__*/_jsx(TableHeaderCell, {
importance: 10,
minWidth: "14rem",
children: viewHeaderText
}), showShare && /*#__PURE__*/_jsx(TableHeaderCell, {
minWidth: "7.5rem",
width: "8rem",
children: sharingHeaderText
}), showSetAsDefault && /*#__PURE__*/_jsx(TableHeaderCell, {
minWidth: "8rem",
width: "8rem",
children: defaultHeaderText
}), showApplyAutomatically && /*#__PURE__*/_jsx(TableHeaderCell, {
minWidth: hasApplyAutomaticallyText ? '12.5rem' : '5rem',
children: applyAutomaticallyHeaderText
}), showCreatedBy && /*#__PURE__*/_jsx(TableHeaderCell, {
minWidth: "7.125rem",
children: createdByHeaderText
})]
});
const [childrenProps, setChildrenProps] = useState(Children.map(children, child => {
if (! /*#__PURE__*/isValidElement(child)) {
return {};
}
return child.props;
}));
// childrenProps syncs from children but also has independent mutations (delete)
/* eslint-disable react-hooks/set-state-in-effect */
useEffect(() => {
let _hasApplyAutomaticallyText = false;
setChildrenProps(Children.map(children, child => {
if (! /*#__PURE__*/isValidElement(child)) {
return {};
}
if (child.props?.applyAutomaticallyText) {
_hasApplyAutomaticallyText = true;
}
return child.props;
}));
setHasApplyAutomaticallyText(_hasApplyAutomaticallyText);
}, [children]);
/* eslint-enable react-hooks/set-state-in-effect */
const [filteredProps, setFilteredProps] = useState(childrenProps);
// Resets search filter when source data changes
/* eslint-disable react-hooks/set-state-in-effect */
useEffect(() => {
setFilteredProps(childrenProps);
}, [childrenProps]);
/* eslint-enable react-hooks/set-state-in-effect */
const [defaultView, setDefaultView] = useState();
const changedTableRows = useRef({});
const handleTableRowChange = (e, payload) => {
if (payload) {
changedTableRows.current[payload.currentVariant] = {
...(changedTableRows.current[payload.currentVariant] ?? {}),
...payload
};
}
};
const deletedTableRows = useRef(new Set([]));
const handleDelete = e => {
const {
nextElementSibling,
previousElementSibling,
dataset
} = e.detail.row;
const variantChild = dataset.id;
deletedTableRows.current.add(variantChild);
let nextFocusElement = null;
if (nextElementSibling?.hasAttribute('ui5-table-row')) {
nextFocusElement = nextElementSibling;
} else if (previousElementSibling?.hasAttribute('ui5-table-row')) {
nextFocusElement = previousElementSibling;
} else {
nextFocusElement = cancelBtnRef.current;
}
void nextFocusElement?.focus();
setChildrenProps(prev => prev.filter(item => item.children !== variantChild));
};
const handleSave = e => {
if (Object.keys(invalidVariants).length === 0) {
handleSaveManageViews(e, {
updatedRows: changedTableRows.current,
defaultView,
deletedRows: deletedTableRows.current
});
} else {
void Object.values(invalidVariants)[0].focus();
}
};
const handleClose = e => {
if (e.detail.escPressed) {
handleCancel(e);
} else {
onAfterClose(e);
}
};
const handleCancel = e => {
if (typeof onManageViewsCancel === 'function') {
onManageViewsCancel(enrichEventWithDetails(e, {
invalidVariants
}));
}
setInvalidVariants(prev => {
Object.values(prev).forEach(item => {
item.isInvalid = false;
});
return {};
});
onAfterClose(e);
};
const handleSearchInput = e => {
const lowerCaseVal = e.target.value.toLowerCase();
setFilteredProps(childrenProps.filter(item => item.children?.toLowerCase()?.includes(lowerCaseVal) || item.author?.toLowerCase()?.includes(lowerCaseVal)));
};
return /*#__PURE__*/_jsx(Dialog, {
open: true,
stretch: isPhone,
className: classNames.manageViewsDialog,
"data-component-name": "VariantManagementManageViewsDialog",
onClose: onAfterClose,
onBeforeClose: handleClose,
headerText: manageViewsText,
initialFocus: `search-${uniqueId}`,
header: /*#__PURE__*/_jsxs(FlexBox, {
direction: FlexBoxDirection.Column,
style: {
width: '100%'
},
alignItems: FlexBoxAlignItems.Center,
children: [/*#__PURE__*/_jsx("div", {
className: classNames.headerText,
children: /*#__PURE__*/_jsx(Title, {
wrappingType: "None",
level: "H1",
children: manageViewsText
})
}), /*#__PURE__*/_jsx(Input, {
id: `search-${uniqueId}`,
className: classNames.search,
placeholder: searchText,
showClearIcon: true,
icon: /*#__PURE__*/_jsx(Icon, {
name: searchIcon,
className: classNames.inputIcon
}),
onInput: handleSearchInput
})]
}),
resizable: true,
footer: /*#__PURE__*/_jsx(Bar, {
design: BarDesign.Footer,
endContent: /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsx(Button, {
design: ButtonDesign.Emphasized,
onClick: handleSave,
children: saveText
}), /*#__PURE__*/_jsx(Button, {
design: ButtonDesign.Transparent,
onClick: handleCancel,
ref: cancelBtnRef,
children: cancelText
})]
})
}),
children: /*#__PURE__*/_jsx(Table, {
ref: tableRef,
headerRow: headerRow,
overflowMode: TableOverflowMode.Popin,
rowActionCount: 1,
onRowActionClick: handleDelete,
noData: /*#__PURE__*/_jsx(IllustratedMessage, {
name: NoEntriesIllu,
design: 'Medium',
titleText: i18nBundle.getText(NO_VIEWS_DEFINED_TITLE),
subtitleText: i18nBundle.getText(NO_VIEWS_DEFINED_SUBTITLE)
}),
children: filteredProps.map(itemProps => {
return /*#__PURE__*/_createElement(ManageViewsTableRows, {
...itemProps,
setInvalidVariants: setInvalidVariants,
setChangedVariantNames: setChangedVariantNames,
changedVariantNames: changedVariantNames,
variantNames: variantNames,
handleRowChange: handleTableRowChange,
defaultView: defaultView,
setDefaultView: setDefaultView,
showShare: showShare,
showApplyAutomatically: showApplyAutomatically,
showSetAsDefault: showSetAsDefault,
showCreatedBy: showCreatedBy,
key: itemProps?.children,
showOnlyFavorites: showOnlyFavorites
});
})
})
});
};