diff --git a/frontend/src/modules/activity/config/filters/main.ts b/frontend/src/modules/activity/config/filters/main.ts index 67dd7321fe..26bd3cc8e9 100644 --- a/frontend/src/modules/activity/config/filters/main.ts +++ b/frontend/src/modules/activity/config/filters/main.ts @@ -6,12 +6,14 @@ import date from './date/config'; import member from './member/config'; import platform from './platform/config'; import sentiment from './sentiment/config'; +import organizations from './organizations/config'; export const activityFilters: Record = { activityType, channel, date, member, + organizations, platform, sentiment, }; diff --git a/frontend/src/modules/activity/config/filters/organizations/config.ts b/frontend/src/modules/activity/config/filters/organizations/config.ts new file mode 100644 index 0000000000..6e60f1a9ea --- /dev/null +++ b/frontend/src/modules/activity/config/filters/organizations/config.ts @@ -0,0 +1,54 @@ +import { FilterConfigType } from '@/shared/modules/filters/types/FilterConfig'; +import { itemLabelRendererByType } from '@/shared/modules/filters/config/itemLabelRendererByType'; +import { + MultiSelectAsyncFilterConfig, + MultiSelectAsyncFilterOptions, MultiSelectAsyncFilterValue, +} from '@/shared/modules/filters/types/filterTypes/MultiSelectAsyncFilterConfig'; +import { OrganizationService } from '@/modules/organization/organization-service'; +import { DEFAULT_ORGANIZATION_FILTERS } from '@/modules/organization/store/constants'; + +const organizations: MultiSelectAsyncFilterConfig = { + id: 'organizations', + label: 'Organization', + iconClass: 'ri-community-line', + type: FilterConfigType.MULTISELECT_ASYNC, + options: { + remoteMethod: (query) => OrganizationService.listAutocomplete(query, 10) + .then((data: any[]) => data.map((organization) => ({ + label: organization.label, + value: organization.id, + logo: organization.logo, + }))), + remotePopulateItems: (ids: string[]) => OrganizationService.listAutocomplete({ + filter: { + and: [ + ...DEFAULT_ORGANIZATION_FILTERS, + { + id: { in: ids }, + }, + ], + }, + orderBy: null, + limit: ids.length, + offset: 0, + }) + .then(({ rows }: any) => rows.map((organization: any) => ({ + label: organization.displayName, + value: organization.id, + logo: organization.logo, + }))), + }, + itemLabelRenderer(value: MultiSelectAsyncFilterValue, options: MultiSelectAsyncFilterOptions, data: any): string { + return itemLabelRendererByType[FilterConfigType.MULTISELECT_ASYNC]('Organization', value, options, data); + }, + apiFilterRenderer({ value, include }: MultiSelectAsyncFilterValue): any[] { + const filter = { + organizationId: value, + }; + return [ + (include ? filter : { not: filter }), + ]; + }, +}; + +export default organizations; diff --git a/frontend/src/modules/member/config/filters/main.ts b/frontend/src/modules/member/config/filters/main.ts index 12a9704440..66be5ccf84 100644 --- a/frontend/src/modules/member/config/filters/main.ts +++ b/frontend/src/modules/member/config/filters/main.ts @@ -14,9 +14,11 @@ import reach from './reach/config'; import tags from './tags/config'; import memberName from './memberName/config'; import jobTitle from './jobTitle/config'; +import organizations from './organizations/config'; export const memberFilters: Record = { memberName, + organizations, noOfActivities, noOfOSSContributions, jobTitle, diff --git a/frontend/src/modules/member/config/filters/organizations/config.ts b/frontend/src/modules/member/config/filters/organizations/config.ts new file mode 100644 index 0000000000..f1379061f1 --- /dev/null +++ b/frontend/src/modules/member/config/filters/organizations/config.ts @@ -0,0 +1,54 @@ +import { FilterConfigType } from '@/shared/modules/filters/types/FilterConfig'; +import { itemLabelRendererByType } from '@/shared/modules/filters/config/itemLabelRendererByType'; +import { + MultiSelectAsyncFilterConfig, + MultiSelectAsyncFilterOptions, MultiSelectAsyncFilterValue, +} from '@/shared/modules/filters/types/filterTypes/MultiSelectAsyncFilterConfig'; +import { OrganizationService } from '@/modules/organization/organization-service'; +import { DEFAULT_ORGANIZATION_FILTERS } from '@/modules/organization/store/constants'; + +const organizations: MultiSelectAsyncFilterConfig = { + id: 'organizations', + label: 'Organization', + iconClass: 'ri-community-line', + type: FilterConfigType.MULTISELECT_ASYNC, + options: { + remoteMethod: (query) => OrganizationService.listAutocomplete(query, 10) + .then((data: any[]) => data.map((organization) => ({ + label: organization.label, + value: organization.id, + logo: organization.logo, + }))), + remotePopulateItems: (ids: string[]) => OrganizationService.listAutocomplete({ + filter: { + and: [ + ...DEFAULT_ORGANIZATION_FILTERS, + { + id: { in: ids }, + }, + ], + }, + orderBy: null, + limit: ids.length, + offset: 0, + }) + .then(({ rows }: any) => rows.map((organization: any) => ({ + label: organization.displayName, + value: organization.id, + logo: organization.logo, + }))), + }, + itemLabelRenderer(value: MultiSelectAsyncFilterValue, options: MultiSelectAsyncFilterOptions, data: any): string { + return itemLabelRendererByType[FilterConfigType.MULTISELECT_ASYNC]('Organization', value, options, data); + }, + apiFilterRenderer({ value, include }: MultiSelectAsyncFilterValue): any[] { + const filter = { + or: value.map((id) => ({ organizations: { eq: id } })), + }; + return [ + (include ? filter : { not: filter }), + ]; + }, +}; + +export default organizations; diff --git a/frontend/src/modules/organization/config/filters/main.ts b/frontend/src/modules/organization/config/filters/main.ts index 8467c3b732..42f726f0dd 100644 --- a/frontend/src/modules/organization/config/filters/main.ts +++ b/frontend/src/modules/organization/config/filters/main.ts @@ -17,8 +17,10 @@ import annualEmployeeGrowthRate from './annualEmployeeGrowthRate/config'; import employeeCount from './employeeCount/config'; import tags from './tags/config'; import type from './type/config'; +import organizations from './organizations/config'; export const organizationFilters: Record = { + organizations, noOfActivities, noOfMembers, activeOn, diff --git a/frontend/src/modules/organization/config/filters/organizations/config.ts b/frontend/src/modules/organization/config/filters/organizations/config.ts new file mode 100644 index 0000000000..aa59fa6b5e --- /dev/null +++ b/frontend/src/modules/organization/config/filters/organizations/config.ts @@ -0,0 +1,54 @@ +import { FilterConfigType } from '@/shared/modules/filters/types/FilterConfig'; +import { itemLabelRendererByType } from '@/shared/modules/filters/config/itemLabelRendererByType'; +import { + MultiSelectAsyncFilterConfig, + MultiSelectAsyncFilterOptions, MultiSelectAsyncFilterValue, +} from '@/shared/modules/filters/types/filterTypes/MultiSelectAsyncFilterConfig'; +import { OrganizationService } from '@/modules/organization/organization-service'; +import { DEFAULT_ORGANIZATION_FILTERS } from '@/modules/organization/store/constants'; + +const organizations: MultiSelectAsyncFilterConfig = { + id: 'organizations', + label: 'Organization', + iconClass: 'ri-community-line', + type: FilterConfigType.MULTISELECT_ASYNC, + options: { + remoteMethod: (query) => OrganizationService.listAutocomplete(query, 10) + .then((data: any[]) => data.map((organization) => ({ + label: organization.label, + value: organization.id, + logo: organization.logo, + }))), + remotePopulateItems: (ids: string[]) => OrganizationService.listAutocomplete({ + filter: { + and: [ + ...DEFAULT_ORGANIZATION_FILTERS, + { + id: { in: ids }, + }, + ], + }, + orderBy: null, + limit: ids.length, + offset: 0, + }) + .then(({ rows }: any) => rows.map((organization: any) => ({ + label: organization.displayName, + value: organization.id, + logo: organization.logo, + }))), + }, + itemLabelRenderer(value: MultiSelectAsyncFilterValue, options: MultiSelectAsyncFilterOptions, data: any): string { + return itemLabelRendererByType[FilterConfigType.MULTISELECT_ASYNC]('Organization', value, options, data); + }, + apiFilterRenderer({ value, include }: MultiSelectAsyncFilterValue): any[] { + const filter = { + or: value.map((id) => ({ id: { eq: id } })), + }; + return [ + (include ? filter : { not: filter }), + ]; + }, +}; + +export default organizations; diff --git a/frontend/src/shared/modules/filters/components/filterTypes/MultiSelectAsyncFilter.vue b/frontend/src/shared/modules/filters/components/filterTypes/MultiSelectAsyncFilter.vue index 30b5bf9347..d8fe876c65 100644 --- a/frontend/src/shared/modules/filters/components/filterTypes/MultiSelectAsyncFilter.vue +++ b/frontend/src/shared/modules/filters/components/filterTypes/MultiSelectAsyncFilter.vue @@ -26,13 +26,19 @@ :value="option" >
+ {{ option.label }} diff --git a/frontend/src/shared/modules/filters/types/filterTypes/MultiSelectAsyncFilterConfig.ts b/frontend/src/shared/modules/filters/types/filterTypes/MultiSelectAsyncFilterConfig.ts index d7b3be6a31..f1dc47919d 100644 --- a/frontend/src/shared/modules/filters/types/filterTypes/MultiSelectAsyncFilterConfig.ts +++ b/frontend/src/shared/modules/filters/types/filterTypes/MultiSelectAsyncFilterConfig.ts @@ -4,6 +4,7 @@ import { BaseFilterConfig, FilterConfigType } from '@/shared/modules/filters/typ export interface MultiSelectAsyncFilterOption { label: string; value: string; + logo?: string; } export interface MultiSelectAsyncFilterOptions { hideIncludeSwitch?: boolean;