feat(grid): incremental column freeze and single-column unfreeze
This commit is contained in:
14 files changed
+108
-26
No files matched your search
@@ -1981,7 +1981,8 @@ const {
|
||||
onTableDataGridColumnOrderChanged,
|
||||
frozenColumnCount,
|
||||
freezeToColumn,
|
||||
freezeSelectedColumns: freezeSelectedColumnsInLayout,
|
||||
freezeSelectedColumnsIncrementally,
|
||||
unfreezeSelectedColumns,
|
||||
unfreezeAllColumns: unfreezeAllColumnsInLayout,
|
||||
} = useDataGridColumnLayoutState({
|
||||
columns: computed(() => props.result.columns),
|
||||
@@ -2329,7 +2330,15 @@ function resetColumnOrder() {
|
||||
}
|
||||
|
||||
function freezeSelectedColumns(selectedVisibleColumnIndexes: number[]) {
|
||||
applyColumnOrderChange(() => freezeSelectedColumnsInLayout(selectedVisibleColumnIndexes));
|
||||
applyColumnOrderChange(() => freezeSelectedColumnsIncrementally(selectedVisibleColumnIndexes));
|
||||
}
|
||||
|
||||
function freezeCurrentOrSelectedColumns(selectedVisibleColumnIndexes: number[]) {
|
||||
applyColumnOrderChange(() => freezeSelectedColumnsIncrementally(selectedVisibleColumnIndexes));
|
||||
}
|
||||
|
||||
function unfreezeCurrentOrSelectedColumns(selectedVisibleColumnIndexes: number[]) {
|
||||
applyColumnOrderChange(() => unfreezeSelectedColumns(selectedVisibleColumnIndexes));
|
||||
}
|
||||
|
||||
function unfreezeAllColumns() {
|
||||
@@ -11614,8 +11623,10 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
|
||||
localDescending: t("grid.sortCurrentPageDescending"),
|
||||
clearSort: t("grid.clearSort"),
|
||||
freezeToColumn: t("grid.freezeToColumn"),
|
||||
freezeSelectedColumns: t("grid.freezeSelectedColumns"),
|
||||
unfreezeColumns: t("grid.unfreezeColumns"),
|
||||
freezeSelectedColumns: t("grid.freezeSelectedColumns", { count: selectedColumnCount }),
|
||||
freezeCurrentColumn: t("grid.freezeCurrentColumn"),
|
||||
unfreezeCurrentColumn: t("grid.unfreezeCurrentColumn"),
|
||||
unfreezeColumns: t("grid.unfreezeColumns", { count: frozenColumnCount.value }),
|
||||
hideColumn: t("grid.hideColumn"),
|
||||
hideSelectedColumns: t("grid.hideSelectedColumns", { count: selectedColumnCount }),
|
||||
showAllColumnsMenu: t("grid.showAllColumnsMenu"),
|
||||
@@ -11645,6 +11656,18 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
|
||||
freezeSelectedColumns(selectedVisibleColumnIndexes());
|
||||
clearCellSelection();
|
||||
},
|
||||
freezeCurrentColumn: () => {
|
||||
const indexes = selectedVisibleColumnIndexes();
|
||||
const idx = contextHeaderVisibleColIdx.value;
|
||||
freezeCurrentOrSelectedColumns(indexes.length > 1 ? indexes : idx === null ? [] : [idx]);
|
||||
clearCellSelection();
|
||||
},
|
||||
unfreezeCurrentColumn: () => {
|
||||
const indexes = selectedVisibleColumnIndexes();
|
||||
const idx = contextHeaderVisibleColIdx.value;
|
||||
unfreezeCurrentOrSelectedColumns(indexes.length > 1 ? indexes : idx === null ? [] : [idx]);
|
||||
clearCellSelection();
|
||||
},
|
||||
unfreezeColumns: () => {
|
||||
unfreezeAllColumns();
|
||||
clearCellSelection();
|
||||
|
||||
+1
-1
@@ -299,7 +299,7 @@ describe("DataGrid context menu target lifecycle", () => {
|
||||
await settle();
|
||||
|
||||
expect(contextMenuLabels()).toContain("Copy Selected Column Names (2)");
|
||||
expect(contextMenuLabels()).toContain("Freeze Selected Columns");
|
||||
expect(contextMenuLabels()).toContain("Freeze Selected Columns (2)");
|
||||
});
|
||||
|
||||
it("offers snapshots for full-column selections from the column header", async () => {
|
||||
|
||||
@@ -297,6 +297,38 @@ export function useDataGridColumnLayoutState(options: {
|
||||
setFrozenColumnCount(selectedActualIdxs.length);
|
||||
}
|
||||
|
||||
function freezeSelectedColumnsIncrementally(selectedVisibleColIdxs: number[]) {
|
||||
if (selectedVisibleColIdxs.length === 0) return;
|
||||
const visibleIdxs = visibleColumnIndexes.value;
|
||||
const selectedActualIdxs = [...new Set(selectedVisibleColIdxs.map((vIdx) => visibleIdxs[vIdx]).filter((idx): idx is number => idx !== undefined))];
|
||||
if (selectedActualIdxs.length === 0) return;
|
||||
const currentOrder = orderedDisplayableColumnIndexes.value;
|
||||
const frozenVisibleIndexes = visibleColumnIndexes.value.slice(0, frozenColumnCount.value);
|
||||
const frozenSet = new Set(frozenVisibleIndexes);
|
||||
const additions = selectedActualIdxs.filter((idx) => !frozenSet.has(idx));
|
||||
if (additions.length === 0) return;
|
||||
if (columnOrderSnapshotBeforeFreeze.value === null) columnOrderSnapshotBeforeFreeze.value = [...persistedColumnOrderKeys.value];
|
||||
const remaining = currentOrder.filter((idx) => !additions.includes(idx));
|
||||
const frozenEnd = frozenVisibleIndexes.reduce((end, idx) => Math.max(end, remaining.indexOf(idx) + 1), 0);
|
||||
persistColumnOrder([...remaining.slice(0, frozenEnd), ...additions, ...remaining.slice(frozenEnd)]);
|
||||
setFrozenColumnCount(frozenColumnCount.value + additions.length);
|
||||
}
|
||||
|
||||
function unfreezeSelectedColumns(selectedVisibleColIdxs: number[]) {
|
||||
if (selectedVisibleColIdxs.length === 0 || frozenColumnCount.value === 0) return;
|
||||
const visibleIdxs = visibleColumnIndexes.value;
|
||||
const selected = new Set(selectedVisibleColIdxs.map((vIdx) => visibleIdxs[vIdx]).filter((idx): idx is number => idx !== undefined));
|
||||
const currentOrder = orderedDisplayableColumnIndexes.value;
|
||||
const frozen = visibleColumnIndexes.value.slice(0, frozenColumnCount.value);
|
||||
const removing = frozen.filter((idx) => selected.has(idx));
|
||||
if (removing.length === 0) return;
|
||||
if (columnOrderSnapshotBeforeFreeze.value === null) columnOrderSnapshotBeforeFreeze.value = [...persistedColumnOrderKeys.value];
|
||||
const nextFrozen = frozen.filter((idx) => !selected.has(idx));
|
||||
persistColumnOrder(currentOrder.filter((idx) => !removing.includes(idx)).concat(removing));
|
||||
setFrozenColumnCount(nextFrozen.length);
|
||||
if (nextFrozen.length === 0) unfreezeAllColumns();
|
||||
}
|
||||
|
||||
function unfreezeAllColumns() {
|
||||
setFrozenColumnCount(0);
|
||||
if (columnOrderSnapshotBeforeFreeze.value !== null) {
|
||||
@@ -441,6 +473,8 @@ export function useDataGridColumnLayoutState(options: {
|
||||
frozenColumnCount,
|
||||
freezeToColumn,
|
||||
freezeSelectedColumns,
|
||||
freezeSelectedColumnsIncrementally,
|
||||
unfreezeSelectedColumns,
|
||||
unfreezeAllColumns,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2048,8 +2048,10 @@ export default withEnglishFallback({
|
||||
sortDatabaseDescending: "Verilənlər bazasını azalan sıra ilə sırala",
|
||||
clearSort: "Sıralamanı təmizlə",
|
||||
freezeToColumn: "Bu sütuna qədər sabitlə",
|
||||
freezeSelectedColumns: "Seçilmiş sütunları sabitlə",
|
||||
unfreezeColumns: "Sütunların sabitlənməsini ləğv et",
|
||||
freezeSelectedColumns: "Seçilmiş sütunları sabitlə ({count})",
|
||||
freezeCurrentColumn: "Cari sütunu sabitlə",
|
||||
unfreezeCurrentColumn: "Cari sütunun sabitini aç",
|
||||
unfreezeColumns: "Sütunların sabitlənməsini ləğv et ({count})",
|
||||
hideColumn: "Bu sütunu gizlət",
|
||||
hideSelectedColumns: "Seçilmiş sütunları gizlət ({count})",
|
||||
showAllColumnsMenu: "Bütün sütunları göstər",
|
||||
|
||||
@@ -2199,8 +2199,10 @@ export default {
|
||||
sortDatabaseDescending: "Sort Database Descending",
|
||||
clearSort: "Clear Sort",
|
||||
freezeToColumn: "Freeze to This Column",
|
||||
freezeSelectedColumns: "Freeze Selected Columns",
|
||||
unfreezeColumns: "Unfreeze Columns",
|
||||
freezeSelectedColumns: "Freeze Selected Columns ({count})",
|
||||
freezeCurrentColumn: "Freeze Current Column",
|
||||
unfreezeCurrentColumn: "Unfreeze Current Column",
|
||||
unfreezeColumns: "Unfreeze Columns ({count})",
|
||||
hideColumn: "Hide This Column",
|
||||
hideSelectedColumns: "Hide Selected Columns ({count})",
|
||||
showAllColumnsMenu: "Show All Columns",
|
||||
|
||||
@@ -2047,8 +2047,10 @@ export default withEnglishFallback({
|
||||
sortDatabaseDescending: "Ordenar base de datos descendente",
|
||||
clearSort: "Limpiar orden",
|
||||
freezeToColumn: "Inmovilizar hasta esta columna",
|
||||
freezeSelectedColumns: "Inmovilizar columnas seleccionadas",
|
||||
unfreezeColumns: "Desinmovilizar columnas",
|
||||
freezeSelectedColumns: "Inmovilizar columnas seleccionadas ({count})",
|
||||
freezeCurrentColumn: "Inmovilizar columna actual",
|
||||
unfreezeCurrentColumn: "Desinmovilizar columna actual",
|
||||
unfreezeColumns: "Desinmovilizar columnas ({count})",
|
||||
hideColumn: "Ocultar esta columna",
|
||||
hideSelectedColumns: "Ocultar columnas seleccionadas ({count})",
|
||||
showAllColumnsMenu: "Mostrar todas las columnas",
|
||||
|
||||
@@ -2045,8 +2045,10 @@ export default withEnglishFallback({
|
||||
sortDatabaseDescending: "Ordina database decrescente",
|
||||
clearSort: "Rimuovi Ordinamento",
|
||||
freezeToColumn: "Blocca fino a questa colonna",
|
||||
freezeSelectedColumns: "Blocca colonne selezionate",
|
||||
unfreezeColumns: "Sblocca colonne",
|
||||
freezeSelectedColumns: "Blocca colonne selezionate ({count})",
|
||||
freezeCurrentColumn: "Blocca colonna corrente",
|
||||
unfreezeCurrentColumn: "Sblocca colonna corrente",
|
||||
unfreezeColumns: "Sblocca colonne ({count})",
|
||||
hideColumn: "Nascondi questa colonna",
|
||||
hideSelectedColumns: "Nascondi colonne selezionate ({count})",
|
||||
showAllColumnsMenu: "Mostra tutte le colonne",
|
||||
|
||||
@@ -2057,8 +2057,10 @@ export default withEnglishFallback({
|
||||
sortDatabaseDescending: "データベースで降順に並び替え",
|
||||
clearSort: "並び替えをクリア",
|
||||
freezeToColumn: "この列まで固定",
|
||||
freezeSelectedColumns: "選択列を固定",
|
||||
unfreezeColumns: "列の固定を解除",
|
||||
freezeSelectedColumns: "選択列を固定 ({count})",
|
||||
freezeCurrentColumn: "現在の列を固定",
|
||||
unfreezeCurrentColumn: "現在の列の固定を解除",
|
||||
unfreezeColumns: "列の固定を解除 ({count})",
|
||||
hideColumn: "この列を非表示",
|
||||
hideSelectedColumns: "選択した列を非表示 ({count})",
|
||||
showAllColumnsMenu: "すべての列を表示",
|
||||
|
||||
@@ -2038,8 +2038,10 @@ export default withEnglishFallback({
|
||||
sortDatabaseDescending: "데이터베이스 내림차순 정렬",
|
||||
clearSort: "정렬 지우기",
|
||||
freezeToColumn: "이 컬럼까지 고정",
|
||||
freezeSelectedColumns: "선택한 컬럼 고정",
|
||||
unfreezeColumns: "컬럼 고정 해제",
|
||||
freezeSelectedColumns: "선택한 컬럼 고정 ({count})",
|
||||
freezeCurrentColumn: "현재 열 고정",
|
||||
unfreezeCurrentColumn: "현재 열 고정 해제",
|
||||
unfreezeColumns: "컬럼 고정 해제 ({count})",
|
||||
hideColumn: "이 컬럼 숨기기",
|
||||
hideSelectedColumns: "선택한 컬럼 숨기기 ({count})",
|
||||
showAllColumnsMenu: "모든 컬럼 표시",
|
||||
|
||||
@@ -2047,8 +2047,10 @@ export default withEnglishFallback({
|
||||
sortDatabaseDescending: "Ordenar Banco de Dados Decrescente",
|
||||
clearSort: "Limpar Ordenação",
|
||||
freezeToColumn: "Congelar até esta coluna",
|
||||
freezeSelectedColumns: "Congelar colunas selecionadas",
|
||||
unfreezeColumns: "Descongelar colunas",
|
||||
freezeSelectedColumns: "Congelar colunas selecionadas ({count})",
|
||||
freezeCurrentColumn: "Congelar coluna atual",
|
||||
unfreezeCurrentColumn: "Descongelar coluna atual",
|
||||
unfreezeColumns: "Descongelar colunas ({count})",
|
||||
hideColumn: "Ocultar esta coluna",
|
||||
hideSelectedColumns: "Ocultar colunas selecionadas ({count})",
|
||||
showAllColumnsMenu: "Mostrar todas as colunas",
|
||||
|
||||
@@ -2043,8 +2043,10 @@ export default withEnglishFallback({
|
||||
sortDatabaseDescending: "Veritabanında Azalan Sırala",
|
||||
clearSort: "Sıralamayı Temizle",
|
||||
freezeToColumn: "Bu Sütuna Kadar Dondur",
|
||||
freezeSelectedColumns: "Seçili Sütunları Dondur",
|
||||
unfreezeColumns: "Sütun Dondurmayı Kaldır",
|
||||
freezeSelectedColumns: "Seçili Sütunları Dondur ({count})",
|
||||
freezeCurrentColumn: "Geçerli sütunu sabitle",
|
||||
unfreezeCurrentColumn: "Geçerli sütunun sabitlemesini kaldır",
|
||||
unfreezeColumns: "Sütun Dondurmayı Kaldır ({count})",
|
||||
hideColumn: "Bu Sütunu Gizle",
|
||||
hideSelectedColumns: "Seçili Sütunları Gizle ({count})",
|
||||
showAllColumnsMenu: "Tüm Sütunları Göster",
|
||||
|
||||
@@ -2114,8 +2114,10 @@ export default withEnglishFallback({
|
||||
sortDatabaseDescending: "数据库降序排序",
|
||||
clearSort: "清除排序",
|
||||
freezeToColumn: "冻结到此列",
|
||||
freezeSelectedColumns: "冻结选中列",
|
||||
unfreezeColumns: "取消冻结",
|
||||
freezeSelectedColumns: "冻结选中列({count} 列)",
|
||||
freezeCurrentColumn: "冻结当前列",
|
||||
unfreezeCurrentColumn: "取消冻结当前列",
|
||||
unfreezeColumns: "取消冻结({count} 列)",
|
||||
hideColumn: "隐藏此列",
|
||||
hideSelectedColumns: "隐藏选中列({count} 列)",
|
||||
showAllColumnsMenu: "显示全部列",
|
||||
|
||||
@@ -2048,8 +2048,10 @@ export default withEnglishFallback({
|
||||
sortDatabaseDescending: "資料庫遞減排序",
|
||||
clearSort: "清除排序",
|
||||
freezeToColumn: "凍結到此欄",
|
||||
freezeSelectedColumns: "凍結選取欄",
|
||||
unfreezeColumns: "取消凍結",
|
||||
freezeSelectedColumns: "凍結選取欄({count} 欄)",
|
||||
freezeCurrentColumn: "凍結目前欄",
|
||||
unfreezeCurrentColumn: "取消凍結目前欄",
|
||||
unfreezeColumns: "取消凍結({count} 欄)",
|
||||
hideColumn: "隱藏此欄",
|
||||
hideSelectedColumns: "隱藏選取欄({count} 欄)",
|
||||
showAllColumnsMenu: "顯示全部欄",
|
||||
|
||||
@@ -90,7 +90,8 @@ export function createDataGridColumnContextMenuItems(options: {
|
||||
labels: Record<
|
||||
"copyName" | "copyNames" | "details" | "copyAlterSql" | "databaseAscending" | "databaseDescending" | "localAscending" | "localDescending" | "clearSort" | "freezeToColumn" | "freezeSelectedColumns" | "unfreezeColumns" | "hideColumn" | "hideSelectedColumns" | "showAllColumnsMenu",
|
||||
string
|
||||
>;
|
||||
> &
|
||||
Partial<Record<"freezeCurrentColumn" | "unfreezeCurrentColumn", string>>;
|
||||
icons: Pick<DataGridContextMenuIcons, "copy" | "columnDetails" | "database" | "ascending" | "descending" | "clearSort">;
|
||||
actions: {
|
||||
copyName: () => void;
|
||||
@@ -100,6 +101,8 @@ export function createDataGridColumnContextMenuItems(options: {
|
||||
sort: (direction: "asc" | "desc" | null, mode: "database" | "local") => void;
|
||||
freezeToColumn: () => void;
|
||||
freezeSelectedColumns: () => void;
|
||||
freezeCurrentColumn?: () => void;
|
||||
unfreezeCurrentColumn?: () => void;
|
||||
unfreezeColumns: () => void;
|
||||
hideColumn: () => void;
|
||||
hideSelectedColumns: () => void;
|
||||
@@ -142,11 +145,13 @@ export function createDataGridColumnContextMenuItems(options: {
|
||||
items.push({ label: options.labels.showAllColumnsMenu, action: options.actions.showAllColumnsMenu });
|
||||
}
|
||||
if ((options.frozenColumnCount ?? 0) > 0) {
|
||||
if ((options.contextVisibleColIdx ?? -1) < (options.frozenColumnCount ?? 0) && options.labels.unfreezeCurrentColumn && options.actions.unfreezeCurrentColumn) items.push({ label: options.labels.unfreezeCurrentColumn, action: options.actions.unfreezeCurrentColumn });
|
||||
items.push({ label: options.labels.unfreezeColumns, action: options.actions.unfreezeColumns });
|
||||
}
|
||||
if (options.hasColumnSelection) {
|
||||
items.push({ label: options.labels.freezeSelectedColumns, action: options.actions.freezeSelectedColumns });
|
||||
}
|
||||
if (options.labels.freezeCurrentColumn && options.actions.freezeCurrentColumn) items.push({ label: options.labels.freezeCurrentColumn, action: options.actions.freezeCurrentColumn });
|
||||
items.push({ label: options.labels.freezeToColumn, action: options.actions.freezeToColumn });
|
||||
}
|
||||
return items;
|
||||
|
||||
Reference in new issue
Block a user