• Prasan De Alwis
  • NEWBIE
  • 10 Points
  • Member since 2020

  • Chatter
    Feed
  • 0
    Best Answers
  • 2
    Likes Received
  • 0
    Likes Given
  • 4
    Questions
  • 1
    Replies
I want to send a set of people(a group) to reminder mail for 1st of every month. There is no object created or edited for emails fire, it fires in every months 1st day automatically. I have created Custom Email Template but struggling to do the schedule. Can I this achieve from workflow rules or am I need to looking into Flows?
Could you please help me to align right side(close to right side border) toggle button, button and help text. Currently it is showing close to center. Below is the UI of the LWC Component. 

User-added image

Please find the HTML full code. I have used list elements show button in horizontal line.

HTML Code
 
<template>
    <lightning-card   title="User Management" icon-name="standard:user" >
            <div class="slds-col slds-size_10-of-12 slds-p-top_medium">
                <lightning-layout multiple-rows="true" class="slds-m-left_xx-large">
                    <lightning-layout-item size = "12" margin= "around-small">
                           <span style="float: right;">
                        <div style="float: right;">
    
                            <ul class="slds-button-group-row slds-m-left_xx-large" >
                                <!-- <template if:true={hasPrev}>-->
    
                                <li class="slds-button-group-item" >
                                    <template if:true={showToggle}>
                                        <lightning-input type="toggle"
                                                         label="Enable Process"
                                                         onchange ={deactivateProcess}
                                                         checked= "{ToggleChecked}"
                                                         class="slds-m-right_xx-small slds-m-left_xx-large" >
                                        </lightning-input>
                                        </template>
    
                                </li>
                                <li class="slds-button-group-item" >
                                    <lightning-button class="slds-m-right_xxx-small slds-m-top_none slds-m-bottom_xxx-small" slot="actions" label="Submit" onclick={updateRecords}>
                                    </lightning-button>
                                    <lightning-helptext class="slds-m-top_none slds-m-bottom_xxx-small slds-m-right_xx-small " content="The users that will exclude from the de-activation."></lightning-helptext>
    
                                </li>
                                </ul>
    
                  </div>
                                </span>
                        </lightning-layout-item>
                    </lightning-layout>
    
            </div>
        <div class="slds-p-left_medium">
            <div class="slds-col slds-size_12-of-12 slds-p-top_medium">
                <div class="slds-p-around_medium lgc-bg">
                    <lightning-datatable
                            key-field="UserId"
                            columns={columns}
                            data={currentPageData}
                            selected-rows= {allSelectedRows}
                            onrowselection= {rowSelection}
                            sorted-by={sortBy}
                            sorted-direction={sortDirection}
                            onsort={handleSortdata}
                    >
                    </lightning-datatable>
                </div>
                <div class="slds-col slds-size_10-of-12 slds-p-top_medium">
                    <lightning-layout multiple-rows="true">
                        <lightning-layout-item size = "12" margin= "around-small">
                            <div class="slds-align_absolute-center">
                                <ul class="slds-button-group-row">
                                    <!-- <template if:true={hasPrev}>-->
                                    <li class="slds-button-group-item" >
                                            <button class="slds-button slds-button_neutral" onclick ={onFirst} disabled={disabledConditionFirst}> First
                                            </button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                              <button class="slds-button slds-button_neutral" disabled={disabledConditionPrev} onclick ={onPrev}> Prev
                                              </button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                          <button class="slds-button slds-button_neutral" disabled={disabledConditionNext} onclick={onNext} >Next</button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                            <button class="slds-button slds-button_neutral"  onclick ={onLast} disabled={disabledConditionLast}> Last
                                            </button>
                                    </li>
                                    <!--</template>-->
                                </ul>
                            </div>
                            </br>
                            <div class="slds-align_absolute-center" >
                        <span
                                disabled={disabledCondition}>Total Records: {totalRecordCount} </span>
                            </div>
                            <div class="slds-align_absolute-center" >
                                <span disabled={disabledCondition}>Page ({page} of {numberOfPages}) </span>
                            </div>
                        </lightning-layout-item>
                    </lightning-layout>
                </div>
            </div>
        </div>
        <div if:true={showLoadingSpinner}>
            <lightning-spinner alternative-text="Loading" size="large"></lightning-spinner>
        </div>
    </lightning-card>


JS

import { LightningElement, track, wire, api} from 'lwc';
import getUserList from '@salesforce/apex/UserManagementController.getUserList';
import userRecordsUpdate from '@salesforce/apex/UserManagementController.userRecordsUpdate';
import { refreshApex} from '@salesforce/apex';
import { ShowToastEvent} from 'lightning/platformShowToastEvent';
import getProfile from '@salesforce/apex/UserManagementController.getProfile';
import updateUserManagementProcess from '@salesforce/apex/UserManagementController.updateUserManagementProcess';

export default class Usermanagement extends LightningElement {

  //Display Coulmns on Datatable
  @track columns = [

    {
      label: 'Name',
      fieldName: 'recordLink',
      type: 'url',
      typeAttributes: { label: { fieldName: "FullName" }, tooltip:"Name", target: "_blank" },
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: 'Email',
      fieldName: 'Email',
      type: 'text',
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: 'Profile',
      fieldName: 'ProfileName',
      type: 'text',
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 170,
    },
    {
      label: 'Role',
      fieldName: 'RoleName',
      type: 'text',
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: "Last Login Date",
      fieldName: "LastLoginDate",
      type: "date",
      typeAttributes: {
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit"
      },
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: 'isFrozen',
      fieldName: 'isFrozen',
      type: 'text',
      sortable: false,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 100,
    },
    {
      label: 'isDeactivate',
      fieldName: 'isDeactivate',
      type: 'text',
      sortable: false,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 125,
    }

  ];

  // Track Gloabal variables
  @track showLoadingSpinner = false;
  @track error;
  @track page = 1;
  @track perpage = 20;
  @track pages = [];
  @track disabledConditionNext = true;
  @track disabledConditionPrev = true;
  @track disabledConditionFirst = true;
  @track disabledConditionLast = true;
  @track preSelectedRows = [];
  @track totalRecordCount = 0;
  @track numberOfPages = 1;
  @track sortBy;
  @track sortDirection;
  @track ToggleChecked;

  //Gloabal variables
  data = [];
  @api allDeSelectedRows = [];
  pageSlice;
  numOfPreviousPages;
  showToggle = false;
  wiredActivities;
  @track profName;

  //  Initial Method Call
  connectedCallback() {
    console.log('Initial' );
    this.init();
  }

  //Enable Deactivate Process button for Admins based on profile
  @wire(getProfile)
  wiredActivities({ error, data }) {
    if (data){
      console.log('profName==> '+JSON.stringify(data));

      this.profName = data;
      if(this.profName == 'System Administrator'){
        this.showToggle = true;
      }else{
      this.showToggle = false;
}
      console.log(this.profName);
      this.error = undefined;
     } else if (error) {
      this.error = error;
      this.data = undefined;

  }
}

  // Initial Method Call - Populate data on UI
  async init() {
    try {
      this.disabledConditionNext = true;
      this.disabledConditionPrev = true;
      this.disabledConditionFirst = true;
      this.disabledConditionLast = true;
      this.showLoadingSpinner = true;
      await getUserList()
        .then((result, error) => {
          console.log('result =' + result);
          var userList = JSON.parse(result);
          if (userList) {
             var tempUserList = [];
             userList.userMngtWrapperList.forEach((record) => {
                 let tempUserRec = Object.assign({}, record);
                 tempUserRec.recordLink = '/' + tempUserRec.UserId;
                 tempUserList.push(tempUserRec);
             });
            this.data = tempUserList;
            this.preSelectedRows = userList.selectedUserIdSet;
            this.ToggleChecked = userList.enableUserMngmtProcess;
            this.allSelectedRows = [];
            //this.data = this.data;
            console.log('this.data new =' + this.data);
            console.log('allSelectedRows =' + this.allSelectedRows);
            console.log('preSelectedRows =' + this.preSelectedRows);
            this.totalRecordCount = this.data.length;
            this.error = undefined;
          } else if (error) {
            console.error(error);
            this.data = undefined;
          }
        });
      this.setPages(this.data);

      if (this.data.length == 0) {
        this.dispatchEvent(
          new ShowToastEvent({
            title: 'No records to Display',
            message: 'No users to de-activates',
            variant: 'info'
          })
        );
      }
      this.showLoadingSpinner = false;

    } catch (error) {
      this.error = error;
    } finally {
      this.showLoadingSpinner = false;
    }
  }

/**
 * Below Methods are to Manipulate Page Load,Navigation and page click
 * pagesList
 * currentPageData
 * pageData
 * setPages
 * onPageClick
 * onNext
 * onPrev
 * onFirst
 * onLast
 * changePage
 */

  // Get Page list
  get pagesList() {
    let mid = Math.floor(this.perpage / 2) + 1;
    if (this.page > mid) {
      return this.pages.slice(this.page - mid, this.page + mid - 1);
    }
    return this.pages.slice(0, this.perpage);
  }

  // Get Data to load to current Page
  get currentPageData() {
    return this.pageData();
  }

 // Get Current Page Data based on page Number
  pageData = () => {
    let numberOfPages = Math.ceil(this.data.length / this.perpage);
    this.numberOfPages = numberOfPages;
    let page = this.page;
    let perpage = this.perpage;
    let startIndex = (page * perpage) - perpage;
    let endIndex = (page * perpage);

    if (this.numberOfPages < 2)
    {
        this.disabledConditionNext = true;
        this.disabledConditionPrev = true;
        this.disabledConditionLast = true;
        this.disabledConditionFirst = true;
    }
    else if (this.page  == this.numberOfPages)
    {
         this.disabledConditionNext = true;
         this.disabledConditionPrev = false;
         this.disabledConditionLast = true;
         this.disabledConditionFirst = false;
    }
    else if (this.page  == 1)
    {
          this.disabledConditionNext = false;
          this.disabledConditionPrev = true;
          this.disabledConditionLast = false;
          this.disabledConditionFirst = true;
    }
    else // if (this.page  < this.numberOfPages)
    {
          this.disabledConditionNext = false;
          this.disabledConditionPrev = false;
          this.disabledConditionLast = false;
          this.disabledConditionFirst = false;
    }

    this.pageSlice = this.data.slice(startIndex, endIndex);
    return this.data.slice(startIndex, endIndex);
  }

  // Get Number of pages need to be visible based on the data amount
  setPages = (data) => {
    let numberOfPages = Math.ceil(data.length / this.perpage);
    this.numOfPreviousPages = numberOfPages;
  }

  // Page Click event
  onPageClick = (e) => {
    this.page = parseInt(e.target.dataset.id, 10);
    }
  }

  // First Page button Click
  onFirst = () => {
    this.changePage(1);
  }

 // Last Page button Click
  onLast = () => {
    this.changePage(this.numberOfPages > 0 ? this.numberOfPages : 1);
  }

  // Page Data Change based on page number
  changePage(pageNumber) {

    let pageData = this.pageData();
    // Preserve rows outside current page and add rows from current page
    this.allSelectedRows = this.allSelectedRows.filter((rowId) => !pageData.find((record) => record.userId === rowId)).concat(this.template.querySelector('lightning-datatable').selectedRows);
    //Distinct the dataset
    this.allSelectedRows = this.allSelectedRows.filter((v, i, a) => a.indexOf(v) == i);
    console.log('changePage-allSelectedRows = ' + this.allSelectedRows);
    this.page = pageNumber;
    pageData = this.pageData();

    console.log('changePage - this.preSelectedRows in current page =' + this.preSelectedRows);
 }

 // On Row Selection - when select/deselect Checkbox
 rowSelection(evt) {
    let deselectedRecs = [];
    this.allSelectedRows = this.allSelectedRows.filter((v, i, a) => a.indexOf(v) == i);
    const selectedRows = evt.detail.selectedRows;
    console.log('rowSelection - Selected Rows are ' + JSON.stringify(selectedRows));
    console.log("rowSelection - selectedRows.length" + selectedRows.length);
    //concat new selected ids to allSelectedRows list
    this.allSelectedRows  = selectedRows
              .map(x => x.UserId)
              .concat(this.allSelectedRows ).filter((v, i, a) => a.indexOf(v) == i);
    console.log("rowSelection - this.allSelectedRows concat new selected ids= " + this.allSelectedRows);
    //remove new selected ids from deselectedRecs list
    this.deselectedRecs = this.pageSlice
        .filter(x => !selectedRows.includes(x))
        .concat(selectedRows.filter(x => !this.pageSlice.includes(x)))
        .map(x => x.UserId).filter((v, i, a) => a.indexOf(v) === i);
    console.log('rowSelection - Deselected Recs are original ' + this.deselectedRecs);
    console.log('rowSelection - deselectedRecs.length ' + this.deselectedRecs.length);
    if (this.deselectedRecs.length > 0) {
        //remove deselected ids from allSelectedRows list
        this.allSelectedRows = this.allSelectedRows.filter(item => !this.deselectedRecs.includes(item)).filter((v, i, a) => a.indexOf(v) === i);
    }
    console.log('rowSelection - Final allSelectedRows= ' + this.allSelectedRows);
  }

  updateRecords(event) {
    console.log('this.allSelectedRows updateRecords'+ this.allSelectedRows);
      console.log('this.preSelectedRows updateRecords'+ this.preSelectedRows);
    this.allDeSelectedRows = this.preSelectedRows
                                  .filter(item => !this.allSelectedRows.some(obj => obj === item))
                                  .filter((v, i, a) => a.indexOf(v) === i);
    if (this.allDeSelectedRows.length > 0) {
      this.showLoadingSpinner = true;
      console.log('this.allDeSelectedRows updateRecords'+ this.allDeSelectedRows);

      userRecordsUpdate({
          deSelectedArrList: this.allDeSelectedRows
        })
        .then(result => {
          if (result) {
            console.log('result userRecordsUpdate ='+ result);
            this.showLoadingSpinner = false;
            this.dispatchEvent(
              new ShowToastEvent({
                title: 'Success',
                message: 'User List updated',
                variant: 'success'
              })
            );
           window.location.reload();
          } else {
             console.log('Update failed.');
             this.dispatchEvent(
                  new ShowToastEvent({
                     title: 'Error updating user records',
                     message: 'Update failed',
                     variant: 'error'
                     }));
          }
        })
        .catch(error => {
          this.showLoadingSpinner = false;
          console.log('Update failed due to - ' + error);
          this.dispatchEvent(
            new ShowToastEvent({
              title: 'Error updating user records',
              message: error,
              variant: 'error'
            }));
        });
    }
    else
    {
        this.dispatchEvent(
        new ShowToastEvent({
            title: 'No records to Update',
            message: 'No users to de-activates',
            variant: 'info'
            })
        );
    }
  }

  deactivateProcess(event) {
        this.showLoadingSpinner = true;
         let chk = event.target.checked;
         console.log("clicked : "+ event.target.checked);

         if (chk != null) {

             updateUserManagementProcess({
                   status: event.target.checked
                 })
                 .then(result => {
                   if (result) {
                     console.log('result updateUserManagementProcess ='+ result);
                     this.showLoadingSpinner = false;

                     if(chk == true)
                     {
                         this.dispatchEvent(
                           new ShowToastEvent({
                             title: 'Success',
                             message: 'User Deactivation is Active',
                             variant: 'success'
                           })
                     );
                     }
                     else
                     {
                          this.dispatchEvent(
                             new ShowToastEvent({
                               title: 'Success',
                               message: 'User Deactivation is Inactive',
                               variant: 'success'
                          })
                       );
                       }


                   } else {
                      console.log('Update failed.');
                      this.dispatchEvent(
                           new ShowToastEvent({
                              title: 'Error updating user management meta-data record',
                              message: 'Update failed',
                              variant: 'error'
                              }));
                   }
                 })
                 .catch(error => {
                   this.showLoadingSpinner = false;
                   console.log('Update failed due to - ' + error);
                   this.dispatchEvent(
                     new ShowToastEvent({
                       title: 'Error updating user management meta-data record',
                       message: error,
                       variant: 'error'
                     }));
                 });
   		}
   else
       {
           this.dispatchEvent(
           new ShowToastEvent({
               title: 'Update Failed',
               message: 'Error updating user management meta-data record',
               variant: 'info'
               })
           );
       }
     }



  // Sorting
   handleSortdata(event) {
          // field name
          this.sortBy = event.detail.fieldName;
          console.log('this.sortBy = '+this.sortBy);
          // sort direction
          this.sortDirection = event.detail.sortDirection;
          console.log('this.sortDirection = '+this.sortDirection);
          // calling sortdata function to sort the data based on direction and selected field
          this.sortData(event.detail.fieldName, event.detail.sortDirection);
      }

      sortData(fieldname, direction) {
          // serialize the data before calling sort function
          let parseData = JSON.parse(JSON.stringify(this.data));
           console.log('this.parseData = '+this.parseData);
           console.log('this.fieldname = '+fieldname);
          // Return the value stored in the field
          let keyValue = (a) => {
              return a[fieldname];
          };

          // cheking reverse direction
          let isReverse = direction === 'asc' ? 1: -1;

          // sorting data
          parseData.sort((x, y) => {
              x = keyValue(x) ? keyValue(x) : ''; // handling null values
              y = keyValue(y) ? keyValue(y) : '';

              // sorting values based on direction
              return isReverse * ((x > y) - (y > x));
          });

          // set the sorted data to data table data
          this.data = parseData;

      }
}

​​​​​​​
Hi,

I have develop LWC component which is normally used by normal users. In that lightning web component button is there as below.
<lightning-button slot="actions" label="Deactivate" onclick={DeactivateProcess}> </lightning-button>
The above button should be only be show to System Admin Profile and Business Admin Profile. How to show the button only to those two Profiles without using record types or different page layouts?
I am loading the user table data to datatable using LWC, the users who has not logging past two months. When the page loads first time I load all the list to front end and using pagination Im going through the records instead going to the server again. Based on the list we can deactivate the users or exclude the user using a checkbox.

Initially all checkbox should come as true but only first page will checked as true. The other pages checkboxes are not checked. Pre selected Row Ids are send to the UI via controller to checked or unchecked. Another issue I faced is the selected checkboxes are not selected when move to another page and coming back to the same page. The selected Ids will be send to the system by clicking the Deactivate Users button.

The Page 1 Checkboxes are pre selected as below when page loads first time,
The Page 1 Checkboxes are pre selected as below,

Page 2 other any other pages checkboxes are not selected. (selected-rows= {preSelectedRows})
Page 2 other any other pages checkboxes are not selected. (selected-rows= {preSelectedRows})

Wrapper Class
 
public class UserMngtWrapper {

//User Id
public String UserId {get; set;}
public String FullName {get; set;}
public String Email {get; set;}
//User ProfileName
public String ProfileName {get; set;}
//User RoleName
public String RoleName {get; set;}
//User is Frozen
public String isFrozen {get; set;}
//User Last Login Date
public Datetime LastLoginDate {get; set;}
//User Last Modified Date by user
public String LastModifiedDate {get; set;}
//User Created Date
public String CreatedDate {get; set;}
//User is Active
public String isActive {get; set;}
//User is Deactivated
public String isDeactivate {get; set;}
}

Controller
 
public class UserManagementController {

@AuraEnabled(cacheable=true)
public static string getUserList() {
    List<UserMngtWrapper> userMngtWrapperList = new List<UserMngtWrapper>();
    UserListMngtWrapper userListMngtWrapper = new UserListMngtWrapper();
    Set<Id> selectedIdSet = new Set<Id>();
    //Get last two months inactive users
    Set<ID> inactiveUserIds = new Map<Id,User>([SELECT id From User
                                                WHERE LastLoginDate < LAST_N_DAYS: 60
                                                      AND IsActive = TRUE                                                                                                                
                                                      AND CreatedDate < LAST_N_DAYS: 60
                                                ]).keySet();
    //Get last two months inactive users Data
    List<User> userList = [Select  id,Profile.Name,Name,Email,UserRole.Name,LastLoginDate,LastModifiedDate,CreatedDate,IsActive,IsDeactivate__c   FROM User where id= : inactiveUserIds order by Profile.Name asc,Name asc];
    
    for (User u : userList)
    {
        UserMngtWrapper userMngtWrapper = new UserMngtWrapper();
        userMngtWrapper.UserId = u.id;
        userMngtWrapper.FullName = (u.Name != null ) ? u.Name: '';
        userMngtWrapper.Email = (u.Email != null ) ? u.Email: '';
        userMngtWrapper.LastLoginDate =  u.LastLoginDate;
        userMngtWrapper.ProfileName =  (u.Profile.Name != null ) ? u.Profile.Name: '';
        userMngtWrapper.RoleName =  (u.UserRole.Name != null ) ? u.UserRole.Name: '';
        userMngtWrapper.isDeactivate =  (u.IsDeactivate__c == false  ) ? 'FALSE': 'TRUE' ;
        userMngtWrapperList.add(userMngtWrapper);
        selectedIdSet.add(u.Id);
    }

    userListMngtWrapper.userMngtWrapperList = userMngtWrapperList;
    userListMngtWrapper.selectedUserIdSet = selectedIdSet;
    return JSON.serialize(userListMngtWrapper);
}


@AuraEnabled(cacheable=true)
public static Boolean userRecordsUpdate() {
   // inprogress
    Return true;
}

//Wrapper List Class
public class UserListMngtWrapper{
    @AuraEnabled public List<UserMngtWrapper> userMngtWrapperList {get; set;}
    @AuraEnabled public set<Id> selectedUserIdSet {get; set;}
}

JS
 
import { LightningElement , track, wire,api } from 'lwc';
import getUserList from '@salesforce/apex/UserManagementController.getUserList';
import userRecordsUpdate from '@salesforce/apex/UserManagementController.userRecordsUpdate';
import {refreshApex} from '@salesforce/apex';

export default class Usermanagement extends LightningElement {
 @track  columns = [
    { label: 'User Id',fieldName: 'UserId',type: 'text',sortable: false,cellAttributes: { alignment: 'left' },initialWidth: 200,},
    { label: 'Name',fieldName: 'FullName',type: 'text',sortable: false,cellAttributes: { alignment: 'left' },initialWidth: 200,},
    { label: 'Email',fieldName: 'Email',type: 'text',sortable: false,cellAttributes: { alignment: 'left' },initialWidth: 200,},
    { label: 'Profile Name',fieldName: 'ProfileName',type: 'text',sortable: false,cellAttributes: { alignment: 'left' },initialWidth: 200,},
    { label: 'Role Name',fieldName: 'RoleName',type: 'text',sortable: false,cellAttributes: { alignment: 'left' },initialWidth: 200,},
    {
            label: "Last Login Date",
            fieldName: "LastLoginDate",
            type: "date",
            typeAttributes:{
                year: "numeric",
                month: "2-digit",
                day: "2-digit",
                hour: "2-digit",
                minute: "2-digit",
                second: "2-digit"
            },
            sortable: false,cellAttributes: { alignment: 'left' },
            initialWidth: 200,
        },
        { label: 'Deactivate',fieldName: 'isDeactivate',type: 'text',sortable: false,cellAttributes: { alignment: 'left' },initialWidth: 200,}

];

     @track showLoadingSpinner = false;
     @track error;
     @track page = 1;
     @track perpage = 5;
     @track pages = [];
     @track disabledConditionNext =false;
     @track disabledConditionPrev =false;
     @track disabledCondition = true;
     @track preSelectedRows=[];
     @track totalRecordCount=0;
     data=[];
     @track numberOfPages =1;
     numOfPreviousPages;
     set_size = 5;
     
     connectedCallback() {
        this.init();
     }
    
     async init()
     {
                 try {
                this.disabledCondition = true;
                this.showLoadingSpinner = true;
                await getUserList()
                 .then((result,error) => {
                     var userList = JSON.parse(result);

                     if (userList) {
this.data=userList.userMngtWrapperList;
                         this.preSelectedRows = userList.selectedUserIdSet;
                         this.data = this.data;
                        this.totalRecordCount = this.data.length;
                     } else if (error) {
                         console.error(error);
                     }
                 });
                    this.disabledConditionPrev =false;
                    this.disabledConditionNext =false;
                    this.disabledCondition = false;
                    this.setPages(this.data);
                    this.showLoadingSpinner = false;

             } catch (error) {
                      this.error = error;
                  } finally {
                      this.showLoadingSpinner = false;
                  }
         }
         
         get currentPageData(){
                       return this.pageData();
                    }
         
         get pagesList(){
        let mid = Math.floor(this.set_size/2) + 1 ;
        if(this.page > mid){
            return this.pages.slice(this.page-mid, this.page+mid-1);
        }
            return this.pages.slice(0,this.set_size);
     }
     
        pageData = ()=>{
                             let numberOfPages = Math.ceil(this.data.length / this.perpage);
                             this.numberOfPages = numberOfPages;
                             let page = this.page;
                             let perpage = this.perpage;
                             let startIndex = (page*perpage) - perpage;
                             let endIndex = (page*perpage);
                             if(this.numberOfPages < 1)
                             {
                                this.disabledConditionPrev =true;
                                this.disabledConditionNext =true;
                             }
                             return this.data.slice(startIndex,endIndex);
                          }

        setPages = (data)=>{
                                      let numberOfPages = Math.ceil(data.length / this.perpage);
                                      this.numOfPreviousPages = numberOfPages;

                                  }


        onNext = ()=>{
                                      if(this.page < this.numberOfPages){
                                         ++this.page;
                                          this.disabledConditionNext =false;
                                          this.disabledConditionPrev =false;
                                          this.hasPageChanged =true;
                                         
                                      }
                                      else {
                                          this.disabledConditionNext =true;                            this.disabledConditionPrev =false;

                                      }

                                  }

        onPrev = ()=>{
                                      if(this.page > 1){
                                            --this.page;
                                            this.disabledConditionPrev =false;
                                            this.disabledConditionNext =false;
                                      }
                                      else {
                                            this.disabledConditionPrev =true;
                                            this.disabledConditionNext =false;
                                      }
                                  }

      onFirst = ()=>{
              this.page = 1;
              }

      onLast = ()=>{
              this.page = this.numberOfPages;
              }

              onPageClick = (e)=>{
                        this.page = parseInt(e.target.dataset.id,10);
                        if(this.numberOfPages < 1)
                        {
                            this.disabledConditionPrev =true;
                            this.disabledConditionNext =true;
                        }
                        else
                        {
                             this.disabledConditionPrev =false;
                             this.disabledConditionNext =false;
                        }
                    }

       // Method didnt develop and test
    updateRecords(){
             var selectedRecords =
              this.template.querySelector("lightning-datatable").getSelectedRows();
              let arrset = [];
              selectedRecords.forEach(row => {
                                 arrset.push(row.userId);
                             });
              userRecordsUpdate()
             .then(result=>{
               return refreshApex(this.refreshTable);
             })
             .catch(error=>{
               alert('Could not update(error));
             })
           }
 
<template>
    <lightning-card   title="User Management" icon-name="standard:user" class="slds-col slds-size_12-of-12 slds-p-top_small">
        <lightning-button slot="actions" label="Deactivate Users" onclick={updateRecords}></lightning-button>
        <div class="slds-p-left_medium">
            <div class="slds-col slds-size_12-of-12 slds-p-top_medium">
                <div class="slds-p-around_medium lgc-bg">

                    <lightning-datatable
                            key-field="UserId"
                            columns={columns}
                            data={currentPageData}
                            selected-rows= {preSelectedRows}
                            onrowaction={getRowActions}
                            >
                    </lightning-datatable>
                </div>

                <div class="slds-col slds-size_10-of-12 slds-p-top_medium">
                    <lightning-layout multiple-rows="true">
                        <lightning-layout-item size = "12" margin= "around-small">
                            <div class="slds-align_absolute-center">
                                <ul class="slds-button-group-row">
                                    <li class="slds-button-group-item" >
                                        <button class="slds-button slds-button_neutral" disabled={disabledCondition} onclick ={onFirst}> First
                                        </button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                        <button class="slds-button slds-button_neutral" disabled={disabledConditionPrev} onclick ={onPrev}> Prev
                                        </button>
                                    </li>

                                    <li class="slds-button-group-item" >
                                        <button class="slds-button slds-button_neutral"  disabled={disabledConditionNext} onclick={onNext} >Next</button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                        <button class="slds-button slds-button_neutral"  disabled={disabledCondition} onclick ={onLast}> Last
                                        </button>
                                    </li>
                                </ul>
                            </div>
                            </br>
                            <div class="slds-align_absolute-center" >
                                <span>Total Records: {totalRecordCount} </span>
                            </div>
                            <div class="slds-align_absolute-center" >
                                <span>Page ({page} of {numberOfPages}) </span>
                            </div>


                        </lightning-layout-item>
                    </lightning-layout>
                </div>
            </div>
        </div>
        <div if:true={showLoadingSpinner}>
            <lightning-spinner alternative-text="Loading" size="large"></lightning-spinner>
        </div>
    </lightning-card>
</template>



Summarizing the Issues are,
  1. Pre selected Row Ids are only selected or checked in page 1. Not checked in other pages.(selected-rows= {preSelectedRows})
  2. The selected checkboxes are not selected(checked box unchecked) after move to another page and coming back to the same page. Selected items should remain even going though any paginations and come back to the same page.
Could you please help me on this.Thank you in advance


 
Could you please help me to align right side(close to right side border) toggle button, button and help text. Currently it is showing close to center. Below is the UI of the LWC Component. 

User-added image

Please find the HTML full code. I have used list elements show button in horizontal line.

HTML Code
 
<template>
    <lightning-card   title="User Management" icon-name="standard:user" >
            <div class="slds-col slds-size_10-of-12 slds-p-top_medium">
                <lightning-layout multiple-rows="true" class="slds-m-left_xx-large">
                    <lightning-layout-item size = "12" margin= "around-small">
                           <span style="float: right;">
                        <div style="float: right;">
    
                            <ul class="slds-button-group-row slds-m-left_xx-large" >
                                <!-- <template if:true={hasPrev}>-->
    
                                <li class="slds-button-group-item" >
                                    <template if:true={showToggle}>
                                        <lightning-input type="toggle"
                                                         label="Enable Process"
                                                         onchange ={deactivateProcess}
                                                         checked= "{ToggleChecked}"
                                                         class="slds-m-right_xx-small slds-m-left_xx-large" >
                                        </lightning-input>
                                        </template>
    
                                </li>
                                <li class="slds-button-group-item" >
                                    <lightning-button class="slds-m-right_xxx-small slds-m-top_none slds-m-bottom_xxx-small" slot="actions" label="Submit" onclick={updateRecords}>
                                    </lightning-button>
                                    <lightning-helptext class="slds-m-top_none slds-m-bottom_xxx-small slds-m-right_xx-small " content="The users that will exclude from the de-activation."></lightning-helptext>
    
                                </li>
                                </ul>
    
                  </div>
                                </span>
                        </lightning-layout-item>
                    </lightning-layout>
    
            </div>
        <div class="slds-p-left_medium">
            <div class="slds-col slds-size_12-of-12 slds-p-top_medium">
                <div class="slds-p-around_medium lgc-bg">
                    <lightning-datatable
                            key-field="UserId"
                            columns={columns}
                            data={currentPageData}
                            selected-rows= {allSelectedRows}
                            onrowselection= {rowSelection}
                            sorted-by={sortBy}
                            sorted-direction={sortDirection}
                            onsort={handleSortdata}
                    >
                    </lightning-datatable>
                </div>
                <div class="slds-col slds-size_10-of-12 slds-p-top_medium">
                    <lightning-layout multiple-rows="true">
                        <lightning-layout-item size = "12" margin= "around-small">
                            <div class="slds-align_absolute-center">
                                <ul class="slds-button-group-row">
                                    <!-- <template if:true={hasPrev}>-->
                                    <li class="slds-button-group-item" >
                                            <button class="slds-button slds-button_neutral" onclick ={onFirst} disabled={disabledConditionFirst}> First
                                            </button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                              <button class="slds-button slds-button_neutral" disabled={disabledConditionPrev} onclick ={onPrev}> Prev
                                              </button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                          <button class="slds-button slds-button_neutral" disabled={disabledConditionNext} onclick={onNext} >Next</button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                            <button class="slds-button slds-button_neutral"  onclick ={onLast} disabled={disabledConditionLast}> Last
                                            </button>
                                    </li>
                                    <!--</template>-->
                                </ul>
                            </div>
                            </br>
                            <div class="slds-align_absolute-center" >
                        <span
                                disabled={disabledCondition}>Total Records: {totalRecordCount} </span>
                            </div>
                            <div class="slds-align_absolute-center" >
                                <span disabled={disabledCondition}>Page ({page} of {numberOfPages}) </span>
                            </div>
                        </lightning-layout-item>
                    </lightning-layout>
                </div>
            </div>
        </div>
        <div if:true={showLoadingSpinner}>
            <lightning-spinner alternative-text="Loading" size="large"></lightning-spinner>
        </div>
    </lightning-card>


JS

import { LightningElement, track, wire, api} from 'lwc';
import getUserList from '@salesforce/apex/UserManagementController.getUserList';
import userRecordsUpdate from '@salesforce/apex/UserManagementController.userRecordsUpdate';
import { refreshApex} from '@salesforce/apex';
import { ShowToastEvent} from 'lightning/platformShowToastEvent';
import getProfile from '@salesforce/apex/UserManagementController.getProfile';
import updateUserManagementProcess from '@salesforce/apex/UserManagementController.updateUserManagementProcess';

export default class Usermanagement extends LightningElement {

  //Display Coulmns on Datatable
  @track columns = [

    {
      label: 'Name',
      fieldName: 'recordLink',
      type: 'url',
      typeAttributes: { label: { fieldName: "FullName" }, tooltip:"Name", target: "_blank" },
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: 'Email',
      fieldName: 'Email',
      type: 'text',
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: 'Profile',
      fieldName: 'ProfileName',
      type: 'text',
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 170,
    },
    {
      label: 'Role',
      fieldName: 'RoleName',
      type: 'text',
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: "Last Login Date",
      fieldName: "LastLoginDate",
      type: "date",
      typeAttributes: {
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit"
      },
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: 'isFrozen',
      fieldName: 'isFrozen',
      type: 'text',
      sortable: false,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 100,
    },
    {
      label: 'isDeactivate',
      fieldName: 'isDeactivate',
      type: 'text',
      sortable: false,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 125,
    }

  ];

  // Track Gloabal variables
  @track showLoadingSpinner = false;
  @track error;
  @track page = 1;
  @track perpage = 20;
  @track pages = [];
  @track disabledConditionNext = true;
  @track disabledConditionPrev = true;
  @track disabledConditionFirst = true;
  @track disabledConditionLast = true;
  @track preSelectedRows = [];
  @track totalRecordCount = 0;
  @track numberOfPages = 1;
  @track sortBy;
  @track sortDirection;
  @track ToggleChecked;

  //Gloabal variables
  data = [];
  @api allDeSelectedRows = [];
  pageSlice;
  numOfPreviousPages;
  showToggle = false;
  wiredActivities;
  @track profName;

  //  Initial Method Call
  connectedCallback() {
    console.log('Initial' );
    this.init();
  }

  //Enable Deactivate Process button for Admins based on profile
  @wire(getProfile)
  wiredActivities({ error, data }) {
    if (data){
      console.log('profName==> '+JSON.stringify(data));

      this.profName = data;
      if(this.profName == 'System Administrator'){
        this.showToggle = true;
      }else{
      this.showToggle = false;
}
      console.log(this.profName);
      this.error = undefined;
     } else if (error) {
      this.error = error;
      this.data = undefined;

  }
}

  // Initial Method Call - Populate data on UI
  async init() {
    try {
      this.disabledConditionNext = true;
      this.disabledConditionPrev = true;
      this.disabledConditionFirst = true;
      this.disabledConditionLast = true;
      this.showLoadingSpinner = true;
      await getUserList()
        .then((result, error) => {
          console.log('result =' + result);
          var userList = JSON.parse(result);
          if (userList) {
             var tempUserList = [];
             userList.userMngtWrapperList.forEach((record) => {
                 let tempUserRec = Object.assign({}, record);
                 tempUserRec.recordLink = '/' + tempUserRec.UserId;
                 tempUserList.push(tempUserRec);
             });
            this.data = tempUserList;
            this.preSelectedRows = userList.selectedUserIdSet;
            this.ToggleChecked = userList.enableUserMngmtProcess;
            this.allSelectedRows = [];
            //this.data = this.data;
            console.log('this.data new =' + this.data);
            console.log('allSelectedRows =' + this.allSelectedRows);
            console.log('preSelectedRows =' + this.preSelectedRows);
            this.totalRecordCount = this.data.length;
            this.error = undefined;
          } else if (error) {
            console.error(error);
            this.data = undefined;
          }
        });
      this.setPages(this.data);

      if (this.data.length == 0) {
        this.dispatchEvent(
          new ShowToastEvent({
            title: 'No records to Display',
            message: 'No users to de-activates',
            variant: 'info'
          })
        );
      }
      this.showLoadingSpinner = false;

    } catch (error) {
      this.error = error;
    } finally {
      this.showLoadingSpinner = false;
    }
  }

/**
 * Below Methods are to Manipulate Page Load,Navigation and page click
 * pagesList
 * currentPageData
 * pageData
 * setPages
 * onPageClick
 * onNext
 * onPrev
 * onFirst
 * onLast
 * changePage
 */

  // Get Page list
  get pagesList() {
    let mid = Math.floor(this.perpage / 2) + 1;
    if (this.page > mid) {
      return this.pages.slice(this.page - mid, this.page + mid - 1);
    }
    return this.pages.slice(0, this.perpage);
  }

  // Get Data to load to current Page
  get currentPageData() {
    return this.pageData();
  }

 // Get Current Page Data based on page Number
  pageData = () => {
    let numberOfPages = Math.ceil(this.data.length / this.perpage);
    this.numberOfPages = numberOfPages;
    let page = this.page;
    let perpage = this.perpage;
    let startIndex = (page * perpage) - perpage;
    let endIndex = (page * perpage);

    if (this.numberOfPages < 2)
    {
        this.disabledConditionNext = true;
        this.disabledConditionPrev = true;
        this.disabledConditionLast = true;
        this.disabledConditionFirst = true;
    }
    else if (this.page  == this.numberOfPages)
    {
         this.disabledConditionNext = true;
         this.disabledConditionPrev = false;
         this.disabledConditionLast = true;
         this.disabledConditionFirst = false;
    }
    else if (this.page  == 1)
    {
          this.disabledConditionNext = false;
          this.disabledConditionPrev = true;
          this.disabledConditionLast = false;
          this.disabledConditionFirst = true;
    }
    else // if (this.page  < this.numberOfPages)
    {
          this.disabledConditionNext = false;
          this.disabledConditionPrev = false;
          this.disabledConditionLast = false;
          this.disabledConditionFirst = false;
    }

    this.pageSlice = this.data.slice(startIndex, endIndex);
    return this.data.slice(startIndex, endIndex);
  }

  // Get Number of pages need to be visible based on the data amount
  setPages = (data) => {
    let numberOfPages = Math.ceil(data.length / this.perpage);
    this.numOfPreviousPages = numberOfPages;
  }

  // Page Click event
  onPageClick = (e) => {
    this.page = parseInt(e.target.dataset.id, 10);
    }
  }

  // First Page button Click
  onFirst = () => {
    this.changePage(1);
  }

 // Last Page button Click
  onLast = () => {
    this.changePage(this.numberOfPages > 0 ? this.numberOfPages : 1);
  }

  // Page Data Change based on page number
  changePage(pageNumber) {

    let pageData = this.pageData();
    // Preserve rows outside current page and add rows from current page
    this.allSelectedRows = this.allSelectedRows.filter((rowId) => !pageData.find((record) => record.userId === rowId)).concat(this.template.querySelector('lightning-datatable').selectedRows);
    //Distinct the dataset
    this.allSelectedRows = this.allSelectedRows.filter((v, i, a) => a.indexOf(v) == i);
    console.log('changePage-allSelectedRows = ' + this.allSelectedRows);
    this.page = pageNumber;
    pageData = this.pageData();

    console.log('changePage - this.preSelectedRows in current page =' + this.preSelectedRows);
 }

 // On Row Selection - when select/deselect Checkbox
 rowSelection(evt) {
    let deselectedRecs = [];
    this.allSelectedRows = this.allSelectedRows.filter((v, i, a) => a.indexOf(v) == i);
    const selectedRows = evt.detail.selectedRows;
    console.log('rowSelection - Selected Rows are ' + JSON.stringify(selectedRows));
    console.log("rowSelection - selectedRows.length" + selectedRows.length);
    //concat new selected ids to allSelectedRows list
    this.allSelectedRows  = selectedRows
              .map(x => x.UserId)
              .concat(this.allSelectedRows ).filter((v, i, a) => a.indexOf(v) == i);
    console.log("rowSelection - this.allSelectedRows concat new selected ids= " + this.allSelectedRows);
    //remove new selected ids from deselectedRecs list
    this.deselectedRecs = this.pageSlice
        .filter(x => !selectedRows.includes(x))
        .concat(selectedRows.filter(x => !this.pageSlice.includes(x)))
        .map(x => x.UserId).filter((v, i, a) => a.indexOf(v) === i);
    console.log('rowSelection - Deselected Recs are original ' + this.deselectedRecs);
    console.log('rowSelection - deselectedRecs.length ' + this.deselectedRecs.length);
    if (this.deselectedRecs.length > 0) {
        //remove deselected ids from allSelectedRows list
        this.allSelectedRows = this.allSelectedRows.filter(item => !this.deselectedRecs.includes(item)).filter((v, i, a) => a.indexOf(v) === i);
    }
    console.log('rowSelection - Final allSelectedRows= ' + this.allSelectedRows);
  }

  updateRecords(event) {
    console.log('this.allSelectedRows updateRecords'+ this.allSelectedRows);
      console.log('this.preSelectedRows updateRecords'+ this.preSelectedRows);
    this.allDeSelectedRows = this.preSelectedRows
                                  .filter(item => !this.allSelectedRows.some(obj => obj === item))
                                  .filter((v, i, a) => a.indexOf(v) === i);
    if (this.allDeSelectedRows.length > 0) {
      this.showLoadingSpinner = true;
      console.log('this.allDeSelectedRows updateRecords'+ this.allDeSelectedRows);

      userRecordsUpdate({
          deSelectedArrList: this.allDeSelectedRows
        })
        .then(result => {
          if (result) {
            console.log('result userRecordsUpdate ='+ result);
            this.showLoadingSpinner = false;
            this.dispatchEvent(
              new ShowToastEvent({
                title: 'Success',
                message: 'User List updated',
                variant: 'success'
              })
            );
           window.location.reload();
          } else {
             console.log('Update failed.');
             this.dispatchEvent(
                  new ShowToastEvent({
                     title: 'Error updating user records',
                     message: 'Update failed',
                     variant: 'error'
                     }));
          }
        })
        .catch(error => {
          this.showLoadingSpinner = false;
          console.log('Update failed due to - ' + error);
          this.dispatchEvent(
            new ShowToastEvent({
              title: 'Error updating user records',
              message: error,
              variant: 'error'
            }));
        });
    }
    else
    {
        this.dispatchEvent(
        new ShowToastEvent({
            title: 'No records to Update',
            message: 'No users to de-activates',
            variant: 'info'
            })
        );
    }
  }

  deactivateProcess(event) {
        this.showLoadingSpinner = true;
         let chk = event.target.checked;
         console.log("clicked : "+ event.target.checked);

         if (chk != null) {

             updateUserManagementProcess({
                   status: event.target.checked
                 })
                 .then(result => {
                   if (result) {
                     console.log('result updateUserManagementProcess ='+ result);
                     this.showLoadingSpinner = false;

                     if(chk == true)
                     {
                         this.dispatchEvent(
                           new ShowToastEvent({
                             title: 'Success',
                             message: 'User Deactivation is Active',
                             variant: 'success'
                           })
                     );
                     }
                     else
                     {
                          this.dispatchEvent(
                             new ShowToastEvent({
                               title: 'Success',
                               message: 'User Deactivation is Inactive',
                               variant: 'success'
                          })
                       );
                       }


                   } else {
                      console.log('Update failed.');
                      this.dispatchEvent(
                           new ShowToastEvent({
                              title: 'Error updating user management meta-data record',
                              message: 'Update failed',
                              variant: 'error'
                              }));
                   }
                 })
                 .catch(error => {
                   this.showLoadingSpinner = false;
                   console.log('Update failed due to - ' + error);
                   this.dispatchEvent(
                     new ShowToastEvent({
                       title: 'Error updating user management meta-data record',
                       message: error,
                       variant: 'error'
                     }));
                 });
   		}
   else
       {
           this.dispatchEvent(
           new ShowToastEvent({
               title: 'Update Failed',
               message: 'Error updating user management meta-data record',
               variant: 'info'
               })
           );
       }
     }



  // Sorting
   handleSortdata(event) {
          // field name
          this.sortBy = event.detail.fieldName;
          console.log('this.sortBy = '+this.sortBy);
          // sort direction
          this.sortDirection = event.detail.sortDirection;
          console.log('this.sortDirection = '+this.sortDirection);
          // calling sortdata function to sort the data based on direction and selected field
          this.sortData(event.detail.fieldName, event.detail.sortDirection);
      }

      sortData(fieldname, direction) {
          // serialize the data before calling sort function
          let parseData = JSON.parse(JSON.stringify(this.data));
           console.log('this.parseData = '+this.parseData);
           console.log('this.fieldname = '+fieldname);
          // Return the value stored in the field
          let keyValue = (a) => {
              return a[fieldname];
          };

          // cheking reverse direction
          let isReverse = direction === 'asc' ? 1: -1;

          // sorting data
          parseData.sort((x, y) => {
              x = keyValue(x) ? keyValue(x) : ''; // handling null values
              y = keyValue(y) ? keyValue(y) : '';

              // sorting values based on direction
              return isReverse * ((x > y) - (y > x));
          });

          // set the sorted data to data table data
          this.data = parseData;

      }
}

​​​​​​​
Could you please help me to align right side(close to right side border) toggle button, button and help text. Currently it is showing close to center. Below is the UI of the LWC Component. 

User-added image

Please find the HTML full code. I have used list elements show button in horizontal line.

HTML Code
 
<template>
    <lightning-card   title="User Management" icon-name="standard:user" >
            <div class="slds-col slds-size_10-of-12 slds-p-top_medium">
                <lightning-layout multiple-rows="true" class="slds-m-left_xx-large">
                    <lightning-layout-item size = "12" margin= "around-small">
                           <span style="float: right;">
                        <div style="float: right;">
    
