mirror of
https://github.com/modrinth/code.git
synced 2026-08-25 09:04:55 +00:00
feat: install flow improvements (#6669)
* feat: better error handling + copy details btn for info * refactor: clean up error handling into diagnostics * feat: extra info for failure states + queuing properly * fix: cleanup * fix: lint * fix: fmt * fix: cleanup * fix: cleanup * fix: lint * feat: use bon builder
This commit is contained in:
@@ -50,10 +50,9 @@
|
||||
:progress-type="progressItem.progressType"
|
||||
:progress-current="progressItem.progressCurrent"
|
||||
:progress-total="progressItem.progressTotal"
|
||||
:action-label="progressItem.buttons?.[0]?.label"
|
||||
:action-icon="progressItem.buttons?.[0]?.icon"
|
||||
:actions="progressItem.buttons"
|
||||
@dismiss="handleProgressItemDismiss(item, progressItem)"
|
||||
@action="handleProgressItemAction(progressItem)"
|
||||
@action="(index) => handleProgressItemAction(progressItem, index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -233,8 +232,11 @@ async function handleProgressItemDismiss(
|
||||
dismiss(item.id)
|
||||
}
|
||||
|
||||
async function handleProgressItemAction(progressItem: PopupNotificationProgressItem) {
|
||||
const button = progressItem.buttons?.[0]
|
||||
async function handleProgressItemAction(
|
||||
progressItem: PopupNotificationProgressItem,
|
||||
index: number,
|
||||
) {
|
||||
const button = progressItem.buttons?.[index]
|
||||
if (button) {
|
||||
await handleProgressItemButtonClick(progressItem, button)
|
||||
}
|
||||
@@ -250,8 +252,8 @@ async function handleProgressItemButtonClick(
|
||||
}
|
||||
}
|
||||
|
||||
function handleButtonClick(id: string | number, btn: PopupNotificationButton) {
|
||||
btn.action()
|
||||
async function handleButtonClick(id: string | number, btn: PopupNotificationButton) {
|
||||
await btn.action()
|
||||
if (!btn.keepOpen) {
|
||||
popupNotificationManager.removeNotification(id)
|
||||
}
|
||||
|
||||
@@ -138,13 +138,17 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="type === 'instance-download' && actionLabel"
|
||||
class="col-start-1 row-start-3 mt-2 flex min-w-0 items-center gap-2"
|
||||
v-if="type === 'instance-download' && actions?.length"
|
||||
class="col-start-1 col-end-3 row-start-3 mt-2 flex min-w-0 flex-wrap items-center gap-2"
|
||||
>
|
||||
<ButtonStyled color="brand">
|
||||
<button @click="$emit('action')">
|
||||
<component :is="actionIcon" v-if="actionIcon" />
|
||||
{{ actionLabel }}
|
||||
<ButtonStyled
|
||||
v-for="(action, index) in actions"
|
||||
:key="index"
|
||||
:color="action.color || (index === 0 ? 'brand' : undefined)"
|
||||
>
|
||||
<button class="!shadow-none" @click="$emit('action', index)">
|
||||
<component :is="action.icon" v-if="action.icon" />
|
||||
{{ action.label }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
@@ -172,10 +176,10 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { XIcon } from '@modrinth/assets'
|
||||
import { type Component, computed, ref } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { useFormatBytes, useFormatNumber } from '../../composables'
|
||||
import type { PopupNotificationProgressType } from '../../providers'
|
||||
import type { PopupNotificationButton, PopupNotificationProgressType } from '../../providers'
|
||||
import { truncatedTooltip } from '../../utils/truncate'
|
||||
import Avatar from '../base/Avatar.vue'
|
||||
import ButtonStyled from '../base/ButtonStyled.vue'
|
||||
@@ -202,8 +206,7 @@ const props = withDefaults(
|
||||
progressType?: PopupNotificationProgressType
|
||||
progressCurrent?: number
|
||||
progressTotal?: number
|
||||
actionLabel?: string
|
||||
actionIcon?: Component
|
||||
actions?: PopupNotificationButton[]
|
||||
}>(),
|
||||
{
|
||||
actorName: null,
|
||||
@@ -221,7 +224,7 @@ defineEmits<{
|
||||
accept: []
|
||||
decline: []
|
||||
dismiss: []
|
||||
action: []
|
||||
action: [index: number]
|
||||
launch: []
|
||||
'open-actor': []
|
||||
'open-instance': []
|
||||
|
||||
@@ -4,7 +4,7 @@ import { createContext } from '.'
|
||||
|
||||
export interface PopupNotificationButton {
|
||||
label: string
|
||||
action: () => void
|
||||
action: () => void | Promise<void>
|
||||
icon?: Component
|
||||
color?: 'brand' | 'red' | 'orange' | 'green' | 'blue' | 'standard'
|
||||
keepOpen?: boolean
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { MinecraftServerIcon } from '@modrinth/assets'
|
||||
import { CopyIcon, MinecraftServerIcon, UpdatedIcon } from '@modrinth/assets'
|
||||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
|
||||
import { NotificationToast } from '../../components/notifications'
|
||||
import type { PopupNotificationButton } from '../../providers'
|
||||
|
||||
const avatarUrl =
|
||||
'https://cdn.modrinth.com/user/6Qo4A5QT/9d81be1a9fb1afd163b7f2f05a791955e7693c90.png'
|
||||
@@ -205,3 +206,43 @@ export const DownloadProgressLabels: Story = {
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
export const FailedDownloadActions: Story = {
|
||||
render: () => ({
|
||||
components: { NotificationToast },
|
||||
setup() {
|
||||
return {
|
||||
instanceIconUrl: MinecraftServerIcon,
|
||||
actions: [
|
||||
{
|
||||
label: 'Retry',
|
||||
icon: UpdatedIcon,
|
||||
color: 'brand',
|
||||
action: noop,
|
||||
},
|
||||
{
|
||||
label: 'Copy details',
|
||||
icon: CopyIcon,
|
||||
color: 'standard',
|
||||
action: noop,
|
||||
},
|
||||
] satisfies PopupNotificationButton[],
|
||||
noop,
|
||||
}
|
||||
},
|
||||
template: /* html */ `
|
||||
<NotificationToast
|
||||
type="instance-download"
|
||||
entity-name="Cobblemon Official Modpack"
|
||||
:entity-icon-url="instanceIconUrl"
|
||||
status-text="Failed while downloading content."
|
||||
:progress="0"
|
||||
:show-progress="false"
|
||||
wrap-text
|
||||
:actions="actions"
|
||||
@action="(index) => actions[index].action()"
|
||||
@dismiss="noop"
|
||||
/>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user