Skip to content

Commit

Permalink
Merge pull request #51 from sfdctaka/uemParser
Browse files Browse the repository at this point in the history
Parse sObjects in the landing page and return them in an array
  • Loading branch information
sfdctaka committed Nov 14, 2023
2 parents e9fa2f8 + 8f19fe3 commit 4030b50
Show file tree
Hide file tree
Showing 13 changed files with 495 additions and 195 deletions.
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.2",
"@types/cli-progress": "^3.11.5",
"@types/glob": "^8.1.0",
"@types/inquirer": "^9.0.6",
"@types/mocha": "^10.0.3",
Expand Down
140 changes: 70 additions & 70 deletions resources/instructions/createSObjectLwcQuickActions.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,76 +35,76 @@
<body>
<h1>Create sObject LWC Quick Actions</h1>

<p>
The following sObjects are present in your configured landing page:
</p>

<table id="quickActionStatusTable">
<thead>
<tr>
<th rowspan="2">sObject</th>
<th colspan="3">LWC Quick Actions</th>
</tr>
<tr>
<th>view</th>
<th>edit</th>
<th>create</th>
</tr>
</thead>
<tbody>
<!-- will be filled in programatically below -->
</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'
);
generateQuickActionsButtonElement.addEventListener('click', () => {
webviewMessaging.sendMessageRequest(
<p id="sobjectDiv">
The following sObjects are present in your configured landing page:
</p>

<table id="quickActionStatusTable">
<thead>
<tr>
<th rowspan="2">sObject</th>
<th colspan="3">LWC Quick Actions</th>
</tr>
<tr>
<th>view</th>
<th>edit</th>
<th>create</th>
</tr>
</thead>
<tbody>
<!-- will be filled in programatically below -->
</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'
);
});

// 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 ? "✅" : "❌";
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 ? "✅" : "❌";
}
}
}
</script>

<script src="--- MESSAGING_SCRIPT_SRC ---"></script>
</body>

</html>
</script>
<script src="--- MESSAGING_SCRIPT_SRC ---"></script>
</body>
</html>
63 changes: 49 additions & 14 deletions src/commands/wizard/lwcGenerationCommand.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Uri, l10n } from 'vscode';
import { access } from 'fs/promises';
import { InstructionsWebviewProvider } from '../../webviews/instructions';
import { UEMParser } from '../../utils/uemParser';
import { WorkspaceUtils } from '../../utils/workspaceUtils';
import { CommonUtils } from '@salesforce/lwc-dev-mobile-core';
import * as fs from 'fs';
import * as path from 'path';

export type QuickActionStatus = {
view: boolean;
Expand All @@ -9,18 +14,53 @@ export type QuickActionStatus = {
};

export type SObjectQuickActionStatus = {
error?: string;
sobjects: {
[name: string]: QuickActionStatus;
};
};

export type GetSObjectsStatus = {
error?: string;
sobjects: string[];
};

export class LwcGenerationCommand {
extensionUri: Uri;

constructor(extensionUri: Uri) {
this.extensionUri = extensionUri;
}

static async getSObjectsFromLandingPage(): Promise<GetSObjectsStatus> {
return new Promise<GetSObjectsStatus>(async (resolve) => {
const staticResourcesPath =
await WorkspaceUtils.getStaticResourcesDir();
const landingPageJson = 'landing_page.json';
const landingPagePath = path.join(
staticResourcesPath,
landingPageJson
);

const getSObjectsStatus: GetSObjectsStatus = {
sobjects: []
};

try {
await access(landingPagePath);
const uem = CommonUtils.loadJsonFromFile(landingPagePath);
getSObjectsStatus.sobjects = UEMParser.findSObjects(uem);
} catch (err) {
console.warn(
`File '${landingPageJson}' does not exist at '${staticResourcesPath}'.`
);
getSObjectsStatus.error = (err as Error).message;
}

resolve(getSObjectsStatus);
});
}

async createSObjectLwcQuickActions() {
return new Promise<void>((resolve) => {
new InstructionsWebviewProvider(
Expand All @@ -39,18 +79,9 @@ export class LwcGenerationCommand {
{
type: 'getQuickActionStatus',
action: async (_panel, _data, callback) => {
// TODO: Hook this up to function that parses landing_page.json.
const sobjects = [
'Account',
'Contact',
'Opportunity',
'SomeOther'
];
if (callback) {
const quickActionStatus =
await LwcGenerationCommand.checkForExistingQuickActions(
sobjects
);
await LwcGenerationCommand.checkForExistingQuickActions();
callback(quickActionStatus);
}
}
Expand All @@ -60,13 +91,17 @@ export class LwcGenerationCommand {
});
}

static async checkForExistingQuickActions(
sobjects: string[]
): Promise<SObjectQuickActionStatus> {
static async checkForExistingQuickActions(): Promise<SObjectQuickActionStatus> {
return new Promise<SObjectQuickActionStatus>(async (resolve) => {
const results: SObjectQuickActionStatus = { sobjects: {} };

sobjects.forEach((sobject) => {
const sObjectsStatus = await this.getSObjectsFromLandingPage();
if (sObjectsStatus.error) {
results.error = sObjectsStatus.error;
return resolve(results);
}

sObjectsStatus.sobjects.forEach((sobject) => {
const quickActionStatus: QuickActionStatus = {
view: false,
edit: false,
Expand Down
1 change: 0 additions & 1 deletion src/commands/wizard/onboardingWizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ 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 Down
38 changes: 5 additions & 33 deletions src/commands/wizard/templateChooserCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ProgressLocation, window, workspace } from 'vscode';
import * as path from 'path';
import { access, copyFile } from 'fs/promises';
import { InstructionsWebviewProvider } from '../../webviews/instructions';
import { WorkspaceUtils } from '../../utils/workspaceUtils';

export type LandingPageStatus = {
exists: boolean;
Expand All @@ -35,12 +36,6 @@ export type LandingPageCollectionStatus = {
* When the project is deployed to the user's org, this file will also be copied into static resources and picked up by SApp+.
*/
export class TemplateChooserCommand {
static readonly STATIC_RESOURCES_PATH = path.join(
'force-app',
'main',
'default',
'staticresources'
);
static readonly LANDING_PAGE_FILENAME_PREFIX = 'landing_page';
static readonly LANDING_PAGE_JSON_FILE_EXTENSION = '.json';
static readonly LANDING_PAGE_METADATA_FILE_EXTENSION = '.resource-meta.xml';
Expand Down Expand Up @@ -110,7 +105,8 @@ export class TemplateChooserCommand {
}

// If a landing page exists, warn about overwriting it.
const staticResourcesPath = await this.getStaticResourcesDir();
const staticResourcesPath =
await WorkspaceUtils.getStaticResourcesDir();
const existingLandingPageFiles = await this.landingPageFilesExist(
staticResourcesPath,
'existing'
Expand Down Expand Up @@ -186,7 +182,8 @@ export class TemplateChooserCommand {

let staticResourcesPath: string;
try {
staticResourcesPath = await this.getStaticResourcesDir();
staticResourcesPath =
await WorkspaceUtils.getStaticResourcesDir();
} catch (err) {
landingPageCollectionStatus.error = (err as Error).message;
return resolve(landingPageCollectionStatus);
Expand Down Expand Up @@ -243,31 +240,6 @@ export class TemplateChooserCommand {
return workspaceFolders[0].uri.fsPath;
}

static async getStaticResourcesDir(): Promise<string> {
return new Promise<string>(async (resolve, reject) => {
let projectPath: string;
try {
projectPath = this.getWorkspaceDir();
} catch (err) {
return reject(err);
}
const staticResourcesPath = path.join(
projectPath,
this.STATIC_RESOURCES_PATH
);
try {
await access(staticResourcesPath);
} catch (err) {
const accessErrorObj = err as Error;
const noAccessError = new NoStaticResourcesDirError(
`Could not read landing page directory at '${staticResourcesPath}': ${accessErrorObj.message}`
);
return reject(noAccessError);
}
return resolve(staticResourcesPath);
});
}

static async landingPageFilesExist(
staticResourcesPath: string,
landingPageType: LandingPageType
Expand Down
Loading

0 comments on commit 4030b50

Please sign in to comment.