The-3Labs-Team/nova-busy-resource-field

View on GitHub
resources/js/components/IndexField.vue

Summary

Maintainability
Test Coverage
<template>
  <div v-if="fieldData" :class="'details-box-'+fieldData.pivot.busiable_id"
       class="absolute bg-white p-4 rounded-lg shadow-lg hidden"
       style="transform: translate(40px, -25px); z-index: 5;">
    <div class="absolute"
         style="top: 50%; right: 100%; transform: translateY(-50%); border-top: 10px solid transparent; border-right: 20px solid white; border-bottom: 10px solid transparent;"></div>
    <p class="relative z-2">
      <span class="text-base">Occupied by <span class="font-bold">{{ fieldData.name }}</span></span>
      <br>
      <span class="text-xs tracking-wide">Last activity: {{ lastUpdate }}</span>
    </p>
  </div>

  <svg v-if="field.isBusy" class="w-6 h-6" fill="none" stroke="currentColor" stroke-width="1.5"
       viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" @mouseout="showDetails" @mouseover="showDetails">
    <path :class="field.isBusyByCurrentUser ? 'text-yellow-500' : 'text-red-500'"
          d="M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z"
          stroke-linecap="round"
          stroke-linejoin="round"/>
  </svg>

  <svg v-else class="w-6 h-6" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"
       xmlns="http://www.w3.org/2000/svg">
    <path
        d="M13.5 10.5V6.75a4.5 4.5 0 1 1 9 0v3.75M3.75 21.75h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H3.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z"
        stroke-linecap="round" stroke-linejoin="round"
        style="color: #b5b5b5;"/>
  </svg>
</template>

<script>
export default {
  props: ['resourceName', 'resource', 'field'],

  data() {
    return {
      fieldData: null,
      lastUpdate: null
    };
  },

  methods: {
    async fetchData() {
      try {
        const response = await fetch('/nova-vendor/the-3labs-team/nova-busy-resource-field/is-busy', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
          },
          body: JSON.stringify({
            'model-id': this.resource.id.value,
            'model-name': this.$page.props.resourceName,
          }),
        });

        const responseData = await response.json();

        if (responseData.success) {
          this.fieldData = responseData.data;
          this.lastUpdate = responseData.lastUpdate;
          this.setTableRowBgColor(this.fieldData.pivot.busiable_id);
        }
      } catch (error) {
        console.error(error);
      }
    },

    showDetails() {
      const detailsBox = document.querySelector('.details-box-' + this.fieldData.pivot.busiable_id);
      detailsBox.classList.toggle('hidden');
    },

    setTableRowBgColor(id) {
      const tableRow = document.querySelector(`[dusk="${id}-row"]`);
      tableRow.querySelectorAll('td').forEach((td) => {
        td.classList.add('active-row');
      });
      tableRow.classList.remove('group');
    }
  },

  mounted() {
    this.fetchData();
  }
};
</script>