feat: improve task sorting and enhance UI component behavior
- Updated task sorting logic in TeamTaskReader to handle non-numeric IDs with stable lexicographic ordering. - Refactored ActivityItem to remove unnecessary whitespace for cleaner code. - Enhanced AttachmentPreviewItem to improve accessibility by adding pointer-events-none class for disabled state. - Modified MessageComposer to ensure the summary remains compact during message sending. - Added cleanup logic in useResizableColumns to handle global listeners and styles during drag events.
This commit is contained in:
parent
524f6f45d2
commit
afb0173c05
5 changed files with 24 additions and 5 deletions
|
|
@ -271,8 +271,16 @@ export class TeamTaskReader {
|
|||
}
|
||||
}
|
||||
|
||||
// Sort by numeric ID so kanban default order is deterministic (#1, #2, ..., #10, #11)
|
||||
tasks.sort((a, b) => Number(a.id) - Number(b.id));
|
||||
// Sort by numeric ID so kanban default order is deterministic (#1, #2, ..., #10, #11).
|
||||
// Fall back to stable lexicographic ordering for unexpected non-numeric IDs.
|
||||
tasks.sort((a, b) => {
|
||||
const aIsNumeric = /^\d+$/.test(a.id);
|
||||
const bIsNumeric = /^\d+$/.test(b.id);
|
||||
if (aIsNumeric && bIsNumeric) return Number(a.id) - Number(b.id);
|
||||
if (aIsNumeric) return -1;
|
||||
if (bIsNumeric) return 1;
|
||||
return a.id.localeCompare(b.id, undefined, { numeric: true, sensitivity: 'base' });
|
||||
});
|
||||
|
||||
return tasks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,7 +176,6 @@ function linkifyMentionsInMarkdown(text: string, memberColorMap: Map<string, str
|
|||
return `${prefix}[@${canonical}](mention://${encodeURIComponent(color)}/${encodeURIComponent(canonical)})`;
|
||||
});
|
||||
}
|
||||
|
||||
/** Render `#<digits>` in plain text as clickable inline elements with TaskTooltip. */
|
||||
function linkifyTaskIds(text: string, onClick: (taskId: string) => void): React.ReactNode[] {
|
||||
return text.split(/(#\d+)/g).map((part, i) => {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export const AttachmentPreviewItem = ({
|
|||
return (
|
||||
<div className="group/att relative flex shrink-0 items-center gap-2 rounded-md border border-[var(--color-border)] bg-[var(--color-surface)] p-1.5">
|
||||
{disabled ? (
|
||||
<div className="absolute inset-0 z-10 flex items-center justify-center rounded-md bg-black/50">
|
||||
<div className="pointer-events-none absolute inset-0 z-10 flex items-center justify-center rounded-md bg-black/50">
|
||||
<Ban size={18} className="text-red-400" />
|
||||
</div>
|
||||
) : null}
|
||||
|
|
|
|||
|
|
@ -168,7 +168,8 @@ export const MessageComposer = ({
|
|||
if (!canSend) return;
|
||||
pendingSendRef.current = true;
|
||||
const serialized = serializeChipsWithText(trimmed, chipDraft.chips);
|
||||
onSend(recipient, serialized, serialized, attachments.length > 0 ? attachments : undefined);
|
||||
// Summary should stay compact (no expanded chip markdown)
|
||||
onSend(recipient, serialized, trimmed, attachments.length > 0 ? attachments : undefined);
|
||||
}, [canSend, recipient, trimmed, onSend, attachments, chipDraft.chips]);
|
||||
|
||||
// Clear draft only after send completes successfully (sending: true → false, no error)
|
||||
|
|
|
|||
|
|
@ -95,6 +95,17 @@ export function useResizableColumns({
|
|||
});
|
||||
}, [handlePointerMove, storageKey]);
|
||||
|
||||
// Safety: if the board unmounts or storageKey changes mid-drag, clean up global listeners/styles.
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
draggingRef.current = null;
|
||||
document.removeEventListener('pointermove', handlePointerMove);
|
||||
document.removeEventListener('pointerup', handlePointerUp);
|
||||
document.body.style.cursor = '';
|
||||
document.body.style.userSelect = '';
|
||||
};
|
||||
}, [handlePointerMove, handlePointerUp]);
|
||||
|
||||
const getHandleProps = useCallback(
|
||||
(leftColumnId: string) => ({
|
||||
onPointerDown: (e: React.PointerEvent) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue