import { useMemo } from 'react';
import { DndContext, closestCenter } from '@dnd-kit/core';
import {
arrayMove,
SortableContext,
sortableKeyboardCoordinates,
useSortable,
} from '@dnd-kit/sortable';
import {
KeyboardSensor,
PointerSensor,
TouchSensor,
useSensor,
useSensors,
} from '@dnd-kit/core';
import { CSS } from '@dnd-kit/utilities';
import { Avatar, ButtonBase } from '@mui/material';
import { AppCircle, AppCircleContainer, AppCircleLabel } from './Apps-styles';
import { getBaseApiReact } from '../../App';
import { executeEvent } from '../../utils/events';
import {
settingsLocalLastUpdatedAtom,
sortablePinnedAppsAtom,
} from '../../atoms/global';
import { saveToLocalStorage } from './AppsNavBarDesktop';
import { ContextMenuPinnedApps } from '../ContextMenuPinnedApps';
import LockIcon from '@mui/icons-material/Lock';
import { useHandlePrivateApps } from './useHandlePrivateApps';
import { useAtom, useSetAtom } from 'jotai';
const SortableItem = ({ id, name, app, isDesktop }) => {
const { openApp } = useHandlePrivateApps();
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id });
const style = {
backgroundColor: '#f9f9f9',
border: '1px solid #ccc',
borderRadius: '4px',
color: 'black',
cursor: 'grab',
marginBottom: '5px',
padding: '10px',
transform: CSS.Transform.toString(transform),
transition,
};
return (
{
if (app?.isPrivate) {
try {
await openApp(app?.privateAppProperties);
} catch (error) {
console.error(error);
}
} else {
executeEvent('addTab', {
data: app,
});
}
}}
>
{app?.isPrivate && !app?.privateAppProperties?.logo ? (
) : (
)}
{app?.isPrivate ? (
{`${app?.privateAppProperties?.appName || 'Private'}`}
) : (
{app?.metadata?.title || app?.name}
)}
);
};
export const SortablePinnedApps = ({
isDesktop,
myWebsite,
myApp,
availableQapps = [],
}) => {
const [pinnedApps, setPinnedApps] = useAtom(sortablePinnedAppsAtom);
const setSettingsLocalLastUpdated = useSetAtom(settingsLocalLastUpdatedAtom);
const transformPinnedApps = useMemo(() => {
// Clone the existing pinned apps list
let pinned = [...pinnedApps];
// Function to add or update `isMine` property
const addOrUpdateIsMine = (pinnedList, appToCheck) => {
if (!appToCheck) return pinnedList;
const existingIndex = pinnedList.findIndex(
(item) =>
item?.service === appToCheck?.service &&
item?.name === appToCheck?.name
);
if (existingIndex !== -1) {
// If the app is already in the list, update it with `isMine: true`
pinnedList[existingIndex] = {
...pinnedList[existingIndex],
isMine: true,
};
} else {
// If not in the list, add it with `isMine: true` at the beginning
pinnedList.unshift({ ...appToCheck, isMine: true });
}
return pinnedList;
};
// Update or add `myWebsite` and `myApp` while preserving their positions
pinned = addOrUpdateIsMine(pinned, myWebsite);
pinned = addOrUpdateIsMine(pinned, myApp);
// Update pinned list based on availableQapps
pinned = pinned.map((pin) => {
const findIndex = availableQapps?.findIndex(
(item) => item?.service === pin?.service && item?.name === pin?.name
);
if (findIndex !== -1)
return {
...availableQapps[findIndex],
...pin,
};
return pin;
});
return pinned;
}, [myApp, myWebsite, pinnedApps, availableQapps]);
const sensors = useSensors(
useSensor(PointerSensor, {
activationConstraint: {
distance: 10, // Set a distance to avoid triggering drag on small movements
},
}),
useSensor(TouchSensor, {
activationConstraint: {
distance: 10, // Also apply to touch
},
}),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
})
);
const handleDragEnd = (event) => {
const { active, over } = event;
if (!over) return; // Make sure the drop target exists
if (active.id !== over.id) {
const oldIndex = transformPinnedApps.findIndex(
(item) => `${item?.service}-${item?.name}` === active.id
);
const newIndex = transformPinnedApps.findIndex(
(item) => `${item?.service}-${item?.name}` === over.id
);
const newOrder = arrayMove(transformPinnedApps, oldIndex, newIndex);
setPinnedApps(newOrder);
saveToLocalStorage('ext_saved_settings', 'sortablePinnedApps', newOrder);
setSettingsLocalLastUpdated(Date.now());
}
};
return (
`${app?.service}-${app?.name}`)}
>
{transformPinnedApps.map((app) => (
))}
);
};