<commit_before><template>
<div class="data-list">

  <div style="overflow: hidden">
    <table class="datatable" ref="headerWrapper">
      <thead class="datatable-head">
        <tr class="datatable-row-header">
          <th class="type">
            {{ $t('tasks.fields.task_type') }}
          </th>
          <th class="status">
            {{ $t('tasks.fields.task_status') }}
          </th>
          <th class="estimation">
            {{ $t('tasks.fields.estimation').substring(0, 3) }}.
          </th>
          <th class="duedate">
            {{ $t('tasks.fields.due_date') }}
          </th>
          <th class="assignees">
            {{ $t('tasks.fields.assignees') }}
          </th>
          <th class="end-cell"></th>
        </tr>
      </thead>
    </table>
  </div>

  <table-info
    :is-loading="isLoading"
    :is-error="isError"
  />

  <div v-scroll="onBodyScroll" v-if="entries.length > 0">
    <table class="datatable">
      <tbody class="datatable-body">
        <tr
          :key="typeof (taskId) === 'string' ? taskId : taskId.id"
          :class="{
            selected: currentTask && currentTask.id === taskId,
            'datatable-row': true,
            'datatable-row--selectable': true
          }"
          @click="selectTask(getTask(taskId))"
          v-for="taskId in sortedEntries"
        >
          <task-type-cell
            class="type"
            :task-type="getTaskType(taskId)"
            :production-id="currentProduction.id"
            v-if="getTaskType(taskId)"
          />
          <td class="status">
            <validation-tag
              :task="getTask(taskId)"
              :is-static="true"
              v-if="getTask(taskId)"
            />
          </td>
          <td class="estimation">
            {{ getTaskEstimation(taskId) }}
          </td>
          <td class="duedate">
            {{ getTaskDueDate(taskId) }}
          </td>
          <td class="assignees">
            <div
              class="flexrow"
              v-if="!isCurrentUserClient && !isCurrentUserVendor"
            >
              <div
                class="avatar-wrapper"
                :key="personId"
                v-for="personId in getAssignees(taskId)"
              >
                <people-avatar
                  class="person-avatar flexrow-item"
                  :key="taskId + '-' + personId"
                  :person="personMap.get(personId)"
                  :size="30"
                  :font-size="15"
                />
              </div>
            </div>
          </td>
          <td class="end-cell"></td>
       </tr>
      </tbody>
    </table>
  </div>

</div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'

import { formatListMixin } from '@/components/mixins/format'

import TaskTypeCell from '../cells/TaskTypeName'
import TableInfo from '../widgets/TableInfo'
import ValidationTag from '../widgets/ValidationTag'
import PeopleAvatar from '../widgets/PeopleAvatar'

export default {
  name: 'entity-task-list',
  mixins: [formatListMixin],

  components: {
    TableInfo,
    TaskTypeCell,
    PeopleAvatar,
    ValidationTag
  },

  props: {
    entries: {
      type: Array,
      default: () => []
    },
    isLoading: {
      type: Boolean,
      default: false
    },
    isError: {
      type: Boolean,
      default: false
    }
  },

  data () {
    return {
      currentTask: null
    }
  },

  computed: {
    ...mapGetters([
      'currentProduction',
      'isCurrentUserClient',
      'isCurrentUserVendor',
      'personMap',
      'taskMap',
      'taskTypeMap'
    ]),

    sortedEntries () {
      return [...this.entries].sort((taskIdA, taskIdB) => {
        const taskA = this.getTask(taskIdA)
        const taskB = this.getTask(taskIdB)
        const taskTypeA =
          this.getTask(this.taskTypeMap.get(taskA.task_type_id))
        const taskTypeB =
          this.getTask(this.taskTypeMap.get(taskB.task_type_id))
        if (taskTypeA.priority === taskTypeB.priority) {
          return this.taskTypeA.localeCompare(this.taskTypeB.name)
        } else {
          return taskTypeA.priority - taskTypeB.priority
        }
      })
    }
  },

  methods: {
    ...mapActions([
    ]),

    onBodyScroll (event, position) {
      this.$refs.headerWrapper.style.left = `-${position.scrollLeft}px`
    },

    getTask (task) {
      if (typeof (task) === 'string') {
        return this.taskMap.get(task)
      } else {
        return task
      }
    },

    getTaskDueDate (taskId) {
      const task = this.getTask(taskId)
      return task && task.due_date
        ? task.due_date.substring(0, 10)
        : ''
    },

    getTaskEstimation (taskId) {
      const task = this.getTask(taskId)
      return task && task.estimation
        ? this.formatDuration(task.estimation)
        : ''
    },

    getTaskType (entry) {
      const task = this.getTask(entry)
      return task ? this.taskTypeMap.get(task.task_type_id) : null
    },

    getAssignees (entry) {
      const task = this.getTask(entry)
      return task ? task.assignees : []
    },

    selectTask (task) {
      this.currentTask = task
      this.$emit('task-selected', task)
    }
  }
}
</script>

<style lang="scss" scoped>
.data-list {
  max-width: 500px;
  margin-top: 0;
}

