From 7d0c78fb256ffcc2ae048439dabfb4c218f41d2d Mon Sep 17 00:00:00 2001 From: RuthShryock <81720958+RuthShryock@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:15:37 -0600 Subject: [PATCH] feat(organizations): update owner filtering on projects table TASK-1335 (#5362) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### 📣 Summary Enable filtering by both the organization name and the owner's name when selecting 'Owner' as a filter on the projects table. ## 💭 Notes Known issues (Olivier's notes from Notion task) Because we are searching on both field at the same time (it would be too difficult to do conditional search on whether the organization is MMO). Returned results could be false positive. Example: Tino sees two projects on in “My Project” list - Project 1 owns by olivierleger the user - Project 2 owns by jnm the user, but filled out the registration form with “leger inc” as his the organization. If Tino searches for “owner” which should contain “leger”, both projects will appear, even if Project 2 shows “jnm” as the owner. ### 👀 Preview steps Feature/no-change template: 1. ℹ️ have account (someuser) and several projects 2. have user (kobouser) with organization name (Some Org) share a project with your account 3. have user (anotheruser) who is part of an MMO (Kobo Inc) share a project with your account 4. 🟡 notice that projects by **_someuser_** and **_kobouser_** have the owner name as the owner label, but projects by **_anotheruser_** have **_Kobo Inc_** as the owner label (not part of this pr but important) 5. ➡️ filter by "Owner" contains "user" 6. 🟢 notice that all projects are shown 7. ➡️ filter by "Owner" contains "kobo" 8. 🟢 notice that projects from **_kobouser_** and **_Kobo Inc_** are shown 9. ➡️ filter by "Owner" contains "some" 10. 🟢 notice that projects from **_someuser_** and **_kobouser_** are shown. (Even though **_kobouser_** is shown as the owner name, we are filtering by the organization name as well, more on false positive in Notes above). --------- Co-authored-by: Olivier Leger --- jsapp/js/projects/projectViews/constants.ts | 4 ++-- jsapp/js/projects/projectViews/utils.tests.ts | 22 ++++++++++++++----- jsapp/js/projects/projectViews/utils.ts | 11 ++++++++++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/jsapp/js/projects/projectViews/constants.ts b/jsapp/js/projects/projectViews/constants.ts index ccd515ddc2..a5935d99d3 100644 --- a/jsapp/js/projects/projectViews/constants.ts +++ b/jsapp/js/projects/projectViews/constants.ts @@ -180,8 +180,8 @@ export const PROJECT_FIELDS: ProjectFields = { ownerUsername: { name: 'ownerUsername', label: t('Owner'), - apiFilteringName: 'owner__username', - apiOrderingName: 'owner__username', + apiFilteringName: 'search_field', + apiOrderingName: 'search_field', availableConditions: [ 'contains', 'doesNotContain', diff --git a/jsapp/js/projects/projectViews/utils.tests.ts b/jsapp/js/projects/projectViews/utils.tests.ts index a65b0fa01f..44dd38707f 100644 --- a/jsapp/js/projects/projectViews/utils.tests.ts +++ b/jsapp/js/projects/projectViews/utils.tests.ts @@ -71,12 +71,22 @@ describe('projectViewsUtils', () => { out: 'settings__description__istartswith:"foo"', }, { - in: { - fieldName: 'ownerUsername', - condition: 'doesNotContain', - value: 'foo', - }, - out: 'NOT owner__username__icontains:"foo"', + in: {fieldName: 'ownerUsername', condition: 'contains', value: 'foo'}, + out: + '(search_field__owner_username__icontains:"foo" ' + + 'OR search_field__organization_name__icontains:"foo")', + }, + { + in: {fieldName: 'ownerUsername', condition: 'is', value: 'foo'}, + out: + '(search_field__owner_username__iexact:"foo" ' + + 'OR search_field__organization_name__iexact:"foo")', + }, + { + in: {fieldName: 'ownerUsername', condition: 'doesNotContain', value: 'foo'}, + out: + '(NOT search_field__owner_username__icontains:"foo" ' + + 'OR NOT search_field__organization_name__icontains:"foo")', }, { in: {fieldName: 'ownerFullName', condition: 'endsWith', value: 'foo'}, diff --git a/jsapp/js/projects/projectViews/utils.ts b/jsapp/js/projects/projectViews/utils.ts index 2ba8cc9ddd..81fcd0ce01 100644 --- a/jsapp/js/projects/projectViews/utils.ts +++ b/jsapp/js/projects/projectViews/utils.ts @@ -69,6 +69,17 @@ export function buildQueriesFromFilters(filters: ProjectsFilterDefinition[]) { const fieldDefinition = PROJECT_FIELDS[filter.fieldName]; const conditionDefinition = FILTER_CONDITIONS[filter.condition]; + // Filtering by `ownerUsername` should filter on both the owner and organization name + if (filter.fieldName === 'ownerUsername') { + const ownerNameQuery = conditionDefinition.filterQuery + .replace('', 'search_field__owner_username') + .replace('', `"${filter.value}"`); + const orgNameQuery = conditionDefinition.filterQuery + .replace('', 'search_field__organization_name') + .replace('', `"${filter.value}"`); + return `(${ownerNameQuery} OR ${orgNameQuery})`; + } + if (conditionDefinition.requiresValue && filter.value) { return ( conditionDefinition.filterQuery