@@ -148,24 +148,32 @@ define(function (require, exports, module) {
148148 /**
149149 * Update the license status display in the dialog
150150 */
151- function _updateLicenseStatusDisplay ( $dialog , licenseData ) {
151+ async function _updateLicenseStatusDisplay ( $dialog , licenseData ) {
152152 const $loading = $dialog . find ( '#license-status-loading' ) ;
153153 const $none = $dialog . find ( '#license-status-none' ) ;
154154 const $valid = $dialog . find ( '#license-status-valid' ) ;
155155 const $error = $dialog . find ( '#license-status-error' ) ;
156+ const $reapplyContainer = $dialog . find ( '#reapply-license-container' ) ;
156157
157158 // Hide all status sections
158159 $loading . hide ( ) ;
159160 $none . hide ( ) ;
160161 $valid . hide ( ) ;
161162 $error . hide ( ) ;
163+ $reapplyContainer . hide ( ) ;
162164
163165 if ( licenseData && licenseData . isValid ) {
164166 // Show valid license info
165167 $dialog . find ( '#licensed-to-name' ) . text ( licenseData . licensedToName || Strings . LICENSE_STATUS_UNKNOWN ) ;
166168 $dialog . find ( '#license-type-name' ) . text ( licenseData . licenseTypeName || Strings . LICENSE_STATUS_UNKNOWN ) ;
167169 $dialog . find ( '#license-valid-till' ) . text ( _formatDate ( licenseData . validTill ) ) ;
168170 $valid . show ( ) ;
171+
172+ // Show reapply button if license is valid but not applied system-wide
173+ const isLicensed = await NodeUtils . isLicensedDevice ( ) ;
174+ if ( ! isLicensed ) {
175+ $reapplyContainer . show ( ) ;
176+ }
169177 } else if ( licenseData && licenseData . isValid === false ) {
170178 // No valid license
171179 $none . show ( ) ;
@@ -270,6 +278,35 @@ define(function (require, exports, module) {
270278 }
271279 }
272280
281+ /**
282+ * Handle reapply license to device
283+ */
284+ async function _handleReapplyLicense ( $dialog ) {
285+ const $link = $dialog . find ( '#reapply-license-link' ) ;
286+ const originalText = $link . html ( ) ;
287+
288+ try {
289+ // Show loading state
290+ $link . html ( '<i class="fa fa-spinner fa-spin" style="margin-right: 6px;"></i>Applying...' ) ;
291+ $link . css ( 'pointer-events' , 'none' ) ;
292+
293+ const addSuccess = await NodeUtils . addDeviceLicense ( ) ;
294+ if ( addSuccess ) {
295+ _showActivationMessage ( $dialog , true , Strings . LICENSE_ACTIVATE_SUCCESS ) ;
296+ // Refresh license status
297+ await _loadLicenseStatus ( $dialog ) ;
298+ } else {
299+ _showActivationMessage ( $dialog , false , 'Failed to apply license to device' ) ;
300+ }
301+ } catch ( error ) {
302+ _showActivationMessage ( $dialog , false , error . message || 'Failed to apply license to device' ) ;
303+ } finally {
304+ // Reset link state
305+ $link . html ( originalText ) ;
306+ $link . css ( 'pointer-events' , 'auto' ) ;
307+ }
308+ }
309+
273310 async function showManageLicensesDialog ( ) {
274311 const $template = $ ( Mustache . render ( licenseManagementHTML , { Strings} ) ) ;
275312
@@ -279,6 +316,7 @@ define(function (require, exports, module) {
279316 const $dialog = $template ;
280317 const $licenseInput = $dialog . find ( '#license-key-input' ) ;
281318 const $activateBtn = $dialog . find ( '#activate-license-btn' ) ;
319+ const $reapplyLink = $dialog . find ( '#reapply-license-link' ) ;
282320
283321 // Handle activate button click
284322 $activateBtn . on ( 'click' , async function ( ) {
@@ -298,6 +336,12 @@ define(function (require, exports, module) {
298336 }
299337 } ) ;
300338
339+ // Handle reapply license link click
340+ $reapplyLink . on ( 'click' , async function ( e ) {
341+ e . preventDefault ( ) ;
342+ await _handleReapplyLicense ( $dialog ) ;
343+ } ) ;
344+
301345 // Load current license status
302346 await _loadLicenseStatus ( $dialog ) ;
303347 }
0 commit comments