[WEB-4944] feat: add base layouts for kanban and list with drag-and-drop support (#8032)

This commit is contained in:
Jayash Tripathy 2025-10-29 14:49:34 +05:30 committed by GitHub
parent 5247fedd23
commit 73e0e8d529
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 796 additions and 0 deletions

View file

@ -639,6 +639,8 @@ export default {
},
common: {
all: "Vše",
no_items_in_this_group: "V této skupině nejsou žádné položky",
drop_here_to_move: "Přetáhněte sem pro přesunutí",
states: "Stavy",
state: "Stav",
state_groups: "Skupiny stavů",

View file

@ -653,6 +653,8 @@ export default {
},
common: {
all: "Alle",
no_items_in_this_group: "Keine Elemente in dieser Gruppe",
drop_here_to_move: "Hier ablegen zum Verschieben",
states: "Status",
state: "Status",
state_groups: "Statusgruppen",

View file

@ -478,6 +478,8 @@ export default {
},
common: {
all: "All",
no_items_in_this_group: "No items in this group",
drop_here_to_move: "Drop here to move",
states: "States",
state: "State",
state_groups: "State groups",

View file

@ -654,6 +654,8 @@ export default {
},
common: {
all: "Todo",
no_items_in_this_group: "No hay elementos en este grupo",
drop_here_to_move: "Suelta aquí para mover",
states: "Estados",
state: "Estado",
state_groups: "Grupos de estados",

View file

@ -652,6 +652,8 @@ export default {
},
common: {
all: "Tout",
no_items_in_this_group: "Aucun élément dans ce groupe",
drop_here_to_move: "Déposer ici pour déplacer",
states: "États",
state: "État",
state_groups: "Groupes d'états",

View file

@ -644,6 +644,8 @@ export default {
},
common: {
all: "Semua",
no_items_in_this_group: "Tidak ada item dalam grup ini",
drop_here_to_move: "Letakkan di sini untuk memindahkan",
states: "Negara-negara",
state: "Negara",
state_groups: "Kelompok negara",

View file

@ -647,6 +647,8 @@ export default {
},
common: {
all: "Tutti",
no_items_in_this_group: "Nessun elemento in questo gruppo",
drop_here_to_move: "Rilascia qui per spostare",
states: "Stati",
state: "Stato",
state_groups: "Gruppi di stati",

View file

@ -640,6 +640,8 @@ export default {
},
common: {
all: "すべて",
no_items_in_this_group: "このグループにアイテムはありません",
drop_here_to_move: "移動するにはここにドロップ",
states: "ステータス",
state: "ステータス",
state_groups: "ステータスグループ",

View file

@ -634,6 +634,8 @@ export default {
},
common: {
all: "모두",
no_items_in_this_group: "이 그룹에 항목이 없습니다",
drop_here_to_move: "이동하려면 여기에 드롭하세요",
states: "상태",
state: "상태",
state_groups: "상태 그룹",

View file

@ -640,6 +640,8 @@ export default {
},
common: {
all: "Wszystko",
no_items_in_this_group: "Brak elementów w tej grupie",
drop_here_to_move: "Upuść tutaj, aby przenieść",
states: "Stany",
state: "Stan",
state_groups: "Grupy stanów",

View file

@ -651,6 +651,8 @@ export default {
},
common: {
all: "Todos",
no_items_in_this_group: "Nenhum item neste grupo",
drop_here_to_move: "Solte aqui para mover",
states: "Estados",
state: "Estado",
state_groups: "Grupos de estado",

View file

@ -646,6 +646,8 @@ export default {
},
common: {
all: "Toate",
no_items_in_this_group: "Nu există elemente în acest grup",
drop_here_to_move: "Eliberează aici pentru a muta",
states: "Stări",
state: "Stare",
state_groups: "Grupuri de stări",

View file

@ -643,6 +643,8 @@ export default {
},
common: {
all: "Все",
no_items_in_this_group: "В этой группе нет элементов",
drop_here_to_move: "Перетащите сюда для перемещения",
states: "Статусы",
state: "Статус",
state_groups: "Группы статусов",

View file

@ -641,6 +641,8 @@ export default {
},
common: {
all: "Všetko",
no_items_in_this_group: "V tejto skupine nie sú žiadne položky",
drop_here_to_move: "Presuňte sem na presunutie",
states: "Stavy",
state: "Stav",
state_groups: "Skupiny stavov",

View file

@ -641,6 +641,8 @@ export default {
},
common: {
all: "Tümü",
no_items_in_this_group: "Bu grupta öğe yok",
drop_here_to_move: "Taşımak için buraya bırakın",
states: "Durumlar",
state: "Durum",
state_groups: "Durum grupları",

View file

@ -643,6 +643,8 @@ export default {
},
common: {
all: "Усе",
no_items_in_this_group: "У цій групі немає елементів",
drop_here_to_move: "Перетягніть сюди для переміщення",
states: "Стани",
state: "Стан",
state_groups: "Групи станів",

View file

@ -648,6 +648,8 @@ export default {
},
common: {
all: "Tất cả",
no_items_in_this_group: "Không có mục nào trong nhóm này",
drop_here_to_move: "Thả vào đây để di chuyển",
states: "Trạng thái",
state: "Trạng thái",
state_groups: "Nhóm trạng thái",

View file

@ -629,6 +629,8 @@ export default {
},
common: {
all: "全部",
no_items_in_this_group: "此组中没有项目",
drop_here_to_move: "拖放到此处以移动",
states: "状态",
state: "状态",
state_groups: "状态组",

View file

@ -628,6 +628,8 @@ export default {
},
common: {
all: "全部",
no_items_in_this_group: "此群組中沒有項目",
drop_here_to_move: "拖放到此處以移動",
states: "狀態",
state: "狀態",
state_groups: "狀態群組",

View file

@ -0,0 +1,101 @@
import type { ReactNode } from "react";
// Base Types
export interface IBaseLayoutsBaseItem {
id: string;
[key: string]: unknown;
}
export interface IBaseLayoutsBaseGroup {
id: string;
name: string;
icon?: ReactNode;
payload?: Record<string, unknown>;
count?: number;
}
// Drag & Drop Types
export interface IDragDropHandlers<T extends IBaseLayoutsBaseItem> {
enableDragDrop?: boolean;
onDrop?: (
sourceId: string,
destinationId: string | null,
sourceGroupId: string,
destinationGroupId: string
) => Promise<void>;
canDrag?: (item: T) => boolean;
}
// Render Props
export interface IItemRenderProps<T extends IBaseLayoutsBaseItem> {
renderItem: (item: T, groupId: string) => ReactNode;
}
export interface IGroupHeaderControls {
isCollapsed: boolean;
onToggleGroup: (groupId: string) => void;
}
export interface IGroupHeaderProps extends IGroupHeaderControls {
group: IBaseLayoutsBaseGroup;
itemCount: number;
}
export interface IGroupRenderProps {
renderGroupHeader?: (props: IGroupHeaderProps) => ReactNode;
}
export interface IRenderProps<T extends IBaseLayoutsBaseItem> extends IItemRenderProps<T>, IGroupRenderProps {}
// Layout Configuration
export type TBaseLayoutType = "list" | "kanban";
export interface IBaseLayoutConfig {
key: TBaseLayoutType;
icon: React.ComponentType<React.SVGProps<SVGSVGElement>>;
label: string;
}
// Base Layout Props
export interface IBaseLayoutsBaseProps<T extends IBaseLayoutsBaseItem> extends IDragDropHandlers<T>, IRenderProps<T> {
items: Record<string, T>;
groupedItemIds: Record<string, string[]>;
groups: IBaseLayoutsBaseGroup[];
collapsedGroups?: string[];
onToggleGroup?: (groupId: string) => void;
isLoading?: boolean;
loadMoreItems?: (groupId: string) => void;
showEmptyGroups?: boolean;
className?: string;
}
// Group Props
export interface IBaseLayoutsBaseGroupProps<T extends IBaseLayoutsBaseItem>
extends IDragDropHandlers<T>,
IRenderProps<T> {
group: IBaseLayoutsBaseGroup;
itemIds: string[];
items: Record<string, T>;
isCollapsed: boolean;
onToggleGroup: (groupId: string) => void;
loadMoreItems?: (groupId: string) => void;
}
// Item Props
export interface IBaseLayoutsBaseItemProps<T extends IBaseLayoutsBaseItem>
extends IDragDropHandlers<T>,
IItemRenderProps<T> {
item: T;
index: number;
groupId: string;
isLast: boolean;
}

View file

@ -0,0 +1,3 @@
export * from "./base";
export * from "./list";
export * from "./kanban";

View file

@ -0,0 +1,24 @@
import type {
IBaseLayoutsBaseItem,
IBaseLayoutsBaseProps,
IBaseLayoutsBaseGroupProps,
IBaseLayoutsBaseItemProps,
} from "./base";
export type IBaseLayoutsKanbanItem = IBaseLayoutsBaseItem;
// Main Kanban Layout Props
export interface IBaseLayoutsKanbanProps<T extends IBaseLayoutsKanbanItem> extends IBaseLayoutsBaseProps<T> {
groupClassName?: string;
}
// Kanban Column/Group Props
export interface IBaseLayoutsKanbanGroupProps<T extends IBaseLayoutsKanbanItem> extends IBaseLayoutsBaseGroupProps<T> {
groupClassName?: string;
}
// Kanban Card/Item Props
export type IBaseLayoutsKanbanItemProps<T extends IBaseLayoutsKanbanItem> = IBaseLayoutsBaseItemProps<T>;

View file

@ -0,0 +1,20 @@
import type {
IBaseLayoutsBaseItem,
IBaseLayoutsBaseProps,
IBaseLayoutsBaseGroupProps,
IBaseLayoutsBaseItemProps,
} from "./base";
export type IBaseLayoutsListItem = IBaseLayoutsBaseItem;
// Main List Layout Props
export type IBaseLayoutsListProps<T extends IBaseLayoutsListItem> = IBaseLayoutsBaseProps<T>;
// Group component props
export type IBaseLayoutsListGroupProps<T extends IBaseLayoutsListItem> = IBaseLayoutsBaseGroupProps<T>;
// Item component props
export type IBaseLayoutsListItemProps<T extends IBaseLayoutsListItem> = IBaseLayoutsBaseItemProps<T>;

View file

@ -47,3 +47,4 @@ export * from "./workspace";
export * from "./workspace-draft-issues/base";
export * from "./workspace-notifications";
export * from "./workspace-views";
export * from "./base-layouts";