release(main): 同步 dev 最新候选改动
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
This commit is contained in:
@@ -1,16 +1,9 @@
|
||||
<template>
|
||||
<div class="page ctms-page-shell page--flush">
|
||||
<div v-if="study.currentStudy" class="unified-shell ctms-table-card">
|
||||
<section class="unified-action-bar bar--flush">
|
||||
<section class="unified-action-bar milestone-action-bar">
|
||||
<div class="card-header ctms-page-header-row">
|
||||
<div>
|
||||
<div class="card-title">{{ TEXT.modules.projectMilestones.listTitle }}</div>
|
||||
<div class="card-subtitle">
|
||||
{{ TEXT.modules.projectMilestones.sourceLabel }}{{ dataSourceLabel }}
|
||||
<span class="dot-sep">·</span>
|
||||
{{ TEXT.common.labels.updatedAt }}{{ updatedAtLabel }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-title">{{ TEXT.modules.projectMilestones.listTitle }}</div>
|
||||
<div class="header-actions">
|
||||
<el-tag size="small" effect="plain">
|
||||
{{ TEXT.modules.projectMilestones.statTotal }}{{ rows.length }}
|
||||
@@ -200,7 +193,6 @@ import { useStudyStore } from "../../store/study";
|
||||
import { listProjectMilestones, updateProjectMilestone } from "../../api/projectMilestones";
|
||||
import { TEXT } from "../../locales";
|
||||
import StateEmpty from "../../components/StateEmpty.vue";
|
||||
import { displayDateTime } from "../../utils/display";
|
||||
import { usePermission } from "../../utils/permission";
|
||||
import { useDrawerDirtyGuard } from "../../utils/drawerDirtyGuard";
|
||||
|
||||
@@ -237,8 +229,6 @@ const study = useStudyStore();
|
||||
const { can } = usePermission();
|
||||
const rows = ref<MilestoneRow[]>([]);
|
||||
const loading = ref(false);
|
||||
const dataSourceLabel = ref<string>(TEXT.modules.projectMilestones.sourcePublished);
|
||||
const updatedAtLabel = ref<string>(TEXT.common.fallback);
|
||||
const editorVisible = ref(false);
|
||||
const editingRowId = ref("");
|
||||
const editorForm = reactive<MilestoneLocalEdit>({
|
||||
@@ -309,15 +299,8 @@ const loadMilestones = async () => {
|
||||
const { data } = (await listProjectMilestones(studyId)) as any;
|
||||
const list = Array.isArray(data) ? data : data?.items || [];
|
||||
rows.value = list.map(normalizeRow);
|
||||
const updatedAt = list
|
||||
.map((item: any) => String(item?.updated_at || ""))
|
||||
.filter(Boolean)
|
||||
.sort()
|
||||
.pop();
|
||||
updatedAtLabel.value = updatedAt ? displayDateTime(updatedAt) : TEXT.common.fallback;
|
||||
} catch (error: any) {
|
||||
rows.value = [];
|
||||
updatedAtLabel.value = TEXT.common.fallback;
|
||||
ElMessage.error(error?.response?.data?.detail || TEXT.common.messages.loadFailed);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
@@ -452,7 +435,6 @@ watch(
|
||||
() => study.currentStudy?.id,
|
||||
() => {
|
||||
rows.value = [];
|
||||
updatedAtLabel.value = TEXT.common.fallback;
|
||||
loadMilestones();
|
||||
}
|
||||
);
|
||||
@@ -462,6 +444,32 @@ watch(
|
||||
.page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* 撑满父容器(desktop-route-shell 已经是 height: 100%)*/
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* 让白色卡片壳撑满 .page 的剩余高度,并去掉圆角 */
|
||||
.page > .unified-shell {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* 让表格 section 撑满卡片壳的剩余高度 */
|
||||
.page > .unified-shell > .unified-section {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* el-table 本身填满 section */
|
||||
.page > .unified-shell > .unified-section :deep(.el-table),
|
||||
.page > .unified-shell > .unified-section :deep(.el-table__inner-wrapper) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ctms-page-content-grid {
|
||||
@@ -477,20 +485,15 @@ watch(
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.milestone-action-bar {
|
||||
min-height: 56px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #0f2345;
|
||||
}
|
||||
|
||||
.card-subtitle {
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
color: var(--ctms-text-secondary);
|
||||
}
|
||||
|
||||
.dot-sep {
|
||||
margin: 0 8px;
|
||||
color: var(--unified-title-color);
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
@@ -520,11 +523,11 @@ watch(
|
||||
border-radius: 50%;
|
||||
border: 3px solid #2f84c6;
|
||||
box-sizing: border-box;
|
||||
background: #ffffff;
|
||||
background: var(--ctms-bg-card);
|
||||
}
|
||||
|
||||
.plan-time-label {
|
||||
color: #4b5563;
|
||||
color: var(--ctms-text-secondary);
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
@@ -546,10 +549,10 @@ watch(
|
||||
}
|
||||
|
||||
.time-editor-group {
|
||||
border: 1px solid #e8eef6;
|
||||
border: 1px solid var(--ctms-border-color);
|
||||
border-radius: 10px;
|
||||
padding: 14px 16px 10px;
|
||||
background: #fbfcfe;
|
||||
background: var(--ctms-bg-muted);
|
||||
}
|
||||
|
||||
.time-editor-group + .time-editor-group {
|
||||
@@ -566,7 +569,7 @@ watch(
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
color: #1a3560;
|
||||
color: var(--ctms-text-main);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
@@ -600,14 +603,14 @@ watch(
|
||||
|
||||
.duration-label {
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
color: var(--ctms-text-secondary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.duration-value {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #1a3560;
|
||||
color: var(--ctms-text-main);
|
||||
}
|
||||
|
||||
.time-editor-footer {
|
||||
@@ -628,7 +631,7 @@ watch(
|
||||
.time-editor-form :deep(.el-form-item__label) {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #4a6283;
|
||||
color: var(--ctms-text-regular);
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
@@ -655,7 +658,7 @@ watch(
|
||||
|
||||
.status-detail {
|
||||
padding-left: 14px;
|
||||
color: #6b7280;
|
||||
color: var(--ctms-text-secondary);
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
@@ -684,9 +687,10 @@ watch(
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #8a97ab;
|
||||
color: var(--ctms-text-secondary);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user