Skip to content

WIP feature analysis tools#1732

Draft
paustint wants to merge 77 commits into
mainfrom
feat/feature-analysis-tools
Draft

WIP feature analysis tools#1732
paustint wants to merge 77 commits into
mainfrom
feat/feature-analysis-tools

Conversation

@paustint
Copy link
Copy Markdown
Contributor

No description provided.

AndyHaas added 30 commits April 30, 2026 16:03
Optional disabled prop blocks selection, refresh, and describe load so read-only contexts (e.g. Permission Analysis v1) can show the objects column without editing.

Revert-friendly: this commit only touches the three UI files.
Adds AnalysisJob table for persisted permission export / field usage jobs with status, result JSON, and org linkage.
- Extend APP_ROUTES and TITLES for permission and data analysis\n- Register lazy routes in web, canvas, desktop, and extension shells\n- Add Analysis section on home and Analysis Tools in the header\n- Update e2e routing spec for new paths
Introduces the features-data-analysis Nx library (selection UI, route shell, tests) and registers the @jetstream/feature/data-analysis path alias in tsconfig.base.json.
- Permission analysis routes: selection, analysis view with job polling\n- Selection mode disables objects column via existing disabled prop; Continue creates analysis job and navigates with ?job=\n- permission-export scaffold (SOQL helpers, sample query, tests)\n- Export new components from feature index
- Prisma-backed helpers to create, fetch, list, and update analysis jobs\n- In-process permission_export processor (pending → running → completed)\n- Zod-validated controller for create, list, and get-by-id
- Register POST/GET /api/analysis/jobs in api.routes.ts\n- Add createAnalysisJob and getAnalysisJob in shared client-data
Add four reviewer-facing SOQL files under permission-export/soql. Each file notes that the canonical builders live in apps/api/src/app/lib/permission-export/soql-templates.ts (Data API).

- permission-set-by-id.soql: loads PermissionSet rows (Id, Name, Label, IsOwnedByProfile, ProfileId, NamespacePrefix) for the union of profile-linked and standalone permission set Ids used as export parents.

- object-permissions-by-parent.soql: loads ObjectPermissions for those parents (standard CRUD / ViewAll / ModifyAll flags) keyed by ParentId.

- field-permissions-by-parent.soql: loads FieldPermissions (SobjectType, Field, read/edit flags) for the same ParentId set.

- tab-settings-by-parent.soql: loads PermissionSetTabSetting rows (Id, ParentId, tab Name, Visibility) for the same ParentId set.

Placeholders use {{PARENT_IDS}} for substitution when tooling reads these templates; the API uses pre-built TypeScript strings for the running export job.
Server\n- permission-export-query.service: run PermissionSet, ObjectPermissions, FieldPermissions, and Tab SOQL (chunked ParentId IN, 50k row budget) via ApiConnection.\n- analysis-job-processor: resolve org with getOrgForBackgroundJob, execute export, persist counts + export payload on analysis_job.result.\n- lib/permission-export: SOQL builders, id IN formatting/chunking, paged query helper, unit tests for id helpers.\n- route.middleware: createUserSessionStubForBackgroundJob + getOrgForBackgroundJob for jobs without HTTP session.\n\nClient\n- permission-export-query-runner: document pairing with API SOQL; buildPermissionExportSoql unchanged.\n\nChore: remove obsolete permission-set-sample.soql (superseded by Id-based templates).
…lysis

Remove the Refresh Status toolbar action; the export job view already polls GET /api/analysis/jobs/:id every 2s until completed or failed, with a spinner for pending/running.

- Remove ToolbarItemActions, refresh handler state, and useCallback
- Keep renderAllContent on Tabs so tab body stays in sync with polled jobRecord
…alysisJobs

- Include Profile.Name in buildPermissionSetByIdSoql and mirrored permission-set-by-id.soql for profile-owned labels.

- Add listAnalysisJobs() calling GET /api/analysis/jobs with optional limit (default 50).
Add formatAnalysisJobStatusForDisplay() to map API lowercase statuses to title-case UI labels with a sensible default for unknown values.
Add permissionScopeBadgeCss() for profile vs permission set chips, default vs onBrand surfaces, aligned with standalone viewer palette notes.
- Add PermissionAnalysisHistoryModal for past runs, scope filtering, and opening a job.

- Add history toolbar action, job URL updates from the modal, and title-case status via formatAnalysisJobStatusForDisplay; normalize status for polling and spinners.
- Reset SLDS adjacent-button margin inside the Filter by Scope surface so profile rows align with All Runs (spacing from flex gap only).

- Drop clear:both from the popover header.
Use SLDS text-link button classes and a baseline flex row so Clear matches the filter banner copy and uses brand link color.
Remove the Query History parenthetical; keep the single-line row-selection hint.
- Expose customer_portal_users, groups, and incident in standardIcons map

- SVG assets already existed; icons are now available to Icon consumers
…groups

- API builders for PermissionSetAssignment, PSG components, PSG by id, MutingPermissionSet

- Reviewer SOQL mirrors under manage-permissions permission-export/soql
… jobs

- Query PermissionSetAssignment, PSG components, groups, and muting sets under the export row budget

- Include new arrays and counts in job result summary and export payload

- Add parsePermissionExportResult and dynamic column helpers for the reviewer UI
…issues

- Add PermissionAnalysisExportGrid and PermissionAnalysisIssuesTab

- Rework PermissionAnalysisView with tabs aligned to editor chrome and dynamic export tables

- Tighten PermissionAnalysisHistoryModal resize handling
…ders

Boolean Permissions* columns defaulted to 100px and truncated labels like View All Records; set width/minWidth from header text with a 200px floor.
- Permission analysis: Profiles (customers icon) and Permission Sets grids from job requestPayload; hide PSG tab when no group data; legacy jobs keep combined perm set tab

- Manage Permissions editor: optional Profiles / Permission Sets object tabs from selection; register standard customers icon

- Add parsePermissionExportRequestScope and filterPermissionSetExportRowsById helpers
…xport grids

- Add PermissionAnalysisObjectPermissionsTree: DataTree grouped by permission set (ParentId). TreeDataGrid clears renderCell on every groupBy column, so object label and actions use a dedicated static-width Object column (SobjectType) instead of a second group level. Permission Set column uses a capped flexible track (min/max), wrapped group headers, and taller group row height; CRUD columns use minmax fr tracks.

- permission-export-result-view: enforce Salesforce object-permission boolean column order (Create, Read, Edit, Delete, View All Records, Modify All Records, View All Fields) via OBJECT_PERMISSION_COLUMN_KEY_ORDER, sortedObjectPermissionBooleanKeys, and reorderExportKeysForObjectPermissions when rows look like ObjectPermissions exports. Export sortedExportColumnKeys (renamed from internal sorted column keys). Add SobjectExportDetail and collectSobjectApiNamesFromPermissionExport for tooling/describe enrichment. Rename SobjectType header label to Object in getExportColumnHeaderLabel.

- PermissionAnalysisView: load Describe Global labels, then chunked Tooling EntityDefinition (QualifiedApiName, Label, Description) for sobjects referenced in object and field permission exports; pass sobjectExportDetails into the Object Permissions tree and export grids.

- PermissionAnalysisExportGrid: SobjectTypeCellContent shows object label with Tooltip body using inverse SLDS text for dark tooltips; optional Object Manager link only (remove redundant info popover). applySobjectTypeColumn enhances SobjectType cells with metadata and min widths; relax permission boolean columns for fr sizing.
- Add shared definitions for finding codes, human-readable titles, and
  default severities used by API and UI.
- Export the module from the shared constants package index.
- Add build-permission-export-findings to derive structured findings from
  export rows (codes and severities aligned with shared constants).
- Wire the processor to attach findings to completed permission export
  analysis job results.
- Add Vitest coverage for the findings builder.
…lysis UI

- Extend permission-export-result-view with finding aggregation, object
  permission cell highlight keys, listFindingsForObjectPermissionCell,
  and getFindingCodeDisplayParts for catalog labels vs technical codes.
- Pass job findings into the object permissions tree from PermissionAnalysisView.
- Add Vitest specs for aggregate counts and cell/highlight helpers.
…ct grid

- Issues tab: roll up findings by code, severity styling, Issue column with
  human labels, and Issue Codes modal using shared display helpers.
- Object permissions tree: highlight cells with findings, click-to-open modal
  with severity chrome, catalog summary, technical code, and scoped detail
  copy; centered content column with left-aligned text inside.
- Data table: utility classes for finding row/cell severity and clickable cells.
Why: Object-level findings already keyed permission set + object; field
permissions and profile/assignment/tab rows need parallel row/column keys
and container rollups so the UI can highlight cells and list matches without
duplicating ad hoc logic in each screen.

- formatObjectLabelForModalSummary: shared object label line for finding modals.
- buildPermissionSetIdLabelMap: Id -> display label (profiles vs perm sets).
- Field permissions: FIELD_PERMISSION_OBJECT_SCOPE_MARKER, row keys, column
  keys per code, buildFieldPermissionFindingCellHighlights, fieldPermissionCellSeverity,
  listFindingsForFieldPermissionCell (FLS_WITHOUT_OLS applies to any field row
  for the same parent + object).
- Container drill-in: buildContainerIdFindingSeverity, listFindingsForExportContainer,
  pickPermissionSetExportClickableColumnKeys, pickAssignmentExportClickableColumnKeys,
  pickTabVisibilityExportClickableColumnKeys.
- Vitest: export-grid-finding-cells.spec.ts for field and container behavior.
…ct tree

Why: Export grids need the same finding list UX (severity strip, catalog
title + technical code, optional detail and field line). Keeping one modal
avoids drift and trims the object permissions tree file.

- New PermissionAnalysisFindingsModal: title, tagline, summary slot, findings
  list, SLDS footer (directional + Close).
- Object permissions tree: drop inline Modal/Grid and duplicated format/severity
  helpers; use buildPermissionSetIdLabelMap from result-view instead of a local
  copy of permission-set label logic.
AndyHaas and others added 24 commits April 30, 2026 23:38
- Enqueue async processor when jobType is field_usage
- Run SOQL field population scan and Tooling where-used map
- Persist field_usage_v1 result envelope on the job row
- Navigate to analysis view after starting a job; add analysis child routes (web, desktop, canvas, extension)
- FieldUsageAnalysisView: poll job, objects/fields tables, low-usage tab, where-used modal, raw JSON
- Generalize PermissionAnalysisHistoryModal for field_usage (object badges; hide scope filter)
- Export formatAnalysisJobStatusForDisplay; add field usage result parser and unit tests
- Replace object summary + selected-object DataTable with a single DataTree grouped by objectApiName on Objects & Fields and Low usage tabs.

- Memoize parseFieldUsageJobResult output so parsedResult is stable and the expandedGroupIds reset effect does not loop (fixes maximum update depth in DataGrid).
- Increase Where Used tree column width (180px, minWidth 140).

- Use "Where Used" in button, modal header, and empty-state copy.
- Persist extended describe-shaped fieldMeta (digits, displayFormat, etc.) from field usage jobs.

- Add getFieldUsageTypeLabel: Reference (targets), Auto Number with pattern/digits, legacy int/double as Number, Lookup→Reference rewrite.

- polyfillFieldDefinition: space before ( in Text Area, Currency, Number, Lookup, Formula, etc.

- Field usage grid: column filters on metrics columns, locale datetime for latest mod, wider Type/Where Used, remove duplicate group chevron, capitalize Where Used.
- Fix Where Used modal DataTable height via AutoFullHeightContainer\n- Resolve whereUsed keys with trim/case fallback; add fieldHasWhereUsedDeps\n- Show Where Used button only when dependency rows exist\n- Add On layout, In automation, In Apex columns from Tooling metadata types\n- Add countWhereUsedByUiCategory helper and unit tests
…ng parser

- Classify ApexClass, ApexPage, and ApexComponent as kind apex; keep triggers in automation; sort deps automation, apex, other.
- When parsing stored whereUsed, infer automation/apex from Tooling type if kind was other (legacy payloads).
- Add parseCustomFieldApiNameForTooling in shared utils with tests; use in where-used Tooling queries, Where Is This Used, and field namespace resolution.
- Classify Layout, FlexiPage, and FieldSet as kind layout; show Kind column label Layout; infer from Tooling type for legacy stored jobs.
- Add shared dedupeFieldUsageWhereUsedRows for Flow/FlowDefinition; sort order includes layout; use from API and parse.
- whereUsed grid totals (on layout / in automation / in apex) use each row’s kind so they match the Kind column.
- Fix API Flow enrichment: query Id and VersionNumber only; Tooling Flow has no DurableId; use Flow Id for Flow Builder URLs
- Add getWhereUsedOpenInSalesforcePath fallback and unit tests; extend parse for stored paths
- Field usage tree: light Popover panels (Object Manager links, ReadOnlyFormElement layout) for object groups and fields; expand/collapse on chevron column only
- Pass org/serverUrl/skipFrontdoorLogin into DataTree
- API: optional loadFullScan on field_usage payload; runFieldUsageQueryForObjects uses uncapped row budget when set
- UI: toolbar button (enabled when job truncated) opens confirmation modal, then starts new job with same objects + loadFullScan and navigates to new job id
Add footer action that builds SELECT Id, LastModifiedDate, analyzed fields FROM object (no WHERE), stores payload in sessionStorage for QueryResults, and opens /query/results in a new tab.
- Narrow requestPayload so loadFullScan is a boolean for runFieldUsageQueryForObjects (fixes TS2322).

- Popover: merge buttonProps.style with buttonStyle instead of replacing it.

- Field usage: pass Popover layout via buttonStyle; wrap Load all records label in span for collapsible-button.
…elds

- Reuse Deploy Metadata delete flow via DeleteMetadataModal for eligible rows on Objects & Fields and Low usage tabs.

- Add field-usage-destructive-delete helpers and tests; export DeleteMetadataModal from feature-deploy.

- Add shared-utils helpers (e.g. isUnmanagedCustomFieldApiName) built on parseCustomFieldApiNameForTooling.

- Align toolbar DropDown settings Icon with default chevron (hint + small + icon_container) so the gear renders.
sessionStorage is not visible to a tab opened with window.open; write the SOQL handoff to localStorage from Field Usage and read it in QueryResults (then clear) after sessionStorage fallback.
window.open used /query/results from the origin root; use useHref so the new tab targets /app/query/results (or the active basename on desktop/canvas).
- Title-case Field Usage, Custom Field/Object, Metadata Type, and related labels across results, selection, history modal, job summary, and DATA_ANALYSIS route description.

- Compute query results href once in FieldUsageAnalysisView and pass into object group popovers (single useHref).
…n code unknown

buildContainerIdFindingSeverity skipped findings whose code was missing from
PERMISSION_EXPORT_FINDING_DEFINITIONS, so Permission Sets / Profiles trees never
showed error or warning badges beside Setup even when the Issues list did.

Fall back to finding.severity for unknown codes (same semantics as issue rollup).
Add a Vitest case for a non-catalog code with error severity.
- Add Field Usage and permission export history buttons opening PermissionAnalysisHistoryModal

- Allow /analysis with ?job= without selected profiles or permission sets

- Render profiles slice with PermissionAnalysisPermissionSetsTree (profiles presentation)

- Profile-aware column labels, empty states, and findings modal copy in perm set tree

- Show Raw JSON job payload tabs only in Vite dev; friendlier prod message for legacy jobs

- Clarify object/field tooltip headings (API name vs label) in grids and field tree
- Match Field Usage: click Popover + ReadOnlyFormElement instead of hover Tooltip
- Permission set/profile rows: shared PermissionSetDetailPopoverContent; chevron-only expand
- Object and field surfaces: SobjectTypeCellContent and field cells use same pattern; shift+click opens Setup
Copilot AI review requested due to automatic review settings May 16, 2026 22:32
@paustint paustint marked this pull request as draft May 16, 2026 22:32
continue;
}
const separatorIdx = key.indexOf('::');
if (separatorIdx <= 0 || separatorIdx === key.length - 2) {
}

