73 lines
1.6 KiB
Vue
73 lines
1.6 KiB
Vue
<script setup lang="ts">
|
|
import { t } from '@/i18n'
|
|
import { computed } from 'vue'
|
|
|
|
const props = defineProps<{
|
|
count: number
|
|
problems: number
|
|
saving: boolean
|
|
conflicted: boolean
|
|
canSave: boolean
|
|
nameMissing: boolean
|
|
isNew: boolean
|
|
}>()
|
|
|
|
defineEmits<{ discard: []; save: [] }>()
|
|
|
|
const message = computed(() => {
|
|
if (props.saving) {
|
|
return t('Saving…')
|
|
}
|
|
if (props.conflicted) {
|
|
return props.count === 1
|
|
? t('1 unsaved change. Save is off until you reload')
|
|
: t('{0} unsaved changes. Save is off until you reload', [props.count])
|
|
}
|
|
if (props.problems > 0) {
|
|
return props.problems === 1
|
|
? t('1 problem to fix')
|
|
: t('{0} problems to fix', [props.problems])
|
|
}
|
|
const count =
|
|
props.count === 0
|
|
? ''
|
|
: props.count === 1
|
|
? t('1 unsaved change')
|
|
: t('{0} unsaved changes', [props.count])
|
|
if (props.isNew && props.nameMissing) {
|
|
return count === ''
|
|
? t('Name your role to save it')
|
|
: `${count} · ${t('Name your role to save it')}`
|
|
}
|
|
return count
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
data-testid="role-save-bar"
|
|
class="flex items-center justify-between gap-3 border-t border-default bg-default px-4 py-3"
|
|
>
|
|
<span role="status" class="text-sm text-highlighted">{{ message }}</span>
|
|
<div class="flex items-center gap-2">
|
|
<UButton
|
|
color="neutral"
|
|
variant="outline"
|
|
class="h-11 px-3 md:h-8"
|
|
:disabled="saving"
|
|
@click="$emit('discard')"
|
|
>
|
|
{{ t('Discard') }}
|
|
</UButton>
|
|
<UButton
|
|
class="h-11 px-3 md:h-8"
|
|
:loading="saving"
|
|
:disabled="!canSave"
|
|
@click="$emit('save')"
|
|
>
|
|
{{ t('Save changes') }}
|
|
</UButton>
|
|
</div>
|
|
</div>
|
|
</template>
|