Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/hooks/src/use-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type TableColumnCheck = {
title: TableColumnCheckTitle;
checked: boolean;
visible: boolean;
fixed: 'left' | 'right' | 'unFixed';
};

export interface UseTableOptions<ResponseData, ApiData, Column, Pagination extends boolean> {
Expand Down Expand Up @@ -78,12 +79,14 @@ export default function useTable<ResponseData, ApiData, Column, Pagination exten

function reloadColumns() {
const checkMap = new Map(columnChecks.value.map(col => [col.key, col.checked]));
const fixedMap = new Map(columnChecks.value.map(col => [col.key, col.fixed]));

const defaultChecks = getColumnChecks(columns());

columnChecks.value = defaultChecks.map(col => ({
...col,
checked: checkMap.get(col.key) ?? col.checked
checked: checkMap.get(col.key) ?? col.checked,
fixed: (fixedMap.get(col.key) !== 'unFixed' ? fixedMap.get(col.key) : undefined) ?? col.fixed
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic for preserving the fixed state has a bug. The current expression (fixedMap.get(col.key) !== 'unFixed' ? fixedMap.get(col.key) : undefined) ?? col.fixed will not correctly preserve a user's explicit choice to unfix a column.

When a user sets a column to 'unFixed', this logic evaluates to undefined ?? col.fixed, which falls back to the default col.fixed value. If the column was originally fixed (e.g., 'left' or 'right'), it will revert to that fixed state, ignoring the user's 'unFixed' preference.

The logic should be:

fixed: fixedMap.has(col.key) ? fixedMap.get(col.key) : col.fixed

This way, if a fixed preference exists in the map (including 'unFixed'), it's used; otherwise, fall back to the default.

Suggested change
fixed: (fixedMap.get(col.key) !== 'unFixed' ? fixedMap.get(col.key) : undefined) ?? col.fixed
fixed: fixedMap.has(col.key) ? fixedMap.get(col.key) : col.fixed

Copilot uses AI. Check for mistakes.
}));
}

Expand Down
42 changes: 34 additions & 8 deletions src/components/advanced/table-column-setting.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ defineOptions({
const columns = defineModel<NaiveUI.TableColumnCheck[]>('columns', {
required: true
});

const tooltipRecord: Record<NaiveUI.TableColumnFixed, App.I18n.I18nKey> = {
left: 'datatable.fixed.right',
right: 'datatable.fixed.unFixed',
unFixed: 'datatable.fixed.left'
};

function handleFixed(column: NaiveUI.TableColumnCheck) {
const fixedOptions: NaiveUI.TableColumnFixed[] = ['left', 'right', 'unFixed'];
const index = fixedOptions.findIndex(item => item === column.fixed);
const nextIndex = index === fixedOptions.length - 1 ? 0 : index + 1;
column.fixed = fixedOptions[nextIndex];
}
</script>

<template>
Expand All @@ -25,16 +38,29 @@ const columns = defineModel<NaiveUI.TableColumnCheck[]>('columns', {
<div
v-for="item in columns"
:key="item.key"
class="h-36px flex-y-center rd-4px hover:(bg-primary bg-opacity-20)"
class="h-36px flex-y-center justify-between gap-6px"
:class="{ hidden: !item.visible }"
>
<icon-mdi-drag class="mr-8px h-full cursor-move text-icon" />
<NCheckbox v-model:checked="item.checked" class="none_draggable flex-1">
<template v-if="typeof item.title === 'function'">
<component :is="item.title" />
</template>
<template v-else>{{ item.title }}</template>
</NCheckbox>
<div class="flex-y-center rd-4px hover:(bg-primary bg-opacity-20)">
<icon-mdi-drag class="mr-8px h-full cursor-move text-icon" />
<NCheckbox v-model:checked="item.checked" class="none_draggable flex-1">
<template v-if="typeof item.title === 'function'">
<component :is="item.title" />
</template>
<template v-else>{{ item.title }}</template>
</NCheckbox>
</div>
<ButtonIcon
:disabled="!item.checked"
text
:focusable="false"
:tooltip-content="$t(tooltipRecord[item.fixed!])"
@click="handleFixed(item)"
>
<icon-octicon-pin-16 v-if="item.fixed === 'unFixed'" />
<icon-octicon-pin-16 v-else-if="item.fixed === 'left'" class="rotate-270" />
<icon-octicon-pin-slash-16 v-else />
Comment on lines +60 to +62
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The icon displayed for the 'right' fixed state is misleading. When a column is fixed to the right (item.fixed === 'right'), the code shows icon-octicon-pin-slash-16, which typically represents "unpinned" or "not fixed". This is confusing for users.

Consider using a more appropriate icon for the right-fixed state, such as:

  • A pin icon rotated to point right (e.g., class="rotate-90")
  • Or keep the regular pin icon with a different styling to distinguish it from left-fixed

The current logic makes it appear that right-fixed columns are unpinned, which contradicts their actual behavior.

Copilot uses AI. Check for mistakes.
</ButtonIcon>
</div>
</VueDraggable>
</NPopover>
Expand Down
12 changes: 11 additions & 1 deletion src/hooks/common/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,20 +266,23 @@ function getColumnChecks<Column extends NaiveUI.TableColumn<any>>(
key: column.key as string,
title: column.title!,
checked: true,
fixed: column.fixed ?? 'unFixed',
visible: getColumnVisible?.(column) ?? true
});
} else if (column.type === 'selection') {
checks.push({
key: SELECTION_KEY,
title: $t('common.check'),
checked: true,
fixed: column.fixed ?? 'unFixed',
visible: getColumnVisible?.(column) ?? false
});
} else if (column.type === 'expand') {
checks.push({
key: EXPAND_KEY,
title: $t('common.expandColumn'),
checked: true,
fixed: column.fixed ?? 'unFixed',
visible: getColumnVisible?.(column) ?? false
});
}
Expand All @@ -301,7 +304,14 @@ function getColumns<Column extends NaiveUI.TableColumn<any>>(cols: Column[], che
}
});

const filteredColumns = checks.filter(item => item.checked).map(check => columnMap.get(check.key) as Column);
const filteredColumns = checks
.filter(item => item.checked)
.map(check => {
return {
...columnMap.get(check.key),
fixed: check.fixed
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fixed property is being set to the string 'unFixed' which is not a valid value for naive-ui's DataTable columns. According to naive-ui's API, the fixed property should be either 'left', 'right', or undefined/false (not set).

When check.fixed is 'unFixed', the fixed property should not be set at all or should be set to undefined. Consider updating the logic to:

fixed: check.fixed !== 'unFixed' ? check.fixed : undefined

This ensures that columns marked as 'unFixed' don't have the fixed property set, which allows them to scroll normally.

Suggested change
fixed: check.fixed
fixed: check.fixed !== 'unFixed' ? check.fixed : undefined

Copilot uses AI. Check for mistakes.
} as Column;
});

return filteredColumns;
}
Expand Down
7 changes: 6 additions & 1 deletion src/locales/langs/en-us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,12 @@ const local: App.I18n.Schema = {
unpin: 'Unpin'
},
datatable: {
itemCount: 'Total {total} items'
itemCount: 'Total {total} items',
fixed: {
left: 'Left Fixed',
right: 'Right Fixed',
unFixed: 'Unfixed'
}
}
};

Expand Down
7 changes: 6 additions & 1 deletion src/locales/langs/zh-cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,12 @@ const local: App.I18n.Schema = {
unpin: '取消固定'
},
datatable: {
itemCount: '共 {total} 条'
itemCount: '共 {total} 条',
fixed: {
left: '左固定',
right: '右固定',
unFixed: '取消固定'
}
}
};

Expand Down
5 changes: 5 additions & 0 deletions src/typings/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,11 @@ declare namespace App {
};
datatable: {
itemCount: string;
fixed: {
left: string;
right: string;
unFixed: string;
};
};
};

Expand Down
1 change: 1 addition & 0 deletions src/typings/naive-ui.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ declare namespace NaiveUI {
type DataTableSelectionColumn<T> = import('naive-ui').DataTableSelectionColumn<T>;
type TableColumnGroup<T> = import('naive-ui/es/data-table/src/interface').TableColumnGroup<T>;
type TableColumnCheck = import('@sa/hooks').TableColumnCheck;
type TableColumnFixed = import('@sa/hooks').TableColumnCheck['fixed'];

type SetTableColumnKey<C, T> = Omit<C, 'key'> & { key: keyof T | (string & {}) };

Expand Down