@singularsystems/neo-react 1.0.0-beta.0 → 1.0.0-beta.2

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 (140) hide show
  1. package/CHANGELOG.md +7 -7
  2. package/dist/React/Decorators.js +0 -1
  3. package/dist/ReactComponents/Button.js +5 -4
  4. package/dist/ReactComponents/Card.js +4 -3
  5. package/dist/ReactComponents/DatePicker.d.ts +1 -0
  6. package/dist/ReactComponents/DatePicker.js +6 -2
  7. package/dist/ReactComponents/DropDown/AutoCompleteDropDown.d.ts +4 -0
  8. package/dist/ReactComponents/DropDown/AutoCompleteDropDown.js +4 -1
  9. package/dist/ReactComponents/Grid/ButtonColumn.d.ts +2 -1
  10. package/dist/ReactComponents/Grid/ButtonColumn.js +1 -1
  11. package/dist/ReactComponents/Grid/Grid.d.ts +11 -3
  12. package/dist/ReactComponents/Grid/Grid.js +23 -8
  13. package/dist/ReactComponents/Grid/StickyTableHeader.d.ts +27 -0
  14. package/dist/ReactComponents/Grid/StickyTableHeader.js +107 -0
  15. package/dist/ReactComponents/Icons/IIconFactory.d.ts +6 -0
  16. package/dist/ReactComponents/Icons/Icon.d.ts +13 -0
  17. package/dist/ReactComponents/Icons/Icon.js +27 -0
  18. package/dist/ReactComponents/Icons/IconFactory.js +7 -1
  19. package/dist/ReactComponents/Icons/MaterialSymbolsFontFactory.d.ts +21 -0
  20. package/dist/ReactComponents/Icons/MaterialSymbolsFontFactory.js +114 -0
  21. package/dist/ReactComponents/Icons/index.d.ts +2 -1
  22. package/dist/ReactComponents/Icons/index.js +1 -0
  23. package/dist/ReactComponents/Input.js +1 -1
  24. package/dist/ReactComponents/InputHelpers.d.ts +1 -1
  25. package/dist/ReactComponents/InputHelpers.js +3 -3
  26. package/dist/ReactComponents/Modal/Modal.js +4 -0
  27. package/dist/ReactComponents/NumberInput.js +14 -7
  28. package/dist/ReactComponents/Paging/Pager.d.ts +1 -0
  29. package/dist/ReactComponents/Paging/Pager.js +3 -0
  30. package/dist/ReactComponents/PropTypes.d.ts +3 -10
  31. package/dist/ReactComponents/PropTypes.js +12 -2
  32. package/dist/ReactComponents/TooltipProvider.js +2 -1
  33. package/dist/ReactComponents/_Exports.d.ts +2 -1
  34. package/dist/ReactComponents/_Exports.js +2 -1
  35. package/dist/Routing/RoutingState.d.ts +2 -0
  36. package/dist/Routing/RoutingState.js +27 -1
  37. package/dist/Routing/ViewParameterList.d.ts +9 -3
  38. package/dist/Routing/ViewParameterList.js +7 -4
  39. package/dist/Views/ViewBase.d.ts +3 -0
  40. package/dist/Views/ViewBase.js +8 -1
  41. package/dist/Views/ViewModelBase.d.ts +1 -1
  42. package/package.json +3 -3
  43. package/styles/Card.scss +8 -1
  44. package/styles/DatePicker.scss +11 -0
  45. package/styles/Grid.scss +5 -0
  46. package/dist/Declarations.d.ts +0 -3
  47. package/dist/Declarations.js +0 -0
  48. package/dist/Modules/NeoReactModule.js.map +0 -1
  49. package/dist/Modules/ReactSetup.js.map +0 -1
  50. package/dist/Modules/Types.js.map +0 -1
  51. package/dist/React/AutoRunner.js.map +0 -1
  52. package/dist/React/DataView.js.map +0 -1
  53. package/dist/React/Decorators.js.map +0 -1
  54. package/dist/React/ReactModelCreator.js.map +0 -1
  55. package/dist/React/Utils.js.map +0 -1
  56. package/dist/ReactComponents/Button.js.map +0 -1
  57. package/dist/ReactComponents/Card.js.map +0 -1
  58. package/dist/ReactComponents/Collapsable.js.map +0 -1
  59. package/dist/ReactComponents/CollapsableBase.js.map +0 -1
  60. package/dist/ReactComponents/ColorPicker.js.map +0 -1
  61. package/dist/ReactComponents/ComponentBase.js.map +0 -1
  62. package/dist/ReactComponents/ContextMenu/ContextMenu.js.map +0 -1
  63. package/dist/ReactComponents/ContextMenu/ContextMenuContainer.js.map +0 -1
  64. package/dist/ReactComponents/ContextMenu/ContextMenuState.js.map +0 -1
  65. package/dist/ReactComponents/DatePicker.js.map +0 -1
  66. package/dist/ReactComponents/DropDown/AutoCompleteDropDown.js.map +0 -1
  67. package/dist/ReactComponents/DropDown/DropDown.js.map +0 -1
  68. package/dist/ReactComponents/DropDown/DropDownBase.js.map +0 -1
  69. package/dist/ReactComponents/ErrorHandler.js.map +0 -1
  70. package/dist/ReactComponents/FileManager/FileBasicInput.js.map +0 -1
  71. package/dist/ReactComponents/FileManager/FileContext.js.map +0 -1
  72. package/dist/ReactComponents/FileManager/FileDropArea.js.map +0 -1
  73. package/dist/ReactComponents/FileManager/FileInput.js.map +0 -1
  74. package/dist/ReactComponents/FileManager/FileUploadButton.js.map +0 -1
  75. package/dist/ReactComponents/FileManager/FileUploadProgress.js.map +0 -1
  76. package/dist/ReactComponents/Form.js.map +0 -1
  77. package/dist/ReactComponents/FormContext.js.map +0 -1
  78. package/dist/ReactComponents/FormGroup/FormGroup.js.map +0 -1
  79. package/dist/ReactComponents/FormGroup/FormGroupFloating.js.map +0 -1
  80. package/dist/ReactComponents/FormGroup/FormGroupInline.js.map +0 -1
  81. package/dist/ReactComponents/Grid/ButtonColumn.js.map +0 -1
  82. package/dist/ReactComponents/Grid/Column.js.map +0 -1
  83. package/dist/ReactComponents/Grid/ColumnHelper.js.map +0 -1
  84. package/dist/ReactComponents/Grid/Grid.js.map +0 -1
  85. package/dist/ReactComponents/Grid/Row.js.map +0 -1
  86. package/dist/ReactComponents/Grid/_Exports.js.map +0 -1
  87. package/dist/ReactComponents/GridLayout.js.map +0 -1
  88. package/dist/ReactComponents/Input.js.map +0 -1
  89. package/dist/ReactComponents/InputHelpers.js.map +0 -1
  90. package/dist/ReactComponents/Loader.js.map +0 -1
  91. package/dist/ReactComponents/Modal/Modal.js.map +0 -1
  92. package/dist/ReactComponents/Modal/ModalContainer.js.map +0 -1
  93. package/dist/ReactComponents/Modal/ModalPortal.js.map +0 -1
  94. package/dist/ReactComponents/Notifications/Alert.js.map +0 -1
  95. package/dist/ReactComponents/Notifications/Toast.js.map +0 -1
  96. package/dist/ReactComponents/Notifications/ToastContainer.js.map +0 -1
  97. package/dist/ReactComponents/NumberInput.js.map +0 -1
  98. package/dist/ReactComponents/Paging/BasicPagerControls.js.map +0 -1
  99. package/dist/ReactComponents/Paging/PageSizeControl.js.map +0 -1
  100. package/dist/ReactComponents/Paging/Pager.js.map +0 -1
  101. package/dist/ReactComponents/ProgressBar.js.map +0 -1
  102. package/dist/ReactComponents/PropTypes.js.map +0 -1
  103. package/dist/ReactComponents/RadioList.js.map +0 -1
  104. package/dist/ReactComponents/ReactHelpers.d.ts +0 -5
  105. package/dist/ReactComponents/ReactHelpers.js +0 -17
  106. package/dist/ReactComponents/ReactHelpers.js.map +0 -1
  107. package/dist/ReactComponents/Slider.js.map +0 -1
  108. package/dist/ReactComponents/StateObserver.js.map +0 -1
  109. package/dist/ReactComponents/Tabs/Tab.js.map +0 -1
  110. package/dist/ReactComponents/Tabs/TabContainer.js.map +0 -1
  111. package/dist/ReactComponents/Tabs/TabManager.js.map +0 -1
  112. package/dist/ReactComponents/Tooltip.js.map +0 -1
  113. package/dist/ReactComponents/TooltipHelper.js.map +0 -1
  114. package/dist/ReactComponents/TooltipProvider.js.map +0 -1
  115. package/dist/ReactComponents/ValidationSummary.js.map +0 -1
  116. package/dist/ReactComponents/_Exports.js.map +0 -1
  117. package/dist/ReactComponents/_Managers.js.map +0 -1
  118. package/dist/Routing/BreadCrumbItem.js.map +0 -1
  119. package/dist/Routing/IRouteChangedProps.js.map +0 -1
  120. package/dist/Routing/IRouteParameter.js.map +0 -1
  121. package/dist/Routing/MenuRoute.js.map +0 -1
  122. package/dist/Routing/NavigationHelper.js.map +0 -1
  123. package/dist/Routing/PageLeaveHandler.js.map +0 -1
  124. package/dist/Routing/RouteProvider.js.map +0 -1
  125. package/dist/Routing/RouteView.js.map +0 -1
  126. package/dist/Routing/RoutingState.js.map +0 -1
  127. package/dist/Routing/ViewParameter.js.map +0 -1
  128. package/dist/Routing/ViewParameterList.js.map +0 -1
  129. package/dist/Routing/index.js.map +0 -1
  130. package/dist/Services/DisposeHelper.js.map +0 -1
  131. package/dist/Services/IDisposeHelper.js.map +0 -1
  132. package/dist/Views/EmptyViewModel.js.map +0 -1
  133. package/dist/Views/IViewModel.js.map +0 -1
  134. package/dist/Views/PersistentViewBase.js.map +0 -1
  135. package/dist/Views/ViewBase.js.map +0 -1
  136. package/dist/Views/ViewComponentBase.js.map +0 -1
  137. package/dist/Views/ViewModelBase.js.map +0 -1
  138. package/dist/Views/ViewState.js.map +0 -1
  139. package/dist/Views/index.js.map +0 -1
  140. package/dist/index.js.map +0 -1
@@ -0,0 +1,114 @@
1
+ import { __extends } from "tslib";
2
+ import { Utils } from "@singularsystems/neo-core";
3
+ import React from "react";
4
+ import { IconFactory } from ".";
5
+ /**
6
+ * Font factory that renders google material symbols icons.
7
+ */
8
+ var MaterialSymbolsFontFactory = /** @class */ (function (_super) {
9
+ __extends(MaterialSymbolsFontFactory, _super);
10
+ function MaterialSymbolsFontFactory(options) {
11
+ var _this = this;
12
+ var _a;
13
+ _this = _super.call(this) || this;
14
+ _this.filledByDefault = (_a = options === null || options === void 0 ? void 0 : options.fillDefault) !== null && _a !== void 0 ? _a : false;
15
+ if ((options === null || options === void 0 ? void 0 : options.fontAwesomeMappings) && (options === null || options === void 0 ? void 0 : options.replaceNeoMappings)) {
16
+ _this.fontAwesomeMap = new Map(options.fontAwesomeMappings);
17
+ }
18
+ else {
19
+ _this.fontAwesomeMap = new Map(neoFontAwesomeMappings);
20
+ if (options === null || options === void 0 ? void 0 : options.fontAwesomeMappings) {
21
+ for (var _i = 0, _b = options.fontAwesomeMappings; _i < _b.length; _i++) {
22
+ var mapping = _b[_i];
23
+ _this.fontAwesomeMap.set(mapping[0], mapping[1]);
24
+ }
25
+ }
26
+ }
27
+ return _this;
28
+ }
29
+ MaterialSymbolsFontFactory.prototype.mapStringToIcon = function (iconName, style) {
30
+ var _a;
31
+ var className = "material-symbols-outlined";
32
+ var isFilled = (_a = style === null || style === void 0 ? void 0 : style.solid) !== null && _a !== void 0 ? _a : this.filledByDefault;
33
+ // TODO: copy spin animation from font-awesome
34
+ if (style === null || style === void 0 ? void 0 : style.spin) {
35
+ className += " fa fa-spin";
36
+ }
37
+ // remove and extract convention styling
38
+ iconName = iconName.replace("fa-fw", "");
39
+ var faProps = Utils.getFontAwesomeIconProps(iconName);
40
+ iconName = faProps.name.trim();
41
+ if (faProps.isSolid !== undefined) {
42
+ isFilled = faProps.isSolid;
43
+ }
44
+ var mappedName = this.mapFontAwesomeToMaterial(iconName);
45
+ if (mappedName === undefined) {
46
+ // replace common differences.
47
+ mappedName = iconName.replace(/-/g, "_")
48
+ .replace("plus", "add")
49
+ .replace("square", "box");
50
+ }
51
+ if (mappedName === "") {
52
+ mappedName = '\u00A0';
53
+ }
54
+ var cssStyle;
55
+ if (isFilled || (style === null || style === void 0 ? void 0 : style.weight)) {
56
+ var styleText = "";
57
+ if (isFilled) {
58
+ styleText += "'FILL' 1";
59
+ }
60
+ if (style === null || style === void 0 ? void 0 : style.weight) {
61
+ styleText += " 'wght' " + style.weight;
62
+ }
63
+ cssStyle = { fontVariationSettings: styleText.trim() };
64
+ }
65
+ return React.createElement("span", { className: className, style: cssStyle }, mappedName);
66
+ };
67
+ MaterialSymbolsFontFactory.prototype.mapFontAwesomeToMaterial = function (faName) {
68
+ return this.fontAwesomeMap.get(faName.trim());
69
+ };
70
+ return MaterialSymbolsFontFactory;
71
+ }(IconFactory));
72
+ export { MaterialSymbolsFontFactory };
73
+ var neoFontAwesomeMappings = [
74
+ ["plus", "add"],
75
+ ["plus-square", "add_box"],
76
+ ["minus", "remove"],
77
+ ["minus-square", "indeterminate_check_box"],
78
+ ["arrow-left", "arrow_back"],
79
+ ["angle-left", "chevron_left"],
80
+ ["caret-left", "arrow_left"],
81
+ ["trash", "delete"],
82
+ ["user", "person"],
83
+ ["users", "groups"],
84
+ ["user-shield", "admin_panel_settings"],
85
+ ["user-plus", "person_add"],
86
+ ["user-times", "person_remove"],
87
+ ["user-lock", "manage_accounts"],
88
+ ["unlock", "lock_open"],
89
+ ["cogs", "settings"],
90
+ ["file-excel", "text_snippet"],
91
+ ["file-code", "code_blocks"],
92
+ ["feather-alt", "filter_alt"],
93
+ ["filter", "filter_alt"],
94
+ ["eye", "visibility"],
95
+ ["envelope", "mail"],
96
+ ["address-book", "contact_mail"],
97
+ ["at", "alternate_email"],
98
+ ["bell", "notifications"],
99
+ ["times", "close"],
100
+ ["eraser", "ink_eraser"],
101
+ ["align-left", "format_align_left"],
102
+ ["align-center", "format_align_center"],
103
+ ["align-right", "format_align_right"],
104
+ ["equals", "equal"],
105
+ ["not-equal", "block"],
106
+ ["copy", "content_copy"],
107
+ ["chart-bar", "bar_chart"],
108
+ ["less-than", ""],
109
+ ["less-than-equal", ""],
110
+ ["greater-than", ""],
111
+ ["greater-than-equal", ""],
112
+ ["stamp", "approval"],
113
+ ["circle-notch", "progress_activity"]
114
+ ];
@@ -1,3 +1,4 @@
1
- export { IIconFactory, IconStyle } from './IIconFactory';
1
+ export type { IIconFactory, IconStyle } from './IIconFactory';
2
2
  export { IconFactory } from './IconFactory';
3
3
  export { FontAwesomeIconFactory } from './FontAwesomeIconFactory';
4
+ export { MaterialSymbolsFontFactory } from './MaterialSymbolsFontFactory';
@@ -1,2 +1,3 @@
1
1
  export { IconFactory } from './IconFactory';
2
2
  export { FontAwesomeIconFactory } from './FontAwesomeIconFactory';
3
+ export { MaterialSymbolsFontFactory } from './MaterialSymbolsFontFactory';
@@ -107,7 +107,7 @@ var Input = /** @class */ (function (_super) {
107
107
  splitProps.editor.append = this.props.bind.value ?
108
108
  React.createElement(Button, __assign({ size: "sm" }, buttonOptions, { icon: !this.showPassword ? "far-eye fa-fw" : "far-eye-slash fa-fw", onClick: function () { return _this.showPassword = !_this.showPassword; } })) : null;
109
109
  }
110
- return (InputHelpers.surroundWithInputGroup(inputElement, splitProps.editor));
110
+ return (InputHelpers.surroundWithInputGroup(inputElement, splitProps.editor, this.domRef));
111
111
  };
112
112
  Input.contextType = FormContext;
113
113
  __decorate([
@@ -2,5 +2,5 @@ import * as React from 'react';
2
2
  import { ICommonEditorProps } from './PropTypes';
3
3
  export declare class InputHelpers {
4
4
  private static iconFactory?;
5
- static surroundWithInputGroup<T extends React.ReactNode>(element: T, props: ICommonEditorProps): JSX.Element | T;
5
+ static surroundWithInputGroup<T extends React.ReactNode>(element: T, props: ICommonEditorProps, inputRef?: React.RefObject<HTMLElement>): JSX.Element | T;
6
6
  }
@@ -4,7 +4,7 @@ import { NeoReactTypes } from '../Modules/Types';
4
4
  var InputHelpers = /** @class */ (function () {
5
5
  function InputHelpers() {
6
6
  }
7
- InputHelpers.surroundWithInputGroup = function (element, props) {
7
+ InputHelpers.surroundWithInputGroup = function (element, props, inputRef) {
8
8
  if (!this.iconFactory) {
9
9
  this.iconFactory = Misc.Globals.appService.get(NeoReactTypes.Components.IconFactory);
10
10
  }
@@ -13,12 +13,12 @@ var InputHelpers = /** @class */ (function () {
13
13
  (props.prependText || props.prepend) &&
14
14
  React.createElement("div", { className: "input-group-prepend" },
15
15
  props.prepend && (props.prepend instanceof Function ? props.prepend() : props.prepend),
16
- props.prependText && React.createElement("span", { className: "input-group-text" }, this.iconFactory.textOrIcon(props.prependText))),
16
+ props.prependText && React.createElement("span", { className: "input-group-text", onClick: function () { var _a; return (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); } }, this.iconFactory.textOrIcon(props.prependText))),
17
17
  element,
18
18
  (props.appendText || props.append) &&
19
19
  React.createElement("div", { className: "input-group-append" },
20
20
  props.append && (props.append instanceof Function ? props.append() : props.append),
21
- props.appendText && React.createElement("span", { className: "input-group-text" }, this.iconFactory.textOrIcon(props.appendText)))));
21
+ props.appendText && React.createElement("span", { className: "input-group-text", onClick: function () { var _a; return (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); } }, this.iconFactory.textOrIcon(props.appendText)))));
22
22
  }
23
23
  else {
24
24
  return element;
@@ -70,6 +70,10 @@ var Modal = /** @class */ (function (_super) {
70
70
  _this.visible = false;
71
71
  _this.forceUpdate();
72
72
  }
73
+ if (_this.props.afterClose) {
74
+ _this.props.afterClose();
75
+ }
76
+ ;
73
77
  _this.closeTimer = null;
74
78
  }, Misc.Settings.modalAnimationTimeMs);
75
79
  }
@@ -96,8 +96,15 @@ var NumberInput = /** @class */ (function (_super) {
96
96
  }
97
97
  NumberInput.prototype.onChanged = function (e) {
98
98
  var newValue;
99
- if (e.target.value !== "") {
100
- var testValue = e.target.value;
99
+ var stringValue = e.target.value;
100
+ if (stringValue !== "") {
101
+ if (NumberUtils.allowAsDecimalSeparator) {
102
+ var firstIndex = stringValue.indexOf(NumberUtils.allowAsDecimalSeparator), lastIndex = stringValue.lastIndexOf(NumberUtils.allowAsDecimalSeparator);
103
+ if (firstIndex >= 0 && firstIndex === lastIndex) {
104
+ stringValue = stringValue.replace(NumberUtils.allowAsDecimalSeparator, ".");
105
+ }
106
+ }
107
+ var testValue = stringValue;
101
108
  if (testValue[0] === "-") {
102
109
  testValue = testValue.substring(1);
103
110
  }
@@ -105,18 +112,18 @@ var NumberInput = /** @class */ (function (_super) {
105
112
  return;
106
113
  }
107
114
  }
108
- if (e.target.value == "") {
115
+ if (stringValue == "") {
109
116
  newValue = this.props.bind.propertyInfo.allowNulls ? null : new Decimal(0);
110
117
  }
111
118
  else if (this.formatState.isPercent && NumberUtils.transformPercent) {
112
- newValue = new Decimal(e.target.value).dividedBy(100);
119
+ newValue = new Decimal(stringValue).dividedBy(100);
113
120
  }
114
121
  else if (this.numericType === Misc.DataType.Float || this.numericType === Misc.DataType.Decimal) {
115
- newValue = new Decimal(e.target.value);
122
+ newValue = new Decimal(stringValue);
116
123
  }
117
124
  else {
118
125
  // Rounds to zero.
119
- newValue = new Decimal(e.target.value).toDecimalPlaces(0, Decimal.ROUND_DOWN);
126
+ newValue = new Decimal(stringValue).toDecimalPlaces(0, Decimal.ROUND_DOWN);
120
127
  }
121
128
  if (newValue === null) {
122
129
  this.props.bind.value = newValue;
@@ -248,7 +255,7 @@ var NumberInput = /** @class */ (function (_super) {
248
255
  var decimals = NumberUtils.getDecimalPlaces(this.formatState.formatString);
249
256
  domProps.step = decimals === 0 ? "1" : "0.".concat("0".repeat(decimals - 1), "1");
250
257
  }
251
- return (InputHelpers.surroundWithInputGroup(React.createElement("input", __assign({}, domProps, { defaultValue: this.formatState.getFormattedValue(editorProps.bind.value), type: useNative ? "number" : "text", onChange: this.onChanged, ref: this.inputElement })), editorProps));
258
+ return (InputHelpers.surroundWithInputGroup(React.createElement("input", __assign({}, domProps, { defaultValue: this.formatState.getFormattedValue(editorProps.bind.value), type: useNative ? "number" : "text", onChange: this.onChanged, ref: this.inputElement })), editorProps, this.inputElement));
252
259
  };
253
260
  NumberInput.contextType = FormContext;
254
261
  NumberInput = __decorate([
@@ -20,5 +20,6 @@ export default class Pager<TCriteria extends ValueObject, TModel extends Model.I
20
20
  dataViewContext: DataViewContextParams<TModel>;
21
21
  constructor(props: IPagerBaseProps<TCriteria, TModel>);
22
22
  componentDidMount(): void;
23
+ componentDidUpdate(): void;
23
24
  render(): JSX.Element | null;
24
25
  }
@@ -16,6 +16,9 @@ var Pager = /** @class */ (function (_super) {
16
16
  Pager.prototype.componentDidMount = function () {
17
17
  this.props.pageManager.initialise();
18
18
  };
19
+ Pager.prototype.componentDidUpdate = function () {
20
+ this.props.pageManager.afterRender();
21
+ };
19
22
  Pager.prototype.render = function () {
20
23
  var _a = this.props, pageManager = _a.pageManager, pageControls = _a.pageControls, pageControlProps = _a.pageControlProps, suppressLoader = _a.suppressLoader, hideBeforeLoad = _a.hideBeforeLoad, domProps = __rest(_a, ["pageManager", "pageControls", "pageControlProps", "suppressLoader", "hideBeforeLoad"]);
21
24
  if (!pageManager.hasFetched && !pageManager.taskRunner.isBusy && hideBeforeLoad !== false) {
@@ -135,22 +135,15 @@ export declare class BindPropsHelper {
135
135
  */
136
136
  static getBindProperty<T>(allProps: IEditorContainerProps<T, any>): Model.IPropertyInstance;
137
137
  static splitCommonEditorProps<T extends ICommonEditorProps>(props: T): {
138
- editor: {
139
- isReadOnly: boolean | undefined;
140
- isDisabled: boolean | undefined;
141
- prependText: string | undefined;
142
- prepend: JSX.Element | (() => JSX.Element) | null | undefined;
143
- appendText: string | undefined;
144
- append: JSX.Element | (() => JSX.Element) | null | undefined;
145
- inputElement: React.RefObject<HTMLElement> | undefined;
146
- requiresGroup: boolean;
147
- };
138
+ editor: ICommonEditorProps;
148
139
  rest: Omit<T, "disabled" | "readOnly" | "isReadOnly" | "isDisabled" | "prependText" | "appendText" | "prepend" | "append" | "inputElement">;
149
140
  };
150
141
  static normaliseContainerProps<T, TContainerDom = React.HTMLProps<T>, TData = any>(component: IComponentBase, props: IEditorContainerProps<T, TData>, inGroup: boolean, isBootstrap?: boolean): IEditorContainerNormalisedProps<TContainerDom, TData>;
151
142
  static normaliseEditorProps<T, TDom = React.HTMLProps<T>>(component: IComponentBase, props: (IEditorAndSelectorProps<T, any> & TDom) | IEditorNormalisedProps<TDom, any>): IEditorNormalisedProps<TDom, any>;
152
143
  static getPlaceholderText(placeholder: string | boolean | undefined, property: PropertyInfo): string | undefined;
153
144
  static autoSetDomProperties<TDom extends React.HTMLProps<HTMLElement>>(props: IEditorNormalisedProps<TDom, any>, formContext: FormContextParams, componentBlurFn?: (e: React.FocusEvent<HTMLElement>) => void, componentFocusFn?: (e: React.FocusEvent<HTMLElement>) => void): TDom;
145
+ static isReadOnly(editorProps: ICommonEditorProps, formContext: FormContextParams): boolean;
146
+ static isDisabled(editorProps: ICommonEditorProps, formContext: FormContextParams): boolean;
154
147
  /**
155
148
  * Intercept the user specified blur event, and run the validation onBlur logic first.
156
149
  * @param props Props specified on component.
@@ -209,12 +209,12 @@ export var BindPropsHelper = /** @class */ (function () {
209
209
  if (this.config.isTestOrDevelopment) {
210
210
  domProps[BindPropsHelper.DataFieldName] = props.bind.propertyInfo.propertyName;
211
211
  }
212
- if (props.editor.isReadOnly || (formContext.allReadOnly && props.editor.isReadOnly === undefined)) {
212
+ if (this.isReadOnly(props.editor, formContext)) {
213
213
  domProps.readOnly = true;
214
214
  if (!domProps.tabIndex)
215
215
  domProps.tabIndex = -1;
216
216
  }
217
- if (props.editor.isDisabled || (formContext.allDisabled && props.editor.isDisabled === undefined)) {
217
+ if (this.isDisabled(props.editor, formContext)) {
218
218
  domProps.disabled = true;
219
219
  }
220
220
  if (props.editor.placeholder) {
@@ -231,6 +231,16 @@ export var BindPropsHelper = /** @class */ (function () {
231
231
  domProps.onBlur = BindPropsHelper.blurIntercept(props.editor, domProps.onBlur, componentBlurFn);
232
232
  return domProps;
233
233
  };
234
+ BindPropsHelper.isReadOnly = function (editorProps, formContext) {
235
+ var _a;
236
+ var propsReadOnly = (_a = editorProps.isReadOnly) !== null && _a !== void 0 ? _a : editorProps.readOnly;
237
+ return propsReadOnly || (formContext.allReadOnly && propsReadOnly === undefined);
238
+ };
239
+ BindPropsHelper.isDisabled = function (editorProps, formContext) {
240
+ var _a;
241
+ var propsDisabled = (_a = editorProps.isDisabled) !== null && _a !== void 0 ? _a : editorProps.disabled;
242
+ return propsDisabled || (formContext.allDisabled && propsDisabled === undefined);
243
+ };
234
244
  /**
235
245
  * Intercept the user specified blur event, and run the validation onBlur logic first.
236
246
  * @param props Props specified on component.
@@ -57,9 +57,10 @@ var TooltipProvider = /** @class */ (function (_super) {
57
57
  var anchor = element;
58
58
  var toolTip = anchor.dataset["tip"];
59
59
  var tryCount = 0;
60
- while (!toolTip && tryCount < 3 && anchor) {
60
+ while (!toolTip && tryCount < 8 && anchor) {
61
61
  anchor = anchor.parentElement;
62
62
  toolTip = anchor && anchor.dataset["tip"];
63
+ tryCount++;
63
64
  }
64
65
  if (toolTip && anchor) {
65
66
  if (!this.currentInfo || this.currentInfo.anchor !== anchor || this.currentInfo.text !== toolTip) {
@@ -7,6 +7,7 @@ import ColorPicker from './ColorPicker';
7
7
  import ContextMenuContainer from './ContextMenu/ContextMenuContainer';
8
8
  import DatePicker from './DatePicker';
9
9
  import DropDown from './DropDown/DropDown';
10
+ import Icon from './Icons/Icon';
10
11
  import Input, { Textbox, Passwordbox, Checkbox } from './Input';
11
12
  import FileBasicInput from './FileManager/FileBasicInput';
12
13
  import FileContext from './FileManager/FileContext';
@@ -38,4 +39,4 @@ import ToastContainer from './Notifications/ToastContainer';
38
39
  import Tooltip from './Tooltip';
39
40
  import TooltipProvider from './TooltipProvider';
40
41
  import ValidationSummary from './ValidationSummary';
41
- export { Alert, AutoCompleteDropDown, Button, Card, Checkbox, Collapsable, ColorPicker, ContextMenuContainer, DatePicker, DropDown, FileBasicInput, FileContext, FileDropArea, FileInput, FileUploadButton, FileUploadProgress, Form, FormContext, FormGroup, FormGroupFloating, FormGroupInline, GridLayout, Input, Link, Loader, Modal, ModalContainer, NumberInput, Pager, PagerControlsBasic, PageSizeControl, Passwordbox, ProgressBar, RadioList, Slider, TabContainer, Tab, Textbox, Toast, ToastContainer, Tooltip, TooltipProvider, ValidationSummary };
42
+ export { Alert, AutoCompleteDropDown, Button, Card, Checkbox, Collapsable, ColorPicker, ContextMenuContainer, DatePicker, DropDown, FileBasicInput, FileContext, FileDropArea, FileInput, FileUploadButton, FileUploadProgress, Form, FormContext, FormGroup, FormGroupFloating, FormGroupInline, GridLayout, Icon, Input, Link, Loader, Modal, ModalContainer, NumberInput, Pager, PagerControlsBasic, PageSizeControl, Passwordbox, ProgressBar, RadioList, Slider, TabContainer, Tab, Textbox, Toast, ToastContainer, Tooltip, TooltipProvider, ValidationSummary };
@@ -7,6 +7,7 @@ import ColorPicker from './ColorPicker';
7
7
  import ContextMenuContainer from './ContextMenu/ContextMenuContainer';
8
8
  import DatePicker from './DatePicker';
9
9
  import DropDown from './DropDown/DropDown';
10
+ import Icon from './Icons/Icon';
10
11
  import Input, { Textbox, Passwordbox, Checkbox } from './Input';
11
12
  import FileBasicInput from './FileManager/FileBasicInput';
12
13
  import FileContext from './FileManager/FileContext';
@@ -38,4 +39,4 @@ import ToastContainer from './Notifications/ToastContainer';
38
39
  import Tooltip from './Tooltip';
39
40
  import TooltipProvider from './TooltipProvider';
40
41
  import ValidationSummary from './ValidationSummary';
41
- export { Alert, AutoCompleteDropDown, Button, Card, Checkbox, Collapsable, ColorPicker, ContextMenuContainer, DatePicker, DropDown, FileBasicInput, FileContext, FileDropArea, FileInput, FileUploadButton, FileUploadProgress, Form, FormContext, FormGroup, FormGroupFloating, FormGroupInline, GridLayout, Input, Link, Loader, Modal, ModalContainer, NumberInput, Pager, PagerControlsBasic, PageSizeControl, Passwordbox, ProgressBar, RadioList, Slider, TabContainer, Tab, Textbox, Toast, ToastContainer, Tooltip, TooltipProvider, ValidationSummary };
42
+ export { Alert, AutoCompleteDropDown, Button, Card, Checkbox, Collapsable, ColorPicker, ContextMenuContainer, DatePicker, DropDown, FileBasicInput, FileContext, FileDropArea, FileInput, FileUploadButton, FileUploadProgress, Form, FormContext, FormGroup, FormGroupFloating, FormGroupInline, GridLayout, Icon, Input, Link, Loader, Modal, ModalContainer, NumberInput, Pager, PagerControlsBasic, PageSizeControl, Passwordbox, ProgressBar, RadioList, Slider, TabContainer, Tab, Textbox, Toast, ToastContainer, Tooltip, TooltipProvider, ValidationSummary };
@@ -11,6 +11,8 @@ export declare class RoutingState {
11
11
  leavePromise?: Promise<boolean> | Promise<Misc.ModalResult> | Promise<void>;
12
12
  observableRoute: IProcessedRoute | null;
13
13
  currentView: IViewBase | null;
14
+ get currentViewFullScreen(): boolean;
15
+ get taskRunner(): import("@singularsystems/neo-core").ITaskRunner | undefined;
14
16
  constructor();
15
17
  setCurrentRoute(routeProps: RouteComponentProps, route: IProcessedRoute): void;
16
18
  private previousRoute?;
@@ -1,12 +1,28 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import { injectable } from 'inversify';
3
- import { makeObservable, observable } from 'mobx';
3
+ import { computed, makeObservable, observable } from 'mobx';
4
4
  export var RoutingState = /** @class */ (function () {
5
5
  function RoutingState() {
6
6
  this.observableRoute = null;
7
7
  this.currentView = null;
8
8
  makeObservable(this);
9
9
  }
10
+ Object.defineProperty(RoutingState.prototype, "currentViewFullScreen", {
11
+ get: function () {
12
+ var _a;
13
+ return ((_a = this.currentView) === null || _a === void 0 ? void 0 : _a.fullScreen) === true;
14
+ },
15
+ enumerable: false,
16
+ configurable: true
17
+ });
18
+ Object.defineProperty(RoutingState.prototype, "taskRunner", {
19
+ get: function () {
20
+ var _a;
21
+ return (_a = this.currentView) === null || _a === void 0 ? void 0 : _a.taskRunner;
22
+ },
23
+ enumerable: false,
24
+ configurable: true
25
+ });
10
26
  RoutingState.prototype.setCurrentRoute = function (routeProps, route) {
11
27
  this.currentRouteProps = routeProps;
12
28
  this.currentRoute = route;
@@ -37,6 +53,16 @@ export var RoutingState = /** @class */ (function () {
37
53
  observable.ref,
38
54
  __metadata("design:type", Object)
39
55
  ], RoutingState.prototype, "currentView", void 0);
56
+ __decorate([
57
+ computed,
58
+ __metadata("design:type", Object),
59
+ __metadata("design:paramtypes", [])
60
+ ], RoutingState.prototype, "currentViewFullScreen", null);
61
+ __decorate([
62
+ computed,
63
+ __metadata("design:type", Object),
64
+ __metadata("design:paramtypes", [])
65
+ ], RoutingState.prototype, "taskRunner", null);
40
66
  RoutingState = __decorate([
41
67
  injectable(),
42
68
  __metadata("design:paramtypes", [])
@@ -6,6 +6,12 @@ import { IViewBase } from '../Views/ViewBase';
6
6
  export type TransformParamsType<T> = {
7
7
  [P in keyof T]: IViewParameter;
8
8
  };
9
+ interface ISetValuesOptions {
10
+ /** True if the url should be set even if none of the values have changed. */
11
+ force?: boolean;
12
+ /** True if the url should be replaced instead of added to the history. This prevents the back button returning the params to the current state. */
13
+ replace?: boolean;
14
+ }
9
15
  export interface IViewParameterList {
10
16
  /**
11
17
  * Returns the breadcrumb items for all url parameters which have a value.
@@ -16,11 +22,10 @@ export interface IViewParameterListOfT<TParams extends RouteParameterObject<TPar
16
22
  /**
17
23
  * Set the view params for each of the provided values. Only 1 navigation event will occur.
18
24
  * @param values New values.
19
- * @param force True if the url should be set even if none of the values have changed.
20
25
  */
21
26
  setValues(values: {
22
27
  [P in keyof TParams]?: number | string | null;
23
- }, force?: boolean): void;
28
+ }, options?: ISetValuesOptions | boolean): void;
24
29
  }
25
30
  export interface IViewParameterListInternal extends IViewParameterList {
26
31
  update(match: match): boolean;
@@ -38,7 +43,7 @@ export declare class ViewParameterList<TParams extends RouteParameterObject<TPar
38
43
  private getQueryString;
39
44
  setValues(values: {
40
45
  [P in keyof TParams]?: number | string | null;
41
- }, force?: boolean): void;
46
+ }, options?: ISetValuesOptions | boolean): void;
42
47
  setUrl(viewParameter: ViewParameter | null, replace?: boolean): void;
43
48
  /**
44
49
  * Updates the parameter values from the values in the url. Returns true if any of the values have changed.
@@ -51,3 +56,4 @@ export declare class ViewParameterList<TParams extends RouteParameterObject<TPar
51
56
  */
52
57
  static getPathForValues<TParams extends RouteParameterObject<TParams>>(basePath: string, params: TParams, values: {}): string;
53
58
  }
59
+ export {};
@@ -69,17 +69,20 @@ var ViewParameterList = /** @class */ (function () {
69
69
  }
70
70
  return queryPath;
71
71
  };
72
- ViewParameterList.prototype.setValues = function (values, force) {
72
+ ViewParameterList.prototype.setValues = function (values, options) {
73
73
  var _a;
74
- if (force === void 0) { force = false; }
75
74
  this.suppressNavigation = true;
76
75
  this.hasSuppressedNavigation = false;
76
+ options !== null && options !== void 0 ? options : (options = {});
77
+ if (typeof options === "boolean") {
78
+ options = { force: true }; // parameter used to be named 'force'- backwards compatibility.
79
+ }
77
80
  for (var paramName in values) {
78
81
  this[paramName].value = (_a = values[paramName]) !== null && _a !== void 0 ? _a : null;
79
82
  }
80
83
  this.suppressNavigation = false;
81
- if (this.hasSuppressedNavigation || force) {
82
- this.setUrl(this.params[this.params.length - 1]);
84
+ if (this.hasSuppressedNavigation || options.force) {
85
+ this.setUrl(this.params[this.params.length - 1], options.replace);
83
86
  }
84
87
  };
85
88
  ViewParameterList.prototype.setUrl = function (viewParameter, replace) {
@@ -10,6 +10,7 @@ import EmptyViewModel from './EmptyViewModel';
10
10
  import { IRouteChangedProps } from '../Routing/IRouteChangedProps';
11
11
  import { valueOrLazy } from './ViewModelBase';
12
12
  export interface IViewBase extends Views.IViewBase {
13
+ readonly fullScreen: boolean;
13
14
  viewParams: IViewParameterList;
14
15
  updateViewParams(match: match): void;
15
16
  getBreadCrumbList(): BreadCrumbItem[];
@@ -22,6 +23,8 @@ export interface IViewBaseConstructor {
22
23
  }
23
24
  export default abstract class ViewBase<TViewModel extends IViewModel = EmptyViewModel, TParams extends RouteParameterObject<TParams> = {}> extends React.Component implements IViewBase {
24
25
  viewName: string;
26
+ /** Indicates that the view requests to be displayed full screen. Up to the main layout to accommodate this. */
27
+ fullScreen: boolean;
25
28
  static get currentView(): IViewBase | null;
26
29
  private routingState;
27
30
  navigation: import("../Routing").INavigationHelper;
@@ -1,6 +1,6 @@
1
1
  import { __awaiter, __decorate, __extends, __generator, __metadata } from "tslib";
2
2
  import React from 'react';
3
- import { observable, runInAction } from 'mobx';
3
+ import { makeObservable, observable, runInAction } from 'mobx';
4
4
  import { Misc } from '@singularsystems/neo-core';
5
5
  import { ViewParameterList } from '../Routing/ViewParameterList';
6
6
  import { ViewState } from './ViewState';
@@ -18,6 +18,8 @@ var ViewBase = /** @class */ (function (_super) {
18
18
  function ViewBase(viewName, viewModel, props) {
19
19
  var _this = _super.call(this, props) || this;
20
20
  _this.viewName = "";
21
+ /** Indicates that the view requests to be displayed full screen. Up to the main layout to accommodate this. */
22
+ _this.fullScreen = false;
21
23
  _this.routingState = Misc.Globals.appService.get(NeoReactTypes.Routing.GlobalRoutingState);
22
24
  _this.navigation = Misc.Globals.appService.get(NeoReactTypes.Routing.NavigationHelper);
23
25
  if (typeof viewName !== "string") {
@@ -26,6 +28,7 @@ var ViewBase = /** @class */ (function (_super) {
26
28
  _this.viewName = viewName;
27
29
  _this.viewState = _this.getStoredViewState(viewModel);
28
30
  _this.routingState.currentView = _this;
31
+ makeObservable(_this);
29
32
  return _this;
30
33
  }
31
34
  Object.defineProperty(ViewBase, "currentView", {
@@ -161,6 +164,10 @@ var ViewBase = /** @class */ (function (_super) {
161
164
  observable.ref,
162
165
  __metadata("design:type", String)
163
166
  ], ViewBase.prototype, "viewName", void 0);
167
+ __decorate([
168
+ observable.ref,
169
+ __metadata("design:type", Boolean)
170
+ ], ViewBase.prototype, "fullScreen", void 0);
164
171
  return ViewBase;
165
172
  }(React.Component));
166
173
  export default ViewBase;
@@ -1,9 +1,9 @@
1
1
  import { ModelBase, Misc, Model, ITaskRunner } from '@singularsystems/neo-core';
2
2
  import { IViewModel } from './IViewModel';
3
3
  import { IReactionDisposer } from 'mobx';
4
- import { BindableBase } from '@singularsystems/neo-core/dist/Model/BindableBase';
5
4
  import { AxiosPromise } from 'axios';
6
5
  import { WaitForTaskRunnerOptions } from '@singularsystems/neo-core/dist/Components/TaskRunner/TaskRunner';
6
+ import { BindableBase } from '@singularsystems/neo-core/dist/Model/BindableBase';
7
7
  export type valueOrLazy<T> = T | (() => T) | (new () => T);
8
8
  export default abstract class ViewModelBase extends ModelBase implements IViewModel {
9
9
  taskRunner: ITaskRunner;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@singularsystems/neo-react",
3
- "version": "1.0.0-beta.0",
3
+ "version": "1.0.0-beta.2",
4
4
  "description": "React application logic and components for the Neo client library",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,7 +29,7 @@
29
29
  "typescript": "5.0.4"
30
30
  },
31
31
  "dependencies": {
32
- "@singularsystems/neo-core": "^1.0.0-alpha.4",
32
+ "@singularsystems/neo-core": "1.0.0-beta.3",
33
33
  "@types/rc-slider": "^8.6.5",
34
34
  "@types/react-color": "^3.0.1",
35
35
  "axios": "1.4.0",
@@ -48,7 +48,7 @@
48
48
  "tslib": "2.5.0"
49
49
  },
50
50
  "peerDependencies": {
51
- "@singularsystems/neo-core": ">=1.0.0",
51
+ "@singularsystems/neo-core": ">=1.0.0-beta.3",
52
52
  "axios": "1.4.0",
53
53
  "inversify": ">=5.0.1",
54
54
  "mobx": ">=6.9.0",
package/styles/Card.scss CHANGED
@@ -14,11 +14,18 @@
14
14
  margin: -10px 0;
15
15
 
16
16
  .card-expand-indicator {
17
- cursor: pointer;
18
17
  margin-left: 0.5rem;
19
18
  padding-top: 0.5rem;
20
19
  padding-bottom: 0.5rem;
21
20
  }
22
21
  }
23
22
  }
23
+
24
+ &.card-collapsible {
25
+ .card-header {
26
+ &:hover {
27
+ cursor: pointer;
28
+ }
29
+ }
30
+ }
24
31
  }
@@ -3,6 +3,17 @@
3
3
  position: relative;
4
4
  width: 100%;
5
5
  color: initial;
6
+
7
+ &.neo-datepicker-always-show {
8
+ width: max-content;
9
+
10
+ input {
11
+ text-align: center;
12
+ padding: 0.125rem 0;
13
+ height: auto;
14
+ margin-bottom: 0.25rem;
15
+ }
16
+ }
6
17
  }
7
18
 
8
19
  .neo-datepicker-popup {
package/styles/Grid.scss CHANGED
@@ -1,4 +1,9 @@
1
1
  table.neo-grid {
2
+ .neo-grid-fixed-header {
3
+ position: fixed;
4
+ z-index: 3;
5
+ }
6
+
2
7
  th {
3
8
  position: relative;
4
9
 
@@ -1,3 +0,0 @@
1
- declare namespace React {
2
- type StatelessComponent<P> = React.FunctionComponent<P>;
3
- }
File without changes
@@ -1 +0,0 @@
1
- {"version":3,"file":"NeoReactModule.js","sourceRoot":"","sources":["../../src/Modules/NeoReactModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,gBAAgB,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iDAAiD,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,IAAM,cAAc,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,UAAA,SAAS;IAEhE,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACrG,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAChG,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACzF,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,eAAe,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC;IACvG,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAEtG,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAC7F,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAE/F,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAE1F,aAAa,CAAC,SAAS,CAAC,CAAC;AAE7B,CAAC,CAAC,CAAC;AAEH,eAAe,cAAc,CAAC"}