@omniumretail/component-library 1.0.37 → 1.0.39

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 (35) hide show
  1. package/dist/bundle.js +148 -5
  2. package/dist/main.css +216 -0
  3. package/dist/types/components/AnalyticsBar/AnalyticsBar.stories.d.ts +5 -0
  4. package/dist/types/components/AnalyticsBar/helpers/codeMutation.d.ts +4 -0
  5. package/dist/types/components/AnalyticsBar/index.d.ts +2 -0
  6. package/dist/types/components/AnalyticsBar/interfaces/analyticsBar.d.ts +12 -0
  7. package/dist/types/components/CategoryResponse/CategoryResponse.stories.d.ts +4 -0
  8. package/dist/types/components/CategoryResponse/evaluationOptions.d.ts +10 -0
  9. package/dist/types/components/CategoryResponse/index.d.ts +9 -0
  10. package/dist/types/components/Menu/Menu.stories.d.ts +5 -0
  11. package/dist/types/components/Menu/helpers/codeMutation.d.ts +4 -0
  12. package/dist/types/components/Menu/index.d.ts +3 -0
  13. package/dist/types/components/index.d.ts +2 -0
  14. package/dist/types/constants/translationHelper.d.ts +2 -0
  15. package/package.json +1 -1
  16. package/src/components/AnalyticsBar/AnalyticsBar.stories.tsx +180 -0
  17. package/src/components/AnalyticsBar/helpers/codeMutation.tsx +19 -0
  18. package/src/components/AnalyticsBar/index.tsx +76 -0
  19. package/src/components/AnalyticsBar/interfaces/analyticsBar.tsx +13 -0
  20. package/src/components/AnalyticsBar/styles.module.scss +108 -0
  21. package/src/components/Category/Category.stories.tsx +64 -37
  22. package/src/components/Category/CategoryContent/index.tsx +9 -9
  23. package/src/components/CategoryResponse/CategoryResponse.stories.tsx +261 -0
  24. package/src/components/CategoryResponse/evaluationOptions.tsx +81 -0
  25. package/src/components/CategoryResponse/index.tsx +279 -0
  26. package/src/components/CategoryResponse/styles.module.scss +135 -0
  27. package/src/components/Menu/Menu.stories.tsx +178 -0
  28. package/src/components/Menu/helpers/codeMutation.tsx +19 -0
  29. package/src/components/Menu/index.tsx +23 -0
  30. package/src/components/Menu/styles.module.scss +0 -0
  31. package/src/components/index.tsx +2 -0
  32. package/src/constants/translationHelper.ts +7 -0
  33. package/src/locales/en.json +3 -0
  34. package/src/locales/es.json +3 -0
  35. package/src/locales/pt.json +3 -0
