From a96e80d34c3f4d77102c4259573e7a762a432d2f Mon Sep 17 00:00:00 2001 From: Igor Androsov Date: Fri, 15 Dec 2023 17:15:13 +0900 Subject: [PATCH 1/6] Add issue creatio script, import from another repo --- .vscode/settings.json | 16 +++++++++ scripts/dx/gitissuescmd | 78 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100755 scripts/dx/gitissuescmd diff --git a/.vscode/settings.json b/.vscode/settings.json index 76decfb..58aa9ed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,21 @@ "**/node_modules": true, "**/bower_components": true, "**/.sfdx": true + }, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + "**/.apivcs": true, + "**/.gitignore": true, + "**/.designer.json": true, + "**/.exchange.xml": true, + "**/.vscode": true, + "**/.mvn": true, + "**/.exchange_modules_tmp": true, + ".mule": true } } diff --git a/scripts/dx/gitissuescmd b/scripts/dx/gitissuescmd new file mode 100755 index 0000000..50214b8 --- /dev/null +++ b/scripts/dx/gitissuescmd @@ -0,0 +1,78 @@ +#!/bin/sh + +# This script is geenrated from exported issues to import to new repository +# GitHub does not provide automated methods to export/import or transfer issue on different organizations. +# using GitHub gh CLI gh - commands to do this +# Example CLI command to export all Open issues as JSON to a file, then use create to add issues from file +# To convert JSON to this command file we use basic Node program +# +# gh issue list --limit 1000 --state open --json 'number,title,body,state,createdAt,updatedAt,label' > ../issues.json +# +# Example command to create new issue in CLI +# gh issue create --title "My new issue" --body "Here are more details." --assignee @me,monalisa --label "bug,help wanted" --project onboarding --milestone "learning codebase" +# --- + +gh issue create --title "UI Improvement - word count inaccurate" --body "**OVERVIEW**

The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:

**The actually word count is undercounting by 1 **

https://salesforce.quip.com/JKMnAsPUEeDd



**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Improvement - Cloning Grant Proposals" --body "**OVERVIEW**

The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:

**Be able to clone an existing grant application to use with another grant**

https://salesforce.quip.com/JKMnAsPUEeDd


**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Improvement - Relate Account Info" --body "**OVERVIEW**

The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:

**Be able to see the Account preview to confirm it's the correct account**

https://salesforce.quip.com/JKMnAsPUEeDd


**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Improvement - Preview function" --body "**OVERVIEW**

The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:

**A preview function (maybe that’s just leveraging the HTML) or like Igor suggested, the preview would have a copy button next to each section.**

https://salesforce.quip.com/JKMnAsPUEeDd


**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Improvement - Caching Bugs" --body "**OVERVIEW**

The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:

**Reorder delay /the visualized order numbers are not updated immediately = bugs fixed**

https://salesforce.quip.com/JKMnAsPUEeDd

**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "Ui Improvement - Unnecessary Tab" --body "**OVERVIEW**


The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:

**Tab is created for "Grant Preview Word" - but the page is empty**

https://salesforce.quip.com/JKMnAsPUEeDd



**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Improvement - Image issue" --body "**OVERVIEW**

The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:

**When I upload an image, I get a strange modal - can we eliminate this modal?**

https://salesforce.quip.com/JKMnAsPUEeDd


**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Improvement - Save/Cancel option" --body "**OVERVIEW**

The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:
https://salesforce.quip.com/JKMnAsPUEeDd

Users would like a Save/Cancel for each section once that section is in edit mode.


**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Improvement - Section Naming " --body "**OVERVIEW**

The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:
https://salesforce.quip.com/JKMnAsPUEeDd

When adding a new section, on submit, after the new section is added, remove the custom Section Name that was manually added to the New field - otherwise, it looks like you still need to add it.


**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Improvement - Text Alignment is confusing" --body "**OVERVIEW**

The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:
https://salesforce.quip.com/JKMnAsPUEeDd

When viewing the list of available Blocks for a section, the text is all centered - which doesn't accurately reflect the alignment.

**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "Ui Improvement - Logo field" --body "**OVERVIEW**
The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:
https://salesforce.quip.com/JKMnAsPUEeDd

Logo field at the top of the Grant Editor screen cannot be removed or turned off - would like to replace it or remove it as an option


**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Improvement - Filter Topic/tagging" --body "**OVERVIEW**
The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:
https://salesforce.quip.com/JKMnAsPUEeDd

Add Filter for the Topic/tagging in Content Blocks


**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Improvement - Copy/Clone Button" --body "**OVERVIEW**

The following is from a list from the Chicago Sprint on Improvements that the group felt would be important to users:

**Button update - Add copy button to blocks**

https://salesforce.quip.com/JKMnAsPUEeDd






**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI/UX Enhancements" --body "**OVERVIEW**
The items below were listed at the Chicago sprint as UI enhancements that were important for nonprofit users.

1. Remove completed from the pie chart on the homepage = unnecessary
2. ChatGPT copy is cut off before/during the return after only about six sentences or less
3. Topics are enabled for all objects from the start
4. From the grant editor page have recent list for quick access - don't want to have to go to the home page
5. Status “Progress” should be “In progress”
6. “Declined” status to be related to an approval process - not related to a foundation's approval or denial of the grant.
7. Import (and other unrelated) buttons on Grant Applications tab should be removed
8. Include a Path (status bar) at top of page layout

https://salesforce.quip.com/JKMnAsPUEeDd

**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "UI Issue on Content Block record page" --body "The Topics related object is missing from the right side of the Content Block record page.
" +# --- create issue --- +gh issue create --title "Selected Item object - field update" --body "On the Selected Item object, the 2nd field down on the page layout is labeled GGW and should be updated to GCK before submitting for Security review." +# --- create issue --- +gh issue create --title "GPT-3 Integration POC" --body "**OVERVIEW**
POC use of GPT models to assist in creation of grant text components (text blocks) for purpose statement or project plan as examples.

**ACCEPTANCE CRITERIA**
Add Named Credential for secure authentication for OpenAI API Key
Apex utility classes to support API calls and parsing the request/response data
LWC UI Component that allows entry prompt to generate requests and render results.
There may be multiple option results rendered where use needs to select one to use in targeted Grant text block
Initial Models choices: text-davinci-003 or gpt-3.5-turbo

**OUT OF SCOPE**
Full scale GPT model integration and tuning of models

**BACKGROUND/REFERENCE**
Use of OpenAI APIs and response data structures" --label "enhancement" +# --- create issue --- +gh issue create --title "Update Test data creation for Scratch Org" --body "**OVERVIEW**
As Spring 23' SFDX requires `sfdx data import tree` command for creating test data in dev scratch org environments.
**ACCEPTANCE CRITERIA**
Create dev scratch org environments with test data.
**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
Issue came up while during CCI testing." +# --- create issue --- +gh issue create --title "Locking Grant record content" --body "**OVERVIEW**
Once submitted the grant record content should be ale to be locked

**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" --label "enhancement" +# --- create issue --- +gh issue create --title "Chatter" --body "**OVERVIEW**
UI Enhancement - Page layout updates
- Chatter should be enabled and included in the page layout of the grant record.
- Add Path for Status
- We were not able to add the Topics to the page layout in the trial

**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "Grant Editor Tab" --body "**OVERVIEW**
UI Enhancement - The Grant Editor tab right next to the first tab makes selecting which grant to edit confusing.

Along with that thought, having the Applications In Progress component higher on the left and moving the Grant launch wizard to the right above the donut chart might help with the confusion.

**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "Swap order of sections: Plan of Action to come after Goals and Objectives" --body "**OVERVIEW**
This is a UI Enhancement request.
Working with a grant writer it was suggested that typically the Goals and Objectives section would come before the Plan of Action.

**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**

![Screenshot 2023-03-30 120200](https://user-images.githubusercontent.com/113560681/228938245-65d28323-5fdd-46e5-b91f-80bf79fd0975.png)
" +# --- create issue --- +gh issue create --title "Convert Package to Manage Package using 2 GP." --body "**OVERVIEW**

**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "Toggle read/edit mode on Grant Editor sections" --body "**OVERVIEW**
As a Grant writer I need ability to toggle Edit mode on/off on Grant Editor enable rich text editor and switch ti read

**ACCEPTANCE CRITERIA**
Click on Edit button to enable Rich text editor to ON. Switch editor off to read mode by click on same button
Toggle action
**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "Enhancement: Attribution/Reference/Link data for content blocks" --body "**OVERVIEW**
Add a rich text field to content block to track source/referenced data related to any facts in the content -- give the user a way to track original source or reference materials related to the content where there was some analysis done to produce facts/stats or link to source materials. Ideally also copy this data when a content block is used in a grant so that it tracks the original "source" data used in that grant.

**ACCEPTANCE CRITERIA**
* One or more fields to store data
* UI to edit/maintain content
* Extend "Add block" functionality to copy field to grant

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" --label "enhancement" +# --- create issue --- +gh issue create --title "Use of merge fields in content blocks text" --body "**OVERVIEW**
Investigate possible use of merge fields in content block to pull data from related parent records such as Grant App->Section

**ACCEPTANCE CRITERIA**
User must enter correct merge field API Name
Must highlight merge field and use Remove formatting on rich text editor toolbar to remove extra tags inside merge delimiters

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
Text blocks are rich text fields and merge fields are not supported from platform as in Flows, VFP or formulas.
There is interesting blog on topic using Flows as workaround https://forcepanda.wordpress.com/2020/02/11/workaround-for-merge-fields-in-standard-rich-text-component/

Rich text inserts extra tags inside merge brackets {!Section_Name__c}" --label "enhancement" +# --- create issue --- +gh issue create --title "Add Samples of Content blocks to sample data" --body "**OVERVIEW**
Current initialize sample data inserts Sections, this feature to add related text content blocks as sample data to initialize new package install.

**ACCEPTANCE CRITERIA**
As part of new install data is initialized with set of sections and related text content blocks.

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" --label "enhancement" +# --- create issue --- +gh issue create --title "Grant Content Kit - FLS/CRUD" --body "**OVERVIEW**

Resolve FLS/CRUD

**ACCEPTANCE CRITERIA**

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "Link Grant Application to Opportunity" --body "**OVERVIEW**
Grants is thought to be started or created as Opportunity for some funding collection with amount and other details.
Add Opportunity lookup field to Grants Application record
Create Formula fields cross object to bring related information to Grant App
Account Name
Amount

**ACCEPTANCE CRITERIA**
View Opportunity and related data because Grant does not exist in a vacuum

**OUT OF SCOPE**
Create new Opportunity from Grant
Automate Opportunity creation

**BACKGROUND/REFERENCE**
" +# --- create issue --- +gh issue create --title "Default metadata issues deploying to Production or sandbox org" --body "While deploy to full org current repo has these issues in metadata that needs to be removed from package

Reports and Dashboard Folders are shared to specific user ID that only for scratch but will never exists on other target org as this examples

Dashboard Folder
test-kdhrnflzy1zq@example.com


Manage
test-kdhrnflzy1zq@example.com
User


Report or Folder


Manage
test-kdhrnflzy1zq@example.com
User


Home page layout has unknown item standard-Tags need to remove that

```

standard-CreateNew
**standard-Tags**
standard-RecentItems
standard-Calendar
standard-Tasks
standard-ProcessWorkitems
standard-Dashboard

```

App Menue - need to remove from repo it not required for any org." --label "documentation" +# --- create issue --- +gh issue create --title "Grant Preview (Export) - Known issue" --body "To pass record context and parameters from Lightning to Visual Force requires keeping a state of current Grant record.
Lightning for security reasons (CROSS-SITE scripting attacks) do not allow any parameter passed to Visual Force because VFP is on different domain from LEX.

This reason launching preview tab with PDF view require a workaround - a state record/object.
We create a single grant state record per user-grant keeping current Grant to initialize preview page when navigating from Grant editor LWC->Preview VisualForce crossing site boundary.
As user changes to work on any new grant state record is updated with new Grant app ID.

This solution leads to limit of user can export only current grant and not able to simultaneously work on many Grants on many tabs/browsers and expect preview/export to work for all.
Only the current active Grant can export.

There are no current other fixes for this limitation in Lightning Salesforce." --label "documentation" +# --- create issue --- +gh issue create --title "Content Blocks - Search" --body "**OVERVIEW**
In order to find the right content block to use in your grant proposal, as a grant writer, i need the ability to search for a content block.
**ACCEPTANCE CRITERIA**
Users should be able to search for content blocks with key words included in the content block (this appears to be standard functionality in the search bar)
Users can search for a specific content block from within the section - In the POC, the user would be editing a grant, they'd select the + in a section and from there be able to search content blocks

**OUT OF SCOPE**

**BACKGROUND/REFERENCE**
" --label "enhancement" +# --- create issue --- From bb4d8da86bc7f3447c8bbbcd7cb25a79cba12085 Mon Sep 17 00:00:00 2001 From: Igor Androsov Date: Fri, 15 Dec 2023 17:56:50 +0900 Subject: [PATCH 2/6] Update dx scripts for issue #36 convert to sf cli --- config/project-scratch-def.json | 2 +- scripts/dx/dxorg | 3 ++- scripts/dx/dxtest | 1 + scripts/dx/dxuser | 1 + scripts/dx/gitissuescmd | 3 ++- scripts/dx/sforg | 46 +++++++++++++++++++++++++++++++++ scripts/dx/sftest | 23 +++++++++++++++++ scripts/dx/sfuser | 33 +++++++++++++++++++++++ 8 files changed, 109 insertions(+), 3 deletions(-) create mode 100755 scripts/dx/sforg create mode 100755 scripts/dx/sftest create mode 100755 scripts/dx/sfuser diff --git a/config/project-scratch-def.json b/config/project-scratch-def.json index 2566341..9922ac6 100644 --- a/config/project-scratch-def.json +++ b/config/project-scratch-def.json @@ -1,7 +1,7 @@ { "orgName": "Salesforce Impact Labs", "edition": "Developer", - "features": ["EnableSetPasswordInApi","AuthorApex"], + "features": ["EnableSetPasswordInApi","AuthorApex", "EinsteinHawkingC2CEnabled", "EinsteinGPT"], "settings": { "lightningExperienceSettings": { "enableS1DesktopEnabled": true diff --git a/scripts/dx/dxorg b/scripts/dx/dxorg index 0a7851e..b522740 100755 --- a/scripts/dx/dxorg +++ b/scripts/dx/dxorg @@ -3,7 +3,7 @@ ########################################################################################## # # Author: Igor Androsov 2022 -# +# SFDX is DEPRECTAED ########################################################################################## # Create new Scratch org environment for development testing and load test data @@ -13,6 +13,7 @@ ORG_ALIAS="$1" # Get input for ORG active days with default to 30 days ACTIVEDAYS="${2:-30}" +echo "--- THIS IS SFDX SCRIPT DEPRECATED START USING SF CLI ---" echo "--- START DEPLOYMENT FOR: $ORG_ALIAS" echo "--- New ORG will be active for: $ACTIVEDAYS" # Set user alias from org name diff --git a/scripts/dx/dxtest b/scripts/dx/dxtest index 8d0b468..fd9ea29 100755 --- a/scripts/dx/dxtest +++ b/scripts/dx/dxtest @@ -14,6 +14,7 @@ ORG_ALIAS="$1" +echo "--- THIS IS SFDX SCRIPT DEPRECATED START USING SF CLI ---" echo "--- START UNIT TESTS FOR: $ORG_ALIAS" # Run Tests - optional step diff --git a/scripts/dx/dxuser b/scripts/dx/dxuser index 21deee5..c4ff958 100755 --- a/scripts/dx/dxuser +++ b/scripts/dx/dxuser @@ -17,6 +17,7 @@ ORG_ALIAS="$1" # Get input for ORG active days with default to 30 days ACTIVEDAYS="${2:-30}" +echo "--- THIS IS SFDX SCRIPT DEPRECATED START USING SF CLI ---" echo "--- START DEPLOYMENT FOR: $ORG_ALIAS" echo "--- New ORG will be active for: $ACTIVEDAYS" # Set user alias from org name diff --git a/scripts/dx/gitissuescmd b/scripts/dx/gitissuescmd index 50214b8..bda78c2 100755 --- a/scripts/dx/gitissuescmd +++ b/scripts/dx/gitissuescmd @@ -1,6 +1,7 @@ #!/bin/sh -# This script is geenrated from exported issues to import to new repository +# THIS SCRIPT IS HERE ONLY FOR REFERENCE How To export/oimport GitHub issues DO NOT RUN +# This script is generated from exported issues to import to new repository # GitHub does not provide automated methods to export/import or transfer issue on different organizations. # using GitHub gh CLI gh - commands to do this # Example CLI command to export all Open issues as JSON to a file, then use create to add issues from file diff --git a/scripts/dx/sforg b/scripts/dx/sforg new file mode 100755 index 0000000..e75a9db --- /dev/null +++ b/scripts/dx/sforg @@ -0,0 +1,46 @@ +#!/bin/sh + +########################################################################################## +# +# Author: Igor Androsov 2023 +# +########################################################################################## + +# Create new Scratch org environment for development testing and load test data +# Set input prameter values + +ORG_ALIAS="$1" +# Get input for ORG active days with default to 30 days +ACTIVEDAYS="${2:-30}" + +echo "--- START DEPLOYMENT FOR: $ORG_ALIAS" +echo "--- New ORG will be active for: $ACTIVEDAYS" +# Set user alias from org name +TESTUSER="${ORG_ALIAS}-user" + +# Create new scratch org 30 days max +sf org create scratch --target-dev-hub labsDevHub --alias $ORG_ALIAS --definition-file config/project-scratch-def.json --set-default --duration-days $ACTIVEDAYS || { echo 'Scratch org create failed' ; exit 1; } + +# Create test user +# sfdx force:user:create --setalias $TESTUSER --definitionfile config/user-def.json || { echo 'Scratch org User create failed' ; exit 1; } +# sfdx force:user:display -u $TESTUSER + +# Push source +echo "--- PUSH SOURCE FOR: $ORG_ALIAS" +sf project deploy start --target-org $ORG_ALIAS || { echo 'Source push failed' ; exit 1; } + +# Assign Permission Set to users +echo "--- ASSIGN PERMISSIONS FOR: $ORG_ALIAS" +sf org assign permset --name GGW_User_Permissions --target-org $ORG_ALIAS || { echo 'User permission failed' ; exit 1; } + +# Push sample data +echo "--- INSERT SAMPLE DATA FOR: $ORG_ALIAS" +sf data import tree --plan test-data/export-section-GGW_Section__c-plan.json --target-org $ORG_ALIAS + +# sfdx force:data:tree:import --target-org $ORG_ALIAS --plan test-data/export-section-GGW_Section__c-plan.json +#sfdx force:data:tree:import -u ggw --plan test-data/export-section-GGW_Section__c-plan.json +# Run Tests - optional step + +# Open new org +#sf org open --target-org $ORG_ALIAS +echo "--- END DEPLOYMENT FOR: $ORG_ALIAS" \ No newline at end of file diff --git a/scripts/dx/sftest b/scripts/dx/sftest new file mode 100755 index 0000000..726eb15 --- /dev/null +++ b/scripts/dx/sftest @@ -0,0 +1,23 @@ +#!/bin/sh + +########################################################################################## +# +# Author: Igor Androsov 2023 +# +# Script to run APEX Unit Tests for project +# For more details on sfdx testing refer to: +# https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_testing.htm +########################################################################################## + +# Run all unit tests on new Scratch org environment asynchronous +# Set input prameter values org alias + +ORG_ALIAS="$1" + +echo "--- START UNIT TESTS FOR: $ORG_ALIAS" + +# Run Tests - optional step +# --- DEPRECTAED CLI OPTIONS change to new version of sfdx +sf apex run test --code-coverage --detailed-coverage --result-format human --target-org $ORG_ALIAS + +echo "--- END UNIT TESTS FOR: $ORG_ALIAS" \ No newline at end of file diff --git a/scripts/dx/sfuser b/scripts/dx/sfuser new file mode 100755 index 0000000..94e36c7 --- /dev/null +++ b/scripts/dx/sfuser @@ -0,0 +1,33 @@ +#!/bin/sh + +########################################################################################## +# +# Author: Igor Androsov 2023 +# +# IMPORTANT! Before exec this script update the QA user email address to allow password +# resets. Replace placeholder value in config/user-def.json file with +# correct user email. +########################################################################################## + +# Create new QA User for Scratch org environment for testing and avlidation +# Required existing scratch org set with alias +# Set input prameter values + +ORG_ALIAS="$1" +# Get input for ORG active days with default to 30 days +ACTIVEDAYS="${2:-30}" + +echo "--- START DEPLOYMENT FOR: $ORG_ALIAS" +echo "--- New ORG will be active for: $ACTIVEDAYS" +# Set user alias from org name +TESTUSER="${ORG_ALIAS}-user" + +# Create test user +sf org create user --set-alias $TESTUSER --definition-file config/user-def.json --target-org $ORG_ALIAS || { echo 'Scratch org User create failed' ; exit 1; } +sfdx force:user:display -u $TESTUSER + +# Assign Permission Set to users +sf org assign permset --name GGW_User_Permissions --onbehalfof $TESTUSER --target-org $ORG_ALIAS || { echo 'User permission failed' ; exit 1; } + +# Open new org +#sf org open -u $ORG_ALIAS \ No newline at end of file From 012ef27f5b0a728335e8dd09675b96d96bcb47a6 Mon Sep 17 00:00:00 2001 From: Igor Androsov Date: Fri, 15 Dec 2023 21:46:30 +0900 Subject: [PATCH 3/6] Add functionality for logo removal from app issue #12 --- .../default/classes/GGW_ApplicationCtrl.cls | 26 +++++++++ .../classes/GGW_ApplicationCtrlTest.cls | 19 +++++++ force-app/main/default/classes/GGW_Util.cls | 2 +- ...c-Grant Application Layout.layout-meta.xml | 18 +++--- .../ggwGrantApplication.html | 24 ++++++++ .../ggwGrantApplication.js | 56 ++++++++++++++++++- .../fields/Include_Logo__c.field-meta.xml | 11 ++++ ...GW_User_Permissions.permissionset-meta.xml | 5 ++ 8 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 force-app/main/default/objects/GGW_Grant_Application__c/fields/Include_Logo__c.field-meta.xml diff --git a/force-app/main/default/classes/GGW_ApplicationCtrl.cls b/force-app/main/default/classes/GGW_ApplicationCtrl.cls index 0513d19..3c6bb1d 100644 --- a/force-app/main/default/classes/GGW_ApplicationCtrl.cls +++ b/force-app/main/default/classes/GGW_ApplicationCtrl.cls @@ -32,6 +32,32 @@ public without sharing class GGW_ApplicationCtrl { } return app; } + // Delete logo file from grant + @AuraEnabled + public static String deleteLogo(String recordId){ + GGW_Grant_Application__c app = new GGW_Grant_Application__c(); + app.Id = recordId; + app.DistributionPublicUrl__c = null; // Logo public URL + app.Logo_Download_Url__c = null; // Logo display URL + // Check object CRUD + if(Schema.sObjectType.GGW_Grant_Application__c.isUpdateable()){ + update app; + } + // TODO Find and delete cintent file and related records + + return 'Logo image deleted'; + } + // Include or exclude logo image into grant application + @AuraEnabled + public static String includeLogo(String recordId, Boolean state){ + GGW_Grant_Application__c app = new GGW_Grant_Application__c(); + app.Id = recordId; + app.Include_Logo__c = state; + if(Schema.sObjectType.GGW_Grant_Application__c.isUpdateable()){ + update app; + } + return 'Application logo updated'; + } private static String getValidLogoURL(GGW_Grant_Application__c grant){ String logourl = null; diff --git a/force-app/main/default/classes/GGW_ApplicationCtrlTest.cls b/force-app/main/default/classes/GGW_ApplicationCtrlTest.cls index 3e87083..952a8a0 100644 --- a/force-app/main/default/classes/GGW_ApplicationCtrlTest.cls +++ b/force-app/main/default/classes/GGW_ApplicationCtrlTest.cls @@ -15,6 +15,25 @@ public class GGW_ApplicationCtrlTest { GGW_TestDataFactory.createGrantContentTestData(); } + @isTest + static void includeLogoTest(){ + GGW_Grant_Application__c app = GGW_ApplicationCtrl.newGrant('MyTest Grant', sections); + + Test.startTest(); + + Test.stopTest(); + + } + @isTest + static void deleteLogoTest(){ + GGW_Grant_Application__c app = GGW_ApplicationCtrl.newGrant('MyTest Grant', sections); + + Test.startTest(); + + + Test.stopTest(); + + } @isTest static void testNewGrant(){ // Query all suggested sections diff --git a/force-app/main/default/classes/GGW_Util.cls b/force-app/main/default/classes/GGW_Util.cls index 66e8423..64fe3fd 100644 --- a/force-app/main/default/classes/GGW_Util.cls +++ b/force-app/main/default/classes/GGW_Util.cls @@ -25,7 +25,7 @@ public without sharing class GGW_Util { } 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 + DistributionPublicUrl__c, Status__c, Description__c, Language__c, Include_Logo__c FROM GGW_Grant_Application__c WHERE Id =: appId WITH SECURITY_ENFORCED LIMIT 1]; } diff --git a/force-app/main/default/layouts/GGW_Grant_Application__c-Grant Application Layout.layout-meta.xml b/force-app/main/default/layouts/GGW_Grant_Application__c-Grant Application Layout.layout-meta.xml index 1543308..11d4490 100644 --- a/force-app/main/default/layouts/GGW_Grant_Application__c-Grant Application Layout.layout-meta.xml +++ b/force-app/main/default/layouts/GGW_Grant_Application__c-Grant Application Layout.layout-meta.xml @@ -25,21 +25,25 @@ Edit - Logo_Download_Url__c + Language__c + + Edit - DistributionPublicUrl__c + OwnerId Edit - Language__c + Include_Logo__c - - Edit - OwnerId + Logo_Download_Url__c + + + Edit + DistributionPublicUrl__c @@ -107,7 +111,7 @@ false false - 00h0R000008ilih + 00h01000002bd1h 4 0 Default diff --git a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html index de3387e..75398f1 100644 --- a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html +++ b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html @@ -60,6 +60,30 @@

+ + +
+ + + + + + +
diff --git a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js index f8e6643..0d846a1 100644 --- a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js +++ b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js @@ -8,6 +8,8 @@ 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 includeLogo from '@salesforce/apex/GGW_ApplicationCtrl.includeLogo'; +import deleteLogo from '@salesforce/apex/GGW_ApplicationCtrl.deleteLogo'; import createContentDistribution from '@salesforce/apex/GGW_ApplicationCtrl.createContentDistribution'; import { ShowToastEvent } from 'lightning/platformShowToastEvent'; //import { updateRecord } from 'lightning/uiRecordApi'; @@ -27,6 +29,7 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen @api grantName; @api contentDownloadUrl;// = 'https://data-drive-2030-dev-ed.file.force.com/sfc/dist/version/renditionDownload?rendition=ORIGINAL_Png&versionId=0680R000001qFvW&operationContext=DELIVERY&contentId=05T0R0000069df5&page=0&d=/a/0R0000008lyn/kf5IDPjQuijS940z47u73Rnb2zSvfmkdSXUpc5S2oSU&oid=00D0R000000nmUQ&dpt=null&viewId='; @api language = 'en_US'; + @track logoState = false; // Exclude or include logo noLogoDisplay = true; // Display empty avatar instead of logo displayTitle; status; @@ -46,6 +49,7 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen showCard = true; // Display Editor card if data grant exists ELSE show illustration @track grantRecordPage = GRANT_RECORD_PAGE_URL; @track currentPageReference; + @wire(CurrentPageReference) setCurrentPageReference(currentPageReference) { this.currentPageReference = currentPageReference; @@ -59,7 +63,57 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen this.displayGrantCard(); this.queryGrantApplication(); } + + handleLogoSelectorClick() { + this.logoState = !this.logoState; + includeLogo({recordId: this.recordId, state: this.logoState}) + .then((data) => { + console.log(`Logo state was updated ${this.logoState}`); + this.error = undefined; + const evt = new ShowToastEvent({ + title: this._title, + message: `${data} ${this.logoState ? 'included' : 'excluded'}`, + variant: 'success', + }); + this.dispatchEvent(evt); + + }) + .catch((error) => { + console.log(error); + this.error = error; + const evt = new ShowToastEvent({ + title: this._title, + message: 'Logo selection error.', + variant: 'error', + }); + this.dispatchEvent(evt); + }); + } + handleLogoDelete(event){ + deleteLogo({recordId: this.recordId}) + .then((data) => { + console.log(`Logo file was deleted`); + this.error = undefined; + const evt = new ShowToastEvent({ + title: this._title, + message: data, + variant: 'success', + }); + this.dispatchEvent(evt); + }) + .catch((error) => { + console.log(error); + this.error = error; + const evt = new ShowToastEvent({ + title: this._title, + message: 'Logo file delete error.', + variant: 'error', + }); + this.dispatchEvent(evt); + }); + + } reloadSections(){ this.queryGrantApplication(); } @@ -91,7 +145,7 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen createContentDistribution({grantId: this.recordId, cvid: uploadedFiles[0].contentVersionId}) .then((data) => { console.log('URL: '+data); - alert('IMAGE URL: ' + data); + //alert('IMAGE URL: ' + data); this.contentDownloadUrl = data; this.noLogoDisplay = false; this.error = undefined; diff --git a/force-app/main/default/objects/GGW_Grant_Application__c/fields/Include_Logo__c.field-meta.xml b/force-app/main/default/objects/GGW_Grant_Application__c/fields/Include_Logo__c.field-meta.xml new file mode 100644 index 0000000..61eebba --- /dev/null +++ b/force-app/main/default/objects/GGW_Grant_Application__c/fields/Include_Logo__c.field-meta.xml @@ -0,0 +1,11 @@ + + + Include_Logo__c + false + This boolean TRU/FALSE field indicates if log be included or not in final application + false + This boolean TRU/FALSE field indicates if log be included or not in final application + + false + Checkbox + diff --git a/force-app/main/default/permissionsets/GGW_User_Permissions.permissionset-meta.xml b/force-app/main/default/permissionsets/GGW_User_Permissions.permissionset-meta.xml index 8d4f235..58e86a0 100644 --- a/force-app/main/default/permissionsets/GGW_User_Permissions.permissionset-meta.xml +++ b/force-app/main/default/permissionsets/GGW_User_Permissions.permissionset-meta.xml @@ -127,6 +127,11 @@ GGW_Grant_Application__c.DistributionPublicUrl__c true + + true + GGW_Grant_Application__c.Include_Logo__c + true + true GGW_Grant_Application__c.Language__c From 172b7ac33b1d9ce2d68eeda272db02c55a825901 Mon Sep 17 00:00:00 2001 From: Igor Androsov Date: Tue, 19 Dec 2023 19:46:27 +0900 Subject: [PATCH 4/6] Add logo delete feature, clean up LWC, update APEX Unit tests --- .../default/classes/GGW_ApplicationCtrl.cls | 42 ++- .../classes/GGW_ApplicationCtrlTest.cls | 106 +++++- .../main/default/classes/GGW_ExportCtrl.cls | 5 + .../classes/GGW_GrantApplicationWrapper.cls | 1 + .../ggwGrantApplication.html | 51 +-- .../ggwGrantApplication.js | 305 ++++++------------ .../main/default/pages/GGW_GrantPreview.page | 7 +- .../default/pages/GGW_GrantPreviewPdf.page | 7 +- .../default/pages/GGW_GrantPreviewWord.page | 6 +- 9 files changed, 281 insertions(+), 249 deletions(-) diff --git a/force-app/main/default/classes/GGW_ApplicationCtrl.cls b/force-app/main/default/classes/GGW_ApplicationCtrl.cls index 3c6bb1d..af7bd77 100644 --- a/force-app/main/default/classes/GGW_ApplicationCtrl.cls +++ b/force-app/main/default/classes/GGW_ApplicationCtrl.cls @@ -24,6 +24,7 @@ public without sharing class GGW_ApplicationCtrl { GGW_GrantApplicationWrapper app = new GGW_GrantApplicationWrapper(); if(!appItems.isEmpty()){ app.recordid = grant.Id; + app.logostate = grant.Include_Logo__c; app.logodisplayurl = getValidLogoURL(grant); app.name = appItems[0].Application_Name__c; app.status = appItems[0].Grant_Application__r.Status__c; @@ -39,12 +40,13 @@ public without sharing class GGW_ApplicationCtrl { app.Id = recordId; app.DistributionPublicUrl__c = null; // Logo public URL app.Logo_Download_Url__c = null; // Logo display URL + app.Include_Logo__c = false; // Check object CRUD if(Schema.sObjectType.GGW_Grant_Application__c.isUpdateable()){ update app; } - // TODO Find and delete cintent file and related records - + // Find and delete content file and related records + deleteImageLogo(recordId); return 'Logo image deleted'; } // Include or exclude logo image into grant application @@ -59,6 +61,24 @@ public without sharing class GGW_ApplicationCtrl { return 'Application logo updated'; } + private static void deleteImageLogo(String recordId){ + ContentDocumentLink cdl = [SELECT Id, LinkedEntityId, ContentDocumentId, IsDeleted, Visibility, ShareType + FROM ContentDocumentLink + WHERE LinkedEntityId =: recordId WITH SECURITY_ENFORCED]; + + ContentDistribution cntdistr = [SELECT Id, Name, ContentVersionId, ContentDocumentId, RelatedRecordId, ContentDownloadUrl + FROM ContentDistribution + WHERE ContentDocumentId =: cdl.ContentDocumentId WITH SECURITY_ENFORCED]; + + ContentDocument cd = new ContentDocument(); + cd.Id = cdl.ContentDocumentId; + if(Schema.sObjectType.ContentDistribution.isDeletable()){ + delete cntdistr; + } + if(Schema.sObjectType.ContentDocument.isDeletable()){ + delete cd; + } + } private static String getValidLogoURL(GGW_Grant_Application__c grant){ String logourl = null; if(grant != null && grant.Logo_Download_Url__c != null){ @@ -312,15 +332,6 @@ public without sharing class GGW_ApplicationCtrl { } */ - // Utility selector method - public static List querySelectedItemsByGrant(String appId){ - List appItems = [SELECT Id, Application_Name__c, Grant_Application__c, GGW_Section__c, - Section_Name__c,Selected_Block__c, Sort_Order__c, Grant_Application__r.Status__c, - Selected_Block__r.Description__c, Text_Block__c, Language__c - FROM GGW_Selected_Item__c - WHERE Grant_Application__c =: appId WITH SECURITY_ENFORCED ORDER BY Sort_Order__c]; - return appItems; - } /** * Method to create a new ContentBlock add to section as part a library to later reuse * on other Grant applications. @@ -544,6 +555,15 @@ public without sharing class GGW_ApplicationCtrl { } ///--- BASIC SELECTOR METHODS + public static List querySelectedItemsByGrant(String appId){ + List appItems = [SELECT Id, Application_Name__c, Grant_Application__c, GGW_Section__c, + Section_Name__c,Selected_Block__c, Sort_Order__c, Grant_Application__r.Status__c, + Selected_Block__r.Description__c, Text_Block__c, Language__c + FROM GGW_Selected_Item__c + WHERE Grant_Application__c =: appId WITH SECURITY_ENFORCED ORDER BY Sort_Order__c]; + return appItems; + } + private static List querySectionsByLanguage(String lang){ List sectionList = [SELECT Id, Name, CreatedDate, Recommended__c, Suggested__c, Sort_Order__c, Language__c diff --git a/force-app/main/default/classes/GGW_ApplicationCtrlTest.cls b/force-app/main/default/classes/GGW_ApplicationCtrlTest.cls index 952a8a0..0fc8da7 100644 --- a/force-app/main/default/classes/GGW_ApplicationCtrlTest.cls +++ b/force-app/main/default/classes/GGW_ApplicationCtrlTest.cls @@ -17,22 +17,120 @@ public class GGW_ApplicationCtrlTest { @isTest static void includeLogoTest(){ + // 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('MyTest Grant', sections); Test.startTest(); - + String msg = GGW_ApplicationCtrl.includeLogo(app.Id, true); Test.stopTest(); + System.assertEquals('Application logo updated', msg, 'Invalid message returnd for Logo include into Grant'); + GGW_GrantApplicationWrapper grant = GGW_ApplicationCtrl.getApplication(app.Id); + System.assertEquals(app.Id, grant.recordid, 'Invalid grant application Id'); + System.assertEquals(true, grant.logostate, 'Logo include state is not valid'); } - @isTest - static void deleteLogoTest(){ + static void excludeLogoTest(){ + // 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('MyTest Grant', sections); Test.startTest(); + String msg = GGW_ApplicationCtrl.includeLogo(app.Id, false); + Test.stopTest(); + + System.assertEquals('Application logo updated', msg, 'Invalid message returnd for Logo include into Grant'); + GGW_GrantApplicationWrapper grant = GGW_ApplicationCtrl.getApplication(app.Id); + System.assertEquals(app.Id, grant.recordid, 'Invalid grant application Id'); + System.assertEquals(false, grant.logostate, 'Logo exclude state is not valid'); + } + + @isTest + static void deleteLogoTest(){ + // 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 Logo delete Test', sections); + + //ContentDocument cdoc = new ContentDocument(); + //cdoc.Title = 'Grant test logo'; + //insert cdoc; + + ContentVersion cvo = new Contentversion(); + //cvo.ContentDocumentId = cdoc.Id; + cvo.Title = 'Test Content file'; + cvo.PathOnClient = 'test'; + cvo.VersionData = EncodingUtil.base64Decode('Unit Test Attachment Body'); + //List cvl = new List(); + //cvl.add(cvo); + insert cvo; + + ContentVersion cvtmp = [SELECT Id, Title, ContentDocumentId FROM ContentVersion WHERE Id =: cvo.Id]; + // Create content document Link + ContentDocumentLink cdl = new ContentDocumentLink(); + cdl.LinkedEntityId = app.Id; + cdl.ContentDocumentId = cvtmp.ContentDocumentId; + insert cdl; + String downloadURL = GGW_ApplicationCtrl.createContentDistribution(app.Id, cvo.Id); + + Test.startTest(); + String result = GGW_ApplicationCtrl.deleteLogo(app.Id); Test.stopTest(); - + System.assertEquals('Logo image deleted', result, 'Logo delete is not valid'); + + } + @isTest + static void createContentDistributionTest(){ + // 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('Content Distribution Test', sections); + ContentVersion cvo = new Contentversion(); + cvo.Title = 'Test Content file'; + cvo.PathOnClient = 'test'; + cvo.VersionData = EncodingUtil.base64Decode('Unit Test Attachment Body'); + insert cvo; + ContentVersion cvtmp = [SELECT Id, Title, ContentDocumentId FROM ContentVersion WHERE Id =: cvo.Id]; + // Create content document Link + ContentDocumentLink cdl = new ContentDocumentLink(); + cdl.LinkedEntityId = app.Id; + cdl.ContentDocumentId = cvtmp.ContentDocumentId; + insert cdl; + + Test.startTest(); + String downloadURL = GGW_ApplicationCtrl.createContentDistribution(app.Id, cvo.Id); + Test.stopTest(); + + System.assertNotEquals(null, downloadURL, 'Contenet distribution is invalid'); + GGW_GrantApplicationWrapper grant = GGW_ApplicationCtrl.getApplication(app.Id); + System.assertEquals(downloadURL, grant.logodisplayurl, 'Logo download URL is not valid'); + } @isTest static void testNewGrant(){ diff --git a/force-app/main/default/classes/GGW_ExportCtrl.cls b/force-app/main/default/classes/GGW_ExportCtrl.cls index 89393cd..2e464a8 100644 --- a/force-app/main/default/classes/GGW_ExportCtrl.cls +++ b/force-app/main/default/classes/GGW_ExportCtrl.cls @@ -11,10 +11,12 @@ public without sharing class GGW_ExportCtrl { public String recordId {get; set;} public String appName {get;set;} public String logoURL {get; set;} + public Boolean isDisplayLogo {get; set;} public List items {get; set;} private final GGW_Grant_Application__c app; public GGW_ExportCtrl(ApexPages.StandardController stdController) { + this.isDisplayLogo = false; this.app = (GGW_Grant_Application__c)stdController.getRecord(); if(this.app != null && this.app.Id != null){ this.recordId = this.app.Id; @@ -36,6 +38,9 @@ public without sharing class GGW_ExportCtrl { GGW_Grant_Application__c app = GGW_Util.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){ + this.isDisplayLogo = true; + } } this.items = GGW_Util.getSelectedItems(this.recordId.escapeHtml4()); diff --git a/force-app/main/default/classes/GGW_GrantApplicationWrapper.cls b/force-app/main/default/classes/GGW_GrantApplicationWrapper.cls index 6b49593..1d03dcf 100644 --- a/force-app/main/default/classes/GGW_GrantApplicationWrapper.cls +++ b/force-app/main/default/classes/GGW_GrantApplicationWrapper.cls @@ -13,6 +13,7 @@ public class GGW_GrantApplicationWrapper { @AuraEnabled public String name; @AuraEnabled public String status; @AuraEnabled public String logodisplayurl; + @AuraEnabled public Boolean logostate; @AuraEnabled public String language; @AuraEnabled public List unselectSectionList; // Used to add new sections to Grant @AuraEnabled public List selectedContentBlock; // Include Section and Text block diff --git a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html index 75398f1..7b3f437 100644 --- a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html +++ b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.html @@ -61,30 +61,31 @@

- -
- - - - - - -
-
+ @@ -100,7 +101,7 @@

selected-item-id={sec.selecteditem} sectioncount={sec.sectioncount} sortorder={sec.sortorder} - onselectedtext={hanldeSelectedTextChange} + onselectedtext={handleSelectedTextChange} ondeletesection={handleDeleteSection} key={sec.value} > diff --git a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js index 0d846a1..d164fab 100644 --- a/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js +++ b/force-app/main/default/lwc/ggwGrantApplication/ggwGrantApplication.js @@ -12,11 +12,6 @@ import includeLogo from '@salesforce/apex/GGW_ApplicationCtrl.includeLogo'; import deleteLogo from '@salesforce/apex/GGW_ApplicationCtrl.deleteLogo'; import createContentDistribution from '@salesforce/apex/GGW_ApplicationCtrl.createContentDistribution'; import { ShowToastEvent } from 'lightning/platformShowToastEvent'; -//import { updateRecord } from 'lightning/uiRecordApi'; -//import { getRecord } from 'lightning/uiRecordApi'; -//import ID_FIELD from '@salesforce/schema/GGW_Grant_Application__c.Id'; -//import GRANTNAME_FIELD from '@salesforce/schema/GGW_Grant_Application__c.Name'; -//import {refreshApex} from '@salesforce/apex'; const GRANT_TITLE = 'Grant Application'; const GRANT_TITLE_HEADER = 'Grant Application:'; @@ -30,6 +25,7 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen @api contentDownloadUrl;// = 'https://data-drive-2030-dev-ed.file.force.com/sfc/dist/version/renditionDownload?rendition=ORIGINAL_Png&versionId=0680R000001qFvW&operationContext=DELIVERY&contentId=05T0R0000069df5&page=0&d=/a/0R0000008lyn/kf5IDPjQuijS940z47u73Rnb2zSvfmkdSXUpc5S2oSU&oid=00D0R000000nmUQ&dpt=null&viewId='; @api language = 'en_US'; @track logoState = false; // Exclude or include logo + @track showLogoButtons = false; noLogoDisplay = true; // Display empty avatar instead of logo displayTitle; status; @@ -50,6 +46,23 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen @track grantRecordPage = GRANT_RECORD_PAGE_URL; @track currentPageReference; + showToastSuccess(msg){ + const evt = new ShowToastEvent({ + title: this._title, + message: msg, + variant: 'success', + }); + this.dispatchEvent(evt); + } + showToastError(msg){ + const evt = new ShowToastEvent({ + title: this._title, + message: msg, + variant: 'error', + }); + this.dispatchEvent(evt); + } + @wire(CurrentPageReference) setCurrentPageReference(currentPageReference) { this.currentPageReference = currentPageReference; @@ -70,53 +83,37 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen .then((data) => { console.log(`Logo state was updated ${this.logoState}`); this.error = undefined; - const evt = new ShowToastEvent({ - title: this._title, - message: `${data} ${this.logoState ? 'included' : 'excluded'}`, - variant: 'success', - }); - this.dispatchEvent(evt); - + this.showToastSuccess(`${data} ${this.logoState ? 'included' : 'excluded'}`); }) .catch((error) => { console.log(error); this.error = error; - const evt = new ShowToastEvent({ - title: this._title, - message: 'Logo selection error.', - variant: 'error', - }); - this.dispatchEvent(evt); + this.showToastError('Logo selection error.'); }); } + handleLogoDelete(event){ deleteLogo({recordId: this.recordId}) .then((data) => { console.log(`Logo file was deleted`); this.error = undefined; - const evt = new ShowToastEvent({ - title: this._title, - message: data, - variant: 'success', - }); - this.dispatchEvent(evt); + this.logoState = false; // OFF Include button on editor page + this.showLogoButtons = false; // remove logo manage buttons + this.noLogoDisplay = true; + this.showToastSuccess(data); }) .catch((error) => { console.log(error); this.error = error; - const evt = new ShowToastEvent({ - title: this._title, - message: 'Logo file delete error.', - variant: 'error', - }); - this.dispatchEvent(evt); + this.showToastError('Logo file delete error.'); }); - } + reloadSections(){ this.queryGrantApplication(); } + displayGrantCard(){ if(this.recordId != null){ this.showCard = true; // SHo current Grant @@ -124,10 +121,12 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen this.showCard = false; // Display Illustration NO Grant Data yet } } + closeModal() { this.dispatchEvent(new CloseActionScreenEvent()); this.openModal = false; } + // This methods used for Logo image uploads accept only png or jpg files get acceptedFormats() { return ['.jpg', '.png']; } @@ -148,6 +147,7 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen //alert('IMAGE URL: ' + data); this.contentDownloadUrl = data; this.noLogoDisplay = false; + this.showLogoButtons = true; this.error = undefined; }) .catch((error) => { @@ -155,8 +155,8 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen this.error = error; this.noLogoDisplay = true; }); - } + handleExportMenuSelect(event){ const selectedItemValue = event.detail.value; console.log('## handleExportMenuSelect: '+selectedItemValue); @@ -169,8 +169,8 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen if(selectedItemValue == 'exportHTML'){ this.exportGrantVFHTML(); } - } + exportGrantVFHTML(){ this[NavigationMixin.Navigate]({ type: 'standard__navItemPage', @@ -182,8 +182,8 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen c__format: 'html' // Need this state object to pass parameters in LEX } // LEX will strip all parameters such as recordID so must add c__recordId }); - } + exportGrantVFWord(){ // Tab name - Grant Preview Word this[NavigationMixin.Navigate]({ @@ -192,15 +192,14 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen apiName: 'Grant_Preview_Word' }, state: { - c__recordId: this.recordId // Need this state object to pass parameters in LEX + c__recordId: this.recordId, // Need this state object to pass parameters in LEX + c__format: 'word' } // LEX will strip all parameters such as recordID so must add c__recordId }); - } - exportGrantVFPdf(){ - //this.grantPageURL = '/apex/GGW_GrantPreview?c__recordId='+this.recordId; - //this.openVFPExportModal = true; + exportGrantVFPdf(){ + // Tab Name - Grant_Preview_PDF this[NavigationMixin.Navigate]({ type: 'standard__navItemPage', attributes: { @@ -211,29 +210,61 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen c__format: 'pdf' } // LEX will strip all parameters such as recordID so must add c__recordId }); -/* - this[NavigationMixin.GenerateUrl]({ - type: 'standard__webPage', - attributes: { - url: this.grantPageURL - } - }).then(generatedUrl => { - window.open(generatedUrl); - }); -*/ } + closePDFModal(){ this.openVFPExportModal = false; } - - queryGrantApplication(){ + + setLogoDisplay(logoUrl){ + if (logoUrl != null){ + this.contentDownloadUrl = logoUrl; // load display URL logo + this.noLogoDisplay = false; + this.showLogoButtons = true; + }else{ + this.noLogoDisplay = true; + this.showLogoButtons = false; + } + } + + setDisplayTitle(name){ + if(name){ + this.displayTitle = ` ${GRANT_TITLE_HEADER} ${name}`; + }else{ + this.displayTitle = GRANT_TITLE_ERROR; + } + } + + setSectionsFromArray(selectedContentBlock){ + if (selectedContentBlock){ + this.sectioncount = selectedContentBlock.length; + for(var i = 0; i < selectedContentBlock.length; i++) { + var item = selectedContentBlock[i]; + var tmpText = item.displaytext ? item.displaytext : 'Text placeholder'; // Set text value condition for null + this.sections = [...this.sections ,{label: item.sectionname, + displaytitle: '['+item.sortorder+'] ' + item.sectionname, + value: item.sectionid, // sfid for Section record + appid: this.recordId, // Id for Grant Application record + hasblocks: true, + sectioncount: this.sectioncount, // pass number of sections to LWC for sorting + sortorder: item.sortorder, + selecteditem: item.selecteditemid, + blockid: item.recordid, // sfid for Content Block record + textblock: tmpText} ]; + + console.log(`Text: ${item.displaytext}`); + } + // Save temp section value + this.currentSections = this.sections; + } + } + + queryGrantApplication() { // --- Need this timeout delay to allow record ID from Quick Action on record page to be set // For some crazy reason LEX/LWC does not init record ID fast enough to init this call setTimeout(() => { console.log(`queryGrantApplication: Init App with ID: ${this.recordId}`); - //this.displayTitle = 'Grant Application: ' + this.grant.data ? this.grant.data.fields.Name.value : null; - - // Change to call imperative insted of wire for data refreshes + // Change to call imperative instead of wire for data refreshes getApplication({recordId: this.recordId}) .then((data) => { console.log(`queryGrantApplication: Grant Name: ${data.name}`); @@ -241,47 +272,17 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen this.currentSections = []; this.recordId = data.recordid; // reset record ID from data in some navi patterns URL parameters can be null this.grantName = data.name; - // Init recrd page URL + this.logoState = data.logostate; + // Init record page URL this.grantRecordPage = `${GRANT_RECORD_PAGE_URL}${this.recordId}/view`; - - // Conditianal display of logo if it is available or show empty placeholder image - if (data.logodisplayurl != null){ - this.contentDownloadUrl = data.logodisplayurl; // load display URL logo - this.noLogoDisplay = false; - }else{ - this.noLogoDisplay = true; - } - this.displayGrantCard(); // nadle UX display fo main card or illustration NO Data - if(data.name){ - this.displayTitle = ` ${GRANT_TITLE_HEADER} ${data.name}`; - }else{ - this.displayTitle = GRANT_TITLE_ERROR; - } + // Conditional display of logo if it is available or show empty placeholder image + this.setLogoDisplay(data.logodisplayurl); + this.displayGrantCard(); // handle UX display fo main card or illustration NO Data + this.setDisplayTitle(data.name) this.status = data.status; - - if (data.selectedContentBlock){ - this.sectioncount = data.selectedContentBlock.length; - for(var i=0; i { console.log(error); @@ -290,12 +291,13 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen this.displayTitle = GRANT_TITLE_ERROR; }); }, 5); - } + } + // when the component is first initialized assign an initial value to sections and other Grant App variables connectedCallback() { this.queryGrantApplication(); - //this.sections = this.currentSections; } + handleDeleteSection(){ // Section - selected item data has been deleted by Section component action // here we only refresh UI/UX @@ -303,45 +305,27 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen this.queryGrantApplication(); this.sections = this.currentSections; } + // Open section Modal to reorder reorderSections(){ - console.log('REORDER MODAL for App: '+this.recordId); + console.log(`REORDER MODAL for App: ${this.recordId}`); this.openModal = true; } - hanldeSelectedTextChange(event){ + handleSelectedTextChange(event){ //this.textBlock = event.detail; - console.log('hanldeSelectedTextChange: Section:'+event.detail.section+' TXT: '+event.detail.text+' BlockID:'+event.detail.blockid); - // Display toaster message - /* - const evt = new ShowToastEvent({ - title: this._title, - message: 'Section:'+event.detail.section+' TXT: '+event.detail.text+' BlockID:'+event.detail.blockid, - variant: this.variant, - }); - this.dispatchEvent(evt); - */ + console.log(`handleSelectedTextChange: Section: ${event.detail.section} TXT: ${event.detail.text} BlockID: ${event.detail.blockid}`); } updateGrant(){ - /* - console.log('Show Text Block:'+this.sections[0].textblock); - // Display toaster message - const evt = new ShowToastEvent({ - title: this._title, - message: 'Show Text Block:'+this.sections[0].textblock, - variant: this.variant, - }); - this.dispatchEvent(evt); - */ this.closeModal(); } // Order section change handleSectionOrderChange(event){ // TODO There strange problem refresh of section list is late even data is reloaded - // Modal Action box still not refresh, for now solve close box repoen will show new order. - console.log('handleSectionOrderChange: ORDER Change event:'+this.recordId); + // Modal Action box still not refresh, for now workaround close box reopen will show new order. + console.log(`handleSectionOrderChange: ORDER Change event: ${this.recordId}`); // Arange new order sections on UI on client side // refreshApex(this.handleLoad()); // Close modal @@ -349,93 +333,10 @@ export default class GgwGrantApplication extends NavigationMixin(LightningElemen this.closeModal(); if(event.detail.items){ // Display toaster message if data was updated - const evt = new ShowToastEvent({ - title: this._title, - message: 'Updated grant sections order or add new section', - variant: this.variant, - }); - this.dispatchEvent(evt); + showToastSuccess(`Updated grant sections order or add new section`); } // Reload data this.queryGrantApplication(); this.sections = this.currentSections; } - - /* This standard call is replaced by Apex method getApplication with related blocks sections. - @wire(getRecord, {recordId: '$recordId',fields: [GRANTNAME_FIELD]}) - wireGrantApp({error,data}){ - if (data) { - console.log('Grant Name: '+data.fields.Name.value); - this.grantName = data.fields.Name.value; - this.displayTitle = 'Grant Application: ' + data.fields.Name.value; - this.error = undefined; - }else if(error){ - console.log(error); - this.error = error; - //this.sections = undefined; - }else{ - // eslint-disable-next-line no-console - console.log('unknown error'); - } - } - */ - - -/* -- Need to to update data and cache=true does not fit here swicth using connected Callback with a GACKy Hack - @wire(getApplication, {recordId: '$recordId'}) - wireApplication({error,data}){ - if (data) { - console.log('Grant Name: '+data.name); - this.grantName = data.name; - this.displayTitle = 'Grant Application: ' + data.name; - this.status = data.status; - if (data.selectedContentBlock){ - for(var i=0; i - Grant Logo -
+ + Grant Logo +
+
+

{!appName}

diff --git a/force-app/main/default/pages/GGW_GrantPreviewPdf.page b/force-app/main/default/pages/GGW_GrantPreviewPdf.page index 81a9bd3..be0e14d 100644 --- a/force-app/main/default/pages/GGW_GrantPreviewPdf.page +++ b/force-app/main/default/pages/GGW_GrantPreviewPdf.page @@ -9,9 +9,10 @@ - - Grant Logo -
+ + Grant Logo +
+

{!appName}

diff --git a/force-app/main/default/pages/GGW_GrantPreviewWord.page b/force-app/main/default/pages/GGW_GrantPreviewWord.page index 2ffac2e..d34f682 100644 --- a/force-app/main/default/pages/GGW_GrantPreviewWord.page +++ b/force-app/main/default/pages/GGW_GrantPreviewWord.page @@ -10,8 +10,10 @@ - Grant Logo -
+ + Grant Logo +
+

{!appName} From bb7ba248c933f26b931175b517c397fc9f0373ba Mon Sep 17 00:00:00 2001 From: Igor Androsov Date: Thu, 21 Dec 2023 19:18:53 +0900 Subject: [PATCH 5/6] Issue #25 Update sample data --- .../main/default/staticresources/GGWSectionData.json | 12 ++++++------ test-data/export-data-GGW_Section__cs.json | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/force-app/main/default/staticresources/GGWSectionData.json b/force-app/main/default/staticresources/GGWSectionData.json index 3bc98f8..0fd011a 100644 --- a/force-app/main/default/staticresources/GGWSectionData.json +++ b/force-app/main/default/staticresources/GGWSectionData.json @@ -63,10 +63,10 @@ { "attributes": { "type": "GGW_Section__c", - "referenceId": "GGW_Section__cRef6" + "referenceId": "GGW_Section__cRef7" }, - "Name": "Plan of action", - "Recommended": true, + "Name": "Goals and objectives", + "Recommended": false, "Section_Details": null, "Sort_Order": 6, "Suggested": true, @@ -75,10 +75,10 @@ { "attributes": { "type": "GGW_Section__c", - "referenceId": "GGW_Section__cRef7" + "referenceId": "GGW_Section__cRef6" }, - "Name": "Goals and objectives", - "Recommended": false, + "Name": "Plan of action", + "Recommended": true, "Section_Details": null, "Sort_Order": 7, "Suggested": true, diff --git a/test-data/export-data-GGW_Section__cs.json b/test-data/export-data-GGW_Section__cs.json index 1204310..80238a5 100644 --- a/test-data/export-data-GGW_Section__cs.json +++ b/test-data/export-data-GGW_Section__cs.json @@ -58,10 +58,10 @@ { "attributes": { "type": "GGW_Section__c", - "referenceId": "GGW_Section__cRef6" + "referenceId": "GGW_Section__cRef7" }, - "Name": "Plan of action", - "Recommended__c": true, + "Name": "Goals and objectives", + "Recommended__c": false, "Section_Details__c": null, "Sort_Order__c": 6, "Suggested__c": true @@ -69,10 +69,10 @@ { "attributes": { "type": "GGW_Section__c", - "referenceId": "GGW_Section__cRef7" + "referenceId": "GGW_Section__cRef6" }, - "Name": "Goals and objectives", - "Recommended__c": false, + "Name": "Plan of action", + "Recommended__c": true, "Section_Details__c": null, "Sort_Order__c": 7, "Suggested__c": true From 3d9ed133fe250f57a3dbc464ca283b059bd32791 Mon Sep 17 00:00:00 2001 From: Igor Androsov Date: Fri, 22 Dec 2023 19:21:10 +0900 Subject: [PATCH 6/6] Add content blocks and sections sample data --- .../staticresources/GGWContentBlockData.json | 124 +++++++++++++--- .../staticresources/GGWSectionData.json | 99 +++++++------ scripts/dx/dxorg | 2 +- .../sample-data-GGW_Content_Block__cs.json | 134 ++++++++++++++++++ ..._Section__c-GGW_Content_Block__c-plan.json | 18 +++ test-data/sample-data-GGW_Section__cs.json | 103 ++++++++++++++ 6 files changed, 418 insertions(+), 62 deletions(-) create mode 100644 test-data/sample-data-GGW_Content_Block__cs.json create mode 100644 test-data/sample-data-GGW_Section__c-GGW_Content_Block__c-plan.json create mode 100644 test-data/sample-data-GGW_Section__cs.json diff --git a/force-app/main/default/staticresources/GGWContentBlockData.json b/force-app/main/default/staticresources/GGWContentBlockData.json index d0a9787..d076f40 100644 --- a/force-app/main/default/staticresources/GGWContentBlockData.json +++ b/force-app/main/default/staticresources/GGWContentBlockData.json @@ -4,43 +4,129 @@ "type": "GGW_Content_Block__c", "referenceId": "GGW_Content_Block__cRef1" }, - "Name": "[SAMPLE CONTENT] - Grow Austin", - "Description": "

SAMPLE CONTENT - Grow Austin aims at improving the overall quality of life of Texas residents by providing education and resources to engage citizens in building more beautiful communities. What started out as a neighborhood project 10 years ago has developed into a 10 person team of dedicated staff serving the greater Austin area and surrounding counties.

Through organized volunteer events and annual programs, GA provides communities with the tools they need to improve their overall community and build a better future for themselves and their neighbors. We provide communities with resources that teach them about necessary information to their environments such as sustainable gardening, native plants and composting. GA also helps coordinate and host large volunteer events to quickly transform spaces in Austin such as vacant lots or overrun trail passes. All with the 'better together' focus in mind, encouraging community involvement and engagement.

With inclusivity at its core, GA offers a wide variety of programs that cater to various groups of individuals. We want individuals to find a home at Beautify Austin and to do that we offer many different programs that we feel can check off one or more volunteer interests.

Grow Austin believes that communities hold the power to keep their neighborhoods clean and thriving. In 2021, over 1000 volunteers participated in the Grow Austin programs, filling over 2000 recycling bags. Grow Austin also did its part of educating and supporting Austin citizens by supplying families with over 350 seed packets for sustainable gardening and tallying over 500 hours with educational seminars and videos.

", - "Section": "GGW_Section__cRef3", - "Short_Description": "Grow Austin aims at improving the overall quality of life of Texas residents", - "Language": "en_US" + "Name": "Program narrative text", + "Description__c": "

SAMPLE CONTENT - [ORG NAME] primarily focuses on beautification and improvement of parks and would like to expand into improving natural waterways. [ORG NAME] plans to build the clean water program over time with education and raising awareness; then, gradually move into organizing volunteers and special volunteer events. Many communities lack public and clean swimming areas for citizens to cool off during the hot summer months. The goal of this new program is to improve natural water sources to make them clean, safe, and accessible.


Similar to our [EXISTING PROGRAM NAME] program, [ORG NAME] plans to start by determining community interest and understanding, and then, expand the program once key success metrics have been established. The clean water program will strive to improve local streams and lakes to make them more accessible and usable for communities. 

", + "Section__c": "@GGW_Section__cRef1", + "Short_Description__c": "SAMPLE CONTENT - [ORG NAME] primarily focuses on beautification and improvement of parks" }, { "attributes": { "type": "GGW_Content_Block__c", "referenceId": "GGW_Content_Block__cRef2" }, - "Name": "[SAMPLE CONTENT] - Goal 1", - "Description": "

SAMPLE CONTENT - Goal 1: Officially launch Clean Water Pilot Program


Key Activities: We will hire a Managing Director by November 2022 who will be responsible for partnership development and local program implementation. We have identified several potential locations to pilot the Clean Water Program at, all within 1 mile of our home office and have secured a team of volunteers to see the pilot from start to finish. The pilot program will select 1 stream as the focus of the pilot and during a 4 month period will host 2 cleanup efforts, 1 community outreach event and 1 online campaign. After the 4 months have completed, the committee consisting of 2 volunteers from the pilot committee and 3 Beautify Austin board members, will meet and assess the future of the program. 


Desired Outcomes:

Two cleanup efforts with a minimum of 10 community volunteers

Petition of more than 50 signatures of interest from local (within 1 mile) citizens of interest in use of the stream

90% positive feedback from local citizens

", - "Section": "GGW_Section__cRef2", - "Short_Description": "Goal 1: Officially launch Clean Water Pilot Program", - "Language": "en_US" + "Name": "Executive Summary text", + "Description__c": "

SAMPLE CONTENT - [ORG NAME] aims to improve the overall quality of life of [LOCATION] residents. [ORG NAME] provides education and resources to engage citizens and improve their communities. What started out as a neighborhood project made up of volunteers 10 years ago has developed into a 12-person team of dedicated, full-time staff serving the greater [LOCATION] area and surrounding counties.


Through annual programs and volunteer events, [ORG NAME] equips citizens with the tools that they need to build a better future for themselves and their neighbors.

With a better-together focus in mind, [ORG NAME] encourages community involvement and engagement. [ORG NAME]:


• Provides educational programs on sustainable gardening, native plants, and composting.

• Hosts large volunteer events to quickly transform spaces, such as vacant lots or overrun trail passes, into clean and accessible spaces for everyone.

• Organizes volunteers throughout the year to assess and maintain public spaces.


With inclusivity at its core, [ORG NAME] offers a wide variety of programs for individuals of all ages and abilities. Individuals should feel pride in [LOCATION]. To help with this, [ORG NAME] offers many different programs that offer a wide range of volunteer interests.

[ORG NAME] believes that communities hold the power to keep their neighborhoods clean and thriving. Last year, over 1,000 volunteers participated in the [ORG NAME] programs, filled over 2,000 recycling bags, and improved 36 natural areas throughout [LOCATION]. [ORG NAME] also educated and supported [LOCATION] citizens by supplying families with over 350 seed packets for sustainable gardening and tallied over 500 hours of educational seminars and videos. 

", + "Section__c": "@GGW_Section__cRef2", + "Short_Description__c": "SAMPLE CONTENT - [ORG NAME] aims to improve the overall quality" }, { "attributes": { "type": "GGW_Content_Block__c", "referenceId": "GGW_Content_Block__cRef3" }, - "Name": "[SAMPLE CONTENT] - Grow Austin 2", - "Description": "

SAMPLE CONTENT - Grow Austin has primarily focused on trash clean up and the beautification of parks. GA would like to expand into water as well and plans to do that gradually by starting with education and gradually moving into volunteering and volunteer programs. The average temperature in Austin during the summer months (June - September) is 95 degrees and many communities lack public pools or swimming holes for community members to cool off. The goal of this program would be to improve natural water sources to make them safe for people to use in the warmer months for swimming and cooling off.


Similar to our Seedling program, GA plans to start small to determine community interest and gradually expand once key success metrics have been established and achieved. The water program will strive to clean local streams and lakes to make them more friendly for communities.

", - "Section": "GGW_Section__cRef2", - "Short_Description": "Grow Austin 2", - "Language": "en_US" + "Name": "Statement of need - Green Spaces", + "Description__c": "

[SAMPLE CONTENT] - [city] faces a serious lack of safe, clean public green spaces. A survey from last year showed that out of 4,505 people, 26% visited parks weekly, and of that amount, approximately 49% found most parks' water unsafe.

A school survey from 2021 showed 30% of parents in [city] felt their local park was too dirty or unsafe for their children to play. The World Health Organization recommends that all people reside within 300 meters of green space.

Yet as of 2020, 100 million people in [country], including 27 million children, reported not having access to decent nearby green space. Racially inequitable urban spaces have long been an issue for the city of [city]. Currently,

the city lacks the transportation infrastructure to ensure that all parks are accessible. Last year a study showed that out of 100 parks in the city, only 12 of these parks had reasonable access to public transportation. Several reviews suggest that access to

neighborhood parks & green spaces are associated with better population health, including improved physical activity and less obesity, which continues to be one of today’s most pressing public health problems. In addition, some research evidence

suggests that this access improves mental health. This nation-wide study covering >900,000 people shows that children who grew up with the lowest levels of green space had up to 55% higher risk of developing a psychiatric disorder independent from effects

of other known risk factors. If [city]’s parks are cleaner and more accessible, more citizens can get outdoors and connect across geographic and other lines. This leads to better health outcomes, potential economic benefits, and a stronger community. 

", + "Section__c": "@GGW_Section__cRef3", + "Short_Description__c": "[city] faces a serious lack of safe, clean public green spaces." }, { "attributes": { "type": "GGW_Content_Block__c", "referenceId": "GGW_Content_Block__cRef4" }, + "Name": "Statement Need", + "Description__c": "

Imperative initiative to test functionality of editor tool

", + "Section__c": "@GGW_Section__cRef3", + "Short_Description__c": null + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef5" + }, + "Name": "Project objectives SAMPLE", + "Description__c": "

