@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,81 +0,0 @@
1
- import isNumeric from "validator/lib/isNumeric";
2
- import isEmail from "validator/lib/isEmail";
3
- import isURL from "validator/lib/isURL";
4
- import dayjs from "dayjs";
5
- import { DataType } from "../../core/enums/DataType";
6
- import { IGridColumn } from "../../core/interfaces/IGridColumn";
7
- import { GridDependency } from "../../core/model/GridDependency";
8
- import { Grid } from "../../core/model/Grid";
9
-
10
- export class ColumnValidation extends GridDependency {
11
- private _column: IGridColumn;
12
- private _forceNullCheck: boolean;
13
-
14
- constructor(grid: Grid, column: IGridColumn, forceNullCheck?: boolean) {
15
- super(grid);
16
- this._column = column;
17
- this._forceNullCheck = forceNullCheck ?? false;
18
- }
19
- public validate(value: any): [boolean, string] {
20
- const isNull = this._isNull(value);
21
- if((this._column.isRequired || this._forceNullCheck)) {
22
- if(isNull) {
23
- return [false, this._labels["validation-input-value"]()]
24
- }
25
- }
26
- //can be null
27
- else if(isNull) {
28
- return [true, ""]
29
- }
30
- switch (this._column.dataType) {
31
- case DataType.WHOLE_NONE:
32
- case DataType.DECIMAL:
33
- {
34
- value = `${value}`;
35
- if (!isNumeric(value)) {
36
- return [false, 'Invalid input!'];
37
- }
38
- break;
39
- }
40
- case DataType.SINGLE_LINE_EMAIL: {
41
- value = `${value}`;
42
- if (!isEmail(value)) {
43
- return [false, this._labels["validation-email"]()]
44
- }
45
- break;
46
- }
47
- case DataType.SINGLE_LINE_URL: {
48
- value = `${value}`;
49
- if (!isURL(value)) {
50
- return [false, this._labels["validation-url"]()]
51
- }
52
- break;
53
- }
54
- case DataType.DATE_AND_TIME_DATE_AND_TIME:
55
- case DataType.DATE_AND_TIME_DATE_ONLY: {
56
- const date = dayjs(value);
57
- if(!date.isValid()) {
58
- return [false, this._labels["validation-date"]()]
59
- }
60
- break;
61
- }
62
- default: {
63
- if(!value) {
64
- return [false, this._labels["validation-input-value"]()]
65
- }
66
- }
67
- }
68
- return [true, ""];
69
- }
70
- private _isNull(value: any) {
71
- if(!value) {
72
- return true;
73
- }
74
- if(value?.length === 0) {
75
- return true;
76
- }
77
- }
78
- private get _labels() {
79
- return this._grid.labels;
80
- }
81
- }
@@ -1,199 +0,0 @@
1
-
2
- import { ILookup } from "./interfaces";
3
- import { useLookup } from "./hooks/useLookup";
4
- import React, { useEffect, useRef } from 'react';
5
- import { useTheme } from "@fluentui/react";
6
- import { IItemProps, TagPicker } from "@talxis/react-components/dist/components/TagPicker";
7
- import { TargetSelector } from "./components/TargetSelector";
8
- import { useMouseOver } from "../../hooks/useMouseOver";
9
- import { getLookupStyles } from "./styles";
10
- import { IBasePicker } from "@fluentui/react/lib/components/pickers/BasePicker.types";
11
- import { ITag } from "@fluentui/react/lib/components/pickers/TagPicker/TagPicker.types";
12
- import { RecordCreator } from "./components/RecordCreator";
13
- import { useFocusIn } from "../../hooks/useFocusIn";
14
-
15
- export const Lookup = (props: ILookup) => {
16
- const context = props.context;
17
- const ref = useRef<HTMLDivElement>(null);
18
- const componentRef = useRef<IBasePicker<ITag>>(null);
19
- const itemLimit = props.parameters.MultipleEnabled?.raw === true ? Infinity : 1
20
- const theme = useTheme();
21
- const styles = getLookupStyles(theme, context.mode.allocatedHeight, itemLimit === 1);
22
- const [value, entities, labels, records, selectEntity, getSearchResults] = useLookup(props);
23
- const mouseOver = useMouseOver(ref);
24
- const isFocused = useFocusIn(ref);
25
- const firstRenderRef = useRef(true);
26
- const shouldFocusRef = useRef(false);
27
-
28
-
29
- useEffect(() => {
30
- if (firstRenderRef.current) {
31
- firstRenderRef.current = false;
32
- return;
33
- }
34
- //@ts-ignore
35
- if (componentRef.current.state.suggestionsVisible) {
36
- //if the suggestions callout is open and the selected target changes, refresh the results
37
- forceSearch();
38
- }
39
- }, [entities])
40
-
41
- useEffect(() => {
42
- const onKeyPress = (ev: KeyboardEvent) => {
43
- if (ev.key === 'Backspace') {
44
- const picker = ref.current?.querySelector('[class*="TALXIS__tag-picker__root"]');
45
- if ((document.activeElement === picker) && value.length === 1) {
46
- records.select(undefined);
47
- setTimeout(() => {
48
- componentRef.current?.focusInput()
49
- }, 200)
50
- }
51
- }
52
- }
53
- document.addEventListener('keydown', onKeyPress)
54
-
55
- return () => {
56
- document.removeEventListener('keydown', onKeyPress);
57
- }
58
- }, [value]);
59
-
60
- useEffect(() => {
61
- if(props.parameters.AutoFocus?.raw === true) {
62
- focus();
63
- }
64
- }, []);
65
-
66
- const focus = () => {
67
- if(componentRef.current?.items?.length === itemLimit) {
68
- //@ts-ignore
69
- ref.current?.querySelector('[class*="TALXIS__tag-picker__root"]').focus();
70
- return;
71
- }
72
- componentRef.current?.focusInput();
73
- }
74
-
75
- const forceSearch = async () => {
76
- //@ts-ignore - We need to use internal methods to show and fill the suggestions on entity change
77
- componentRef.current.suggestionStore.updateSuggestions([]);
78
- //@ts-ignore - ^^same as above
79
- componentRef.current.setState({
80
- suggestionsVisible: true,
81
- suggestionsLoading: true,
82
- });
83
- //@ts-ignore - ^^same as above
84
- const results = await onResolveSuggestions(componentRef.current.input.current.value)
85
- //@ts-ignore - ^^same as above
86
- componentRef.current.updateSuggestionsList(results);
87
- //@ts-ignore - ^^same above
88
- componentRef.current.setState({
89
- isMostRecentlyUsedVisible: false,
90
- suggestionsVisible: true,
91
- moreSuggestionsAvailable: false,
92
- });
93
- }
94
-
95
- const isComponentActive = () => {
96
- return mouseOver || isFocused;
97
- }
98
-
99
- const onResolveSuggestions = async (filter: string, selectedItems?: IItemProps[] | undefined): Promise<IItemProps[]> => {
100
- //TODO: onResolveSuggestions gets called when the record gets selected resulting in unnecessary call
101
- const results = await getSearchResults(filter);
102
- const suggestions: IItemProps[] = [];
103
- for(const result of results) {
104
- if(selectedItems?.find(x => x.key === result.id)) {
105
- continue;
106
- }
107
- const metadata = await entities.find(x => x.entityName === result.entityType)?.metadata;
108
- suggestions.push({
109
- key: result.id,
110
- text: result.name || labels.noName(),
111
- secondaryText: metadata?.DisplayName,
112
- 'data-entity': result.entityType
113
- })
114
- }
115
- return suggestions;
116
- }
117
- return (
118
- <div className={styles.root} ref={ref}>
119
- <TagPicker
120
- componentRef={componentRef}
121
- resolveDelay={200}
122
- stackItems={itemLimit === 1}
123
- pickerCalloutProps={{
124
- className: styles.suggestions,
125
- }}
126
- pickerSuggestionsProps={{
127
- loadingText: labels.searching(),
128
- noResultsFoundText: labels.noRecordsFound(),
129
- //@ts-ignore
130
- suggestionsHeaderText: <>
131
- {props.parameters.IsInlineNewEnabled?.raw !== false &&
132
- <RecordCreator labels={labels} entities={entities} onCreateRecord={records.create} />
133
- }
134
- {props.parameters.value.attributes.Targets.length > 1 &&
135
- <TargetSelector labels={labels} entities={entities} onEntitySelected={(entityName) => {
136
- selectEntity(entityName);
137
-
138
- }} />
139
- }
140
- </>
141
- }}
142
- transparent={!isComponentActive() && itemLimit === 1}
143
- onChange={(items) => {
144
- records.select(items?.map(item => {
145
- return {
146
- entityType: item['data-entity'],
147
- id: item.key,
148
- name: item.text
149
- }
150
- }))
151
- }}
152
- searchBtnProps={{
153
- iconProps: {
154
- iconName: 'Search'
155
- }
156
- }}
157
- selectedItems={value.map(lookup => {
158
- return {
159
- key: lookup.id,
160
- text: lookup.name || labels.noName(),
161
- 'data-entity': lookup.entityType,
162
- 'data-navigation-enabled': props.parameters.EnableNavigation?.raw !== false,
163
- onClick: () => {
164
- if (props.parameters.EnableNavigation?.raw === false) {
165
- return;
166
- }
167
- context.navigation.openForm({
168
- entityName: lookup.entityType,
169
- entityId: lookup.id
170
- })
171
- },
172
-
173
- deleteButtonProps: isComponentActive() || itemLimit > 1 ? {
174
- key: 'delete',
175
- iconProps: {
176
- iconName: 'ChromeClose',
177
- styles: {
178
- root: {
179
- fontSize: 12,
180
- width: 16,
181
- color: `${theme.palette.black} !important`
182
- }
183
- }
184
- },
185
- onClick: () => {
186
- shouldFocusRef.current = false;
187
- records.deselect(lookup);
188
- setTimeout(() => {
189
- focus()
190
- }, 200)
191
- }
192
- } : undefined
193
- }
194
- })}
195
- itemLimit={itemLimit}
196
- onResolveSuggestions={onResolveSuggestions} />
197
- </div>
198
- )
199
- };
@@ -1,53 +0,0 @@
1
-
2
- //@ts-nocheck - typescript
3
- import { ContextualMenuItemType, IContextualMenuItem, useTheme } from "@fluentui/react";
4
- import { CommandBarButton } from "@fluentui/react/lib/components/Button/CommandBarButton/CommandBarButton";
5
- import { IEntity, ILookupTranslations } from "../interfaces";
6
- import { getLookupStyles } from "../styles";
7
- import { StringProps } from '../../../types';
8
- import { useLoadedEntities } from "../hooks/useLoadedEntities";
9
- import React from 'react';
10
-
11
- interface IRecordCreator {
12
- labels: Required<StringProps<ILookupTranslations>>,
13
- entities: IEntity[];
14
- onCreateRecord: (entityName: string) => void;
15
- }
16
-
17
- export const RecordCreator = (props: IRecordCreator) => {
18
- const {labels, entities, onCreateRecord} = {...props};
19
- const [loadedEntities] = useLoadedEntities(entities);
20
- const theme = useTheme();
21
- const styles = getLookupStyles(theme, 0)
22
- const selectedEntity = entities.find(x => x.selected);
23
-
24
- return (
25
- <CommandBarButton
26
- className={styles.createRecordBtn}
27
- iconProps={{
28
- iconName: 'Add'
29
- }}
30
- onClick={selectedEntity ? () => onCreateRecord(selectedEntity.entityName) : undefined}
31
- menuProps={!selectedEntity ? {
32
- calloutProps: {
33
- coverTarget: false
34
- },
35
- isBeakVisible: true,
36
- items: loadedEntities ? (() => {
37
- const items: IContextualMenuItem[] = [{
38
- key: 'header',
39
- itemType: ContextualMenuItemType.Header,
40
- text: 'Vyberte tabulku'
41
- }]
42
- return [...items, ...loadedEntities.map(entity => {
43
- return {
44
- key: entity.entityName,
45
- text: entity.metadata.DisplayName,
46
- onClick: () => onCreateRecord(entity.entityName)
47
- }
48
- })];
49
- })() : []
50
- }: undefined}
51
- text={labels.newRecord()} />
52
- )
53
- }
@@ -1,43 +0,0 @@
1
- import React from 'react';
2
- import { IEntity, ILookupTranslations } from '../interfaces';
3
- import { Text } from '@fluentui/react/lib/Text';
4
- import { Link, useTheme } from '@fluentui/react';
5
- import { getLookupStyles, getTargetSelectorStyles } from '../styles';
6
- import { StringProps } from '../../../types';
7
- import { useLoadedEntities } from '../hooks/useLoadedEntities';
8
-
9
- interface ITargetSelector {
10
- labels: Required<StringProps<ILookupTranslations>>,
11
- entities: IEntity[];
12
- onEntitySelected: (entityName: string | null) => void;
13
- }
14
-
15
-
16
- export const TargetSelector = (props: ITargetSelector) => {
17
- const { labels, entities, onEntitySelected } = { ...props };
18
- const [loadedEntities] = useLoadedEntities(entities);
19
- const theme = useTheme();
20
- const styles = getTargetSelectorStyles(theme);
21
-
22
- return (
23
- <div className={styles.targetSelector}>
24
- <Text variant='small'>{labels.resultsFrom()} </Text>
25
- <div className={styles.targetSelectorLinks}>
26
- <Link
27
- onClick={() => onEntitySelected(null)}
28
- className={styles.targetSelectorLink}
29
- data-selected={!entities.find(x => x.selected)}>All</Link>
30
- {loadedEntities &&
31
- <>
32
- {loadedEntities.map((entity) => {
33
- return <Link
34
- className={styles.targetSelectorLink}
35
- data-selected={entity.selected}
36
- onClick={() => onEntitySelected(entity.entityName)}>{entity.metadata.DisplayName}</Link>
37
- })}
38
- </>
39
- }
40
- </div>
41
- </div>
42
- )
43
- }
@@ -1,31 +0,0 @@
1
- import { useRef } from "react"
2
- import { IEntity } from "../interfaces";
3
- import { Sdk } from "../lib";
4
-
5
- export const useFetchXml = (context: ComponentFramework.Context<any>): [
6
- (viewId: string) => Promise<string>,
7
- (entity: IEntity, fetchXml: string, query: string) => Promise<string>
8
- ] => {
9
- const cachedFetchXml = useRef<{
10
- [viewId: string]: Promise<ComponentFramework.WebApi.Entity>
11
- }>({});
12
-
13
- const get = async (viewId: string): Promise<string> => {
14
- if (!cachedFetchXml.current[viewId]) {
15
- cachedFetchXml.current[viewId] = context.webAPI.retrieveRecord('savedquery', viewId, '?$select=fetchxml');
16
- }
17
- return (await cachedFetchXml.current[viewId]).fetchxml;
18
- }
19
- const applyLookupQuery = async (entity: IEntity, fetchXml: string, query: string): Promise<string> => {
20
- if (!query) {
21
- return fetchXml
22
- }
23
- const metadata = await entity.metadata;
24
- const xmlObject = Sdk.FetchXml.fetch.fromXml(fetchXml);
25
- xmlObject.entity.addFilter(new Sdk.FetchXml.filter(Sdk.FetchXml.FilterType.Or, [
26
- new Sdk.FetchXml.condition(metadata.PrimaryNameAttribute, Sdk.FetchXml.Operator.Like, [new Sdk.FetchXml.value(`%${query}%`)])
27
- ]))
28
- return xmlObject.toXml();
29
- }
30
- return [get, applyLookupQuery]
31
- }
@@ -1,23 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- import { IEntity, IMetadata } from "../interfaces";
3
-
4
- interface ILoadedEntity extends Omit<IEntity, 'metadata'> {
5
- metadata: IMetadata
6
- }
7
-
8
- export const useLoadedEntities = (entities: IEntity[]): [ILoadedEntity[] | null] => {
9
- const [loadedEntities, setLoadedEntities] = useState<ILoadedEntity[] | null>(null);
10
- useEffect(() => {
11
- (async () => {
12
- setLoadedEntities(await Promise.all(entities.map(async entity => {
13
- return {
14
- entityName: entity.entityName,
15
- selected: entity.selected,
16
- metadata: await entity.metadata
17
- }
18
- })))
19
- })();
20
- }, [entities]);
21
-
22
- return [loadedEntities]
23
- }
@@ -1,126 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- import { useComponent } from "../../../hooks";
3
- import { StringProps } from "../../../types";
4
- import { IEntity, ILookup, ILookupTranslations } from "../interfaces";
5
- import { lookupTranslations } from "../translations";
6
- import { useFetchXml } from "./useFetchXml";
7
-
8
- export const useLookup = (props: ILookup): [
9
- ComponentFramework.LookupValue[],
10
- IEntity[],
11
- Required<StringProps<ILookupTranslations>>,
12
- {
13
- create: (entityName: string) => void,
14
- select: (record: ComponentFramework.LookupValue[] | undefined) => void,
15
- deselect: (record: ComponentFramework.LookupValue) => void,
16
- },
17
- (entityName: string | null) => void,
18
- (query: string) => Promise<ComponentFramework.LookupValue[]>
19
- ] => {
20
-
21
- const targets = props.parameters.value.attributes.Targets;
22
- const boundValue = props.parameters.value.raw;
23
- const context = props.context;
24
- const [labels, notifyOutputChanged] = useComponent('Lookup', props, lookupTranslations);
25
- const [getFetchXml, applyLookupQuery] = useFetchXml(context);
26
-
27
- const [entities, setEntities] = useState<IEntity[]>(() => {
28
- return targets.map(target => {
29
- return {
30
- entityName: target,
31
- selected: targets.length === 1 ? true : false,
32
- metadata: props.context.utils.getEntityMetadata(target, []) as any,
33
- }
34
- })
35
- });
36
-
37
- const selectedEntity = entities.find(x => x.selected);
38
-
39
- const selectEntity = (entityName: string | null) => {
40
- setEntities([...entities as IEntity[]].map(entity => {
41
- return {
42
- entityName: entity.entityName,
43
- metadata: entity.metadata,
44
- selected: entity.entityName === entityName
45
- }
46
- }))
47
- }
48
-
49
- const selectRecords = (records: ComponentFramework.LookupValue[] | undefined) => {
50
- notifyOutputChanged({
51
- value: records
52
- })
53
- }
54
- const getSearchFetchXml = async (entityName: string, query: string): Promise<string> => {
55
- const response = (await props.parameters.value.getAllViews(entityName)).find(x => x.isDefault);
56
- if (!response?.viewId) {
57
- throw new Error(`Entity ${entityName} does not have a default view id!`);
58
- }
59
- let fetchXml = response?.fetchXml
60
- if(!fetchXml) {
61
- fetchXml = await getFetchXml(response.viewId)
62
- }
63
- return applyLookupQuery(entities.find(x => x.entityName === entityName)!, fetchXml, query);
64
-
65
- }
66
- const getSearchResults = async (query: string): Promise<ComponentFramework.LookupValue[]> => {
67
- const fetchXmlMap = new Map<string, Promise<string>>();
68
- if(selectedEntity) {
69
- fetchXmlMap.set(selectedEntity.entityName, getSearchFetchXml(selectedEntity.entityName, query))
70
- }
71
- else {
72
- for (const entity of targets) {
73
- fetchXmlMap.set(entity, getSearchFetchXml(entity, query))
74
- }
75
- }
76
- await Promise.all(fetchXmlMap.values());
77
- const responsePromiseMap = new Map<string, Promise<ComponentFramework.WebApi.RetrieveMultipleResponse>>()
78
- for (const [entityName, fetchXml] of fetchXmlMap) {
79
- responsePromiseMap.set(entityName, context.webAPI.retrieveMultipleRecords(entityName, `?fetchXml=${encodeURIComponent((await fetchXml))}`))
80
- }
81
- await Promise.all(responsePromiseMap.values());
82
- const result: ComponentFramework.LookupValue[] = [];
83
- for (const [entityName, response] of responsePromiseMap) {
84
- for (const entity of (await response).entities) {
85
- const entityMetadata = await entities.find(x => x.entityName === entityName)!.metadata;
86
- result.push({
87
- entityType: entityName,
88
- id: entity[entityMetadata.PrimaryIdAttribute],
89
- name: entity[entityMetadata.PrimaryNameAttribute]
90
- });
91
- }
92
- }
93
- return result;
94
- }
95
-
96
- const createRecord = async (entityName: string) => {
97
- const result = await context.navigation.openForm({
98
- entityName: entityName,
99
- useQuickCreateForm: true
100
- });
101
- if (!result.savedEntityReference) {
102
- return;
103
- }
104
- notifyOutputChanged({
105
- value: result.savedEntityReference
106
- })
107
- }
108
-
109
- const deselectRecord = (record: ComponentFramework.LookupValue) => {
110
- const map = new Map<string, ComponentFramework.LookupValue>(boundValue.map(value => [value.id, value]));
111
- map.delete(record.id);
112
- notifyOutputChanged({
113
- value: [...map.values()]
114
- })
115
- }
116
-
117
- return [
118
- boundValue, entities, labels, {
119
- create: createRecord,
120
- deselect: deselectRecord,
121
- select: selectRecords
122
- },
123
- selectEntity,
124
- getSearchResults
125
- ];
126
- };
@@ -1,2 +0,0 @@
1
- export * from './Lookup';
2
- export * from './interfaces';
@@ -1,45 +0,0 @@
1
- import { ILookupProperty, ITwoOptionsProperty } from "../../interfaces";
2
- import { IComponent, IOutputs, ITranslations } from "../../interfaces/context";
3
- import { IBaseParameters } from "../../interfaces/parameters";
4
-
5
- export interface ILookup extends IComponent<ILookupParameters, ILookupOutputs, ILookupTranslations> {
6
- /**
7
- * If provided, the Lookup will use the returned values of this function to display search results.
8
- * @param {any} entityNames An array of entity names that he Lookup is currently targeting.
9
- * @param {any} query: User text input
10
- * @returns {any}
11
- */
12
- onSearch?: (entityNames: string[], query: string) => Promise<ComponentFramework.LookupValue[]>
13
- }
14
-
15
- export interface ILookupParameters extends IBaseParameters {
16
- IsInlineNewEnabled?: ITwoOptionsProperty;
17
- MultipleEnabled?: ITwoOptionsProperty;
18
- EnableNavigation?: ITwoOptionsProperty;
19
- value: ILookupProperty;
20
- }
21
-
22
- export interface ILookupOutputs extends IOutputs {
23
- value?: ComponentFramework.LookupValue[]
24
- }
25
-
26
- export interface ILookupTranslations extends ITranslations {
27
- search: {[LCID: number]: string};
28
- newRecord: {[LCID: number]: string};
29
- searching: {[LCID: number]: string};
30
- noRecordsFound: {[LCID: number]: string};
31
- resultsFrom: {[LCID: number]: string};
32
- noName: {[LCID: number]: string};
33
- }
34
-
35
- export interface IMetadata extends ComponentFramework.PropertyHelper.EntityMetadata {
36
- DisplayName: string;
37
- PrimaryNameAttribute: string;
38
- PrimaryIdAttribute: string;
39
- }
40
-
41
- export interface IEntity {
42
- entityName: string;
43
- selected: boolean;
44
- metadata: Promise<IMetadata>
45
- }