diff --git a/.gitignore b/.gitignore index 553c445..6bb3d61 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,11 @@ node_modules # built webapp resource bundle resource-bundles/FullCalendar.resource/* npm-debug.log + + +salesforce_marketing_calendar.sublime-project +config/.debug +config/.describe +config/.lightning +config/.local_store +config/.session diff --git a/src/aura/MarketingCalendar/MarketingCalendar.app b/src/aura/MarketingCalendar/MarketingCalendar.app new file mode 100644 index 0000000..f95dc57 --- /dev/null +++ b/src/aura/MarketingCalendar/MarketingCalendar.app @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/aura/MarketingCalendar/MarketingCalendar.app-meta.xml b/src/aura/MarketingCalendar/MarketingCalendar.app-meta.xml new file mode 100644 index 0000000..0f17919 --- /dev/null +++ b/src/aura/MarketingCalendar/MarketingCalendar.app-meta.xml @@ -0,0 +1,5 @@ + + + 33.0 + Lightning version of Marketing Calendar + diff --git a/src/aura/MarketingCalendar/MarketingCalendarController.js b/src/aura/MarketingCalendar/MarketingCalendarController.js new file mode 100644 index 0000000..2fbfba8 --- /dev/null +++ b/src/aura/MarketingCalendar/MarketingCalendarController.js @@ -0,0 +1,4 @@ +({ + myAction : function(component, event, helper) { + } +}) \ No newline at end of file diff --git a/src/aura/calendar/calendar.cmp b/src/aura/calendar/calendar.cmp new file mode 100644 index 0000000..5047b2a --- /dev/null +++ b/src/aura/calendar/calendar.cmp @@ -0,0 +1,63 @@ + + + + +
+
+ FILTERS +
+
+ Parent Campaign +
+ +
+
+
+ Campaign Type +
+ +
+
+
+
+
+
+
+
+ + +
+ diff --git a/src/aura/calendar/calendar.cmp-meta.xml b/src/aura/calendar/calendar.cmp-meta.xml new file mode 100644 index 0000000..237ef76 --- /dev/null +++ b/src/aura/calendar/calendar.cmp-meta.xml @@ -0,0 +1,5 @@ + + + 33.0 + lightning version of marketing calendar + diff --git a/src/aura/calendar/calendar.css b/src/aura/calendar/calendar.css new file mode 100644 index 0000000..e78d7af --- /dev/null +++ b/src/aura/calendar/calendar.css @@ -0,0 +1,66 @@ +.THIS #calendarX{ + background-color: #fff; + border-width: 1px; + border-color:#ddd; + padding:10px; + box-shadow: none; + border-style:solid; + border-radius: 4px 4px; + margin-top:15px; +} + +.THIS .filterBox { + margin-top:5px; + background-color: #fff; + border-width: 1px; + border-color:#ddd; + padding:5px; + box-shadow: none; + border-style:solid; + border-radius: 4px 4px; + float:right; + background: linear-gradient(#E5F2F6,#CDE8F0); + -moz-box-shadow: 0 3px 5px hsla(100,0%,0%,.3); + -webkit-box-shadow: 0 3px 5px hsla(100,0%,0%,.3); + box-shadow: 0 3px 5px hsla(100,0%,0%,.3); + +} + +.THIS .uiInputSelect{ + display: inline-block; +} + +.THIS .filterBoxTitle{ + position:absolute; + color:#808080; + font-weight:bold; + font-size: 12px; +} + +.THIS .label{ + margin-left:8px; + font-size: 13px; + margin-right:5px; +} + +.THIS .combo{ + margin-left:4px; +} + +.THIS .filter{ + float:right; +} + +.THIS #filter-elem-1{ + float:left; +} + +.THIS #filter-elem-2{ + float:right; +} + +@media all and (max-width: 980px) { + .THIS #filter-elem-2{ + display: block;; + } +} diff --git a/src/aura/calendar/calendarController.js b/src/aura/calendar/calendarController.js new file mode 100644 index 0000000..91d335d --- /dev/null +++ b/src/aura/calendar/calendarController.js @@ -0,0 +1,9 @@ +({ + doInit : function(component, event, helper) { + helper.doInit(helper,component); + }, + reload :function(component, event, helper){ + console.log('reloading'); + helper.load(component,helper); + } +}) diff --git a/src/aura/calendar/calendarHelper.js b/src/aura/calendar/calendarHelper.js new file mode 100644 index 0000000..c193d8e --- /dev/null +++ b/src/aura/calendar/calendarHelper.js @@ -0,0 +1,126 @@ +({ + doInit : function(helper,component) { + var me = this; + helper.getParentCampaigns(component); + helper.describeFieldSet("MarketingCalendarPopup",component,function(r){ + component.set('v.MarketingCalendarPopupFields',r.getReturnValue()); + helper.load(helper,component,"",""); + $('.forceInputPicklist select').removeAttr('disabled'); + $('select').select2({width: 'resolve'}).on('change',function(){ + helper.load(helper,component,$('#parentCampaign').val(),$('.forceInputPicklist select').val()); + }); + }); + }, + load : function(helper,component,parentCampaignId,type){ + helper.fetchCalendarData(helper,component,parentCampaignId,type,function(response){ + if (response.getState() === "SUCCESS") { + //component.set('v.campaigns',response.getReturnValue()); + helper.initCalendar(helper,helper.parseEnteries(response.getReturnValue())); + } + else{ + var error = helper.parseErrors(response.getError()); + component.set("v.errors",error); + } + }) + }, + fetchCalendarData : function(helper,component,parentCampaignId,type,cb){ + parentCampaignId = (parentCampaignId == '--None--' ? '' : parentCampaignId); + type = (type == '--None--' ? '' : type); + var action = component.get("c.getCalendarEntryAura"); + action.setParams({"parentCampaignId":parentCampaignId,"type" : type}); + action.setCallback(helper,cb); + $A.enqueueAction(action); + }, + describeFieldSet : function(fs,component,cb){ + var action = component.get("c.describeFieldSet"); + action.setParams({"fieldset":fs}); + action.setCallback(this,cb); + $A.enqueueAction(action); + }, + parseCampaigns : function(campaigns){ + var enteries = []; + for(var i =0 ;i < campaigns.length; i++){ + enteries.push({ + title : campaigns[i].Name, + start : campaigns[i].StartDate, + end : campaigns[i].EndDate + }); + } + return enteries; + }, + parseEnteries : function(results){ + for(var i =0 ;i < results.length; i++){ + results[i].start = new Date(results[i].startDate); + results[i].end = new Date(results[i].endDate); + } + return results; + }, + initCalendar : function(helper,calendarEntries){ + console.log(calendarEntries); + $('#calendarX').fullCalendar('destroy'); + $('#calendarX').fullCalendar({ + editable: false, + events: calendarEntries, + eventClick: function(event) { + if (event.url) { + window.open(event.url); + return false; + } + }, + eventRender: function(event, element, view){ + element.qtip({ + position: { + my: 'top left', + at: 'bottom center' + }, + style: { + width: 300, + color: 'black', + name: 'light' + }, + content: $.templates(helper.decodeEntities($("#qtipTemplate").html())).render(event.campaign) + }); + } + }); + }, + toast : function(title,message){ + var toastEvent = $A.get("e.force:showToast"); + if(toastEvent){ + toastEvent.setParams({ + "title": title, + "message": message + }); + + toastEvent.fire(); + } + }, + parseErrors : function(errorObj){ + console.log('error',errorObj); + var error = []; + for(var i = 0; i < errorObj.length > 0; i ++){ + if(errorObj[i].pageErrors){ + error = error.concat(errorObj[i].pageErrors); + } + + if(errorObj[i].fieldErrors){ + for(f in errorObj[i].fieldErrors){ + error = errorObj[i].fieldErrors[f].concat(errorObj[i].pageErrors); + } + } + } + return error; + }, + decodeEntities : function(input) { + var y = document.createElement('textarea'); + y.innerHTML = input; + return y.value; + }, + getParentCampaigns : function(component){ + var action = component.get("c.getActiveParentCampaignObjects"); + action.setParams({}); + action.setCallback(this,function(response){ + component.set("v.parentCampaigns",response.getReturnValue()); + }); + $A.enqueueAction(action); + } +}) diff --git a/src/classes/CampaignCalendar.cls b/src/classes/CampaignCalendar.cls index 1b32595..0acc49a 100644 --- a/src/classes/CampaignCalendar.cls +++ b/src/classes/CampaignCalendar.cls @@ -6,7 +6,7 @@ Copyright (c) 2011 James Sullivan, Cambridge Cloud Partners public with sharing class CampaignCalendar { public Campaign campaignObj{get;set;} private static String titleFieldAPI; //variable to cache the api name of the title field - + public class CalendarEntry{ public Campaign campaign; public String className; @@ -19,6 +19,8 @@ public with sharing class CampaignCalendar { public Date startDate; public Date endDate; public Boolean allDay = true; + public String textColor; + public String color; public CalendarEntry(Campaign campaign){ this.campaign = campaign; this.title = getCalendarTitleFieldValue(campaign); @@ -29,17 +31,22 @@ public with sharing class CampaignCalendar { this.startDate = '' + this.campaign.StartDate.year() + '-' + this.campaign.StartDate.month() + '-' + this.campaign.StartDate.day(); if(this.campaign.EndDate != null) this.endDate = '' + this.campaign.EndDate.year() + '-' + this.campaign.EndDate.month() + '-' + this.campaign.EndDate.day(); + TimeZone tz = UserInfo.getTimeZone(); */ - TimeZone tz = UserInfo.getTimeZone(); + this.startDate = this.campaign.StartDate; this.endDate = this.campaign.endDate == NULL ? this.campaign.StartDate : this.campaign.endDate; if(campaign.Color_Status__c == null || campaign.Color_Status__c == 'null' || campaign.Color_Status__c == ''){ campaign.Color_Status__c = 'blue'; } className = 'calcolor-'+campaign.Color_Status__c.toLowerCase(); + if(colors.get(campaign.Color_Status__c) != NULL){ + this.textColor = colors.get(campaign.Color_Status__c); + this.color = campaign.Color_Status__c; + } } } - + // taken from w3c web colors public static final Map colors = new Map{ 'maroon' => 'white', @@ -50,15 +57,15 @@ public with sharing class CampaignCalendar { 'black' => 'white', 'blue' => 'white', 'olive' => 'white', - 'gray' => 'white', - 'deepskyblue' => 'white', - 'darksalmon' => 'white', + 'gray' => 'white', + 'deepskyblue' => 'white', + 'darksalmon' => 'white', 'forestgreen' => 'white', - 'palvioletred' => 'white', + 'palvioletred' => 'white', 'powederblue' => 'white', 'tomato' => 'white', - 'saddlebrown' => 'white', - + 'saddlebrown' => 'white', + 'moccasin' => 'black', 'orange' => 'black', 'red' => 'black', @@ -77,31 +84,49 @@ public with sharing class CampaignCalendar { this.fg = fg; } } - + + @AuraEnabled public List getColors(){ List displayColors = new List(); for(String bgcolor : colors.keySet()) displayColors.add( new Color(bgcolor,colors.get(bgcolor)) ); return displayColors; } - + public List getActiveParentCampaigns(){ List SelectOptions = new List(); SelectOptions.add(new SelectOption('', '--None--')); + + for(Campaign cn : getActiveParentCampaignObjects()){ + SelectOptions.add(new SelectOption(cn.Id, cn.Name)); + } + return SelectOptions; + } + + @AuraEnabled + public static List getActiveParentCampaignObjects(){ Set campaignSet = new Set(); - - for(AggregateResult ar : [SELECT ParentId,Count(Id)recordCount FROM Campaign WHERE ParentId !=NULL AND isActive=TRUE WITH SECURITY_ENFORCED GROUP BY ParentId]){ + for(AggregateResult ar : [ + SELECT ParentId,Count(Id)recordCount + FROM Campaign + WHERE ParentId !=NULL AND isActive=TRUE GROUP BY ParentId] + ){ if(ar.get('recordCount') != NULL && Integer.valueOf(ar.get('recordCount')) > 0){ campaignSet.add((Id)ar.get('ParentId')); } } - - for(Campaign cn : [SELECT Id,Name FROM Campaign WHERE Id=:campaignSet WITH SECURITY_ENFORCED ORDER BY Name]){ - SelectOptions.add(new SelectOption(cn.Id, cn.Name)); - } - return SelectOptions; + return [ + SELECT Id,Name + FROM Campaign + WHERE Id=:campaignSet ORDER BY Name + ]; } - + + @AuraEnabled + public static List describeFieldSet(String fieldset){ + return (List)JSON.deserializeUntyped(JSON.serialize(SObjectType.Campaign.FieldSets.getMap().get(fieldset).getFields())); + } + @RemoteAction public static List getCalendarEntry(String parentCampaignId, String type) { @@ -141,28 +166,58 @@ public with sharing class CampaignCalendar { for(Schema.FieldSetMember f : SObjectType.Campaign.FieldSets.MarketingCalendarPopup.getFields()) { fields.add(f.getFieldPath().toLowerCase()); } - + for(Schema.FieldSetMember f : SObjectType.Campaign.FieldSets.MarketingCalendarEventTitle.getFields()) { fields.add(f.getFieldPath().toLowerCase()); } return new List(fields); } - + + @AuraEnabled + public static List getCalendarEntryAura(String parentCampaignId,String type){ + return (List)JSON.deserializeUntyped(JSON.serialize(getCalendarEntry(parentCampaignId,type))); + } + + + private static List queryCampaign(Set additionalFields,String whereClause ) { + Set fields = new Set{'id'}; + String query = 'SELECT Id'; + + for(String fs : additionalFields){ + if(!fields.contains(fs) && !fields.contains(fs.toLowerCase())){ + fs = fs.toLowerCase(); + fields.add(fs); + query = query+','+fs; + } + } + List fieldSetMembers = SObjectType.Campaign.FieldSets.MarketingCalendarPopup.getFields(); + fieldSetMembers.addAll(SObjectType.Campaign.FieldSets.MarketingCalendarEventTitle.getFields()); + for(Schema.FieldSetMember f : fieldSetMembers) { + if(!fields.contains(f.getFieldPath().toLowerCase())){ + query = query+','+f.getFieldPath().toLowerCase(); + } + } + + query = query + ' FROM Campaign'; + query = (whereClause !=null && whereClause!='') ? query +' WHERE ' +whereClause : query; + return Database.query(query); + } + private static String getCalendarTitleFieldValue(Campaign c){ - + if(titleFieldAPI == NULL){ for(Schema.FieldSetMember f : SObjectType.Campaign.FieldSets.MarketingCalendarEventTitle.getFields()) { titleFieldAPI = f.getFieldPath(); break; //take the first field } } - + if(titleFieldAPI == NULL){ titleFieldAPI = 'Name'; } - + return String.valueOf(c.get(titleFieldAPI)); } -} \ No newline at end of file +} diff --git a/src/package.xml b/src/package.xml index 3efc1ed..043756a 100644 --- a/src/package.xml +++ b/src/package.xml @@ -41,5 +41,9 @@ For support or to hear about our other apps, visit us at https://cloudanswers.co PoweredBy StaticResource + + * + AuraDefinitionBundle + 48.0