SAMPLE CONTENT - [ORG]’s mission is to rehabilitate existing spaces so they are greener, cleaner, and more accessible.

We want to show that with an inclusive aim, the community can grow friendships as well as trees. Over the next year, our objectives are:


  • Increasing inclusivity by providing safe, outdoor spaces that are accessible to people of all ages and abilities.
  • Making our green spaces beautiful and sustainable by fostering more diverse plant species that are native to our city.
  • Growing the community’s relationship with nature through school programs.
  • Making our volunteer programs a pipeline for work-ready individuals in the conservation and ecological sciences sectors.
  • Gaining visibility and support in [city] through our efforts to create a cleaner, accessible, and connected community. 
", + "Section__c": "@GGW_Section__cRef4", + "Short_Description__c": "[ORG]’s mission is to rehabilitate existing spaces so they are greener, cleaner, and more accessible." + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef6" + }, + "Name": "[SAMPLE CONTENT] - Grow Austin", + "Description__c": "

SAMPLE CONTENT - Grow Austin aims at improving the overall quality of life of Texas residents by providing education and resources to engage citizens in building more beautiful communities. What started out as a neighborhood project 10 years ago has developed into a 10 person team of dedicated staff serving the greater Austin area and surrounding counties.

Through organized volunteer events and annual programs, GA provides communities with the tools they need to improve their overall community and build a better future for themselves and their neighbors. We provide communities with resources that teach them about necessary information to their environments such as sustainable gardening, native plants and composting. GA also helps coordinate and host large volunteer events to quickly transform spaces in Austin such as vacant lots or overrun trail passes. All with the 'better together' focus in mind, encouraging community involvement and engagement.