.type {
  max-width: 250px;
  min-width: 250px;
}<commit_msg>[entities] Add task duration to entity pages infos<commit_after><template>
<div class="data-list">

  <div style="overflow: hidden">
    <table class="datatable" ref="headerWrapper">
      <thead class="datatable-head">
        <tr class="datatable-row-header">
          <th class="type">
            {{ $t('tasks.fields.task_type') }}
          </th>
          <th class="status">
            {{ $t('tasks.fields.task_status') }}
          </th>
          <th class="estimation">
            {{ $t('tasks.fields.estimation').substring(0, 3) }}.
          </th>
          <th class="estimation">
            {{ $t('tasks.fields.duration').substring(0, 3) }}.
          </th>
          <th class="duedate">
            {{ $t('tasks.fields.due_date') }}
          </th>
          <th class="assignees">
            {{ $t('tasks.fields.assignees') }}
          </th>
          <th class="end-cell"></th>
        </tr>
      </thead>
    </table>
  </div>

  <table-info
    :is-loading="isLoading"
    :is-error="isError"
  />

  <div v-scroll="onBodyScroll" v-if="entries.length > 0">
    <table class="datatable">
      <tbody class="datatable-body">
        <tr
          :key="typeof (taskId) === 'string' ? taskId : taskId.id"
          :class="{
            selected: currentTask && currentTask.id === taskId,
            'datatable-row': true,
            'datatable-row--selectable': true
          }"
          @click="selectTask(getTask(taskId))"
          v-for="taskId in sortedEntries"
        >
          <task-type-cell
            class="type"
            :task-type="getTaskType(taskId)"
            :production-id="currentProduction.id"
            v-if="getTaskType(taskId)"
          />
          <td class="status">
            <validation-tag
              :task="getTask(taskId)"
              :is-static="true"
              v-if="getTask(taskId)"
            />
          </td>
          <td class="estimation">
            {{ getTaskEstimation(taskId) }}
          </td>
          <td class="estimation">
            {{ getTaskDuration(taskId) }}
          </td>
          <td class="duedate">
            {{ getTaskDueDate(taskId) }}
          </td>
          <td class="assignees">
            <div
              class="flexrow"
              v-if="!isCurrentUserClient && !isCurrentUserVendor"
            >
              <div
                class="avatar-wrapper"
                :key="personId"
                v-for="personId in getAssignees(taskId)"
              >
                <people-avatar
                  class="person-avatar flexrow-item"
                  :key="taskId + '-' + personId"
                  :person="personMap.get(personId)"
                  :size="30"
                  :font-size="15"
                />
              </div>
            </div>
          </td>
          <td class="end-cell"></td>
       </tr>
      </tbody>
    </table>
  </div>

</div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'

import { formatListMixin } from '@/components/mixins/format'

import TaskTypeCell from '../cells/TaskTypeName'
import TableInfo from '../widgets/TableInfo'
import ValidationTag from '../widgets/ValidationTag'
import PeopleAvatar from '../widgets/PeopleAvatar'

export default {
  name: 'entity-task-list',
  mixins: [formatListMixin],

  components: {
    TableInfo,
    TaskTypeCell,
    PeopleAvatar,
    ValidationTag
  },

  props: {
    entries: {
      type: Array,
      default: () => []
    },
    isLoading: {
      type: Boolean,
      default: false
    },
    isError: {
      type: Boolean,
      default: false
    }
  },

  data () {
    return {
      currentTask: null
    }
  },

  computed: {
    ...mapGetters([
      'currentProduction',
      'isCurrentUserClient',
      'isCurrentUserVendor',
      'personMap',
      'taskMap',
      'taskTypeMap'
    ]),

    sortedEntries () {
      return [...this.entries].sort((taskIdA, taskIdB) => {
        const taskA = this.getTask(taskIdA)
        const taskB = this.getTask(taskIdB)
        const taskTypeA =
          this.getTask(this.taskTypeMap.get(taskA.task_type_id))
        const taskTypeB =
          this.getTask(this.taskTypeMap.get(taskB.task_type_id))
        if (taskTypeA.priority === taskTypeB.priority) {
          return this.taskTypeA.localeCompare(this.taskTypeB.name)
        } else {
          return taskTypeA.priority - taskTypeB.priority
        }
      })
    }
  },

  methods: {
    ...mapActions([
    ]),

    onBodyScroll (event, position) {
      this.$refs.headerWrapper.style.left = `-${position.scrollLeft}px`
    },

    getTask (task) {
      if (typeof (task) === 'string') {
        return this.taskMap.get(task)
      } else {
        return task
      }
    },

    getTaskDueDate (taskId) {
      const task = this.getTask(taskId)
      return task && task.due_date
        ? task.due_date.substring(0, 10)
        : ''
    },

    getTaskEstimation (taskId) {
      const task = this.getTask(taskId)
      return task && task.estimation
        ? this.formatDuration(task.estimation)
        : ''
    },

    getTaskDuration (taskId) {
      const task = this.getTask(taskId)
      return task && task.duration
        ? this.formatDuration(task.duration)
        : ''
    },

    getTaskType (entry) {
      const task = this.getTask(entry)
      return task ? this.taskTypeMap.get(task.task_type_id) : null
    },

    getAssignees (entry) {
      const task = this.getTask(entry)
      return task ? task.assignees : []
    },

    selectTask (task) {
      this.currentTask = task
      this.$emit('task-selected', task)
    }
  }
}
</script>

<style lang="scss" scoped>
.data-list {
  max-width: 500px;
  margin-top: 0;
}

.type {
  max-width: 250px;
  min-width: 250px;
}
{'fraction_non_alphanumeric': 0.14760280122104508, 'fraction_numerical': 0.0037708744837493266, 'mean_word_length': 1.7599108027750248, 'pattern_counts': {'":': 0, '<': 113, '<?xml version=': 0, '>': 119, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4925210', 'n_tokens_mistral': 3566, 'n_tokens_neox': 3438, 'n_words': 593}