Skip to content

Frontend/cosmo search updates#1308

Open
jsandoval81 wants to merge 14 commits intocsg-org:mainfrom
InspiringApps:frontend/cosmo-search-updates
Open

Frontend/cosmo search updates#1308
jsandoval81 wants to merge 14 commits intocsg-org:mainfrom
InspiringApps:frontend/cosmo-search-updates

Conversation

@jsandoval81
Copy link
Copy Markdown
Collaborator

@jsandoval81 jsandoval81 commented Mar 3, 2026

Requirements List

  • None

Description List

  • Update Licensee Search UI for cosmetology-specific capability
  • Update Licensee List UI for cosmetology-specific capability
  • Update Licensee Detail UI for cosmetology-specific capability
  • Improve the License & Privilege card sorting on the Licensee Detail UI
  • Improve app-mode setting to be set automatically in store, rather than per component
  • Minor update to eslintrc for using v-for keys in <template> elements

TODO

  • Wait for backend changes to be merged
  • Wait for tickets to be broken out on board and assign Closed # below

Testing List

  • yarn test:unit:all should run without errors or warnings
  • yarn serve should run without errors or warnings
  • yarn build should run without errors or warnings
  • Code review
  • Testing
    • Public search
      • Public search for JCC (ASLP, OT, COUN) should continue to work as it has
      • Public search for Cosmetology should match the Figma designs
        • Adding License number search and no longer requiring Last Name if First Name is searched
        • List results should no longer have a Privileges column, and instead have a State License Number Column
        • Detail results should include Licenses
          • Licenses should be sorted by state, then license type
          • Privileges should be sorted by license type, then state
    • Staff search
      • Public search for JCC (ASLP, OT, COUN) should continue to work as it has
      • Public search for Cosmetology should match the Figma designs
        • Remove unused fields for cosmetology, add license number search + dob search
        • List results should no longer have a Privileges column, and instead have a State License Number Column
        • Detail results should have more limited privilege information in privilege cards
          • Licenses should be sorted by state, then license type
          • Privileges should be sorted by license type, then state

Closes #1268
Closes #1269
Closes #1280

Summary by CodeRabbit

  • New Features

    • Cosmetology professional mode with mode-specific search forms and displays
    • License number and date-of-birth search/filters and a new license-number column when cosmetology mode is active
    • Added cosmetologist and esthetician license types
    • Mock-populate and clear form actions in the search UI
  • Improvements

    • Fields and details now show/hide per app mode (JCC vs Cosmetology)
    • Search results include DOB and license number in summaries
    • Licenses and privileges consistently sorted; improved tablet wrapping and localized label for state license number

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 3, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds cosmetology app-mode support and licenseNumber/DOB search plumbing: new global app-mode getters and store dispatch, mode-conditional UI and validation, network/search APIs extended for licenseNumber and DOB, model/locales updates, sorting for licenses/privileges, mock/test adjustments.

Changes

Cohort / File(s) Summary
ESLint
webroot/.eslintrc.js
Disabled vue/no-v-for-template-key rule.
Global getters
webroot/src/store/global/global.getters.ts
Added isAppModeJcc and isAppModeCosmetology getters.
Compact / User flow
webroot/src/store/user/user.actions.ts, webroot/src/components/CompactSelector/CompactSelector.ts
Selecting a compact now drives setAppMode dispatch and fetches compact states; CompactSelector removed its internal app-mode dispatch.
Search APIs / Network
webroot/src/network/searchApi/data.api.ts, webroot/src/network/licenseApi/data.api.ts
Added dob and licenseNumber to local request interfaces and query construction (OpenSearch/license API).
Licensee Search (forms & UI)
webroot/src/components/Licensee/LicenseeSearch/..., webroot/src/components/Licensee/LicenseeSearchLegacy/...
Added licenseNumber and dob form fields, mode-aware allowed search props, conditional rendering, mockPopulate/reset changes, and mode-driven validation/submit logic.
Licensee list & rows
webroot/src/components/Licensee/LicenseeList/..., webroot/src/components/Licensee/LicenseeRow/...
Exposed app-mode getters; conditionally render licenseNumber column for Cosmetology and hide practicing-locations for JCC; include licenseNumber in search requests.
PrivilegeCard & Licensing detail
webroot/src/components/PrivilegeCard/..., webroot/src/pages/LicensingDetail/..., webroot/src/pages/LicensingDetail/LicensingDetail.less
Added app-mode getters; conditionally render privilege/military details for JCC; introduced sorting helpers for licenses/privileges and minor tablet wrap CSS.
Models & locales
webroot/src/models/License/License.model.ts, webroot/src/models/Licensee/Licensee.model.ts, webroot/src/locales/en.json, webroot/src/locales/es.json
Added COSMETOLOGIST and ESTHETICIAN license types and stateLicenseNumber locale keys; minor whitespace tweak in Licensee model.
Store state & tests
webroot/src/store/license/license.mutations.ts, webroot/src/store/license/license.spec.ts, webroot/src/store/user/user.spec.ts
Added licenseNumber to license search/reset state and tests; updated user.spec to assert setAppMode dispatch for COSMETOLOGY and JCC compacts.
Mocks & styles
webroot/src/network/mocks/mock.data.ts, webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.less
Expanded cosmetology jurisdictions in mock data and added .clear-form style for legacy search UI.

