Skip to content

Add standalone lead and opportunity forms#65

Draft
LoesV wants to merge 20 commits into
mainfrom
lead-creation-flow
Draft

Add standalone lead and opportunity forms#65
LoesV wants to merge 20 commits into
mainfrom
lead-creation-flow

Conversation

@LoesV

@LoesV LoesV commented Jul 15, 2026

Copy link
Copy Markdown
Member

No description provided.

LoesV and others added 20 commits July 14, 2026 17:07
Add "Add lead" and "Add opportunity" forms that are accessible to users without Dynamics/Dataverse access. These forms submit via new DataMiner automation scripts (DynamicsActivities_SubmitLead and DynamicsActivities_SubmitOpportunity) that email the submissions to a configured recipient.

Includes:
- Two new automation scripts with HTML email formatting
- Form components with validation and success states
- Hash-based router for standalone form pages
- Form registry system for adding future forms
- "Add lead" and "Add opportunity" buttons on auth-denied screens
- Styling for form grids, actions, and success messages
- Updated documentation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add isTestEnvironment() so the bottom-left license view tester renders on localhost and the DataMiner dev deployment (/public/DynamicsActivitiesDev/) but never on production or RC. Enrich the detected label with the full systemuser.caltype option-set names (verified against the Dataverse Web API reference). Bump package to 1.11.0 and document the control in the README.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reworked lead and opportunity submissions to open a prefilled email draft in the user’s mail client instead of calling DataMiner automation scripts. Added a shared `mailto` helper to build and launch drafts, updated both API clients to use it, and simplified both form components by removing async submit/loading and confirmation modal flows. The solution file was also updated to remove the now-unused submit script projects.
Lead and opportunity mailto drafts now include a 'Submitted by: Name <email>' line populated from the DMA session user. Both name and email are guarded — empty/missing values are omitted. Adds a reusable `formatSubmitter` helper in mailto.js.
Lead and opportunity forms now reuse the shared Dataverse account search via `AutocompletePicker`, suggesting existing accounts while still allowing free-text company entry through raw query updates. The picker now supports an `onQueryChange` callback and resets cleanly when submitting another item.

This update also adjusts lead handling: first name, last name, and email are now optional (with email format checked only when provided), and lead email subjects use the lead topic plus optional company instead of contact name. Package version metadata was bumped to 1.12.4 with an updated version comment.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds standalone lead/opportunity submission flows to the DynamicsActivities SPA, aimed at Team Member CAL users who can browse but can’t manage leads/opportunities natively in Dynamics. It introduces hash-based routing for these standalone pages and adds a local/dev-only license “view override” widget to preview access states, alongside packaging and CI/CD updates for dev deployments.

Changes:

  • Added standalone #/forms/lead and #/forms/opportunity pages (registry + shared shell) that submit via prefilled mailto: drafts.
  • Added Team Member-only “Add lead/opportunity” entry points from the Leads/Opportunities browse views, plus license/CAL detection and a local/dev test override control.
  • Updated DMAPP packaging + GitHub workflows to better support dev folder deployments and non-production version suffixing.

Reviewed changes

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

