Skip to content

Commit

Permalink
Merge pull request #52 from dbreese/code_generate
Browse files Browse the repository at this point in the history
Now able to generate LWCs using template files.
  • Loading branch information
dbreese committed Nov 16, 2023
2 parents 7632f66 + e592589 commit 3f1a5ed
Show file tree
Hide file tree
Showing 9 changed files with 932 additions and 95 deletions.
119 changes: 73 additions & 46 deletions resources/instructions/createSObjectLwcQuickActions.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,54 +56,81 @@ <h1>Create sObject LWC Quick Actions</h1>
</tbody>
</table>

<label
style="display: block; margin-top: 10px; margin-bottom: 8px"
for="generateLwcQuickActionsButton"
>
Click 'Generate LWC Quick Actions' to create the missing LWC Quick
Actions:
</label>
<button id="generateLwcQuickActionsButton">
Generate LWC Quick Actions
</button>
<script>
const generateQuickActionsButtonElement = document.getElementById(
'generateLwcQuickActionsButton'
<label style="display: block; margin-top: 10px; margin-bottom: 8px" for="generateLwcQuickActionsButton">
Click 'Generate LWC Quick Actions' to create the missing LWC Quick
Actions:
</label>

<button id="generateLwcQuickActionsButton">
Generate LWC Quick Actions
</button>

<button id="continueButton">
Continue
</button>

<script>
const generateQuickActionsButtonElement = document.getElementById(
'generateLwcQuickActionsButton'
);

const continueButtonElement = document.getElementById(
'continueButton'
);

const quickActionStatusTable = document.getElementById(
'quickActionStatusTable'
);

generateQuickActionsButtonElement.addEventListener('click', () => {
webviewMessaging.sendMessageRequest(
'generateLwcQuickActions',
{},
handleQuickActionStatusResponse
);
generateQuickActionsButtonElement.addEventListener('click', () => {
webviewMessaging.sendMessageRequest(
'generateLwcQuickActionsButton'
);
});

// Wait until all scripts are loaded, before engaging with e.g.
// messaging functionality.
window.addEventListener('load', () => {
// What's the status of the various sobject quick actions in the landing_page.json?
webviewMessaging.sendMessageRequest(
'getQuickActionStatus',
{},
handleQuickActionStatusResponse
);
});

function handleQuickActionStatusResponse(response) {
const table = document.getElementById('quickActionStatusTable');
for (const sobject in response.sobjects) {
const quickActions = response.sobjects[sobject];

const sobjectRow = table.insertRow();
const name = sobjectRow.insertCell(0);
const view = sobjectRow.insertCell(1);
const edit = sobjectRow.insertCell(2);
const create = sobjectRow.insertCell(3);

name.innerText = sobject;
view.innerHTML = quickActions.view == true ? "✅" : "❌";
edit.innerHTML = quickActions.edit == true ? "✅" : "❌";
create.innerHTML = quickActions.create == true ? "✅" : "❌";
}
});

continueButtonElement.addEventListener('click', () => {
webviewMessaging.sendMessageRequest(
'continueButton'
);
});

// Wait until all scripts are loaded, before engaging with e.g.
// messaging functionality.
window.addEventListener('load', () => {
// What's the status of the various sobject quick actions in the landing_page.json?
webviewMessaging.sendMessageRequest(
'getQuickActionStatus',
{},
handleQuickActionStatusResponse
);
});

function handleQuickActionStatusResponse(response) {
var tbody = quickActionStatusTable.getElementsByTagName('tbody')[0];

// remove all table rows first
while (tbody.firstChild) {
tbody.removeChild(tbody.firstChild);
}

// now re-populate the table body with updated results
for (const sobject in response.sobjects) {
const quickActions = response.sobjects[sobject];

const sobjectRow = tbody.insertRow();
const name = sobjectRow.insertCell(0);
const view = sobjectRow.insertCell(1);
const edit = sobjectRow.insertCell(2);
const create = sobjectRow.insertCell(3);

name.innerText = sobject;
view.innerHTML = quickActions.view == true ? "✅" : "❌";
edit.innerHTML = quickActions.edit == true ? "✅" : "❌";
create.innerHTML = quickActions.create == true ? "✅" : "❌";
}
}
</script>
<script src="--- MESSAGING_SCRIPT_SRC ---"></script>
</body>
Expand Down
9 changes: 9 additions & 0 deletions resources/templates/quickAction.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<QuickAction xmlns="http://soap.sforce.com/2006/04/metadata">
<actionSubtype>ScreenAction</actionSubtype>
<label>///TEMPLATE_QUICK_ACTION_LABEL///</label>
<lightningWebComponent>///TEMPLATE_LWC_NAME///</lightningWebComponent>
<optionsCreateFeedItem>false</optionsCreateFeedItem>
<type>LightningWebComponent</type>
///TEMPLATE_QUICK_ACTION_ICON///
</QuickAction>
147 changes: 106 additions & 41 deletions src/commands/wizard/lwcGenerationCommand.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/*
* Copyright (c) 2023, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/

import { Uri, l10n } from 'vscode';
import { access } from 'fs/promises';
import { InstructionsWebviewProvider } from '../../webviews/instructions';
Expand All @@ -6,6 +13,7 @@ import { WorkspaceUtils } from '../../utils/workspaceUtils';
import { CommonUtils } from '@salesforce/lwc-dev-mobile-core';
import { OrgUtils } from '../../utils/orgUtils';
import * as fs from 'fs';
import { CodeBuilder } from '../../utils/codeBuilder';
import * as path from 'path';

export type QuickActionStatus = {
Expand All @@ -27,10 +35,52 @@ export type GetSObjectsStatus = {
};

export class LwcGenerationCommand {
extensionUri: Uri;
static async createSObjectLwcQuickActions(extensionUri: Uri) {
return new Promise<void>((resolve) => {
new InstructionsWebviewProvider(
extensionUri
).showInstructionWebview(
l10n.t('Offline Starter Kit: Create sObject LWC Quick Actions'),
'resources/instructions/createSObjectLwcQuickActions.html',
[
{
type: 'continueButton',
action: (panel) => {
panel.dispose();
return resolve();
}
},
{
type: 'generateLwcQuickActions',
action: async (_panel, _data, callback) => {
const quickActionStatus =
await LwcGenerationCommand.checkForExistingQuickActions();

constructor(extensionUri: Uri) {
this.extensionUri = extensionUri;
const newLwcQuickActionStatus =
await LwcGenerationCommand.generateMissingLwcsAndQuickActions(
extensionUri,
quickActionStatus
);

// send back updates so UI can be refreshed
if (callback) {
callback(newLwcQuickActionStatus);
}
}
},
{
type: 'getQuickActionStatus',
action: async (_panel, _data, callback) => {
if (callback) {
const quickActionStatus =
await LwcGenerationCommand.checkForExistingQuickActions();
callback(quickActionStatus);
}
}
}
]
);
});
}

static async getSObjectsFromLandingPage(): Promise<GetSObjectsStatus> {
Expand Down Expand Up @@ -62,44 +112,6 @@ export class LwcGenerationCommand {
});
}

async createSObjectLwcQuickActions() {
return new Promise<void>((resolve) => {
new InstructionsWebviewProvider(
this.extensionUri
).showInstructionWebview(
l10n.t('Offline Starter Kit: Create sObject LWC Quick Actions'),
'resources/instructions/createSObjectLwcQuickActions.html',
[
{
type: 'generateLwcQuickActionsButton',
action: (panel) => {
panel.dispose();
return resolve();
}
},
{
type: 'getQuickActionStatus',
action: async (_panel, _data, callback) => {
if (callback) {
const quickActionStatus =
await LwcGenerationCommand.checkForExistingQuickActions();

for (const key in quickActionStatus.sobjects) {
const layoutFields =
await OrgUtils.getCompactLayoutFieldsForSObject(
key
);
}

callback(quickActionStatus);
}
}
}
]
);
});
}

static async checkForExistingQuickActions(): Promise<SObjectQuickActionStatus> {
return new Promise<SObjectQuickActionStatus>(async (resolve) => {
const results: SObjectQuickActionStatus = { sobjects: {} };
Expand Down Expand Up @@ -139,6 +151,59 @@ export class LwcGenerationCommand {
});
}

static async generateMissingLwcsAndQuickActions(
extensionUri: Uri,
quickActionStatus: SObjectQuickActionStatus
): Promise<SObjectQuickActionStatus> {
return new Promise<SObjectQuickActionStatus>(async (resolve) => {
for (const sobject in quickActionStatus.sobjects) {
try {
const quickActions = quickActionStatus.sobjects[sobject];

if (
!quickActions.create ||
!quickActions.edit ||
!quickActions.view
) {
// at least 1 needs to be created
const compactLayoutFields =
await OrgUtils.getCompactLayoutFieldsForSObject(
sobject
);

const codeBuilder = new CodeBuilder(
extensionUri,
sobject,
compactLayoutFields
);

if (!quickActions.view) {
await codeBuilder.generateView();
}

if (!quickActions.edit) {
await codeBuilder.generateEdit();
}

if (!quickActions.create) {
await codeBuilder.generateCreate();
}
}
} catch (err) {
console.error(
`Could not generate quick actions for sobject ${sobject}, so skipping`,
err
);
}
}

// Just double check now that things have been created.
const newStatus =
await LwcGenerationCommand.checkForExistingQuickActions();
resolve(newStatus);
});
}

private static checkForExistingQuickAction(
sobject: string,
qaName: string
Expand Down
2 changes: 2 additions & 0 deletions src/commands/wizard/onboardingWizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { DeployToOrgCommand } from './deployToOrgCommand';
import { ConfigureProjectCommand } from './configureProjectCommand';
import { AuthorizeCommand } from './authorizeCommand';
import { InstructionsWebviewProvider } from '../../webviews/instructions';
import { LwcGenerationCommand } from './lwcGenerationCommand';

const wizardCommand = 'salesforcedx-vscode-offline-app.onboardingWizard';
const onboardingWizardStateKey =
Expand All @@ -28,6 +29,7 @@ async function runPostProjectConfigurationSteps(
await AuthorizeCommand.authorizeToOrg();
await BriefcaseCommand.setupBriefcase(extensionUri);
await TemplateChooserCommand.chooseTemplate(extensionUri);
await LwcGenerationCommand.createSObjectLwcQuickActions(extensionUri);

await AuthorizeCommand.authorizeToOrg();
await DeployToOrgCommand.deployToOrg();
Expand Down
Loading

0 comments on commit 3f1a5ed

Please sign in to comment.