fix: final content tab qa (#5611)

* fix: queued admonition always showing

* fix: dont apply grayscale to checkbox in content card item

* fix: actual stable id for disable/enable/bulk state

* fix: vue-router resolve workaround

* fix: show disable/enable btns same time

* fix: remove mr-2 on toggle

* fix: type errors + add ModpackAlreadyInstalledModal

* fix: bulk actions + overflow menu hitting ad container

* fix: responsiveness of ContentSelectionBar

* feat: better backup naming for inline backups + sorting fixes

* fix: lint

* fix: typo
This commit is contained in:
Calum H.
2026-03-18 18:03:55 +00:00
committed by GitHub
parent cf1b5f5e2d
commit 1d10af09f5
35 changed files with 503 additions and 215 deletions

View File

@@ -87,22 +87,23 @@ const deleteHovered = ref(false)
:class="{ 'opacity-50': disabled }"
>
<div
class="flex min-w-0 items-center gap-4 transition-[filter,opacity] duration-200"
:class="[
hideActions ? 'flex-1' : 'flex-1 @[800px]:w-[350px] @[800px]:shrink-0 @[800px]:flex-none',
enabled === false && !disabled ? 'grayscale opacity-50' : '',
]"
class="flex min-w-0 items-center gap-4"
:class="
hideActions ? 'flex-1' : 'flex-1 @[800px]:w-[350px] @[800px]:shrink-0 @[800px]:flex-none'
"
>
<Checkbox
v-if="showCheckbox"
:model-value="selected ?? false"
:disabled="disabled"
:aria-label="`Select ${project.title}`"
class="shrink-0"
@update:model-value="selected = $event"
/>
<div class="flex min-w-0 items-center gap-3">
<div
class="flex min-w-0 items-center gap-3 transition-[filter,opacity] duration-200"
:class="enabled === false && !disabled ? 'grayscale opacity-50' : ''"
>
<div
v-tooltip="installing ? formatMessage(commonMessages.installingLabel) : undefined"
class="relative shrink-0"
@@ -256,7 +257,7 @@ const deleteHovered = ref(false)
:model-value="enabled"
:disabled="disabled"
:aria-label="project.title"
class="mr-2 my-auto"
class="my-auto"
@update:model-value="(val) => emit('update:enabled', val as boolean)"
/>

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { PowerIcon, PowerOffIcon } from '@modrinth/assets'
import { PowerIcon, PowerOffIcon, XIcon } from '@modrinth/assets'
import { computed } from 'vue'
import ButtonStyled from '#ui/components/base/ButtonStyled.vue'
@@ -61,6 +61,14 @@ const messages = defineMessages({
id: 'content.selection-bar.bulk.deleting-waiting',
defaultMessage: 'Deleting {contentType}...',
},
allAlreadyEnabled: {
id: 'content.selection-bar.all-already-enabled',
defaultMessage: 'All selected content is already enabled',
},
allAlreadyDisabled: {
id: 'content.selection-bar.all-already-disabled',
defaultMessage: 'All selected content is already disabled',
},
})
interface Props {
@@ -95,6 +103,7 @@ const emit = defineEmits<{
const shown = computed(() => props.selectedItems.length > 0 || props.isBulkOperating)
const allDisabled = computed(() => props.selectedItems.every((m) => !m.enabled))
const allEnabled = computed(() => props.selectedItems.every((m) => m.enabled))
const selectedCountText = computed(() => {
const count = props.selectedItems.length || props.bulkTotal
@@ -135,12 +144,14 @@ const bulkProgressMessage = computed(() => {
<div class="mx-1 h-6 w-px bg-surface-5" />
<ButtonStyled type="transparent">
<button
v-tooltip="formatMessage(commonMessages.clearButton)"
class="!text-primary"
:disabled="isBulkOperating"
:class="{ 'opacity-60 pointer-events-none': isBulkOperating }"
@click="emit('clear')"
>
{{ formatMessage(commonMessages.clearButton) }}
<XIcon class="hidden cq-show-icon" />
<span class="bar-label">{{ formatMessage(commonMessages.clearButton) }}</span>
</button>
</ButtonStyled>
</div>
@@ -148,16 +159,30 @@ const bulkProgressMessage = computed(() => {
<div v-if="!isBulkOperating" class="ml-auto flex items-center gap-0.5">
<slot name="actions" />
<ButtonStyled v-if="allDisabled" type="transparent">
<button :disabled="isBusy" @click="emit('enable')">
<ButtonStyled type="transparent">
<button
v-tooltip="
allEnabled ? formatMessage(messages.allAlreadyEnabled) : formatMessage(messages.enable)
"
:disabled="isBusy || allEnabled"
@click="emit('enable')"
>
<PowerIcon />
{{ formatMessage(messages.enable) }}
<span class="bar-label">{{ formatMessage(messages.enable) }}</span>
</button>
</ButtonStyled>
<ButtonStyled v-else type="transparent">
<button :disabled="isBusy" @click="emit('disable')">
<ButtonStyled type="transparent">
<button
v-tooltip="
allDisabled
? formatMessage(messages.allAlreadyDisabled)
: formatMessage(messages.disable)
"
:disabled="isBusy || allDisabled"
@click="emit('disable')"
>
<PowerOffIcon />
{{ formatMessage(messages.disable) }}
<span class="bar-label">{{ formatMessage(messages.disable) }}</span>
</button>
</ButtonStyled>

View File

@@ -12,7 +12,7 @@
</Admonition>
<InlineBackupCreator
ref="backupCreator"
backup-name="Before bulk update"
:backup-name="backupTip ? `Before bulk update (${backupTip})` : 'Before bulk update'"
@update:buttons-disabled="buttonsDisabled = $event"
/>
</div>
@@ -73,6 +73,7 @@ const messages = defineMessages({
defineProps<{
count: number
server?: boolean
backupTip?: string
}>()
const emit = defineEmits<{

View File

@@ -15,7 +15,7 @@
</Admonition>
<InlineBackupCreator
ref="backupCreator"
backup-name="Before deletion"
:backup-name="backupTip ? `Before deletion (${backupTip})` : 'Before deletion'"
@update:buttons-disabled="buttonsDisabled = $event"
/>
</div>
@@ -78,9 +78,11 @@ withDefaults(
count: number
itemType: string
variant?: 'instance' | 'server'
backupTip?: string
}>(),
{
variant: 'instance',
backupTip: undefined,
},
)

View File

@@ -17,7 +17,7 @@
</Admonition>
<InlineBackupCreator
ref="backupCreator"
:backup-name="downgrade ? 'Before modpack downgrade' : 'Before modpack update'"
:backup-name="backupName"
@update:buttons-disabled="buttonsDisabled = $event"
/>
</div>
@@ -45,7 +45,7 @@
<script setup lang="ts">
import { DownloadIcon, XIcon } from '@modrinth/assets'
import { ref } from 'vue'
import { computed, ref } from 'vue'
import Admonition from '#ui/components/base/Admonition.vue'
import ButtonStyled from '#ui/components/base/ButtonStyled.vue'
@@ -55,13 +55,21 @@ import { commonMessages } from '#ui/utils/common-messages'
import InlineBackupCreator from './InlineBackupCreator.vue'
defineProps<{
const props = defineProps<{
downgrade?: boolean
server?: boolean
backupTip?: string
}>()
const { formatMessage } = useVIntl()
const backupName = computed(() => {
const action = props.downgrade ? 'downgrade' : 'update'
return props.backupTip
? `Before modpack ${action} (${props.backupTip})`
: `Before modpack ${action}`
})
const messages = defineMessages({
header: {
id: 'content.confirm-modpack-update.header',

View File

@@ -12,7 +12,7 @@
</Admonition>
<InlineBackupCreator
ref="backupCreator"
backup-name="Before reinstall"
:backup-name="backupTip ? `Before reinstall (${backupTip})` : 'Before reinstall'"
@update:buttons-disabled="buttonsDisabled = $event"
/>
</div>
@@ -72,6 +72,7 @@ const messages = defineMessages({
defineProps<{
server?: boolean
backupTip?: string
}>()
const emit = defineEmits<{

View File

@@ -12,7 +12,7 @@
</Admonition>
<InlineBackupCreator
ref="backupCreator"
backup-name="Before unlink"
:backup-name="backupTip ? `Before unlink (${backupTip})` : 'Before unlink'"
@update:buttons-disabled="buttonsDisabled = $event"
/>
</div>
@@ -50,6 +50,7 @@ import InlineBackupCreator from './InlineBackupCreator.vue'
defineProps<{
server?: boolean
backupTip?: string
}>()
const { formatMessage } = useVIntl()