With inclusivity at its core, GA offers a wide variety of programs that cater to various groups of individuals. We want individuals to find a home at Beautify Austin and to do that we offer many different programs that we feel can check off one or more volunteer interests.

Grow Austin believes that communities hold the power to keep their neighborhoods clean and thriving. In 2021, over 1000 volunteers participated in the Grow Austin programs, filling over 2000 recycling bags. Grow Austin also did its part of educating and supporting Austin citizens by supplying families with over 350 seed packets for sustainable gardening and tallying over 500 hours with educational seminars and videos.

", + "Section__c": "@GGW_Section__cRef5", + "Short_Description__c": "Grow Austin aims at improving the overall quality of life of Texas residents" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef7" + }, + "Name": "Goals objectives SAMPLE", + "Description__c": "

A general operating support grant from [GRANT FUNDER] will enable [PROGRAM] to work toward the following six-month organizational goals:



  • Recruit and train 50 volunteers
  • Spend 100 hours in local schools
  • Improve the local diversity of nature by planting 150 trees that are native species
  • Raise the profile of the organization locally by giving interviews to local press, organizing cleanup events
  • Improve facilities for disabled people by installing benches at parks 
", + "Section__c": "@GGW_Section__cRef5", + "Short_Description__c": "A general operating support grant from [GRANT FUNDER] will enable" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef8" + }, + "Name": "[SAMPLE CONTENT] - Goal 1", + "Description__c": "

SAMPLE CONTENT - Goal 1: Officially launch Clean Water Pilot Program


Key Activities: We will hire a Managing Director by November 2022 who will be responsible for partnership development and local program implementation. We have identified several potential locations to pilot the Clean Water Program at, all within 1 mile of our home office and have secured a team of volunteers to see the pilot from start to finish. The pilot program will select 1 stream as the focus of the pilot and during a 4 month period will host 2 cleanup efforts, 1 community outreach event and 1 online campaign. After the 4 months have completed, the committee consisting of 2 volunteers from the pilot committee and 3 Beautify Austin board members, will meet and assess the future of the program. 


Desired Outcomes:

Two cleanup efforts with a minimum of 10 community volunteers

Petition of more than 50 signatures of interest from local (within 1 mile) citizens of interest in use of the stream

90% positive feedback from local citizens

", + "Section__c": "@GGW_Section__cRef6", + "Short_Description__c": "Goal 1: Officially launch Clean Water Pilot Program" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef9" + }, + "Name": "[SAMPLE CONTENT] - Grow Austin 2", + "Description__c": "

SAMPLE CONTENT - Grow Austin has primarily focused on trash clean up and the beautification of parks. GA would like to expand into water as well and plans to do that gradually by starting with education and gradually moving into volunteering and volunteer programs. The average temperature in Austin during the summer months (June - September) is 95 degrees and many communities lack public pools or swimming holes for community members to cool off. The goal of this program would be to improve natural water sources to make them safe for people to use in the warmer months for swimming and cooling off.


Similar to our Seedling program, GA plans to start small to determine community interest and gradually expand once key success metrics have been established and achieved. The water program will strive to clean local streams and lakes to make them more friendly for communities.

", + "Section__c": "@GGW_Section__cRef6", + "Short_Description__c": "Grow Austin 2" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef10" + }, "Name": "[SAMPLE CONTENT] - Grow Austin 1", - "Description": "

SAMPLE CONTENT - Grow Austin is grateful for our ongoing and multifaceted partnership with Salesforce.org. Thanks to the previous $15,000 Salesforce.org investment, we were able to expand our highly successful Seedling program, piloted in Travis county, to our neighboring counties. This will enable 50 additional families in underserved communities to receive the supplies and training needed to build and grow their own sustainable garden in their backyard. Crops and seeds from these gardens can be shared with neighbors, providing nourishment and the ability to provide for many years.


Salesforce employees also actively volunteered at our annual Grow Austin event, collectively contributing over 250 hours at our Zilker Park cleanup. There are also 10 individuals who contribute 50+ volunteer hours per year as regular volunteers in our programs, sit on our board and support our staff.


Grow Austin is a customer of Salesforce technology, which is critical to tracking our organizational outcomes and overall success. This system enables us to record, analyze and report on data about counties, volunteers and other key audiences and help all program staff assess day-to-day progress and challenges, at both micro and macro levels.


", - "Section": "GGW_Section__cRef2", - "Short_Description": "Grow Austin 1", - "Language": "en_US" + "Description__c": "

SAMPLE CONTENT - Grow Austin is grateful for our ongoing and multifaceted partnership with Salesforce.org. Thanks to the previous $15,000 Salesforce.org investment, we were able to expand our highly successful Seedling program, piloted in Travis county, to our neighboring counties. This will enable 50 additional families in underserved communities to receive the supplies and training needed to build and grow their own sustainable garden in their backyard. Crops and seeds from these gardens can be shared with neighbors, providing nourishment and the ability to provide for many years.


Salesforce employees also actively volunteered at our annual Grow Austin event, collectively contributing over 250 hours at our Zilker Park cleanup. There are also 10 individuals who contribute 50+ volunteer hours per year as regular volunteers in our programs, sit on our board and support our staff.


Grow Austin is a customer of Salesforce technology, which is critical to tracking our organizational outcomes and overall success. This system enables us to record, analyze and report on data about counties, volunteers and other key audiences and help all program staff assess day-to-day progress and challenges, at both micro and macro levels.


", + "Section__c": "@GGW_Section__cRef6", + "Short_Description__c": "Grow Austin 1" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef11" + }, + "Name": "Plan of action - Green spaces", + "Description__c": "

The core of our Greenspace initiative lies in hands-on work in our local parks, specifically introducing new trees and seating. Our flagship event is an annual Plant Out, held every autumn. At this event, hundreds of volunteers plant trees in local parks. [Org] staff oversee tree planting, including enrolling and briefing volunteers; co-ordinating volunteers with correct planting conditions and supplies; and liaising with local landowners to gain necessary permissions. Your grant will fund these efforts, as well as site reconnaissance by an arboreal expert who will advise on sourcing native trees and advising when planting should take place.


The Plant Out’s sister event is our annual spring Build-a-Bench day. Seating is a critical component of park accessibility, providing space for parents, elders, and people with disabilities. We aim for every park in [city] to have 10 benches per acre. For the upcoming 2024 Build-a-Bench, we will target parks in [neighborhood], aiming to install 700 benches. This effort is made possible through an in kind gift of materials and labor from the Cloud Lumber Company.

None of this would be possible without [org]’s dedicated volunteers. To support our Greenspace initiative we recruit, train and retain 50 volunteers every year. We do this by identifying the skills needed as well as engaging and creating a culture of stewardship. To accomplish this we have a volunteer program that includes inductions, rewards and recognition as well as skill training.


We also recruit volunteers from our local school community. At the [School Name] we have supported a Greenspace garden in order to foster creative play, environmental education, and interactive community participation. Participants in our school garden programs also attend our Plant Out and Build-a-Bench

events as well as quarterly cleanup events focusing primarily on neighborhood playgrounds and school campuses. These students attend with their families, providing an intergenerational volunteer force.

Our events, volunteer recruitment, and school programs rely on marketing efforts and public education. Each program will be promoted via multiple media outlets including print, radio, television, social media (e.g. Facebook, Instagram, NextDoor, etc.) and influencer promotions.

", + "Section__c": "@GGW_Section__cRef6", + "Short_Description__c": "The core of our Greenspace initiative lies in hands-on work in our local parks," + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef12" + }, + "Name": "Budget narrative SAMPLE", + "Description__c": "

Expenses

  • Salaries (1.2 FTE) - $60,000
  • Materials - $5,000
  • Trees - $30,000
  • Rental equipment - $5,000
  • Transport - $500
  • Marketing - $2,000
  • Overhead - $8,000
  • Requested amount: $25,000


Income

  • Own funds: $50,000
  • Other partners funds: $25,000
  • Other income: $10,000
  • In-kind contribution (e.g. volunteering hours): $25,000


This grant will cover portions of our Program Manager and Volunteer Coordinator’s salaries.

Materials, trees, equipment and transport, and marketing are all used for our Build-a-Bench

and Plant Out events. 

", + "Section__c": "@GGW_Section__cRef7", + "Short_Description__c": null + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef13" + }, + "Name": "Outcomes SAMPLE", + "Description__c": "

Impact & Requirements

  • Impact requirements - How it's measured
  • Report requirements - How it's measured 
", + "Section__c": "@GGW_Section__cRef8", + "Short_Description__c": null } ] \ No newline at end of file diff --git a/force-app/main/default/staticresources/GGWSectionData.json b/force-app/main/default/staticresources/GGWSectionData.json index 0fd011a..c8c3c0d 100644 --- a/force-app/main/default/staticresources/GGWSectionData.json +++ b/force-app/main/default/staticresources/GGWSectionData.json @@ -8,69 +8,64 @@ "Name": "Contact Information", "Recommended": false, "Section_Details": null, - "Sort_Order": 1, + "Sort_Order": 0, "Suggested": false, "Language": "en_US" }, { "attributes": { "type": "GGW_Section__c", - "referenceId": "GGW_Section__cRef2" + "referenceId": "GGW_Section__cRef1" }, "Name": "Program narrative", - "Recommended": false, - "Section_Details": null, - "Sort_Order": 2, - "Suggested": true, - "Language": "en_US" + "Recommended__c": false, + "Section_Details__c": null, + "Sort_Order__c": 1, + "Suggested__c": true }, { "attributes": { "type": "GGW_Section__c", - "referenceId": "GGW_Section__cRef3" + "referenceId": "GGW_Section__cRef2" }, "Name": "Executive Summary", - "Recommended": true, - "Section_Details": "(maximum 500 words) Provide a brief summary of the project)\r\nExecutive Summary of Project (maximum 500 words) Provide a brief summary of the project that may be used as a project description for our grant adjudication and communication purposes.", - "Sort_Order": 3, - "Suggested": true, - "Language": "en_US" + "Recommended__c": true, + "Section_Details__c": "(maximum 500 words) Provide a brief summary of the project)\r\nExecutive Summary of Project (maximum 500 words) Provide a brief summary of the project that may be used as a project description for our grant adjudication and communication purposes.", + "Sort_Order__c": 2, + "Suggested__c": true }, { "attributes": { "type": "GGW_Section__c", - "referenceId": "GGW_Section__cRef4" + "referenceId": "GGW_Section__cRef3" }, "Name": "Statement of need", - "Recommended": true, - "Section_Details": null, - "Sort_Order": 4, - "Suggested": true, - "Language": "en_US" + "Recommended__c": true, + "Section_Details__c": null, + "Sort_Order__c": 3, + "Suggested__c": true }, { "attributes": { "type": "GGW_Section__c", - "referenceId": "GGW_Section__cRef5" + "referenceId": "GGW_Section__cRef4" }, "Name": "Project Objectives", - "Recommended": true, - "Section_Details": "Briefly describe the community and the issue your project is designed to address. If the project has been offered before, briefly describe the results and any changes that have been made to improve outcomes.", - "Sort_Order": 5, - "Suggested": true, - "Language": "en_US" + "Recommended__c": true, + "Section_Details__c": "Briefly describe the community and the issue your project is designed to address. If the project has been offered before, briefly describe the results and any changes that have been made to improve outcomes.", + "Sort_Order__c": 4, + "Suggested__c": true }, { "attributes": { "type": "GGW_Section__c", - "referenceId": "GGW_Section__cRef7" + "referenceId": "GGW_Section__cRef5" }, "Name": "Goals and objectives", - "Recommended": false, - "Section_Details": null, - "Sort_Order": 6, - "Suggested": true, - "Language": "en_US" + "Recommended__c": false, + "Section_Details__c": null, + "Sort_Order__c": 5, + "Suggested__c": true }, { "attributes": { @@ -78,22 +73,42 @@ "referenceId": "GGW_Section__cRef6" }, "Name": "Plan of action", - "Recommended": true, - "Section_Details": null, - "Sort_Order": 7, - "Suggested": true, - "Language": "en_US" + "Recommended__c": true, + "Section_Details__c": null, + "Sort_Order__c": 6, + "Suggested__c": true }, { "attributes": { "type": "GGW_Section__c", - "referenceId": "GGW_Section__cRef8" + "referenceId": "GGW_Section__cRef7" }, "Name": "Budget narrative", - "Recommended": true, - "Section_Details": null, - "Sort_Order": 8, - "Suggested": true, - "Language": "en_US" + "Recommended__c": true, + "Section_Details__c": null, + "Sort_Order__c": 7, + "Suggested__c": true + }, + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef8" + }, + "Name": "Measurable outcomes", + "Recommended__c": true, + "Section_Details__c": null, + "Sort_Order__c": 8, + "Suggested__c": true + }, + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef9" + }, + "Name": "Impact narrative", + "Recommended__c": false, + "Section_Details__c": null, + "Sort_Order__c": 9, + "Suggested__c": false } ] diff --git a/scripts/dx/dxorg b/scripts/dx/dxorg index b522740..1dcf4cf 100755 --- a/scripts/dx/dxorg +++ b/scripts/dx/dxorg @@ -36,7 +36,7 @@ sfdx force:user:permset:assign -n GGW_User_Permissions --target-org $ORG_ALIAS | # Push sample data echo "--- INSERT SAMPLE DATA FOR: $ORG_ALIAS" -sfdx data:import:tree --target-org $ORG_ALIAS --plan test-data/export-section-GGW_Section__c-plan.json +sfdx data:import:tree --target-org $ORG_ALIAS --plan test-data/sample-data-GGW_Section__c-plan.json # sfdx force:data:tree:import --target-org $ORG_ALIAS --plan test-data/export-section-GGW_Section__c-plan.json #sfdx force:data:tree:import -u ggw --plan test-data/export-section-GGW_Section__c-plan.json diff --git a/test-data/sample-data-GGW_Content_Block__cs.json b/test-data/sample-data-GGW_Content_Block__cs.json new file mode 100644 index 0000000..c2e1a1f --- /dev/null +++ b/test-data/sample-data-GGW_Content_Block__cs.json @@ -0,0 +1,134 @@ +{ + "records": [ + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef1" + }, + "Name": "Program narrative text", + "Description__c": "

SAMPLE CONTENT - [ORG NAME] primarily focuses on beautification and improvement of parks and would like to expand into improving natural waterways. [ORG NAME] plans to build the clean water program over time with education and raising awareness; then, gradually move into organizing volunteers and special volunteer events. Many communities lack public and clean swimming areas for citizens to cool off during the hot summer months. The goal of this new program is to improve natural water sources to make them clean, safe, and accessible.


Similar to our [EXISTING PROGRAM NAME] program, [ORG NAME] plans to start by determining community interest and understanding, and then, expand the program once key success metrics have been established. The clean water program will strive to improve local streams and lakes to make them more accessible and usable for communities. 

", + "Section__c": "@GGW_Section__cRef1", + "Short_Description__c": "SAMPLE CONTENT - [ORG NAME] primarily focuses on beautification and improvement of parks" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef2" + }, + "Name": "Executive Summary text", + "Description__c": "

SAMPLE CONTENT - [ORG NAME] aims to improve the overall quality of life of [LOCATION] residents. [ORG NAME] provides education and resources to engage citizens and improve their communities. What started out as a neighborhood project made up of volunteers 10 years ago has developed into a 12-person team of dedicated, full-time staff serving the greater [LOCATION] area and surrounding counties.


Through annual programs and volunteer events, [ORG NAME] equips citizens with the tools that they need to build a better future for themselves and their neighbors.

With a better-together focus in mind, [ORG NAME] encourages community involvement and engagement. [ORG NAME]:


• Provides educational programs on sustainable gardening, native plants, and composting.

• Hosts large volunteer events to quickly transform spaces, such as vacant lots or overrun trail passes, into clean and accessible spaces for everyone.

• Organizes volunteers throughout the year to assess and maintain public spaces.


With inclusivity at its core, [ORG NAME] offers a wide variety of programs for individuals of all ages and abilities. Individuals should feel pride in [LOCATION]. To help with this, [ORG NAME] offers many different programs that offer a wide range of volunteer interests.

[ORG NAME] believes that communities hold the power to keep their neighborhoods clean and thriving. Last year, over 1,000 volunteers participated in the [ORG NAME] programs, filled over 2,000 recycling bags, and improved 36 natural areas throughout [LOCATION]. [ORG NAME] also educated and supported [LOCATION] citizens by supplying families with over 350 seed packets for sustainable gardening and tallied over 500 hours of educational seminars and videos. 

", + "Section__c": "@GGW_Section__cRef2", + "Short_Description__c": "SAMPLE CONTENT - [ORG NAME] aims to improve the overall quality" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef3" + }, + "Name": "Statement of need - Green Spaces", + "Description__c": "

[SAMPLE CONTENT] - [city] faces a serious lack of safe, clean public green spaces. A survey from last year showed that out of 4,505 people, 26% visited parks weekly, and of that amount, approximately 49% found most parks' water unsafe.

A school survey from 2021 showed 30% of parents in [city] felt their local park was too dirty or unsafe for their children to play. The World Health Organization recommends that all people reside within 300 meters of green space.

Yet as of 2020, 100 million people in [country], including 27 million children, reported not having access to decent nearby green space. Racially inequitable urban spaces have long been an issue for the city of [city]. Currently,

the city lacks the transportation infrastructure to ensure that all parks are accessible. Last year a study showed that out of 100 parks in the city, only 12 of these parks had reasonable access to public transportation. Several reviews suggest that access to

neighborhood parks & green spaces are associated with better population health, including improved physical activity and less obesity, which continues to be one of today’s most pressing public health problems. In addition, some research evidence

suggests that this access improves mental health. This nation-wide study covering >900,000 people shows that children who grew up with the lowest levels of green space had up to 55% higher risk of developing a psychiatric disorder independent from effects

of other known risk factors. If [city]’s parks are cleaner and more accessible, more citizens can get outdoors and connect across geographic and other lines. This leads to better health outcomes, potential economic benefits, and a stronger community. 

", + "Section__c": "@GGW_Section__cRef3", + "Short_Description__c": "[city] faces a serious lack of safe, clean public green spaces." + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef4" + }, + "Name": "Statement Need", + "Description__c": "

Imperative initiative to test functionality of editor tool

", + "Section__c": "@GGW_Section__cRef3", + "Short_Description__c": null + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef5" + }, + "Name": "Project objectives SAMPLE", + "Description__c": "

SAMPLE CONTENT - [ORG]’s mission is to rehabilitate existing spaces so they are greener, cleaner, and more accessible.

We want to show that with an inclusive aim, the community can grow friendships as well as trees. Over the next year, our objectives are:


  • Increasing inclusivity by providing safe, outdoor spaces that are accessible to people of all ages and abilities.
  • Making our green spaces beautiful and sustainable by fostering more diverse plant species that are native to our city.
  • Growing the community’s relationship with nature through school programs.
  • Making our volunteer programs a pipeline for work-ready individuals in the conservation and ecological sciences sectors.
  • Gaining visibility and support in [city] through our efforts to create a cleaner, accessible, and connected community. 
", + "Section__c": "@GGW_Section__cRef4", + "Short_Description__c": "[ORG]’s mission is to rehabilitate existing spaces so they are greener, cleaner, and more accessible." + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef6" + }, + "Name": "[SAMPLE CONTENT] - Grow Austin", + "Description__c": "

SAMPLE CONTENT - Grow Austin aims at improving the overall quality of life of Texas residents by providing education and resources to engage citizens in building more beautiful communities. What started out as a neighborhood project 10 years ago has developed into a 10 person team of dedicated staff serving the greater Austin area and surrounding counties.

Through organized volunteer events and annual programs, GA provides communities with the tools they need to improve their overall community and build a better future for themselves and their neighbors. We provide communities with resources that teach them about necessary information to their environments such as sustainable gardening, native plants and composting. GA also helps coordinate and host large volunteer events to quickly transform spaces in Austin such as vacant lots or overrun trail passes. All with the 'better together' focus in mind, encouraging community involvement and engagement.

With inclusivity at its core, GA offers a wide variety of programs that cater to various groups of individuals. We want individuals to find a home at Beautify Austin and to do that we offer many different programs that we feel can check off one or more volunteer interests.

Grow Austin believes that communities hold the power to keep their neighborhoods clean and thriving. In 2021, over 1000 volunteers participated in the Grow Austin programs, filling over 2000 recycling bags. Grow Austin also did its part of educating and supporting Austin citizens by supplying families with over 350 seed packets for sustainable gardening and tallying over 500 hours with educational seminars and videos.

", + "Section__c": "@GGW_Section__cRef5", + "Short_Description__c": "Grow Austin aims at improving the overall quality of life of Texas residents" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef7" + }, + "Name": "Goals objectives SAMPLE", + "Description__c": "

A general operating support grant from [GRANT FUNDER] will enable [PROGRAM] to work toward the following six-month organizational goals:



  • Recruit and train 50 volunteers
  • Spend 100 hours in local schools
  • Improve the local diversity of nature by planting 150 trees that are native species
  • Raise the profile of the organization locally by giving interviews to local press, organizing cleanup events
  • Improve facilities for disabled people by installing benches at parks 
", + "Section__c": "@GGW_Section__cRef5", + "Short_Description__c": "A general operating support grant from [GRANT FUNDER] will enable" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef8" + }, + "Name": "[SAMPLE CONTENT] - Goal 1", + "Description__c": "

SAMPLE CONTENT - Goal 1: Officially launch Clean Water Pilot Program


Key Activities: We will hire a Managing Director by November 2022 who will be responsible for partnership development and local program implementation. We have identified several potential locations to pilot the Clean Water Program at, all within 1 mile of our home office and have secured a team of volunteers to see the pilot from start to finish. The pilot program will select 1 stream as the focus of the pilot and during a 4 month period will host 2 cleanup efforts, 1 community outreach event and 1 online campaign. After the 4 months have completed, the committee consisting of 2 volunteers from the pilot committee and 3 Beautify Austin board members, will meet and assess the future of the program. 


Desired Outcomes:

Two cleanup efforts with a minimum of 10 community volunteers

Petition of more than 50 signatures of interest from local (within 1 mile) citizens of interest in use of the stream

90% positive feedback from local citizens

", + "Section__c": "@GGW_Section__cRef6", + "Short_Description__c": "Goal 1: Officially launch Clean Water Pilot Program" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef9" + }, + "Name": "[SAMPLE CONTENT] - Grow Austin 2", + "Description__c": "

SAMPLE CONTENT - Grow Austin has primarily focused on trash clean up and the beautification of parks. GA would like to expand into water as well and plans to do that gradually by starting with education and gradually moving into volunteering and volunteer programs. The average temperature in Austin during the summer months (June - September) is 95 degrees and many communities lack public pools or swimming holes for community members to cool off. The goal of this program would be to improve natural water sources to make them safe for people to use in the warmer months for swimming and cooling off.


Similar to our Seedling program, GA plans to start small to determine community interest and gradually expand once key success metrics have been established and achieved. The water program will strive to clean local streams and lakes to make them more friendly for communities.

", + "Section__c": "@GGW_Section__cRef6", + "Short_Description__c": "Grow Austin 2" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef10" + }, + "Name": "[SAMPLE CONTENT] - Grow Austin 1", + "Description__c": "

SAMPLE CONTENT - Grow Austin is grateful for our ongoing and multifaceted partnership with Salesforce.org. Thanks to the previous $15,000 Salesforce.org investment, we were able to expand our highly successful Seedling program, piloted in Travis county, to our neighboring counties. This will enable 50 additional families in underserved communities to receive the supplies and training needed to build and grow their own sustainable garden in their backyard. Crops and seeds from these gardens can be shared with neighbors, providing nourishment and the ability to provide for many years.


Salesforce employees also actively volunteered at our annual Grow Austin event, collectively contributing over 250 hours at our Zilker Park cleanup. There are also 10 individuals who contribute 50+ volunteer hours per year as regular volunteers in our programs, sit on our board and support our staff.


Grow Austin is a customer of Salesforce technology, which is critical to tracking our organizational outcomes and overall success. This system enables us to record, analyze and report on data about counties, volunteers and other key audiences and help all program staff assess day-to-day progress and challenges, at both micro and macro levels.


", + "Section__c": "@GGW_Section__cRef6", + "Short_Description__c": "Grow Austin 1" + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef11" + }, + "Name": "Plan of action - Green spaces", + "Description__c": "

The core of our Greenspace initiative lies in hands-on work in our local parks, specifically introducing new trees and seating. Our flagship event is an annual Plant Out, held every autumn. At this event, hundreds of volunteers plant trees in local parks. [Org] staff oversee tree planting, including enrolling and briefing volunteers; co-ordinating volunteers with correct planting conditions and supplies; and liaising with local landowners to gain necessary permissions. Your grant will fund these efforts, as well as site reconnaissance by an arboreal expert who will advise on sourcing native trees and advising when planting should take place.


The Plant Out’s sister event is our annual spring Build-a-Bench day. Seating is a critical component of park accessibility, providing space for parents, elders, and people with disabilities. We aim for every park in [city] to have 10 benches per acre. For the upcoming 2024 Build-a-Bench, we will target parks in [neighborhood], aiming to install 700 benches. This effort is made possible through an in kind gift of materials and labor from the Cloud Lumber Company.

None of this would be possible without [org]’s dedicated volunteers. To support our Greenspace initiative we recruit, train and retain 50 volunteers every year. We do this by identifying the skills needed as well as engaging and creating a culture of stewardship. To accomplish this we have a volunteer program that includes inductions, rewards and recognition as well as skill training.


We also recruit volunteers from our local school community. At the [School Name] we have supported a Greenspace garden in order to foster creative play, environmental education, and interactive community participation. Participants in our school garden programs also attend our Plant Out and Build-a-Bench

events as well as quarterly cleanup events focusing primarily on neighborhood playgrounds and school campuses. These students attend with their families, providing an intergenerational volunteer force.

Our events, volunteer recruitment, and school programs rely on marketing efforts and public education. Each program will be promoted via multiple media outlets including print, radio, television, social media (e.g. Facebook, Instagram, NextDoor, etc.) and influencer promotions.

", + "Section__c": "@GGW_Section__cRef6", + "Short_Description__c": "The core of our Greenspace initiative lies in hands-on work in our local parks," + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef12" + }, + "Name": "Budget narrative SAMPLE", + "Description__c": "

Expenses

  • Salaries (1.2 FTE) - $60,000
  • Materials - $5,000
  • Trees - $30,000
  • Rental equipment - $5,000
  • Transport - $500
  • Marketing - $2,000
  • Overhead - $8,000
  • Requested amount: $25,000


Income

  • Own funds: $50,000
  • Other partners funds: $25,000
  • Other income: $10,000
  • In-kind contribution (e.g. volunteering hours): $25,000


This grant will cover portions of our Program Manager and Volunteer Coordinator’s salaries.

Materials, trees, equipment and transport, and marketing are all used for our Build-a-Bench

and Plant Out events. 

", + "Section__c": "@GGW_Section__cRef7", + "Short_Description__c": null + }, + { + "attributes": { + "type": "GGW_Content_Block__c", + "referenceId": "GGW_Content_Block__cRef13" + }, + "Name": "Outcomes SAMPLE", + "Description__c": "

Impact & Requirements

  • Impact requirements - How it's measured
  • Report requirements - How it's measured 
", + "Section__c": "@GGW_Section__cRef8", + "Short_Description__c": null + } + ] +} \ No newline at end of file diff --git a/test-data/sample-data-GGW_Section__c-GGW_Content_Block__c-plan.json b/test-data/sample-data-GGW_Section__c-GGW_Content_Block__c-plan.json new file mode 100644 index 0000000..a2bf7f4 --- /dev/null +++ b/test-data/sample-data-GGW_Section__c-GGW_Content_Block__c-plan.json @@ -0,0 +1,18 @@ +[ + { + "sobject": "GGW_Section__c", + "saveRefs": true, + "resolveRefs": false, + "files": [ + "sample-data-GGW_Section__cs.json" + ] + }, + { + "sobject": "GGW_Content_Block__c", + "saveRefs": false, + "resolveRefs": true, + "files": [ + "sample-data-GGW_Content_Block__cs.json" + ] + } +] \ No newline at end of file diff --git a/test-data/sample-data-GGW_Section__cs.json b/test-data/sample-data-GGW_Section__cs.json new file mode 100644 index 0000000..d2ca81a --- /dev/null +++ b/test-data/sample-data-GGW_Section__cs.json @@ -0,0 +1,103 @@ +{ + "records": [ + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef1" + }, + "Name": "Program narrative", + "Recommended__c": false, + "Section_Details__c": null, + "Sort_Order__c": 1, + "Suggested__c": true + }, + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef2" + }, + "Name": "Executive Summary", + "Recommended__c": true, + "Section_Details__c": "(maximum 500 words) Provide a brief summary of the project)\r\nExecutive Summary of Project (maximum 500 words) Provide a brief summary of the project that may be used as a project description for our grant adjudication and communication purposes.", + "Sort_Order__c": 2, + "Suggested__c": true + }, + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef3" + }, + "Name": "Statement of need", + "Recommended__c": true, + "Section_Details__c": null, + "Sort_Order__c": 3, + "Suggested__c": true + }, + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef4" + }, + "Name": "Project Objectives", + "Recommended__c": true, + "Section_Details__c": "Briefly describe the community and the issue your project is designed to address. If the project has been offered before, briefly describe the results and any changes that have been made to improve outcomes.", + "Sort_Order__c": 4, + "Suggested__c": true + }, + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef5" + }, + "Name": "Goals and objectives", + "Recommended__c": false, + "Section_Details__c": null, + "Sort_Order__c": 5, + "Suggested__c": true + }, + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef6" + }, + "Name": "Plan of action", + "Recommended__c": true, + "Section_Details__c": null, + "Sort_Order__c": 6, + "Suggested__c": true + }, + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef7" + }, + "Name": "Budget narrative", + "Recommended__c": true, + "Section_Details__c": null, + "Sort_Order__c": 7, + "Suggested__c": true + }, + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef8" + }, + "Name": "Measurable outcomes", + "Recommended__c": true, + "Section_Details__c": null, + "Sort_Order__c": 8, + "Suggested__c": true + }, + { + "attributes": { + "type": "GGW_Section__c", + "referenceId": "GGW_Section__cRef9" + }, + "Name": "Impact narrative", + "Recommended__c": false, + "Section_Details__c": null, + "Sort_Order__c": 9, + "Suggested__c": false + } + ] +} \ No newline at end of file