fix(web): make kanban column titles readable

Widen board columns and keep counts inside the add button so stage and card titles have room.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-28 17:24:58 +03:30
co-authored by Cursor
parent 463a1652a6
commit 2cc2d358e4
4 changed files with 42 additions and 51 deletions
@@ -1,10 +1,6 @@
<script setup lang="ts">
import { computed, nextTick, ref } from 'vue';
import {
HolderOutlined,
MoreOutlined,
PlusOutlined,
} from '@ant-design/icons-vue';
import { HolderOutlined, MoreOutlined } from '@ant-design/icons-vue';
import {
Button as AButton,
Dropdown as ADropdown,
@@ -17,7 +13,7 @@ import {
import AddDealButton from './AddDealButton.vue';
import DealCard from './DealCard.vue';
import type { PipelineDeal, PipelineStage, PipelineUiCopy } from '@/lib/pipeline-board';
import { DEAL_BOARD_COPY, PIPELINE_ACCENT, toFaItemCount } from '@/lib/pipeline-board';
import { DEAL_BOARD_COPY, PIPELINE_ACCENT } from '@/lib/pipeline-board';
const props = withDefaults(
defineProps<{
@@ -67,8 +63,8 @@ const columnStyle = computed(() => ({
display: 'flex',
flexDirection: 'column' as const,
gap: '12px',
flex: '0 0 280px',
width: '280px',
flex: '0 0 310px',
width: '310px',
alignSelf: 'stretch' as const,
minHeight: 0,
padding: 0,
@@ -154,15 +150,21 @@ function onColumnDragStart(event: DragEvent) {
}
const menuItems = computed(() => [
{ key: 'add', label: 'افزودن' },
{ key: 'rename', label: 'تغییر نام' },
{ key: 'right', label: 'انتقال به راست', disabled: props.isFirst },
{ key: 'left', label: 'انتقال به چپ', disabled: props.isLast },
{ key: 'delete', label: 'حذف ستون', danger: true },
]);
const itemCountLabel = computed(() =>
new Intl.NumberFormat('fa-IR').format(props.stage.total ?? props.stage.deals.length),
);
function onMenuClick({ key }: { key: string | number }) {
menuOpen.value = false;
if (key === 'rename') startRename();
if (key === 'add') emit('addDeal', props.stage.id);
else if (key === 'rename') startRename();
else if (key === 'right') emit('move', props.stage.id, -1);
else if (key === 'left') emit('move', props.stage.id, 1);
else if (key === 'delete') emit('delete', props.stage.id);
@@ -224,12 +226,13 @@ function onMenuClick({ key }: { key: string | number }) {
/>
<a-typography-text
v-else
strong
ellipsis
:style="{
flex: 1,
minWidth: 0,
margin: 0,
fontSize: `${token.fontSizeSM}px`,
fontWeight: 600,
cursor: canManage ? 'text' : 'default',
}"
:title="canManage ? 'برای تغییر نام کلیک کنید' : stage.title"
@@ -242,10 +245,6 @@ function onMenuClick({ key }: { key: string | number }) {
{{ stage.badge }}
</a-tag>
<a-typography-text type="secondary" :style="{ whiteSpace: 'nowrap', flexShrink: 0 }">
{{ toFaItemCount(stage.total ?? stage.deals.length, copy.itemNoun) }}
</a-typography-text>
<a-dropdown
v-if="canManage"
v-model:open="menuOpen"
@@ -259,15 +258,6 @@ function onMenuClick({ key }: { key: string | number }) {
<a-menu :items="menuItems" @click="onMenuClick" />
</template>
</a-dropdown>
<a-button
type="text"
:aria-label="copy.addItemAria"
:style="{ color: accent.solid }"
@click="emit('addDeal', stage.id)"
>
<template #icon><PlusOutlined /></template>
</a-button>
</div>
<div role="list" :aria-label="stage.title" :style="bodyStyle">
@@ -311,7 +301,12 @@ function onMenuClick({ key }: { key: string | number }) {
</div>
<div :style="{ padding: '0 12px 12px', flexShrink: 0 }">
<AddDealButton :accent="stage.color" :label="copy.addItem" @add="emit('addDeal', stage.id)" />
<AddDealButton
:accent="stage.color"
:label="copy.addItem"
:count="itemCountLabel"
@add="emit('addDeal', stage.id)"
/>
</div>
</section>
</template>