• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Yoast / wordpress-seo / f050301100f5df0caf88b5f6cf2ec493f81e9bd4

19 Nov 2024 09:08AM UTC coverage: 54.641% (+0.004%) from 54.637%
f050301100f5df0caf88b5f6cf2ec493f81e9bd4

push

github

YoastBot
Bump version to 23.9 on free

7575 of 13561 branches covered (55.86%)

Branch coverage included in aggregate %.

29709 of 54673 relevant lines covered (54.34%)

41694.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.91
/packages/js/src/components/SEMrushRelatedKeyphrasesModalContent.js
1
/* External dependencies */
2
import { Fragment } from "@wordpress/element";
3
import { KeyphrasesTable } from "@yoast/related-keyphrase-suggestions";
4
import { Root } from "@yoast/ui-library";
5
import { __, sprintf } from "@wordpress/i18n";
6
import PropTypes from "prop-types";
7
import { isEmpty } from "lodash";
8

9
/* Internal dependencies */
10
import SEMrushLoading from "./modals/SEMrushLoading";
11
import SEMrushLimitReached from "./modals/SEMrushLimitReached";
12
import SEMrushCountrySelector from "./modals/SEMrushCountrySelector";
13
import SEMrushUpsellAlert from "./modals/SEMrushUpsellAlert";
14
import SEMrushRequestFailed from "./modals/SEMrushRequestFailed";
15
import SEMrushMaxRelatedKeyphrases from "./modals/SEMrushMaxRelatedKeyphrases";
16
import getL10nObject from "../analysis/getL10nObject";
17
import { makeOutboundLink } from "@yoast/helpers";
18

19
/**
20
 * Determines whether the error property is present in the passed response object.
21
 *
22
 * @param {Object} response The response object.
23
 *
24
 * @returns {boolean} Whether or not the error property is present.
25
 */
26
export function hasError( response ) {
27
        return ! isEmpty( response ) && "error" in response;
6✔
28
}
29

30
/**
31
 * Gets a user message based on the passed props' values.
32
 *
33
 * @param {Object} props The props to use.
34
 *
35
 * @returns {wp.Element} The user message.
36
 */
37
export function getUserMessage( props ) {
38
        const {
39
                isPending,
40
                requestLimitReached,
41
                isSuccess,
42
                response,
43
                requestHasData,
44
        } = props;
8✔
45

46
        if ( isPending ) {
8✔
47
                return <SEMrushLoading />;
2✔
48
        }
49

50
        if ( requestLimitReached ) {
6✔
51
                return <SEMrushLimitReached />;
2✔
52
        }
53

54
        if ( ! isSuccess && hasError( response ) ) {
4✔
55
                return <SEMrushRequestFailed />;
2✔
56
        }
57

58
        if ( ! requestHasData ) {
2!
59
                return <p>{ __( "Sorry, there's no data available for that keyphrase/country combination.", "wordpress-seo" ) }</p>;
2✔
60
        }
61
}
62

63
/**
64
 * Determines whether the maximum amount of related keyphrases has been reached.
65
 *
66
 * @param {array} relatedKeyphrases The related keyphrases. Can be empty.
67
 *
68
 * @returns {boolean} Whether or not the maximum limit has been reached.
69
 */
70
export function hasMaximumRelatedKeyphrases( relatedKeyphrases ) {
71
        return relatedKeyphrases && relatedKeyphrases.length >= 4;
6✔
72
}
73

74
/**
75
 * Renders the SEMrush related keyphrases modal content.
76
 *
77
 * @param {Object} props The props to use within the content.
78
 *
79
 * @returns {wp.Element} The SEMrush related keyphrases modal content.
80
 */
81
export default function RelatedKeyphraseModalContent( props ) {
82
        const {
83
                response,
84
                lastRequestKeyphrase,
85
                keyphrase,
86
                newRequest,
87
                setCountry,
88
                renderAction,
89
                countryCode,
90
                requestLimitReached,
91
                setRequestFailed,
92
                setNoResultsFound,
93
                relatedKeyphrases,
94
                setRequestSucceeded,
95
                setRequestLimitReached,
96
                isPending,
97
                isRtl,
98
        } = props;
×
99

100
        const isPremium = getL10nObject().isPremium;
×
101
        const GetMoreInsightsLink = makeOutboundLink();
×
102
        const url = "https://www.semrush.com/analytics/keywordoverview/?q=" + encodeURIComponent( keyphrase ) +
×
103
                        "&db=" + encodeURIComponent( countryCode );
104

105
        return (
×
106
                <Fragment>
107
                        { ! requestLimitReached && (
×
108
                                <Fragment>
109
                                        { ! isPremium && <SEMrushUpsellAlert /> }
×
110
                                        { isPremium && hasMaximumRelatedKeyphrases( relatedKeyphrases ) && <SEMrushMaxRelatedKeyphrases /> }
×
111
                                        <SEMrushCountrySelector
112
                                                countryCode={ countryCode }
113
                                                setCountry={ setCountry }
114
                                                newRequest={ newRequest }
115
                                                keyphrase={ keyphrase }
116
                                                setRequestFailed={ setRequestFailed }
117
                                                setNoResultsFound={ setNoResultsFound }
118
                                                setRequestSucceeded={ setRequestSucceeded }
119
                                                setRequestLimitReached={ setRequestLimitReached }
120
                                                response={ response }
121
                                                lastRequestKeyphrase={ lastRequestKeyphrase }
122
                                        />
123
                                </Fragment>
124
                        ) }
125

126
                        { getUserMessage( props ) }
127
                        <Root context={ { isRtl } }>
128
                                <KeyphrasesTable
129
                                        relatedKeyphrases={ relatedKeyphrases }
130
                                        columnNames={ response?.results?.columnNames }
131
                                        data={ response?.results?.rows }
132
                                        isPending={ isPending }
133
                                        renderButton={ renderAction }
134
                                />
135
                                { response?.results?.rows && <p className="yst-mb-0 yst-mt-2">
×
136
                                        <GetMoreInsightsLink href={ url }>
137
                                                { sprintf(
138
                                                /* translators: %s expands to Semrush */
139
                                                        __( "Get more insights at %s", "wordpress-seo" ),
140
                                                        "Semrush"
141
                                                ) }
142
                                        </GetMoreInsightsLink>
143
                                </p> }
144
                        </Root>
145

146
                </Fragment>
147
        );
148
}
149

150
RelatedKeyphraseModalContent.propTypes = {
2✔
151
        keyphrase: PropTypes.string,
152
        relatedKeyphrases: PropTypes.array,
153
        renderAction: PropTypes.func,
154
        requestLimitReached: PropTypes.bool,
155
        countryCode: PropTypes.string.isRequired,
156
        setCountry: PropTypes.func.isRequired,
157
        newRequest: PropTypes.func.isRequired,
158
        setRequestSucceeded: PropTypes.func.isRequired,
159
        setRequestLimitReached: PropTypes.func.isRequired,
160
        setRequestFailed: PropTypes.func.isRequired,
161
        setNoResultsFound: PropTypes.func.isRequired,
162
        response: PropTypes.object,
163
        lastRequestKeyphrase: PropTypes.string,
164
        isRtl: PropTypes.bool,
165
        isPending: PropTypes.bool,
166
};
167

168
RelatedKeyphraseModalContent.defaultProps = {
2✔
169
        keyphrase: "",
170
        relatedKeyphrases: [],
171
        renderAction: null,
172
        requestLimitReached: false,
173
        response: {},
174
        lastRequestKeyphrase: "",
175
        isRtl: false,
176
        isPending: false,
177
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc