mirror of
https://github.com/modrinth/code.git
synced 2026-09-05 06:19:11 +00:00
fix: qa
This commit is contained in:
@@ -163,11 +163,12 @@ const installTooltip = computed(() => {
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
role="row"
|
role="row"
|
||||||
class="flex items-center justify-between"
|
class="flex items-center"
|
||||||
:class="{
|
:class="{
|
||||||
'h-[74px] gap-4 px-3': !inline && !enabledFor,
|
'h-[74px] gap-4 px-3': !inline && !enabledFor,
|
||||||
'h-[72px] gap-4 px-3': !inline && enabledFor,
|
'h-[72px] gap-2 px-3': !inline && enabledFor,
|
||||||
'gap-3': inline,
|
'gap-3': inline,
|
||||||
|
'justify-between': !enabledFor,
|
||||||
'opacity-50 grayscale': disabled && !installing,
|
'opacity-50 grayscale': disabled && !installing,
|
||||||
'opacity-50': installing || (enabledFor && isEnabledForDisabled && !disabled),
|
'opacity-50': installing || (enabledFor && isEnabledForDisabled && !disabled),
|
||||||
}"
|
}"
|
||||||
@@ -328,7 +329,7 @@ const installTooltip = computed(() => {
|
|||||||
hideActions
|
hideActions
|
||||||
? 'flex-1'
|
? 'flex-1'
|
||||||
: enabledFor
|
: enabledFor
|
||||||
? 'w-[250px] min-w-0 shrink-0'
|
? 'min-w-0 flex-1'
|
||||||
: 'flex-1 min-w-0',
|
: 'flex-1 min-w-0',
|
||||||
!enabledFor && enabled === false && !disabled ? 'grayscale opacity-50' : '',
|
!enabledFor && enabled === false && !disabled ? 'grayscale opacity-50' : '',
|
||||||
]"
|
]"
|
||||||
|
|||||||
@@ -27,10 +27,6 @@ const messages = defineMessages({
|
|||||||
defaultMessage:
|
defaultMessage:
|
||||||
'Choose whether this content runs on the server, is sent to players, or is disabled in both places.',
|
'Choose whether this content runs on the server, is sent to players, or is disabled in both places.',
|
||||||
},
|
},
|
||||||
sortEnabledFor: {
|
|
||||||
id: 'content.enabled-for.sort',
|
|
||||||
defaultMessage: 'Sort by where content is enabled',
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -45,7 +41,6 @@ interface Props {
|
|||||||
flat?: boolean
|
flat?: boolean
|
||||||
showItemActions?: boolean
|
showItemActions?: boolean
|
||||||
showEnabledForColumn?: boolean
|
showEnabledForColumn?: boolean
|
||||||
enabledForSortDirection?: ContentCardTableSortDirection
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -59,7 +54,6 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
flat: false,
|
flat: false,
|
||||||
showItemActions: false,
|
showItemActions: false,
|
||||||
showEnabledForColumn: false,
|
showEnabledForColumn: false,
|
||||||
enabledForSortDirection: undefined,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const stickyHeaderRef = ref<HTMLElement | null>(null)
|
const stickyHeaderRef = ref<HTMLElement | null>(null)
|
||||||
@@ -74,7 +68,6 @@ const emit = defineEmits<{
|
|||||||
update: [id: string]
|
update: [id: string]
|
||||||
switchVersion: [id: string]
|
switchVersion: [id: string]
|
||||||
sort: [column: ContentCardTableSortColumn, direction: ContentCardTableSortDirection]
|
sort: [column: ContentCardTableSortColumn, direction: ContentCardTableSortDirection]
|
||||||
'sort-enabled-for': [direction: ContentCardTableSortDirection]
|
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// Check if any actions are available
|
// Check if any actions are available
|
||||||
@@ -194,11 +187,6 @@ function handleSort(column: ContentCardTableSortColumn) {
|
|||||||
emit('sort', column, newDirection)
|
emit('sort', column, newDirection)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEnabledForSort() {
|
|
||||||
const newDirection: ContentCardTableSortDirection =
|
|
||||||
props.enabledForSortDirection === 'desc' ? 'asc' : 'desc'
|
|
||||||
emit('sort-enabled-for', newDirection)
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -211,8 +199,9 @@ function handleEnabledForSort() {
|
|||||||
v-if="!hideHeader"
|
v-if="!hideHeader"
|
||||||
ref="stickyHeaderRef"
|
ref="stickyHeaderRef"
|
||||||
role="rowgroup"
|
role="rowgroup"
|
||||||
class="sticky top-0 z-10 flex h-12 items-center justify-between gap-4 bg-surface-3 px-3"
|
class="sticky top-0 z-10 flex h-12 items-center bg-surface-3 px-3"
|
||||||
:class="[
|
:class="[
|
||||||
|
hasEnabledForColumn ? 'gap-2' : 'justify-between gap-4',
|
||||||
flat || isStuck ? 'rounded-none' : 'rounded-t-[20px]',
|
flat || isStuck ? 'rounded-none' : 'rounded-t-[20px]',
|
||||||
isStuck
|
isStuck
|
||||||
? 'transition-[border-radius] duration-100 border-0 border-y border-solid border-surface-4 shadow-md before:pointer-events-none before:absolute before:inset-x-0 before:-top-4 before:h-5 before:bg-surface-3'
|
? 'transition-[border-radius] duration-100 border-0 border-y border-solid border-surface-4 shadow-md before:pointer-events-none before:absolute before:inset-x-0 before:-top-4 before:h-5 before:bg-surface-3'
|
||||||
@@ -264,22 +253,9 @@ function handleEnabledForSort() {
|
|||||||
<div
|
<div
|
||||||
v-if="hasEnabledForColumn"
|
v-if="hasEnabledForColumn"
|
||||||
role="columnheader"
|
role="columnheader"
|
||||||
:aria-sort="
|
|
||||||
enabledForSortDirection
|
|
||||||
? enabledForSortDirection === 'asc'
|
|
||||||
? 'ascending'
|
|
||||||
: 'descending'
|
|
||||||
: 'none'
|
|
||||||
"
|
|
||||||
class="hidden w-[200px] shrink-0 items-center gap-1.5 font-semibold text-secondary @[800px]:flex"
|
class="hidden w-[200px] shrink-0 items-center gap-1.5 font-semibold text-secondary @[800px]:flex"
|
||||||
>
|
>
|
||||||
<button
|
<span>{{ formatMessage(messages.enabledFor) }}</span>
|
||||||
type="button"
|
|
||||||
class="cursor-pointer border-0 bg-transparent p-0 font-semibold text-secondary"
|
|
||||||
@click="handleEnabledForSort"
|
|
||||||
>
|
|
||||||
{{ formatMessage(messages.enabledFor) }}
|
|
||||||
</button>
|
|
||||||
<span
|
<span
|
||||||
v-tooltip="formatMessage(messages.enabledForDescription)"
|
v-tooltip="formatMessage(messages.enabledForDescription)"
|
||||||
class="inline-flex size-4 cursor-help items-center justify-center"
|
class="inline-flex size-4 cursor-help items-center justify-center"
|
||||||
@@ -287,15 +263,6 @@ function handleEnabledForSort() {
|
|||||||
>
|
>
|
||||||
<InfoIcon class="size-4" />
|
<InfoIcon class="size-4" />
|
||||||
</span>
|
</span>
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="flex cursor-pointer items-center border-0 bg-transparent p-0 text-secondary"
|
|
||||||
:aria-label="formatMessage(messages.sortEnabledFor)"
|
|
||||||
@click="handleEnabledForSort"
|
|
||||||
>
|
|
||||||
<ChevronUpIcon v-if="enabledForSortDirection === 'asc'" class="size-4" />
|
|
||||||
<ChevronDownIcon v-else class="size-4" />
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -303,7 +270,7 @@ function handleEnabledForSort() {
|
|||||||
:class="
|
:class="
|
||||||
hasAnyActions
|
hasAnyActions
|
||||||
? hasEnabledForColumn
|
? hasEnabledForColumn
|
||||||
? 'w-[250px] min-w-0 shrink-0'
|
? 'min-w-0 flex-1'
|
||||||
: 'flex-1 min-w-0'
|
: 'flex-1 min-w-0'
|
||||||
: 'flex-1'
|
: 'flex-1'
|
||||||
"
|
"
|
||||||
|
|||||||
+15
-3
@@ -8,6 +8,7 @@ import {
|
|||||||
PaintbrushIcon,
|
PaintbrushIcon,
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
SpinnerIcon,
|
SpinnerIcon,
|
||||||
|
UnknownIcon,
|
||||||
} from '@modrinth/assets'
|
} from '@modrinth/assets'
|
||||||
import Fuse from 'fuse.js'
|
import Fuse from 'fuse.js'
|
||||||
import { computed, nextTick, ref, watchSyncEffect } from 'vue'
|
import { computed, nextTick, ref, watchSyncEffect } from 'vue'
|
||||||
@@ -116,6 +117,11 @@ const messages = defineMessages({
|
|||||||
id: 'content.enabled-for.label',
|
id: 'content.enabled-for.label',
|
||||||
defaultMessage: 'Enabled for',
|
defaultMessage: 'Enabled for',
|
||||||
},
|
},
|
||||||
|
enabledForDescription: {
|
||||||
|
id: 'content.enabled-for.description',
|
||||||
|
defaultMessage:
|
||||||
|
'Choose whether this content runs on the server, is sent to players, or is disabled in both places.',
|
||||||
|
},
|
||||||
pleaseWait: {
|
pleaseWait: {
|
||||||
id: 'content.enabled-for.please-wait',
|
id: 'content.enabled-for.please-wait',
|
||||||
defaultMessage: 'Please wait',
|
defaultMessage: 'Please wait',
|
||||||
@@ -577,7 +583,8 @@ defineExpose({ show, showLoading, hide, getState, restore, updateItem, setItems
|
|||||||
|
|
||||||
<div v-else class="@container flex-1 min-h-0 flex flex-col">
|
<div v-else class="@container flex-1 min-h-0 flex flex-col">
|
||||||
<div
|
<div
|
||||||
class="flex h-12 shrink-0 items-center justify-between gap-4 border-0 border-b border-solid border-surface-4 bg-surface-3 px-3"
|
class="flex h-12 shrink-0 items-center border-0 border-b border-solid border-surface-4 bg-surface-3 px-3"
|
||||||
|
:class="props.enableEnabledFor ? 'gap-2' : 'justify-between gap-4'"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex min-w-0 items-center gap-4"
|
class="flex min-w-0 items-center gap-4"
|
||||||
@@ -603,18 +610,23 @@ defineExpose({ show, showLoading, hide, getState, restore, updateItem, setItems
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="props.enableEnabledFor"
|
v-if="props.enableEnabledFor"
|
||||||
class="hidden w-[200px] shrink-0 @[800px]:flex"
|
class="hidden w-[200px] shrink-0 items-center gap-1.5 @[800px]:flex"
|
||||||
>
|
>
|
||||||
<span class="font-semibold text-secondary">{{
|
<span class="font-semibold text-secondary">{{
|
||||||
formatMessage(messages.enabledFor)
|
formatMessage(messages.enabledFor)
|
||||||
}}</span>
|
}}</span>
|
||||||
|
<UnknownIcon
|
||||||
|
v-tooltip="formatMessage(messages.enabledForDescription)"
|
||||||
|
class="size-4 cursor-help text-secondary"
|
||||||
|
tabindex="0"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="hidden @[800px]:flex"
|
class="hidden @[800px]:flex"
|
||||||
:class="
|
:class="
|
||||||
showTableActions
|
showTableActions
|
||||||
? props.enableEnabledFor
|
? props.enableEnabledFor
|
||||||
? 'w-[250px] min-w-0 shrink-0'
|
? 'min-w-0 flex-1'
|
||||||
: 'flex-1 min-w-0'
|
: 'flex-1 min-w-0'
|
||||||
: 'flex-1'
|
: 'flex-1'
|
||||||
"
|
"
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import {
|
|||||||
OrganizationIcon,
|
OrganizationIcon,
|
||||||
RefreshCwIcon,
|
RefreshCwIcon,
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
ServerIcon,
|
|
||||||
ShareIcon,
|
ShareIcon,
|
||||||
TextCursorInputIcon,
|
TextCursorInputIcon,
|
||||||
TrashIcon,
|
TrashIcon,
|
||||||
@@ -111,14 +110,6 @@ const messages = defineMessages({
|
|||||||
id: 'content.page-layout.sort.date-added-oldest',
|
id: 'content.page-layout.sort.date-added-oldest',
|
||||||
defaultMessage: 'Oldest first',
|
defaultMessage: 'Oldest first',
|
||||||
},
|
},
|
||||||
sortEnabledForDescending: {
|
|
||||||
id: 'content.page-layout.sort.enabled-for-descending',
|
|
||||||
defaultMessage: 'Enabled for (most first)',
|
|
||||||
},
|
|
||||||
sortEnabledForAscending: {
|
|
||||||
id: 'content.page-layout.sort.enabled-for-ascending',
|
|
||||||
defaultMessage: 'Enabled for (least first)',
|
|
||||||
},
|
|
||||||
filter: {
|
filter: {
|
||||||
id: 'content.page-layout.filter.add',
|
id: 'content.page-layout.filter.add',
|
||||||
defaultMessage: 'Filter',
|
defaultMessage: 'Filter',
|
||||||
@@ -193,20 +184,24 @@ type SortMode =
|
|||||||
| 'alphabetical-desc'
|
| 'alphabetical-desc'
|
||||||
| 'date-added-newest'
|
| 'date-added-newest'
|
||||||
| 'date-added-oldest'
|
| 'date-added-oldest'
|
||||||
| 'enabled-for-desc'
|
const defaultSortMode: SortMode = 'alphabetical-asc'
|
||||||
| 'enabled-for-asc'
|
|
||||||
const defaultSortMode: SortMode = ctx.setEnabledFor ? 'enabled-for-desc' : 'alphabetical-asc'
|
|
||||||
const sortMode = ctx.filterPersistKey
|
const sortMode = ctx.filterPersistKey
|
||||||
? useSessionStorage<SortMode>(`content-sort:${ctx.filterPersistKey}`, defaultSortMode)
|
? useSessionStorage<SortMode>(`content-sort:${ctx.filterPersistKey}`, defaultSortMode)
|
||||||
: ref<SortMode>(defaultSortMode)
|
: ref<SortMode>(defaultSortMode)
|
||||||
|
|
||||||
|
const validSortModes: readonly string[] = [
|
||||||
|
'alphabetical-asc',
|
||||||
|
'alphabetical-desc',
|
||||||
|
'date-added-newest',
|
||||||
|
'date-added-oldest',
|
||||||
|
]
|
||||||
|
if (!validSortModes.includes(sortMode.value)) sortMode.value = defaultSortMode
|
||||||
|
|
||||||
const sortLabels: Record<SortMode, () => string> = {
|
const sortLabels: Record<SortMode, () => string> = {
|
||||||
'alphabetical-asc': () => formatMessage(messages.sortAlphabeticalAscending),
|
'alphabetical-asc': () => formatMessage(messages.sortAlphabeticalAscending),
|
||||||
'alphabetical-desc': () => formatMessage(messages.sortAlphabeticalDescending),
|
'alphabetical-desc': () => formatMessage(messages.sortAlphabeticalDescending),
|
||||||
'date-added-newest': () => formatMessage(messages.sortDateAddedNewest),
|
'date-added-newest': () => formatMessage(messages.sortDateAddedNewest),
|
||||||
'date-added-oldest': () => formatMessage(messages.sortDateAddedOldest),
|
'date-added-oldest': () => formatMessage(messages.sortDateAddedOldest),
|
||||||
'enabled-for-desc': () => formatMessage(messages.sortEnabledForDescending),
|
|
||||||
'enabled-for-asc': () => formatMessage(messages.sortEnabledForAscending),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortOptions = computed<ButtonMenuOption[]>(() => {
|
const sortOptions = computed<ButtonMenuOption[]>(() => {
|
||||||
@@ -237,27 +232,9 @@ const sortOptions = computed<ButtonMenuOption[]>(() => {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
if (ctx.setEnabledFor) {
|
|
||||||
options.push(
|
|
||||||
{
|
|
||||||
id: 'enabled-for-desc',
|
|
||||||
label: formatMessage(messages.sortEnabledForDescending),
|
|
||||||
action: () => (sortMode.value = 'enabled-for-desc'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'enabled-for-asc',
|
|
||||||
label: formatMessage(messages.sortEnabledForAscending),
|
|
||||||
action: () => (sortMode.value = 'enabled-for-asc'),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return options
|
return options
|
||||||
})
|
})
|
||||||
|
|
||||||
function getEnabledForRank(item: ContentItem) {
|
|
||||||
return Number(item.enabledFor?.server) * 2 + Number(item.enabledFor?.player)
|
|
||||||
}
|
|
||||||
const sortedItems = computed(() => {
|
const sortedItems = computed(() => {
|
||||||
const items = [...ctx.items.value]
|
const items = [...ctx.items.value]
|
||||||
switch (sortMode.value) {
|
switch (sortMode.value) {
|
||||||
@@ -282,16 +259,6 @@ const sortedItems = computed(() => {
|
|||||||
const dateB = b.date_added ?? ''
|
const dateB = b.date_added ?? ''
|
||||||
return dateA.localeCompare(dateB) || a.file_name.localeCompare(b.file_name)
|
return dateA.localeCompare(dateB) || a.file_name.localeCompare(b.file_name)
|
||||||
})
|
})
|
||||||
case 'enabled-for-desc':
|
|
||||||
return items.sort(
|
|
||||||
(a, b) =>
|
|
||||||
getEnabledForRank(b) - getEnabledForRank(a) || a.file_name.localeCompare(b.file_name),
|
|
||||||
)
|
|
||||||
case 'enabled-for-asc':
|
|
||||||
return items.sort(
|
|
||||||
(a, b) =>
|
|
||||||
getEnabledForRank(a) - getEnabledForRank(b) || a.file_name.localeCompare(b.file_name),
|
|
||||||
)
|
|
||||||
default:
|
default:
|
||||||
return items.sort((a, b) => {
|
return items.sort((a, b) => {
|
||||||
const nameA = a.project?.title ?? a.file_name
|
const nameA = a.project?.title ?? a.file_name
|
||||||
@@ -885,10 +852,6 @@ async function handleSetEnabledForById(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEnabledForSort(direction: 'asc' | 'desc') {
|
|
||||||
sortMode.value = direction === 'asc' ? 'enabled-for-asc' : 'enabled-for-desc'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bulk updating
|
// Bulk updating
|
||||||
const confirmBulkUpdateModal = ref<InstanceType<typeof ConfirmBulkUpdateModal>>()
|
const confirmBulkUpdateModal = ref<InstanceType<typeof ConfirmBulkUpdateModal>>()
|
||||||
const pendingBulkUpdateItems = ref<ContentItem[]>([])
|
const pendingBulkUpdateItems = ref<ContentItem[]>([])
|
||||||
@@ -1090,7 +1053,6 @@ const confirmUnlinkModal = ref<InstanceType<typeof ConfirmUnlinkModal>>()
|
|||||||
<ArrowUpZAIcon v-if="sortMode === 'alphabetical-desc'" />
|
<ArrowUpZAIcon v-if="sortMode === 'alphabetical-desc'" />
|
||||||
<ClockArrowDownIcon v-else-if="sortMode === 'date-added-newest'" />
|
<ClockArrowDownIcon v-else-if="sortMode === 'date-added-newest'" />
|
||||||
<ClockArrowUpIcon v-else-if="sortMode === 'date-added-oldest'" />
|
<ClockArrowUpIcon v-else-if="sortMode === 'date-added-oldest'" />
|
||||||
<ServerIcon v-else-if="sortMode.startsWith('enabled-for')" />
|
|
||||||
<ArrowDownAZIcon v-else />
|
<ArrowDownAZIcon v-else />
|
||||||
{{ sortLabels[sortMode]() }}
|
{{ sortLabels[sortMode]() }}
|
||||||
<DropdownIcon />
|
<DropdownIcon />
|
||||||
@@ -1306,16 +1268,8 @@ const confirmUnlinkModal = ref<InstanceType<typeof ConfirmUnlinkModal>>()
|
|||||||
:items="tableItems"
|
:items="tableItems"
|
||||||
:show-selection="true"
|
:show-selection="true"
|
||||||
:show-enabled-for-column="!!ctx.setEnabledFor"
|
:show-enabled-for-column="!!ctx.setEnabledFor"
|
||||||
:enabled-for-sort-direction="
|
|
||||||
sortMode === 'enabled-for-asc'
|
|
||||||
? 'asc'
|
|
||||||
: sortMode === 'enabled-for-desc'
|
|
||||||
? 'desc'
|
|
||||||
: undefined
|
|
||||||
"
|
|
||||||
@update:enabled="handleToggleEnabledById"
|
@update:enabled="handleToggleEnabledById"
|
||||||
@update:enabled-for="handleSetEnabledForById"
|
@update:enabled-for="handleSetEnabledForById"
|
||||||
@sort-enabled-for="handleEnabledForSort"
|
|
||||||
@delete="handleDeleteById"
|
@delete="handleDeleteById"
|
||||||
@update="handleUpdateById"
|
@update="handleUpdateById"
|
||||||
@switch-version="handleSwitchVersionById"
|
@switch-version="handleSwitchVersionById"
|
||||||
|
|||||||
@@ -116,11 +116,11 @@ const messages = defineMessages({
|
|||||||
},
|
},
|
||||||
lockEnvironment: {
|
lockEnvironment: {
|
||||||
id: 'hosting.content.enabled-for.lock-environment',
|
id: 'hosting.content.enabled-for.lock-environment',
|
||||||
defaultMessage: 'Lock detected environment',
|
defaultMessage: 'Lock',
|
||||||
},
|
},
|
||||||
unlockEnvironment: {
|
unlockEnvironment: {
|
||||||
id: 'hosting.content.enabled-for.unlock-environment',
|
id: 'hosting.content.enabled-for.unlock-environment',
|
||||||
defaultMessage: 'Unlock environment controls',
|
defaultMessage: 'Unlock',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user