From 9904c8f01977c11fe3511c05c94f0c941c1856f3 Mon Sep 17 00:00:00 2001 From: Bam6ycha <84175555+Bam6ycha@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:39:18 +0500 Subject: [PATCH 1/9] EPMRPP-85840 || Add events for plugins (#3632) * EPMRPP-85840 || Add events for plugins * EPMRPP-85840 || Code review fixes - 1 * EPMRPP-85840 || Code review fixes - 2 --- .../addIntegrationModal.jsx | 17 ++++++---- .../analytics/events/pluginsPageEvents.js | 34 +++++++++++++------ .../actionPanel/actionPanel.jsx | 2 +- .../common/modals/importModal/importModal.jsx | 12 ++++++- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/app/src/components/integrations/modals/addIntegrationModal/addIntegrationModal.jsx b/app/src/components/integrations/modals/addIntegrationModal/addIntegrationModal.jsx index fdcda9a604..9aeec7bfad 100644 --- a/app/src/components/integrations/modals/addIntegrationModal/addIntegrationModal.jsx +++ b/app/src/components/integrations/modals/addIntegrationModal/addIntegrationModal.jsx @@ -29,6 +29,8 @@ import { INTEGRATIONS_FORM_FIELDS_COMPONENTS_MAP } from 'components/integrations import { uiExtensionIntegrationFormFieldsSelector } from 'controllers/plugins'; import { ExtensionLoader } from 'components/extensionLoader'; import { INTEGRATION_FORM } from 'components/integrations/elements'; +import { useTracking } from 'react-tracking'; +import { PLUGINS_PAGE_EVENTS } from 'components/main/analytics/events'; import styles from './addIntegrationModal.scss'; const cx = classNames.bind(styles); @@ -62,13 +64,22 @@ const AddIntegrationModal = ({ data, initialize, change, handleSubmit }) => { const fieldsExtensions = useSelector(uiExtensionIntegrationFormFieldsSelector); const dispatch = useDispatch(); const { formatMessage } = useIntl(); + const { trackEvent } = useTracking(); const { onConfirm, customProps, isGlobal } = data; + const integrationFieldsExtension = fieldsExtensions.find( + (ext) => ext.pluginName === data.instanceType, + ); + const updateMetaData = (newMetaData) => { setMetaData({ ...metaData, ...newMetaData }); }; const onSubmit = (newData) => { + if (isGlobal && !customProps.editAuthMode) { + trackEvent(PLUGINS_PAGE_EVENTS.clickCreateGlobalIntegration(data.instanceType)); + } + onConfirm(newData, metaData); }; @@ -84,9 +95,6 @@ const AddIntegrationModal = ({ data, initialize, change, handleSubmit }) => { const createTitle = isGlobal ? messages.createGlobalTitle : messages.createProjectTitle; - const integrationFieldsExtension = fieldsExtensions.find( - (ext) => ext.pluginName === data.instanceType, - ); const FieldsComponent = INTEGRATIONS_FORM_FIELDS_COMPONENTS_MAP[data.instanceType] || (integrationFieldsExtension && ExtensionLoader); @@ -126,9 +134,6 @@ AddIntegrationModal.propTypes = { change: PropTypes.func.isRequired, handleSubmit: PropTypes.func.isRequired, }; -AddIntegrationModal.defaultProps = { - data: {}, -}; export default withModal('addIntegrationModal')( reduxForm({ form: INTEGRATION_FORM })(AddIntegrationModal), diff --git a/app/src/components/main/analytics/events/pluginsPageEvents.js b/app/src/components/main/analytics/events/pluginsPageEvents.js index 5b38d22795..4b561b1289 100644 --- a/app/src/components/main/analytics/events/pluginsPageEvents.js +++ b/app/src/components/main/analytics/events/pluginsPageEvents.js @@ -17,7 +17,6 @@ import { getClickDeleteBtnRemoveIntegrationEvent, getClickSaveBtnEditAuthorizationEvent, - getIntegrationAddClickEvent, getPluginChoosePropertiesCheckboxClickEvent, getPluginConfigureClickEvent, getPluginConfigureClickSubmitEvent, @@ -26,6 +25,7 @@ import { getPluginRemoveIntegrationClickEvent, getSaveIntegrationModalEvents, } from 'components/main/analytics/events/common/pluginsPage/actionEventCreators'; +import { getBasicClickEventParameters, normalizeEventParameter } from './common/ga4Utils'; export const PLUGINS_PAGE = 'plugins'; @@ -51,18 +51,33 @@ export const getUninstallPluginBtnClickEvent = (pluginName) => ({ }); const PLUGINS_MODAL = 'Modal plugins'; +const BASIC_PLUGINS_EVENT_PARAMS = getBasicClickEventParameters(PLUGINS_PAGE); export const PLUGINS_PAGE_EVENTS = { + // GA 4 CLICK_UPLOAD_BTN: { - category: PLUGINS_MODAL, - action: 'Click on Btn Upload', - label: 'Arise Modal Upload Plugin', - }, - OK_BTN_UPLOAD_MODAL: { - category: PLUGINS_MODAL, - action: 'Click on Btn Ok on Modal "Upload plugins"', - label: 'Upload Plugins', + ...BASIC_PLUGINS_EVENT_PARAMS, + element_name: 'upload', + place: 'navigation_panel', }, + clickUploadModalBtn: (type) => ({ + ...BASIC_PLUGINS_EVENT_PARAMS, + element_name: 'upload', + modal: 'upload_plugin', + type, + }), + clickCreateGlobalIntegration: (type) => ({ + ...BASIC_PLUGINS_EVENT_PARAMS, + element_name: 'button_create', + modal: 'create_global_integration', + type: normalizeEventParameter(type), + }), + integrationAddClickEvent: (type) => ({ + ...BASIC_PLUGINS_EVENT_PARAMS, + element_name: 'add_integration', + type: normalizeEventParameter(type), + }), + // GA 3 CANCEL_BTN_UPLOAD_MODAL: { category: PLUGINS_MODAL, action: 'Click on Btn Cancel on Modal "Upload plugins"', @@ -107,6 +122,5 @@ export const PLUGINS_PAGE_EVENTS = { pluginConfigureClick: getPluginConfigureClickEvent(PLUGINS_PAGE), pluginChoosePropertiesCheckboxClick: getPluginChoosePropertiesCheckboxClickEvent(PLUGINS_PAGE), pluginConfigureClickSubmit: getPluginConfigureClickSubmitEvent(PLUGINS_PAGE), - integrationAddClickEvent: getIntegrationAddClickEvent(PLUGINS_PAGE), saveIntegrationModalEvents: getSaveIntegrationModalEvents(PLUGINS_PAGE), }; diff --git a/app/src/pages/admin/pluginsPage/pluginsToolbar/actionPanel/actionPanel.jsx b/app/src/pages/admin/pluginsPage/pluginsToolbar/actionPanel/actionPanel.jsx index 563c641772..c6b343ad77 100644 --- a/app/src/pages/admin/pluginsPage/pluginsToolbar/actionPanel/actionPanel.jsx +++ b/app/src/pages/admin/pluginsPage/pluginsToolbar/actionPanel/actionPanel.jsx @@ -110,7 +110,7 @@ export class ActionPanel extends Component { url: URLS.plugin(), singleImport: true, eventsInfo: { - okBtn: PLUGINS_PAGE_EVENTS.OK_BTN_UPLOAD_MODAL, + uploadButton: PLUGINS_PAGE_EVENTS.clickUploadModalBtn, cancelBtn: PLUGINS_PAGE_EVENTS.CANCEL_BTN_UPLOAD_MODAL, closeIcon: PLUGINS_PAGE_EVENTS.CLOSE_ICON_UPLOAD_MODAL, }, diff --git a/app/src/pages/common/modals/importModal/importModal.jsx b/app/src/pages/common/modals/importModal/importModal.jsx index f17debb329..a775a34f78 100644 --- a/app/src/pages/common/modals/importModal/importModal.jsx +++ b/app/src/pages/common/modals/importModal/importModal.jsx @@ -66,7 +66,7 @@ export class ImportModal extends Component { }; static defaultProps = { - data: {}, + data: { eventsInfo: { uploadButton: () => {}, cancelBtn: {}, closeIcon: {} } }, }; state = { @@ -168,6 +168,8 @@ export class ImportModal extends Component { }; }; + getFilesNames = (files) => files.map(({ file: { name } }) => name).join('#'); + formValidationMessage = (validationProperties) => { const { intl, @@ -222,6 +224,14 @@ export class ImportModal extends Component { successUploadHandler = (id) => { this.props.data.onImport(); const { files } = this.state; + const { + tracking: { trackEvent }, + data: { eventsInfo: { uploadButton } = {} }, + } = this.props; + + if (uploadButton) { + trackEvent(uploadButton(this.getFilesNames(files))); + } this.setState({ files: files.map((item) => { From 1ef736d152ba5039aaaa15e26c1aa184ce874039 Mon Sep 17 00:00:00 2001 From: Vadim73i <55870906+Vadim73i@users.noreply.github.com> Date: Mon, 6 Nov 2023 18:39:38 +0400 Subject: [PATCH 2/9] EPMRPP-83572 || Update the view of Notification rule with attributes (#3636) * EPMRPP-83572 || Update the view of Notification rule with attributes * EPMRPP-83572 || code review fixes - 1 * EPMRPP-83572 || code review fixes - 2 * EPMRPP-83572 || code review fixes - 3 * EPMRPP-83572 || code review fixes - 4 --- app/localization/translated/be.json | 65 +++++++--------- app/localization/translated/ru.json | 62 +++++++-------- app/localization/translated/uk.json | 76 +++++++------------ app/localization/translated/zh.json | 48 +++++++----- .../attributeListFormField.jsx | 13 +--- .../notificationRuleContent.jsx | 47 +++++++++--- .../notificationRuleContent.scss | 4 + .../content/notifications/messages.js | 4 - .../addEditNotificationModal.jsx | 9 ++- 9 files changed, 157 insertions(+), 171 deletions(-) diff --git a/app/localization/translated/be.json b/app/localization/translated/be.json index 1ec324ab52..683483b29d 100644 --- a/app/localization/translated/be.json +++ b/app/localization/translated/be.json @@ -57,8 +57,10 @@ "AddEditNotificationCaseModal.active": "Актыўнае правіла", "AddEditNotificationCaseModal.addAttribute": "Дадаць атрыбут", "AddEditNotificationCaseModal.attributesLabel": "Атрыбуты", + "AddEditNotificationCaseModal.attributesLabelAll": "(Усе атрыбуты павінны супадаць)", + "AddEditNotificationCaseModal.attributesLabelAny": "(Любы атрыбут павінен адпавядаць)", "AddEditNotificationCaseModal.attributesNotActive": "Атрыбуты не актыўныя. Каб актываваць, усталюйце сцяжок `Атрыбуты`", - "AddEditNotificationCaseModal.attributesNote": "Адпраўляць апавяшчэнні аб запуску, якія змяшчаюць зададзеныя атрыбуты", + "AddEditNotificationCaseModal.attributesNote": "Адпраўляць апавяшчэнні, калі запуск мае ўсе/хоць бы адзін з указаных атрыбутаў", "AddEditNotificationCaseModal.attributesOperatorAnd": "Усе атрыбуты павінны супадаць", "AddEditNotificationCaseModal.attributesOperatorOr": "Любы атрыбут павінен супадаць", "AddEditNotificationCaseModal.controlPanelName": "Правіла", @@ -190,7 +192,6 @@ "AttributesContainer.addAttribute": "Дадаць атрыбут", "AttributesContainer.attributes": "Атрыбуты", "AttributesContainer.attributesNotActive": "Атрыбуты не актыўныя. Для актывацыі ўсталюеце сцяжок ‘Атрыбуты’", - "AttributesContainer.attributesNote": "Адпраўляць апавяшчэнні аб запусках, якія змяшчаюць названыя атрыбуты", "AttributesFieldArrayControl.addOneMoreLevel": "Дадаць яшчэ адзін узровень", "AttributesFieldArrayControl.attributeKeyFieldLabel": "ўзровень {number} {view}", "AttributesFieldArrayControl.attributeKeyFieldPlaceholder": "Калі ласка, увядзіце ключ аттрибута", @@ -199,12 +200,17 @@ "AutoAnalysis.AutoAnalysisMode": "Аўта-Аналіз на аснове", "AutoAnalysis.AutoAnalysisModeDescription": "Вы можаце выбраць тып аналізу тэставага элемента на аснове раней даследаваных даных пры запуску з такім жа назвай або для ўсіх запускаў", "AutoAnalysis.allLaunchesCaption": "Усе запускі", + "AutoAnalysis.allMessagesShouldMatch": "Усе логі з 3 ці больш радкамі павінны супадаць", + "AutoAnalysis.allMessagesShouldMatchDescription": "Калі аналізаваны элемент тэсту змяшчае логі з 3 ці больш радкамі", "AutoAnalysis.autoAnalysis": "Аўта-Аналіз", "AutoAnalysis.autoAnalysisDescription": "Актыўны аўта-аналіз пачнецца адразу пасля завяршэння любога запуску", "AutoAnalysis.current": "Толькі бягучы запуск", "AutoAnalysis.currentAndWithSameName": "Бягучы запуск і запускі з такой жа назвай", "AutoAnalysis.minShouldMatch": "Мінімум павінен супадаць для аўта-аналізу", "AutoAnalysis.minShouldMatchDescription": "Працэнт супадзення слоў паміж аналізаваным логам і канкрэтным логам з ElasticSearch. Калі ў логу з ElasticSearch значэнне менш за ўсталяванае, гэты часопіс будзе ігнаравацца для AA", + "AutoAnalysis.numberOfLogLines": "Колькасць радкоў лога, якія варта ўлічваць у Elasticsearch", + "AutoAnalysis.numberOfLogLinesAllOption": "Усе", + "AutoAnalysis.numberOfLogLinesDescription": "Колькасць першых радкоў лога, якое варта ўлічваць у ElasticSearch", "AutoAnalysis.previousLaunch": "Папярэдні запуск з такой жа назвай", "AutoAnalysis.sameNameLaunchesCaption": "Запускі з аднолькавымі імёнамі", "AutoAnalysis.tabDescription": "Аўта-Аналіз дазваляе скараціць час, затрачаны на даследаванне выканання тэсту, аналізуючы няўдачы тэсту ў аўтаматычным рэжыме. Працэс аўтаматычнага аналізу заснаваны на папярэдніх выніках даследавання карыстальнікаў з дапамогай машыннага навучання. Налады прымяняюцца, калі аўтаматычны аналіз запускаецца падчас падзеі завяршэння запуску, а таксама падчас падзеі завяршэння тэставага элемента. Больш падрабязную інфармацыю пра аўтаматычны аналіз можна прачытаць у Дакументацыі", @@ -248,6 +254,7 @@ "ChangeProjectRoleModal.changeAccountRoleText": "Вы ўпэўнены, што хочаце змяніць праектную ролю для ''{name}''?", "ChangeProjectRoleModal.changeAccountRoleTitle": "змянiць ролю", "ChangeProjectRoleModal.submitText": "Змяніць", + "ChangeRole": "роля была зменена на праекце", "Chart.label.automationBug": "Праблемы аўтаматызацыі", "Chart.label.investigated": "Прааналізаваныя", "Chart.label.launchesQuantity": "Запускі", @@ -271,7 +278,6 @@ "Charts.skipped": "Прапушчана", "Charts.testCasesCaption": "Тэставыя выпадкі", "Charts.total": "Усяго {type}", - "ChangeRole": "роля была зменена на праекце", "ClusterItemsGridRow.loadLabel": "Загрузіць яшчэ", "ColorPicker.pickSwatch": "Выберыце ўзор", "ColorPicker.selectColor": "Выберыце свой колер", @@ -291,8 +297,6 @@ "Common.closeModalWarning": "Вы павінны захаваць змены або адмяніць іх перад закрыццём вокны", "Common.compare": "Параўнаць", "Common.confirm": "Пацвердзіць", - "Common.create": "Стварыць", - "Common.december": "Снежань", "Common.copyToClipboard": "Скапіраваць у буфер абмену", "Common.create": "Стварыць", "Common.december": "Снежань", @@ -310,7 +314,6 @@ "Common.forceFinish": "Скончыць прымусова", "Common.friday": "Пятніца", "Common.generate": "Генераваць", - "Common.friday": "Пятніца", "Common.invite": "Запрасіць", "Common.january": "Студзень", "Common.july": "Ліпень", @@ -427,6 +430,7 @@ "ConnectionSection.connectionFailedDescription": "Не ўдалося падключыцца да {pluginName}", "ConnectionSection.connectionFailedHeader": "Памылка злучэння", "ConnectionSection.connectionFailedMessage": "Падключэнне не ўдалося", + "ConnectionSection.deleteIntegrationDescription": "Вы ўпэўненыя, што жадаеце выдаліць Інтэграцыю", "ConnectionSection.removeIntegrationSuccess": "Інтэграцыя паспяхова выдалена", "ConnectionSection.warningMessage": "Папярэджанне", "ConnectionSection.warningMessageDescription": "Глабальныя інтэграцыі неактыўныя, паколькі вы наладзілі інтэграцыю праекту.", @@ -562,18 +566,18 @@ "DeleteAccountBlock.deleteAccount": "Выдаліць уліковы запіс", "DeleteAccountBlock.tooltipText": "Выдаліць свой уліковы запіс могуць толькі карыстальнікі, якія не з'яўляюцца адміністратарамі.\nАкрамя таго, гэта можа зрабіць іншы адміністратар.", "DeleteAccountFeedbackModal.alternative": "Знайшоў лепшую альтэрнатыву", - "DeleteAccountFeedbackModal.dissatisfied": "Незадаволены абслугоўваннем", - "DeleteAccountFeedbackModal.noNeeded": "Уліковы запіс больш не патрэбны", - "DeleteAccountFeedbackModal.other": "Іншае", "DeleteAccountFeedbackModal.continue": "Працягнуць", + "DeleteAccountFeedbackModal.deleteAccountReasonSizeHint": "Памер поля павінен быць не больш за 128 сімвалаў.", "DeleteAccountFeedbackModal.description": "Чаму вы выдаляеце свой уліковы запіс?", + "DeleteAccountFeedbackModal.dissatisfied": "Незадаволены абслугоўваннем", "DeleteAccountFeedbackModal.header": "Выдаліць уліковы запіс", - "DeleteAccountFeedbackModal.deleteAccountReasonSizeHint": "Памер поля павінен быць не больш за 128 сімвалаў.", + "DeleteAccountFeedbackModal.noNeeded": "Уліковы запіс больш не патрэбны", + "DeleteAccountFeedbackModal.other": "Іншае", "DeleteAccountModal.deleteAccountNote": "Працэс беспаваротны. Націснуўшы на \"Выдаліць\" кнопку вы згаджаецеся выдаліць усе вашу асабістую інфармацыю, уключаючы імя ўліковага запісу, адрас электроннай пошты і фота з нашай базы дадзеных.", + "DeleteAccountModal.deletePersonalDataNote": "Усе даныя, якія вы стварылі або паведамілі ў ReportPortal, застануцца ў праграме, але больш не будуць даступныя для вас. Сюды ўваходзяць любыя запускі, фільтры, віджэты, панэлі кіравання і г.д.", "DeleteAccountModal.header": "Выдаліць уліковы запіс", "DeleteAccountModal.label": "Увядзіце \"DELETE\" для пацверджання", "DeleteAccountModal.question": "Вы ўпэўнены, што хочаце выдаліць свой уліковы запіс?", - "DeleteAccountModal.deletePersonalDataNote": "Усе даныя, якія вы стварылі або паведамілі ў ReportPortal, застануцца ў праграме, але больш не будуць даступныя для вас. Сюды ўваходзяць любыя запускі, фільтры, віджэты, панэлі кіравання і г.д.", "DeleteDefectTypeModal.message": "Вы ўпэўнены, што хочаце выдаліць {name}?", "DeleteDefectTypeModal.title": "Выдаліць {name}", "DeleteFilterDialog.deleteFilter": "Вы ўпэўнены, што хочаце выдаліць фільтр '{name}'? Ён больш не будзе існаваць.", @@ -685,14 +689,15 @@ "ErrorLogsBlock.showErrorLog": "Паказаць", "EventActions.analyzeItem": "Змена дэфекту автоанализом", "EventActions.assignUser": "Прызначыць карыстальніка", + "EventActions.changeRole": "Змяніць ролю", "EventActions.createDashboard": "Стварэнне панэлі кіравання", "EventActions.createDefect": "Стварэнне карыстацкага дэфекту", "EventActions.createFilter": "Стварэнне фiльтра", "EventActions.createIntegration": "Стварэнне інтэграцыі", + "EventActions.createInvitationLink": "Стварыць спасылку для запрашэння", "EventActions.createPattern": "Стварэнне шаблону", "EventActions.createProject": "Стварыць праект", "EventActions.createWidget": "Стварэнне відждэта", - "EventActions.createInvitationLink": "Стварыць спасылку для запрашэння", "EventActions.deleteDashboard": "Выдаленне панэлі кіравання", "EventActions.deleteDefect": "Выдаленне дэфекта", "EventActions.deleteFilter": "Выдаленне фiильтра", @@ -701,27 +706,26 @@ "EventActions.deleteLaunch": "Выдаленне запуску", "EventActions.deletePattern": "Выдаленне шаблону", "EventActions.deleteWidget": "Выдаленне віджэта", - "EventActions.import": "Імпарт", - "EventActions.startImport": "Пачаць імпарт", "EventActions.finishImport": "Скончыць імпарт", "EventActions.finishLaunch": "Канчатак запуску", "EventActions.generateIndex": "Генерацыя індэкса", + "EventActions.import": "Імпарт", "EventActions.linkIssue": "Прывязка праблемы", "EventActions.linkIssueAA": "Прывязка праблемы автоанализом", "EventActions.matchedPattern": "Патэрн-аналіз выявіў адпаведнасць", "EventActions.postIssue": "Cтварэнне праблемы", + "EventActions.startImport": "Пачаць імпарт", "EventActions.startLaunch": "Старт запуску", "EventActions.unassignUser": "Адмяніць прызначэнне карыстальніка", - "EventActions.changeRole": "Змяніць ролю", "EventActions.unlinkIssue": "Адвязка праблемы", "EventActions.updateAnalyzer": "Абнаўленне автоанализа", + "EventActions.updateAutoPatternAnalysisSettings": "Абнавіць налады Pattern-Analysis", "EventActions.updateDashboard": "Абнаўленне панэлі кіравання", "EventActions.updateDefect": "Абнаўленне дэфекта", "EventActions.updateFilter": "Абнаўленне фiльтра", "EventActions.updateIntegration": "Абнаўленне інтэграцыі", "EventActions.updateItem": "Абнавіць элемент", "EventActions.updatePattern": "Абнаўленне шаблону", - "EventActions.updateAutoPatternAnalysisSettings": "Абнавіць налады Pattern-Analysis", "EventActions.updateProject": "Абнаўленне праекта", "EventActions.updateWidget": "Абнаўленне відждэт", "EventObjectTypes.dashboard": "Панэль кіравання", @@ -732,10 +736,10 @@ "EventObjectTypes.index": "Iндэкс", "EventObjectTypes.integration": "Iнтэграцыя", "EventObjectTypes.invitationLink": "Спасылка на запрашэнне", + "EventObjectTypes.itemIssue": "Тэст элемент", "EventObjectTypes.launch": "Запуск", "EventObjectTypes.patternRule": "Шаблон", "EventObjectTypes.project": "Праект", - "EventObjectTypes.itemIssue": "Тэст элемент", "EventObjectTypes.user": "Kарыстальнік", "EventObjectTypes.widget": "Вiджэт", "EventsGrid.actionCol": "Дзеянне", @@ -975,14 +979,9 @@ "IndexActionsBlock.removeIndexButtonCaption": "Выдаліць Iндэкс", "IndexActionsBlock.removeIndexDescription": "Уся інфармацыя будзе выдалена з ElasticSearch. Для генерацыі дадзеных зноў Вы можаце пачаць аналізаваць тэставыя вынікі ўручную, або згенераваць дадзеныя аўтаматычна", "IndexActionsBlock.title": "Деянні з індексам", - "AutoAnalysis.allMessagesShouldMatch": "Усе логі з 3 ці больш радкамі павінны супадаць", - "AutoAnalysis.allMessagesShouldMatchDescription": "Калі аналізаваны элемент тэсту змяшчае логі з 3 ці больш радкамі", "IndexSettings.generateIndexButtonCaption": "Згеніраваць індэкс", "IndexSettings.generateIndexDescription": "усе дадзеныя выдаляюцца з ElasticSearch, а новыя генеруюцца на аснове ўсіх папярэдніх расследаванняў праекта. Вы можаце пачаць выкарыстоўваць аўтааналіз пасля атрымання паведамлення па электроннай пошце аб заканчэнні працэсу генерацыі.", "IndexSettings.inCaseOf": "У выпадку", - "AutoAnalysis.numberOfLogLines": "Колькасць радкоў лога, якія варта ўлічваць у Elasticsearch", - "AutoAnalysis.numberOfLogLinesAllOption": "Усе", - "AutoAnalysis.numberOfLogLinesDescription": "Колькасць першых радкоў лога, якое варта ўлічваць у ElasticSearch", "IndexSettings.regenerateIndexDescription": "Вамі быў зменены параметр 'Колькасць радкоў лога'. Гэта дзеянне можа паўплываць на вынікі аўта-аналізу. Для карэктнай працы аналізатар, калі ласка, перагенеруйце індэкс у ElasticSearch. Ці жадаеце Вы перагеніраваць індэкс зараз?", "IndexSettings.regenerateIndexProgress": "Калі ласка, пачакайце, мы геніруем новы індэкс", "IndexSettings.regenerateIndexTitle": "Рэгенераваць індэкс", @@ -1044,6 +1043,7 @@ "IntegrationsCase.noIntegrationsDescription": "У вашым праекце яшчэ няма інтэграцый", "IntegrationsCase.noIntegrationsMessage": "Ніякіх інтэграцый", "IntegrationsDescription.ConnectionErrorMessage": "Памылка злучэння", + "IntegrationsDescription.GlobalIntegrationsSystemMessage": "Папярэджанне", "IntegrationsDescription.GlobalIntegrationsSystemMessageModalCaption": "Глабальная і праектная інтэграцыі не могуць працаваць адначасова.", "IntegrationsDescription.GlobalIntegrationsSystemMessageModalText": "Звярніце ўвагу, што глабальныя інтэграцыі будуць адключаныя, калі вы створыце інтэграцыю праекту!", "IntegrationsDescription.GlobalIntegrationsSystemMessageText": "Глабальныя інтэграцыі неактыўныя, паколькі вы наладзілі інтэграцыю праекту.", @@ -1055,8 +1055,6 @@ "IntegrationsDescription.noGlobalIntegrationsButtonAdd": "Дадаць інтэграцыю праекта", "IntegrationsDescription.noGlobalIntegrationsDescription": "Інтэграцыі не настроены. Вы можаце ўручную наладзіць інтэграцыю для гэтага праекту.", "IntegrationsDescription.noGlobalIntegrationsMessage": "Ніякіх Iнтэграцый", - "IntegrationsDescription.projectIntegrationCreate": "Стварыць інтэграцыю праекта", - "ConnectionSection.deleteIntegrationDescription": "Вы ўпэўненыя, што жадаеце выдаліць Інтэграцыю", "IntegrationsDescription.projectIntegrationReset": "Скід да глабальных інтэграцый", "IntegrationsDescription.projectIntegrationResetDescription": "Вы ўпэўненыя, што хочаце скінуць наладкі да Глабальных Інтэграцый? Усе вашыя прэктныя інтэграцыі будуць выдаленыя без магчымасці аднаўлення.", "IntegrationsDescription.projectIntegrationText": "Інтэграцыі праекта ствараюцца для кожнага праекта", @@ -1278,11 +1276,6 @@ "LoginForm.loginPlaceholder": "Лагін", "LoginForm.or": "альбо", "LoginForm.passwordPlaceholder": "Пароль", - "AccountRemovedPage.description": "Ваш уліковы запіс і асабістыя даныя былі выдалены з базы дадзеных ReportPortal.\nНам шкада, што вы сыходзіце. Апавяшчэнне па электроннай пошце было адпраўлена на адрас электроннай пошты, звязаны з вашым уліковым запісам.", - "AccountRemovedPage.header": "уліковы запіс быў выдалены", - "AccountRemovedPage.login": "Увайсці", - "AccountRemovedPage.message": "Дзякуй за выкарыстанне ReportPortal", - "AccountRemovedPage.signup": "Зарэгістравацца", "LogsGrid.noResults": "Вынікаў не знойдзена", "LogsGrid.statusColumnTitle": "Статус", "LogsGrid.timeColumnTitle": "Час", @@ -1491,7 +1484,6 @@ "NotPassedTestCasesTrendControls.ItemsValidationError": "Колькасць элементаў павінна мець памер ад '1' да '600'", "NotificationCase.attributesLabel": "Атрыбуты", "NotificationCase.attributesLabelWithOperator": "Атрыбуты ({attributesOperator})", - "NotificationCase.attributesNote": "Send notifications about launches containing specified attributes", "NotificationCase.attributesOperatorAnd": "Усе атрыбуты", "NotificationCase.attributesOperatorNote": "Апавяшчаць, калі запуск мае ўсе/прынамсі адзін указаны атрыбут", "NotificationCase.attributesOperatorOr": "Любы атрыбут", @@ -2067,9 +2059,9 @@ "UpdateAnalysisSettings.numbersInErrorLog": "выдаліць лічбы ў часопісе памылак", "UpdateAnalysisSettings.uniqueError": "пераключэнне ўнікальных памылак", "UpdateAnalysisSettings.updated": "абнавіў", - "UpdateAutoPatternAnalysisSettings.updated": "абнавіў", "UpdateAutoPatternAnalysisSettings.description": "пераключыў значэнне з {oldValue} на {newValue}.", "UpdateAutoPatternAnalysisSettings.linkText": "параметры Аналізу-Шаблонаў:", + "UpdateAutoPatternAnalysisSettings.updated": "абнавіў", "UserBlock.adminBadge": "Адміністратар", "UserBlock.administrate": "Адміністраваць", "UserBlock.logout": "Выйсці", @@ -2083,11 +2075,6 @@ "ViewTabs.uniqueErrorsView": "Унікальныя памылкі", "Widget.forceUpdateWidgetMessage": "Вы ўпэўненыя, што хочаце абнавіць дадзеныя ў гэтым віджэце? Гэта можа заняць да 15 хвілін у залежнасці ад памеру базы дадзеных праекта.", "Widget.forceUpdateWidgetTitle": "Абнавіць дадзеныя віджэту", - "WidgetCriteriaOption.AUTOMATION_BUG": "Automation Bug", - "WidgetCriteriaOption.AUTOMATION_BUG_TOTAL": "Усяго Automation Bug", - "WidgetCriteriaOption.assign_user": "Прызначыць, запрасіць карыстальніка", - "WidgetCriteriaOption.create_project": "Стварыць праект", - "WidgetCriteriaOption.change_role": "Змяніць ролю", "WidgetCriteriaOption.CriteriaFailed": "Непройдзеныя тэсты", "WidgetCriteriaOption.CriteriaPassed": "Пройдзеныя тэсты", "WidgetCriteriaOption.CriteriaSkipped": "Прапушчаныя тэсты", @@ -2095,7 +2082,9 @@ "WidgetCriteriaOption.aa_settings_actions": "Абнавіць Аўта-Аналіз", "WidgetCriteriaOption.assign_user": "Прызначыць, запрасіць карыстальніка", "WidgetCriteriaOption.attributes": "Атрыбуты", + "WidgetCriteriaOption.change_role": "Змяніць ролю", "WidgetCriteriaOption.create_pattern": "Стварыць патэрн", + "WidgetCriteriaOption.create_project": "Стварыць праект", "WidgetCriteriaOption.dashboards_actions": "Абнавіць Панэль кіравання", "WidgetCriteriaOption.defects_actions": "Абнавіць тыпы дэфектаў", "WidgetCriteriaOption.delete_launch": "Выдаліць запуск", @@ -2111,9 +2100,9 @@ "WidgetCriteriaOption.startTime": "Старт", "WidgetCriteriaOption.start_launch": "Пачаць запуск", "WidgetCriteriaOption.unassign_user": "Адмяніць прызначэнне карыстальніка", + "WidgetCriteriaOption.updateAutoPatternAnalysisSettings": "Абнавіць налады Pattern-Analysis", "WidgetCriteriaOption.update_pattern": "Абнавіць патэрн", "WidgetCriteriaOption.update_project": "Абнавіць налады праекта", - "WidgetCriteriaOption.updateAutoPatternAnalysisSettings": "Абнавіць налады Pattern-Analysis", "WidgetCriteriaOption.user": "Карыстальнік", "WidgetCriteriaOption.widgets_actions": "Абнавiць вiджэт", "WidgetHeader.forceUpdate": "Абнавіць", @@ -2182,6 +2171,7 @@ "WizardInfoSection.addWidgetButton": "Дадаць", "WizardInfoSection.nextStepButton": "Наступны крок", "WizardInfoSection.prevStepButton": "Папярэднi крок", + "administrateEventsPageToolbar.searchPlaceholder": "Пошук па карыстальніку, дзеянні, тыпу аб'екта, назве аб'екта", "administrateUsersPage.allUsers": "Усе карыстальнікі", "administrateUsersPage.deleteModalContent": "Вы ўпэўненыя, што хочаце выдаліць карыстальніка {name}?", "administrateUsersPage.deleteModalHeader": "Выдаленне карыстальніка", @@ -2193,7 +2183,6 @@ "administrateUsersPage.successMultiple": "Карыстальнікі выдаленыя", "administrateUsersPageToolbar.allUsers": "{count} карыстальнікаў выбрана", "administrateUsersPageToolbar.searchPlaceholder": "Шукаць па імені, лагіне, электронным адрасе", - "administrateEventsPageToolbar.searchPlaceholder": "Пошук па карыстальніку, дзеянні, тыпу аб'екта, назве аб'екта", "dashboardControl.dashboardName": "Мая першая панэль кіравання", "dashboardControl.title": "Захаваць віджэт на панэлі кіравання", "entityInputConditional.defaultPlaceholder": "Увядзiце iмя", diff --git a/app/localization/translated/ru.json b/app/localization/translated/ru.json index 2c8005b5f9..ea44a48d1a 100644 --- a/app/localization/translated/ru.json +++ b/app/localization/translated/ru.json @@ -57,8 +57,10 @@ "AddEditNotificationCaseModal.active": "Активное правило", "AddEditNotificationCaseModal.addAttribute": "Добавить атрибут", "AddEditNotificationCaseModal.attributesLabel": "Атрибуты", + "AddEditNotificationCaseModal.attributesLabelAll": "(Все атрибуты должны совпадать)", + "AddEditNotificationCaseModal.attributesLabelAny": "(Любой атрибут должен совпасть)", "AddEditNotificationCaseModal.attributesNotActive": "Атрибуты не активны. Чтобы активировать, установите флажок `Атрибуты`", - "AddEditNotificationCaseModal.attributesNote": "Отправлять уведомления о запусках, содержащих указанные атрибуты", + "AddEditNotificationCaseModal.attributesNote": "Уведомлять, если запуск имеет все/хотя бы один из указанных атрибутов", "AddEditNotificationCaseModal.attributesOperatorAnd": "Все атрибуты должны совпадать", "AddEditNotificationCaseModal.attributesOperatorOr": "Любой атрибут должен совпадать", "AddEditNotificationCaseModal.controlPanelName": "Правило", @@ -190,7 +192,6 @@ "AttributesContainer.addAttribute": "Добавить атрибут", "AttributesContainer.attributes": "Атрибуты", "AttributesContainer.attributesNotActive": "Атрибуты не активны. Для активации установите флажок ‘Атрибуты‘", - "AttributesContainer.attributesNote": "Отправлять уведомления о запусках, содержащих указанные атрибуты", "AttributesFieldArrayControl.addOneMoreLevel": "Добавить еще один уровень", "AttributesFieldArrayControl.attributeKeyFieldLabel": "Уровень {number} {view}", "AttributesFieldArrayControl.attributeKeyFieldPlaceholder": "Введить ключ аттрибута", @@ -199,12 +200,17 @@ "AutoAnalysis.AutoAnalysisMode": "Авто-Анализ на основе", "AutoAnalysis.AutoAnalysisModeDescription": "Вы можете выбрать тип анализа тестового элемента на основе ранее исследованных данных в запусках с таким же названием или во всех запусках", "AutoAnalysis.allLaunchesCaption": "Все запуски", + "AutoAnalysis.allMessagesShouldMatch": "Все логи с 3 или более строками должны совпадать", + "AutoAnalysis.allMessagesShouldMatchDescription": "Когда анализируемый элемент теста содержит логи с 3 или более строками", "AutoAnalysis.autoAnalysis": "Авто-Анализ", "AutoAnalysis.autoAnalysisDescription": "Активный авто-анализ начнется сразу после завершения любого запуска", "AutoAnalysis.current": "Только текущий запуск", "AutoAnalysis.currentAndWithSameName": "Предыдущий запуск с таким же названием", "AutoAnalysis.minShouldMatch": "Минимум должен совпадать для авто-анализа", "AutoAnalysis.minShouldMatchDescription": "Процент совпадения слов между анализируемым логом и конкретным логом из ElasticSearch. Если в логе из ElasticSearch значение меньше установленного, этот журнал будет игнорироваться для AA", + "AutoAnalysis.numberOfLogLines": "Количество строк лога, которые следует учитывать в Elasticsearch", + "AutoAnalysis.numberOfLogLinesAllOption": "Все", + "AutoAnalysis.numberOfLogLinesDescription": "Количество первых строк лога, которое следует учитывать в ElasticSearch", "AutoAnalysis.previousLaunch": "Текущий запуск и запуски с таким же названием", "AutoAnalysis.sameNameLaunchesCaption": "Запуски с одинаковыми именами", "AutoAnalysis.tabDescription": "Авто-анализ позволяет сократить время, затрачиваемое на исследование выполнения теста, за счет анализа отказов теста в автоматическом режиме. Процесс автоматического анализа основан на предыдущих результатах, полученных пользователем с помощью машинного обучения. Настройки применяются, когда автоматический анализ запускается при событии завершения запуска, а также при событии завершения элемента тестирования. Дополнительную информацию об авто-анализе вы можете прочитать в Документации", @@ -248,6 +254,7 @@ "ChangeProjectRoleModal.changeAccountRoleText": "Вы уверены, что хотите изменить проектную роль для ''{name}''?", "ChangeProjectRoleModal.changeAccountRoleTitle": "изменить роль", "ChangeProjectRoleModal.submitText": "Изменить", + "ChangeRole": "изменил на проекте роль", "Chart.label.automationBug": "Проблемы автоматизации", "Chart.label.investigated": "Проанализированные", "Chart.label.launchesQuantity": "Запуски", @@ -271,7 +278,6 @@ "Charts.skipped": "Пропущено", "Charts.testCasesCaption": "Тествовые случаи", "Charts.total": "Всего {type}", - "ChangeRole": "изменил на проекте роль", "ClusterItemsGridRow.loadLabel": "Загрузить еще", "ColorPicker.pickSwatch": "Выберите образец", "ColorPicker.selectColor": "Выберите свой цвет", @@ -424,6 +430,7 @@ "ConnectionSection.connectionFailedDescription": "Не удалось подключиться к {pluginName}", "ConnectionSection.connectionFailedHeader": "Ошибка соединения", "ConnectionSection.connectionFailedMessage": "Ошибка соединения", + "ConnectionSection.deleteIntegrationDescription": "Вы уверены, что хотите удалить Интеграцию", "ConnectionSection.removeIntegrationSuccess": "Интеграция успешно удалена", "ConnectionSection.warningMessage": "Предупреждение", "ConnectionSection.warningMessageDescription": "Глобальные интеграции неактивны, поскольку вы настроили интеграцию проекта.", @@ -559,18 +566,18 @@ "DeleteAccountBlock.deleteAccount": "Удалить аккаунт", "DeleteAccountBlock.tooltipText": "Только пользователи с ролью, отличной от администратора, могут удалить свою учетную запись.\nКроме того, это может сделать другой администратор.", "DeleteAccountFeedbackModal.alternative": "Нашел лучшую альтернативу", - "DeleteAccountFeedbackModal.dissatisfied": "Недовольны обслуживанием", - "DeleteAccountFeedbackModal.noNeeded": "Аккаунт больше не нужен", - "DeleteAccountFeedbackModal.other": "Другое", "DeleteAccountFeedbackModal.continue": "Продолжить", + "DeleteAccountFeedbackModal.deleteAccountReasonSizeHint": "Поле должно иметь размер не более 128 символов.", "DeleteAccountFeedbackModal.description": "Почему вы удаляете свой аккаунт?", + "DeleteAccountFeedbackModal.dissatisfied": "Недовольны обслуживанием", "DeleteAccountFeedbackModal.header": "Удалить аккаунт", - "DeleteAccountFeedbackModal.deleteAccountReasonSizeHint": "Поле должно иметь размер не более 128 символов.", + "DeleteAccountFeedbackModal.noNeeded": "Аккаунт больше не нужен", + "DeleteAccountFeedbackModal.other": "Другое", "DeleteAccountModal.deleteAccountNote": "Процесс необратим. Нажав на кнопку \"Удалить\"вы соглашаетесь удалить все ваша личная информация, включая имя вашей учетной записи, адрес электронной почты и фото из нашей базы данных.", + "DeleteAccountModal.deletePersonalDataNote": "Все данные, которые вы создали или передали в ReportPortal, останутся в приложении, но больше не будут вам доступны. Сюда входят любые запуски, фильтры, виджеты, панели управления и т.д.", "DeleteAccountModal.header": "Удалить аккаунт", "DeleteAccountModal.label": "Введите \"DELETE\" для подтверждения", "DeleteAccountModal.question": "Вы уверены, что хотите удалить свой аккаунт?", - "DeleteAccountModal.deletePersonalDataNote": "Все данные, которые вы создали или передали в ReportPortal, останутся в приложении, но больше не будут вам доступны. Сюда входят любые запуски, фильтры, виджеты, панели управления и т.д.", "DeleteDefectTypeModal.message": "Вы уверены, что хотите удалить {имя}?", "DeleteDefectTypeModal.title": "Удалить {имя}", "DeleteFilterDialog.deleteFilter": "Вы уверены, что хотите удалить фильтр '{name}'?", @@ -682,14 +689,15 @@ "ErrorLogsBlock.showErrorLog": "Показать", "EventActions.analyzeItem": "AA изменил тип дефекта", "EventActions.assignUser": "Назначить пользователя", + "EventActions.changeRole": "Изменить роль", "EventActions.createDashboard": "Создание панели управления", "EventActions.createDefect": "Создание пользовательского дефекта", "EventActions.createFilter": "Создание фильтра", "EventActions.createIntegration": "Создание интеграции", + "EventActions.createInvitationLink": "Создать ссылку для приглашения", "EventActions.createPattern": "Создание шаблона", "EventActions.createProject": "Создать проект", "EventActions.createWidget": "Создание виджета", - "EventActions.createInvitationLink": "Создать ссылку для приглашения", "EventActions.deleteDashboard": "Удаление панели управления", "EventActions.deleteDefect": "Удаление дефекта", "EventActions.deleteFilter": "Удаление фильтра", @@ -698,27 +706,26 @@ "EventActions.deleteLaunch": "Удаление запуска", "EventActions.deletePattern": "Удаление шаблона", "EventActions.deleteWidget": "Удаление виджета", - "EventActions.import": "Импорт", - "EventActions.startImport": "Начать импорт", "EventActions.finishImport": "Закончить импорт", "EventActions.finishLaunch": "Окончание запуска", "EventActions.generateIndex": "Генерация индекса", + "EventActions.import": "Импорт", "EventActions.linkIssue": "Привязка ошибки", "EventActions.linkIssueAA": "Привязка ошибки автоанализом", "EventActions.matchedPattern": "Паттерн-анализ обнаружил соответствие", "EventActions.postIssue": "Создание ошибки", + "EventActions.startImport": "Начать импорт", "EventActions.startLaunch": "Старт запуска", "EventActions.unassignUser": "Отменить назначение пользователя", - "EventActions.changeRole": "Изменить роль", "EventActions.unlinkIssue": "Открепление ошибки", "EventActions.updateAnalyzer": "Обновление автоанализа", + "EventActions.updateAutoPatternAnalysisSettings": "Обновить настройки Pattern-Analysis", "EventActions.updateDashboard": "Oбновление панели управления", "EventActions.updateDefect": "Обновление дефекта", "EventActions.updateFilter": "Обновление фильтра", "EventActions.updateIntegration": "Обновление интеграции", "EventActions.updateItem": "Обновление элемента", "EventActions.updatePattern": "Обновление шаблона", - "EventActions.updateAutoPatternAnalysisSettings": "Обновить настройки Pattern-Analysis", "EventActions.updateProject": "Обновление проекта", "EventActions.updateWidget": "Обновление виджета", "EventObjectTypes.dashboard": "Панель управления", @@ -729,10 +736,10 @@ "EventObjectTypes.index": "Индекс", "EventObjectTypes.integration": "Интеграция", "EventObjectTypes.invitationLink": "Ссылка для приглашения", + "EventObjectTypes.itemIssue": "Элемент тестирования", "EventObjectTypes.launch": "Запуск", "EventObjectTypes.patternRule": "Шаблон", "EventObjectTypes.project": "Проект", - "EventObjectTypes.itemIssue": "Элемент тестирования", "EventObjectTypes.user": "Пользователь", "EventObjectTypes.widget": "Виджет", "EventsGrid.actionCol": "Действие", @@ -972,14 +979,9 @@ "IndexActionsBlock.removeIndexButtonCaption": "Удалить Индекс", "IndexActionsBlock.removeIndexDescription": "Вся информация будет удалена из ElasticSearch. Для генерации данных заново Вы можете начать анализировать тестовые результаты вручную или сгенерировать данные автоматически", "IndexActionsBlock.title": "Действия с индексом", - "AutoAnalysis.allMessagesShouldMatch": "Все логи с 3 или более строками должны совпадать", - "AutoAnalysis.allMessagesShouldMatchDescription": "Когда анализируемый элемент теста содержит логи с 3 или более строками", "IndexSettings.generateIndexButtonCaption": "Сгенирировать индекс", "IndexSettings.generateIndexDescription": "все данные удаляются из ElasticSearch и создаются новые на основе всех предыдущих исследований проекта. Вы можете начать использовать автоанализ после получения электронного письма об окончании процесса генерации.", "IndexSettings.inCaseOf": "В случае", - "AutoAnalysis.numberOfLogLines": "Количество строк лога, которые следует учитывать в Elasticsearch", - "AutoAnalysis.numberOfLogLinesAllOption": "Все", - "AutoAnalysis.numberOfLogLinesDescription": "Количество первых строк лога, которое следует учитывать в ElasticSearch", "IndexSettings.regenerateIndexDescription": "Вами был изменены параметр 'Количество строк лога'. Это действие может повлиять на результаты авто-анализа. Для корректной работы анализатор, пожалуйста, перегенерируйте индекс в ElasticSearch. Хотите ли Вы перегенирировать индекс сейчас?", "IndexSettings.regenerateIndexProgress": "Пожалуйста, подождите, мы генирироуем новый индекс", "IndexSettings.regenerateIndexTitle": "Регенерировать индекс", @@ -1041,6 +1043,7 @@ "IntegrationsCase.noIntegrationsDescription": "В вашем проекте еще нет интеграций", "IntegrationsCase.noIntegrationsMessage": "Нет интеграций", "IntegrationsDescription.ConnectionErrorMessage": "Ошибка соединения", + "IntegrationsDescription.GlobalIntegrationsSystemMessage": "Внимание", "IntegrationsDescription.GlobalIntegrationsSystemMessageModalCaption": "Глобальная и проектная интеграции не могут работать одновременно.", "IntegrationsDescription.GlobalIntegrationsSystemMessageModalText": "Обратите внимание, что глобальные интеграции будут отключены, если вы создадите интеграцию проекта!", "IntegrationsDescription.GlobalIntegrationsSystemMessageText": "Глобальные интеграции неактивны, поскольку вы настроили интеграцию проекта.", @@ -1052,8 +1055,6 @@ "IntegrationsDescription.noGlobalIntegrationsButtonAdd": "Добавить интеграцию проекта", "IntegrationsDescription.noGlobalIntegrationsDescription": "Интеграции не настроены. Вы можете вручную настроить интеграцию для этого проекта.", "IntegrationsDescription.noGlobalIntegrationsMessage": "Нет Интеграций", - "IntegrationsDescription.projectIntegrationCreate": "Создать интеграцию проекта", - "ConnectionSection.deleteIntegrationDescription": "Вы уверены, что хотите удалить Интеграцию", "IntegrationsDescription.projectIntegrationReset": "Сброс к глобальным интеграциям", "IntegrationsDescription.projectIntegrationResetDescription": "Вы уверены, что хотите сбросить настройки к Глобальным Интеграциям? Все ваши пректные интеграции будут удалены без возможности восстановления.", "IntegrationsDescription.projectIntegrationText": "Интеграции проекта создаются для каждого проекта", @@ -1275,11 +1276,6 @@ "LoginForm.loginPlaceholder": "Логин", "LoginForm.or": "или", "LoginForm.passwordPlaceholder": "Пароль", - "AccountRemovedPage.description": "Ваша учетная запись и личные данные были удалены из базы данных ReportPortal.\nНам жаль, что вы уходите. Уведомление по электронной почте было отправлено на адрес электронной почты, связанный с вашей учетной записью.", - "AccountRemovedPage.header": "учетная запись была удалена", - "AccountRemovedPage.login": "Авторизоваться", - "AccountRemovedPage.message": "Благодарим вас за использование ReportPortal", - "AccountRemovedPage.signup": "Зарегистрироваться", "LogsGrid.noResults": "Результатов не найдено", "LogsGrid.statusColumnTitle": "Статус", "LogsGrid.timeColumnTitle": "Время", @@ -1488,7 +1484,6 @@ "NotPassedTestCasesTrendControls.ItemsValidationError": "Количество элементов принимает значения от '1' до '600'", "NotificationCase.attributesLabel": "Атрибуты", "NotificationCase.attributesLabelWithOperator": "Атрибуты ({attributesOperator})", - "NotificationCase.attributesNote": "Send notifications about launches containing specified attributes", "NotificationCase.attributesOperatorAnd": "Все атрибуты", "NotificationCase.attributesOperatorNote": "Уведомлять, если запуск имеет все/хотя бы один указанный атрибут", "NotificationCase.attributesOperatorOr": "Любой атрибут", @@ -2064,9 +2059,9 @@ "UpdateAnalysisSettings.numbersInErrorLog": "удалить цифры в журнале ошибок", "UpdateAnalysisSettings.uniqueError": "переключение уникальных ошибок", "UpdateAnalysisSettings.updated": "обновил", - "UpdateAutoPatternAnalysisSettings.updated": "обновил", "UpdateAutoPatternAnalysisSettings.description": "переключив значение с {oldValue} на {newValue}.", "UpdateAutoPatternAnalysisSettings.linkText": "параметры Анализа-Шаблонов:", + "UpdateAutoPatternAnalysisSettings.updated": "обновил", "UserBlock.adminBadge": "Администратор", "UserBlock.administrate": "Администрировать", "UserBlock.logout": "Выйти", @@ -2080,10 +2075,6 @@ "ViewTabs.uniqueErrorsView": "Уникальные ошибки", "Widget.forceUpdateWidgetMessage": "Вы уверены, что хотите обновить данные в этом виджете? Это может занять до 15 минут в зависимости от размера базы данных проекта.", "Widget.forceUpdateWidgetTitle": "Обновить данные виджета", - "WidgetCriteriaOption.AUTOMATION_BUG": "Automation Bug", - "WidgetCriteriaOption.AUTOMATION_BUG_TOTAL": "Всего Automation Bug", - "WidgetCriteriaOption.assign_user": "Назначить, пригласить пользователя", - "WidgetCriteriaOption.create_project": "Создать проект", "WidgetCriteriaOption.CriteriaFailed": "Неудачно", "WidgetCriteriaOption.CriteriaPassed": "Успешно", "WidgetCriteriaOption.CriteriaSkipped": "Пропущено", @@ -2091,7 +2082,9 @@ "WidgetCriteriaOption.aa_settings_actions": "Обновить Авто-Анализ", "WidgetCriteriaOption.assign_user": "Назначить, пригласить пользователя", "WidgetCriteriaOption.attributes": "Атрибуты", + "WidgetCriteriaOption.change_role": "Изменить роль", "WidgetCriteriaOption.create_pattern": "Создать паттерн", + "WidgetCriteriaOption.create_project": "Создать проект", "WidgetCriteriaOption.dashboards_actions": "Обновить Панель управления", "WidgetCriteriaOption.defects_actions": "Обновить типы дефектов", "WidgetCriteriaOption.delete_launch": "Удалить запуск", @@ -2107,10 +2100,9 @@ "WidgetCriteriaOption.startTime": "Старт", "WidgetCriteriaOption.start_launch": "Начать запуск", "WidgetCriteriaOption.unassign_user": "Отменить назначение пользователя", - "WidgetCriteriaOption.change_role": "Изменить роль", + "WidgetCriteriaOption.updateAutoPatternAnalysisSettings": "Обновить настройки Pattern-Analysis", "WidgetCriteriaOption.update_pattern": "Обновить паттерн", "WidgetCriteriaOption.update_project": "Обновить настройки проекта", - "WidgetCriteriaOption.updateAutoPatternAnalysisSettings": "Обновить настройки Pattern-Analysis", "WidgetCriteriaOption.user": "Пользователь", "WidgetCriteriaOption.widgets_actions": "Обновить виджет", "WidgetHeader.forceUpdate": "Обновить", @@ -2179,6 +2171,7 @@ "WizardInfoSection.addWidgetButton": "Добавить", "WizardInfoSection.nextStepButton": "Следующий шаг", "WizardInfoSection.prevStepButton": "Предыдущий шаг", + "administrateEventsPageToolbar.searchPlaceholder": "Поиск по пользователю, действию, типу объекта, имени объекта", "administrateUsersPage.allUsers": "Все пользователи", "administrateUsersPage.deleteModalContent": "Вы уверены, что хотите удалить пользователя {name}?", "administrateUsersPage.deleteModalHeader": "Удаление пользователя", @@ -2190,7 +2183,6 @@ "administrateUsersPage.successMultiple": "Пользователи удалены", "administrateUsersPageToolbar.allUsers": "{count} пользователей выбрано", "administrateUsersPageToolbar.searchPlaceholder": "Поиск по имени, логину, электронному адресу", - "administrateEventsPageToolbar.searchPlaceholder": "Поиск по пользователю, действию, типу объекта, имени объекта", "dashboardControl.dashboardName": "Моя первая панель управления", "dashboardControl.title": "Сохранить виджет на панели управления", "entityInputConditional.defaultPlaceholder": "Введите имя", diff --git a/app/localization/translated/uk.json b/app/localization/translated/uk.json index 5cb1b0f9f9..e4da8383f9 100644 --- a/app/localization/translated/uk.json +++ b/app/localization/translated/uk.json @@ -57,8 +57,10 @@ "AddEditNotificationCaseModal.active": "Активне правило", "AddEditNotificationCaseModal.addAttribute": "Додати атрибут", "AddEditNotificationCaseModal.attributesLabel": "Атрибути", + "AddEditNotificationCaseModal.attributesLabelAll": "(Усі атрибути мають збігатися)", + "AddEditNotificationCaseModal.attributesLabelAny": "(Будь-який атрибут має відповідати)", "AddEditNotificationCaseModal.attributesNotActive": "Атрибути не є активними. Щоб активувати, встановіть прапорець `Атрибути`", - "AddEditNotificationCaseModal.attributesNote": "Надсилати сповіщення про запуски, що містять вказані атрибути", + "AddEditNotificationCaseModal.attributesNote": "Повідомити, якщо запуск має всі/принаймні один із зазначених атрибутів", "AddEditNotificationCaseModal.attributesOperatorAnd": "Усі атрибути мають збігатися", "AddEditNotificationCaseModal.attributesOperatorOr": "Будь-який атрибут має збігатися", "AddEditNotificationCaseModal.controlPanelName": "Правило", @@ -190,7 +192,6 @@ "AttributesContainer.addAttribute": "Додати атрибут", "AttributesContainer.attributes": "Атрибути", "AttributesContainer.attributesNotActive": "Атрибути не є активними. Для активації встановіть прапорець 'Атрибути’", - "AttributesContainer.attributesNote": "Надсилати повідомлення про запуски, що містять вказані атрибути", "AttributesFieldArrayControl.addOneMoreLevel": "Додати ще один рівень", "AttributesFieldArrayControl.attributeKeyFieldLabel": "Рівень {number} {view}", "AttributesFieldArrayControl.attributeKeyFieldPlaceholder": "Введить ключ атрибуту", @@ -199,12 +200,17 @@ "AutoAnalysis.AutoAnalysisMode": "Авто-Аналіз на основі", "AutoAnalysis.AutoAnalysisModeDescription": "Ви можете вибрати тип аналізу тестового елемента на основі раніше досліджуваних даних для запуску з таким же назвою або для всіх запусків", "AutoAnalysis.allLaunchesCaption": "Всі запуски", + "AutoAnalysis.allMessagesShouldMatch": "Всі логи з 3 або більше рядками повинні співпадати", + "AutoAnalysis.allMessagesShouldMatchDescription": "Коли аналізований елемент тесту містить логи з 3 або більше рядками", "AutoAnalysis.autoAnalysis": "Авто-Аналіз", "AutoAnalysis.autoAnalysisDescription": "Активний авто-аналіз розпочнеться відразу після завершення будь-якого запуску", "AutoAnalysis.current": "Тільки запуск поточний", "AutoAnalysis.currentAndWithSameName": "Поточний запуск і запуски з такою ж назвою", "AutoAnalysis.minShouldMatch": "Мінімум повинен збігатися для авто-аналізу", "AutoAnalysis.minShouldMatchDescription": "Відсоток збігу слів між аналізованим логом та конкретним логом з ElasticSearch. Якщо в лозі з ElasticSearch значення менше встановленого, цей журнал буде ігноруватися для AA", + "AutoAnalysis.numberOfLogLines": "Кількість рядків лога, які слід враховувати в Elasticsearch", + "AutoAnalysis.numberOfLogLinesAllOption": "Усе", + "AutoAnalysis.numberOfLogLinesDescription": "Кількість перших рядків лога, яку слід враховувати в ElasticSearch", "AutoAnalysis.previousLaunch": "Попередній запуск з такою ж назвою", "AutoAnalysis.sameNameLaunchesCaption": "Запуски з однаковими іменами", "AutoAnalysis.tabDescription": "Авто-Аналіз дозволяє скоротити час, витрачений на перевірку виконання тесту, шляхом аналізу помилок тесту в автоматичному режимі. Процес автоматичного аналізу базується на результатах попереднього дослідження користувачами за допомогою машинного навчання. Налаштування застосовуються, коли автоаналіз запускається при події завершення запуску, а також при події завершення тестового елемента. Додаткову інформацію про автоматичний аналіз можна прочитати в Документації", @@ -248,6 +254,7 @@ "ChangeProjectRoleModal.changeAccountRoleText": "Вы уверены, что хотите изменить проектную роль для ''{name}''?", "ChangeProjectRoleModal.changeAccountRoleTitle": "змінити роль", "ChangeProjectRoleModal.submitText": "Змінити", + "ChangeRole": "на проекті змінилася роль", "Chart.label.automationBug": "Проблеми автоматизації", "Chart.label.investigated": "Проаналізовані", "Chart.label.launchesQuantity": "Запуски", @@ -271,7 +278,6 @@ "Charts.skipped": "Пропущено", "Charts.testCasesCaption": "Тествовые випадки", "Charts.total": "Всього {type}", - "ChangeRole": "на проекті змінилася роль", "ClusterItemsGridRow.loadLabel": "Завантажити", "ColorPicker.pickSwatch": "Виберіть зразок", "ColorPicker.selectColor": "Виберіть свій колір", @@ -308,7 +314,6 @@ "Common.forceFinish": "Примусово завершити", "Common.friday": "П’ятниця", "Common.generate": "Генерувати", - "Common.friday": "П’ятниця", "Common.invite": "Запросити", "Common.january": "Січень", "Common.july": "Липень", @@ -425,6 +430,7 @@ "ConnectionSection.connectionFailedDescription": "Не вдалося підключитися до {pluginName}", "ConnectionSection.connectionFailedHeader": "Помилка з'єднання", "ConnectionSection.connectionFailedMessage": "Помилка з'єднання", + "ConnectionSection.deleteIntegrationDescription": "Ви впевнені, що хочете видалити Інтеграцію", "ConnectionSection.removeIntegrationSuccess": "Інтеграція успішно видалена", "ConnectionSection.warningMessage": "Попередження", "ConnectionSection.warningMessageDescription": "Глобальні інтеграції є неактивними, оскільки ви налаштували інтеграцію проекту.", @@ -560,18 +566,18 @@ "DeleteAccountBlock.deleteAccount": "Видалити аккаунт", "DeleteAccountBlock.tooltipText": "Лише користувачі з роллю не адміністратора можуть видалити свій обліковий запис.\nКрім того, це може зробити інший адміністратор.", "DeleteAccountFeedbackModal.alternative": "Знайшов кращу альтернативу", - "DeleteAccountFeedbackModal.dissatisfied": "Незадоволений сервісом", - "DeleteAccountFeedbackModal.noNeeded": "Обліковий запис більше не потрібен", - "DeleteAccountFeedbackModal.other": "Інше", "DeleteAccountFeedbackModal.continue": "Продовжити", + "DeleteAccountFeedbackModal.deleteAccountReasonSizeHint": "Поле має бути розміром не більше 128 символів.", "DeleteAccountFeedbackModal.description": "Чому ви видаляєте свій акаунт?", + "DeleteAccountFeedbackModal.dissatisfied": "Незадоволений сервісом", "DeleteAccountFeedbackModal.header": "Видалити аккаунт", - "DeleteAccountFeedbackModal.deleteAccountReasonSizeHint": "Поле має бути розміром не більше 128 символів.", + "DeleteAccountFeedbackModal.noNeeded": "Обліковий запис більше не потрібен", + "DeleteAccountFeedbackModal.other": "Інше", "DeleteAccountModal.deleteAccountNote": "Процес безповоротний. Натиснувши на \"Видалити\" кнопку ви погоджуєтеся видалити всі вашу особисту інформацію, включаючи ім’я облікового запису, адресу електронної пошти та фото з нашої бази даних.", + "DeleteAccountModal.deletePersonalDataNote": "Усі дані, які ви створили або повідомили в ReportPortal, залишаться в додатку, але більше не будуть вам доступні. Сюди входить будь-який запуски, фільтри, віджети, інформаційні панелі тощо.", "DeleteAccountModal.header": "Видалити аккаунт", "DeleteAccountModal.label": "Введіть \"DELETE\" для підтвердження", "DeleteAccountModal.question": "Ви впевнені, що хочете видалити свій обліковий запис?", - "DeleteAccountModal.deletePersonalDataNote": "Усі дані, які ви створили або повідомили в ReportPortal, залишаться в додатку, але більше не будуть вам доступні. Сюди входить будь-який запуски, фільтри, віджети, інформаційні панелі тощо.", "DeleteDefectTypeModal.message": "Ви впевнені, що хочете видалити {name}?", "DeleteDefectTypeModal.title": "Видалити {name}", "DeleteFilterDialog.deleteFilter": "Вы уверены, что хотите удалить фильтр '{name}'?", @@ -683,14 +689,15 @@ "ErrorLogsBlock.showErrorLog": "Показати", "EventActions.analyzeItem": "Змінив АА дефекту тип", "EventActions.assignUser": "Призначити користувача", + "EventActions.changeRole": "Змінити роль", "EventActions.createDashboard": "Створення панелі управління", "EventActions.createDefect": "Створення користувальницького дефекту", "EventActions.createFilter": "Створення фільтра", "EventActions.createIntegration": "Створення інтеграції", + "EventActions.createInvitationLink": "Створити посилання на запрошення", "EventActions.createPattern": "Створення шаблону", "EventActions.createProject": "Створити проект", "EventActions.createWidget": "Створення віджета", - "EventActions.createInvitationLink": "Створити посилання на запрошення", "EventActions.deleteDashboard": "Видалення панелі управління", "EventActions.deleteDefect": "Видалення дефекта", "EventActions.deleteFilter": "Видалення фільтра", @@ -699,27 +706,26 @@ "EventActions.deleteLaunch": "Видалення запуску", "EventActions.deletePattern": "Видалення шаблону", "EventActions.deleteWidget": "Видалення міні-програми", - "EventActions.import": "Імпорт", - "EventActions.startImport": "Розпочати імпорт", "EventActions.finishImport": "Завершити імпорт", "EventActions.finishLaunch": "Закінчення запуску", "EventActions.generateIndex": "Генерація індексу", + "EventActions.import": "Імпорт", "EventActions.linkIssue": "Прив’язка помилки", "EventActions.linkIssueAA": "Прив’язка помилки автоанализом", "EventActions.matchedPattern": "Патерн-аналіз виявив відповідність", "EventActions.postIssue": "Створення помилки", + "EventActions.startImport": "Розпочати імпорт", "EventActions.startLaunch": "Старт запуску", "EventActions.unassignUser": "Скасувати призначення користувача", - "EventActions.changeRole": "Змінити роль", "EventActions.unlinkIssue": "Відкріплення помилки", "EventActions.updateAnalyzer": "Оновлення автоанализа", + "EventActions.updateAutoPatternAnalysisSettings": "Оновити параметри Pattern-Analysis", "EventActions.updateDashboard": "Оновлення панелі управління", "EventActions.updateDefect": "Оновлення дефекту", "EventActions.updateFilter": "Оновлення фільтра", "EventActions.updateIntegration": "Оновлення інтеграції", "EventActions.updateItem": "Оновлення елемента", "EventActions.updatePattern": "Оновлення шаблону", - "EventActions.updateAutoPatternAnalysisSettings": "Оновити параметри Pattern-Analysis", "EventActions.updateProject": "Оновлення проекту", "EventActions.updateWidget": "Оновлення віджету", "EventObjectTypes.dashboard": "Панель управління", @@ -730,10 +736,10 @@ "EventObjectTypes.index": "Iндэкс", "EventObjectTypes.integration": "Інтеграція", "EventObjectTypes.invitationLink": "Посилання на запрошення", + "EventObjectTypes.itemIssue": "Елемент тестування", "EventObjectTypes.launch": "Запуск", "EventObjectTypes.patternRule": "Шаблон", "EventObjectTypes.project": "Проект", - "EventObjectTypes.itemIssue": "Елемент тестування", "EventObjectTypes.user": "Користувач", "EventObjectTypes.widget": "Віджет", "EventsGrid.actionCol": "Дія", @@ -973,14 +979,9 @@ "IndexActionsBlock.removeIndexButtonCaption": "Видалити Індекс", "IndexActionsBlock.removeIndexDescription": "Вся інформація буде видалена з прикладу подібного. Для генерації даних заново Ви можете почати аналізувати тестові результати вручну або автоматично згенерувати дані", "IndexActionsBlock.title": "Індексом Дії з", - "AutoAnalysis.allMessagesShouldMatch": "Всі логи з 3 або більше рядками повинні співпадати", - "AutoAnalysis.allMessagesShouldMatchDescription": "Коли аналізований елемент тесту містить логи з 3 або більше рядками", "IndexSettings.generateIndexButtonCaption": "Сгенувати індекс", "IndexSettings.generateIndexDescription": "всі дані видаляються з ElasticSearch, а нові генеруються на основі всіх попередніх досліджень проекту. Ви можете почати використовувати автоматичний аналіз після отримання електронного листа про закінчення процесу генерації.", "IndexSettings.inCaseOf": "В випадку", - "AutoAnalysis.numberOfLogLines": "Кількість рядків лога, які слід враховувати в Elasticsearch", - "AutoAnalysis.numberOfLogLinesAllOption": "Усе", - "AutoAnalysis.numberOfLogLinesDescription": "Кількість перших рядків лога, яку слід враховувати в ElasticSearch", "IndexSettings.regenerateIndexDescription": "Вами було змінено параметр 'Кількість рядків лога'. Ця дія може вплинути на результати авто-аналізу. Для коректної роботи аналізатор, будь ласка, перегенеруйте індекс в ElasticSearch. Чи бажаєте Ви перегенірувати індекс зараз?", "IndexSettings.regenerateIndexProgress": "Будь ласка, зачекайте, ми геніруємо новий індекс", "IndexSettings.regenerateIndexTitle": "Регенерувати індекс", @@ -1042,6 +1043,7 @@ "IntegrationsCase.noIntegrationsDescription": "Ваш проект ще не має інтеграцій", "IntegrationsCase.noIntegrationsMessage": "Ніяких інтеграцій", "IntegrationsDescription.ConnectionErrorMessage": "Помилка з'єднання", + "IntegrationsDescription.GlobalIntegrationsSystemMessage": "Увага", "IntegrationsDescription.GlobalIntegrationsSystemMessageModalCaption": "Глобальна та проектна інтеграції не можуть працювати одночасно.", "IntegrationsDescription.GlobalIntegrationsSystemMessageModalText": "Зверніть увагу, що глобальні інтеграції буде відключено, якщо ви створите інтеграцію проекту!", "IntegrationsDescription.GlobalIntegrationsSystemMessageText": "Глобальні інтеграції є неактивними, оскільки ви налаштували інтеграцію проекту.", @@ -1053,8 +1055,6 @@ "IntegrationsDescription.noGlobalIntegrationsButtonAdd": "Додати інтеграцію проекту", "IntegrationsDescription.noGlobalIntegrationsDescription": "Інтеграції не налаштовані. Ви можете вручну настроїти інтеграцію для цього проекту.", "IntegrationsDescription.noGlobalIntegrationsMessage": "Ніяких Iнтеграцій", - "IntegrationsDescription.projectIntegrationCreate": "Створити інтеграцію проекту", - "ConnectionSection.deleteIntegrationDescription": "Ви впевнені, що хочете видалити Інтеграцію", "IntegrationsDescription.projectIntegrationReset": "Скидання до глобальних інтеграцій", "IntegrationsDescription.projectIntegrationResetDescription": "Ви впевнені, що хочете скинути налаштування до Глобальних Інтеграцій? Всі ваші проектні інтеграції будуть видалені без можливості відновлення.", "IntegrationsDescription.projectIntegrationText": "Інтеграції проекту створюються для кожного проекту", @@ -1276,11 +1276,6 @@ "LoginForm.loginPlaceholder": "Логін", "LoginForm.or": "або", "LoginForm.passwordPlaceholder": "Пароль", - "AccountRemovedPage.description": "Ваш обліковий запис і особисті дані видалено з бази даних ReportPortal.\nНам шкода, що ви йдете. Сповіщення електронною поштою надіслано на адресу електронної пошти, пов’язану з вашим обліковим записом.", - "AccountRemovedPage.header": "обліковий запис видалено", - "AccountRemovedPage.login": "Авторизуватися", - "AccountRemovedPage.message": "Дякуємо за використання ReportPortal", - "AccountRemovedPage.signup": "Зареєструватися", "LogsGrid.noResults": "Результатів не знайдено", "LogsGrid.statusColumnTitle": "Статус", "LogsGrid.timeColumnTitle": "Час", @@ -1489,7 +1484,6 @@ "NotPassedTestCasesTrendControls.ItemsValidationError": "Кількість елементів приймає значення від '1' до '600'", "NotificationCase.attributesLabel": "Атрибути", "NotificationCase.attributesLabelWithOperator": "Атрибути ({attributesOperator})", - "NotificationCase.attributesNote": "Send notifications about launches containing specified attributes", "NotificationCase.attributesOperatorAnd": "Всі атрибути", "NotificationCase.attributesOperatorNote": "Повідомити, якщо запуск має всі/принаймні один указаний атрибут", "NotificationCase.attributesOperatorOr": "Будь-який атрибут", @@ -2065,9 +2059,9 @@ "UpdateAnalysisSettings.numbersInErrorLog": "вилучити цифри в журналі помилок", "UpdateAnalysisSettings.uniqueError": "перемикання унікальних помилок", "UpdateAnalysisSettings.updated": "оновив", - "UpdateAutoPatternAnalysisSettings.updated": "оновив", "UpdateAutoPatternAnalysisSettings.description": "переключив значенне з {oldValue} на {newValue}.", "UpdateAutoPatternAnalysisSettings.linkText": "параметри Аналізу-Шаблонау:", + "UpdateAutoPatternAnalysisSettings.updated": "оновив", "UserBlock.adminBadge": "Адміністратор", "UserBlock.administrate": "Адмініструвати", "UserBlock.logout": "Вийти", @@ -2081,31 +2075,16 @@ "ViewTabs.uniqueErrorsView": "Унікальні помилки", "Widget.forceUpdateWidgetMessage": "Ви впевнені, що хочете оновити дані в цьому віджеті? Це може зайняти до 15 хвилин в залежності від розміру бази даних проекту.", "Widget.forceUpdateWidgetTitle": "Оновити дані віджета", - "WidgetCriteriaOption.AUTOMATION_BUG": "Помилка Автоматизації", - "WidgetCriteriaOption.AUTOMATION_BUG_TOTAL": "Помилка Автоматизації", - "WidgetCriteriaOption.assign_user": "Призначити, запросити користувача", "WidgetCriteriaOption.CriteriaFailed": "Невдало", "WidgetCriteriaOption.CriteriaPassed": "Успішно", "WidgetCriteriaOption.CriteriaSkipped": "Пропущено", "WidgetCriteriaOption.CriteriaTotal": "Всього", - "WidgetCriteriaOption.create_project": "Створити проект", - "WidgetCriteriaOption.Defect_Type_AB001": "Помилка Автоматизації", - "WidgetCriteriaOption.Defect_Type_ND001": "Ніякої Дефект", - "WidgetCriteriaOption.Defect_Type_PB001": "Помилка Продукту", - "WidgetCriteriaOption.Defect_Type_SI001": "Проблема Системи", - "WidgetCriteriaOption.Defect_Type_TI001": "Для Розслідування", - "WidgetCriteriaOption.NO_DEFECT": "Проблеми Немає", - "WidgetCriteriaOption.NO_DEFECT_TOTAL": "Всього Не Дефект", - "WidgetCriteriaOption.PRODUCT_BUG": "Помилка Продукту", - "WidgetCriteriaOption.PRODUCT_BUG_TOTAL": "Всього Помилок", - "WidgetCriteriaOption.SYSTEM_ISSUE": "Проблема Системи", - "WidgetCriteriaOption.SYSTEM_ISSUE_TOTAL": "Питання Системи Всього", - "WidgetCriteriaOption.TO_INVESTIGATE": "Для Розслідування", - "WidgetCriteriaOption.TO_INVESTIGATE_TOTAL": "Всього Для Розслідування", "WidgetCriteriaOption.aa_settings_actions": "Оновити Авто-Аналіз", "WidgetCriteriaOption.assign_user": "Призначити, запросити користувача", "WidgetCriteriaOption.attributes": "Атрибути", + "WidgetCriteriaOption.change_role": "Змінити роль", "WidgetCriteriaOption.create_pattern": "Створити патерн", + "WidgetCriteriaOption.create_project": "Створити проект", "WidgetCriteriaOption.dashboards_actions": "Оновити Панель управління", "WidgetCriteriaOption.defects_actions": "Оновити типи дефектів", "WidgetCriteriaOption.delete_launch": "Видалити запуск", @@ -2121,10 +2100,9 @@ "WidgetCriteriaOption.startTime": "Старт", "WidgetCriteriaOption.start_launch": "Почати запуск", "WidgetCriteriaOption.unassign_user": "Скасувати призначення користувача", - "WidgetCriteriaOption.change_role": "Змінити роль", + "WidgetCriteriaOption.updateAutoPatternAnalysisSettings": "Оновити параметри Pattern-Analysis", "WidgetCriteriaOption.update_pattern": "Оновити патерн", "WidgetCriteriaOption.update_project": "Оновити налаштування проекту", - "WidgetCriteriaOption.updateAutoPatternAnalysisSettings": "Оновити параметри Pattern-Analysis", "WidgetCriteriaOption.user": "Користувач", "WidgetCriteriaOption.widgets_actions": "Оновити віджет", "WidgetHeader.forceUpdate": "Оновити", @@ -2193,6 +2171,7 @@ "WizardInfoSection.addWidgetButton": "Додати", "WizardInfoSection.nextStepButton": "Наступний крок", "WizardInfoSection.prevStepButton": "Попередній крок", + "administrateEventsPageToolbar.searchPlaceholder": "Пошук за користувачем, дією, типом об'єкта, назвою об'єкта", "administrateUsersPage.allUsers": "Всі Користувачі", "administrateUsersPage.deleteModalContent": "Вы уверены, что хотите удалить пользователя {name}?", "administrateUsersPage.deleteModalHeader": "Видалення користувача", @@ -2204,7 +2183,6 @@ "administrateUsersPage.successMultiple": "Користувачі видалені", "administrateUsersPageToolbar.allUsers": "{count} пользователей выбрано", "administrateUsersPageToolbar.searchPlaceholder": "Пошук по імені, логіну, електронну адресу", - "administrateEventsPageToolbar.searchPlaceholder": "Пошук за користувачем, дією, типом об'єкта, назвою об'єкта", "dashboardControl.dashboardName": "Моя перша панель управління", "dashboardControl.title": "Зберегти віджет на панелі управління", "entityInputConditional.defaultPlaceholder": "Введіть ім’я", diff --git a/app/localization/translated/zh.json b/app/localization/translated/zh.json index 51ab395263..90f2596911 100644 --- a/app/localization/translated/zh.json +++ b/app/localization/translated/zh.json @@ -57,8 +57,10 @@ "AddEditNotificationCaseModal.active": "激活规则", "AddEditNotificationCaseModal.addAttribute": "添加属性", "AddEditNotificationCaseModal.attributesLabel": "属性", + "AddEditNotificationCaseModal.attributesLabelAll": "(All attributes should match)", + "AddEditNotificationCaseModal.attributesLabelAny": "(Any attribute should match)", "AddEditNotificationCaseModal.attributesNotActive": "属性未生效。请勾选复选框“属性”进行激活", - "AddEditNotificationCaseModal.attributesNote": "发送有关包含了指定属性的测试任务的通知", + "AddEditNotificationCaseModal.attributesNote": "Notify if the launch has all/at least one of specified attributes", "AddEditNotificationCaseModal.attributesOperatorAnd": "所有属性应当匹配", "AddEditNotificationCaseModal.attributesOperatorOr": "任何属性应当匹配", "AddEditNotificationCaseModal.controlPanelName": "规则", @@ -156,6 +158,7 @@ "Analyzer.updateErrorNotification": "未知错误,请联系管理员。", "Analyzer.updateSuccessNotification": "项目设置更新成功", "ApiKeyGeneratedModal.description": "拷贝API密钥并保存在安全的地方。\n在点击“关闭”按钮后,您将无法再看到该密钥。", + "ApiKeyGeneratedModal.descriptionNote": "You won’t be able to see your Key once you click \"Close\" button.", "ApiKeyGeneratedModal.header": "API密钥已生成", "ApiKeyGeneratedModal.loaderText": "正在生成...", "ApiKeyGeneratedModal.successNotification": "API密钥已被成功拷贝", @@ -189,7 +192,6 @@ "AttributesContainer.addAttribute": "添加属性", "AttributesContainer.attributes": "属性", "AttributesContainer.attributesNotActive": "属性未生效。请勾选复选框“属性”进行激活", - "AttributesContainer.attributesNote": "发送有关包含了指定属性的测试任务的通知", "AttributesFieldArrayControl.addOneMoreLevel": "+ 再添加一级", "AttributesFieldArrayControl.attributeKeyFieldLabel": "等级 {number} {view}", "AttributesFieldArrayControl.attributeKeyFieldPlaceholder": "请输入属性名", @@ -198,12 +200,17 @@ "AutoAnalysis.AutoAnalysisMode": "自动分析服务基于的数据", "AutoAnalysis.AutoAnalysisModeDescription": "您可以选择测试分析是基于之前同名测试任务的分析结果,还是基于全部测试任务的分析结果", "AutoAnalysis.allLaunchesCaption": "所有测试任务", + "AutoAnalysis.allMessagesShouldMatch": "包含3行或更多行的所有日志都应匹配", + "AutoAnalysis.allMessagesShouldMatchDescription": "当分析的测试项包含3行或更多行的日志时", "AutoAnalysis.autoAnalysis": "自动分析模块", "AutoAnalysis.autoAnalysisDescription": "任何测试任务完成后,将立即主动开始自动分析", "AutoAnalysis.current": "仅限当前测试任务", "AutoAnalysis.currentAndWithSameName": "Current launch and Launches with the same name", "AutoAnalysis.minShouldMatch": "自动分析时匹配的最低精度", "AutoAnalysis.minShouldMatchDescription": "已分析的日志与来自ElasticSearch的指定日志之间单词相等部分所占百分比。如果通过分析ElasticSearch的日志得到的值小于设置的值,那么该日志将被自动分析服务忽略", + "AutoAnalysis.numberOfLogLines": "在Elasticsearch中应考虑的日志行数", + "AutoAnalysis.numberOfLogLinesAllOption": "全部", + "AutoAnalysis.numberOfLogLinesDescription": "在ElasticSearch中应考虑的日志消息的前几行", "AutoAnalysis.previousLaunch": "之前具有相同名称的启动", "AutoAnalysis.sameNameLaunchesCaption": "同名的测试任务", "AutoAnalysis.tabDescription": "自动分析允许通过在自动模式下分析测试失败来减少测试执行调查所花费的时间。自动分析的过程基于之前使用机器学习进行的用户调查结果。当启动完成事件和测试项完成事件触发自动分析时,将应用这些设置。有关自动分析的更多信息,您可以在文档中阅读。", @@ -247,6 +254,7 @@ "ChangeProjectRoleModal.changeAccountRoleText": "您确定要更改”{name}”的帐户角色吗?", "ChangeProjectRoleModal.changeAccountRoleTitle": "更改角色", "ChangeProjectRoleModal.submitText": "确定", + "ChangeRole": "role was changed on the project by", "Chart.label.automationBug": "自动化错误", "Chart.label.investigated": "已调查分析", "Chart.label.launchesQuantity": "所有测试任务", @@ -422,6 +430,7 @@ "ConnectionSection.connectionFailedDescription": "未能连接至{pluginName}.", "ConnectionSection.connectionFailedHeader": "连接错误", "ConnectionSection.connectionFailedMessage": "连接失败", + "ConnectionSection.deleteIntegrationDescription": "您确定要删除项目集成吗", "ConnectionSection.removeIntegrationSuccess": "已成功删除集成", "ConnectionSection.warningMessage": "警告", "ConnectionSection.warningMessageDescription": "由于您已配置项目集成,全局集成将不会生效", @@ -439,7 +448,7 @@ "CreatePatternAnalysisModal.createPatternModalToggle": "激活规则", "CreatePatternAnalysisModal.createPatternModalType": "类型", "CreatePatternAnalysisModal.patternConditionPlaceholder": "请输入文字说明", - "CreateUser.welcome": "欢迎使用ReportPortal!", + "CreateProject": "is created", "CumulativeTrendControls.CriteriaFieldLabel": "小部件的标准", "CumulativeTrendControls.LaunchesLimitFieldLabel": "测试任务的数量", "CumulativeTrendControls.LaunchesLimitValidationError": "测试项个数应为1到20000个", @@ -680,12 +689,14 @@ "ErrorLogsBlock.showErrorLog": "显示", "EventActions.analyzeItem": "自动分析服务已更改缺陷类型", "EventActions.assignUser": "分配用户", + "EventActions.changeRole": "Change role", "EventActions.createDashboard": "创建报告面板", "EventActions.createDefect": "创建自定义缺陷类型", "EventActions.createFilter": "创建过滤器", "EventActions.createIntegration": "创建集成", + "EventActions.createInvitationLink": "Create invitation link", "EventActions.createPattern": "创建模板规则", - "EventActions.createUser": "创建用户", + "EventActions.createProject": "Create project", "EventActions.createWidget": "创建小部件", "EventActions.deleteDashboard": "删除报告面板", "EventActions.deleteDefect": "删除缺陷", @@ -695,26 +706,26 @@ "EventActions.deleteLaunch": "删除测试任务", "EventActions.deletePattern": "删除模板规则", "EventActions.deleteWidget": "删除小部件", - "EventActions.import": "导入", - "EventActions.startImport": "开始导入", "EventActions.finishImport": "完成导入", "EventActions.finishLaunch": "完成测试任务", "EventActions.generateIndex": "生成索引", + "EventActions.import": "导入", "EventActions.linkIssue": "与问题关联", "EventActions.linkIssueAA": "自动分析服务关联的问题", "EventActions.matchedPattern": "模板分析已找到模板", "EventActions.postIssue": "发布问题", + "EventActions.startImport": "开始导入", "EventActions.startLaunch": "开始执行测试任务", "EventActions.unassignUser": "取消分配用户", "EventActions.unlinkIssue": "取消已关联的问题", "EventActions.updateAnalyzer": "更新分析器", + "EventActions.updateAutoPatternAnalysisSettings": "更新模式分析设置", "EventActions.updateDashboard": "更新报告面板", "EventActions.updateDefect": "更新缺陷", "EventActions.updateFilter": "更新过滤器", "EventActions.updateIntegration": "更新集成", "EventActions.updateItem": "更新测试项", "EventActions.updatePattern": "更新模板规则", - "EventActions.updateAutoPatternAnalysisSettings": "更新模式分析设置", "EventActions.updateProject": "更新项目", "EventActions.updateWidget": "更新小部件", "EventObjectTypes.dashboard": "报告面板", @@ -722,13 +733,13 @@ "EventObjectTypes.emailConfig": "通知规则", "EventObjectTypes.filter": "过滤器", "EventObjectTypes.import": "导入", + "EventObjectTypes.index": "Index", "EventObjectTypes.integration": "集成", + "EventObjectTypes.invitationLink": "Invitation link", "EventObjectTypes.itemIssue": "缺陷", "EventObjectTypes.launch": "测试任务", "EventObjectTypes.patternRule": "模板规则", "EventObjectTypes.project": "项目", - "EventObjectTypes.testItem": "测试项", - "EventObjectTypes.ticket": "关联到BTS", "EventObjectTypes.user": "用户", "EventObjectTypes.widget": "小部件", "EventsGrid.actionCol": "操作", @@ -968,14 +979,9 @@ "IndexActionsBlock.removeIndexButtonCaption": "删除索引", "IndexActionsBlock.removeIndexDescription": "您调查的所有数据都将从ElasticSearch中删除。如需创建新数据,您可以再次手动调查测试结果或根据先前的项目结果生成数据", "IndexActionsBlock.title": "操作索引", - "AutoAnalysis.allMessagesShouldMatch": "包含3行或更多行的所有日志都应匹配", - "AutoAnalysis.allMessagesShouldMatchDescription": "当分析的测试项包含3行或更多行的日志时", "IndexSettings.generateIndexButtonCaption": "生成索引", "IndexSettings.generateIndexDescription": "所有数据已从ElasticSearch中删除,新数据已根据之前对该项目的所有调查生成。您可以在收到关于生成过程结束的电子邮件后开始使用自动分析。", "IndexSettings.inCaseOf": "当", - "AutoAnalysis.numberOfLogLines": "在Elasticsearch中应考虑的日志行数", - "AutoAnalysis.numberOfLogLinesAllOption": "全部", - "AutoAnalysis.numberOfLogLinesDescription": "在ElasticSearch中应考虑的日志消息的前几行", "IndexSettings.regenerateIndexDescription": "您已更改参数“日志行数”。此操作会影响分析结果。为了保证分析器能正常工作,请在ElasticSearch中重新生成索引。您想现在就重新生成吗?", "IndexSettings.regenerateIndexProgress": "请稍候,正在生成新索引", "IndexSettings.regenerateIndexTitle": "重新生成索引", @@ -1037,6 +1043,7 @@ "IntegrationsCase.noIntegrationsDescription": "您的项目还没有任何集成", "IntegrationsCase.noIntegrationsMessage": "无集成", "IntegrationsDescription.ConnectionErrorMessage": "连接错误", + "IntegrationsDescription.GlobalIntegrationsSystemMessage": "Warning", "IntegrationsDescription.GlobalIntegrationsSystemMessageModalCaption": "全局集成和项目集成不能同时工作。", "IntegrationsDescription.GlobalIntegrationsSystemMessageModalText": "请注意!如果您创建了项目集成,全局集成将被取消关联!", "IntegrationsDescription.GlobalIntegrationsSystemMessageText": "由于您已配置项目集成,全局集成将不会生效", @@ -1048,8 +1055,6 @@ "IntegrationsDescription.noGlobalIntegrationsButtonAdd": "添加项目集成", "IntegrationsDescription.noGlobalIntegrationsDescription": "未配置任何集成。您可以手动为此项目设置集成。", "IntegrationsDescription.noGlobalIntegrationsMessage": "无集成", - "IntegrationsDescription.projectIntegrationCreate": "创建项目集成", - "ConnectionSection.deleteIntegrationDescription": "您确定要删除项目集成吗", "IntegrationsDescription.projectIntegrationReset": "重置为全局集成", "IntegrationsDescription.projectIntegrationResetDescription": "您确定要重置为全球集成吗?您的所有项目集成都将被永久删除。", "IntegrationsDescription.projectIntegrationText": "项目集成已基于项目创建", @@ -1479,7 +1484,6 @@ "NotPassedTestCasesTrendControls.ItemsValidationError": "测试项的数量应为1到600个", "NotificationCase.attributesLabel": "属性(与)", "NotificationCase.attributesLabelWithOperator": "属性({attributesOperator})", - "NotificationCase.attributesNote": "发送有关包含指定属性的测试任务的通知", "NotificationCase.attributesOperatorAnd": "所有属性", "NotificationCase.attributesOperatorNote": "通知是否启动具有所有或至少一个指定属性。", "NotificationCase.attributesOperatorOr": "任一属性", @@ -2055,6 +2059,9 @@ "UpdateAnalysisSettings.numbersInErrorLog": "删除错误日志中的数字", "UpdateAnalysisSettings.uniqueError": "开关独特错误", "UpdateAnalysisSettings.updated": "已更新", + "UpdateAutoPatternAnalysisSettings.description": "switch from {oldValue} to {newValue}.", + "UpdateAutoPatternAnalysisSettings.linkText": "Pattern-Analysis properties:", + "UpdateAutoPatternAnalysisSettings.updated": "updated", "UserBlock.adminBadge": "管理", "UserBlock.administrate": "管理", "UserBlock.logout": "登出", @@ -2075,8 +2082,9 @@ "WidgetCriteriaOption.aa_settings_actions": "更新自动分析设置", "WidgetCriteriaOption.assign_user": "分配,邀请用户", "WidgetCriteriaOption.attributes": "属性", + "WidgetCriteriaOption.change_role": "Change role", "WidgetCriteriaOption.create_pattern": "创建模板", - "WidgetCriteriaOption.create_user": "添加、注册用户", + "WidgetCriteriaOption.create_project": "Create project", "WidgetCriteriaOption.dashboards_actions": "更新报告面板", "WidgetCriteriaOption.defects_actions": "更新缺陷类型", "WidgetCriteriaOption.delete_launch": "删除测试任务", @@ -2092,6 +2100,7 @@ "WidgetCriteriaOption.startTime": "开始时间", "WidgetCriteriaOption.start_launch": "启动测试任务", "WidgetCriteriaOption.unassign_user": "Unassign user", + "WidgetCriteriaOption.updateAutoPatternAnalysisSettings": "Update Pattern-Analysis settings", "WidgetCriteriaOption.update_pattern": "更新模板", "WidgetCriteriaOption.update_project": "更新项目设置", "WidgetCriteriaOption.user": "用户", @@ -2162,6 +2171,7 @@ "WizardInfoSection.addWidgetButton": "添加", "WizardInfoSection.nextStepButton": "下一步", "WizardInfoSection.prevStepButton": "上一步", + "administrateEventsPageToolbar.searchPlaceholder": "Search by user, action, object type, object name", "administrateUsersPage.allUsers": "全部用户", "administrateUsersPage.deleteModalContent": "您确定要删除用户{name}吗?", "administrateUsersPage.deleteModalHeader": "删除用户", @@ -2233,4 +2243,4 @@ "usersGrid.roleNonAdmin": "非管理", "usersGrid.type": "类型", "usersGrid.user": "登录" -} +} \ No newline at end of file diff --git a/app/src/components/containers/AttributeListFormField/attributeListFormField.jsx b/app/src/components/containers/AttributeListFormField/attributeListFormField.jsx index ae27a5df2a..b8cfef72a5 100644 --- a/app/src/components/containers/AttributeListFormField/attributeListFormField.jsx +++ b/app/src/components/containers/AttributeListFormField/attributeListFormField.jsx @@ -25,10 +25,6 @@ import styles from './attributeListFormField.scss'; const cx = className.bind(styles); const messages = defineMessages({ - attributesNote: { - id: 'AttributesContainer.attributesNote', - defaultMessage: 'Send notifications about launches containing specified attributes', - }, attributesNotActive: { id: 'AttributesContainer.attributesNotActive', defaultMessage: 'Attributes are non active. To activate please select checkbox ‘Attributes’', @@ -54,11 +50,6 @@ export const AttributeListFormField = ({ }) => { const { formatMessage } = useIntl(); - const attributesCaption = - shown || (!shown && !value?.length) - ? attributesNote || formatMessage(messages.attributesNote) - : formatMessage(messages.attributesNotActive); - const attributeControlHandler = (e) => { setShowEditor(e.target.checked); const filteredAttributes = value.reduce((acc, curr) => { @@ -82,7 +73,9 @@ export const AttributeListFormField = ({ > {formatMessage(messages.attributes)} -
{attributesCaption}
+
+ {!shown && value?.length ? formatMessage(messages.attributesNotActive) : attributesNote} +
); diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/elements/notificationRuleContent/notificationRuleContent.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/elements/notificationRuleContent/notificationRuleContent.jsx index 155bd7e7aa..e42f0ff6db 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/elements/notificationRuleContent/notificationRuleContent.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/elements/notificationRuleContent/notificationRuleContent.jsx @@ -19,7 +19,7 @@ import PropTypes from 'prop-types'; import classNames from 'classnames/bind'; import { defineMessages, useIntl } from 'react-intl'; import { AttributeListContainer } from 'components/containers/attributeListContainer'; -import { LAUNCH_CASES } from '../../notifications/constants'; +import { ATTRIBUTES_OPERATORS, LAUNCH_CASES } from '../../notifications/constants'; import styles from './notificationRuleContent.scss'; const cx = classNames.bind(styles); @@ -46,6 +46,14 @@ const messages = defineMessages({ id: 'AddEditNotificationCaseModal.attributesLabel', defaultMessage: 'Attributes', }, + attributesLabelAll: { + id: 'AddEditNotificationCaseModal.attributesLabelAll', + defaultMessage: '(All attributes should match)', + }, + attributesLabelAny: { + id: 'AddEditNotificationCaseModal.attributesLabelAny', + defaultMessage: '(Any attribute should match)', + }, [LAUNCH_CASES.ALWAYS]: { id: 'AddEditNotificationCaseModal.dropdownValueAlways', defaultMessage: 'Always', @@ -72,12 +80,14 @@ const messages = defineMessages({ }, }); -export const NotificationRuleContent = ({ item }) => { +export const NotificationRuleContent = ({ + item: { informOwner, recipients, attributes, attributesOperator, launchNames, sendCase }, +}) => { const { formatMessage } = useIntl(); - const recipients = item.informOwner - ? [formatMessage(messages.launchOwner), ...item.recipients] - : item.recipients; + const recipientsValue = informOwner + ? [formatMessage(messages.launchOwner), ...recipients] + : recipients; const inCaseOptions = { [LAUNCH_CASES.ALWAYS]: formatMessage(messages[LAUNCH_CASES.ALWAYS]), @@ -88,23 +98,35 @@ export const NotificationRuleContent = ({ item }) => { [LAUNCH_CASES.TO_INVESTIGATE]: formatMessage(messages[LAUNCH_CASES.TO_INVESTIGATE]), }; + const getAttributesFieldText = () => { + if (attributes.length > 1) { + return `${formatMessage(messages.attributesLabel)} ${formatMessage( + attributesOperator === ATTRIBUTES_OPERATORS.AND + ? messages.attributesLabelAll + : messages.attributesLabelAny, + )}`; + } else { + return formatMessage(messages.attributesLabel); + } + }; + return (
- {item.launchNames.length > 0 && ( + {launchNames.length > 0 && ( <> {formatMessage(messages.launchNameLabel)} - {item.launchNames.join(SEPARATOR)} + {launchNames.join(SEPARATOR)} )} {formatMessage(messages.inCaseLabel)} - {inCaseOptions[item.sendCase]} + {inCaseOptions[sendCase]} {formatMessage(messages.recipientsLabel)} - {recipients.join(SEPARATOR)} - {item.attributes.length > 0 && ( + {recipientsValue.join(SEPARATOR)} + {attributes.length > 0 && ( <> - {formatMessage(messages.attributesLabel)} + {getAttributesFieldText()}
- +
)} @@ -118,5 +140,6 @@ NotificationRuleContent.propTypes = { recipients: PropTypes.array, attributes: PropTypes.array, informOwner: PropTypes.bool, + attributesOperator: PropTypes.oneOf([ATTRIBUTES_OPERATORS.AND, ATTRIBUTES_OPERATORS.OR]), }).isRequired, }; diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/elements/notificationRuleContent/notificationRuleContent.scss b/app/src/pages/inside/projectSettingsPageContainer/content/elements/notificationRuleContent/notificationRuleContent.scss index e7f4d58d89..c3473753b3 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/elements/notificationRuleContent/notificationRuleContent.scss +++ b/app/src/pages/inside/projectSettingsPageContainer/content/elements/notificationRuleContent/notificationRuleContent.scss @@ -37,3 +37,7 @@ color: $COLOR--almost-black; margin-bottom: 16px; } + +.attributes-text { + text-transform: none; +} diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/notifications/messages.js b/app/src/pages/inside/projectSettingsPageContainer/content/notifications/messages.js index 73ee4d474d..623a783b03 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/notifications/messages.js +++ b/app/src/pages/inside/projectSettingsPageContainer/content/notifications/messages.js @@ -58,10 +58,6 @@ export const messages = defineMessages({ id: 'NotificationCase.attributesLabel', defaultMessage: 'Attributes (and)', }, - attributesNote: { - id: 'NotificationCase.attributesNote', - defaultMessage: 'Send notifications about launches containing specified attributes', - }, [LAUNCH_CASES.ALWAYS]: { id: 'NotificationCase.dropdownValueAlways', defaultMessage: 'Always', diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/notifications/modals/addEditNotificationModal/addEditNotificationModal.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/notifications/modals/addEditNotificationModal/addEditNotificationModal.jsx index 239c5795a5..9317baa831 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/notifications/modals/addEditNotificationModal/addEditNotificationModal.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/notifications/modals/addEditNotificationModal/addEditNotificationModal.jsx @@ -112,10 +112,6 @@ const messages = defineMessages({ id: 'AddEditNotificationCaseModal.attributesLabel', defaultMessage: 'Attributes', }, - attributesNote: { - id: 'AddEditNotificationCaseModal.attributesNote', - defaultMessage: 'Send notifications about launches containing specified attributes', - }, attributesNotActive: { id: 'AddEditNotificationCaseModal.attributesNotActive', defaultMessage: 'Attributes are non active. To activate please select checkbox ‘Attributes’', @@ -184,6 +180,10 @@ const messages = defineMessages({ id: 'NotificationsEnableForm.attributes', defaultMessage: 'Attributes', }, + attributesNote: { + id: 'AddEditNotificationCaseModal.attributesNote', + defaultMessage: 'Notify if the launch has all/at least one of specified attributes', + }, }); const FIELD = 'Field'; @@ -377,6 +377,7 @@ const AddEditNotificationModal = ({ setShowEditor={setShowEditor} shown={isEditorShown} changeValue={change} + attributesNote={formatMessage(messages.attributesNote)} /> {attributesValue.length > 0 && ( From 64b2e675864b41db4f8298da2512fa4500898bd1 Mon Sep 17 00:00:00 2001 From: Bam6ycha <84175555+Bam6ycha@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:48:03 +0500 Subject: [PATCH 3/9] EPMRPP-79105 || Fix modal closing on click outside (#3638) --- app/src/common/hooks/useOnClickOutside.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/common/hooks/useOnClickOutside.js b/app/src/common/hooks/useOnClickOutside.js index f3d01ee40b..ce4d582bcd 100644 --- a/app/src/common/hooks/useOnClickOutside.js +++ b/app/src/common/hooks/useOnClickOutside.js @@ -28,10 +28,10 @@ export const useOnClickOutside = (ref, handler) => { } }; - document.addEventListener('pointerdown', listener); + document.addEventListener('pointerup', listener); return () => { - document.removeEventListener('pointerdown', listener); + document.removeEventListener('pointerup', listener); }; }, [ref, handler]); }; From 70b4f49bbbdab733f11840cf9cbe44d4cdca56ea Mon Sep 17 00:00:00 2001 From: Iukou Siarhei <45054016+BlazarQSO@users.noreply.github.com> Date: Wed, 8 Nov 2023 16:49:58 +0300 Subject: [PATCH 4/9] =?UTF-8?q?EPMRPP-87386=20||=20=D0=A1orrect=20the=20di?= =?UTF-8?q?splay=20of=20the=20Delete=20account=20button=20(#3640)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/controllers/administrate/projects/reducer.js | 4 ++-- .../administrate/projects/reducer.test.js | 6 +++--- app/src/controllers/appInfo/constants.js | 2 +- app/src/controllers/appInfo/selectors.js | 4 ++-- app/src/controllers/user/actionCreators.js | 12 ++++++------ app/src/controllers/user/constants.js | 6 +++--- app/src/controllers/user/index.js | 6 +++--- app/src/controllers/user/reducer.js | 6 +++--- app/src/controllers/user/reducer.test.js | 6 +++--- app/src/controllers/user/sagas.js | 4 ++-- app/src/pages/inside/profilePage/profilePage.jsx | 6 +++++- 11 files changed, 33 insertions(+), 29 deletions(-) diff --git a/app/src/controllers/administrate/projects/reducer.js b/app/src/controllers/administrate/projects/reducer.js index e8d2253083..cf3d345981 100644 --- a/app/src/controllers/administrate/projects/reducer.js +++ b/app/src/controllers/administrate/projects/reducer.js @@ -20,7 +20,7 @@ import { paginationReducer } from 'controllers/pagination'; import { loadingReducer } from 'controllers/loading'; import { PROJECTS_PAGE } from 'controllers/pages'; import { groupOperationsReducer } from 'controllers/groupOperations'; -import { ASSIGN_TO_RROJECT_SUCCESS, UNASSIGN_FROM_PROJECT_SUCCESS } from 'controllers/user'; +import { ASSIGN_TO_PROJECT_SUCCESS, UNASSIGN_FROM_PROJECT_SUCCESS } from 'controllers/user'; import { queueReducers } from 'common/utils/queueReducers'; import { createPageScopedReducer } from 'common/utils/createPageScopedReducer'; import { NAMESPACE, SET_PROJECTS_VIEW_MODE, GRID_VIEW } from './constants'; @@ -42,7 +42,7 @@ export const projectFetchReducer = fetchReducer(NAMESPACE, { export const assignProjectReducer = (state = [], { type, payload }) => { switch (type) { - case ASSIGN_TO_RROJECT_SUCCESS: + case ASSIGN_TO_PROJECT_SUCCESS: return state.map((project) => project.projectName === payload.projectName ? { ...project, usersQuantity: project.usersQuantity + 1 } diff --git a/app/src/controllers/administrate/projects/reducer.test.js b/app/src/controllers/administrate/projects/reducer.test.js index fb2b3d6486..c24be45e84 100644 --- a/app/src/controllers/administrate/projects/reducer.test.js +++ b/app/src/controllers/administrate/projects/reducer.test.js @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ASSIGN_TO_RROJECT_SUCCESS, UNASSIGN_FROM_PROJECT_SUCCESS } from 'controllers/user'; +import { ASSIGN_TO_PROJECT_SUCCESS, UNASSIGN_FROM_PROJECT_SUCCESS } from 'controllers/user'; import { FETCH_SUCCESS } from 'controllers/fetch'; import { SET_PROJECTS_VIEW_MODE, TABLE_VIEW, GRID_VIEW, NAMESPACE } from './constants'; import { setViewModeReducer, assignProjectReducer, projectFetchReducer } from './reducer'; @@ -133,12 +133,12 @@ describe('projects reducer', () => { expect(assignProjectReducer(oldState, [{ id: 2 }])).toBe(oldState); }); - test('should handle ASSIGN_TO_RROJECT_SUCCESS', () => { + test('should handle ASSIGN_TO_PROJECT_SUCCESS', () => { const payload = { projectName: PROJECTS[0].projectName, }; const newState = assignProjectReducer(PROJECTS, { - type: ASSIGN_TO_RROJECT_SUCCESS, + type: ASSIGN_TO_PROJECT_SUCCESS, payload, }); expect(newState).toEqual(PROJECTS_AFTER_ASSIGN); diff --git a/app/src/controllers/appInfo/constants.js b/app/src/controllers/appInfo/constants.js index 440b82ccfc..d0a2b22f06 100644 --- a/app/src/controllers/appInfo/constants.js +++ b/app/src/controllers/appInfo/constants.js @@ -15,7 +15,7 @@ */ export const APP_INFO_NAMESPACE = 'appInfo'; -export const ANALYICS_INSTANCE_KEY = 'server.details.instance'; +export const ANALYTICS_INSTANCE_KEY = 'server.details.instance'; export const ANALYTICS_ALL_KEY = 'server.analytics.all'; export const OLD_HISTORY_KEY = 'history_old'; export const GA_MEASUREMENT_ID = 'ga_measurement_id'; diff --git a/app/src/controllers/appInfo/selectors.js b/app/src/controllers/appInfo/selectors.js index 1476810199..b2b1934b8a 100644 --- a/app/src/controllers/appInfo/selectors.js +++ b/app/src/controllers/appInfo/selectors.js @@ -15,7 +15,7 @@ */ import { - ANALYICS_INSTANCE_KEY, + ANALYTICS_INSTANCE_KEY, ANALYTICS_ALL_KEY, OLD_HISTORY_KEY, GA_MEASUREMENT_ID, @@ -43,7 +43,7 @@ const apiJobsSelector = (state) => apiInfoSelector(state).jobs || {}; const extensionsSelector = (state) => apiInfoSelector(state).extensions || {}; const extensionsConfigSelector = (state) => extensionsSelector(state).result || {}; export const instanceIdSelector = (state) => - extensionsConfigSelector(state)[ANALYICS_INSTANCE_KEY] || ''; + extensionsConfigSelector(state)[ANALYTICS_INSTANCE_KEY] || ''; export const analyticsEnabledSelector = (state) => extensionsConfigSelector(state)[ANALYTICS_ALL_KEY] === 'true'; export const analyzerExtensionsSelector = (state) => extensionsSelector(state).analyzers || []; diff --git a/app/src/controllers/user/actionCreators.js b/app/src/controllers/user/actionCreators.js index f6c54bd1aa..52fe2012e7 100644 --- a/app/src/controllers/user/actionCreators.js +++ b/app/src/controllers/user/actionCreators.js @@ -19,9 +19,9 @@ import { SET_START_TIME_FORMAT, SET_API_KEYS, SET_PHOTO_TIME_STAMP, - ASSIGN_TO_RROJECT, - ASSIGN_TO_RROJECT_SUCCESS, - ASSIGN_TO_RROJECT_ERROR, + ASSIGN_TO_PROJECT, + ASSIGN_TO_PROJECT_SUCCESS, + ASSIGN_TO_PROJECT_ERROR, UNASSIGN_FROM_PROJECT, UNASSIGN_FROM_PROJECT_SUCCESS, FETCH_API_KEYS, @@ -95,17 +95,17 @@ export const setStartTimeFormatAction = (format) => ({ }); export const assignToProjectAction = (project) => ({ - type: ASSIGN_TO_RROJECT, + type: ASSIGN_TO_PROJECT, payload: project, }); export const assignToProjectSuccessAction = (projectInfo) => ({ - type: ASSIGN_TO_RROJECT_SUCCESS, + type: ASSIGN_TO_PROJECT_SUCCESS, payload: projectInfo, }); export const assignToProjectErrorAction = (projectInfo) => ({ - type: ASSIGN_TO_RROJECT_ERROR, + type: ASSIGN_TO_PROJECT_ERROR, payload: projectInfo, }); diff --git a/app/src/controllers/user/constants.js b/app/src/controllers/user/constants.js index bc39ef9842..80ad9831d3 100644 --- a/app/src/controllers/user/constants.js +++ b/app/src/controllers/user/constants.js @@ -29,9 +29,9 @@ export const SETTINGS_INITIAL_STATE = { photoTimeStamp: Date.now(), }; -export const ASSIGN_TO_RROJECT = 'assignToProject'; -export const ASSIGN_TO_RROJECT_SUCCESS = 'assignToProjectSuccess'; -export const ASSIGN_TO_RROJECT_ERROR = 'assignToProjectError'; +export const ASSIGN_TO_PROJECT = 'assignToProject'; +export const ASSIGN_TO_PROJECT_SUCCESS = 'assignToProjectSuccess'; +export const ASSIGN_TO_PROJECT_ERROR = 'assignToProjectError'; export const UNASSIGN_FROM_PROJECT = 'unassignFromProject'; export const UNASSIGN_FROM_PROJECT_SUCCESS = 'unassignFromProjectSuccess'; diff --git a/app/src/controllers/user/index.js b/app/src/controllers/user/index.js index bb4b6da2a9..4608882069 100644 --- a/app/src/controllers/user/index.js +++ b/app/src/controllers/user/index.js @@ -17,9 +17,9 @@ export { START_TIME_FORMAT_ABSOLUTE, START_TIME_FORMAT_RELATIVE, - ASSIGN_TO_RROJECT, - ASSIGN_TO_RROJECT_SUCCESS, - ASSIGN_TO_RROJECT_ERROR, + ASSIGN_TO_PROJECT, + ASSIGN_TO_PROJECT_SUCCESS, + ASSIGN_TO_PROJECT_ERROR, UNASSIGN_FROM_PROJECT_SUCCESS, SET_ACTIVE_PROJECT, FETCH_USER_SUCCESS, diff --git a/app/src/controllers/user/reducer.js b/app/src/controllers/user/reducer.js index 827586c466..8e98af1694 100644 --- a/app/src/controllers/user/reducer.js +++ b/app/src/controllers/user/reducer.js @@ -20,7 +20,7 @@ import { SET_START_TIME_FORMAT, SETTINGS_INITIAL_STATE, SET_PHOTO_TIME_STAMP, - ASSIGN_TO_RROJECT_SUCCESS, + ASSIGN_TO_PROJECT_SUCCESS, UNASSIGN_FROM_PROJECT_SUCCESS, FETCH_USER_SUCCESS, SET_API_KEYS, @@ -41,7 +41,7 @@ export const settingsReducer = (state = SETTINGS_INITIAL_STATE, { type, payload export const userAssignedProjectReducer = (state = {}, { type, payload }) => { switch (type) { - case ASSIGN_TO_RROJECT_SUCCESS: { + case ASSIGN_TO_PROJECT_SUCCESS: { const { projectName, projectRole, entryType } = payload; return { ...state, @@ -73,7 +73,7 @@ export const userInfoReducer = (state = {}, { type, payload }) => { switch (type) { case FETCH_USER_SUCCESS: return payload; - case ASSIGN_TO_RROJECT_SUCCESS: + case ASSIGN_TO_PROJECT_SUCCESS: case UNASSIGN_FROM_PROJECT_SUCCESS: return { ...state, diff --git a/app/src/controllers/user/reducer.test.js b/app/src/controllers/user/reducer.test.js index 0e131a6561..a2dd665b37 100644 --- a/app/src/controllers/user/reducer.test.js +++ b/app/src/controllers/user/reducer.test.js @@ -22,7 +22,7 @@ import { SETTINGS_INITIAL_STATE, START_TIME_FORMAT_ABSOLUTE, SET_PHOTO_TIME_STAMP, - ASSIGN_TO_RROJECT_SUCCESS, + ASSIGN_TO_PROJECT_SUCCESS, UNASSIGN_FROM_PROJECT_SUCCESS, SET_API_KEYS, } from './constants'; @@ -145,7 +145,7 @@ describe('user reducer', () => { expect(userAssignedProjectReducer(oldState, { type: 'foo' })).toBe(oldState); }); - test('should handle ASSIGN_TO_RROJECT_SUCCESS', () => { + test('should handle ASSIGN_TO_PROJECT_SUCCESS', () => { const payloadProject = { projectName: 'superadmin_personal', entryType: 'INTERNAL', @@ -163,7 +163,7 @@ describe('user reducer', () => { }; expect( userAssignedProjectReducer(oldState, { - type: ASSIGN_TO_RROJECT_SUCCESS, + type: ASSIGN_TO_PROJECT_SUCCESS, payload: payloadProject, }), ).toEqual(assignResult); diff --git a/app/src/controllers/user/sagas.js b/app/src/controllers/user/sagas.js index b5aafa016e..a94a76b798 100644 --- a/app/src/controllers/user/sagas.js +++ b/app/src/controllers/user/sagas.js @@ -22,7 +22,7 @@ import { PROJECT_MANAGER } from 'common/constants/projectRoles'; import { getStorageItem, setStorageItem } from 'common/utils/storageUtils'; import { userIdSelector, userInfoSelector } from './selectors'; import { - ASSIGN_TO_RROJECT, + ASSIGN_TO_PROJECT, UNASSIGN_FROM_PROJECT, SET_ACTIVE_PROJECT, ADD_API_KEY, @@ -268,7 +268,7 @@ function* watchFetchUser() { } function* watchAssignToProject() { - yield takeLatest(ASSIGN_TO_RROJECT, assignToProject); + yield takeLatest(ASSIGN_TO_PROJECT, assignToProject); } function* watchUnassignFromProject() { diff --git a/app/src/pages/inside/profilePage/profilePage.jsx b/app/src/pages/inside/profilePage/profilePage.jsx index 1c0ce463a7..d3630acbde 100644 --- a/app/src/pages/inside/profilePage/profilePage.jsx +++ b/app/src/pages/inside/profilePage/profilePage.jsx @@ -23,6 +23,7 @@ import { connect } from 'react-redux'; import { PageLayout, PageHeader } from 'layouts/pageLayout'; import { PROFILE_PAGE } from 'components/main/analytics/events'; import { userProfileRouteSelector, USER_PROFILE_SUB_PAGE } from 'controllers/pages'; +import { allowDeleteAccountSelector } from 'controllers/appInfo/selectors'; import { NavigationTabs } from 'components/main/navigationTabs'; import { API_KEYS_ROUTE, @@ -85,6 +86,7 @@ const getNavigationTabsConfig = (formatMessage) => ({ @connect((state) => ({ activeTab: userProfileRouteSelector(state), + allowDeleteAccount: allowDeleteAccountSelector(state), })) @injectIntl @track({ page: PROFILE_PAGE }) @@ -93,11 +95,13 @@ export class ProfilePage extends Component { intl: PropTypes.object.isRequired, activeTab: PropTypes.string, dispatch: PropTypes.func, + allowDeleteAccount: PropTypes.bool, }; static defaultProps = { activeTab: PROJECT_ASSIGNMENT_ROUTE, dispatch: () => {}, + allowDeleteAccount: false, }; getBreadcrumbs = () => [{ title: this.props.intl.formatMessage(messages.profilePageTitle) }]; @@ -117,7 +121,7 @@ export class ProfilePage extends Component {
- + {this.props.allowDeleteAccount && }
From 8f51d164b7e2fa596b35bb1f1fe21b37345e0342 Mon Sep 17 00:00:00 2001 From: Iukou Siarhei <45054016+BlazarQSO@users.noreply.github.com> Date: Wed, 8 Nov 2023 19:01:07 +0300 Subject: [PATCH 5/9] EPMRPP-85839 || Add events for API KEYS (#3637) * EPMRPP-85839 || Add events for API KEYS * EPMRPP-85839 || fix accessibility bugs * EPMRPP-85839 || Code Review fix - 1 --- .../events/ga4Events/profilePageEvent.js | 63 +++++++++++++++++-- .../apiKeys/apiKeysBlock/apiKeysBlock.jsx | 38 ++++++++++- .../apiKeys/noApiKeysBlock/noApiKeysBlock.jsx | 26 +++++++- .../localizationBlock/localizationBlock.jsx | 4 +- .../apiKeyGeneratedModal.jsx | 4 ++ .../generateApiKeyModal.jsx | 4 ++ .../revokeApiKeyModal/revokeApiKeyModal.jsx | 4 ++ .../pages/inside/profilePage/profilePage.jsx | 2 + 8 files changed, 132 insertions(+), 13 deletions(-) diff --git a/app/src/components/main/analytics/events/ga4Events/profilePageEvent.js b/app/src/components/main/analytics/events/ga4Events/profilePageEvent.js index fdf375a77e..0a299a8cbc 100644 --- a/app/src/components/main/analytics/events/ga4Events/profilePageEvent.js +++ b/app/src/components/main/analytics/events/ga4Events/profilePageEvent.js @@ -14,18 +14,69 @@ * limitations under the License. */ +import { getBasicClickEventParameters } from '../common/ga4Utils'; + const PROFILE_PAGE = 'profile'; -const BASIC_EVENT_PARAMETERS_PROFILE = { - action: 'click', - category: PROFILE_PAGE, - place: PROFILE_PAGE, -}; +const BASIC_EVENT_PARAMETERS_PROFILE = getBasicClickEventParameters(PROFILE_PAGE); -export const PROFILE_EVENT = { +export const PROFILE_EVENTS = { CHANGE_LANGUAGE: (lang) => ({ ...BASIC_EVENT_PARAMETERS_PROFILE, + place: PROFILE_PAGE, type: lang, element_name: 'language_drop_down', }), + + CLICK_API_KEYS_TAB_EVENT: { + ...BASIC_EVENT_PARAMETERS_PROFILE, + element_name: 'tab_api_keys', + }, + + CLICK_GENERATE_BUTTON_WITH_API_KEY: { + ...BASIC_EVENT_PARAMETERS_PROFILE, + element_name: 'generate_api_key', + type: 'with_api_key', + }, + + CLICK_GENERATE_BUTTON_NO_API_KEY: { + ...BASIC_EVENT_PARAMETERS_PROFILE, + element_name: 'generate_api_key', + type: 'no_api_key', + }, + + CLICK_GENERATE_API_KEY_BUTTON_IN_MODAL: { + ...BASIC_EVENT_PARAMETERS_PROFILE, + element_name: 'generate', + modal: 'generate_api_key', + }, + + CLICK_COPY_TO_CLIPBOARD_BUTTON: { + ...BASIC_EVENT_PARAMETERS_PROFILE, + element_name: 'copy', + modal: 'api_key_generated', + }, + + CLICK_DOCUMENTATION_LINK_WITH_API_KEY: { + ...BASIC_EVENT_PARAMETERS_PROFILE, + link_name: 'documentation', + place: 'with_api_key', + }, + + CLICK_DOCUMENTATION_LINK_NO_API_KEY: { + ...BASIC_EVENT_PARAMETERS_PROFILE, + link_name: 'documentation', + place: 'no_api_key', + }, + + CLICK_REVOKE_BUTTON: { + ...BASIC_EVENT_PARAMETERS_PROFILE, + element_name: 'revoke', + }, + + CLICK_REVOKE_BUTTON_IN_MODAL: { + ...BASIC_EVENT_PARAMETERS_PROFILE, + element_name: 'revoke', + modal: 'revoke_api_key', + }, }; diff --git a/app/src/pages/inside/profilePage/apiKeys/apiKeysBlock/apiKeysBlock.jsx b/app/src/pages/inside/profilePage/apiKeys/apiKeysBlock/apiKeysBlock.jsx index 77466bddb9..adf62b9224 100644 --- a/app/src/pages/inside/profilePage/apiKeys/apiKeysBlock/apiKeysBlock.jsx +++ b/app/src/pages/inside/profilePage/apiKeys/apiKeysBlock/apiKeysBlock.jsx @@ -17,6 +17,7 @@ import React from 'react'; import Parser from 'html-react-parser'; import { useIntl, defineMessages } from 'react-intl'; +import { useTracking } from 'react-tracking'; import PropTypes from 'prop-types'; import classNames from 'classnames/bind'; import { useDispatch } from 'react-redux'; @@ -26,6 +27,8 @@ import { ScrollWrapper } from 'components/main/scrollWrapper'; import { daysFromNow, createExternalLink } from 'common/utils'; import { GhostButton } from 'components/buttons/ghostButton'; import { docsReferences } from 'common/utils/referenceDictionary'; +import { PROFILE_EVENTS } from 'analyticsEvents/profilePageEvent'; +import { ENTER_KEY_CODE } from 'common/constants/keyCodes'; import styles from './apiKeysBlock.scss'; const cx = classNames.bind(styles); @@ -56,13 +59,42 @@ const messages = defineMessages({ export const ApiKeysBlock = ({ apiKeys }) => { const { formatMessage } = useIntl(); const dispatch = useDispatch(); + const { trackEvent } = useTracking(); - const onGenerateClick = () => dispatch(showModalAction({ id: 'generateApiKeyModal' })); - const onRevokeClick = (key) => dispatch(showModalAction({ id: 'revokeApiKeyModal', data: key })); + const onGenerateClick = () => { + dispatch(showModalAction({ id: 'generateApiKeyModal' })); + trackEvent(PROFILE_EVENTS.CLICK_GENERATE_BUTTON_WITH_API_KEY); + }; + + const onRevokeClick = (key) => { + dispatch(showModalAction({ id: 'revokeApiKeyModal', data: key })); + trackEvent(PROFILE_EVENTS.CLICK_REVOKE_BUTTON); + }; + + const onDocumentationClick = (event) => { + const { tagName } = event.target; + + if (tagName === 'A') { + trackEvent(PROFILE_EVENTS.CLICK_DOCUMENTATION_LINK_WITH_API_KEY); + } + }; + + const onDocumentationKeyDown = (event) => { + const { keyCode } = event; + const { tagName } = event.target; + + if (tagName === 'A' && keyCode === ENTER_KEY_CODE) { + trackEvent(PROFILE_EVENTS.CLICK_DOCUMENTATION_LINK_WITH_API_KEY); + } + }; return ( <> -
+
{Parser( formatMessage(messages.description, { a: (data) => diff --git a/app/src/pages/inside/profilePage/apiKeys/noApiKeysBlock/noApiKeysBlock.jsx b/app/src/pages/inside/profilePage/apiKeys/noApiKeysBlock/noApiKeysBlock.jsx index 2c15ce97c6..d904a31ed7 100644 --- a/app/src/pages/inside/profilePage/apiKeys/noApiKeysBlock/noApiKeysBlock.jsx +++ b/app/src/pages/inside/profilePage/apiKeys/noApiKeysBlock/noApiKeysBlock.jsx @@ -16,11 +16,14 @@ import React from 'react'; import { useIntl, defineMessages } from 'react-intl'; +import { useTracking } from 'react-tracking'; import classNames from 'classnames/bind'; import { useDispatch } from 'react-redux'; import { showModalAction } from 'controllers/modal'; import { GhostButton } from 'components/buttons/ghostButton'; import { docsReferences } from 'common/utils/referenceDictionary'; +import { PROFILE_EVENTS } from 'analyticsEvents/profilePageEvent'; +import { ENTER_KEY_CODE } from 'common/constants/keyCodes'; import styles from './noApiKeysBlock.scss'; const cx = classNames.bind(styles); @@ -46,9 +49,23 @@ const messages = defineMessages({ export const NoApiKeysBlock = () => { const { formatMessage } = useIntl(); + const { trackEvent } = useTracking(); const dispatch = useDispatch(); - const onGenerateClick = () => dispatch(showModalAction({ id: 'generateApiKeyModal' })); + const onGenerateClick = () => { + dispatch(showModalAction({ id: 'generateApiKeyModal' })); + trackEvent(PROFILE_EVENTS.CLICK_GENERATE_BUTTON_NO_API_KEY); + }; + + const onDocumentationClick = () => { + trackEvent(PROFILE_EVENTS.CLICK_DOCUMENTATION_LINK_NO_API_KEY); + }; + + const onDocumentationKeyDown = ({ keyCode }) => { + if (keyCode === ENTER_KEY_CODE) { + trackEvent(PROFILE_EVENTS.CLICK_DOCUMENTATION_LINK_NO_API_KEY); + } + }; return (
@@ -60,7 +77,12 @@ export const NoApiKeysBlock = () => { {formatMessage(messages.generateApiKey)}
-
+
{ const { trackEvent } = this.props.tracking; - trackEvent(PROFILE_EVENT.CHANGE_LANGUAGE(langNameByCode(lang))); + trackEvent(PROFILE_EVENTS.CHANGE_LANGUAGE(langNameByCode(lang))); updateStorageItem(APPLICATION_SETTINGS, { appLanguage: lang }); this.props.setLangAction(lang); }; diff --git a/app/src/pages/inside/profilePage/modals/apiKeyGeneratedModal/apiKeyGeneratedModal.jsx b/app/src/pages/inside/profilePage/modals/apiKeyGeneratedModal/apiKeyGeneratedModal.jsx index e39cf842a7..45438bca18 100644 --- a/app/src/pages/inside/profilePage/modals/apiKeyGeneratedModal/apiKeyGeneratedModal.jsx +++ b/app/src/pages/inside/profilePage/modals/apiKeyGeneratedModal/apiKeyGeneratedModal.jsx @@ -17,6 +17,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { useDispatch } from 'react-redux'; +import { useTracking } from 'react-tracking'; import { defineMessages, useIntl } from 'react-intl'; import classNames from 'classnames/bind'; import { ModalLayout, withModal } from 'components/main/modal'; @@ -25,6 +26,7 @@ import { Input } from 'components/inputs/input'; import { NOTIFICATION_TYPES, showNotification } from 'controllers/notification'; import { CopyToClipboard } from 'react-copy-to-clipboard'; import { BigButton } from 'components/buttons/bigButton'; +import { PROFILE_EVENTS } from 'analyticsEvents/profilePageEvent'; import styles from './apiKeyGeneratedModal.scss'; const cx = classNames.bind(styles); @@ -54,6 +56,7 @@ const messages = defineMessages({ const ApiKeyGenerated = ({ data }) => { const { formatMessage } = useIntl(); const dispatch = useDispatch(); + const { trackEvent } = useTracking(); const { apiKey } = data; const onCopy = () => { @@ -63,6 +66,7 @@ const ApiKeyGenerated = ({ data }) => { message: formatMessage(messages.successNotification), }), ); + trackEvent(PROFILE_EVENTS.CLICK_COPY_TO_CLIPBOARD_BUTTON); }; const copyButton = ( diff --git a/app/src/pages/inside/profilePage/modals/generateApiKeyModal/generateApiKeyModal.jsx b/app/src/pages/inside/profilePage/modals/generateApiKeyModal/generateApiKeyModal.jsx index 1d61bb1117..2405557f03 100644 --- a/app/src/pages/inside/profilePage/modals/generateApiKeyModal/generateApiKeyModal.jsx +++ b/app/src/pages/inside/profilePage/modals/generateApiKeyModal/generateApiKeyModal.jsx @@ -18,6 +18,7 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; import { defineMessages, useIntl } from 'react-intl'; import { connect, useDispatch } from 'react-redux'; +import { useTracking } from 'react-tracking'; import { formValueSelector, reduxForm } from 'redux-form'; import classNames from 'classnames/bind'; import { LoaderBlock } from 'pages/inside/profilePage/modals/loaderBlock'; @@ -34,6 +35,7 @@ import { import { COMMON_LOCALE_KEYS } from 'common/constants/localization'; import { showModalAction } from 'controllers/modal'; import { addApiKeyAction, apiKeysSelector } from 'controllers/user'; +import { PROFILE_EVENTS } from 'analyticsEvents/profilePageEvent'; import styles from './generateApiKeyModal.scss'; const LABEL_WIDTH = 85; @@ -87,6 +89,7 @@ const lengthAndUniqueNameValidator = (existNames) => const GenerateApiKey = ({ invalid, handleSubmit, apiKeyName }) => { const { formatMessage } = useIntl(); const dispatch = useDispatch(); + const { trackEvent } = useTracking(); const [loading, setLoading] = useState(false); const onSuccessfulGeneration = (apiKey) => { @@ -103,6 +106,7 @@ const GenerateApiKey = ({ invalid, handleSubmit, apiKeyName }) => { onSuccessfulGeneration, ), ); + trackEvent(PROFILE_EVENTS.CLICK_GENERATE_API_KEY_BUTTON_IN_MODAL); }; const okButton = { diff --git a/app/src/pages/inside/profilePage/modals/revokeApiKeyModal/revokeApiKeyModal.jsx b/app/src/pages/inside/profilePage/modals/revokeApiKeyModal/revokeApiKeyModal.jsx index 87858a161e..1a5d6cb1d2 100644 --- a/app/src/pages/inside/profilePage/modals/revokeApiKeyModal/revokeApiKeyModal.jsx +++ b/app/src/pages/inside/profilePage/modals/revokeApiKeyModal/revokeApiKeyModal.jsx @@ -16,6 +16,7 @@ import React, { useState } from 'react'; import { useDispatch } from 'react-redux'; +import { useTracking } from 'react-tracking'; import PropTypes from 'prop-types'; import { defineMessages, useIntl } from 'react-intl'; import classNames from 'classnames/bind'; @@ -23,6 +24,7 @@ import { LoaderBlock } from 'pages/inside/profilePage/modals/loaderBlock'; import { ModalLayout, withModal } from 'components/main/modal'; import { COMMON_LOCALE_KEYS } from 'common/constants/localization'; import { deleteApiKeyAction } from 'controllers/user'; +import { PROFILE_EVENTS } from 'analyticsEvents/profilePageEvent'; import styles from './revokeApiKeyModal.scss'; const cx = classNames.bind(styles); @@ -56,6 +58,7 @@ const messages = defineMessages({ const RevokeApiKey = ({ data }) => { const { formatMessage } = useIntl(); const dispatch = useDispatch(); + const { trackEvent } = useTracking(); const { name, id } = data; const [loading, setLoading] = useState(false); @@ -69,6 +72,7 @@ const RevokeApiKey = ({ data }) => { closeModal, ), ); + trackEvent(PROFILE_EVENTS.CLICK_REVOKE_BUTTON_IN_MODAL); }; const revokeButton = { diff --git a/app/src/pages/inside/profilePage/profilePage.jsx b/app/src/pages/inside/profilePage/profilePage.jsx index d3630acbde..297943341b 100644 --- a/app/src/pages/inside/profilePage/profilePage.jsx +++ b/app/src/pages/inside/profilePage/profilePage.jsx @@ -31,6 +31,7 @@ import { PROJECT_ASSIGNMENT_ROUTE, } from 'common/constants/userProfileRoutes'; import { DeleteAccountBlock } from 'pages/inside/profilePage/deleteAccountBlock'; +import { PROFILE_EVENTS } from 'analyticsEvents/profilePageEvent'; import { PersonalInfoBlock } from './personalInfoBlock'; import { ApiKeys } from './apiKeys'; import { AssignedProjectsBlock } from './assignedProjectsBlock'; @@ -76,6 +77,7 @@ const getNavigationTabsConfig = (formatMessage) => ({ name: formatMessage(messages.profilePageProjectApiKeysTab), link: getProfilePageLink(API_KEYS_ROUTE), component: , + eventInfo: PROFILE_EVENTS.CLICK_API_KEYS_TAB_EVENT, }, [CONFIG_EXAMPLES_ROUTE]: { name: formatMessage(messages.profilePageConfigurationExamplesTab), From 1d6b3712b60828599f33fd9bf57132a9dc4d7c17 Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 9 Nov 2023 09:23:31 +0100 Subject: [PATCH 6/9] EPMRPP-87435 || Reset to global integrations button fix (#3641) --- .../integrationsList/integrationInfo/integrationInfo.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/integrations/integrationsList/integrationInfo/integrationInfo.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/integrations/integrationsList/integrationInfo/integrationInfo.jsx index 3e21867f1e..f75db6fce3 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/integrations/integrationsList/integrationInfo/integrationInfo.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/integrations/integrationsList/integrationInfo/integrationInfo.jsx @@ -225,7 +225,7 @@ export const IntegrationInfo = (props) => { const onResetProjectIntegration = () => { dispatch( showModalAction({ - id: 'deleteProjectIntegrationModal', + id: 'deleteIntegrationModal', data: { onConfirm: resetProjectIntegrations, modalTitle: formatMessage(messages.projectIntegrationReset), From 944d804aca49d866b454f649377a1d314594471e Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 9 Nov 2023 09:29:00 +0100 Subject: [PATCH 7/9] EPMRPP-81919 || Creational modals. Use 'create' title (#3642) --- .../defectTypeRow/defectTypeRow.jsx | 5 ++-- .../content/defectTypes/defectTypes.jsx | 14 +++------- .../addEditDefectTypeModal.jsx | 13 +++++----- .../content/elements/constants.js | 19 ++++++++++++++ .../content/elements/index.js | 3 ++- .../addEditNotificationModal.jsx | 26 ++++++++++++++----- .../content/notifications/notifications.jsx | 17 ++++++++---- .../createPatternAnalysisModal.jsx | 4 +-- 8 files changed, 67 insertions(+), 34 deletions(-) create mode 100644 app/src/pages/inside/projectSettingsPageContainer/content/elements/constants.js diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypeRow/defectTypeRow.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypeRow/defectTypeRow.jsx index a4e9786416..e380f2bd67 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypeRow/defectTypeRow.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypeRow/defectTypeRow.jsx @@ -1,5 +1,5 @@ /* - * Copyright 2022 EPAM Systems + * Copyright 2023 EPAM Systems * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import { showModalAction } from 'controllers/modal'; import { deleteDefectTypeAction, updateDefectTypeAction } from 'controllers/project'; import { PROJECT_SETTINGS_DEFECT_TYPES_EVENTS } from 'analyticsEvents/projectSettingsPageEvents'; import { NOTIFICATION_TYPES, showNotification } from 'controllers/notification'; +import { MODAL_ACTION_TYPE_EDIT } from '../../elements'; import { defectTypeShape } from '../defectTypeShape'; import { messages } from '../defectTypesMessages'; import styles from './defectTypeRow.scss'; @@ -116,7 +117,7 @@ export const DefectTypeRow = ({ data: { onSave: editDefect, defectType: { ...data }, - actionType: 'edit', + actionType: MODAL_ACTION_TYPE_EDIT, }, }), ); diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypes.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypes.jsx index c2c5eb64c7..acdfcd722d 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypes.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypes.jsx @@ -1,5 +1,5 @@ /* - * Copyright 2022 EPAM Systems + * Copyright 2023 EPAM Systems * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,21 +28,15 @@ import { DEFECT_TYPES_SEQUENCE } from 'common/constants/defectTypes'; import { Button } from 'componentLibrary/button'; import CreateDefectIcon from 'common/img/newIcons/create-subtype-inline.svg'; import DefectGroupIcon from 'common/img/newIcons/defect-group-inline.svg'; -import { - Divider, - TabDescription, -} from 'pages/inside/projectSettingsPageContainer/content/elements'; import { withTooltip } from 'componentLibrary/tooltip'; import { showModalAction } from 'controllers/modal'; -import { - MAX_DEFECT_TYPES_COUNT, - WARNING_DEFECT_TYPES_COUNT, -} from 'pages/inside/projectSettingsPageContainer/content/defectTypes/constants'; import { SystemMessage } from 'componentLibrary/systemMessage'; import { COMMON_LOCALE_KEYS } from 'common/constants/localization'; import { PROJECT_SETTINGS_DEFECT_TYPES_EVENTS } from 'analyticsEvents/projectSettingsPageEvents'; import { docsReferences, createExternalLink } from 'common/utils'; import { ENTER_KEY_CODE } from 'common/constants/keyCodes'; +import { Divider, TabDescription, MODAL_ACTION_TYPE_EDIT } from '../elements'; +import { MAX_DEFECT_TYPES_COUNT, WARNING_DEFECT_TYPES_COUNT } from './constants'; import { SettingsPageContent } from '../settingsPageContent'; import { DefectTypeRow } from './defectTypeRow'; import { messages } from './defectTypesMessages'; @@ -96,7 +90,7 @@ export const DefectTypes = ({ setHeaderTitleNode }) => { id: 'addEditDefectTypeModal', data: { onSave: addDefect, - actionType: 'add', + actionType: MODAL_ACTION_TYPE_EDIT, defectType: { color: defectGroup.color, typeRef: defectGroup.typeRef }, defectTypes, }, diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/modals/addEditDefectTypeModal/addEditDefectTypeModal.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/modals/addEditDefectTypeModal/addEditDefectTypeModal.jsx index 939738a46a..8e876ccd63 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/modals/addEditDefectTypeModal/addEditDefectTypeModal.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/modals/addEditDefectTypeModal/addEditDefectTypeModal.jsx @@ -1,5 +1,5 @@ /* - * Copyright 2022 EPAM Systems + * Copyright 2023 EPAM Systems * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ import { hideModalAction } from 'controllers/modal'; import { FieldText } from 'componentLibrary/fieldText'; import { HexColorPickerComponent } from 'components/main/hexColorPicker'; import { DEFECT_TYPES_MAP } from 'common/constants/defectTypes'; -import { FieldElement } from '../../../elements'; +import { FieldElement, MODAL_ACTION_TYPE_ADD } from '../../../elements'; import { NAME_FIELD_KEY, COLOR_FIELD_KEY, @@ -102,7 +102,6 @@ const messages = defineMessages({ }, }); -const ACTION_TYPE_ADD = 'add'; const FIELD = 'Field'; const AddEditDefectTypeModal = ({ @@ -149,7 +148,7 @@ const AddEditDefectTypeModal = ({ const submitActions = (formFieldValues) => { onSave( - actionType === ACTION_TYPE_ADD + actionType === MODAL_ACTION_TYPE_ADD ? formFieldValues : [{ ...formFieldValues, typeRef: defectType.typeRef }], ); @@ -157,7 +156,7 @@ const AddEditDefectTypeModal = ({ const okButton = { text: - actionType === ACTION_TYPE_ADD + actionType === MODAL_ACTION_TYPE_ADD ? formatMessage(COMMON_LOCALE_KEYS.CREATE) : formatMessage(COMMON_LOCALE_KEYS.SAVE), onClick: () => { @@ -183,9 +182,9 @@ const AddEditDefectTypeModal = ({ onClose={() => dispatch(hideModalAction())} allowCloseOutside={!dirty} > - {actionType === ACTION_TYPE_ADD && formatMessage(messages.description)} + {actionType === MODAL_ACTION_TYPE_ADD && formatMessage(messages.description)}
- {actionType === ACTION_TYPE_ADD && ( + {actionType === MODAL_ACTION_TYPE_ADD && ( { handleSubmit(submitActions)(); }, @@ -399,7 +407,11 @@ AddEditNotificationModal.propTypes = { notifications: PropTypes.array, onSave: PropTypes.func, eventsInfo: PropTypes.object, - actionType: PropTypes.string, + actionType: PropTypes.oneOf([ + MODAL_ACTION_TYPE_ADD, + MODAL_ACTION_TYPE_EDIT, + MODAL_ACTION_TYPE_COPY, + ]), }), initialize: PropTypes.func.isRequired, handleSubmit: PropTypes.func.isRequired, diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx index e0b950ae2c..5def731df3 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx @@ -1,5 +1,5 @@ /* - * Copyright 2022 EPAM Systems + * Copyright 2023 EPAM Systems * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,7 +47,14 @@ import { projectNotificationsLoadingSelector } from 'controllers/project/selecto import { SpinningPreloader } from 'components/preloaders/spinningPreloader'; import { PROJECT_SETTINGS_NOTIFICATIONS_EVENTS } from 'analyticsEvents/projectSettingsPageEvents'; import { docsReferences, createExternalLink } from 'common/utils'; -import { RuleList, FieldElement, NotificationRuleContent } from '../elements'; +import { + RuleList, + FieldElement, + NotificationRuleContent, + MODAL_ACTION_TYPE_ADD, + MODAL_ACTION_TYPE_EDIT, + MODAL_ACTION_TYPE_COPY, +} from '../elements'; import { Layout } from '../layout'; import { SettingsPageContent } from '../settingsPageContent'; import styles from './notifications.scss'; @@ -118,7 +125,7 @@ export const Notifications = ({ setHeaderTitleNode }) => { showModalAction({ id: 'addEditNotificationModal', data: { - actionType: 'add', + actionType: MODAL_ACTION_TYPE_ADD, onSave: confirmAdd, notification: DEFAULT_CASE_CONFIG, notifications, @@ -134,7 +141,7 @@ export const Notifications = ({ setHeaderTitleNode }) => { showModalAction({ id: 'addEditNotificationModal', data: { - actionType: 'edit', + actionType: MODAL_ACTION_TYPE_EDIT, onSave: confirmEdit, notification, notifications, @@ -164,7 +171,7 @@ export const Notifications = ({ setHeaderTitleNode }) => { showModalAction({ id: 'addEditNotificationModal', data: { - actionType: 'copy', + actionType: MODAL_ACTION_TYPE_COPY, onSave: (withoutAttributes) => confirmAdd(withoutAttributes), notification: { ...newNotification, diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/modals/createPatternAnalysisModal/createPatternAnalysisModal.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/modals/createPatternAnalysisModal/createPatternAnalysisModal.jsx index e6b216cf36..c483c09479 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/modals/createPatternAnalysisModal/createPatternAnalysisModal.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/modals/createPatternAnalysisModal/createPatternAnalysisModal.jsx @@ -1,5 +1,5 @@ /* - * Copyright 2022 EPAM Systems + * Copyright 2023 EPAM Systems * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ const CreatePatternAnalysisModal = ({ data, handleSubmit, initialize, dirty }) = const { formatMessage } = useIntl(); const okButton = { - text: formatMessage(COMMON_LOCALE_KEYS.SAVE), + text: formatMessage(COMMON_LOCALE_KEYS.CREATE), onClick: () => handleSubmit(onSave)(), }; const cancelButton = { From 94c2c27405f5370e61dfcebe439668d985cf8e60 Mon Sep 17 00:00:00 2001 From: Iukou Siarhei <45054016+BlazarQSO@users.noreply.github.com> Date: Thu, 9 Nov 2023 15:28:27 +0300 Subject: [PATCH 8/9] EPMRPP-82712 || Add events for feature Help and Support (#3634) * EPMRPP-82712 || Add events for feature Help and Support * EPMRPP-82712 || Code Review fix - 1 --- .../events/ga4Events/helpAndSupportEvents.js | 58 +++++++++++++++++++ .../components/main/analytics/events/index.js | 7 +-- .../analytics/events/sidebarFooterEvents.js | 19 ------ .../modal/requestSupportModal.jsx | 16 +---- .../sidebar/supportBlock/supportBlock.jsx | 17 +++--- 5 files changed, 70 insertions(+), 47 deletions(-) create mode 100644 app/src/components/main/analytics/events/ga4Events/helpAndSupportEvents.js diff --git a/app/src/components/main/analytics/events/ga4Events/helpAndSupportEvents.js b/app/src/components/main/analytics/events/ga4Events/helpAndSupportEvents.js new file mode 100644 index 0000000000..5cb45733d5 --- /dev/null +++ b/app/src/components/main/analytics/events/ga4Events/helpAndSupportEvents.js @@ -0,0 +1,58 @@ +/* + * Copyright 2023 EPAM Systems + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getBasicClickEventParameters, getBasicChooseEventParameters } from '../common/ga4Utils'; + +const HELP_AND_SUPPORT = 'help_and_support'; + +export const HELP_AND_SUPPORT_EVENTS = { + CLICK_HELP_AND_SUPPORT_BUTTON: { + ...getBasicClickEventParameters(HELP_AND_SUPPORT), + place: 'sidebar', + element_name: 'help_and_support', + }, + + CLICK_REQUEST_SUPPORT_BUTTON: { + ...getBasicClickEventParameters(HELP_AND_SUPPORT), + modal: 'help_and_support', + element_name: 'request_support', + }, + + CLICK_ON_SUPPORT_LINK: (linkName) => ({ + ...getBasicClickEventParameters(HELP_AND_SUPPORT), + modal: 'help_and_support', + link_name: linkName, + }), + + CLICK_SEND_REQUEST_SUPPORT_BUTTON: { + ...getBasicClickEventParameters(HELP_AND_SUPPORT), + modal: 'request_support', + element_name: 'send', + }, + + CHOOSE_INSTRUCTION_BUTTON: (typeName) => ({ + ...getBasicChooseEventParameters(HELP_AND_SUPPORT), + modal: 'help_and_support', + element_name: 'instruction', + type: typeName, + }), + + CLICK_ASK_A_QUESTION_BUTTON: { + ...getBasicClickEventParameters(HELP_AND_SUPPORT), + modal: 'help_and_support', + element_name: 'ask_a_question', + }, +}; diff --git a/app/src/components/main/analytics/events/index.js b/app/src/components/main/analytics/events/index.js index 045b3305b0..4297540761 100644 --- a/app/src/components/main/analytics/events/index.js +++ b/app/src/components/main/analytics/events/index.js @@ -21,12 +21,7 @@ export { } from './filtersPageEvents'; export { LAUNCHES_PAGE_EVENTS, LAUNCHES_MODAL_EVENTS, LAUNCHES_PAGE } from './launchesPageEvents'; export { LOGIN_PAGE_EVENTS, LOGIN_PAGE } from './loginPageEvents'; -export { - SIDEBAR_EVENTS, - ADMIN_SIDEBAR_EVENTS, - FOOTER_EVENTS, - HELP_AND_SUPPORT_EVENTS, -} from './sidebarFooterEvents'; +export { SIDEBAR_EVENTS, ADMIN_SIDEBAR_EVENTS, FOOTER_EVENTS } from './sidebarFooterEvents'; export { MEMBERS_PAGE, MEMBERS_PAGE_EVENTS } from './membersPageEvents'; export { PLUGINS_PAGE_EVENTS, diff --git a/app/src/components/main/analytics/events/sidebarFooterEvents.js b/app/src/components/main/analytics/events/sidebarFooterEvents.js index e16202ba6b..a2b79185c2 100644 --- a/app/src/components/main/analytics/events/sidebarFooterEvents.js +++ b/app/src/components/main/analytics/events/sidebarFooterEvents.js @@ -158,22 +158,3 @@ export const FOOTER_EVENTS = { label: `${pageNumber}#${page}`, }), }; - -const HELP_AND_SUPPORT = 'Help and Support'; -export const HELP_AND_SUPPORT_EVENTS = { - clickOnSupportModalBtn: (linkName) => ({ - category: HELP_AND_SUPPORT, - action: 'Click on Button/Link on Modal Help and Support', - label: linkName || HELP_AND_SUPPORT, - }), - clickInstructionLink: (label) => ({ - category: HELP_AND_SUPPORT, - action: 'Click on Button Instruction on Modal Help and Support ', - label, - }), - clickOnRequestModalBtn: (btn) => ({ - category: HELP_AND_SUPPORT, - action: 'Click on Button on Modal Request Support', - label: btn, - }), -}; diff --git a/app/src/layouts/common/sidebar/supportBlock/modal/requestSupportModal.jsx b/app/src/layouts/common/sidebar/supportBlock/modal/requestSupportModal.jsx index 494855ff6d..537d973488 100644 --- a/app/src/layouts/common/sidebar/supportBlock/modal/requestSupportModal.jsx +++ b/app/src/layouts/common/sidebar/supportBlock/modal/requestSupportModal.jsx @@ -31,7 +31,7 @@ import { InputOutside } from 'components/inputs/inputOutside'; import LoginIcon from 'common/img/login-field-icon-inline.svg'; import { COMMON_LOCALE_KEYS } from 'common/constants/localization'; import { NOTIFICATION_TYPES, showNotification } from 'controllers/notification'; -import { HELP_AND_SUPPORT_EVENTS } from 'components/main/analytics/events'; +import { HELP_AND_SUPPORT_EVENTS } from 'analyticsEvents/helpAndSupportEvents'; import { messages } from '../messages'; import styles from './requestSupportModal.scss'; @@ -88,19 +88,9 @@ const RequestSupport = ({ handleSubmit, initialize, invalid }) => { }, disabled: invalid, attributes: { type: 'submit', form: REQUEST_FORM_ID }, - eventInfo: HELP_AND_SUPPORT_EVENTS.clickOnRequestModalBtn( - COMMON_LOCALE_KEYS.SEND.defaultMessage, - ), + eventInfo: HELP_AND_SUPPORT_EVENTS.CLICK_SEND_REQUEST_SUPPORT_BUTTON, }} - cancelButton={{ - text: formatMessage(COMMON_LOCALE_KEYS.CANCEL), - eventInfo: HELP_AND_SUPPORT_EVENTS.clickOnRequestModalBtn( - COMMON_LOCALE_KEYS.CANCEL.defaultMessage, - ), - }} - closeIconEventInfo={HELP_AND_SUPPORT_EVENTS.clickOnRequestModalBtn( - COMMON_LOCALE_KEYS.CLOSE.defaultMessage, - )} + cancelButton={{ text: formatMessage(COMMON_LOCALE_KEYS.CANCEL) }} > <> {Parser(formatMessage(messages.modalText))} diff --git a/app/src/layouts/common/sidebar/supportBlock/supportBlock.jsx b/app/src/layouts/common/sidebar/supportBlock/supportBlock.jsx index 3acef265cd..5b97a2c2d8 100644 --- a/app/src/layouts/common/sidebar/supportBlock/supportBlock.jsx +++ b/app/src/layouts/common/sidebar/supportBlock/supportBlock.jsx @@ -25,7 +25,7 @@ import { withTooltip } from 'components/main/tooltips/tooltip'; import { TextTooltip } from 'components/main/tooltips/textTooltip'; import { InputDropdown } from 'components/inputs/inputDropdown'; import { GhostButton } from 'components/buttons/ghostButton'; -import { HELP_AND_SUPPORT_EVENTS } from 'components/main/analytics/events'; +import { HELP_AND_SUPPORT_EVENTS } from 'analyticsEvents/helpAndSupportEvents'; import { showModalAction } from 'controllers/modal'; import { referenceDictionary } from 'common/utils'; import { messages } from './messages'; @@ -70,7 +70,7 @@ export const SupportBlock = ({ options }) => { const toggleModal = () => { setModalShown(!isModalShown); - !isModalShown && trackEvent(HELP_AND_SUPPORT_EVENTS.clickOnSupportModalBtn()); + !isModalShown && trackEvent(HELP_AND_SUPPORT_EVENTS.CLICK_HELP_AND_SUPPORT_BUTTON); }; const openModal = () => { @@ -80,20 +80,19 @@ export const SupportBlock = ({ options }) => { id: 'requestSupportModal', }), ); - trackEvent( - HELP_AND_SUPPORT_EVENTS.clickOnSupportModalBtn(messages.requestSupport.defaultMessage), - ); + trackEvent(HELP_AND_SUPPORT_EVENTS.CLICK_REQUEST_SUPPORT_BUTTON); }; const onClickLink = (nameLink) => { toggleModal(); - trackEvent(HELP_AND_SUPPORT_EVENTS.clickOnSupportModalBtn(nameLink)); + trackEvent(HELP_AND_SUPPORT_EVENTS.CLICK_ON_SUPPORT_LINK(nameLink)); }; const onClickUserChoiceBtn = () => { toggleModal(); const label = options.find(({ value }) => value === userChoice).label; - trackEvent(HELP_AND_SUPPORT_EVENTS.clickInstructionLink(label)); + !userChoice && trackEvent(HELP_AND_SUPPORT_EVENTS.CLICK_ASK_A_QUESTION_BUTTON); + userChoice && trackEvent(HELP_AND_SUPPORT_EVENTS.CHOOSE_INSTRUCTION_BUTTON(label)); }; return ( @@ -141,7 +140,7 @@ export const SupportBlock = ({ options }) => { target="_blank" rel="noreferrer noopener" className={cx('support-link')} - onClick={() => onClickLink('email')} + onClick={() => onClickLink('support_team')} key={EMAIL_SUPPORT} > {formatMessage(messages.ourSupportTeam)} @@ -153,7 +152,7 @@ export const SupportBlock = ({ options }) => { target="_blank" rel="noreferrer noopener" className={cx('support-link')} - onClick={() => onClickLink(messages.slackChannel.defaultMessage)} + onClick={() => onClickLink('slack')} key={referenceDictionary.rpSlack} > {formatMessage(messages.slackChannel)} From 6bef3a0560da8b53276f6a67931a31ebc7535a8f Mon Sep 17 00:00:00 2001 From: Bam6ycha <84175555+Bam6ycha@users.noreply.github.com> Date: Fri, 10 Nov 2023 02:54:07 +0500 Subject: [PATCH 9/9] EPMRPP-87396 || Error on extension page (#3639) --- app/src/components/extensionLoader/hooks.js | 1 + .../uiExtensionPage/uiExtensionPage.jsx | 47 +++++++++++-------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/app/src/components/extensionLoader/hooks.js b/app/src/components/extensionLoader/hooks.js index b67ddad764..f6d86dad7c 100644 --- a/app/src/components/extensionLoader/hooks.js +++ b/app/src/components/extensionLoader/hooks.js @@ -28,6 +28,7 @@ const useDynamicScript = (scope, url) => { element.onerror = () => { setReady(false); setFailed(true); + element.remove(); }; document.head.appendChild(element); diff --git a/app/src/pages/common/uiExtensionPage/uiExtensionPage.jsx b/app/src/pages/common/uiExtensionPage/uiExtensionPage.jsx index 3475298c5d..242aa559df 100644 --- a/app/src/pages/common/uiExtensionPage/uiExtensionPage.jsx +++ b/app/src/pages/common/uiExtensionPage/uiExtensionPage.jsx @@ -32,26 +32,33 @@ export const UiExtensionPage = ({ extensions, activePluginPage }) => { const [headerNodes, setHeaderNodes] = useState({}); - const pageLayout = - extension && extension.newLayout ? ( - <> -
-
- {headerNodes.children} -
-
- - - - - ) : ( - - {extension && } - - - - - ); + let pageLayout = null; + + if (extension) { + if (extension.newLayout) { + pageLayout = ( + <> +
+
+ {headerNodes.children} +
+
+ + + + + ); + } else { + pageLayout = ( + + + + + + + ); + } + } return pageLayout; };