Skip to content

feat: React-based Profile/PermissionSet Editor UI for VSCode#438

Draft
Copilot wants to merge 10 commits into
mainfrom
copilot/add-ui-for-salesforce-profiles
Draft

feat: React-based Profile/PermissionSet Editor UI for VSCode#438
Copilot wants to merge 10 commits into
mainfrom
copilot/add-ui-for-salesforce-profiles

Conversation

Copy link
Copy Markdown

Copilot AI commented Mar 15, 2026

Adds a table-driven webview editor for Salesforce Profiles and Permission Sets, focused on FLS and object access management at scale (500+ objects, 800+ fields per object).

Webview Infrastructure

  • WebviewPanel<TIn, TOut> — reusable base class for VSCode webview panels; handles CSP nonces, HTML scaffolding, and typed bidirectional postMessage communication
  • src/lib/webview/types.ts — shared message/data contracts used by both the extension host and the React bundle

Extension Backend

  • ProfileEditorWebview — loads profile/permset metadata, saves changes as source file or to the org, exposes object/field describe for "Add Permission" flow, runs structural validation automatically on load and org-level validation on request
  • ProfileEditorCommand (vlocode.editProfilePermissions) — opens on .profile-meta.xml / .permissionset-meta.xml; registered in command palette and explorer/editor context menus
  • OpenProfileFromOrgCommand (vlocode.openProfileFromOrg) — new command to open a Profile or PermissionSet directly from the org via a Quick Pick selector

React UI (src/webviews/profileEditor/)

  • Two virtualized tables (react-window) — Object Permissions (R/C/E/D/View All/Modify All columns) and Field-Level Security (Object/Field/R/E columns); both enforce Salesforce access dependency rules in-place (e.g. Modify All → sets all others; editable → readable)
  • Multi-row selection — shift-click and ctrl-click for range/toggle selection in both tables; bulk remove of selected rows
  • Per-row remove action — remove a single object or field permission directly from the row
  • Filter bar — live filter with match count; filter hits rendered bold; uses codicon-search / codicon-close
  • Profile header — VS Code Codicon type badge (codicon-account for Profile, codicon-shield for PermissionSet), user license, object/field counts, and description using codicon-tag, codicon-symbol-class, codicon-symbol-field, and codicon-info
  • Floating ActionBar — save/reset only visible when changes exist; save targets both source file and org; shows unsaved change count; refresh button to reload from org
  • AddPermissionDialog — fetches available objects/fields via describeSObjects / describeSObject on demand; uses codicon-close
  • Problems tab — displays structural and org-level validation problems plus deployment errors in a table; each row shows severity, item name, explanation, optional Salesforce documentation link, and a Fix button for fixable problems (auto-applies the correction in-place)
  • Status banners — use codicon-error and codicon-loading (with spin modifier) instead of emoji

SalesforceProfileValidator (@vlocode/salesforce)

A reusable, config-table-driven validator living in the salesforce package — the profile editor consumes it rather than implementing its own rules.

// Each rule is a plain-object entry in a config table:
// { id, type, metadata, evaluate(profile, item, itemType, meta, ctx) }

SalesforceProfileValidator.validate(profile);
// → runs all structural rules, returns ProfileValidationProblem[]

await SalesforceProfileValidator.validateAgainstOrg(profile, schemaService);
// → additionally checks for unknown objects/fields in the org (parallel describeSObject calls)

Structural rules: obj-editable-not-readable, obj-viewall-not-readable, obj-modifyall-incomplete, obj-no-permissions, field-editable-not-readable, field-no-object-read, field-no-permissions, class-disabled.
Org-level rules: org-unknown-object, org-unknown-field.
Each problem carries severity, category, itemType, itemName, message, optional docsUrl, and fixable / fixAction metadata.
A ProfileValidationContext (pre-built Map<string, ObjectPermission>) is passed to every evaluator for O(1) lookups instead of O(n) linear scans.

SalesforceUserPermissions API additions

profile.setObjectPermissions('Account', { modifyAllRecords: true });
// → automatically sets viewAllRecords, allowRead, allowCreate, allowEdit, allowDelete = true