function readSalesforceRelationshipName(value: unknown): string | null {
if (value && typeof value === 'object' && value !== null && 'Name' in value) {
const profileName =
profileBlock &&
typeof profileBlock === 'object' &&
profileBlock !== null &&
const profileName =
profileBlock &&
typeof profileBlock === 'object' &&
profileBlock !== null &&
const counts = parsedExport.counts;

const containerLabelById = buildPermissionSetIdLabelMap(exportBundle.permissionSets);
const exportFindingProps = { findings: globallyFilteredFindings, containerLabelById };
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds browser-side Permission Analysis and Data Analysis/Field Usage tooling, backed by local Dexie history, background jobs, compressed result storage, new analysis routes, and UI surfaces for viewing/exporting findings.

Changes:

  • Adds analysis job schemas, Dexie local history, gzip helpers, background job handling, routes, nav/home entries, and job popover “View” support.
  • Adds permission export analysis runners, finding aggregation, result parsing/view helpers, history modal integration, and UI highlighting/filtering.
  • Adds Field Usage analysis runner, where-used lookup, destructive-delete helpers, result views/tests, and supporting shared utilities.

Reviewed changes

Copilot reviewed 121 out of 122 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tsconfig.base.json Adds path alias for data-analysis feature.
libs/ui/src/lib/widgets/ProfileOrPermSetPopover.tsx Adds Salesforce setup URL helpers.
libs/ui/src/lib/widgets/ItemSelectionSummary.tsx Honors disabled state for item clearing.
libs/ui/src/lib/sobject-list/SobjectListMultiSelect.tsx Propagates disabled state through object selection UI.
libs/ui/src/lib/sobject-list/ConnectedSobjectListMultiSelect.tsx Adds disabled support to connected object list.
libs/ui/src/lib/sobject-field-list/useWhereIsThisUsed.tsx Uses shared custom-field tooling-name parser.
libs/ui/src/lib/popover/Popover.tsx Merges trigger styles from button props.
libs/ui/src/lib/data-table/useDataTable.tsx Lazily builds quick-filter row text.
libs/ui/src/lib/data-table/DataTree.tsx Enables virtualization on tree grids.
libs/ui/src/lib/data-table/DataTable.tsx Formatting-only interface change.
libs/ui/src/lib/data-table/data-table-styles.scss Adds permission analysis finding highlight styles.
libs/ui/src/lib/card/Card.tsx Adjusts card header min-width behavior.
libs/types/src/lib/ui/types.ts Adds analysis async job types and metadata.
libs/types/src/lib/analysis-job-types.ts Adds Zod schemas/types for analysis history/results.
libs/types/src/index.ts Exports analysis job types.
libs/shared/utils/src/lib/sobject-api-name-utils.ts Adds Salesforce ID and object-name sanitizers.
libs/shared/utils/src/lib/regex.ts Corrects Salesforce ID length regex.
libs/shared/utils/src/lib/dedupe-field-usage-where-used.ts Adds where-used dedupe/sort helpers.
libs/shared/utils/src/lib/custom-field-tooling-names.ts Adds custom-field API-name parsing helpers.
libs/shared/utils/src/lib/compression.ts Adds gzip encode/decode helpers.
libs/shared/utils/src/lib/__tests__/sobject-api-name-utils.spec.ts Tests object-name/ID utilities.
libs/shared/utils/src/lib/__tests__/dedupe-field-usage-where-used.spec.ts Tests where-used dedupe/sort helpers.
libs/shared/utils/src/lib/__tests__/custom-field-tooling-names.spec.ts Tests custom-field parsing helpers.
libs/shared/utils/src/index.ts Exports new shared utilities.
libs/shared/ui-utils/src/lib/shared-ui-utils.ts Updates field type display formatting.
libs/shared/ui-router/src/lib/ui-router.ts Adds analysis app routes.
libs/shared/ui-db/src/lib/ui-db.ts Adds local analysis history Dexie table.
libs/shared/ui-db/src/lib/analysis-job-history-retention.ts Adds analysis history pruning.
libs/shared/ui-db/src/index.ts Exports retention helper.
libs/shared/ui-core/src/jobs/JobWorker.ts Runs analysis jobs and writes compressed history rows.
libs/shared/ui-core/src/jobs/Jobs.tsx Handles analysis job progress/results.
libs/shared/ui-core/src/jobs/Job.tsx Adds cancel/view support for analysis jobs.
libs/shared/ui-core/src/index.ts Exports jobs state.
libs/shared/ui-core/src/create-fields/create-fields-load-utils.ts Uses shared field namespace parser.
libs/shared/ui-core/src/app/HeaderNavbarItems.tsx Adds Analysis Tools navbar menu.
libs/shared/ui-core/src/app/AppHome/AppHome.tsx Adds Analysis home card.
libs/shared/data/src/lib/data-utils.ts Adds paginated query-with-budget helper.
libs/shared/data/src/lib/client-data.ts Formatting-only change.
libs/shared/data/src/index.ts Exports data utilities.
libs/shared/constants/src/lib/shared-constants.ts Adds analysis page titles.
libs/shared/constants/src/lib/permission-export-finding-codes.ts Adds permission finding code catalog.
libs/shared/constants/src/index.ts Exports finding constants.
libs/icon-factory/src/lib/icon-factory.tsx Registers additional icons.
libs/features/query/src/QueryResults/QueryResults.tsx Adds localStorage query handoff fallback.
libs/features/manage-permissions/src/PermissionAnalysisSelection.tsx Adds permission analysis selection entry.
libs/features/manage-permissions/src/PermissionAnalysisFindingsModal.tsx Adds finding detail modal.
libs/features/manage-permissions/src/PermissionAnalysisFindingsFiltersBar.tsx Adds issue filter toolbar.
libs/features/manage-permissions/src/PermissionAnalysis.tsx Adds permission analysis route shell.
libs/features/manage-permissions/src/PermissionAnalysisView.tsx Adds permission analysis result view.
libs/features/manage-permissions/src/permission-export/substitute-soql-placeholders.ts Adds SOQL placeholder substitution.
libs/features/manage-permissions/src/permission-export/substitute-soql-placeholders.spec.ts Tests placeholder substitution.
libs/features/manage-permissions/src/permission-export/soql/*.soql Adds reviewer/reference SOQL templates.
libs/features/manage-permissions/src/permission-export/soql-templates.ts Adds composed permission export SOQL builders.
libs/features/manage-permissions/src/permission-export/permission-export-query-runner.ts Adds template query runner wrapper.
libs/features/manage-permissions/src/permission-export/index.ts Exports permission export modules.
libs/features/manage-permissions/src/permission-export/build-permission-export-findings.ts Builds permission analysis findings and summaries.
libs/features/manage-permissions/src/permission-export/__tests__/soql-templates.spec.ts Tests SOQL builders.
libs/features/manage-permissions/src/permission-export/__tests__/run-permission-export.spec.ts Tests export runner.
libs/features/manage-permissions/src/permission-export/__tests__/build-permission-export-findings.spec.ts Tests finding generation.
libs/features/manage-permissions/src/permission-export-result-view.ts Re-exports result-view modules.
libs/features/manage-permissions/src/permission-export-result-view-modules/* Adds permission export parsing/sorting/column helpers.
libs/features/manage-permissions/src/permission-analysis-viewer-badge.styles.ts Adds analysis badge styles.
libs/features/manage-permissions/src/permission-analysis-tree-group-title.ts Adds group-title helper.
libs/features/manage-permissions/src/permission-analysis-issues-filters.ts Adds URL-backed issue filters.
libs/features/manage-permissions/src/permission-analysis-export-metadata-context.tsx Adds export metadata context.
libs/features/manage-permissions/src/ManagePermissionsSelection.tsx Adds permission-analysis mode and job start flow.
libs/features/manage-permissions/src/ManagePermissionsEditor.tsx Splits object permission columns into profile/permission-set tabs.
libs/features/manage-permissions/src/index.ts Exports analysis modules.
libs/features/manage-permissions/src/analysis-job-status-display.ts Adds status label formatter.
libs/features/manage-permissions/src/__tests__/export-grid-finding-cells.spec.ts Tests finding cell helpers.
libs/features/manage-permissions/src/__tests__/aggregate-permission-findings.spec.ts Tests finding aggregation.
libs/features/manage-permissions/eslint.config.js Adds lint suppression comment.
libs/features/deploy/src/index.ts Exports delete metadata modal.
libs/features/data-analysis/* Adds new data-analysis project config.
libs/features/data-analysis/src/DataAnalysis.tsx Adds data analysis route shell.
libs/features/data-analysis/src/DataAnalysisSelection.tsx Adds field usage selection/job launcher.
libs/features/data-analysis/src/FieldUsageAnalysisView.tsx Adds field usage result view.
libs/features/data-analysis/src/field-usage/run-field-usage.ts Adds field usage scan runner.
libs/features/data-analysis/src/field-usage/compute-field-usage-where-used.ts Adds Tooling where-used lookup.
libs/features/data-analysis/src/field-usage-destructive-delete.ts Adds destructive delete eligibility/metadata helpers.
libs/features/data-analysis/src/where-used-open-in-salesforce.ts Adds Salesforce deep-link fallback helpers.
libs/features/data-analysis/src/shared/analysis-job-runtime-state.ts Adds analysis job runtime helpers.
libs/features/data-analysis/src/field-usage-result-parse.ts Adds field usage parsing helpers.
libs/features/data-analysis/src/**/*.spec.ts Adds data-analysis tests.
apps/jetstream/src/app/components/core/AppInitializer.tsx Prunes analysis history after DB init.
apps/jetstream/src/app/AppRoutes.tsx Adds web analysis routes.
apps/jetstream-e2e/src/tests/app/routing.spec.ts Adds routing coverage for analysis links.
apps/jetstream-desktop-client/src/app/components/core/AppInitializer.tsx Prunes analysis history after DB init.
apps/jetstream-desktop-client/src/app/AppRoutes.tsx Adds desktop analysis routes.
apps/jetstream-canvas/src/app/AppRoutes.tsx Adds canvas analysis routes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

title: `Field Usage Analysis (${selectedSObjects.length} Object${selectedSObjects.length === 1 ? '' : 's'})`,
org: selectedOrg,
meta,
viewUrl: `/analysis?job=${encodeURIComponent(jobHistoryKey)}`,
Comment on lines +23 to +24
const selectedSObjectsAtom = atom<string[]>([]);
const sobjectsAtom = atom<DescribeGlobalSObjectResult[] | null>(null);
Comment on lines +21 to +42
return `/lightning/setup/ApexClasses/page?address=${encodeURIComponent(encodeURIComponent(`/${id}`))}`;
}
if (t === 'ApexTrigger') {
return `/lightning/setup/ApexTriggers/page?address=${encodeURIComponent(encodeURIComponent(`/${id}`))}`;
}
if (t === 'ApexPage') {
return `/lightning/setup/ApexPages/page?address=${encodeURIComponent(encodeURIComponent(`/${id}`))}`;
}
if (t === 'ApexComponent') {
return `/lightning/setup/ApexComponents/page?address=${encodeURIComponent(encodeURIComponent(`/${id}`))}`;
}
if (t === 'FlexiPage') {
return `/lightning/setup/FlexiPageList/page?address=${encodeURIComponent(encodeURIComponent(`/${id}`))}`;
}
if (t === 'Layout') {
return `/lightning/setup/LayoutDefinitions/page?address=${encodeURIComponent(encodeURIComponent(`/${id}`))}`;
}
if (t === 'FieldSet') {
return `/lightning/setup/FieldSets/page?address=${encodeURIComponent(encodeURIComponent(`/${id}`))}`;
}
if (t === 'WorkflowRule' || t === 'WorkflowFieldUpdate') {
return `/lightning/setup/WorkflowRules/page?address=${encodeURIComponent(encodeURIComponent(`/${id}`))}`;
Comment on lines +474 to +476
let whereUsed: Record<string, unknown[]> = {};
try {
whereUsed = (await computeFieldUsageWhereUsed(org, queryOutcome.objects)) as unknown as Record<string, unknown[]>;
Comment on lines +131 to +145
row.openInSalesforcePath = `/lightning/setup/ApexClasses/page?address=${encodeURIComponent(encodeURIComponent(`/${componentId}`))}`;
} else if (componentType === 'ApexTrigger') {
row.openInSalesforcePath = `/lightning/setup/ApexTriggers/page?address=${encodeURIComponent(encodeURIComponent(`/${componentId}`))}`;
} else if (componentType === 'ApexPage') {
row.openInSalesforcePath = `/lightning/setup/ApexPages/page?address=${encodeURIComponent(encodeURIComponent(`/${componentId}`))}`;
} else if (componentType === 'ApexComponent') {
row.openInSalesforcePath = `/lightning/setup/ApexComponents/page?address=${encodeURIComponent(encodeURIComponent(`/${componentId}`))}`;
} else if (componentType === 'FlexiPage') {
row.openInSalesforcePath = `/lightning/setup/FlexiPageList/page?address=${encodeURIComponent(encodeURIComponent(`/${componentId}`))}`;
} else if (componentType === 'Layout') {
row.openInSalesforcePath = `/lightning/setup/LayoutDefinitions/page?address=${encodeURIComponent(encodeURIComponent(`/${componentId}`))}`;
} else if (componentType === 'FieldSet') {
row.openInSalesforcePath = `/lightning/setup/FieldSets/page?address=${encodeURIComponent(encodeURIComponent(`/${componentId}`))}`;
} else if (componentType === 'WorkflowRule' || componentType === 'WorkflowFieldUpdate') {
row.openInSalesforcePath = `/lightning/setup/WorkflowRules/page?address=${encodeURIComponent(encodeURIComponent(`/${componentId}`))}`;
* Terminal Dexie row for this jobHistoryKey, kept reactive via useLiveQuery so the view updates
* the moment the JobWorker writes the row.
*/
const historyRow = useLiveQuery(() => (jobId ? dexieDb.analysis_job_history.get(jobId) : undefined), [jobId]);
* Terminal Dexie row for this jobHistoryKey, kept reactive via useLiveQuery so the view updates
* the moment the JobWorker writes the row.
*/
const historyRow = useLiveQuery(() => (jobId ? dexieDb.analysis_job_history.get(jobId) : undefined), [jobId]);
import { FunctionComponent } from 'react';
import { ManagePermissionsSelection } from './ManagePermissionsSelection';

/** Permission analysis entry: same selection UX as Manage Permissions with objects disabled (v1). */
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.

4 participants