Skip to content

feat: move activity type list to mui - #969

Merged
smarcet merged 13 commits into
masterfrom
feature/move-activity-types-grid-mui
Jul 3, 2026
Merged

feat: move activity type list to mui#969
smarcet merged 13 commits into
masterfrom
feature/move-activity-types-grid-mui

Conversation

@priscila-moneo

@priscila-moneo priscila-moneo commented Jun 10, 2026

Copy link
Copy Markdown

ref: https://app.clickup.com/t/86bac70mf

image

Summary by CodeRabbit

  • New Features
    • Event type lists now support search, sorting, and pagination.
    • Create/edit event types are handled in a dialog with “Main” and “Schedule settings” tabs, including media upload linking.
  • Bug Fixes
    • List view refreshes reliably after save, delete, and seed actions; totals and ordering stay in sync.
    • Validation errors are cleared correctly when updated entity data is received.
    • Save/delete feedback is now consistently shown via snackbar notifications.
  • Documentation
    • Updated the activity-type delete confirmation text.
  • Other
    • Improved color input behavior/validation to better support hex color entry and submission timing.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 16 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: 6bbe4e2d-2f16-431a-b2ee-053bc4b631a3

📥 Commits

Reviewing files that changed from the base of the PR and between 4b61cfa and ede821e.

📒 Files selected for processing (6)
  • src/actions/__tests__/event-type-actions.test.js
  • src/actions/event-type-actions.js
  • src/components/mui/__tests__/mui-formik-color-field.test.js
  • src/components/mui/formik-inputs/mui-formik-color-field.js
  • src/pages/events/__tests__/event-type-list-page.test.js
  • src/pages/events/event-type-list-page.js
📝 Walkthrough

Walkthrough

Event type pages now fetch with filters, paging, and sorting, open a dialog for create/edit, and update list state and translations. Shared Formik color input behavior was added and reused in the company and event type forms.

Changes

Form color inputs and event types

