fix: prepr

This commit is contained in:
Calum H. (IMB11)
2026-08-10 12:58:02 +01:00
parent eb5897b553
commit 7deb7e9ef1
10 changed files with 30 additions and 50 deletions
@@ -284,9 +284,9 @@
<component <component
:is="opt.icon" :is="opt.icon"
v-if="opt.icon" v-if="opt.icon"
class="mr-2" class="mr-2"
:class="{ 'opacity-50': opt.visited }" :class="{ 'opacity-50': opt.visited }"
aria-hidden="true" aria-hidden="true"
/> />
<span :class="{ 'opacity-50': opt.visited }"> <span :class="{ 'opacity-50': opt.visited }">
{{ opt.text {{ opt.text
@@ -1343,9 +1343,7 @@ async function generateMessage() {
const hasNextProject = ref(false) const hasNextProject = ref(false)
const finishedId = import.meta.client const finishedId = import.meta.client ? localStorage.getItem('moderation-checklist-finished') : null
? localStorage.getItem('moderation-checklist-finished')
: null
if (finishedId === projectV2.value.id) { if (finishedId === projectV2.value.id) {
localStorage.removeItem('moderation-checklist-finished') localStorage.removeItem('moderation-checklist-finished')
hasNextProject.value = moderationQueue.queueLength > 0 hasNextProject.value = moderationQueue.queueLength > 0
@@ -70,6 +70,7 @@ const {
</div> </div>
<template v-if="hasChildrenCap(item) && !hasValueCap(item)"> <template v-if="hasChildrenCap(item) && !hasValueCap(item)">
<!-- eslint-disable-next-line vue/no-undef-components -- recursive component named via defineOptions -->
<NodeRenderer <NodeRenderer
:nodes="resolveChildren(item, containerScope(item).state)" :nodes="resolveChildren(item, containerScope(item).state)"
:state="containerScope(item).state" :state="containerScope(item).state"
@@ -90,7 +91,9 @@ const {
:[modelProp(item)]=" :[modelProp(item)]="
getEffectiveValue(item as RenderableValueNode, state[item.id], wrappedState) getEffectiveValue(item as RenderableValueNode, state[item.id], wrappedState)
" "
@[updateEvent(item)]="(value: unknown) => updateValue(item as RenderableValueNode, value)" @[updateEvent(item)]="
(value: unknown) => updateValue(item as RenderableValueNode, value)
"
/> />
<template <template
v-for="(tweak, tweakIndex) in (item as RenderableValueNode)._tweaks ?? []" v-for="(tweak, tweakIndex) in (item as RenderableValueNode)._tweaks ?? []"
@@ -132,6 +135,7 @@ const {
</template> </template>
<template v-for="(item, idx) in nodes" :key="`children-${nodeKey(item, idx)}`"> <template v-for="(item, idx) in nodes" :key="`children-${nodeKey(item, idx)}`">
<!-- eslint-disable-next-line vue/no-undef-components -- recursive component named via defineOptions -->
<NodeRenderer <NodeRenderer
v-if=" v-if="
typeof item === 'object' && typeof item === 'object' &&
@@ -10,10 +10,7 @@ import type { RenderableValueNode, RendererPropsContext } from './types'
interface RendererDefinition { interface RendererDefinition {
component: Component component: Component
props?: ( props?: (node: RenderableValueNode, context: RendererPropsContext) => Record<string, unknown>
node: RenderableValueNode,
context: RendererPropsContext,
) => Record<string, unknown>
} }
const builtinRenderers = { const builtinRenderers = {
@@ -25,8 +25,8 @@ import {
originScope, originScope,
resolve, resolve,
resolveChildren, resolveChildren,
writeNodeValue,
withStateDefaults, withStateDefaults,
writeNodeValue,
} from '@modrinth/moderation/src/types/node' } from '@modrinth/moderation/src/types/node'
import type { Component } from 'vue' import type { Component } from 'vue'
import { computed, watchEffect } from 'vue' import { computed, watchEffect } from 'vue'
@@ -122,9 +122,7 @@ export function useNodeRenderer(props: NodeRendererProps) {
? { ? {
class: '!w-auto max-w-full', class: '!w-auto max-w-full',
style: { style: {
minWidth: getDropdownMinWidth( minWidth: getDropdownMinWidth(node._options as unknown as Array<{ label: string }>),
node._options as unknown as Array<{ label: string }>,
),
}, },
} }
: undefined : undefined
@@ -211,9 +209,7 @@ export function useNodeRenderer(props: NodeRendererProps) {
} }
function nodeKey(item: ChildNode, index: number): string { function nodeKey(item: ChildNode, index: number): string {
return typeof item === 'object' && item !== null && hasIdCap(item) return typeof item === 'object' && item !== null && hasIdCap(item) ? item.id : `n-${index}`
? item.id
: `n-${index}`
} }
function modelProp(item: object): string { function modelProp(item: object): string {
@@ -229,7 +225,9 @@ export function useNodeRenderer(props: NodeRendererProps) {
? (item._onChange as OnChangeFn | undefined) ? (item._onChange as OnChangeFn | undefined)
: undefined : undefined
if (onChange) { if (onChange) {
const result = onChange(value as string, { override: (override) => ({ __override: override }) }) const result = onChange(value as string, {
override: (override) => ({ __override: override }),
})
if (result && typeof result === 'object' && '__override' in result) { if (result && typeof result === 'object' && '__override' in result) {
writeNodeValue( writeNodeValue(
item, item,
@@ -1,10 +1,7 @@
import type { AbstractWebNotificationManager } from '@modrinth/ui' import type { AbstractWebNotificationManager } from '@modrinth/ui'
import { ref } from 'vue' import { ref } from 'vue'
import type { import type { LockAcquireResponse, ModerationQueueService } from '~/services/moderation/queue.ts'
LockAcquireResponse,
ModerationQueueService,
} from '~/services/moderation/queue.ts'
interface ChecklistLockOptions { interface ChecklistLockOptions {
projectId: string projectId: string
@@ -110,10 +107,13 @@ export function useChecklistLock({
function startHeartbeat() { function startHeartbeat() {
if (heartbeat) clearInterval(heartbeat) if (heartbeat) clearInterval(heartbeat)
heartbeat = setInterval(async () => { heartbeat = setInterval(
const result = await queue.refreshLock() async () => {
if (!result.success) handleLost(result) const result = await queue.refreshLock()
}, 5 * 60 * 1000) if (!result.success) handleLost(result)
},
5 * 60 * 1000,
)
} }
function handleAcquired() { function handleAcquired() {
@@ -1,5 +1,6 @@
import type { Labrinth } from '@modrinth/api-client' import type { Labrinth } from '@modrinth/api-client'
import { expandVariables } from '@modrinth/moderation' import { expandVariables } from '@modrinth/moderation'
import type { FixBuilder, NodeState, StageNode, Writer } from '@modrinth/moderation/src/types/node'
import { import {
collectMessageNodes, collectMessageNodes,
computeAttentionMap, computeAttentionMap,
@@ -7,12 +8,6 @@ import {
evalActiveAction, evalActiveAction,
resolveChildren, resolveChildren,
} from '@modrinth/moderation/src/types/node' } from '@modrinth/moderation/src/types/node'
import type {
FixBuilder,
NodeState,
StageNode,
Writer,
} from '@modrinth/moderation/src/types/node'
import { renderHighlightedString } from '@modrinth/utils' import { renderHighlightedString } from '@modrinth/utils'
import type { ComputedRef, Ref } from 'vue' import type { ComputedRef, Ref } from 'vue'
import { computed, ref, watchEffect } from 'vue' import { computed, ref, watchEffect } from 'vue'
@@ -16,9 +16,7 @@ export async function loadChecklistPersistence(projectId: string) {
const persistedState = import.meta.client ? await loadChecklistState(projectId) : null const persistedState = import.meta.client ? await loadChecklistState(projectId) : null
const activatedStages = ref<Set<string>>(new Set(persistedState?.activatedStages ?? [])) const activatedStages = ref<Set<string>>(new Set(persistedState?.activatedStages ?? []))
const visitedStages = ref<Set<string>>( const visitedStages = ref<Set<string>>(
new Set( new Set(import.meta.client ? (getSessionChecklistState(projectId).visitedStages ?? []) : []),
import.meta.client ? (getSessionChecklistState(projectId).visitedStages ?? []) : [],
),
) )
const reviewedAnyway = ref(persistedState?.reviewAnyway ?? false) const reviewedAnyway = ref(persistedState?.reviewAnyway ?? false)
const message = ref<string | null>(persistedState?.message ?? null) const message = ref<string | null>(persistedState?.message ?? null)
@@ -20,9 +20,7 @@ interface ModerationSubmission {
} }
function getFixes(node: object): FixBuilder[] { function getFixes(node: object): FixBuilder[] {
return hasCap(node, '_fixes') && Array.isArray(node._fixes) return hasCap(node, '_fixes') && Array.isArray(node._fixes) ? (node._fixes as FixBuilder[]) : []
? (node._fixes as FixBuilder[])
: []
} }
function shouldApplyFixes(actions: ActiveAction[]): boolean { function shouldApplyFixes(actions: ActiveAction[]): boolean {
@@ -259,17 +259,9 @@ export interface NodePropsContext {
toggleSetValue?: (value: string) => void toggleSetValue?: (value: string) => void
} }
export type BuiltinRendererKey = export type BuiltinRendererKey = 'action' | 'checkbox' | 'toggle' | 'dropdown' | 'text' | 'markdown'
| 'action'
| 'checkbox'
| 'toggle'
| 'dropdown'
| 'text'
| 'markdown'
export type NodeRendererDescriptor = export type NodeRendererDescriptor = { type: BuiltinRendererKey } | { type: 'custom'; key: string }
| { type: BuiltinRendererKey }
| { type: 'custom'; key: string }
export interface Renderable { export interface Renderable {
_renderer: NodeRendererDescriptor _renderer: NodeRendererDescriptor
@@ -12,8 +12,8 @@ import {
withNoneLabel, withNoneLabel,
withOnClick, withOnClick,
withPriority, withPriority,
withRequired,
withRenderer, withRenderer,
withRequired,
withSelectable, withSelectable,
withShown, withShown,
withStageMeta, withStageMeta,