profile.setFieldPermissions('Account.Name', readable, editable);
// → editable=true forces readable=true

profile.removeObjectPermissions('Account');
profile.removeFieldPermissions('Account.Name');

profile.license;      // userLicense (Profile) or license (PermissionSet)
profile.description;  // optional description text

Build

  • Webview bundled as a browser-platform entry via tsdown (dist/webviews/profile-editor.mjs)
  • codicons.scss@vscode/codicons font embedded as a base64 data:font/truetype URI for reliable delivery inside VSCode webviews
  • Added react, react-dom, react-window, @vscode/codicons as devDependencies

Screenshot

Original prompt

extend Vlocode with an UI for editing Salesforce profiles and permission sets. The focus of the UI is to make it easier to set FLS and object access and manage other permissions of the profile or permissionssets. Use tables to edit the fls in the profile or permissionssets and allow filtering the object or field. the rows are the field and object whereas the columns display the access level. keep in mind the SF rules areound fields. the ui will have filter on top that can be used to only display fields/objects that you are interested in. when filtering matches should be made bold. on the bottom of the screen there will be a floating save/reset button to persisit changes. on top display information about the profile such as the name, license type as well as number of objects in the profile. the UI also allows adding now permission for that use describe to list available objects and Fields.

use React for the UI and ensure it fits well into vscode following th best practices for VScode UI development. ensure that the VScode extension can communicate with the UI. for this build a reusable component.

all code is following OOO approach with proper soc. the UI must be responsive and take into consideration that some objects have 800 fields, and there can be more then 500 Objects.


📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

Copilot AI and others added 2 commits March 15, 2026 23:49
- Add reusable WebviewPanel base class for VSCode webview panels
- Add ProfileEditorWebview backend with profile data loading and save
- Add ProfileEditorCommand to open the editor from context menu or palette
- Add React-based UI with virtualized object/field permission tables
- Add filter bar with match highlighting for 500+ objects / 800+ fields
- Add floating ActionBar for save/reset operations
- Add AddPermissionDialog for adding new object/field permissions
- Add setObjectPermissions() and setFieldPermissions() public API to SalesforceUserPermissions
- Add license and description public getters to SalesforceUserPermissions
- Add esbuild script for bundling React webview
- Register editProfilePermissions command in constants.ts and commands.yaml
- Add React, react-dom, react-window, esbuild as devDependencies"

Co-authored-by: Codeneos <[email protected]>
- Fix Salesforce field type comparison to be case-insensitive (id vs ID)
- Fix modifyAllRecords to unconditionally set all object permissions
- Remove duplicate config.vlocity.salesforce.enabled from menu when conditions
- Remove unnecessary type cast in App.tsx reducer
- Add 'saving' to AppAction union type for proper type safety
- Fix handleSave to dispatch 'saving' action instead of 'loading'"

Co-authored-by: Codeneos <[email protected]>
Copilot AI changed the title [WIP] Add UI for editing Salesforce profiles and permission sets feat: React-based Profile/PermissionSet Editor UI for VSCode Mar 16, 2026
Copilot AI requested a review from Codeneos March 16, 2026 00:01
@Codeneos
Copy link
Copy Markdown
Owner

@copilot Update the profile header to be more inline with the VScode standards.
Change the icons to the vscode standard icon set.

- Install @vscode/codicons devDependency
- Generate codicons.scss with base64-embedded font for reliable webview delivery
- ProfileHeader: replace 👤/🔑 with codicon-account/codicon-shield
- ProfileHeader: replace bold labels with codicon-tag/symbol-class/symbol-field/info
- FilterBar: replace 🔍 search emoji with codicon-search
- FilterBar: replace ✕ clear button text with codicon-close
- AddPermissionDialog: replace ✕ close button text with codicon-close
- App.tsx: replace ⚠/⏳ banner emojis with codicon-error/codicon-loading
- Update styles.scss to use symbolIcon color tokens for codicons
- Profile icon uses --vscode-symbolIcon-classForeground (orange)
- PermissionSet icon uses --vscode-symbolIcon-keywordForeground (blue)"

