AddonsPage.vue
563 lines
| 1 | <template> |
| 2 | <div |
| 3 | class="jfb-addons-page wrap" |
| 4 | :class="{ 'proccesing-state': proccesingState }" |
| 5 | > |
| 6 | <h1 class="cs-vui-title">{{ 'JetFormBuilder Addons' }}</h1> |
| 7 | <div class="jfb-addons-page__inner cx-vui-panel"> |
| 8 | <div class="jfb-addons-page__header"> |
| 9 | <div class="jfb-addons-page__header-controls" v-if="isLicenseMode"> |
| 10 | <cx-vui-button |
| 11 | button-style="accent" |
| 12 | size="mini" |
| 13 | :loading="checkUpdatesProcessed" |
| 14 | @click="checkPluginsUpdate" |
| 15 | > |
| 16 | <span slot="label"> |
| 17 | <svg class="button-icon" width="14" height="14" viewBox="0 0 14 14" fill="none" |
| 18 | xmlns="http://www.w3.org/2000/svg"> |
| 19 | <path |
| 20 | d="M11.7085 2.29171C10.5001 1.08337 8.8418 0.333374 7.00013 0.333374C3.3168 0.333374 0.341797 3.31671 0.341797 7.00004C0.341797 10.6834 3.3168 13.6667 7.00013 13.6667C10.1085 13.6667 12.7001 11.5417 13.4418 8.66671H11.7085C11.0251 10.6084 9.17513 12 7.00013 12C4.2418 12 2.00013 9.75837 2.00013 7.00004C2.00013 4.24171 4.2418 2.00004 7.00013 2.00004C8.38346 2.00004 9.6168 2.57504 10.5168 3.48337L7.83346 6.16671H13.6668V0.333374L11.7085 2.29171Z" |
| 21 | fill="#007CBA"/> |
| 22 | </svg> |
| 23 | <span>Check For Updates</span> |
| 24 | </span> |
| 25 | </cx-vui-button> |
| 26 | |
| 27 | <cx-vui-button |
| 28 | :class="[ !isLicenseActivated ? 'cx-vui-button--style-accent' : 'cx-vui-button--style-danger' ]" |
| 29 | size="mini" |
| 30 | @click="showLicensePopup" |
| 31 | > |
| 32 | <span slot="label"> |
| 33 | <svg class="button-icon" width="16" height="16" viewBox="0 0 16 16" fill="none" |
| 34 | xmlns="http://www.w3.org/2000/svg"> |
| 35 | <path |
| 36 | d="M15.4985 0H12.4897C12.4166 0 12.3487 0.0156709 12.286 0.0470127C12.2338 0.0679073 12.1867 0.104473 12.145 0.156709L5.7669 6.47209C5.62063 6.44074 5.46392 6.41463 5.29677 6.39373C5.12961 6.37284 4.96768 6.36239 4.81097 6.36239C4.16324 6.36239 3.54685 6.48776 2.9618 6.73849C2.37675 6.97878 1.85961 7.32354 1.41038 7.77277C0.961149 8.222 0.611166 8.73914 0.360431 9.32419C0.120144 9.90924 0 10.5309 0 11.189C0 11.8368 0.120144 12.4532 0.360431 13.0382C0.611166 13.6232 0.961149 14.1404 1.41038 14.5896C1.85961 15.0389 2.37675 15.3836 2.9618 15.6239C3.54685 15.8746 4.16324 16 4.81097 16C5.46915 16 6.09076 15.8746 6.67581 15.6239C7.26086 15.3836 7.778 15.0389 8.22723 14.5896C8.80183 14.015 9.19882 13.3464 9.41822 12.5837C9.64806 11.8211 9.68462 11.0375 9.52791 10.2331L10.8913 8.86974C10.9331 8.82795 10.9644 8.78093 10.9853 8.7287C11.0167 8.66601 11.0323 8.59811 11.0323 8.52498V7.02057H12.5367C12.6934 7.02057 12.8136 6.97356 12.8972 6.87953C12.9912 6.7855 13.0382 6.66536 13.0382 6.5191V5.01469H14.5426C14.6157 5.01469 14.6784 5.00424 14.7307 4.98335C14.7933 4.95201 14.8508 4.91022 14.903 4.85798L15.906 3.85504C15.9269 3.81326 15.9478 3.76624 15.9687 3.71401C15.9896 3.65132 16 3.58342 16 3.51028V0.501469C16 0.355207 15.953 0.235064 15.859 0.141038C15.7649 0.0470127 15.6448 0 15.4985 0ZM4.96768 12.7875C4.79008 12.9651 4.5968 13.0957 4.38786 13.1792C4.18936 13.2524 3.96474 13.2889 3.71401 13.2889C3.46327 13.2889 3.23343 13.2419 3.02449 13.1479C2.82599 13.0539 2.63794 12.9337 2.46033 12.7875C2.28273 12.6099 2.15214 12.4218 2.06856 12.2233C1.99543 12.0144 1.95886 11.7845 1.95886 11.5338C1.95886 11.2831 2.00588 11.0584 2.0999 10.8599C2.19393 10.651 2.31407 10.4577 2.46033 10.2801C2.7842 9.95625 3.19164 9.79432 3.68266 9.79432C4.18413 9.79432 4.5968 9.95625 4.92067 10.2801C5.09827 10.4577 5.22364 10.651 5.29677 10.8599C5.38035 11.0584 5.42214 11.2831 5.42214 11.5338C5.42214 11.7845 5.38035 12.0144 5.29677 12.2233C5.22364 12.4218 5.11394 12.6099 4.96768 12.7875Z" |
| 37 | fill="#D3D3D3"/> |
| 38 | </svg> |
| 39 | <span v-if="!isLicenseActivated">Activate License</span> |
| 40 | <span v-if="isLicenseActivated">Deactivate License</span> |
| 41 | </span> |
| 42 | </cx-vui-button> |
| 43 | </div> |
| 44 | <div |
| 45 | class="go-pro-banner" |
| 46 | v-if="!isLicenseActivated" |
| 47 | > |
| 48 | <div class="go-pro-banner__subtitle">Features & Integrations</div> |
| 49 | <div class="go-pro-banner__title">Extend functionality with PRO Addons</div> |
| 50 | <cx-vui-button |
| 51 | class="go-pro-banner__button" |
| 52 | button-style="default" |
| 53 | size="mini" |
| 54 | :url="goProLink" |
| 55 | tag-name="a" |
| 56 | target="_blank" |
| 57 | > |
| 58 | <span slot="label"> |
| 59 | <span>Go Pro</span> |
| 60 | </span> |
| 61 | </cx-vui-button> |
| 62 | </div> |
| 63 | </div> |
| 64 | |
| 65 | <div |
| 66 | class="jfb-addons" |
| 67 | v-if="0!==Object.keys(installedAddonList).length" |
| 68 | > |
| 69 | <div class="jfb-addons__header"> |
| 70 | <span class="cx-vui-subtitle">Your Installed Addons</span> |
| 71 | </div> |
| 72 | <div class="jfb-addons__list"> |
| 73 | <AddonItem |
| 74 | v-for="( addonData, index ) in installedAddonList" |
| 75 | :key="index" |
| 76 | :addon-data="addonData" |
| 77 | ></AddonItem> |
| 78 | </div> |
| 79 | </div> |
| 80 | |
| 81 | <div |
| 82 | class="jfb-addons" |
| 83 | v-if="0!==Object.keys(availableAddonList).length" |
| 84 | > |
| 85 | <div class="jfb-addons__header"> |
| 86 | <span class="cx-vui-subtitle">All Available Addons</span> |
| 87 | </div> |
| 88 | <div class="jfb-addons__list"> |
| 89 | <AddonItem |
| 90 | v-for="( addonData, index ) in availableAddonList" |
| 91 | :key="index" |
| 92 | :addon-data="addonData" |
| 93 | ></AddonItem> |
| 94 | </div> |
| 95 | </div> |
| 96 | </div> |
| 97 | |
| 98 | <cx-vui-popup |
| 99 | class="jfb-addons-page__license-popup" |
| 100 | v-model="licensePopupVisible" |
| 101 | :footer="false" |
| 102 | body-width="540px" |
| 103 | > |
| 104 | <div class="cx-vui-popup__header-title" slot="title"> |
| 105 | <span v-if="!isLicenseActivated">Activate License</span> |
| 106 | <span v-if="isLicenseActivated">Deactivate License</span> |
| 107 | </div> |
| 108 | <div class="jfb-addons-page__license-form" slot="content"> |
| 109 | <span v-if="!isLicenseActivated">Activate license for automatic updates and awesome support</span> |
| 110 | <span |
| 111 | v-if="isLicenseActivated">By deactivating the license you will not be able to update the addons</span> |
| 112 | <cx-vui-input |
| 113 | class="jfb-addons-page__license-input" |
| 114 | size="fullwidth" |
| 115 | type="password" |
| 116 | :autofocus="true" |
| 117 | :prevent-wrap="true" |
| 118 | placeholder="Just paste it here" |
| 119 | v-model="licenseKey" |
| 120 | ></cx-vui-input> |
| 121 | <cx-vui-button |
| 122 | class="jfb-addons-page__license-action" |
| 123 | button-style="accent" |
| 124 | size="mini" |
| 125 | :loading="licenseProccesingState" |
| 126 | @click="licenseAction" |
| 127 | > |
| 128 | <span slot="label"> |
| 129 | <span v-if="!isLicenseActivated">Activate</span> |
| 130 | <span v-if="isLicenseActivated">Deactivate</span> |
| 131 | </span> |
| 132 | </cx-vui-button> |
| 133 | </div> |
| 134 | </cx-vui-popup> |
| 135 | </div> |
| 136 | |
| 137 | </template> |
| 138 | |
| 139 | <script> |
| 140 | import AddonItem from './components/AddonItem.vue'; |
| 141 | |
| 142 | const { applyFilters, doAction } = wp.hooks; |
| 143 | |
| 144 | window.jfbEventBus = new Vue(); |
| 145 | |
| 146 | export default { |
| 147 | name: 'jfb-addons', |
| 148 | components: { |
| 149 | AddonItem, |
| 150 | }, |
| 151 | data() { |
| 152 | return { |
| 153 | allAddons: window.JetFBPageConfig.allAddons || {}, |
| 154 | licenseList: window.JetFBPageConfig.licenseList || [], |
| 155 | licenseKey: window.JetFBPageConfig.licenseKey || '', |
| 156 | themeInfo: window.JetFBPageConfig.themeInfo || false, |
| 157 | miscInfo: window.JetFBPageConfig.miscInfo || false, |
| 158 | |
| 159 | licenseActivated: false, |
| 160 | licensePopupVisible: false, |
| 161 | licenseProccesingState: false, |
| 162 | licenseAjaxAction: null, |
| 163 | |
| 164 | checkUpdatesAction: null, |
| 165 | checkUpdatesProcessed: false, |
| 166 | |
| 167 | proccesingState: false, |
| 168 | }; |
| 169 | }, |
| 170 | mounted: function () { |
| 171 | window.jfbEventBus.$on( 'updateAddonData', this.updateAddonData ); |
| 172 | window.jfbEventBus.$on( 'showLicensePopup', this.showLicensePopup ); |
| 173 | }, |
| 174 | computed: { |
| 175 | isLicenseMode() { |
| 176 | return '' !== window.JetFBPageConfig.licenseMode ? true : false; |
| 177 | }, |
| 178 | |
| 179 | isLicenseActivated() { |
| 180 | return 0 !== this.licenseList.length; |
| 181 | }, |
| 182 | |
| 183 | licenseActionType() { |
| 184 | return !this.isLicenseActivated ? 'activate_license' : 'deactivate_license'; |
| 185 | }, |
| 186 | |
| 187 | installedAddonList() { |
| 188 | let installedAddonsList = {}; |
| 189 | |
| 190 | for ( let addonSlug in this.allAddons ) { |
| 191 | |
| 192 | if ( this.allAddons[ addonSlug ][ 'isInstalled' ] ) { |
| 193 | installedAddonsList[ addonSlug ] = this.allAddons[ addonSlug ]; |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | return installedAddonsList; |
| 198 | }, |
| 199 | |
| 200 | availableAddonList() { |
| 201 | let availableAddonList = {}; |
| 202 | |
| 203 | for ( let addonSlug in this.allAddons ) { |
| 204 | |
| 205 | if ( !this.allAddons[ addonSlug ][ 'isInstalled' ] ) { |
| 206 | availableAddonList[ addonSlug ] = this.allAddons[ addonSlug ]; |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | return availableAddonList; |
| 211 | }, |
| 212 | |
| 213 | goProLink() { |
| 214 | let pricingPageUrl = this.miscInfo.pricingPageUrl, |
| 215 | utmParams = this.getUtmParamsString( { |
| 216 | utm_source: `jetformbuilder-dashboard/addons`, |
| 217 | utm_medium: `license-not-activated/${ this.themeInfo.authorSlug }`, |
| 218 | utm_campaign: 'go-pro-button', |
| 219 | } ); |
| 220 | |
| 221 | return `${ pricingPageUrl }?${ utmParams }`; |
| 222 | }, |
| 223 | }, |
| 224 | methods: { |
| 225 | showLicensePopup() { |
| 226 | this.licensePopupVisible = true; |
| 227 | }, |
| 228 | |
| 229 | updateAddonData( data ) { |
| 230 | let slug = data.slug, |
| 231 | addonData = data.addonData, |
| 232 | pluginAction = data.action, |
| 233 | reloadActionMap = [ 'activate', 'deactivate', 'update' ]; |
| 234 | |
| 235 | this.allAddons[ slug ] = Object.assign( {}, this.allAddons[ slug ], addonData ); |
| 236 | |
| 237 | if ( reloadActionMap.includes( pluginAction ) ) { |
| 238 | this.proccesingState = true; |
| 239 | |
| 240 | setTimeout( function () { |
| 241 | window.location.reload(); |
| 242 | }, 1000 ); |
| 243 | } |
| 244 | }, |
| 245 | |
| 246 | licenseAction() { |
| 247 | var self = this; |
| 248 | |
| 249 | if ( '' === this.licenseKey ) { |
| 250 | self.$CXNotice.add( { |
| 251 | message: 'License key is missing', |
| 252 | type: 'error', |
| 253 | duration: 4000, |
| 254 | } ); |
| 255 | |
| 256 | return false; |
| 257 | } |
| 258 | |
| 259 | this.licenseProccesingState = true; |
| 260 | |
| 261 | self.licenseAjaxAction = jQuery.ajax( { |
| 262 | type: 'POST', |
| 263 | url: window.JetFBPageConfig.ajaxUrl, |
| 264 | dataType: 'json', |
| 265 | data: { |
| 266 | action: 'jfb_license_action', |
| 267 | nonce: window.JetFBPageConfig.nonce, |
| 268 | data: { |
| 269 | license: self.licenseKey, |
| 270 | action: self.licenseActionType, |
| 271 | }, |
| 272 | }, |
| 273 | beforeSend: ( jqXHR, ajaxSettings ) => { |
| 274 | |
| 275 | if ( null !== self.licenseAjaxAction ) { |
| 276 | self.licenseAjaxAction.abort(); |
| 277 | } |
| 278 | }, |
| 279 | success: ( responce, textStatus, jqXHR ) => { |
| 280 | self.licenseProccesingState = false; |
| 281 | |
| 282 | if ( responce.success ) { |
| 283 | self.$CXNotice.add( { |
| 284 | message: responce.message, |
| 285 | type: 'success', |
| 286 | duration: 4000, |
| 287 | } ); |
| 288 | |
| 289 | let licenseData = responce.data; |
| 290 | |
| 291 | licenseData[ 'license_key' ] = self.licenseKey; |
| 292 | |
| 293 | switch ( self.licenseActionType ) { |
| 294 | case 'activate_license': |
| 295 | |
| 296 | self.licenseList.push( licenseData ); |
| 297 | break; |
| 298 | case 'deactivate_license': |
| 299 | |
| 300 | self.licenseList = self.licenseList.filter( ( licenseData ) => { |
| 301 | return self.licenseKey !== licenseData[ 'license_key' ]; |
| 302 | } ); |
| 303 | |
| 304 | self.licenseKey = ''; |
| 305 | break; |
| 306 | } |
| 307 | |
| 308 | self.licensePopupVisible = false; |
| 309 | } |
| 310 | else { |
| 311 | self.$CXNotice.add( { |
| 312 | message: responce.message, |
| 313 | type: 'error', |
| 314 | duration: 4000, |
| 315 | } ); |
| 316 | } |
| 317 | }, |
| 318 | } ); |
| 319 | }, |
| 320 | |
| 321 | checkPluginsUpdate: function () { |
| 322 | var self = this; |
| 323 | |
| 324 | self.checkUpdatesAction = jQuery.ajax( { |
| 325 | type: 'POST', |
| 326 | url: window.JetFBPageConfig.ajaxUrl, |
| 327 | dataType: 'json', |
| 328 | data: { |
| 329 | action: 'jfb_license_service_action', |
| 330 | nonce: window.JetFBPageConfig.nonce, |
| 331 | data: { |
| 332 | action: 'check-plugin-update', |
| 333 | }, |
| 334 | }, |
| 335 | beforeSend: ( jqXHR, ajaxSettings ) => { |
| 336 | |
| 337 | if ( null !== self.checkUpdatesAction ) { |
| 338 | self.checkUpdatesAction.abort(); |
| 339 | } |
| 340 | |
| 341 | self.checkUpdatesProcessed = true; |
| 342 | }, |
| 343 | success: function ( responce, textStatus, jqXHR ) { |
| 344 | self.checkUpdatesProcessed = false; |
| 345 | |
| 346 | if ( responce.success ) { |
| 347 | self.$CXNotice.add( { |
| 348 | message: responce.message, |
| 349 | type: 'success', |
| 350 | duration: 4000, |
| 351 | } ); |
| 352 | |
| 353 | self.proccesingState = true; |
| 354 | |
| 355 | setTimeout( function () { |
| 356 | window.location.reload(); |
| 357 | }, 1000 ); |
| 358 | } |
| 359 | else { |
| 360 | self.$CXNotice.add( { |
| 361 | message: responce.message, |
| 362 | type: 'error', |
| 363 | duration: 4000, |
| 364 | } ); |
| 365 | } |
| 366 | }, |
| 367 | } ); |
| 368 | }, |
| 369 | |
| 370 | addLicense( licenseData ) { |
| 371 | this.licenseList.push( licenseData ); |
| 372 | |
| 373 | self.proccesingState = true; |
| 374 | |
| 375 | setTimeout( function () { |
| 376 | window.location.reload(); |
| 377 | }, 3000 ); |
| 378 | }, |
| 379 | |
| 380 | removeLicense( licenceKey ) { |
| 381 | |
| 382 | let removingIndex = false; |
| 383 | |
| 384 | for ( let licenceIndex in this.licenseList ) { |
| 385 | let licenseData = this.licenseList[ licenceIndex ]; |
| 386 | |
| 387 | if ( licenseData[ 'licenseKey' ] === licenceKey ) { |
| 388 | removingIndex = licenceIndex; |
| 389 | |
| 390 | break; |
| 391 | } |
| 392 | } |
| 393 | |
| 394 | if ( removingIndex ) { |
| 395 | this.licenseList.splice( removingIndex, 1 ); |
| 396 | } |
| 397 | |
| 398 | this.licensePopupVisible = false; |
| 399 | |
| 400 | setTimeout( function () { |
| 401 | window.location.reload(); |
| 402 | }, 500 ); |
| 403 | }, |
| 404 | |
| 405 | getUtmParamsString( data = {} ) { |
| 406 | let utmString = false; |
| 407 | |
| 408 | if ( 0 === Object.keys( data ).length ) { |
| 409 | return utmString; |
| 410 | } |
| 411 | |
| 412 | utmString = Object.keys( data ).map( ( key ) => { |
| 413 | return [ key, data[ key ] ].map( encodeURIComponent ).join( '=' ); |
| 414 | } ).join( '&' ); |
| 415 | |
| 416 | return utmString; |
| 417 | }, |
| 418 | }, |
| 419 | }; |
| 420 | </script> |
| 421 | |
| 422 | <style lang="scss"> |
| 423 | |
| 424 | .proccesing-state { |
| 425 | opacity: 0.5; |
| 426 | pointer-events: none; |
| 427 | } |
| 428 | |
| 429 | .jfb-addons-page { |
| 430 | &__inner { |
| 431 | padding: 30px; |
| 432 | height: 100%; |
| 433 | } |
| 434 | |
| 435 | &__header { |
| 436 | margin-bottom: 30px; |
| 437 | } |
| 438 | |
| 439 | &__header-controls { |
| 440 | display: flex; |
| 441 | justify-content: flex-end; |
| 442 | align-items: center; |
| 443 | padding-bottom: 15px; |
| 444 | border-bottom: 1px solid #DCDCDD; |
| 445 | |
| 446 | > .cx-vui-button { |
| 447 | margin-left: 10px; |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | .cx-vui-button { |
| 452 | font-size: 13px; |
| 453 | font-weight: 400; |
| 454 | background-color: transparent; |
| 455 | |
| 456 | .button-icon { |
| 457 | margin-right: 5px; |
| 458 | } |
| 459 | |
| 460 | &--style-accent { |
| 461 | color: #007cba; |
| 462 | box-shadow: inset 0 0 0 1px #007cba; |
| 463 | |
| 464 | &:hover { |
| 465 | background-color: #007cba12; |
| 466 | } |
| 467 | |
| 468 | .button-icon { |
| 469 | path { |
| 470 | fill: #007cba; |
| 471 | } |
| 472 | } |
| 473 | } |
| 474 | |
| 475 | &--style-danger { |
| 476 | color: #d6336c; |
| 477 | box-shadow: inset 0 0 0 1px #d6336c; |
| 478 | |
| 479 | &:hover { |
| 480 | background-color: #d6336c12; |
| 481 | } |
| 482 | |
| 483 | .button-icon { |
| 484 | path { |
| 485 | fill: #d6336c; |
| 486 | } |
| 487 | } |
| 488 | } |
| 489 | |
| 490 | &__content { |
| 491 | > span { |
| 492 | display: flex; |
| 493 | justify-content: center; |
| 494 | align-items: center; |
| 495 | } |
| 496 | } |
| 497 | } |
| 498 | |
| 499 | .cx-vui-popup { |
| 500 | &__header { |
| 501 | padding-bottom: 15px; |
| 502 | border-bottom: 1px solid #DCDCDD; |
| 503 | margin-bottom: 30px; |
| 504 | } |
| 505 | |
| 506 | &__header-title { |
| 507 | font-weight: 500; |
| 508 | font-size: 24px; |
| 509 | line-height: 36px; |
| 510 | color: #23282D; |
| 511 | } |
| 512 | } |
| 513 | |
| 514 | &__license-popup { |
| 515 | } |
| 516 | |
| 517 | &__license-form { |
| 518 | display: flex; |
| 519 | flex-direction: column; |
| 520 | justify-content: flex-start; |
| 521 | align-items: stretch; |
| 522 | |
| 523 | > span { |
| 524 | margin-bottom: 10px; |
| 525 | } |
| 526 | } |
| 527 | |
| 528 | &__license-input { |
| 529 | margin-bottom: 10px; |
| 530 | } |
| 531 | |
| 532 | .go-pro-banner { |
| 533 | display: flex; |
| 534 | flex-direction: column; |
| 535 | justify-content: center; |
| 536 | align-items: center; |
| 537 | padding: 24px 0; |
| 538 | border-bottom: 1px solid #DCDCDD; |
| 539 | |
| 540 | &__subtitle { |
| 541 | font-size: 18px; |
| 542 | line-height: 1.25; |
| 543 | font-weight: 500; |
| 544 | color: #007CBA; |
| 545 | margin-bottom: 5px; |
| 546 | } |
| 547 | |
| 548 | &__title { |
| 549 | font-size: 24px; |
| 550 | line-height: 1.25; |
| 551 | font-weight: 500; |
| 552 | color: #23282D; |
| 553 | margin-bottom: 20px; |
| 554 | } |
| 555 | |
| 556 | &__button { |
| 557 | color: white; |
| 558 | background-color: #007CBA; |
| 559 | } |
| 560 | } |
| 561 | } |
| 562 | |
| 563 | </style> |