Skip to content

Commit

Permalink
Merge branch 'sort-by-enrollments' of 'https://github.com/evamillan/g…
Browse files Browse the repository at this point in the history
…rimoirelab-sortinghat'

Merges #943
Closes #943
Fixes #940
  • Loading branch information
sduenas authored Nov 21, 2024
2 parents 6720315 + 324cc5e commit f508600
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Sort organizations by number of enrollments
category: added
author: Eva Millán <[email protected]>
issue: 940
notes: >
Organizations are now sorted by the number of enrollments
they have by default. Clicking on a column header sorts the
table results by that field.
5 changes: 4 additions & 1 deletion sortinghat/core/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,7 @@ class SortingHatQuery:
page_size=graphene.Int(),
page=graphene.Int(),
filters=OrganizationFilterType(required=False),
order_by=graphene.String(required=False),
description='Find organizations.'
)
teams = graphene.Field(
Expand Down Expand Up @@ -1731,8 +1732,10 @@ def resolve_countries(self, info, filters=None,
def resolve_organizations(self, info, filters=None,
page=1,
page_size=settings.SORTINGHAT_API_PAGE_SIZE,
order_by='name',
**kwargs):
query = Organization.objects.all_organizations().order_by('name')
query = Organization.objects.all_organizations().annotate(enrollments_count=Count('enrollments')
).order_by(to_snake_case(order_by))

if filters and 'name' in filters:
query = query.distinct().filter(Q(name=filters['name']) | Q(aliases__alias=filters['name']))
Expand Down
68 changes: 68 additions & 0 deletions tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,16 @@
}
}
}"""
SH_ORGS_QUERY_ORDER_BY = """{
organizations (orderBy: "%s"){
entities {
name
enrollments {
id
}
}
}
}"""
SH_ORGS_QUERY_PAGINATION = """{
organizations (
page: %d
Expand Down Expand Up @@ -1843,6 +1853,64 @@ def test_filter_term(self):
orgs = executed['data']['organizations']['entities']
self.assertEqual(len(orgs), 0)

def test_order_by_enrollments(self):
"""Check whether it returns the organizations ordered by number of enrollments"""

indv1 = Individual.objects.create(mk='a9b403e150dd4af8953a52a4bb841051e4b705d9')
indv2 = Individual.objects.create(mk='0010a5211c03c46d340ada434b9f5b5072a8d491')
indv3 = Individual.objects.create(mk='86172d829d61adabde125d2442093213f745fbfd')

org1 = Organization.add_root(name='Example')
Enrollment.objects.create(individual=indv1, group=org1)
Enrollment.objects.create(individual=indv2, group=org1)
Enrollment.objects.create(individual=indv3, group=org1)

org2 = Organization.add_root(name='Bitergia')
Enrollment.objects.create(individual=indv1, group=org2)
Enrollment.objects.create(individual=indv2, group=org2)

org3 = Organization.add_root(name='LibreSoft')

# Test default order by name
client = graphene.test.Client(schema)
executed = client.execute(SH_ORGS_QUERY_ORDER_BY % 'name',
context_value=self.context_value)

orgs = executed['data']['organizations']['entities']

org = orgs[0]
self.assertEqual(org['name'], org2.name)
org = orgs[1]
self.assertEqual(org['name'], org1.name)
org = orgs[2]
self.assertEqual(org['name'], org3.name)

# Test ascending order
executed = client.execute(SH_ORGS_QUERY_ORDER_BY % 'enrollments_count',
context_value=self.context_value)

orgs = executed['data']['organizations']['entities']

org = orgs[0]
self.assertEqual(org['name'], org3.name)
org = orgs[1]
self.assertEqual(org['name'], org2.name)
org = orgs[2]
self.assertEqual(org['name'], org1.name)

# Test descending order
executed = client.execute(SH_ORGS_QUERY_ORDER_BY % '-enrollments_count',
context_value=self.context_value)

orgs = executed['data']['organizations']['entities']

org = orgs[0]
self.assertEqual(org['name'], org1.name)
org = orgs[1]
self.assertEqual(org['name'], org2.name)
org = orgs[2]
self.assertEqual(org['name'], org3.name)

def test_pagination(self):
"""Check whether it returns the organizations searched when using pagination"""

Expand Down
17 changes: 15 additions & 2 deletions ui/src/apollo/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,14 @@ const GET_PAGINATED_ORGANIZATIONS = gql`
$page: Int!
$pageSize: Int!
$filters: OrganizationFilterType
$orderBy: String
) {
organizations(page: $page, pageSize: $pageSize, filters: $filters) {
organizations(
page: $page
pageSize: $pageSize
filters: $filters
orderBy: $orderBy
) {
entities {
id
name
Expand Down Expand Up @@ -364,13 +370,20 @@ const getProfileByUuid = (apollo, uuid) => {
return response;
};

const getPaginatedOrganizations = (apollo, currentPage, pageSize, filters) => {
const getPaginatedOrganizations = (
apollo,
currentPage,
pageSize,
filters,
orderBy
) => {
let response = apollo.query({
query: GET_PAGINATED_ORGANIZATIONS,
variables: {
page: currentPage,
pageSize: pageSize,
filters: filters,
orderBy: orderBy,
},
fetchPolicy: "no-cache",
});
Expand Down
32 changes: 27 additions & 5 deletions ui/src/components/OrganizationsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
hover
return-object
@update:expanded="($event) => (expandedItems = $event)"
@update:sortBy="sortItems($event)"
>
<template v-slot:item="{ item, internalItem, toggleExpand, isExpanded }">
<organization-entry
Expand Down Expand Up @@ -241,12 +242,12 @@ export default {
data() {
return {
headers: [
{ value: "name", title: "Name", sortable: false },
{ value: "name", title: "Name", sortable: true },
{
value: "enrollments",
value: "enrollments_count",
title: "Enrollments",
align: "end",
sortable: false,
sortable: true,
},
{ value: "actions", sortable: false },
],
Expand Down Expand Up @@ -278,17 +279,27 @@ export default {
},
loading: false,
error: null,
sortBy: "-enrollments_count",
};
},
created() {
this.getTableItems(1);
},
methods: {
async getTableItems(page = this.page, filters = this.filters) {
async getTableItems(
page = this.page,
filters = this.filters,
sortBy = this.sortBy
) {
this.loading = true;
this.error = null;
try {
let response = await this.fetchPage(page, this.itemsPerPage, filters);
let response = await this.fetchPage(
page,
this.itemsPerPage,
filters,
sortBy
);
if (response) {
this.items = response.entities;
this.pageCount = response.pageInfo.numPages;
Expand Down Expand Up @@ -528,6 +539,17 @@ export default {
this.$logger.error(`Error merging ${fromOrg} with ${toOrg}: ${error}`);
}
},
sortItems(options) {
if (options[0]) {
const key = options[0].key;
const order = options[0].order === "asc" ? "-" : "";
this.sortBy = `${order}${key}`;
} else {
this.sortBy = "-enrollments_count";
}
this.getTableItems();
},
},
};
</script>
Expand Down
5 changes: 3 additions & 2 deletions ui/src/views/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,13 @@ export default {
);
return response;
},
async getOrganizationsPage(page, items, filters) {
async getOrganizationsPage(page, items, filters, orderBy) {
const response = await getPaginatedOrganizations(
this.$apollo,
page,
items,
filters
filters,
orderBy
);
return response.data.organizations;
},
Expand Down
42 changes: 30 additions & 12 deletions ui/tests/unit/__snapshots__/storybook.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -29779,7 +29779,7 @@ exports[`Storybook Tests OrganizationsTable Groups 1`] = `
<tr>

<th
class="v-data-table__td v-data-table-column--align-start v-data-table__th"
class="v-data-table__td v-data-table-column--align-start v-data-table__th v-data-table__th--sortable"
colspan="1"
rowspan="1"
>
Expand All @@ -29790,13 +29790,16 @@ exports[`Storybook Tests OrganizationsTable Groups 1`] = `
<span>
Name
</span>
<!---->
<i
aria-hidden="true"
class="mdi-arrow-up mdi v-icon notranslate v-theme--light v-icon--size-default v-data-table-header__sort-icon"
/>
<!---->
</div>

</th>
<th
class="v-data-table__td v-data-table-column--align-end v-data-table__th"
class="v-data-table__td v-data-table-column--align-end v-data-table__th v-data-table__th--sortable"
colspan="1"
rowspan="1"
>
Expand All @@ -29807,7 +29810,10 @@ exports[`Storybook Tests OrganizationsTable Groups 1`] = `
<span>
Enrollments
</span>
<!---->
<i
aria-hidden="true"
class="mdi-arrow-up mdi v-icon notranslate v-theme--light v-icon--size-default v-data-table-header__sort-icon"
/>
<!---->
</div>

Expand Down Expand Up @@ -30769,7 +30775,7 @@ exports[`Storybook Tests OrganizationsTable OnError 1`] = `
<tr>

<th
class="v-data-table__td v-data-table-column--align-start v-data-table__th"
class="v-data-table__td v-data-table-column--align-start v-data-table__th v-data-table__th--sortable"
colspan="1"
rowspan="1"
>
Expand All @@ -30780,13 +30786,16 @@ exports[`Storybook Tests OrganizationsTable OnError 1`] = `
<span>
Name
</span>
<!---->
<i
aria-hidden="true"
class="mdi-arrow-up mdi v-icon notranslate v-theme--light v-icon--size-default v-data-table-header__sort-icon"
/>
<!---->
</div>

</th>
<th
class="v-data-table__td v-data-table-column--align-end v-data-table__th"
class="v-data-table__td v-data-table-column--align-end v-data-table__th v-data-table__th--sortable"
colspan="1"
rowspan="1"
>
Expand All @@ -30797,7 +30806,10 @@ exports[`Storybook Tests OrganizationsTable OnError 1`] = `
<span>
Enrollments
</span>
<!---->
<i
aria-hidden="true"
class="mdi-arrow-up mdi v-icon notranslate v-theme--light v-icon--size-default v-data-table-header__sort-icon"
/>
<!---->
</div>

Expand Down Expand Up @@ -31362,7 +31374,7 @@ exports[`Storybook Tests OrganizationsTable Organizations 1`] = `
<tr>

<th
class="v-data-table__td v-data-table-column--align-start v-data-table__th"
class="v-data-table__td v-data-table-column--align-start v-data-table__th v-data-table__th--sortable"
colspan="1"
rowspan="1"
>
Expand All @@ -31373,13 +31385,16 @@ exports[`Storybook Tests OrganizationsTable Organizations 1`] = `
<span>
Name
</span>
<!---->
<i
aria-hidden="true"
class="mdi-arrow-up mdi v-icon notranslate v-theme--light v-icon--size-default v-data-table-header__sort-icon"
/>
<!---->
</div>

</th>
<th
class="v-data-table__td v-data-table-column--align-end v-data-table__th"
class="v-data-table__td v-data-table-column--align-end v-data-table__th v-data-table__th--sortable"
colspan="1"
rowspan="1"
>
Expand All @@ -31390,7 +31405,10 @@ exports[`Storybook Tests OrganizationsTable Organizations 1`] = `
<span>
Enrollments
</span>
<!---->
<i
aria-hidden="true"
class="mdi-arrow-up mdi v-icon notranslate v-theme--light v-icon--size-default v-data-table-header__sort-icon"
/>
<!---->
</div>

Expand Down
2 changes: 1 addition & 1 deletion ui/tests/unit/queries.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ describe("OrganizationsTable", () => {
},
});

expect(query).toHaveBeenCalledWith(1, 10, { term: "Bitergia" });
expect(query).toHaveBeenCalledWith(1, 10, { term: "Bitergia" }, "-enrollments_count");
});
});

Expand Down

0 comments on commit f508600

Please sign in to comment.