Skip to content

Expose reusable settings UI for add-ons#95

Open
kzamanbd wants to merge 16 commits into
developfrom
feat/expose-shared-components
Open

Expose reusable settings UI for add-ons#95
kzamanbd wants to merge 16 commits into
developfrom
feat/expose-shared-components

Conversation

@kzamanbd

@kzamanbd kzamanbd commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Lets add-ons (e.g. Texty Pro) reuse Texty's schema-driven settings UI instead of
duplicating it, using the same webpack dependency-extraction pattern as Dokan
lite → pro. Underpins the Texty Pro SMS Automations PR.

What's included

Component export (webpack library + dependency extraction)

  • New components webpack entry → dist/components.js exposing
    window.texty.components (handle texty-components).
  • webpack-dependency-mapping.js (requestToExternal/requestToHandle) wired to a
    custom DependencyExtractionWebpackPlugin, so @texty/components externalizes to
    the global + script handle.
  • src/components/index.tsx barrel exports NotificationGroupSettings and
    PhoneField.
  • Admin/Menu registers texty-components (depends on texty-admin so it merges
    onto window.texty after the localized data).

Generalized NotificationGroupSettings

  • Optional schemaPath / savePath props + a generic save-fold (collapse any
    <id>_<key> / <id>::<key> children into the per-id payload) → renders any
    feature's { schema, values }, not just built-in notification groups.

Extensibility / cleanup

  • ICON_MAP / LOGO_MAP made filterable via texty_notification_icon_map /
    texty_notification_logo_map.
  • REST query strings built with @wordpress/url addQueryArgs.
  • Includes the earlier gateway-logo/customization filter work on this branch.

Consumer

Add-ons: import { NotificationGroupSettings, PhoneField } from '@texty/components'.

Test

  • npm run build (tsc clean); User Events / Integrations tabs render unchanged;
    the components bundle exposes window.texty.components.

Summary by CodeRabbit

  • New Features

    • Notifications settings are now schema-driven, with configurable schema/save endpoints and extensible tabs (additional tabs can be injected).
    • A reusable shared components bundle is now exposed for extensions and add-ons.
  • Bug Fixes

    • Updated multiple gateway logos to load from the correct image locations.
    • Improved notification fetching/saving reliability by building requests dynamically and using group-aware, schema-based payloads.
    • Refined phone input behavior and formatting updates.
  • Documentation

    • Added clarifying comments around the shared components bundle usage.

kzamanbd added 7 commits June 29, 2026 15:38
… style)

Expose Texty's schema-driven settings UI so add-ons (Texty Pro) can import it
instead of duplicating the renderer:

- Build a `components` webpack entry from src/components/index.tsx as a window
  library `textyComponents` (handle `texty-components`), and wire a custom
  DependencyExtractionWebpackPlugin via webpack-dependency-mapping.js so
  `@texty/components` externalizes to that global + handle.
- Register the `texty-components` script in Admin/Menu so dependents load it.
- Generalize NotificationGroupSettings: optional schemaPath/savePath props and a
  generic save-fold (collapse any `<id>_<key>` / `<id>::<key>` children into the
  per-id payload), so it renders any feature's {schema, values} — not just the
  built-in notifications groups. Exported as `SchemaSettings`.
Use the nested window.texty.components global (Dokan style) instead of a flat
textyComponents. The library assignment is merge-safe
((window.texty = window.texty || {}).components = …), and texty-components now
depends on texty-admin so it loads after the localized `var texty = {…}` data and
merges onto it rather than being clobbered.
…uery args

- Apply `texty_notification_icon_map` / `texty_notification_logo_map` JS filters
  to the header ICON_MAP / LOGO_MAP so add-ons can register icons/logos for their
  own groups.
- Build REST query strings with @wordpress/url's addQueryArgs instead of manual
  concatenation / encodeURIComponent (schema?group, notifications?context).
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kzamanbd, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 30 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d4d123e3-a329-4405-ae9e-e9a7d2f259f0

