assets_js_controllers_revoke-form-controller.js

import { Controller } from "@hotwired/stimulus"

/**
 * **INTERNAL CODE DOCUMENTATION COMPLETE**
 * 
 * Revoke Form Controller
 * 
 * A specialized Stimulus controller that manages revocation workflows with outlet communication
 * and form validation. Provides seamless integration between trigger elements and revocation
 * forms with real-time validation and submit control.
 * 
 * Key Features:
 * - Inter-controller communication through outlet pattern
 * - Dynamic ID management from external triggers
 * - Real-time form validation with submit control
 * - Automatic event listener management and cleanup
 * - Bootstrap form integration with disabled state management
 * 
 * @class RevokeForm
 * @extends Controller
 * 
 * HTML Structure Example:
 * ```html
 * <!-- Revocation form with outlet communication -->
 * <form data-controller="revoke-form" 
 *       data-revoke-form-url-value="/revoke"
 *       data-revoke-form-outlet-btn-outlet="[data-controller*='outlet-btn']">
 *   <input type="hidden" data-revoke-form-target="id">
 *   
 *   <div class="mb-3">
 *     <label for="reason" class="form-label">Revocation Reason</label>
 *     <textarea data-revoke-form-target="reason" 
 *               data-action="input->revoke-form#checkReadyToSubmit"
 *               class="form-control" 
 *               rows="3" 
 *               required></textarea>
 *   </div>
 *   
 *   <button type="submit" 
 *           data-revoke-form-target="submitBtn"
 *           class="btn btn-danger">
 *     Revoke Access
 *   </button>
 * </form>
 * 
 * <!-- Trigger button with outlet communication -->
 * <button data-controller="outlet-btn" 
 *         data-outlet-btn-id-value="123"
 *         data-action="click->outlet-btn#fireNotice">
 *   Revoke User 123
 * </button>
 * ```
 */
class RevokeForm extends Controller {
    static values = {
        url: String,
    }
    static targets = ["submitBtn", "reason", "id"]

    static outlets = ["outlet-btn"]

    /**
     * Handle ID setting from outlet communication
     * Receives ID from outlet button clicks and updates hidden form field
     * 
     * @param {CustomEvent} event - Custom event containing ID details
     * @param {Object} event.detail - Event details object
     * @param {String} event.detail.id - The ID value to set in the form
     */
    setId(event) {
        this.idTarget.value = event.detail.id;
    }

    /**
     * Handle outlet button connection
     * Sets up event listener for ID communication from outlet buttons
     * 
     * @param {Controller} outlet - The connected outlet button controller
     * @param {HTMLElement} element - The outlet button element
     */
    outletBtnOutletConnected(outlet, element) {
        outlet.addListener(this.setId.bind(this));
    }

    /**
     * Handle outlet button disconnection
     * Removes event listener to prevent memory leaks
     * 
     * @param {Controller} outlet - The disconnected outlet button controller
     */
    outletBtnOutletDisconnected(outlet) {
        outlet.removeListener(this.setId.bind(this));
    }

    /**
     * Validate form readiness and control submit button state
     * Enables submit button only when reason field contains valid content
     * Provides real-time feedback for form completion status
     */
    checkReadyToSubmit() {
        let reasonValue = this.reasonTarget.value;
        if (reasonValue.length > 0) {
            this.submitBtnTarget.disabled = false;
        } else {
            this.submitBtnTarget.disabled = true;
        }
    }


    /**
     * Initialize controller state and disable form submission
     * Sets initial form state with disabled submit button until validation passes
     */
    connect() {
        this.submitBtnTarget.disabled = true;
    }

}
// add to window.Controllers with a name of the controller
if (!window.Controllers) {
    window.Controllers = {};
}
window.Controllers["revoke-form"] = RevokeForm;