@elyra/canvas 12.10.1 → 12.11.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.
Files changed (207) hide show
  1. package/dist/canvas-constants-7f93e705.js +2 -0
  2. package/dist/canvas-constants-7f93e705.js.map +1 -0
  3. package/dist/canvas-constants-ac5daafb.js +2 -0
  4. package/dist/canvas-constants-ac5daafb.js.map +1 -0
  5. package/dist/canvas-controller-09d0c333.js +2 -0
  6. package/dist/canvas-controller-09d0c333.js.map +1 -0
  7. package/dist/canvas-controller-c2793ca2.js +2 -0
  8. package/dist/canvas-controller-c2793ca2.js.map +1 -0
  9. package/dist/canvas-logger-815781bb.js +2 -0
  10. package/dist/canvas-logger-815781bb.js.map +1 -0
  11. package/dist/canvas-logger-a0f1beaa.js +2 -0
  12. package/dist/canvas-logger-a0f1beaa.js.map +1 -0
  13. package/dist/common-canvas-5b046a86.js +2 -0
  14. package/dist/common-canvas-5b046a86.js.map +1 -0
  15. package/dist/common-canvas-985cc0a2.js +2 -0
  16. package/dist/common-canvas-985cc0a2.js.map +1 -0
  17. package/dist/common-canvas.es.js +1 -1
  18. package/dist/common-canvas.es.js.map +1 -1
  19. package/dist/common-canvas.js +1 -1
  20. package/dist/common-canvas.js.map +1 -1
  21. package/dist/common-properties-4f471b2b.js +2 -0
  22. package/dist/common-properties-4f471b2b.js.map +1 -0
  23. package/dist/common-properties-9161cd27.js +2 -0
  24. package/dist/common-properties-9161cd27.js.map +1 -0
  25. package/dist/datarecord-metadata-v3-schema-bda88f2e.js +2 -0
  26. package/dist/datarecord-metadata-v3-schema-bda88f2e.js.map +1 -0
  27. package/dist/datarecord-metadata-v3-schema-d7ad05cd.js +2 -0
  28. package/dist/datarecord-metadata-v3-schema-d7ad05cd.js.map +1 -0
  29. package/dist/en-2ed89528.js +2 -0
  30. package/dist/en-2ed89528.js.map +1 -0
  31. package/dist/en-e93855cc.js +2 -0
  32. package/dist/en-e93855cc.js.map +1 -0
  33. package/dist/extends-39f57612.js +7 -0
  34. package/dist/extends-39f57612.js.map +1 -0
  35. package/dist/extends-51d9ddcc.js +7 -0
  36. package/dist/extends-51d9ddcc.js.map +1 -0
  37. package/dist/flexible-table-154a3359.js +2 -0
  38. package/dist/flexible-table-154a3359.js.map +1 -0
  39. package/dist/flexible-table-5e4a1e6d.js +2 -0
  40. package/dist/flexible-table-5e4a1e6d.js.map +1 -0
  41. package/dist/icon-811ffddd.js +2 -0
  42. package/dist/icon-811ffddd.js.map +1 -0
  43. package/dist/icon-d6909a68.js +2 -0
  44. package/dist/icon-d6909a68.js.map +1 -0
  45. package/dist/index-4fd90a14.js +2 -0
  46. package/dist/index-4fd90a14.js.map +1 -0
  47. package/dist/index-6d138021.js +2 -0
  48. package/dist/index-6d138021.js.map +1 -0
  49. package/dist/isArrayLikeObject-31e5e646.js +2 -0
  50. package/dist/isArrayLikeObject-31e5e646.js.map +1 -0
  51. package/dist/isArrayLikeObject-7c33c7fd.js +2 -0
  52. package/dist/isArrayLikeObject-7c33c7fd.js.map +1 -0
  53. package/dist/lib/canvas-controller.es.js +1 -1
  54. package/dist/lib/canvas-controller.js +1 -1
  55. package/dist/lib/canvas.es.js +1 -1
  56. package/dist/lib/canvas.js +1 -1
  57. package/dist/lib/context-menu.es.js +1 -1
  58. package/dist/lib/context-menu.es.js.map +1 -1
  59. package/dist/lib/context-menu.js +1 -1
  60. package/dist/lib/context-menu.js.map +1 -1
  61. package/dist/lib/properties/field-picker.es.js +1 -1
  62. package/dist/lib/properties/field-picker.js +1 -1
  63. package/dist/lib/properties/flexible-table.es.js +1 -1
  64. package/dist/lib/properties/flexible-table.js +1 -1
  65. package/dist/lib/properties.es.js +1 -1
  66. package/dist/lib/properties.js +1 -1
  67. package/dist/lib/tooltip.es.js +1 -1
  68. package/dist/lib/tooltip.es.js.map +1 -1
  69. package/dist/lib/tooltip.js +1 -1
  70. package/dist/lib/tooltip.js.map +1 -1
  71. package/dist/styles/common-canvas.min.css +1 -1
  72. package/dist/styles/common-canvas.min.css.map +1 -1
  73. package/dist/toolbar-335252dd.js +2 -0
  74. package/dist/toolbar-335252dd.js.map +1 -0
  75. package/dist/toolbar-85e6c77b.js +2 -0
  76. package/dist/toolbar-85e6c77b.js.map +1 -0
  77. package/locales/command-actions/locales/en.json +7 -1
  78. package/locales/command-actions/locales/eo.json +7 -1
  79. package/locales/command-actions/locales/index.js +3 -1
  80. package/locales/command-actions/locales/ko.json +9 -0
  81. package/locales/common-canvas/locales/en.json +1 -0
  82. package/locales/common-canvas/locales/eo.json +1 -0
  83. package/locales/common-canvas/locales/index.js +3 -1
  84. package/locales/common-canvas/locales/ko.json +32 -0
  85. package/locales/common-properties/locales/index.js +3 -1
  86. package/locales/common-properties/locales/ko.json +93 -0
  87. package/locales/palette/locales/index.js +3 -1
  88. package/locales/palette/locales/ko.json +10 -0
  89. package/locales/toolbar/locales/index.js +3 -1
  90. package/locales/toolbar/locales/ko.json +8 -0
  91. package/package.json +2 -1
  92. package/src/color-picker/color-picker-panel.jsx +61 -0
  93. package/src/color-picker/color-picker.jsx +37 -0
  94. package/src/color-picker/color-picker.scss +46 -0
  95. package/src/command-actions/colorSelectedObjectsAction.js +72 -0
  96. package/src/command-actions/deleteObjectsAction.js +16 -11
  97. package/src/command-actions/pasteAction.js +50 -21
  98. package/src/common-canvas/canvas-controller.js +32 -5
  99. package/src/common-canvas/cc-bottom-panel.jsx +34 -37
  100. package/src/common-canvas/cc-contents.jsx +110 -8
  101. package/src/common-canvas/cc-toolbar.jsx +3 -2
  102. package/src/common-canvas/common-canvas-utils.js +73 -90
  103. package/src/common-canvas/common-canvas.scss +28 -14
  104. package/src/common-canvas/constants/canvas-constants.js +17 -16
  105. package/src/common-canvas/label-util.js +1 -1
  106. package/src/common-canvas/svg-canvas-d3.js +20 -107
  107. package/src/common-canvas/svg-canvas-d3.scss +67 -6
  108. package/src/common-canvas/svg-canvas-pipeline.js +201 -0
  109. package/src/common-canvas/svg-canvas-renderer.js +325 -339
  110. package/src/common-canvas/svg-canvas-utils-links.js +3 -3
  111. package/src/common-canvas/svg-canvas-utils-nodes.js +22 -44
  112. package/src/common-properties/actions.js +4 -0
  113. package/src/common-properties/components/field-picker/field-picker.jsx +33 -36
  114. package/src/common-properties/components/field-picker/field-picker.scss +20 -23
  115. package/src/common-properties/components/flexible-table/flexible-table.jsx +46 -31
  116. package/src/common-properties/components/flexible-table/flexible-table.scss +14 -17
  117. package/src/common-properties/components/properties-buttons/properties-buttons.jsx +28 -21
  118. package/src/common-properties/components/table-buttons/table-buttons.jsx +3 -1
  119. package/src/common-properties/components/table-buttons/table-buttons.scss +8 -8
  120. package/src/common-properties/components/title-editor/title-editor.jsx +31 -4
  121. package/src/common-properties/components/title-editor/title-editor.scss +30 -5
  122. package/src/common-properties/components/virtualized-table/virtualized-table.jsx +119 -27
  123. package/src/common-properties/components/virtualized-table/virtualized-table.scss +72 -8
  124. package/src/common-properties/constants/constants.js +5 -1
  125. package/src/common-properties/constants/form-constants.js +1 -0
  126. package/src/common-properties/controls/abstract-table.jsx +12 -11
  127. package/src/common-properties/controls/abstract-table.scss +6 -2
  128. package/src/common-properties/controls/dropdown/dropdown.scss +4 -0
  129. package/src/common-properties/controls/expression/expression-builder/expression-select-field-function.jsx +2 -2
  130. package/src/common-properties/controls/expression/expression.scss +1 -1
  131. package/src/common-properties/controls/passwordfield/passwordfield.jsx +2 -2
  132. package/src/common-properties/controls/readonlytable/readonlytable.jsx +4 -2
  133. package/src/common-properties/controls/selectcolumns/selectcolumns.scss +0 -19
  134. package/src/common-properties/controls/someofselect/someofselect.scss +2 -2
  135. package/src/common-properties/form/ControlInfo.js +8 -0
  136. package/src/common-properties/form/EditorForm.js +4 -0
  137. package/src/common-properties/form/ParameterInfo.js +4 -0
  138. package/src/common-properties/panels/sub-panel/cell.jsx +18 -23
  139. package/src/common-properties/panels/sub-panel/sub-panel.scss +5 -22
  140. package/src/common-properties/properties-controller.js +18 -0
  141. package/src/common-properties/properties-main/properties-main.jsx +15 -9
  142. package/src/common-properties/properties-main/properties-main.scss +9 -2
  143. package/src/common-properties/properties-store.js +27 -1
  144. package/src/common-properties/reducers/properties-settings.js +17 -1
  145. package/src/context-menu/common-context-menu.jsx +74 -29
  146. package/src/context-menu/context-menu-wrapper.jsx +2 -2
  147. package/src/icons/icon.jsx +5 -46
  148. package/src/index.scss +1 -0
  149. package/src/object-model/api-pipeline.js +26 -43
  150. package/src/object-model/object-model.js +27 -3
  151. package/src/object-model/redux/canvas-store.js +68 -0
  152. package/src/object-model/redux/reducers/canvasinfo.js +36 -0
  153. package/src/object-model/redux/reducers/comments.js +58 -10
  154. package/src/object-model/redux/reducers/externalpipelineflows.js +1 -0
  155. package/src/object-model/redux/reducers/links.js +9 -7
  156. package/src/object-model/redux/reducers/selectioninfo.js +2 -1
  157. package/src/palette/palette-content-list-item.jsx +8 -1
  158. package/src/palette/palette-dialog-content-grid-node.jsx +8 -1
  159. package/src/palette/palette-flyout-utils.js +3 -3
  160. package/src/toolbar/toolbar-action-item.jsx +75 -11
  161. package/src/toolbar/toolbar-overflow-item.jsx +2 -3
  162. package/src/tooltip/tooltip.jsx +4 -1
  163. package/stats.html +1 -1
  164. package/dist/canvas-constants-af93267a.js +0 -2
  165. package/dist/canvas-constants-af93267a.js.map +0 -1
  166. package/dist/canvas-constants-ffce3b78.js +0 -2
  167. package/dist/canvas-constants-ffce3b78.js.map +0 -1
  168. package/dist/canvas-controller-27101eb5.js +0 -2
  169. package/dist/canvas-controller-27101eb5.js.map +0 -1
  170. package/dist/canvas-controller-a57e3b7a.js +0 -2
  171. package/dist/canvas-controller-a57e3b7a.js.map +0 -1
  172. package/dist/common-canvas-f409dcd4.js +0 -2
  173. package/dist/common-canvas-f409dcd4.js.map +0 -1
  174. package/dist/common-canvas-f6fc2fff.js +0 -2
  175. package/dist/common-canvas-f6fc2fff.js.map +0 -1
  176. package/dist/common-properties-653e50e3.js +0 -2
  177. package/dist/common-properties-653e50e3.js.map +0 -1
  178. package/dist/common-properties-e2c6def7.js +0 -2
  179. package/dist/common-properties-e2c6def7.js.map +0 -1
  180. package/dist/datarecord-metadata-v3-schema-10ddafaf.js +0 -2
  181. package/dist/datarecord-metadata-v3-schema-10ddafaf.js.map +0 -1
  182. package/dist/datarecord-metadata-v3-schema-1504c843.js +0 -2
  183. package/dist/datarecord-metadata-v3-schema-1504c843.js.map +0 -1
  184. package/dist/en-517f38fc.js +0 -2
  185. package/dist/en-517f38fc.js.map +0 -1
  186. package/dist/en-dc6f2e9f.js +0 -2
  187. package/dist/en-dc6f2e9f.js.map +0 -1
  188. package/dist/extends-5a45f92e.js +0 -7
  189. package/dist/extends-5a45f92e.js.map +0 -1
  190. package/dist/extends-a52336ca.js +0 -8
  191. package/dist/extends-a52336ca.js.map +0 -1
  192. package/dist/flexible-table-e6ccbe58.js +0 -2
  193. package/dist/flexible-table-e6ccbe58.js.map +0 -1
  194. package/dist/flexible-table-f60c1680.js +0 -2
  195. package/dist/flexible-table-f60c1680.js.map +0 -1
  196. package/dist/index-567978da.js +0 -2
  197. package/dist/index-567978da.js.map +0 -1
  198. package/dist/index-59486e9a.js +0 -2
  199. package/dist/index-59486e9a.js.map +0 -1
  200. package/dist/isEmpty-def8f509.js +0 -2
  201. package/dist/isEmpty-def8f509.js.map +0 -1
  202. package/dist/isEmpty-e171b734.js +0 -2
  203. package/dist/isEmpty-e171b734.js.map +0 -1
  204. package/dist/toolbar-404bf690.js +0 -2
  205. package/dist/toolbar-404bf690.js.map +0 -1
  206. package/dist/toolbar-611d8ab9.js +0 -2
  207. package/dist/toolbar-611d8ab9.js.map +0 -1
