@gisce/react-ooui 1.2.0-rc.7 → 1.2.0-rc.71

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 (133) hide show
  1. package/dist/actionbar/FormActionBar.d.ts.map +1 -1
  2. package/dist/actionbar/TreeActionBar.d.ts.map +1 -1
  3. package/dist/common/DatePicker.d.ts +12 -0
  4. package/dist/common/DatePicker.d.ts.map +1 -1
  5. package/dist/context/ActionViewContext.d.ts +5 -1
  6. package/dist/context/ActionViewContext.d.ts.map +1 -1
  7. package/dist/context/ContentRootContext.d.ts.map +1 -1
  8. package/dist/context/FormContext.d.ts +4 -2
  9. package/dist/context/FormContext.d.ts.map +1 -1
  10. package/dist/helpers/formHelper.d.ts +5 -3
  11. package/dist/helpers/formHelper.d.ts.map +1 -1
  12. package/dist/helpers/iconMapper.d.ts +5 -1
  13. package/dist/helpers/iconMapper.d.ts.map +1 -1
  14. package/dist/helpers/one2manyHelper.d.ts +12 -4
  15. package/dist/helpers/one2manyHelper.d.ts.map +1 -1
  16. package/dist/helpers/searchHelper.d.ts +1 -1
  17. package/dist/helpers/searchHelper.d.ts.map +1 -1
  18. package/dist/helpers/treeHelper.d.ts +1 -1
  19. package/dist/helpers/treeHelper.d.ts.map +1 -1
  20. package/dist/hooks/useExport.d.ts +44 -0
  21. package/dist/hooks/useExport.d.ts.map +1 -0
  22. package/dist/index.d.ts +2 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/locales/ca_ES.d.ts +2 -0
  25. package/dist/locales/ca_ES.d.ts.map +1 -1
  26. package/dist/locales/en_US.d.ts +2 -0
  27. package/dist/locales/en_US.d.ts.map +1 -1
  28. package/dist/locales/es_ES.d.ts +2 -0
  29. package/dist/locales/es_ES.d.ts.map +1 -1
  30. package/dist/react-ooui.es.js +25403 -27411
  31. package/dist/react-ooui.es.js.map +1 -1
  32. package/dist/react-ooui.umd.js +46 -184
  33. package/dist/react-ooui.umd.js.map +1 -1
  34. package/dist/types/index.d.ts +1 -0
  35. package/dist/types/index.d.ts.map +1 -1
  36. package/dist/views/RootView.d.ts.map +1 -1
  37. package/dist/views/actionViews/GraphActionView.d.ts.map +1 -1
  38. package/dist/views/actionViews/TreeActionView.d.ts.map +1 -1
  39. package/dist/widgets/WidgetFactory.d.ts.map +1 -1
  40. package/dist/widgets/base/Integer.d.ts.map +1 -1
  41. package/dist/widgets/base/Label.d.ts.map +1 -1
  42. package/dist/widgets/base/Reference.d.ts.map +1 -1
  43. package/dist/widgets/base/ReferenceTree.d.ts +8 -0
  44. package/dist/widgets/base/ReferenceTree.d.ts.map +1 -0
  45. package/dist/widgets/base/Separator.d.ts.map +1 -1
  46. package/dist/widgets/base/many2one/Many2one.d.ts.map +1 -1
  47. package/dist/widgets/base/many2one/Many2oneTree.d.ts +6 -0
  48. package/dist/widgets/base/many2one/Many2oneTree.d.ts.map +1 -0
  49. package/dist/widgets/base/one2many/One2manyInput.d.ts.map +1 -1
  50. package/dist/widgets/containers/Group.d.ts.map +1 -1
  51. package/dist/widgets/custom/MultiCheckbox.d.ts.map +1 -1
  52. package/dist/widgets/custom/Tag.d.ts +5 -0
  53. package/dist/widgets/custom/Tag.d.ts.map +1 -0
  54. package/dist/widgets/custom/Tags.d.ts.map +1 -1
  55. package/dist/widgets/custom/Timeline.d.ts.map +1 -1
  56. package/dist/widgets/modals/ExportModal.d.ts +2 -1
  57. package/dist/widgets/modals/ExportModal.d.ts.map +1 -1
  58. package/dist/widgets/views/Dashboard/Dashboard.d.ts.map +1 -1
  59. package/dist/widgets/views/Dashboard/DashboardTree.d.ts.map +1 -1
  60. package/dist/widgets/views/Form.d.ts.map +1 -1
  61. package/dist/widgets/views/Graph/GraphChart.d.ts.map +1 -1
  62. package/dist/widgets/views/Graph/GraphDefaults.d.ts +36 -0
  63. package/dist/widgets/views/Graph/GraphDefaults.d.ts.map +1 -1
  64. package/dist/widgets/views/SearchTree.d.ts.map +1 -1
  65. package/dist/widgets/views/Tree.d.ts +2 -0
  66. package/dist/widgets/views/Tree.d.ts.map +1 -1
  67. package/dist/widgets/views/searchFilter/SearchFilter.d.ts +1 -0
  68. package/dist/widgets/views/searchFilter/SearchFilter.d.ts.map +1 -1
  69. package/package.json +8 -7
  70. package/src/__tests__/iconMapper.test.ts +20 -5
  71. package/src/actionbar/ChangeViewButton.tsx +2 -2
  72. package/src/actionbar/FormActionBar.tsx +82 -11
  73. package/src/actionbar/TreeActionBar.tsx +23 -28
  74. package/src/common/DatePicker.tsx +4 -3
  75. package/src/context/ActionViewContext.tsx +7 -4
  76. package/src/context/ContentRootContext.tsx +15 -7
  77. package/src/context/FormContext.tsx +1 -4
  78. package/src/helpers/formHelper.ts +26 -5
  79. package/src/helpers/iconMapper.ts +134 -107
  80. package/src/helpers/one2manyHelper.ts +94 -39
  81. package/src/helpers/searchHelper.ts +8 -7
  82. package/src/helpers/treeHelper.ts +17 -5
  83. package/src/hooks/useExport.ts +439 -0
  84. package/src/index.ts +2 -0
  85. package/src/locales/ca_ES.tsx +2 -0
  86. package/src/locales/en_US.tsx +2 -0
  87. package/src/locales/es_ES.tsx +2 -0
  88. package/src/stories/Label.stories.tsx +7 -8
  89. package/src/stories/Separator.stories.tsx +33 -0
  90. package/src/stories/containers/Group.stories.tsx +24 -0
  91. package/src/stories/containers/Notebook.stories.tsx +27 -0
  92. package/src/stories/custom/Tag.stories.tsx +57 -0
  93. package/src/stories/mocks/models/crm_case.ts +7 -10
  94. package/src/stories/views/Tree.stories.jsx +5 -5
  95. package/src/types/index.ts +1 -0
  96. package/src/ui/FavouriteButton.tsx +4 -4
  97. package/src/views/RootView.tsx +7 -1
  98. package/src/views/actionViews/GraphActionView.tsx +1 -0
  99. package/src/views/actionViews/TreeActionView.tsx +10 -1
  100. package/src/widgets/WidgetFactory.tsx +3 -0
  101. package/src/widgets/base/Integer.tsx +1 -0
  102. package/src/widgets/base/Label.tsx +5 -9
  103. package/src/widgets/base/Reference.tsx +13 -3
  104. package/src/widgets/base/ReferenceTree.tsx +62 -0
  105. package/src/widgets/base/Separator.tsx +11 -3
  106. package/src/widgets/base/many2one/Many2one.tsx +10 -19
  107. package/src/widgets/base/many2one/Many2oneTree.tsx +18 -0
  108. package/src/widgets/base/one2many/One2manyInput.tsx +79 -23
  109. package/src/widgets/containers/Group.tsx +7 -4
  110. package/src/widgets/custom/ButtonGroup.tsx +1 -1
  111. package/src/widgets/custom/MultiCheckbox.tsx +1 -0
  112. package/src/widgets/custom/Tag.tsx +24 -0
  113. package/src/widgets/custom/Tags.tsx +27 -28
  114. package/src/widgets/custom/Timeline.tsx +9 -3
  115. package/src/widgets/modals/ExportModal.tsx +33 -134
  116. package/src/widgets/views/Dashboard/Dashboard.tsx +15 -4
  117. package/src/widgets/views/Dashboard/DashboardTree.tsx +1 -0
  118. package/src/widgets/views/Form.tsx +38 -31
  119. package/src/widgets/views/Graph/GraphChart.tsx +6 -1
  120. package/src/widgets/views/Graph/GraphDefaults.ts +113 -0
  121. package/src/widgets/views/Graph/GraphIndicator.tsx +17 -3
  122. package/src/widgets/views/SearchTree.tsx +3 -0
  123. package/src/widgets/views/Tree.tsx +111 -25
  124. package/src/widgets/views/searchFilter/SearchFilter.tsx +12 -6
  125. package/dist/helpers/icons/antd_icons.d.ts +0 -4
  126. package/dist/helpers/icons/antd_icons.d.ts.map +0 -1
  127. package/dist/helpers/icons/tabler_icons.d.ts +0 -4
  128. package/dist/helpers/icons/tabler_icons.d.ts.map +0 -1
  129. package/dist/ui/Fieldset.d.ts +0 -8
  130. package/dist/ui/Fieldset.d.ts.map +0 -1
  131. package/src/helpers/icons/antd_icons.ts +0 -1583
  132. package/src/helpers/icons/tabler_icons.ts +0 -5367
  133. package/src/ui/Fieldset.tsx +0 -31
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
- import { Divider } from "antd";
2
+ import { Divider, Space } from "antd";
3
3
  import { Separator as SeparatorOoui } from "@gisce/ooui";
