Apex Class:
public with sharing class PublicGroupOrQueueAssignmentController {
@AuraEnabled( cacheable=false )
public static UserWrapper fetchGroupAssignments( String strGroupId ) {
UserWrapper objUW = new UserWrapper();
Set < String > setAssignedUserIds = new Set < String >();
List < UserOptionWrapper > allUsers = new List < UserOptionWrapper >();
for ( GroupMember objGM : [ SELECT Id, UserOrGroupId FROM GroupMember WHERE GroupId =: strGroupId ] ) {
String strUserOrGroupId = String.valueOf( objGM.UserOrGroupId );
if ( strUserOrGroupId.startsWith( '005' ) ) {
setAssignedUserIds.add( objGM.UserOrGroupId );
}
}
for ( User objUser : [ SELECT Id, Name FROM User WHERE IsActive = true ] ) {
UserOptionWrapper objUOW = new UserOptionWrapper();
objUOW.label = objUser.Name;
objUOW.value = objUser.Id;
allUsers.add( objUOW );
}
objUW.availableUsers = allUsers;
objUW.selectedUsers = new List < String >();
if ( setAssignedUserIds.size() > 0 )
objUW.selectedUsers.addAll( setAssignedUserIds );
return objUW;
}
@AuraEnabled
public static String addRemoveUsers( String strGroupId, List < String > selectedUsers, List < String > updatedUsers ) {
List < GroupMember > listGroupMembersForInsert = new List < GroupMember >();
Set < String > setUserIds = new Set < String >();
try {
Set < String > setSelectedUsers = new Set < String >();
Set < String > setUpdatedUsers = new Set < String >();
setSelectedUsers.addAll( selectedUsers );
setUpdatedUsers.addAll( updatedUsers );
for ( String strUserId : updatedUsers ) {
if ( !setSelectedUsers.contains( strUserId ) ) {
GroupMember objGM = new GroupMember();
objGM.UserOrGroupId = strUserId;
objGM.GroupId = strGroupId;
listGroupMembersForInsert.add( objGM );
}
}
for ( String strUserId : setSelectedUsers ) {
if ( !updatedUsers.contains( strUserId ) ) {
setUserIds.add( strUserId );
}
}
if ( setUserIds.size() > 0 ) {
delete [ SELECT Id FROM GroupMember WHERE UserOrGroupId IN: setUserIds AND GroupId =: strGroupId ];
}
if ( listGroupMembersForInsert.size() > 0 ) {
insert listGroupMembersForInsert;
}
return 'Successful';
} catch ( Exception e ) {
throw new AuraHandledException( e.getMessage() );
}
}
public class UserWrapper {
@AuraEnabled
public List < UserOptionWrapper > availableUsers;
@AuraEnabled
public List < String > selectedUsers;
}
public class UserOptionWrapper {
@AuraEnabled
public String value;
@AuraEnabled
public String label;
}
}
Lightning Web Component:
HTML:
<template>
<div class="slds-box slds-theme--default">
<lightning-input
type="text"
label="Enter the Queue or Public Group Id"
onchange={handleChane}>
</lightning-input>
<br/>
<lightning-button
variant="brand"
label="Fetch Details"
onclick={fetchGropus}
class="slds-m-left_x-small"
disabled={showBool}>
</lightning-button>
<template if:true={showBool}>
<lightning-dual-listbox
label="Select/Remove User(s)"
source-label="Available User(s)"
selected-label="Selected User(s)"
options={availableUsers}
value={selectedUsers}
onchange={handleUserChange}
class="slds-m-around_medium">
</lightning-dual-listbox>
<lightning-button
variant="brand"
label="Save"
onclick={saveChanges}
disabled={disableBool}>
</lightning-button>
</template>
</div>
</template>
JavaScript:
import { LightningElement } from 'lwc';
import fetchGroupAssignments from '@salesforce/apex/PublicGroupOrQueueAssignmentController.fetchGroupAssignments';
import addRemoveUsers from '@salesforce/apex/PublicGroupOrQueueAssignmentController.addRemoveUsers';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex';
export default class PublicGroupOrQueueAssignment extends LightningElement {
publicGroupOrQueueId;
availableUsers;
selectedUsers;
updatedUsers;
showBool = false;
disableBool = false;
handleChane( event ) {
this.publicGroupOrQueueId = event.target.value;
}
fetchGropus() {
console.log( 'Public Group or Queue Id is ' + this.publicGroupOrQueueId );
fetchGroupAssignments( { strGroupId : this.publicGroupOrQueueId } )
.then( data => {
console.log( 'Records are ' + JSON.stringify( data ) );
this.availableUsers = data.availableUsers;
this.selectedUsers = data.selectedUsers;
this.showBool = true;
})
.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'
} ),
);
} )
}
handleUserChange( event ) {
const selectedOptionsList = event.detail.value;
console.log( 'Selected Options are ' + JSON.stringify( selectedOptionsList ) );
this.updatedUsers = selectedOptionsList;
console.log( 'Selected Users are ' + JSON.stringify( this.selectedUsers ) );
console.log( 'Updated Users are ' + JSON.stringify( this.updatedUsers ) );
}
saveChanges() {
let updatedBool = false;
this.disableBool = true;
if ( JSON.stringify( this.selectedUsers ) != JSON.stringify( this.updatedUsers ) ) {
updatedBool = true;
}
if ( updatedBool == true ) {
addRemoveUsers( { strGroupId : this.publicGroupOrQueueId,
selectedUsers : this.selectedUsers, updatedUsers : this.updatedUsers } )
.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: 'Group(s) Assignment',
message: message,
variant: variant
} );
this.dispatchEvent( toastEvent );
} )
.catch( error => {
console.log( 'Error ' + JSON.stringify( error ) );
} );
} else {
alert( "No changes made!!!" );
}
}
}
JS-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: