From 4aa7f52b561cb89e9fb221571810660cc3b97e7e Mon Sep 17 00:00:00 2001 From: Igor Androsov Date: Tue, 26 Dec 2023 15:46:03 +0900 Subject: [PATCH] Add grant selector to editor for USer changing grant app without navigation to tabs --- .../default/classes/GGW_ApplicationCtrl.cls | 480 +++++++++--------- .../classes/GGW_ApplicationSelector.cls | 27 + .../GGW_ApplicationSelector.cls-meta.xml | 5 + .../classes/GGW_ApplicationSelectorTest.cls | 67 +++ .../GGW_ApplicationSelectorTest.cls-meta.xml | 5 + .../main/default/classes/GGW_ExportCtrl.cls | 2 +- force-app/main/default/classes/GGW_Util.cls | 6 - .../main/default/classes/GGW_UtilTest.cls | 18 - .../ggwGrantApplication.html | 12 + .../ggwGrantApplication.js | 29 +- 10 files changed, 371 insertions(+), 280 deletions(-) create mode 100644 force-app/main/default/classes/GGW_ApplicationSelector.cls create mode 100644 force-app/main/default/classes/GGW_ApplicationSelector.cls-meta.xml create mode 100644 force-app/main/default/classes/GGW_ApplicationSelectorTest.cls create mode 100644 force-app/main/default/classes/GGW_ApplicationSelectorTest.cls-meta.xml diff --git a/force-app/main/default/classes/GGW_ApplicationCtrl.cls b/force-app/main/default/classes/GGW_ApplicationCtrl.cls index c9df4bf..768f443 100644 --- a/force-app/main/default/classes/GGW_ApplicationCtrl.cls +++ b/force-app/main/default/classes/GGW_ApplicationCtrl.cls @@ -10,14 +10,14 @@ public without sharing class GGW_ApplicationCtrl { public static String ggGtSteObj = GGW_Grant_State__c.sobjecttype.getDescribe().getName(); public static String ggGtStLanField = GGW_Grant_State__c.Language__c.getDescribe().getName(); - + // -- START LWC CONtroller Methods // Return Grant Aplication Wrapper object @AuraEnabled public static GGW_GrantApplicationWrapper getApplication(String recordId){ String tempId = validateAppId(recordId); List appItems = querySelectedItemsByGrant(tempId); - GGW_Grant_Application__c grant = GGW_Util.queryGrantApp(tempId); + GGW_Grant_Application__c grant = GGW_ApplicationSelector.queryGrantApp(tempId); // Save current app state GGW_Util.saveGrantState(tempId); @@ -33,6 +33,10 @@ public without sharing class GGW_ApplicationCtrl { } return app; } + @AuraEnabled (cacheable=true) + public static List getApplicationList(){ + return GGW_ApplicationSelector.getGrantApplications(); + } // Delete logo file from grant @AuraEnabled public static String deleteLogo(String recordId){ @@ -60,7 +64,226 @@ public without sharing class GGW_ApplicationCtrl { } return 'Application logo updated'; } + /** + * Creating ContentDistribution record + * parameter: contentVersionId + * response return URL image + * + * SELECT Id, LinkedEntityId, ContentDocumentId, ShareType, Visibility FROM ContentDocumentLink WHERE LinkedEntityId = 'a010R00000FYjbAQAT' + SELECT Id, ContentDocumentId, Title FROM ContentVersion WHERE ContentDocumentId = '0690R000001qBEgQAM' + */ + @AuraEnabled + public static String createContentDistribution(String grantId, String cvid){ + ContentVersion file = getContentFile(cvid); + // Creating ContentDistribution record + ContentDistribution cdr = insertContentDistribution(file); + if(cdr.Id == null){ + return null; // could not insert ContentDistribution no CRUD + } + // After Distribution record need to get DistributionPublicUrl, ContentDownloadUrl + // and update Grant record to use these for display + ContentDistribution cdURL = getContentDistributionById(cdr.Id); + System.debug('## ContentDownloadUrl:'+cdURL.ContentDownloadUrl); + System.debug('## DistributionPublicUrl: '+cdURL.DistributionPublicUrl); + // Update Grant with new logo + updateGrantAppLogoURL(grantId, cdURL); + + return cdURL.ContentDownloadUrl; + } + /** + * Update text block selection, wire block to item and copy block text data for display and edits + * + */ + @AuraEnabled + public static void saveSelectedSectionText(String itemid, String blockid){ + GGW_Content_Block__c cBlock = queryContentBlockById(blockid); + // Construct selected Item to update + GGW_Selected_Item__c item = new GGW_Selected_Item__c(); + item.Id = itemid; + item.Selected_Block__c = blockid; + item.Text_Block__c = cBlock.Description__c; // Copy rich text from block to item for edits + if(Schema.sObjectType.GGW_Selected_Item__c.isUpdateable()){ + update item; + } + } + /** + * Create new section on Grant landing home page component + * with defaulted values of Sugested and recommended. + * Assumption user needs new section on Grant that do not exist yet, this is + * general section NOT related yet to Grant record. + */ + @AuraEnabled + public static GGW_SectionWrapper createNewSection(String name){ + GGW_Section__c maxOrder = findMaxOrderSection(); + GGW_Section__c s = new GGW_Section__c(); + s.Name = name; + s.Recommended__c = true; + s.Suggested__c = true; + s.Language__c = GGW_Util.getGrantLanguage(); + s.Sort_Order__c = getSectionSortOrder(maxOrder); + if(Schema.sObjectType.GGW_Section__c.isCreateable()){ + insert s; + } + return new GGW_SectionWrapper(s); + } + // Edit rich text inside item method called from Section component when edit rich text + @AuraEnabled + public static void updateSelectedItemText(String itemid, String richtext){ + GGW_Selected_Item__c item = new GGW_Selected_Item__c(); + item.Id = itemid; + item.Text_Block__c = richtext; // Update rich text from block to item on edit button click + if(Schema.sObjectType.GGW_Selected_Item__c.isUpdateable()){ + update item; + } + } + // Delete Section as selected item junction for grant - remoes a section + @AuraEnabled + public static void deleteSection(String itemId){ + GGW_Selected_Item__c item = new GGW_Selected_Item__c(); + item.Id = itemId; + if(Schema.sObjectType.GGW_Selected_Item__c.isDeletable()){ + delete item; + } + } + + @AuraEnabled + public static void reorderSections(List sectionList, String appId){ + List updateOrderList = new List(); + // Clean up items for reorder, delete items that are NOT on this list + cleanSelectedSections(sectionList, appId); + Integer cnt = 1; + for (String s : sectionList){ + + Id sectionId = s; + GGW_Selected_Item__c ggws = new GGW_Selected_Item__c(); + System.debug('### reorderSections APP ID: '+appId); + if(isSectionId(s)){ // Create new selected item junction for section + ggws.GGW_Section__c = sectionId; + System.debug('## Add new section: '+s); + }else{ // Update selected existing item junction + ggws.Id = s; + System.debug('## Update existing section: '+s); + } + + ggws.Grant_Application__c = appId; + ggws.Sort_Order__c = cnt; + updateOrderList.add(ggws); + cnt++; + } + if(Schema.sObjectType.GGW_Selected_Item__c.isUpdateable() || + Schema.sObjectType.GGW_Selected_Item__c.isCreateable()){ + upsert updateOrderList; // Some records here exist some may be new added sections + } + } + @AuraEnabled(cacheable=true) + public static List getContentBlocks(String sectionId){ + List cbwResultList = new List(); + List cbList = queryContentBlocksBySection(sectionId); + // Get map of block tags to display as badges + Map> blockTags = getBlockTopics(); + for(GGW_Content_Block__c c : cbList){ + GGW_ContentBlockWrapper cbw = new GGW_ContentBlockWrapper(c, cbList.size()); + if(blockTags.containsKey(c.Id)){ + List badgeList = blockTags.get(c.Id); + // TODO - HERE we get 1st tag string assign to display + // Only 1 badge tag shown today, this may need to be multiple Tags per block + if (badgeList.size()>0){ + cbw.displaybadge = badgeList[0]; // DEPRECATED: switch to use list + cbw.badgeList = badgeList; + } + } + cbwResultList.add(cbw); + } + return cbwResultList; + } + /** + * Create a new Grant Application record and also add all selected list of sections + * as selected items. + * Application starting point, user can add text blocks to build out thsi record + * + */ + @AuraEnabled + public static GGW_Grant_Application__c newGrant(String name, List sections){ + System.debug('## NEW GRANT Parm: '+name+' SECTIONS:'+sections); + GGW_Grant_Application__c gapp = insertGrantRecord(name); + insertSelectedItemsForGrant(gapp.Id, sections); + System.debug('## NEW GRANT: '+name+' ID:'+gapp.Id+' SECTIONS:'+sections); + return gapp; + } + /** + * Method to create a new ContentBlock add to section as part a library to later reuse + * on other Grant applications. + * + */ + @AuraEnabled + public static String addTextBlockToLibrary(String sectionid, String richtext, String name){ + GGW_Content_Block__c cb = new GGW_Content_Block__c(); + cb.name = getValidBlockName(name); // strange error Layout Field:Name must not be Readonly + cb.Section__c = sectionid; + cb.Description__c = richtext; + if(Schema.sObjectType.GGW_Content_Block__c.isCreateable()){ + insert cb; + } + return cb.Id+''; + } + // Return all Suggested section for shorter list + @AuraEnabled //(cacheable=true) + public static List getSections(){ + List swList = new List(); + String lang = GGW_Util.getGrantLanguage(); + Set setOfSectionsWithBlock = getBlocksForSection(); + List sectionList = querySectionsByLanguage(lang); + for(GGW_Section__c s : sectionList){ + GGW_SectionWrapper sw = new GGW_SectionWrapper(s,setOfSectionsWithBlock); + swList.add(sw); + } + return swList; + } + // Search any section by text key + @AuraEnabled(cacheable=true) + public static List findSections(String searchKey) { + List swList = new List(); + if(searchKey != null && searchKey.length() > 0){ + List sectionList = querySectionsByName(searchKey); + + for(GGW_Section__c s : sectionList){ + GGW_SectionWrapper sw = new GGW_SectionWrapper(s); + swList.add(sw); + } + } + return swList; + } + /** + Save user selected langauge for Grant in a Grant/User state + State record is used to store small setting selection data to drive + logic. In this case Language filtering for content. + This method is called from LWC language selector + */ + @AuraEnabled + public static String saveLanguageSelection(String lang, String appId){ + // If lang = null then User langauge SFDC setting will be used by default + return GGW_Util.saveGrantLanguage(lang, appId); + } + // app ID not used to init new grant pass it for copatible api + // This method query user selected language from state record + @AuraEnabled + public static String getLanguageSelection(String appId){ + return GGW_Util.getGrantLanguage(); + } + @AuraEnabled (cacheable=true) + public static String getLanguageSelectionForWire(String appId){ + return getApplicationLanguage(appId); + } + @AuraEnabled (cacheable=true) + public static List getSupportedLanguages(){ + return GGW_Util.getSelectOptionFromPicklist(ggGtSteObj, ggGtStLanField, false); + } + + + // -------------------------------- + // -- END LWC Controller Methods -- + // -------------------------------- private static void deleteImageLogo(String recordId){ ContentDocumentLink cdl = [SELECT Id, LinkedEntityId, ContentDocumentId, IsDeleted, Visibility, ShareType FROM ContentDocumentLink @@ -121,32 +344,6 @@ public without sharing class GGW_ApplicationCtrl { } return null; } - /** - * Creating ContentDistribution record - * parameter: contentVersionId - * response return URL image - * - * SELECT Id, LinkedEntityId, ContentDocumentId, ShareType, Visibility FROM ContentDocumentLink WHERE LinkedEntityId = 'a010R00000FYjbAQAT' - SELECT Id, ContentDocumentId, Title FROM ContentVersion WHERE ContentDocumentId = '0690R000001qBEgQAM' - */ - @AuraEnabled - public static String createContentDistribution(String grantId, String cvid){ - ContentVersion file = getContentFile(cvid); - // Creating ContentDistribution record - ContentDistribution cdr = insertContentDistribution(file); - if(cdr.Id == null){ - return null; // could not insert ContentDistribution no CRUD - } - // After Distribution record need to get DistributionPublicUrl, ContentDownloadUrl - // and update Grant record to use these for display - ContentDistribution cdURL = getContentDistributionById(cdr.Id); - System.debug('## ContentDownloadUrl:'+cdURL.ContentDownloadUrl); - System.debug('## DistributionPublicUrl: '+cdURL.DistributionPublicUrl); - // Update Grant with new logo - updateGrantAppLogoURL(grantId, cdURL); - - return cdURL.ContentDownloadUrl; - } private static void updateGrantAppLogoURL(String grantId, ContentDistribution cdURL){ // Update Grant with new logo if(cdURL.ContentDownloadUrl != null){ @@ -185,43 +382,6 @@ public without sharing class GGW_ApplicationCtrl { } return cdr; } - /** - * Update text block selection, wire block to item and copy block text data for display and edits - * - */ - @AuraEnabled - public static void saveSelectedSectionText(String itemid, String blockid){ - GGW_Content_Block__c cBlock = queryContentBlockById(blockid); - // Construct selected Item to update - GGW_Selected_Item__c item = new GGW_Selected_Item__c(); - item.Id = itemid; - item.Selected_Block__c = blockid; - item.Text_Block__c = cBlock.Description__c; // Copy rich text from block to item for edits - if(Schema.sObjectType.GGW_Selected_Item__c.isUpdateable()){ - update item; - } - } - /** - * Create new section on Grant landing home page component - * with defaulted values of Sugested and recommended. - * Assumption user needs new section on Grant that do not exist yet, this is - * general section NOT related yet to Grant record. - */ - @AuraEnabled - public static GGW_SectionWrapper createNewSection(String name){ - GGW_Section__c maxOrder = findMaxOrderSection(); - String lang = GGW_Util.getGrantLanguage(); - GGW_Section__c s = new GGW_Section__c(); - s.Name = name; - s.Recommended__c = true; - s.Suggested__c = true; - s.Language__c = lang; - s.Sort_Order__c = getSectionSortOrder(maxOrder); - if(Schema.sObjectType.GGW_Section__c.isCreateable()){ - insert s; - } - return new GGW_SectionWrapper(s); - } // Return section with max order to add next section private static GGW_Section__c findMaxOrderSection(){ List maxOrderList = [SELECT Sort_Order__c @@ -246,55 +406,6 @@ public without sharing class GGW_ApplicationCtrl { } return order; } - // Edit rich text inside item method called from Section component when edit rich text - @AuraEnabled - public static void updateSelectedItemText(String itemid, String richtext){ - GGW_Selected_Item__c item = new GGW_Selected_Item__c(); - item.Id = itemid; - item.Text_Block__c = richtext; // Update rich text from block to item on edit button click - if(Schema.sObjectType.GGW_Selected_Item__c.isUpdateable()){ - update item; - } - } - // Delete Section as selected item junction for grant - remoes a section - @AuraEnabled - public static void deleteSection(String itemId){ - GGW_Selected_Item__c item = new GGW_Selected_Item__c(); - item.Id = itemId; - if(Schema.sObjectType.GGW_Selected_Item__c.isDeletable()){ - delete item; - } - } - - @AuraEnabled - public static void reorderSections(List sectionList, String appId){ - List updateOrderList = new List(); - // Clean up items for reorder, delete items that are NOT on this list - cleanSelectedSections(sectionList, appId); - Integer cnt = 1; - for (String s : sectionList){ - - Id sectionId = s; - GGW_Selected_Item__c ggws = new GGW_Selected_Item__c(); - System.debug('### reorderSections APP ID: '+appId); - if(isSectionId(s)){ // Create new selected item junction for section - ggws.GGW_Section__c = sectionId; - System.debug('## Add new section: '+s); - }else{ // Update selected existing item junction - ggws.Id = s; - System.debug('## Update existing section: '+s); - } - - ggws.Grant_Application__c = appId; - ggws.Sort_Order__c = cnt; - updateOrderList.add(ggws); - cnt++; - } - if(Schema.sObjectType.GGW_Selected_Item__c.isUpdateable() || - Schema.sObjectType.GGW_Selected_Item__c.isCreateable()){ - upsert updateOrderList; // Some records here exist some may be new added sections - } - } // Check if giveb string ID is Id of Section record private static Boolean isSectionId(String s){ Boolean res = false; @@ -322,34 +433,7 @@ public without sharing class GGW_ApplicationCtrl { } } } - // Convert Selecetd Item to Map - NOT USED AT THIS TIME COMMENT - /** - private Map getSelectedItemsMap(String appId){ - List appItems = querySelectedItemsByGrant(appId); - Map mapGrantSelected = new Map(); - for(GGW_Selected_Item__c item : appItems){ - mapGrantSelected.put(item.Id,item); - } - return mapGrantSelected; - } - */ - /** - * Method to create a new ContentBlock add to section as part a library to later reuse - * on other Grant applications. - * - */ - @AuraEnabled - public static String addTextBlockToLibrary(String sectionid, String richtext, String name){ - GGW_Content_Block__c cb = new GGW_Content_Block__c(); - cb.name = getValidBlockName(name); // strange error Layout Field:Name must not be Readonly - cb.Section__c = sectionid; - cb.Description__c = richtext; - if(Schema.sObjectType.GGW_Content_Block__c.isCreateable()){ - insert cb; - } - return cb.Id+''; - } // Always return valid string, default block name if given name is null private static String getValidBlockName(String name){ String blockName = '[CHANGE] New Text Block'; @@ -358,19 +442,6 @@ public without sharing class GGW_ApplicationCtrl { } return blockName; } - // Return all Suggested section for shorter list - @AuraEnabled //(cacheable=true) - public static List getSections(){ - List swList = new List(); - String lang = GGW_Util.getGrantLanguage(); - Set setOfSectionsWithBlock = getBlocksForSection(); - List sectionList = querySectionsByLanguage(lang); - for(GGW_Section__c s : sectionList){ - GGW_SectionWrapper sw = new GGW_SectionWrapper(s,setOfSectionsWithBlock); - swList.add(sw); - } - return swList; - } // Return all available section in library private static List getLeftoverSections(List appItems){ List swList = new List(); @@ -395,20 +466,6 @@ public without sharing class GGW_ApplicationCtrl { } return section; } - // Search any section by text key - @AuraEnabled(cacheable=true) - public static List findSections(String searchKey) { - List swList = new List(); - if(searchKey != null && searchKey.length() > 0){ - List sectionList = querySectionsByName(searchKey); - - for(GGW_Section__c s : sectionList){ - GGW_SectionWrapper sw = new GGW_SectionWrapper(s); - swList.add(sw); - } - } - return swList; - } private static Set getBlocksForSection(){ Set s1 = new Set(); List cbList = queryContentBlocks(); @@ -418,40 +475,6 @@ public without sharing class GGW_ApplicationCtrl { return s1; } - /** DEPERCATED - * Not used method, leaving commented code for reference - private static Map> getSectionBlocks(){ - Map> blockMap = new Map>(); - List cbList = [SELECT Id, Name, Description__c, Short_Description__c, - Section__c, Section__r.Name, CreatedDate - FROM GGW_Content_Block__c ORDER BY Section__c]; - for(GGW_Content_Block__c c : cbList){ - - } - return blockMap; - } - */ - @AuraEnabled(cacheable=true) - public static List getContentBlocks(String sectionId){ - List cbwResultList = new List(); - List cbList = queryContentBlocksBySection(sectionId); - // Get map of block tags to display as badges - Map> blockTags = getBlockTopics(); - for(GGW_Content_Block__c c : cbList){ - GGW_ContentBlockWrapper cbw = new GGW_ContentBlockWrapper(c, cbList.size()); - if(blockTags.containsKey(c.Id)){ - List badgeList = blockTags.get(c.Id); - // TODO - HERE we get 1st tag string assign to display - // Only 1 badge tag shown today, this may need to be multiple Tags per block - if (badgeList.size()>0){ - cbw.displaybadge = badgeList[0]; // DEPRECATED: switch to use list - cbw.badgeList = badgeList; - } - } - cbwResultList.add(cbw); - } - return cbwResultList; - } // Query Topics for content blocks, display tags/badge for each block private static Map> getBlockTopics(){ Map> mapTags = new Map>(); @@ -467,20 +490,6 @@ public without sharing class GGW_ApplicationCtrl { return mapTags; } - /** - * Create a new Grant Application record and also add all selected list of sections - * as selected items. - * Application starting point, user can add text blocks to build out thsi record - * - */ - @AuraEnabled - public static GGW_Grant_Application__c newGrant(String name, List sections){ - System.debug('## NEW GRANT Parm: '+name+' SECTIONS:'+sections); - GGW_Grant_Application__c gapp = insertGrantRecord(name); - insertSelectedItemsForGrant(gapp.Id, sections); - System.debug('## NEW GRANT: '+name+' ID:'+gapp.Id+' SECTIONS:'+sections); - return gapp; - } private static GGW_Grant_Application__c insertGrantRecord(String name){ GGW_Grant_Application__c gapp = new GGW_Grant_Application__c(); if (GGW_Util.isValidString(name)){ @@ -509,47 +518,10 @@ public without sharing class GGW_ApplicationCtrl { insert selectedItems; } } - /** - Save user selected langauge for Grant in a Grant/User state - State record is used to store small setting selection data to drive - logic. In this case Language filtering for content. - This method is called from LWC language selector - */ - @AuraEnabled - public static String saveLanguageSelection(String lang, String appId){ - // If lang = null then User langauge SFDC setting will be used by default - return GGW_Util.saveGrantLanguage(lang, appId); - } - // app ID not used to init new grant pass it for copatible api - @AuraEnabled - public static String getLanguageSelection(String appId){ - // String lang = 'en_US'; // Default to US English code - //if(GGW_Util.isValidString(appId)){ - // lang = getApplicationLanguage(appId); - //}else{ - // lang = GGW_Util.getGrantLanguage(); - //} - return GGW_Util.getGrantLanguage(); - } - @AuraEnabled (cacheable=true) - public static String getLanguageSelectionForWire(String appId){ - ///String lang = 'en_US'; // Default to US English code - //if(GGW_Util.isValidString(appId)){ - //lang = getApplicationLanguage(appId); - //}else{ - // lang = GGW_Util.getGrantLanguage(); - //} - return getApplicationLanguage(appId); - } - - @AuraEnabled (cacheable=true) - public static List getSupportedLanguages(){ - return GGW_Util.getSelectOptionFromPicklist(ggGtSteObj, ggGtStLanField, false); - } // Get application language from existing Grant record private static String getApplicationLanguage(String appId){ String lang = 'en_US'; // Default to US English code - GGW_Grant_Application__c app = [SELECT Id, Name, Language__c FROM GGW_Grant_Application__c WHERE Id =: appId WITH SECURITY_ENFORCED LIMIT 1]; + GGW_Grant_Application__c app = GGW_ApplicationSelector.queryGrantApp(appId); if(GGW_Util.isValidString(app.Language__c)){ lang = app.Language__c; } diff --git a/force-app/main/default/classes/GGW_ApplicationSelector.cls b/force-app/main/default/classes/GGW_ApplicationSelector.cls new file mode 100644 index 0000000..a972955 --- /dev/null +++ b/force-app/main/default/classes/GGW_ApplicationSelector.cls @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + * + * GGW_ApplicationSelector SOQL Query class support GGW. + * + */ +public with sharing class GGW_ApplicationSelector { + public static List getGrantApplications(){ + return [SELECT Id, Name, Application_Name__c, Logo_Download_Url__c, + DistributionPublicUrl__c, Status__c, Description__c, + Language__c, Include_Logo__c + FROM GGW_Grant_Application__c + WITH SECURITY_ENFORCED]; + } + + public static GGW_Grant_Application__c queryGrantApp(String appId){ + return [SELECT Id, Name, Application_Name__c, Logo_Download_Url__c, + DistributionPublicUrl__c, Status__c, Description__c, + Language__c, Include_Logo__c + FROM GGW_Grant_Application__c + WHERE Id =: appId WITH SECURITY_ENFORCED LIMIT 1]; + } + +} \ No newline at end of file diff --git a/force-app/main/default/classes/GGW_ApplicationSelector.cls-meta.xml b/force-app/main/default/classes/GGW_ApplicationSelector.cls-meta.xml new file mode 100644 index 0000000..642d054 --- /dev/null +++ b/force-app/main/default/classes/GGW_ApplicationSelector.cls-meta.xml @@ -0,0 +1,5 @@ + + + 58.0 + Active + \ No newline at end of file diff --git a/force-app/main/default/classes/GGW_ApplicationSelectorTest.cls b/force-app/main/default/classes/GGW_ApplicationSelectorTest.cls new file mode 100644 index 0000000..c62d2f6 --- /dev/null +++ b/force-app/main/default/classes/GGW_ApplicationSelectorTest.cls @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2022, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + + * This class contains unit tests for validating the behavior of Apex classes + * and triggers. + * + * Unit tests are class methods that verify whether a particular piece + * of code is working properly. Unit test methods take no arguments, + * commit no data to the database, and are flagged with the testMethod + * keyword in the method definition. + * + * All test methods in an org are executed whenever Apex code is deployed + * to a production org to confirm correctness, ensure code + * coverage, and prevent regressions. All Apex classes are + * required to have at least 75% code coverage in order to be deployed + * to a production org. In addition, all triggers must have some code coverage. + * + * The @isTest class annotation indicates this class only contains test + * methods. Classes defined with the @isTest annotation do not count against + * the org size limit for all Apex scripts. + * + * See the Apex Language Reference for more information about Testing and Code Coverage. + */ +@isTest +private class GGW_ApplicationSelectorTest { + + @isTest + static void testQueryGrantApp(){ + // Query all suggested sections + List lst = GGW_ApplicationCtrl.getSections(); + List sections = new List(); + for (GGW_SectionWrapper gww : lst){ + if(gww.selected){ + sections.add(gww.recordid); + } + } + GGW_Grant_Application__c app = GGW_ApplicationCtrl.newGrant('Grant App', sections); + + Test.startTest(); + GGW_Grant_Application__c grant = GGW_ApplicationSelector.queryGrantApp(app.Id); + Test.stopTest(); + System.assertEquals(grant.Name, 'Grant App', 'Could not create a new grant application'); + + } + @isTest + static void getGrantApplicationsTest(){ + // Query all suggested sections + List lst = GGW_ApplicationCtrl.getSections(); + List sections = new List(); + for (GGW_SectionWrapper gww : lst){ + if(gww.selected){ + sections.add(gww.recordid); + } + } + // Create 2 grants with same sections top test list + GGW_ApplicationCtrl.newGrant('Grant App 1', sections); + GGW_ApplicationCtrl.newGrant('Grant App 2', sections); + + Test.startTest(); + List grantList = GGW_ApplicationSelector.getGrantApplications(); + Test.stopTest(); + System.assertEquals(2, grantList.size(), 'Query grant application invalid'); + } +} \ No newline at end of file diff --git a/force-app/main/default/classes/GGW_ApplicationSelectorTest.cls-meta.xml b/force-app/main/default/classes/GGW_ApplicationSelectorTest.cls-meta.xml new file mode 100644 index 0000000..642d054 --- /dev/null +++ b/force-app/main/default/classes/GGW_ApplicationSelectorTest.cls-meta.xml @@ -0,0 +1,5 @@ + + + 58.0 + Active + \ No newline at end of file diff --git a/force-app/main/default/classes/GGW_ExportCtrl.cls b/force-app/main/default/classes/GGW_ExportCtrl.cls index 2e464a8..16175b5 100644 --- a/force-app/main/default/classes/GGW_ExportCtrl.cls +++ b/force-app/main/default/classes/GGW_ExportCtrl.cls @@ -35,7 +35,7 @@ public without sharing class GGW_ExportCtrl { system.debug('### PDF VIew ID:'+this.recordId); this.appName = 'This view requires a Grant record, missing.'; if(this.recordId != null && this.recordId.length() > 0){ - GGW_Grant_Application__c app = GGW_Util.queryGrantApp(this.recordId.escapeHtml4()); + GGW_Grant_Application__c app = GGW_ApplicationSelector.queryGrantApp(this.recordId.escapeHtml4()); if(app != null && app.Logo_Download_Url__c != null){ this.logoURL = app.Logo_Download_Url__c; if(app.Include_Logo__c == true){ diff --git a/force-app/main/default/classes/GGW_Util.cls b/force-app/main/default/classes/GGW_Util.cls index 64fe3fd..5f24bbc 100644 --- a/force-app/main/default/classes/GGW_Util.cls +++ b/force-app/main/default/classes/GGW_Util.cls @@ -23,12 +23,6 @@ public without sharing class GGW_Util { WHERE Grant_Application__c =: appId WITH SECURITY_ENFORCED ORDER BY Sort_Order__c]; return items; } - public static GGW_Grant_Application__c queryGrantApp(String appId){ - return [SELECT Id, Name, Application_Name__c, Logo_Download_Url__c, - DistributionPublicUrl__c, Status__c, Description__c, Language__c, Include_Logo__c - FROM GGW_Grant_Application__c - WHERE Id =: appId WITH SECURITY_ENFORCED LIMIT 1]; - } public static Boolean isValidString(String str){ Boolean res = false; if(str != null && str.length() > 0){ diff --git a/force-app/main/default/classes/GGW_UtilTest.cls b/force-app/main/default/classes/GGW_UtilTest.cls index 6ad2728..c2e70c2 100644 --- a/force-app/main/default/classes/GGW_UtilTest.cls +++ b/force-app/main/default/classes/GGW_UtilTest.cls @@ -117,24 +117,6 @@ public class GGW_UtilTest { Test.stopTest(); System.assertEquals(sections.size(), lstItems.size(), 'Grant app missing selected items'); - } - @isTest - static void testQueryGrantApp(){ - // Query all suggested sections - List lst = GGW_ApplicationCtrl.getSections(); - List sections = new List(); - for (GGW_SectionWrapper gww : lst){ - if(gww.selected){ - sections.add(gww.recordid); - } - } - GGW_Grant_Application__c app = GGW_ApplicationCtrl.newGrant('Grant App', sections); - - Test.startTest(); - GGW_Grant_Application__c grant = GGW_Util.queryGrantApp(app.Id); - Test.stopTest(); - System.assertEquals(grant.Name, 'Grant App', 'Could not create a new grant application'); - } @isTest static void testSelectOptionFromPicklist(){ diff --git a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html index 3b2e938..c2f381c 100644 --- a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html +++ b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html @@ -2,6 +2,7 @@ diff --git a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js index 8be41af..8f1f98f 100644 --- a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js +++ b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js @@ -4,10 +4,11 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import { LightningElement ,wire , api, track } from "lwc"; +import { LightningElement, wire, api, track } from "lwc"; import { CloseActionScreenEvent } from 'lightning/actions'; import { CurrentPageReference, NavigationMixin } from 'lightning/navigation'; import getApplication from '@salesforce/apex/GGW_ApplicationCtrl.getApplication'; +import getApplicationList from '@salesforce/apex/GGW_ApplicationCtrl.getApplicationList'; import includeLogo from '@salesforce/apex/GGW_ApplicationCtrl.includeLogo'; import deleteLogo from '@salesforce/apex/GGW_ApplicationCtrl.deleteLogo'; import createContentDistribution from '@salesforce/apex/GGW_ApplicationCtrl.createContentDistribution'; @@ -46,6 +47,8 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen container = 'modal'; showModalFooter = false; showCard = true; // Display Editor card if data grant exists ELSE show illustration + grantOptions = []; // List of available Grants for combo box + selectedGrant; showToastSuccess(msg){ const evt = new ShowToastEvent({ @@ -64,6 +67,23 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen this.dispatchEvent(evt); } + @wire(getApplicationList) + grantApplications({ error, data }) { + if (data) { + this.grantOptions = []; + for(let i = 0; i < data.length; i++) { + let grantItem = data[i]; + if(grantItem){ + this.grantOptions.push({ label: grantItem.Name, value: grantItem.Id }); + } + } + this.error = undefined; + } else if (error) { + this.error = error; + this.grantOptions = undefined; + } + } + @wire(CurrentPageReference) setCurrentPageReference(currentPageReference) { this.currentPageReference = currentPageReference; @@ -78,6 +98,13 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen this.queryGrantApplication(); } + handleGrantChange(event) { + this.selectedGrant = event.detail.value; + this.recordId = this.selectedGrant; + this.displayGrantCard(); + this.queryGrantApplication(); + } + handleLogoSelectorClick() { this.logoState = !this.logoState; includeLogo({recordId: this.recordId, state: this.logoState})