@omniumretail/component-library 1.0.73 → 1.0.74

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 (177) hide show
  1. package/.storybook/main.js +16 -16
  2. package/.storybook/preview-head.html +20 -20
  3. package/.storybook/preview.js +27 -27
  4. package/NPMPUBLISH.md +29 -29
  5. package/README.md +54 -54
  6. package/bitbucket-pipelines.yml +94 -94
  7. package/dist/bundle.js +290 -246
  8. package/dist/main.css +5 -5
  9. package/dist/types/components/AnalyticsBar/AnalyticsBar.stories.d.ts +5 -5
  10. package/dist/types/components/AnalyticsBar/helpers/codeMutation.d.ts +4 -4
  11. package/dist/types/components/AnalyticsBar/index.d.ts +2 -2
  12. package/dist/types/components/AnalyticsBar/interfaces/analyticsBar.d.ts +12 -12
  13. package/dist/types/components/Button/Button.stories.d.ts +6 -6
  14. package/dist/types/components/Button/index.d.ts +7 -7
  15. package/dist/types/components/Category/Category.stories.d.ts +4 -4
  16. package/dist/types/components/Category/CategoryContent/index.d.ts +7 -7
  17. package/dist/types/components/Category/CategorySidebar/index.d.ts +26 -26
  18. package/dist/types/components/Category/index.d.ts +7 -7
  19. package/dist/types/components/CategoryReadOnly/CategoryReadOnly.stories.d.ts +4 -4
  20. package/dist/types/components/CategoryReadOnly/evaluationOptions.d.ts +10 -10
  21. package/dist/types/components/CategoryReadOnly/index.d.ts +9 -9
  22. package/dist/types/components/CategoryResponse/CategoryResponse.stories.d.ts +4 -4
  23. package/dist/types/components/CategoryResponse/evaluationOptions.d.ts +10 -10
  24. package/dist/types/components/CategoryResponse/index.d.ts +9 -9
  25. package/dist/types/components/DatePicker/DatePicker.stories.d.ts +5 -5
  26. package/dist/types/components/DatePicker/index.d.ts +8 -8
  27. package/dist/types/components/DatePickerTag/DatePickerTag.stories.d.ts +5 -5
  28. package/dist/types/components/DatePickerTag/index.d.ts +6 -6
  29. package/dist/types/components/Footer/Footer.stories.d.ts +5 -5
  30. package/dist/types/components/Footer/index.d.ts +4 -4
  31. package/dist/types/components/Input/Input.stories.d.ts +5 -5
  32. package/dist/types/components/Input/index.d.ts +10 -10
  33. package/dist/types/components/InputCountryCode/index.d.ts +10 -10
  34. package/dist/types/components/InputCountryCode/inputCountryCode.stories.d.ts +5 -5
  35. package/dist/types/components/Label/Label.stories.d.ts +6 -6
  36. package/dist/types/components/Label/index.d.ts +7 -7
  37. package/dist/types/components/Link/Link.stories.d.ts +7 -7
  38. package/dist/types/components/Link/index.d.ts +7 -7
  39. package/dist/types/components/Menu/Menu.stories.d.ts +5 -5
  40. package/dist/types/components/Menu/helpers/codeMutation.d.ts +4 -4
  41. package/dist/types/components/Menu/index.d.ts +2 -3
  42. package/dist/types/components/ModalConfirmation/ModalConfirmation.stories.d.ts +5 -5
  43. package/dist/types/components/ModalConfirmation/ModalStatusList.d.ts +5 -5
  44. package/dist/types/components/ModalConfirmation/index.d.ts +9 -9
  45. package/dist/types/components/ModalWithTable/ModalWithTable.stories.d.ts +5 -5
  46. package/dist/types/components/ModalWithTable/index.d.ts +13 -13
  47. package/dist/types/components/Navigation/Navigation.stories.d.ts +5 -5
  48. package/dist/types/components/Navigation/index.d.ts +10 -10
  49. package/dist/types/components/Notification/Notification.stories.d.ts +5 -5
  50. package/dist/types/components/Notification/index.d.ts +9 -9
  51. package/dist/types/components/Questions/Questions.stories.d.ts +4 -4
  52. package/dist/types/components/Questions/SingleQuestion/index.d.ts +1 -1
  53. package/dist/types/components/Questions/index.d.ts +5 -5
  54. package/dist/types/components/Radio/Radio.stories.d.ts +5 -5
  55. package/dist/types/components/Radio/index.d.ts +10 -10
  56. package/dist/types/components/Select/Select.stories.d.ts +6 -6
  57. package/dist/types/components/Select/index.d.ts +5 -5
  58. package/dist/types/components/Separator/Separator.stories.d.ts +6 -6
  59. package/dist/types/components/Separator/index.d.ts +11 -11
  60. package/dist/types/components/Sidebar/Sidebar.stories.d.ts +6 -6
  61. package/dist/types/components/Sidebar/index.d.ts +15 -15
  62. package/dist/types/components/Switch/Switch.stories.d.ts +5 -5
  63. package/dist/types/components/Switch/index.d.ts +2 -2
  64. package/dist/types/components/Table/Table.stories.d.ts +9 -9
  65. package/dist/types/components/Table/index.d.ts +37 -37
  66. package/dist/types/components/Tag/Tag.stories.d.ts +5 -5
  67. package/dist/types/components/Tag/index.d.ts +8 -8
  68. package/dist/types/components/Upload/Upload.stories.d.ts +4 -4
  69. package/dist/types/components/Upload/index.d.ts +8 -8
  70. package/dist/types/components/UserInfo/UserInfo.stories.d.ts +4 -4
  71. package/dist/types/components/UserInfo/index.d.ts +8 -8
  72. package/dist/types/components/index.d.ts +25 -25
  73. package/dist/types/constants/i18n.d.ts +1 -1
  74. package/dist/types/constants/translationHelper.d.ts +2 -2
  75. package/dist/types/index.d.ts +2 -2
  76. package/package.json +198 -198
  77. package/src/assets/scss/_global.scss +89 -89
  78. package/src/assets/scss/index.scss +2 -2
  79. package/src/components/AnalyticsBar/AnalyticsBar.stories.tsx +236 -236
  80. package/src/components/AnalyticsBar/helpers/codeMutation.tsx +19 -19
  81. package/src/components/AnalyticsBar/index.tsx +76 -76
  82. package/src/components/AnalyticsBar/interfaces/analyticsBar.tsx +13 -13
  83. package/src/components/AnalyticsBar/styles.module.scss +108 -108
  84. package/src/components/Button/Button.stories.tsx +26 -26
  85. package/src/components/Button/index.tsx +24 -24
  86. package/src/components/Button/styles.module.scss +65 -65
  87. package/src/components/Category/Category.stories.tsx +88 -88
  88. package/src/components/Category/CategoryContent/index.tsx +188 -188
  89. package/src/components/Category/CategoryContent/styles.module.scss +51 -51
  90. package/src/components/Category/CategorySidebar/index.tsx +268 -268
  91. package/src/components/Category/CategorySidebar/styles.module.scss +28 -28
  92. package/src/components/Category/index.tsx +76 -76
  93. package/src/components/Category/styles.module.scss +13 -13
  94. package/src/components/CategoryReadOnly/CategoryReadOnly.stories.tsx +270 -270
  95. package/src/components/CategoryReadOnly/evaluationOptions.tsx +81 -81
  96. package/src/components/CategoryReadOnly/index.tsx +254 -254
  97. package/src/components/CategoryReadOnly/styles.module.scss +184 -184
  98. package/src/components/CategoryResponse/CategoryResponse.stories.tsx +251 -251
  99. package/src/components/CategoryResponse/evaluationOptions.tsx +81 -81
  100. package/src/components/CategoryResponse/index.tsx +277 -277
  101. package/src/components/CategoryResponse/styles.module.scss +180 -180
  102. package/src/components/DatePicker/DatePicker.stories.tsx +16 -16
  103. package/src/components/DatePicker/index.tsx +38 -38
  104. package/src/components/DatePicker/styles.module.scss +3 -3
  105. package/src/components/DatePickerTag/DatePickerTag.stories.tsx +19 -19
  106. package/src/components/DatePickerTag/index.tsx +89 -89
  107. package/src/components/DatePickerTag/styles.module.scss +31 -31
  108. package/src/components/Footer/Footer.stories.tsx +14 -14
  109. package/src/components/Footer/index.tsx +38 -38
  110. package/src/components/Footer/styles.module.scss +38 -38
  111. package/src/components/Input/Input.stories.tsx +13 -13
  112. package/src/components/Input/index.tsx +31 -31
  113. package/src/components/Input/styles.module.scss +8 -8
  114. package/src/components/InputCountryCode/index.tsx +75 -75
  115. package/src/components/InputCountryCode/inputCountryCode.stories.tsx +55 -55
  116. package/src/components/InputCountryCode/styles.module.scss +3 -3
  117. package/src/components/Label/Label.stories.tsx +21 -21
  118. package/src/components/Label/index.tsx +19 -19
  119. package/src/components/Label/styles.module.scss +16 -16
  120. package/src/components/Link/Link.stories.tsx +30 -30
  121. package/src/components/Link/index.tsx +21 -21
  122. package/src/components/Link/styles.module.scss +24 -24
  123. package/src/components/Menu/Menu.stories.tsx +178 -178
  124. package/src/components/Menu/helpers/codeMutation.tsx +19 -19
  125. package/src/components/Menu/index.tsx +23 -23
  126. package/src/components/ModalConfirmation/ModalConfirmation.stories.tsx +40 -40
  127. package/src/components/ModalConfirmation/ModalStatusList.tsx +5 -5
  128. package/src/components/ModalConfirmation/index.tsx +70 -70
  129. package/src/components/ModalConfirmation/styles.module.scss +62 -62
  130. package/src/components/ModalWithTable/ModalWithTable.stories.tsx +96 -96
  131. package/src/components/ModalWithTable/index.tsx +232 -232
  132. package/src/components/ModalWithTable/styles.module.scss +77 -77
  133. package/src/components/Navigation/Navigation.stories.tsx +17 -17
  134. package/src/components/Navigation/index.tsx +33 -33
  135. package/src/components/Navigation/styles.module.scss +59 -58
  136. package/src/components/Notification/Notification.stories.tsx +29 -29
  137. package/src/components/Notification/index.tsx +21 -21
  138. package/src/components/Questions/Questions.stories.tsx +37 -37
  139. package/src/components/Questions/SingleQuestion/index.tsx +84 -84
  140. package/src/components/Questions/SingleQuestion/styles.module.scss +81 -81
  141. package/src/components/Questions/index.tsx +78 -78
  142. package/src/components/Radio/Radio.stories.tsx +43 -43
  143. package/src/components/Radio/index.tsx +26 -26
  144. package/src/components/Radio/styles.module.scss +23 -23
  145. package/src/components/Select/Select.stories.tsx +39 -39
  146. package/src/components/Select/index.tsx +27 -27
  147. package/src/components/Select/styles.module.scss +13 -13
  148. package/src/components/Separator/Separator.stories.tsx +22 -22
  149. package/src/components/Separator/index.tsx +27 -27
  150. package/src/components/Separator/styles.module.scss +25 -25
  151. package/src/components/Sidebar/Sidebar.stories.tsx +85 -85
  152. package/src/components/Sidebar/index.tsx +103 -103
  153. package/src/components/Sidebar/styles.module.scss +85 -85
  154. package/src/components/Switch/Switch.stories.tsx +14 -14
  155. package/src/components/Switch/index.tsx +8 -8
  156. package/src/components/Switch/styles.module.scss +7 -7
  157. package/src/components/Table/Table.stories.tsx +222 -222
  158. package/src/components/Table/index.tsx +275 -275
  159. package/src/components/Table/styles.module.scss +75 -75
  160. package/src/components/Tag/Tag.stories.tsx +22 -22
  161. package/src/components/Tag/index.tsx +189 -189
  162. package/src/components/Tag/styles.module.scss +60 -60
  163. package/src/components/Upload/Upload.stories.tsx +45 -45
  164. package/src/components/Upload/index.tsx +91 -91
  165. package/src/components/UserInfo/UserInfo.stories.tsx +37 -37
  166. package/src/components/UserInfo/index.tsx +62 -62
  167. package/src/components/UserInfo/styles.module.scss +29 -29
  168. package/src/components/index.tsx +25 -25
  169. package/src/constants/i18n.ts +25 -25
  170. package/src/constants/translationHelper.ts +7 -7
  171. package/src/index.ts +2 -2
  172. package/src/locales/en.json +86 -86
  173. package/src/locales/es.json +86 -86
  174. package/src/locales/pt.json +86 -86
  175. package/src/types/Global.d.ts +4 -4
  176. package/tsconfig.json +29 -29
  177. package/webpack.config.js +51 -51
