Repository: bcgov/business-ui
Pull request #122: 27629 - Fixed text filtering bug + put minimum characters
Author: login: JazzarKarim
Created: 2025-05-08T22:40:29Z | Merged: 2025-05-09T19:04:26Z

https://github.com/bcgov/entity/issues/27629

Sev found a bug. Let's say you type NR4 and then the table starts loading. While the table is loading, if you type x after 4, the results will still be for NR4 which is very bad user experience honestly and will be probably frustrating for users. This PR fixes this. 

I also added a minimum requirement for how many characters is needed. Sev, please if you can test the bug in the temp link, that would be great. Thanks.


Diff:
diff --git a/business-registry-dashboard/app/stores/affiliations.ts b/business-registry-dashboard/app/stores/affiliations.ts
index 846de7af1..22a2a8d9f 100644
--- a/business-registry-dashboard/app/stores/affiliations.ts
+++ b/business-registry-dashboard/app/stores/affiliations.ts
@@ -32,6 +32,21 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
     error: false
   })
 
+  // Track if filters changed during loading
+  const filtersChangedDuringLoading = ref(false)
+  // Store the latest filter values
+  const latestFilters = reactive({
+    businessName: '',
+    businessNumber: ''
+  })
+
+  // Helper function to check if filters have minimum required characters
+  function hasMinimumFilterCharacters (filters: { businessName: string, businessNumber: string }): boolean {
+    return filters.businessName.length >= 3 ||
+           filters.businessNumber.length >= 2 ||
+           (filters.businessName.length === 0 && filters.businessNumber.length === 0)
+  }
+
   // Pagination limit options
   const paginationLimitOptions = ref([
     { label: '50', value: 50 },
@@ -284,6 +299,24 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
       affiliations.error = true
     } finally {
       affiliations.loading = false
+
+      // Check if filters changed during loading and initiate a new search if needed
+      if (filtersChangedDuringLoading.value) {
+        filtersChangedDuringLoading.value = false
+
+        // Update the actual filters with the latest values
+        if (affiliations.filters.businessName !== latestFilters.businessName) {
+          affiliations.filters.businessName = latestFilters.businessName
+        }
+        if (affiliations.filters.businessNumber !== latestFilters.businessNumber) {
+          affiliations.filters.businessNumber = latestFilters.businessNumber
+        }
+
+        // Trigger a new search with the latest filters if they meet the minimum criteria
+        const hasMinimumCharacters = hasMinimumFilterCharacters(affiliations.filters)
+
+        if (hasMinimumCharacters) { loadAffiliations() }
+      }
     }
   }
 
@@ -332,9 +365,25 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
       // Reset to page 1 when filter changes
       affiliations.pagination.page = 1
 
+      // Update the latest filter values
+      latestFilters.businessName = affiliations.filters.businessName
+      latestFilters.businessNumber = affiliations.filters.businessNumber
+
       // Only call loadAffiliations when server-side filtering is enabled
-      if (!affiliations.loading && enableServerFiltering.value) {
-        await loadAffiliations()
+      if (enableServerFiltering.value) {
+        // Only trigger search when there are at least 3 characters for business name
+        // 2 characters for business number
+        // or 0 characters for both to reset
+        const hasMinimumCharacters = hasMinimumFilterCharacters(affiliations.filters)
+
+        if (hasMinimumCharacters) {
+          if (affiliations.loading) {
+            // Mark that filters changed during loading
+            filtersChangedDuringLoading.value = true
+          } else {
+            await loadAffiliations()
+          }
+        }
       }
     },
     { debounce: 400 } // 400ms debounce time - wait for user input to settle
diff --git a/business-registry-dashboard/package.json b/business-registry-dashboard/package.json
index c5ab28124..0e242c70d 100644
--- a/business-registry-dashboard/package.json
+++ b/business-registry-dashboard/package.json
@@ -2,7 +2,7 @@
   "name": "business-registry-dashboard",
   "private": true,
   "type": "module",
