@talxis/base-controls 1.2406.2 → 1.2406.4

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 (214) hide show
  1. package/package.json +1 -1
  2. package/.env +0 -1
  3. package/.eslintrc +0 -117
  4. package/.npmgitignore +0 -9
  5. package/.vscode/settings.json +0 -3
  6. package/.yalcignore +0 -2
  7. package/azure-pipelines.yml +0 -44
  8. package/examples/Currency/Currency/ControlManifest.Input.xml +0 -53
  9. package/examples/Currency/Currency/index.ts +0 -66
  10. package/examples/Currency/Currency.pcfproj +0 -46
  11. package/examples/Currency/package-lock.json +0 -15900
  12. package/examples/Currency/package.json +0 -29
  13. package/examples/Currency/pcfconfig.json +0 -3
  14. package/examples/Currency/tsconfig.json +0 -7
  15. package/examples/DateTime/DateTime/ControlManifest.Input.xml +0 -58
  16. package/examples/DateTime/DateTime/index.ts +0 -69
  17. package/examples/DateTime/DateTime.pcfproj +0 -46
  18. package/examples/DateTime/package-lock.json +0 -15900
  19. package/examples/DateTime/package.json +0 -29
  20. package/examples/DateTime/pcfconfig.json +0 -3
  21. package/examples/DateTime/tsconfig.json +0 -7
  22. package/examples/Decimal/Decimal/ControlManifest.Input.xml +0 -66
  23. package/examples/Decimal/Decimal/index.ts +0 -66
  24. package/examples/Decimal/Decimal.pcfproj +0 -46
  25. package/examples/Decimal/package-lock.json +0 -15900
  26. package/examples/Decimal/package.json +0 -28
  27. package/examples/Decimal/pcfconfig.json +0 -3
  28. package/examples/Decimal/tsconfig.json +0 -7
  29. package/examples/Duration/Duration/ControlManifest.Input.xml +0 -53
  30. package/examples/Duration/Duration/index.ts +0 -66
  31. package/examples/Duration/Duration.pcfproj +0 -46
  32. package/examples/Duration/package-lock.json +0 -15900
  33. package/examples/Duration/package.json +0 -29
  34. package/examples/Duration/pcfconfig.json +0 -3
  35. package/examples/Duration/tsconfig.json +0 -7
  36. package/examples/Grid/Grid/ControlManifest.Input.xml +0 -28
  37. package/examples/Grid/Grid/index.ts +0 -100
  38. package/examples/Grid/Grid.pcfproj +0 -46
  39. package/examples/Grid/package-lock.json +0 -15901
  40. package/examples/Grid/package.json +0 -30
  41. package/examples/Grid/pcfconfig.json +0 -3
  42. package/examples/Grid/tsconfig.json +0 -7
  43. package/examples/Lookup/Lookup/ControlManifest.Input.xml +0 -51
  44. package/examples/Lookup/Lookup/index.ts +0 -90
  45. package/examples/Lookup/Lookup.pcfproj +0 -46
  46. package/examples/Lookup/package-lock.json +0 -15900
  47. package/examples/Lookup/package.json +0 -29
  48. package/examples/Lookup/pcfconfig.json +0 -3
  49. package/examples/Lookup/tsconfig.json +0 -8
  50. package/examples/MultiSelectOptionSet/MultiSelectOptionSet/ControlManifest.Input.xml +0 -53
  51. package/examples/MultiSelectOptionSet/MultiSelectOptionSet/index.ts +0 -86
  52. package/examples/MultiSelectOptionSet/MultiSelectOptionSet.pcfproj +0 -46
  53. package/examples/MultiSelectOptionSet/package-lock.json +0 -15900
  54. package/examples/MultiSelectOptionSet/package.json +0 -31
  55. package/examples/MultiSelectOptionSet/pcfconfig.json +0 -3
  56. package/examples/MultiSelectOptionSet/tsconfig.json +0 -7
  57. package/examples/OptionSet/OptionSet/ControlManifest.Input.xml +0 -53
  58. package/examples/OptionSet/OptionSet/index.ts +0 -70
  59. package/examples/OptionSet/OptionSet.pcfproj +0 -46
  60. package/examples/OptionSet/package-lock.json +0 -15900
  61. package/examples/OptionSet/package.json +0 -29
  62. package/examples/OptionSet/pcfconfig.json +0 -3
  63. package/examples/OptionSet/tsconfig.json +0 -7
  64. package/examples/TwoOptions/TwoOptions/ControlManifest.Input.xml +0 -53
  65. package/examples/TwoOptions/TwoOptions/index.ts +0 -69
  66. package/examples/TwoOptions/TwoOptions.pcfproj +0 -46
  67. package/examples/TwoOptions/package-lock.json +0 -15900
  68. package/examples/TwoOptions/package.json +0 -29
  69. package/examples/TwoOptions/pcfconfig.json +0 -3
  70. package/examples/TwoOptions/tsconfig.json +0 -7
  71. package/public/index.html +0 -43
  72. package/public/manifest.json +0 -25
  73. package/rollup.config.js +0 -44
  74. package/src/components/DateTime/DateTime.tsx +0 -97
  75. package/src/components/DateTime/components/Calendar.tsx +0 -80
  76. package/src/components/DateTime/hooks/useDateTime.ts +0 -144
  77. package/src/components/DateTime/index.ts +0 -2
  78. package/src/components/DateTime/interfaces.ts +0 -22
  79. package/src/components/DateTime/styles.ts +0 -37
  80. package/src/components/DateTime/translations.ts +0 -18
  81. package/src/components/Decimal/Decimal.tsx +0 -120
  82. package/src/components/Decimal/index.ts +0 -2
  83. package/src/components/Decimal/interfaces.ts +0 -20
  84. package/src/components/Duration/Duration.tsx +0 -143
  85. package/src/components/Duration/index.ts +0 -2
  86. package/src/components/Duration/interfaces.ts +0 -22
  87. package/src/components/Duration/translations.ts +0 -30
  88. package/src/components/Grid/Grid.tsx +0 -24
  89. package/src/components/Grid/core/components/AgGrid/AgGrid.tsx +0 -206
  90. package/src/components/Grid/core/components/AgGrid/components/EmptyRecordsOverlay/EmptyRecords.tsx +0 -16
  91. package/src/components/Grid/core/components/AgGrid/components/EmptyRecordsOverlay/styles.ts +0 -20
  92. package/src/components/Grid/core/components/AgGrid/components/LoadingOverlay/LoadingOverlay.tsx +0 -7
  93. package/src/components/Grid/core/components/AgGrid/controllers/useAgGridController.ts +0 -68
  94. package/src/components/Grid/core/components/AgGrid/model/AgGrid.ts +0 -100
  95. package/src/components/Grid/core/components/AgGrid/styles.ts +0 -72
  96. package/src/components/Grid/core/components/Cell/Commands/Commands.tsx +0 -32
  97. package/src/components/Grid/core/components/Cell/Commands/Icon.tsx +0 -17
  98. package/src/components/Grid/core/components/Cell/Commands/styles.ts +0 -21
  99. package/src/components/Grid/core/components/Cell/Commands/useCommands.tsx +0 -53
  100. package/src/components/Grid/core/components/Cell/EditableCell/EditableCell.tsx +0 -140
  101. package/src/components/Grid/core/components/Cell/ReadOnlyCell/ReadOnlyCell.tsx +0 -176
  102. package/src/components/Grid/core/components/Cell/ReadOnlyCell/ReadOnlyOptionSet/ReadOnlyOptionSet.tsx +0 -67
  103. package/src/components/Grid/core/components/Cell/ReadOnlyCell/ReadOnlyOptionSet/styles.ts +0 -24
  104. package/src/components/Grid/core/components/Cell/ReadOnlyCell/styles.ts +0 -56
  105. package/src/components/Grid/core/components/ColumnHeader/ColumnHeader.tsx +0 -71
  106. package/src/components/Grid/core/components/ColumnHeader/components/GlobalCheckbox/GlobalCheckbox.tsx +0 -31
  107. package/src/components/Grid/core/components/ColumnHeader/components/GlobalCheckbox/styles.ts +0 -16
  108. package/src/components/Grid/core/components/ColumnHeader/styles.ts +0 -40
  109. package/src/components/Grid/core/components/Component/Component.tsx +0 -59
  110. package/src/components/Grid/core/components/Component/controller/useComponentController.ts +0 -39
  111. package/src/components/Grid/core/components/Component/model/Component.ts +0 -251
  112. package/src/components/Grid/core/components/Dialog/Constants.tsx +0 -8
  113. package/src/components/Grid/core/components/Dialog/Styles.tsx +0 -61
  114. package/src/components/Grid/core/components/Dialog/index.tsx +0 -22
  115. package/src/components/Grid/core/components/Dialog/interfaces/index.d.ts +0 -7
  116. package/src/components/Grid/core/components/Save/Save.tsx +0 -74
  117. package/src/components/Grid/core/components/Save/components/ChangeEditor/ChangeEditor.tsx +0 -63
  118. package/src/components/Grid/core/components/Save/components/ChangeEditor/components/RecordGrids/RecordGrids.tsx +0 -153
  119. package/src/components/Grid/core/components/Save/components/ChangeEditor/components/RecordGrids/styles.ts +0 -52
  120. package/src/components/Grid/core/components/Save/components/ChangeEditor/styles.ts +0 -34
  121. package/src/components/Grid/core/components/Save/hooks/useSave.ts +0 -59
  122. package/src/components/Grid/core/components/Save/styles.ts +0 -41
  123. package/src/components/Grid/core/controllers/useGridController.ts +0 -46
  124. package/src/components/Grid/core/enums/ConditionOperator.ts +0 -46
  125. package/src/components/Grid/core/enums/DataType.ts +0 -25
  126. package/src/components/Grid/core/hooks/useGridInstance.ts +0 -7
  127. package/src/components/Grid/core/hooks/useRefreshCallback.ts +0 -20
  128. package/src/components/Grid/core/hooks/useRerender.ts +0 -15
  129. package/src/components/Grid/core/interfaces/IGridColumn.ts +0 -19
  130. package/src/components/Grid/core/interfaces/IGridContext.ts +0 -7
  131. package/src/components/Grid/core/model/Grid.ts +0 -250
  132. package/src/components/Grid/core/model/GridDependency.ts +0 -34
  133. package/src/components/Grid/core/model/Metadata.ts +0 -20
  134. package/src/components/Grid/core/services/RecordUpdateService/controllers/useRecordUpdateServiceController.ts +0 -36
  135. package/src/components/Grid/core/services/RecordUpdateService/model/RecordUpdateService.ts +0 -222
  136. package/src/components/Grid/filtering/components/FilterCallout/FilterCallout.tsx +0 -83
  137. package/src/components/Grid/filtering/components/FilterCallout/components/ConditionOperator/ConditionOperator.tsx +0 -66
  138. package/src/components/Grid/filtering/components/FilterCallout/components/ConditionValue/ConditionValue.tsx +0 -48
  139. package/src/components/Grid/filtering/components/FilterCallout/components/ConditionValue/model/ConditionComponentValue.ts +0 -120
  140. package/src/components/Grid/filtering/components/FilterCallout/styles.ts +0 -37
  141. package/src/components/Grid/filtering/constants.ts +0 -48
  142. package/src/components/Grid/filtering/controller/useColumnFilterConditionController.ts +0 -63
  143. package/src/components/Grid/filtering/model/Condition.ts +0 -309
  144. package/src/components/Grid/filtering/model/Filtering.ts +0 -78
  145. package/src/components/Grid/filtering/utils/FilteringUtilts.ts +0 -190
  146. package/src/components/Grid/interfaces.ts +0 -109
  147. package/src/components/Grid/paging/components/Paging/Paging.tsx +0 -76
  148. package/src/components/Grid/paging/components/Paging/styles.ts +0 -38
  149. package/src/components/Grid/paging/controllers/usePagingController.ts +0 -34
  150. package/src/components/Grid/paging/model/Paging.ts +0 -49
  151. package/src/components/Grid/selection/controllers/useSelectionController.ts +0 -25
  152. package/src/components/Grid/selection/model/Selection.ts +0 -60
  153. package/src/components/Grid/sorting/Sorting.ts +0 -30
  154. package/src/components/Grid/sorting/components/SortingContextualMenu/SortingContextualMenu.tsx +0 -126
  155. package/src/components/Grid/sorting/components/SortingContextualMenu/styles.ts +0 -12
  156. package/src/components/Grid/sorting/controllers/useColumnSortingController.ts +0 -26
  157. package/src/components/Grid/translations.ts +0 -80
  158. package/src/components/Grid/validation/controllers/useRecordValidationController.ts +0 -31
  159. package/src/components/Grid/validation/model/ColumnValidation.ts +0 -81
  160. package/src/components/Lookup/Lookup.tsx +0 -199
  161. package/src/components/Lookup/components/RecordCreator.tsx +0 -53
  162. package/src/components/Lookup/components/TargetSelector.tsx +0 -43
  163. package/src/components/Lookup/hooks/useFetchXml.ts +0 -31
  164. package/src/components/Lookup/hooks/useLoadedEntities.ts +0 -23
  165. package/src/components/Lookup/hooks/useLookup.ts +0 -126
  166. package/src/components/Lookup/index.ts +0 -2
  167. package/src/components/Lookup/interfaces.ts +0 -45
  168. package/src/components/Lookup/lib.ts +0 -3110
  169. package/src/components/Lookup/styles.ts +0 -106
  170. package/src/components/Lookup/translations.ts +0 -28
  171. package/src/components/MultiSelectOptionSet/MultiSelectOptionSet.tsx +0 -83
  172. package/src/components/MultiSelectOptionSet/index.ts +0 -2
  173. package/src/components/MultiSelectOptionSet/interfaces.ts +0 -14
  174. package/src/components/OptionSet/OptionSet.tsx +0 -67
  175. package/src/components/OptionSet/index.ts +0 -2
  176. package/src/components/OptionSet/interfaces.ts +0 -17
  177. package/src/components/TextField/TextField.tsx +0 -58
  178. package/src/components/TextField/hooks/useTextField.ts +0 -42
  179. package/src/components/TextField/index.ts +0 -2
  180. package/src/components/TextField/interfaces.ts +0 -20
  181. package/src/components/TwoOptions/TwoOptions.tsx +0 -43
  182. package/src/components/TwoOptions/index.ts +0 -2
  183. package/src/components/TwoOptions/interfaces.ts +0 -17
  184. package/src/hooks/index.ts +0 -1
  185. package/src/hooks/useComponent.ts +0 -83
  186. package/src/hooks/useFocusIn.ts +0 -23
  187. package/src/hooks/useInputBasedComponent.ts +0 -71
  188. package/src/hooks/useMouseOver.ts +0 -23
  189. package/src/index.tsx +0 -12
  190. package/src/interfaces/context.ts +0 -21
  191. package/src/interfaces/index.ts +0 -12
  192. package/src/interfaces/parameters.ts +0 -26
  193. package/src/interfaces/property.ts +0 -111
  194. package/src/sandbox/index.tsx +0 -137
  195. package/src/sandbox/mock/Context.ts +0 -18
  196. package/src/sandbox/mock/Formatting.ts +0 -186
  197. package/src/sandbox/mock/Mode.ts +0 -25
  198. package/src/sandbox/mock/UserSettings.ts +0 -31
  199. package/src/sandbox/mock/Utility.ts +0 -14
  200. package/src/sandbox/shared/durationList.tsx +0 -24
  201. package/src/sandbox/shared/multiSelectOptionList.tsx +0 -5
  202. package/src/sandbox/shared/optionList.tsx +0 -5
  203. package/src/stories/Introduction.stories.mdx +0 -122
  204. package/src/stories/assets/code-brackets.svg +0 -1
  205. package/src/stories/assets/colors.svg +0 -1
  206. package/src/stories/assets/comments.svg +0 -1
  207. package/src/stories/assets/direction.svg +0 -1
  208. package/src/stories/assets/flow.svg +0 -1
  209. package/src/stories/assets/plugin.svg +0 -1
  210. package/src/stories/assets/repo.svg +0 -1
  211. package/src/stories/assets/stackalt.svg +0 -1
  212. package/src/types/index.ts +0 -3
  213. package/src/utils/NumeralPCF.ts +0 -62
  214. package/tsconfig.json +0 -28
