@adaptabletools/adaptable 22.0.6 → 22.0.8

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 (58) hide show
  1. package/index.css +19 -1
  2. package/index.css.map +1 -1
  3. package/package.json +1 -1
  4. package/src/AdaptableOptions/FilterOptions.d.ts +1 -0
  5. package/src/AdaptableState/Common/ColumnScope.d.ts +4 -0
  6. package/src/AdaptableState/Common/ColumnScope.js +12 -1
  7. package/src/Api/Implementation/ColumnFilterApiImpl.js +1 -0
  8. package/src/Api/Implementation/StateApiImpl.d.ts +1 -1
  9. package/src/Api/Implementation/StateApiImpl.js +12 -15
  10. package/src/Api/StateApi.d.ts +1 -1
  11. package/src/Redux/Store/AdaptableReduxMerger.js +4 -1
  12. package/src/Redux/Store/AdaptableStore.d.ts +2 -1
  13. package/src/Redux/Store/AdaptableStore.js +12 -8
  14. package/src/Redux/Store/Interface/IAdaptableStore.d.ts +1 -1
  15. package/src/View/Alert/Wizard/AlertScopeWizardSection.js +10 -3
  16. package/src/View/CalculatedColumn/Wizard/CalculatedColumnDefinitionWizardSection.js +8 -8
  17. package/src/View/CalculatedColumn/Wizard/CalculatedColumnTypeSection.js +1 -1
  18. package/src/View/CalculatedColumn/Wizard/CalculatedColumnWizard.js +4 -2
  19. package/src/View/Components/ColumnFilter/components/FloatingFilterValues.js +1 -0
  20. package/src/View/Components/ColumnGroupTag/index.d.ts +5 -0
  21. package/src/View/Components/ColumnGroupTag/index.js +9 -0
  22. package/src/View/Components/ColumnSelector/index.js +4 -1
  23. package/src/View/Components/FilterForm/ListBoxFilterForm.js +9 -2
  24. package/src/View/Components/NewScopeComponent.js +19 -37
  25. package/src/View/Components/ReorderDraggable/index.d.ts +1 -0
  26. package/src/View/Components/ReorderDraggable/index.js +2 -1
  27. package/src/View/CustomSort/Wizard/CustomSortColumnWizardSection.js +7 -1
  28. package/src/View/CustomSort/Wizard/CustomSortWizard.js +1 -1
  29. package/src/View/FlashingCell/Wizard/FlashingCellScopeWizardSection.js +10 -3
  30. package/src/View/FormatColumn/Wizard/FormatColumnColumnScopeWizardSection.js +14 -7
  31. package/src/View/FormatColumn/Wizard/FormatColumnRuleWizardSection.js +1 -3
  32. package/src/View/FormatColumn/Wizard/FormatColumnWizard.js +1 -3
  33. package/src/View/FreeTextColumn/Wizard/FreeTextColumnSettingsWizardSection.d.ts +1 -1
  34. package/src/View/FreeTextColumn/Wizard/FreeTextColumnSettingsWizardSection.js +7 -7
  35. package/src/View/Layout/Wizard/LayoutWizard.js +2 -2
  36. package/src/View/Layout/Wizard/sections/AggregationsSection.js +2 -0
  37. package/src/View/Layout/Wizard/sections/ColumnsSection.js +149 -140
  38. package/src/View/Layout/Wizard/sections/FilterSection.js +8 -1
  39. package/src/View/Layout/Wizard/sections/PivotAggregationsSection.js +2 -0
  40. package/src/View/Layout/Wizard/sections/PivotRowGroupingSection.js +5 -2
  41. package/src/View/Layout/Wizard/sections/RowGroupingSection.js +4 -1
  42. package/src/View/Layout/Wizard/sections/RowSummarySection.js +8 -3
  43. package/src/View/Layout/Wizard/sections/SortSection.js +4 -2
  44. package/src/View/StyledColumn/Wizard/StyledColumnWizardColumnSection.js +8 -2
  45. package/src/View/Wizard/OnePageAdaptableWizard.d.ts +0 -1
  46. package/src/View/Wizard/OnePageAdaptableWizard.js +1 -1
  47. package/src/View/Wizard/OnePageWizards.d.ts +1 -0
  48. package/src/View/Wizard/OnePageWizards.js +11 -4
  49. package/src/agGrid/AdaptableAgGrid.js +19 -28
  50. package/src/agGrid/AgGridAdapter.d.ts +1 -0
  51. package/src/agGrid/AgGridAdapter.js +4 -0
  52. package/src/agGrid/AgGridColumnAdapter.js +3 -3
  53. package/src/agGrid/AgGridExportAdapter.js +1 -3
  54. package/src/components/Tree/TreeDropdown/index.d.ts +9 -0
  55. package/src/components/Tree/TreeDropdown/index.js +20 -1
  56. package/src/env.js +2 -2
  57. package/src/layout-manager/src/index.js +6 -0
  58. package/tsconfig.esm.tsbuildinfo +1 -1
@@ -155,7 +155,7 @@ const ColumnRow = (props) => {
155
155
  event.stopPropagation();
156
156
  }, checked: visible }),
157
157
  React.createElement(Flex, { className: "twa:mx-2", alignItems: "center", "data-name": "column-label" }, initialHeader),
158
- props.column.columnGroup && props.column.columnGroup.groupCount > 1 ? (React.createElement(Box, { className: "ab-Layout-Wizard__ColumnRow__Title twa:mx-2 twa:p-1" },
158
+ props.column.columnGroup && props.column.columnGroup.groupCount > 1 ? (React.createElement(Box, { className: "ab-Layout-Wizard__ColumnRow__Title twa:mx-2 twa:p-1 twa:flex twa:items-center" },
159
159
  "Column Group: ",
160
160
  props.column.columnGroup.friendlyName)) : null)));
161
161
  };
@@ -373,82 +373,89 @@ export const ColumnsSection = (props) => {
373
373
  .map((col) => col.columnId)
374
374
  : currentOrder.map((col) => col.columnId);
375
375
  const visibleIdsCurrentlyDisplayed = visibleIds.filter((colId) => currentlyDisplayedColumnIds.includes(colId));
376
- return (React.createElement(Tabs, null,
376
+ return (React.createElement(Tabs, { className: "twa:h-full" },
377
377
  React.createElement(Tabs.Tab, null, "Columns"),
378
- React.createElement(Tabs.Content, { className: "twa:overflow-hidden" },
379
- React.createElement(Box, { className: "twa:grid twa:grid-cols-2 twa:gap-2 twa:focus:outline-none", "data-name": "columns-container", tabIndex: -1, onKeyDown: (event) => {
380
- if (event.key === 'ArrowDown') {
381
- event.preventDefault();
382
- event.stopPropagation();
383
- const index = currentlyDisplayedColumnIds.indexOf(selectedColumnId);
384
- if (index === -1) {
385
- return;
386
- }
387
- const nextColumnId = currentlyDisplayedColumnIds[index + 1];
388
- const nextColumn = colIdToCol[nextColumnId];
389
- if (nextColumn) {
390
- setSelectedColumnId(nextColumn.columnId);
391
- }
392
- }
393
- if (event.key === 'ArrowUp') {
394
- event.preventDefault();
395
- event.stopPropagation();
396
- const index = currentlyDisplayedColumnIds.indexOf(selectedColumnId);
397
- if (index === -1) {
398
- return;
399
- }
400
- const previousColumnId = currentlyDisplayedColumnIds[index - 1];
401
- const previousColumn = colIdToCol[previousColumnId];
402
- if (previousColumn) {
403
- setSelectedColumnId(previousColumn.columnId);
404
- }
405
- }
406
- if (event.key === ' ') {
407
- event.preventDefault();
408
- event.stopPropagation();
409
- const selectedColumn = colIdToCol[selectedColumnId];
410
- if (!selectedColumn) {
411
- return;
378
+ React.createElement(Tabs.Content, null,
379
+ React.createElement(Box, { className: "twa:gap-2 twa:overflow-hidden twa:grid twa:grid-cols-2 twa:h-full" },
380
+ React.createElement(Box, { className: "twa:gap-2 twa:focus:outline-none twa:flex-1 twa:max-h-full twa:overflow-hidden", "data-name": "columns-container", tabIndex: -1, onKeyDown: (event) => {
381
+ const scrollIntoView = (columnId) => {
382
+ const el = event.currentTarget.querySelector(`[data-id="${columnId}"]`);
383
+ el?.scrollIntoView({ block: 'nearest' });
384
+ };
385
+ if (event.key === 'ArrowDown') {
386
+ event.preventDefault();
387
+ event.stopPropagation();
388
+ const index = currentlyDisplayedColumnIds.indexOf(selectedColumnId);
389
+ if (index === -1) {
390
+ return;
391
+ }
392
+ const nextColumnId = currentlyDisplayedColumnIds[index + 1];
393
+ const nextColumn = colIdToCol[nextColumnId];
394
+ if (nextColumn) {
395
+ setSelectedColumnId(nextColumn.columnId);
396
+ scrollIntoView(nextColumn.columnId);
397
+ }
412
398
  }
413
- const visible = isColumnVisible({ columnId: selectedColumnId, layout });
414
- handleColumnVisibilityChange(selectedColumnId, !visible);
415
- }
416
- } },
417
- React.createElement(Box, { className: "twa:flex twa:flex-col twa:gap-2" },
418
- React.createElement(AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: "Search Columns...", className: "twa:w-full twa:border-none twa:p-1" }),
419
- React.createElement(Box, { className: clsx('twa:font-bold', 'twa:border-b twa:border-primarydark/30 twa:rounded-standard') },
420
- React.createElement(CheckBox, { checked: currentlyDisplayedColumnIds.length
421
- ? currentlyDisplayedColumnIds.length === visibleIdsCurrentlyDisplayed.length
422
- ? true
423
- : visibleIdsCurrentlyDisplayed.length
424
- ? null
425
- : false
426
- : false, onChange: (checked) => {
427
- handleColumnVisibilityChange(currentlyDisplayedColumnIds, checked);
428
- } }, "Select All")),
429
- React.createElement(ReorderDraggable, { toIdentifier: (option) => `${option.columnId}`, isOptionDraggable: (option) => {
430
- return option.moveable;
431
- }, optionClassName: (option) => {
432
- const baseCls = 'ab-Layout-Wizard__ColumnRow twa:cursor-pointer twa:rounded-standard';
433
- if (selectedColumnId !== option.columnId) {
434
- return baseCls;
399
+ if (event.key === 'ArrowUp') {
400
+ event.preventDefault();
401
+ event.stopPropagation();
402
+ const index = currentlyDisplayedColumnIds.indexOf(selectedColumnId);
403
+ if (index === -1) {
404
+ return;
435
405
  }
436
- return clsx(baseCls, 'twa:after:border-accent twa:relative twa:after:border-2 twa:after:rounded-standard twa:after:pointer-events-none twa:after:inset-0 twa:after:absolute twa:after:bg-accent/15');
437
- }, order: currentOrder, onOptionClick: (option, event) => {
438
- if (event.ctrlKey || option.columnId === selectedColumnId) {
439
- setSelectedColumnId(null);
406
+ const previousColumnId = currentlyDisplayedColumnIds[index - 1];
407
+ const previousColumn = colIdToCol[previousColumnId];
408
+ if (previousColumn) {
409
+ setSelectedColumnId(previousColumn.columnId);
410
+ scrollIntoView(previousColumn.columnId);
440
411
  }
441
- else {
442
- setSelectedColumnId(option.columnId);
412
+ }
413
+ if (event.key === ' ') {
414
+ event.preventDefault();
415
+ event.stopPropagation();
416
+ const selectedColumn = colIdToCol[selectedColumnId];
417
+ if (!selectedColumn) {
418
+ return;
443
419
  }
444
- }, renderOption: (option) => {
445
- return (React.createElement(ColumnRow, { onColumnNameChange: handleColumnNameChange, onColumnWidthChange: handleColumnWidthChange, onColumnFlexChange: handleColumnFlexChange, onColumnMinWidthChange: handleColumnMinWidthChange, onColumnMaxWidthChange: handleColumnMaxWidthChange, onColumnVisibilityChange: handleColumnVisibilityChange, onPinChange: handlePinChange, layout: layout, column: option }));
446
- }, onChange: handleColumnsChange })),
420
+ const visible = isColumnVisible({ columnId: selectedColumnId, layout });
421
+ handleColumnVisibilityChange(selectedColumnId, !visible);
422
+ }
423
+ } },
424
+ React.createElement(Box, { className: "twa:flex twa:flex-col twa:gap-2 twa:h-full twa:overflow-hidden" },
425
+ React.createElement(AdaptableFormControlTextClear, { value: searchInputValue, OnTextChange: setSearchInputValue, placeholder: "Search Columns...", className: "twa:w-full twa:border-none twa:p-1" }),
426
+ React.createElement(Box, { className: clsx('twa:font-bold', 'twa:border-b twa:border-primarydark/30 twa:rounded-standard') },
427
+ React.createElement(CheckBox, { checked: currentlyDisplayedColumnIds.length
428
+ ? currentlyDisplayedColumnIds.length === visibleIdsCurrentlyDisplayed.length
429
+ ? true
430
+ : visibleIdsCurrentlyDisplayed.length
431
+ ? null
432
+ : false
433
+ : false, onChange: (checked) => {
434
+ handleColumnVisibilityChange(currentlyDisplayedColumnIds, checked);
435
+ } }, "Select All")),
436
+ React.createElement(ReorderDraggable, { className: "twa:overflow-y-auto", toIdentifier: (option) => `${option.columnId}`, isOptionDraggable: (option) => {
437
+ return option.moveable;
438
+ }, optionClassName: (option) => {
439
+ const baseCls = 'ab-Layout-Wizard__ColumnRow twa:cursor-pointer twa:rounded-standard';
440
+ if (selectedColumnId !== option.columnId) {
441
+ return baseCls;
442
+ }
443
+ return clsx(baseCls, 'twa:after:border-accent twa:relative twa:after:border-2 twa:after:rounded-standard twa:after:pointer-events-none twa:after:inset-0 twa:after:absolute twa:after:bg-accent/15');
444
+ }, order: currentOrder, onOptionClick: (option, event) => {
445
+ if (event.ctrlKey || option.columnId === selectedColumnId) {
446
+ setSelectedColumnId(null);
447
+ }
448
+ else {
449
+ setSelectedColumnId(option.columnId);
450
+ }
451
+ }, renderOption: (option) => {
452
+ return (React.createElement(ColumnRow, { onColumnNameChange: handleColumnNameChange, onColumnWidthChange: handleColumnWidthChange, onColumnFlexChange: handleColumnFlexChange, onColumnMinWidthChange: handleColumnMinWidthChange, onColumnMaxWidthChange: handleColumnMaxWidthChange, onColumnVisibilityChange: handleColumnVisibilityChange, onPinChange: handlePinChange, layout: layout, column: option }));
453
+ }, onChange: handleColumnsChange }))),
447
454
  currentOrderIds.length ? (React.createElement(ColumnPropertiesEditor, { column: selectedColumnId && currentOrderIds.includes(selectedColumnId)
448
- ? colIdToCol[selectedColumnId] ?? null
455
+ ? (colIdToCol[selectedColumnId] ?? null)
449
456
  : null, layout: layout, onPinChange: handlePinChange, onColumnNameChange: handleColumnNameChange, onColumnWidthChange: handleColumnWidthChange, onColumnFlexChange: handleColumnFlexChange, onColumnMinWidthChange: handleColumnMinWidthChange, onColumnMaxWidthChange: handleColumnMaxWidthChange, onColumnVisibilityChange: handleColumnVisibilityChange })) : null))));
450
457
  };
451
- const hr = React.createElement("hr", { className: "twa:my-2 twa:h-[0.5px] twa:bg-inputborder/50 twa:border-none" });
458
+ const hr = (React.createElement("hr", { className: "twa:my-3 twa:mb-0 twa:w-full twa:h-[0.5px] twa:bg-inputborder/50 twa:border-none" }));
452
459
  const ColumnPropertiesEditor = (props) => {
453
460
  const adaptable = useAdaptable();
454
461
  const baseCls = 'ab-Layout-Wizard__ColumnPropertiesEditor twa:border twa:rounded-standard';
@@ -470,76 +477,78 @@ const ColumnPropertiesEditor = (props) => {
470
477
  const columnPinning = props.layout.ColumnPinning?.[props.column.columnId] || 'None';
471
478
  const initialHeader = adaptable.api.columnApi.getFriendlyNameForColumnId(props.column.columnId, props.layout);
472
479
  const customHeader = props.layout.ColumnHeaders?.[props.column.columnId] ?? initialHeader;
473
- return (React.createElement(Box, { className: clsx(baseCls, 'ab-Layout-Wizard__ColumnPropertiesEditor__Container twa:border-none twa:bg-defaultbackground twa:shadow-md twa:p-4') },
474
- React.createElement(Box, { className: "twa:text-5 twa:font-bold twa:leading-relaxed ab-Layout-Wizard__ColumnPropertiesEditor__Title" },
475
- "Column Settings: ",
476
- column.friendlyName),
477
- React.createElement(Box, { className: "twa:text-3 twa:opacity-80 twa:flex twa:flex-row twa:gap-1 twa:items-center" },
478
- "Column ID:",
479
- ' ',
480
- React.createElement(Box, { className: "twa:bg-primarydark/20 twa:text-text-on-primarydark twa:px-1 twa:py-0.5 twa:rounded-standard" }, column.columnId)),
481
- props.column.columnGroup && props.column.columnGroup.groupCount > 1 ? (React.createElement(Box, { className: "ab-Layout-Wizard__ColumnRow__Title twa:mx-2 twa:p-1" },
482
- "Column Group: ",
483
- props.column.columnGroup.friendlyName)) : null,
484
- hr,
485
- React.createElement(Flex, { flexDirection: "column", className: "twa:gap-3" },
486
- React.createElement(Flex, { flexDirection: "column", className: "twa:gap-1" },
487
- "Header",
488
- React.createElement(Input, { "data-name": "column-header", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input twa:w-full", placeholder: "Custom name (optional)", onChange: () => {
489
- props.onColumnNameChange(props.column.columnId, event.target.value);
490
- }, value: customHeader })),
491
- React.createElement(Box, { className: "twa:grid twa:grid-cols-[1fr_1fr] twa:gap-2" },
492
- React.createElement(Box, null, "Width:"),
493
- " ",
494
- React.createElement(Box, null, "Flex:"),
495
- React.createElement(Input, { "data-name": "column-width", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input", type: "number", placeholder: "Column width", disabled: resizable === false, onChange: (event) => {
496
- let value = parseFloat(event.target.value);
497
- value = typeof value === 'number' && !isNaN(value) ? value : void 0;
498
- props.onColumnWidthChange(props.column.columnId, value);
499
- }, value: columnWidth ?? '' }),
500
- React.createElement(Input, { "data-name": "column-flex", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input", type: "number", placeholder: "Column flex", disabled: resizable === false, onChange: (event) => {
501
- let value = parseFloat(event.target.value);
502
- value = typeof value === 'number' && !isNaN(value) ? value : void 0;
503
- props.onColumnFlexChange(props.column.columnId, value);
504
- }, value: columnFlex ?? '' }),
505
- React.createElement(Box, null, "Min Width:"),
506
- React.createElement(Box, null, "Max Width:"),
507
- React.createElement(Input, { "data-name": "column-min-width", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input", type: "number", placeholder: "Column min width", disabled: resizable === false, onChange: (event) => {
508
- let value = parseFloat(event.target.value);
509
- value = typeof value === 'number' && !isNaN(value) ? value : void 0;
510
- props.onColumnMinWidthChange(props.column.columnId, value);
511
- }, value: minWidth ?? '' }),
512
- React.createElement(Input, { "data-name": "column-max-width", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input", type: "number", placeholder: "Column max width", disabled: resizable === false, onChange: (event) => {
513
- let value = parseFloat(event.target.value);
514
- value = typeof value === 'number' && !isNaN(value) ? value : void 0;
515
- props.onColumnMaxWidthChange(props.column.columnId, value);
516
- }, value: maxWidth ?? '' })),
517
- "Pinning:",
518
- React.createElement(RadioGroup, { value: columnPinning || 'None', name: "columnPinning", orientation: "horizontal", variant: "text-only", className: radioGroupStyling.horizontalTextOnly, onRadioChange: (columnPinning) => {
519
- props.onPinChange(column.columnId, columnPinning === 'None' ? null : columnPinning);
520
- } },
521
- React.createElement(Radio, { value: "left" }, "Left"),
522
- React.createElement(Radio, { value: "None" }, "None"),
523
- React.createElement(Radio, { value: "right" }, "Right"))),
524
- React.createElement(Box, { className: "twa:mt-5" }),
480
+ return (React.createElement(Box, { className: clsx(baseCls, 'ab-Layout-Wizard__ColumnPropertiesEditor__Container twa:border-none twa:bg-defaultbackground twa:shadow-md', 'twa:max-h-full twa:overflow-hidden twa:flex twa:flex-col') },
481
+ React.createElement(Box, { className: "twa:px-4 twa:pt-4" },
482
+ React.createElement(Box, { className: "twa:text-5 twa:font-bold twa:leading-relaxed ab-Layout-Wizard__ColumnPropertiesEditor__Title" },
483
+ "Column Settings: ",
484
+ column.friendlyName),
485
+ React.createElement(Box, { className: "twa:text-3 twa:opacity-80 twa:flex twa:flex-row twa:gap-1 twa:items-center" },
486
+ "Column ID:",
487
+ ' ',
488
+ React.createElement(Box, { className: "twa:bg-primarydark/20 twa:text-text-on-primarydark twa:px-1 twa:py-0.5 twa:rounded-standard" }, column.columnId)),
489
+ props.column.columnGroup && props.column.columnGroup.groupCount > 1 ? (React.createElement(Box, { className: "ab-Layout-Wizard__ColumnRow__Title twa:mx-2 twa:p-1" },
490
+ "Column Group: ",
491
+ props.column.columnGroup.friendlyName)) : null),
525
492
  hr,
526
- React.createElement(Box, null,
527
- React.createElement(Box, { className: "twa:my-3" }, "Column Attributes"),
528
- React.createElement(Box, { className: clsx({
529
- 'twa:bg-primarylight': 'the bg color',
530
- 'twa:gap-2 twa:flex twa:flex-col': 'layout configuration for small screens',
531
- 'twa:lg:gap-3 twa:lg:grid twa:md:grid-cols-[1fr_1fr]': 'layout configuration for normal screens',
532
- 'twa:p-5 twa:rounded-standard': true,
533
- }) }, [
534
- { label: 'Aggregatable', checked: props.column.aggregatable },
535
- { label: 'Filterable', checked: props.column.filterable },
536
- { label: 'Groupable', checked: props.column.groupable },
537
- { label: 'Moveable', checked: props.column.moveable },
538
- { label: 'Pivotable', checked: props.column.pivotable },
539
- { label: 'Sortable', checked: props.column.sortable },
540
- ].map(({ label, checked }) => (React.createElement(Flex, { key: label, alignItems: "center", className: clsx({
541
- 'twa:rounded-standard twa:gap-2': true,
542
- }) },
543
- React.createElement(Box, { className: "twa:size-5" }, checked ? (React.createElement(Icon, { name: "check", className: "twa:text-success" })) : (React.createElement(Icon, { name: "close", className: "twa:text-error" }))),
544
- label)))))));
493
+ React.createElement(Box, { className: "twa:px-4 twa:flex-1 twa:overflow-y-auto twa:pb-3" },
494
+ React.createElement(Flex, { flexDirection: "column", className: "twa:gap-3 twa:mt-3" },
495
+ React.createElement(Flex, { flexDirection: "column", className: "twa:gap-1" },
496
+ "Header",
497
+ React.createElement(Input, { "data-name": "column-header", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input twa:w-full", placeholder: "Custom name (optional)", onChange: () => {
498
+ props.onColumnNameChange(props.column.columnId, event.target.value);
499
+ }, value: customHeader })),
500
+ React.createElement(Box, { className: "twa:grid twa:grid-cols-[1fr_1fr] twa:gap-2" },
501
+ React.createElement(Box, null, "Width:"),
502
+ " ",
503
+ React.createElement(Box, null, "Flex:"),
504
+ React.createElement(Input, { "data-name": "column-width", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input", type: "number", placeholder: "Column width", disabled: resizable === false, onChange: (event) => {
505
+ let value = parseFloat(event.target.value);
506
+ value = typeof value === 'number' && !isNaN(value) ? value : void 0;
507
+ props.onColumnWidthChange(props.column.columnId, value);
508
+ }, value: columnWidth ?? '' }),
509
+ React.createElement(Input, { "data-name": "column-flex", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input", type: "number", placeholder: "Column flex", disabled: resizable === false, onChange: (event) => {
510
+ let value = parseFloat(event.target.value);
511
+ value = typeof value === 'number' && !isNaN(value) ? value : void 0;
512
+ props.onColumnFlexChange(props.column.columnId, value);
513
+ }, value: columnFlex ?? '' }),
514
+ React.createElement(Box, null, "Min Width:"),
515
+ React.createElement(Box, null, "Max Width:"),
516
+ React.createElement(Input, { "data-name": "column-min-width", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input", type: "number", placeholder: "Column min width", disabled: resizable === false, onChange: (event) => {
517
+ let value = parseFloat(event.target.value);
518
+ value = typeof value === 'number' && !isNaN(value) ? value : void 0;
519
+ props.onColumnMinWidthChange(props.column.columnId, value);
520
+ }, value: minWidth ?? '' }),
521
+ React.createElement(Input, { "data-name": "column-max-width", className: "ab-Layout-Wizard__ColumnPropertiesEditor__Input", type: "number", placeholder: "Column max width", disabled: resizable === false, onChange: (event) => {
522
+ let value = parseFloat(event.target.value);
523
+ value = typeof value === 'number' && !isNaN(value) ? value : void 0;
524
+ props.onColumnMaxWidthChange(props.column.columnId, value);
525
+ }, value: maxWidth ?? '' })),
526
+ "Pinning:",
527
+ React.createElement(RadioGroup, { value: columnPinning || 'None', name: "columnPinning", orientation: "horizontal", variant: "text-only", className: radioGroupStyling.horizontalTextOnly, onRadioChange: (columnPinning) => {
528
+ props.onPinChange(column.columnId, columnPinning === 'None' ? null : columnPinning);
529
+ } },
530
+ React.createElement(Radio, { value: "left" }, "Left"),
531
+ React.createElement(Radio, { value: "None" }, "None"),
532
+ React.createElement(Radio, { value: "right" }, "Right"))),
533
+ React.createElement(Box, { className: "twa:mt-5" }),
534
+ hr,
535
+ React.createElement(Box, null,
536
+ React.createElement(Box, { className: "twa:my-3" }, "Column Attributes"),
537
+ React.createElement(Box, { className: clsx({
538
+ 'twa:bg-primarylight': 'the bg color',
539
+ 'twa:gap-2 twa:flex twa:flex-col': 'layout configuration for small screens',
540
+ 'twa:lg:gap-3 twa:lg:grid twa:md:grid-cols-[1fr_1fr]': 'layout configuration for normal screens',
541
+ 'twa:p-5 twa:rounded-standard': true,
542
+ }) }, [
543
+ { label: 'Aggregatable', checked: props.column.aggregatable },
544
+ { label: 'Filterable', checked: props.column.filterable },
545
+ { label: 'Groupable', checked: props.column.groupable },
546
+ { label: 'Moveable', checked: props.column.moveable },
547
+ { label: 'Pivotable', checked: props.column.pivotable },
548
+ { label: 'Sortable', checked: props.column.sortable },
549
+ ].map(({ label, checked }) => (React.createElement(Flex, { key: label, alignItems: "center", className: clsx({
550
+ 'twa:rounded-standard twa:gap-2': true,
551
+ }) },
552
+ React.createElement(Box, { className: "twa:size-5" }, checked ? (React.createElement(Icon, { name: "check", className: "twa:text-success" })) : (React.createElement(Icon, { name: "close", className: "twa:text-error" }))),
553
+ label))))))));
545
554
  };
