Queue and Public Group Assignments using Lightning Web Component (LWC) in Salesforce

Queue and Public Group Assignments using Lightning Web Component (LWC) in Salesforce

Sample Code:

Apex:

public class QueueAssignmentController {

    @AuraEnabled( cacheable=true )
    public static QueuePublicGroupWrapper fetchQueueAssignments( String strUserId ) {
    
        QueuePublicGroupWrapper objQW = new QueuePublicGroupWrapper();
        Set < String > setAssignedQueueIds = new Set < String >();
        List < OptionWrapper > allQueues = new List < OptionWrapper >();
        Set < String > setAssignedPublicGroupIds = new Set < String >();
        List < OptionWrapper > allPublicGroups = new List < OptionWrapper >();
        Set < String > groupTypes = new Set < String > { 'Queue', 'Regular' };
        Set < Id > setGroupIds = new Set < Id >();
        
        for ( GroupMember objGM : [ SELECT Id, Group.Name, GroupId, Group.Type FROM GroupMember WHERE UserOrGroupId =: strUserId AND Group.Type IN: groupTypes ] ) {
            
            if ( objGM.Group.Type == 'Queue' ) {

                setAssignedQueueIds.add( objGM.GroupId );
                OptionWrapper objOW = new OptionWrapper();
                objOW.label = objGM.Group.Name;
                objOW.value = objGM.GroupId;
                allQueues.add( objOW );

            } else {

                setAssignedPublicGroupIds.add( objGM.GroupId );
                OptionWrapper objOW = new OptionWrapper();
                objOW.label = objGM.Group.Name;
                objOW.value = objGM.GroupId;
                allPublicGroups.add( objOW );

            }

            setGroupIds.add( objGM.GroupId );
        
        }
        
        for ( Group objGroup : [ SELECT Id, Name, Type FROM Group WHERE Id NOT IN:setGroupIds AND Type IN: groupTypes ] ) {
            
            if ( objGroup.Type == 'Queue' ) {

                OptionWrapper objOW = new OptionWrapper();
                objOW.label = objGroup.Name;
                objOW.value = objGroup.Id;
                allQueues.add( objOW );

            } else {

                OptionWrapper objOW = new OptionWrapper();
                objOW.label = objGroup.Name;
                objOW.value = objGroup.Id;
                allPublicGroups.add( objOW );

            }
        
        }
        
        objQW.availableQueues = allQueues;
        objQW.availablePublicGroups = allPublicGroups;
        objQW.selectedQueues = new List < String >();
        objQW.selectedPublicGroups = new List < String >();
        
        if ( setAssignedQueueIds.size() > 0 ) {

            objQW.selectedQueues.addAll( setAssignedQueueIds );

        }
        
        if ( setAssignedPublicGroupIds.size() > 0 ) {
            
            objQW.selectedPublicGroups.addAll( setAssignedPublicGroupIds );

        }
        
        return objQW;
    
    }
    