-  "version": "1.0.47",
+  "version": "1.0.48",
   "scripts": {
     "build-check": "nuxt build",
     "build": "nuxt generate",


Reviews:
user: login: severinbeauvais
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T22:53:49Z
user: login: severinbeauvais
body: LGTM
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T22:54:13Z
user: login: JazzarKarim
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-08T22:55:04Z
user: login: TVWerdal
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-08T22:56:30Z
user: login: TVWerdal
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-08T22:57:39Z
user: login: JazzarKarim
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-08T23:01:48Z
user: login: JazzarKarim
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-08T23:03:16Z
user: login: severinbeauvais
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T23:12:08Z
user: login: JazzarKarim
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-09T17:12:48Z

Review comments:
diff_hunk: @@ -32,6 +32,21 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
     error: false
   })
 
+  // Track if filters changed during loading
+  const filtersChangedDuringLoading = ref(false)
+  // Store the latest filter values
+  const latestFilters = reactive({
+    businessName: '',
+    businessNumber: ''
+  })
+
+  // Helper function to check if filters have minimum required characters
+  function hasMinimumFilterCharacters (filters: { businessName: string, businessNumber: string }): boolean {
+    return filters.businessName.length >= 2 ||
+           filters.businessNumber.length >= 2 ||
path: business-registry-dashboard/app/stores/affiliations.ts
user: login: severinbeauvais
body: I think a min length of 2 for business number is nice, as it allows you to search for all "BC"s.

I recommend changing min length for business name to 3 (which matches other places we do this in the code).
created_at: 2025-05-08T22:53:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -32,6 +32,21 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
     error: false
   })
 
+  // Track if filters changed during loading
+  const filtersChangedDuringLoading = ref(false)
+  // Store the latest filter values
+  const latestFilters = reactive({
+    businessName: '',
+    businessNumber: ''
+  })
+
+  // Helper function to check if filters have minimum required characters
+  function hasMinimumFilterCharacters (filters: { businessName: string, businessNumber: string }): boolean {
+    return filters.businessName.length >= 2 ||
+           filters.businessNumber.length >= 2 ||
path: business-registry-dashboard/app/stores/affiliations.ts
user: login: JazzarKarim
body: Yup, exactly. In my head, users will search NR or BC first right. So I thought 2 is good.

Sounds good to me about the name. I agree.
created_at: 2025-05-08T22:55:04Z
author_association: COLLABORATOR
diff_hunk: @@ -32,6 +32,21 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
     error: false
   })
 
+  // Track if filters changed during loading
+  const filtersChangedDuringLoading = ref(false)
+  // Store the latest filter values
+  const latestFilters = reactive({
+    businessName: '',
+    businessNumber: ''
+  })
+
+  // Helper function to check if filters have minimum required characters
+  function hasMinimumFilterCharacters (filters: { businessName: string, businessNumber: string }): boolean {
+    return filters.businessName.length >= 2 ||
+           filters.businessNumber.length >= 2 ||
path: business-registry-dashboard/app/stores/affiliations.ts
user: login: TVWerdal
body: Do you think there would ever be a case where someone was like "What was the name of that company again? It started with an A" and just put an A in and wonder why nothing happens? I mean I doubt there would be many people with enough businesses to run into that type of thing, but just speculating.
created_at: 2025-05-08T22:56:30Z
author_association: COLLABORATOR
diff_hunk: @@ -284,6 +299,24 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
       affiliations.error = true
     } finally {
       affiliations.loading = false
+
+      // Check if filters changed during loading and initiate a new search if needed
+      if (filtersChangedDuringLoading.value) {
path: business-registry-dashboard/app/stores/affiliations.ts
user: login: TVWerdal
body: This works really well. I kept trying to trip it up and I couldn't. Great job.
created_at: 2025-05-08T22:57:31Z
author_association: COLLABORATOR
diff_hunk: @@ -284,6 +299,24 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
       affiliations.error = true
     } finally {
       affiliations.loading = false
+
+      // Check if filters changed during loading and initiate a new search if needed
+      if (filtersChangedDuringLoading.value) {
path: business-registry-dashboard/app/stores/affiliations.ts
user: login: JazzarKarim
body: Awesome, appreciate you helping with the testing Thayne!
created_at: 2025-05-08T23:01:48Z
author_association: COLLABORATOR
diff_hunk: @@ -32,6 +32,21 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
     error: false
   })
 
+  // Track if filters changed during loading
+  const filtersChangedDuringLoading = ref(false)
+  // Store the latest filter values
+  const latestFilters = reactive({
+    businessName: '',
+    businessNumber: ''
+  })
+
+  // Helper function to check if filters have minimum required characters
+  function hasMinimumFilterCharacters (filters: { businessName: string, businessNumber: string }): boolean {
+    return filters.businessName.length >= 2 ||
+           filters.businessNumber.length >= 2 ||
path: business-registry-dashboard/app/stores/affiliations.ts
user: login: JazzarKarim
body: Really good point. Hmmm, I think you are correct. @severinbeauvais Sev, I'm tempted to remove the minimum requirements for the name as per what Thayne just said. Thoughts?
created_at: 2025-05-08T23:03:15Z
author_association: COLLABORATOR
diff_hunk: @@ -32,6 +32,21 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
     error: false
   })
 
+  // Track if filters changed during loading
+  const filtersChangedDuringLoading = ref(false)
+  // Store the latest filter values
+  const latestFilters = reactive({
+    businessName: '',
+    businessNumber: ''
+  })
+
+  // Helper function to check if filters have minimum required characters
+  function hasMinimumFilterCharacters (filters: { businessName: string, businessNumber: string }): boolean {
+    return filters.businessName.length >= 2 ||
+           filters.businessNumber.length >= 2 ||
path: business-registry-dashboard/app/stores/affiliations.ts
user: login: severinbeauvais
body: I think tough luck for them. This isn't Google. We have the 3-char limitation in other searches already.

For a tie-breaker, ask Jacqueline or Janis.
created_at: 2025-05-08T23:12:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -32,6 +32,21 @@ export const useAffiliationsStore = defineStore('brd-affiliations-store', () =>
     error: false
   })
 
+  // Track if filters changed during loading
+  const filtersChangedDuringLoading = ref(false)
+  // Store the latest filter values
+  const latestFilters = reactive({
+    businessName: '',
+    businessNumber: ''
+  })
+
+  // Helper function to check if filters have minimum required characters
+  function hasMinimumFilterCharacters (filters: { businessName: string, businessNumber: string }): boolean {
+    return filters.businessName.length >= 2 ||
+           filters.businessNumber.length >= 2 ||
path: business-registry-dashboard/app/stores/affiliations.ts
user: login: JazzarKarim
body: I'm merging this PR. Both of them are away and like you mentioned, we already have that 3-char limit. It's OK. 
created_at: 2025-05-09T17:12:48Z
author_association: COLLABORATOR

PR comments:
user: login: JazzarKarim
created_at: 2025-05-08T22:40:37Z
body: /gcbrun
author_association: COLLABORATOR
user: login: bcregistry-sre
created_at: 2025-05-08T22:44:13Z
body: Temporary Url for review: https://business-registry-dev--pr-122-an6zahr6.web.app
author_association: COLLABORATOR
user: login: severinbeauvais
created_at: 2025-05-08T22:52:19Z
body: > Sev, please if you can test the bug in the temp link, that would be great. Thanks.

Looks to be functioning well. I can't reproduce it!
author_association: CONTRIBUTOR
user: login: JazzarKarim
created_at: 2025-05-08T22:53:12Z
body: > > Sev, please if you can test the bug in the temp link, that would be great. Thanks.
> 
> Looks to be functioning well. I can't reproduce it!

Awesome, thank you!
author_association: COLLABORATOR
user: login: JazzarKarim
created_at: 2025-05-08T22:57:39Z
body: /gcbrun
author_association: COLLABORATOR
user: login: bcregistry-sre
created_at: 2025-05-08T23:01:29Z
body: Temporary Url for review: https://business-registry-dev--pr-122-an6zahr6.web.app
author_association: COLLABORATOR
user: login: JazzarKarim
created_at: 2025-05-09T19:00:01Z
body: /gcbrun
author_association: COLLABORATOR
user: login: bcregistry-sre
created_at: 2025-05-09T19:04:11Z
body: Temporary Url for review: https://business-registry-dev--pr-122-an6zahr6.web.app
author_association: COLLABORATOR