Sequence Diagram(s)

sequenceDiagram
  participant UI as rgba(79,129,189,0.5) User UI
  participant Store as rgba(124,181,71,0.5) Vuex Store
  participant Components as rgba(192,80,77,0.5) Vue Components
  participant API as rgba(155,89,182,0.5) Network API

  UI->>Store: dispatch setCurrentCompact(compact)
  Store->>Store: dispatch setAppMode(AppModes.COSMETOLOGY|JCC)
  Store->>Store: dispatch getCompactStatesRequest(compact.type)
  Store-->>Components: getters isAppMode* update
  UI->>Components: render mode-conditional fields (licenseNumber/dob or privilege fields)
  UI->>API: submit search params (includes licenseNumber/dob when cosmetology)
  API-->>Components: return search results
  Components->>UI: render rows/columns per app mode
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • jlkravitz
  • rmolinares
  • isabeleliassen

Poem

🐰 Hopping through modes with delight,
A new number peeks into the light,
Lists and cards reshuffle their view,
Fields wake up depending on the cue,
The rabbit nods: "Search on—one, two, woohoo!"

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'Frontend/cosmo search updates' directly describes the main changes: updates to the frontend UI for cosmetology-specific search capabilities across multiple components.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The pull request description is comprehensive and well-structured, covering all required sections with clear objectives, requirements, and testing criteria.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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.

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
webroot/src/network/licenseApi/data.api.ts (1)

127-147: ⚠️ Potential issue | 🟠 Major

licenseNumber-only searches are currently ignored.

hasSearchTerms does not include licenseNumber, so requestParams.query.licenseNumber is never set unless id/first/last name is also provided.

Suggested fix
-        const hasSearchTerms = Boolean(licenseeId || licenseeFirstName || licenseeLastName);
+        const hasSearchTerms = Boolean(licenseeId || licenseeFirstName || licenseeLastName || licenseNumber);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webroot/src/network/licenseApi/data.api.ts` around lines 127 - 147, The
current gating variable hasSearchTerms excludes licenseNumber, so
requestParams.query.licenseNumber is never set for license-number-only searches;
update the logic in data.api.ts by either adding licenseNumber to the
hasSearchTerms expression (e.g., include licenseNumber in the Boolean(...) that
defines hasSearchTerms) or move the licenseNumber assignment
(requestParams.query.licenseNumber) out of the hasSearchTerms conditional so
that licenseNumber is applied independently; ensure you reference and modify the
hasSearchTerms variable and the requestParams.query.licenseNumber assignment
accordingly.
🧹 Nitpick comments (3)
webroot/src/store/user/user.spec.ts (1)

1086-1090: Strengthen the compact-states dispatch assertion with payload checks.

Both tests verify the second dispatched action name, but not the compact type argument. Add payload checks so regressions in downstream state-fetch routing are caught.

Suggested test assertion tightening
-        expect([dispatch.secondCall.args[0]]).to.matchPattern(['getCompactStatesRequest']);
+        expect(dispatch.secondCall.args).to.matchPattern(['getCompactStatesRequest', CompactType.ASLP]);
...
-        expect([dispatch.secondCall.args[0]]).to.matchPattern(['getCompactStatesRequest']);
+        expect(dispatch.secondCall.args).to.matchPattern(['getCompactStatesRequest', CompactType.COSMETOLOGY]);

Also applies to: 1100-1103

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webroot/src/store/user/user.spec.ts` around lines 1086 - 1090, The test
currently only asserts the second dispatched action name; update the assertion
to also verify the payload/argument passed to getCompactStatesRequest (e.g.,
inspect dispatch.secondCall.args[1] or the appropriate payload position) equals
the expected compact type so downstream routing won't regress; change the
assertion in the block referencing dispatch and getCompactStatesRequest (and
mirror the same tightening for the similar assertions around lines with the
other test) to assert both action name and payload value alongside existing
AppModes.JCC checks.
webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts (2)

