Skip to content

fix(composio): collect Dynamics 365 org name via required-fields registry (#2127)#2181

Merged
senamakel merged 3 commits into
tinyhumansai:mainfrom
obchain:fix/2127-composio-required-fields-registry
May 20, 2026
Merged

fix(composio): collect Dynamics 365 org name via required-fields registry (#2127)#2181
senamakel merged 3 commits into
tinyhumansai:mainfrom
obchain:fix/2127-composio-required-fields-registry

Conversation

@obchain
Copy link
Copy Markdown
Contributor

@obchain obchain commented May 19, 2026

Summary

  • Add a declarative [ToolkitRequiredField] registry so any Composio toolkit with provider-specific required fields (Jira subdomain, WhatsApp WABA id, Dynamics 365 org name, …) renders its fields generically — no per-toolkit branches inside the connect modal.
  • Wire dynamics365.org_name (with the .crm.dynamics.com suffix and the shared DNS-label validator) into the registry so the connect modal collects the org name before calling openhuman.composio_authorize, instead of failing after submit.
  • Refactor ComposioConnectModal to use the new registry + a generic RequiredFieldsForm subcomponent. The 612-recovery phase is generalised from the old needs-subdomain to needs-fields so it re-uses the same renderer.
  • Existing Jira subdomain + WhatsApp WABA id flows still work — they are sourced from the same registry, with parity assertions in the test suite.

Problem

When a user tries to connect Dynamics 365 today, Composio rejects the authorization request with code 612 (ConnectedAccount_MissingRequiredFields):

Missing required fields: Dynamics 365 Organization Name

The connect modal renders a generic OAuth button and submits without first collecting the org name (the myorg part of myorg.crm.dynamics.com). Users only learn about the missing field after the failed submit — and on failure they see the raw backend payload, not an actionable form.

The fix has to be generic, not a one-off Dynamics 365 patch: future Composio integrations with required fields should not require another UI patch.

Solution

  1. New app/src/components/composio/toolkitRequiredFields.ts declares one entry per toolkit-with-required-fields. Each entry binds a field key (also used verbatim as the extra_params name on the backend authorize request) to label / hint / placeholder / optional fixed suffix / optional custom validator.
  2. The seed registry covers WhatsApp (waba_id), Jira (subdomain), and Dynamics 365 (org_name) — Jira and Dynamics 365 share a DNS-label validator that rejects full URLs and accepts the short subdomain form.
  3. ComposioConnectModal drops the hand-rolled needsWabaId / needsAtlassianSubdomain booleans. Field state is now a single Record<string, string> keyed by registry field key; validation runs through validateRequiredFieldValues; submission pulls values straight into the extra_params object of composio_authorize.
  4. The 612-recovery phase that fires when Composio still returns the missing-fields error is generalised: it renders the same RequiredFieldsForm with autoFocusFirst so any registry-known toolkit gets a useful retry form, not just Jira. Toolkits without a registry entry fall back to the existing sanitized error path so the retry loop can never spin forever.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — CI is expected to validate; locally Vitest covers the registry (10/10) and the modal (41/41 — 5 new test cases for Dynamics 365 + WhatsApp parity).
  • Coverage matrix updated — N/A: behaviour-only change on the existing Composio connect flow; no new feature row added/removed/renamed.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related — N/A: no matrix feature ID changed.
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • Manual smoke checklist updated if this touches release-cut surfaces (docs/RELEASE-MANUAL-SMOKE.md) — N/A: scoped Composio connect-flow change.
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

  • Frontend-only change in app/src/components/composio/*. No persistence, security, migration, or backend changes.
  • openhuman.composio_authorize API contract unchanged — the new fields ride the existing extra_params channel that already supports waba_id and subdomain.
  • Existing Jira and WhatsApp connect flows are functionally identical (parity verified in tests).
  • 12 locales updated with the 6 new composio.connect.* keys (dynamicsOrgNameLabel, dynamicsOrgNameHint, wabaIdHint, needsFieldsPrefix, needsFieldsSuffix, requiredFieldEmpty).

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Keep this section for AI-authored PRs. For human-only PRs, mark each field N/A.

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: fix/2127-composio-required-fields-registry
  • Commit SHA: 31dd2bc6a4378a460077428924421188680a26ce

Validation Run

  • pnpm --filter openhuman-app format:check — pre-push hook ran prettier; format-only fixes amended in.
  • pnpm typecheck — clean.
  • Focused tests: pnpm debug unit toolkitRequiredFields 10/10, pnpm debug unit ComposioConnectModal 41/41.
  • Rust fmt/check (if changed): N/A — no Rust changes.
  • Tauri fmt/check (if changed): N/A — no Tauri changes.

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: Dynamics 365 connect flow now collects the org name upfront, so users never hit the raw code: 612 failure. The Composio missing-fields error path becomes a registry-driven recovery form rather than a Jira-only special case.
  • User-visible effect: Dynamics 365 connect modal renders a labelled Dynamics 365 Organization Name input with .crm.dynamics.com suffix + hint; empty or full-URL values are blocked with inline validation. Existing Jira + WhatsApp UIs are visually identical (now driven by the same registry).

Parity Contract

  • Legacy behavior preserved: Jira subdomain and WhatsApp WABA id flows continue to render their existing inputs, with identical validation rules and the same extra_params payload shape on the wire.
  • Guard/fallback/dispatch parity checks: isMissingRequiredFieldsError slug-only detection unchanged. The 612-recovery phase now activates for any registry-known toolkit (previously Jira-only); toolkits without a registry entry fall back to the existing sanitized error path so the retry loop cannot spin forever.

Summary by CodeRabbit

  • New Features

    • Added support for connecting Dynamics 365 accounts.
    • Enhanced required fields validation with generic error messaging across all connections.
  • Improvements

    • Improved error recovery flow for connections requiring additional fields.
    • Added validation and user-friendly hints for Dynamics 365 organization names and WhatsApp Business Account IDs.
  • Internationalization

    • Added translations in 11 languages for new connection fields and validation messages.

Review Change Stack

obchain added 3 commits May 19, 2026 12:50
Declarative per-toolkit registry for provider-specific required fields
the Composio connect flow must collect before calling
openhuman.composio_authorize. Each entry binds a field key (also used
as the extra_params name on the backend request) to label / hint /
placeholder / optional suffix / optional validator. Adding a new
provider-specific field is a single registry entry — no per-toolkit
branches in ComposioConnectModal.

Seeded with:
- whatsapp.waba_id (existing)
- jira.subdomain (existing) — uses the shared subdomain-label validator
- dynamics365.org_name — new, with .crm.dynamics.com suffix and the
  same subdomain-label validator so users see the same DNS-label
  guidance Composio enforces server-side.

Refs tinyhumansai#2127.
…lds registry (tinyhumansai#2127)

Composio rejects Dynamics 365 authorization with code 612 (`ConnectedAccount_MissingRequiredFields`) because the org name (the `myorg` part of `myorg.crm.dynamics.com`) is required server-side but the connect modal previously rendered only a generic OAuth button.

Replace the hand-rolled `needsWabaId` / `needsAtlassianSubdomain` booleans with the new
[ToolkitRequiredField] registry. The modal now renders the registry's required-field
list generically (via the new RequiredFieldsForm subcomponent), validates per-field
with optional custom validators, and threads the values verbatim into the
`extra_params` object of `openhuman.composio_authorize`. The recovery phase that
fires when Composio still returns code 612 is generalised from `needs-subdomain` to
`needs-fields` so it re-uses the same generic renderer.

User-visible impact:
- Dynamics 365 connect flow now collects the org name upfront, with
  `.crm.dynamics.com` suffix and a hint that the short org name is required.
- Local validation blocks submission when the field is empty or looks like a
  full URL.
- Existing Jira subdomain + WhatsApp WABA id flows still work — they are now
  sourced from the same registry.

i18n: 5 new keys (`dynamicsOrgNameLabel`, `dynamicsOrgNameHint`, `wabaIdHint`,
`needsFieldsPrefix`, `needsFieldsSuffix`, `requiredFieldEmpty`) shipped for 12
locales.

Closes tinyhumansai#2127.
@obchain obchain requested a review from a team May 19, 2026 07:24
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

📝 Walkthrough

Walkthrough

ComposioConnectModal is refactored from per-toolkit required-field handling to a registry-driven workflow. A new toolkitRequiredFields module defines field metadata and validators; the modal consumes it to validate and collect fields before authorization, includes them as extra_params, and recovers from missing-required-fields errors (code 612) by re-prompting users. A new RequiredFieldsForm component unifies idle and recovery UI rendering with full i18n support across 11 languages.

Changes

Provider-Specific Required Fields for Composio Connect

Layer / File(s) Summary
Required Fields Registry & Validation Utilities
app/src/components/composio/toolkitRequiredFields.ts, app/src/components/composio/toolkitRequiredFields.test.ts
Defines the ToolkitRequiredField interface with key, labels, placeholder, suffix, and optional validator contract. Introduces a frozen TOOLKIT_REQUIRED_FIELDS registry mapping toolkit slugs to required field arrays (Jira subdomain + .atlassian.net, Dynamics 365 org_name + .crm.dynamics.com, WhatsApp waba_id). Implements validateSubdomainLabel regex validator and exports getRequiredFieldsForToolkit() and validateRequiredFieldValues() utilities. Comprehensive test coverage validates registry mappings, empty/whitespace rejection, custom validator application, and fields without validators.
Modal State Machine & Connect Handler
app/src/components/composio/ComposioConnectModal.tsx (state, imports, handler, error recovery), app/src/components/composio/ComposioConnectModal.test.tsx (Jira validation tests)
Replaces the needs-subdomain phase with needs-fields recovery. Adds state for requiredFields (from registry), fieldValues, and fieldErrors. Updated handleConnect validates fields via validateRequiredFieldValues, includes valid values as extra_params, and calls authorize. Error handler checks for code 612, logs toolkit + field count, and transitions to needs-fields phase when registry has entries (otherwise error state). Tests verify Jira validation now shows generic "This field is required" message and Jira error-clearing behavior.
RequiredFieldsForm Component & Recovery UI
app/src/components/composio/ComposioConnectModal.tsx (RequiredFieldsForm component, idle & recovery rendering), app/src/components/composio/ComposioConnectModal.test.tsx (Dynamics 365 & WhatsApp tests)
New generic RequiredFieldsForm component renders registry fields with labels, optional suffix, hint, error paragraphs, and ARIA attributes; supports autofocus on first input. Idle phase replaces hardcoded Jira/WABA inputs with RequiredFieldsForm; needs-fields recovery phase reuses it. Tests validate Dynamics 365 org_name rendering with ".crm.dynamics.com" suffix, empty rejection, URL rejection, trimmed forwarding as extra_params, recovery state on 612 error, and WhatsApp WABA input/forwarding.
Localization: Multi-Language Required Fields Strings
app/src/lib/i18n/en.ts, app/src/lib/i18n/chunks/{ar,bn,en,es,fr,hi,id,it,pt,ru,zh-CN}-4.ts
Added i18n entries across 11 languages for Dynamics 365 organization name label/hint, generic "needs fields" prefix/suffix messaging, required-field-empty error message, and WhatsApp WABA ID acquisition hint referencing Meta API endpoints. Strings support the new generic required-fields workflow and recovery UI across all locales.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Modal as ComposioConnectModal
  participant Validator as validateRequiredFieldValues
  participant Authorize as Composio Authorize
  autonumber
  User->>Modal: render, update fieldValue[key]
  User->>Modal: click "Connect" (handleConnect)
  Modal->>Validator: validateRequiredFieldValues(requiredFields, fieldValues)
  alt validation errors
    Validator-->>Modal: error map with field errors
    Modal-->>User: display inline errors, stay in idle/needs-fields
  else validation succeeds
    Validator-->>Modal: empty error map
    Modal->>Modal: build extraParams from fieldValues
    Modal->>Authorize: authorize(oauth, extraParams)
    alt success
      Authorize-->>Modal: success response
      Modal-->>User: close modal, update connection
    else code 612 (missing required fields)
      Authorize-->>Modal: ConnectedAccount_MissingRequiredFields
      alt registry has entries for toolkit
        Modal-->>User: transition to needs-fields phase<br/>(show recovery copy, retry button, form)
      else no registry entries
        Modal-->>User: error state (no recovery path)
      end
    else other error
      Authorize-->>Modal: error response
      Modal-->>User: error state
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • tinyhumansai/openhuman#1726: Prior Jira subdomain error recovery logic that this PR generalizes into a registry-based workflow.
  • tinyhumansai/openhuman#1733: Jira required-field validation work that overlaps with the main PR's refactoring of field handling into the toolkit registry.
  • tinyhumansai/openhuman#1986: Broader i18n backfill work that overlaps with the new Composio Connect required-field translation keys added in this PR.

Suggested labels

working

Suggested reviewers

  • graycyrus

Poem

🐰 The fields now speak for all their tongues,
No more one-off code for Jira's sung.
A registry holds the truth so clear,
Dynamics, WhatsApp—translate, don't fear!
Recovery blooms when auth stumbles 612,
The modal asks again; the user will.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main change: refactoring Dynamics 365 organization name collection via a required-fields registry, which is the primary objective of this changeset.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from issue #2127: required field rendering (Dynamics 365 org_name input), user guidance (label/hint/suffix), local validation (DNS-label pattern, empty-check), auth payload inclusion (extra_params), schema-driven approach (toolkitRequiredFields registry for whatsapp/jira/dynamics365), error recovery (needs-fields phase for 612 errors), comprehensive test coverage (vitest for modal/registry/validation), and i18n support (12 locales).
Out of Scope Changes check ✅ Passed All changes align with the PR objective: registry setup, modal refactor, validation logic, test coverage, and i18n updates. No unrelated modifications detected; the changeset cohesively addresses Dynamics 365 required-field collection and refactors related toolkits (Jira, WhatsApp) under the same generic framework.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the working A PR that is being worked on by the team. label May 19, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/components/composio/ComposioConnectModal.test.tsx (1)

359-361: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

This assertion no longer verifies that the active validation error is cleared.

Line 360 still checks for the retired Atlassian-specific copy, so the test can pass even if "This field is required" remains visible.

Proposed patch
     await waitFor(() => {
-      expect(screen.queryByText(/Please enter your Atlassian subdomain/i)).not.toBeInTheDocument();
+      expect(screen.queryByText(/This field is required/i)).not.toBeInTheDocument();
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/components/composio/ComposioConnectModal.test.tsx` around lines 359 -
361, The test currently only asserts that the retired Atlassian-specific copy is
gone, which can mask that the active validation error ("This field is required")
still shows; update the assertion inside the waitFor in
ComposioConnectModal.test.tsx to assert that the actual validation message
("This field is required") is not in the document (use
expect(screen.queryByText(/This field is required/i)).not.toBeInTheDocument())
instead of or in addition to the Atlassian copy, keeping the waitFor wrapper and
existing use of screen.queryByText so the test fails if the required-field
validation isn't cleared.
🧹 Nitpick comments (1)
app/src/components/composio/ComposioConnectModal.tsx (1)

343-348: ⚡ Quick win

Use the namespaced frontend logger instead of raw console.* in the new authorization logs.

These added log points should follow the project’s debug-namespace pattern so verbosity can be controlled consistently in frontend builds.

Proposed patch
-import { type ChangeEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import createDebug from 'debug';
+import { type ChangeEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
@@
+const debug = createDebug('composio:connect-modal');
@@
-    console.debug(
+    debug(
       '[composio][authorize] → toolkit=%s has_extra_params=%s field_count=%d',
       toolkit.slug,
       Object.keys(extraParams).length > 0,
       requiredFields.length
     );
@@
-      console.error(
+      debug(
         '[composio][authorize] failed toolkit=%s slug_check=%s',
         toolkit.slug,
         isMissingRequiredFieldsError(err)
       );
@@
-        console.debug(
+        debug(
           '[composio][authorize] missing-required-fields toolkit=%s registry_field_count=%d',
           toolkit.slug,
           requiredFields.length
         );

As per coding guidelines "Follow existing patterns for debug logging (e.g. the debug npm package with a namespace per area) ...".

Also applies to: 365-369, 379-383

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/components/composio/ComposioConnectModal.tsx` around lines 343 - 348,
Replace raw console calls in ComposioConnectModal.tsx with the project's
namespaced frontend debug logger (the same debug/namespace pattern used
elsewhere in the app). Locate the console.debug/console.* calls around the
authorize flow (the log using toolkit.slug, Object.keys(extraParams).length,
requiredFields.length and the two other console blocks referenced) and swap them
to use the namespaced logger (e.g., logger('composio:authorize') or the existing
debug instance used by this component), preserving the message and interpolated
values (toolkit.slug, extraParams, requiredFields) so verbosity is controllable
via the debug namespace.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@app/src/components/composio/ComposioConnectModal.test.tsx`:
- Around line 359-361: The test currently only asserts that the retired
Atlassian-specific copy is gone, which can mask that the active validation error
("This field is required") still shows; update the assertion inside the waitFor
in ComposioConnectModal.test.tsx to assert that the actual validation message
("This field is required") is not in the document (use
expect(screen.queryByText(/This field is required/i)).not.toBeInTheDocument())
instead of or in addition to the Atlassian copy, keeping the waitFor wrapper and
existing use of screen.queryByText so the test fails if the required-field
validation isn't cleared.

---

Nitpick comments:
In `@app/src/components/composio/ComposioConnectModal.tsx`:
- Around line 343-348: Replace raw console calls in ComposioConnectModal.tsx
with the project's namespaced frontend debug logger (the same debug/namespace
pattern used elsewhere in the app). Locate the console.debug/console.* calls
around the authorize flow (the log using toolkit.slug,
Object.keys(extraParams).length, requiredFields.length and the two other console
blocks referenced) and swap them to use the namespaced logger (e.g.,
logger('composio:authorize') or the existing debug instance used by this
component), preserving the message and interpolated values (toolkit.slug,
extraParams, requiredFields) so verbosity is controllable via the debug
namespace.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0021c2cb-52c3-43df-ab8a-0ad7b5daea0c

📥 Commits

Reviewing files that changed from the base of the PR and between c25fc8e and 31dd2bc.

📒 Files selected for processing (16)
  • app/src/components/composio/ComposioConnectModal.test.tsx
  • app/src/components/composio/ComposioConnectModal.tsx
  • app/src/components/composio/toolkitRequiredFields.test.ts
  • app/src/components/composio/toolkitRequiredFields.ts
  • app/src/lib/i18n/chunks/ar-4.ts
  • app/src/lib/i18n/chunks/bn-4.ts
  • app/src/lib/i18n/chunks/en-4.ts
  • app/src/lib/i18n/chunks/es-4.ts
  • app/src/lib/i18n/chunks/fr-4.ts
  • app/src/lib/i18n/chunks/hi-4.ts
  • app/src/lib/i18n/chunks/id-4.ts
  • app/src/lib/i18n/chunks/it-4.ts
  • app/src/lib/i18n/chunks/pt-4.ts
  • app/src/lib/i18n/chunks/ru-4.ts
  • app/src/lib/i18n/chunks/zh-CN-4.ts
  • app/src/lib/i18n/en.ts

Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

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

Nice refactor — the declarative registry approach is clean and will scale well for future Composio integrations. The three-way alignment with #2127 checks out: required field rendered, validated, forwarded, and recovery phase generalized. Tests are thorough.

Two minor cleanup items below (neither blocking). CodeRabbit already caught the stale test assertion at line ~360 and the console.debug → namespaced logger nit, so I'm skipping those.

Area Files Verdict
Registry toolkitRequiredFields.ts Clean — frozen, typed, shared DNS-label validator
Modal refactor ComposioConnectModal.tsx Clean — per-toolkit booleans eliminated, generic form
Tests both test files Solid coverage, parity assertions
i18n 12 locales + en.ts All 6 new keys present

Comment thread app/src/lib/i18n/en.ts
"account. We'll open a browser window, you approve access there, and this app will detect the connection automatically.",
'composio.connect.isConnected': 'is connected.',
'composio.connect.manage': 'Manage',
'composio.connect.needsFieldsPrefix': 'To connect',
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.

[minor] Dead i18n keys left behind: composio.connect.needsSubdomain, needsSubdomainSuffix, subdomainRequired, and wabaIdRequired are no longer referenced by the modal (replaced by needsFieldsPrefix/needsFieldsSuffix and requiredFieldEmpty). They're harmless but add translation maintenance burden across 12 locales — worth a quick cleanup pass.

* `<subdomain>.atlassian.net` — alphanumerics and hyphens, 1-63 chars,
* no leading/trailing hyphens. Rejects full URLs so users are not confused
* about what to paste.
*
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.

[minor] The isValidAtlassianSubdomain export is retained for "backwards compatibility" but the registry now uses validateSubdomainLabel internally. Worth grepping for external callers — if none exist, this is dead code that can be removed to avoid maintaining two copies of the same regex.

@senamakel senamakel merged commit 7cbe82d into tinyhumansai:main May 20, 2026
26 of 30 checks passed
mtkik pushed a commit to mtkik/openhuman-meet that referenced this pull request May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dynamics 365 connect form misses required organization name

3 participants