@@ -0,0 +1,279 @@
1
+ import styles from './styles.module.scss';
2
+ import { useEffect, useImperativeHandle, useState } from 'react';
3
+ import { Form } from 'antd';
4
+ import { useForm } from 'antd/es/form/Form';
5
+ import { Button } from '../Button';
6
+ import classNames from 'classnames';
7
+ import TextArea from 'antd/es/input/TextArea';
8
+ import { Select } from '../Select';
9
+ import { evaluationOptions } from './evaluationOptions';
10
+ import React from 'react';
11
+
12
+ interface CategoryResponse {
13
+ data: any;
14
+ serverReadyData: any;
15
+ onNextCategoryAvailabilityChange: (hasNext: boolean) => void;
16
+ onPreviousCategoryAvailabilityChange: (hasPrevious: boolean) => void;
17
+ };
18
+
19
+ type Category = {
20
+ title: string;
21
+ key: string;
22
+ data: any;
23
+ children?: Category[];
24
+ };
25
+
26
+ const updateCategoryAnswers = (categoryAnswers: any[], categoryToUpdate: any, updatedQuestions: any) => {
27
+ categoryAnswers.forEach((category: any) => {
28
+ if (category.data.category_id === categoryToUpdate.category_id) {
29
+ category.data.questions = category.data.questions.map((question: any, index: any) => {
30
+ return {
31
+ ...question,
32
+ answer: updatedQuestions[index].answer
33
+ };
34
+ });
35
+ }
36
+ else if (category.children && category.children.length > 0) {
37
+ updateCategoryAnswers(category.children, categoryToUpdate, updatedQuestions);
38
+ }
39
+ });
40
+ return categoryAnswers;
41
+ };
42
+
43
+ const findCategoryWithQuestions = (currentKey: string, categories: Category[], direction: 'next' | 'prev'): Category | null => {
44
+ let foundCurrent = false;
45
+
46
+ const searchCategories = (categoryList: Category[], direction: 'next' | 'prev'): Category | null => {
47
+ const iterable = direction === 'next' ? categoryList : [...categoryList].reverse();
48
+
49
+ for (const category of iterable) {
50
+ if (foundCurrent) {
51
+ if (category.data.questions.length > 0) {
52
+ return category;
53
+ }
54
+ } else if (category.key === currentKey) {
55
+ foundCurrent = true;
56
+ }
57
+
58
+ if (category.children) {
59
+ const result = searchCategories(category.children, direction);
60
+ if (result) {
61
+ return result;
62
+ }
63
+ }
64
+ }
65
+ return null;
66
+ };
67
+
68
+ return searchCategories(categories, direction);
69
+ };
70
+
71
+ const getCategoryObject = (currentKey: string, categories: Category[], direction: 'next' | 'prev'): any => {
72
+ const category = findCategoryWithQuestions(currentKey, categories, direction);
73
+ return category ? category.data : null;
74
+ };
75
+
76
+ const hasCategory = (currentKey: string, categories: Category[], direction: 'next' | 'prev'): boolean => {
77
+ const category = findCategoryWithQuestions(currentKey, categories, direction);
78
+ return !!category;
79
+ };
80
+
81
+ const getTitleWithQuestionCount = (category: any): string => {
82
+ const questionCount = category?.data?.questions?.length;
83
+ const answeredQuestions = category?.data?.questions?.filter((question: any) => question.answer !== null && question.answer !== undefined && question.answer !== '').length;
84
+
85
+ return questionCount
86
+ ? `${category.title} - ${answeredQuestions} / ${questionCount}`
87
+ : category.title ;
88
+ };
89
+
90
+ export const CategoryResponse = React.forwardRef((props: CategoryResponse, ref) => {
91
+ const { data } = props;
92
+
93
+ const [currentKey, setCurrentKey] = useState(data.categoryAnswers[0].key);
94
+ const [localData, setLocalData] = useState<any>(data);
95
+ // Setting first set of questions as default open
96
+ const [selectedCategory, setSelectedCategory] = useState<any>(data.categoryAnswers[0]);
97
+ const [initialValues, setInitialValues] = useState<any>(data.categoryAnswers[0].data);
98
+ const [form] = useForm();
99
+
100
+
101
+ const updateInitialValues = (data: any) => {
102
+ const {
103
+ questions,
104
+ openAnswer
105
+ } = data;
106
+
107
+ const initial = {
108
+ questions: questions.map((question: any) => ({
109
+ subject: question.subject,
110
+ description: question.description,
111
+ answer: question.answer || ""
112
+ })),
113
+ openAnswer: openAnswer
114
+ };
115
+
116
+ setInitialValues(initial);
117
+ form.setFieldsValue(initial);
118
+ };
119
+
120
+ const handleLabelClick = (category: any, index: number) => {
121
+ setSelectedCategory(category);
122
+ updateInitialValues(category.data);
123
+ setCurrentKey(index);
124
+ };
125
+
126
+ const onFinish = (values: any) => {
127
+ const updatedQuestions = initialValues.questions.map((question: any, index: number) => {
128
+ return {
129
+ ...question,
130
+ answer: values.questions[index].answer
131
+ };
132
+ });
133
+
134
+ const updatedCategory = updateCategoryAnswers(localData.categoryAnswers, selectedCategory.data, updatedQuestions);
135
+
136
+ const updatedLocalData = { ...localData, categoryAnswers: updatedCategory };
137
+
138
+ setLocalData(updatedLocalData);
139
+ };
140
+
141
+ const renderCategories = (categories: any) => {
142
+ return categories.map((category: any, index: number) => {
143
+ const labelClasses = classNames({
144
+ [styles.cursorPointer]: category.data.questions.length > 0
145
+ }, [styles.label]);
146
+
147
+ const indexCheck = category.data.questions.length > 0 && category.key;
148
+
149
+ return (
150
+ <div
151
+ className={`${styles.labelWrapper} ${category.data.category_id === selectedCategory.data.category_id ? styles.active : ""}`}
152
+ key={index}
153
+ >
154
+ <div
155
+ className={labelClasses}
156
+ data-index={indexCheck}
157
+ onClick={() => category.data.questions.length > 0 && handleLabelClick(category, indexCheck)}
158
+ >
159
+ {getTitleWithQuestionCount(category)}
160
+ </div>
161
+ {category.children && (
162
+ <div className={styles.subCategory}>
163
+ {renderCategories(category.children)}
164
+ </div>
165
+ )}
166
+ </div>
167
+ )
168
+ });
169
+ };
170
+
171
+ const handleNextClick = () => {
172
+ const nextCategory = findCategoryWithQuestions(currentKey, localData.categoryAnswers, 'next');
173
+ if (nextCategory) {
174
+ setCurrentKey(nextCategory.key);
175
+ setSelectedCategory(nextCategory);
176
+ }
177
+
178
+ const nextCategoryData = getCategoryObject(currentKey, localData.categoryAnswers, 'next');
179
+ setSelectedCategory(nextCategoryData ? { ...nextCategory, data: nextCategoryData } : null);
180
+ updateInitialValues(nextCategoryData);
181
+ };
182
+
183
+ const handlePreviousClick = () => {
184
+ const prevCategory = findCategoryWithQuestions(currentKey, localData.categoryAnswers, 'prev');
185
+ if (prevCategory) {
186
+ setCurrentKey(prevCategory.key);
187
+ setSelectedCategory(prevCategory);
188
+ }
189
+
190
+ const prevCategoryData = getCategoryObject(currentKey, localData.categoryAnswers, 'prev');
191
+ setSelectedCategory(prevCategoryData ? { ...prevCategory, data: prevCategoryData } : null);
192
+ updateInitialValues(prevCategoryData);
193
+ };
194
+
195
+ useImperativeHandle(ref, () => ({
196
+ handleNextClick,
197
+ handlePreviousClick,
198
+ }));
199
+
200
+ useEffect(() => {
201
+ props.serverReadyData(localData);
202
+ }, [localData]);
203
+
204
+ useEffect(() => {
205
+ const hasNext = hasCategory(currentKey, localData.categoryAnswers, 'next');
206
+ props.onNextCategoryAvailabilityChange(hasNext);
207
+
208
+ const hasPrevious = hasCategory(currentKey, localData.categoryAnswers, 'prev');
209
+ props.onPreviousCategoryAvailabilityChange(hasPrevious);
210
+ }, [currentKey, localData.categoryAnswers, props]);
211
+
212
+ const questionWrapper = classNames({
213
+ [styles.questionWrapperOpenAnswer]: selectedCategory.data.openAnswer,
214
+ }, [styles.questionWrapper]);
215
+
216
+ // This gets the scale we use for each select from the database using a key based variable,if
217
+ // any new generalEvaluationLevel is added to the backend we need to update our own without
218
+ // deleting any of the previous so we dont mess up the project history.
219
+ const selectedEvaluationOption = `scale_${selectedCategory?.data?.generalEvaluationLevel}` as keyof typeof evaluationOptions;
220
+
221
+ return (
222
+ <div className={styles.categoryResponse}>
223
+ <div className={styles.sidebarWrapper}>
224
+ <div className={styles.title}>Categorias</div>
225
+ {renderCategories(localData.categoryAnswers)}
226
+ </div>
227
+ <div className={styles.contentWrapper}>
228
+ <Form
229
+ initialValues={initialValues}
230
+ name="dynamic_form_nest_item"
231
+ onFinish={onFinish}
232
+ autoComplete="off"
233
+ form={form}
234
+ >
235
+ <div className={styles.details}>
236
+ <div className={styles.categoryName}>
237
+ {selectedCategory?.data?.categoryName}
238
+ </div>
239
+ <div className={styles.categoryDescription}>
240
+ {selectedCategory?.data?.description}
241
+ </div>
242
+ </div>
243
+ {selectedCategory?.data?.questions.map((question: any, index: number) => (
244
+ <div className={questionWrapper} key={index}>
245
+ <div className={styles.question}>
246
+ <div className={styles.subject}>
247
+ {question.subject}
248
+ </div>
249
+ <div className={styles.description}>
250
+ {question.description}
251
+ </div>
252
+ </div>
253
+ <div className={styles.answer}>
254
+ {selectedCategory.data.openAnswer
255
+ ? <Form.Item
256
+ name={["questions", index, "answer"]}
257
+ >
258
+ <TextArea />
259
+ </Form.Item>
260
+ : <Form.Item
261
+ name={["questions", index, "answer"]}
262
+ >
263
+ <Select options={evaluationOptions[selectedEvaluationOption]}
264
+ style={{ minWidth: '100%' }}
265
+ />
266
+ </Form.Item>
267
+ }
268
+ </div>
269
+ </div>
270
+ ))}
271
+
272
+ {selectedCategory?.data?.questions.length > 0 && (
273
+ <Button onClick={() => form.submit()}>Answer</Button>
274
+ )}
275
+ </Form>
276
+ </div>
277
+ </div>
278
+ );
279
+ });
@@ -0,0 +1,135 @@
1
+ .categoryResponse {
2
+ display: grid;
3
+ grid-template-columns: 300px auto;
4
+ gap: 16px;
5
+ height: 100%;
6
+ }
7
+
8
+ .sidebarWrapper {
9
+ background: #EBECED;
10
+ }
11
+
12
+ .contentWrapper {
13
+ background: var(--color-white);
14
+ }
15
+
16
+ .sidebarWrapper,
17
+ .contentWrapper {
18
+ padding: 20px;
19
+ }
20
+
21
+ .title {
22
+ font-size: var(--font-size-body-4);
23
+ color: var(--color-blue);
24
+ margin-bottom: 36px;
25
+ font-weight: var(--font-weight-semibold);
26
+ text-transform: uppercase;
27
+
28
+ }
29
+
30
+ .label {
31
+ padding-bottom: 15px;
32
+ font-weight: var(--font-weight-bold);
33
+ font-size: var(--font-size-body-4);
34
+ }
35
+
36
+ .cursorPointer {
37
+ cursor: pointer;
38
+ }
39
+
40
+ .subCategory {
41
+ padding-left: 16px;
42
+
43
+ .label {
44
+ font-weight: var(--font-weight-medium);
45
+ }
46
+
47
+ .labelWrapper {
48
+ .subCategory {
49
+ .label {
50
+ font-weight: var(--font-weight-light);
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ .labelWrapper {
57
+ display: block;
58
+ }
59
+
60
+ .active {
61
+ color: var(--color-orange);
62
+ }
63
+
64
+ .details {
65
+ margin-bottom: 24px;
66
+ }
67
+
68
+ .categoryName {
69
+ font-size: var(--font-size-body-4);
70
+ color: var(--color-blue);
71
+ font-weight: var(--font-weight-semibold);
72
+ margin-bottom: 8px;
73
+ }
74
+
75
+ .categoryDescription {
76
+ font-size: var(--font-size-body-3);
77
+ font-weight: var(--font-weight-light);
78
+ color: var(--color-black);
79
+ }
80
+
81
+ // Questions
82
+ .questionWrapper {
83
+ display: flex;
84
+ flex-direction: row;
85
+ gap: 12px;
86
+ margin-bottom: 36px;
87
+ }
88
+
89
+ .questionWrapperOpenAnswer {
90
+ flex-direction: column;
91
+ border-bottom: 1px solid rgba(var(--color-blue-rgb), .2);
92
+ margin-bottom: 24px;
93
+
94
+ .question {
95
+ width: 100%;
96
+ border-bottom: none;
97
+ }
98
+
99
+ .answer {
100
+ width: 100%;
101
+ height: auto;
102
+
103
+ :global {
104
+ .ant-input {
105
+ min-height: 140px;
106
+ }
107
+
108
+ .ant-form-item {
109
+ margin-bottom: 16px;
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ .question {
116
+ width: calc(100% - 112px);
117
+ border-bottom: 1px solid rgba(var(--color-blue-rgb), .2);
118
+ }
119
+
120
+ .answer {
121
+ width: 100px;
122
+ height: 50px;
123
+ align-self: flex-end;
124
+ }
125
+
126
+ .subject {
127
+ font-size: var(--font-size-body-3);
128
+ font-weight: var(--font-weight-medium);
129
+ margin-bottom: 8px;
130
+ }
131
+
132
+ .description {
133
+ font-weight: var(--font-weight-light);
134
+ margin-bottom: 4px;
135
+ }
@@ -0,0 +1,178 @@
1
+ import { Meta, Story } from "@storybook/react";
2
+ import { Menu } from '.';
3
+ import { MenuProps } from 'antd';
4
+ import { getItem } from './helpers/codeMutation';
5
+
6
+ export default {
7
+ title: 'Menu',
8
+ component: Menu,
9
+ } as Meta;
10
+
11
+ const Template: Story<MenuProps> = (args) => {
12
+ const data = [
13
+ {
14
+ "Year": 2023,
15
+ "EvaluationCycles": [
16
+ {
17
+ "Id": "D5A77A3B-1163-4590-9C98-2E6D62442F62",
18
+ "Type": "Permanent",
19
+ "Name": "EV1",
20
+ "Year": 2023,
21
+ "StartDate": "2023-03-01T00:00:00Z",
22
+ "EndDate": "2023-05-31T23:00:00Z",
23
+ "Users": [
24
+ {
25
+ "UserId": "A200F4C5-8E41-41D4-A90C-B15EEC448517",
26
+ "UserAnswer": null,
27
+ "UserScore": null,
28
+ "SupervisorId": null,
29
+ "SupervisorAnswer": null,
30
+ "SupervisorScore": null
31
+ },
32
+ {
33
+ "UserId": "9D361E92-A748-4E4A-BC5E-0134CE62328E",
34
+ "UserAnswer": "982FF376-56AD-4E3F-B0D0-5BD4282A7F78",
35
+ "UserScore": 3.333,
36
+ "SupervisorId": null,
37
+ "SupervisorAnswer": null,
38
+ "SupervisorScore": null
39
+ },
40
+ {
41
+ "UserId": "594A4DD5-12B1-4ED0-B00C-EDF729B85C57",
42
+ "UserAnswer": null,
43
+ "UserScore": null,
44
+ "SupervisorId": null,
45
+ "SupervisorAnswer": null,
46
+ "SupervisorScore": null
47
+ }
48
+ ],
49
+ "QuestionnaireId": "4C15A0A0-7DDF-4952-810C-B46105807CB7",
50
+ "State": "Started",
51
+ "Notifications": [],
52
+ "NotificationAgenda": null,
53
+ "Status": "A",
54
+ "IsOnlyForUsers": false,
55
+ "CreateDate": "2023-02-27T10:50:41.737Z",
56
+ "UpdateDate": "2023-02-27T10:52:50.661Z",
57
+ "CreateUserId": "A200F4C5-8E41-41D4-A90C-B15EEC448517",
58
+ "UpdateUserId": null,
59
+ "InitiatDate": "2023-02-27T10:51:00Z",
60
+ "CancelDate": "0001-01-01T00:00:00Z"
61
+ },
62
+ {
63
+ "Id": "42A6EFDD-6D74-4905-94AE-5B5588967BE6",
64
+ "Type": "Permanent",
65
+ "Name": "EV1",
66
+ "Year": 2023,
67
+ "StartDate": "2023-03-01T00:00:00Z",
68
+ "EndDate": "2023-05-31T23:00:00Z",
69
+ "Users": [],
70
+ "QuestionnaireId": "4C15A0A0-7DDF-4952-810C-B46105807CB7",
71
+ "State": "Draft",
72
+ "Notifications": [],
73
+ "NotificationAgenda": null,
74
+ "Status": "A",
75
+ "IsOnlyForUsers": false,
76
+ "CreateDate": "2023-02-27T14:52:16.523Z",
77
+ "UpdateDate": "2023-02-27T14:53:04.987Z",
78
+ "CreateUserId": "A200F4C5-8E41-41D4-A90C-B15EEC448517",
79
+ "UpdateUserId": "A200F4C5-8E41-41D4-A90C-B15EEC448517",
80
+ "InitiatDate": "0001-01-01T00:00:00Z",
81
+ "CancelDate": "0001-01-01T00:00:00Z"
82
+ }
83
+ ]
84
+ },
85
+ {
86
+ "Year": 2024,
87
+ "EvaluationCycles": [
88
+ {
89
+ "Id": "D5A77A3B-1163-4590-9C98-2E6D62442F62",
90
+ "Type": "Permanent",
91
+ "Name": "EV2",
92
+ "Year": 2024,
93
+ "StartDate": "2023-03-01T00:00:00Z",
94
+ "EndDate": "2023-05-31T23:00:00Z",
95
+ "Users": [
96
+ {
97
+ "UserId": "A200F4C5-8E41-41D4-A90C-B15EEC448517",
98
+ "UserAnswer": null,
99
+ "UserScore": null,
100
+ "SupervisorId": null,
101
+ "SupervisorAnswer": null,
102
+ "SupervisorScore": null
103
+ },
104
+ {
105
+ "UserId": "9D361E92-A748-4E4A-BC5E-0134CE62328E",
106
+ "UserAnswer": "982FF376-56AD-4E3F-B0D0-5BD4282A7F78",
107
+ "UserScore": 3.333,
108
+ "SupervisorId": null,
109
+ "SupervisorAnswer": null,
110
+ "SupervisorScore": null
111
+ },
112
+ {
113
+ "UserId": "594A4DD5-12B1-4ED0-B00C-EDF729B85C57",
114
+ "UserAnswer": null,
115
+ "UserScore": null,
116
+ "SupervisorId": null,
117
+ "SupervisorAnswer": null,
118
+ "SupervisorScore": null
119
+ }
120
+ ],
121
+ "QuestionnaireId": "4C15A0A0-7DDF-4952-810C-B46105807CB7",
122
+ "State": "Started",
123
+ "Notifications": [],
124
+ "NotificationAgenda": null,
125
+ "Status": "A",
126
+ "IsOnlyForUsers": false,
127
+ "CreateDate": "2023-02-27T10:50:41.737Z",
128
+ "UpdateDate": "2023-02-27T10:52:50.661Z",
129
+ "CreateUserId": "A200F4C5-8E41-41D4-A90C-B15EEC448517",
130
+ "UpdateUserId": null,
131
+ "InitiatDate": "2023-02-27T10:51:00Z",
132
+ "CancelDate": "0001-01-01T00:00:00Z"
133
+ },
134
+ {
135
+ "Id": "42A6EFDD-6D74-4905-94AE-5B5588967BE6",
136
+ "Type": "Permanent",
137
+ "Name": "EV2",
138
+ "Year": 2024,
139
+ "StartDate": "2023-03-01T00:00:00Z",
140
+ "EndDate": "2023-05-31T23:00:00Z",
141
+ "Users": [],
142
+ "QuestionnaireId": "4C15A0A0-7DDF-4952-810C-B46105807CB7",
143
+ "State": "Draft",
144
+ "Notifications": [],
145
+ "NotificationAgenda": null,
146
+ "Status": "A",
147
+ "IsOnlyForUsers": false,
148
+ "CreateDate": "2023-02-27T14:52:16.523Z",
149
+ "UpdateDate": "2023-02-27T14:53:04.987Z",
150
+ "CreateUserId": "A200F4C5-8E41-41D4-A90C-B15EEC448517",
151
+ "UpdateUserId": "A200F4C5-8E41-41D4-A90C-B15EEC448517",
152
+ "InitiatDate": "0001-01-01T00:00:00Z",
153
+ "CancelDate": "0001-01-01T00:00:00Z"
154
+ }
155
+ ]
156
+ }
157
+ ];
158
+
159
+ const items = data.map((el: any, index: any) => {
160
+ return (
161
+ getItem(
162
+ el.Year,
163
+ index,
164
+ <></>,
165
+ el.EvaluationCycles?.map((evCycle: any, subIndex: any) => {
166
+ return getItem(evCycle.Name, `${index}-${subIndex}`);
167
+ })
168
+ )
169
+ )
170
+ });
171
+
172
+
173
+ return <Menu {...args} items={items}></Menu>;
174
+ }
175
+
176
+ export const Primary = Template.bind({});
177
+ Primary.args = {
178
+ };
@@ -0,0 +1,19 @@
1
+ import type { MenuProps } from 'antd';
2
+
3
+ export type MenuItem = Required<MenuProps>['items'][number];
4
+
5
+ export function getItem(
6
+ label: React.ReactNode,
7
+ key: React.Key,
8
+ icon?: React.ReactNode,
9
+ children?: MenuItem[],
10
+ type?: 'group',
11
+ ): MenuItem {
12
+ return {
13
+ key,
14
+ icon,
15
+ children,
16
+ label,
17
+ type,
18
+ } as MenuItem;
19
+ }
@@ -0,0 +1,23 @@
1
+ import styles from './styles.module.scss';
2
+ import { MinusOutlined, PlusOutlined } from '@ant-design/icons';
3
+ import type { MenuProps } from 'antd';
4
+ import { Menu as MenuAntd} from 'antd';
5
+
6
+ export const Menu = (props: MenuProps) => {
7
+ const {
8
+ items
9
+ } = props;
10
+
11
+ const onClick: MenuProps['onClick'] = (e) => {
12
+ // console.log('click ', e);
13
+ };
14
+
15
+ return (
16
+ <MenuAntd
17
+ onClick={onClick}
18
+ mode="inline"
19
+ items={items}
20
+ expandIcon={({ isOpen }) => (isOpen ? <MinusOutlined /> : <PlusOutlined />)}
21
+ />
22
+ );
23
+ };
File without changes
@@ -17,3 +17,5 @@ export * from './Sidebar';
17
17
  export * from './Switch';
18
18
  export * from './Category';
19
19
  export * from './DatePickerTag';
20
+ export * from './AnalyticsBar';
21
+ export * from './CategoryResponse';
@@ -0,0 +1,7 @@
1
+ import i18next from 'i18next';
2
+
3
+ const translate = (key: any, options = {}) => {
4
+ return i18next.t(key, options);
5
+ };
6
+
7
+ export default translate;
@@ -26,6 +26,9 @@
26
26
  "errorQuestion": "Missing Question",
27
27
  "placeholderGrade": "Grade",
28
28
  "errorGrade": "Missing Grade"
29
+ },
30
+ "categoryResponse": {
31
+ "notApplicable": "Not Applicable"
29
32
  }
30
33
  }
31
34
  }
@@ -26,6 +26,9 @@
26
26
  "errorQuestion": "Missing Question ES",
27
27
  "placeholderGrade": "Grade ES",
28
28
  "errorGrade": "Missing Grade ES"
29
+ },
30
+ "categoryResponse": {
31
+ "notApplicable": "Not Applicable ES"
29
32
  }
30
33
  }
31
34
  }
@@ -27,6 +27,9 @@
27
27
  "errorQuestion": "Missing Question PT",
28
28
  "placeholderGrade": "Grade PT",
29
29
  "errorGrade": "Missing Grade PT"
30
+ },
31
+ "categoryResponse": {
32
+ "notApplicable": "Não Aplicável"
30
33
  }
31
34
  }
32
35
  }