Layer / File(s) Summary
Shared color inputs
src/utils/yup.js, src/components/mui/formik-inputs/*, src/components/mui/__tests__/mui-formik-color-field.test.js
The Formik color field, hex color validation, async select disabled state, select value rendering, and their tests were added or updated.
Company color dialog
src/pages/companies/components/company-dialog.js, src/pages/companies/components/__tests__/company-dialog.test.js
The company dialog now uses the Formik color field, validates the color value, submits the Formik color field value, and has matching dialog tests for blur-driven color submission.
Event type list state
src/actions/event-type-actions.js, src/reducers/events/event-type-list-reducer.js, src/reducers/events/__tests__/event-type-reducer.test.js, src/i18n/en.json
The event type list actions now support filtered, paged, and sorted fetches, snackbar handling, seed success messaging, and reducer state for request parameters, pagination, totals, and cleared entity errors.
Event type dialog
src/pages/events/event-type-dialog.js, src/pages/events/components/__tests__/event-type-dialog.test.js
The event type dialog was rewritten as a Formik dialog with tabbed fields, media upload linking, save-state gating, and matching tests for validation, save behavior, and media selection.
Event type page and routing
src/pages/events/event-type-list-page.js, src/layouts/event-type-layout.js
The event type list page now uses hooks, table controls, and the dialog flow, and the layout now routes only to the list page plus the fallback page.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: smarcet, santipalenque

🚥 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 accurately summarizes the main change: migrating the Activity Type list page to MUI.
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 feature/move-activity-types-grid-mui

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.

@santipalenque santipalenque 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.

LGTM

Comment thread src/reducers/events/event-type-list-reducer.js

@smarcet smarcet 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.

@priscila-moneo please review

@priscila-moneo
priscila-moneo force-pushed the feature/move-activity-types-grid-mui branch from 77cea30 to 6872754 Compare June 24, 2026 21:57
@priscila-moneo
priscila-moneo requested a review from smarcet June 24, 2026 21:57

@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: 3

🤖 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/events/event-type-list-page.js`:
- Around line 45-47: The initial mount fetch in the event type list page is
passing a null search term into state, which then propagates to SearchInput and
paging/sorting handlers. Update the getEventTypes flow in
event-type-list-page.js so the first load uses the current term value or an
empty string instead of null, and ensure the reducer state.term stays normalized
to a string. Use the getEventTypes call inside useEffect and the
SearchInput/handlePageChange/handleSort path as the key places to verify the
fix.
- Around line 75-77: Sorting in handleSort keeps the existing currentPage, which
can leave the list on a later page after a new sort. Update handleSort in
event-type-list-page.js to call getEventTypes with DEFAULT_CURRENT_PAGE instead
of currentPage so sorting always restarts from the first page.
- Around line 124-136: The seed action in event-type-list-page is updating the
store without refreshing the server-paginated table, so the current page can
show extra rows and become out of sync. Update the seed button flow in
event-type-list-page to use a handler similar to handleDelete: await dispatching
seedEventTypes, then trigger a fresh page-1 fetch so the list resets to the
server state. Keep the fix centered around the seedEventTypes click handler and
the existing pagination fetch logic used by handleDelete/currentPage/perPage.
🪄 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: 94243037-e829-4dfe-b4ec-f4f93d3a1e3a

📥 Commits

Reviewing files that changed from the base of the PR and between d3f018b and 6872754.

📒 Files selected for processing (4)
  • src/actions/event-type-actions.js
  • src/i18n/en.json
  • src/pages/events/event-type-list-page.js
  • src/reducers/events/event-type-list-reducer.js

Comment thread src/pages/events/event-type-list-page.js
Comment thread src/pages/events/event-type-list-page.js

@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/events/event-type-list-page.js`:
- Around line 53-55: The `useEffect` in `event-type-list-page` currently calls
`getEventTypes()` on mount before `currentSummit.id` is available, which can
trigger a fetch with an undefined summit id and leave stale data. Update the
effect to wait until `currentSummit.id` is present, and include that id in the
dependency list so `getEventTypes` reruns when the summit becomes available; use
the existing `getEventTypes` and `currentSummit.id` references to place the fix.
- Around line 66-69: The success path in handleSave should not depend on the
follow-up refresh request, because EventTypeDialog only closes when onSave
resolves. Update handleSave in event-type-list-page.js so it awaits
saveEventType(eventTypeEntity) first and resolves immediately on success, then
trigger getEventTypes(...) separately with its own error handling or
fire-and-forget behavior. Keep the save completion independent from the list
refresh while preserving the existing refresh call after save.
🪄 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: 08db461c-3f17-4d10-b879-a849c7afd3ab

📥 Commits

Reviewing files that changed from the base of the PR and between 6872754 and 09d60d6.

📒 Files selected for processing (6)
  • src/actions/event-type-actions.js
  • src/components/forms/event-type-form.js
  • src/layouts/event-type-layout.js
  • src/pages/events/components/event-type-dialog.js
  • src/pages/events/edit-event-type-page.js
  • src/pages/events/event-type-list-page.js
💤 Files with no reviewable changes (1)
  • src/pages/events/edit-event-type-page.js

Comment thread src/pages/events/event-type-list-page.js
Comment thread src/pages/events/event-type-list-page.js Outdated
priscila-moneo and others added 6 commits July 2, 2026 18:04
Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>
Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>
* feat: move activity types new and edit to mui

Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>

* fix: feedback from PR

Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>

---------

Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>
Replaces the legacy Bootstrap class-component EventTypeForm (embedded
in the MUI dialog shipped in PR #969 with no DialogActions footer)
with a single pure Formik + MUI EventTypeDialog, following
company-dialog.js (PR #910) as the primary pattern and the tabbed
layout from selection-plan-form.js (PR #917).

- Main / Schedule settings tabs; MuiFormikTextField/Select/Checkbox/
  AsyncAutocomplete; MuiColorInput with ref-based color tracking to
  avoid re-rendering the whole form on every drag
- Media upload types linked-list rebuilt with Autocomplete + MuiTable,
  matching the track-groups-tab.js / company-dialog.js sponsorship
  table pattern, with dedup against already-linked types
- EventTypeDialog is now a pure component; Redux wiring moved up into
  event-type-list-page.js, whose mapStateToProps now exposes
  currentEventType/currentEventTypeErrors matching every other
  list+dialog page's naming convention
- Yup validation (positiveNumberValidation from utils/yup.js) for the
  numeric fields, with a NaN-safe fallback in handleSubmit since
  Formik does not auto-cast values on submit
- Fixed a real renderValue bug in the shared MuiFormikSelect wrapper
  (echoed the raw value instead of resolving the MenuItem label,
  invisible elsewhere because other consumers' labels matched their
  values) - benefits 8 other call sites
- Fixed a stale-errors-across-entities bug in event-type-reducer.js
  (RECEIVE_EVENT_TYPE didn't reset errors, unlike UPDATE_EVENT_TYPE)

87 test suites / 733 tests passing, 0 lint errors on touched files.
Live-verified against a real summit without modifying its data.

ref: https://app.clickup.com/t/86bac70mf
Both dialogs duplicated a ColorPickerField that tracked the picked
color in a useRef, splicing it into the payload only at submit time.
This was a workaround for mui-color-input firing onChange on every
pointermove while dragging, but it meant the color never participated
in Formik state: no yup validation, stale server-side errors that
never cleared on a corrective edit, and no name/id for the label or
useScrollToError to target.

Extract a shared MuiFormikColorField (src/components/mui/formik-inputs)
that keeps local state for instant drag/typing feedback but commits to
Formik (value + touched + validation) only on blur, avoiding a
full-dialog re-render storm while still getting real validation and
error-clearing. Add hexColorValidation() to src/utils/yup.js and wire
it into both dialogs' schemas.

Also fixes an unrelated pre-existing bug found while running the
suite: MuiFormikAsyncAutocomplete referenced an undeclared
defaultOptions variable, crashing every page that uses it.
…r wrapper

company-actions.js and event-type-actions.js now import snackbarErrorHandler
and snackbarSuccessHandler directly from openstack-uicore-foundation instead
of the local src/actions/base-actions.js wrapper, which is being phased out
in favor of uicore-foundation as the single source of truth. Other action
files still using the base-actions wrapper will be migrated incrementally
(tracked in docs/plans/clickup-migrate-snackbar-handlers-to-uicore.md).

event-type-actions.js also switches getEventTypes/getEventType/saveEventType/
deleteEventType/seedEventTypes from authErrorHandler (blocking alert) to
snackbarErrorHandler, adds a success snackbar for seedEventTypes, and adds
the event_types_seed i18n key.

Also removes a leftover dispatch(showMessage(success_message, ...)) call in
saveEventType's create branch left over from this migration - its backing
success_message const had been deleted, so it would have thrown
ReferenceError: success_message is not defined on every new event type
creation. The snackbarSuccessHandler dispatch right below it already covers
the success message.
@smarcet
smarcet force-pushed the feature/move-activity-types-grid-mui branch from 09d60d6 to 5a5376d Compare July 2, 2026 21:55
@smarcet
smarcet requested a review from Copilot July 2, 2026 22:05

@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: 4

Caution

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

⚠️ Outside diff range comments (1)
src/actions/company-actions.js (1)

196-223: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Stuck loading spinner if company creation fails during logo attach.

When entity.id is falsy, the postRequest(...).then(...) chain (lines 213-222) only dispatches uploadFile (which internally stops loading) on success. If the postRequest promise rejects, uploadFile is never called, so stopLoading() — dispatched only inside uploadLogo/uploadBigLogo's .finally — never fires, and the loading state dispatched at line 199 stays stuck. Every other request in this file explicitly attaches .finally(() => dispatch(stopLoading())) to the outer promise; this branch doesn't.

🐛 Proposed fix
   return postRequest(
     createAction(UPDATE_COMPANY),
     createAction(COMPANY_ADDED),
     `${window.API_BASE_URL}/api/v1/companies`,
     normalizedEntity,
     snackbarErrorHandler,
     entity
-  )(params)(dispatch).then((payload) => {
-    dispatch(uploadFile(payload.response, file));
-  });
+  )(params)(dispatch)
+    .then((payload) => {
+      dispatch(uploadFile(payload.response, file));
+    })
+    .catch(() => dispatch(stopLoading()));
 };
🤖 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/actions/company-actions.js` around lines 196 - 223, The `attachLogo`
thunk can leave the loading state stuck when company creation fails because the
`postRequest(...).then(...)` branch only triggers `uploadLogo`/`uploadBigLogo`
on success. Update this `attachLogo` flow so the outer `postRequest` promise
always dispatches `stopLoading()` in a `.finally(...)`, matching the other
request handlers in this file, and make sure failures in the `entity.id` falsy
path still clear the spinner even when `uploadFile` is never reached.
🧹 Nitpick comments (1)
src/pages/events/components/event-type-dialog.js (1)

532-535: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Media upload search options aren't cleared when the input is emptied.

onInputChange only calls getMediaUploads when val is truthy, so clearing the search text leaves stale mediaUploadOptions from the prior query displayed in the dropdown.

♻️ Suggested fix
             onInputChange={(_, val) => {
-              if (val)
-                getMediaUploads(val, setMediaUploadOptions);
+              if (val) {
+                getMediaUploads(val, setMediaUploadOptions);
+              } else {
+                setMediaUploadOptions([]);
+              }
             }}
🤖 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/events/components/event-type-dialog.js` around lines 532 - 535, The
media upload autocomplete in event-type-dialog.js is leaving stale results
because the onInputChange handler only calls getMediaUploads when val is truthy.
Update the onInputChange logic so that when the input is cleared it also resets
the media upload options state, using the existing
getMediaUploads/setMediaUploadOptions flow in the EventTypeDialog component.
🤖 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/actions/company-actions.js`:
- Around line 259-272: The normalizeEntity helper is assuming color is always
present, which can crash callers like saveCompany, attachLogo, uploadLogo, and
uploadBigLogo. Update normalizeEntity in company-actions.js to guard the color
access before calling startsWith, only stripping the leading hash when
normalizedEntity.color is a non-empty string. Keep the rest of the entity
cleanup logic unchanged.

In `@src/components/mui/formik-inputs/mui-formik-color-field.js`:
- Around line 10-21: The local color state in MuiFormikColorField is only
initialized from field.value once, so it can get out of sync when Formik updates
externally. Add synchronization in MuiFormikColorField so changes to field.value
are reflected back into the local value state, especially after reinitialization
or resets, while keeping handleChange and handleBlur consistent with the synced
state.

In `@src/pages/companies/components/company-dialog.js`:
- Around line 327-342: The Country label in company-dialog is still bound to the
State field because its InputLabel uses htmlFor="state"; update the Country
label to point at the Country control and ensure the MuiFormikAsyncAutocomplete
for the country field receives a matching id (for example via id on the
autocomplete, per the MuiFormikAsyncAutocomplete implementation) so the
label/input association is correct. Use the existing Country block and the
MuiFormikAsyncAutocomplete component names to locate and fix both the label and
control wiring.

In `@src/pages/events/components/event-type-dialog.js`:
- Around line 163-171: The effect in event-type-dialog’s useEffect is
overwriting Formik’s local validation state by calling formik.setErrors with an
empty object when currentEventTypeState.errors is reset. Update the sync logic
so it only pushes external errors into Formik when the errors prop actually has
entries, and avoid clearing existing Yup errors on empty Redux error bags; keep
the touched update tied to the same non-empty error check.

---

Outside diff comments:
In `@src/actions/company-actions.js`:
- Around line 196-223: The `attachLogo` thunk can leave the loading state stuck
when company creation fails because the `postRequest(...).then(...)` branch only
triggers `uploadLogo`/`uploadBigLogo` on success. Update this `attachLogo` flow
so the outer `postRequest` promise always dispatches `stopLoading()` in a
`.finally(...)`, matching the other request handlers in this file, and make sure
failures in the `entity.id` falsy path still clear the spinner even when
`uploadFile` is never reached.

---

Nitpick comments:
In `@src/pages/events/components/event-type-dialog.js`:
- Around line 532-535: The media upload autocomplete in event-type-dialog.js is
leaving stale results because the onInputChange handler only calls
getMediaUploads when val is truthy. Update the onInputChange logic so that when
the input is cleared it also resets the media upload options state, using the
existing getMediaUploads/setMediaUploadOptions flow in the EventTypeDialog
component.
🪄 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: 5b6c3fd2-6a99-4ecd-95b7-9b489ead8829

📥 Commits

Reviewing files that changed from the base of the PR and between 09d60d6 and 5a5376d.

📒 Files selected for processing (19)
  • src/actions/company-actions.js
  • src/actions/event-type-actions.js
  • src/components/forms/event-type-form.js
  • src/components/mui/__tests__/mui-formik-color-field.test.js
  • src/components/mui/formik-inputs/mui-formik-async-select.js
  • src/components/mui/formik-inputs/mui-formik-color-field.js
  • src/components/mui/formik-inputs/mui-formik-select.js
  • src/i18n/en.json
  • src/layouts/event-type-layout.js
  • src/pages/companies/components/__tests__/company-dialog.test.js
  • src/pages/companies/components/company-dialog.js
  • src/pages/events/components/__tests__/event-type-dialog.test.js
  • src/pages/events/components/event-type-dialog.js
  • src/pages/events/edit-event-type-page.js
  • src/pages/events/event-type-list-page.js
  • src/reducers/events/__tests__/event-type-reducer.test.js
  • src/reducers/events/event-type-list-reducer.js
  • src/reducers/events/event-type-reducer.js
  • src/utils/yup.js
💤 Files with no reviewable changes (6)
  • src/reducers/events/event-type-reducer.js
  • src/utils/yup.js
  • src/reducers/events/tests/event-type-reducer.test.js
  • src/components/forms/event-type-form.js
  • src/pages/events/edit-event-type-page.js
  • src/reducers/events/event-type-list-reducer.js
✅ Files skipped from review due to trivial changes (1)
  • src/i18n/en.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/layouts/event-type-layout.js
  • src/pages/events/event-type-list-page.js

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
src/actions/company-actions.js (1)

196-223: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Stuck loading spinner if company creation fails during logo attach.

When entity.id is falsy, the postRequest(...).then(...) chain (lines 213-222) only dispatches uploadFile (which internally stops loading) on success. If the postRequest promise rejects, uploadFile is never called, so stopLoading() — dispatched only inside uploadLogo/uploadBigLogo's .finally — never fires, and the loading state dispatched at line 199 stays stuck. Every other request in this file explicitly attaches .finally(() => dispatch(stopLoading())) to the outer promise; this branch doesn't.

🐛 Proposed fix
   return postRequest(
     createAction(UPDATE_COMPANY),
     createAction(COMPANY_ADDED),
     `${window.API_BASE_URL}/api/v1/companies`,
     normalizedEntity,
     snackbarErrorHandler,
     entity
-  )(params)(dispatch).then((payload) => {
-    dispatch(uploadFile(payload.response, file));
-  });
+  )(params)(dispatch)
+    .then((payload) => {
+      dispatch(uploadFile(payload.response, file));
+    })
+    .catch(() => dispatch(stopLoading()));
 };
🤖 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/actions/company-actions.js` around lines 196 - 223, The `attachLogo`
thunk can leave the loading state stuck when company creation fails because the
`postRequest(...).then(...)` branch only triggers `uploadLogo`/`uploadBigLogo`
on success. Update this `attachLogo` flow so the outer `postRequest` promise
always dispatches `stopLoading()` in a `.finally(...)`, matching the other
request handlers in this file, and make sure failures in the `entity.id` falsy
path still clear the spinner even when `uploadFile` is never reached.
🧹 Nitpick comments (1)
src/pages/events/components/event-type-dialog.js (1)

532-535: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Media upload search options aren't cleared when the input is emptied.

onInputChange only calls getMediaUploads when val is truthy, so clearing the search text leaves stale mediaUploadOptions from the prior query displayed in the dropdown.

♻️ Suggested fix
             onInputChange={(_, val) => {
-              if (val)
-                getMediaUploads(val, setMediaUploadOptions);
+              if (val) {
+                getMediaUploads(val, setMediaUploadOptions);
+              } else {
+                setMediaUploadOptions([]);
+              }
             }}
🤖 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/events/components/event-type-dialog.js` around lines 532 - 535, The
media upload autocomplete in event-type-dialog.js is leaving stale results
because the onInputChange handler only calls getMediaUploads when val is truthy.
Update the onInputChange logic so that when the input is cleared it also resets
the media upload options state, using the existing
getMediaUploads/setMediaUploadOptions flow in the EventTypeDialog component.
🤖 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/actions/company-actions.js`:
- Around line 259-272: The normalizeEntity helper is assuming color is always
present, which can crash callers like saveCompany, attachLogo, uploadLogo, and
uploadBigLogo. Update normalizeEntity in company-actions.js to guard the color
access before calling startsWith, only stripping the leading hash when
normalizedEntity.color is a non-empty string. Keep the rest of the entity
cleanup logic unchanged.

In `@src/components/mui/formik-inputs/mui-formik-color-field.js`:
- Around line 10-21: The local color state in MuiFormikColorField is only
initialized from field.value once, so it can get out of sync when Formik updates
externally. Add synchronization in MuiFormikColorField so changes to field.value
are reflected back into the local value state, especially after reinitialization
or resets, while keeping handleChange and handleBlur consistent with the synced
state.

In `@src/pages/companies/components/company-dialog.js`:
- Around line 327-342: The Country label in company-dialog is still bound to the
State field because its InputLabel uses htmlFor="state"; update the Country
label to point at the Country control and ensure the MuiFormikAsyncAutocomplete
for the country field receives a matching id (for example via id on the
autocomplete, per the MuiFormikAsyncAutocomplete implementation) so the
label/input association is correct. Use the existing Country block and the
MuiFormikAsyncAutocomplete component names to locate and fix both the label and
control wiring.

In `@src/pages/events/components/event-type-dialog.js`:
- Around line 163-171: The effect in event-type-dialog’s useEffect is
overwriting Formik’s local validation state by calling formik.setErrors with an
empty object when currentEventTypeState.errors is reset. Update the sync logic
so it only pushes external errors into Formik when the errors prop actually has
entries, and avoid clearing existing Yup errors on empty Redux error bags; keep
the touched update tied to the same non-empty error check.

---

Outside diff comments:
In `@src/actions/company-actions.js`:
- Around line 196-223: The `attachLogo` thunk can leave the loading state stuck
when company creation fails because the `postRequest(...).then(...)` branch only
triggers `uploadLogo`/`uploadBigLogo` on success. Update this `attachLogo` flow
so the outer `postRequest` promise always dispatches `stopLoading()` in a
`.finally(...)`, matching the other request handlers in this file, and make sure
failures in the `entity.id` falsy path still clear the spinner even when
`uploadFile` is never reached.

---

Nitpick comments:
In `@src/pages/events/components/event-type-dialog.js`:
- Around line 532-535: The media upload autocomplete in event-type-dialog.js is
leaving stale results because the onInputChange handler only calls
getMediaUploads when val is truthy. Update the onInputChange logic so that when
the input is cleared it also resets the media upload options state, using the
existing getMediaUploads/setMediaUploadOptions flow in the EventTypeDialog
component.
🪄 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: 5b6c3fd2-6a99-4ecd-95b7-9b489ead8829

📥 Commits

Reviewing files that changed from the base of the PR and between 09d60d6 and 5a5376d.

📒 Files selected for processing (19)
  • src/actions/company-actions.js
  • src/actions/event-type-actions.js
  • src/components/forms/event-type-form.js
  • src/components/mui/__tests__/mui-formik-color-field.test.js
  • src/components/mui/formik-inputs/mui-formik-async-select.js
  • src/components/mui/formik-inputs/mui-formik-color-field.js
  • src/components/mui/formik-inputs/mui-formik-select.js
  • src/i18n/en.json
  • src/layouts/event-type-layout.js
  • src/pages/companies/components/__tests__/company-dialog.test.js
  • src/pages/companies/components/company-dialog.js
  • src/pages/events/components/__tests__/event-type-dialog.test.js
  • src/pages/events/components/event-type-dialog.js
  • src/pages/events/edit-event-type-page.js
  • src/pages/events/event-type-list-page.js
  • src/reducers/events/__tests__/event-type-reducer.test.js
  • src/reducers/events/event-type-list-reducer.js
  • src/reducers/events/event-type-reducer.js
  • src/utils/yup.js
💤 Files with no reviewable changes (6)
  • src/reducers/events/event-type-reducer.js
  • src/utils/yup.js
  • src/reducers/events/tests/event-type-reducer.test.js
  • src/components/forms/event-type-form.js
  • src/pages/events/edit-event-type-page.js
  • src/reducers/events/event-type-list-reducer.js
✅ Files skipped from review due to trivial changes (1)
  • src/i18n/en.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/layouts/event-type-layout.js
  • src/pages/events/event-type-list-page.js
🛑 Comments failed to post (4)
src/actions/company-actions.js (1)

259-272: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Unguarded entity.color access can throw.

normalizedEntity.color.startsWith("#") will throw a TypeError if entity.color is undefined/null (e.g., a company created without a color set yet). saveCompany, attachLogo, uploadLogo, and uploadBigLogo all funnel through this helper, so any caller passing an entity without color will crash instead of failing gracefully.

🛡️ Proposed fix
   // remove # from color hexa
-  if (normalizedEntity.color.startsWith("#"))
+  if (normalizedEntity.color?.startsWith("#"))
     normalizedEntity.color = normalizedEntity.color.substr(1);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

const normalizeEntity = (entity) => {
  const normalizedEntity = { ...entity };

  // remove # from color hexa
  if (normalizedEntity.color?.startsWith("#"))
    normalizedEntity.color = normalizedEntity.color.substr(1);

  if (entity.id > 0) {
    delete normalizedEntity.logo;
    delete normalizedEntity.big_logo;
  }

  return normalizedEntity;
};
🤖 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/actions/company-actions.js` around lines 259 - 272, The normalizeEntity
helper is assuming color is always present, which can crash callers like
saveCompany, attachLogo, uploadLogo, and uploadBigLogo. Update normalizeEntity
in company-actions.js to guard the color access before calling startsWith, only
stripping the leading hash when normalizedEntity.color is a non-empty string.
Keep the rest of the entity cleanup logic unchanged.
src/components/mui/formik-inputs/mui-formik-color-field.js (1)

10-21: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Local color value goes stale if Formik value changes externally.

value is seeded from field.value only once via useState. If the Formik field value is reset/reinitialized from outside this component (e.g. enableReinitialize: true, used by the downstream CompanyDialog), the displayed color never updates to match, since there's no effect syncing field.value → local value.

🐛 Proposed fix
-import React, { useState } from "react";
+import React, { useState, useEffect } from "react";
 import PropTypes from "prop-types";
 import { useField } from "formik";
 import { MuiColorInput } from "mui-color-input";
 
 const MuiFormikColorField = ({ name, ...props }) => {
   const [field, meta, helpers] = useField(name);
   const [value, setValue] = useState(field.value || "");
 
+  // Keep local display value in sync when Formik's field value changes
+  // from outside this component (e.g. resetForm/enableReinitialize).
+  useEffect(() => {
+    setValue(field.value || "");
+  }, [field.value]);
+
   const handleChange = (newValue) => {
     setValue(newValue);
   };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

const MuiFormikColorField = ({ name, ...props }) => {
  const [field, meta, helpers] = useField(name);
  const [value, setValue] = useState(field.value || "");

  useEffect(() => {
    setValue(field.value || "");
  }, [field.value]);

  const handleChange = (newValue) => {
    setValue(newValue);
  };

  const handleBlur = (ev) => {
    field.onBlur(ev);
    helpers.setValue(value);
  };
🧰 Tools
🪛 ast-grep (0.44.0)

[warning] 14-14: Avoid using the initial state variable in setState
Context: setValue(newValue)
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.

(setstate-same-var)

🤖 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/components/mui/formik-inputs/mui-formik-color-field.js` around lines 10 -
21, The local color state in MuiFormikColorField is only initialized from
field.value once, so it can get out of sync when Formik updates externally. Add
synchronization in MuiFormikColorField so changes to field.value are reflected
back into the local value state, especially after reinitialization or resets,
while keeping handleChange and handleBlur consistent with the synced state.
src/pages/companies/components/company-dialog.js (1)

327-342: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Country label points to the wrong field (htmlFor="state").

Copy-paste from the State field above: both the State and Country InputLabels use htmlFor="state", so clicking/focusing the "Country" label activates the State input instead, and the Country field has no working label association.

♿ Proposed fix
               <Grid2 size={4}>
-                <InputLabel htmlFor="state">
+                <InputLabel htmlFor="country">
                   {T.translate("edit_company.country")}
                 </InputLabel>
                 <MuiFormikAsyncAutocomplete
                   name="country"

Note: MuiFormikAsyncAutocomplete doesn't currently forward an id, so fully fixing this association may also require passing id="country" (see companion comment on mui-formik-async-select.js).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

              <Grid2 size={4}>
                <InputLabel htmlFor="country">
                  {T.translate("edit_company.country")}
                </InputLabel>
                <MuiFormikAsyncAutocomplete
                  name="country"
                  fullWidth
                  margin="none"
                  queryFunction={(_input, callback) => getCountryList(callback)}
                  formatOption={(country) => ({
                    value: country.iso_code,
                    label: country.name
                  })}
                  defaultOptions
                />
              </Grid2>
🤖 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/companies/components/company-dialog.js` around lines 327 - 342, The
Country label in company-dialog is still bound to the State field because its
InputLabel uses htmlFor="state"; update the Country label to point at the
Country control and ensure the MuiFormikAsyncAutocomplete for the country field
receives a matching id (for example via id on the autocomplete, per the
MuiFormikAsyncAutocomplete implementation) so the label/input association is
correct. Use the existing Country block and the MuiFormikAsyncAutocomplete
component names to locate and fix both the label and control wiring.
src/pages/events/components/event-type-dialog.js (1)

163-171: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the component around the reported lines
nl -ba src/pages/events/components/event-type-dialog.js | sed -n '1,260p'

# Find where this component is used and where `errors` comes from
rg -n "EventTypeDialog|event-type-dialog|errors=" src -g '!**/node_modules/**'

# Look for Formik initialization/validation in this file
rg -n "useFormik|Formik|validationSchema|setErrors|setTouched|initialValues|validate" src/pages/events/components/event-type-dialog.js

Repository: fntechgit/summit-admin

Length of output: 200


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Print the target file with line numbers using awk (nl is unavailable here)
awk '{printf "%5d  %s\n", NR, $0}' src/pages/events/components/event-type-dialog.js | sed -n '1,260p'

# Search for the component usage and `errors` prop source
rg -n "EventTypeDialog|event-type-dialog|errors=" src -g '!**/node_modules/**'

# Search for Formik-related logic in the file
rg -n "useFormik|Formik|validationSchema|setErrors|setTouched|initialValues|validate" src/pages/events/components/event-type-dialog.js

Repository: fntechgit/summit-admin

Length of output: 19584


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the event type list page around currentEventTypeErrors and dialog usage
awk '{printf "%5d  %s\n", NR, $0}' src/pages/events/event-type-list-page.js | sed -n '1,280p'

# Search for currentEventTypeErrors updates in that file
rg -n "currentEventTypeErrors|set.*Errors|errors" src/pages/events/event-type-list-page.js

Repository: fntechgit/summit-admin

Length of output: 10696


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the event type reducer/actions that manage errors
rg -n "errors\s*:|errors\s*=|currentEventTypeState|RESET|resetEventTypeForm|SAVE_EVENT_TYPE|GET_EVENT_TYPE|GET_EVENT_TYPES|EVENT_TYPE" src/actions src/reducers src -g '!**/node_modules/**' | sed -n '1,220p'

Repository: fntechgit/summit-admin

Length of output: 21479


🏁 Script executed:

#!/bin/bash
set -euo pipefail

awk '{printf "%5d  %s\n", NR, $0}' src/reducers/events/event-type-reducer.js | sed -n '1,240p'

Repository: fntechgit/summit-admin

Length of output: 5554


Avoid clearing Formik’s local errors on empty Redux error bags
currentEventTypeState.errors is reset to {} on several reducer paths, so this effect can wipe an active Yup error by calling formik.setErrors({}) even when the field is still invalid. Only sync external errors when the prop actually contains entries.

🤖 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/events/components/event-type-dialog.js` around lines 163 - 171, The
effect in event-type-dialog’s useEffect is overwriting Formik’s local validation
state by calling formik.setErrors with an empty object when
currentEventTypeState.errors is reset. Update the sync logic so it only pushes
external errors into Formik when the errors prop actually has entries, and avoid
clearing existing Yup errors on empty Redux error bags; keep the touched update
tied to the same non-empty error check.

Copilot AI 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.

Pull request overview

This PR modernizes the “Activity / Event Types” UI by moving the list to the MUI table components and replacing the separate edit page with an in-place dialog editor. It also introduces shared hex color validation and a Formik-friendly MUI color picker field that commits on blur.

Changes:

  • Migrates Event Type list to MUI with search, sorting, and pagination, and edits/creates via a new EventTypeDialog.
  • Updates reducers/actions to support list query state (term/order/paging), improved snackbar notifications, and clears stale validation errors when receiving an entity.
  • Adds reusable hexColorValidation and a new MuiFormikColorField, and adopts them in both Event Type and Company dialogs with accompanying tests.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/utils/yup.js Adds shared hex color Yup validation helper.
src/reducers/events/event-type-reducer.js Clears stale errors when receiving/resetting an entity.
src/reducers/events/event-type-list-reducer.js Stores list query/pagination state and total counts.
src/reducers/events/tests/event-type-reducer.test.js Tests clearing stale reducer errors when receiving a new entity.
src/pages/events/event-type-list-page.js Replaces legacy table + navigation with MUI table + dialog-based create/edit.
src/pages/events/edit-event-type-page.js Removes the legacy dedicated edit page.
src/pages/events/components/event-type-dialog.js New MUI/Formik-based create/edit dialog with tabs and media-upload linking UI.
src/pages/events/components/tests/event-type-dialog.test.js Adds extensive dialog behavior + validation tests.
src/pages/companies/components/company-dialog.js Switches company color input to the shared Formik MUI color field + validation.
src/pages/companies/components/tests/company-dialog.test.js Adds test ensuring color commits on blur and is submitted correctly.
src/layouts/event-type-layout.js Removes edit routes and leaves list route only.
src/i18n/en.json Adds/updates strings for the new dialog UX and notifications.
src/components/mui/formik-inputs/mui-formik-select.js Improves select display by rendering the option label instead of raw value.
src/components/mui/formik-inputs/mui-formik-color-field.js Introduces blur-commit color picker to reduce re-render churn during dragging.
src/components/mui/formik-inputs/mui-formik-async-select.js Adds disabled support for the async autocomplete input.
src/components/mui/tests/mui-formik-color-field.test.js Tests blur-commit behavior and validation error clearing for the new color field.
src/components/forms/event-type-form.js Removes the legacy non-MUI event type form.
src/actions/event-type-actions.js Adds list query params, snackbar handlers, and updates save/delete/seed flows.
src/actions/company-actions.js Aligns snackbar handler imports with the foundation utilities.

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

Comment thread src/pages/events/event-type-list-page.js
Comment thread src/components/mui/formik-inputs/mui-formik-select.js
Comment thread src/components/mui/formik-inputs/mui-formik-color-field.js
Comment thread src/actions/event-type-actions.js
Comment thread src/actions/event-type-actions.js

@smarcet smarcet 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.

LGTM

@smarcet
smarcet merged commit ada1234 into master Jul 3, 2026
9 checks passed
smarcet added a commit that referenced this pull request Jul 16, 2026
* feat: move activity type list to mui

Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>

* fix: feedback from PR

Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>

* feat: move activity types new and edit to mui (#977)

* feat: move activity types new and edit to mui

Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>

* fix: feedback from PR

Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>

---------

Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>

* feat: migrate EventTypeForm to Formik + MUI dialog

Replaces the legacy Bootstrap class-component EventTypeForm (embedded
in the MUI dialog shipped in PR #969 with no DialogActions footer)
with a single pure Formik + MUI EventTypeDialog, following
company-dialog.js (PR #910) as the primary pattern and the tabbed
layout from selection-plan-form.js (PR #917).

- Main / Schedule settings tabs; MuiFormikTextField/Select/Checkbox/
  AsyncAutocomplete; MuiColorInput with ref-based color tracking to
  avoid re-rendering the whole form on every drag
- Media upload types linked-list rebuilt with Autocomplete + MuiTable,
  matching the track-groups-tab.js / company-dialog.js sponsorship
  table pattern, with dedup against already-linked types
- EventTypeDialog is now a pure component; Redux wiring moved up into
  event-type-list-page.js, whose mapStateToProps now exposes
  currentEventType/currentEventTypeErrors matching every other
  list+dialog page's naming convention
- Yup validation (positiveNumberValidation from utils/yup.js) for the
  numeric fields, with a NaN-safe fallback in handleSubmit since
  Formik does not auto-cast values on submit
- Fixed a real renderValue bug in the shared MuiFormikSelect wrapper
  (echoed the raw value instead of resolving the MenuItem label,
  invisible elsewhere because other consumers' labels matched their
  values) - benefits 8 other call sites
- Fixed a stale-errors-across-entities bug in event-type-reducer.js
  (RECEIVE_EVENT_TYPE didn't reset errors, unlike UPDATE_EVENT_TYPE)

87 test suites / 733 tests passing, 0 lint errors on touched files.
Live-verified against a real summit without modifying its data.

ref: https://app.clickup.com/t/86bac70mf

* fix: unify color picker field between event-type and company dialogs

Both dialogs duplicated a ColorPickerField that tracked the picked
color in a useRef, splicing it into the payload only at submit time.
This was a workaround for mui-color-input firing onChange on every
pointermove while dragging, but it meant the color never participated
in Formik state: no yup validation, stale server-side errors that
never cleared on a corrective edit, and no name/id for the label or
useScrollToError to target.

Extract a shared MuiFormikColorField (src/components/mui/formik-inputs)
that keeps local state for instant drag/typing feedback but commits to
Formik (value + touched + validation) only on blur, avoiding a
full-dialog re-render storm while still getting real validation and
error-clearing. Add hexColorValidation() to src/utils/yup.js and wire
it into both dialogs' schemas.

Also fixes an unrelated pre-existing bug found while running the
suite: MuiFormikAsyncAutocomplete referenced an undeclared
defaultOptions variable, crashing every page that uses it.

* refactor: migrate company/event-type actions off base-actions snackbar wrapper

company-actions.js and event-type-actions.js now import snackbarErrorHandler
and snackbarSuccessHandler directly from openstack-uicore-foundation instead
of the local src/actions/base-actions.js wrapper, which is being phased out
in favor of uicore-foundation as the single source of truth. Other action
files still using the base-actions wrapper will be migrated incrementally
(tracked in docs/plans/clickup-migrate-snackbar-handlers-to-uicore.md).

event-type-actions.js also switches getEventTypes/getEventType/saveEventType/
deleteEventType/seedEventTypes from authErrorHandler (blocking alert) to
snackbarErrorHandler, adds a success snackbar for seedEventTypes, and adds
the event_types_seed i18n key.

Also removes a leftover dispatch(showMessage(success_message, ...)) call in
saveEventType's create branch left over from this migration - its backing
success_message const had been deleted, so it would have thrown
ReferenceError: success_message is not defined on every new event type
creation. The snackbarSuccessHandler dispatch right below it already covers
the success message.

* fix: commit color field pending value on Enter to avoid stale submit

* test: add event type list page coverage for search, pagination and crud flows

* fix: reset to first page when sorting event type list

* fix: refresh paginated event type list after seeding defaults

* fix: close event type dialog on save success regardless of list refresh outcome

* fix: sync color field display when formik value changes externally

* fix: show global spinner during event type delete and seed operations

---------

Signed-off-by: Priscila Moneo <priscila_moneo@hotmail.com.ar>
Co-authored-by: smarcet <smarcet@gmail.com>
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