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 { toISODate } from '@/shared/types/date'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useTaskRecordStore } from '../stores/useTaskRecordStore'
|
import { useTaskRecordStore } from '../stores/useTaskRecordStore'
|
||||||
|
import StepRecord from './StepRecord.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
taskId: string
|
taskId: string
|
||||||
@@ -85,19 +86,14 @@ const nextStep = () => {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<StepRecord
|
||||||
v-for="(step, key) in task.steps"
|
v-for="(step, key) in task.steps"
|
||||||
|
:task-id="taskId"
|
||||||
|
:record-id="recordId"
|
||||||
:key="step.id"
|
:key="step.id"
|
||||||
:class="{ current: recordStore.currentStepId === step.id }"
|
:step-id="step.id"
|
||||||
>
|
:step-number="key"
|
||||||
<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>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { ISODate } from '@/shared/types/date'
|
import type { ISODate } from '@/shared/types/date'
|
||||||
|
|
||||||
export interface StepRecordable {
|
export interface StepRecordable {
|
||||||
problems: string[]
|
|
||||||
start: ISODate
|
start: ISODate
|
||||||
end?: ISODate
|
end?: ISODate
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ export const useTaskRecordStore = defineStore('task-record-store', {
|
|||||||
stepRecords: {
|
stepRecords: {
|
||||||
...record.stepRecords,
|
...record.stepRecords,
|
||||||
[params.stepId]: {
|
[params.stepId]: {
|
||||||
problems: [],
|
|
||||||
start: params.start
|
start: params.start
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,15 +85,6 @@ export const useTaskRecordStore = defineStore('task-record-store', {
|
|||||||
endRecord(recordId: string) {
|
endRecord(recordId: string) {
|
||||||
this.records[recordId].end = toISODate(new Date())
|
this.records[recordId].end = toISODate(new Date())
|
||||||
this.currentStepId = null
|
this.currentStepId = null
|
||||||
},
|
|
||||||
addProblemToStepRecord(recordId: string, stepId: string, problem: string) {
|
|
||||||
const stepRecord = this.getStepRecord(recordId, stepId)
|
|
||||||
|
|
||||||
if (!stepRecord) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
stepRecord.problems.push(problem)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
@@ -118,6 +108,9 @@ export const useTaskRecordStore = defineStore('task-record-store', {
|
|||||||
return newTaskRecord
|
return newTaskRecord
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getRecord() {
|
||||||
|
return (recordId: string) => this.records?.[recordId] ?? null
|
||||||
|
},
|
||||||
getStepRecord() {
|
getStepRecord() {
|
||||||
return (recordId: string, stepId: string): StepRecordable | null =>
|
return (recordId: string, stepId: string): StepRecordable | null =>
|
||||||
this.records?.[recordId]?.stepRecords[stepId] ?? null
|
this.records?.[recordId]?.stepRecords[stepId] ?? null
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import type { Taskable } from '../interfaces/taskable'
|
import type { Taskable } from '../interfaces/taskable'
|
||||||
|
import type { Step } from '../models/step'
|
||||||
import { Task } from '../models/task'
|
import { Task } from '../models/task'
|
||||||
|
|
||||||
export interface TaskStoreState {
|
export interface TaskStoreState {
|
||||||
@@ -26,8 +27,12 @@ export const useTaskStore = defineStore('task-store', {
|
|||||||
.sort((a, b) => (a.date > b.date ? -1 : 1))
|
.sort((a, b) => (a.date > b.date ? -1 : 1))
|
||||||
},
|
},
|
||||||
getTask() {
|
getTask() {
|
||||||
return (taskId: string): Task | undefined =>
|
return (taskId: string): Task | null =>
|
||||||
this.recentTasks.find((task) => task.id === taskId)
|
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