@teselagen/ui 0.7.34 → 0.7.36

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 (161) hide show
  1. package/isBeingCalledExcessively.js +2 -0
  2. package/package.json +1 -1
  3. package/style.css +26 -10
  4. package/DataTable/utils/filterLocalEntitiesToHasura.d.ts +0 -5
  5. package/DataTable/utils/initializeHasuraWhereAndFilter.d.ts +0 -2
  6. package/DataTable/utils/tableQueryParamsToHasuraClauses.d.ts +0 -26
  7. package/src/AdvancedOptions.js +0 -33
  8. package/src/AdvancedOptions.spec.js +0 -26
  9. package/src/AssignDefaultsModeContext.js +0 -22
  10. package/src/AsyncValidateFieldSpinner/index.js +0 -12
  11. package/src/BlueprintError/index.js +0 -14
  12. package/src/BounceLoader/index.js +0 -16
  13. package/src/BounceLoader/style.css +0 -45
  14. package/src/CollapsibleCard/index.js +0 -68
  15. package/src/CollapsibleCard/style.css +0 -23
  16. package/src/DNALoader/index.js +0 -20
  17. package/src/DNALoader/style.css +0 -251
  18. package/src/DataTable/CellDragHandle.js +0 -132
  19. package/src/DataTable/ColumnFilterMenu.js +0 -62
  20. package/src/DataTable/Columns.js +0 -979
  21. package/src/DataTable/DisabledLoadingComponent.js +0 -15
  22. package/src/DataTable/DisplayOptions.js +0 -199
  23. package/src/DataTable/DropdownCell.js +0 -61
  24. package/src/DataTable/EditableCell.js +0 -44
  25. package/src/DataTable/FilterAndSortMenu.js +0 -388
  26. package/src/DataTable/PagingTool.js +0 -225
  27. package/src/DataTable/RenderCell.js +0 -191
  28. package/src/DataTable/SearchBar.js +0 -69
  29. package/src/DataTable/SortableColumns.js +0 -100
  30. package/src/DataTable/TableFormTrackerContext.js +0 -10
  31. package/src/DataTable/ThComponent.js +0 -44
  32. package/src/DataTable/dataTableEnhancer.js +0 -41
  33. package/src/DataTable/defaultFormatters.js +0 -32
  34. package/src/DataTable/defaultValidators.js +0 -40
  35. package/src/DataTable/editCellHelper.js +0 -44
  36. package/src/DataTable/getCellVal.js +0 -20
  37. package/src/DataTable/getVals.js +0 -8
  38. package/src/DataTable/index.js +0 -3209
  39. package/src/DataTable/isTruthy.js +0 -12
  40. package/src/DataTable/isValueEmpty.js +0 -3
  41. package/src/DataTable/style.css +0 -608
  42. package/src/DataTable/utils/convertSchema.js +0 -69
  43. package/src/DataTable/utils/filterLocalEntitiesToHasura.js +0 -236
  44. package/src/DataTable/utils/filterLocalEntitiesToHasura.test.js +0 -587
  45. package/src/DataTable/utils/formatPasteData.js +0 -16
  46. package/src/DataTable/utils/getAllRows.js +0 -11
  47. package/src/DataTable/utils/getCellCopyText.js +0 -7
  48. package/src/DataTable/utils/getCellInfo.js +0 -36
  49. package/src/DataTable/utils/getFieldPathToField.js +0 -7
  50. package/src/DataTable/utils/getIdOrCodeOrIndex.js +0 -9
  51. package/src/DataTable/utils/getLastSelectedEntity.js +0 -11
  52. package/src/DataTable/utils/getNewEntToSelect.js +0 -25
  53. package/src/DataTable/utils/getRowCopyText.js +0 -28
  54. package/src/DataTable/utils/getTableConfigFromStorage.js +0 -5
  55. package/src/DataTable/utils/handleCopyColumn.js +0 -21
  56. package/src/DataTable/utils/handleCopyHelper.js +0 -15
  57. package/src/DataTable/utils/handleCopyRows.js +0 -23
  58. package/src/DataTable/utils/handleCopyTable.js +0 -16
  59. package/src/DataTable/utils/index.js +0 -55
  60. package/src/DataTable/utils/initializeHasuraWhereAndFilter.js +0 -26
  61. package/src/DataTable/utils/isBottomRightCornerOfRectangle.js +0 -20
  62. package/src/DataTable/utils/isEntityClean.js +0 -15
  63. package/src/DataTable/utils/primarySelectedValue.js +0 -1
  64. package/src/DataTable/utils/queryParams.js +0 -350
  65. package/src/DataTable/utils/removeCleanRows.js +0 -22
  66. package/src/DataTable/utils/rowClick.js +0 -181
  67. package/src/DataTable/utils/selection.js +0 -8
  68. package/src/DataTable/utils/tableQueryParamsToHasuraClauses.js +0 -253
  69. package/src/DataTable/utils/tableQueryParamsToHasuraClauses.test.js +0 -206
  70. package/src/DataTable/utils/useTableEntities.js +0 -38
  71. package/src/DataTable/utils/utils.js +0 -37
  72. package/src/DataTable/utils/withSelectedEntities.js +0 -65
  73. package/src/DataTable/utils/withTableParams.js +0 -288
  74. package/src/DataTable/validateTableWideErrors.js +0 -160
  75. package/src/DataTable/viewColumn.js +0 -97
  76. package/src/DialogFooter/index.js +0 -86
  77. package/src/DialogFooter/style.css +0 -9
  78. package/src/DropdownButton.js +0 -36
  79. package/src/FillWindow.css +0 -6
  80. package/src/FillWindow.js +0 -69
  81. package/src/FormComponents/FormSeparator.js +0 -9
  82. package/src/FormComponents/LoadingDots.js +0 -14
  83. package/src/FormComponents/Uploader.js +0 -1278
  84. package/src/FormComponents/getNewName.js +0 -31
  85. package/src/FormComponents/index.js +0 -1266
  86. package/src/FormComponents/itemUpload.js +0 -84
  87. package/src/FormComponents/sortify.js +0 -73
  88. package/src/FormComponents/style.css +0 -275
  89. package/src/FormComponents/tryToMatchSchemas.js +0 -264
  90. package/src/FormComponents/utils.js +0 -6
  91. package/src/HotkeysDialog/index.js +0 -79
  92. package/src/HotkeysDialog/style.css +0 -54
  93. package/src/InfoHelper/index.js +0 -78
  94. package/src/InfoHelper/style.css +0 -7
  95. package/src/IntentText/index.js +0 -18
  96. package/src/Loading/index.js +0 -70
  97. package/src/Loading/style.css +0 -4
  98. package/src/MatchHeaders.js +0 -234
  99. package/src/MenuBar/index.js +0 -423
  100. package/src/MenuBar/style.css +0 -45
  101. package/src/PromptUnsavedChanges/index.js +0 -38
  102. package/src/ResizableDraggableDialog/index.js +0 -141
  103. package/src/ResizableDraggableDialog/style.css +0 -42
  104. package/src/ScrollToTop/index.js +0 -72
  105. package/src/SimpleStepViz.js +0 -22
  106. package/src/Tag.js +0 -112
  107. package/src/TagSelect/index.js +0 -69
  108. package/src/TagSelect/style.css +0 -13
  109. package/src/TgHtmlSelect/index.js +0 -20
  110. package/src/TgSelect/index.js +0 -537
  111. package/src/TgSelect/style.css +0 -61
  112. package/src/TgSuggest/index.js +0 -124
  113. package/src/Timeline/TimelineEvent.js +0 -31
  114. package/src/Timeline/index.js +0 -15
  115. package/src/Timeline/style.css +0 -29
  116. package/src/UploadCsvWizard.css +0 -4
  117. package/src/UploadCsvWizard.js +0 -719
  118. package/src/autoTooltip.js +0 -201
  119. package/src/constants.js +0 -1
  120. package/src/customIcons.js +0 -361
  121. package/src/enhancers/withDialog/index.js +0 -196
  122. package/src/enhancers/withDialog/tg_modalState.js +0 -47
  123. package/src/enhancers/withField.js +0 -20
  124. package/src/enhancers/withFields.js +0 -11
  125. package/src/enhancers/withLocalStorage.js +0 -11
  126. package/src/index.js +0 -88
  127. package/src/rerenderOnWindowResize.js +0 -26
  128. package/src/showAppSpinner.js +0 -12
  129. package/src/showConfirmationDialog/index.js +0 -148
  130. package/src/showDialogOnDocBody.js +0 -33
  131. package/src/style.css +0 -265
  132. package/src/throwFormError.js +0 -16
  133. package/src/toastr.js +0 -148
  134. package/src/typeToCommonType.js +0 -6
  135. package/src/useDialog.js +0 -63
  136. package/src/utils/adHoc.js +0 -10
  137. package/src/utils/basicHandleActionsWithFullState.js +0 -14
  138. package/src/utils/browserUtils.js +0 -3
  139. package/src/utils/combineReducersWithFullState.js +0 -14
  140. package/src/utils/commandControls.js +0 -82
  141. package/src/utils/commandUtils.js +0 -112
  142. package/src/utils/determineBlackOrWhiteTextColor.js +0 -4
  143. package/src/utils/getDayjsFormatter.js +0 -35
  144. package/src/utils/getTextFromEl.js +0 -28
  145. package/src/utils/handlerHelpers.js +0 -24
  146. package/src/utils/hooks/index.js +0 -1
  147. package/src/utils/hooks/useDeepEqualMemo.js +0 -15
  148. package/src/utils/hooks/useStableReference.js +0 -9
  149. package/src/utils/hotkeyUtils.js +0 -131
  150. package/src/utils/isBeingCalledExcessively.js +0 -24
  151. package/src/utils/menuUtils.js +0 -433
  152. package/src/utils/popoverOverflowModifiers.js +0 -11
  153. package/src/utils/pureNoFunc.js +0 -31
  154. package/src/utils/renderOnDoc.js +0 -32
  155. package/src/utils/showProgressToast.js +0 -22
  156. package/src/utils/tagUtils.js +0 -45
  157. package/src/utils/tgFormValues.js +0 -35
  158. package/src/utils/useTraceUpdate.js +0 -19
  159. package/src/utils/withSelectTableRecords.js +0 -43
  160. package/src/utils/withStore.js +0 -10
  161. package/src/wrapDialog.js +0 -116
@@ -1,537 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-empty-function */
2
- import { MultiSelect, getCreateNewItem } from "@blueprintjs/select";
3
- import { Keys, Button, MenuItem, Tag } from "@blueprintjs/core";
4
- import React, { useEffect, useState } from "react";
5
- import { filter, isEqual } from "lodash-es";
6
- import classNames from "classnames";
7
- import "./style.css";
8
- import { withProps } from "recompose";
9
- import fuzzysearch from "fuzzysearch";
10
- import getTextFromEl from "../utils/getTextFromEl";
11
- import { getTagColorStyle, getTagProps } from "../utils/tagUtils";
12
- import popoverOverflowModifiers from "../utils/popoverOverflowModifiers";
13
- import { compose } from "redux";
14
-
15
- class TgSelect extends React.Component {
16
- constructor(props) {
17
- super(props);
18
- const { autoOpen = false } = this.props;
19
-
20
- this.state = {
21
- isOpen: autoOpen,
22
- activeItem: null,
23
- query: ""
24
- };
25
- }
26
- setOpenState = isOpen => {
27
- const { handleOpenChange } = this.props;
28
- if (handleOpenChange) {
29
- handleOpenChange(isOpen);
30
- }
31
- this.setState({ isOpen });
32
- };
33
-
34
- static defaultProps = {
35
- onChange: () => {},
36
- options: [],
37
- unfilteredOptions: [],
38
- value: undefined
39
- };
40
-
41
- itemRenderer = (i, { index, handleClick, modifiers }) => {
42
- const optionRenderer = this.getOptionRenderer();
43
- const onClick = i.onClick || handleClick;
44
- return (
45
- <div //we specifically don't use a BP MenuItem component here because the menu item is too slow when 100s are loaded and will cause the component to lag
46
- onClick={modifiers.disabled ? undefined : onClick}
47
- key={index}
48
- className={classNames(
49
- "tg-select-option bp3-menu-item bp3-fill bp3-text-overflow-ellipsis",
50
- {
51
- "bp3-active": modifiers.active,
52
- "bp3-disabled": modifiers.disabled
53
- }
54
- )}
55
- >
56
- {optionRenderer ? optionRenderer(i, this.props) : i.label}
57
- </div>
58
- );
59
- };
60
- tagRenderer = i => {
61
- if (!i || (!this.props.multi && this.state.query)) {
62
- return null;
63
- }
64
- // return i
65
- return i.label;
66
- };
67
-
68
- handleItemSelect = (item, e) => {
69
- e.stopPropagation();
70
- const { onChange, value, multi, closeOnSelect, isTagSelect } = this.props;
71
- this.setState({ activeItem: null });
72
- if (multi) {
73
- let valArray = getValueArray(value);
74
-
75
- if (closeOnSelect || item.closeOnSelect) {
76
- this.setOpenState(false);
77
- this.input && this.input.blur();
78
- }
79
- if (
80
- isTagSelect &&
81
- item.value &&
82
- item.value.includes &&
83
- item.value.includes(":")
84
- ) {
85
- const topLevelId = item.value.split(":")[0];
86
- valArray = valArray.filter(val => {
87
- if (val?.value && val.value.includes && val.value.includes(":")) {
88
- const valId = val.value.split(":")[0];
89
- if (valId === topLevelId) {
90
- return false;
91
- }
92
- }
93
- return true;
94
- });
95
- }
96
- return onChange([...valArray, item], e);
97
- } else {
98
- this.setOpenState(false);
99
- this.input && this.input.blur();
100
- return onChange(item, e);
101
- }
102
- };
103
-
104
- handleTagRemove = (e, tagProps) => {
105
- const { onChange, value } = this.props;
106
- const filteredVals = filter(
107
- value,
108
- (obj, i) => !isEqual(i, tagProps["data-tag-index"])
109
- );
110
- e.stopPropagation();
111
- onChange(filteredVals);
112
- this.setOpenState(false);
113
- this.input.focus();
114
- };
115
- handleTagInputRemove = (val, index) => {
116
- const { onChange, value } = this.props;
117
- const filteredVals = filter(value, (obj, i) => !isEqual(i, index));
118
- // e.stopPropagation();
119
- return onChange(filteredVals);
120
- };
121
-
122
- handleClear = e => {
123
- const { multi, value } = this.props;
124
-
125
- e.stopPropagation();
126
- e.preventDefault();
127
- let newValue = null;
128
- if (multi) {
129
- newValue = filter(value, obj => obj?.disabled) || [];
130
- } else if (value && value.disabled) {
131
- newValue = value;
132
- }
133
- const { onChange } = this.props;
134
- this.setState({ query: "" });
135
- onChange(newValue);
136
- this.setOpenState(false);
137
- this.input.focus();
138
- };
139
-
140
- itemListPredicate = (queryString, item) => {
141
- // this will hide an option if it returns false
142
- // each item is an individual option item
143
- const { isSimpleSearch } = this.props;
144
-
145
- return itemListPredicate(queryString, item, isSimpleSearch);
146
- };
147
-
148
- onQueryChange = query => {
149
- const { onInputChange = () => {} } = this.props;
150
- this.setState({
151
- query
152
- });
153
- onInputChange(query);
154
- };
155
- handleActiveItemChange = (item, isCreateNewItem) => {
156
- this.setState({
157
- activeItem:
158
- item ||
159
- //if there's no item and we're in creatable mode, auto-select the create-new option
160
- (isCreateNewItem || this.props.creatable ? getCreateNewItem() : null)
161
- });
162
- };
163
- onInteraction = () => {
164
- if (this.input != null && this.input !== document.activeElement) {
165
- // the input is no longer focused so we can close the popover
166
- this.setOpenState(false);
167
- this.setState({
168
- query: ""
169
- });
170
- } else if (!this.props.openOnKeyDown) {
171
- // open the popover when focusing the tag input
172
- this.setOpenState(true);
173
- }
174
- };
175
-
176
- queryHasExactOptionMatch = () => {
177
- //we don't want to show the creatable if the thing being created already exactly matches the label
178
- return (
179
- [
180
- ...(this.props.options || []),
181
- ...(Array.isArray(this.props.value)
182
- ? this.props.value
183
- : [this.props.value])
184
- ].filter(o => {
185
- const { label, value } = o || {};
186
- const lowerQuery = (this.state.query || "").toLowerCase();
187
- const lowerLabelOrVal =
188
- label && label.toLowerCase
189
- ? label.toLowerCase()
190
- : value && value.toLowerCase && value.toLowerCase();
191
- const textFromEl = getTextFromEl(label);
192
-
193
- return lowerQuery === lowerLabelOrVal || lowerQuery === textFromEl;
194
- }).length > 0
195
- );
196
- };
197
-
198
- getTagProps = label => {
199
- const { multi, value = [], disabled: _disabled } = this.props;
200
- const val = Array.isArray(value) ? value : [value];
201
- const matchingVal = val.find(op => op?.label === label);
202
- const disabled = _disabled || (matchingVal && matchingVal.disabled);
203
- const className = matchingVal && matchingVal.className;
204
-
205
- return {
206
- ...getTagColorStyle(multi && matchingVal && matchingVal.color),
207
- intent: disabled ? "" : "primary",
208
- minimal: true,
209
- className: classNames(className, "tg-select-value", {
210
- disabled
211
- }),
212
- onRemove: multi && !disabled ? this.handleTagRemove : null
213
- };
214
- };
215
-
216
- getOptionRenderer = () => {
217
- const { isTagSelect, optionRenderer, multi } = this.props;
218
-
219
- if (isTagSelect && multi) {
220
- return tagOptionRender;
221
- }
222
- return optionRenderer;
223
- };
224
- renderCreateNewOption = (query, active, handleClick) => {
225
- if (this.props.renderCreateNewOption) {
226
- return this.props.renderCreateNewOption(query, active, handleClick);
227
- }
228
- return (
229
- <MenuItem
230
- icon="add"
231
- text={`Create "${query}"`}
232
- active={active}
233
- onClick={(...args) => {
234
- const shouldStopEarly = this.props.onCreateNewOption?.(query);
235
- if (shouldStopEarly) {
236
- this.setOpenState(false);
237
- } else {
238
- handleClick(...args);
239
- }
240
- }}
241
- shouldDismissPopover={false}
242
- />
243
- );
244
- };
245
-
246
- render() {
247
- let {
248
- multi,
249
- asTag,
250
- options,
251
- unfilteredOptions,
252
- value,
253
- creatable,
254
- optionRenderer, //pull this one out here so it doesn't get passsed along
255
- tagInputProps,
256
- autoFocus,
257
- autoOpen,
258
- mustHaveQueryToOpen,
259
- noResultsText,
260
- noResults: _noResults,
261
- inputProps,
262
- backgroundColor,
263
- doNotFillWidth,
264
- noToggle,
265
- small,
266
- placeholder,
267
- isLoading,
268
- disallowClear,
269
- onBlur,
270
- disabled,
271
- popoverProps,
272
- additionalRightEl,
273
- resetOnSelect = true,
274
- ...rest
275
- } = this.props;
276
- if (asTag) {
277
- small = true;
278
- placeholder = " ";
279
- backgroundColor = "red";
280
- disallowClear = true;
281
- doNotFillWidth = true;
282
- noToggle = true;
283
- }
284
- let noResults = _noResults;
285
-
286
- // Null is also a valid value for a React Component, noResultsDefault should only be appplied when noResults is undefined
287
- if (noResults === undefined) noResults = noResultsDefault;
288
- const hasQuery = this.state.query?.length > 0;
289
- const hasValue = Array.isArray(value)
290
- ? value.length > 0
291
- : !!value || value === 0;
292
-
293
- const rightElement = isLoading ? (
294
- <Button loading minimal />
295
- ) : (
296
- <span>
297
- {additionalRightEl}
298
- {hasValue && !disallowClear && !disabled && (
299
- <Button
300
- className="tg-select-clear-all"
301
- icon="cross"
302
- minimal
303
- onClick={this.handleClear}
304
- />
305
- )}
306
- {noResults !== null && !noToggle && (
307
- <Button
308
- onClick={e => {
309
- if (this.state.isOpen) {
310
- e.stopPropagation();
311
-
312
- this.setOpenState(false);
313
- }
314
- }}
315
- disabled={disabled}
316
- className="tg-select-toggle"
317
- minimal
318
- icon={this.state.isOpen ? "caret-up" : "caret-down"}
319
- />
320
- )}
321
- </span>
322
- );
323
-
324
- const maybeCreateNewItemFromQuery = creatable ? createNewOption : undefined;
325
- const maybeCreateNewItemRenderer =
326
- creatable && !this.queryHasExactOptionMatch()
327
- ? this.renderCreateNewOption
328
- : null;
329
- const selectedItems = getValueArray(value).map(value => {
330
- if (value && value.label) return value; //if the value has a label, just use that
331
- //if not, look for an existing option to use that value
332
- // unfilteredOptions will have every option included selected ones
333
- return unfilteredOptions.find(
334
- opt => opt && opt.value === ((value && value.value) || value)
335
- );
336
- });
337
- const toRet = (
338
- <MultiSelect
339
- onActiveItemChange={this.handleActiveItemChange}
340
- closeOnSelect={!multi}
341
- resetOnSelect={resetOnSelect}
342
- items={options || []}
343
- activeItem={
344
- this.state.activeItem ||
345
- (options && options.filter(opt => !selectedItems.includes(opt))[0]) ||
346
- null //it's important we pass null here instead of undefined if no active item is found
347
- }
348
- itemDisabled={itemDisabled}
349
- query={this.state.query}
350
- popoverProps={{
351
- captureDismiss: true,
352
- minimal: true,
353
- className: classNames("tg-select", "tg-stop-dialog-form-enter", {
354
- "tg-single-select": !multi,
355
- "tg-select-as-tag": asTag,
356
- "do-not-fill-width": doNotFillWidth,
357
- "tg-small": small
358
- }),
359
- wrapperTagName: "div",
360
- canEscapeKeyClose: true,
361
- onInteraction: this.onInteraction,
362
- isOpen: mustHaveQueryToOpen
363
- ? hasQuery && this.state.isOpen
364
- : this.state.isOpen,
365
- modifiers: popoverOverflowModifiers,
366
- ...popoverProps
367
- }}
368
- onItemSelect={this.handleItemSelect}
369
- createNewItemFromQuery={maybeCreateNewItemFromQuery}
370
- createNewItemRenderer={maybeCreateNewItemRenderer}
371
- noResults={noResultsText || noResults}
372
- onQueryChange={this.onQueryChange}
373
- itemRenderer={this.itemRenderer}
374
- itemListPredicate={this.itemListPredicate}
375
- {...{
376
- selectedItems,
377
- tagRenderer: this.tagRenderer,
378
- tagInputProps: {
379
- inputRef: n => {
380
- if (n) this.input = n;
381
- },
382
- placeholder:
383
- placeholder || (creatable ? "Select/Create..." : "Select..."),
384
- tagProps: this.getTagProps,
385
- onRemove: multi ? this.handleTagInputRemove : null,
386
- rightElement: rightElement,
387
- disabled: disabled, // tg: adding isLoading will cause the input to be blurred when using generic select asReactSelect (don't do it),
388
- ...tagInputProps, //spread additional tag input props here
389
- intent: this.props.intent,
390
- onKeyDown: e => {
391
- const { which } = e;
392
- e.persist();
393
- if (which === Keys.ENTER) {
394
- e.preventDefault();
395
- // e.stopPropagation();
396
- }
397
- if (which === Keys.ESCAPE || which === Keys.TAB) {
398
- // By default the escape key will not trigger a blur on the
399
- // input element. It must be done explicitly.
400
- if (this.input != null) {
401
- this.input.blur();
402
- }
403
- this.setOpenState(false);
404
- e.preventDefault();
405
- e.stopPropagation(); //this prevents dialog's it is in from closing
406
- } else if (
407
- !(
408
- which === Keys.BACKSPACE ||
409
- which === Keys.ARROW_LEFT ||
410
- which === Keys.ARROW_RIGHT
411
- )
412
- ) {
413
- this.setOpenState(true);
414
- }
415
- },
416
- inputProps: {
417
- autoFocus: autoFocus || autoOpen,
418
- onBlur,
419
- ...(tagInputProps && tagInputProps.inputProps)
420
- }
421
- }
422
- }}
423
- {...rest}
424
- />
425
- );
426
- return toRet;
427
- }
428
- }
429
-
430
- const withAsyncOptions = Component => props => {
431
- const { loadOptions, options, ...rest } = props;
432
- const [asyncOptions, setAsyncOptions] = useState([]);
433
- const [isLoading, setLoading] = useState(false);
434
- useEffect(() => {
435
- if (loadOptions) {
436
- setLoading(true);
437
- loadOptions().then(options => {
438
- setAsyncOptions(options);
439
- setLoading(false);
440
- });
441
- }
442
- }, [loadOptions]);
443
-
444
- return (
445
- <Component
446
- {...rest}
447
- isLoading={isLoading || rest.isLoading}
448
- options={loadOptions ? asyncOptions : options}
449
- />
450
- );
451
- };
452
-
453
- export default compose(
454
- withAsyncOptions,
455
- withProps(props => {
456
- const { multi, value, options = [] } = props;
457
- let optionsToRet = options;
458
- // based on incoming value hide those selected options from the option list
459
- if (multi && value) {
460
- const valArray = getValueArray(value);
461
- optionsToRet = options.filter(op => {
462
- const isOptionSelected = valArray.some(val => {
463
- if (!val) return false;
464
- const matching = isEqual(val.value, op.value);
465
- return matching;
466
- });
467
- return !isOptionSelected;
468
- });
469
- }
470
- return {
471
- // unfilteredOptions is needed for finding selected items
472
- unfilteredOptions: options,
473
- options: optionsToRet
474
- };
475
- })
476
- )(TgSelect);
477
-
478
- const itemDisabled = i => i.disabled;
479
- const noResultsDefault = <div>No Results...</div>;
480
-
481
- export function createNewOption(newValString) {
482
- if (!newValString) return;
483
- return {
484
- userCreated: true,
485
- label: newValString,
486
- value: newValString
487
- };
488
- }
489
-
490
- function getValueArray(value) {
491
- return value || value === 0 ? (Array.isArray(value) ? value : [value]) : [];
492
- }
493
-
494
- //we export this here for use in createGenericSelect
495
- export const itemListPredicate = (_queryString = "", items, isSimpleSearch) => {
496
- const queryString = _queryString.toLowerCase();
497
- const toSearchArr = (items || []).map(item => {
498
- return {
499
- item,
500
- text: item.toLowerCase
501
- ? item.toLowerCase()
502
- : item.label
503
- ? item.label.toLowerCase
504
- ? item.label.toLowerCase()
505
- : getTextFromEl(item.label).toLowerCase()
506
- : (item.value &&
507
- item.value.toLowerCase &&
508
- item.value.toLowerCase()) ||
509
- ""
510
- };
511
- });
512
- let toRet = toSearchArr.filter(({ text }) =>
513
- (isSimpleSearch ? simplesearch : fuzzysearch)(queryString, text)
514
- );
515
- toRet = toRet.sort(({ text }, { text: text2 }) => {
516
- return getSort(text, queryString) - getSort(text2, queryString);
517
- });
518
-
519
- toRet = toRet.map(({ item }) => item);
520
- return toRet;
521
- };
522
-
523
- export function simplesearch(needle, haystack) {
524
- return (haystack || "").indexOf(needle) !== -1;
525
- }
526
- function tagOptionRender(vals) {
527
- if (vals.noTagStyle) return vals.label;
528
- return <Tag {...getTagProps(vals)}></Tag>;
529
- }
530
-
531
- function getSort(text, queryString) {
532
- let ret;
533
- if (text === queryString) ret = -1;
534
- else if (text.includes(queryString)) ret = text.indexOf(queryString);
535
- else ret = text.length;
536
- return ret;
537
- }
@@ -1,61 +0,0 @@
1
- .tg-select {
2
- width: 100%;
3
- min-width: 170px;
4
- }
5
- .tg-select.tg-select-as-tag {
6
- /* background-color: red; */
7
- border-radius: 4px;
8
- width: fit-content;
9
- color: white;
10
- border: 2px solid white;
11
- }
12
- .tg-select.tg-select-as-tag .bp3-tag.bp3-minimal.bp3-intent-primary {
13
- color: white !important;
14
- }
15
- .tg-select.do-not-fill-width {
16
- width: auto;
17
- min-width: 50px;
18
- }
19
- .tg-select.tg-small .bp3-input {
20
- min-height: 25px;
21
- height: 25px;
22
- }
23
- .tg-select.tg-small input {
24
- line-height: 10.5px;
25
- }
26
- .tg-select.tg-small .bp3-tag-input .bp3-input-ghost {
27
- line-height: 10.5px;
28
- }
29
- .tg-select.tg-small .bp3-tag-input .bp3-tag-input-values {
30
- margin-top: 2px;
31
- }
32
- .tg-select input {
33
- font-size: 14px;
34
- }
35
- .tg-select-option {
36
- width: fit-content;
37
- min-width: 100%;
38
- }
39
- /* Fix cutoff placeholder */
40
- .tg-select .bp3-input-ghost[placeholder] {
41
- width: 80%;
42
- text-overflow: ellipsis;
43
- }
44
-
45
- .tg-single-select input {
46
- position: absolute;
47
- top: 5px;
48
- }
49
- .tg-single-select .bp3-tag {
50
- background-color: initial !important;
51
- font-size: 14px;
52
- }
53
- .tg-single-select .bp3-popover-open .bp3-tag {
54
- opacity: 0.6;
55
- }
56
- .bp3-multi-select-popover .bp3-menu,
57
- .bp3-select-popover .bp3-menu {
58
- max-width: 400px;
59
- max-height: 300px;
60
- overflow: auto;
61
- }
@@ -1,124 +0,0 @@
1
- import { Suggest } from "@blueprintjs/select";
2
- import { Keys } from "@blueprintjs/core";
3
- import React, { useCallback, useMemo, useRef } from "react";
4
- import classNames from "classnames";
5
- import { itemListPredicate } from "../TgSelect";
6
-
7
- const itemRenderer = (i = "", { index, handleClick, modifiers }) => (
8
- <div //we specifically don't use a BP MenuItem component here because the menu item is too slow when 100s are loaded and will cause the component to lag
9
- onClick={handleClick}
10
- key={index}
11
- className={classNames(
12
- "tg-select-option bp3-menu-item bp3-fill bp3-text-overflow-ellipsis",
13
- {
14
- "bp3-active": modifiers.active
15
- }
16
- )}
17
- >
18
- {i}
19
- </div>
20
- );
21
-
22
- const TgSuggest = ({
23
- disabled,
24
- inputProps: _inputProps,
25
- intent,
26
- isLoading,
27
- isSimpleSearch,
28
- multi,
29
- noResultsText,
30
- notCreateable,
31
- onBlur,
32
- onChange,
33
- optionRenderer, //pull this one out here so it doesn't get passsed along
34
- options,
35
- placeholder,
36
- popoverProps: _popoverProps,
37
- value,
38
- ...rest
39
- }) => {
40
- const inputRef = useRef(null);
41
-
42
- const handleItemSelect = useCallback(
43
- item => {
44
- inputRef.current && inputRef.current.blur();
45
- return onChange?.(item);
46
- },
47
- [onChange]
48
- );
49
-
50
- const _itemListPredicate = useCallback(
51
- (queryString, item) => {
52
- return itemListPredicate(queryString, item, isSimpleSearch);
53
- },
54
- [isSimpleSearch]
55
- );
56
-
57
- const popoverProps = useMemo(
58
- () => ({
59
- minimal: true,
60
- className: classNames("tg-select", {
61
- "tg-single-select": !multi
62
- }),
63
- wrapperTagName: "div",
64
- usePortal: false,
65
- canEscapeKeyClose: true,
66
- ..._popoverProps
67
- }),
68
- [multi, _popoverProps]
69
- );
70
-
71
- const onKeyDown = useCallback(e => {
72
- const { which } = e;
73
- if (which === Keys.ENTER) {
74
- e.preventDefault();
75
- e.stopPropagation(); //this prevents the dialog it is in from closing
76
- }
77
- if (which === Keys.ESCAPE || which === Keys.TAB) {
78
- // By default the escape key will not trigger a blur on the
79
- // input element. It must be done explicitly.
80
- if (inputRef.current != null) {
81
- inputRef.current.blur();
82
- }
83
- e.preventDefault();
84
- e.stopPropagation(); //this prevents dialog's it is in from closing
85
- }
86
- }, []);
87
-
88
- const inputProps = useMemo(
89
- () => ({
90
- inputRef: n => {
91
- if (n) inputRef.current = n;
92
- },
93
- placeholder: placeholder || "Type here...",
94
- disabled: disabled, // tg: adding isLoading will cause the input to be blurred when using generic select asReactSelect (don't do it),
95
- intent: intent,
96
- ..._inputProps
97
- }),
98
- [disabled, _inputProps, intent, placeholder]
99
- );
100
-
101
- return (
102
- <Suggest
103
- closeOnSelect
104
- items={options}
105
- query={value}
106
- popoverProps={popoverProps}
107
- onKeyDown={onKeyDown}
108
- onItemSelect={handleItemSelect}
109
- noResults={null}
110
- resetOnSelect={false}
111
- onQueryChange={onChange}
112
- itemRenderer={itemRenderer}
113
- itemListPredicate={_itemListPredicate}
114
- selectedItem={value}
115
- inputValueRenderer={item => item}
116
- inputProps={inputProps}
117
- isSimpleSearch={isSimpleSearch}
118
- onChange={onChange}
119
- {...rest}
120
- />
121
- );
122
- };
123
-
124
- export default TgSuggest;