106 lines
3.0 KiB
Vue
106 lines
3.0 KiB
Vue
|
|
<script setup lang="ts">
|
|||
|
|
import { computed, ref } from 'vue';
|
|||
|
|
import { useRouterPush } from '@/hooks/common/router';
|
|||
|
|
import { type WorkbenchMyTaskBucket, buildWorkbenchMyTaskItems, filterWorkbenchMyTaskItems } from '../homepage';
|
|||
|
|
import { workbenchMyTaskMock } from '../mock';
|
|||
|
|
import WorkbenchModuleCard from './workbench-module-card.vue';
|
|||
|
|
|
|||
|
|
interface Props {
|
|||
|
|
editing?: boolean;
|
|||
|
|
collapsed?: boolean;
|
|||
|
|
}
|
|||
|
|
withDefaults(defineProps<Props>(), { editing: false, collapsed: false });
|
|||
|
|
defineEmits<{ (e: 'hide'): void; (e: 'toggle-collapse'): void; (e: 'refresh'): void }>();
|
|||
|
|
|
|||
|
|
const { routerPushByKey } = useRouterPush();
|
|||
|
|
|
|||
|
|
const allItems = computed(() => buildWorkbenchMyTaskItems(workbenchMyTaskMock));
|
|||
|
|
const bucket = ref<WorkbenchMyTaskBucket>('today');
|
|||
|
|
const visibleItems = computed(() => filterWorkbenchMyTaskItems(allItems.value, bucket.value));
|
|||
|
|
|
|||
|
|
function handleClickItem() {
|
|||
|
|
routerPushByKey('project_list');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function handleRefresh() {
|
|||
|
|
window.$message?.success('已刷新(v1 mock)');
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<template>
|
|||
|
|
<WorkbenchModuleCard
|
|||
|
|
title="我的任务"
|
|||
|
|
icon="mdi:checkbox-marked-circle-outline"
|
|||
|
|
:badge-count="visibleItems.length"
|
|||
|
|
:editing="editing"
|
|||
|
|
:collapsed="collapsed"
|
|||
|
|
@hide="$emit('hide')"
|
|||
|
|
@toggle-collapse="$emit('toggle-collapse')"
|
|||
|
|
@navigate="handleClickItem"
|
|||
|
|
@refresh="handleRefresh"
|
|||
|
|
>
|
|||
|
|
<ElTabs v-model="bucket" class="my-task-tabs">
|
|||
|
|
<ElTabPane label="今日" name="today" />
|
|||
|
|
<ElTabPane label="本周" name="week" />
|
|||
|
|
<ElTabPane label="逾期" name="overdue" />
|
|||
|
|
<ElTabPane label="全部" name="all" />
|
|||
|
|
</ElTabs>
|
|||
|
|
<ul v-if="visibleItems.length" class="my-task-list">
|
|||
|
|
<li v-for="item in visibleItems" :key="item.id" class="my-task-item" @click="handleClickItem">
|
|||
|
|
<ElTag size="small" :type="item.overdue ? 'danger' : 'info'">{{ item.statusLabel }}</ElTag>
|
|||
|
|
<span class="my-task-title">{{ item.title }}</span>
|
|||
|
|
<span class="my-task-meta">{{ item.projectName }} · {{ item.executionName }}</span>
|
|||
|
|
<span class="my-task-deadline" :class="{ overdue: item.overdue }">{{ item.deadlineLabel }}</span>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
<ElEmpty v-else description="暂无任务" :image-size="60" />
|
|||
|
|
</WorkbenchModuleCard>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<style scoped>
|
|||
|
|
.my-task-tabs {
|
|||
|
|
margin-bottom: 4px;
|
|||
|
|
}
|
|||
|
|
.my-task-list {
|
|||
|
|
list-style: none;
|
|||
|
|
margin: 0;
|
|||
|
|
padding: 0;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
gap: 6px;
|
|||
|
|
}
|
|||
|
|
.my-task-item {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: auto 1fr auto;
|
|||
|
|
grid-template-rows: auto auto;
|
|||
|
|
gap: 2px 8px;
|
|||
|
|
padding: 8px 10px;
|
|||
|
|
border-radius: 6px;
|
|||
|
|
cursor: pointer;
|
|||
|
|
background: var(--el-fill-color-lighter);
|
|||
|
|
transition: background 120ms;
|
|||
|
|
}
|
|||
|
|
.my-task-item:hover {
|
|||
|
|
background: var(--el-color-primary-light-9);
|
|||
|
|
}
|
|||
|
|
.my-task-title {
|
|||
|
|
font-weight: 500;
|
|||
|
|
}
|
|||
|
|
.my-task-meta {
|
|||
|
|
grid-column: 2 / 3;
|
|||
|
|
font-size: 12px;
|
|||
|
|
color: var(--el-text-color-secondary);
|
|||
|
|
}
|
|||
|
|
.my-task-deadline {
|
|||
|
|
grid-column: 3 / 4;
|
|||
|
|
grid-row: 1 / 3;
|
|||
|
|
align-self: center;
|
|||
|
|
font-size: 12px;
|
|||
|
|
color: var(--el-text-color-secondary);
|
|||
|
|
}
|
|||
|
|
.my-task-deadline.overdue {
|
|||
|
|
color: var(--el-color-danger);
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
</style>
|