PluginProbe ʕ •ᴥ•ʔ
Advanced Ads – Ad Manager & AdSense / 2.0.25
Advanced Ads – Ad Manager & AdSense v2.0.25
2.0.25 2.0.24 2.0.23 2.0.22 2.0.21 1.38.0 1.39.0 1.39.1 1.39.2 1.39.3 1.39.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.40.0 1.40.1 1.40.2 1.41.0 1.42.0 1.42.1 1.42.2 1.43.0 1.44.0 1.44.1 1.45.0 1.45.1 1.46.0 1.47.0 1.47.1 1.47.2 1.47.3 1.47.4 1.47.5 1.48.0 1.48.1 1.49.0 1.5.0 1.5.0.1 1.5.1 1.5.2 1.5.2.1 1.5.4 1.5.4.1 1.5.5 1.50.0 1.51.0 1.51.1 1.51.2 1.51.3 1.52.0 1.52.1 1.52.2 1.52.3 1.52.4 1.53.0 1.53.1 1.53.2 1.54.0 1.54.1 1.55.0 1.56.0 1.56.1 1.56.2 1.56.3 1.56.4 1.6 1.6.1 1.6.10 1.6.10.1 1.6.10.2 1.6.11 1.6.11.1 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.17.1 1.6.17.2 1.6.2 1.6.2.1 1.6.3 1.6.4 1.6.4.1 1.6.5 1.6.6 1.6.6.1 1.6.7 1.6.7.1 1.6.8 1.6.8.1 1.6.8.2 1.6.8.3 1.6.9 1.6.9.1 1.6.9.2 1.6.9.3 1.6.9.4 1.7 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.1.1 1.7.1.2 1.7.1.3 1.7.1.4 1.7.1.5 1.7.10 trunk 1.7.11 1.0.1 1.7.12 1.0.2 1.7.13 1.0.3 1.7.14 1.1.0 1.7.15 1.1.1 1.7.16 1.1.2 1.7.17 1.1.3 1.7.18 1.10 1.7.19 1.10.1 1.7.2 1.10.10 1.7.2.1 1.10.11 1.7.20 1.10.12 1.7.21 1.10.2 1.7.22 1.10.3 1.7.23 1.10.4 1.7.24 1.10.5 1.7.25 1.10.6 1.7.3 1.10.7 1.7.4 1.10.8 1.7.4.1 1.10.9 1.7.4.2 1.11 1.7.4.3 1.11.1 1.7.4.4 1.11.2 1.7.4.5 1.12 1.7.5 1.13 1.7.5.1 1.13.1 1.7.6 1.13.2 1.7.7 1.13.3 1.7.8 1.13.4 1.7.9 1.13.5 1.7.9.1 1.13.6 1.7.9.2 1.13.7 1.7.9.3 1.13.8 1.8 1.14 1.8.1 1.14.1 1.8.10 1.14.10 1.8.11 1.14.11 1.8.12 1.14.2 1.8.13 1.14.3 1.8.14 1.14.4 1.8.15 1.14.5 1.8.16 1.14.6 1.8.17 1.14.7 1.8.18 1.14.8 1.8.19 1.14.9 1.8.2 1.15 1.8.20 1.16 1.8.21 1.16.1 1.8.22 1.17 1.8.23 1.17.1 1.8.24 1.17.10 1.8.25 1.17.10-rc.1 1.8.26 1.17.11 1.8.27 1.17.12 1.8.28 1.17.12-rc.1 1.8.29 1.17.2 1.8.3 1.17.3 1.8.30 1.17.4 1.8.4 1.17.5 1.8.5 1.17.6 1.8.6 1.17.7 1.8.7 1.17.8 1.8.8 1.17.9 1.8.9 1.17.9-beta.1 1.9 1.18.0 2.0.0 1.19.0 2.0.1 1.19.1 2.0.10 1.2 2.0.11 1.2.1 2.0.12 1.2.2 2.0.13 1.2.3 2.0.14 1.2.4 2.0.15 1.2.5 2.0.16 1.2.6 2.0.17 1.2.7 2.0.18 1.20.0 2.0.19 1.20.0-rc.1 2.0.2 1.20.0-rc.2 2.0.20 1.20.1 2.0.3 1.20.2 2.0.4 1.20.3 2.0.5 1.21.0 2.0.6 1.21.1 2.0.7 1.22.0 2.0.8 1.22.1 2.0.9 1.22.2 1.23.0 1.23.1 1.23.2 1.24.0 1.24.1 1.24.2 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.29.0 1.29.1 1.3 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.30.0 1.30.1 1.30.2 1.30.2-rc.1 1.30.3 1.30.4 1.30.4-rc.1 1.30.5 1.31.0 1.31.1 1.32.0 1.32.0-rc.1 1.33.0 1.33.1 1.33.2 1.34.0 1.35.0 1.35.1 1.36.0 1.36.1 1.36.2 1.36.3 1.37.0 1.37.1 1.37.2
advanced-ads / src / admin / screen-licenses / components / AddonRowActions.jsx
advanced-ads / src / admin / screen-licenses / components Last commit date
AddonRowActions.jsx 1 week ago AddonsList.jsx 1 week ago AllAccessAddonsSummary.jsx 1 week ago AutoUpdateModal.jsx 1 week ago DownloadActivateButton.jsx 1 week ago EmptyState.jsx 1 week ago FeatureList.jsx 1 week ago LicenseField.jsx 1 week ago LicenseItem.jsx 1 week ago LicenseNotices.jsx 1 week ago LicenseStatus.jsx 1 week ago Loader.jsx 1 week ago PricingModal.jsx 1 week ago PricingTable.jsx 1 week ago PricingTableItem.jsx 1 week ago SitesModal.jsx 1 week ago
AddonRowActions.jsx
290 lines
1 /**
2 * WordPress Dependencies
3 */
4 import { __ } from '@wordpress/i18n';
5 import { useState } from '@wordpress/element';
6 import { useDispatch, useSelect } from '@wordpress/data';
7 import { store as noticesStore } from '@wordpress/notices';
8
9 /**
10 * External Dependencies
11 */
12 import { Check, AlertCircle, Loader2 } from 'lucide-react';
13
14 /**
15 * Internal Dependencies
16 */
17 import { STORE_NAME } from '@admin/store';
18 import { getManualInstallGuideUrl } from '../addon-catalog';
19 import {
20 activateAddonFromLicense,
21 deactivateAddonFromLicense,
22 } from '../hooks/licenses-api';
23 import { getAddonInstallState, getAddonRowStatus } from '../utils';
24 import { publishLicenseWarningNotice } from './LicenseNotices';
25
26 export function AddonRowActions( {
27 addonId,
28 licenseKey,
29 licenses,
30 downloadUrl = '',
31 isApplied = false,
32 disabled = false,
33 managedByOtherLicense = false,
34 addonInstallStates = {},
35 noticesContext,
36 isInstalling = false,
37 installFailed = false,
38 onInstallStart,
39 onInstallEnd,
40 } ) {
41 const [ isWorking, setIsWorking ] = useState( false );
42 const [ isDeactivating, setIsDeactivating ] = useState( false );
43 const { createErrorNotice, removeNotice } = useDispatch( noticesStore );
44 const licensesFromStore = useSelect(
45 ( select ) => select( STORE_NAME ).getLicenses(),
46 []
47 );
48 const licenseList =
49 licensesFromStore.length > 0 ? licensesFromStore : licenses;
50
51 const rowStatus = getAddonRowStatus(
52 addonId,
53 addonInstallStates,
54 isApplied
55 );
56 const { installed } = getAddonInstallState( addonId, addonInstallStates );
57 // Active + Deactivate only when this All Access key owns the add-on (isApplied), not when the plugin is merely running.
58 const isActiveUnderAllAccess = rowStatus === 'installed';
59 const isBusy = isInstalling || isWorking || isDeactivating;
60 // Install/download requires AA entitled; Activate/Deactivate on a row stay available when entitled.
61 const installActionsDisabled = disabled;
62 const takeOverFromOtherLicense =
63 managedByOtherLicense && ! isApplied && installed;
64
65 function showAddonErrorNotice( message ) {
66 const noticeId = `advanced-ads/addon-error-${ addonId }`;
67
68 removeNotice( noticeId, noticesContext );
69 publishLicenseWarningNotice( createErrorNotice, {
70 id: noticeId,
71 context: noticesContext,
72 message,
73 } );
74 }
75
76 async function handleActivateUnderAllAccess() {
77 if ( isBusy || ! licenseKey || ! addonId ) {
78 return;
79 }
80
81 setIsWorking( true );
82
83 try {
84 await activateAddonFromLicense( licenseKey, addonId, licenseList );
85 } catch ( err ) {
86 const message =
87 err instanceof Error
88 ? err.message
89 : __( 'Activation failed.', 'advanced-ads' );
90 showAddonErrorNotice( message );
91 } finally {
92 setIsWorking( false );
93 }
94 }
95
96 async function handleDownloadAndInstall() {
97 if ( isBusy || installActionsDisabled || ! licenseKey || ! addonId ) {
98 return;
99 }
100
101 onInstallStart?.( addonId );
102 setIsWorking( true );
103
104 try {
105 await activateAddonFromLicense( licenseKey, addonId, licenseList );
106 onInstallEnd?.( addonId, false );
107 } catch ( err ) {
108 const message =
109 err instanceof Error
110 ? err.message
111 : __( 'Installation failed.', 'advanced-ads' );
112 showAddonErrorNotice( message );
113 onInstallEnd?.( addonId, true );
114 } finally {
115 setIsWorking( false );
116 }
117 }
118
119 async function handleDeactivate() {
120 if ( isBusy || ! addonId ) {
121 return;
122 }
123
124 setIsDeactivating( true );
125
126 try {
127 await deactivateAddonFromLicense( addonId, licenseList );
128 } catch ( err ) {
129 const message =
130 err instanceof Error
131 ? err.message
132 : __( 'Deactivation failed.', 'advanced-ads' );
133 showAddonErrorNotice( message );
134 } finally {
135 setIsDeactivating( false );
136 }
137 }
138
139 function handleManualInstall() {
140 const packageUrl = String( downloadUrl ?? '' ).trim();
141 const guideUrl = getManualInstallGuideUrl( addonId );
142
143 if ( packageUrl ) {
144 window.open( packageUrl, '_blank', 'noopener,noreferrer' );
145 }
146
147 window.open( guideUrl, '_blank', 'noopener,noreferrer' );
148 }
149
150 if ( isDeactivating ) {
151 return (
152 <span className="inline-flex items-center gap-2 text-sm text-gray-600">
153 <Loader2
154 className="size-4 shrink-0"
155 strokeWidth={ 2 }
156 aria-hidden
157 />
158 { __( 'Deactivating…', 'advanced-ads' ) }
159 </span>
160 );
161 }
162
163 if ( isActiveUnderAllAccess ) {
164 return (
165 <div className="inline-flex flex-wrap items-center gap-3">
166 <span className="inline-flex items-center gap-2 text-sm text-green-700">
167 <Check
168 className="size-4 shrink-0"
169 strokeWidth={ 2 }
170 aria-hidden
171 />
172 { __( 'Active', 'advanced-ads' ) }
173 </span>
174 <button
175 type="button"
176 className="button advads-button-secondary is-small"
177 onClick={ handleDeactivate }
178 disabled={ isBusy }
179 aria-busy={ isDeactivating }
180 >
181 { __( 'Deactivate', 'advanced-ads' ) }
182 </button>
183 </div>
184 );
185 }
186
187 if ( isInstalling || isWorking ) {
188 return (
189 <span className="inline-flex items-center gap-2 text-sm text-gray-600">
190 <Loader2
191 className="size-4 shrink-0"
192 strokeWidth={ 2 }
193 aria-hidden
194 />
195 { isWorking && takeOverFromOtherLicense
196 ? __( 'Activating…', 'advanced-ads' )
197 : __( 'Installing…', 'advanced-ads' ) }
198 </span>
199 );
200 }
201
202 if ( takeOverFromOtherLicense ) {
203 return (
204 <div className="inline-flex flex-wrap items-center gap-3">
205 <button
206 type="button"
207 className="button advads-button-neutral is-small"
208 onClick={ handleActivateUnderAllAccess }
209 disabled={ isBusy }
210 aria-busy={ isWorking }
211 >
212 { __( 'Activate', 'advanced-ads' ) }
213 </button>
214 </div>
215 );
216 }
217
218 if ( rowStatus === 'running' ) {
219 return (
220 <div className="inline-flex flex-wrap items-center gap-3">
221 <span className="inline-flex items-center gap-2 text-sm text-gray-600">
222 <Check
223 className="size-4 shrink-0 text-green-700"
224 strokeWidth={ 2 }
225 aria-hidden
226 />
227 { __( 'Plugin active', 'advanced-ads' ) }
228 </span>
229 <button
230 type="button"
231 className="button advads-button-neutral is-small"
232 onClick={ handleActivateUnderAllAccess }
233 disabled={ isBusy }
234 aria-busy={ isWorking }
235 >
236 { __( 'Activate', 'advanced-ads' ) }
237 </button>
238 </div>
239 );
240 }
241
242 if ( rowStatus === 'ready' ) {
243 return (
244 <button
245 type="button"
246 className="button advads-button-neutral is-small"
247 onClick={ handleActivateUnderAllAccess }
248 disabled={ isBusy }
249 aria-busy={ isWorking }
250 >
251 { __( 'Activate', 'advanced-ads' ) }
252 </button>
253 );
254 }
255
256 return (
257 <div className="inline-flex flex-wrap items-center gap-3">
258 { installFailed ? (
259 <span className="inline-flex items-center gap-2 text-sm text-red-700">
260 <AlertCircle
261 className="size-4 shrink-0"
262 strokeWidth={ 2 }
263 aria-hidden
264 />
265 { __( 'Installation failed', 'advanced-ads' ) }
266 </span>
267 ) : null }
268 <button
269 type="button"
270 className="button advads-button-neutral is-small whitespace-nowrap"
271 onClick={ handleDownloadAndInstall }
272 disabled={ installActionsDisabled || isBusy }
273 aria-busy={ isBusy }
274 >
275 { __( 'Download and install', 'advanced-ads' ) }
276 </button>
277 { installFailed ? (
278 <button
279 type="button"
280 className="button advads-button-secondary is-small"
281 onClick={ handleManualInstall }
282 disabled={ installActionsDisabled || isBusy }
283 >
284 { __( 'Manual install', 'advanced-ads' ) }
285 </button>
286 ) : null }
287 </div>
288 );
289 }
290