@@ -47,28 +47,35 @@ class PropertiesButtons extends Component {
47
47
  </Button>
48
48
  );
49
49
  }
50
- const applyButton = (
51
- <Button
52
- data-id="properties-apply-button"
53
- className="properties-apply-button"
54
- type="button"
55
- size="small"
56
- onClick={this.props.okHandler}
57
- disabled={!this.props.applyButtonEnabled}
58
- >
59
- {applyButtonLabel}
60
- </Button>
61
- );
50
+ let applyButton;
51
+ if (this.props.okHandler) {
52
+ applyButton = (
53
+ <Button
54
+ data-id="properties-apply-button"
55
+ className="properties-apply-button"
56
+ type="button"
57
+ size="small"
58
+ onClick={this.props.okHandler}
59
+ disabled={!this.props.applyButtonEnabled}
60
+ >
61
+ {applyButtonLabel}
62
+ </Button>
63
+ );
64
+ }
65
+
66
+ const propertiesModalButtons = this.props.okHandler || this.props.cancelHandler
67
+ ? (
68
+ <div
69
+ className={classNames("properties-modal-buttons", { "hide": (typeof (this.props.showPropertiesButtons) !== "undefined" &&
70
+ !this.props.showPropertiesButtons) })}
71
+ >
72
+ {rejectButton}
73
+ {applyButton}
74
+ </div>
75
+ )
76
+ : null;
62
77
 
63
- return (
64
- <div
65
- className={classNames("properties-modal-buttons", { "hide": (typeof (this.props.showPropertiesButtons) !== "undefined" &&
66
- !this.props.showPropertiesButtons) })}
67
- >
68
- {rejectButton}
69
- {applyButton}
70
- </div>
71
- );
78
+ return propertiesModalButtons;
72
79
  }
73
80
  }
74
81
 
@@ -17,7 +17,8 @@
17
17
 
18
18
  import React from "react";
19
19
  import PropTypes from "prop-types";
20
- import Toolbar from "../../../toolbar/toolbar.jsx";
20
+
21
+ import Toolbar from "../../../toolbar/toolbar";
21
22
 
22
23
  import { STATES } from "./../../constants/constants";
23
24
 
@@ -84,6 +85,7 @@ class TableButtons extends React.Component {
84
85
  if (buttonConfig.label) {
85
86
  buttonDef.label = buttonConfig.label.text;
86
87
  buttonDef.incLabelWithIcon = "before";
88
+ buttonDef.kind = "ghost";
87
89
  }
88
90
 
89
91
  if (buttonConfig.description) {
@@ -16,28 +16,28 @@
16
16
 
17
17
  .properties-custom-table-buttons {
18
18
  .toolbar-div {
19
- height: 32px;
19
+ height: $spacing-07;
20
20
 
21
21
  .toolbar-left-bar {
22
22
  padding-right: 0;
23
23
 
24
24
  .toolbar-item button {
25
- height: 32px;
25
+ height: $spacing-07;
26
26
  }
27
27
 
28
28
  .toolbar-item-content {
29
- padding: 3px 7px;
30
- height: 32px;
31
- min-width: 32px;
29
+ padding: $spacing-02 $spacing-03;
30
+ height: $spacing-07;
31
+ min-width: $spacing-07;
32
32
  align-items: center;
33
33
  }
34
34
 
35
35
  .toolbar-overflow-item button {
36
- height: 32px;
36
+ height: $spacing-07;
37
37
  }
38
38
 
39
39
  .toolbar-popover-list {
40
- top: 32px;
40
+ top: $spacing-07;
41
41
  right: 0;
42
42
  }
43
43
  }
@@ -46,4 +46,4 @@
46
46
  display: none;
47
47
  }
48
48
  }
49
- }
49
+ }
@@ -24,7 +24,7 @@ import { TextInput, Button } from "carbon-components-react";
24
24
  import { MESSAGE_KEYS, CONDITION_MESSAGE_TYPE } from "./../../constants/constants";
25
25
  import * as PropertyUtils from "./../../util/property-utils";
26
26
  import classNames from "classnames";
27
- import { Information16, Edit16 } from "@carbon/icons-react";
27
+ import { Information16, Edit16, Close16 } from "@carbon/icons-react";
28
28
 
29
29
 
30
30
  class TitleEditor extends Component {
@@ -95,7 +95,10 @@ class TitleEditor extends Component {
95
95
  render() {
96
96
  const propertiesTitleEditButtonLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.TITLE_EDITOR_LABEL);
97
97
  const helpButtonLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.TITLE_EDITOR_HELPBUTTON_LABEL);
98
+ const closeButtonLabel = PropertyUtils.formatMessage(this.props.controller.getReactIntl(), MESSAGE_KEYS.PROPERTIESEDIT_CLOSEBUTTON_LABEL);
98
99
  const titleValidationTypes = [CONDITION_MESSAGE_TYPE.ERROR, CONDITION_MESSAGE_TYPE.WARNING];
100
+ const titleWithWarning = get(this.state.titleValidation, "type", null) === CONDITION_MESSAGE_TYPE.WARNING;
101
+ const titleWithErrror = get(this.state.titleValidation, "type", null) === CONDITION_MESSAGE_TYPE.ERROR;
99
102
 
100
103
  const propertiesTitleEdit = this.props.labelEditable === false || this.state.focused ? <div />
101
104
  : (<Button
@@ -106,6 +109,7 @@ class TitleEditor extends Component {
106
109
  tooltipPosition="bottom"
107
110
  tooltipAlignment="end"
108
111
  renderIcon={Edit16}
112
+ size="small"
109
113
  iconDescription={propertiesTitleEditButtonLabel}
110
114
  hasIconOnly
111
115
  />);
@@ -118,11 +122,27 @@ class TitleEditor extends Component {
118
122
  onClick={this.helpClickHandler}
119
123
  tooltipPosition="bottom"
120
124
  renderIcon={Information16}
125
+ size="small"
121
126
  iconDescription={helpButtonLabel}
122
127
  hasIconOnly
123
128
  />)
124
129
  : null;
125
130
 
131
+ const closeButton = this.props.closeHandler
132
+ ? (<div className="properties-close-button">
133
+ <Button
134
+ kind="ghost"
135
+ size="small"
136
+ data-id="close"
137
+ onClick={this.props.closeHandler}
138
+ tooltipPosition="left"
139
+ renderIcon={Close16}
140
+ iconDescription={closeButtonLabel}
141
+ hasIconOnly
142
+ />
143
+ </div>)
144
+ : null;
145
+
126
146
  let heading = null;
127
147
  if (this.headingEnabled) {
128
148
  const label = this.props.heading
@@ -146,10 +166,15 @@ class TitleEditor extends Component {
146
166
  <div className={classNames("properties-title-editor",
147
167
  { "properties-title-with-heading": this.headingEnabled })}
148
168
  >
169
+ {closeButton}
149
170
  {heading}
150
171
  <div className={classNames(
151
172
  "properties-title-editor-input",
152
- { "properties-title-editor-with-help": this.props.help && !this.headingEnabled && !titleValidationTypes.includes(get(this.state.titleValidation, "type")) }
173
+ {
174
+ "properties-title-editor-with-help": this.props.help && !this.headingEnabled && !titleValidationTypes.includes(get(this.state.titleValidation, "type")),
175
+ "properties-title-editor-with-warning": titleWithWarning,
176
+ "properties-title-editor-with-error": titleWithErrror
177
+ }
153
178
  )}
154
179
  >
155
180
  <TextInput
@@ -161,12 +186,13 @@ class TitleEditor extends Component {
161
186
  readOnly={this.props.labelEditable === false} // shows a non editable icon
162
187
  labelText={this.labelText}
163
188
  hideLabel
189
+ size="sm"
164
190
  onFocus={this.textInputOnFocus}
165
191
  onBlur={this.textInputOnBlur}
166
192
  light={this.props.controller.getLight()}
167
- invalid={get(this.state.titleValidation, "type", null) === CONDITION_MESSAGE_TYPE.ERROR}
193
+ invalid={titleWithErrror}
168
194
  invalidText={get(this.state.titleValidation, "message")}
169
- warn={get(this.state.titleValidation, "type", null) === CONDITION_MESSAGE_TYPE.WARNING}
195
+ warn={titleWithWarning}
170
196
  warnText={get(this.state.titleValidation, "message")}
171
197
  {... this.state.focused && { className: "properties-title-editor-focused" }}
172
198
  />
@@ -180,6 +206,7 @@ class TitleEditor extends Component {
180
206
 
181
207
  TitleEditor.propTypes = {
182
208
  helpClickHandler: PropTypes.func,
209
+ closeHandler: PropTypes.func,
183
210
  controller: PropTypes.object.isRequired,
184
211
  labelEditable: PropTypes.bool,
185
212
  help: PropTypes.object,
@@ -39,14 +39,14 @@
39
39
  }
40
40
  }
41
41
  .properties-title-editor-input {
42
- width: calc(100% - 2px); // subtract 2px for input active right border
42
+ width: calc(100% - #{$spacing-03}); // subtract 8px to align with Close icon when applyOnBlur is set
43
43
  top: 1px; // align input with bottom border
44
44
  position: relative;
45
45
  display: inline-flex;
46
46
  align-items: center;
47
47
 
48
48
  &.properties-title-editor-with-help {
49
- width: calc(100% - #{$spacing-08}); // subtract the size of the help button
49
+ width: calc(100% - #{$spacing-07} - #{$spacing-03}); // subtract the size of the help button and 8px to align with Close icon when applyOnBlur is set
50
50
  }
51
51
  .bx--form-item.bx--text-input-wrapper {
52
52
  // allow edit icon to be at the end of text input
@@ -79,11 +79,16 @@
79
79
  }
80
80
  }
81
81
 
82
+ // warning and invalid icons should be aligned with close icon. And input field should stretch full width
83
+ .properties-title-editor-with-warning, .properties-title-editor-with-error {
84
+ width: calc(100% - 2px); // subtract 2px for input active right border
85
+ }
86
+
82
87
  .properties-title-editor-btn.help, .properties-title-editor-btn.edit {
83
88
  fill: $icon-02;
84
- // edit & help buttons size - 40x40
85
- width: $spacing-08;
86
- min-height: $spacing-08;
89
+ // edit & help buttons size - 32x32
90
+ width: $spacing-07;
91
+ min-height: $spacing-07;
87
92
  padding-left: $spacing-04;
88
93
  padding-right: $spacing-04;
89
94
  &:hover {
@@ -93,3 +98,23 @@
93
98
  background-color: $ui-03;
94
99
  }
95
100
  }
101
+
102
+ // Close icon without heading
103
+ .properties-close-button {
104
+ position: relative;
105
+ display: flex;
106
+ align-items: center;
107
+ justify-content: flex-end;
108
+ padding-right: $spacing-03;
109
+ }
110
+
111
+ // Close icon with heading
112
+ .properties-title-with-heading > .properties-close-button {
113
+ position: absolute;
114
+ top: $spacing-03;
115
+ right: $spacing-03;
116
+ display: flex;
117
+ align-items: center;
118
+ justify-content: center;
119
+ padding: 0;
120
+ }
@@ -15,15 +15,15 @@
15
15
  */
16
16
 
17
17
  import { Column, Table, AutoSizer } from "react-virtualized";
18
-
18
+ import Draggable from "react-draggable";
19
19
  import { Checkbox, Loading } from "carbon-components-react";
20
- import Icon from "./../../../icons/icon.jsx";
20
+ import { ArrowUp16, ArrowDown16, ArrowsVertical16 } from "@carbon/icons-react";
21
21
  import Tooltip from "./../../../tooltip/tooltip.jsx";
22
- import { SORT_DIRECTION, STATES, ROW_SELECTION, CARBON_ICONS } from "./../../constants/constants";
22
+ import { SORT_DIRECTION, STATES, ROW_SELECTION, MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH_WITHOUT_LABEL } from "./../../constants/constants";
23
23
  import { injectIntl } from "react-intl";
24
24
  import defaultMessages from "../../../../locales/common-properties/locales/en.json";
25
25
 
26
- import { isEmpty } from "lodash";
26
+ import { isEmpty, differenceBy } from "lodash";
27
27
  import { v4 as uuid4 } from "uuid";
28
28
  import classNames from "classnames";
29
29
 
@@ -33,17 +33,25 @@ import React from "react";
33
33
  class VirtualizedTable extends React.Component {
34
34
 
35
35
  static getDerivedStateFromProps(nextProps, prevState) {
36
+ const updatedState = {};
36
37
  if (nextProps.rowCount !== prevState.rowCount) {
37
- return ({ rowCount: nextProps.rowCount });
38
+ updatedState.rowCount = nextProps.rowCount;
39
+ }
40
+ // Only get new columns if column label (headerLabel) is different. This is useful when changing "View in tables" dropdown in Expression control.
41
+ // We're not comparing all properties in columns object because width can be different after resizing.
42
+ if (!prevState.columnResized || !isEmpty(differenceBy(nextProps.columns, prevState.columns, "headerLabel"))) {
43
+ updatedState.columns = nextProps.columns;
38
44
  }
39
- return ({});
45
+ return (updatedState);
40
46
  }
41
47
 
42
48
  constructor(props, context) {
43
49
  super(props, context);
44
50
 
45
51
  this.state = {
46
- rowCount: this.props.rowCount
52
+ rowCount: this.props.rowCount,
53
+ columns: this.props.columns,
54
+ columnResized: false
47
55
  };
48
56
  this.virtualizedTableRef = React.createRef();
49
57
 
@@ -56,6 +64,7 @@ class VirtualizedTable extends React.Component {
56
64
  this.headerColRenderer = this.headerColRenderer.bind(this);
57
65
  this.onRowClick = this.onRowClick.bind(this);
58
66
  this.overSelectOption = this.overSelectOption.bind(this);
67
+ this.resizeColumn = this.resizeColumn.bind(this);
59
68
  }
60
69
 
61
70
  componentDidUpdate() {
@@ -101,6 +110,11 @@ class VirtualizedTable extends React.Component {
101
110
  return 0;
102
111
  }
103
112
 
113
+ getColumnIndex(columns, key) {
114
+ const index = columns.findIndex((column) => column.key === key);
115
+ return index;
116
+ }
117
+
104
118
  isRowSelected(index) {
105
119
  if (this.props.rowsSelected) {
106
120
  return this.props.rowsSelected.indexOf(index) > -1;
@@ -108,6 +122,12 @@ class VirtualizedTable extends React.Component {
108
122
  return false;
109
123
  }
110
124
 
125
+ isLastColumn(dataKey) {
126
+ const columnIndex = this.getColumnIndex(this.props.columns, dataKey);
127
+ const isLastColumn = (columnIndex === (this.props.columns.length - 1));
128
+ return isLastColumn;
129
+ }
130
+
111
131
  selectAll(selected) {
112
132
  this.props.setAllRowsSelected(selected);
113
133
  }
@@ -161,12 +181,20 @@ class VirtualizedTable extends React.Component {
161
181
  headerColRenderer({ columnData, dataKey, disableSort, label, sortBy, sortDirection }) {
162
182
  let sortIcon = null;
163
183
  if (typeof this.props.sortColumns[dataKey] !== "undefined") {
164
- sortIcon = this.props.sortColumns[dataKey] === SORT_DIRECTION.ASC
165
- ? <Icon type={CARBON_ICONS.CHEVRONARROWS.UP} disabled={this.props.tableState === STATES.DISABLED} />
166
- : <Icon type={CARBON_ICONS.CHEVRONARROWS.DOWN} disabled={this.props.tableState === STATES.DISABLED} />;
167
- sortIcon = (<div className="properties-ft-column-sort-icon">
168
- {sortIcon}
169
- </div>);
184
+ let type = null;
185
+ switch (this.props.sortColumns[dataKey]) {
186
+ case SORT_DIRECTION.ASC:
187
+ type = <ArrowUp16 disabled={this.props.tableState === STATES.DISABLED} />;
188
+ break;
189
+ case SORT_DIRECTION.DESC:
190
+ type = <ArrowDown16 disabled={this.props.tableState === STATES.DISABLED} />;
191
+ break;
192
+ default:
193
+ type = <ArrowsVertical16 disabled={this.props.tableState === STATES.DISABLED} />;
194
+ }
195
+ sortIcon = (<span className="properties-ft-column-sort-icon">
196
+ {type}
197
+ </span>);
170
198
  }
171
199
 
172
200
  let tooltip = null;
@@ -194,20 +222,84 @@ class VirtualizedTable extends React.Component {
194
222
 
195
223
  const tooltipId = uuid4() + "-tooltip-column-" + dataKey;
196
224
 
197
- return (<div className={classNames("properties-vt-column properties-tooltips-container", { "sort-column-active": dataKey === this.props.sortBy })}>
198
- { isEmpty(tooltip)
199
- ? label
200
- : <Tooltip
201
- id={tooltipId}
202
- tip={tooltip}
203
- direction="bottom"
204
- className="properties-tooltips"
205
- >
206
- {label}
207
- </Tooltip>
225
+ const resizeElem = columnData.resizable && !this.isLastColumn(dataKey)
226
+ ? (<Draggable
227
+ axis="x"
228
+ defaultClassName="properties-vt-header-resize"
229
+ defaultClassNameDragging="properties-vt-header-resize-active"
230
+ onDrag={
231
+ (evt, { deltaX }) => {
232
+ this.resizeColumn({ dataKey, deltaX });
233
+ }
234
+ }
235
+ position={{ x: 0 }}
236
+ zIndex={999}
237
+ >
238
+ <div
239
+ role="button" tabIndex="0"
240
+ aria-label="Resize column"
241
+ />
242
+ </Draggable>)
243
+ : "";
244
+
245
+ return (
246
+ <div className={classNames({ "properties-vt-column-with-resize": resizeElem !== "", "properties-vt-column-without-resize": resizeElem === "" })}>
247
+ <div className={classNames("properties-vt-column properties-tooltips-container", { "sort-column-active": dataKey === this.props.sortBy })}>
248
+ { isEmpty(tooltip)
249
+ ? label
250
+ : <Tooltip
251
+ id={tooltipId}
252
+ tip={tooltip}
253
+ direction="bottom"
254
+ className="properties-tooltips"
255
+ >
256
+ {label}
257
+ </Tooltip>
258
+ }
259
+ {disableSort === false && sortIcon}
260
+ </div>
261
+ { resizeElem }
262
+ </div>
263
+ );
264
+ }
265
+
266
+ /* Columns are not resizable by default. Host application specifies resizable columns in parameter definition.
267
+ * When a column is resized, width of ALL the columns to the right of resized column is adjusted.
268
+ * Example: If a column width is reduced by 10px and there are 5 columns on the right of resized column. Each of the 5 columns width is increased by 2px (10px/number of columns)
269
+ * When any column's width reaches MINIMUM_COLUMN_WIDTH (56px), resizing is stopped.
270
+ * Special case - For columns without labels, when their width reaches MINIMUM_COLUMN_WIDTH_WITHOUT_LABEL (32px), resizing is stopped.
271
+ */
272
+ resizeColumn({ dataKey, deltaX }) {
273
+ this.setState((prevState) => {
274
+
275
+ const columns = prevState.columns;
276
+ // Calculate number of columns on the right of resized column
277
+ const resizedColumnIndex = this.getColumnIndex(columns, dataKey);
278
+ const numberOfColumnsOnTheRight = columns.length - 1 - resizedColumnIndex;
279
+ const rightColumnsDelta = deltaX / numberOfColumnsOnTheRight;
280
+
281
+ // Verify adjusted width of every column on the right is greater than minimum width
282
+ const everyColumnGreaterThanMinWidth = columns.slice(resizedColumnIndex + 1).every((col) => {
283
+ if (col.headerLabel.length > 0) {
284
+ // Column with label has min width 56px
285
+ return (col.width - rightColumnsDelta > MINIMUM_COLUMN_WIDTH);
286
+ }
287
+ // Column without label has min width 32px
288
+ return (col.width - rightColumnsDelta > MINIMUM_COLUMN_WIDTH_WITHOUT_LABEL);
289
+ });
290
+
291
+ if ((columns[resizedColumnIndex].width + deltaX) > MINIMUM_COLUMN_WIDTH && everyColumnGreaterThanMinWidth) {
292
+ columns[resizedColumnIndex].width += deltaX;
293
+ // Adjust width of all columns on the right
294
+ for (let i = resizedColumnIndex + 1; i < columns.length; i++) {
295
+ columns[i].width -= rightColumnsDelta;
296
+ }
208
297
  }
209
- {disableSort === false && sortIcon}
210
- </div>);
298
+ return {
299
+ columnResized: true,
300
+ columns: columns
301
+ };
302
+ });
211
303
  }
212
304
 
213
305
  overSelectOption(evt) {
@@ -353,7 +445,7 @@ class VirtualizedTable extends React.Component {
353
445
  sortDirection={this.props.sortDirection}
354
446
  >
355
447
  {
356
- this.props.columns.map((column) => (
448
+ this.state.columns.map((column) => (
357
449
  <Column
358
450
  key={column.key}
359
451
  label={column.label}
@@ -14,12 +14,10 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- $properties-vt-checkbox-width: 45px;
18
17
 
19
18
  .properties-vt {
20
19
  width: 100%;
21
20
  height: 100%;
22
- background: $ui-02;
23
21
 
24
22
  .properties-autosized-vt {
25
23
  // Table rows container
@@ -41,14 +39,22 @@ $properties-vt-checkbox-width: 45px;
41
39
  height: $spacing-07;
42
40
  display: flex;
43
41
  align-items: center;
44
- flex: 0 1 $properties-vt-checkbox-width;
45
42
  margin-left: $spacing-05;
43
+ margin-right: $spacing-02;
44
+ }
45
+
46
+ div[data-role="properties-header-row"] {
47
+ background-color: $ui-03;
48
+ }
49
+
50
+ div[data-role="properties-data-row"] {
51
+ background-color: $ui-02;
46
52
  }
47
53
 
48
54
  .properties-autosized-vt-header {
49
55
  // Override text-transform: uppercase from .ReactVirtualized__Table__headerRow
50
56
  text-transform: none;
51
-
57
+ margin-left: 0;
52
58
  .properties-vt-column .bx--checkbox-wrapper {
53
59
  margin-top: 0;
54
60
  margin-bottom: 0;
@@ -68,10 +74,36 @@ $properties-vt-checkbox-width: 45px;
68
74
  }
69
75
  }
70
76
 
77
+ .properties-vt-column-with-resize, .properties-vt-column-without-resize {
78
+ display: inline-flex;
79
+ width: 100%;
80
+ }
81
+
82
+ .properties-vt-column-with-resize {
83
+ .properties-vt-header-resize {
84
+ flex: 0 0 $spacing-02;
85
+ z-index: 2;
86
+ cursor: col-resize;
87
+ }
88
+ .properties-vt-header-resize:hover {
89
+ background-color: $active-secondary;
90
+ }
91
+
92
+ .properties-vt-header-resize-active {
93
+ z-index: 3;
94
+ }
95
+ &:hover {
96
+ background-color: $active-ui;
97
+ .properties-vt-header-resize {
98
+ background-color: $active-secondary;
99
+ }
100
+ }
101
+ }
102
+
71
103
  .properties-vt-row-checkbox {
72
104
  height: $spacing-07;
73
105
  margin-left: $spacing-05;
74
- flex: 0 1 $properties-vt-checkbox-width;
106
+ margin-right: $spacing-02;
75
107
  }
76
108
 
77
109
  .properties-vt-double-click:first-of-type {
@@ -111,7 +143,30 @@ $properties-vt-checkbox-width: 45px;
111
143
  // Required to position the warning/error icons correctly within react-virtualized table cell
112
144
  .ReactVirtualized__Table__headerColumn {
113
145
  margin-right: 0;
114
- margin-left: $spacing-04;
146
+ display: flex;
147
+ flex-direction: row;
148
+ justify-content: center;
149
+ height: 100%;
150
+ }
151
+
152
+ .ReactVirtualized__Table__rowColumn {
153
+ margin-right: 0; // Align cell text with header label
154
+ margin-left: 0;
155
+ }
156
+
157
+ // Override padding for sortable columns to show space between column label and sort icon
158
+ .ReactVirtualized__Table__sortableHeaderColumn {
159
+ .properties-tooltips-container {
160
+ padding: 0;
161
+ padding-left: $spacing-05;
162
+ }
163
+ &:hover {
164
+ background-color: $active-ui;
165
+ }
166
+ }
167
+
168
+ .ReactVirtualized__Table__headerTruncatedText {
169
+ flex: auto;
115
170
  }
116
171
  }
117
172
 
@@ -126,7 +181,7 @@ $properties-vt-checkbox-width: 45px;
126
181
  .properties-vt-single-selection {
127
182
  // Table header
128
183
  div[data-role="properties-header-row"] {
129
- padding-left: 9px;
184
+ padding-left: 3px;
130
185
  }
131
186
 
132
187
  // Table rows
@@ -153,9 +208,18 @@ $properties-vt-checkbox-width: 45px;
153
208
  }
154
209
 
155
210
  .properties-light-disabled {
156
- background-color: $ui-01;
211
+ div[data-role="properties-data-row"] {
212
+ background-color: $ui-01;
213
+ }
157
214
  .bx--select--inline .bx--select-input[disabled] {
158
215
  background-color: $ui-background;
159
216
  }
160
217
  }
218
+
219
+ .properties-ft-column-sort-icon {
220
+ flex: 0 0 $spacing-05;
221
+ align-self: center;
222
+ height: $spacing-05;
223
+ margin-right: $spacing-03; // spacing between sort icon and end of column
224
+ }
161
225
  }
@@ -187,7 +187,8 @@ export const CONDITION_RETURN_VALUE_HANDLING = {
187
187
 
188
188
  export const SORT_DIRECTION = {
189
189
  ASC: "ASC",
190
- DESC: "DESC"
190
+ DESC: "DESC",
191
+ NOT_SORTED: "not-sorted"
191
192
  };
192
193
 
193
194
  export const ROW_SELECTION = {
@@ -225,3 +226,6 @@ export const CANCEL = "cancel";
225
226
  export const CARBON_MODAL_SIZE_XSMALL = "xs";
226
227
  export const CARBON_MODAL_SIZE_SMALL = "sm";
227
228
  export const CARBON_MODAL_SIZE_LARGE = "lg";
229
+
230
+ export const MINIMUM_COLUMN_WIDTH = 56; // 16px padding on both sides + 24px label
231
+ export const MINIMUM_COLUMN_WIDTH_WITHOUT_LABEL = 32; // 16px padding on both sides
@@ -122,6 +122,7 @@ const Type = {
122
122
  PASSWORD: "password",
123
123
  DATE: "date",
124
124
  TIME: "time",
125
+ TIMESTAMP: "timestamp",
125
126
  STRUCTURE: "structure",
126
127
  OBJECT: "object"
127
128
  };