update tags page + sort project types consistently (#7044)

This commit is contained in:
Prospector
2026-08-07 13:19:36 -07:00
committed by GitHub
parent a71a361e0f
commit 75335647ee
24 changed files with 452 additions and 470 deletions
@@ -15,20 +15,25 @@ const emit = defineEmits<{
(e: 'reset' | 'save', event: MouseEvent): void
}>()
type SaveDisabledReason = MessageDescriptor | string
const props = withDefaults(
defineProps<{
canReset?: boolean
canSave?: boolean
original: T
modified: Partial<T>
saving?: boolean
text?: MessageDescriptor | string
saveLabel?: MessageDescriptor | string
savingLabel?: MessageDescriptor | string
saveDisabledReason?: SaveDisabledReason | SaveDisabledReason[]
saveIcon?: Component
inline?: boolean
}>(),
{
canReset: true,
canSave: true,
saving: false,
text: () =>
defineMessage({
@@ -37,6 +42,7 @@ const props = withDefaults(
}),
saveLabel: () => commonMessages.saveButton,
savingLabel: () => commonMessages.savingButton,
saveDisabledReason: undefined,
saveIcon: SaveIcon,
inline: false,
},
@@ -50,6 +56,22 @@ function localizeIfPossible(message: MessageDescriptor | string) {
return typeof message === 'string' ? message : formatMessage(message)
}
const saveDisabled = computed(() => props.saving || !props.canSave)
const saveDisabledTooltip = computed(() => {
if (!saveDisabled.value || props.saving || !props.saveDisabledReason) {
return undefined
}
const reasons = (
Array.isArray(props.saveDisabledReason) ? props.saveDisabledReason : [props.saveDisabledReason]
).map(localizeIfPossible)
return reasons.length > 0
? { content: reasons.join('\n'), popperClass: 'unsaved-changes-save-tooltip' }
: undefined
})
const actionBar = ref<InstanceType<typeof FloatingActionBar> | null>(null)
function nudge(): void {
@@ -66,11 +88,32 @@ defineExpose({ nudge })
<Button v-if="canReset" type="quiet" :disabled="saving" @click="(e) => emit('reset', e)">
<HistoryIcon /> {{ formatMessage(commonMessages.resetButton) }}
</Button>
<Button type="colored" color="brand" :disabled="saving" @click="(e) => emit('save', e)">
<SpinnerIcon v-if="saving" class="animate-spin" />
<component :is="saveIcon" v-else />
{{ localizeIfPossible(saving ? savingLabel : saveLabel) }}
</Button>
<span
v-tooltip="saveDisabledTooltip"
class="flex"
:class="{ 'cursor-not-allowed': saveDisabled }"
>
<Button
type="colored"
color="brand"
:disabled="saveDisabled"
:class="{ 'pointer-events-none': saveDisabled }"
@click="(e) => emit('save', e)"
>
<SpinnerIcon v-if="saving" class="animate-spin" />
<component :is="saveIcon" v-else />
{{ localizeIfPossible(saving ? savingLabel : saveLabel) }}
</Button>
</span>
</div>
</FloatingActionBar>
</template>
<style lang="scss">
/* unscoped because floating-vue teleports the tooltip outside of scope */
.v-popper__popper.v-popper--theme-tooltip.unsaved-changes-save-tooltip .v-popper__inner {
max-width: 22rem;
white-space: pre-line;
line-height: 1.4;
}
</style>