<template>
  <q-btn v-if="hasPermission()" flat padding="xs" round size="1em" icon="more_vert" class="action-menu">
    <q-menu :max-width="maxWidth">
      <q-list dense :style="{ 'min-width': minWidth }">
        <template v-for="(item, index) in actions" :key="index" >
          <q-item v-if="isAction(item)" v-permissions="item.permission" :disable="isFunction(item.disable) ? item.disable(row) : item.disable"
            :class="item.class" clickable v-close-popup @click="item.action(row)">
            <q-item-section side style="color: inherit;">
              <q-icon size="1.2em" :name="item.icon" />
            </q-item-section>
            <q-item-section>{{ item.label }}</q-item-section>
            <q-tooltip v-if="item.tooltip && !isFunction(item.tooltip) || (isFunction(item.tooltip) && item.tooltip(row))" :delay="500" self="center middle">
              {{ isFunction(item.tooltip) ? item.tooltip(row) : item.tooltip }}
            </q-tooltip>
          </q-item>
          <q-separator v-else />
        </template>
      </q-list>
    </q-menu>
  </q-btn>
</template>

<script lang="ts">
import { PropType, getCurrentInstance } from 'vue';
import { IDomainOwnerDisplay } from '../types/DomainTypes';

interface Action {
  label: string;
  icon?: string;
  tooltip?: string|((row: IDomainOwnerDisplay) => string);
  disable?: boolean|((row: IDomainOwnerDisplay) => boolean);
  permission?: string|object;
  action: (row: any) => void|Promise<void>;
  class?: string;
}
interface Separator {
  separator: boolean;
}
type MenuItem = Action | Separator;

export default {
  name: 'TableActionMenu',
  props: {
    row: {
      type: Object as PropType<IDomainOwnerDisplay>,
      required: true
    },
    maxWidth: {
      type: String,
      default: '150px'
    },
    minWidth: {
      type: String,
      default: '100px'
    },
    actions: {
      type: Array as PropType<MenuItem[]>,
      required: true
    }
  },
  methods: {
    isAction(item: MenuItem): item is Action {
      return !('separator' in item);
    },

    isFunction(item: any): item is ((row: IDomainOwnerDisplay) => boolean|string) {
      return typeof item === 'function';
    },

    hasPermission() {
      const proxy = getCurrentInstance()?.proxy;
      if (!proxy) {
        return false;
      }
      for (const item of this.actions) {
        if (this.isAction(item) && proxy.$hasPermission(item.permission)) {
          return true;
        }
      }
    }
  }
};
</script>
<style lang="scss" scoped>
.q-table tr > td:last-child .action-menu {
  opacity: 0.25 !important;
}

.q-table tr:hover > td:last-child .action-menu:not([disabled]) {
  opacity: 1 !important;
}
</style>