Show a summary per file
File Description
src/styles/main.css Adds styling for standalone forms, confirmation modal/footer, filter add button placement, and the license test widget.
src/main.jsx Wraps app in LicenseTestProvider and conditionally renders the license test control in test environments.
src/hooks/useHashRoute.js Introduces a minimal hash router + navigation helper for #/forms/... routes.
src/forms/registry.js Central registry for standalone forms (lead, opportunity).
src/context/LicenseTestContext.jsx Adds persisted license-view override state and helpers for Sales vs Team Member behavior.
src/components/NotesList.jsx Adds per-view “Add lead/opportunity” buttons for Team Member users and persists active browse view in sessionStorage.
src/components/LicenseTestControl.jsx Adds a pinned local/dev test UI to force access/license views.
src/components/forms/OpportunityForm.jsx New standalone opportunity form that opens a prefilled email draft.
src/components/forms/LeadForm.jsx New standalone lead form that opens a prefilled email draft.
src/components/forms/FormPage.jsx Generic standalone form page shell with header/back navigation.
src/components/AutocompletePicker.jsx Adds onQueryChange hook to support free-text entry alongside suggestions.
src/components/AuthGuard.jsx Reports detected CAL type and supports test overrides for license/access state.
src/components/ActivityForm.jsx Honors license test override when deciding whether to show lead-management links.
src/App.jsx Routes forms/* outside the AuthGuard; wires currentUserId into NotesList.
src/api/opportunities.js Mailto-based submission client for opportunity form.
src/api/mailto.js Shared helpers to build and open mailto: drafts and format submitter info.
src/api/leads.js Mailto-based submission client for lead form.
src/api/dataminer.js Adds DataMinerServerError surfacing option and isTestEnvironment() helper.
README.md Updates docs for standalone forms and adds documentation for license test control.
package.json Bumps frontend package version.
DynamicsActivitiesPackage/DynamicsActivitiesPackage/PackageContent/CompanionFiles/Skyline DataMiner/.gitignore Broadens ignore to cover production + dev web public folders.
DynamicsActivitiesPackage/DynamicsActivitiesPackage/DynamicsActivitiesPackage.csproj Updates version/comment and adjusts companion file copying/cleaning logic for dev/prod folder targets.
.github/workflows/deploy-dmapp-reusable.yml Adds workflow inputs for dev builds/version suffix and passes extra MSBuild properties.
.github/workflows/deploy-dma-on-pr-merge.yml Improves manual deploy UX; adds dev deployment defaults and version suffixing.
.github/copilot-instructions.md Updates key source file list to include new standalone-form and mailto modules.

Comment on lines +49 to +56
function readStoredOverride() {
try {
const stored = localStorage.getItem(STORAGE_KEY)
return LICENSE_OVERRIDES.some((o) => o.value === stored) ? stored : ''
} catch {
return ''
}
}
Comment on lines +403 to +421
const [activeViewId, setActiveViewId] = useState(readStoredActiveView)
const [canManageLeads, setCanManageLeads] = useState(false)

// Remember the active view so returning from a standalone form restores it.
useEffect(() => {
try { sessionStorage.setItem(ACTIVE_VIEW_STORAGE_KEY, activeViewId) } catch {}
}, [activeViewId])

// Team Member CAL users cannot create leads/opportunities natively in Dynamics,
// so they get the email-based "Add lead" / "Add opportunity" forms instead.
// Sales/Enterprise users manage these directly in Dynamics and don't see the buttons.
const isTeamMember = !resolveCanManageLeads(override, canManageLeads)

useEffect(() => {
if (!currentUserId) return
getUserCanManageLeads(instance, currentUserId)
.then(setCanManageLeads)
.catch(() => setCanManageLeads(false))
}, [instance, currentUserId]) // eslint-disable-line react-hooks/exhaustive-deps
Comment on lines +35 to +45
<!-- Public web folder the app is served from (…\Webpages\public\<folder>).
Defaults to the production folder; override for a dev deploy with
-p:WebAppPublicFolder=DynamicsActivitiesDev. -->
<WebAppPublicFolder Condition="'$(WebAppPublicFolder)' == ''">DynamicsActivities</WebAppPublicFolder>
<!-- Repository root (two levels up) where package.json and vite.config.js live. -->
<WebAppRoot>$(MSBuildProjectDirectory)\..\..</WebAppRoot>
<WebAppDistDir>$(WebAppRoot)\dist-dataminer</WebAppDistDir>
<!-- Default install folder for production; can be overridden via /p:WebAppPublicFolder=... -->
<WebAppPublicFolder Condition="'$(WebAppPublicFolder)' == ''">DynamicsActivities</WebAppPublicFolder>
<WebAppCompanionDir>$(MSBuildProjectDirectory)\PackageContent\CompanionFiles\Skyline DataMiner\Webpages\public\$(WebAppPublicFolder)</WebAppCompanionDir>
<WebAppCompanionRoot>$(MSBuildProjectDirectory)\PackageContent\CompanionFiles\Skyline DataMiner\Webpages\public</WebAppCompanionRoot>
<WebAppCompanionDir>$(WebAppCompanionRoot)\$(WebAppPublicFolder)</WebAppCompanionDir>
Comment on lines +11 to +12
<Version>1.12.5</Version>
<VersionComment>Fix: lead/opportunity forms no longer open multiple email drafts on a fast double-click or Enter+click. Added a synchronous submit guard so the mail draft opens exactly once per submission.</VersionComment>
Comment on lines +95 to +103
app_base_path:
description: >
Public base path the SPA is served from (e.g. /public/MyApp/).
Passed to the frontend build as VITE_APP_BASE_PATH so asset URLs
and MSAL redirect paths resolve correctly. Leave empty to use the
app's built-in default.
required: false
type: string
default: ""
Comment thread README.md
Comment on lines +23 to +24
| Access gate | Request-license / request-access screen for users without Dynamics access |
| Standalone forms | `#/forms/lead` and `#/forms/opportunity` render the **Add lead** / **Add opportunity** forms, opened from the Leads / Opportunities browse views by Team Member CAL users |
Comment on lines +164 to +166
| `src/components/forms/FormPage.jsx` | Generic shell for standalone forms (header + back button); renders forms from the registry |
| `src/components/forms/LeadForm.jsx` | "Add lead" form shown to users without Dynamics/Dataverse access |
| `src/components/forms/OpportunityForm.jsx` | "Add opportunity" form shown to users without Dynamics/Dataverse access |
Comment thread src/styles/main.css
.mail-detail-pane { flex: 1; }
}

/* License test control (local testing only) */
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