plugins_Awards_Assets_js_controllers_rec-bulk-edit-controller.js



import { Controller } from "@hotwired/stimulus";

/**
 * Awards Recommendation Bulk Edit Controller
 *
 * Modal form for batch state updates on multiple recommendations with
 * state-driven field rules and gathering intersection logic.
 *
 * Targets: bulkIds, gatherings, state, planToGiveBlock, planToGiveGathering,
 *          givenBlock, recId, turboFrame, givenDate, closeReason, closeReasonBlock,
 *          stateRulesBlock
 * Values: formUrl (String), turboFrameUrl (String), bulkIds (Array), gatheringsUrl (String)
 * Outlets: outlet-btn
 */
class AwardsRecommendationBulkEditForm extends Controller {
    static targets = [
        "bulkIds",
        "gatherings",
        "state",
        "planToGiveBlock",
        "planToGiveGathering",
        "givenBlock",
        "recId",
        "turboFrame",
        "givenDate",
        "closeReason",
        "closeReasonBlock",
        "stateRulesBlock",
    ];
    static values = {
        formUrl: String,
        turboFrameUrl: String,
        bulkIds: Array,
        gatheringsUrl: String,
        gatheringsLookupUrl: String,
    };
    static outlets = ['outlet-btn'];

    /** Receive bulk IDs from table selection and update form action URL. */
    setId(event) {

        console.log("setId called", event.detail);
        //debugger;

        let selected = event.detail.ids;
        if (!selected) {
            return;
        }
        if (!selected.length) {
            return;
        }
        this.bulkIdsValue = selected;
        this.bulkIdsTarget.value = selected;
        let actionUrl = this.element.getAttribute("action");
        //replace url
        actionUrl = actionUrl.replace(/update-states/, "updateStates");
        this.element.setAttribute("action", actionUrl);
        console.log("setId", this.element["action"]);

        // Update gatherings list based on selected recommendations
        this.updateGatherings();

        return
    }

    /** Update backend lookup URL for gathering autocomplete in bulk edit. */
    updateGatherings() {
        if (!this.hasPlanToGiveGatheringTarget || !this.hasGatheringsLookupUrlValue) {
            return;
        }

        const selectedIds = (this.bulkIdsValue || []).filter(Boolean);
        const idsKey = selectedIds.join(',');
        if (
            this.planToGiveGatheringTarget.dataset.lookupIdsKey !== undefined &&
            this.planToGiveGatheringTarget.dataset.lookupIdsKey !== idsKey
        ) {
            this.planToGiveGatheringTarget.value = '';
            this.planToGiveGatheringTarget.dataset.initialValue = '';
        }
        this.planToGiveGatheringTarget.dataset.lookupIdsKey = idsKey;

        const currentSelection = this.planToGiveGatheringTarget.value ||
            this.planToGiveGatheringTarget.dataset.initialValue ||
            '';

        const params = new URLSearchParams();
        if (selectedIds.length > 0) {
            params.append('ids', selectedIds.join(','));
        }
        if (this.hasStateTarget && this.stateTarget.value) {
            params.append('status', this.stateTarget.value);
        }
        if (currentSelection) {
            params.append('selected_id', currentSelection);
            this.planToGiveGatheringTarget.dataset.initialValue = currentSelection;
        }

        let lookupUrl = this.gatheringsLookupUrlValue;
        if (params.toString()) {
            lookupUrl += `?${params.toString()}`;
        }
        this.planToGiveGatheringTarget.setAttribute('data-ac-url-value', lookupUrl);
    }

    /** Sync required state to autocomplete text input. */
    setPlanToGiveRequired(required) {
        if (!this.hasPlanToGiveGatheringTarget) {
            return;
        }
        this.planToGiveGatheringTarget.required = required;
        const input = this.planToGiveGatheringTarget.querySelector("[data-ac-target='input']");
        if (input) {
            input.required = required;
        }
    }

    /** Register listener when outlet-btn connects. */
    outletBtnOutletConnected(outlet, element) {
        outlet.addListener(this.setId.bind(this));
    }

    /** Remove listener when outlet-btn disconnects. */
    outletBtnOutletDisconnected(outlet) {
        outlet.removeListener(this.setId.bind(this));
    }

    /** Close modal after form submission. */
    submit(event) {
        document.getElementById("recommendation_bulk_edit_close").click();
    }

    /** Apply field rules when state target connects. */
    stateTargetConnected() {
        this.setFieldRules();
    }

    /** Parse JSON state rules and apply Visible/Required/Disabled field states. */
    setFieldRules() {
        var rulesstring = this.stateRulesBlockTarget.textContent;
        var rules = JSON.parse(rulesstring);
        this.planToGiveBlockTarget.style.display = "none";
        this.givenBlockTarget.style.display = "none";
        this.setPlanToGiveRequired(false);
        this.givenDateTarget.required = false;
        this.closeReasonBlockTarget.style.display = "none";
        this.closeReasonTarget.required = false;
        var state = this.stateTarget.value;

        //check status rules for the status
        if (rules[state]) {
            var statusRules = rules[state];
            var controller = this;
            if (statusRules["Visible"]) {
                statusRules["Visible"].forEach(function (field) {
                    if (controller[field]) {
                        controller[field].style.display = "block";
                    }
                });
            }
            if (statusRules["Disabled"]) {
                statusRules["Disabled"].forEach(function (field) {
                    if (controller[field]) {
                        controller[field].disabled = true;
                    }
                });
            }
            if (statusRules["Required"]) {
                statusRules["Required"].forEach(function (field) {
                    if (controller[field]) {
                        controller[field].required = true;
                    }
                });
            }
        }
        this.setPlanToGiveRequired(!!this.planToGiveGatheringTarget.required);

        // Update gatherings list when status changes (affects future vs all gatherings)
        this.updateGatherings();
    }

    /** Initialize bulk edit controller and set up event listeners. */
    connect() {
        // Listen for bulk action events from grid-view controller
        this.boundHandleGridBulkAction = this.handleGridBulkAction.bind(this);
        document.addEventListener('grid-view:bulk-action', this.boundHandleGridBulkAction);
    }

    /** Clean up event listeners on disconnect. */
    disconnect() {
        if (this.boundHandleGridBulkAction) {
            document.removeEventListener('grid-view:bulk-action', this.boundHandleGridBulkAction);
        }
    }

    /** Handle bulk action event from grid-view controller. */
    handleGridBulkAction(event) {
        // Create a synthetic event structure matching outlet-btn pattern
        this.setId({ detail: event.detail });
    }
}
// add to window.Controllers with a name of the controller
if (!window.Controllers) {
    window.Controllers = {};
}
window.Controllers["awards-rec-bulk-edit"] = AwardsRecommendationBulkEditForm;