4
+ import iconMapper from "@/helpers/iconMapper";
4
5
 
5
6
  type Props = {
6
7
  ooui: SeparatorOoui;
@@ -8,11 +9,18 @@ type Props = {
8
9
 
9
10
  export const Separator = (props: Props) => {
10
11
  const { ooui } = props;
11
- const { label } = ooui;
12
+ const { label, icon } = ooui;
13
+ const Icon : React.ElementType | undefined = iconMapper(icon || "");
14
+
12
15
 
13
16
  return (
14
17
  <Divider orientation="left" className="text-sm">
15
- {label}
18
+ { (Icon || label) &&
19
+ <Space>
20
+ {Icon ? <Icon /> : null}
21
+ {label}
22
+ </Space>
23
+ }
16
24
  </Divider>
17
25
  );
18
26
  };
@@ -80,7 +80,6 @@ export const Many2oneInput: React.FC<Many2oneInputProps> = (
80
80
  getValues,
81
81
  getFields,
82
82
  getContext,
83
- setOriginalValue,
84
83
  elementHasLostFocus,
85
84
  } = formContext || {};
86
85
  const transformedDomain = useRef<any[]>([]);
@@ -132,13 +131,12 @@ export const Many2oneInput: React.FC<Many2oneInputProps> = (
132
131
  if (transformedDomain.current && transformedDomain.current.length > 0) {
133
132
  tryFetchFirstResultOrShowSearch(inputTextRef.current as string);
134
133
  } else {
135
- const results: any[] = await ConnectionProvider.getHandler().nameSearch(
136
- {
134
+ const results: any[] =
135
+ await ConnectionProvider.getHandler().nameSearch({
137
136
  model: relation,
138
137
  payload: inputTextRef.current as string,
139
138
  context: { ...getContext?.(), ...context },
140
- }
141
- );
139
+ });
142
140
 
143
141
  if (results.length === 1) {
144
142
  inputTextRef.current = undefined;
@@ -167,7 +165,7 @@ export const Many2oneInput: React.FC<Many2oneInputProps> = (
167
165
  });
168
166
 
169
167
  if (resultIds.length === 1) {
170
- fetchNameAndUpdate(resultIds[0], true);
168
+ fetchNameAndUpdate(resultIds[0]);
171
169
  } else {
172
170
  setSearchText(text);
173
171
  setShowSearchModal(true);
@@ -179,10 +177,7 @@ export const Many2oneInput: React.FC<Many2oneInputProps> = (
179
177
  setShowSearchModal(true);
180
178
  };
181
179
 
182
- const fetchNameAndUpdate = async (
183
- id: number,
184
- mustUpdateOriginalForm?: boolean
185
- ) => {
180
+ const fetchNameAndUpdate = async (id: number) => {
186
181
  setSearching(true);
187
182
 
188
183
  try {
@@ -194,10 +189,6 @@ export const Many2oneInput: React.FC<Many2oneInputProps> = (
194
189
  });
195
190
 
196
191
  triggerChange([id, value[0][1]]);
197
-
198
- if (mustUpdateOriginalForm) {
199
- setOriginalValue(ooui.id, [id, value[0][1]]);
200
- }
201
192
  } catch (err) {
202
193
  showErrorDialog(err);
203
194
  } finally {
@@ -207,16 +198,16 @@ export const Many2oneInput: React.FC<Many2oneInputProps> = (
207
198
 
208
199
  async function parseDomain() {
209
200
  if (widgetDomain) {
210
- transformedDomain.current = await ConnectionProvider.getHandler().evalDomain(
211
- {
201
+ transformedDomain.current =
202
+ await ConnectionProvider.getHandler().evalDomain({
212
203
  domain: widgetDomain,
213
204
  values: transformPlainMany2Ones({
214
205
  fields: getFields(),
215
206
  values: getValues(),
216
207
  }),
208
+ fields: getFields(),
217
209
  context: getContext(),
218
- }
219
- );
210
+ });
220
211
  }
221
212
 
222
213
  if (domain && domain.length > 0) {
@@ -232,7 +223,7 @@ export const Many2oneInput: React.FC<Many2oneInputProps> = (
232
223
  }
233
224
 
234
225
  async function onKeyDown(event: any) {
235
- if (event.code === "Enter") {
226
+ if (event.keyCode === 13) {
236
227
  event.preventDefault();
237
228
  event.stopPropagation();
238
229
  await onElementLostFocus();
@@ -0,0 +1,18 @@
1
+ import { Space } from "antd";
2
+ import React from "react";
3
+ import { Many2oneSuffix } from "./Many2oneSuffix";
4
+
5
+ export type Many2oneTreeProps = { m2oField: any };
6
+
7
+ export const Many2oneTree = (props: Many2oneTreeProps): React.ReactElement => {
8
+ const { m2oField } = props;
9
+ if (!m2oField) {
10
+ return <></>;
11
+ }
12
+ return (
13
+ <Space>
14
+ <>{m2oField.value}</>
15
+ <Many2oneSuffix id={m2oField.id} model={m2oField.model} />
16
+ </Space>
17
+ );
18
+ };
@@ -1,4 +1,10 @@
1
- import React, { useState, useRef, useContext, useEffect } from "react";
1
+ import React, {
2
+ useState,
3
+ useRef,
4
+ useContext,
5
+ useEffect,
6
+ useCallback,
7
+ } from "react";
2
8
  import { One2many as One2manyOoui } from "@gisce/ooui";
3
9
  import { Alert, Spin } from "antd";
4
10
  import { Form } from "@/index";
@@ -25,7 +31,7 @@ import { One2manyTopBar } from "@/widgets/base/one2many/One2manyTopBar";
25
31
  import { readObjectValues, getNextPendingId } from "@/helpers/one2manyHelper";
26
32
  import { SearchModal } from "@/widgets/modals/SearchModal";
27
33
  import { LocaleContext, LocaleContextType } from "@/context/LocaleContext";
28
- import { sortResults } from "@/helpers/treeHelper";
34
+ import { getColorMap, getTree, sortResults } from "@/helpers/treeHelper";
29
35
  import { transformPlainMany2Ones } from "@/helpers/formHelper";
30
36
 
31
37
  type One2manyValue = {
@@ -83,7 +89,6 @@ const One2manyInput: React.FC<One2manyInputProps> = (
83
89
  formContext || {};
84
90
  const { lang, t } = useContext(LocaleContext) as LocaleContextType;
85
91
 
86
- const formRef = useRef();
87
92
  const [formHasChanges, setFormHasChanges] = useState<boolean>(false);
88
93
  const [isLoading, setIsLoading] = useState<boolean>(false);
89
94
  const [error, setError] = useState<string>();
@@ -96,6 +101,7 @@ const One2manyInput: React.FC<One2manyInputProps> = (
96
101
  const transformedDomain = useRef<any[]>([]);
97
102
  const [sorter, setSorter] = useState<any>();
98
103
  const originalSortItemIds = useRef<number[]>();
104
+ const [colorsForResults, setColorsForResults] = useState<any>(undefined);
99
105
 
100
106
  const {
101
107
  readOnly,
@@ -106,14 +112,31 @@ const One2manyInput: React.FC<One2manyInputProps> = (
106
112
  const isMany2many = ooui.type === "many2many";
107
113
  const { id: fieldName } = ooui;
108
114
  const itemsToShow = items.filter(
109
- (item) => item.values && item.operation !== "pendingRemove"
115
+ (item) =>
116
+ (item.values || item.treeValues) && item.operation !== "pendingRemove"
110
117
  );
118
+ const previousCurrentView = useRef<ViewType>();
111
119
 
112
120
  useEffect(() => {
113
- if (items.some((item) => !item.values)) {
121
+ if (previousCurrentView.current !== currentView) {
122
+ previousCurrentView.current = currentView;
123
+ fetchDataIfNeeded();
124
+ return;
125
+ }
126
+
127
+ fetchDataIfNeeded();
128
+ }, [items, currentView]);
129
+
130
+ const fetchDataIfNeeded = useCallback(() => {
131
+ if (currentView === "form" && items.some((item) => !item.values)) {
132
+ fetchData();
133
+ } else if (
134
+ currentView === "tree" &&
135
+ items.some((item) => !item.treeValues)
136
+ ) {
114
137
  fetchData();
115
138
  }
116
- }, [items]);
139
+ }, [items, currentView]);
117
140
 
118
141
  useEffect(() => {
119
142
  parseDomain();
@@ -133,25 +156,36 @@ const One2manyInput: React.FC<One2manyInputProps> = (
133
156
  }
134
157
  };
135
158
 
136
- const fetchOriginalItemsFromApi = async () => {
159
+ const fetchOriginalItemsFromApi = async (mode?: ViewType) => {
137
160
  setIsLoading(true);
138
161
  setFormHasChanges(false);
139
162
  setError(undefined);
140
163
 
141
164
  try {
142
- const itemsWithValues = await readObjectValues({
143
- treeFields: views.get("tree").fields,
144
- formFields: views.get("form")?.fields || {},
165
+ const [itemsWithValues, evaluatedColorsForTree] = await readObjectValues({
166
+ treeView: {
167
+ arch: views.get("tree")?.arch,
168
+ fields: views.get("tree")?.fields,
169
+ },
170
+ formView: {
171
+ fields: views.get("form")?.fields || {},
172
+ },
145
173
  model: relation,
146
174
  items,
147
175
  context: { ...getContext?.(), ...context },
176
+ currentView: mode || currentView,
148
177
  });
149
178
 
150
179
  if (!originalSortItemIds.current) {
151
180
  originalSortItemIds.current = itemsWithValues.map((item) => item.id!);
152
181
  }
153
182
 
183
+ if ((currentView || mode) === "tree" && evaluatedColorsForTree) {
184
+ setColorsForResults(evaluatedColorsForTree);
185
+ }
186
+
154
187
  triggerChange(itemsWithValues);
188
+ return itemsWithValues;
155
189
  } catch (err) {
156
190
  setError(err as any);
157
191
  } finally {
@@ -168,6 +202,7 @@ const One2manyInput: React.FC<One2manyInputProps> = (
168
202
  fields: getFields(),
169
203
  values: getValues(),
170
204
  }),
205
+ fields: getFields(),
171
206
  context: getContext(),
172
207
  }),
173
208
  widgetFieldName: fieldName,
@@ -437,10 +472,19 @@ const One2manyInput: React.FC<One2manyInputProps> = (
437
472
  }
438
473
  };
439
474
 
440
- const onTreeRowClicked = (record: any) => {
475
+ const onTreeRowClicked = async (record: any) => {
441
476
  const { id: itemId } = record;
477
+
478
+ let itemsToLoadFrom: One2manyItem[] | undefined = items;
479
+
480
+ // We should fetch the form data if needed in order to get the form values
481
+ const modalItem = items.find((item) => item.id === itemId);
482
+ if (modalItem?.values === undefined) {
483
+ itemsToLoadFrom = await fetchOriginalItemsFromApi("form");
484
+ }
485
+
442
486
  // We show the detail for the clicked item in a Form modal
443
- setModalItem(items.find((item) => item.id === itemId));
487
+ setModalItem(itemsToLoadFrom!.find((item) => item.id === itemId));
444
488
  setContinuousEntryMode(false);
445
489
  setShowFormModal(true);
446
490
  };
@@ -506,12 +550,18 @@ const One2manyInput: React.FC<One2manyInputProps> = (
506
550
  return t("noCurrentEntries");
507
551
  }
508
552
 
553
+ if (
554
+ currentView !== previousCurrentView.current &&
555
+ items.some((item) => !item.values)
556
+ ) {
557
+ return <Spin />;
558
+ }
559
+
509
560
  return (
510
561
  <Form
511
562
  formView={views.get("form")}
512
563
  values={itemsToShow[itemIndex]?.values}
513
564
  parentContext={{ ...getContext?.(), ...context }}
514
- ref={formRef}
515
565
  model={relation}
516
566
  id={itemsToShow[itemIndex]?.id}
517
567
  submitMode={"values"}
@@ -542,16 +592,20 @@ const One2manyInput: React.FC<One2manyInputProps> = (
542
592
  );
543
593
  }
544
594
 
545
- const resultsToShow = sorter
546
- ? sortResults({
547
- resultsToSort: itemsToShow.map((item) => item.treeValues),
548
- sorter,
549
- fields: {
550
- ...views.get("tree").fields,
551
- ...(views.get("form")?.fields || {}),
552
- },
553
- })
554
- : itemsToShow.map((item) => item.treeValues);
595
+ let resultsToShow = [];
596
+
597
+ if (itemsToShow.some((item) => item.treeValues)) {
598
+ resultsToShow = sorter
599
+ ? sortResults({
600
+ resultsToSort: itemsToShow.map((item) => item.treeValues),
601
+ sorter,
602
+ fields: {
603
+ ...views.get("tree").fields,
604
+ ...(views.get("form")?.fields || {}),
605
+ },
606
+ })
607
+ : itemsToShow.map((item) => item.treeValues);
608
+ }
555
609
 
556
610
  if (currentView === "tree") {
557
611
  return (
@@ -573,6 +627,8 @@ const One2manyInput: React.FC<One2manyInputProps> = (
573
627
  }}
574
628
  sorter={sorter}
575
629
  onChangeSort={setSorter}
630
+ context={{ ...getContext?.(), ...context }}
631
+ colorsForResults={colorsForResults}
576
632
  />
577
633
  );
578
634
  }
@@ -1,7 +1,9 @@
1
1
  import React from "react";
2
2
  import { Group as GroupOoui } from "@gisce/ooui";
3
3
  import Container from "./Container";
4
- import Fieldset from "@/ui/Fieldset";
4
+ import { FieldSet } from "@gisce/react-formiga-components";
5
+ import { Space } from "antd";
6
+ import iconMapper from "@/helpers/iconMapper";
5
7
 
6
8
  type Props = {
7
9
  ooui: GroupOoui;
@@ -11,16 +13,17 @@ type Props = {
11
13
 
12
14
  function Group(props: Props): React.ReactElement {
13
15
  const { ooui, showLabel = true, responsiveBehaviour } = props;
16
+ const icon: React.ElementType | undefined = iconMapper(ooui.icon || "");
14
17
 
15
18
  return (
16
19
  <>
17
- {ooui.label && showLabel ? (
18
- <Fieldset label={ooui.label}>
20
+ {(ooui.label || icon) && showLabel ? (
21
+ <FieldSet label={ooui.label} icon={icon}>
19
22
  <Container
20
23
  container={ooui!.container}
21
24
  responsiveBehaviour={responsiveBehaviour}
22
25
  />
23
- </Fieldset>
26
+ </FieldSet>
24
27
  ) : (
25
28
  <Container
26
29
  container={ooui!.container}
@@ -83,7 +83,7 @@ export const ButtonGroup = (props: ButtonGroupProps) => {
83
83
  type={primary ? "primary" : undefined}
84
84
  //danger={danger ? true : undefined} This works but typescript
85
85
  // doesn't accept
86
- overlay={<Items ooui={secondaryButtons} />}
86
+ overlay={Items({ooui: secondaryButtons})}
87
87
  >
88
88
  {getButtonIcon()}
89
89
  {caption}
@@ -62,6 +62,7 @@ export const MultiCheckboxInput = (props: MultiCheckboxInputProps) => {
62
62
  fields: formContext?.getFields(),
63
63
  values: formContext.getPlainValues(),
64
64
  }),
65
+ fields: formContext?.getFields(),
65
66
  context: formContext.getContext(),
66
67
  });
67
68
  params = [...params, ...evaluatedDomain];
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ import Field from "@/common/Field";
3
+ import { WidgetProps } from "@/types";
4
+ import { Tag as AntdTag } from 'antd';
5
+ import { colorFromString } from "@/helpers/formHelper";
6
+
7
+ export const Tag = (props: WidgetProps) => {
8
+ return (
9
+ <Field {...props}>
10
+ <TagInput {...props}/>
11
+ </Field>
12
+ );
13
+ };
14
+
15
+ export const TagInput = (props: any) => {
16
+ const {ooui, value} = props;
17
+ if (!value) {
18
+ return null
19
+ }
20
+ const color = ooui.colors === "auto" ? colorFromString(value) : ooui.colors[value]
21
+ return (
22
+ <AntdTag color={color}>{ooui.selectionValues.get(value)}</AntdTag>
23
+ );
24
+ }
@@ -23,7 +23,7 @@ export const Tags = (props: TagsProps) => {
23
23
 
24
24
  return (
25
25
  <Field type={"array"} {...props}>
26
- <TagsInput ooui={ooui} />
26
+ <TagsInput ooui={ooui} />
27
27
  </Field>
28
28
  );
29
29
  };
@@ -31,16 +31,15 @@ export const Tags = (props: TagsProps) => {
31
31
  export const TagsInput = (props: TagsInputProps) => {
32
32
  const { value, ooui, onChange } = props;
33
33
  const { items = [] } = value || {};
34
- const itemsToShow = items.filter(
35
- (item) => item.operation !== "pendingRemove"
36
- ).map((item) => item.id) as number[];
34
+ const itemsToShow = items
35
+ .filter((item) => item.operation !== "pendingRemove")
36
+ .map((item) => item.id) as number[];
37
37
 
38
38
  const [options, setOptions] = useState<any[]>([]);
39
39
  const [error, setError] = useState<string>();
40
40
  const [isLoadingOptions, setIsLoadingOptions] = useState<boolean>(false);
41
41
  const { relation, context, readOnly, field } = ooui;
42
42
 
43
-
44
43
  const formContext = useContext(FormContext) as FormContextType;
45
44
  const { getContext } = formContext || {};
46
45
 
@@ -62,16 +61,16 @@ export const TagsInput = (props: TagsInputProps) => {
62
61
  params = [["id", "in", itemsToShow]];
63
62
  }
64
63
  if (ooui.domain) {
65
- const evaluatedDomain = await ConnectionProvider.getHandler().evalDomain(
66
- {
64
+ const evaluatedDomain =
65
+ await ConnectionProvider.getHandler().evalDomain({
67
66
  domain: ooui.domain,
68
67
  values: transformPlainMany2Ones({
69
68
  fields: formContext?.getFields(),
70
69
  values: formContext.getPlainValues(),
71
70
  }),
72
- context: formContext.getContext(),
73
- }
74
- );
71
+ fields: formContext?.getFields(),
72
+ context: formContext.getContext(),
73
+ });
75
74
  params = [...params, ...evaluatedDomain];
76
75
  }
77
76
 
@@ -81,18 +80,17 @@ export const TagsInput = (props: TagsInputProps) => {
81
80
  fields: [field],
82
81
  context: { ...getContext?.(), ...context },
83
82
  });
84
- const options = optionsRead.map((item:any) => {
83
+ const options = optionsRead.map((item: any) => {
85
84
  const value = item[field];
86
85
  let formattedValue = value;
87
86
  if (Array.isArray(value)) {
88
87
  formattedValue = value[1];
89
88
  }
90
- return {label: formattedValue, value: item.id}
89
+ return { label: formattedValue, value: item.id };
91
90
  });
92
91
  setOptions(options);
93
-
94
92
  } catch (err) {
95
- setError(err as any)
93
+ setError(err as any);
96
94
  } finally {
97
95
  setIsLoadingOptions(false);
98
96
  }
@@ -104,19 +102,21 @@ export const TagsInput = (props: TagsInputProps) => {
104
102
  if (item.operation == "pendingRemove") {
105
103
  return {
106
104
  ...item,
107
- operation: "pendingLink"
108
- }
105
+ operation: "pendingLink",
106
+ };
109
107
  } else {
110
- return item
108
+ return item;
111
109
  }
112
110
  } else {
113
- return {id: item.id, operation: 'pendingRemove'}
111
+ return { id: item.id, operation: "pendingRemove" };
114
112
  }
115
- })
116
- const currentIds = newItems.map(item => item.id)
117
- ids.filter(id => !currentIds.includes(id)).map((id) => {
118
- newItems.push({id, operation: 'pendingLink'});
119
113
  });
114
+ const currentIds = newItems.map((item) => item.id);
115
+ ids
116
+ .filter((id) => !currentIds.includes(id))
117
+ .map((id) => {
118
+ newItems.push({ id, operation: "pendingLink" });
119
+ });
120
120
  triggerChange(newItems);
121
121
  };
122
122
 
@@ -130,10 +130,11 @@ export const TagsInput = (props: TagsInputProps) => {
130
130
  <AntTag
131
131
  color={colorFromString(label)}
132
132
  onMouseDown={onPreventMouseDown}
133
- style={{margin: '5px'}}
133
+ style={{ margin: "5px" }}
134
134
  closable={closable}
135
- onClose={onClose}>
136
- {label}
135
+ onClose={onClose}
136
+ >
137
+ {label}
137
138
  </AntTag>
138
139
  );
139
140
  };
@@ -154,10 +155,8 @@ export const TagsInput = (props: TagsInputProps) => {
154
155
  options={options}
155
156
  onChange={onChangeSelected}
156
157
  loading={isLoadingOptions}
157
- >
158
- </Select>
158
+ ></Select>
159
159
  </div>
160
160
  </>
161
161
  );
162
-
163
162
  };
@@ -105,12 +105,18 @@ export const TimelineInput = (props: TimelineInputProps) => {
105
105
  setError(undefined);
106
106
 
107
107
  try {
108
- const itemsWithValues = await readObjectValues({
109
- treeFields: views.get("tree").fields,
110
- formFields: views.get("form").fields,
108
+ const [itemsWithValues] = await readObjectValues({
109
+ treeView: {
110
+ fields: views.get("tree").fields,
111
+ arch: views.get("tree").arch
112
+ },
113
+ formView: {
114
+ fields: views.get("form").fields,
115
+ },
111
116
  model: relation,
112
117
  items,
113
118
  context: { ...getContext?.(), ...context },
119
+ currentView: "form",
114
120
  });
115
121
 
116
122
  triggerChange(itemsWithValues);