Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse sObjects in the landing page and return them in an array #51

Merged
merged 21 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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",
sfdctaka marked this conversation as resolved.
Show resolved Hide resolved
"@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">
khawkins marked this conversation as resolved.
Show resolved Hide resolved
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>
62 changes: 48 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 { UIUtils } from '../../utils/uiUtils';
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,52 @@ 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 UIUtils.getStaticResourcesDir();
sfdctaka marked this conversation as resolved.
Show resolved Hide resolved
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 +78,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 +90,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
36 changes: 3 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 { UIUtils } from '../../utils/uiUtils';

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,7 @@ export class TemplateChooserCommand {
}

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

let staticResourcesPath: string;
try {
staticResourcesPath = await this.getStaticResourcesDir();
staticResourcesPath = await UIUtils.getStaticResourcesDir();
} catch (err) {
landingPageCollectionStatus.error = (err as Error).message;
return resolve(landingPageCollectionStatus);
Expand Down Expand Up @@ -243,31 +238,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