📥 Commits

Reviewing files that changed from the base of the PR and between 2b0e160 and 3e66322.

📒 Files selected for processing (2)
  • src/pages/notifications/components/NotificationGroupSettings.tsx
  • src/pages/notifications/index.tsx
📝 Walkthrough

Walkthrough

Adds a shared texty-components bundle and registers it for plugin use, updates notification settings to use configurable schema/save endpoints and filtered icon/logo maps, makes notification tabs filter-driven, and moves gateway logos into a new assets/images/gateways/ directory.

Changes

Add-on extensibility infrastructure and notification refactoring

Layer / File(s) Summary
Shared components bundle registration
webpack-dependency-mapping.js, webpack.config.js, includes/Assets.php, texty.php, includes/Admin/Menu.php
Adds @texty/components external/handle mapping, exposes a separate components webpack entry, registers the resulting texty-components asset during plugin boot, and documents its dependency-based loading in admin enqueue code.
Public components barrel
src/components/index.tsx
Adds the public components entry that imports the shared react-phone-input-2 stylesheet and re-exports NotificationGroupSettings and PhoneField.
Configurable notification settings
src/pages/notifications/components/NotificationGroupSettings.tsx
Makes schema/save endpoints configurable, reloads schema data from the computed path, folds schema fields into the save payload, and applies filterable icon/logo maps.
Dynamic notifications tabs
src/pages/notifications/index.tsx, src/pages/notifications/hooks/useNotifications.ts
Builds tabs from a filter-extensible list, controls the active tab from the URL, and switches the notifications request path to addQueryArgs.
Gateway logo path updates
includes/Gateways/Clickatell.php, includes/Gateways/Fake.php, includes/Gateways/Plivo.php, includes/Gateways/Twilio.php, includes/Gateways/Vonage.php
Changes the gateway logo asset URLs to the new assets/images/gateways/ locations.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: exposing reusable settings UI components for add-ons.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/expose-shared-components

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.

@kzamanbd kzamanbd changed the title Expose reusable settings UI for add-ons (dokan-lite style) Expose reusable settings UI for add-ons Jun 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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.

Inline comments:
In `@src/pages/notifications/components/NotificationGroupSettings.tsx`:
- Around line 55-63: The Settings form key is currently derived only from
groupId in NotificationGroupSettings, so custom consumers using
schemaPath/savePath without a groupId can reuse the same instance and leak form
state between endpoints. Update the keying logic in NotificationGroupSettings to
include the resolved endpoint identity from fetchPath and postPath, and keep the
existing groupId-based key only as part of that composite so different
schemas/save targets mount distinct Settings instances.
- Around line 42-49: Make NotificationGroupSettings’ public props contract
mutually exclusive so invalid combinations cannot compile: in
NotificationGroupSettings, replace the current Props shape with a union that
allows either the built-in groupId flow or the custom endpoint flow, and require
schemaPath and savePath together for the custom case. Update the component’s
prop typing and any related call sites/helpers in NotificationGroupSettings so
<NotificationGroupSettings schemaPath="..." /> and bare
<NotificationGroupSettings /> are rejected unless they provide the correct
paired fields.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2855e4f2-edb2-4a6d-8abf-87a340aab108

📥 Commits

Reviewing files that changed from the base of the PR and between ea4c8d6 and d36b30b.

