fix(usage): sort deleted filter options to the bottom of every dropdown
Deleted users / models / API keys / instances / volumes now sink below the live entries in each usage tab's filter, while the current account stays on top and live entries keep their order (stable sort).
This commit is contained in:
@@ -26,11 +26,16 @@ const EMPTY: ResourceMetaOptions = {
|
|||||||
volumes: []
|
volumes: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Deleted entries sink to the bottom of the dropdown; live ones keep their
|
||||||
|
// incoming order (sort is stable).
|
||||||
const toOptions = (items: ResourceFilterOption[]): SelectOption[] =>
|
const toOptions = (items: ResourceFilterOption[]): SelectOption[] =>
|
||||||
items.map((i) => ({ value: i.id, label: i.label, deleted: i.deleted }));
|
items
|
||||||
|
.map((i) => ({ value: i.id, label: i.label, deleted: i.deleted }))
|
||||||
|
.sort((a, b) => Number(!!a.deleted) - Number(!!b.deleted));
|
||||||
|
|
||||||
// Tag the signed-in user's own entry and sort it first, matching the Tokens
|
// Tag the signed-in user's own entry. Ordering: current account first, deleted
|
||||||
// tab's "[Current Account]" treatment.
|
// entries last, everything else keeps its incoming order — matching the Tokens
|
||||||
|
// tab's "[Current Account]" treatment while pushing stale rows out of the way.
|
||||||
const toUserOptions = (
|
const toUserOptions = (
|
||||||
items: ResourceFilterOption[],
|
items: ResourceFilterOption[],
|
||||||
currentUserId?: number
|
currentUserId?: number
|
||||||
@@ -41,12 +46,8 @@ const toUserOptions = (
|
|||||||
deleted: i.deleted,
|
deleted: i.deleted,
|
||||||
isCurrent: currentUserId != null && i.id === currentUserId
|
isCurrent: currentUserId != null && i.id === currentUserId
|
||||||
}));
|
}));
|
||||||
if (currentUserId == null) return options;
|
const rank = (o: SelectOption) => (o.isCurrent ? 0 : o.deleted ? 2 : 1);
|
||||||
return options.sort((a, b) => {
|
return options.sort((a, b) => rank(a) - rank(b));
|
||||||
if (a.isCurrent) return -1;
|
|
||||||
if (b.isCurrent) return 1;
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -40,18 +40,17 @@ export default function useQueryUsageMetaData() {
|
|||||||
routes: []
|
routes: []
|
||||||
});
|
});
|
||||||
|
|
||||||
// the current user sort in the first place
|
// Current account first, deleted entries last, everything else keeps its
|
||||||
|
// incoming order (sort is stable).
|
||||||
const sortUsers = (users: UsageFilterItem[]) => {
|
const sortUsers = (users: UsageFilterItem[]) => {
|
||||||
const currentUserId = initialState?.currentUser?.id;
|
const currentUserId = initialState?.currentUser?.id;
|
||||||
if (!currentUserId) return users;
|
const rank = (u: UsageFilterItem) =>
|
||||||
|
currentUserId && u.identity.current?.user_id === currentUserId
|
||||||
const sortedUsers = [...users].sort((a, b) => {
|
? 0
|
||||||
if (a.identity.current?.user_id === currentUserId) return -1;
|
: u.deleted
|
||||||
if (b.identity.current?.user_id === currentUserId) return 1;
|
? 2
|
||||||
return 0;
|
: 1;
|
||||||
});
|
return [...users].sort((a, b) => rank(a) - rank(b));
|
||||||
|
|
||||||
return sortedUsers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const queryMetaData = async () => {
|
const queryMetaData = async () => {
|
||||||
@@ -74,12 +73,21 @@ export default function useQueryUsageMetaData() {
|
|||||||
value: optionValue(item.identity.current?.api_key_id, index),
|
value: optionValue(item.identity.current?.api_key_id, index),
|
||||||
label: item.identity.value.api_key_name || ''
|
label: item.identity.value.api_key_name || ''
|
||||||
})
|
})
|
||||||
}),
|
// Deleted keys sink to the bottom within each user group.
|
||||||
|
}).map((group) => ({
|
||||||
|
...group,
|
||||||
|
children: [...group.children].sort(
|
||||||
|
(a, b) => Number(!!(a as any).deleted) - Number(!!(b as any).deleted)
|
||||||
|
)
|
||||||
|
})),
|
||||||
|
// Deleted models sink to the bottom of the dropdown.
|
||||||
routes:
|
routes:
|
||||||
(res?.filters?.routes || []).map((item, index) => ({
|
(res?.filters?.routes || [])
|
||||||
...item,
|
.map((item, index) => ({
|
||||||
value: optionValue(item.identity.current?.route_id, index)
|
...item,
|
||||||
})) || []
|
value: optionValue(item.identity.current?.route_id, index)
|
||||||
|
}))
|
||||||
|
.sort((a, b) => Number(!!a.deleted) - Number(!!b.deleted)) || []
|
||||||
};
|
};
|
||||||
setResult(data);
|
setResult(data);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -271,13 +271,11 @@ const SummaryTab: React.FC = () => {
|
|||||||
isCurrent: currentUserId != null && id === currentUserId
|
isCurrent: currentUserId != null && id === currentUserId
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// Sort the signed-in user first, tagged "[Current Account]" (matches the
|
// Signed-in user first (tagged "[Current Account]", matches the Tokens
|
||||||
// Tokens tab), regardless of which source it came from.
|
// tab), deleted entries last, everything else keeps its order — regardless
|
||||||
return Array.from(map.values()).sort((a, b) => {
|
// of which source it came from.
|
||||||
if (a.isCurrent) return -1;
|
const rank = (o: SelectOption) => (o.isCurrent ? 0 : o.deleted ? 2 : 1);
|
||||||
if (b.isCurrent) return 1;
|
return Array.from(map.values()).sort((a, b) => rank(a) - rank(b));
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
}, [resourceUsers, tokenMeta, currentUserId]);
|
}, [resourceUsers, tokenMeta, currentUserId]);
|
||||||
|
|
||||||
// user id → the identity object the token series filters by. Built from the
|
// user id → the identity object the token series filters by. Built from the
|
||||||
|
|||||||
Reference in New Issue
Block a user