From ad1521fd81aaa232ab5b73d86e6a7d2e3aeb7679 Mon Sep 17 00:00:00 2001 From: JimmFly <447268514@qq.com> Date: Wed, 24 Jan 2024 12:44:01 +0000 Subject: [PATCH] feat(core): adjust member order (#5685) close #5686 `Owner >> Unaccepted > Admin > Write > Read` This algorithm contains two parts: firstly, it calculates the weight of the Member (calculateWeight), and then, it uses set weights to sort the Members (useMembers). In the calculateWeight part, the computation of the weight involves three primary factors: 1. **Permission Level**: The `Owner` is given the highest weight of `4`, followed by `Admin` with a weight of `3`, then `Write` with a weight of `2`, and finally, `Read`, with a weight of `1`. 2. **Acceptance Status**: `Unaccepted` members have a higher weight, this weight is `1`. 3. The weight corresponding to the permission level, if the member does not exist, this weight is 0. These three `factors` are stored in the factors array and then processed through the reduce function for weighted sum calculation. Among them, `factor * Math.pow(10, arr.length - 1 - index)` means the more significant weight factors (i.e., the earlier factors) will be assigned a higher value. Sorting rules are primarily based on the weight values obtained from the calculateWeight function. If the weights are identical, it then sorts by name, here assuming the weight of the name being `null` is the highest. If the names are not `null`, they are sorted alphabetically. --- .../core/src/hooks/affine/use-members.ts | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/frontend/core/src/hooks/affine/use-members.ts b/packages/frontend/core/src/hooks/affine/use-members.ts index 0f6c78b57..af435dc48 100644 --- a/packages/frontend/core/src/hooks/affine/use-members.ts +++ b/packages/frontend/core/src/hooks/affine/use-members.ts @@ -1,10 +1,31 @@ import { type GetMembersByWorkspaceIdQuery, getMembersByWorkspaceIdQuery, + Permission, } from '@affine/graphql'; +import { useMemo } from 'react'; import { useQuery } from '../use-query'; +export function calculateWeight(member: Member) { + const permissionWeight = { + [Permission.Owner]: 4, + [Permission.Admin]: 3, + [Permission.Write]: 2, + [Permission.Read]: 1, + }; + + const factors = [ + Number(member.permission === Permission.Owner), // Owner weight is the highest + Number(!member.accepted), // Unaccepted members are before accepted members + permissionWeight[member.permission] || 0, + ]; + + return factors.reduce((ret, factor, index, arr) => { + return ret + factor * Math.pow(10, arr.length - 1 - index); + }, 0); +} + export type Member = Omit< GetMembersByWorkspaceIdQuery['workspace']['members'][number], '__typename' @@ -22,5 +43,20 @@ export function useMembers( take, }, }); - return data.workspace.members; + + const members = data.workspace.members; + + return useMemo(() => { + // sort members by weight + return members.sort((a, b) => { + const weightDifference = calculateWeight(b) - calculateWeight(a); + if (weightDifference !== 0) { + return weightDifference; + } + // if weight is the same, sort by name + if (a.name === null) return 1; + if (b.name === null) return -1; + return a.name.localeCompare(b.name); + }); + }, [members]); }