    @AuraEnabled
    public static String addRemoveQueues( String strUserId, List < String > selectedQueues, List < String > updatedQueues,
        List < String > selectedPublicGroups, List < String > updatedPublicGroups,
        Boolean queuesUpdatedBool, Boolean publicGroupsUpdatedBool
    ) {
    
        List < GroupMember > listGroupMembersForInsert = new List < GroupMember >();
        Set < String > setGroupIds = new Set < String >();
    
        try {
        
            Set < String > setSelectedQueues = new Set < String >();
            Set < String > setUpdatedQueues = new Set < String >();
            Set < String > setSelectedPublicGroups = new Set < String >();
            Set < String > setUpdatedPublicGroups = new Set < String >();
            setSelectedQueues.addAll( selectedQueues );
            setUpdatedQueues.addAll( updatedQueues );
            setSelectedPublicGroups.addAll( selectedPublicGroups );
            setUpdatedPublicGroups.addAll( updatedPublicGroups );
            
            if ( queuesUpdatedBool ) {
                for ( String strQueue : setUpdatedQueues ) {
                
                    if ( !setSelectedQueues.contains( strQueue ) ) {
                        
                        GroupMember objGM = new GroupMember();
                        objGM.UserOrGroupId = strUserId;
                        objGM.GroupId = strqueue;
                        listGroupMembersForInsert.add( objGM );
                        
                    }
                
                }
                
                for ( String strQueue : setSelectedQueues ) {
                
                    if ( !setUpdatedQueues.contains( strQueue ) ) {
                        
                        setGroupIds.add( strQueue );
                        
                    }
                
                }
        
            }

            if ( publicGroupsUpdatedBool ) {

                for ( String strPublicGroup : setUpdatedPublicGroups ) {
                
                    if ( !setSelectedPublicGroups.contains( strPublicGroup ) ) {
                        
                        GroupMember objGM = new GroupMember();
                        objGM.UserOrGroupId = strUserId;
                        objGM.GroupId = strPublicGroup;
                        listGroupMembersForInsert.add( objGM );
                        
                    }
                
                }

            }
            
            for ( String strPublicGroup : setSelectedPublicGroups ) {
            
                if ( !setUpdatedPublicGroups.contains( strPublicGroup ) ) {
                    
                    setGroupIds.add( strPublicGroup );
                    
                }
            
            }
            
            if ( setGroupIds.size() > 0 ) {
                
                delete [ SELECT Id FROM GroupMember WHERE UserOrGroupId =: strUserId AND GroupId IN: setGroupIds ];

            }
            
            if ( listGroupMembersForInsert.size() > 0 ) {
            
                insert listGroupMembersForInsert;
                
            }

            return 'Successful';
            
        
        } catch ( Exception e ) {
        
            throw new AuraHandledException( e.getMessage() );
            
        }
    
    }
    
    public class QueuePublicGroupWrapper {

        @AuraEnabled
        public List < OptionWrapper > availableQueues;
        @AuraEnabled
        public List < String > selectedQueues;
        @AuraEnabled
        public List < OptionWrapper > availablePublicGroups;
        @AuraEnabled
        public List < String > selectedPublicGroups;

    }

    public class OptionWrapper {

        @AuraEnabled
        public String value;
        @AuraEnabled
        public String label;

    }

}

HTML:

<template>
    <div class="slds-box slds-theme--default">
        <lightning-record-edit-form object-api-name="Account">
            <lightning-input-field field-name="User__c" onchange={handleUserChange}></lightning-input-field>
        </lightning-record-edit-form>
        <template if:true={showBool}>
            <lightning-card>
                <lightning-dual-listbox
                    label="Select/Remove Queues"
                    source-label="Available Queues"
                    selected-label="Selected Queues"
                    options={availableQueues}
                    value={selectedQueues}
                    onchange={handleQueuesChange}
                    class="slds-m-around_medium">
                </lightning-dual-listbox><br/><br/>
                <lightning-dual-listbox
                    label="Select/Remove Public Groups"
                    source-label="Available Public Groups"
                    selected-label="Selected Public Groups"
                    options={availablePublicGroups}
                    value={selectedPublicGroups}
                    onchange={handlePublicGroupsChange}
                    class="slds-m-around_medium">
                </lightning-dual-listbox>
                <p slot="footer">
                    <lightning-button
                        variant="brand"
                        label="Save"
                        onclick={saveChanges}
                        disabled={buttonBool}>
                    </lightning-button>
                </p>
            </lightning-card>    
        </template>
    </div>
</template>

JavaScript:

import { LightningElement } from 'lwc';
import fetchQueueAssignments from '@salesforce/apex/QueueAssignmentController.fetchQueueAssignments';
import addRemoveQueues from '@salesforce/apex/QueueAssignmentController.addRemoveQueues';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class QueueAssignment extends LightningElement {

    availableQueues;
    selectedQueues;
    updatedQueues;
    availablePublicGroups;
    selectedPublicGroups;
    updatedPublicGroups;
    showBool = false;
    buttonBool = false;
    userId;

    handleUserChange( event ) {

        let selectedUserId = event.target.value;
        console.log( 'Selected User Id is ' + selectedUserId );

        if ( selectedUserId ) {

            this.userId = selectedUserId;
            this.showBool = true;
            
        } else {

            this.showBool = false;

        }

        fetchQueueAssignments( { strUserId : this.userId } )
        .then( data => {

            console.log( 'Data ===> ' + data );
            console.log( 'Records are ' + JSON.stringify( data ) );
            this.availableQueues = data.availableQueues;
            this.selectedQueues = data.selectedQueues;
            this.updatedQueues = data.selectedQueues;
            this.availablePublicGroups = data.availablePublicGroups;
            this.selectedPublicGroups = data.selectedPublicGroups;
            this.updatedPublicGroups = data.selectedPublicGroups;

        })
        .catch( error => {

            this.dispatchEvent(
                new ShowToastEvent( {
                    title: 'Error!!',
                    message: 'Some error occured. Please reach out to your Salesforce Admin for help!',
                    variant: 'error',
                    mode: 'sticky'
                } ),
            );     

        } )

    }

    handleQueuesChange( event ) {

        const selectedOptionsList = event.detail.value;
        console.log( 'Selected Options are ' + JSON.stringify( selectedOptionsList ) );
        this.updatedQueues = selectedOptionsList;
        console.log( 'Updated Selected Queues are ' + JSON.stringify( this.selectedQueues ) );

    }

    handlePublicGroupsChange( event ) {

        const selectedOptionsList = event.detail.value;
        console.log( 'Selected Options are ' + JSON.stringify( selectedOptionsList ) );
        this.updatedPublicGroups = selectedOptionsList;
        console.log( 'Updated Selected Public Groups are ' + JSON.stringify( this.selectedPublicGroups ) );

    }

    saveChanges() {

        let queuesUpdatedBool = false;
        let publicGroupsUpdatedBool = false;

        console.log( 'selectedQueues is ' + JSON.stringify( this.selectedQueues ) );
        console.log( 'updatedQueues is ' + JSON.stringify( this.updatedQueues ) );
        console.log( 'selectedPublicGroups is ' + JSON.stringify( this.selectedPublicGroups ) );
        console.log( 'updatedPublicGroups is ' + JSON.stringify( this.updatedPublicGroups ) );

        if ( JSON.stringify( this.selectedQueues ) != JSON.stringify( this.updatedQueues ) ) {

            queuesUpdatedBool = true;

        }

        if ( JSON.stringify( this.selectedPublicGroups ) != JSON.stringify( this.updatedPublicGroups ) ) {

            publicGroupsUpdatedBool = true;

        }

        console.log( 'queuesUpdatedBool is ' + queuesUpdatedBool );
        console.log( 'queuesUpdatedBool is ' + publicGroupsUpdatedBool );

        if ( queuesUpdatedBool || publicGroupsUpdatedBool ) {
            
            addRemoveQueues( { strUserId : this.userId,
                selectedQueues : this.selectedQueues, updatedQueues : this.updatedQueues,
                selectedPublicGroups : this.selectedPublicGroups, updatedPublicGroups : this.updatedPublicGroups,
                queuesUpdatedBool : queuesUpdatedBool, publicGroupsUpdatedBool : publicGroupsUpdatedBool } )
            .then( result => {

                console.log( 'Result ' + JSON.stringify( result ) );
                let message;
                let variant;

                if ( result === 'Successful' ) {

                    message = 'Successfully Processed!';
                    variant = 'success';

                } else {

                    message = 'Some error occured. Please reach out to your Salesforce Admin for help!';
                    variant = 'error';
                    
                }

                const toastEvent = new ShowToastEvent( {

                    title: 'Queue(s) and Public Group(s) Assignment',
                    message: message,
                    variant: variant

                } );
                this.dispatchEvent( toastEvent );

            } )
            .catch( error => {

                console.log( 'Error ' + JSON.stringify( error ) );
                
            } );
            this.buttonBool = true;

        } else {

            alert( "No changes made!!!" );

        }
            
    }

}

Meta.xml:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

Output:

Leave a Reply