@sap-ux/ui-components 1.13.5 → 1.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Icons.d.ts +150 -150
- package/dist/components/Icons.js +628 -628
- package/dist/components/UIActionCallout/UIActionCallout.d.ts +64 -64
- package/dist/components/UIActionCallout/UIActionCallout.js +67 -67
- package/dist/components/UIActionCallout/index.d.ts +1 -1
- package/dist/components/UIActionCallout/index.js +17 -17
- package/dist/components/UIBreadcrumb/UIBreadcrumb.d.ts +23 -23
- package/dist/components/UIBreadcrumb/UIBreadcrumb.js +38 -38
- package/dist/components/UIBreadcrumb/index.d.ts +1 -1
- package/dist/components/UIBreadcrumb/index.js +17 -17
- package/dist/components/UIButton/UIActionButton.d.ts +23 -23
- package/dist/components/UIButton/UIActionButton.js +89 -89
- package/dist/components/UIButton/UIDefaultButton.d.ts +41 -23
- package/dist/components/UIButton/UIDefaultButton.d.ts.map +1 -1
- package/dist/components/UIButton/UIDefaultButton.js +255 -237
- package/dist/components/UIButton/UIDefaultButton.js.map +1 -1
- package/dist/components/UIButton/UIIconButton.d.ts +37 -37
- package/dist/components/UIButton/UIIconButton.js +106 -106
- package/dist/components/UIButton/UISmallButton.d.ts +34 -34
- package/dist/components/UIButton/UISmallButton.js +115 -115
- package/dist/components/UIButton/UISplitButton.d.ts +44 -44
- package/dist/components/UIButton/UISplitButton.js +86 -86
- package/dist/components/UIButton/index.d.ts +7 -7
- package/dist/components/UIButton/index.js +21 -21
- package/dist/components/UICallout/CalloutCollisionTransform.d.ts +54 -54
- package/dist/components/UICallout/CalloutCollisionTransform.js +160 -160
- package/dist/components/UICallout/UICallout.d.ts +48 -48
- package/dist/components/UICallout/UICallout.js +122 -122
- package/dist/components/UICallout/index.d.ts +2 -2
- package/dist/components/UICallout/index.js +18 -18
- package/dist/components/UICheckbox/UICheckbox.d.ts +34 -34
- package/dist/components/UICheckbox/UICheckbox.js +135 -135
- package/dist/components/UICheckbox/index.d.ts +1 -1
- package/dist/components/UICheckbox/index.js +17 -17
- package/dist/components/UIChoiceGroup/UIChoiceGroup.d.ts +28 -28
- package/dist/components/UIChoiceGroup/UIChoiceGroup.js +182 -182
- package/dist/components/UIChoiceGroup/index.d.ts +1 -1
- package/dist/components/UIChoiceGroup/index.js +17 -17
- package/dist/components/UIComboBox/UIComboBox.d.ts +208 -200
- package/dist/components/UIComboBox/UIComboBox.d.ts.map +1 -1
- package/dist/components/UIComboBox/UIComboBox.js +563 -541
- package/dist/components/UIComboBox/UIComboBox.js.map +1 -1
- package/dist/components/UIComboBox/index.d.ts +1 -1
- package/dist/components/UIComboBox/index.js +17 -17
- package/dist/components/UIContextualMenu/UIContextualMenu.d.ts +31 -31
- package/dist/components/UIContextualMenu/UIContextualMenu.js +126 -126
- package/dist/components/UIContextualMenu/UIHighlightMenuOption.d.ts +19 -19
- package/dist/components/UIContextualMenu/UIHighlightMenuOption.js +50 -50
- package/dist/components/UIContextualMenu/index.d.ts +2 -2
- package/dist/components/UIContextualMenu/index.js +18 -18
- package/dist/components/UICreateSelect/UICreateSelect.d.ts +36 -36
- package/dist/components/UICreateSelect/UICreateSelect.js +172 -172
- package/dist/components/UICreateSelect/index.d.ts +1 -1
- package/dist/components/UICreateSelect/index.js +17 -17
- package/dist/components/UIDatePicker/UIDatePicker.d.ts +49 -49
- package/dist/components/UIDatePicker/UIDatePicker.js +72 -72
- package/dist/components/UIDatePicker/index.d.ts +1 -1
- package/dist/components/UIDatePicker/index.js +17 -17
- package/dist/components/UIDialog/UIDialog.d.ts +118 -118
- package/dist/components/UIDialog/UIDialog.js +281 -281
- package/dist/components/UIDialog/index.d.ts +1 -1
- package/dist/components/UIDialog/index.js +17 -17
- package/dist/components/UIDropdown/UIDropdown.d.ts +94 -94
- package/dist/components/UIDropdown/UIDropdown.js +224 -224
- package/dist/components/UIDropdown/index.d.ts +2 -2
- package/dist/components/UIDropdown/index.js +18 -18
- package/dist/components/UIDropdown/utils.d.ts +20 -20
- package/dist/components/UIDropdown/utils.js +43 -43
- package/dist/components/UIFlexibleTable/RowActions.d.ts +16 -16
- package/dist/components/UIFlexibleTable/RowActions.js +73 -73
- package/dist/components/UIFlexibleTable/RowData.d.ts +16 -16
- package/dist/components/UIFlexibleTable/RowData.js +111 -111
- package/dist/components/UIFlexibleTable/UIFlexibleTable.d.ts +11 -11
- package/dist/components/UIFlexibleTable/UIFlexibleTable.js +280 -280
- package/dist/components/UIFlexibleTable/UIFlexibleTableActionButton.d.ts +20 -20
- package/dist/components/UIFlexibleTable/UIFlexibleTableActionButton.js +20 -20
- package/dist/components/UIFlexibleTable/UIFlexibleTableRow.d.ts +26 -26
- package/dist/components/UIFlexibleTable/UIFlexibleTableRow.js +219 -219
- package/dist/components/UIFlexibleTable/UIFlexibleTableRowActionButton.d.ts +20 -20
- package/dist/components/UIFlexibleTable/UIFlexibleTableRowActionButton.js +19 -19
- package/dist/components/UIFlexibleTable/UIFlexibleTableRowNoData.d.ts +15 -15
- package/dist/components/UIFlexibleTable/UIFlexibleTableRowNoData.js +28 -28
- package/dist/components/UIFlexibleTable/index.d.ts +5 -5
- package/dist/components/UIFlexibleTable/index.js +21 -21
- package/dist/components/UIFlexibleTable/types.d.ts +143 -143
- package/dist/components/UIFlexibleTable/types.js +14 -14
- package/dist/components/UIFlexibleTable/utils.d.ts +25 -25
- package/dist/components/UIFlexibleTable/utils.js +49 -49
- package/dist/components/UIFocusZone/UIFocusTrapZone.d.ts +22 -22
- package/dist/components/UIFocusZone/UIFocusTrapZone.js +33 -33
- package/dist/components/UIFocusZone/UIFocusZone.d.ts +23 -23
- package/dist/components/UIFocusZone/UIFocusZone.js +35 -35
- package/dist/components/UIFocusZone/index.d.ts +2 -2
- package/dist/components/UIFocusZone/index.js +18 -18
- package/dist/components/UIIcon/UIIcon.d.ts +24 -24
- package/dist/components/UIIcon/UIIcon.js +37 -37
- package/dist/components/UIIcon/index.d.ts +1 -1
- package/dist/components/UIIcon/index.js +17 -17
- package/dist/components/UIInput/UITextInput.d.ts +51 -51
- package/dist/components/UIInput/UITextInput.js +244 -244
- package/dist/components/UIInput/index.d.ts +1 -1
- package/dist/components/UIInput/index.js +17 -17
- package/dist/components/UILabel/UILabel.d.ts +30 -30
- package/dist/components/UILabel/UILabel.js +64 -64
- package/dist/components/UILabel/index.d.ts +1 -1
- package/dist/components/UILabel/index.js +17 -17
- package/dist/components/UILink/UILink.d.ts +25 -25
- package/dist/components/UILink/UILink.js +71 -71
- package/dist/components/UILink/index.d.ts +1 -1
- package/dist/components/UILink/index.js +17 -17
- package/dist/components/UIList/UIList.d.ts +31 -31
- package/dist/components/UIList/UIList.js +120 -120
- package/dist/components/UIList/index.d.ts +1 -1
- package/dist/components/UIList/index.js +17 -17
- package/dist/components/UILoader/UILoader.d.ts +27 -27
- package/dist/components/UILoader/UILoader.js +78 -78
- package/dist/components/UILoader/index.d.ts +1 -1
- package/dist/components/UILoader/index.js +17 -17
- package/dist/components/UIMessageBar/UIMessageBar.d.ts +25 -25
- package/dist/components/UIMessageBar/UIMessageBar.js +56 -56
- package/dist/components/UIMessageBar/index.d.ts +1 -1
- package/dist/components/UIMessageBar/index.js +17 -17
- package/dist/components/UIModal/UIModal.d.ts +23 -23
- package/dist/components/UIModal/UIModal.js +43 -43
- package/dist/components/UIModal/index.d.ts +1 -1
- package/dist/components/UIModal/index.js +17 -17
- package/dist/components/UIOverlay/UIOverlay.d.ts +22 -22
- package/dist/components/UIOverlay/UIOverlay.js +38 -38
- package/dist/components/UIOverlay/index.d.ts +1 -1
- package/dist/components/UIOverlay/index.js +17 -17
- package/dist/components/UIPersona/UIPersona.d.ts +27 -27
- package/dist/components/UIPersona/UIPersona.js +48 -48
- package/dist/components/UIPersona/index.d.ts +1 -1
- package/dist/components/UIPersona/index.js +17 -17
- package/dist/components/UISearchBox/UISearchBox.d.ts +22 -22
- package/dist/components/UISearchBox/UISearchBox.js +155 -155
- package/dist/components/UISearchBox/index.d.ts +3 -3
- package/dist/components/UISearchBox/index.js +17 -17
- package/dist/components/UISection/UISection.d.ts +34 -34
- package/dist/components/UISection/UISection.js +44 -44
- package/dist/components/UISection/UISections.d.ts +249 -249
- package/dist/components/UISection/UISections.js +707 -707
- package/dist/components/UISection/UISplitter.d.ts +96 -96
- package/dist/components/UISection/UISplitter.js +220 -220
- package/dist/components/UISection/index.d.ts +3 -3
- package/dist/components/UISection/index.js +19 -19
- package/dist/components/UISeparator/UISeparator.d.ts +25 -25
- package/dist/components/UISeparator/UISeparator.js +65 -65
- package/dist/components/UISeparator/index.d.ts +1 -1
- package/dist/components/UISeparator/index.js +17 -17
- package/dist/components/UITable/UITable-helper.d.ts +88 -88
- package/dist/components/UITable/UITable-helper.js +263 -263
- package/dist/components/UITable/UITable.d.ts +213 -213
- package/dist/components/UITable/UITable.js +779 -779
- package/dist/components/UITable/index.d.ts +2 -2
- package/dist/components/UITable/index.js +18 -18
- package/dist/components/UITable/types.d.ts +77 -77
- package/dist/components/UITable/types.js +28 -28
- package/dist/components/UITabs/UITabs.d.ts +28 -28
- package/dist/components/UITabs/UITabs.js +70 -70
- package/dist/components/UITabs/index.d.ts +1 -1
- package/dist/components/UITabs/index.js +17 -17
- package/dist/components/UIToggle/UIToggle.d.ts +39 -39
- package/dist/components/UIToggle/UIToggle.js +181 -181
- package/dist/components/UIToggle/index.d.ts +1 -1
- package/dist/components/UIToggle/index.js +17 -17
- package/dist/components/UIToggleGroup/UIToggleGroup.d.ts +31 -31
- package/dist/components/UIToggleGroup/UIToggleGroup.js +139 -139
- package/dist/components/UIToggleGroup/UIToggleGroup.types.d.ts +22 -22
- package/dist/components/UIToggleGroup/UIToggleGroup.types.js +2 -2
- package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.d.ts +25 -25
- package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.js +77 -77
- package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.types.d.ts +10 -10
- package/dist/components/UIToggleGroup/UIToggleGroupOption/UIToggleGroupOption.types.js +2 -2
- package/dist/components/UIToggleGroup/UIToggleGroupOption/index.d.ts +2 -2
- package/dist/components/UIToggleGroup/UIToggleGroupOption/index.js +18 -18
- package/dist/components/UIToggleGroup/index.d.ts +2 -2
- package/dist/components/UIToggleGroup/index.js +18 -18
- package/dist/components/UIToolbar/UIToolbar.d.ts +36 -36
- package/dist/components/UIToolbar/UIToolbar.js +104 -104
- package/dist/components/UIToolbar/UIToolbarColumn.d.ts +7 -7
- package/dist/components/UIToolbar/UIToolbarColumn.js +33 -33
- package/dist/components/UIToolbar/UIToolbarDivider.d.ts +27 -27
- package/dist/components/UIToolbar/UIToolbarDivider.js +52 -52
- package/dist/components/UIToolbar/index.d.ts +3 -3
- package/dist/components/UIToolbar/index.js +19 -19
- package/dist/components/UITooltip/UITooltip.d.ts +29 -29
- package/dist/components/UITooltip/UITooltip.js +77 -77
- package/dist/components/UITooltip/UITooltipUtils.d.ts +17 -17
- package/dist/components/UITooltip/UITooltipUtils.js +45 -45
- package/dist/components/UITooltip/index.d.ts +2 -2
- package/dist/components/UITooltip/index.js +18 -18
- package/dist/components/UITranslationInput/UIFormattedText.d.ts +46 -46
- package/dist/components/UITranslationInput/UIFormattedText.js +121 -121
- package/dist/components/UITranslationInput/UILoadButton.d.ts +52 -52
- package/dist/components/UITranslationInput/UILoadButton.js +109 -109
- package/dist/components/UITranslationInput/UITranslationButton.d.ts +14 -14
- package/dist/components/UITranslationInput/UITranslationButton.js +88 -88
- package/dist/components/UITranslationInput/UITranslationButton.types.d.ts +67 -67
- package/dist/components/UITranslationInput/UITranslationButton.types.js +21 -21
- package/dist/components/UITranslationInput/UITranslationInput.d.ts +25 -25
- package/dist/components/UITranslationInput/UITranslationInput.js +169 -169
- package/dist/components/UITranslationInput/UITranslationUtils.d.ts +64 -64
- package/dist/components/UITranslationInput/UITranslationUtils.js +168 -168
- package/dist/components/UITranslationInput/defaults.d.ts +2 -2
- package/dist/components/UITranslationInput/defaults.js +15 -15
- package/dist/components/UITranslationInput/index.d.ts +2 -2
- package/dist/components/UITranslationInput/index.js +18 -18
- package/dist/components/UITreeDropdown/UITreeDropdown.d.ts +265 -265
- package/dist/components/UITreeDropdown/UITreeDropdown.js +660 -660
- package/dist/components/UITreeDropdown/index.d.ts +1 -1
- package/dist/components/UITreeDropdown/index.js +17 -17
- package/dist/components/UIVerticalDivider/UIVerticalDivider.d.ts +23 -23
- package/dist/components/UIVerticalDivider/UIVerticalDivider.js +41 -41
- package/dist/components/UIVerticalDivider/index.d.ts +1 -1
- package/dist/components/UIVerticalDivider/index.js +17 -17
- package/dist/components/UIVirtualList/UIAutoSizer.d.ts +22 -22
- package/dist/components/UIVirtualList/UIAutoSizer.js +33 -33
- package/dist/components/UIVirtualList/UICellMeasurer.d.ts +23 -23
- package/dist/components/UIVirtualList/UICellMeasurer.js +33 -33
- package/dist/components/UIVirtualList/UIVirtualList.d.ts +43 -43
- package/dist/components/UIVirtualList/UIVirtualList.js +70 -70
- package/dist/components/UIVirtualList/index.d.ts +3 -3
- package/dist/components/UIVirtualList/index.js +19 -19
- package/dist/components/index.d.ts +38 -38
- package/dist/components/index.js +54 -54
- package/dist/helper/ValidationMessage/MessageWrapper.d.ts +17 -17
- package/dist/helper/ValidationMessage/MessageWrapper.js +34 -34
- package/dist/helper/ValidationMessage/index.d.ts +2 -2
- package/dist/helper/ValidationMessage/index.js +18 -18
- package/dist/helper/ValidationMessage/utils.d.ts +31 -31
- package/dist/helper/ValidationMessage/utils.js +121 -121
- package/dist/index.d.ts +2 -2
- package/dist/index.js +18 -18
- package/dist/utilities/DeepMerge.d.ts +10 -10
- package/dist/utilities/DeepMerge.js +48 -48
- package/dist/utilities/Dom.d.ts +14 -7
- package/dist/utilities/Dom.d.ts.map +1 -1
- package/dist/utilities/Dom.js +23 -13
- package/dist/utilities/Dom.js.map +1 -1
- package/dist/utilities/Focus.d.ts +14 -14
- package/dist/utilities/Focus.js +34 -34
- package/dist/utilities/Id.d.ts +2 -2
- package/dist/utilities/Id.js +5 -5
- package/dist/utilities/Keys.d.ts +2 -2
- package/dist/utilities/Keys.js +5 -5
- package/dist/utilities/index.d.ts +4 -4
- package/dist/utilities/index.js +20 -20
- package/package.json +1 -1
- package/storybook/494.d8aaa4d7.iframe.bundle.js +1 -0
- package/storybook/580.057c85e9.iframe.bundle.js +1 -0
- package/storybook/{930.1b3c5615.iframe.bundle.js → 930.3177b0dc.iframe.bundle.js} +2 -2
- package/storybook/UIActionCallout-story.9ee56c83.iframe.bundle.js +2 -0
- package/storybook/UIToggleGroup-story.573848ba.iframe.bundle.js +2 -0
- package/storybook/iframe.html +3 -3
- package/storybook/main.5f68bcca.iframe.bundle.js +1 -0
- package/storybook/project.json +1 -1
- package/storybook/{runtime~main.7c93d414.iframe.bundle.js → runtime~main.a213c0ae.iframe.bundle.js} +1 -1
- package/storybook/494.1829058d.iframe.bundle.js +0 -1
- package/storybook/580.c5ddde6e.iframe.bundle.js +0 -1
- package/storybook/UIActionCallout-story.13bdf055.iframe.bundle.js +0 -2
- package/storybook/UIToggleGroup-story.6f3e7d06.iframe.bundle.js +0 -2
- package/storybook/main.4ed99289.iframe.bundle.js +0 -1
|
@@ -1,780 +1,780 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.UITable = void 0;
|
|
7
|
-
const react_1 = __importDefault(require("react"));
|
|
8
|
-
const react_2 = require("@fluentui/react");
|
|
9
|
-
const UICheckbox_1 = require("../UICheckbox");
|
|
10
|
-
const UIInput_1 = require("../UIInput");
|
|
11
|
-
const UIDropdown_1 = require("../UIDropdown");
|
|
12
|
-
const UIComboBox_1 = require("../UIComboBox");
|
|
13
|
-
const UIDatePicker_1 = require("../UIDatePicker");
|
|
14
|
-
const UITable_helper_1 = require("./UITable-helper");
|
|
15
|
-
const types_1 = require("./types");
|
|
16
|
-
require("./UITable.scss");
|
|
17
|
-
/**
|
|
18
|
-
* UITable component
|
|
19
|
-
* based on: https://developer.microsoft.com/en-us/fluentui#/controls/web/detailslist
|
|
20
|
-
*
|
|
21
|
-
* @exports
|
|
22
|
-
* @class {UITable}
|
|
23
|
-
* @extends {React.Component<UITableProps, UITableState>}
|
|
24
|
-
*/
|
|
25
|
-
class UITable extends react_1.default.Component {
|
|
26
|
-
/**
|
|
27
|
-
* Initializes component properties.
|
|
28
|
-
*
|
|
29
|
-
* @param props
|
|
30
|
-
*/
|
|
31
|
-
constructor(props) {
|
|
32
|
-
super(props);
|
|
33
|
-
this.inputRefs = {};
|
|
34
|
-
this.activeElement = {};
|
|
35
|
-
this.caretPosition = -1;
|
|
36
|
-
this._onRenderRow = (props) => {
|
|
37
|
-
if (!props) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
const toggle = !!this.props.renderInputs;
|
|
41
|
-
return react_1.default.createElement(react_2.DetailsRow, { "data-selection-toggle": toggle, rowFieldsAs: this.renderRowFields.bind(this), ...props });
|
|
42
|
-
};
|
|
43
|
-
this.onComboBoxChange = (option) => {
|
|
44
|
-
this.setState((prevState) => {
|
|
45
|
-
const editedCell = prevState.editedCell ?? this.activeElement;
|
|
46
|
-
if (editedCell && option) {
|
|
47
|
-
editedCell.newValue = option.text;
|
|
48
|
-
}
|
|
49
|
-
return { editedCell };
|
|
50
|
-
});
|
|
51
|
-
};
|
|
52
|
-
this.onDropdownCellValueChange = (selectedOption, item, rowIndex, column) => {
|
|
53
|
-
const newValue = selectedOption.key;
|
|
54
|
-
if (typeof this.props.onSave === 'function' &&
|
|
55
|
-
typeof rowIndex === 'number' &&
|
|
56
|
-
Number.isInteger(rowIndex) &&
|
|
57
|
-
column) {
|
|
58
|
-
const currentValue = this.props.items[rowIndex][column.key];
|
|
59
|
-
const editedCell = { rowIndex, item, column, errorMessage: undefined };
|
|
60
|
-
if (currentValue !== newValue) {
|
|
61
|
-
this.props.onSave(editedCell, newValue);
|
|
62
|
-
}
|
|
63
|
-
const field = column?.fieldName;
|
|
64
|
-
if (field && item) {
|
|
65
|
-
item[field] = newValue;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
this.cancelEdit();
|
|
69
|
-
};
|
|
70
|
-
this.state = {
|
|
71
|
-
columns: props.columns || [],
|
|
72
|
-
items: props.items || []
|
|
73
|
-
};
|
|
74
|
-
this.tableRef = react_1.default.createRef();
|
|
75
|
-
this.selection = new react_2.Selection({
|
|
76
|
-
onSelectionChanged: () => {
|
|
77
|
-
if (typeof this.props.onSelectionChange !== 'function') {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
this.props.onSelectionChange(this.selection.getSelectedIndices());
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
if (this.props.selectionRef) {
|
|
84
|
-
this.props.selectionRef.current = this.selection;
|
|
85
|
-
}
|
|
86
|
-
this.onTextInputChange = this.onTextInputChange.bind(this);
|
|
87
|
-
this.onComboBoxChange = this.onComboBoxChange.bind(this);
|
|
88
|
-
this.onDocumentMousedown = this.onDocumentMousedown.bind(this);
|
|
89
|
-
this.onKeyDown = this.onKeyDown.bind(this);
|
|
90
|
-
this.onComboBoxKeyDownCapture = this.onComboBoxKeyDownCapture.bind(this);
|
|
91
|
-
this.validateCell = this.validateCell.bind(this);
|
|
92
|
-
this.editNextCell = this.editNextCell.bind(this);
|
|
93
|
-
this._onColumnClick = this._onColumnClick.bind(this);
|
|
94
|
-
this._onCellRender = this._onCellRender.bind(this);
|
|
95
|
-
this._onRenderCheckbox = this._onRenderCheckbox.bind(this);
|
|
96
|
-
this._onRenderField = this._onRenderField?.bind(this);
|
|
97
|
-
this._onRenderRow = this._onRenderRow?.bind(this);
|
|
98
|
-
this._onRenderItemColumn = this._onRenderItemColumn?.bind(this);
|
|
99
|
-
this._onCellActivation = this._onCellActivation?.bind(this);
|
|
100
|
-
}
|
|
101
|
-
componentDidMount() {
|
|
102
|
-
this.onDocMousedown = this.onDocumentMousedown;
|
|
103
|
-
document.addEventListener('mousedown', this.onDocMousedown, true);
|
|
104
|
-
window.dispatchEvent(new Event('resize'));
|
|
105
|
-
this._setTextRefs();
|
|
106
|
-
}
|
|
107
|
-
componentWillUnmount() {
|
|
108
|
-
document.removeEventListener('mousedown', this.onDocMousedown);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* On component update.
|
|
112
|
-
*
|
|
113
|
-
* @param prevProps
|
|
114
|
-
* @param prevState
|
|
115
|
-
*/
|
|
116
|
-
componentDidUpdate(prevProps, prevState) {
|
|
117
|
-
const scrollContainer = document.querySelector('.ms-ScrollablePane--contentContainer');
|
|
118
|
-
if (scrollContainer) {
|
|
119
|
-
const left = scrollContainer.scrollLeft || 0;
|
|
120
|
-
requestAnimationFrame(() => (scrollContainer.scrollLeft = left));
|
|
121
|
-
}
|
|
122
|
-
if (prevProps.items !== this.props.items) {
|
|
123
|
-
this.setState({ items: this.props.items });
|
|
124
|
-
this._setTextRefs();
|
|
125
|
-
}
|
|
126
|
-
if (prevProps.columns !== this.props.columns) {
|
|
127
|
-
this.setState({ columns: this.props.columns });
|
|
128
|
-
}
|
|
129
|
-
if (prevProps.dataSetKey !== this.props.dataSetKey) {
|
|
130
|
-
this.setState({ editedCell: undefined });
|
|
131
|
-
}
|
|
132
|
-
if (typeof this.props.selectedRow !== 'undefined' && prevProps.selectedRow !== this.props.selectedRow) {
|
|
133
|
-
(0, UITable_helper_1.scrollToRow)(this.props.selectedRow, this.tableRef?.current);
|
|
134
|
-
}
|
|
135
|
-
if (this.props.scrollToAddedRow) {
|
|
136
|
-
const dataSetChanged = this.props.dataSetKey !== prevProps.dataSetKey;
|
|
137
|
-
const { items } = this.state;
|
|
138
|
-
const { items: prevItems } = prevState;
|
|
139
|
-
const itemsDelta = items.length - prevItems.length;
|
|
140
|
-
const shouldScrollToNewRow = !dataSetChanged && itemsDelta === 1;
|
|
141
|
-
if (shouldScrollToNewRow && this.tableRef && this.tableRef.current) {
|
|
142
|
-
const newRowIndex = items.length - 1;
|
|
143
|
-
this.tableRef.current.scrollToIndex(newRowIndex);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
const { selectedColumnId } = this.props;
|
|
147
|
-
const { selectedColumnId: prevSelectedColumnId } = prevProps;
|
|
148
|
-
// Due to table rendering using columns data from state, instead of props,
|
|
149
|
-
// to sync selected column change callback with rendered dataset change
|
|
150
|
-
// selected column id/key needs to be stored on a state level along with columns data
|
|
151
|
-
if (selectedColumnId !== prevSelectedColumnId) {
|
|
152
|
-
this.setState({ selectedColumnId });
|
|
153
|
-
}
|
|
154
|
-
const columnIsSelected = typeof this.state.selectedColumnId !== 'undefined';
|
|
155
|
-
const selectedColumnDidChange = prevState.selectedColumnId !== this.state.selectedColumnId;
|
|
156
|
-
if (columnIsSelected && selectedColumnDidChange) {
|
|
157
|
-
(0, UITable_helper_1.scrollToColumn)(this.state.selectedColumnId || '', this.state.columns, this.props.selectedRow || 0, this.props.showRowNumbers);
|
|
158
|
-
}
|
|
159
|
-
this._restoreCaretPosition();
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Restores the caret position. Caret position gets lost when validation finds issue in cell.
|
|
163
|
-
*/
|
|
164
|
-
_restoreCaretPosition() {
|
|
165
|
-
const editedCell = this.state.editedCell;
|
|
166
|
-
if (this.caretPosition !== -1 && typeof editedCell?.rowIndex === 'number' && editedCell.column?.key) {
|
|
167
|
-
const cell = (0, UITable_helper_1.getCellFromCoords)(editedCell.rowIndex, editedCell.column.key, this.props.columns, true);
|
|
168
|
-
const input = cell.querySelector('input');
|
|
169
|
-
if (input && input.selectionStart !== this.caretPosition) {
|
|
170
|
-
input.setSelectionRange(this.caretPosition, this.caretPosition);
|
|
171
|
-
this.caretPosition = -1;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
_setTextRefs() {
|
|
176
|
-
if (this.props.columns && this.props.items) {
|
|
177
|
-
for (const rowIndexTmp in this.props.items) {
|
|
178
|
-
for (const col of this.props.columns) {
|
|
179
|
-
if (col.editable === true && this.inputRefs) {
|
|
180
|
-
this.inputRefs[rowIndexTmp] = this.inputRefs[rowIndexTmp] || {};
|
|
181
|
-
this.inputRefs[rowIndexTmp][col.key] = react_1.default.createRef();
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* On render row fields event.
|
|
189
|
-
*
|
|
190
|
-
* @param props
|
|
191
|
-
* @returns {JSX.Element}
|
|
192
|
-
*/
|
|
193
|
-
renderRowFields(props) {
|
|
194
|
-
// disabled is set to false when selectionMode === undefined || selectionMode === SelectionMode.single
|
|
195
|
-
let disabled = false;
|
|
196
|
-
const selectionMode = this.props.selectionMode;
|
|
197
|
-
if (selectionMode === react_2.SelectionMode.multiple || selectionMode === react_2.SelectionMode.none) {
|
|
198
|
-
disabled = true;
|
|
199
|
-
}
|
|
200
|
-
return (react_1.default.createElement("div", { "data-selection-disabled": disabled },
|
|
201
|
-
react_1.default.createElement(react_2.DetailsRowFields, { ...props })));
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* On render field event.
|
|
205
|
-
*
|
|
206
|
-
* @param props
|
|
207
|
-
* @param defaultRender
|
|
208
|
-
* @returns {null | JSX.Element}
|
|
209
|
-
*/
|
|
210
|
-
_onRenderField(props, defaultRender) {
|
|
211
|
-
if (!props || !defaultRender) {
|
|
212
|
-
return null;
|
|
213
|
-
}
|
|
214
|
-
const cell = defaultRender(props);
|
|
215
|
-
const onClick = (e) => {
|
|
216
|
-
const target = e?.target;
|
|
217
|
-
const targetTag = target?.tagName;
|
|
218
|
-
if (['INPUT', 'TEXTAREA', 'SELECT'].includes(targetTag)) {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
const { item, rowIndex, column } = this.activeElement;
|
|
222
|
-
this._onCellClick(e, item, rowIndex || 0, column);
|
|
223
|
-
};
|
|
224
|
-
// in app-migrator, show a warning message for library projects on main migration view
|
|
225
|
-
if (props.item.hideCells && props.column.fieldName === 'moduleName' && !props.item.status) {
|
|
226
|
-
return (react_1.default.createElement("div", { ...(cell?.props || {}), "data-is-focusable": true, onClick: onClick, tabIndex: "0" },
|
|
227
|
-
cell?.props?.children || null,
|
|
228
|
-
react_1.default.createElement("div", { className: "table-item-warning" }, "This is a reuse library and does not require input during migration")));
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
return (react_1.default.createElement("div", { ...(cell?.props || {}), "data-is-focusable": true, onClick: onClick, tabIndex: "0" }, cell?.props?.children || null));
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
// just sets the active element property on the table, to track it later
|
|
235
|
-
/**
|
|
236
|
-
* On cell activation event.
|
|
237
|
-
*
|
|
238
|
-
* @param item
|
|
239
|
-
* @param rowIndex
|
|
240
|
-
* @param ev
|
|
241
|
-
*/
|
|
242
|
-
_onCellActivation(item, rowIndex, ev) {
|
|
243
|
-
const rowEl = ev?.target?.closest('.ms-DetailsRow');
|
|
244
|
-
let column = {};
|
|
245
|
-
const cells = rowEl?.querySelectorAll('.ms-DetailsRow-fields .ms-DetailsRow-cell');
|
|
246
|
-
if (!cells || !cells.length) {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
// focusing cell, not the row
|
|
250
|
-
const cellEl = ev?.target?.closest('.ms-DetailsRow-cell');
|
|
251
|
-
if (cellEl) {
|
|
252
|
-
const cellIdx = Array.from(cells).indexOf(cellEl);
|
|
253
|
-
if (cellIdx === -1) {
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
column = this.props.columns[cellIdx];
|
|
257
|
-
if (!column) {
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
this.activeElement = { item, rowIndex: rowIndex || 0, column };
|
|
262
|
-
if (this.props.renderInputs && column?.editable) {
|
|
263
|
-
const isDropdown = this.activeElement?.column?.columnControlType === types_1.ColumnControlType?.UIDropdown;
|
|
264
|
-
if (!isDropdown && this.state.editedCell?.column?.key !== this.activeElement?.column?.key) {
|
|
265
|
-
this.setState({ editedCell: this.activeElement });
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* On render item column event.
|
|
271
|
-
*
|
|
272
|
-
* @param {UIDocument} item
|
|
273
|
-
* @param {number} index
|
|
274
|
-
* @param {UIColumn} column
|
|
275
|
-
* @returns {React.ReactNode}
|
|
276
|
-
*/
|
|
277
|
-
_onRenderItemColumn(item, index, column) {
|
|
278
|
-
if (column?.key === '__row_number__') {
|
|
279
|
-
return react_1.default.createElement("div", { className: "ms-DetailsList-row-number" }, (index || 0) + 1);
|
|
280
|
-
}
|
|
281
|
-
return item[column?.fieldName || ''] || '';
|
|
282
|
-
}
|
|
283
|
-
// Replace weird radio-button-checkboxes with proper checkboxes
|
|
284
|
-
/**
|
|
285
|
-
* On render checkbox event.
|
|
286
|
-
*
|
|
287
|
-
* @param {IDetailsListCheckboxProps | undefined} props
|
|
288
|
-
* @returns {React.ReactElement}
|
|
289
|
-
*/
|
|
290
|
-
_onRenderCheckbox(props) {
|
|
291
|
-
return react_1.default.createElement(UICheckbox_1.UICheckbox, { ...props });
|
|
292
|
-
}
|
|
293
|
-
// COLUMN HEADER SORT
|
|
294
|
-
/**
|
|
295
|
-
* On column click event.
|
|
296
|
-
*
|
|
297
|
-
* @param ev
|
|
298
|
-
* @param column
|
|
299
|
-
*/
|
|
300
|
-
_onColumnClick(ev, column) {
|
|
301
|
-
const { columns, items } = this.state;
|
|
302
|
-
const newColumns = columns.slice();
|
|
303
|
-
const currColumn = newColumns.filter((currCol) => column.key === currCol.key)[0];
|
|
304
|
-
newColumns.forEach((newCol) => {
|
|
305
|
-
if (newCol === currColumn) {
|
|
306
|
-
currColumn.isSortedDescending = !currColumn.isSortedDescending;
|
|
307
|
-
currColumn.isSorted = true;
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
newCol.isSorted = false;
|
|
311
|
-
newCol.isSortedDescending = false;
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
const field = currColumn.fieldName || currColumn.name || '';
|
|
315
|
-
const newItems = (0, UITable_helper_1._copyAndSort)(items, field, currColumn.isSortedDescending);
|
|
316
|
-
this.setState({ columns: newColumns, items: newItems });
|
|
317
|
-
}
|
|
318
|
-
// CELL EDITING
|
|
319
|
-
/**
|
|
320
|
-
* On start edit event call.
|
|
321
|
-
*
|
|
322
|
-
* @param rowIndex
|
|
323
|
-
* @param item
|
|
324
|
-
* @param column
|
|
325
|
-
* @param errorMessage
|
|
326
|
-
*/
|
|
327
|
-
startEdit(rowIndex, item, column, errorMessage) {
|
|
328
|
-
const { editedCell } = this.state;
|
|
329
|
-
const isAlreadyInEdit = editedCell?.rowIndex === rowIndex && column?.key && editedCell?.column?.key === column?.key;
|
|
330
|
-
if (!isAlreadyInEdit) {
|
|
331
|
-
this.setState({ editedCell: { rowIndex, item, column, errorMessage } });
|
|
332
|
-
if (!this.props.renderInputs) {
|
|
333
|
-
this.rerenderTable();
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
requestAnimationFrame(() => {
|
|
337
|
-
if (column?.columnControlType === types_1.ColumnControlType.UITextInput) {
|
|
338
|
-
this.inputRefs?.[rowIndex][column?.key]?.current?.select();
|
|
339
|
-
}
|
|
340
|
-
else if (column?.columnControlType === types_1.ColumnControlType.UICombobox ||
|
|
341
|
-
column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
|
|
342
|
-
const combo = this.inputRefs?.[rowIndex][column?.key];
|
|
343
|
-
(0, UITable_helper_1.getComboBoxInput)(combo)?.focus();
|
|
344
|
-
}
|
|
345
|
-
else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
|
|
346
|
-
this.inputRefs?.[rowIndex][column?.key]?.current?.select();
|
|
347
|
-
}
|
|
348
|
-
else if (column?.key) {
|
|
349
|
-
const otherElement = this.inputRefs?.[rowIndex][column.key]?.current;
|
|
350
|
-
otherElement.focus();
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
rerenderTable() {
|
|
355
|
-
if (this.tableRef.current) {
|
|
356
|
-
this.tableRef.current.forceUpdate();
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
cancelEdit() {
|
|
360
|
-
this.caretPosition = -1;
|
|
361
|
-
this.setState({ editedCell: undefined });
|
|
362
|
-
this.rerenderTable();
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* On save cell event.
|
|
366
|
-
*
|
|
367
|
-
* @param cancelEdit
|
|
368
|
-
* @param value
|
|
369
|
-
*/
|
|
370
|
-
saveCell(cancelEdit = false, value) {
|
|
371
|
-
this.caretPosition = -1;
|
|
372
|
-
if (typeof this.props.onSave === 'function' && this.state.editedCell) {
|
|
373
|
-
const { rowIndex, column } = this.state.editedCell;
|
|
374
|
-
if (column?.columnControlType !== types_1.ColumnControlType.UIDropdown && !this.state.editedCell.errorMessage) {
|
|
375
|
-
let compRef;
|
|
376
|
-
if (column && this?.inputRefs?.[rowIndex]?.[column.key]) {
|
|
377
|
-
compRef = this?.inputRefs[rowIndex][column.key];
|
|
378
|
-
}
|
|
379
|
-
const currentValue = column && this.props.items[rowIndex][column.key];
|
|
380
|
-
let refValue = '';
|
|
381
|
-
if (column?.columnControlType === types_1.ColumnControlType.UITextInput) {
|
|
382
|
-
refValue = compRef?.current?.value || '';
|
|
383
|
-
}
|
|
384
|
-
else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
|
|
385
|
-
refValue = compRef?.current?.value || '';
|
|
386
|
-
}
|
|
387
|
-
else if (column?.columnControlType === types_1.ColumnControlType.UICombobox ||
|
|
388
|
-
column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
|
|
389
|
-
const combo = compRef;
|
|
390
|
-
refValue = (0, UITable_helper_1.getComboBoxInput)(combo)?.value || '';
|
|
391
|
-
}
|
|
392
|
-
const newValue = value ?? refValue;
|
|
393
|
-
if (currentValue !== newValue) {
|
|
394
|
-
this.props.onSave(this.state.editedCell, newValue);
|
|
395
|
-
}
|
|
396
|
-
const item = this.state.editedCell?.item;
|
|
397
|
-
const field = column?.fieldName;
|
|
398
|
-
if (field && item) {
|
|
399
|
-
item[field] = newValue;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if (cancelEdit) {
|
|
404
|
-
this.cancelEdit();
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
/**
|
|
408
|
-
* On mouse down event.
|
|
409
|
-
*
|
|
410
|
-
* @param e
|
|
411
|
-
*/
|
|
412
|
-
onDocumentMousedown(e) {
|
|
413
|
-
const target = e.target; // needed for TSC
|
|
414
|
-
if (target.closest('.ms-TextField, .ms-ComboBox, .ms-ComboBox-option, .ui-DatePicker') &&
|
|
415
|
-
!this.props.renderInputs) {
|
|
416
|
-
return;
|
|
417
|
-
}
|
|
418
|
-
if (this.state.editedCell) {
|
|
419
|
-
if (this.state.editedCell.errorMessage) {
|
|
420
|
-
e.preventDefault();
|
|
421
|
-
}
|
|
422
|
-
else {
|
|
423
|
-
this.saveCell(true);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* On key down event.
|
|
429
|
-
*
|
|
430
|
-
* @param {React.KeyboardEvent<Element | IDropdown>} e
|
|
431
|
-
* @returns {void}
|
|
432
|
-
*/
|
|
433
|
-
onKeyDown(e) {
|
|
434
|
-
if (!['Enter', 'Tab', 'Escape', 'ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
const isArrow = ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(e.key);
|
|
438
|
-
const isInput = e.target.tagName === 'INPUT';
|
|
439
|
-
if (isArrow && isInput) {
|
|
440
|
-
e.stopPropagation();
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
443
|
-
e.preventDefault();
|
|
444
|
-
if (e.key === 'Escape') {
|
|
445
|
-
this.cancelEdit();
|
|
446
|
-
(0, UITable_helper_1.focusEditedCell)(this.state.editedCell, this.props).catch(() => {
|
|
447
|
-
// Ignore focus cell error
|
|
448
|
-
});
|
|
449
|
-
(0, UITable_helper_1.showFocus)();
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
if (this.state.editedCell?.errorMessage) {
|
|
453
|
-
return;
|
|
454
|
-
}
|
|
455
|
-
e.stopPropagation();
|
|
456
|
-
if (e.key === 'Enter' || e.key === 'Tab') {
|
|
457
|
-
this.editNextCell(e.key, e.shiftKey);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
/**
|
|
461
|
-
* On ComboBox keydown event call.
|
|
462
|
-
*
|
|
463
|
-
* @param e
|
|
464
|
-
*/
|
|
465
|
-
onComboBoxKeyDownCapture(e) {
|
|
466
|
-
if (e.key === 'Enter' || e.key === 'Tab') {
|
|
467
|
-
// stop Enter from opening combobox
|
|
468
|
-
e.stopPropagation();
|
|
469
|
-
e.preventDefault();
|
|
470
|
-
this.editNextCell(e.key, e.shiftKey);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
/**
|
|
474
|
-
* On Edit next cell.
|
|
475
|
-
*
|
|
476
|
-
* @param key
|
|
477
|
-
* @param shiftKey
|
|
478
|
-
*/
|
|
479
|
-
editNextCell(key, shiftKey) {
|
|
480
|
-
this.saveCell();
|
|
481
|
-
let direction = '';
|
|
482
|
-
if (key === 'Enter') {
|
|
483
|
-
direction = shiftKey ? 'up' : 'down';
|
|
484
|
-
}
|
|
485
|
-
else if (key === 'Tab') {
|
|
486
|
-
direction = shiftKey ? 'left' : 'right';
|
|
487
|
-
}
|
|
488
|
-
if (direction) {
|
|
489
|
-
(0, UITable_helper_1.hideFocus)();
|
|
490
|
-
}
|
|
491
|
-
setTimeout(() => {
|
|
492
|
-
(0, UITable_helper_1.focusEditedCell)(this.state.editedCell, this.props, direction)
|
|
493
|
-
.then(() => {
|
|
494
|
-
if (!direction) {
|
|
495
|
-
(0, UITable_helper_1.showFocus)();
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
498
|
-
(0, UITable_helper_1.hideFocus)();
|
|
499
|
-
const { rowIndex, item, column } = this.activeElement;
|
|
500
|
-
this.startEdit(rowIndex, item, column);
|
|
501
|
-
})
|
|
502
|
-
.catch((e) => {
|
|
503
|
-
throw e;
|
|
504
|
-
});
|
|
505
|
-
}, 100);
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* On Cell click.
|
|
509
|
-
*
|
|
510
|
-
* @param e
|
|
511
|
-
* @param item
|
|
512
|
-
* @param rowIndex
|
|
513
|
-
* @param column
|
|
514
|
-
*/
|
|
515
|
-
_onCellClick(e, item, rowIndex, column) {
|
|
516
|
-
const previousCellHasErrors = this.state.editedCell?.errorMessage;
|
|
517
|
-
if (previousCellHasErrors) {
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
if (this.props.renderInputs) {
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
const el = e?.target;
|
|
524
|
-
requestAnimationFrame(() => {
|
|
525
|
-
// check the checkbox & focus the clicked cell
|
|
526
|
-
if (el) {
|
|
527
|
-
const fz = el.closest('.ms-FocusZone');
|
|
528
|
-
if (fz && fz.click) {
|
|
529
|
-
fz.click();
|
|
530
|
-
}
|
|
531
|
-
const cell = el.closest('.ms-DetailsRow-cell');
|
|
532
|
-
if (cell && cell.focus) {
|
|
533
|
-
cell.focus();
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
if (column?.editable !== true) {
|
|
537
|
-
(0, UITable_helper_1.showFocus)();
|
|
538
|
-
}
|
|
539
|
-
});
|
|
540
|
-
if (rowIndex !== undefined && item && column && column.editable === true) {
|
|
541
|
-
e?.stopPropagation();
|
|
542
|
-
requestAnimationFrame(() => this.startEdit(rowIndex, item, column));
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Validates passed value for cell and updates "errorMessage" property based on validation result.
|
|
547
|
-
*
|
|
548
|
-
* @param editedCell Cell to validate
|
|
549
|
-
* @param value
|
|
550
|
-
*/
|
|
551
|
-
validateCell(editedCell, value) {
|
|
552
|
-
const column = editedCell?.column;
|
|
553
|
-
let errorMessage = '';
|
|
554
|
-
if (column && typeof column.validate === 'function') {
|
|
555
|
-
errorMessage = column.validate(value);
|
|
556
|
-
}
|
|
557
|
-
if (editedCell && editedCell.errorMessage !== errorMessage) {
|
|
558
|
-
if (typeof editedCell.rowIndex === 'number' && editedCell.column?.key) {
|
|
559
|
-
const cell = (0, UITable_helper_1.getCellFromCoords)(editedCell.rowIndex, editedCell.column.key, this.props.columns, true);
|
|
560
|
-
const input = cell.querySelector('input');
|
|
561
|
-
this.caretPosition = input.selectionStart || 0;
|
|
562
|
-
}
|
|
563
|
-
editedCell.errorMessage = errorMessage || undefined;
|
|
564
|
-
// Rerender table to show error message
|
|
565
|
-
this.rerenderTable();
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
/**
|
|
569
|
-
* On Text input change.
|
|
570
|
-
*
|
|
571
|
-
* @param e
|
|
572
|
-
* @param newValue
|
|
573
|
-
*/
|
|
574
|
-
onTextInputChange(e, newValue = '') {
|
|
575
|
-
this.setState((prevState) => {
|
|
576
|
-
const editedCell = prevState.editedCell ?? this.activeElement;
|
|
577
|
-
if (editedCell) {
|
|
578
|
-
editedCell.newValue = newValue;
|
|
579
|
-
const column = editedCell.column;
|
|
580
|
-
if (column && typeof column.validate === 'function') {
|
|
581
|
-
this.validateCell(editedCell, newValue);
|
|
582
|
-
}
|
|
583
|
-
if (this.props.renderInputs) {
|
|
584
|
-
this.saveCell(false, newValue);
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
return { editedCell };
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
/**
|
|
591
|
-
* Gets input ref.
|
|
592
|
-
*
|
|
593
|
-
* @param rowIndex
|
|
594
|
-
* @param column
|
|
595
|
-
* @returns { React.RefObject<ITextField | IDropdown | HTMLDivElement> | undefined}
|
|
596
|
-
*/
|
|
597
|
-
_getInputRef(rowIndex, column) {
|
|
598
|
-
return typeof rowIndex === 'number' && typeof column?.key === 'string'
|
|
599
|
-
? this?.inputRefs?.[rowIndex]?.[column.key]
|
|
600
|
-
: undefined;
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Renders dropdown.
|
|
604
|
-
*
|
|
605
|
-
* @param item
|
|
606
|
-
* @param rowIndex
|
|
607
|
-
* @param column
|
|
608
|
-
* @returns {any}
|
|
609
|
-
*/
|
|
610
|
-
_renderDropdown(item, rowIndex, column) {
|
|
611
|
-
const compRef = this._getInputRef(rowIndex, column);
|
|
612
|
-
return (react_1.default.createElement(UIDropdown_1.UIDropdown, { id: `dropdown_row${rowIndex}_col${column?.key}`, hidden: item.hideCells ?? false, placeholder: "Select an option", componentRef: compRef, options: column?.data.dropdownOptions, defaultSelectedKey: typeof column?.key === 'string' && item[column?.key]
|
|
613
|
-
? item[column?.key]
|
|
614
|
-
: column?.data.defaultSelectedKey, onChange: (ev, text) => this.onDropdownCellValueChange(text, item, rowIndex, column), onKeyDown: this.onKeyDown }));
|
|
615
|
-
}
|
|
616
|
-
/**
|
|
617
|
-
* Renders combobox.
|
|
618
|
-
*
|
|
619
|
-
* @param item
|
|
620
|
-
* @param rowIndex
|
|
621
|
-
* @param column
|
|
622
|
-
* @returns {any}
|
|
623
|
-
*/
|
|
624
|
-
_renderCombobox(item, rowIndex, column) {
|
|
625
|
-
const compRef = this._getInputRef(rowIndex, column);
|
|
626
|
-
const newValue = this.state.editedCell?.newValue;
|
|
627
|
-
let value;
|
|
628
|
-
if (column?.fieldName) {
|
|
629
|
-
value = item[column?.fieldName];
|
|
630
|
-
}
|
|
631
|
-
if (typeof newValue !== 'undefined') {
|
|
632
|
-
value = newValue;
|
|
633
|
-
}
|
|
634
|
-
const options = column?.comboboxOptions?.map((o) => ({ key: o, text: o })) || [];
|
|
635
|
-
return (react_1.default.createElement(UIComboBox_1.UIComboBox, { highlight: true, defaultSelectedKey: value, allowFreeform: false, autoComplete: "on", shouldRestoreFocus: false, wrapperRef: compRef, errorMessage: this.state.editedCell?.errorMessage, openMenuOnClick: false, onPendingValueChanged: this.onComboBoxChange, onKeyDown: this.onKeyDown, onKeyDownCapture: this.onComboBoxKeyDownCapture, onClick: (e) => {
|
|
636
|
-
e.stopPropagation();
|
|
637
|
-
}, options: options }));
|
|
638
|
-
}
|
|
639
|
-
/**
|
|
640
|
-
* Renders date picker.
|
|
641
|
-
*
|
|
642
|
-
* @param item
|
|
643
|
-
* @param rowIndex
|
|
644
|
-
* @param column
|
|
645
|
-
* @param dateOnly
|
|
646
|
-
* @returns {any}
|
|
647
|
-
*/
|
|
648
|
-
_renderDatePicker(item, rowIndex, column, dateOnly = true) {
|
|
649
|
-
const compRef = this._getInputRef(rowIndex, column);
|
|
650
|
-
const newValue = this.state.editedCell?.newValue;
|
|
651
|
-
let value;
|
|
652
|
-
if (column?.fieldName) {
|
|
653
|
-
value = item[column?.fieldName];
|
|
654
|
-
}
|
|
655
|
-
if (typeof newValue !== 'undefined') {
|
|
656
|
-
value = newValue;
|
|
657
|
-
}
|
|
658
|
-
return (react_1.default.createElement(UIDatePicker_1.UIDatePicker, { defaultValue: value, componentRef: compRef, dateOnly: dateOnly, errorMessage: this.state.editedCell?.errorMessage, onChange: this.onTextInputChange, onKeyDown: this.onKeyDown, onClick: (e) => {
|
|
659
|
-
e.stopPropagation();
|
|
660
|
-
} }));
|
|
661
|
-
}
|
|
662
|
-
/**
|
|
663
|
-
* Renders text input.
|
|
664
|
-
*
|
|
665
|
-
* @param item
|
|
666
|
-
* @param rowIndex
|
|
667
|
-
* @param column
|
|
668
|
-
* @returns {any}
|
|
669
|
-
*/
|
|
670
|
-
_renderTextInput(item, rowIndex, column) {
|
|
671
|
-
const compRef = this._getInputRef(rowIndex, column);
|
|
672
|
-
const newValue = this.state.editedCell?.newValue;
|
|
673
|
-
let element;
|
|
674
|
-
let value;
|
|
675
|
-
if (column?.fieldName) {
|
|
676
|
-
value = item[column?.fieldName];
|
|
677
|
-
}
|
|
678
|
-
if (typeof newValue !== 'undefined') {
|
|
679
|
-
value = newValue;
|
|
680
|
-
}
|
|
681
|
-
if (!item.hideCells) {
|
|
682
|
-
element = (react_1.default.createElement(UIInput_1.UITextInput, { defaultValue: value, componentRef: compRef, errorMessage: this.state.editedCell?.errorMessage, onChange: this.onTextInputChange, onKeyDown: this.onKeyDown, onClick: (e) => {
|
|
683
|
-
e.stopPropagation();
|
|
684
|
-
} }));
|
|
685
|
-
}
|
|
686
|
-
return element;
|
|
687
|
-
}
|
|
688
|
-
/**
|
|
689
|
-
* On cell render.
|
|
690
|
-
*
|
|
691
|
-
* @param item
|
|
692
|
-
* @param rowIndex
|
|
693
|
-
* @param column
|
|
694
|
-
* @returns {any}
|
|
695
|
-
*/
|
|
696
|
-
_onCellRender(item, rowIndex, column) {
|
|
697
|
-
// inputs & dropdowns always visible
|
|
698
|
-
if (this.props.renderInputs && rowIndex !== undefined) {
|
|
699
|
-
if (column?.columnControlType === types_1.ColumnControlType.UIDropdown) {
|
|
700
|
-
return this._renderDropdown(item, rowIndex, column);
|
|
701
|
-
}
|
|
702
|
-
return this._renderTextInput(item, rowIndex, column);
|
|
703
|
-
}
|
|
704
|
-
// inputs visible only in "edit mode" (after cell click)
|
|
705
|
-
const editedCell = this.state.editedCell;
|
|
706
|
-
const itsThisRow = editedCell && editedCell.rowIndex === rowIndex;
|
|
707
|
-
const itsThisCol = editedCell && editedCell.column?.key === column?.key;
|
|
708
|
-
const isCellInEditMode = itsThisRow && itsThisCol;
|
|
709
|
-
if (isCellInEditMode && rowIndex !== undefined) {
|
|
710
|
-
if (column?.columnControlType === types_1.ColumnControlType.UICombobox) {
|
|
711
|
-
return this._renderCombobox(item, rowIndex, column);
|
|
712
|
-
}
|
|
713
|
-
else if (column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
|
|
714
|
-
return this._renderCombobox(item, rowIndex, { ...column, comboboxOptions: ['true', 'false'] });
|
|
715
|
-
}
|
|
716
|
-
else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
|
|
717
|
-
return this._renderDatePicker(item, rowIndex, column, column?.type === 'Date');
|
|
718
|
-
}
|
|
719
|
-
else {
|
|
720
|
-
return this._renderTextInput(item, rowIndex, column);
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
const onClick = (e) => {
|
|
724
|
-
e.stopPropagation();
|
|
725
|
-
this._onCellClick(e, item, rowIndex || 0, column);
|
|
726
|
-
};
|
|
727
|
-
return (react_1.default.createElement("span", { style: { cursor: 'text', padding: 5 }, onClick: onClick }, item[column?.fieldName || 0]));
|
|
728
|
-
}
|
|
729
|
-
/**
|
|
730
|
-
* @returns {JSX.Element}
|
|
731
|
-
*/
|
|
732
|
-
render() {
|
|
733
|
-
// get columns & items from props, so that detailsListProps does not contain them
|
|
734
|
-
// because we want them to come from state, and be passed to component only once
|
|
735
|
-
let { columns, items, checkboxVisibility, headerRenderer, selectionMode } = this.props;
|
|
736
|
-
const { scrollablePaneProps, showRowNumbers, ...detailsListProps } = this.props;
|
|
737
|
-
// get them from state if they exist
|
|
738
|
-
if (this.state.columns) {
|
|
739
|
-
columns = this.state.columns;
|
|
740
|
-
}
|
|
741
|
-
if (this.state.items) {
|
|
742
|
-
items = this.state.items;
|
|
743
|
-
}
|
|
744
|
-
if (columns) {
|
|
745
|
-
columns.forEach((col) => {
|
|
746
|
-
col.onColumnClick = this._onColumnClick;
|
|
747
|
-
if (col.editable === true) {
|
|
748
|
-
col.onRender = this._onCellRender;
|
|
749
|
-
}
|
|
750
|
-
else {
|
|
751
|
-
col.className = 'uneditable';
|
|
752
|
-
}
|
|
753
|
-
if (col.key === this.props.selectedColumnId) {
|
|
754
|
-
col.headerClassName = 'selected';
|
|
755
|
-
}
|
|
756
|
-
});
|
|
757
|
-
columns = (0, UITable_helper_1.addRowNumbers)(columns, showRowNumbers);
|
|
758
|
-
}
|
|
759
|
-
const styles = (0, UITable_helper_1.getStylesForSelectedCell)(this.state);
|
|
760
|
-
if (typeof checkboxVisibility === 'undefined') {
|
|
761
|
-
checkboxVisibility = react_2.CheckboxVisibility.hidden;
|
|
762
|
-
}
|
|
763
|
-
if (typeof selectionMode === 'undefined') {
|
|
764
|
-
selectionMode = react_2.SelectionMode.single;
|
|
765
|
-
}
|
|
766
|
-
if (typeof headerRenderer === 'undefined') {
|
|
767
|
-
headerRenderer = UITable_helper_1._onHeaderRender;
|
|
768
|
-
}
|
|
769
|
-
const focusZoneProps = {
|
|
770
|
-
direction: react_2.FocusZoneDirection.vertical,
|
|
771
|
-
shouldEnterInnerZone: (ev) => {
|
|
772
|
-
return ev.key === 'ArrowRight';
|
|
773
|
-
}
|
|
774
|
-
};
|
|
775
|
-
return (react_1.default.createElement(react_2.ScrollablePane, { ...scrollablePaneProps, styles: { stickyAbove: { zIndex: 2 } } },
|
|
776
|
-
react_1.default.createElement(react_2.DetailsList, { checkboxVisibility: checkboxVisibility, componentRef: this.tableRef, selection: this.selection, selectionMode: selectionMode, onRenderCheckbox: this._onRenderCheckbox, onRenderDetailsHeader: headerRenderer, onRenderField: this._onRenderField, onRenderRow: this._onRenderRow, onRenderItemColumn: this._onRenderItemColumn, layoutMode: react_2.DetailsListLayoutMode.fixedColumns, constrainMode: react_2.ConstrainMode.unconstrained, focusZoneProps: focusZoneProps, onActiveItemChanged: this._onCellActivation, ...detailsListProps, items: items, columns: columns, styles: styles })));
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
exports.UITable = UITable;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.UITable = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const react_2 = require("@fluentui/react");
|
|
9
|
+
const UICheckbox_1 = require("../UICheckbox");
|
|
10
|
+
const UIInput_1 = require("../UIInput");
|
|
11
|
+
const UIDropdown_1 = require("../UIDropdown");
|
|
12
|
+
const UIComboBox_1 = require("../UIComboBox");
|
|
13
|
+
const UIDatePicker_1 = require("../UIDatePicker");
|
|
14
|
+
const UITable_helper_1 = require("./UITable-helper");
|
|
15
|
+
const types_1 = require("./types");
|
|
16
|
+
require("./UITable.scss");
|
|
17
|
+
/**
|
|
18
|
+
* UITable component
|
|
19
|
+
* based on: https://developer.microsoft.com/en-us/fluentui#/controls/web/detailslist
|
|
20
|
+
*
|
|
21
|
+
* @exports
|
|
22
|
+
* @class {UITable}
|
|
23
|
+
* @extends {React.Component<UITableProps, UITableState>}
|
|
24
|
+
*/
|
|
25
|
+
class UITable extends react_1.default.Component {
|
|
26
|
+
/**
|
|
27
|
+
* Initializes component properties.
|
|
28
|
+
*
|
|
29
|
+
* @param props
|
|
30
|
+
*/
|
|
31
|
+
constructor(props) {
|
|
32
|
+
super(props);
|
|
33
|
+
this.inputRefs = {};
|
|
34
|
+
this.activeElement = {};
|
|
35
|
+
this.caretPosition = -1;
|
|
36
|
+
this._onRenderRow = (props) => {
|
|
37
|
+
if (!props) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const toggle = !!this.props.renderInputs;
|
|
41
|
+
return react_1.default.createElement(react_2.DetailsRow, { "data-selection-toggle": toggle, rowFieldsAs: this.renderRowFields.bind(this), ...props });
|
|
42
|
+
};
|
|
43
|
+
this.onComboBoxChange = (option) => {
|
|
44
|
+
this.setState((prevState) => {
|
|
45
|
+
const editedCell = prevState.editedCell ?? this.activeElement;
|
|
46
|
+
if (editedCell && option) {
|
|
47
|
+
editedCell.newValue = option.text;
|
|
48
|
+
}
|
|
49
|
+
return { editedCell };
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
this.onDropdownCellValueChange = (selectedOption, item, rowIndex, column) => {
|
|
53
|
+
const newValue = selectedOption.key;
|
|
54
|
+
if (typeof this.props.onSave === 'function' &&
|
|
55
|
+
typeof rowIndex === 'number' &&
|
|
56
|
+
Number.isInteger(rowIndex) &&
|
|
57
|
+
column) {
|
|
58
|
+
const currentValue = this.props.items[rowIndex][column.key];
|
|
59
|
+
const editedCell = { rowIndex, item, column, errorMessage: undefined };
|
|
60
|
+
if (currentValue !== newValue) {
|
|
61
|
+
this.props.onSave(editedCell, newValue);
|
|
62
|
+
}
|
|
63
|
+
const field = column?.fieldName;
|
|
64
|
+
if (field && item) {
|
|
65
|
+
item[field] = newValue;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
this.cancelEdit();
|
|
69
|
+
};
|
|
70
|
+
this.state = {
|
|
71
|
+
columns: props.columns || [],
|
|
72
|
+
items: props.items || []
|
|
73
|
+
};
|
|
74
|
+
this.tableRef = react_1.default.createRef();
|
|
75
|
+
this.selection = new react_2.Selection({
|
|
76
|
+
onSelectionChanged: () => {
|
|
77
|
+
if (typeof this.props.onSelectionChange !== 'function') {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.props.onSelectionChange(this.selection.getSelectedIndices());
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
if (this.props.selectionRef) {
|
|
84
|
+
this.props.selectionRef.current = this.selection;
|
|
85
|
+
}
|
|
86
|
+
this.onTextInputChange = this.onTextInputChange.bind(this);
|
|
87
|
+
this.onComboBoxChange = this.onComboBoxChange.bind(this);
|
|
88
|
+
this.onDocumentMousedown = this.onDocumentMousedown.bind(this);
|
|
89
|
+
this.onKeyDown = this.onKeyDown.bind(this);
|
|
90
|
+
this.onComboBoxKeyDownCapture = this.onComboBoxKeyDownCapture.bind(this);
|
|
91
|
+
this.validateCell = this.validateCell.bind(this);
|
|
92
|
+
this.editNextCell = this.editNextCell.bind(this);
|
|
93
|
+
this._onColumnClick = this._onColumnClick.bind(this);
|
|
94
|
+
this._onCellRender = this._onCellRender.bind(this);
|
|
95
|
+
this._onRenderCheckbox = this._onRenderCheckbox.bind(this);
|
|
96
|
+
this._onRenderField = this._onRenderField?.bind(this);
|
|
97
|
+
this._onRenderRow = this._onRenderRow?.bind(this);
|
|
98
|
+
this._onRenderItemColumn = this._onRenderItemColumn?.bind(this);
|
|
99
|
+
this._onCellActivation = this._onCellActivation?.bind(this);
|
|
100
|
+
}
|
|
101
|
+
componentDidMount() {
|
|
102
|
+
this.onDocMousedown = this.onDocumentMousedown;
|
|
103
|
+
document.addEventListener('mousedown', this.onDocMousedown, true);
|
|
104
|
+
window.dispatchEvent(new Event('resize'));
|
|
105
|
+
this._setTextRefs();
|
|
106
|
+
}
|
|
107
|
+
componentWillUnmount() {
|
|
108
|
+
document.removeEventListener('mousedown', this.onDocMousedown);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* On component update.
|
|
112
|
+
*
|
|
113
|
+
* @param prevProps
|
|
114
|
+
* @param prevState
|
|
115
|
+
*/
|
|
116
|
+
componentDidUpdate(prevProps, prevState) {
|
|
117
|
+
const scrollContainer = document.querySelector('.ms-ScrollablePane--contentContainer');
|
|
118
|
+
if (scrollContainer) {
|
|
119
|
+
const left = scrollContainer.scrollLeft || 0;
|
|
120
|
+
requestAnimationFrame(() => (scrollContainer.scrollLeft = left));
|
|
121
|
+
}
|
|
122
|
+
if (prevProps.items !== this.props.items) {
|
|
123
|
+
this.setState({ items: this.props.items });
|
|
124
|
+
this._setTextRefs();
|
|
125
|
+
}
|
|
126
|
+
if (prevProps.columns !== this.props.columns) {
|
|
127
|
+
this.setState({ columns: this.props.columns });
|
|
128
|
+
}
|
|
129
|
+
if (prevProps.dataSetKey !== this.props.dataSetKey) {
|
|
130
|
+
this.setState({ editedCell: undefined });
|
|
131
|
+
}
|
|
132
|
+
if (typeof this.props.selectedRow !== 'undefined' && prevProps.selectedRow !== this.props.selectedRow) {
|
|
133
|
+
(0, UITable_helper_1.scrollToRow)(this.props.selectedRow, this.tableRef?.current);
|
|
134
|
+
}
|
|
135
|
+
if (this.props.scrollToAddedRow) {
|
|
136
|
+
const dataSetChanged = this.props.dataSetKey !== prevProps.dataSetKey;
|
|
137
|
+
const { items } = this.state;
|
|
138
|
+
const { items: prevItems } = prevState;
|
|
139
|
+
const itemsDelta = items.length - prevItems.length;
|
|
140
|
+
const shouldScrollToNewRow = !dataSetChanged && itemsDelta === 1;
|
|
141
|
+
if (shouldScrollToNewRow && this.tableRef && this.tableRef.current) {
|
|
142
|
+
const newRowIndex = items.length - 1;
|
|
143
|
+
this.tableRef.current.scrollToIndex(newRowIndex);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const { selectedColumnId } = this.props;
|
|
147
|
+
const { selectedColumnId: prevSelectedColumnId } = prevProps;
|
|
148
|
+
// Due to table rendering using columns data from state, instead of props,
|
|
149
|
+
// to sync selected column change callback with rendered dataset change
|
|
150
|
+
// selected column id/key needs to be stored on a state level along with columns data
|
|
151
|
+
if (selectedColumnId !== prevSelectedColumnId) {
|
|
152
|
+
this.setState({ selectedColumnId });
|
|
153
|
+
}
|
|
154
|
+
const columnIsSelected = typeof this.state.selectedColumnId !== 'undefined';
|
|
155
|
+
const selectedColumnDidChange = prevState.selectedColumnId !== this.state.selectedColumnId;
|
|
156
|
+
if (columnIsSelected && selectedColumnDidChange) {
|
|
157
|
+
(0, UITable_helper_1.scrollToColumn)(this.state.selectedColumnId || '', this.state.columns, this.props.selectedRow || 0, this.props.showRowNumbers);
|
|
158
|
+
}
|
|
159
|
+
this._restoreCaretPosition();
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Restores the caret position. Caret position gets lost when validation finds issue in cell.
|
|
163
|
+
*/
|
|
164
|
+
_restoreCaretPosition() {
|
|
165
|
+
const editedCell = this.state.editedCell;
|
|
166
|
+
if (this.caretPosition !== -1 && typeof editedCell?.rowIndex === 'number' && editedCell.column?.key) {
|
|
167
|
+
const cell = (0, UITable_helper_1.getCellFromCoords)(editedCell.rowIndex, editedCell.column.key, this.props.columns, true);
|
|
168
|
+
const input = cell.querySelector('input');
|
|
169
|
+
if (input && input.selectionStart !== this.caretPosition) {
|
|
170
|
+
input.setSelectionRange(this.caretPosition, this.caretPosition);
|
|
171
|
+
this.caretPosition = -1;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
_setTextRefs() {
|
|
176
|
+
if (this.props.columns && this.props.items) {
|
|
177
|
+
for (const rowIndexTmp in this.props.items) {
|
|
178
|
+
for (const col of this.props.columns) {
|
|
179
|
+
if (col.editable === true && this.inputRefs) {
|
|
180
|
+
this.inputRefs[rowIndexTmp] = this.inputRefs[rowIndexTmp] || {};
|
|
181
|
+
this.inputRefs[rowIndexTmp][col.key] = react_1.default.createRef();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* On render row fields event.
|
|
189
|
+
*
|
|
190
|
+
* @param props
|
|
191
|
+
* @returns {JSX.Element}
|
|
192
|
+
*/
|
|
193
|
+
renderRowFields(props) {
|
|
194
|
+
// disabled is set to false when selectionMode === undefined || selectionMode === SelectionMode.single
|
|
195
|
+
let disabled = false;
|
|
196
|
+
const selectionMode = this.props.selectionMode;
|
|
197
|
+
if (selectionMode === react_2.SelectionMode.multiple || selectionMode === react_2.SelectionMode.none) {
|
|
198
|
+
disabled = true;
|
|
199
|
+
}
|
|
200
|
+
return (react_1.default.createElement("div", { "data-selection-disabled": disabled },
|
|
201
|
+
react_1.default.createElement(react_2.DetailsRowFields, { ...props })));
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* On render field event.
|
|
205
|
+
*
|
|
206
|
+
* @param props
|
|
207
|
+
* @param defaultRender
|
|
208
|
+
* @returns {null | JSX.Element}
|
|
209
|
+
*/
|
|
210
|
+
_onRenderField(props, defaultRender) {
|
|
211
|
+
if (!props || !defaultRender) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
const cell = defaultRender(props);
|
|
215
|
+
const onClick = (e) => {
|
|
216
|
+
const target = e?.target;
|
|
217
|
+
const targetTag = target?.tagName;
|
|
218
|
+
if (['INPUT', 'TEXTAREA', 'SELECT'].includes(targetTag)) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const { item, rowIndex, column } = this.activeElement;
|
|
222
|
+
this._onCellClick(e, item, rowIndex || 0, column);
|
|
223
|
+
};
|
|
224
|
+
// in app-migrator, show a warning message for library projects on main migration view
|
|
225
|
+
if (props.item.hideCells && props.column.fieldName === 'moduleName' && !props.item.status) {
|
|
226
|
+
return (react_1.default.createElement("div", { ...(cell?.props || {}), "data-is-focusable": true, onClick: onClick, tabIndex: "0" },
|
|
227
|
+
cell?.props?.children || null,
|
|
228
|
+
react_1.default.createElement("div", { className: "table-item-warning" }, "This is a reuse library and does not require input during migration")));
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
return (react_1.default.createElement("div", { ...(cell?.props || {}), "data-is-focusable": true, onClick: onClick, tabIndex: "0" }, cell?.props?.children || null));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// just sets the active element property on the table, to track it later
|
|
235
|
+
/**
|
|
236
|
+
* On cell activation event.
|
|
237
|
+
*
|
|
238
|
+
* @param item
|
|
239
|
+
* @param rowIndex
|
|
240
|
+
* @param ev
|
|
241
|
+
*/
|
|
242
|
+
_onCellActivation(item, rowIndex, ev) {
|
|
243
|
+
const rowEl = ev?.target?.closest('.ms-DetailsRow');
|
|
244
|
+
let column = {};
|
|
245
|
+
const cells = rowEl?.querySelectorAll('.ms-DetailsRow-fields .ms-DetailsRow-cell');
|
|
246
|
+
if (!cells || !cells.length) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
// focusing cell, not the row
|
|
250
|
+
const cellEl = ev?.target?.closest('.ms-DetailsRow-cell');
|
|
251
|
+
if (cellEl) {
|
|
252
|
+
const cellIdx = Array.from(cells).indexOf(cellEl);
|
|
253
|
+
if (cellIdx === -1) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
column = this.props.columns[cellIdx];
|
|
257
|
+
if (!column) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
this.activeElement = { item, rowIndex: rowIndex || 0, column };
|
|
262
|
+
if (this.props.renderInputs && column?.editable) {
|
|
263
|
+
const isDropdown = this.activeElement?.column?.columnControlType === types_1.ColumnControlType?.UIDropdown;
|
|
264
|
+
if (!isDropdown && this.state.editedCell?.column?.key !== this.activeElement?.column?.key) {
|
|
265
|
+
this.setState({ editedCell: this.activeElement });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* On render item column event.
|
|
271
|
+
*
|
|
272
|
+
* @param {UIDocument} item
|
|
273
|
+
* @param {number} index
|
|
274
|
+
* @param {UIColumn} column
|
|
275
|
+
* @returns {React.ReactNode}
|
|
276
|
+
*/
|
|
277
|
+
_onRenderItemColumn(item, index, column) {
|
|
278
|
+
if (column?.key === '__row_number__') {
|
|
279
|
+
return react_1.default.createElement("div", { className: "ms-DetailsList-row-number" }, (index || 0) + 1);
|
|
280
|
+
}
|
|
281
|
+
return item[column?.fieldName || ''] || '';
|
|
282
|
+
}
|
|
283
|
+
// Replace weird radio-button-checkboxes with proper checkboxes
|
|
284
|
+
/**
|
|
285
|
+
* On render checkbox event.
|
|
286
|
+
*
|
|
287
|
+
* @param {IDetailsListCheckboxProps | undefined} props
|
|
288
|
+
* @returns {React.ReactElement}
|
|
289
|
+
*/
|
|
290
|
+
_onRenderCheckbox(props) {
|
|
291
|
+
return react_1.default.createElement(UICheckbox_1.UICheckbox, { ...props });
|
|
292
|
+
}
|
|
293
|
+
// COLUMN HEADER SORT
|
|
294
|
+
/**
|
|
295
|
+
* On column click event.
|
|
296
|
+
*
|
|
297
|
+
* @param ev
|
|
298
|
+
* @param column
|
|
299
|
+
*/
|
|
300
|
+
_onColumnClick(ev, column) {
|
|
301
|
+
const { columns, items } = this.state;
|
|
302
|
+
const newColumns = columns.slice();
|
|
303
|
+
const currColumn = newColumns.filter((currCol) => column.key === currCol.key)[0];
|
|
304
|
+
newColumns.forEach((newCol) => {
|
|
305
|
+
if (newCol === currColumn) {
|
|
306
|
+
currColumn.isSortedDescending = !currColumn.isSortedDescending;
|
|
307
|
+
currColumn.isSorted = true;
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
newCol.isSorted = false;
|
|
311
|
+
newCol.isSortedDescending = false;
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
const field = currColumn.fieldName || currColumn.name || '';
|
|
315
|
+
const newItems = (0, UITable_helper_1._copyAndSort)(items, field, currColumn.isSortedDescending);
|
|
316
|
+
this.setState({ columns: newColumns, items: newItems });
|
|
317
|
+
}
|
|
318
|
+
// CELL EDITING
|
|
319
|
+
/**
|
|
320
|
+
* On start edit event call.
|
|
321
|
+
*
|
|
322
|
+
* @param rowIndex
|
|
323
|
+
* @param item
|
|
324
|
+
* @param column
|
|
325
|
+
* @param errorMessage
|
|
326
|
+
*/
|
|
327
|
+
startEdit(rowIndex, item, column, errorMessage) {
|
|
328
|
+
const { editedCell } = this.state;
|
|
329
|
+
const isAlreadyInEdit = editedCell?.rowIndex === rowIndex && column?.key && editedCell?.column?.key === column?.key;
|
|
330
|
+
if (!isAlreadyInEdit) {
|
|
331
|
+
this.setState({ editedCell: { rowIndex, item, column, errorMessage } });
|
|
332
|
+
if (!this.props.renderInputs) {
|
|
333
|
+
this.rerenderTable();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
requestAnimationFrame(() => {
|
|
337
|
+
if (column?.columnControlType === types_1.ColumnControlType.UITextInput) {
|
|
338
|
+
this.inputRefs?.[rowIndex][column?.key]?.current?.select();
|
|
339
|
+
}
|
|
340
|
+
else if (column?.columnControlType === types_1.ColumnControlType.UICombobox ||
|
|
341
|
+
column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
|
|
342
|
+
const combo = this.inputRefs?.[rowIndex][column?.key];
|
|
343
|
+
(0, UITable_helper_1.getComboBoxInput)(combo)?.focus();
|
|
344
|
+
}
|
|
345
|
+
else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
|
|
346
|
+
this.inputRefs?.[rowIndex][column?.key]?.current?.select();
|
|
347
|
+
}
|
|
348
|
+
else if (column?.key) {
|
|
349
|
+
const otherElement = this.inputRefs?.[rowIndex][column.key]?.current;
|
|
350
|
+
otherElement.focus();
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
rerenderTable() {
|
|
355
|
+
if (this.tableRef.current) {
|
|
356
|
+
this.tableRef.current.forceUpdate();
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
cancelEdit() {
|
|
360
|
+
this.caretPosition = -1;
|
|
361
|
+
this.setState({ editedCell: undefined });
|
|
362
|
+
this.rerenderTable();
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* On save cell event.
|
|
366
|
+
*
|
|
367
|
+
* @param cancelEdit
|
|
368
|
+
* @param value
|
|
369
|
+
*/
|
|
370
|
+
saveCell(cancelEdit = false, value) {
|
|
371
|
+
this.caretPosition = -1;
|
|
372
|
+
if (typeof this.props.onSave === 'function' && this.state.editedCell) {
|
|
373
|
+
const { rowIndex, column } = this.state.editedCell;
|
|
374
|
+
if (column?.columnControlType !== types_1.ColumnControlType.UIDropdown && !this.state.editedCell.errorMessage) {
|
|
375
|
+
let compRef;
|
|
376
|
+
if (column && this?.inputRefs?.[rowIndex]?.[column.key]) {
|
|
377
|
+
compRef = this?.inputRefs[rowIndex][column.key];
|
|
378
|
+
}
|
|
379
|
+
const currentValue = column && this.props.items[rowIndex][column.key];
|
|
380
|
+
let refValue = '';
|
|
381
|
+
if (column?.columnControlType === types_1.ColumnControlType.UITextInput) {
|
|
382
|
+
refValue = compRef?.current?.value || '';
|
|
383
|
+
}
|
|
384
|
+
else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
|
|
385
|
+
refValue = compRef?.current?.value || '';
|
|
386
|
+
}
|
|
387
|
+
else if (column?.columnControlType === types_1.ColumnControlType.UICombobox ||
|
|
388
|
+
column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
|
|
389
|
+
const combo = compRef;
|
|
390
|
+
refValue = (0, UITable_helper_1.getComboBoxInput)(combo)?.value || '';
|
|
391
|
+
}
|
|
392
|
+
const newValue = value ?? refValue;
|
|
393
|
+
if (currentValue !== newValue) {
|
|
394
|
+
this.props.onSave(this.state.editedCell, newValue);
|
|
395
|
+
}
|
|
396
|
+
const item = this.state.editedCell?.item;
|
|
397
|
+
const field = column?.fieldName;
|
|
398
|
+
if (field && item) {
|
|
399
|
+
item[field] = newValue;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (cancelEdit) {
|
|
404
|
+
this.cancelEdit();
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* On mouse down event.
|
|
409
|
+
*
|
|
410
|
+
* @param e
|
|
411
|
+
*/
|
|
412
|
+
onDocumentMousedown(e) {
|
|
413
|
+
const target = e.target; // needed for TSC
|
|
414
|
+
if (target.closest('.ms-TextField, .ms-ComboBox, .ms-ComboBox-option, .ui-DatePicker') &&
|
|
415
|
+
!this.props.renderInputs) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (this.state.editedCell) {
|
|
419
|
+
if (this.state.editedCell.errorMessage) {
|
|
420
|
+
e.preventDefault();
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
this.saveCell(true);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* On key down event.
|
|
429
|
+
*
|
|
430
|
+
* @param {React.KeyboardEvent<Element | IDropdown>} e
|
|
431
|
+
* @returns {void}
|
|
432
|
+
*/
|
|
433
|
+
onKeyDown(e) {
|
|
434
|
+
if (!['Enter', 'Tab', 'Escape', 'ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const isArrow = ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(e.key);
|
|
438
|
+
const isInput = e.target.tagName === 'INPUT';
|
|
439
|
+
if (isArrow && isInput) {
|
|
440
|
+
e.stopPropagation();
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
e.preventDefault();
|
|
444
|
+
if (e.key === 'Escape') {
|
|
445
|
+
this.cancelEdit();
|
|
446
|
+
(0, UITable_helper_1.focusEditedCell)(this.state.editedCell, this.props).catch(() => {
|
|
447
|
+
// Ignore focus cell error
|
|
448
|
+
});
|
|
449
|
+
(0, UITable_helper_1.showFocus)();
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
if (this.state.editedCell?.errorMessage) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
e.stopPropagation();
|
|
456
|
+
if (e.key === 'Enter' || e.key === 'Tab') {
|
|
457
|
+
this.editNextCell(e.key, e.shiftKey);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* On ComboBox keydown event call.
|
|
462
|
+
*
|
|
463
|
+
* @param e
|
|
464
|
+
*/
|
|
465
|
+
onComboBoxKeyDownCapture(e) {
|
|
466
|
+
if (e.key === 'Enter' || e.key === 'Tab') {
|
|
467
|
+
// stop Enter from opening combobox
|
|
468
|
+
e.stopPropagation();
|
|
469
|
+
e.preventDefault();
|
|
470
|
+
this.editNextCell(e.key, e.shiftKey);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* On Edit next cell.
|
|
475
|
+
*
|
|
476
|
+
* @param key
|
|
477
|
+
* @param shiftKey
|
|
478
|
+
*/
|
|
479
|
+
editNextCell(key, shiftKey) {
|
|
480
|
+
this.saveCell();
|
|
481
|
+
let direction = '';
|
|
482
|
+
if (key === 'Enter') {
|
|
483
|
+
direction = shiftKey ? 'up' : 'down';
|
|
484
|
+
}
|
|
485
|
+
else if (key === 'Tab') {
|
|
486
|
+
direction = shiftKey ? 'left' : 'right';
|
|
487
|
+
}
|
|
488
|
+
if (direction) {
|
|
489
|
+
(0, UITable_helper_1.hideFocus)();
|
|
490
|
+
}
|
|
491
|
+
setTimeout(() => {
|
|
492
|
+
(0, UITable_helper_1.focusEditedCell)(this.state.editedCell, this.props, direction)
|
|
493
|
+
.then(() => {
|
|
494
|
+
if (!direction) {
|
|
495
|
+
(0, UITable_helper_1.showFocus)();
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
(0, UITable_helper_1.hideFocus)();
|
|
499
|
+
const { rowIndex, item, column } = this.activeElement;
|
|
500
|
+
this.startEdit(rowIndex, item, column);
|
|
501
|
+
})
|
|
502
|
+
.catch((e) => {
|
|
503
|
+
throw e;
|
|
504
|
+
});
|
|
505
|
+
}, 100);
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* On Cell click.
|
|
509
|
+
*
|
|
510
|
+
* @param e
|
|
511
|
+
* @param item
|
|
512
|
+
* @param rowIndex
|
|
513
|
+
* @param column
|
|
514
|
+
*/
|
|
515
|
+
_onCellClick(e, item, rowIndex, column) {
|
|
516
|
+
const previousCellHasErrors = this.state.editedCell?.errorMessage;
|
|
517
|
+
if (previousCellHasErrors) {
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
if (this.props.renderInputs) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
const el = e?.target;
|
|
524
|
+
requestAnimationFrame(() => {
|
|
525
|
+
// check the checkbox & focus the clicked cell
|
|
526
|
+
if (el) {
|
|
527
|
+
const fz = el.closest('.ms-FocusZone');
|
|
528
|
+
if (fz && fz.click) {
|
|
529
|
+
fz.click();
|
|
530
|
+
}
|
|
531
|
+
const cell = el.closest('.ms-DetailsRow-cell');
|
|
532
|
+
if (cell && cell.focus) {
|
|
533
|
+
cell.focus();
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
if (column?.editable !== true) {
|
|
537
|
+
(0, UITable_helper_1.showFocus)();
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
if (rowIndex !== undefined && item && column && column.editable === true) {
|
|
541
|
+
e?.stopPropagation();
|
|
542
|
+
requestAnimationFrame(() => this.startEdit(rowIndex, item, column));
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Validates passed value for cell and updates "errorMessage" property based on validation result.
|
|
547
|
+
*
|
|
548
|
+
* @param editedCell Cell to validate
|
|
549
|
+
* @param value
|
|
550
|
+
*/
|
|
551
|
+
validateCell(editedCell, value) {
|
|
552
|
+
const column = editedCell?.column;
|
|
553
|
+
let errorMessage = '';
|
|
554
|
+
if (column && typeof column.validate === 'function') {
|
|
555
|
+
errorMessage = column.validate(value);
|
|
556
|
+
}
|
|
557
|
+
if (editedCell && editedCell.errorMessage !== errorMessage) {
|
|
558
|
+
if (typeof editedCell.rowIndex === 'number' && editedCell.column?.key) {
|
|
559
|
+
const cell = (0, UITable_helper_1.getCellFromCoords)(editedCell.rowIndex, editedCell.column.key, this.props.columns, true);
|
|
560
|
+
const input = cell.querySelector('input');
|
|
561
|
+
this.caretPosition = input.selectionStart || 0;
|
|
562
|
+
}
|
|
563
|
+
editedCell.errorMessage = errorMessage || undefined;
|
|
564
|
+
// Rerender table to show error message
|
|
565
|
+
this.rerenderTable();
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* On Text input change.
|
|
570
|
+
*
|
|
571
|
+
* @param e
|
|
572
|
+
* @param newValue
|
|
573
|
+
*/
|
|
574
|
+
onTextInputChange(e, newValue = '') {
|
|
575
|
+
this.setState((prevState) => {
|
|
576
|
+
const editedCell = prevState.editedCell ?? this.activeElement;
|
|
577
|
+
if (editedCell) {
|
|
578
|
+
editedCell.newValue = newValue;
|
|
579
|
+
const column = editedCell.column;
|
|
580
|
+
if (column && typeof column.validate === 'function') {
|
|
581
|
+
this.validateCell(editedCell, newValue);
|
|
582
|
+
}
|
|
583
|
+
if (this.props.renderInputs) {
|
|
584
|
+
this.saveCell(false, newValue);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
return { editedCell };
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Gets input ref.
|
|
592
|
+
*
|
|
593
|
+
* @param rowIndex
|
|
594
|
+
* @param column
|
|
595
|
+
* @returns { React.RefObject<ITextField | IDropdown | HTMLDivElement> | undefined}
|
|
596
|
+
*/
|
|
597
|
+
_getInputRef(rowIndex, column) {
|
|
598
|
+
return typeof rowIndex === 'number' && typeof column?.key === 'string'
|
|
599
|
+
? this?.inputRefs?.[rowIndex]?.[column.key]
|
|
600
|
+
: undefined;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Renders dropdown.
|
|
604
|
+
*
|
|
605
|
+
* @param item
|
|
606
|
+
* @param rowIndex
|
|
607
|
+
* @param column
|
|
608
|
+
* @returns {any}
|
|
609
|
+
*/
|
|
610
|
+
_renderDropdown(item, rowIndex, column) {
|
|
611
|
+
const compRef = this._getInputRef(rowIndex, column);
|
|
612
|
+
return (react_1.default.createElement(UIDropdown_1.UIDropdown, { id: `dropdown_row${rowIndex}_col${column?.key}`, hidden: item.hideCells ?? false, placeholder: "Select an option", componentRef: compRef, options: column?.data.dropdownOptions, defaultSelectedKey: typeof column?.key === 'string' && item[column?.key]
|
|
613
|
+
? item[column?.key]
|
|
614
|
+
: column?.data.defaultSelectedKey, onChange: (ev, text) => this.onDropdownCellValueChange(text, item, rowIndex, column), onKeyDown: this.onKeyDown }));
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Renders combobox.
|
|
618
|
+
*
|
|
619
|
+
* @param item
|
|
620
|
+
* @param rowIndex
|
|
621
|
+
* @param column
|
|
622
|
+
* @returns {any}
|
|
623
|
+
*/
|
|
624
|
+
_renderCombobox(item, rowIndex, column) {
|
|
625
|
+
const compRef = this._getInputRef(rowIndex, column);
|
|
626
|
+
const newValue = this.state.editedCell?.newValue;
|
|
627
|
+
let value;
|
|
628
|
+
if (column?.fieldName) {
|
|
629
|
+
value = item[column?.fieldName];
|
|
630
|
+
}
|
|
631
|
+
if (typeof newValue !== 'undefined') {
|
|
632
|
+
value = newValue;
|
|
633
|
+
}
|
|
634
|
+
const options = column?.comboboxOptions?.map((o) => ({ key: o, text: o })) || [];
|
|
635
|
+
return (react_1.default.createElement(UIComboBox_1.UIComboBox, { highlight: true, defaultSelectedKey: value, allowFreeform: false, autoComplete: "on", shouldRestoreFocus: false, wrapperRef: compRef, errorMessage: this.state.editedCell?.errorMessage, openMenuOnClick: false, onPendingValueChanged: this.onComboBoxChange, onKeyDown: this.onKeyDown, onKeyDownCapture: this.onComboBoxKeyDownCapture, onClick: (e) => {
|
|
636
|
+
e.stopPropagation();
|
|
637
|
+
}, options: options }));
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Renders date picker.
|
|
641
|
+
*
|
|
642
|
+
* @param item
|
|
643
|
+
* @param rowIndex
|
|
644
|
+
* @param column
|
|
645
|
+
* @param dateOnly
|
|
646
|
+
* @returns {any}
|
|
647
|
+
*/
|
|
648
|
+
_renderDatePicker(item, rowIndex, column, dateOnly = true) {
|
|
649
|
+
const compRef = this._getInputRef(rowIndex, column);
|
|
650
|
+
const newValue = this.state.editedCell?.newValue;
|
|
651
|
+
let value;
|
|
652
|
+
if (column?.fieldName) {
|
|
653
|
+
value = item[column?.fieldName];
|
|
654
|
+
}
|
|
655
|
+
if (typeof newValue !== 'undefined') {
|
|
656
|
+
value = newValue;
|
|
657
|
+
}
|
|
658
|
+
return (react_1.default.createElement(UIDatePicker_1.UIDatePicker, { defaultValue: value, componentRef: compRef, dateOnly: dateOnly, errorMessage: this.state.editedCell?.errorMessage, onChange: this.onTextInputChange, onKeyDown: this.onKeyDown, onClick: (e) => {
|
|
659
|
+
e.stopPropagation();
|
|
660
|
+
} }));
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Renders text input.
|
|
664
|
+
*
|
|
665
|
+
* @param item
|
|
666
|
+
* @param rowIndex
|
|
667
|
+
* @param column
|
|
668
|
+
* @returns {any}
|
|
669
|
+
*/
|
|
670
|
+
_renderTextInput(item, rowIndex, column) {
|
|
671
|
+
const compRef = this._getInputRef(rowIndex, column);
|
|
672
|
+
const newValue = this.state.editedCell?.newValue;
|
|
673
|
+
let element;
|
|
674
|
+
let value;
|
|
675
|
+
if (column?.fieldName) {
|
|
676
|
+
value = item[column?.fieldName];
|
|
677
|
+
}
|
|
678
|
+
if (typeof newValue !== 'undefined') {
|
|
679
|
+
value = newValue;
|
|
680
|
+
}
|
|
681
|
+
if (!item.hideCells) {
|
|
682
|
+
element = (react_1.default.createElement(UIInput_1.UITextInput, { defaultValue: value, componentRef: compRef, errorMessage: this.state.editedCell?.errorMessage, onChange: this.onTextInputChange, onKeyDown: this.onKeyDown, onClick: (e) => {
|
|
683
|
+
e.stopPropagation();
|
|
684
|
+
} }));
|
|
685
|
+
}
|
|
686
|
+
return element;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* On cell render.
|
|
690
|
+
*
|
|
691
|
+
* @param item
|
|
692
|
+
* @param rowIndex
|
|
693
|
+
* @param column
|
|
694
|
+
* @returns {any}
|
|
695
|
+
*/
|
|
696
|
+
_onCellRender(item, rowIndex, column) {
|
|
697
|
+
// inputs & dropdowns always visible
|
|
698
|
+
if (this.props.renderInputs && rowIndex !== undefined) {
|
|
699
|
+
if (column?.columnControlType === types_1.ColumnControlType.UIDropdown) {
|
|
700
|
+
return this._renderDropdown(item, rowIndex, column);
|
|
701
|
+
}
|
|
702
|
+
return this._renderTextInput(item, rowIndex, column);
|
|
703
|
+
}
|
|
704
|
+
// inputs visible only in "edit mode" (after cell click)
|
|
705
|
+
const editedCell = this.state.editedCell;
|
|
706
|
+
const itsThisRow = editedCell && editedCell.rowIndex === rowIndex;
|
|
707
|
+
const itsThisCol = editedCell && editedCell.column?.key === column?.key;
|
|
708
|
+
const isCellInEditMode = itsThisRow && itsThisCol;
|
|
709
|
+
if (isCellInEditMode && rowIndex !== undefined) {
|
|
710
|
+
if (column?.columnControlType === types_1.ColumnControlType.UICombobox) {
|
|
711
|
+
return this._renderCombobox(item, rowIndex, column);
|
|
712
|
+
}
|
|
713
|
+
else if (column?.columnControlType === types_1.ColumnControlType.UIBooleanSelect) {
|
|
714
|
+
return this._renderCombobox(item, rowIndex, { ...column, comboboxOptions: ['true', 'false'] });
|
|
715
|
+
}
|
|
716
|
+
else if (column?.columnControlType === types_1.ColumnControlType.UIDatePicker) {
|
|
717
|
+
return this._renderDatePicker(item, rowIndex, column, column?.type === 'Date');
|
|
718
|
+
}
|
|
719
|
+
else {
|
|
720
|
+
return this._renderTextInput(item, rowIndex, column);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
const onClick = (e) => {
|
|
724
|
+
e.stopPropagation();
|
|
725
|
+
this._onCellClick(e, item, rowIndex || 0, column);
|
|
726
|
+
};
|
|
727
|
+
return (react_1.default.createElement("span", { style: { cursor: 'text', padding: 5 }, onClick: onClick }, item[column?.fieldName || 0]));
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* @returns {JSX.Element}
|
|
731
|
+
*/
|
|
732
|
+
render() {
|
|
733
|
+
// get columns & items from props, so that detailsListProps does not contain them
|
|
734
|
+
// because we want them to come from state, and be passed to component only once
|
|
735
|
+
let { columns, items, checkboxVisibility, headerRenderer, selectionMode } = this.props;
|
|
736
|
+
const { scrollablePaneProps, showRowNumbers, ...detailsListProps } = this.props;
|
|
737
|
+
// get them from state if they exist
|
|
738
|
+
if (this.state.columns) {
|
|
739
|
+
columns = this.state.columns;
|
|
740
|
+
}
|
|
741
|
+
if (this.state.items) {
|
|
742
|
+
items = this.state.items;
|
|
743
|
+
}
|
|
744
|
+
if (columns) {
|
|
745
|
+
columns.forEach((col) => {
|
|
746
|
+
col.onColumnClick = this._onColumnClick;
|
|
747
|
+
if (col.editable === true) {
|
|
748
|
+
col.onRender = this._onCellRender;
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
col.className = 'uneditable';
|
|
752
|
+
}
|
|
753
|
+
if (col.key === this.props.selectedColumnId) {
|
|
754
|
+
col.headerClassName = 'selected';
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
columns = (0, UITable_helper_1.addRowNumbers)(columns, showRowNumbers);
|
|
758
|
+
}
|
|
759
|
+
const styles = (0, UITable_helper_1.getStylesForSelectedCell)(this.state);
|
|
760
|
+
if (typeof checkboxVisibility === 'undefined') {
|
|
761
|
+
checkboxVisibility = react_2.CheckboxVisibility.hidden;
|
|
762
|
+
}
|
|
763
|
+
if (typeof selectionMode === 'undefined') {
|
|
764
|
+
selectionMode = react_2.SelectionMode.single;
|
|
765
|
+
}
|
|
766
|
+
if (typeof headerRenderer === 'undefined') {
|
|
767
|
+
headerRenderer = UITable_helper_1._onHeaderRender;
|
|
768
|
+
}
|
|
769
|
+
const focusZoneProps = {
|
|
770
|
+
direction: react_2.FocusZoneDirection.vertical,
|
|
771
|
+
shouldEnterInnerZone: (ev) => {
|
|
772
|
+
return ev.key === 'ArrowRight';
|
|
773
|
+
}
|
|
774
|
+
};
|
|
775
|
+
return (react_1.default.createElement(react_2.ScrollablePane, { ...scrollablePaneProps, styles: { stickyAbove: { zIndex: 2 } } },
|
|
776
|
+
react_1.default.createElement(react_2.DetailsList, { checkboxVisibility: checkboxVisibility, componentRef: this.tableRef, selection: this.selection, selectionMode: selectionMode, onRenderCheckbox: this._onRenderCheckbox, onRenderDetailsHeader: headerRenderer, onRenderField: this._onRenderField, onRenderRow: this._onRenderRow, onRenderItemColumn: this._onRenderItemColumn, layoutMode: react_2.DetailsListLayoutMode.fixedColumns, constrainMode: react_2.ConstrainMode.unconstrained, focusZoneProps: focusZoneProps, onActiveItemChanged: this._onCellActivation, ...detailsListProps, items: items, columns: columns, styles: styles })));
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
exports.UITable = UITable;
|
|
780
780
|
//# sourceMappingURL=UITable.js.map
|