From 6ffa097dc8d2925808530317c84ce7d239312af5 Mon Sep 17 00:00:00 2001 From: Dzmitry Kosarau Date: Thu, 2 Nov 2023 16:44:57 +0500 Subject: [PATCH 1/3] EPMRPP-82207 || Add events for Documentation links in Project Settings --- .../main/analytics/events/common/utils.js | 14 +++++++ .../ga4Events/projectSettingsPageEvents.js | 16 ++++++- .../autoAnalysis/autoAnalysis.jsx | 12 ++++++ .../indexSettings/indexSettings.jsx | 13 ++++++ .../similarItems/similarItems.jsx | 12 ++++++ .../uniqueErrors/uniqueErrors.jsx | 12 ++++++ .../content/defectTypes/defectTypes.jsx | 42 +++++++++---------- .../tabDescription/tabDescription.jsx | 12 +++++- .../content/layout/layout.jsx | 17 +++++++- .../content/notifications/notifications.jsx | 14 ++++++- .../patternAnalysis/patternAnalysis.jsx | 7 ++++ .../patternAnalysisContent.jsx | 12 ++++++ 12 files changed, 153 insertions(+), 30 deletions(-) diff --git a/app/src/components/main/analytics/events/common/utils.js b/app/src/components/main/analytics/events/common/utils.js index 14d5fbfd46..bc6f592589 100644 --- a/app/src/components/main/analytics/events/common/utils.js +++ b/app/src/components/main/analytics/events/common/utils.js @@ -14,6 +14,8 @@ * limitations under the License. */ +import { ENTER_KEY_CODE } from 'common/constants/keyCodes'; + // conditions should look like 'statistics$defects$product_bug$pb001' export const getDefectTypeLabel = (condition) => { try { @@ -42,3 +44,15 @@ export const getIncludedData = ({ includeData, includeComments, includeLogs }) = .filter((key) => analyticsDataMap[key]) .join('#'); }; + +export const handleExternalLinkClick = (trackEvent, event) => ({ target: { tagName } }) => { + if (tagName === 'A') { + trackEvent(event); + } +}; + +export const handleExternalLinkKeyDown = (trackEvent, event) => ({ keyCode }) => { + if (keyCode === ENTER_KEY_CODE) { + trackEvent(event); + } +}; diff --git a/app/src/components/main/analytics/events/ga4Events/projectSettingsPageEvents.js b/app/src/components/main/analytics/events/ga4Events/projectSettingsPageEvents.js index abcb49d622..9b160a7e33 100644 --- a/app/src/components/main/analytics/events/ga4Events/projectSettingsPageEvents.js +++ b/app/src/components/main/analytics/events/ga4Events/projectSettingsPageEvents.js @@ -91,6 +91,12 @@ export const PROJECT_SETTINGS_ANALYZER_EVENTS = { status: getStatus(status), type: type ? 'exclude' : 'include', }), + + CLICK_LINK_DOCUMENTATION: (place) => ({ + ...BASIC_EVENT_PARAMETERS, + place: `${ANALYZER}_${place}`, + link_name: 'documentation', + }), }; export const PROJECT_SETTINGS_DEMO_DATA_EVENTS = { @@ -123,10 +129,11 @@ export const PROJECT_SETTINGS_NOTIFICATIONS_EVENTS = { switcher: getSwitcher(switcher), }), - CLICK_LINK_DOCUMENTATION: { + CLICK_LINK_DOCUMENTATION: (place) => ({ ...BASIC_EVENT_PARAMETERS_NOTIFICATIONS, + ...(place && { place }), link_name: 'documentation', - }, + }), CLICK_CREATE_RULE_BUTTON: { ...BASIC_EVENT_PARAMETERS_NOTIFICATIONS, @@ -235,4 +242,9 @@ export const PROJECT_SETTINGS_PATTERN_ANALYSIS_EVENTS = { element_name: 'pattern_name', status: 'open', }, + CLICK_LINK_DOCUMENTATION: (place) => ({ + ...BASIC_EVENT_PARAMETERS_PATTERN_ANALYSIS, + ...(place && { place }), + link_name: 'documentation', + }), }; diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/autoAnalysis/autoAnalysis.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/autoAnalysis/autoAnalysis.jsx index 049d826ef3..8da99d9ca3 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/autoAnalysis/autoAnalysis.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/autoAnalysis/autoAnalysis.jsx @@ -31,6 +31,10 @@ import { useTracking } from 'react-tracking'; import Parser from 'html-react-parser'; import { PROJECT_SETTINGS_ANALYZER_EVENTS } from 'analyticsEvents/projectSettingsPageEvents'; import { docsReferences, createExternalLink } from 'common/utils'; +import { + handleExternalLinkClick, + handleExternalLinkKeyDown, +} from 'components/main/analytics/events/common/utils'; import { Layout } from '../../layout'; import { FieldElement, LabeledPreloader } from '../../elements'; import { messages } from './messages'; @@ -122,6 +126,14 @@ const AutoAnalysis = ({ return ( diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/indexSettings/indexSettings.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/indexSettings/indexSettings.jsx index 41c2a16e00..b3acb3dc2f 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/indexSettings/indexSettings.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/indexSettings/indexSettings.jsx @@ -26,6 +26,11 @@ import { useTracking } from 'react-tracking'; import { showModalAction } from 'controllers/modal'; import { useDispatch } from 'react-redux'; import { docsReferences, createExternalLink } from 'common/utils'; +import { + handleExternalLinkClick, + handleExternalLinkKeyDown, +} from 'components/main/analytics/events/common/utils'; +import { PROJECT_SETTINGS_ANALYZER_EVENTS } from 'components/main/analytics/events/ga4Events/projectSettingsPageEvents'; import { Layout } from '../../layout'; import { LabeledPreloader } from '../../elements'; import { messages } from './messages'; @@ -52,6 +57,14 @@ const IndexSettings = ({ indexingRunning, analyzerUnavailableTitle, hasPermissio return ( diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/similarItems/similarItems.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/similarItems/similarItems.jsx index a69b305f76..1443c9cd4c 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/similarItems/similarItems.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/similarItems/similarItems.jsx @@ -27,6 +27,10 @@ import { bindMessageToValidator, validate } from 'common/utils/validation'; import { useTracking } from 'react-tracking'; import { PROJECT_SETTINGS_ANALYZER_EVENTS } from 'analyticsEvents/projectSettingsPageEvents'; import { docsReferences, createExternalLink } from 'common/utils'; +import { + handleExternalLinkClick, + handleExternalLinkKeyDown, +} from 'components/main/analytics/events/common/utils'; import { FIELD } from 'common/constants/dataAutomation'; import { Layout } from '../../layout'; import { LabeledPreloader, FieldElement } from '../../elements'; @@ -66,6 +70,14 @@ const SimilarItems = ({ return ( diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/uniqueErrors/uniqueErrors.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/uniqueErrors/uniqueErrors.jsx index ef404d58ba..d5c4c6c9ba 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/uniqueErrors/uniqueErrors.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/uniqueErrors/uniqueErrors.jsx @@ -26,6 +26,10 @@ import { Checkbox } from 'componentLibrary/checkbox'; import { useTracking } from 'react-tracking'; import { PROJECT_SETTINGS_ANALYZER_EVENTS } from 'analyticsEvents/projectSettingsPageEvents'; import { docsReferences, createExternalLink } from 'common/utils'; +import { + handleExternalLinkClick, + handleExternalLinkKeyDown, +} from 'components/main/analytics/events/common/utils'; import { FieldElement, LabeledPreloader } from '../../elements'; import { messages } from './messages'; import { UNIQUE_ERROR_ENABLED, UNIQUE_ERROR_REMOVE_NUMBERS } from '../constants'; @@ -84,6 +88,14 @@ const UniqueErrors = ({ return ( diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypes.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypes.jsx index acdfcd722d..6c796712f3 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypes.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/defectTypes/defectTypes.jsx @@ -34,7 +34,10 @@ 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 { + handleExternalLinkClick, + handleExternalLinkKeyDown, +} from 'components/main/analytics/events/common/utils'; import { Divider, TabDescription, MODAL_ACTION_TYPE_EDIT } from '../elements'; import { MAX_DEFECT_TYPES_COUNT, WARNING_DEFECT_TYPES_COUNT } from './constants'; import { SettingsPageContent } from '../settingsPageContent'; @@ -98,20 +101,6 @@ export const DefectTypes = ({ setHeaderTitleNode }) => { ); }; - const handleDocumentationClick = (event) => { - const { tagName } = event.target; - - if (tagName === 'A') { - trackEvent(PROJECT_SETTINGS_DEFECT_TYPES_EVENTS.CLICK_DOCUMENTATION_LINK); - } - }; - - const handleDocumentationKeyDown = ({ keyCode }) => { - if (keyCode === ENTER_KEY_CODE) { - trackEvent(PROJECT_SETTINGS_DEFECT_TYPES_EVENTS.CLICK_DOCUMENTATION_LINK); - } - }; - const defectTypesLength = useMemo( () => DEFECT_TYPES_SEQUENCE.reduce((acc, groupName) => defectTypes[groupName].length + acc, 0), [defectTypes], @@ -158,14 +147,21 @@ export const DefectTypes = ({ setHeaderTitleNode }) => { return ( - - - {Parser( - formatMessage(messages.description, { - a: (data) => createExternalLink(data, docsReferences.workWithReports), - }), - )} - + + {Parser( + formatMessage(messages.description, { + a: (data) => createExternalLink(data, docsReferences.workWithReports), + }), + )} {(isInformationMessage || !canAddNewDefectType) && ( diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/elements/tabDescription/tabDescription.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/elements/tabDescription/tabDescription.jsx index f453596431..4be62afce4 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/elements/tabDescription/tabDescription.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/elements/tabDescription/tabDescription.jsx @@ -21,9 +21,17 @@ import styles from './tabDescription.scss'; const cx = className.bind(styles); -export const TabDescription = ({ children }) => ( - {children} +export const TabDescription = ({ children, handleClick, handleKeyDown }) => ( + + {children} + ); TabDescription.propTypes = { children: PropTypes.node.isRequired, + handleClick: PropTypes.func, + handleKeyDown: PropTypes.func, +}; +TabDescription.defaultProps = { + handleClick: () => {}, + handleKeyDown: () => {}, }; diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/layout/layout.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/layout/layout.jsx index d3560d67a0..2001fae244 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/layout/layout.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/layout/layout.jsx @@ -22,10 +22,17 @@ import styles from './layout.scss'; const cx = classNames.bind(styles); -export const Layout = ({ description, children }) => { +export const Layout = ({ + description, + children, + handleDescriptionClick, + handleDescriptionKeyDown, +}) => { return ( <> - {description} + + {description} +
{children}
@@ -34,4 +41,10 @@ export const Layout = ({ description, children }) => { Layout.propTypes = { description: PropTypes.string.isRequired, children: PropTypes.node.isRequired, + handleDescriptionClick: PropTypes.func, + handleDescriptionKeyDown: PropTypes.func, +}; +Layout.defaultProps = { + handleDescriptionClick: () => {}, + handleDescriptionKeyDown: () => {}, }; diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx index 5def731df3..97d13c1aaa 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx @@ -47,6 +47,10 @@ 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 { + handleExternalLinkClick, + handleExternalLinkKeyDown, +} from 'components/main/analytics/events/common/utils'; import { RuleList, FieldElement, @@ -245,7 +249,7 @@ export const Notifications = ({ setHeaderTitleNode }) => { }; const handleDocumentationClick = () => { - trackEvent(PROJECT_SETTINGS_NOTIFICATIONS_EVENTS.CLICK_LINK_DOCUMENTATION); + trackEvent(PROJECT_SETTINGS_NOTIFICATIONS_EVENTS.CLICK_LINK_DOCUMENTATION('no_notifications')); }; if (loading) { @@ -257,6 +261,14 @@ export const Notifications = ({ setHeaderTitleNode }) => { {notifications.length ? ( createExternalLink(data, docsReferences.notificationsDocs), diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/patternAnalysis.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/patternAnalysis.jsx index 37a3ba224b..f2c2c2c49e 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/patternAnalysis.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/patternAnalysis.jsx @@ -73,6 +73,12 @@ export const PatternAnalysis = ({ setHeaderTitleNode }) => { const isAbleToCreate = canUpdateSettings(userRole, projectRole); + const handleDocumentationClick = () => { + trackEvent( + PROJECT_SETTINGS_PATTERN_ANALYSIS_EVENTS.CLICK_LINK_DOCUMENTATION('no_pattern_analysis'), + ); + }; + return ( <> {patterns.length > 0 ? ( @@ -93,6 +99,7 @@ export const PatternAnalysis = ({ setHeaderTitleNode }) => { documentationLink={docsReferences.emptyStatePatternAnalysisDocs} disableButton={!isAbleToCreate} handleButton={onAddPattern} + handleDocumentationClick={handleDocumentationClick} /> )} diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/patternAnalysisContent/patternAnalysisContent.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/patternAnalysisContent/patternAnalysisContent.jsx index fcd7585f73..10f6c6dd55 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/patternAnalysisContent/patternAnalysisContent.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/patternAnalysis/patternAnalysisContent/patternAnalysisContent.jsx @@ -37,6 +37,10 @@ import BinIcon from 'common/img/newIcons/bin-inline.svg'; import CopyIcon from 'common/img/newIcons/copy-inline.svg'; import { docsReferences, createExternalLink } from 'common/utils'; import { PROJECT_SETTINGS_PATTERN_ANALYSIS_EVENTS } from 'analyticsEvents/projectSettingsPageEvents'; +import { + handleExternalLinkClick, + handleExternalLinkKeyDown, +} from 'components/main/analytics/events/common/utils'; import { PatternRuleContent, FieldElement, RuleList } from '../../elements'; import { Layout } from '../../layout'; import { messages } from '../messages'; @@ -181,6 +185,14 @@ export const PatternAnalysisContent = ({ return ( <> createExternalLink(data, docsReferences.patternAnalysisDocs), From 07cdd0ddf3aa2c9320fe3baafa68f98b614b3313 Mon Sep 17 00:00:00 2001 From: Dzmitry Kosarau Date: Fri, 10 Nov 2023 12:43:48 +0500 Subject: [PATCH 2/3] EPMRPP-82207 || Code review fixes - 1 --- .../main/analytics/events/common/utils.js | 14 ------ .../ga4Events/projectSettingsPageEvents.js | 35 ++++++------- .../apiKeys/apiKeysBlock/apiKeysBlock.jsx | 16 +----- .../autoAnalysis/autoAnalysis.jsx | 34 +++++-------- .../indexSettings/indexSettings.jsx | 32 +++++------- .../similarItems/similarItems.jsx | 32 +++++------- .../uniqueErrors/uniqueErrors.jsx | 32 +++++------- .../content/defectTypes/defectTypes.jsx | 26 +++------- .../formattedDescription.jsx | 49 +++++++++++++++++++ .../formattedDescription.scss | 34 +++++++++++++ .../elements/formattedDescription/index.js | 1 + .../content/elements/index.js | 1 + .../tabDescription/tabDescription.jsx | 12 +---- .../content/layout/layout.jsx | 17 +------ .../content/notifications/notifications.jsx | 29 ++++------- .../patternAnalysisContent.jsx | 28 ++++------- 16 files changed, 179 insertions(+), 213 deletions(-) create mode 100644 app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.jsx create mode 100644 app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.scss create mode 100644 app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/index.js diff --git a/app/src/components/main/analytics/events/common/utils.js b/app/src/components/main/analytics/events/common/utils.js index bc6f592589..14d5fbfd46 100644 --- a/app/src/components/main/analytics/events/common/utils.js +++ b/app/src/components/main/analytics/events/common/utils.js @@ -14,8 +14,6 @@ * limitations under the License. */ -import { ENTER_KEY_CODE } from 'common/constants/keyCodes'; - // conditions should look like 'statistics$defects$product_bug$pb001' export const getDefectTypeLabel = (condition) => { try { @@ -44,15 +42,3 @@ export const getIncludedData = ({ includeData, includeComments, includeLogs }) = .filter((key) => analyticsDataMap[key]) .join('#'); }; - -export const handleExternalLinkClick = (trackEvent, event) => ({ target: { tagName } }) => { - if (tagName === 'A') { - trackEvent(event); - } -}; - -export const handleExternalLinkKeyDown = (trackEvent, event) => ({ keyCode }) => { - if (keyCode === ENTER_KEY_CODE) { - trackEvent(event); - } -}; diff --git a/app/src/components/main/analytics/events/ga4Events/projectSettingsPageEvents.js b/app/src/components/main/analytics/events/ga4Events/projectSettingsPageEvents.js index 9b160a7e33..97290a0e8e 100644 --- a/app/src/components/main/analytics/events/ga4Events/projectSettingsPageEvents.js +++ b/app/src/components/main/analytics/events/ga4Events/projectSettingsPageEvents.js @@ -25,10 +25,7 @@ const DEFECT_TYPES = 'defect_types'; const INTEGRATIONS = 'integrations'; const PATTERN_ANALYSIS = 'pattern_analysis'; const GENERAL = 'general'; -const BASIC_EVENT_PARAMETERS = { - ...getBasicClickEventParameters(PROJECT_SETTINGS), - element_name: 'button_submit', -}; +const BASIC_EVENT_PARAMETERS_ANALYZER_TAB = getBasicClickEventParameters(PROJECT_SETTINGS); const BASIC_EVENT_PARAMETERS_NOTIFICATIONS = { ...getBasicClickEventParameters(PROJECT_SETTINGS), place: NOTIFICATIONS, @@ -64,36 +61,40 @@ const getStatus = (status) => (status ? 'active' : 'disabled'); const getSwitcher = (switcher) => (switcher ? 'on' : 'off'); export const PROJECT_SETTINGS_ANALYZER_EVENTS = { - CLICK_SUBMIT_IN_INDEX_TAB: (number, status) => ({ - ...BASIC_EVENT_PARAMETERS, + clickSubmitInIndexTab: (number, status) => ({ + ...BASIC_EVENT_PARAMETERS_ANALYZER_TAB, + element_name: 'button_submit', place: `${ANALYZER}_index_settings`, number, status: getStatus(status), }), - CLICK_SUBMIT_IN_AUTO_ANALYZER_TAB: (number, status, condition) => ({ - ...BASIC_EVENT_PARAMETERS, + clickSubmitInAutoAnalyzerTab: (number, status, condition) => ({ + ...BASIC_EVENT_PARAMETERS_ANALYZER_TAB, place: `${ANALYZER}_auto_analyzer`, + element_name: 'button_submit', number, status: getStatus(status), condition: LAUNCH_ANALYZE_TYPES_TO_ANALYTICS_TITLES_MAP[condition], }), - CLICK_SUBMIT_IN_SIMILAR_ITEMS_TAB: (number) => ({ - ...BASIC_EVENT_PARAMETERS, + clickSubmitInSimilarItemsTab: (number) => ({ + ...BASIC_EVENT_PARAMETERS_ANALYZER_TAB, place: `${ANALYZER}_similar_items`, + element_name: 'button_submit', number, }), - CLICK_SUBMIT_IN_UNIQUE_ERRORS_TAB: (status, type) => ({ - ...BASIC_EVENT_PARAMETERS, + clickSubmitInUniqueErrorsTab: (status, type) => ({ + ...BASIC_EVENT_PARAMETERS_ANALYZER_TAB, place: `${ANALYZER}_unique_errors`, status: getStatus(status), + element_name: 'button_submit', type: type ? 'exclude' : 'include', }), - CLICK_LINK_DOCUMENTATION: (place) => ({ - ...BASIC_EVENT_PARAMETERS, + clickDocumentationLink: (place) => ({ + ...BASIC_EVENT_PARAMETERS_ANALYZER_TAB, place: `${ANALYZER}_${place}`, link_name: 'documentation', }), @@ -101,7 +102,7 @@ export const PROJECT_SETTINGS_ANALYZER_EVENTS = { export const PROJECT_SETTINGS_DEMO_DATA_EVENTS = { CLICK_GENERATE_DATA_IN_DEMO_DATA_TAB: { - ...BASIC_EVENT_PARAMETERS, + ...getBasicClickEventParameters(PROJECT_SETTINGS), element_name: 'button_generate_demo_data', place: 'demo_data', }, @@ -129,7 +130,7 @@ export const PROJECT_SETTINGS_NOTIFICATIONS_EVENTS = { switcher: getSwitcher(switcher), }), - CLICK_LINK_DOCUMENTATION: (place) => ({ + clickDocumentationLink: (place) => ({ ...BASIC_EVENT_PARAMETERS_NOTIFICATIONS, ...(place && { place }), link_name: 'documentation', @@ -242,7 +243,7 @@ export const PROJECT_SETTINGS_PATTERN_ANALYSIS_EVENTS = { element_name: 'pattern_name', status: 'open', }, - CLICK_LINK_DOCUMENTATION: (place) => ({ + clickDocumentationLink: (place) => ({ ...BASIC_EVENT_PARAMETERS_PATTERN_ANALYSIS, ...(place && { place }), link_name: 'documentation', diff --git a/app/src/pages/inside/profilePage/apiKeys/apiKeysBlock/apiKeysBlock.jsx b/app/src/pages/inside/profilePage/apiKeys/apiKeysBlock/apiKeysBlock.jsx index adf62b9224..f7b345d9a6 100644 --- a/app/src/pages/inside/profilePage/apiKeys/apiKeysBlock/apiKeysBlock.jsx +++ b/app/src/pages/inside/profilePage/apiKeys/apiKeysBlock/apiKeysBlock.jsx @@ -28,7 +28,6 @@ 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); @@ -79,22 +78,9 @@ export const ApiKeysBlock = ({ apiKeys }) => { } }; - 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/projectSettingsPageContainer/content/analyzerContainer/autoAnalysis/autoAnalysis.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/autoAnalysis/autoAnalysis.jsx index 8da99d9ca3..800720bafe 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/autoAnalysis/autoAnalysis.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/autoAnalysis/autoAnalysis.jsx @@ -28,15 +28,10 @@ import { bindMessageToValidator, validate } from 'common/utils/validation'; import { Dropdown } from 'componentLibrary/dropdown'; import { Checkbox } from 'componentLibrary/checkbox'; import { useTracking } from 'react-tracking'; -import Parser from 'html-react-parser'; import { PROJECT_SETTINGS_ANALYZER_EVENTS } from 'analyticsEvents/projectSettingsPageEvents'; import { docsReferences, createExternalLink } from 'common/utils'; -import { - handleExternalLinkClick, - handleExternalLinkKeyDown, -} from 'components/main/analytics/events/common/utils'; import { Layout } from '../../layout'; -import { FieldElement, LabeledPreloader } from '../../elements'; +import { FieldElement, LabeledPreloader, FormattedDescription } from '../../elements'; import { messages } from './messages'; import { ALL_MESSAGES_SHOULD_MATCH, @@ -105,7 +100,7 @@ const AutoAnalysis = ({ setPending(false); trackEvent( - PROJECT_SETTINGS_ANALYZER_EVENTS.CLICK_SUBMIT_IN_AUTO_ANALYZER_TAB( + PROJECT_SETTINGS_ANALYZER_EVENTS.clickSubmitInAutoAnalyzerTab( data[MIN_SHOULD_MATCH], data[ANALYZER_ENABLED], data[ANALYZER_MODE], @@ -115,7 +110,7 @@ const AutoAnalysis = ({ const numberOfLogLines = data[NUMBER_OF_LOG_LINES] === '-1' ? 'all' : data[NUMBER_OF_LOG_LINES]; trackEvent( - PROJECT_SETTINGS_ANALYZER_EVENTS.CLICK_SUBMIT_IN_INDEX_TAB( + PROJECT_SETTINGS_ANALYZER_EVENTS.clickSubmitInIndexTab( numberOfLogLines, data[ALL_MESSAGES_SHOULD_MATCH], ), @@ -126,20 +121,15 @@ const AutoAnalysis = ({ return ( - createExternalLink(data, docsReferences.autoAnalysisDocs, 'documentationLink'), - }), - )} + description={ + + createExternalLink(data, docsReferences.autoAnalysisDocs, 'documentationLink'), + })} + event={PROJECT_SETTINGS_ANALYZER_EVENTS.clickDocumentationLink('auto_analyzer')} + /> + } >
- createExternalLink(data, docsReferences.indexSettingsDocs, 'documentationLink'), - }), - )} + description={ + + createExternalLink(data, docsReferences.indexSettingsDocs, 'documentationLink'), + })} + event={PROJECT_SETTINGS_ANALYZER_EVENTS.clickDocumentationLink('index_settings')} + /> + } >
diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/similarItems/similarItems.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/similarItems/similarItems.jsx index 1443c9cd4c..aba3a6d307 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/similarItems/similarItems.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/analyzerContainer/similarItems/similarItems.jsx @@ -18,7 +18,6 @@ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { useIntl } from 'react-intl'; import { reduxForm } from 'redux-form'; -import Parser from 'html-react-parser'; import { COMMON_LOCALE_KEYS } from 'common/constants/localization'; import { Button } from 'componentLibrary/button'; import { FieldNumber } from 'componentLibrary/fieldNumber'; @@ -27,13 +26,9 @@ import { bindMessageToValidator, validate } from 'common/utils/validation'; import { useTracking } from 'react-tracking'; import { PROJECT_SETTINGS_ANALYZER_EVENTS } from 'analyticsEvents/projectSettingsPageEvents'; import { docsReferences, createExternalLink } from 'common/utils'; -import { - handleExternalLinkClick, - handleExternalLinkKeyDown, -} from 'components/main/analytics/events/common/utils'; import { FIELD } from 'common/constants/dataAutomation'; import { Layout } from '../../layout'; -import { LabeledPreloader, FieldElement } from '../../elements'; +import { LabeledPreloader, FieldElement, FormattedDescription } from '../../elements'; import { messages } from './messages'; import { SEARCH_LOGS_MIN_SHOULD_MATCH } from '../constants'; @@ -60,7 +55,7 @@ const SimilarItems = ({ setPending(false); trackEvent( - PROJECT_SETTINGS_ANALYZER_EVENTS.CLICK_SUBMIT_IN_SIMILAR_ITEMS_TAB( + PROJECT_SETTINGS_ANALYZER_EVENTS.clickSubmitInSimilarItemsTab( data[SEARCH_LOGS_MIN_SHOULD_MATCH], ), ); @@ -70,20 +65,15 @@ const SimilarItems = ({ return ( - createExternalLink(data, docsReferences.similarItemsDocs, 'documentationLink'), - }), - )} + description={ + + createExternalLink(data, docsReferences.similarItemsDocs, 'documentationLink'), + })} + event={PROJECT_SETTINGS_ANALYZER_EVENTS.clickDocumentationLink('similar_items')} + /> + } > - createExternalLink(data, docsReferences.uniqueErrorsDocs, 'documentationLink'), - }), - )} + description={ + + createExternalLink(data, docsReferences.uniqueErrorsDocs, 'documentationLink'), + })} + event={PROJECT_SETTINGS_ANALYZER_EVENTS.clickDocumentationLink('unique_errors')} + /> + } > { return ( - - {Parser( - formatMessage(messages.description, { + + createExternalLink(data, docsReferences.workWithReports), - }), - )} + })} + event={PROJECT_SETTINGS_DEFECT_TYPES_EVENTS.CLICK_DOCUMENTATION_LINK} + /> {(isInformationMessage || !canAddNewDefectType) && ( diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.jsx new file mode 100644 index 0000000000..63740ddef2 --- /dev/null +++ b/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.jsx @@ -0,0 +1,49 @@ +/* + * 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 PropTypes from 'prop-types'; +import Parser from 'html-react-parser'; +import { useTracking } from 'react-tracking'; +import classNames from 'classnames/bind'; +import styles from './formattedDescription.scss'; + +const cx = classNames.bind(styles); + +const isAnchorElement = (tagName) => tagName === 'A'; + +export const FormattedDescription = ({ content, event }) => { + const { trackEvent } = useTracking(); + + const handleExternalLinkClick = ({ target: { tagName } }) => { + if (isAnchorElement(tagName)) { + trackEvent(event); + } + }; + + return ( + + {Parser(content)} + + ); +}; +FormattedDescription.propTypes = { + content: PropTypes.string, + event: PropTypes.object, +}; +FormattedDescription.defaultProps = { + content: '', + event: {}, +}; diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.scss b/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.scss new file mode 100644 index 0000000000..1721d2c7ba --- /dev/null +++ b/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.scss @@ -0,0 +1,34 @@ +/*! + * 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. + */ + +.formatted-description { + font-family: $FONT-ROBOTO-REGULAR; + font-size: 13px; + line-height: 20px; + color: $COLOR--almost-black; + + & > a { + font-family: $FONT-ROBOTO-REGULAR; + font-size: 13px; + line-height: 20px; + color: $COLOR--topaz-2; + text-decoration: none; + &:hover { + text-decoration: underline; + color: $COLOR--topaz-hover-2; + } + } +} diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/index.js b/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/index.js new file mode 100644 index 0000000000..ef047bc362 --- /dev/null +++ b/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/index.js @@ -0,0 +1 @@ +export { FormattedDescription } from './formattedDescription'; diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/elements/index.js b/app/src/pages/inside/projectSettingsPageContainer/content/elements/index.js index 2a92cf53ee..652bfccf13 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/elements/index.js +++ b/app/src/pages/inside/projectSettingsPageContainer/content/elements/index.js @@ -21,4 +21,5 @@ export { Divider } from './divider'; export { RuleList, DraggableRuleList } from './ruleList'; export { PatternRuleContent } from './patternRuleContent'; export { NotificationRuleContent } from './notificationRuleContent'; +export { FormattedDescription } from './formattedDescription'; export * from './constants'; diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/elements/tabDescription/tabDescription.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/elements/tabDescription/tabDescription.jsx index 4be62afce4..f453596431 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/elements/tabDescription/tabDescription.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/elements/tabDescription/tabDescription.jsx @@ -21,17 +21,9 @@ import styles from './tabDescription.scss'; const cx = className.bind(styles); -export const TabDescription = ({ children, handleClick, handleKeyDown }) => ( - - {children} - +export const TabDescription = ({ children }) => ( + {children} ); TabDescription.propTypes = { children: PropTypes.node.isRequired, - handleClick: PropTypes.func, - handleKeyDown: PropTypes.func, -}; -TabDescription.defaultProps = { - handleClick: () => {}, - handleKeyDown: () => {}, }; diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/layout/layout.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/layout/layout.jsx index 2001fae244..d3560d67a0 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/layout/layout.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/layout/layout.jsx @@ -22,17 +22,10 @@ import styles from './layout.scss'; const cx = classNames.bind(styles); -export const Layout = ({ - description, - children, - handleDescriptionClick, - handleDescriptionKeyDown, -}) => { +export const Layout = ({ description, children }) => { return ( <> - - {description} - + {description}
{children}
@@ -41,10 +34,4 @@ export const Layout = ({ Layout.propTypes = { description: PropTypes.string.isRequired, children: PropTypes.node.isRequired, - handleDescriptionClick: PropTypes.func, - handleDescriptionKeyDown: PropTypes.func, -}; -Layout.defaultProps = { - handleDescriptionClick: () => {}, - handleDescriptionKeyDown: () => {}, }; diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx b/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx index 97d13c1aaa..47ea6413f7 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx +++ b/app/src/pages/inside/projectSettingsPageContainer/content/notifications/notifications.jsx @@ -20,7 +20,6 @@ import { useDispatch, useSelector } from 'react-redux'; import classNames from 'classnames/bind'; import { useTracking } from 'react-tracking'; import { useIntl } from 'react-intl'; -import Parser from 'html-react-parser'; import { canUpdateSettings } from 'common/utils/permissions'; import { projectNotificationsSelector, @@ -47,14 +46,11 @@ 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 { - handleExternalLinkClick, - handleExternalLinkKeyDown, -} from 'components/main/analytics/events/common/utils'; import { RuleList, FieldElement, NotificationRuleContent, + FormattedDescription, MODAL_ACTION_TYPE_ADD, MODAL_ACTION_TYPE_EDIT, MODAL_ACTION_TYPE_COPY, @@ -249,7 +245,7 @@ export const Notifications = ({ setHeaderTitleNode }) => { }; const handleDocumentationClick = () => { - trackEvent(PROJECT_SETTINGS_NOTIFICATIONS_EVENTS.CLICK_LINK_DOCUMENTATION('no_notifications')); + trackEvent(PROJECT_SETTINGS_NOTIFICATIONS_EVENTS.clickDocumentationLink('no_notifications')); }; if (loading) { @@ -261,19 +257,14 @@ export const Notifications = ({ setHeaderTitleNode }) => { {notifications.length ? ( createExternalLink(data, docsReferences.notificationsDocs), - }), - )} + description={ + createExternalLink(data, docsReferences.notificationsDocs), + })} + event={PROJECT_SETTINGS_NOTIFICATIONS_EVENTS.clickDocumentationLink()} + /> + } > createExternalLink(data, docsReferences.patternAnalysisDocs), - }), - )} + description={ + createExternalLink(data, docsReferences.patternAnalysisDocs), + })} + event={PROJECT_SETTINGS_PATTERN_ANALYSIS_EVENTS.clickDocumentationLink()} + /> + } > Date: Fri, 10 Nov 2023 15:51:11 +0500 Subject: [PATCH 3/3] EPMRPP-82207 || Code review fixes - 2 --- .../formattedDescription.scss | 5 ----- .../elements/formattedDescription/index.js | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.scss b/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.scss index 1721d2c7ba..ada691a9af 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.scss +++ b/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/formattedDescription.scss @@ -15,11 +15,6 @@ */ .formatted-description { - font-family: $FONT-ROBOTO-REGULAR; - font-size: 13px; - line-height: 20px; - color: $COLOR--almost-black; - & > a { font-family: $FONT-ROBOTO-REGULAR; font-size: 13px; diff --git a/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/index.js b/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/index.js index ef047bc362..7b19f596d3 100644 --- a/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/index.js +++ b/app/src/pages/inside/projectSettingsPageContainer/content/elements/formattedDescription/index.js @@ -1 +1,17 @@ +/* + * 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. + */ + export { FormattedDescription } from './formattedDescription';