Co-authored-by: Codeneos <[email protected]>
Copy link
Copy Markdown
Author

Copilot AI commented Mar 17, 2026

@copilot Update the profile header to be more inline with the VScode standards.
Change the icons to the vscode standard icon set.

Done in commit 7622301. All emoji icons have been replaced with VS Code Codicons:

  • Profile header: codicon-account (Profile) / codicon-shield (PermissionSet), with color tokens --vscode-symbolIcon-classForeground (orange) and --vscode-symbolIcon-keywordForeground (blue)
  • Metadata tags: codicon-tag (license), codicon-symbol-class (objects), codicon-symbol-field (fields), codicon-info (description)
  • Filter bar: codicon-search + codicon-close
  • Banners: codicon-error and codicon-loading (with spin modifier)

The codicon font is embedded as a base64 data URI in codicons.scss so it loads reliably inside the VSCode webview without any resource URI workarounds.

Profile editor with VS Code Codicons

@sonarqubecloud
Copy link
Copy Markdown

@Codeneos
Copy link
Copy Markdown
Owner

@copilot update the UI to support changing fields permissions in bulk by allowing selecting multiple rows using shift-click or ctrl-click. Allow removing permissions from the profile by adding a remove action for each row. Add support for refreshing the profile/permissionsset from the org and saving changes both as source file and to the org. Add a new command in the command pallet to open a profile or permissionset from the org instead of loading it from the file. Add a new tab in which problems and profile errors would be shown. When possible allow individuap errors to be fixed through a fix button behind the error. Errors are also displayed in a table. Possible errors are none existing fields, objects and classes or inconsistencues such as having permissions for a requir de field. Include a explanation of the error and when possible a link to a Salesforce documentation page. The prermission problem scanner must use a config table in the from of an Ja object that stores and evaluator that accepts the profile, the profile irem being scanned (FieldAccess, etc) and the type (FieldAccess, ApexClassAccess) as well as rule metadata. When a profile cannot be saved to the org because of errors add these errors to the same tab but catorgeize as deployment error.

Copy link
Copy Markdown
Author

Copilot AI commented Mar 19, 2026

@copilot update the UI to support changing fields permissions in bulk by allowing selecting multiple rows using shift-click or ctrl-click. Allow removing permissions from the profile by adding a remov...

Done in commit e7d8f20. Here's a summary of what was implemented:

Permission Validator (new requirement) — @vlocode/salesforce

  • Created SalesforceProfileValidator in packages/salesforce/src/salesforceProfileValidator.ts
  • Config-table of named evaluators: each rule stores { id, type, metadata, evaluate(profile, item, itemType, meta, ctx) }
  • Pre-computed ProfileValidationContext with a Map<string, AnyObjectPermission> so the field-no-object-read rule avoids O(n×m) linear scans
  • Structural rules (no org connection): obj-editable-not-readable, obj-viewall-not-readable, obj-modifyall-incomplete, obj-no-permissions, field-editable-not-readable, field-no-object-read, field-no-permissions, class-disabled
  • Org-level rules (validateAgainstOrg): org-unknown-object, org-unknown-field — all describeSObject calls are dispatched in parallel via Promise.allSettled
  • Exported from @vlocode/salesforce/src/index.ts

Extension backend — profileEditorWebview.ts

  • Structural validation runs automatically on every profile load (results sent as problems message)
  • Org-level validation runs on user request (Validate button in Problems tab)
  • mapValidationProblem() bridges the salesforce package DTO to the webview-facing DTO
  • Deployment errors are categorized separately when org save fails

React UI — Problem tab

  • Removed permissionRules.ts from the webview frontend entirely
  • ProblemsTable.tsx receives all problems from the backend; Fix actions look up current state before dispatching to avoid overwriting existing permissions
  • actions.ts is the single source for AppAction type

Other features (also in this PR)

  • Multi-row shift/ctrl-click selection + bulk remove in both tables
  • Per-row remove button
  • Refresh from org button
  • Save to source file vs. save to org split
  • New command: Open Profile/PermissionSet from Org (Quick Pick in command palette)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants