Add notices system to Servers (#3502)

* Servers notices

* Refresh on unassign
This commit is contained in:
Prospector
2025-04-12 22:00:22 -07:00
committed by GitHub
parent 56520572b2
commit 59edc8d618
16 changed files with 1065 additions and 7 deletions

View File

@@ -2,14 +2,14 @@
<div v-bind="$attrs">
<button
v-if="!!slots.title"
:class="buttonClass ?? 'flex flex-col gap-2'"
:class="buttonClass ?? 'flex flex-col gap-2 bg-transparent m-0 p-0 border-none'"
@click="() => (isOpen ? close() : open())"
>
<slot name="button" :open="isOpen">
<div class="flex items-center w-full">
<div class="flex items-center gap-1 w-full">
<slot name="title" />
<DropdownIcon
class="ml-auto size-5 transition-transform duration-300 shrink-0 text-contrast"
class="ml-auto size-5 transition-transform duration-300 shrink-0"
:class="{ 'rotate-180': isOpen }"
/>
</div>

View File

@@ -10,13 +10,16 @@
:class="['hidden h-8 w-8 flex-none sm:block', iconClasses[type]]"
/>
<div class="flex flex-col gap-2">
<div class="font-semibold">
<div class="font-semibold flex justify-between gap-4">
<slot name="header">{{ header }}</slot>
</div>
<div class="font-normal">
<slot>{{ body }}</slot>
</div>
</div>
<div class="ml-auto w-fit">
<slot name="actions" />
</div>
</div>
</template>

View File

@@ -11,10 +11,10 @@
</h1>
<slot name="title-suffix" />
</div>
<p class="m-0 line-clamp-2 max-w-[40rem] empty:hidden">
<p v-if="$slots.summary" class="m-0 line-clamp-2 max-w-[40rem] empty:hidden">
<slot name="summary" />
</p>
<div class="mt-auto flex flex-wrap gap-4 empty:hidden">
<div v-if="$slots.stats" class="mt-auto flex flex-wrap gap-4 empty:hidden">
<slot name="stats" />
</div>
</div>

View File

@@ -0,0 +1,73 @@
<template>
<Admonition :type="NOTICE_TYPE[props.level]">
<template #header>
{{ formatMessage(heading) }}
</template>
<template #actions>
<ButtonStyled v-if="dismissable" circular>
<button
v-tooltip="formatMessage(messages.dismiss)"
@click="() => (preview ? {} : emit('dismiss'))"
>
<XIcon />
</button>
</ButtonStyled>
</template>
<div v-if="message" class="markdown-body" v-html="renderString(message)" />
</Admonition>
</template>
<script setup lang="ts">
import { renderString } from '@modrinth/utils'
import { Admonition } from '../index'
import { XIcon } from '@modrinth/assets'
import { defineMessages, type MessageDescriptor, useVIntl } from '@vintl/vintl'
import { computed } from 'vue'
import ButtonStyled from './ButtonStyled.vue'
const { formatMessage } = useVIntl()
const emit = defineEmits<{
(e: 'dismiss'): void
}>()
const props = withDefaults(
defineProps<{
level: string
message: string
dismissable: boolean
preview?: boolean
}>(),
{
preview: false,
},
)
const messages = defineMessages({
info: {
id: 'servers.notice.heading.info',
defaultMessage: 'Info',
},
attention: {
id: 'servers.notice.heading.attention',
defaultMessage: 'Attention',
},
dismiss: {
id: 'servers.notice.dismiss',
defaultMessage: 'Dismiss',
},
})
const NOTICE_HEADINGS: Record<string, MessageDescriptor> = {
info: messages.info,
warn: messages.attention,
critical: messages.attention,
}
const NOTICE_TYPE: Record<string, 'info' | 'warning' | 'critical'> = {
info: 'info',
warn: 'warning',
critical: 'critical',
}
const heading = computed(() => NOTICE_HEADINGS[props.level] ?? messages.info)
</script>

View File

@@ -30,6 +30,7 @@ export { default as ProjectCard } from './base/ProjectCard.vue'
export { default as RadialHeader } from './base/RadialHeader.vue'
export { default as RadioButtons } from './base/RadioButtons.vue'
export { default as ScrollablePanel } from './base/ScrollablePanel.vue'
export { default as ServerNotice } from './base/ServerNotice.vue'
export { default as SimpleBadge } from './base/SimpleBadge.vue'
export { default as Slider } from './base/Slider.vue'
export { default as StatItem } from './base/StatItem.vue'