376-389: Consider logging unhandled app modes in the default case.

The switch statement cleanly separates mode-specific search properties. However, the empty default case silently falls through. If a new AppModes value is added in the future without updating this switch, it would use only common search props without any indication.

Consider adding a console warning for development or using TypeScript's exhaustive check pattern.

💡 Optional: Add exhaustive check or warning
 case AppModes.COSMETOLOGY:
     allowedSearchProps.push('licenseNumber');
     break;
-default:
-    break;
+default: {
+    // Exhaustive check - TypeScript will error if a new AppModes value is added
+    const _exhaustiveCheck: never = this.appMode;
+    console.warn(`Unhandled app mode: ${_exhaustiveCheck}`);
+    break;
+}
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts` around
lines 376 - 389, The switch on this.appMode (inside LicenseeSearch where
allowedSearchProps is built) currently has an empty default and will silently
ignore any new AppModes values; add a dev-only warning or an exhaustive check in
the default branch to surface unhandled app modes (e.g., console.warn or throw
in non-production), or implement a TypeScript exhaustive check using a helper
that accepts the unreachable value, referencing AppModes, allowedSearchProps,
and the switch block so future additions to AppModes are detected and logged.

257-265: Consider adding a placeholder for consistency.

The licenseNumber FormInput has an empty placeholder while similar fields like firstName and lastName use computed placeholders. If a placeholder would help users, consider adding one.

💡 Optional: Add a placeholder
 licenseNumber: new FormInput({
     id: 'license-number',
     name: 'license-number',
     label: computed(() => this.$t('licensing.licenseNumber')),
-    placeholder: '',
+    placeholder: computed(() => this.$t('licensing.searchPlaceholderLicenseNumber')),
     validation: Joi.string().min(0).max(100).messages(this.joiMessages.string),
     value: this.searchParams.licenseNumber || '',
     enforceMax: true,
 }),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts` around
lines 257 - 265, Add a computed placeholder to the licenseNumber FormInput (the
new FormInput instance assigned to licenseNumber) to match other fields: replace
the empty placeholder with a computed translation like computed(() =>
this.$t('licensing.licenseNumberPlaceholder')) or an appropriate i18n key so the
field shows a consistent placeholder text; update the i18n strings if needed to
include that key.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@webroot/src/models/License/License.model.ts`:
- Around line 33-34: Rename the misspelled enum key COSMOTOLOGIST to
COSMETOLOGIST in the License enum (License.model.ts) so the key matches its
value 'cosmetologist'; update the enum declaration (replace COSMOTOLOGIST =
'cosmetologist' with COSMETOLOGIST = 'cosmetologist') and run a quick global
search/replace for COSMOTOLOGIST to ensure no references remain, adjusting any
usages to the new COSMETOLOGIST identifier.

In `@webroot/src/network/mocks/mock.data.ts`:
- Around line 188-225: In the mock permissions objects for regions ne, oh, nv,
and ma inside the actions blocks, replace the incorrect key readSsn with the
canonical readSSN to match the rest of the mock schema; update each actions
object (e.g., the actions object nested under the ne, oh, nv, ma entries) so the
permission key is readSSN and run a quick search to ensure no other occurrences
of readSsn remain.

---

Outside diff comments:
In `@webroot/src/network/licenseApi/data.api.ts`:
- Around line 127-147: The current gating variable hasSearchTerms excludes
licenseNumber, so requestParams.query.licenseNumber is never set for
license-number-only searches; update the logic in data.api.ts by either adding
licenseNumber to the hasSearchTerms expression (e.g., include licenseNumber in
the Boolean(...) that defines hasSearchTerms) or move the licenseNumber
assignment (requestParams.query.licenseNumber) out of the hasSearchTerms
conditional so that licenseNumber is applied independently; ensure you reference
and modify the hasSearchTerms variable and the requestParams.query.licenseNumber
assignment accordingly.

---

Nitpick comments:
In `@webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts`:
- Around line 376-389: The switch on this.appMode (inside LicenseeSearch where
allowedSearchProps is built) currently has an empty default and will silently
ignore any new AppModes values; add a dev-only warning or an exhaustive check in
the default branch to surface unhandled app modes (e.g., console.warn or throw
in non-production), or implement a TypeScript exhaustive check using a helper
that accepts the unreachable value, referencing AppModes, allowedSearchProps,
and the switch block so future additions to AppModes are detected and logged.
- Around line 257-265: Add a computed placeholder to the licenseNumber FormInput
(the new FormInput instance assigned to licenseNumber) to match other fields:
replace the empty placeholder with a computed translation like computed(() =>
this.$t('licensing.licenseNumberPlaceholder')) or an appropriate i18n key so the
field shows a consistent placeholder text; update the i18n strings if needed to
include that key.

In `@webroot/src/store/user/user.spec.ts`:
- Around line 1086-1090: The test currently only asserts the second dispatched
action name; update the assertion to also verify the payload/argument passed to
getCompactStatesRequest (e.g., inspect dispatch.secondCall.args[1] or the
appropriate payload position) equals the expected compact type so downstream
routing won't regress; change the assertion in the block referencing dispatch
and getCompactStatesRequest (and mirror the same tightening for the similar
assertions around lines with the other test) to assert both action name and
payload value alongside existing AppModes.JCC checks.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d1c77a3 and 76fe73e.

📒 Files selected for processing (27)
  • webroot/.eslintrc.js
  • webroot/src/components/CompactSelector/CompactSelector.ts
  • webroot/src/components/Licensee/LicenseeList/LicenseeList.ts
  • webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.ts
  • webroot/src/components/Licensee/LicenseeRow/LicenseeRow.ts
  • webroot/src/components/Licensee/LicenseeRow/LicenseeRow.vue
  • webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts
  • webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
  • webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts
  • webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vue
  • webroot/src/components/PrivilegeCard/PrivilegeCard.ts
  • webroot/src/components/PrivilegeCard/PrivilegeCard.vue
  • webroot/src/locales/en.json
  • webroot/src/locales/es.json
  • webroot/src/models/License/License.model.ts
  • webroot/src/models/Licensee/Licensee.model.ts
  • webroot/src/network/licenseApi/data.api.ts
  • webroot/src/network/mocks/mock.data.ts
  • webroot/src/network/searchApi/data.api.ts
  • webroot/src/pages/LicensingDetail/LicensingDetail.less
  • webroot/src/pages/LicensingDetail/LicensingDetail.ts
  • webroot/src/pages/LicensingDetail/LicensingDetail.vue
  • webroot/src/store/global/global.getters.ts
  • webroot/src/store/license/license.mutations.ts
  • webroot/src/store/license/license.spec.ts
  • webroot/src/store/user/user.actions.ts
  • webroot/src/store/user/user.spec.ts

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.

Actionable comments posted: 4

🧹 Nitpick comments (1)
webroot/src/components/Licensee/LicenseeList/LicenseeList.ts (1)

395-397: Guard licenseNumber serialization by app mode.

For defensive correctness, only attach licenseNumber when cosmetology mode is active.

♻️ Suggested hardening
-        if (searchParams?.licenseNumber) {
+        if (this.isAppModeCosmetology && searchParams?.licenseNumber) {
             requestConfig.licenseNumber = searchParams.licenseNumber;
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webroot/src/components/Licensee/LicenseeList/LicenseeList.ts` around lines
395 - 397, Only set requestConfig.licenseNumber from searchParams?.licenseNumber
when the app is running in cosmetology mode: guard the assignment by checking
the app mode (e.g., call the existing isCosmetologyMode() helper or compare
appMode === 'cosmetology') before assigning requestConfig.licenseNumber; leave
it unset otherwise. Update the block around searchParams?.licenseNumber and
requestConfig to perform that conditional check so license numbers are only
serialized for cosmetology mode.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.ts`:
- Around line 299-301: Only set requestConfig.licenseNumber when the app is in
cosmetology mode: wrap the existing assignment that reads
searchParams.licenseNumber and assigns requestConfig.licenseNumber with an
additional condition that verifies cosmetology mode (e.g., check the relevant
mode flag/enum used in this component such as isCosmetologyMode or appMode ===
'cosmetology'); change the current block that uses searchParams.licenseNumber so
it only runs if both searchParams.licenseNumber is present and the
cosmetology-mode check passes, leaving all other requestConfig fields unchanged.
- Around line 127-135: The assembly of the combined search display in
searchDisplayAll should filter out empty/blank parts before joining to avoid
malformed separators; instead of building the array then joining and running
regex cleanup, filter the array elements (this.searchDisplayCompact,
this.searchDisplayFullName, this.searchDisplayState,
this.searchDisplayLicenseNumber) for truthy/non-blank values and then join them
with ', ' to produce the final string (remove the current joined variable +
regex replaces and return the filtered-then-joined result).

In
`@webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts`:
- Around line 249-263: The resetForm() method currently clears
this.formData.compact.value only when enableCompactSelect is true but does not
clear the store-backed compact state; update resetForm() (within
LicenseeSearchLegacy.resetForm) to also clear the compact state in the store
whenever you reset the form (respecting enableCompactSelect), e.g., invoke the
existing action/mutation or method that sets the store compact value (the same
mechanism used elsewhere to set compact state), and keep the existing resets for
firstName, lastName, state, licenseNumber and the calls to
updateFormSubmitSuccess and updateFormSubmitError so form submit state is fully
cleared.

In
`@webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vue`:
- Around line 23-28: Replace the anchor used for the clear action with a native
button to restore keyboard accessibility: where the template conditionally
renders the anchor (v-if="isMockPopulateEnabled") that binds `@click` and
`@keyup.enter` to resetForm(), change it to a <button type="button"> that keeps
the same v-if, `@click`="resetForm()" and remove the redundant `@keyup.enter`
handler (buttons handle Enter/Space natively); ensure the CSS class "clear-form
search-input" is preserved and adjust any styling selectors if they relied on an
<a> element.

---

Nitpick comments:
In `@webroot/src/components/Licensee/LicenseeList/LicenseeList.ts`:
- Around line 395-397: Only set requestConfig.licenseNumber from
searchParams?.licenseNumber when the app is running in cosmetology mode: guard
the assignment by checking the app mode (e.g., call the existing
isCosmetologyMode() helper or compare appMode === 'cosmetology') before
assigning requestConfig.licenseNumber; leave it unset otherwise. Update the
block around searchParams?.licenseNumber and requestConfig to perform that
conditional check so license numbers are only serialized for cosmetology mode.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b92c7b95-1df5-4cf8-851d-e4cb1af6a234

📥 Commits

Reviewing files that changed from the base of the PR and between 8077130 and b0fb88f.

📒 Files selected for processing (5)
  • webroot/src/components/Licensee/LicenseeList/LicenseeList.ts
  • webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.ts
  • webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.less
  • webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts
  • webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.vue

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.

Actionable comments posted: 1

♻️ Duplicate comments (1)
webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts (1)

249-264: ⚠️ Potential issue | 🟡 Minor

Reset should also clear field-level validation state.

resetForm() clears values and submit-level flags, but it does not explicitly reset/recompute per-input touched/error state. Add a non-touched validation pass (or equivalent field reset) to avoid stale inline errors after clear.

🧹 Suggested adjustment
     async resetForm(): Promise<void> {
         if (this.enableCompactSelect) {
             this.formData.compact.value = '';
             await this.$store.dispatch('user/setCurrentCompact', null);
         }

         this.formData.firstName.value = '';
         this.formData.lastName.value = '';
         this.formData.state.value = '';
         this.formData.licenseNumber.value = '';
+        this.validateAll({ asTouched: false });
         this.isFormLoading = false;
         this.isFormSuccessful = false;
         this.isFormError = false;
         this.updateFormSubmitSuccess('');
         this.updateFormSubmitError('');
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts`
around lines 249 - 264, resetForm currently clears values and submit flags but
leaves per-field validation state intact; update resetForm (in
LicenseeSearchLegacy.resetForm) to also clear field-level validation by either
calling the form validation reset API (e.g., this.$v && this.$v.$reset()) or
explicitly resetting each field's validation props: for compact, firstName,
lastName, state, licenseNumber set touched/dirty flags to false and clear any
error messages (e.g., field.touched = false; field.error = ''), then optionally
re-run a non-touched validation pass if your app relies on computed validation
state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts`:
- Around line 219-221: handleSubmit() now emits licenseNumber for cosmetology
but the request mapper omits licenseNumber when other name/id fields are blank;
update the mapper that builds the outgoing request (the hasSearchTerms branch /
mapping logic) to explicitly check for and include query.licenseNumber (or move
the licenseNumber mapping out of the hasSearchTerms-only block) so that when
AppModes.COSMETOLOGY submits only licenseNumber it is serialized into the
request; adjust the conditional that computes hasSearchTerms or the mapping
function so licenseNumber is honored independently of firstName/lastName/id.

---

Duplicate comments:
In
`@webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts`:
- Around line 249-264: resetForm currently clears values and submit flags but
leaves per-field validation state intact; update resetForm (in
LicenseeSearchLegacy.resetForm) to also clear field-level validation by either
calling the form validation reset API (e.g., this.$v && this.$v.$reset()) or
explicitly resetting each field's validation props: for compact, firstName,
lastName, state, licenseNumber set touched/dirty flags to false and clear any
error messages (e.g., field.touched = false; field.error = ''), then optionally
re-run a non-touched validation pass if your app relies on computed validation
state.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 649aa13f-d463-428c-989d-30b28c18bd41

📥 Commits

Reviewing files that changed from the base of the PR and between b0fb88f and 5e21083.

📒 Files selected for processing (2)
  • webroot/src/components/Licensee/LicenseeListLegacy/LicenseeListLegacy.ts
  • webroot/src/components/Licensee/LicenseeSearchLegacy/LicenseeSearchLegacy.ts

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)
webroot/src/network/searchApi/data.api.ts (1)

26-35: ⚠️ Potential issue | 🔴 Critical

Add dateOfBirth to the OpenSearch document structure for cosmetology license searches.

The frontend queries licenseNumber (root level) and licenses.dateOfBirth, but the backend's LicenseGeneralResponseSchema used in generate_provider_opensearch_document() includes licenseNumber on line 168 but omits dateOfBirth entirely. dateOfBirth only exists in LicenseReadPrivateResponseSchema, which is not used for search documents. Without this field indexed, searches by date of birth will silently return no results.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@webroot/src/network/searchApi/data.api.ts` around lines 26 - 35, The
OpenSearch document schema and generator are missing the licenses.dateOfBirth
field required for cosmetology license searches: update
LicenseGeneralResponseSchema to include dateOfBirth on the license object (same
type/format used in LicenseReadPrivateResponseSchema) and modify
generate_provider_opensearch_document() to populate licenses[].dateOfBirth from
the source license data so licenses.dateOfBirth is indexed (ensure the field
uses the correct string/ISO date format expected by the frontend query).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@webroot/src/network/searchApi/data.api.ts`:
- Around line 26-35: The OpenSearch document schema and generator are missing
the licenses.dateOfBirth field required for cosmetology license searches: update
LicenseGeneralResponseSchema to include dateOfBirth on the license object (same
type/format used in LicenseReadPrivateResponseSchema) and modify
generate_provider_opensearch_document() to populate licenses[].dateOfBirth from
the source license data so licenses.dateOfBirth is indexed (ensure the field
uses the correct string/ISO date format expected by the frontend query).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9646b276-3894-4639-a88e-383dfe481998

📥 Commits

Reviewing files that changed from the base of the PR and between 5e21083 and 05fff36.

📒 Files selected for processing (6)
  • webroot/src/components/Licensee/LicenseeList/LicenseeList.ts
  • webroot/src/components/Licensee/LicenseeRow/LicenseeRow.vue
  • webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.ts
  • webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
  • webroot/src/network/licenseApi/data.api.ts
  • webroot/src/network/searchApi/data.api.ts
✅ Files skipped from review due to trivial changes (1)
  • webroot/src/components/Licensee/LicenseeSearch/LicenseeSearch.vue
🚧 Files skipped from review as they are similar to previous changes (3)
  • webroot/src/components/Licensee/LicenseeRow/LicenseeRow.vue
  • webroot/src/network/licenseApi/data.api.ts
  • webroot/src/components/Licensee/LicenseeList/LicenseeList.ts

@jsandoval81 jsandoval81 requested a review from rmolinares March 31, 2026 21:38
Comment on lines +267 to +273
dob: new FormInput({
id: 'dob',
name: 'dob',
label: computed(() => this.$t('common.dateOfBirth')),
placeholder: computed(() => 'MM/DD/YYYY'),
value: this.searchParams.dob || '',
}),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Should you add validation here? MfaResetStartLicensee.ts and RegisterLicensee.ts have similar dob validations that you can possibly reuse here.

@rmolinares rmolinares self-requested a review April 3, 2026 20:16
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.

cosmetology list view and detail view cosmetology staff search cosmetology public search

2 participants