@@ -1,120 +0,0 @@
1
- import { TextField } from "@talxis/react-components/dist/components/TextField";
2
- import { useInputBasedComponent } from "../../hooks/useInputBasedComponent";
3
- import { IDecimal, IDecimalOutputs, IDecimalParameters, IDecimalTranslations } from "./interfaces";
4
- import React, { useEffect } from "react";
5
- import numeral from "numeral";
6
- import { NumeralPCF } from "../../utils/NumeralPCF";
7
-
8
- export const Decimal = (props: IDecimal) => {
9
- const context = props.context;
10
- const parameters = props.parameters;
11
- const boundValue = parameters.value;
12
- const numberFormatting = context.userSettings.numberFormattingInfo;
13
-
14
- const formatter = (value: string | number | null): string | undefined => {
15
- if (value == null) {
16
- return undefined;
17
- }
18
- if (isNaN(value as number)) {
19
- return value as string;
20
- }
21
- if (props.parameters.value.type === 'Decimal') {
22
- return context.formatting.formatDecimal(parseFloat(value as string), boundValue.attributes?.Precision);
23
- }
24
- if(props.parameters.value.type === 'Currency') {
25
- return props.parameters.value.formatted;
26
- }
27
- return context.formatting.formatInteger(parseInt(value as string));
28
- };
29
-
30
- const extractNumericPart = (str: any): number | undefined => {
31
- // Currency control just sends the string up and lets the framework decide whether the value is correct
32
- // It only tries to parse the number based on the current user format
33
- // This means that the value will also pass if the user inputs his own currency even though
34
- // the currency is different on the field
35
- const escapeRegExp = (string: string) => {
36
- return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // Escaping utility function
37
- }
38
-
39
- let regex: RegExp;
40
- NumeralPCF.decimal(numberFormatting);
41
- if (props.parameters.value.type === 'Decimal') {
42
- regex = new RegExp('^[' + '\\d' + escapeRegExp(numberFormatting.numberDecimalSeparator) + escapeRegExp(numberFormatting.numberGroupSeparator) + '\\s' + escapeRegExp(numberFormatting.negativeSign) + ']+$');
43
- } else if (props.parameters.value.type === 'Currency') {
44
- NumeralPCF.currency(numberFormatting);
45
- regex = new RegExp(
46
- '^\\s*' +
47
- '(?:' + escapeRegExp(numberFormatting.currencySymbol) + '\\s*)?' +
48
- '[' +
49
- '\\d' +
50
- escapeRegExp(numberFormatting.currencyDecimalSeparator) +
51
- escapeRegExp(numberFormatting.currencyGroupSeparator) +
52
- '\\s' +
53
- escapeRegExp(numberFormatting.negativeSign) +
54
- ']*' +
55
- '(?:\\s*' + escapeRegExp(numberFormatting.currencySymbol) + ')?' +
56
- '\\s*$'
57
- );
58
- } else {
59
- regex = new RegExp('^[' + '\\d' + escapeRegExp(numberFormatting.numberGroupSeparator) + '\\s' + escapeRegExp(numberFormatting.negativeSign) + ']+$');
60
- }
61
- if (regex.test(str)) {
62
- return numeral(str).value() ?? undefined;
63
- }
64
- return str; // Return undefined if no numeric part is extracted
65
- };
66
-
67
-
68
-
69
- const [value, labels, setValue, onNotifyOutputChanged] = useInputBasedComponent<string | undefined, IDecimalParameters, IDecimalOutputs, IDecimalTranslations>('Decimal', props, {
70
- formatter: formatter,
71
- valueExtractor: extractNumericPart
72
- });
73
-
74
- return (
75
- <TextField
76
- readOnly={context.mode.isControlDisabled}
77
- autoFocus={parameters.AutoFocus?.raw}
78
- borderless={parameters.EnableBorder?.raw === false}
79
- errorMessage={boundValue.errorMessage}
80
- styles={{
81
- fieldGroup: {
82
- height: context.mode.allocatedHeight || undefined,
83
- width: context.mode.allocatedWidth || undefined
84
- }
85
- }}
86
- deleteButtonProps={
87
- parameters.EnableDeleteButton?.raw === true
88
- ? {
89
- key: "delete",
90
- showOnlyOnHover: true,
91
- iconProps: {
92
- iconName: "Delete",
93
- },
94
- onClick: () => setValue(undefined),
95
- }
96
- : undefined
97
- }
98
- clickToCopyProps={
99
- parameters.EnableCopyButton?.raw === true
100
- ? {
101
- key: "copy",
102
- showOnlyOnHover: true,
103
- iconProps: {
104
- iconName: "Copy",
105
- },
106
- }
107
- : undefined
108
- }
109
- value={value ?? ""}
110
- onBlur={(event) => {
111
- onNotifyOutputChanged({
112
- value: extractNumericPart(event.target.value)
113
- });
114
- }}
115
- onChange={(e, value) => {
116
- setValue(value);
117
- }}
118
- />
119
- );
120
- };
@@ -1,2 +0,0 @@
1
- export * from "./Decimal";
2
- export * from "./interfaces";
@@ -1,20 +0,0 @@
1
- import { IDecimalNumberProperty } from "../../interfaces";
2
- import { IInputParameters } from "../../interfaces/parameters";
3
- import { IComponent, IOutputs, ITranslations } from "../../interfaces/context";
4
-
5
- export interface IDecimal extends IComponent<IDecimalParameters, IDecimalOutputs, IDecimalTranslations> {
6
-
7
- }
8
-
9
- export interface IDecimalParameters extends IInputParameters {
10
- //bound parameter
11
- value: IDecimalNumberProperty;
12
- }
13
-
14
- export interface IDecimalOutputs extends IOutputs {
15
- value?: number;
16
- }
17
-
18
- export interface IDecimalTranslations extends ITranslations {
19
-
20
- }
@@ -1,143 +0,0 @@
1
- import { ComboBox } from '@talxis/react-components/dist/components/ComboBox';
2
- import React, { useEffect } from 'react';
3
- import { useInputBasedComponent } from '../../hooks/useInputBasedComponent';
4
- import { IDuration, IDurationOutputs, IDurationParameters, IDurationTranslations } from './interfaces';
5
- import { IComboBoxOption } from '@fluentui/react';
6
- import { durationOptions } from '../../sandbox/shared/durationList';
7
- import { UserSettings } from '../../sandbox/mock/UserSettings';
8
- import numeral from "numeral";
9
- import { NumeralPCF } from '../../utils/NumeralPCF';
10
- import { getDefaultDurationTranslations } from './translations';
11
-
12
- export const Duration = (props: IDuration) => {
13
- const parameters = props.parameters;
14
- const boundValue = parameters.value;
15
- const context = props.context;
16
- const humanizeDuration = require("humanize-duration");
17
- const formattingInfo = context.userSettings as UserSettings;
18
- const language = formattingInfo.locale;
19
- const numberFormatting = context.userSettings.numberFormattingInfo;
20
-
21
- const formatter = (value: number | null) => {
22
- //all duration formatting should happen here
23
- if (value === null) return null;
24
- const durationInMilliseconds = value * 60000;
25
- const units = value < 60 ? ['m'] : value >= 1440 ? ['d'] : ['h'];
26
- const options = {
27
- units: units,
28
- maxDecimalPoints: 2,
29
- language: language.slice(0, language.indexOf("-")),
30
- decimal: context.userSettings.numberFormattingInfo.numberDecimalSeparator,
31
- fallbacks: ["en"]
32
- };
33
- return humanizeDuration(durationInMilliseconds, options);
34
- };
35
-
36
- const valueExtractor = (str: string | null): number | undefined => {
37
- //extraction of number of minutes from formatted string should happen here
38
- // parsing because labels are string that represent array of strings
39
- const minuteLabels= JSON.parse(labels.minute());
40
- const minutesLabels= JSON.parse(labels.minutes());
41
- const hourLabels= JSON.parse(labels.hour());
42
- const hoursLabels= JSON.parse(labels.hours());
43
- const dayLabels= JSON.parse(labels.day());
44
- const daysLabels= JSON.parse(labels.days());
45
- const minuteRegex = new RegExp("^(" + minuteLabels.join('|') + ")\\s|\\s(" + minuteLabels.join('|') + ")$|^(" + minutesLabels.join('|') + ")\\s|\\s(" + minutesLabels.join('|') + ")$", "i");
46
- const hourRegex = new RegExp("^(" + hourLabels.join('|') + ")\\s|\\s(" + hourLabels.join('|') + ")$|^(" + hoursLabels.join('|') + ")\\s|\\s(" + hoursLabels.join('|') + ")$", "i");
47
- const dayRegex = new RegExp("^(" + dayLabels.join('|') + ")\\s|\\s(" + dayLabels.join('|') + ")$|^(" + daysLabels.join('|') + ")\\s|\\s(" + daysLabels.join('|') + ")$", "i");
48
-
49
- if (str && str.trim()) {
50
- let input = str.trim().toLowerCase();
51
- let unit = 'minute';
52
-
53
- if (minuteRegex.test(input)) {
54
- input = input.replace(minuteRegex, "").trim();
55
- } else if (hourRegex.test(input)) {
56
- input = input.replace(hourRegex, "").trim();
57
- unit = 'hour';
58
- } else if (dayRegex.test(input)) {
59
- input = input.replace(dayRegex, "").trim();
60
- unit = 'day';
61
- }
62
- const parsedNumber = parseNumber(input);
63
- if (parsedNumber && !isNaN(parsedNumber)) {
64
- return getDurationInMinutes(parsedNumber, unit);
65
- }
66
- return NaN;
67
- }
68
- return undefined;
69
- };
70
-
71
- const parseNumber = (input: string): number | undefined => {
72
- NumeralPCF.decimal(numberFormatting);
73
- return numeral(input).value() ?? undefined;
74
- };
75
-
76
- const getDurationInMinutes = (value: number, unit: string): number => {
77
- switch (unit) {
78
- case 'hour':
79
- return 60 * value;
80
- case 'day':
81
- return 60 * value * 24;
82
- case 'minute':
83
- default:
84
- return value;
85
- }
86
- };
87
-
88
- const presetOptions = (): IComboBoxOption[] => {
89
- const formattedOptions = durationOptions.map(option => ({
90
- key: option.Value.toString(),
91
- text: formatter(parseInt(option.Label)),
92
- }));
93
- return formattedOptions;
94
- };
95
-
96
- const comboBoxOptions: IComboBoxOption[] = presetOptions();
97
-
98
- const [value, labels, setValue, onNotifyOutputChanged] = useInputBasedComponent<string | null, IDurationParameters, IDurationOutputs, IDurationTranslations>('Duration', props, {
99
- formatter: formatter,
100
- valueExtractor: valueExtractor,
101
- defaultTranslations: getDefaultDurationTranslations(),
102
- });
103
-
104
- return (
105
- <ComboBox
106
- borderless={parameters.EnableBorder?.raw === false}
107
- options={comboBoxOptions}
108
- allowFreeInput={true}
109
- autoComplete='on'
110
- autofill={parameters.AutoFocus?.raw === true ? {
111
- autoFocus: true
112
- } : undefined}
113
- readOnly={context.mode.isControlDisabled}
114
- useComboBoxAsMenuWidth
115
- errorMessage={boundValue.errorMessage}
116
- text={value ?? ''}
117
- styles={{
118
- root: {
119
- height: context.mode.allocatedHeight || undefined,
120
- width: context.mode.allocatedWidth || undefined,
121
- display: 'flex',
122
- alignItems: 'center',
123
- },
124
- callout: {
125
- height: 300
126
- }
127
- }}
128
- onInputValueChange={(text) => {
129
- setValue(text ?? '');
130
- }}
131
- onBlur={(event) => {
132
- onNotifyOutputChanged({
133
- value: valueExtractor(value)
134
- });
135
- }}
136
- onChange={(e, value) => {
137
- onNotifyOutputChanged({
138
- value: valueExtractor(value?.text ?? '')
139
- });
140
- }}
141
- />
142
- );
143
- };
@@ -1,2 +0,0 @@
1
- export * from './Duration';
2
- export * from './interfaces';
@@ -1,22 +0,0 @@
1
- import { IWholeNumberProperty } from "../../interfaces";
2
- import { IComponent, IOutputs, ITranslations } from "../../interfaces/context";
3
- import { IBaseParameters } from "../../interfaces/parameters";
4
-
5
- export interface IDuration extends IComponent<IDurationParameters, IDurationOutputs, IDurationTranslations> {
6
- }
7
-
8
- export interface IDurationParameters extends IBaseParameters {
9
- value: IWholeNumberProperty;
10
- }
11
-
12
- export interface IDurationOutputs extends IOutputs {
13
- value?: number
14
- }
15
- export interface IDurationTranslations extends ITranslations {
16
- minute?: {[LCID: number]: string []}
17
- minutes?: {[LCID: number]: string[]}
18
- hour?: {[LCID: number]: string[]}
19
- hours?: {[LCID: number]: string[]}
20
- day?: {[LCID: number]: string[]}
21
- days?: {[LCID: number]: string[]}
22
- }
@@ -1,30 +0,0 @@
1
- import { IDurationTranslations } from "./interfaces";
2
-
3
- export const getDefaultDurationTranslations = (): Required<IDurationTranslations> => {
4
- return {
5
- minute: {
6
- 1029: ['min','minuta', 'minuty', 'minute', 'minutu', 'minutě', 'minutou', 'minuta', 'minuty', 'minute', 'minutu', 'minute', 'minutou'],
7
- 1033: ['min','minute']
8
- },
9
- minutes: {
10
- 1029: ['minuty', 'minut', 'minutám', 'minutách', 'minutami', 'minuty', 'minut', 'minutam', 'minutach', 'minutami'],
11
- 1033: ['minutes']
12
- },
13
- hour: {
14
- 1029: ['hod','hodina', 'hodiny', 'hodině', 'hodinu', 'hodinou', 'hodina', 'hodiny', 'hodine', 'hodinu', 'hodinou'],
15
- 1033: ['hour']
16
- },
17
- hours: {
18
- 1029: ['hodiny', 'hodin', 'hodinám', 'hodinách', 'hodinami', 'hodiny', 'hodin', 'hodinam', 'hodinach', 'hodinami'],
19
- 1033: ['hours']
20
- },
21
- day: {
22
- 1029: ['den', 'dne', 'dni', 'dnu', 'dnem', 'den', 'dne', 'dni', 'dnu', 'dnem'],
23
- 1033: ['day']
24
- },
25
- days: {
26
- 1029: ['dny', 'dnů', 'dnům', 'dnech', 'dny', 'dní', 'dny', 'dnu', 'dnom', 'dnech', 'dny', 'dni'],
27
- 1033: ['days']
28
- },
29
- };
30
- };
@@ -1,24 +0,0 @@
1
- import { createContext, useMemo } from "react";
2
- import { useComponent } from "../../hooks"
3
- import { IGridContext } from "./core/interfaces/IGridContext";
4
- import { Grid as GridModel } from "./core/model/Grid";
5
- import { IGrid } from "./interfaces";
6
- import { AgGrid } from './core/components/AgGrid/AgGrid';
7
- import React from 'react';
8
- import { gridTranslations } from './translations';
9
-
10
- export const GridContext = createContext<IGridContext>(null as any);
11
-
12
- export const Grid = (props: IGrid) => {
13
- const [labels, notifyOutputChanged] = useComponent('Grid', props, gridTranslations);
14
- const grid = useMemo(() => new GridModel(props, labels), []);
15
- grid.updateDependencies(props);
16
-
17
- return (
18
- <GridContext.Provider value={{
19
- gridInstance: grid
20
- }}>
21
- <AgGrid />
22
- </GridContext.Provider>
23
- )
24
- }
@@ -1,206 +0,0 @@
1
- import { AgGridReact } from '@ag-grid-community/react';
2
- import { MessageBar, MessageBarType, useTheme } from "@fluentui/react";
3
- import { ColumnApi, GridApi, GridState } from "@ag-grid-community/core";
4
- import { useEffect, useRef } from "react";
5
- import { useSelectionController } from "../../../selection/controllers/useSelectionController";
6
- import { useGridInstance } from "../../hooks/useGridInstance";
7
- import { getGridStyles } from "./styles";
8
- import React from 'react';
9
- import { useAgGridController } from "./controllers/useAgGridController";
10
- import { Paging } from "../../../paging/components/Paging/Paging";
11
- import { EmptyRecords } from "./components/EmptyRecordsOverlay/EmptyRecords";
12
- import { Save } from "../Save/Save";
13
- import { LoadingOverlay } from "./components/LoadingOverlay/LoadingOverlay";
14
- import { useStateValues } from '@talxis/react-components/dist/hooks';
15
- import { usePagingController } from '../../../paging/controllers/usePagingController';
16
- import { IUpdatedRecord } from '../../services/RecordUpdateService/model/RecordUpdateService';
17
-
18
- interface IAgGridState extends GridState {
19
- '__updatedRecords'?: IUpdatedRecord[]
20
- }
21
-
22
- export const AgGrid = () => {
23
- const grid = useGridInstance();
24
- const selection = useSelectionController();
25
- const gridApiRef = useRef<GridApi<ComponentFramework.PropertyHelper.DataSetApi.EntityRecord>>();
26
- const gridColumnApiRef = useRef<ColumnApi>();
27
- const containerRef = useRef<HTMLDivElement>(null);
28
- const theme = useTheme();
29
- //used for grid sizing - only the initial pageSize is relevant for this case
30
- let { agColumns, records, onGridReady } = useAgGridController(gridApiRef);
31
- const [stateValuesRef, getNewStateValues, setDefaultStateValues] = useStateValues<IAgGridState>(grid.state as IAgGridState);
32
- const pagingController = usePagingController();
33
- const pageSizeRef = useRef<number>(pagingController.pageSize);
34
- const firstRenderRef = useRef(true);
35
-
36
- useEffect(() => {
37
- const globalClickHandler = (e: MouseEvent) => {
38
- const hasAncestorWithClass = (element: HTMLElement, className: string): boolean => {
39
- let parent = element;
40
- while (!parent.classList.contains('ag-theme-balham')) {
41
- if (parent.classList.contains(className)) {
42
- return true;
43
- }
44
- if (parent.tagName === 'HTML') {
45
- return false;
46
- }
47
- parent = parent.parentElement!;
48
- if (!parent) {
49
- return true;
50
- }
51
- }
52
- return false;
53
- };
54
- try {
55
- if (!hasAncestorWithClass(e.target as HTMLElement, 'ag-cell')) {
56
- gridApiRef.current?.stopEditing();
57
- }
58
- }
59
- catch (err) {
60
- }
61
- }
62
- document.addEventListener('click', globalClickHandler)
63
- return () => {
64
- document.removeEventListener('click', globalClickHandler);
65
- if (!gridApiRef.current || grid.isNested) {
66
- return;
67
- }
68
- stateValuesRef.current.__updatedRecords = grid.recordUpdateService.updatedRecords;
69
- grid.pcfContext.mode.setControlState(getNewStateValues());
70
- }
71
- }, []);
72
-
73
- useEffect(() => {
74
- const onBeforeUnload = (ev: BeforeUnloadEvent) => {
75
- if(grid.recordUpdateService.isDirty) {
76
- ev.preventDefault();
77
- return 'Unsaved changes!'
78
- }
79
- }
80
- window.addEventListener('beforeunload', onBeforeUnload);
81
- return () => {
82
- window.removeEventListener('beforeunload', onBeforeUnload);
83
- }
84
- }, []);
85
-
86
- useEffect(() => {
87
- if (!gridApiRef.current) {
88
- return;
89
- }
90
- if (grid.loading) {
91
- gridApiRef.current.showLoadingOverlay();
92
- return;
93
- }
94
- gridApiRef.current.hideOverlay()
95
- }, [grid.loading]);
96
-
97
- useEffect(() => {
98
- if (firstRenderRef.current) {
99
- firstRenderRef.current = false;
100
- return;
101
- }
102
- gridApiRef.current?.ensureIndexVisible(0)
103
- }, [pagingController.pageNumber]);
104
-
105
-
106
-
107
- const getColumnsWidth = () => {
108
- let width = 0;
109
- for (const column of gridColumnApiRef.current!.getAllGridColumns()) {
110
- width = width + column.getActualWidth();
111
- }
112
- return width;
113
- }
114
-
115
- const getAvailableWidth = () => {
116
- const rootWrapper = containerRef.current?.querySelector('.ag-root-wrapper');
117
- return rootWrapper?.clientWidth ?? 0;
118
- }
119
-
120
- const sizeColumnsIfSpaceAvailable = () => {
121
- const totalWidth = getColumnsWidth();
122
- const availableWidth = getAvailableWidth();
123
- if (availableWidth > totalWidth) {
124
- gridApiRef.current!.sizeColumnsToFit();
125
- }
126
- }
127
-
128
- const getGridHeight = () => {
129
- if (pageSizeRef.current < grid.records.length) {
130
- return pageSizeRef.current;
131
- }
132
- return grid.records.length;
133
- }
134
-
135
- const styles = getGridStyles(theme, getGridHeight());
136
- return (
137
- <div ref={containerRef} className={`${styles.root} ag-theme-balham`}>
138
- {((grid.isEditable && grid.parameters.ChangeEditorMode?.raw !== 'edit') || grid.parameters.ChangeEditorMode?.raw === 'read') &&
139
- <Save />
140
- }
141
- {grid.error &&
142
- <MessageBar messageBarType={MessageBarType.error}>
143
- <span dangerouslySetInnerHTML={{
144
- __html: grid.errorMessage!
145
- }} />
146
- </MessageBar>
147
- }
148
- <AgGridReact
149
- animateRows
150
- rowBuffer={0}
151
- rowSelection={grid.selection.type}
152
- noRowsOverlayComponent={EmptyRecords}
153
- loadingOverlayComponent={LoadingOverlay}
154
- onRowSelected={(e) => {
155
- //prevent infinite loop since we are also setting the rows
156
- //when the selection comes from above
157
- if (e.source.includes('api')) {
158
- return;
159
- }
160
- selection.toggle(e.data!, e.node.isSelected()!)
161
- }}
162
- onCellDoubleClicked={(e) => {
163
- if (grid.isNavigationEnabled && !grid.isEditable) {
164
- grid.openDatasetItem(e.data!.getNamedReference())
165
- }
166
- }}
167
- onCellMouseOver={(e) => {
168
- if (e.colDef.colId === '__checkbox') {
169
- gridApiRef.current?.setSuppressRowClickSelection(true);
170
- }
171
- }}
172
- onCellMouseOut={(e) => {
173
- gridApiRef.current?.setSuppressRowClickSelection(false);
174
- }}
175
- getRowId={(params) => params.data.getRecordId()}
176
- onGridReady={(e) => {
177
- gridApiRef.current = e.api as any;
178
- gridColumnApiRef.current = e.columnApi;
179
- if (grid.loading) {
180
- gridApiRef.current?.showLoadingOverlay();
181
- }
182
- setDefaultStateValues({
183
- ...e.api.getState(),
184
- __updatedRecords: []
185
- });
186
- sizeColumnsIfSpaceAvailable();
187
- onGridReady();
188
- }}
189
- initialState={!grid.isNested ? stateValuesRef.current : undefined}
190
- onStateUpdated={(e) => {
191
- if (grid.isNested) {
192
- return;
193
- }
194
- stateValuesRef.current = e.state
195
- }}
196
- rowHeight={42}
197
- columnDefs={agColumns as any}
198
- rowData={records}
199
- >
200
- </AgGridReact>
201
- {grid.props.parameters.EnablePagination?.raw !== false &&
202
- <Paging />
203
- }
204
- </div>
205
- );
206
- }
@@ -1,16 +0,0 @@
1
- import React from 'react';
2
- import {Icon} from '@fluentui/react';
3
- import { useGridInstance } from '../../../../hooks/useGridInstance';
4
- import { Text } from '@fluentui/react/lib/Text';
5
- import { emptyRecordStyles } from './styles';
6
-
7
- export const EmptyRecords = () => {
8
- const labels = useGridInstance().labels;
9
-
10
- return (
11
- <div className={`${emptyRecordStyles.root} TALXIS__grid__empty-records`}>
12
- <Icon className={emptyRecordStyles.icon} iconName='SearchAndApps' />
13
- <Text>{labels.norecordsfound()}</Text>
14
- </div>
15
- )
16
- }
@@ -1,20 +0,0 @@
1
- import { mergeStyleSets } from "@fluentui/react";
2
-
3
- export const emptyRecordStyles = mergeStyleSets({
4
- root: {
5
- display: 'flex',
6
- flexDirection: 'column',
7
- gap: 10,
8
- alignItems: 'center',
9
- position: 'relative',
10
- top: 18
11
- },
12
- icon: {
13
- fontSize: 46
14
- },
15
- image: {
16
- 'img': {
17
- width: '100px'
18
- }
19
- }
20
- })
@@ -1,7 +0,0 @@
1
- import { SpinnerSize } from '@fluentui/react';
2
- import { Spinner } from '@fluentui/react/lib/components/Spinner/Spinner';
3
- import React from 'react';
4
-
5
- export const LoadingOverlay = () => {
6
- return <Spinner size={SpinnerSize.large} />
7
- }