row moves to step record component
This commit is contained in:
72
src/modules/record/components/StepRecord.vue
Normal file
72
src/modules/record/components/StepRecord.vue
Normal file
@@ -0,0 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import { useTaskStore } from '@/modules/task/stores/useTask.store'
|
||||
import { toISODate } from '@/shared/types/date'
|
||||
import { computed, onUnmounted, ref } from 'vue'
|
||||
import { useTaskRecordStore } from '../stores/useTaskRecordStore'
|
||||
|
||||
const props = defineProps<{
|
||||
taskId: string
|
||||
recordId: string
|
||||
stepId: string
|
||||
stepNumber: number
|
||||
}>()
|
||||
|
||||
const taskStore = useTaskStore()
|
||||
const recordStore = useTaskRecordStore()
|
||||
|
||||
const step = computed(() => taskStore.getStep(props.taskId, props.stepId))
|
||||
const stepRecord = computed(() =>
|
||||
recordStore.getStepRecord(props.recordId, props.stepId)
|
||||
)
|
||||
|
||||
const now = ref(toISODate(new Date()))
|
||||
|
||||
const id = setInterval(() => {
|
||||
now.value = toISODate(new Date())
|
||||
}, 1000)
|
||||
|
||||
onUnmounted(() => clearInterval(id))
|
||||
|
||||
const duration = computed(() => {
|
||||
if (!stepRecord.value) {
|
||||
return null
|
||||
}
|
||||
|
||||
const diffInMs =
|
||||
new Date(stepRecord.value?.end ?? now.value).getTime() -
|
||||
new Date(stepRecord.value.start).getTime()
|
||||
|
||||
// TODO: diff in minutes not in seconds
|
||||
return Math.round(diffInMs / 1000)
|
||||
})
|
||||
|
||||
const isSuperiorToEstimation = computed(() => {
|
||||
if (!step.value || !stepRecord.value || !duration.value) {
|
||||
return false
|
||||
}
|
||||
|
||||
return duration.value > step.value.estimation
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<tr
|
||||
v-if="step"
|
||||
class="step-record"
|
||||
:class="{ current: recordStore.currentStepId === stepId }"
|
||||
>
|
||||
<td>{{ stepNumber }}</td>
|
||||
<td>{{ step.title }}</td>
|
||||
<td class="estimation">{{ step.estimation }} minutes</td>
|
||||
<td v-if="stepRecord">
|
||||
<span v-if="isSuperiorToEstimation">⚠️</span>
|
||||
{{ duration }} minutes
|
||||
</td>
|
||||
<td v-else>NA</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.step-record {
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@ import { formatDate } from '@/shared/format-date'
|
||||
import { toISODate } from '@/shared/types/date'
|
||||
import { computed } from 'vue'
|
||||
import { useTaskRecordStore } from '../stores/useTaskRecordStore'
|
||||
import StepRecord from './StepRecord.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
taskId: string
|
||||
@@ -85,19 +86,14 @@ const nextStep = () => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
<StepRecord
|
||||
v-for="(step, key) in task.steps"
|
||||
:task-id="taskId"
|
||||
:record-id="recordId"
|
||||
:key="step.id"
|
||||
:class="{ current: recordStore.currentStepId === step.id }"
|
||||
>
|
||||
<td>{{ key + 1 }}</td>
|
||||
<td>{{ step.title }}</td>
|
||||
<td class="estimation">{{ step.estimation }} minutes</td>
|
||||
<td v-if="record.stepRecords[step.id]">
|
||||
{{ record.stepRecords[step.id] }} minutes
|
||||
</td>
|
||||
<td v-else>NA</td>
|
||||
</tr>
|
||||
:step-id="step.id"
|
||||
:step-number="key"
|
||||
/>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { ISODate } from '@/shared/types/date'
|
||||
|
||||
export interface StepRecordable {
|
||||
problems: string[]
|
||||
start: ISODate
|
||||
end?: ISODate
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ export const useTaskRecordStore = defineStore('task-record-store', {
|
||||
stepRecords: {
|
||||
...record.stepRecords,
|
||||
[params.stepId]: {
|
||||
problems: [],
|
||||
start: params.start
|
||||
}
|
||||
}
|
||||
@@ -86,15 +85,6 @@ export const useTaskRecordStore = defineStore('task-record-store', {
|
||||
endRecord(recordId: string) {
|
||||
this.records[recordId].end = toISODate(new Date())
|
||||
this.currentStepId = null
|
||||
},
|
||||
addProblemToStepRecord(recordId: string, stepId: string, problem: string) {
|
||||
const stepRecord = this.getStepRecord(recordId, stepId)
|
||||
|
||||
if (!stepRecord) {
|
||||
return
|
||||
}
|
||||
|
||||
stepRecord.problems.push(problem)
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@@ -118,6 +108,9 @@ export const useTaskRecordStore = defineStore('task-record-store', {
|
||||
return newTaskRecord
|
||||
}
|
||||
},
|
||||
getRecord() {
|
||||
return (recordId: string) => this.records?.[recordId] ?? null
|
||||
},
|
||||
getStepRecord() {
|
||||
return (recordId: string, stepId: string): StepRecordable | null =>
|
||||
this.records?.[recordId]?.stepRecords[stepId] ?? null
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import type { Taskable } from '../interfaces/taskable'
|
||||
import type { Step } from '../models/step'
|
||||
import { Task } from '../models/task'
|
||||
|
||||
export interface TaskStoreState {
|
||||
@@ -26,8 +27,12 @@ export const useTaskStore = defineStore('task-store', {
|
||||
.sort((a, b) => (a.date > b.date ? -1 : 1))
|
||||
},
|
||||
getTask() {
|
||||
return (taskId: string): Task | undefined =>
|
||||
this.recentTasks.find((task) => task.id === taskId)
|
||||
return (taskId: string): Task | null =>
|
||||
this.recentTasks.find((task) => task.id === taskId) ?? null
|
||||
},
|
||||
getStep() {
|
||||
return (taskId: string, stepId: string): Step | null =>
|
||||
this.getTask(taskId)?.steps.find((step) => step.id === stepId) ?? null
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user