Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sortMembersBy #6098

Merged
merged 2 commits into from
Jan 20, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Change Log
* Add missing default Legend to `TableAutomaticStylesStratum.defaultStyle`
* Fix a bug in CompositeCatalogItem that causes share URLs to become extremely long.
* Fix `OpacitySection` number precision.
* Add `sortMembersBy` to `GroupTraits`. This can be set to sort group member models - For example `sortMembersBy = "name"` will alphabetically sort members by name.
* [The next improvement]

#### 8.1.17
Expand Down
31 changes: 30 additions & 1 deletion lib/ModelMixins/GroupMixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import AsyncLoader from "../Core/AsyncLoader";
import Constructor from "../Core/Constructor";
import filterOutUndefined from "../Core/filterOutUndefined";
import isDefined from "../Core/isDefined";
import { isJsonNumber, isJsonString } from "../Core/Json";
import Result from "../Core/Result";
import Group from "../Models/Catalog/Group";
import hasTraits from "../Models/Definition/hasTraits";
import Model, { BaseModel } from "../Models/Definition/Model";
import ModelReference from "../Traits/ModelReference";
import GroupTraits from "../Traits/TraitsClasses/GroupTraits";
import CatalogMemberMixin, { getName } from "./CatalogMemberMixin";

const naturalSort = require("javascript-natural-sort");
naturalSort.insensitive = true;

function GroupMixin<T extends Constructor<Model<GroupTraits>>>(Base: T) {
abstract class Klass extends Base implements Group {
private _memberLoader = new AsyncLoader(this.forceLoadMembers.bind(this));
Expand Down Expand Up @@ -51,7 +56,7 @@ function GroupMixin<T extends Constructor<Model<GroupTraits>>>(Base: T) {
if (members === undefined) {
return [];
}
return filterOutUndefined(
const models = filterOutUndefined(
members.map(id => {
if (!ModelReference.isRemoved(id)) {
const model = this.terria.getModelById(BaseModel, id);
Expand Down Expand Up @@ -82,6 +87,30 @@ function GroupMixin<T extends Constructor<Model<GroupTraits>>>(Base: T) {
}
})
);

// Sort members if necessary
// Check if trait "this.sortMembersBy" exists and is a string or number
// If not, then the model will be placed at the end of the array
if (isDefined(this.sortMembersBy)) {
return models.sort((a, b) => {
const aValue =
CatalogMemberMixin.isMixedInto(a) &&
hasTraits(a, a.TraitsClass, this.sortMembersBy as any)
? a[this.sortMembersBy!]
: Infinity;
const bValue =
CatalogMemberMixin.isMixedInto(b) &&
hasTraits(b, b.TraitsClass, this.sortMembersBy as any)
? b[this.sortMembersBy!]
: Infinity;
return naturalSort(
isJsonString(aValue) || isJsonNumber(aValue) ? aValue : Infinity,
isJsonString(bValue) || isJsonNumber(bValue) ? bValue : Infinity
);
});
}

return models;
}

/**
Expand Down
14 changes: 11 additions & 3 deletions lib/Traits/TraitsClasses/GroupTraits.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import CatalogMemberFactory from "../../Models/Catalog/CatalogMemberFactory";
import ModelReference from "../ModelReference";
import modelReferenceArrayTrait from "../Decorators/modelReferenceArrayTrait";
import ModelTraits from "../ModelTraits";
import primitiveTrait from "../Decorators/primitiveTrait";
import primitiveArrayTrait from "../Decorators/primitiveArrayTrait";
import primitiveTrait from "../Decorators/primitiveTrait";
import ModelReference from "../ModelReference";
import ModelTraits from "../ModelTraits";

export default class GroupTraits extends ModelTraits {
@primitiveArrayTrait({
Expand All @@ -21,6 +21,14 @@ export default class GroupTraits extends ModelTraits {
})
isOpen: boolean = false;

@primitiveTrait({
name: "Sort members by",
description:
"Sort members by this property/trait. For example `name`, will sort all members by alphabetically",
type: "string"
})
sortMembersBy: string | undefined;

@modelReferenceArrayTrait({
name: "Members",
description: "The members of this group.",
Expand Down
69 changes: 64 additions & 5 deletions test/Models/Catalog/CatalogGroupSpec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import CatalogMemberMixin from "../../../lib/ModelMixins/CatalogMemberMixin";
import CatalogGroup from "../../../lib/Models/Catalog/CatalogGroup";
import GeoJsonCatalogItem from "../../../lib/Models/Catalog/CatalogItems/GeoJsonCatalogItem";
import BaseModel from "../../../lib/Models/Catalog/CatalogItems/GeoJsonCatalogItem";
import Terria from "../../../lib/Models/Terria";
import upsertModelFromJson from "../../../lib/Models/Definition/upsertModelFromJson";
import CatalogMemberFactory from "../../../lib/Models/Catalog/CatalogMemberFactory";
import CommonStrata from "../../../lib/Models/Definition/CommonStrata";
import StubCatalogItem from "../../../lib/Models/Catalog/CatalogItems/StubCatalogItem";
import CatalogMemberFactory from "../../../lib/Models/Catalog/CatalogMemberFactory";
import { getUniqueStubName } from "../../../lib/Models/Catalog/createStubCatalogItem";
import CommonStrata from "../../../lib/Models/Definition/CommonStrata";
import upsertModelFromJson from "../../../lib/Models/Definition/upsertModelFromJson";
import Terria from "../../../lib/Models/Terria";

describe("CatalogGroup", function() {
let terria: Terria, json: any, catalogGroup: CatalogGroup;
Expand Down Expand Up @@ -243,4 +243,63 @@ describe("CatalogGroup", function() {
"parent3"
]);
});

it("sortMembersBy", function() {
const item = new CatalogGroup("what", terria);

item.addMembersFromJson(CommonStrata.definition, [
{
type: "group",
name: "1",
description: "f"
},
{
type: "group",
name: "aCC"
},
{
type: "group",
name: "10",
description: "d"
},
{
type: "group",
name: "2",
description: "c"
},
{
type: "group",
name: "AC",
description: "a"
},

{
type: "group",
name: "ab",
description: "b"
}
]);

expect(
item.memberModels.map(member =>
CatalogMemberMixin.isMixedInto(member) ? member.name : ""
)
).toEqual(["1", "aCC", "10", "2", "AC", "ab"]);

item.setTrait(CommonStrata.user, "sortMembersBy", "name");

expect(
item.memberModels.map(member =>
CatalogMemberMixin.isMixedInto(member) ? member.name : ""
)
).toEqual(["1", "2", "10", "ab", "AC", "aCC"]);

item.setTrait(CommonStrata.user, "sortMembersBy", "description");

expect(
item.memberModels.map(member =>
CatalogMemberMixin.isMixedInto(member) ? member.name : ""
)
).toEqual(["AC", "ab", "2", "10", "1", "aCC"]);
});
});