@@ -1,81 +1,81 @@
1
- import translate from '../../constants/translationHelper';
2
-
3
- export type EvaluationOption = {
4
- value: string;
5
- label: string;
6
- };
7
-
8
- export type EvaluationOptions = {
9
- scale_0: EvaluationOption[];
10
- scale_1: EvaluationOption[];
11
- scale_2: EvaluationOption[];
12
- };
13
-
14
- export const evaluationOptions: EvaluationOptions = {
15
- scale_0: [
16
- {
17
- value: '1',
18
- label: '1',
19
- },
20
- {
21
- value: '2',
22
- label: '2',
23
- },
24
- {
25
- value: '3',
26
- label: '3',
27
- },
28
- {
29
- value: '4',
30
- label: '4',
31
- },
32
- {
33
- value: '5',
34
- label: '5',
35
- }
36
- ],
37
- scale_1: [
38
- {
39
- value: '1',
40
- label: '1',
41
- },
42
- {
43
- value: '2',
44
- label: '2',
45
- },
46
- {
47
- value: '3',
48
- label: '3',
49
- },
50
- {
51
- value: '4',
52
- label: '4',
53
- },
54
- ],
55
- scale_2: [
56
- {
57
- value: '1',
58
- label: '1',
59
- },
60
- {
61
- value: '2',
62
- label: '2',
63
- },
64
- {
65
- value: '3',
66
- label: '3',
67
- },
68
- {
69
- value: '4',
70
- label: '4',
71
- },
72
- {
73
- value: '5',
74
- label: '5',
75
- },
76
- {
77
- value: 'na',
78
- label: translate('components.categoryResponse.notApplicable')
79
- }
80
- ]
81
- }
1
+ import translate from '../../constants/translationHelper';
2
+
3
+ export type EvaluationOption = {
4
+ value: string;
5
+ label: string;
6
+ };
7
+
8
+ export type EvaluationOptions = {
9
+ scale_0: EvaluationOption[];
10
+ scale_1: EvaluationOption[];
11
+ scale_2: EvaluationOption[];
12
+ };
13
+
14
+ export const evaluationOptions: EvaluationOptions = {
15
+ scale_0: [
16
+ {
17
+ value: '1',
18
+ label: '1',
19
+ },
20
+ {
21
+ value: '2',
22
+ label: '2',
23
+ },
24
+ {
25
+ value: '3',
26
+ label: '3',
27
+ },
28
+ {
29
+ value: '4',
30
+ label: '4',
31
+ },
32
+ {
33
+ value: '5',
34
+ label: '5',
35
+ }
36
+ ],
37
+ scale_1: [
38
+ {
39
+ value: '1',
40
+ label: '1',
41
+ },
42
+ {
43
+ value: '2',
44
+ label: '2',
45
+ },
46
+ {
47
+ value: '3',
48
+ label: '3',
49
+ },
50
+ {
51
+ value: '4',
52
+ label: '4',
53
+ },
54
+ ],
55
+ scale_2: [
56
+ {
57
+ value: '1',
58
+ label: '1',
59
+ },
60
+ {
61
+ value: '2',
62
+ label: '2',
63
+ },
64
+ {
65
+ value: '3',
66
+ label: '3',
67
+ },
68
+ {
69
+ value: '4',
70
+ label: '4',
71
+ },
72
+ {
73
+ value: '5',
74
+ label: '5',
75
+ },
76
+ {
77
+ value: 'na',
78
+ label: translate('components.categoryResponse.notApplicable')
79
+ }
80
+ ]
81
+ }
@@ -1,254 +1,254 @@
1
- import styles from './styles.module.scss';
2
- import { useEffect, useImperativeHandle, useState } from 'react';
3
- import { useForm } from 'antd/es/form/Form';
4
- import classNames from 'classnames';
5
- import React from 'react';
6
- import { t } from 'i18next';
7
-
8
- interface CategoryResponse {
9
- data: any;
10
- serverReadyData: any;
11
- onNextCategoryAvailabilityChange: (hasNext: boolean) => void;
12
- onPreviousCategoryAvailabilityChange: (hasPrevious: boolean) => void;
13
- };
14
-
15
- type Category = {
16
- Title: string;
17
- Key: string;
18
- Data: any;
19
- Children?: Category[];
20
- };
21
-
22
- const updateCategoryAnswers = (CategoryAnswers: any[], categoryToUpdate: any, updatedQuestions: any) => {
23
- CategoryAnswers.forEach((category: any) => {
24
- if (category.Data.CategoryId === categoryToUpdate.CategoryId) {
25
- category.Data.Questions = category.Data.Questions.map((question: any, index: any) => {
26
- return {
27
- ...question,
28
- Answer: updatedQuestions[index].Answer
29
- };
30
- });
31
- }
32
- else if (category.Children && category.Children.length > 0) {
33
- updateCategoryAnswers(category.Children, categoryToUpdate, updatedQuestions);
34
- }
35
- });
36
- return CategoryAnswers;
37
- };
38
-
39
- const findCategoryWithQuestions = (currentKey: string, categories: Category[], direction: 'next' | 'prev'): Category | null => {
40
- let foundCurrent = false;
41
-
42
- const searchCategories = (categoryList: Category[], direction: 'next' | 'prev'): Category | null => {
43
- const iterable = direction === 'next' ? categoryList : [...categoryList].reverse();
44
-
45
- for (const category of iterable) {
46
- if (foundCurrent) {
47
- if (category.Data.Questions.length > 0) {
48
- return category;
49
- }
50
- } else if (category.Key === currentKey) {
51
- foundCurrent = true;
52
- }
53
-
54
- if (category.Children) {
55
- const result = searchCategories(category.Children, direction);
56
- if (result) {
57
- return result;
58
- }
59
- }
60
- }
61
- return null;
62
- };
63
-
64
- return searchCategories(categories, direction);
65
- };
66
-
67
- const getCategoryObject = (currentKey: string, categories: Category[], direction: 'next' | 'prev'): any => {
68
- const category = findCategoryWithQuestions(currentKey, categories, direction);
69
- return category ? category.Data : null;
70
- };
71
-
72
- const hasCategory = (currentKey: string, categories: Category[], direction: 'next' | 'prev'): boolean => {
73
- const category = findCategoryWithQuestions(currentKey, categories, direction);
74
- return !!category;
75
- };
76
-
77
- export const CategoryReadOnly = React.forwardRef((props: CategoryResponse, ref) => {
78
- const { data } = props;
79
-
80
- const [currentKey, setCurrentKey] = useState(data.CategoryAnswers[0].Key);
81
- const [localData, setLocalData] = useState<any>(data);
82
- // Setting first set of questions as default open
83
- const [selectedCategory, setSelectedCategory] = useState<any>(data.CategoryAnswers[0]);
84
- const [initialValues, setInitialValues] = useState<any>(data.CategoryAnswers[0].Data);
85
- const [form] = useForm();
86
-
87
-
88
- const updateInitialValues = (data: any) => {
89
- const {
90
- Questions,
91
- OpenAnswer
92
- } = data;
93
-
94
- const initial = {
95
- Questions: Questions.map((question: any) => ({
96
- Subject: question.Subject,
97
- Description: question.Description,
98
- Answer: question.Answer || ""
99
- })),
100
- OpenAnswer: OpenAnswer
101
- };
102
-
103
- setInitialValues(initial);
104
- form.setFieldsValue(initial);
105
- };
106
-
107
- const handleLabelClick = (category: any, index: number) => {
108
- setSelectedCategory(category);
109
- updateInitialValues(category.Data);
110
- setCurrentKey(index);
111
- };
112
-
113
- const onFinish = (values: any) => {
114
- const updatedQuestions = initialValues.Questions.map((question: any, index: number) => {
115
- return {
116
- ...question,
117
- Answer: values.Questions[index].Answer
118
- };
119
- });
120
-
121
- const updatedCategory = updateCategoryAnswers(localData.CategoryAnswers, selectedCategory.Data, updatedQuestions);
122
-
123
- const updatedLocalData = { ...localData, CategoryAnswers: updatedCategory };
124
-
125
- setLocalData(updatedLocalData);
126
- };
127
-
128
- const renderCategories = (categories: any) => {
129
- return categories.map((category: any, index: number) => {
130
- const labelClasses = classNames({
131
- [styles.cursorPointer]: category.Data.Questions.length > 0
132
- }, [styles.label]);
133
-
134
- const indexCheck = category.Data.Questions.length > 0 && category.Key;
135
-
136
- return (
137
- <div
138
- className={`${styles.labelWrapper} ${category.Data.CategoryId === selectedCategory.Data.CategoryId ? styles.active : ""}`}
139
- key={index}
140
- >
141
- <div
142
- className={labelClasses}
143
- data-index={indexCheck}
144
- onClick={() => category.Data.Questions.length > 0 && handleLabelClick(category, indexCheck)}
145
- >
146
- {category.Title}
147
- </div>
148
- {category.Children && (
149
- <div className={styles.subCategory}>
150
- {renderCategories(category.Children)}
151
- </div>
152
- )}
153
- </div>
154
- )
155
- });
156
- };
157
-
158
- const handleNextClick = () => {
159
- const nextCategory = findCategoryWithQuestions(currentKey, localData.CategoryAnswers, 'next');
160
- if (nextCategory) {
161
- setCurrentKey(nextCategory.Key);
162
- setSelectedCategory(nextCategory);
163
- }
164
-
165
- const nextCategoryData = getCategoryObject(currentKey, localData.CategoryAnswers, 'next');
166
- setSelectedCategory(nextCategoryData ? { ...nextCategory, data: nextCategoryData } : null);
167
- updateInitialValues(nextCategoryData);
168
- };
169
-
170
- const handlePreviousClick = () => {
171
- const prevCategory = findCategoryWithQuestions(currentKey, localData.CategoryAnswers, 'prev');
172
- if (prevCategory) {
173
- setCurrentKey(prevCategory.Key);
174
- setSelectedCategory(prevCategory);
175
- }
176
-
177
- const prevCategoryData = getCategoryObject(currentKey, localData.CategoryAnswers, 'prev');
178
- setSelectedCategory(prevCategoryData ? { ...prevCategory, data: prevCategoryData } : null);
179
- updateInitialValues(prevCategoryData);
180
- };
181
-
182
- useImperativeHandle(ref, () => ({
183
- handleNextClick,
184
- handlePreviousClick,
185
- }));
186
-
187
- useEffect(() => {
188
- props.serverReadyData(localData);
189
- }, [localData]);
190
-
191
- useEffect(() => {
192
- const hasNext = hasCategory(currentKey, localData.CategoryAnswers, 'next');
193
- props.onNextCategoryAvailabilityChange(hasNext);
194
-
195
- const hasPrevious = hasCategory(currentKey, localData.CategoryAnswers, 'prev');
196
- props.onPreviousCategoryAvailabilityChange(hasPrevious);
197
- }, [currentKey, localData.CategoryAnswers, props]);
198
-
199
- const questionWrapperClasses = classNames({
200
- [styles.questionWrapperOpenAnswer]: selectedCategory.Data.OpenAnswer,
201
- }, [styles.questionWrapper]);
202
-
203
- const answerClasses = classNames({
204
- [styles.answerOpenAnswer]: selectedCategory.Data.OpenAnswer,
205
- }, [styles.answer]);
206
-
207
- return (
208
- <div className={styles.categoryResponse}>
209
- <div className={styles.sidebarWrapper}>
210
- <div className={styles.title}>{t('components.categoryReadOnly.categories')}</div>
211
- {renderCategories(localData.CategoryAnswers)}
212
- </div>
213
- <div className={styles.contentWrapper}>
214
-
215
- <div className={styles.details}>
216
- <div className={styles.categoryName}>
217
- {selectedCategory?.Data?.CategoryName}
218
- </div>
219
- <div className={styles.categoryGradesWrapper}>
220
- <div className={styles.categoryGradesTitle}>
221
- {t('components.categoryReadOnly.categoryAverage')}
222
- </div>
223
- <div className={styles.categoryGrades}>
224
- <div className={styles.gradeBox} style={{ backgroundColor: localData.UserColor }}>
225
- {selectedCategory?.Data.Score}
226
- </div>
227
- <div className={styles.gradeBox} style={{ backgroundColor: localData.SupervisorColor }}>
228
- {selectedCategory?.Data.SupervisorScore}
229
- </div>
230
- </div>
231
- </div>
232
- </div>
233
-
234
- {selectedCategory?.Data?.Questions.map((question: any, index: number) => (
235
- <div className={questionWrapperClasses} key={index}>
236
- <div className={styles.question}>
237
- <div className={styles.subject}>
238
- {question.Subject}
239
- </div>
240
- </div>
241
- <div className={answerClasses}>
242
- <div className={styles.gradeBox} style={{ backgroundColor: localData.UserColor }}>
243
- {question.UserAnswer}
244
- </div>
245
- <div className={styles.gradeBox} style={{ backgroundColor: localData.SupervisorColor }}>
246
- {question.SupervisorAnswer}
247
- </div>
248
- </div>
249
- </div>
250
- ))}
251
- </div>
252
- </div>
253
- );
254
- });
1
+ import styles from './styles.module.scss';
2
+ import { useEffect, useImperativeHandle, useState } from 'react';
3
+ import { useForm } from 'antd/es/form/Form';
4
+ import classNames from 'classnames';
5
+ import React from 'react';
6
+ import { t } from 'i18next';
7
+
8
+ interface CategoryResponse {
9
+ data: any;
10
+ serverReadyData: any;
11
+ onNextCategoryAvailabilityChange: (hasNext: boolean) => void;
12
+ onPreviousCategoryAvailabilityChange: (hasPrevious: boolean) => void;
13
+ };
14
+
15
+ type Category = {
16
+ Title: string;
17
+ Key: string;
18
+ Data: any;
19
+ Children?: Category[];
20
+ };
21
+
22
+ const updateCategoryAnswers = (CategoryAnswers: any[], categoryToUpdate: any, updatedQuestions: any) => {
23
+ CategoryAnswers.forEach((category: any) => {
24
+ if (category.Data.CategoryId === categoryToUpdate.CategoryId) {
25
+ category.Data.Questions = category.Data.Questions.map((question: any, index: any) => {
26
+ return {
27
+ ...question,
28
+ Answer: updatedQuestions[index].Answer
29
+ };
30
+ });
31
+ }
32
+ else if (category.Children && category.Children.length > 0) {
33
+ updateCategoryAnswers(category.Children, categoryToUpdate, updatedQuestions);
34
+ }
35
+ });
36
+ return CategoryAnswers;
37
+ };
38
+
39
+ const findCategoryWithQuestions = (currentKey: string, categories: Category[], direction: 'next' | 'prev'): Category | null => {
40
+ let foundCurrent = false;
41
+
42
+ const searchCategories = (categoryList: Category[], direction: 'next' | 'prev'): Category | null => {
43
+ const iterable = direction === 'next' ? categoryList : [...categoryList].reverse();
44
+
45
+ for (const category of iterable) {
46
+ if (foundCurrent) {
47
+ if (category.Data.Questions.length > 0) {
48
+ return category;
49
+ }
50
+ } else if (category.Key === currentKey) {
51
+ foundCurrent = true;
52
+ }
53
+
54
+ if (category.Children) {
55
+ const result = searchCategories(category.Children, direction);
56
+ if (result) {
57
+ return result;
58
+ }
59
+ }
60
+ }
61
+ return null;
62
+ };
63
+
64
+ return searchCategories(categories, direction);
65
+ };
66
+
67
+ const getCategoryObject = (currentKey: string, categories: Category[], direction: 'next' | 'prev'): any => {
68
+ const category = findCategoryWithQuestions(currentKey, categories, direction);
69
+ return category ? category.Data : null;
70
+ };
71
+
72
+ const hasCategory = (currentKey: string, categories: Category[], direction: 'next' | 'prev'): boolean => {
73
+ const category = findCategoryWithQuestions(currentKey, categories, direction);
74
+ return !!category;
75
+ };
76
+
77
+ export const CategoryReadOnly = React.forwardRef((props: CategoryResponse, ref) => {
78
+ const { data } = props;
79
+
80
+ const [currentKey, setCurrentKey] = useState(data.CategoryAnswers[0].Key);
81
+ const [localData, setLocalData] = useState<any>(data);
82
+ // Setting first set of questions as default open
83
+ const [selectedCategory, setSelectedCategory] = useState<any>(data.CategoryAnswers[0]);
84
+ const [initialValues, setInitialValues] = useState<any>(data.CategoryAnswers[0].Data);
85
+ const [form] = useForm();
86
+
87
+
88
+ const updateInitialValues = (data: any) => {
89
+ const {
90
+ Questions,
91
+ OpenAnswer
92
+ } = data;
93
+
94
+ const initial = {
95
+ Questions: Questions.map((question: any) => ({
96
+ Subject: question.Subject,
97
+ Description: question.Description,
98
+ Answer: question.Answer || ""
99
+ })),
100
+ OpenAnswer: OpenAnswer
101
+ };
102
+
103
+ setInitialValues(initial);
104
+ form.setFieldsValue(initial);
105
+ };
106
+
107
+ const handleLabelClick = (category: any, index: number) => {
108
+ setSelectedCategory(category);
109
+ updateInitialValues(category.Data);
110
+ setCurrentKey(index);
111
+ };
112
+
113
+ const onFinish = (values: any) => {
114
+ const updatedQuestions = initialValues.Questions.map((question: any, index: number) => {
115
+ return {
116
+ ...question,
117
+ Answer: values.Questions[index].Answer
118
+ };
119
+ });
120
+
121
+ const updatedCategory = updateCategoryAnswers(localData.CategoryAnswers, selectedCategory.Data, updatedQuestions);
122
+
123
+ const updatedLocalData = { ...localData, CategoryAnswers: updatedCategory };
124
+
125
+ setLocalData(updatedLocalData);
126
+ };
127
+
128
+ const renderCategories = (categories: any) => {
129
+ return categories.map((category: any, index: number) => {
130
+ const labelClasses = classNames({
131
+ [styles.cursorPointer]: category.Data.Questions.length > 0
132
+ }, [styles.label]);
133
+
134
+ const indexCheck = category.Data.Questions.length > 0 && category.Key;
135
+
136
+ return (
137
+ <div
138
+ className={`${styles.labelWrapper} ${category.Data.CategoryId === selectedCategory.Data.CategoryId ? styles.active : ""}`}
139
+ key={index}
140
+ >
141
+ <div
142
+ className={labelClasses}
143
+ data-index={indexCheck}
144
+ onClick={() => category.Data.Questions.length > 0 && handleLabelClick(category, indexCheck)}
145
+ >
146
+ {category.Title}
147
+ </div>
148
+ {category.Children && (
149
+ <div className={styles.subCategory}>
150
+ {renderCategories(category.Children)}
151
+ </div>
152
+ )}
153
+ </div>
154
+ )
155
+ });
156
+ };
157
+
158
+ const handleNextClick = () => {
159
+ const nextCategory = findCategoryWithQuestions(currentKey, localData.CategoryAnswers, 'next');
160
+ if (nextCategory) {
161
+ setCurrentKey(nextCategory.Key);
162
+ setSelectedCategory(nextCategory);
163
+ }
164
+
165
+ const nextCategoryData = getCategoryObject(currentKey, localData.CategoryAnswers, 'next');
166
+ setSelectedCategory(nextCategoryData ? { ...nextCategory, data: nextCategoryData } : null);
167
+ updateInitialValues(nextCategoryData);
168
+ };
169
+
170
+ const handlePreviousClick = () => {
171
+ const prevCategory = findCategoryWithQuestions(currentKey, localData.CategoryAnswers, 'prev');
172
+ if (prevCategory) {
173
+ setCurrentKey(prevCategory.Key);
174
+ setSelectedCategory(prevCategory);
175
+ }
176
+
177
+ const prevCategoryData = getCategoryObject(currentKey, localData.CategoryAnswers, 'prev');
178
+ setSelectedCategory(prevCategoryData ? { ...prevCategory, data: prevCategoryData } : null);
179
+ updateInitialValues(prevCategoryData);
180
+ };
181
+
182
+ useImperativeHandle(ref, () => ({
183
+ handleNextClick,
184
+ handlePreviousClick,
185
+ }));
186
+
187
+ useEffect(() => {
188
+ props.serverReadyData(localData);
189
+ }, [localData]);
190
+
191
+ useEffect(() => {
192
+ const hasNext = hasCategory(currentKey, localData.CategoryAnswers, 'next');
193
+ props.onNextCategoryAvailabilityChange(hasNext);
194
+
195
+ const hasPrevious = hasCategory(currentKey, localData.CategoryAnswers, 'prev');
196
+ props.onPreviousCategoryAvailabilityChange(hasPrevious);
197
+ }, [currentKey, localData.CategoryAnswers, props]);
198
+
199
+ const questionWrapperClasses = classNames({
200
+ [styles.questionWrapperOpenAnswer]: selectedCategory.Data.OpenAnswer,
201
+ }, [styles.questionWrapper]);
202
+
203
+ const answerClasses = classNames({
204
+ [styles.answerOpenAnswer]: selectedCategory.Data.OpenAnswer,
205
+ }, [styles.answer]);
206
+
207
+ return (
208
+ <div className={styles.categoryResponse}>
209
+ <div className={styles.sidebarWrapper}>
210
+ <div className={styles.title}>{t('components.categoryReadOnly.categories')}</div>
211
+ {renderCategories(localData.CategoryAnswers)}
212
+ </div>
213
+ <div className={styles.contentWrapper}>
214
+
215
+ <div className={styles.details}>
216
+ <div className={styles.categoryName}>
217
+ {selectedCategory?.Data?.CategoryName}
218
+ </div>
219
+ <div className={styles.categoryGradesWrapper}>
220
+ <div className={styles.categoryGradesTitle}>
221
+ {t('components.categoryReadOnly.categoryAverage')}
222
+ </div>
223
+ <div className={styles.categoryGrades}>
224
+ <div className={styles.gradeBox} style={{ backgroundColor: localData.UserColor }}>
225
+ {selectedCategory?.Data.Score}
226
+ </div>
227
+ <div className={styles.gradeBox} style={{ backgroundColor: localData.SupervisorColor }}>
228
+ {selectedCategory?.Data.SupervisorScore}
229
+ </div>
230
+ </div>
231
+ </div>
232
+ </div>
233
+
234
+ {selectedCategory?.Data?.Questions.map((question: any, index: number) => (
235
+ <div className={questionWrapperClasses} key={index}>
236
+ <div className={styles.question}>
237
+ <div className={styles.subject}>
238
+ {question.Subject}
239
+ </div>
240
+ </div>
241
+ <div className={answerClasses}>
242
+ <div className={styles.gradeBox} style={{ backgroundColor: localData.UserColor }}>
243
+ {question.UserAnswer}
244
+ </div>
245
+ <div className={styles.gradeBox} style={{ backgroundColor: localData.SupervisorColor }}>
246
+ {question.SupervisorAnswer}
247
+ </div>
248
+ </div>
249
+ </div>
250
+ ))}
251
+ </div>
252
+ </div>
253
+ );
254
+ });