From fdb499c42e97e60f916a123c346561bd606c7b0f Mon Sep 17 00:00:00 2001
From: Mikhail Sidarkevich <42434528+chivekrodis@users.noreply.github.com>
Date: Mon, 8 Aug 2022 21:07:07 +0300
Subject: [PATCH] EPMRPP-78125 || refactor widgetCriteriaOption, add sub-option
 to dropdown (#3218)

---
 app/localization/translated/be.json           | 10 ++--
 app/localization/translated/ru.json           | 10 ++--
 app/localization/translated/uk.json           | 10 ++--
 .../componentLibrary/dropdown/dropdown.jsx    | 11 ++--
 .../dropdownOption/dropdownOption.jsx         | 41 ++++++-------
 .../dropdownOption/dropdownOption.scss        |  5 +-
 .../utils/getWidgetCriteriaOptions.js         | 57 +++++++------------
 .../projectSettingsPageContainer.jsx          |  2 +-
 8 files changed, 69 insertions(+), 77 deletions(-)

diff --git a/app/localization/translated/be.json b/app/localization/translated/be.json
index bccc88e4f5..42e29ac912 100644
--- a/app/localization/translated/be.json
+++ b/app/localization/translated/be.json
@@ -1939,7 +1939,7 @@
   "Widget.forceUpdateWidgetMessage": "Вы ўпэўненыя, што хочаце абнавіць дадзеныя ў гэтым віджэце? Гэта можа заняць <b> да 15 хвілін </ b> у залежнасці ад памеру базы дадзеных праекта.",
   "Widget.forceUpdateWidgetTitle": "Абнавіць дадзеныя віджэту",
   "WidgetCriteriaOption.AUTOMATION_BUG": "Automation Bug",
-  "WidgetCriteriaOption.AUTOMATION_BUG_TOTAL": "Усяго Automation Bug",
+  "WidgetCriteriaOption.AUTOMATION_BUG_TOTAL": "Група Automation Bug",
   "WidgetCriteriaOption.CriteriaFailed": "Непройдзеныя тэсты",
   "WidgetCriteriaOption.CriteriaPassed": "Пройдзеныя тэсты",
   "WidgetCriteriaOption.CriteriaSkipped": "Прапушчаныя тэсты",
@@ -1950,13 +1950,13 @@
   "WidgetCriteriaOption.Defect_Type_SI001": "System Issue",
   "WidgetCriteriaOption.Defect_Type_TI001": "To Investigate",
   "WidgetCriteriaOption.NO_DEFECT": "Няма праблемы",
-  "WidgetCriteriaOption.NO_DEFECT_TOTAL": "Усяго No Defects",
+  "WidgetCriteriaOption.NO_DEFECT_TOTAL": "Група No Defects",
   "WidgetCriteriaOption.PRODUCT_BUG": "Product Bug",
-  "WidgetCriteriaOption.PRODUCT_BUG_TOTAL": "Усяго Product Bugs",
+  "WidgetCriteriaOption.PRODUCT_BUG_TOTAL": "Група Product Bugs",
   "WidgetCriteriaOption.SYSTEM_ISSUE": "System Issue",
-  "WidgetCriteriaOption.SYSTEM_ISSUE_TOTAL": "Усяго System Issues",
+  "WidgetCriteriaOption.SYSTEM_ISSUE_TOTAL": "Група System Issues",
   "WidgetCriteriaOption.TO_INVESTIGATE": "To Investigate",
-  "WidgetCriteriaOption.TO_INVESTIGATE_TOTAL": "Усяго To Investigate",
+  "WidgetCriteriaOption.TO_INVESTIGATE_TOTAL": "Група To Investigate",
   "WidgetCriteriaOption.aa_settings_actions": "Абнавіць Аўта-Аналіз",
   "WidgetCriteriaOption.attributes": "Атрыбуты",
   "WidgetCriteriaOption.create_pattern": "Стварыць патэрн",
diff --git a/app/localization/translated/ru.json b/app/localization/translated/ru.json
index 2001bb7ebe..ea93ddc255 100644
--- a/app/localization/translated/ru.json
+++ b/app/localization/translated/ru.json
@@ -1939,7 +1939,7 @@
   "Widget.forceUpdateWidgetMessage": "Вы уверены, что хотите обновить данные в этом виджете? Это может занять <b> до 15 минут </ b> в зависимости от размера базы данных проекта.",
   "Widget.forceUpdateWidgetTitle": "Обновить данные виджета",
   "WidgetCriteriaOption.AUTOMATION_BUG": "Automation Bug",
-  "WidgetCriteriaOption.AUTOMATION_BUG_TOTAL": "Всего Automation Bug",
+  "WidgetCriteriaOption.AUTOMATION_BUG_TOTAL": "Группа Automation Bug",
   "WidgetCriteriaOption.CriteriaFailed": "Неудачно",
   "WidgetCriteriaOption.CriteriaPassed": "Успешно",
   "WidgetCriteriaOption.CriteriaSkipped": "Пропущено",
@@ -1950,13 +1950,13 @@
   "WidgetCriteriaOption.Defect_Type_SI001": "System Issue",
   "WidgetCriteriaOption.Defect_Type_TI001": "To Investigate",
   "WidgetCriteriaOption.NO_DEFECT": "Нет проблемы",
-  "WidgetCriteriaOption.NO_DEFECT_TOTAL": "Всего No Defect",
+  "WidgetCriteriaOption.NO_DEFECT_TOTAL": "Группа No Defects",
   "WidgetCriteriaOption.PRODUCT_BUG": "Product Bug",
-  "WidgetCriteriaOption.PRODUCT_BUG_TOTAL": "Всего Product Bugs",
+  "WidgetCriteriaOption.PRODUCT_BUG_TOTAL": "Группа Product Bugs",
   "WidgetCriteriaOption.SYSTEM_ISSUE": "System Issue",
-  "WidgetCriteriaOption.SYSTEM_ISSUE_TOTAL": "Всего System Issues",
+  "WidgetCriteriaOption.SYSTEM_ISSUE_TOTAL": "Группа System Issues",
   "WidgetCriteriaOption.TO_INVESTIGATE": "To Investigate",
-  "WidgetCriteriaOption.TO_INVESTIGATE_TOTAL": "Всего To Investigate",
+  "WidgetCriteriaOption.TO_INVESTIGATE_TOTAL": "Группа To Investigate",
   "WidgetCriteriaOption.aa_settings_actions": "Обновить Авто-Анализ",
   "WidgetCriteriaOption.attributes": "Атрибуты",
   "WidgetCriteriaOption.create_pattern": "Создать паттерн",
diff --git a/app/localization/translated/uk.json b/app/localization/translated/uk.json
index 6ccb7d3459..d5d9aa2873 100644
--- a/app/localization/translated/uk.json
+++ b/app/localization/translated/uk.json
@@ -1939,7 +1939,7 @@
   "Widget.forceUpdateWidgetMessage": "Ви впевнені, що хочете оновити дані в цьому віджеті? Це може зайняти <b> до 15 хвилин </ b> в залежності від розміру бази даних проекту.",
   "Widget.forceUpdateWidgetTitle": "Оновити дані віджета",
   "WidgetCriteriaOption.AUTOMATION_BUG": "Помилка Автоматизації",
-  "WidgetCriteriaOption.AUTOMATION_BUG_TOTAL": "Помилка Автоматизації",
+  "WidgetCriteriaOption.AUTOMATION_BUG_TOTAL": "Група Automation Bug",
   "WidgetCriteriaOption.CriteriaFailed": "Невдало",
   "WidgetCriteriaOption.CriteriaPassed": "Успішно",
   "WidgetCriteriaOption.CriteriaSkipped": "Пропущено",
@@ -1950,13 +1950,13 @@
   "WidgetCriteriaOption.Defect_Type_SI001": "Проблема Системи",
   "WidgetCriteriaOption.Defect_Type_TI001": "Для Розслідування",
   "WidgetCriteriaOption.NO_DEFECT": "Проблеми Немає",
-  "WidgetCriteriaOption.NO_DEFECT_TOTAL": "Всього Не Дефект",
+  "WidgetCriteriaOption.NO_DEFECT_TOTAL": "Група No Defects",
   "WidgetCriteriaOption.PRODUCT_BUG": "Помилка Продукту",
-  "WidgetCriteriaOption.PRODUCT_BUG_TOTAL": "Всього Помилок",
+  "WidgetCriteriaOption.PRODUCT_BUG_TOTAL": "Група Product Bugs",
   "WidgetCriteriaOption.SYSTEM_ISSUE": "Проблема Системи",
-  "WidgetCriteriaOption.SYSTEM_ISSUE_TOTAL": "Питання Системи Всього",
+  "WidgetCriteriaOption.SYSTEM_ISSUE_TOTAL": "Група System Issues",
   "WidgetCriteriaOption.TO_INVESTIGATE": "Для Розслідування",
-  "WidgetCriteriaOption.TO_INVESTIGATE_TOTAL": "Всього Для Розслідування",
+  "WidgetCriteriaOption.TO_INVESTIGATE_TOTAL": "Група To Investigate",
   "WidgetCriteriaOption.aa_settings_actions": "Оновити Авто-Аналіз",
   "WidgetCriteriaOption.attributes": "Атрибути",
   "WidgetCriteriaOption.create_pattern": "Створити патерн",
diff --git a/app/src/componentLibrary/dropdown/dropdown.jsx b/app/src/componentLibrary/dropdown/dropdown.jsx
index 7afd8565aa..a168e388a6 100644
--- a/app/src/componentLibrary/dropdown/dropdown.jsx
+++ b/app/src/componentLibrary/dropdown/dropdown.jsx
@@ -42,6 +42,7 @@ export const Dropdown = ({
   variant,
   placeholder,
   defaultWidth,
+  renderOption,
 }) => {
   const [isOpened, setOpened] = useState(false);
   const containerRef = useRef();
@@ -90,14 +91,12 @@ export const Dropdown = ({
       return (
         <DropdownOption
           key={option.value}
-          value={option.value}
-          disabled={option.disabled}
-          hidden={option.hidden}
           selected={isSelected}
-          label={option.label}
-          title={option.title}
           onChange={option.disabled ? null : () => handleChange(option)}
           variant={variant}
+          option={option}
+          render={renderOption}
+          isOpened={isOpened}
         />
       );
     });
@@ -187,6 +186,7 @@ Dropdown.propTypes = {
   variant: PropTypes.oneOf(['light', 'dark', 'ghost']),
   placeholder: PropTypes.string,
   defaultWidth: PropTypes.bool,
+  renderOption: PropTypes.func,
 };
 
 Dropdown.defaultProps = {
@@ -204,4 +204,5 @@ Dropdown.defaultProps = {
   variant: 'light',
   placeholder: '',
   defaultWidth: true,
+  renderOption: null,
 };
diff --git a/app/src/componentLibrary/dropdown/dropdownOption/dropdownOption.jsx b/app/src/componentLibrary/dropdown/dropdownOption/dropdownOption.jsx
index 077e0d7427..8b012a47f8 100644
--- a/app/src/componentLibrary/dropdown/dropdownOption/dropdownOption.jsx
+++ b/app/src/componentLibrary/dropdown/dropdownOption/dropdownOption.jsx
@@ -21,16 +21,14 @@ import styles from './dropdownOption.scss';
 
 const cx = classNames.bind(styles);
 
-export const DropdownOption = ({
-  label,
-  disabled,
-  hidden,
-  selected,
-  onChange,
-  value,
-  title,
-  variant,
-}) => {
+export const DropdownOption = (props) => {
+  const {
+    option: { value, disabled, hidden, label, title, groupRef },
+    selected,
+    onChange,
+    variant,
+    render,
+  } = props;
   const onChangeHandler = () => onChange && onChange(value);
 
   return (
@@ -43,28 +41,31 @@ export const DropdownOption = ({
       title={(disabled && title) || undefined}
       onClick={onChangeHandler}
     >
-      <div className={cx('single-option')}>{label}</div>
+      <div className={cx('single-option', { 'sub-option': !!groupRef })}>
+        {render ? render(props) : label}
+      </div>
     </div>
   );
 };
 
 DropdownOption.propTypes = {
-  value: PropTypes.oneOfType([PropTypes.string, PropTypes.bool, PropTypes.number]),
-  label: PropTypes.node,
-  disabled: PropTypes.bool,
-  hidden: PropTypes.bool,
+  option: PropTypes.shape({
+    label: PropTypes.node.isRequired,
+    value: PropTypes.oneOfType([PropTypes.string, PropTypes.bool, PropTypes.number]).isRequired,
+    disabled: PropTypes.bool,
+    hidden: PropTypes.bool,
+    title: PropTypes.string,
+    groupRef: PropTypes.string,
+  }),
   selected: PropTypes.bool,
   onChange: PropTypes.func,
-  title: PropTypes.string,
   variant: PropTypes.oneOf(['light', 'dark', 'ghost']),
+  render: PropTypes.func,
 };
 
 DropdownOption.defaultProps = {
-  value: '',
-  label: '',
-  disabled: false,
-  hidden: false,
   selected: false,
   onChange: () => {},
   title: '',
+  render: null,
 };
diff --git a/app/src/componentLibrary/dropdown/dropdownOption/dropdownOption.scss b/app/src/componentLibrary/dropdown/dropdownOption/dropdownOption.scss
index ebe8dcf9dd..f28ebb9fb2 100644
--- a/app/src/componentLibrary/dropdown/dropdownOption/dropdownOption.scss
+++ b/app/src/componentLibrary/dropdown/dropdownOption/dropdownOption.scss
@@ -85,5 +85,8 @@
   display: flex;
   align-items: center;
   height: 100%;
-  width: 100%;
+}
+
+.sub-option {
+  padding-left: 24px;
 }
diff --git a/app/src/pages/inside/dashboardItemPage/modals/common/widgetControls/utils/getWidgetCriteriaOptions.js b/app/src/pages/inside/dashboardItemPage/modals/common/widgetControls/utils/getWidgetCriteriaOptions.js
index aaf6419a7b..85321f029a 100644
--- a/app/src/pages/inside/dashboardItemPage/modals/common/widgetControls/utils/getWidgetCriteriaOptions.js
+++ b/app/src/pages/inside/dashboardItemPage/modals/common/widgetControls/utils/getWidgetCriteriaOptions.js
@@ -107,23 +107,23 @@ const messages = defineMessages({
 
   PRODUCT_BUG_TOTAL: {
     id: 'WidgetCriteriaOption.PRODUCT_BUG_TOTAL',
-    defaultMessage: 'Total product bugs',
+    defaultMessage: 'Product bugs group',
   },
   AUTOMATION_BUG_TOTAL: {
     id: 'WidgetCriteriaOption.AUTOMATION_BUG_TOTAL',
-    defaultMessage: 'Total automation bugs',
+    defaultMessage: 'Automation bugs group',
   },
   SYSTEM_ISSUE_TOTAL: {
     id: 'WidgetCriteriaOption.SYSTEM_ISSUE_TOTAL',
-    defaultMessage: 'Total system issues',
+    defaultMessage: 'System issues group',
   },
   TO_INVESTIGATE_TOTAL: {
     id: 'WidgetCriteriaOption.TO_INVESTIGATE_TOTAL',
-    defaultMessage: 'Total to investigate',
+    defaultMessage: 'To investigate group',
   },
   NO_DEFECT_TOTAL: {
     id: 'WidgetCriteriaOption.NO_DEFECT_TOTAL',
-    defaultMessage: 'Total no defects',
+    defaultMessage: 'No defects group',
   },
   Defect_Type_AB001: {
     id: 'WidgetCriteriaOption.Defect_Type_AB001',
@@ -275,37 +275,24 @@ export const getGroupedDefectTypesOptions = (
   let defectTypesOptions = [];
   defectTypesSequence.forEach((defectTypeId) => {
     const defectTypeGroup = defectTypes[defectTypeId];
-    const hasSubTypes = defectTypeGroup.length > 1;
-    if (hasSubTypes) {
-      defectTypesOptions.push({
-        label: formatMessage(messages[`${defectTypeGroup[0].typeRef}_TOTAL`]),
-        value: `${DEFECT_STATISTICS_BASE}${defectTypeGroup[0].typeRef.toLowerCase()}$total`,
-        groupId: defectTypeGroup[0].typeRef,
-      });
-      defectTypesOptions = defectTypesOptions.concat(
-        defectTypeGroup.map((defectType) => ({
-          groupRef: defectType.typeRef,
-          value: `${DEFECT_STATISTICS_BASE}${defectType.typeRef.toLowerCase()}$${
-            defectType.locator
-          }`,
-          label: messages[defectType.locator]
-            ? formatMessage(messages[`Defect_Type_${defectType.locator}`])
-            : defectType.longName,
-        })),
-      );
-    } else {
-      defectTypesOptions = defectTypesOptions.concat(
-        defectTypeGroup.map((defectType) => ({
-          value: `${DEFECT_STATISTICS_BASE}${defectType.typeRef.toLowerCase()}$${
-            defectType.locator
-          }`,
-          label: messages[defectType.locator]
-            ? formatMessage(messages[`Defect_Type_${defectType.locator}`])
-            : defectType.longName,
-        })),
-      );
-    }
+    defectTypesOptions.push({
+      label: formatMessage(messages[`${defectTypeGroup[0].typeRef}_TOTAL`]),
+      value: `${DEFECT_STATISTICS_BASE}${defectTypeGroup[0].typeRef.toLowerCase()}$total`,
+      groupId: defectTypeGroup[0].typeRef,
+      color: defectTypeGroup[0].color,
+    });
+    defectTypesOptions = defectTypesOptions.concat(
+      defectTypeGroup.map((defectType) => ({
+        groupRef: defectType.typeRef,
+        value: `${DEFECT_STATISTICS_BASE}${defectType.typeRef.toLowerCase()}$${defectType.locator}`,
+        label: messages[defectType.locator]
+          ? formatMessage(messages[`Defect_Type_${defectType.locator}`])
+          : defectType.longName,
+        color: defectType.color,
+      })),
+    );
   });
+
   return defectTypesOptions;
 };
 
diff --git a/app/src/pages/inside/projectSettingsPageContainer/projectSettingsPageContainer.jsx b/app/src/pages/inside/projectSettingsPageContainer/projectSettingsPageContainer.jsx
index 470773e138..e8fa6b98b4 100644
--- a/app/src/pages/inside/projectSettingsPageContainer/projectSettingsPageContainer.jsx
+++ b/app/src/pages/inside/projectSettingsPageContainer/projectSettingsPageContainer.jsx
@@ -179,7 +179,7 @@ export const ProjectSettingsPageContainer = () => {
 
   return (
     <SettingsLayout navigation={navigation}>
-      <ScrollWrapper>
+      <ScrollWrapper resetRequired>
         {!subPage && (
           <div className={cx('header')}>
             <Header