fe4512f80c
- Fix duplication of tabs in dashboards that didn't open the duplicated tab in the side panel: replaced the logic that used Math.round with an algorithm that switches the positions of the elements. We will keep relying on integers, but it will work well in all cases. - Make dnd work with record page layouts, where there is a pinned tab - Make tab movements work with pinned tab, too - Allow user to set a tab as the pinned tab - Make backend changes to be able to save tabs with `layoutMode` https://github.com/user-attachments/assets/ce1130fa-71df-49ba-ba2f-6f971e15dd49 --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
84 lines
2.7 KiB
TypeScript
84 lines
2.7 KiB
TypeScript
import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext';
|
|
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
|
import { sortTabsByPosition } from '@/page-layout/utils/sortTabsByPosition';
|
|
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
|
import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState';
|
|
import { useStore } from 'jotai';
|
|
import { useCallback } from 'react';
|
|
|
|
export const useMovePageLayoutTab = (pageLayoutIdFromProps?: string) => {
|
|
const pageLayoutId = useAvailableComponentInstanceIdOrThrow(
|
|
PageLayoutComponentInstanceContext,
|
|
pageLayoutIdFromProps,
|
|
);
|
|
|
|
const pageLayoutDraftState = useAtomComponentStateCallbackState(
|
|
pageLayoutDraftComponentState,
|
|
pageLayoutId,
|
|
);
|
|
|
|
const store = useStore();
|
|
|
|
const moveLeft = useCallback(
|
|
(tabId: string) => {
|
|
store.set(pageLayoutDraftState, (prev) => {
|
|
const sorted = sortTabsByPosition(prev.tabs);
|
|
const index = sorted.findIndex((t) => t.id === tabId);
|
|
if (index <= 0) {
|
|
return prev;
|
|
}
|
|
|
|
const neighborId = sorted[index - 1].id;
|
|
const currentPosition = sorted[index].position;
|
|
const neighborPosition = sorted[index - 1].position;
|
|
|
|
return {
|
|
...prev,
|
|
tabs: prev.tabs.map((t) => {
|
|
if (t.id === tabId) {
|
|
return { ...t, position: neighborPosition };
|
|
}
|
|
if (t.id === neighborId) {
|
|
return { ...t, position: currentPosition };
|
|
}
|
|
return t;
|
|
}),
|
|
};
|
|
});
|
|
},
|
|
[pageLayoutDraftState, store],
|
|
);
|
|
|
|
const moveRight = useCallback(
|
|
(tabId: string) => {
|
|
store.set(pageLayoutDraftState, (prev) => {
|
|
const sorted = sortTabsByPosition(prev.tabs);
|
|
const index = sorted.findIndex((t) => t.id === tabId);
|
|
if (index < 0 || index >= sorted.length - 1) {
|
|
return prev;
|
|
}
|
|
|
|
const neighborId = sorted[index + 1].id;
|
|
const currentPosition = sorted[index].position;
|
|
const neighborPosition = sorted[index + 1].position;
|
|
|
|
return {
|
|
...prev,
|
|
tabs: prev.tabs.map((t) => {
|
|
if (t.id === tabId) {
|
|
return { ...t, position: neighborPosition };
|
|
}
|
|
if (t.id === neighborId) {
|
|
return { ...t, position: currentPosition };
|
|
}
|
|
return t;
|
|
}),
|
|
};
|
|
});
|
|
},
|
|
[pageLayoutDraftState, store],
|
|
);
|
|
|
|
return { moveLeft, moveRight };
|
|
};
|