Version: 0.8.2.dev.260327
后端: 1.修复了消息重试链路的相关问题 2.新增redis乐观写消息机制,即使前端在重试完消息后立刻刷新,也能在redis里面读到数据 前端: 1.修了一些bug
This commit is contained in:
@@ -122,10 +122,6 @@ const isProgrammaticMessageScroll = ref(false)
|
||||
const isStandaloneMode = computed(() => props.viewMode === 'standalone')
|
||||
|
||||
const assistantBodyStyle = computed(() => {
|
||||
if (isStandaloneMode.value) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return {
|
||||
'--assistant-history-width': `${historyExpanded.value ? historyPanelWidth.value : 68}px`,
|
||||
}
|
||||
@@ -1010,6 +1006,37 @@ function handleHistoryScroll(event: Event) {
|
||||
}
|
||||
}
|
||||
|
||||
function getHistoryPanelWidthBounds(containerWidth: number) {
|
||||
const standalone = isStandaloneMode.value
|
||||
const minHistoryWidth = standalone ? 196 : 188
|
||||
const minChatWidth = standalone ? 560 : 420
|
||||
const splitterWidth = 8
|
||||
const rawMaxHistoryWidth = standalone
|
||||
? Math.min(320, containerWidth - splitterWidth - minChatWidth)
|
||||
: containerWidth - splitterWidth - minChatWidth
|
||||
|
||||
return {
|
||||
minHistoryWidth,
|
||||
maxHistoryWidth: Math.max(minHistoryWidth, rawMaxHistoryWidth),
|
||||
}
|
||||
}
|
||||
|
||||
function syncHistoryPanelWidthForViewport() {
|
||||
if (!historyExpanded.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const body = assistantBodyRef.value
|
||||
const containerWidth =
|
||||
body?.getBoundingClientRect().width ??
|
||||
Math.max(0, window.innerWidth - (isStandaloneMode.value ? 120 : 0))
|
||||
const bounds = getHistoryPanelWidthBounds(containerWidth)
|
||||
historyPanelWidth.value = Math.min(
|
||||
Math.max(historyPanelWidth.value, bounds.minHistoryWidth),
|
||||
bounds.maxHistoryWidth,
|
||||
)
|
||||
}
|
||||
|
||||
// startResizeHistoryPanel 负责处理会话列表与聊天主区之间的横向拖拽。
|
||||
// 职责边界:
|
||||
// 1. 只负责更新助手面板内部的历史区宽度,不修改外层 Dashboard 的左右二分布局。
|
||||
@@ -1017,21 +1044,27 @@ function handleHistoryScroll(event: Event) {
|
||||
// 3. 拖拽结束后统一解绑事件并清理全局样式,防止页面残留 col-resize 状态。
|
||||
function startResizeHistoryPanel(event: PointerEvent) {
|
||||
const body = assistantBodyRef.value
|
||||
if (isStandaloneMode.value || !body || window.innerWidth <= 960 || !historyExpanded.value) {
|
||||
if (!body || !historyExpanded.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const isStandalone = isStandaloneMode.value
|
||||
const minViewportWidth = isStandalone ? 860 : 960
|
||||
if (window.innerWidth <= minViewportWidth) {
|
||||
return
|
||||
}
|
||||
|
||||
const rect = body.getBoundingClientRect()
|
||||
const startX = event.clientX
|
||||
const startWidth = historyPanelWidth.value
|
||||
const bounds = getHistoryPanelWidthBounds(rect.width)
|
||||
|
||||
const handlePointerMove = (moveEvent: PointerEvent) => {
|
||||
const deltaX = moveEvent.clientX - startX
|
||||
const minHistoryWidth = 188
|
||||
const minChatWidth = 420
|
||||
const splitterWidth = 8
|
||||
const maxHistoryWidth = rect.width - splitterWidth - minChatWidth
|
||||
historyPanelWidth.value = Math.min(Math.max(startWidth + deltaX, minHistoryWidth), maxHistoryWidth)
|
||||
historyPanelWidth.value = Math.min(
|
||||
Math.max(startWidth + deltaX, bounds.minHistoryWidth),
|
||||
bounds.maxHistoryWidth,
|
||||
)
|
||||
}
|
||||
|
||||
const stopResize = () => {
|
||||
@@ -1469,7 +1502,10 @@ onMounted(async () => {
|
||||
reasoningTicker = window.setInterval(() => {
|
||||
reasoningDisplayNow.value = Date.now()
|
||||
}, 1000)
|
||||
window.addEventListener('resize', syncHistoryPanelWidthForViewport)
|
||||
syncHistoryPanelWidthForViewport()
|
||||
await loadConversationListData(true)
|
||||
syncHistoryPanelWidthForViewport()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -1483,6 +1519,7 @@ onBeforeUnmount(() => {
|
||||
window.clearInterval(reasoningTicker)
|
||||
reasoningTicker = 0
|
||||
}
|
||||
window.removeEventListener('resize', syncHistoryPanelWidthForViewport)
|
||||
document.body.classList.remove('dashboard-resizing')
|
||||
})
|
||||
</script>
|
||||
@@ -1584,7 +1621,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
<div
|
||||
class="assistant-splitter"
|
||||
:class="{ 'assistant-splitter--hidden': !historyExpanded || isStandaloneMode }"
|
||||
:class="{ 'assistant-splitter--hidden': !historyExpanded }"
|
||||
role="separator"
|
||||
aria-label="调整会话列表宽度"
|
||||
@pointerdown.prevent="startResizeHistoryPanel"
|
||||
@@ -1994,7 +2031,7 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
|
||||
.assistant-body--standalone {
|
||||
grid-template-columns: minmax(212px, 1fr) 8px minmax(0, 5fr);
|
||||
grid-template-columns: var(--assistant-history-width) 8px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.assistant-body--standalone.assistant-body--collapsed {
|
||||
@@ -2073,15 +2110,20 @@ onBeforeUnmount(() => {
|
||||
.assistant-history__content {
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
display: grid;
|
||||
align-content: start;
|
||||
gap: 12px;
|
||||
padding: 0 10px 14px 12px;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.assistant-history__new {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
height: 42px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid rgba(15, 23, 42, 0.1);
|
||||
border-radius: 12px;
|
||||
background: #ffffff;
|
||||
@@ -2114,6 +2156,7 @@ onBeforeUnmount(() => {
|
||||
.assistant-history__group {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.assistant-history__group-title {
|
||||
@@ -2127,17 +2170,21 @@ onBeforeUnmount(() => {
|
||||
|
||||
.assistant-history__item {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
min-height: 38px;
|
||||
padding: 8px 10px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 10px;
|
||||
background: transparent;
|
||||
color: #1f2937;
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
|
||||
}
|
||||
|
||||
@@ -2148,6 +2195,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
.assistant-history__item-title {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
font-size: 13px;
|
||||
line-height: 1.3;
|
||||
color: inherit;
|
||||
@@ -2174,6 +2222,7 @@ onBeforeUnmount(() => {
|
||||
.assistant-shell--standalone .assistant-history {
|
||||
background: linear-gradient(180deg, #f8f9fc 0%, #f4f7fb 100%);
|
||||
border-right: 1px solid rgba(15, 23, 42, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__item--active {
|
||||
@@ -2182,6 +2231,28 @@ onBeforeUnmount(() => {
|
||||
box-shadow: 0 4px 10px rgba(36, 67, 127, 0.08);
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__toolbar {
|
||||
padding: 10px 9px 8px 10px;
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__content {
|
||||
gap: 10px;
|
||||
padding: 0 8px 12px 10px;
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__new {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__item {
|
||||
min-height: 54px;
|
||||
padding: 10px 10px 10px 11px;
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__item-title {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.assistant-history--collapsed .assistant-history__toolbar {
|
||||
padding-inline: 8px;
|
||||
justify-content: center;
|
||||
@@ -2265,6 +2336,14 @@ onBeforeUnmount(() => {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.assistant-body--standalone .assistant-splitter {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-splitter__line {
|
||||
background: linear-gradient(180deg, rgba(130, 148, 180, 0.18), rgba(78, 110, 168, 0.32), rgba(130, 148, 180, 0.18));
|
||||
}
|
||||
|
||||
.assistant-splitter__line {
|
||||
width: 3px;
|
||||
height: 56px;
|
||||
@@ -3010,6 +3089,57 @@ onBeforeUnmount(() => {
|
||||
padding-right: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
.assistant-body--standalone {
|
||||
grid-template-columns: var(--assistant-history-width) 8px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__content {
|
||||
padding-left: 7px;
|
||||
padding-right: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1120px) {
|
||||
.assistant-body--standalone {
|
||||
grid-template-columns: var(--assistant-history-width) 8px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__toolbar {
|
||||
padding-inline: 8px;
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__content {
|
||||
gap: 8px;
|
||||
padding-inline: 6px;
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__item {
|
||||
min-height: 50px;
|
||||
padding: 9px 9px 9px 10px;
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__item-title {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 860px) {
|
||||
.assistant-body--standalone,
|
||||
.assistant-body--standalone.assistant-body--collapsed {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history {
|
||||
border-right: none;
|
||||
border-bottom: 1px solid rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
.assistant-shell--standalone .assistant-history__content {
|
||||
max-height: 260px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.assistant-model-select-panel.el-popper {
|
||||
|
||||
@@ -197,6 +197,9 @@ function handleSubmit() {
|
||||
.task-class-dialog__body {
|
||||
display: grid;
|
||||
gap: 22px;
|
||||
min-height: 0;
|
||||
max-height: min(72vh, 760px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.task-class-dialog__grid {
|
||||
@@ -230,6 +233,8 @@ function handleSubmit() {
|
||||
.task-class-dialog__items {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.task-class-dialog__items-head {
|
||||
@@ -237,6 +242,8 @@ function handleSubmit() {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.task-class-dialog__add {
|
||||
@@ -254,6 +261,13 @@ function handleSubmit() {
|
||||
.task-class-dialog__items-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
min-width: 0;
|
||||
max-height: min(44vh, 360px);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding-right: 4px;
|
||||
scrollbar-gutter: stable;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.task-class-dialog__item {
|
||||
@@ -261,6 +275,7 @@ function handleSubmit() {
|
||||
grid-template-columns: 36px minmax(0, 1fr) auto;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.task-class-dialog__item-order {
|
||||
@@ -297,9 +312,46 @@ function handleSubmit() {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@media (max-height: 900px) {
|
||||
.task-class-dialog__body {
|
||||
max-height: min(76vh, 680px);
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.task-class-dialog__items-list {
|
||||
max-height: min(40vh, 300px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 820px) {
|
||||
.task-class-dialog__items-list {
|
||||
max-height: min(34vh, 240px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 840px) {
|
||||
.task-class-dialog__grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.task-class-dialog__item {
|
||||
grid-template-columns: 32px minmax(0, 1fr);
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.task-class-dialog__item-remove {
|
||||
grid-column: 2;
|
||||
justify-self: start;
|
||||
}
|
||||
}
|
||||
|
||||
.task-class-dialog :deep(.el-dialog) {
|
||||
width: min(720px, calc(100vw - 24px));
|
||||
max-height: calc(100vh - 24px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.task-class-dialog :deep(.el-dialog__body) {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import type { TaskClassDetail, TaskClassListItem } from '@/types/schedule'
|
||||
|
||||
@@ -21,6 +21,10 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const taskClassCountLabel = computed(() => `共 ${props.taskClasses.length} 个`)
|
||||
const viewportHeight = ref(typeof window === 'undefined' ? 900 : window.innerHeight)
|
||||
const taskClassListRef = ref<HTMLElement | null>(null)
|
||||
const listViewportHeight = ref(0)
|
||||
let listResizeObserver: ResizeObserver | null = null
|
||||
|
||||
function isExpanded(taskClassId: number) {
|
||||
return props.expandedTaskClassId === taskClassId && !props.taskClassMultiSelectMode
|
||||
@@ -40,6 +44,76 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
const day = `${date.getDate()}`.padStart(2, '0')
|
||||
return `${month}.${day} ${value.section_from}-${value.section_to}节`
|
||||
}
|
||||
|
||||
function syncViewportHeight() {
|
||||
viewportHeight.value = window.innerHeight
|
||||
}
|
||||
|
||||
function syncTaskClassListViewportHeight() {
|
||||
listViewportHeight.value = taskClassListRef.value?.clientHeight ?? 0
|
||||
}
|
||||
|
||||
function resolveDetailPanelStyle(items: TaskClassDetail['items']) {
|
||||
const count = items.length
|
||||
const itemHeight = viewportHeight.value <= 820 ? 54 : viewportHeight.value <= 900 ? 58 : 62
|
||||
const gap = 6
|
||||
const panelPadding = 14
|
||||
const preferredHeight = count * itemHeight + Math.max(0, count - 1) * gap + panelPadding
|
||||
const maxVisibleItems = viewportHeight.value <= 820 ? 4 : viewportHeight.value <= 900 ? 5 : 6
|
||||
const maxHeightByItemCount =
|
||||
maxVisibleItems * itemHeight + Math.max(0, maxVisibleItems - 1) * gap + panelPadding
|
||||
const maxHeightByContainer = Math.max(
|
||||
180,
|
||||
(listViewportHeight.value || Math.round(viewportHeight.value * 0.6)) - 116,
|
||||
)
|
||||
const finalHeight = Math.min(preferredHeight, maxHeightByItemCount, maxHeightByContainer)
|
||||
|
||||
// 1. 条目少时让卡片自然长高,避免只有两三条时还出现大块留白。
|
||||
// 2. 条目超过“当前屏幕可安全展示的最大条数”后,立即锁住高度并进入内部滚动。
|
||||
// 3. 这样像 8 条 task_item 这类中等长度列表会稳定触发滚动,不会再因为估算过大而失效。
|
||||
return {
|
||||
height: `${finalHeight}px`,
|
||||
maxHeight: `${finalHeight}px`,
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('resize', syncViewportHeight)
|
||||
window.addEventListener('resize', syncTaskClassListViewportHeight)
|
||||
syncTaskClassListViewportHeight()
|
||||
if (typeof ResizeObserver !== 'undefined') {
|
||||
listResizeObserver = new ResizeObserver(() => {
|
||||
syncTaskClassListViewportHeight()
|
||||
})
|
||||
if (taskClassListRef.value) {
|
||||
listResizeObserver.observe(taskClassListRef.value)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', syncViewportHeight)
|
||||
window.removeEventListener('resize', syncTaskClassListViewportHeight)
|
||||
listResizeObserver?.disconnect()
|
||||
listResizeObserver = null
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.expandedTaskClassId,
|
||||
async (expandedId) => {
|
||||
await nextTick()
|
||||
syncTaskClassListViewportHeight()
|
||||
if (!expandedId || !taskClassListRef.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const expandedCard = taskClassListRef.value.querySelector<HTMLElement>('.task-class-card--expanded')
|
||||
expandedCard?.scrollIntoView({
|
||||
block: 'nearest',
|
||||
inline: 'nearest',
|
||||
})
|
||||
},
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -68,7 +142,7 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
<div v-for="index in 4" :key="index" class="task-class-sidebar__skeleton-item" />
|
||||
</div>
|
||||
|
||||
<div v-else class="task-class-sidebar__list">
|
||||
<div v-else ref="taskClassListRef" class="task-class-sidebar__list">
|
||||
<article
|
||||
v-for="taskClass in taskClasses"
|
||||
:key="taskClass.id"
|
||||
@@ -98,7 +172,11 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<div v-if="isExpanded(taskClass.id)" class="task-class-card__detail">
|
||||
<div
|
||||
v-if="isExpanded(taskClass.id)"
|
||||
class="task-class-card__detail"
|
||||
:style="expandedTaskClassDetail ? resolveDetailPanelStyle(expandedTaskClassDetail.items) : undefined"
|
||||
>
|
||||
<div v-if="detailLoading" class="task-class-card__detail-loading">正在载入任务块…</div>
|
||||
|
||||
<div v-else-if="expandedTaskClassDetail" class="task-class-card__detail-list">
|
||||
@@ -146,6 +224,7 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
border-right: 1px solid rgba(196, 209, 227, 0.55);
|
||||
background: linear-gradient(180deg, rgba(251, 253, 255, 0.96), rgba(247, 250, 254, 0.98));
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.task-class-sidebar__header {
|
||||
@@ -153,6 +232,7 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
border-bottom: 1px solid rgba(214, 223, 238, 0.68);
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.task-class-sidebar__title-row {
|
||||
@@ -160,6 +240,8 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.task-class-sidebar__title-wrap {
|
||||
@@ -167,11 +249,13 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: #1f2c42;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.task-class-sidebar__title-wrap strong {
|
||||
font-size: 15px;
|
||||
font-weight: 800;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.task-class-sidebar__title-icon {
|
||||
@@ -213,10 +297,12 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
.task-class-sidebar__skeleton {
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding: 24px;
|
||||
display: grid;
|
||||
align-content: start;
|
||||
gap: 14px;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
.task-class-sidebar__skeleton-item {
|
||||
@@ -228,6 +314,7 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
}
|
||||
|
||||
.task-class-card {
|
||||
min-width: 0;
|
||||
border-radius: 24px;
|
||||
border: 1px solid rgba(216, 225, 238, 0.9);
|
||||
background: linear-gradient(180deg, #fdfefe 0%, #f8fbff 100%);
|
||||
@@ -242,6 +329,7 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
|
||||
.task-class-card__summary {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 18px 20px 18px 18px;
|
||||
@@ -284,6 +372,7 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
font-size: 16px;
|
||||
line-height: 1.35;
|
||||
font-weight: 800;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.task-class-card__content span {
|
||||
@@ -292,6 +381,7 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
}
|
||||
|
||||
.task-class-card__corner {
|
||||
flex: 0 0 auto;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 999px;
|
||||
@@ -304,7 +394,14 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
}
|
||||
|
||||
.task-class-card__detail {
|
||||
min-width: 0;
|
||||
padding: 0 14px 14px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
scrollbar-gutter: stable;
|
||||
overscroll-behavior: contain;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(114, 130, 157, 0.65) transparent;
|
||||
}
|
||||
|
||||
.task-class-card__detail-loading {
|
||||
@@ -313,14 +410,29 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.task-class-card__detail::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.task-class-card__detail::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.task-class-card__detail::-webkit-scrollbar-thumb {
|
||||
border-radius: 999px;
|
||||
background: rgba(114, 130, 157, 0.55);
|
||||
}
|
||||
|
||||
.task-class-card__detail-list {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.task-class-card__detail-item {
|
||||
min-width: 0;
|
||||
padding: 10px 12px;
|
||||
padding: 8px 10px;
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(197, 209, 226, 0.8);
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
@@ -346,11 +458,13 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
}
|
||||
|
||||
.task-class-card__detail-status {
|
||||
max-width: 100%;
|
||||
padding: 4px 10px;
|
||||
border-radius: 999px;
|
||||
background: #f1f5f9;
|
||||
color: #74839a;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.task-class-card__detail-status--arranged {
|
||||
@@ -376,6 +490,7 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
}
|
||||
|
||||
.task-class-sidebar__create {
|
||||
min-width: 0;
|
||||
min-height: 108px;
|
||||
border: 1px dashed rgba(204, 216, 232, 0.92);
|
||||
border-radius: 24px;
|
||||
@@ -416,4 +531,107 @@ function formatEmbeddedTime(value: TaskClassDetail['items'][number]['embedded_ti
|
||||
background-position: -200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1520px) {
|
||||
.task-class-sidebar__header,
|
||||
.task-class-sidebar__list,
|
||||
.task-class-sidebar__skeleton {
|
||||
padding-left: 18px;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.task-class-card__summary {
|
||||
padding: 16px 16px 16px 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1380px) {
|
||||
.task-class-sidebar {
|
||||
border-right: none;
|
||||
border-bottom: 1px solid rgba(196, 209, 227, 0.55);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1180px) {
|
||||
.task-class-card__detail-item {
|
||||
grid-template-columns: 28px minmax(0, 1fr) 24px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.task-class-card__detail-status {
|
||||
grid-column: 2;
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.task-class-card__detail-delete {
|
||||
grid-column: 3;
|
||||
grid-row: 1 / span 2;
|
||||
align-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 900px) {
|
||||
.task-class-sidebar__header {
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.task-class-sidebar__list,
|
||||
.task-class-sidebar__skeleton {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.task-class-card {
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.task-class-card__summary {
|
||||
padding: 14px 14px 14px 13px;
|
||||
}
|
||||
|
||||
.task-class-card__content {
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.task-class-card__content strong {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.task-class-sidebar__create {
|
||||
min-height: 88px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-height: 820px) {
|
||||
.task-class-sidebar__header,
|
||||
.task-class-sidebar__list,
|
||||
.task-class-sidebar__skeleton {
|
||||
padding-left: 14px;
|
||||
padding-right: 14px;
|
||||
}
|
||||
|
||||
.task-class-card__summary {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.task-class-card__corner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.task-class-card__content strong {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.task-class-card__content span,
|
||||
.task-class-card__detail-text,
|
||||
.task-class-card__detail-status {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -144,12 +144,22 @@ function resolveCellMeta(event?: ScheduleWeekEvent) {
|
||||
|
||||
<style scoped>
|
||||
.planning-board {
|
||||
--planning-grid-padding-x: 24px;
|
||||
--planning-grid-padding-y: 28px;
|
||||
--planning-grid-gap-x: 12px;
|
||||
--planning-grid-gap-y: 10px;
|
||||
--planning-time-column-width: 74px;
|
||||
--planning-day-column-min: 96px;
|
||||
--planning-cell-height: clamp(72px, 9.2vh, 112px);
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
border-radius: 28px;
|
||||
border: 1px solid rgba(214, 223, 236, 0.82);
|
||||
background: linear-gradient(180deg, rgba(252, 253, 255, 0.98), rgba(248, 251, 255, 0.98));
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.82);
|
||||
display: grid;
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.planning-board__header {
|
||||
@@ -161,10 +171,13 @@ function resolveCellMeta(event?: ScheduleWeekEvent) {
|
||||
|
||||
.planning-board__grid {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
display: grid;
|
||||
grid-template-columns: 74px repeat(7, minmax(0, 1fr));
|
||||
gap: 10px 12px;
|
||||
padding: 28px 24px 24px;
|
||||
grid-template-columns: var(--planning-time-column-width) repeat(7, minmax(var(--planning-day-column-min), 1fr));
|
||||
gap: var(--planning-grid-gap-y) var(--planning-grid-gap-x);
|
||||
padding: var(--planning-grid-padding-y) var(--planning-grid-padding-x) 24px;
|
||||
overflow: auto;
|
||||
scrollbar-gutter: stable both-edges;
|
||||
}
|
||||
|
||||
.planning-board__corner {
|
||||
@@ -189,7 +202,7 @@ function resolveCellMeta(event?: ScheduleWeekEvent) {
|
||||
}
|
||||
|
||||
.planning-board__time-cell {
|
||||
min-height: 112px;
|
||||
min-height: var(--planning-cell-height);
|
||||
display: grid;
|
||||
align-content: center;
|
||||
justify-items: end;
|
||||
@@ -211,7 +224,7 @@ function resolveCellMeta(event?: ScheduleWeekEvent) {
|
||||
|
||||
.planning-board__cell {
|
||||
position: relative;
|
||||
min-height: 112px;
|
||||
min-height: var(--planning-cell-height);
|
||||
border-radius: 22px;
|
||||
border: 1px solid rgba(228, 234, 243, 0.92);
|
||||
padding: 18px 14px;
|
||||
@@ -225,6 +238,7 @@ function resolveCellMeta(event?: ScheduleWeekEvent) {
|
||||
.planning-board__cell-main {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.planning-board__cell-main strong {
|
||||
@@ -232,11 +246,15 @@ function resolveCellMeta(event?: ScheduleWeekEvent) {
|
||||
font-size: 15px;
|
||||
line-height: 1.35;
|
||||
font-weight: 700;
|
||||
min-width: 0;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.planning-board__cell-main span {
|
||||
color: #9badc5;
|
||||
font-size: 12px;
|
||||
min-width: 0;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.planning-board__cell--course {
|
||||
@@ -321,7 +339,99 @@ function resolveCellMeta(event?: ScheduleWeekEvent) {
|
||||
|
||||
@media (max-width: 1560px) {
|
||||
.planning-board__grid {
|
||||
grid-template-columns: 64px repeat(7, minmax(118px, 1fr));
|
||||
--planning-time-column-width: 64px;
|
||||
--planning-day-column-min: 92px;
|
||||
--planning-grid-padding-x: 18px;
|
||||
--planning-grid-padding-y: 22px;
|
||||
--planning-grid-gap-x: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1380px) {
|
||||
.planning-board__header {
|
||||
padding: 16px 20px 14px;
|
||||
}
|
||||
|
||||
.planning-board__grid {
|
||||
--planning-time-column-width: 58px;
|
||||
--planning-day-column-min: 84px;
|
||||
--planning-grid-padding-x: 14px;
|
||||
--planning-grid-padding-y: 18px;
|
||||
--planning-grid-gap-x: 8px;
|
||||
--planning-grid-gap-y: 8px;
|
||||
}
|
||||
|
||||
.planning-board__time-cell,
|
||||
.planning-board__cell {
|
||||
min-height: 98px;
|
||||
}
|
||||
|
||||
.planning-board__cell {
|
||||
padding: 14px 10px;
|
||||
border-radius: 18px;
|
||||
}
|
||||
|
||||
.planning-board__cell-main {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.planning-board__cell-main strong {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1180px) {
|
||||
.planning-board__grid {
|
||||
--planning-time-column-width: 56px;
|
||||
--planning-day-column-min: 78px;
|
||||
}
|
||||
|
||||
.planning-board__day-head span {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.planning-board__day-head small,
|
||||
.planning-board__cell-main span {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 900px) {
|
||||
.planning-board {
|
||||
--planning-grid-padding-y: 18px;
|
||||
--planning-cell-height: clamp(66px, 8.2vh, 92px);
|
||||
}
|
||||
|
||||
.planning-board__header {
|
||||
padding-top: 14px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.planning-board__header strong {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 820px) {
|
||||
.planning-board {
|
||||
--planning-grid-padding-y: 14px;
|
||||
--planning-grid-gap-y: 6px;
|
||||
--planning-cell-height: clamp(58px, 7.2vh, 82px);
|
||||
}
|
||||
|
||||
.planning-board__time-cell strong,
|
||||
.planning-board__cell-main strong {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.planning-board__time-cell small,
|
||||
.planning-board__day-head small,
|
||||
.planning-board__cell-main span {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.planning-board__cell {
|
||||
padding: 12px 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user