⛔ Files ignored due to path filters (10)
  • assets/images/gateways/clickatell-logo.png is excluded by !**/*.png
  • assets/images/gateways/clickatell.svg is excluded by !**/*.svg
  • assets/images/gateways/common-sms.png is excluded by !**/*.png
  • assets/images/gateways/plivo-logo.png is excluded by !**/*.png
  • assets/images/gateways/plivo.svg is excluded by !**/*.svg
  • assets/images/gateways/twilio-logo.png is excluded by !**/*.png
  • assets/images/gateways/twilio.svg is excluded by !**/*.svg
  • assets/images/gateways/vonage-logo.png is excluded by !**/*.png
  • assets/images/gateways/vonage.svg is excluded by !**/*.svg
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (12)
  • includes/Admin/Menu.php
  • includes/Gateways/Clickatell.php
  • includes/Gateways/Fake.php
  • includes/Gateways/Plivo.php
  • includes/Gateways/Twilio.php
  • includes/Gateways/Vonage.php
  • src/components/index.tsx
  • src/pages/notifications/components/NotificationGroupSettings.tsx
  • src/pages/notifications/hooks/useNotifications.ts
  • src/pages/notifications/index.tsx
  • webpack-dependency-mapping.js
  • webpack.config.js

Comment thread src/pages/notifications/components/NotificationGroupSettings.tsx Outdated
Comment thread src/pages/notifications/components/NotificationGroupSettings.tsx
kzamanbd added 8 commits June 29, 2026 17:36
Add-ons that enqueue on wp-login.php (e.g. the registration OTP widget)
declare a texty-components dependency, but the handle was only registered
on admin_enqueue_scripts and wp_enqueue_scripts — never login_enqueue_scripts.
On the registration form the script dep and its stylesheet went unresolved.
Register on login_enqueue_scripts too.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/pages/notifications/index.tsx (1)

45-48: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

URL not corrected when tab param is invalid.

When requested doesn't match any tab, the UI falls back to tabs[0], but the tab query param stays at its invalid value — the URL and displayed tab diverge.

🔧 Sync the URL to the resolved tab
+  useEffect(() => {
+    if (activeTab && requested !== activeTab) {
+      handleTabChange(activeTab);
+    }
+  }, [activeTab, requested]);
🤖 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 `@src/pages/notifications/index.tsx` around lines 45 - 48, The `activeTab`
fallback in `src/pages/notifications/index.tsx` resolves invalid `requested`
values to `tabs[0]`, but the `tab` query param is never updated, so the URL can
diverge from the displayed tab. Update the logic around `requested`,
`activeTab`, and `TAB_PARAM` so that when the param is missing or invalid, the
URL is synchronized to the resolved tab value (using the existing
navigation/router state in this page) instead of only falling back in render
state.
🤖 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.

Inline comments:
In `@src/pages/notifications/index.tsx`:
- Around line 20-43: The tab list in Notifications is being frozen by useMemo
with an empty dependency array, so late-registered `texty_notifications_tabs`
entries never appear after the admin SPA mounts. Update `Notifications` to
derive the tabs from the current filter state on each render, or add the proper
dependencies so `applyFilters('texty_notifications_tabs', [])` can be
re-evaluated when extensions register; keep the logic around `useSearchParams`,
`useMemo`, and the `tabs` array in sync with dynamic add-on hooks.

---

Nitpick comments:
In `@src/pages/notifications/index.tsx`:
- Around line 45-48: The `activeTab` fallback in
`src/pages/notifications/index.tsx` resolves invalid `requested` values to
`tabs[0]`, but the `tab` query param is never updated, so the URL can diverge
from the displayed tab. Update the logic around `requested`, `activeTab`, and
`TAB_PARAM` so that when the param is missing or invalid, the URL is
synchronized to the resolved tab value (using the existing navigation/router
state in this page) instead of only falling back in render state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4ce4b5f7-70ee-4c6e-9b3d-9098b198e97b

📥 Commits

Reviewing files that changed from the base of the PR and between d36b30b and 2b0e160.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • includes/Admin/Menu.php
  • includes/Assets.php
  • src/components/PhoneField.tsx
  • src/components/index.tsx
  • src/pages/notifications/components/NotificationGroupSettings.tsx
  • src/pages/notifications/index.tsx
  • texty.php
✅ Files skipped from review due to trivial changes (1)
  • includes/Admin/Menu.php
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/components/index.tsx
  • src/pages/notifications/components/NotificationGroupSettings.tsx

Comment thread src/pages/notifications/index.tsx Outdated
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.

1 participant