                            <ul class="slds-button-group-row slds-m-left_xx-large" >
                                <!-- <template if:true={hasPrev}>-->
    
                                <li class="slds-button-group-item" >
                                    <template if:true={showToggle}>
                                        <lightning-input type="toggle"
                                                         label="Enable Process"
                                                         onchange ={deactivateProcess}
                                                         checked= "{ToggleChecked}"
                                                         class="slds-m-right_xx-small slds-m-left_xx-large" >
                                        </lightning-input>
                                        </template>
    
                                </li>
                                <li class="slds-button-group-item" >
                                    <lightning-button class="slds-m-right_xxx-small slds-m-top_none slds-m-bottom_xxx-small" slot="actions" label="Submit" onclick={updateRecords}>
                                    </lightning-button>
                                    <lightning-helptext class="slds-m-top_none slds-m-bottom_xxx-small slds-m-right_xx-small " content="The users that will exclude from the de-activation."></lightning-helptext>
    
                                </li>
                                </ul>
    
                  </div>
                                </span>
                        </lightning-layout-item>
                    </lightning-layout>
    
            </div>
        <div class="slds-p-left_medium">
            <div class="slds-col slds-size_12-of-12 slds-p-top_medium">
                <div class="slds-p-around_medium lgc-bg">
                    <lightning-datatable
                            key-field="UserId"
                            columns={columns}
                            data={currentPageData}
                            selected-rows= {allSelectedRows}
                            onrowselection= {rowSelection}
                            sorted-by={sortBy}
                            sorted-direction={sortDirection}
                            onsort={handleSortdata}
                    >
                    </lightning-datatable>
                </div>
                <div class="slds-col slds-size_10-of-12 slds-p-top_medium">
                    <lightning-layout multiple-rows="true">
                        <lightning-layout-item size = "12" margin= "around-small">
                            <div class="slds-align_absolute-center">
                                <ul class="slds-button-group-row">
                                    <!-- <template if:true={hasPrev}>-->
                                    <li class="slds-button-group-item" >
                                            <button class="slds-button slds-button_neutral" onclick ={onFirst} disabled={disabledConditionFirst}> First
                                            </button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                              <button class="slds-button slds-button_neutral" disabled={disabledConditionPrev} onclick ={onPrev}> Prev
                                              </button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                          <button class="slds-button slds-button_neutral" disabled={disabledConditionNext} onclick={onNext} >Next</button>
                                    </li>
                                    <li class="slds-button-group-item" >
                                            <button class="slds-button slds-button_neutral"  onclick ={onLast} disabled={disabledConditionLast}> Last
                                            </button>
                                    </li>
                                    <!--</template>-->
                                </ul>
                            </div>
                            </br>
                            <div class="slds-align_absolute-center" >
                        <span
                                disabled={disabledCondition}>Total Records: {totalRecordCount} </span>
                            </div>
                            <div class="slds-align_absolute-center" >
                                <span disabled={disabledCondition}>Page ({page} of {numberOfPages}) </span>
                            </div>
                        </lightning-layout-item>
                    </lightning-layout>
                </div>
            </div>
        </div>
        <div if:true={showLoadingSpinner}>
            <lightning-spinner alternative-text="Loading" size="large"></lightning-spinner>
        </div>
    </lightning-card>


JS

import { LightningElement, track, wire, api} from 'lwc';
import getUserList from '@salesforce/apex/UserManagementController.getUserList';
import userRecordsUpdate from '@salesforce/apex/UserManagementController.userRecordsUpdate';
import { refreshApex} from '@salesforce/apex';
import { ShowToastEvent} from 'lightning/platformShowToastEvent';
import getProfile from '@salesforce/apex/UserManagementController.getProfile';
import updateUserManagementProcess from '@salesforce/apex/UserManagementController.updateUserManagementProcess';

export default class Usermanagement extends LightningElement {

  //Display Coulmns on Datatable
  @track columns = [

    {
      label: 'Name',
      fieldName: 'recordLink',
      type: 'url',
      typeAttributes: { label: { fieldName: "FullName" }, tooltip:"Name", target: "_blank" },
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: 'Email',
      fieldName: 'Email',
      type: 'text',
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: 'Profile',
      fieldName: 'ProfileName',
      type: 'text',
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 170,
    },
    {
      label: 'Role',
      fieldName: 'RoleName',
      type: 'text',
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: "Last Login Date",
      fieldName: "LastLoginDate",
      type: "date",
      typeAttributes: {
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit"
      },
      sortable: true,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 200,
    },
    {
      label: 'isFrozen',
      fieldName: 'isFrozen',
      type: 'text',
      sortable: false,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 100,
    },
    {
      label: 'isDeactivate',
      fieldName: 'isDeactivate',
      type: 'text',
      sortable: false,
      cellAttributes: {
        alignment: 'left'
      },
      initialWidth: 125,
    }

  ];

  // Track Gloabal variables
  @track showLoadingSpinner = false;
  @track error;
  @track page = 1;
  @track perpage = 20;
  @track pages = [];
  @track disabledConditionNext = true;
  @track disabledConditionPrev = true;
  @track disabledConditionFirst = true;
  @track disabledConditionLast = true;
  @track preSelectedRows = [];
  @track totalRecordCount = 0;
  @track numberOfPages = 1;
  @track sortBy;
  @track sortDirection;
  @track ToggleChecked;

  //Gloabal variables
  data = [];
  @api allDeSelectedRows = [];
  pageSlice;
  numOfPreviousPages;
  showToggle = false;
  wiredActivities;
  @track profName;

  //  Initial Method Call
  connectedCallback() {
    console.log('Initial' );
    this.init();
  }

  //Enable Deactivate Process button for Admins based on profile
  @wire(getProfile)
  wiredActivities({ error, data }) {
    if (data){
      console.log('profName==> '+JSON.stringify(data));

      this.profName = data;
      if(this.profName == 'System Administrator'){
        this.showToggle = true;
      }else{
      this.showToggle = false;
}
      console.log(this.profName);
      this.error = undefined;
     } else if (error) {
      this.error = error;
      this.data = undefined;

  }
}

  // Initial Method Call - Populate data on UI
  async init() {
    try {
      this.disabledConditionNext = true;
      this.disabledConditionPrev = true;
      this.disabledConditionFirst = true;
      this.disabledConditionLast = true;
      this.showLoadingSpinner = true;
      await getUserList()
        .then((result, error) => {
          console.log('result =' + result);
          var userList = JSON.parse(result);
          if (userList) {
             var tempUserList = [];
             userList.userMngtWrapperList.forEach((record) => {
                 let tempUserRec = Object.assign({}, record);
                 tempUserRec.recordLink = '/' + tempUserRec.UserId;
                 tempUserList.push(tempUserRec);
             });
            this.data = tempUserList;
            this.preSelectedRows = userList.selectedUserIdSet;
            this.ToggleChecked = userList.enableUserMngmtProcess;
            this.allSelectedRows = [];
            //this.data = this.data;
            console.log('this.data new =' + this.data);
            console.log('allSelectedRows =' + this.allSelectedRows);
            console.log('preSelectedRows =' + this.preSelectedRows);
            this.totalRecordCount = this.data.length;
            this.error = undefined;
          } else if (error) {
            console.error(error);
            this.data = undefined;
          }
        });
      this.setPages(this.data);

      if (this.data.length == 0) {
        this.dispatchEvent(
          new ShowToastEvent({
            title: 'No records to Display',
            message: 'No users to de-activates',
            variant: 'info'
          })
        );
      }
      this.showLoadingSpinner = false;

    } catch (error) {
      this.error = error;
    } finally {
      this.showLoadingSpinner = false;
    }
  }

/**
 * Below Methods are to Manipulate Page Load,Navigation and page click
 * pagesList
 * currentPageData
 * pageData
 * setPages
 * onPageClick
 * onNext
 * onPrev
 * onFirst
 * onLast
 * changePage
 */

  // Get Page list
  get pagesList() {
    let mid = Math.floor(this.perpage / 2) + 1;
    if (this.page > mid) {
      return this.pages.slice(this.page - mid, this.page + mid - 1);
    }
    return this.pages.slice(0, this.perpage);
  }

  // Get Data to load to current Page
  get currentPageData() {
    return this.pageData();
  }