@@ -58,8 +58,15 @@ export const FilterSection = (props) => {
58
58
  });
59
59
  } }))),
60
60
  layoutFilters?.length > 0 && (React.createElement(Box, { className: "twa:p-0", as: "ul" }, layoutFilters.map((columnFilter) => {
61
+ const moduleItems = filterModule.toView(columnFilter).items;
62
+ const column = adaptable.api.columnApi.getColumnWithColumnId(columnFilter.ColumnId);
63
+ const columnGroupItems = column?.columnGroup && column.columnGroup.groupCount > 1
64
+ ? [{ name: 'Column Group', values: [column.columnGroup.friendlyName] }]
65
+ : [];
61
66
  const items = [
62
- ...filterModule.toView(columnFilter).items,
67
+ moduleItems[0],
68
+ ...columnGroupItems,
69
+ ...moduleItems.slice(1),
63
70
  {
64
71
  name: 'Column Filter',
65
72
  view: (React.createElement(LayoutColumnFilter, { columnFilter: columnFilter, onColumnFilterChange: (columnFilter) => {
@@ -9,6 +9,7 @@ import { useAdaptable } from '../../../AdaptableContext';
9
9
  import { ValueSelector } from '../../../Components/ValueSelector';
10
10
  import { useOnePageAdaptableWizardContext } from '../../../Wizard/OnePageAdaptableWizard';
11
11
  import { columnFilter } from './Utilities';
12
+ import { ColumnGroupTag } from '../../../Components/ColumnGroupTag';
12
13
  import ArrayExtensions from '../../../../Utilities/Extensions/ArrayExtensions';
13
14
  import StringExtensions from '../../../../Utilities/Extensions/StringExtensions';
14
15
  import { Select } from '../../../../components/Select';
@@ -173,6 +174,7 @@ const PivotColumnRow = (props) => {
173
174
  React.createElement(Flex, { alignItems: "flex-start" },
174
175
  React.createElement(Flex, { className: "twa:flex-[0_0_auto]", alignItems: "center" },
175
176
  React.createElement(Flex, { className: "twa:min-w-[80px]" }, props.column.friendlyName),
177
+ React.createElement(ColumnGroupTag, { column: props.column }),
176
178
  aggValue && (React.createElement(DropdownButton, { columns: ['label'], items: aggOptions, className: "twa:ml-2" }, currentAggFnName)),
177
179
  currentAggFnName === WEIGHTED_AVERAGE_AGG_FN_NAME && (React.createElement(Flex, { className: "twa:bg-primary twa:ml-3", alignItems: "center" },
178
180
  React.createElement(Box, null, "Weight"),
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { columnFilter } from './Utilities';
3
+ import { ColumnGroupTag } from '../../../Components/ColumnGroupTag';
3
4
  import { Tabs } from '../../../../components/Tabs';
4
5
  import { Tag } from '../../../../components/Tag';
5
6
  import { useAdaptable } from '../../../AdaptableContext';
@@ -8,7 +9,7 @@ import { useOnePageAdaptableWizardContext } from '../../../Wizard/OnePageAdaptab
8
9
  import ArrayExtensions from '../../../../Utilities/Extensions/ArrayExtensions';
9
10
  import { normalizeLayout } from '../../../../Api/Implementation/LayoutHelpers';
10
11
  import { RowGroupBehaviorSection } from './RowGroupingSection';
11
- import { Box } from '../../../../components/Flex';
12
+ import { Box, Flex } from '../../../../components/Flex';
12
13
  export const PivotRowGroupingSectionSummary = () => {
13
14
  const adaptable = useAdaptable();
14
15
  const { data: layout } = useOnePageAdaptableWizardContext();
@@ -38,7 +39,9 @@ export const PivotRowGroupingSection = (props) => {
38
39
  React.createElement(Tabs.Tab, null, "Row Grouped Columns"),
39
40
  React.createElement(Tabs.Tab, null, rowGroupsText),
40
41
  React.createElement(Tabs.Content, null,
41
- React.createElement(ValueSelector, { showFilterInput: true, filter: columnFilter, toIdentifier: (option) => `${option.columnId}`, toLabel: (option) => option.friendlyName ?? option.columnId, options: sortedGroupableColumns, value: layout.PivotGroupedColumns ?? [], allowReorder: true, onChange: handleColumnsChange })),
42
+ React.createElement(ValueSelector, { showFilterInput: true, filter: columnFilter, toIdentifier: (option) => `${option.columnId}`, toLabel: (option) => option.friendlyName ?? option.columnId, toListLabel: (option) => (React.createElement(Flex, { alignItems: "center" },
43
+ option.friendlyName ?? option.columnId,
44
+ React.createElement(ColumnGroupTag, { column: option }))), options: sortedGroupableColumns, value: layout.PivotGroupedColumns ?? [], allowReorder: true, onChange: handleColumnsChange })),
42
45
  React.createElement(Tabs.Content, null,
43
46
  React.createElement(RowGroupBehaviorSection, { layout: layout, onChange: onChange }))));
44
47
  };
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import FormLayout from '../../../../components/FormLayout';
3
3
  import { columnFilter } from './Utilities';
4
+ import { ColumnGroupTag } from '../../../Components/ColumnGroupTag';
4
5
  import { RadioGroup } from '../../../../components/Radio';
5
6
  import { Tabs } from '../../../../components/Tabs';
6
7
  import { Tag } from '../../../../components/Tag';
@@ -95,7 +96,9 @@ export const RowGroupingSection = (props) => {
95
96
  React.createElement(Tabs.Tab, null, "Row Grouped Columns"),
96
97
  React.createElement(Tabs.Tab, null, rowGroupsText),
97
98
  React.createElement(Tabs.Content, null,
98
- React.createElement(ValueSelector, { showFilterInput: true, filter: columnFilter, toIdentifier: (option) => `${option.columnId}`, toLabel: (option) => option.friendlyName ?? option.columnId, options: sortedGroupableColumns, value: layout.RowGroupedColumns ?? [], allowReorder: true, onChange: handleColumnsChange })),
99
+ React.createElement(ValueSelector, { showFilterInput: true, filter: columnFilter, toIdentifier: (option) => `${option.columnId}`, toLabel: (option) => option.friendlyName ?? option.columnId, toListLabel: (option) => (React.createElement(Flex, { alignItems: "center" },
100
+ option.friendlyName ?? option.columnId,
101
+ React.createElement(ColumnGroupTag, { column: option }))), options: sortedGroupableColumns, value: layout.RowGroupedColumns ?? [], allowReorder: true, onChange: handleColumnsChange })),
99
102
  React.createElement(Tabs.Content, null,
100
103
  React.createElement(RowGroupBehaviorSection, { layout: layout, onChange: onChange })))));
101
104
  };
@@ -15,6 +15,7 @@ import { SuspendToggleButton } from '../../../Components/Buttons/SuspendToggleBu
15
15
  import { ValueSelector } from '../../../Components/ValueSelector';
16
16
  import { useOnePageAdaptableWizardContext } from '../../../Wizard/OnePageAdaptableWizard';
17
17
  import { columnFilter } from './Utilities';
18
+ import { ColumnGroupTag } from '../../../Components/ColumnGroupTag';
18
19
  import ArrayExtensions from '../../../../Utilities/Extensions/ArrayExtensions';
19
20
  import { Box, Flex } from '../../../../components/Flex';
20
21
  export const areSummaryRowsValid = (layout) => {
@@ -150,11 +151,13 @@ const RowSummaryEditor = React.memo(({ rowSummary, onChange, availableScalarExpr
150
151
  } }, "Include Only Filtered Rows"))),
151
152
  React.createElement(Flex, { flexDirection: "column", className: "twa:mt-2 twa:mb-1" },
152
153
  React.createElement(Flex, { alignItems: "center", className: "twa:flex-1 twa:mb-2" }, "Column Aggregations"),
153
- React.createElement(Panel, { bodyProps: { className: 'twa:max-h-full ' }, className: "twa:h-[360px]" },
154
+ React.createElement(Panel, { bodyProps: { className: 'twa:max-h-full twa:bg-primarylight ' }, className: "twa:h-[360px]" },
154
155
  React.createElement(ValueSelector, { style: { maxHeight: '100%' }, showFilterInput: true, filter: columnFilter, toIdentifier: (column) => column.columnId, toLabel: (option) => option.friendlyName ?? option.columnId, options: columns, toListLabel: (column) => {
155
156
  const label = column.friendlyName ?? column.columnId;
156
157
  if (!(column.columnId in (rowSummary.ColumnsMap ?? {}))) {
157
- return label;
158
+ return (React.createElement(Flex, { alignItems: "center" },
159
+ label,
160
+ React.createElement(ColumnGroupTag, { column: column })));
158
161
  }
159
162
  const expressionOptions = getAvailableExpressionsForColumnType(column.dataType, availableScalarExpressions).map((expression) => ({
160
163
  label: expression,
@@ -172,7 +175,9 @@ const RowSummaryEditor = React.memo(({ rowSummary, onChange, availableScalarExpr
172
175
  }
173
176
  const expression = rowSummary.ColumnsMap[column.columnId];
174
177
  return (React.createElement(Flex, null,
175
- React.createElement(Flex, { className: "twa:mr-2", alignItems: 'center' }, label),
178
+ React.createElement(Flex, { className: "twa:mr-2", alignItems: 'center' },
179
+ label,
180
+ React.createElement(ColumnGroupTag, { column: column })),
176
181
  React.createElement(Select, { value: expression, options: expressionOptions, onChange: (expression) => {
177
182
  onChange({
178
183
  ...rowSummary,
@@ -7,8 +7,9 @@ import { useAdaptable } from '../../../AdaptableContext';
7
7
  import { ValueSelector } from '../../../Components/ValueSelector';
8
8
  import { useOnePageAdaptableWizardContext } from '../../../Wizard/OnePageAdaptableWizard';
9
9
  import { columnFilter } from './Utilities';
10
+ import { ColumnGroupTag } from '../../../Components/ColumnGroupTag';
10
11
  import ArrayExtensions from '../../../../Utilities/Extensions/ArrayExtensions';
11
- import { Box } from '../../../../components/Flex';
12
+ import { Box, Flex } from '../../../../components/Flex';
12
13
  export const SortSectionSummary = () => {
13
14
  const { data: layout } = useOnePageAdaptableWizardContext();
14
15
  const adaptable = useAdaptable();
@@ -18,8 +19,9 @@ export const SortSectionSummary = () => {
18
19
  const ColumnRow = (props) => {
19
20
  const SortOrder = (props.layout?.ColumnSorts ?? []).find((sort) => sort.ColumnId === props.column.columnId)?.SortOrder;
20
21
  const icon = SortOrder === 'Asc' ? 'sort-asc' : 'sort-desc';
21
- return (React.createElement(Box, null,
22
+ return (React.createElement(Flex, { alignItems: "center" },
22
23
  props.column.friendlyName,
24
+ React.createElement(ColumnGroupTag, { column: props.column }),
23
25
  SortOrder && (React.createElement(SimpleButton, { className: "twa:ml-2", onClick: () => props.onSortChange(props.column.columnId, SortOrder === 'Asc' ? 'Desc' : 'Asc'), variant: "raised", icon: icon }))));
24
26
  };
25
27
  export const SortSection = (props) => {
@@ -3,7 +3,8 @@ import { Tabs } from '../../../components/Tabs';
3
3
  import { Tag } from '../../../components/Tag';
4
4
  import { NewColumnSelector } from '../../Components/ColumnSelector';
5
5
  import { useOnePageAdaptableWizardContext } from '../../Wizard/OnePageAdaptableWizard';
6
- import { Box } from '../../../components/Flex';
6
+ import { Box, Flex } from '../../../components/Flex';
7
+ import { AdaptableFormControlTextClear } from '../../Components/Forms/AdaptableFormControlTextClear';
7
8
  export const renderStyledColumnColumnSummary = (data) => {
8
9
  const { api } = useOnePageAdaptableWizardContext();
9
10
  return (React.createElement(Box, { className: "twa:pr-2 twa:py-2" },
@@ -76,8 +77,13 @@ export const StyledColumnWizardColumnSection = (props) => {
76
77
  }
77
78
  props.onChange(newStyledColumn);
78
79
  };
80
+ const [columnsSearchText, setColumnsSearchText] = React.useState('');
79
81
  return (React.createElement(Tabs, { style: { height: '100%' } },
80
82
  React.createElement(Tabs.Tab, null, "Column"),
81
83
  React.createElement(Tabs.Content, null,
82
- React.createElement(NewColumnSelector, { availableColumns: sortableCols, selected: data.ColumnId ? [data.ColumnId] : [], singleSelect: true, onChange: handleColumnsChange, allowReorder: false }))));
84
+ React.createElement(Flex, { flexDirection: "row", alignItems: "center", className: "twa:p-2" },
85
+ React.createElement(Box, { className: "twa:text-2" }, "Columns"),
86
+ React.createElement(Box, { className: "twa:flex-3" }),
87
+ React.createElement(AdaptableFormControlTextClear, { value: columnsSearchText, OnTextChange: setColumnsSearchText, placeholder: "Type to search columns", style: { flex: 1 } })),
88
+ React.createElement(NewColumnSelector, { columnFilterText: columnsSearchText, availableColumns: sortableCols, selected: data.ColumnId ? [data.ColumnId] : [], singleSelect: true, onChange: handleColumnsChange, allowReorder: false }))));
83
89
  };
@@ -41,7 +41,6 @@ export interface OnePageAdaptableWizardProps<ENTITY> {
41
41
  onFinish?: (data: ENTITY) => any;
42
42
  children?: React.ReactNode;
43
43
  style?: CSSProperties;
44
- titleContainerStyle?: CSSProperties;
45
44
  closeText?: React.ReactNode;
46
45
  closeTooltip?: string;
47
46
  finishText?: React.ReactNode;
@@ -72,7 +72,7 @@ export const OnePageAdaptableWizard = (props) => {
72
72
  };
73
73
  return (React.createElement(OnePageAdaptableWizardContext.Provider, { value: extraContext },
74
74
  React.createElement(NamedQueryContext.Provider, { value: { namedQuery, setNamedQuery } },
75
- React.createElement(OnePageWizard, { ...props, name: name, sections: sections, onFinish: handleClickFinish }))));
75
+ React.createElement(OnePageWizard, { ...props, name: name, sections: sections, onFinish: handleClickFinish, moduleName: props.moduleInfo.FriendlyName }))));
76
76
  };
77
77
  export const OnePageWizardSummary = () => {
78
78
  const { sections, data, api, moduleInfo } = useOnePageAdaptableWizardContext();
@@ -40,6 +40,7 @@ export interface OnePageWizardProps<ENTITY> {
40
40
  closeText?: React.ReactNode;
41
41
  closeTooltip?: string;
42
42
  finishText?: React.ReactNode;
43
+ moduleName?: string;
43
44
  }
44
45
  export declare const OnePageWizard: <ENTITY extends unknown>(props: OnePageWizardProps<ENTITY>) => React.JSX.Element;
45
46
  export {};
@@ -13,6 +13,8 @@ import { useKeyboardNavigation } from './useKeyboardNavigation';
13
13
  import { Box, Flex } from '../../components/Flex';
14
14
  import { twMerge } from '../../twMerge';
15
15
  import { targetOwn } from '../../components/twUtils';
16
+ /** Same template for header row and main row so module/details align with nav / content columns. */
17
+ const ONE_PAGE_WIZARD_SECTION_GRID = 'twa:grid twa:grid-cols-[minmax(160px,14rem)_minmax(0,1fr)]';
16
18
  export const SummaryTag = (props) => (React.createElement(Box, { ...props }));
17
19
  export const SummaryText = (props) => (React.createElement(Box, { ...props, className: twMerge('twa:text-2 twa:mb-3', props.className) }));
18
20
  export const FormDescriptionText = (props) => React.createElement(Box, { ...props, className: twMerge('twa:text-2 twa:mt-1', props.className) });
@@ -63,7 +65,6 @@ export const OnePageWizard = (props) => {
63
65
  return React.createElement(React.Fragment, { key: index });
64
66
  }
65
67
  return (React.createElement(Flex, { flexDirection: "column", key: index, "data-name": `section-${index}`, className: "twa:min-h-full twa:mr-2" },
66
- React.createElement(Box, { className: "ab-OnePageWizard__details twa:text-4 twa:py-3 twa:pl-2" }, section.details),
67
68
  React.createElement(Box, { className: "ab-OnePageWizard__section twa:flex-1 twa:rounded-standard twa:overflow-auto twa:bg-defaultbackground" }, section.render(props.data, index))));
68
69
  };
69
70
  const handleNavigation = useKeyboardNavigation(setCurrentSection, visibleSections);
@@ -104,6 +105,8 @@ export const OnePageWizard = (props) => {
104
105
  return acc;
105
106
  }, new Map());
106
107
  const canFinish = !invalidCount;
108
+ const activeSection = visibleSections[currentSection];
109
+ const activeSectionDetails = activeSection !== '-' ? activeSection?.details : undefined;
107
110
  return (React.createElement(NamedQueryContext.Provider, { value: { namedQuery, setNamedQuery } },
108
111
  React.createElement(OnePageWizardContext.Provider, { value: contextValue },
109
112
  React.createElement(Dialog, { modal: props.modal ?? true, isOpen: true, showCloseButton: false, focusOnBrowserVisible: true, className: "twa:rounded-standard twa:overflow-hidden twa:h-[90vh]", ref: dialogRef, onDismiss: () => props.onHide?.(), onKeyDown: (event) => {
@@ -124,8 +127,12 @@ export const OnePageWizard = (props) => {
124
127
  }
125
128
  } },
126
129
  React.createElement(Box, { className: clsx('ab-OnePageWizard twa:flex twa:flex-col twa:h-full twa:w-[90vw] twa:max-w-[1200px]', 'twa:bg-primarylight twa:text-primary-foreground'), "data-name": props.name, style: props.style },
127
- React.createElement(Flex, { flexDirection: "row", alignItems: "stretch", className: "twa:flex-1 twa:overflow-auto" },
128
- React.createElement(Flex, { flexDirection: "column", className: "ab-OnePageWizard__section-title-container twa:p-3 twa:flex-none twa:overflow-auto twa:relative", ref: sizeOwnerRef, style: props.titleContainerStyle },
130
+ (props.moduleName || activeSectionDetails) && (React.createElement(Box, { className: clsx('ab-OnePageWizard__header', ONE_PAGE_WIZARD_SECTION_GRID, 'twa:items-start twa:mt-4 twa:mb-2 twa:px-2') },
131
+ React.createElement(Box, { className: "ab-OnePageWizard__module-name twa:min-w-0 twa:pl-3 twa:font-bold" }, props.moduleName),
132
+ React.createElement(Box, { className: "ab-OnePageWizard__details twa:min-w-0 twa:pr-2 twa:text-4" }, activeSectionDetails))),
133
+ React.createElement(Box, { as: "hr", className: "ab-OnePageWizard__module-separator twa:w-full twa:border-0 twa:border-t twa:border-t-inputborder" }),
134
+ React.createElement(Box, { className: clsx(ONE_PAGE_WIZARD_SECTION_GRID, 'twa:flex-1 twa:min-h-0 twa:overflow-auto twa:items-stretch') },
135
+ React.createElement(Flex, { flexDirection: "column", className: "ab-OnePageWizard__section-title-container twa:min-h-0 twa:min-w-0 twa:overflow-auto twa:p-3 twa:relative", ref: sizeOwnerRef, style: props.titleContainerStyle },
129
136
  visibleSections.map((section, index) => {
130
137
  if (section === '-') {
131
138
  return (React.createElement(Box, { as: "hr", className: "ab-OnePageWizard__section-separator twa:mt-2 twa:w-full twa:border-t twa:border-t-inputborder", key: `${index}-` }));
@@ -167,7 +174,7 @@ export const OnePageWizard = (props) => {
167
174
  "or arrow keys",
168
175
  React.createElement("br", null),
169
176
  "to navigate")),
170
- React.createElement(Flex, { flexDirection: "column", className: "ab-OnePageWizard__section-container twa:flex-1" }, renderSection(currentSection))),
177
+ React.createElement(Flex, { flexDirection: "column", className: "ab-OnePageWizard__section-container twa:min-h-0 twa:min-w-0 twa:flex-1" }, renderSection(currentSection))),
171
178
  React.createElement(Flex, { flexDirection: "row", alignItems: "center", className: "ab-WizardDialog__footer ab-OnePageWizard__footer twa:p-2" },
172
179
  React.createElement(SimpleButton, { tone: "neutral", variant: "text", "data-name": "close", onClick: () => props.onHide?.(), tooltip: props.closeTooltip ?? 'Close wizard', accessLevel: 'Full' }, props.closeText ?? 'CLOSE'),
173
180
  React.createElement(KeyHint, { className: "twa:ml-2" }, "Esc"),