Show pending ISAC contributions immediately

This commit is contained in:
JB
2026-07-25 21:10:08 -04:00
parent 67db106fba
commit 6d2e8176ee
18 changed files with 288 additions and 68 deletions
+31 -6
View File
@@ -7,6 +7,7 @@ import { fail } from '@sveltejs/kit';
import { randomUUID } from 'node:crypto';
import type { Actions, PageServerLoad } from './$types';
import { applyIconMutation, gameDataIconMetadata, gameDataIconUrl, GameDataIconValidationError, readIconMutation } from '$lib/server/game-data-icons';
import { getPendingEntities } from '$lib/server/data-moderation';
const qualities = ['Standard', 'Specialized', 'Superior', 'High-end'];
const attributeTypes = ['Firepower', 'Toughness', 'Engineering'];
@@ -48,7 +49,7 @@ async function profileSnapshot(id: string) {
}
export const load: PageServerLoad = async ({ cookies, url }) => {
await requireDataView(await getSessionUser(cookies));
const user = await requireDataView(await getSessionUser(cookies));
const database = await getDatabase();
const requestedFilter = url.searchParams.get('filter') ?? '';
const filter = [...qualities.map((quality) => quality.toLowerCase()), ...attributeTypes.map((type) => type.toLowerCase()), 'active', 'archived'].includes(requestedFilter)
@@ -75,7 +76,7 @@ export const load: PageServerLoad = async ({ cookies, url }) => {
(await database.prepare(`SELECT COUNT(*) AS total FROM os_protocols ${where}`)).get(...args)
]);
const pagination = getPagination(url, Number(filtered?.total ?? 0));
const [protocols, primaryEffects, profiles, secondaryEffects, talents, talentTriggers, talentEffects, stats, triggers, icons] = await Promise.all([
const [protocols, primaryEffects, profiles, secondaryEffects, talents, talentTriggers, talentEffects, stats, triggers, icons, pending] = await Promise.all([
(await database.prepare(`SELECT * FROM os_protocols ${where} ORDER BY active DESC,quality,name COLLATE NOCASE LIMIT ? OFFSET ?`)).all(...args, pagination.perPage, pagination.offset),
(await database.prepare('SELECT * FROM os_protocol_primary_effects')).all(),
(await database.prepare('SELECT * FROM os_protocol_secondary_profiles ORDER BY quality,primary_attribute_type')).all(),
@@ -85,11 +86,33 @@ export const load: PageServerLoad = async ({ cookies, url }) => {
(await database.prepare('SELECT * FROM os_protocol_talent_effects ORDER BY sort_order')).all(),
(await database.prepare('SELECT id,name,unit FROM stat_attributes WHERE active=1 ORDER BY name COLLATE NOCASE')).all(),
(await database.prepare('SELECT id,name,description FROM talent_triggers WHERE active=1 ORDER BY name COLLATE NOCASE')).all(),
(await database.prepare("SELECT entity_id,updated_at FROM game_data_icons WHERE entity_type='os_protocol'")).all()
(await database.prepare("SELECT entity_id,updated_at FROM game_data_icons WHERE entity_type='os_protocol'")).all(),
getPendingEntities(user.id, [
{ module: 'attributes', action: 'save', kind: 'attribute', fields: ['unit'] },
{ module: 'talents', action: 'saveTrigger', kind: 'trigger', fields: ['description'] },
{ module: 'protocols', action: 'save', kind: 'protocol', fields: ['quality', 'attributeType', 'primaryStatId', 'primaryBaseValue', 'talentName', 'descriptionTemplate', 'talentEffects', 'triggerIds'] }
])
]);
const configuredProfiles = profiles.map((profile) => ({ ...profile, effects: secondaryEffects.filter((effect) => effect.profile_id === profile.id) }));
const pendingProtocols = pending.filter((item) => item.kind === 'protocol').filter((item) =>
filter === 'archived' ? false
: qualities.some((quality) => quality.toLowerCase() === filter) ? String(item.quality).toLowerCase() === filter
: attributeTypes.some((type) => type.toLowerCase() === filter) ? String(item.attributeType).toLowerCase() === filter : true
).map((protocol) => ({
...protocol,
iconUrl: '',
primary_attribute_type: protocol.attributeType,
primaryEffect: { stat_attribute_id: protocol.primaryStatId, base_value: Number(protocol.primaryBaseValue) },
secondaryProfile: configuredProfiles.find((profile) => profile.quality === protocol.quality && profile.primary_attribute_type === protocol.attributeType) ?? null,
talent: {
name: protocol.talentName,
description_template: protocol.descriptionTemplate,
effects: (() => { try { return JSON.parse(String(protocol.talentEffects ?? '[]')); } catch { return []; } })(),
triggerIds: Array.isArray(protocol.triggerIds) ? protocol.triggerIds : [protocol.triggerIds].filter(Boolean)
}
}));
return {
protocols: protocols.map((protocol) => {
protocols: [...pendingProtocols, ...protocols.map((protocol) => {
const talent = talents.find((item) => item.protocol_id === protocol.id);
return {
...protocol,
@@ -102,11 +125,13 @@ export const load: PageServerLoad = async ({ cookies, url }) => {
effects: talentEffects.filter((item) => item.talent_id === talent.id)
} : null
};
}),
})],
profiles: qualities.flatMap((quality) => attributeTypes.map((attributeType) => configuredProfiles.find((profile) =>
profile.quality === quality && profile.primary_attribute_type === attributeType
) ?? { id: '', quality, primary_attribute_type: attributeType, effects: [] })),
stats, triggers, summary, filter, pagination
stats: [...pending.filter((item) => item.kind === 'attribute'), ...stats],
triggers: [...pending.filter((item) => item.kind === 'trigger'), ...triggers],
summary: { ...summary, total: Number(summary?.total ?? 0) + pending.filter((item) => item.kind === 'protocol').length, pending: pending.filter((item) => item.kind === 'protocol').length }, filter, pagination
};
};