feat(pokemon): remove manual sorting and enforce ID-based order
Remove pokemon.order permission and related API endpoints Update queries to sort Pokemon by internal ID ascending Replace reorderable list with standard list in Admin view
This commit is contained in:
@@ -231,7 +231,6 @@ VALUES
|
||||
('pokemon.create', 'Create Pokemon', 'Create Pokemon records.', 'Pokemon', true),
|
||||
('pokemon.update', 'Update Pokemon', 'Edit Pokemon records.', 'Pokemon', true),
|
||||
('pokemon.delete', 'Delete Pokemon', 'Delete Pokemon records.', 'Pokemon', true),
|
||||
('pokemon.order', 'Order Pokemon', 'Reorder Pokemon records.', 'Pokemon', true),
|
||||
('pokemon.fetch', 'Fetch Pokemon data', 'Fetch Pokemon data and sprite candidates.', 'Pokemon', true),
|
||||
('pokemon.upload', 'Upload Pokemon images', 'Upload Pokemon images.', 'Pokemon', true),
|
||||
('habitats.create', 'Create habitats', 'Create habitat records.', 'Habitats', true),
|
||||
@@ -275,6 +274,9 @@ VALUES
|
||||
('discussions.comments.like', 'Like discussion comments', 'Like and unlike entity discussion comments.', 'Discussions', true)
|
||||
ON CONFLICT (key) DO NOTHING;
|
||||
|
||||
DELETE FROM permissions
|
||||
WHERE key = 'pokemon.order';
|
||||
|
||||
INSERT INTO roles (key, name, description, level, enabled, system_role)
|
||||
VALUES
|
||||
('owner', 'Owner', 'Highest-level system owner with all permissions.', 1000, true, true),
|
||||
@@ -329,7 +331,6 @@ JOIN permissions p ON p.key = ANY (ARRAY[
|
||||
'pokemon.create',
|
||||
'pokemon.update',
|
||||
'pokemon.delete',
|
||||
'pokemon.order',
|
||||
'pokemon.fetch',
|
||||
'pokemon.upload',
|
||||
'habitats.create',
|
||||
@@ -411,7 +412,6 @@ JOIN permissions p ON p.key = ANY (ARRAY[
|
||||
'checklist.order',
|
||||
'pokemon.create',
|
||||
'pokemon.update',
|
||||
'pokemon.order',
|
||||
'pokemon.fetch',
|
||||
'pokemon.upload',
|
||||
'habitats.create',
|
||||
|
||||
@@ -108,7 +108,7 @@ type ConfigDefinition = {
|
||||
hasRateable?: boolean;
|
||||
hasChangeLog?: boolean;
|
||||
};
|
||||
type SortableContentType = 'pokemon' | 'items' | 'ancient-artifacts' | 'recipes' | 'habitats';
|
||||
type SortableContentType = 'items' | 'ancient-artifacts' | 'recipes' | 'habitats';
|
||||
type SortableContentDefinition = {
|
||||
table: string;
|
||||
entityType: SortableContentType;
|
||||
@@ -691,7 +691,6 @@ const configDefinitions: Record<ConfigType, ConfigDefinition> = {
|
||||
};
|
||||
|
||||
const sortableContentDefinitions: Record<SortableContentType, SortableContentDefinition> = {
|
||||
pokemon: { table: 'pokemon', entityType: 'pokemon' },
|
||||
items: { table: 'items', entityType: 'items' },
|
||||
'ancient-artifacts': { table: 'items', entityType: 'ancient-artifacts' },
|
||||
recipes: { table: 'recipes', entityType: 'recipes' },
|
||||
@@ -2809,7 +2808,7 @@ export async function globalSearch(paramsQuery: QueryParams = {}, locale = defau
|
||||
${pokemonImageJson('p')} AS image
|
||||
FROM pokemon p
|
||||
WHERE ${pokemonName} ILIKE $1
|
||||
ORDER BY ${orderByEntity('p')}
|
||||
ORDER BY p.id
|
||||
LIMIT $2
|
||||
`,
|
||||
[pattern, limit]
|
||||
@@ -5746,11 +5745,6 @@ async function reorderContent(type: SortableContentType, payload: Record<string,
|
||||
});
|
||||
}
|
||||
|
||||
export async function reorderPokemon(payload: Record<string, unknown>, userId: number, locale = defaultLocale) {
|
||||
await reorderContent('pokemon', payload, userId);
|
||||
return listPokemon({}, locale);
|
||||
}
|
||||
|
||||
export async function reorderItems(payload: Record<string, unknown>, userId: number, locale = defaultLocale) {
|
||||
await reorderContent('items', payload, userId);
|
||||
return listItems({}, locale);
|
||||
@@ -5822,7 +5816,7 @@ export async function listPokemon(paramsQuery: QueryParams, locale = defaultLoca
|
||||
}
|
||||
|
||||
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
||||
return queryMaybePaged(`${pokemonProjection(locale)} ${whereClause} ORDER BY ${orderByEntity('p')}`, params, paramsQuery);
|
||||
return queryMaybePaged(`${pokemonProjection(locale)} ${whereClause} ORDER BY p.id`, params, paramsQuery);
|
||||
}
|
||||
|
||||
export async function getPokemon(id: number, locale = defaultLocale) {
|
||||
@@ -5927,7 +5921,6 @@ export async function getPokemon(id: number, locale = defaultLocale) {
|
||||
scored_pokemon AS (
|
||||
SELECT
|
||||
related_pokemon.id,
|
||||
related_pokemon.sort_order,
|
||||
(related_pokemon.environment_id = current_pokemon.environment_id) AS "environmentMatches",
|
||||
COUNT(current_favourites.favorite_thing_id)::integer AS "favoriteThingMatchCount"
|
||||
FROM current_pokemon
|
||||
@@ -5936,7 +5929,7 @@ export async function getPokemon(id: number, locale = defaultLocale) {
|
||||
ON related_pokemon_favourite.pokemon_id = related_pokemon.id
|
||||
LEFT JOIN current_favourites
|
||||
ON current_favourites.favorite_thing_id = related_pokemon_favourite.favorite_thing_id
|
||||
GROUP BY related_pokemon.id, related_pokemon.sort_order, related_pokemon.environment_id, current_pokemon.environment_id
|
||||
GROUP BY related_pokemon.id, related_pokemon.environment_id, current_pokemon.environment_id
|
||||
HAVING related_pokemon.environment_id = current_pokemon.environment_id
|
||||
OR COUNT(current_favourites.favorite_thing_id) > 0
|
||||
)
|
||||
@@ -5981,7 +5974,7 @@ export async function getPokemon(id: number, locale = defaultLocale) {
|
||||
FROM scored_pokemon
|
||||
JOIN pokemon related_pokemon ON related_pokemon.id = scored_pokemon.id
|
||||
JOIN environments related_environment ON related_environment.id = related_pokemon.environment_id
|
||||
ORDER BY scored_pokemon."environmentMatches" DESC, scored_pokemon."favoriteThingMatchCount" DESC, scored_pokemon.sort_order, related_pokemon.id
|
||||
ORDER BY scored_pokemon."environmentMatches" DESC, scored_pokemon."favoriteThingMatchCount" DESC, related_pokemon.id
|
||||
`,
|
||||
[id]
|
||||
),
|
||||
@@ -6369,10 +6362,10 @@ export async function listHabitats(paramsQuery: QueryParams = {}, locale = defau
|
||||
'name', pokemon_rows.name,
|
||||
'isEventItem', pokemon_rows.is_event_item
|
||||
)
|
||||
ORDER BY pokemon_rows.sort_order, pokemon_rows.id
|
||||
ORDER BY pokemon_rows.id
|
||||
)
|
||||
FROM (
|
||||
SELECT DISTINCT p.id, p.display_id, ${pokemonName} AS name, p.is_event_item, p.sort_order
|
||||
SELECT DISTINCT p.id, p.display_id, ${pokemonName} AS name, p.is_event_item
|
||||
FROM habitat_pokemon hp
|
||||
JOIN pokemon p ON p.id = hp.pokemon_id
|
||||
WHERE hp.habitat_id = h.id
|
||||
@@ -6443,7 +6436,7 @@ export async function getHabitat(id: number, locale = defaultLocale) {
|
||||
JOIN pokemon p ON p.id = hp.pokemon_id
|
||||
JOIN maps m ON m.id = hp.map_id
|
||||
WHERE hp.habitat_id = $1
|
||||
ORDER BY hp.rarity, ${orderByEntity('p')}, ${orderByEntity('m')}
|
||||
ORDER BY hp.rarity, p.id, ${orderByEntity('m')}
|
||||
`,
|
||||
[id]
|
||||
),
|
||||
@@ -6855,7 +6848,7 @@ export async function getItem(id: number, locale = defaultLocale) {
|
||||
JOIN skills s ON s.id = psid.skill_id
|
||||
WHERE psid.item_id = $1
|
||||
AND s.has_item_drop = true
|
||||
ORDER BY ${orderByEntity('p')}, ${orderByEntity('s')}
|
||||
ORDER BY p.id, ${orderByEntity('s')}
|
||||
`,
|
||||
[id]
|
||||
),
|
||||
@@ -6893,7 +6886,7 @@ export async function getItem(id: number, locale = defaultLocale) {
|
||||
WHERE ps.pokemon_id = p.id
|
||||
AND trading_skill.has_trading = true
|
||||
)
|
||||
ORDER BY pti.preference DESC, ${orderByEntity('p')}
|
||||
ORDER BY pti.preference DESC, p.id
|
||||
`,
|
||||
[id]
|
||||
),
|
||||
@@ -8493,7 +8486,7 @@ async function exportGenericScopeData(client: DbClient, entityType: string, incl
|
||||
async function exportScopeData(client: DbClient, scope: DataToolScope): Promise<DataToolScopeData> {
|
||||
if (scope === 'pokemon') {
|
||||
return {
|
||||
pokemon: await tableRows(client, 'SELECT * FROM pokemon ORDER BY sort_order, id'),
|
||||
pokemon: await tableRows(client, 'SELECT * FROM pokemon ORDER BY id'),
|
||||
pokemonTypeLinks: await tableRows(client, 'SELECT * FROM pokemon_pokemon_types ORDER BY pokemon_id, slot_order'),
|
||||
pokemonSkills: await tableRows(client, 'SELECT * FROM pokemon_skills ORDER BY pokemon_id, skill_id'),
|
||||
pokemonFavoriteThings: await tableRows(client, 'SELECT * FROM pokemon_favorite_things ORDER BY pokemon_id, favorite_thing_id'),
|
||||
|
||||
@@ -111,7 +111,6 @@ import {
|
||||
reorderHabitats,
|
||||
reorderItems,
|
||||
reorderLanguages,
|
||||
reorderPokemon,
|
||||
reorderRecipes,
|
||||
retryEntityDiscussionCommentModeration,
|
||||
retryLifeCommentModeration,
|
||||
@@ -2092,11 +2091,6 @@ app.delete('/api/admin/daily-checklist/:id', async (request, reply) => {
|
||||
return deleted ? reply.code(204).send() : notFound(reply, request);
|
||||
});
|
||||
|
||||
app.put('/api/admin/pokemon/order', async (request, reply) => {
|
||||
const user = await requirePermissionWithRateLimits(request, reply, 'pokemon.order', 'wikiWrite');
|
||||
return user ? reorderPokemon(request.body as Record<string, unknown>, user.id, requestLocale(request)) : undefined;
|
||||
});
|
||||
|
||||
app.put('/api/admin/items/order', async (request, reply) => {
|
||||
const user = await requirePermissionWithRateLimits(request, reply, 'items.order', 'wikiWrite');
|
||||
return user ? reorderItems(request.body as Record<string, unknown>, user.id, requestLocale(request)) : undefined;
|
||||
|
||||
Reference in New Issue
Block a user