├── .eslintignore ├── .forceignore ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── LICENSE ├── README.md ├── config └── project-scratch-def.json ├── force-app └── main │ └── default │ ├── appMenus │ └── AppSwitcher.appMenu-meta.xml │ ├── applications │ └── Drag_and_Drop.app-meta.xml │ ├── classes │ ├── AccountsData.cls │ ├── AccountsData.cls-meta.xml │ ├── CasePicker.cls │ ├── CasePicker.cls-meta.xml │ ├── CasesData.cls │ ├── CasesData.cls-meta.xml │ ├── ContactsData.cls │ ├── ContactsData.cls-meta.xml │ ├── LeadsData.cls │ ├── LeadsData.cls-meta.xml │ ├── LoadData.cls │ └── LoadData.cls-meta.xml │ ├── flexipages │ ├── Case_Picker_App.flexipage-meta.xml │ └── Drag_and_Drop_Demos_UtilityBar.flexipage-meta.xml │ ├── lwc │ ├── .eslintrc.json │ ├── caseItem │ │ ├── caseItem.css │ │ ├── caseItem.html │ │ ├── caseItem.js │ │ └── caseItem.js-meta.xml │ ├── caseList │ │ ├── caseList.css │ │ ├── caseList.html │ │ ├── caseList.js │ │ └── caseList.js-meta.xml │ ├── caseListForPage │ │ ├── caseListForPage.html │ │ ├── caseListForPage.js │ │ └── caseListForPage.js-meta.xml │ ├── casePicker │ │ ├── casePicker.html │ │ ├── casePicker.js │ │ └── casePicker.js-meta.xml │ └── pubsub │ │ ├── pubsub.js │ │ └── pubsub.js-meta.xml │ ├── objects │ ├── Account │ │ └── listViews │ │ │ └── All_Accounts.listView-meta.xml │ ├── Case │ │ └── listViews │ │ │ └── All_Cases.listView-meta.xml │ ├── Contact │ │ └── listViews │ │ │ └── All_Contacts.listView-meta.xml │ └── Lead │ │ └── listViews │ │ └── All_Leads.listView-meta.xml │ ├── pages │ ├── DragAndDropHTMLDemo.page │ └── DragAndDropHTMLDemo.page-meta.xml │ ├── profiles │ ├── Admin.profile-meta.xml │ ├── Custom%3A Marketing Profile.profile-meta.xml │ ├── Custom%3A Sales Profile.profile-meta.xml │ └── Custom%3A Support Profile.profile-meta.xml │ ├── staticresources │ ├── case.png │ └── case.resource-meta.xml │ └── tabs │ ├── Case_Picker_App.tab-meta.xml │ ├── Case_Picker_Demo.tab-meta.xml │ └── HTML_Standard_DnD_Example.tab-meta.xml ├── package.json ├── scripts ├── CreateOrg.sh └── ResetData.txt └── sfdx-project.json /.eslintignore: -------------------------------------------------------------------------------- 1 | **/lwc/**/*.css 2 | **/lwc/**/*.html 3 | **/lwc/**/*.json 4 | **/lwc/**/*.svg 5 | **/lwc/**/*.xml 6 | .sfdx -------------------------------------------------------------------------------- /.forceignore: -------------------------------------------------------------------------------- 1 | # List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status 2 | # More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm 3 | # 4 | 5 | package.xml 6 | 7 | # LWC configuration files 8 | **/jsconfig.json 9 | **/.eslintrc.json 10 | 11 | # LWC Jest 12 | **/__tests__/** -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used for Git repositories to specify intentionally untracked files that Git should ignore. 2 | # If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore 3 | # For useful gitignore templates see: https://github.com/github/gitignore 4 | 5 | # Salesforce cache 6 | .sfdx/ 7 | .localdevserver/ 8 | 9 | # LWC VSCode autocomplete 10 | **/lwc/jsconfig.json 11 | 12 | # LWC Jest coverage reports 13 | coverage/ 14 | 15 | # Logs 16 | logs 17 | *.log 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | 22 | # Dependency directories 23 | node_modules/ 24 | 25 | # Eslint cache 26 | .eslintcache 27 | 28 | # MacOS system files 29 | .DS_Store 30 | 31 | # Windows system files 32 | Thumbs.db 33 | ehthumbs.db 34 | [Dd]esktop.ini 35 | $RECYCLE.BIN/ 36 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # List files or directories below to ignore them when running prettier 2 | # More information: https://prettier.io/docs/en/ignore.html 3 | # 4 | 5 | .localdevserver 6 | .sfdx 7 | 8 | coverage/ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "overrides": [ 4 | { 5 | "files": "**/lwc/**/*.html", 6 | "options": { "parser": "lwc" } 7 | }, 8 | { 9 | "files": "*.{cmp,page,component}", 10 | "options": { "parser": "html" } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "salesforce.salesforcedx-vscode", 4 | "redhat.vscode-xml", 5 | "dbaeumer.vscode-eslint", 6 | "esbenp.prettier-vscode" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch Apex Replay Debugger", 9 | "type": "apex-replay", 10 | "request": "launch", 11 | "logFile": "${command:AskForLogFileName}", 12 | "stopOnEntry": true, 13 | "trace": true 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "search.exclude": { 3 | "**/node_modules": true, 4 | "**/bower_components": true, 5 | "**/.sfdx": true 6 | } 7 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Outformations, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LWC Drag and Drop Demos 2 | 3 | This is a reference app to demonstrate drag and drop functionality using Lightning Web Components in Salesforce development. 4 | 5 | The sample apps are intended to demonstrate the basic usage of standard HTML5 drag and drop functionality using Lightning Web Components. Two samples Apps are included, and the architectural approach is designed to reuse the custom base components for both loosely and tightly coupled apps. 6 | 7 | The first app uses a tightly coupled model and a component hierarchy, and leverages custom events for messaging activated by handling and raising standard HTML5 drag and drop events within that hierarchy. 8 | 9 | The other app uses a loosly coupled model allowing reuse of the custom base components that can be dropped and configured on an App Page. Cross component messaging is accomplished using a pubsub eventing model. Reusability of the base components is accomplished by adding a wrapper component that handles the custom events and brokers them with pubsub events allowing cross page messaging. 10 | 11 | One key architectural approach is to minimize the data transfer of messaging payloads using custom eventing payloads instead of the data transfer capability of the HTML drag and drop events, as would be the case with standard web development. 12 | 13 | A second key architectural approach is to use the data processing logic capabilities of the Lightning Web Component framework, and to manage the reactive rerendering of the components in response to the drag and drop events processed rather than the direct manipulation of the DOM as would be the case with standard web development. 14 | 15 | And finally, validation of the associated UI rules is accomplished with JavaScript logic written into the event handlers, rather than implementation of the standard HTML5 drop effects to control allowable behavior. 16 | 17 | ## To Set Up The Project 18 | 19 | This is a scratch org project that requires Visual Studio Code and SFDX. 20 | 21 | Once you have cloned the Git repository on your computer, authorize a DevHub by running the following SFDX command in your terminal (name the alias however you want): 22 | 23 | sfdx force:auth:web:login -d -a dhDnD 24 | 25 | Next run the CreateOrg.sh script in your terminal as follows (this is for a Mac, adjust as needed for a PC): 26 | 27 | ./scripts/CreateOrg.sh 28 | 29 | ## The script will do the following: 30 | 31 | 1 - Creates 30 day scratch Org with the alias soDnD 32 | 33 | 2 - Pushes the project metadata to the scratch Org 34 | 35 | 3 - Pushes some sample Account, Contact and Case data to the scratch Org 36 | 37 | 4 - Opens the scratch Org and navigates to the first Demo page 38 | 39 | Play and dissect! 40 | -------------------------------------------------------------------------------- /config/project-scratch-def.json: -------------------------------------------------------------------------------- 1 | { 2 | "orgName": "Forcementor", 3 | "edition": "Developer", 4 | "features": [] 5 | } 6 | -------------------------------------------------------------------------------- /force-app/main/default/appMenus/AppSwitcher.appMenu-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | standard__Platform 5 | CustomApplication 6 | 7 | 8 | standard__Sales 9 | CustomApplication 10 | 11 | 12 | standard__Service 13 | CustomApplication 14 | 15 | 16 | standard__Marketing 17 | CustomApplication 18 | 19 | 20 | standard__ServiceConsole 21 | CustomApplication 22 | 23 | 24 | standard__AppLauncher 25 | CustomApplication 26 | 27 | 28 | standard__Community 29 | CustomApplication 30 | 31 | 32 | standard__Sites 33 | CustomApplication 34 | 35 | 36 | standard__Chatter 37 | CustomApplication 38 | 39 | 40 | standard__Content 41 | CustomApplication 42 | 43 | 44 | standard__Insights 45 | CustomApplication 46 | 47 | 48 | standard__LightningSales 49 | CustomApplication 50 | 51 | 52 | standard__AllTabSet 53 | CustomApplication 54 | 55 | 56 | CPQIntegrationUserApp 57 | ConnectedApp 58 | 59 | 60 | standard__LightningBolt 61 | CustomApplication 62 | 63 | 64 | standard__SalesforceCMS 65 | CustomApplication 66 | 67 | 68 | Drag_and_Drop 69 | CustomApplication 70 | 71 | 72 | -------------------------------------------------------------------------------- /force-app/main/default/applications/Drag_and_Drop.app-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #0070D2 5 | false 6 | 7 | Demos for drag and drop functionality with Lightning Web Components 8 | Small 9 | Large 10 | false 11 | false 12 | Drag and Drop 13 | Standard 14 | HTML_Standard_DnD_Example 15 | Case_Picker_Demo 16 | Case_Picker_App 17 | standard-Case 18 | standard-Account 19 | standard-Contact 20 | standard-Lead 21 | Lightning 22 | Drag_and_Drop_Demos_UtilityBar 23 | 24 | -------------------------------------------------------------------------------- /force-app/main/default/classes/AccountsData.cls: -------------------------------------------------------------------------------- 1 | public without sharing class AccountsData { 2 | 3 | public static Map buildData () { 4 | 5 | Map accounts = new Map{ 6 | 'Account 001' => new Account(ANNUALREVENUE=50000,BILLINGCITY='New York',BILLINGCOUNTRY='United States',BILLINGPOSTALCODE='10012',BILLINGSTATE='New York',BILLINGSTREET='1500 Broadway',FAX='',INDUSTRY='',NAME='Manhatten Technologies',NUMBEROFEMPLOYEES=20,PHONE='(212) 799-5000',SHIPPINGCITY='New York',SHIPPINGCOUNTRY='United States',SHIPPINGPOSTALCODE='10012',SHIPPINGSTATE='New York',SHIPPINGSTREET='1500 Broadway',TYPE='',WEBSITE='https://www.manhattentech.com'), 7 | 'Account 002' => new Account(ANNUALREVENUE=15000,BILLINGCITY='San Francisco',BILLINGCOUNTRY='United States',BILLINGPOSTALCODE='94117',BILLINGSTATE='California',BILLINGSTREET='568 Clayton Street',FAX='',INDUSTRY='',NAME='Train Them Young',NUMBEROFEMPLOYEES=30,PHONE='(415) 354-6780',SHIPPINGCITY='San Francisco',SHIPPINGCOUNTRY='United States',SHIPPINGPOSTALCODE='94117',SHIPPINGSTATE='California',SHIPPINGSTREET='568 Clayton Street',TYPE='',WEBSITE='https://www.trainthemyoung.com') 8 | }; 9 | 10 | insert accounts.values(); 11 | 12 | return accounts; 13 | } 14 | } -------------------------------------------------------------------------------- /force-app/main/default/classes/AccountsData.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/CasePicker.cls: -------------------------------------------------------------------------------- 1 | public without sharing class CasePicker { 2 | 3 | //Fetch all Cases 4 | @AuraEnabled(cacheable=true) 5 | public static List getAllCases() { 6 | string query = 'SELECT Id, Subject, Status, Priority FROM Case ORDER BY Subject'; 7 | return Database.query(query); 8 | } 9 | 10 | //Reset all Cases to New status 11 | @AuraEnabled 12 | public static void resetAllCasesNew() { 13 | list allCases = [SELECT Id, Status FROM Case]; 14 | for (Case c : allCases) { 15 | c.Status = 'New'; 16 | } 17 | Database.update(allCases); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /force-app/main/default/classes/CasePicker.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/CasesData.cls: -------------------------------------------------------------------------------- 1 | public without sharing class CasesData { 2 | 3 | public static Map buildData () { 4 | 5 | Map cases = new Map{ 6 | 'Case001'=> new Case(SUBJECT='Review Material DEX602',STATUS='New',PRIORITY='Medium'), 7 | 'Case002'=> new Case(SUBJECT='Review Material ADX211',STATUS='New',PRIORITY='Medium'), 8 | 'Case003'=> new Case(SUBJECT='Review Material CCD102',STATUS='New',PRIORITY='Medium'), 9 | 'Case004'=> new Case(SUBJECT='Review Material DEX403',STATUS='New',PRIORITY='Medium'), 10 | 'Case005'=> new Case(SUBJECT='Review Material DEX502',STATUS='New',PRIORITY='Medium') 11 | }; 12 | insert cases.values(); 13 | 14 | return cases; 15 | } 16 | } -------------------------------------------------------------------------------- /force-app/main/default/classes/CasesData.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/ContactsData.cls: -------------------------------------------------------------------------------- 1 | public without sharing class ContactsData { 2 | 3 | public static Map buildData (Map accounts) { 4 | 5 | Map contacts = new Map{ 6 | 'PeterG'=> new Contact(EMAIL='peter@manhattentech.com',FIRSTNAME='Peter',LASTNAME='Grapple',MAILINGCITY='Reno',MAILINGCOUNTRY='United States', MAILINGPOSTALCODE='92030',MAILINGSTATE='Nevada',MAILINGSTREET='150 Main Street',PHONE='1-465-555-2123',MOBILEPHONE='',TITLE='Technical Instructor',ACCOUNTID=accounts.get('Account 001').Id), 7 | 'JoeF' => new Contact(EMAIL='joe@manhattentech.com',FIRSTNAME='Joe',LASTNAME='Tulip',MAILINGCITY='Arlington',MAILINGCOUNTRY='United States', MAILINGPOSTALCODE='54909',MAILINGSTATE='Virginia',MAILINGSTREET='2910 Broadway',PHONE='1-375-555-2123',MOBILEPHONE='',TITLE='Technical Instructor',ACCOUNTID=accounts.get('Account 001').Id), 8 | 'FredZ' => new Contact(EMAIL='fred@manhattentech.com',FIRSTNAME='Fred',LASTNAME='Zappa',MAILINGCITY='Pleasonton',MAILINGCOUNTRY='United States', MAILINGPOSTALCODE='58390',MAILINGSTATE='California',MAILINGSTREET='86 Robertson Road',PHONE='1-856-555-2123',MOBILEPHONE='',TITLE='Technical Instructor',ACCOUNTID=accounts.get('Account 001').Id), 9 | 'DanG' => new Contact(EMAIL='dan@trainthemyoung.com',FIRSTNAME='Dan',LASTNAME='Gould',MAILINGCITY='Los Angeles',MAILINGCOUNTRY='United States', MAILINGPOSTALCODE='30949',MAILINGSTATE='California',MAILINGSTREET='7 William Street',PHONE='1-510-666-6627',MOBILEPHONE='',TITLE='Technical Instructor',ACCOUNTID=accounts.get('Account 002').Id), 10 | 'AdamD' => new Contact(EMAIL='adam@trainthemyoung.com',FIRSTNAME='Adam',LASTNAME='Downey',MAILINGCITY='Madison',MAILINGCOUNTRY='United States',MAILINGPOSTALCODE='79009',MAILINGSTATE='Wisconsin',MAILINGSTREET='7809 Waller Way',PHONE='1-766-897-3456',MOBILEPHONE='',TITLE='Technical Instructor',ACCOUNTID=accounts.get('Account 002').Id) 11 | }; 12 | insert contacts.values(); 13 | 14 | return contacts; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /force-app/main/default/classes/ContactsData.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/LeadsData.cls: -------------------------------------------------------------------------------- 1 | public without sharing class LeadsData { 2 | 3 | public static Map buildData () { 4 | 5 | Map leads = new Map{ 6 | 'JohnS'=> new Lead(EMAIL='john@smith.com',FIRSTNAME='John',LASTNAME='Smith',TITLE='Developer',COMPANY='Tech Co.',STATUS='Open - Not Contacted'), 7 | 'TimH'=> new Lead(EMAIL='tim@harrington.com',FIRSTNAME='Tim', LASTNAME='Harrington',TITLE='Administrator',COMPANY='Global Inc.',STATUS='Open - Not Contacted'), 8 | 'SallyR'=> new Lead(EMAIL='sally@rogers.com',FIRSTNAME='Sally',LASTNAME='Rogers',TITLE='QA Lead',COMPANY='QA Co.',STATUS='Open - Not Contacted'), 9 | 'MannyW'=> new Lead(EMAIL='manny@williams.com',FIRSTNAME='Manny',LASTNAME='Williams',TITLE='Developer',COMPANY='IBM',STATUS='Open - Not Contacted'), 10 | 'HarryK'=> new Lead(EMAIL='harry@kelly.com',FIRSTNAME='Harry',LASTNAME='Kelly',TITLE='DevOps Manager',COMPANY='Google',STATUS='Open - Not Contacted'), 11 | 'CharlieR'=> new Lead(EMAIL='charlie@robinson.com',FIRSTNAME='Charlie',LASTNAME='Robinson',TITLE='Documentation Director',COMPANY='Salesforce',STATUS='Open - Not Contacted') 12 | }; 13 | insert leads.values(); 14 | 15 | return leads; 16 | } 17 | } -------------------------------------------------------------------------------- /force-app/main/default/classes/LeadsData.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/classes/LoadData.cls: -------------------------------------------------------------------------------- 1 | public without sharing class LoadData { 2 | 3 | public static void buildData() { 4 | 5 | Map accounts = AccountsData.buildData(); 6 | Map contacts = ContactsData.buildData(accounts); 7 | Map cases = CasesData.buildData(); 8 | Map leads = LeadsData.buildData(); 9 | 10 | } 11 | 12 | public static void clearData() { 13 | 14 | delete [SELECT Id FROM Lead]; 15 | delete [SELECT Id FROM Case]; 16 | delete [SELECT Id FROM Contact]; 17 | delete [SELECT Id FROM Account]; 18 | 19 | } 20 | } -------------------------------------------------------------------------------- /force-app/main/default/classes/LoadData.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /force-app/main/default/flexipages/Case_Picker_App.flexipage-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | selectedStatus 7 | New 8 | 9 | caseListForPage 10 | 11 | 12 | 13 | selectedStatus 14 | Working 15 | 16 | caseListForPage 17 | 18 | 19 | 20 | selectedStatus 21 | Escalated 22 | 23 | caseListForPage 24 | 25 | main 26 | Region 27 | 28 | Case Picker App 29 | 30 | flexipage:defaultAppHomeTemplate 31 | 32 | AppPage 33 | 34 | -------------------------------------------------------------------------------- /force-app/main/default/flexipages/Drag_and_Drop_Demos_UtilityBar.flexipage-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | utilityItems 5 | Region 6 | 7 | 8 | backgroundComponents 9 | Background 10 | 11 | Drag and Drop Demos UtilityBar 12 | 13 | one:utilityBarTemplateDesktop 14 | 15 | UtilityBar 16 | 17 | -------------------------------------------------------------------------------- /force-app/main/default/lwc/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@salesforce/eslint-config-lwc/recommended"] 3 | } 4 | -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseItem/caseItem.css: -------------------------------------------------------------------------------- 1 | .draggable-card { 2 | background-color: white; 3 | border: 2px solid black; 4 | border-style: solid; 5 | border-radius: 5px; 6 | } 7 | 8 | .drag { 9 | border-style: dashed; 10 | opacity: 0.25; 11 | } -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseItem/caseItem.html: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | Status: {caseRecord.Status} 12 | Priority: {caseRecord.Priority} 13 | Id: {caseRecord.Id} 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseItem/caseItem.js: -------------------------------------------------------------------------------- 1 | import { LightningElement, api } from 'lwc'; 2 | 3 | export default class CaseItem extends LightningElement { 4 | @api caseRecord; 5 | 6 | //Property to track the original status of the DRAG target 7 | originalStatus; 8 | 9 | //DRAG SOURCE dragstart event handler 10 | itemDragStart(evt) { 11 | 12 | console.log('Handling DragStart for item: ' + this.caseRecord.Id); 13 | 14 | //Store the original status 15 | this.originalStatus = this.caseRecord.Status; 16 | 17 | //Fetch the element to set the style 18 | let draggableElement = this.template.querySelector('[data-id="' + this.caseRecord.Id + '"]'); 19 | draggableElement.classList.add('drag'); 20 | 21 | //Dispatch the custom event and pass the record Id and Status 22 | const event = new CustomEvent('itemdrag', { 23 | detail: { 24 | dragTargetId: this.caseRecord.Id, 25 | dragTargetStatus: this.originalStatus 26 | } 27 | }); 28 | this.dispatchEvent(event); 29 | } 30 | 31 | //DRAG SOURCE dragend event handler 32 | itemDragEnd(evt) { 33 | 34 | console.log('Handling DragEnd for item: ' + this.caseRecord.Id); 35 | 36 | //Reset the style 37 | let draggableElement = this.template.querySelector('[data-id="' + this.caseRecord.Id + '"]'); 38 | draggableElement.classList.remove('drag'); 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseItem/caseItem.js-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | false 5 | -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseList/caseList.css: -------------------------------------------------------------------------------- 1 | .over { 2 | border-style: solid dotted; 3 | border-color: green; 4 | } -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseList/caseList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | No {caseStatus} Cases 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseList/caseList.js: -------------------------------------------------------------------------------- 1 | import { LightningElement, api, track } from 'lwc'; 2 | 3 | export default class CaseList extends LightningElement { 4 | 5 | @api caseList; 6 | @api caseStatus; 7 | 8 | //Getter indicates if any items in the list 9 | get areCases() { 10 | if(this.caseList) { 11 | return this.caseList.length>0; 12 | } else { 13 | return false; 14 | } 15 | } 16 | 17 | //Function to cancel drag n drop events 18 | cancel(evt) { 19 | if (evt.stopPropagation) evt.stopPropagation(); 20 | if (evt.preventDefault) evt.preventDefault(); 21 | return false; 22 | }; 23 | 24 | //DRAG SOURCE drag event handler dispatched from the child component 25 | handleItemDrag(evt) { 26 | 27 | console.log('Drag event from the drag target: ' + evt.detailinto + ' for drop target: ' + this.caseStatus); 28 | this.cancel(evt); 29 | 30 | //Dispatch the custom event to raise the detail payload up one level 31 | const event = new CustomEvent('listitemdrag', { 32 | detail: evt.detail 33 | }); 34 | this.dispatchEvent(event); 35 | } 36 | 37 | //DROP TARGET dragenter event handler 38 | handleDragEnter(evt) { 39 | 40 | console.log('Drag Enter event for ' + this.caseStatus); 41 | 42 | //Cancel the event 43 | this.cancel(evt); 44 | 45 | } 46 | 47 | //DROP TARGET dragover event handler 48 | handleDragOver(evt) { 49 | 50 | console.log('Drag Over event for ' + this.caseStatus); 51 | 52 | //Cancel the event 53 | this.cancel(evt); 54 | 55 | this.addDragOverStyle() 56 | 57 | } 58 | 59 | //DROP TARGET dragleave event handler 60 | handleDragLeave(evt) { 61 | 62 | console.log('Drag Leave event for ' + this.caseStatus); 63 | 64 | //Cancel the event 65 | this.cancel(evt); 66 | 67 | this.removeDragOverStyle(); 68 | 69 | } 70 | 71 | //DROP TARGET drop event handler 72 | handleDrop(evt) { 73 | 74 | console.log('Handling Drop into drop tagert for status: ' + this.caseStatus); 75 | 76 | //Cancel the event 77 | this.cancel(evt); 78 | 79 | //Dispatch the custom event to raise the detail payload up one level 80 | const event = new CustomEvent('itemdrop', { 81 | detail: this.caseStatus 82 | }); 83 | this.dispatchEvent(event); 84 | 85 | this.removeDragOverStyle(); 86 | 87 | } 88 | 89 | //Set the style to indicate the element is being dragged over 90 | addDragOverStyle() { 91 | let draggableElement = this.template.querySelector('[data-role="drop-target"]'); 92 | draggableElement.classList.add('over'); 93 | } 94 | 95 | //Reset the style 96 | removeDragOverStyle() { 97 | let draggableElement = this.template.querySelector('[data-role="drop-target"]'); 98 | draggableElement.classList.remove('over'); 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseList/caseList.js-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | false 5 | -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseListForPage/caseListForPage.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseListForPage/caseListForPage.js: -------------------------------------------------------------------------------- 1 | import { LightningElement, api, track, wire } from 'lwc'; 2 | import getAllCases from '@salesforce/apex/CasePicker.getAllCases'; 3 | import { updateRecord} from 'lightning/uiRecordApi'; 4 | import { refreshApex } from '@salesforce/apex'; 5 | import { ShowToastEvent } from 'lightning/platformShowToastEvent'; 6 | 7 | //Required for PubSub 8 | import { fireEvent } from 'c/pubsub'; 9 | import { registerListener } from 'c/pubsub'; 10 | import { CurrentPageReference } from 'lightning/navigation'; 11 | 12 | //The fields required for the update of the Drag target record 13 | import FIELD_CASE_ID from '@salesforce/schema/Case.Id'; 14 | import FIELD_CASE_STATUS from '@salesforce/schema/Case.Status'; 15 | 16 | //Constants for the status picklist 17 | const STATUS_NEW = 'New'; 18 | const STATUS_WORKING = 'Working'; 19 | const STATUS_ESCALATED = 'Escalated'; 20 | 21 | export default class CaseListForPage extends LightningElement { 22 | 23 | //Will be selected from the App Page 24 | @api selectedStatus = ""; 25 | 26 | //A list of all cases for all status 27 | @track caseListAll = []; 28 | 29 | //Filtered array 30 | @track caseListFiltered = []; 31 | 32 | //Status values for the lists 33 | @track newStatus = STATUS_NEW; 34 | @track workingStatus = STATUS_WORKING; 35 | @track escalatedStatus = STATUS_ESCALATED; 36 | 37 | //Vars to track the DRAG COURSE data 38 | @track draggingId = ""; 39 | @track draggingStatus = ""; 40 | 41 | //Var to force initilization of data 42 | isInitialized = false; 43 | 44 | connectedCallback() { 45 | registerListener('statusChange', this.handleStatusChange, this); 46 | registerListener('dragStarted', this.handleDragStarted, this); 47 | console.log('Connected Callback this.selectedStatus: ', this.selectedStatus); 48 | } 49 | 50 | renderedCallback() { 51 | 52 | if(!this.isInitialized) { 53 | 54 | //Should only be needed once on render 55 | this.isInitialized = true; 56 | 57 | //Attempt to build the filtered list 58 | //'Belt and Suspenders' redundant call as async behavior requires it 59 | this.buildFilteredList(); 60 | }; 61 | } 62 | 63 | @wire(CurrentPageReference) pageRef; 64 | 65 | //Wired Apex method to fetch all records 66 | @wire( getAllCases ) 67 | wired_getAllCases(result) { 68 | 69 | console.log('wired_getAllCases() this.selectedStatus: ', this.selectedStatus); 70 | 71 | //Capture the returned data and any errors 72 | this.caseListAll = result; 73 | 74 | //Attempt to build the filtered list 75 | //'Belt and Suspenders' redundant call as async behavior requires it 76 | this.buildFilteredList(); 77 | 78 | } 79 | 80 | //Will build the filtered list from the all data list 81 | buildFilteredList() { 82 | 83 | //Only build if the data and status are present 84 | if (this.caseListAll.data && this.selectedStatus != '') { 85 | 86 | this.caseListFiltered = 87 | this.caseListAll.data.filter( 88 | (caseItem) => { 89 | return caseItem.Status === this.selectedStatus; 90 | }); 91 | 92 | } 93 | } 94 | 95 | //Handle the custom event dispatched originally from a DRAG SOURCE 96 | //and proxied from a DROP TARGET 97 | handleListItemDrag(evt) { 98 | 99 | console.log('Setting draggingId to: ' + evt.detail); 100 | 101 | //Capture the detail passed with the event from the DRAG target 102 | this.draggingId = evt.detail.dragTargetId; 103 | this.draggingStatus = evt.detail.dragTargetStatus; 104 | 105 | //Fire an event to broadcast the drag and include the data 106 | fireEvent(this.pageRef, 'dragStarted', 107 | { 108 | dragTargetId: this.draggingId, 109 | dragTargetStatus: this.draggingStatus 110 | }); 111 | } 112 | 113 | //Handle the custom event dispatched from a DROP TARGET 114 | handleItemDrop(evt) { 115 | 116 | //Set the DRAG SOURCE Id and new DROP TARGET Status for the update 117 | let draggedId = this.draggingId; 118 | let updatedStatus = evt.detail; 119 | 120 | console.log('Dropped - Id is: ' + draggedId + ', new Status is ' + updatedStatus); 121 | 122 | //Handle custom validations before allowing an update 123 | if (updatedStatus === this.draggingStatus) { 124 | 125 | //DO NOTHING if the DRAG status is NOT the DROP target Status 126 | 127 | } else if (this.newStatus == updatedStatus) { 128 | 129 | //Don't allow any record to be assigned to the New list 130 | this.showToast(this,'Drop Not Allowed','Case may not be reset as New!', 'error'); 131 | 132 | } else { 133 | 134 | //Update the DRAG SOURCE record with its new status 135 | let fieldsToSave = {}; 136 | fieldsToSave[FIELD_CASE_ID.fieldApiName] = draggedId; 137 | fieldsToSave[FIELD_CASE_STATUS.fieldApiName] = updatedStatus; 138 | const recordInput = { fields:fieldsToSave} 139 | 140 | updateRecord(recordInput) 141 | .then(() => { 142 | //Force a refresh of all bound lists 143 | refreshApex(this.caseListAll); 144 | }) 145 | .catch(error => { 146 | //Notify any error 147 | this.showToast(this,'Error Updating Record', error.body.message, 'error'); 148 | }); 149 | } 150 | 151 | //Fire an event to broadcast the need to refresh lists 152 | fireEvent(this.pageRef, 'statusChange'); 153 | } 154 | 155 | //Notification utility function 156 | showToast = (firingComponent, toastTitle, toastBody, variant) => { 157 | const evt = new ShowToastEvent({ 158 | title: toastTitle, 159 | message: toastBody, 160 | variant: variant 161 | }); 162 | firingComponent.dispatchEvent(evt); 163 | } 164 | 165 | //Handler for a PubSub status change event 166 | handleStatusChange() { 167 | refreshApex(this.caseListAll); 168 | } 169 | 170 | //Handler for a PubSub drag started event 171 | handleDragStarted(detail) { 172 | this.draggingId = detail.dragTargetId; 173 | this.draggingStatus = detail.dragTargetStatus; 174 | } 175 | 176 | } -------------------------------------------------------------------------------- /force-app/main/default/lwc/caseListForPage/caseListForPage.js-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | true 5 | 6 | lightning__AppPage 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /force-app/main/default/lwc/casePicker/casePicker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /force-app/main/default/lwc/casePicker/casePicker.js: -------------------------------------------------------------------------------- 1 | import { LightningElement, track, wire } from 'lwc'; 2 | import getAllCases from '@salesforce/apex/CasePicker.getAllCases'; 3 | import resetAllCasesNew from '@salesforce/apex/CasePicker.resetAllCasesNew'; 4 | import { updateRecord} from 'lightning/uiRecordApi'; 5 | import { refreshApex } from '@salesforce/apex'; 6 | import { ShowToastEvent } from 'lightning/platformShowToastEvent'; 7 | 8 | //The fields required for the update of the Drag target record 9 | import FIELD_CASE_ID from '@salesforce/schema/Case.Id'; 10 | import FIELD_CASE_STATUS from '@salesforce/schema/Case.Status'; 11 | 12 | //Constants for the status picklist 13 | const STATUS_NEW = 'New'; 14 | const STATUS_WORKING = 'Working'; 15 | const STATUS_ESCALATED = 'Escalated'; 16 | 17 | export default class CasePicker extends LightningElement { 18 | 19 | //A list of all cases for all status 20 | @track caseListAll; 21 | 22 | //Filtered arrays 23 | @track caseListNew; 24 | @track caseListWorking; 25 | @track caseListEscalated; 26 | 27 | //Status values for the lists 28 | @track newStatus = STATUS_NEW; 29 | @track workingStatus = STATUS_WORKING; 30 | @track escalatedStatus = STATUS_ESCALATED; 31 | 32 | //Vars to track the DRAG COURSE data 33 | @track draggingId = ""; 34 | @track draggingStatus = ""; 35 | 36 | //Wired Apex method to fetch all records 37 | @wire( getAllCases ) 38 | wired_getAllCases(result) { 39 | 40 | //Capture the returned data and any errors 41 | this.caseListAll = result; 42 | 43 | //Build filtered arrays if data returned 44 | //These lists are bound to the DROP TARGET components 45 | if(this.caseListAll.data) { 46 | 47 | this.caseListNew = 48 | this.caseListAll.data.filter( 49 | (caseItem) => { 50 | return caseItem.Status === this.newStatus; 51 | }); 52 | 53 | this.caseListWorking = 54 | this.caseListAll.data.filter( 55 | (caseItem) => { 56 | return caseItem.Status === this.workingStatus; 57 | }); 58 | 59 | this.caseListEscalated = 60 | this.caseListAll.data.filter( 61 | (caseItem) => { 62 | return caseItem.Status === this.escalatedStatus; 63 | }); 64 | 65 | } 66 | } 67 | 68 | //Manually reset all Cases to New 69 | resetData() { 70 | resetAllCasesNew() 71 | .then( () => { 72 | this.refreshData(); 73 | }) 74 | .catch(error => { 75 | //Notify any error 76 | this.showToast(this,'Error Resetting Data', error.body.message, 'error'); 77 | }); 78 | } 79 | 80 | //Manually refresh the data and the reactive DROP TARGET lists 81 | refreshData() { 82 | refreshApex(this.caseListAll); 83 | } 84 | 85 | //Handle the custom event dispatched originally from a DRAG SOURCE 86 | //and proxied from a DROP TARGET 87 | handleListItemDrag(evt) { 88 | 89 | console.log('Setting draggingId to: ' + evt.detail); 90 | 91 | //Capture the detail passed with the event from the DRAG target 92 | this.draggingId = evt.detail.dragTargetId; 93 | this.draggingStatus = evt.detail.dragTargetStatus; 94 | 95 | } 96 | 97 | //Handle the custom event dispatched from a DROP TARGET 98 | handleItemDrop(evt) { 99 | 100 | //Set the DRAG SOURCE Id and new DROP TARGET Status for the update 101 | let draggedId = this.draggingId; 102 | let updatedStatus = evt.detail; 103 | 104 | console.log('Dropped - Id is: ' + draggedId + ', new Status is ' + updatedStatus); 105 | 106 | //Handle custom validations before allowing an update 107 | if (updatedStatus === this.draggingStatus) { 108 | 109 | //DO NOTHING if the DRAG status is NOT the DROP target Status 110 | 111 | } else if (updatedStatus == this.newStatus) { 112 | 113 | //Don't allow any record to be assigned to the New list 114 | this.showToast(this,'Drop Not Allowed','Case may not be reset as New!', 'error'); 115 | 116 | } else { 117 | 118 | //Update the DRAG SOURCE record with its new status 119 | let fieldsToSave = {}; 120 | fieldsToSave[FIELD_CASE_ID.fieldApiName] = draggedId; 121 | fieldsToSave[FIELD_CASE_STATUS.fieldApiName] = updatedStatus; 122 | const recordInput = { fields:fieldsToSave} 123 | 124 | updateRecord(recordInput) 125 | .then(() => { 126 | //Force a refresh of all bound lists 127 | refreshApex(this.caseListAll); 128 | }) 129 | .catch(error => { 130 | //Notify any error 131 | this.showToast(this,'Error Updating Record', error.body.message, 'error'); 132 | }); 133 | } 134 | } 135 | 136 | //Notification utility function 137 | showToast = (firingComponent, toastTitle, toastBody, variant) => { 138 | const evt = new ShowToastEvent({ 139 | title: toastTitle, 140 | message: toastBody, 141 | variant: variant 142 | }); 143 | firingComponent.dispatchEvent(evt); 144 | } 145 | 146 | } -------------------------------------------------------------------------------- /force-app/main/default/lwc/casePicker/casePicker.js-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | true 5 | 6 | lightning__Tab 7 | 8 | -------------------------------------------------------------------------------- /force-app/main/default/lwc/pubsub/pubsub.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A basic pub-sub mechanism for sibling component communication 3 | * 4 | * TODO - adopt standard flexipage sibling communication mechanism when it's available. 5 | */ 6 | 7 | const events = {}; 8 | 9 | /** 10 | * Confirm that two page references have the same attributes 11 | * @param {object} pageRef1 - The first page reference 12 | * @param {object} pageRef2 - The second page reference 13 | */ 14 | const samePageRef = (pageRef1, pageRef2) => { 15 | const obj1 = pageRef1.attributes; 16 | const obj2 = pageRef2.attributes; 17 | return Object.keys(obj1) 18 | .concat(Object.keys(obj2)) 19 | .every(key => { 20 | return obj1[key] === obj2[key]; 21 | }); 22 | }; 23 | 24 | /** 25 | * Registers a callback for an event 26 | * @param {string} eventName - Name of the event to listen for. 27 | * @param {function} callback - Function to invoke when said event is fired. 28 | * @param {object} thisArg - The value to be passed as the this parameter to the callback function is bound. 29 | */ 30 | const registerListener = (eventName, callback, thisArg) => { 31 | // Checking that the listener has a pageRef property. We rely on that property for filtering purpose in fireEvent() 32 | if (!thisArg.pageRef) { 33 | throw new Error( 34 | 'pubsub listeners need a "@wire(CurrentPageReference) pageRef" property' 35 | ); 36 | } 37 | 38 | if (!events[eventName]) { 39 | events[eventName] = []; 40 | } 41 | const duplicate = events[eventName].find(listener => { 42 | return listener.callback === callback && listener.thisArg === thisArg; 43 | }); 44 | if (!duplicate) { 45 | events[eventName].push({ callback, thisArg }); 46 | } 47 | }; 48 | 49 | /** 50 | * Unregisters a callback for an event 51 | * @param {string} eventName - Name of the event to unregister from. 52 | * @param {function} callback - Function to unregister. 53 | * @param {object} thisArg - The value to be passed as the this parameter to the callback function is bound. 54 | */ 55 | const unregisterListener = (eventName, callback, thisArg) => { 56 | if (events[eventName]) { 57 | events[eventName] = events[eventName].filter( 58 | listener => 59 | listener.callback !== callback || listener.thisArg !== thisArg 60 | ); 61 | } 62 | }; 63 | 64 | /** 65 | * Unregisters all event listeners bound to an object. 66 | * @param {object} thisArg - All the callbacks bound to this object will be removed. 67 | */ 68 | const unregisterAllListeners = thisArg => { 69 | Object.keys(events).forEach(eventName => { 70 | events[eventName] = events[eventName].filter( 71 | listener => listener.thisArg !== thisArg 72 | ); 73 | }); 74 | }; 75 | 76 | /** 77 | * Fires an event to listeners. 78 | * @param {object} pageRef - Reference of the page that represents the event scope. 79 | * @param {string} eventName - Name of the event to fire. 80 | * @param {*} payload - Payload of the event to fire. 81 | */ 82 | const fireEvent = (pageRef, eventName, payload) => { 83 | if (events[eventName]) { 84 | const listeners = events[eventName]; 85 | listeners.forEach(listener => { 86 | if (samePageRef(pageRef, listener.thisArg.pageRef)) { 87 | try { 88 | listener.callback.call(listener.thisArg, payload); 89 | } catch (error) { 90 | // fail silently 91 | } 92 | } 93 | }); 94 | } 95 | }; 96 | 97 | export { 98 | registerListener, 99 | unregisterListener, 100 | unregisterAllListeners, 101 | fireEvent 102 | }; -------------------------------------------------------------------------------- /force-app/main/default/lwc/pubsub/pubsub.js-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | false 5 | -------------------------------------------------------------------------------- /force-app/main/default/objects/Account/listViews/All_Accounts.listView-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | All_Accounts 4 | ACCOUNT.NAME 5 | ACCOUNT.SITE 6 | ACCOUNT.ADDRESS1_STATE 7 | ACCOUNT.PHONE1 8 | ACCOUNT.TYPE 9 | CORE.USERS.ALIAS 10 | Mine 11 | All Accounts 12 | 13 | -------------------------------------------------------------------------------- /force-app/main/default/objects/Case/listViews/All_Cases.listView-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | All_Cases 4 | CASES.CASE_NUMBER 5 | NAME 6 | CASES.SUBJECT 7 | CASES.STATUS 8 | CASES.PRIORITY 9 | CORE.USERS.ALIAS 10 | Everything 11 | All Cases 12 | 13 | -------------------------------------------------------------------------------- /force-app/main/default/objects/Contact/listViews/All_Contacts.listView-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | All_Contacts 4 | FULL_NAME 5 | ACCOUNT.NAME 6 | CONTACT.PHONE1 7 | CONTACT.EMAIL 8 | CONTACT.TITLE 9 | CORE.USERS.ALIAS 10 | Mine 11 | All Contacts 12 | 13 | -------------------------------------------------------------------------------- /force-app/main/default/objects/Lead/listViews/All_Leads.listView-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | All_Leads 4 | FULL_NAME 5 | LEAD.EMAIL 6 | LEAD.COMPANY 7 | LEAD.STATE 8 | LEAD.STATUS 9 | LEAD.UNREAD 10 | LEAD.CREATED_DATE 11 | CORE.USERS.ALIAS 12 | Mine 13 | All Leads 14 | 15 | -------------------------------------------------------------------------------- /force-app/main/default/pages/DragAndDropHTMLDemo.page: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | New 33 | 34 | 39 | 40 | 41 | 43 | Working 44 | 45 | 46 | 47 | 49 | Escalated 50 | 51 | 52 | 53 | 54 | 55 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /force-app/main/default/pages/DragAndDropHTMLDemo.page-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 48.0 4 | false 5 | false 6 | DragAndDropHTMLDemo 7 | 8 | 1 9 | 19 10 | sf_chttr_apps 11 | 12 | 13 | -------------------------------------------------------------------------------- /force-app/main/default/profiles/Admin.profile-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Drag_and_Drop 5 | false 6 | true 7 | 8 | 9 | AccountsData 10 | true 11 | 12 | 13 | CasePicker 14 | true 15 | 16 | 17 | CasesData 18 | true 19 | 20 | 21 | ContactsData 22 | true 23 | 24 | 25 | LeadsData 26 | true 27 | 28 | 29 | LoadData 30 | true 31 | 32 | false 33 | 34 | DragAndDropHTMLDemo 35 | true 36 | 37 | 38 | Case_Picker_App 39 | DefaultOn 40 | 41 | 42 | Case_Picker_Demo 43 | DefaultOn 44 | 45 | 46 | HTML_Standard_DnD_Example 47 | DefaultOn 48 | 49 | Salesforce 50 | 51 | true 52 | ActivateContract 53 | 54 | 55 | true 56 | ActivateOrder 57 | 58 | 59 | true 60 | ActivitiesAccess 61 | 62 | 63 | true 64 | AddDirectMessageMembers 65 | 66 | 67 | true 68 | AllowUniversalSearch 69 | 70 | 71 | true 72 | AllowViewKnowledge 73 | 74 | 75 | true 76 | ApexRestServices 77 | 78 | 79 | true 80 | ApiEnabled 81 | 82 | 83 | true 84 | AssignPermissionSets 85 | 86 | 87 | true 88 | AssignTopics 89 | 90 | 91 | true 92 | AuthorApex 93 | 94 | 95 | true 96 | BulkMacrosAllowed 97 | 98 | 99 | true 100 | CanInsertFeedSystemFields 101 | 102 | 103 | true 104 | CanUseNewDashboardBuilder 105 | 106 | 107 | true 108 | CanVerifyComment 109 | 110 | 111 | true 112 | ChangeDashboardColors 113 | 114 | 115 | true 116 | ChatterEditOwnPost 117 | 118 | 119 | true 120 | ChatterEditOwnRecordPost 121 | 122 | 123 | true 124 | ChatterFileLink 125 | 126 | 127 | true 128 | ChatterInternalUser 129 | 130 | 131 | true 132 | ChatterInviteExternalUsers 133 | 134 | 135 | true 136 | ChatterOwnGroups 137 | 138 | 139 | true 140 | ConnectOrgToEnvironmentHub 141 | 142 | 143 | true 144 | ConsentApiUpdate 145 | 146 | 147 | true 148 | ContentAdministrator 149 | 150 | 151 | true 152 | ContentWorkspaces 153 | 154 | 155 | true 156 | ConvertLeads 157 | 158 | 159 | true 160 | CreateCustomizeDashboards 161 | 162 | 163 | true 164 | CreateCustomizeFilters 165 | 166 | 167 | true 168 | CreateCustomizeReports 169 | 170 | 171 | true 172 | CreateDashboardFolders 173 | 174 | 175 | true 176 | CreateLtngTempFolder 177 | 178 | 179 | true 180 | CreateReportFolders 181 | 182 | 183 | true 184 | CreateTopics 185 | 186 | 187 | true 188 | CreateWorkBadgeDefinition 189 | 190 | 191 | true 192 | CreateWorkspaces 193 | 194 | 195 | true 196 | CustomizeApplication 197 | 198 | 199 | true 200 | DataExport 201 | 202 | 203 | true 204 | DelegatedTwoFactor 205 | 206 | 207 | true 208 | DeleteActivatedContract 209 | 210 | 211 | true 212 | DeleteTopics 213 | 214 | 215 | true 216 | DistributeFromPersWksp 217 | 218 | 219 | true 220 | EditActivatedOrders 221 | 222 | 223 | true 224 | EditBrandTemplates 225 | 226 | 227 | true 228 | EditCaseComments 229 | 230 | 231 | true 232 | EditEvent 233 | 234 | 235 | true 236 | EditHtmlTemplates 237 | 238 | 239 | true 240 | EditKnowledge 241 | 242 | 243 | true 244 | EditMyDashboards 245 | 246 | 247 | true 248 | EditMyReports 249 | 250 | 251 | true 252 | EditOppLineItemUnitPrice 253 | 254 | 255 | true 256 | EditPublicDocuments 257 | 258 | 259 | true 260 | EditPublicFilters 261 | 262 | 263 | true 264 | EditPublicTemplates 265 | 266 | 267 | true 268 | EditReadonlyFields 269 | 270 | 271 | true 272 | EditTask 273 | 274 | 275 | true 276 | EditTopics 277 | 278 | 279 | true 280 | EmailMass 281 | 282 | 283 | true 284 | EmailSingle 285 | 286 | 287 | true 288 | EnableCommunityAppLauncher 289 | 290 | 291 | true 292 | EnableNotifications 293 | 294 | 295 | true 296 | ExportReport 297 | 298 | 299 | true 300 | FieldServiceAccess 301 | 302 | 303 | true 304 | GiveRecognitionBadge 305 | 306 | 307 | true 308 | ImportCustomObjects 309 | 310 | 311 | true 312 | ImportLeads 313 | 314 | 315 | true 316 | ImportPersonal 317 | 318 | 319 | true 320 | InstallPackaging 321 | 322 | 323 | true 324 | LightningConsoleAllowedForUser 325 | 326 | 327 | true 328 | LightningExperienceUser 329 | 330 | 331 | true 332 | ListEmailSend 333 | 334 | 335 | true 336 | ManageAnalyticSnapshots 337 | 338 | 339 | true 340 | ManageAuthProviders 341 | 342 | 343 | true 344 | ManageBusinessHourHolidays 345 | 346 | 347 | true 348 | ManageCMS 349 | 350 | 351 | true 352 | ManageCallCenters 353 | 354 | 355 | true 356 | ManageCases 357 | 358 | 359 | true 360 | ManageCategories 361 | 362 | 363 | true 364 | ManageCertificates 365 | 366 | 367 | true 368 | ManageContentPermissions 369 | 370 | 371 | true 372 | ManageContentProperties 373 | 374 | 375 | true 376 | ManageContentTypes 377 | 378 | 379 | true 380 | ManageCustomPermissions 381 | 382 | 383 | true 384 | ManageCustomReportTypes 385 | 386 | 387 | true 388 | ManageDashbdsInPubFolders 389 | 390 | 391 | true 392 | ManageDataCategories 393 | 394 | 395 | true 396 | ManageDataIntegrations 397 | 398 | 399 | true 400 | ManageDynamicDashboards 401 | 402 | 403 | true 404 | ManageEmailClientConfig 405 | 406 | 407 | true 408 | ManageExchangeConfig 409 | 410 | 411 | true 412 | ManageHealthCheck 413 | 414 | 415 | true 416 | ManageHubConnections 417 | 418 | 419 | true 420 | ManageInteraction 421 | 422 | 423 | true 424 | ManageInternalUsers 425 | 426 | 427 | true 428 | ManageIpAddresses 429 | 430 | 431 | true 432 | ManageKnowledge 433 | 434 | 435 | true 436 | ManageKnowledgeImportExport 437 | 438 | 439 | true 440 | ManageLeads 441 | 442 | 443 | true 444 | ManageLoginAccessPolicies 445 | 446 | 447 | true 448 | ManageMobile 449 | 450 | 451 | true 452 | ManageNetworks 453 | 454 | 455 | true 456 | ManagePackageLicenses 457 | 458 | 459 | true 460 | ManagePasswordPolicies 461 | 462 | 463 | true 464 | ManageProfilesPermissionsets 465 | 466 | 467 | true 468 | ManagePropositions 469 | 470 | 471 | true 472 | ManagePvtRptsAndDashbds 473 | 474 | 475 | true 476 | ManageRecommendationStrategies 477 | 478 | 479 | true 480 | ManageRemoteAccess 481 | 482 | 483 | true 484 | ManageReportsInPubFolders 485 | 486 | 487 | true 488 | ManageRoles 489 | 490 | 491 | true 492 | ManageSearchPromotionRules 493 | 494 | 495 | true 496 | ManageSharing 497 | 498 | 499 | true 500 | ManageSolutions 501 | 502 | 503 | true 504 | ManageSubscriptions 505 | 506 | 507 | true 508 | ManageSynonyms 509 | 510 | 511 | true 512 | ManageUnlistedGroups 513 | 514 | 515 | true 516 | ManageUsers 517 | 518 | 519 | true 520 | MassInlineEdit 521 | 522 | 523 | true 524 | MergeTopics 525 | 526 | 527 | true 528 | ModerateChatter 529 | 530 | 531 | true 532 | ModifyAllData 533 | 534 | 535 | true 536 | ModifyDataClassification 537 | 538 | 539 | true 540 | ModifyMetadata 541 | 542 | 543 | true 544 | NewReportBuilder 545 | 546 | 547 | true 548 | Packaging2 549 | 550 | 551 | true 552 | PrivacyDataAccess 553 | 554 | 555 | true 556 | RemoveDirectMessageMembers 557 | 558 | 559 | true 560 | ResetPasswords 561 | 562 | 563 | true 564 | RunReports 565 | 566 | 567 | true 568 | ScheduleReports 569 | 570 | 571 | true 572 | SelectFilesFromSalesforce 573 | 574 | 575 | true 576 | SendExternalEmailAvailable 577 | 578 | 579 | true 580 | SendSitRequests 581 | 582 | 583 | true 584 | ShareInternalArticles 585 | 586 | 587 | true 588 | ShowCompanyNameAsUserBadge 589 | 590 | 591 | true 592 | SolutionImport 593 | 594 | 595 | true 596 | SubmitMacrosAllowed 597 | 598 | 599 | true 600 | SubscribeDashboardRolesGrps 601 | 602 | 603 | true 604 | SubscribeDashboardToOtherUsers 605 | 606 | 607 | true 608 | SubscribeReportRolesGrps 609 | 610 | 611 | true 612 | SubscribeReportToOtherUsers 613 | 614 | 615 | true 616 | SubscribeReportsRunAsUser 617 | 618 | 619 | true 620 | SubscribeToLightningDashboards 621 | 622 | 623 | true 624 | SubscribeToLightningReports 625 | 626 | 627 | true 628 | TransactionalEmailSend 629 | 630 | 631 | true 632 | TransferAnyCase 633 | 634 | 635 | true 636 | TransferAnyEntity 637 | 638 | 639 | true 640 | TransferAnyLead 641 | 642 | 643 | true 644 | UseTeamReassignWizards 645 | 646 | 647 | true 648 | UseWebLink 649 | 650 | 651 | true 652 | ViewAllData 653 | 654 | 655 | true 656 | ViewAllUsers 657 | 658 | 659 | true 660 | ViewDataAssessment 661 | 662 | 663 | true 664 | ViewDataCategories 665 | 666 | 667 | true 668 | ViewDataLeakageEvents 669 | 670 | 671 | true 672 | ViewEventLogFiles 673 | 674 | 675 | true 676 | ViewFlowUsageAndFlowEventData 677 | 678 | 679 | true 680 | ViewHealthCheck 681 | 682 | 683 | true 684 | ViewHelpLink 685 | 686 | 687 | true 688 | ViewMyTeamsDashboards 689 | 690 | 691 | true 692 | ViewPublicDashboards 693 | 694 | 695 | true 696 | ViewPublicReports 697 | 698 | 699 | true 700 | ViewRoles 701 | 702 | 703 | true 704 | ViewSetup 705 | 706 | 707 | true 708 | WorkCalibrationUser 709 | 710 | 711 | -------------------------------------------------------------------------------- /force-app/main/default/profiles/Custom%3A Marketing Profile.profile-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Drag_and_Drop 5 | false 6 | false 7 | 8 | 9 | AccountsData 10 | false 11 | 12 | 13 | CasePicker 14 | false 15 | 16 | 17 | CasesData 18 | false 19 | 20 | 21 | ContactsData 22 | false 23 | 24 | 25 | LeadsData 26 | false 27 | 28 | 29 | LoadData 30 | false 31 | 32 | true 33 | 34 | DragAndDropHTMLDemo 35 | false 36 | 37 | 38 | Case_Picker_App 39 | DefaultOn 40 | 41 | 42 | Case_Picker_Demo 43 | DefaultOn 44 | 45 | 46 | HTML_Standard_DnD_Example 47 | DefaultOn 48 | 49 | Salesforce 50 | 51 | true 52 | ActivitiesAccess 53 | 54 | 55 | true 56 | AllowViewKnowledge 57 | 58 | 59 | true 60 | ApexRestServices 61 | 62 | 63 | true 64 | ApiEnabled 65 | 66 | 67 | true 68 | AssignTopics 69 | 70 | 71 | true 72 | ChatterInternalUser 73 | 74 | 75 | true 76 | ChatterInviteExternalUsers 77 | 78 | 79 | true 80 | ChatterOwnGroups 81 | 82 | 83 | true 84 | ConvertLeads 85 | 86 | 87 | true 88 | CreateCustomizeFilters 89 | 90 | 91 | true 92 | CreateCustomizeReports 93 | 94 | 95 | true 96 | CreateTopics 97 | 98 | 99 | true 100 | DistributeFromPersWksp 101 | 102 | 103 | true 104 | EditEvent 105 | 106 | 107 | true 108 | EditOppLineItemUnitPrice 109 | 110 | 111 | true 112 | EditTask 113 | 114 | 115 | true 116 | EditTopics 117 | 118 | 119 | true 120 | EmailMass 121 | 122 | 123 | true 124 | EmailSingle 125 | 126 | 127 | true 128 | EnableNotifications 129 | 130 | 131 | true 132 | ExportReport 133 | 134 | 135 | true 136 | ImportPersonal 137 | 138 | 139 | true 140 | LightningConsoleAllowedForUser 141 | 142 | 143 | true 144 | ListEmailSend 145 | 146 | 147 | true 148 | ManageEncryptionKeys 149 | 150 | 151 | true 152 | RunReports 153 | 154 | 155 | true 156 | SelectFilesFromSalesforce 157 | 158 | 159 | true 160 | SendSitRequests 161 | 162 | 163 | true 164 | ShowCompanyNameAsUserBadge 165 | 166 | 167 | true 168 | SubmitMacrosAllowed 169 | 170 | 171 | true 172 | SubscribeToLightningReports 173 | 174 | 175 | true 176 | TransactionalEmailSend 177 | 178 | 179 | true 180 | UseWebLink 181 | 182 | 183 | true 184 | ViewEventLogFiles 185 | 186 | 187 | true 188 | ViewHelpLink 189 | 190 | 191 | true 192 | ViewRoles 193 | 194 | 195 | true 196 | ViewSetup 197 | 198 | 199 | -------------------------------------------------------------------------------- /force-app/main/default/profiles/Custom%3A Sales Profile.profile-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Drag_and_Drop 5 | false 6 | false 7 | 8 | 9 | AccountsData 10 | false 11 | 12 | 13 | CasePicker 14 | false 15 | 16 | 17 | CasesData 18 | false 19 | 20 | 21 | ContactsData 22 | false 23 | 24 | 25 | LeadsData 26 | false 27 | 28 | 29 | LoadData 30 | false 31 | 32 | true 33 | 34 | DragAndDropHTMLDemo 35 | false 36 | 37 | 38 | Case_Picker_App 39 | DefaultOn 40 | 41 | 42 | Case_Picker_Demo 43 | DefaultOn 44 | 45 | 46 | HTML_Standard_DnD_Example 47 | DefaultOn 48 | 49 | Salesforce 50 | 51 | true 52 | ActivitiesAccess 53 | 54 | 55 | true 56 | AllowViewKnowledge 57 | 58 | 59 | true 60 | ApexRestServices 61 | 62 | 63 | true 64 | ApiEnabled 65 | 66 | 67 | true 68 | AssignTopics 69 | 70 | 71 | true 72 | ChatterInternalUser 73 | 74 | 75 | true 76 | ChatterInviteExternalUsers 77 | 78 | 79 | true 80 | ChatterOwnGroups 81 | 82 | 83 | true 84 | ConvertLeads 85 | 86 | 87 | true 88 | CreateCustomizeFilters 89 | 90 | 91 | true 92 | CreateCustomizeReports 93 | 94 | 95 | true 96 | CreateTopics 97 | 98 | 99 | true 100 | DistributeFromPersWksp 101 | 102 | 103 | true 104 | EditEvent 105 | 106 | 107 | true 108 | EditOppLineItemUnitPrice 109 | 110 | 111 | true 112 | EditTask 113 | 114 | 115 | true 116 | EditTopics 117 | 118 | 119 | true 120 | EmailMass 121 | 122 | 123 | true 124 | EmailSingle 125 | 126 | 127 | true 128 | EnableNotifications 129 | 130 | 131 | true 132 | ExportReport 133 | 134 | 135 | true 136 | ImportPersonal 137 | 138 | 139 | true 140 | LightningConsoleAllowedForUser 141 | 142 | 143 | true 144 | ListEmailSend 145 | 146 | 147 | true 148 | ManageEncryptionKeys 149 | 150 | 151 | true 152 | RunReports 153 | 154 | 155 | true 156 | SelectFilesFromSalesforce 157 | 158 | 159 | true 160 | SendSitRequests 161 | 162 | 163 | true 164 | ShowCompanyNameAsUserBadge 165 | 166 | 167 | true 168 | SubmitMacrosAllowed 169 | 170 | 171 | true 172 | SubscribeToLightningReports 173 | 174 | 175 | true 176 | TransactionalEmailSend 177 | 178 | 179 | true 180 | UseWebLink 181 | 182 | 183 | true 184 | ViewEventLogFiles 185 | 186 | 187 | true 188 | ViewHelpLink 189 | 190 | 191 | true 192 | ViewRoles 193 | 194 | 195 | true 196 | ViewSetup 197 | 198 | 199 | -------------------------------------------------------------------------------- /force-app/main/default/profiles/Custom%3A Support Profile.profile-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Drag_and_Drop 5 | false 6 | false 7 | 8 | 9 | AccountsData 10 | false 11 | 12 | 13 | CasePicker 14 | false 15 | 16 | 17 | CasesData 18 | false 19 | 20 | 21 | ContactsData 22 | false 23 | 24 | 25 | LeadsData 26 | false 27 | 28 | 29 | LoadData 30 | false 31 | 32 | true 33 | 34 | DragAndDropHTMLDemo 35 | false 36 | 37 | 38 | Case_Picker_App 39 | DefaultOn 40 | 41 | 42 | Case_Picker_Demo 43 | DefaultOn 44 | 45 | 46 | HTML_Standard_DnD_Example 47 | DefaultOn 48 | 49 | Salesforce 50 | 51 | true 52 | ActivitiesAccess 53 | 54 | 55 | true 56 | AllowViewKnowledge 57 | 58 | 59 | true 60 | ApexRestServices 61 | 62 | 63 | true 64 | ApiEnabled 65 | 66 | 67 | true 68 | AssignTopics 69 | 70 | 71 | true 72 | ChatterInternalUser 73 | 74 | 75 | true 76 | ChatterInviteExternalUsers 77 | 78 | 79 | true 80 | ChatterOwnGroups 81 | 82 | 83 | true 84 | ConvertLeads 85 | 86 | 87 | true 88 | CreateCustomizeFilters 89 | 90 | 91 | true 92 | CreateCustomizeReports 93 | 94 | 95 | true 96 | CreateTopics 97 | 98 | 99 | true 100 | DistributeFromPersWksp 101 | 102 | 103 | true 104 | EditEvent 105 | 106 | 107 | true 108 | EditOppLineItemUnitPrice 109 | 110 | 111 | true 112 | EditTask 113 | 114 | 115 | true 116 | EditTopics 117 | 118 | 119 | true 120 | EmailMass 121 | 122 | 123 | true 124 | EmailSingle 125 | 126 | 127 | true 128 | EnableNotifications 129 | 130 | 131 | true 132 | ExportReport 133 | 134 | 135 | true 136 | ImportPersonal 137 | 138 | 139 | true 140 | LightningConsoleAllowedForUser 141 | 142 | 143 | true 144 | ListEmailSend 145 | 146 | 147 | true 148 | ManageCases 149 | 150 | 151 | true 152 | ManageEncryptionKeys 153 | 154 | 155 | true 156 | ManageSolutions 157 | 158 | 159 | true 160 | RunReports 161 | 162 | 163 | true 164 | SelectFilesFromSalesforce 165 | 166 | 167 | true 168 | SendSitRequests 169 | 170 | 171 | true 172 | ShowCompanyNameAsUserBadge 173 | 174 | 175 | true 176 | SubmitMacrosAllowed 177 | 178 | 179 | true 180 | SubscribeToLightningReports 181 | 182 | 183 | true 184 | TransactionalEmailSend 185 | 186 | 187 | true 188 | TransferAnyCase 189 | 190 | 191 | true 192 | UseWebLink 193 | 194 | 195 | true 196 | ViewEventLogFiles 197 | 198 | 199 | true 200 | ViewHelpLink 201 | 202 | 203 | true 204 | ViewRoles 205 | 206 | 207 | true 208 | ViewSetup 209 | 210 | 211 | -------------------------------------------------------------------------------- /force-app/main/default/staticresources/case.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/forcementor/lwc-dnd-demos/102d9ba61a3b172322e6fa52fc606826f416570c/force-app/main/default/staticresources/case.png -------------------------------------------------------------------------------- /force-app/main/default/staticresources/case.resource-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Private 4 | image/png 5 | Case image 6 | 7 | -------------------------------------------------------------------------------- /force-app/main/default/tabs/Case_Picker_App.tab-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Created by Lightning App Builder 4 | Case_Picker_App 5 | Case Picker (Loosely Coupled) 6 | Custom86: Red Cross 7 | 8 | -------------------------------------------------------------------------------- /force-app/main/default/tabs/Case_Picker_Demo.tab-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Case Picker (Tightly Coupled) 4 | casePicker 5 | Custom94: Stethoscope 6 | 7 | -------------------------------------------------------------------------------- /force-app/main/default/tabs/HTML_Standard_DnD_Example.tab-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | HTML Standard DnD Example 4 | Custom9: Lightning 5 | DragAndDropHTMLDemo 6 | 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "salesforce-app", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "Salesforce LWC Drag andf Drop Demos", 6 | "scripts": { 7 | "lint": "npm run lint:lwc", 8 | "lint:lwc": "eslint force-app/main/default/lwc", 9 | "test": "npm run test:unit", 10 | "test:unit": "sfdx-lwc-jest", 11 | "test:unit:watch": "sfdx-lwc-jest --watch", 12 | "test:unit:debug": "sfdx-lwc-jest --debug", 13 | "test:unit:coverage": "sfdx-lwc-jest --coverage", 14 | "prettier": "prettier --write \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"", 15 | "prettier:verify": "prettier --list-different \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"" 16 | }, 17 | "devDependencies": { 18 | "@prettier/plugin-xml": "^0.7.0", 19 | "@salesforce/eslint-config-lwc": "^0.4.0", 20 | "@salesforce/sfdx-lwc-jest": "^0.7.0", 21 | "eslint": "^5.16.0", 22 | "prettier": "^1.19.1", 23 | "prettier-plugin-apex": "^1.0.0" 24 | } 25 | } -------------------------------------------------------------------------------- /scripts/CreateOrg.sh: -------------------------------------------------------------------------------- 1 | # Execute in Mac using: ./scripts/CreateOrg.sh 2 | echo "*** Creating scratch Org..." 3 | sfdx force:org:create -f config/project-scratch-def.json --setdefaultusername --setalias soDnD -d 30 4 | echo "*** Pushing metadata to scratch Org..." 5 | sfdx force:source:push 6 | echo "*** Push data to scratch Org..." 7 | sfdx force:apex:execute -f ./scripts/ResetData.txt 8 | echo "*** Opening scratch Org..." 9 | sfdx force:org:open --path "/lightning/n/HTML_Standard_DnD_Example" -------------------------------------------------------------------------------- /scripts/ResetData.txt: -------------------------------------------------------------------------------- 1 | LoadData.clearData(); 2 | LoadData.buildData(); -------------------------------------------------------------------------------- /sfdx-project.json: -------------------------------------------------------------------------------- 1 | { 2 | "packageDirectories": [ 3 | { 4 | "path": "force-app", 5 | "default": true 6 | } 7 | ], 8 | "namespace": "", 9 | "sfdcLoginUrl": "https://login.salesforce.com", 10 | "sourceApiVersion": "48.0" 11 | } --------------------------------------------------------------------------------
Status: {caseRecord.Status}
Priority: {caseRecord.Priority}
Id: {caseRecord.Id}