 // Get Current Page Data based on page Number
  pageData = () => {
    let numberOfPages = Math.ceil(this.data.length / this.perpage);
    this.numberOfPages = numberOfPages;
    let page = this.page;
    let perpage = this.perpage;
    let startIndex = (page * perpage) - perpage;
    let endIndex = (page * perpage);

    if (this.numberOfPages < 2)
    {
        this.disabledConditionNext = true;
        this.disabledConditionPrev = true;
        this.disabledConditionLast = true;
        this.disabledConditionFirst = true;
    }
    else if (this.page  == this.numberOfPages)
    {
         this.disabledConditionNext = true;
         this.disabledConditionPrev = false;
         this.disabledConditionLast = true;
         this.disabledConditionFirst = false;
    }
    else if (this.page  == 1)
    {
          this.disabledConditionNext = false;
          this.disabledConditionPrev = true;
          this.disabledConditionLast = false;
          this.disabledConditionFirst = true;
    }
    else // if (this.page  < this.numberOfPages)
    {
          this.disabledConditionNext = false;
          this.disabledConditionPrev = false;
          this.disabledConditionLast = false;
          this.disabledConditionFirst = false;
    }

    this.pageSlice = this.data.slice(startIndex, endIndex);
    return this.data.slice(startIndex, endIndex);
  }

  // Get Number of pages need to be visible based on the data amount
  setPages = (data) => {
    let numberOfPages = Math.ceil(data.length / this.perpage);
    this.numOfPreviousPages = numberOfPages;
  }

  // Page Click event
  onPageClick = (e) => {
    this.page = parseInt(e.target.dataset.id, 10);
    }
  }

  // First Page button Click
  onFirst = () => {
    this.changePage(1);
  }

 // Last Page button Click
  onLast = () => {
    this.changePage(this.numberOfPages > 0 ? this.numberOfPages : 1);
  }

  // Page Data Change based on page number
  changePage(pageNumber) {

    let pageData = this.pageData();
    // Preserve rows outside current page and add rows from current page
    this.allSelectedRows = this.allSelectedRows.filter((rowId) => !pageData.find((record) => record.userId === rowId)).concat(this.template.querySelector('lightning-datatable').selectedRows);
    //Distinct the dataset
    this.allSelectedRows = this.allSelectedRows.filter((v, i, a) => a.indexOf(v) == i);
    console.log('changePage-allSelectedRows = ' + this.allSelectedRows);
    this.page = pageNumber;
    pageData = this.pageData();

    console.log('changePage - this.preSelectedRows in current page =' + this.preSelectedRows);
 }

 // On Row Selection - when select/deselect Checkbox
 rowSelection(evt) {
    let deselectedRecs = [];
    this.allSelectedRows = this.allSelectedRows.filter((v, i, a) => a.indexOf(v) == i);
    const selectedRows = evt.detail.selectedRows;
    console.log('rowSelection - Selected Rows are ' + JSON.stringify(selectedRows));
    console.log("rowSelection - selectedRows.length" + selectedRows.length);
    //concat new selected ids to allSelectedRows list
    this.allSelectedRows  = selectedRows
              .map(x => x.UserId)
              .concat(this.allSelectedRows ).filter((v, i, a) => a.indexOf(v) == i);
    console.log("rowSelection - this.allSelectedRows concat new selected ids= " + this.allSelectedRows);
    //remove new selected ids from deselectedRecs list
    this.deselectedRecs = this.pageSlice
        .filter(x => !selectedRows.includes(x))
        .concat(selectedRows.filter(x => !this.pageSlice.includes(x)))
        .map(x => x.UserId).filter((v, i, a) => a.indexOf(v) === i);
    console.log('rowSelection - Deselected Recs are original ' + this.deselectedRecs);
    console.log('rowSelection - deselectedRecs.length ' + this.deselectedRecs.length);
    if (this.deselectedRecs.length > 0) {
        //remove deselected ids from allSelectedRows list
        this.allSelectedRows = this.allSelectedRows.filter(item => !this.deselectedRecs.includes(item)).filter((v, i, a) => a.indexOf(v) === i);
    }
    console.log('rowSelection - Final allSelectedRows= ' + this.allSelectedRows);
  }

  updateRecords(event) {
    console.log('this.allSelectedRows updateRecords'+ this.allSelectedRows);
      console.log('this.preSelectedRows updateRecords'+ this.preSelectedRows);
    this.allDeSelectedRows = this.preSelectedRows
                                  .filter(item => !this.allSelectedRows.some(obj => obj === item))
                                  .filter((v, i, a) => a.indexOf(v) === i);
    if (this.allDeSelectedRows.length > 0) {
      this.showLoadingSpinner = true;
      console.log('this.allDeSelectedRows updateRecords'+ this.allDeSelectedRows);

      userRecordsUpdate({
          deSelectedArrList: this.allDeSelectedRows
        })
        .then(result => {
          if (result) {
            console.log('result userRecordsUpdate ='+ result);
            this.showLoadingSpinner = false;
            this.dispatchEvent(
              new ShowToastEvent({
                title: 'Success',
                message: 'User List updated',
                variant: 'success'
              })
            );
           window.location.reload();
          } else {
             console.log('Update failed.');
             this.dispatchEvent(
                  new ShowToastEvent({
                     title: 'Error updating user records',
                     message: 'Update failed',
                     variant: 'error'
                     }));
          }
        })
        .catch(error => {
          this.showLoadingSpinner = false;
          console.log('Update failed due to - ' + error);
          this.dispatchEvent(
            new ShowToastEvent({
              title: 'Error updating user records',
              message: error,
              variant: 'error'
            }));
        });
    }
    else
    {
        this.dispatchEvent(
        new ShowToastEvent({
            title: 'No records to Update',
            message: 'No users to de-activates',
            variant: 'info'
            })
        );
    }
  }

  deactivateProcess(event) {
        this.showLoadingSpinner = true;
         let chk = event.target.checked;
         console.log("clicked : "+ event.target.checked);

         if (chk != null) {

             updateUserManagementProcess({
                   status: event.target.checked
                 })
                 .then(result => {
                   if (result) {
                     console.log('result updateUserManagementProcess ='+ result);
                     this.showLoadingSpinner = false;

                     if(chk == true)
                     {
                         this.dispatchEvent(
                           new ShowToastEvent({
                             title: 'Success',
                             message: 'User Deactivation is Active',
                             variant: 'success'
                           })
                     );
                     }
                     else
                     {
                          this.dispatchEvent(
                             new ShowToastEvent({
                               title: 'Success',
                               message: 'User Deactivation is Inactive',
                               variant: 'success'
                          })
                       );
                       }


                   } else {
                      console.log('Update failed.');
                      this.dispatchEvent(
                           new ShowToastEvent({
                              title: 'Error updating user management meta-data record',
                              message: 'Update failed',
                              variant: 'error'
                              }));
                   }
                 })
                 .catch(error => {
                   this.showLoadingSpinner = false;
                   console.log('Update failed due to - ' + error);
                   this.dispatchEvent(
                     new ShowToastEvent({
                       title: 'Error updating user management meta-data record',
                       message: error,
                       variant: 'error'
                     }));
                 });
   		}
   else
       {
           this.dispatchEvent(
           new ShowToastEvent({
               title: 'Update Failed',
               message: 'Error updating user management meta-data record',
               variant: 'info'
               })
           );
       }
     }



  // Sorting
   handleSortdata(event) {
          // field name
          this.sortBy = event.detail.fieldName;
          console.log('this.sortBy = '+this.sortBy);
          // sort direction
          this.sortDirection = event.detail.sortDirection;
          console.log('this.sortDirection = '+this.sortDirection);
          // calling sortdata function to sort the data based on direction and selected field
          this.sortData(event.detail.fieldName, event.detail.sortDirection);
      }

      sortData(fieldname, direction) {
          // serialize the data before calling sort function
          let parseData = JSON.parse(JSON.stringify(this.data));
           console.log('this.parseData = '+this.parseData);
           console.log('this.fieldname = '+fieldname);
          // Return the value stored in the field
          let keyValue = (a) => {
              return a[fieldname];
          };

          // cheking reverse direction
          let isReverse = direction === 'asc' ? 1: -1;

          // sorting data
          parseData.sort((x, y) => {
              x = keyValue(x) ? keyValue(x) : ''; // handling null values
              y = keyValue(y) ? keyValue(y) : '';

              // sorting values based on direction
              return isReverse * ((x > y) - (y > x));
          });

          // set the sorted data to data table data
          this.data = parseData;

      }
}

​​​​​​​