All files / web/src/components/shared EmptyState.vue

0% Statements 0/33
100% Branches 1/1
100% Functions 1/1
0% Lines 0/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73                                                                                                                                                 
<script setup lang="ts">
import { computed } from 'vue'
import { ElButton, ElEmpty } from 'element-plus'
 
interface Props {
  description?: string
  searchQuery?: string
  actionText?: string
  actionType?: 'primary' | 'default'
  createText?: string
  itemName?: string
  isLoading?: boolean
}
 
const props = withDefaults(defineProps<Props>(), {
  actionType: 'primary',
  actionText: '',
  createText: 'Create First',
  itemName: 'item'
})
 
const emit = defineEmits<{
  action: []
  clearSearch: []
}>()
 
const computedDescription = computed(() => {
  if (props.description) return props.description
  return props.searchQuery
    ? `No ${props.itemName}s found matching your search`
    : `No ${props.itemName}s yet`
})
 
const computedActionText = computed(() => {
  if (props.actionText) return props.actionText
  return props.searchQuery ? 'Clear search' : `${props.createText} ${props.itemName}`
})
 
const computedActionType = computed(() => {
  return props.searchQuery ? 'default' : props.actionType
})
 
function handleAction() {
  if (props.searchQuery) {
    emit('clearSearch')
  } else {
    emit('action')
  }
}
</script>
 
<template>
  <div v-if="!isLoading" class="empty-state">
    <ElEmpty :description="computedDescription">
      <ElButton
        :type="computedActionType"
        @click="handleAction"
      >
        {{ computedActionText }}
      </ElButton>
    </ElEmpty>
  </div>
</template>
 
<style lang="scss" scoped>
.empty-state {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: var(--rf-size-xl);
  padding: var(--rf-spacing-xl);
}
</style>