Navbar drag drop using dnd kit (#18288)
This commit is contained in:
+22
-9
@@ -1,11 +1,24 @@
|
||||
import { Droppable, type DroppableProvided } from '@hello-pangea/dnd';
|
||||
import { type ReactNode, useContext } from 'react';
|
||||
import { lazy, Suspense, useContext, type ReactNode } from 'react';
|
||||
|
||||
import { ADD_TO_NAV_SOURCE_DROPPABLE_ID } from '@/navigation-menu-item/constants/AddToNavSourceDroppableId';
|
||||
import { NavigationDragSourceContext } from '@/navigation-menu-item/contexts/NavigationDragSourceContext';
|
||||
|
||||
import type { AddToNavDroppableProvided } from '@/command-menu/components/CommandMenuAddToNavDroppableTypes';
|
||||
|
||||
const FALLBACK_PROVIDED: AddToNavDroppableProvided = {
|
||||
innerRef: () => {},
|
||||
droppableProps: {},
|
||||
placeholder: null,
|
||||
};
|
||||
|
||||
const CommandMenuAddToNavDroppableDndKit = lazy(() =>
|
||||
import('@/command-menu/components/CommandMenuAddToNavDroppableDndKit').then(
|
||||
(m) => ({ default: m.CommandMenuAddToNavDroppableDndKit }),
|
||||
),
|
||||
);
|
||||
|
||||
type SidePanelAddToNavigationDroppableProps = {
|
||||
children: (provided: DroppableProvided) => ReactNode;
|
||||
children: (provided: AddToNavDroppableProvided) => ReactNode;
|
||||
};
|
||||
|
||||
export const SidePanelAddToNavigationDroppable = ({
|
||||
@@ -15,11 +28,11 @@ export const SidePanelAddToNavigationDroppable = ({
|
||||
const isDropDisabled = sourceDroppableId === ADD_TO_NAV_SOURCE_DROPPABLE_ID;
|
||||
|
||||
return (
|
||||
<Droppable
|
||||
droppableId={ADD_TO_NAV_SOURCE_DROPPABLE_ID}
|
||||
isDropDisabled={isDropDisabled}
|
||||
>
|
||||
{(provided) => children(provided)}
|
||||
</Droppable>
|
||||
<Suspense fallback={children(FALLBACK_PROVIDED)}>
|
||||
<CommandMenuAddToNavDroppableDndKit
|
||||
children={children}
|
||||
isDropDisabled={isDropDisabled}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
+56
-34
@@ -1,23 +1,22 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { Draggable } from '@hello-pangea/dnd';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { type ReactNode, useState } from 'react';
|
||||
import { type ReactNode, lazy, Suspense, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { AddToNavigationDragHandle } from '@/navigation-menu-item/components/AddToNavigationDragHandle';
|
||||
import { addToNavPayloadRegistryState } from '@/navigation-menu-item/states/addToNavPayloadRegistryState';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import type { AddToNavigationDragPayload } from '@/navigation-menu-item/types/add-to-navigation-drag-payload';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
|
||||
const StyledDraggableMenuItem = styled.div`
|
||||
cursor: grab;
|
||||
width: 100%;
|
||||
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
`;
|
||||
const CommandMenuItemWithAddToNavigationDragDndKit = lazy(() =>
|
||||
import(
|
||||
'@/command-menu/components/CommandMenuItemWithAddToNavigationDragDndKit'
|
||||
).then((m) => ({
|
||||
default: m.CommandMenuItemWithAddToNavigationDragDndKit,
|
||||
})),
|
||||
);
|
||||
|
||||
type SidePanelItemWithAddToNavigationDragProps = {
|
||||
icon?: IconComponent;
|
||||
@@ -28,8 +27,25 @@ type SidePanelItemWithAddToNavigationDragProps = {
|
||||
onClick: () => void;
|
||||
payload: AddToNavigationDragPayload;
|
||||
dragIndex?: number;
|
||||
disabled?: boolean;
|
||||
disableDrag?: boolean;
|
||||
};
|
||||
|
||||
const StyledDraggableMenuItem = styled.div<{
|
||||
$disabled?: boolean;
|
||||
$disableDrag?: boolean;
|
||||
}>`
|
||||
cursor: ${({ $disabled, $disableDrag }) =>
|
||||
$disabled || $disableDrag ? 'default' : 'grab'};
|
||||
pointer-events: ${({ $disabled }) => ($disabled ? 'none' : 'auto')};
|
||||
width: 100%;
|
||||
|
||||
&:active {
|
||||
cursor: ${({ $disabled, $disableDrag }) =>
|
||||
$disabled || $disableDrag ? 'default' : 'grabbing'};
|
||||
}
|
||||
`;
|
||||
|
||||
export const SidePanelItemWithAddToNavigationDrag = ({
|
||||
icon,
|
||||
customIconContent,
|
||||
@@ -39,6 +55,8 @@ export const SidePanelItemWithAddToNavigationDrag = ({
|
||||
onClick,
|
||||
payload,
|
||||
dragIndex,
|
||||
disabled = false,
|
||||
disableDrag = false,
|
||||
}: SidePanelItemWithAddToNavigationDragProps) => {
|
||||
const { t } = useLingui();
|
||||
const setAddToNavPayloadRegistry = useSetAtomState(
|
||||
@@ -46,7 +64,8 @@ export const SidePanelItemWithAddToNavigationDrag = ({
|
||||
);
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
const contextualDescription = isHovered
|
||||
const showDragAffordance = !disabled && !disableDrag && isHovered;
|
||||
const contextualDescription = showDragAffordance
|
||||
? t`Drag to add to navbar`
|
||||
: description;
|
||||
|
||||
@@ -55,23 +74,31 @@ export const SidePanelItemWithAddToNavigationDrag = ({
|
||||
icon={icon}
|
||||
customIconContent={customIconContent}
|
||||
payload={payload}
|
||||
isHovered={isHovered}
|
||||
isHovered={showDragAffordance}
|
||||
disabled={disabled}
|
||||
disableDrag={disableDrag}
|
||||
/>
|
||||
);
|
||||
|
||||
const registerPayload = () => {
|
||||
if (dragIndex !== undefined) {
|
||||
if (!disabled && !disableDrag && isDefined(dragIndex)) {
|
||||
setAddToNavPayloadRegistry((prev) => new Map(prev).set(id, payload));
|
||||
}
|
||||
};
|
||||
|
||||
const menuItemContent = (
|
||||
<StyledDraggableMenuItem
|
||||
$disabled={disabled}
|
||||
$disableDrag={disableDrag}
|
||||
onMouseEnter={() => {
|
||||
setIsHovered(true);
|
||||
registerPayload();
|
||||
if (!disabled && !disableDrag) {
|
||||
setIsHovered(true);
|
||||
registerPayload();
|
||||
}
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
if (!disabled && !disableDrag) setIsHovered(false);
|
||||
}}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
onMouseDown={registerPayload}
|
||||
>
|
||||
<CommandMenuItem
|
||||
@@ -80,27 +107,22 @@ export const SidePanelItemWithAddToNavigationDrag = ({
|
||||
description={contextualDescription}
|
||||
id={id}
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</StyledDraggableMenuItem>
|
||||
);
|
||||
|
||||
if (dragIndex !== undefined) {
|
||||
return (
|
||||
<Draggable draggableId={id} index={dragIndex} isDragDisabled={false}>
|
||||
{(provided) => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
// oxlint-disable-next-line react/jsx-props-no-spreading
|
||||
{...provided.draggableProps}
|
||||
// oxlint-disable-next-line react/jsx-props-no-spreading
|
||||
{...provided.dragHandleProps}
|
||||
>
|
||||
{menuItemContent}
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
);
|
||||
if (!isDefined(dragIndex) || disableDrag) {
|
||||
return menuItemContent;
|
||||
}
|
||||
|
||||
return menuItemContent;
|
||||
return (
|
||||
<Suspense fallback={menuItemContent}>
|
||||
<CommandMenuItemWithAddToNavigationDragDndKit
|
||||
id={id}
|
||||
dragIndex={dragIndex}
|
||||
menuItemContent={menuItemContent}
|
||||
/>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconLink } from 'twenty-ui/display';
|
||||
import { IconLink, IconWorld } from 'twenty-ui/display';
|
||||
|
||||
import { SidePanelPageInfoLayout } from '@/side-panel/components/SidePanelPageInfoLayout';
|
||||
import { sidePanelPageInfoState } from '@/side-panel/states/sidePanelPageInfoState';
|
||||
import { sidePanelShouldFocusTitleInputComponentState } from '@/side-panel/states/sidePanelShouldFocusTitleInputComponentState';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { LinkIconWithLinkOverlay } from '@/navigation-menu-item/components/LinkIconWithLinkOverlay';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { useUpdateLinkInDraft } from '@/navigation-menu-item/hooks/useUpdateLinkInDraft';
|
||||
import { useWorkspaceSectionItems } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems';
|
||||
import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState';
|
||||
import { SidePanelPageInfoLayout } from '@/side-panel/components/SidePanelPageInfoLayout';
|
||||
import { sidePanelPageInfoState } from '@/side-panel/states/sidePanelPageInfoState';
|
||||
import { sidePanelShouldFocusTitleInputComponentState } from '@/side-panel/states/sidePanelShouldFocusTitleInputComponentState';
|
||||
import { TitleInput } from '@/ui/input/components/TitleInput';
|
||||
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
@@ -59,8 +59,10 @@ export const SidePanelLinkInfo = () => {
|
||||
return (
|
||||
<SidePanelPageInfoLayout
|
||||
icon={
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={IconLink}
|
||||
<LinkIconWithLinkOverlay
|
||||
link={selectedItem.link}
|
||||
LinkIcon={IconLink}
|
||||
DefaultIcon={IconWorld}
|
||||
color={selectedItem.color}
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { sidePanelPageState } from '@/side-panel/states/sidePanelPageState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { styled } from '@linaria/react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useContext } from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ThemeContext } from 'twenty-ui/theme-constants';
|
||||
|
||||
@@ -21,11 +21,16 @@ export const SidePanelRouter = () => {
|
||||
const sidePanelPage = useAtomStateValue(sidePanelPageState);
|
||||
const sidePanelPageInfo = useAtomStateValue(sidePanelPageInfoState);
|
||||
|
||||
const sidePanelPageComponent = isDefined(sidePanelPage) ? (
|
||||
SIDE_PANEL_PAGES_CONFIG.get(sidePanelPage)
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
const rawPageComponent = isDefined(sidePanelPage)
|
||||
? SIDE_PANEL_PAGES_CONFIG.get(sidePanelPage)
|
||||
: null;
|
||||
|
||||
const sidePanelPageComponent =
|
||||
isDefined(rawPageComponent) && React.isValidElement(rawPageComponent)
|
||||
? React.cloneElement(rawPageComponent, {
|
||||
key: sidePanelPageInfo.instanceId,
|
||||
})
|
||||
: rawPageComponent;
|
||||
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
|
||||
+39
-16
@@ -3,22 +3,24 @@ import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useState } from 'react';
|
||||
import { getAbsoluteUrl } from 'twenty-shared/utils';
|
||||
|
||||
import { type ProcessedNavigationMenuItem } from '@/navigation-menu-item/types/processed-navigation-menu-item';
|
||||
import { extractDomainFromUrl } from '@/navigation-menu-item/utils/extractDomainFromUrl';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { SidePanelEditColorOption } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditColorOption';
|
||||
import {
|
||||
type OrganizeActionsProps,
|
||||
SidePanelEditOrganizeActions,
|
||||
} from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditOrganizeActions';
|
||||
import { SidePanelEditOwnerSection } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditOwnerSection';
|
||||
import { getOrganizeActionsSelectableItemIds } from '@/side-panel/pages/navigation-menu-item/utils/getOrganizeActionsSelectableItemIds';
|
||||
import { type ProcessedNavigationMenuItem } from '@/navigation-menu-item/types/processed-navigation-menu-item';
|
||||
import { parseThemeColor } from '@/navigation-menu-item/utils/parseThemeColor';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
|
||||
type SidePanelEditLinkItemViewProps = OrganizeActionsProps & {
|
||||
selectedItem: ProcessedNavigationMenuItem;
|
||||
onUpdateLink: (linkId: string, link: string) => void;
|
||||
onUpdateLink: (
|
||||
linkId: string,
|
||||
updates: { link?: string; name?: string },
|
||||
) => void;
|
||||
onOpenFolderPicker: () => void;
|
||||
};
|
||||
|
||||
@@ -36,28 +38,49 @@ export const SidePanelEditLinkItemView = ({
|
||||
}: SidePanelEditLinkItemViewProps) => {
|
||||
const { t } = useLingui();
|
||||
const [urlEditInput, setUrlEditInput] = useState('');
|
||||
const [lastAutoSetName, setLastAutoSetName] = useState<string | null>(null);
|
||||
|
||||
const defaultLabel = t`Link label`;
|
||||
const selectableItemIds = getOrganizeActionsSelectableItemIds(true);
|
||||
|
||||
const currentName = selectedItem.name ?? defaultLabel;
|
||||
const currentDomain = selectedItem.link
|
||||
? extractDomainFromUrl(getAbsoluteUrl(selectedItem.link))
|
||||
: undefined;
|
||||
const canAutoUpdateName =
|
||||
currentName === defaultLabel ||
|
||||
currentName === currentDomain ||
|
||||
currentName === lastAutoSetName;
|
||||
|
||||
const handleUrlChange = (value: string) => {
|
||||
setUrlEditInput(value);
|
||||
if (!canAutoUpdateName) return;
|
||||
const trimmed = value.trim();
|
||||
if (!isNonEmptyString(trimmed)) return;
|
||||
const domain = extractDomainFromUrl(getAbsoluteUrl(trimmed));
|
||||
if (domain !== undefined) {
|
||||
setLastAutoSetName(domain);
|
||||
onUpdateLink(selectedItem.id, { name: domain });
|
||||
}
|
||||
};
|
||||
|
||||
const handleUrlBlur = (event: React.FocusEvent<HTMLInputElement>) => {
|
||||
const value = event.target.value.trim();
|
||||
if (isNonEmptyString(value)) {
|
||||
onUpdateLink(selectedItem.id, { link: getAbsoluteUrl(value) });
|
||||
setUrlEditInput('');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SidePanelList commandGroups={[]} selectableItemIds={selectableItemIds}>
|
||||
<SidePanelGroup heading={t`Customize`}>
|
||||
<SidePanelEditColorOption
|
||||
navigationMenuItemId={selectedItem.id}
|
||||
color={parseThemeColor(selectedItem.color)}
|
||||
/>
|
||||
<TextInput
|
||||
fullWidth
|
||||
placeholder="www.google.com"
|
||||
value={urlEditInput || selectedItem.link}
|
||||
onChange={(value) => setUrlEditInput(value)}
|
||||
onBlur={(event) => {
|
||||
const value = event.target.value.trim();
|
||||
if (isNonEmptyString(value)) {
|
||||
onUpdateLink(selectedItem.id, getAbsoluteUrl(value));
|
||||
setUrlEditInput('');
|
||||
}
|
||||
}}
|
||||
onChange={handleUrlChange}
|
||||
onBlur={handleUrlBlur}
|
||||
/>
|
||||
</SidePanelGroup>
|
||||
<SidePanelEditOrganizeActions
|
||||
|
||||
+13
-11
@@ -1,14 +1,4 @@
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { SidePanelEditColorOption } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditColorOption';
|
||||
import { SidePanelEditFolderPickerSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditFolderPickerSubView';
|
||||
import { SidePanelEditLinkItemView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditLinkItemView';
|
||||
import { SidePanelEditObjectViewBase } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditObjectViewBase';
|
||||
import { SidePanelEditOrganizeActions } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditOrganizeActions';
|
||||
import { SidePanelEditOwnerSection } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditOwnerSection';
|
||||
import { useNavigationMenuItemEditOrganizeActions } from '@/side-panel/pages/navigation-menu-item/hooks/useNavigationMenuItemEditOrganizeActions';
|
||||
import { getOrganizeActionsSelectableItemIds } from '@/side-panel/pages/navigation-menu-item/utils/getOrganizeActionsSelectableItemIds';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/hooks/useNavigationMenuItemsDraftState';
|
||||
import { useOpenAddItemToFolderPage } from '@/navigation-menu-item/hooks/useOpenAddItemToFolderPage';
|
||||
@@ -18,6 +8,16 @@ import { useSelectedNavigationMenuItemEditItemObjectMetadata } from '@/navigatio
|
||||
import { useUpdateLinkInDraft } from '@/navigation-menu-item/hooks/useUpdateLinkInDraft';
|
||||
import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState';
|
||||
import { parseThemeColor } from '@/navigation-menu-item/utils/parseThemeColor';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { SidePanelEditColorOption } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditColorOption';
|
||||
import { SidePanelEditFolderPickerSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditFolderPickerSubView';
|
||||
import { SidePanelEditLinkItemView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditLinkItemView';
|
||||
import { SidePanelEditObjectViewBase } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditObjectViewBase';
|
||||
import { SidePanelEditOrganizeActions } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditOrganizeActions';
|
||||
import { SidePanelEditOwnerSection } from '@/side-panel/pages/navigation-menu-item/components/SidePanelEditOwnerSection';
|
||||
import { useNavigationMenuItemEditOrganizeActions } from '@/side-panel/pages/navigation-menu-item/hooks/useNavigationMenuItemEditOrganizeActions';
|
||||
import { getOrganizeActionsSelectableItemIds } from '@/side-panel/pages/navigation-menu-item/utils/getOrganizeActionsSelectableItemIds';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { ViewKey } from '@/views/types/ViewKey';
|
||||
@@ -132,7 +132,9 @@ export const SidePanelNavigationMenuItemEditPage = () => {
|
||||
<SidePanelEditLinkItemView
|
||||
key={selectedItem.id}
|
||||
selectedItem={selectedItem}
|
||||
onUpdateLink={(linkId, link) => updateLinkInDraft(linkId, { link })}
|
||||
onUpdateLink={(linkId, updates) =>
|
||||
updateLinkInDraft(linkId, updates)
|
||||
}
|
||||
onOpenFolderPicker={openFolderPicker}
|
||||
canMoveUp={canMoveUp}
|
||||
canMoveDown={canMoveDown}
|
||||
|
||||
+98
-68
@@ -1,4 +1,5 @@
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
Avatar,
|
||||
IconBuildingSkyscraper,
|
||||
@@ -6,20 +7,20 @@ import {
|
||||
IconLink,
|
||||
IconTable,
|
||||
} from 'twenty-ui/display';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelAddToNavigationDraggablePlaceholder } from '@/side-panel/components/SidePanelAddToNavigationDraggablePlaceholder';
|
||||
import { SidePanelAddToNavigationDroppable } from '@/side-panel/components/SidePanelAddToNavigationDroppable';
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState';
|
||||
import { SidePanelAddToNavigationDroppable } from '@/side-panel/components/SidePanelAddToNavigationDroppable';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelItemWithAddToNavigationDrag } from '@/side-panel/components/SidePanelItemWithAddToNavigationDrag';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { useAddFolderToNavigationMenu } from '@/side-panel/pages/navigation-menu-item/hooks/useAddFolderToNavigationMenu';
|
||||
import { useAddLinkToNavigationMenu } from '@/side-panel/pages/navigation-menu-item/hooks/useAddLinkToNavigationMenu';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme-constants';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
|
||||
type SidePanelNewSidebarItemMainMenuProps = {
|
||||
onSelectObject: () => void;
|
||||
@@ -27,104 +28,133 @@ type SidePanelNewSidebarItemMainMenuProps = {
|
||||
onSelectRecord: () => void;
|
||||
};
|
||||
|
||||
const MAIN_MENU_ITEM_TYPES = [
|
||||
NavigationMenuItemType.OBJECT,
|
||||
NavigationMenuItemType.VIEW,
|
||||
NavigationMenuItemType.RECORD,
|
||||
NavigationMenuItemType.FOLDER,
|
||||
NavigationMenuItemType.LINK,
|
||||
] as const;
|
||||
|
||||
export const SidePanelNewSidebarItemMainMenu = ({
|
||||
onSelectObject,
|
||||
onSelectView,
|
||||
onSelectRecord,
|
||||
}: SidePanelNewSidebarItemMainMenuProps) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const addMenuItemInsertionContext = useAtomStateValue(
|
||||
addMenuItemInsertionContextState,
|
||||
);
|
||||
const { handleAddFolder } = useAddFolderToNavigationMenu();
|
||||
const { handleAddLink } = useAddLinkToNavigationMenu();
|
||||
|
||||
const isAddingToFolder = isDefined(
|
||||
addMenuItemInsertionContext?.targetFolderId,
|
||||
);
|
||||
const isDragDisabled = addMenuItemInsertionContext?.disableDrag === true;
|
||||
const selectableItemIds = isAddingToFolder
|
||||
? MAIN_MENU_ITEM_TYPES.filter(
|
||||
(type) => type !== NavigationMenuItemType.FOLDER,
|
||||
)
|
||||
: [...MAIN_MENU_ITEM_TYPES];
|
||||
|
||||
return (
|
||||
<SidePanelAddToNavigationDroppable>
|
||||
{({ innerRef, droppableProps, placeholder }) => (
|
||||
<SidePanelList
|
||||
commandGroups={[]}
|
||||
selectableItemIds={['object', 'view', 'record', 'folder', 'link']}
|
||||
>
|
||||
{/* oxlint-disable-next-line react/jsx-props-no-spreading */}
|
||||
<SidePanelList commandGroups={[]} selectableItemIds={selectableItemIds}>
|
||||
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
|
||||
<div ref={innerRef} {...droppableProps}>
|
||||
<SidePanelGroup heading={t`Data`}>
|
||||
<SidePanelAddToNavigationDraggablePlaceholder index={0}>
|
||||
<SelectableListItem itemId="object" onEnter={onSelectObject}>
|
||||
<CommandMenuItem
|
||||
Icon={() => (
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={IconBuildingSkyscraper}
|
||||
color="blue"
|
||||
/>
|
||||
)}
|
||||
label={t`Object`}
|
||||
id="object"
|
||||
hasSubMenu={true}
|
||||
onClick={onSelectObject}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
</SidePanelAddToNavigationDraggablePlaceholder>
|
||||
<SidePanelAddToNavigationDraggablePlaceholder index={1}>
|
||||
<SelectableListItem itemId="view" onEnter={onSelectView}>
|
||||
<CommandMenuItem
|
||||
Icon={() => (
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={IconTable}
|
||||
color="gray"
|
||||
/>
|
||||
)}
|
||||
label={t`View`}
|
||||
id="view"
|
||||
hasSubMenu={true}
|
||||
onClick={onSelectView}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
</SidePanelAddToNavigationDraggablePlaceholder>
|
||||
<SidePanelAddToNavigationDraggablePlaceholder index={2}>
|
||||
<SelectableListItem itemId="record" onEnter={onSelectRecord}>
|
||||
<CommandMenuItem
|
||||
Icon={() => (
|
||||
<Avatar
|
||||
placeholder="L"
|
||||
type="rounded"
|
||||
backgroundColor={theme.color.green4}
|
||||
/>
|
||||
)}
|
||||
label={t`Record`}
|
||||
id="record"
|
||||
hasSubMenu={true}
|
||||
onClick={onSelectRecord}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
</SidePanelAddToNavigationDraggablePlaceholder>
|
||||
<SelectableListItem
|
||||
itemId={NavigationMenuItemType.OBJECT}
|
||||
onEnter={onSelectObject}
|
||||
>
|
||||
<CommandMenuItem
|
||||
Icon={() => (
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={IconBuildingSkyscraper}
|
||||
color="blue"
|
||||
/>
|
||||
)}
|
||||
label={t`Object`}
|
||||
id={NavigationMenuItemType.OBJECT}
|
||||
hasSubMenu={true}
|
||||
onClick={onSelectObject}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
<SelectableListItem
|
||||
itemId={NavigationMenuItemType.VIEW}
|
||||
onEnter={onSelectView}
|
||||
>
|
||||
<CommandMenuItem
|
||||
Icon={() => (
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={IconTable}
|
||||
color="gray"
|
||||
/>
|
||||
)}
|
||||
label={t`View`}
|
||||
id={NavigationMenuItemType.VIEW}
|
||||
hasSubMenu={true}
|
||||
onClick={onSelectView}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
<SelectableListItem
|
||||
itemId={NavigationMenuItemType.RECORD}
|
||||
onEnter={onSelectRecord}
|
||||
>
|
||||
<CommandMenuItem
|
||||
Icon={() => (
|
||||
<Avatar
|
||||
placeholder="L"
|
||||
type="rounded"
|
||||
backgroundColor={themeCssVariables.color.green4}
|
||||
/>
|
||||
)}
|
||||
label={t`Record`}
|
||||
id={NavigationMenuItemType.RECORD}
|
||||
hasSubMenu={true}
|
||||
onClick={onSelectRecord}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
</SidePanelGroup>
|
||||
<SidePanelGroup heading={t`Other`}>
|
||||
<SelectableListItem itemId="folder" onEnter={handleAddFolder}>
|
||||
<SelectableListItem
|
||||
itemId={NavigationMenuItemType.FOLDER}
|
||||
onEnter={isAddingToFolder ? undefined : handleAddFolder}
|
||||
>
|
||||
<SidePanelItemWithAddToNavigationDrag
|
||||
icon={IconFolder}
|
||||
label={t`Folder`}
|
||||
id="folder"
|
||||
id={NavigationMenuItemType.FOLDER}
|
||||
onClick={handleAddFolder}
|
||||
dragIndex={3}
|
||||
dragIndex={isDragDisabled ? undefined : 3}
|
||||
payload={{
|
||||
type: NavigationMenuItemType.FOLDER,
|
||||
folderId: 'new',
|
||||
name: t`New folder`,
|
||||
}}
|
||||
disabled={isAddingToFolder}
|
||||
disableDrag={isDragDisabled}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
<SelectableListItem itemId="link" onEnter={handleAddLink}>
|
||||
<SelectableListItem
|
||||
itemId={NavigationMenuItemType.LINK}
|
||||
onEnter={handleAddLink}
|
||||
>
|
||||
<SidePanelItemWithAddToNavigationDrag
|
||||
icon={IconLink}
|
||||
label={t`Link`}
|
||||
id="link"
|
||||
id={NavigationMenuItemType.LINK}
|
||||
onClick={handleAddLink}
|
||||
dragIndex={4}
|
||||
dragIndex={isDragDisabled ? undefined : 4}
|
||||
payload={{
|
||||
type: NavigationMenuItemType.LINK,
|
||||
linkId: 'new',
|
||||
name: t`Link label`,
|
||||
link: 'https://www.example.com',
|
||||
}}
|
||||
disableDrag={isDragDisabled}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
</SidePanelGroup>
|
||||
|
||||
+21
-10
@@ -1,21 +1,22 @@
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { SidePanelObjectPickerSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelObjectPickerSubView';
|
||||
import { SidePanelSystemObjectPickerSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelSystemObjectPickerSubView';
|
||||
import { getAvailableObjectMetadataForNewSidebarItem } from '@/side-panel/pages/navigation-menu-item/utils/getAvailableObjectMetadataForNewSidebarItem';
|
||||
import { useAddObjectToNavigationMenuDraft } from '@/navigation-menu-item/hooks/useAddObjectToNavigationMenuDraft';
|
||||
import { getStandardObjectIconColor } from '@/navigation-menu-item/utils/getStandardObjectIconColor';
|
||||
import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems';
|
||||
import { useNavigationMenuObjectMetadataFromDraft } from '@/navigation-menu-item/hooks/useNavigationMenuObjectMetadataFromDraft';
|
||||
import { useOpenNavigationMenuItemInSidePanel } from '@/navigation-menu-item/hooks/useOpenNavigationMenuItemInSidePanel';
|
||||
import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { getStandardObjectIconColor } from '@/navigation-menu-item/utils/getStandardObjectIconColor';
|
||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SidePanelObjectPickerSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelObjectPickerSubView';
|
||||
import { SidePanelSystemObjectPickerSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelSystemObjectPickerSubView';
|
||||
import { getAvailableObjectMetadataForNewSidebarItem } from '@/side-panel/pages/navigation-menu-item/utils/getAvailableObjectMetadataForNewSidebarItem';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { ViewKey } from '@/views/types/ViewKey';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
type SidePanelNewSidebarItemObjectFlowProps = {
|
||||
onBack: () => void;
|
||||
@@ -25,7 +26,7 @@ export const SidePanelNewSidebarItemObjectFlow = ({
|
||||
onBack,
|
||||
}: SidePanelNewSidebarItemObjectFlowProps) => {
|
||||
const { t } = useLingui();
|
||||
const { closeSidePanelMenu } = useSidePanelMenu();
|
||||
const { getIcon } = useIcons();
|
||||
const [objectSearchInput, setObjectSearchInput] = useState('');
|
||||
const [systemObjectSearchInput, setSystemObjectSearchInput] = useState('');
|
||||
const [isInSystemPicker, setIsInSystemPicker] = useState(false);
|
||||
@@ -33,6 +34,8 @@ export const SidePanelNewSidebarItemObjectFlow = ({
|
||||
const { currentDraft } = useDraftNavigationMenuItems();
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
const { addObjectToDraft } = useAddObjectToNavigationMenuDraft();
|
||||
const { openNavigationMenuItemInSidePanel } =
|
||||
useOpenNavigationMenuItemInSidePanel();
|
||||
const { activeNonSystemObjectMetadataItems } =
|
||||
useFilteredObjectMetadataItems();
|
||||
const addMenuItemInsertionContext = useAtomStateValue(
|
||||
@@ -68,7 +71,7 @@ export const SidePanelNewSidebarItemObjectFlow = ({
|
||||
if (objectMetadataIdsInWorkspace.has(objectMetadataItem.id)) {
|
||||
return;
|
||||
}
|
||||
addObjectToDraft(
|
||||
const itemId = addObjectToDraft(
|
||||
objectMetadataItem.id,
|
||||
defaultViewId,
|
||||
currentDraft,
|
||||
@@ -77,7 +80,11 @@ export const SidePanelNewSidebarItemObjectFlow = ({
|
||||
getStandardObjectIconColor(objectMetadataItem.nameSingular),
|
||||
);
|
||||
setAddMenuItemInsertionContext(null);
|
||||
closeSidePanelMenu();
|
||||
openNavigationMenuItemInSidePanel({
|
||||
itemId,
|
||||
pageTitle: objectMetadataItem.labelSingular,
|
||||
pageIcon: getIcon(objectMetadataItem.icon),
|
||||
});
|
||||
};
|
||||
|
||||
const handleBackToObjectList = () => {
|
||||
@@ -85,6 +92,8 @@ export const SidePanelNewSidebarItemObjectFlow = ({
|
||||
setSystemObjectSearchInput('');
|
||||
};
|
||||
|
||||
const disableDrag = addMenuItemInsertionContext?.disableDrag === true;
|
||||
|
||||
if (isInSystemPicker) {
|
||||
return (
|
||||
<SidePanelSystemObjectPickerSubView
|
||||
@@ -96,6 +105,7 @@ export const SidePanelNewSidebarItemObjectFlow = ({
|
||||
onChangeObject={handleSelectObject}
|
||||
objectMenuItemVariant="add"
|
||||
emptyNoResultsText={t`All system objects are already in the sidebar`}
|
||||
disableDrag={disableDrag}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -110,6 +120,7 @@ export const SidePanelNewSidebarItemObjectFlow = ({
|
||||
isViewItem={false}
|
||||
onChangeObject={handleSelectObject}
|
||||
objectMenuItemVariant="add"
|
||||
disableDrag={disableDrag}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+13
-1
@@ -1,14 +1,21 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState';
|
||||
import { SidePanelNewSidebarItemMainMenu } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemMainMenu';
|
||||
import { SidePanelNewSidebarItemObjectFlow } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemObjectFlow';
|
||||
import { SidePanelNewSidebarItemRecordSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemRecordSubView';
|
||||
import { SidePanelNewSidebarItemViewFlow } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemViewFlow';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
type SelectedOption = 'object' | 'record' | 'view' | null;
|
||||
|
||||
export const SidePanelNewSidebarItemPage = () => {
|
||||
const [selectedOption, setSelectedOption] = useState<SelectedOption>(null);
|
||||
const addMenuItemInsertionContext = useAtomStateValue(
|
||||
addMenuItemInsertionContextState,
|
||||
);
|
||||
const disableDrag = isDefined(addMenuItemInsertionContext);
|
||||
|
||||
const handleBackToMain = () => {
|
||||
setSelectedOption(null);
|
||||
@@ -20,7 +27,12 @@ export const SidePanelNewSidebarItemPage = () => {
|
||||
case 'object':
|
||||
return <SidePanelNewSidebarItemObjectFlow onBack={handleBackToMain} />;
|
||||
case 'record':
|
||||
return <SidePanelNewSidebarItemRecordSubView onBack={handleBackToMain} />;
|
||||
return (
|
||||
<SidePanelNewSidebarItemRecordSubView
|
||||
onBack={handleBackToMain}
|
||||
disableDrag={disableDrag}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<SidePanelNewSidebarItemMainMenu
|
||||
|
||||
+21
-10
@@ -1,17 +1,17 @@
|
||||
import { Avatar } from 'twenty-ui/display';
|
||||
import { Avatar, IconFolder, useIcons } from 'twenty-ui/display';
|
||||
|
||||
import { SidePanelItemWithAddToNavigationDrag } from '@/side-panel/components/SidePanelItemWithAddToNavigationDrag';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems';
|
||||
import { useAddRecordToNavigationMenuDraft } from '@/navigation-menu-item/hooks/useAddRecordToNavigationMenuDraft';
|
||||
import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems';
|
||||
import { useOpenNavigationMenuItemInSidePanel } from '@/navigation-menu-item/hooks/useOpenNavigationMenuItemInSidePanel';
|
||||
import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import type { AddToNavigationDragPayload } from '@/navigation-menu-item/types/add-to-navigation-drag-payload';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { CoreObjectNameSingular } from 'twenty-shared/types';
|
||||
import { SidePanelItemWithAddToNavigationDrag } from '@/side-panel/components/SidePanelItemWithAddToNavigationDrag';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { CoreObjectNameSingular } from 'twenty-shared/types';
|
||||
|
||||
type SearchRecord = {
|
||||
recordId: string;
|
||||
@@ -23,13 +23,15 @@ type SearchRecord = {
|
||||
type SidePanelNewSidebarItemRecordItemProps = {
|
||||
record: SearchRecord;
|
||||
dragIndex?: number;
|
||||
disableDrag?: boolean;
|
||||
};
|
||||
|
||||
export const SidePanelNewSidebarItemRecordItem = ({
|
||||
record,
|
||||
dragIndex,
|
||||
disableDrag = false,
|
||||
}: SidePanelNewSidebarItemRecordItemProps) => {
|
||||
const { closeSidePanelMenu } = useSidePanelMenu();
|
||||
const { getIcon } = useIcons();
|
||||
const { addRecordToDraft } = useAddRecordToNavigationMenuDraft();
|
||||
const { currentDraft } = useDraftNavigationMenuItems();
|
||||
const addMenuItemInsertionContext = useAtomStateValue(
|
||||
@@ -38,6 +40,8 @@ export const SidePanelNewSidebarItemRecordItem = ({
|
||||
const setAddMenuItemInsertionContext = useSetAtomState(
|
||||
addMenuItemInsertionContextState,
|
||||
);
|
||||
const { openNavigationMenuItemInSidePanel } =
|
||||
useOpenNavigationMenuItemInSidePanel();
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
const objectMetadataItem = objectMetadataItems.find(
|
||||
(item) => item.nameSingular === record.objectNameSingular,
|
||||
@@ -52,7 +56,7 @@ export const SidePanelNewSidebarItemRecordItem = ({
|
||||
};
|
||||
|
||||
const handleSelectRecord = () => {
|
||||
addRecordToDraft(
|
||||
const itemId = addRecordToDraft(
|
||||
{
|
||||
recordId: record.recordId,
|
||||
objectNameSingular: record.objectNameSingular,
|
||||
@@ -64,7 +68,13 @@ export const SidePanelNewSidebarItemRecordItem = ({
|
||||
addMenuItemInsertionContext?.targetIndex,
|
||||
);
|
||||
setAddMenuItemInsertionContext(null);
|
||||
closeSidePanelMenu();
|
||||
openNavigationMenuItemInSidePanel({
|
||||
itemId,
|
||||
pageTitle: record.label,
|
||||
pageIcon: objectMetadataItem
|
||||
? getIcon(objectMetadataItem.icon)
|
||||
: IconFolder,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -89,6 +99,7 @@ export const SidePanelNewSidebarItemRecordItem = ({
|
||||
id={record.recordId}
|
||||
onClick={handleSelectRecord}
|
||||
dragIndex={dragIndex}
|
||||
disableDrag={disableDrag}
|
||||
payload={recordPayload}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
|
||||
+16
-6
@@ -3,17 +3,19 @@ import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useDebounce } from 'use-debounce';
|
||||
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelAddToNavigationDroppable } from '@/side-panel/components/SidePanelAddToNavigationDroppable';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { SidePanelSubViewWithSearch } from '@/side-panel/components/SidePanelSubViewWithSearch';
|
||||
import { MAX_SEARCH_RESULTS } from '@/command-menu/constants/MaxSearchResults';
|
||||
import { SidePanelNewSidebarItemRecordItem } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemRecordItem';
|
||||
import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems';
|
||||
import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState';
|
||||
import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
|
||||
import { getObjectPermissionsFromMapByObjectMetadataId } from '@/settings/roles/role-permissions/objects-permissions/utils/getObjectPermissionsFromMapByObjectMetadataId';
|
||||
import { SidePanelAddToNavigationDroppable } from '@/side-panel/components/SidePanelAddToNavigationDroppable';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { SidePanelSubViewWithSearch } from '@/side-panel/components/SidePanelSubViewWithSearch';
|
||||
import { SidePanelNewSidebarItemRecordItem } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemRecordItem';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useSearchQuery } from '~/generated/graphql';
|
||||
|
||||
type SearchRecordBase = {
|
||||
@@ -25,12 +27,19 @@ type SearchRecordBase = {
|
||||
|
||||
type SidePanelNewSidebarItemRecordSubViewProps = {
|
||||
onBack: () => void;
|
||||
disableDrag?: boolean;
|
||||
};
|
||||
|
||||
export const SidePanelNewSidebarItemRecordSubView = ({
|
||||
onBack,
|
||||
disableDrag: disableDragProp,
|
||||
}: SidePanelNewSidebarItemRecordSubViewProps) => {
|
||||
const { t } = useLingui();
|
||||
const addMenuItemInsertionContext = useAtomStateValue(
|
||||
addMenuItemInsertionContextState,
|
||||
);
|
||||
const disableDrag =
|
||||
disableDragProp ?? addMenuItemInsertionContext?.disableDrag === true;
|
||||
const { currentDraft } = useDraftNavigationMenuItems();
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
const [recordSearchInput, setRecordSearchInput] = useState('');
|
||||
@@ -105,7 +114,8 @@ export const SidePanelNewSidebarItemRecordSubView = ({
|
||||
<SidePanelNewSidebarItemRecordItem
|
||||
key={record.recordId}
|
||||
record={record}
|
||||
dragIndex={index}
|
||||
dragIndex={disableDrag ? undefined : index}
|
||||
disableDrag={disableDrag}
|
||||
/>
|
||||
))}
|
||||
</SidePanelGroup>
|
||||
|
||||
+9
-5
@@ -1,15 +1,16 @@
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { SidePanelNewSidebarItemViewObjectPickerSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemViewObjectPickerSubView';
|
||||
import { SidePanelNewSidebarItemViewPickerSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemViewPickerSubView';
|
||||
import { SidePanelNewSidebarItemViewSystemSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemViewSystemSubView';
|
||||
import { getAvailableObjectMetadataForNewSidebarItem } from '@/side-panel/pages/navigation-menu-item/utils/getAvailableObjectMetadataForNewSidebarItem';
|
||||
import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems';
|
||||
import { useNavigationMenuObjectMetadataFromDraft } from '@/navigation-menu-item/hooks/useNavigationMenuObjectMetadataFromDraft';
|
||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { SidePanelNewSidebarItemViewObjectPickerSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemViewObjectPickerSubView';
|
||||
import { SidePanelNewSidebarItemViewPickerSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemViewPickerSubView';
|
||||
import { SidePanelNewSidebarItemViewSystemSubView } from '@/side-panel/pages/navigation-menu-item/components/SidePanelNewSidebarItemViewSystemSubView';
|
||||
import { getAvailableObjectMetadataForNewSidebarItem } from '@/side-panel/pages/navigation-menu-item/utils/getAvailableObjectMetadataForNewSidebarItem';
|
||||
import { ViewKey } from '@/views/types/ViewKey';
|
||||
import { ViewType } from '@/views/types/ViewType';
|
||||
|
||||
type SidePanelNewSidebarItemViewFlowProps = {
|
||||
onBack: () => void;
|
||||
@@ -33,7 +34,10 @@ export const SidePanelNewSidebarItemViewFlow = ({
|
||||
|
||||
const objectMetadataIdsWithDisplayableViews = new Set(
|
||||
views
|
||||
.filter((view) => view.key !== ViewKey.Index)
|
||||
.filter(
|
||||
(view) =>
|
||||
view.key !== ViewKey.Index && view.type !== ViewType.FieldsWidget,
|
||||
)
|
||||
.map((view) => view.objectMetadataId),
|
||||
);
|
||||
|
||||
|
||||
+24
-12
@@ -1,27 +1,29 @@
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelAddToNavigationDroppable } from '@/side-panel/components/SidePanelAddToNavigationDroppable';
|
||||
import { SidePanelItemWithAddToNavigationDrag } from '@/side-panel/components/SidePanelItemWithAddToNavigationDrag';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { SidePanelSubViewWithSearch } from '@/side-panel/components/SidePanelSubViewWithSearch';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { useSidePanelFilteredPickerItems } from '@/side-panel/hooks/useSidePanelFilteredPickerItems';
|
||||
import { ObjectIconWithViewOverlay } from '@/navigation-menu-item/components/ObjectIconWithViewOverlay';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { useAddViewToNavigationMenuDraft } from '@/navigation-menu-item/hooks/useAddViewToNavigationMenuDraft';
|
||||
import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems';
|
||||
import { useNavigationMenuObjectMetadataFromDraft } from '@/navigation-menu-item/hooks/useNavigationMenuObjectMetadataFromDraft';
|
||||
import { useOpenNavigationMenuItemInSidePanel } from '@/navigation-menu-item/hooks/useOpenNavigationMenuItemInSidePanel';
|
||||
import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState';
|
||||
import { getStandardObjectIconColor } from '@/navigation-menu-item/utils/getStandardObjectIconColor';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { SidePanelAddToNavigationDroppable } from '@/side-panel/components/SidePanelAddToNavigationDroppable';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelItemWithAddToNavigationDrag } from '@/side-panel/components/SidePanelItemWithAddToNavigationDrag';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { SidePanelSubViewWithSearch } from '@/side-panel/components/SidePanelSubViewWithSearch';
|
||||
import { useSidePanelFilteredPickerItems } from '@/side-panel/hooks/useSidePanelFilteredPickerItems';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { type View } from '@/views/types/View';
|
||||
import { ViewKey } from '@/views/types/ViewKey';
|
||||
import { ViewType } from '@/views/types/ViewType';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { ViewVisibility } from '~/generated-metadata/graphql';
|
||||
|
||||
type SidePanelNewSidebarItemViewPickerSubViewProps = {
|
||||
selectedObjectMetadataIdForView: string;
|
||||
@@ -35,7 +37,6 @@ export const SidePanelNewSidebarItemViewPickerSubView = ({
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const { closeSidePanelMenu } = useSidePanelMenu();
|
||||
const { addViewToDraft } = useAddViewToNavigationMenuDraft();
|
||||
const { currentDraft } = useDraftNavigationMenuItems();
|
||||
const addMenuItemInsertionContext = useAtomStateValue(
|
||||
@@ -44,6 +45,8 @@ export const SidePanelNewSidebarItemViewPickerSubView = ({
|
||||
const setAddMenuItemInsertionContext = useSetAtomState(
|
||||
addMenuItemInsertionContextState,
|
||||
);
|
||||
const { openNavigationMenuItemInSidePanel } =
|
||||
useOpenNavigationMenuItemInSidePanel();
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
const { views } = useNavigationMenuObjectMetadataFromDraft(currentDraft);
|
||||
|
||||
@@ -51,7 +54,9 @@ export const SidePanelNewSidebarItemViewPickerSubView = ({
|
||||
.filter(
|
||||
(view) =>
|
||||
view.objectMetadataId === selectedObjectMetadataIdForView &&
|
||||
view.key !== ViewKey.Index,
|
||||
view.key !== ViewKey.Index &&
|
||||
view.type !== ViewType.FieldsWidget &&
|
||||
view.visibility === ViewVisibility.WORKSPACE,
|
||||
)
|
||||
.sort((a, b) => a.position - b.position);
|
||||
|
||||
@@ -75,8 +80,10 @@ export const SidePanelNewSidebarItemViewPickerSubView = ({
|
||||
? t`No results found`
|
||||
: t`No custom views available`;
|
||||
|
||||
const isDragDisabled = addMenuItemInsertionContext?.disableDrag === true;
|
||||
|
||||
const handleSelectView = (view: View) => {
|
||||
addViewToDraft(
|
||||
const itemId = addViewToDraft(
|
||||
view.id,
|
||||
currentDraft,
|
||||
addMenuItemInsertionContext?.targetFolderId ?? null,
|
||||
@@ -86,7 +93,11 @@ export const SidePanelNewSidebarItemViewPickerSubView = ({
|
||||
: undefined,
|
||||
);
|
||||
setAddMenuItemInsertionContext(null);
|
||||
closeSidePanelMenu();
|
||||
openNavigationMenuItemInSidePanel({
|
||||
itemId,
|
||||
pageTitle: view.name,
|
||||
pageIcon: getIcon(view.icon),
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -136,7 +147,8 @@ export const SidePanelNewSidebarItemViewPickerSubView = ({
|
||||
label={view.name}
|
||||
id={view.id}
|
||||
onClick={() => handleSelectView(view)}
|
||||
dragIndex={index}
|
||||
dragIndex={isDragDisabled ? undefined : index}
|
||||
disableDrag={isDragDisabled}
|
||||
payload={{
|
||||
type: NavigationMenuItemType.VIEW,
|
||||
viewId: view.id,
|
||||
|
||||
+5
-1
@@ -3,13 +3,13 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { SidePanelItemWithAddToNavigationDrag } from '@/side-panel/components/SidePanelItemWithAddToNavigationDrag';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems';
|
||||
import { useNavigationMenuObjectMetadataFromDraft } from '@/navigation-menu-item/hooks/useNavigationMenuObjectMetadataFromDraft';
|
||||
import { getStandardObjectIconColor } from '@/navigation-menu-item/utils/getStandardObjectIconColor';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SidePanelItemWithAddToNavigationDrag } from '@/side-panel/components/SidePanelItemWithAddToNavigationDrag';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
|
||||
import { coreIndexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreIndexViewIdFromObjectMetadataItemFamilySelector';
|
||||
@@ -22,6 +22,7 @@ type SidePanelObjectMenuItemProps = {
|
||||
) => void;
|
||||
variant: 'add' | 'edit';
|
||||
dragIndex?: number;
|
||||
disableDrag?: boolean;
|
||||
};
|
||||
|
||||
export const SidePanelObjectMenuItem = ({
|
||||
@@ -29,6 +30,7 @@ export const SidePanelObjectMenuItem = ({
|
||||
onSelect,
|
||||
variant,
|
||||
dragIndex,
|
||||
disableDrag = false,
|
||||
}: SidePanelObjectMenuItemProps) => {
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
@@ -66,11 +68,13 @@ export const SidePanelObjectMenuItem = ({
|
||||
id={objectMetadataItem.id}
|
||||
onClick={handleClick}
|
||||
dragIndex={dragIndex}
|
||||
disableDrag={disableDrag}
|
||||
payload={{
|
||||
type: NavigationMenuItemType.OBJECT,
|
||||
objectMetadataId: objectMetadataItem.id,
|
||||
defaultViewId: defaultViewId ?? '',
|
||||
label: objectMetadataItem.labelPlural,
|
||||
iconColor,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
|
||||
+4
-1
@@ -2,10 +2,10 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { SidePanelObjectMenuItem } from '@/side-panel/pages/navigation-menu-item/components/SidePanelObjectMenuItem';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { getStandardObjectIconColor } from '@/navigation-menu-item/utils/getStandardObjectIconColor';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SidePanelObjectMenuItem } from '@/side-panel/pages/navigation-menu-item/components/SidePanelObjectMenuItem';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
|
||||
type SidePanelObjectPickerItemProps = {
|
||||
@@ -18,6 +18,7 @@ type SidePanelObjectPickerItemProps = {
|
||||
) => void;
|
||||
objectMenuItemVariant?: 'add' | 'edit';
|
||||
dragIndex?: number;
|
||||
disableDrag?: boolean;
|
||||
};
|
||||
|
||||
export const SidePanelObjectPickerItem = ({
|
||||
@@ -27,6 +28,7 @@ export const SidePanelObjectPickerItem = ({
|
||||
onChangeObject,
|
||||
objectMenuItemVariant = 'edit',
|
||||
dragIndex,
|
||||
disableDrag = false,
|
||||
}: SidePanelObjectPickerItemProps) => {
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
@@ -59,6 +61,7 @@ export const SidePanelObjectPickerItem = ({
|
||||
onSelect={onChangeObject}
|
||||
variant={objectMenuItemVariant}
|
||||
dragIndex={dragIndex}
|
||||
disableDrag={disableDrag}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+17
-31
@@ -1,16 +1,15 @@
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconSettings } from 'twenty-ui/display';
|
||||
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelAddToNavigationDraggablePlaceholder } from '@/side-panel/components/SidePanelAddToNavigationDraggablePlaceholder';
|
||||
import { SidePanelAddToNavigationDroppable } from '@/side-panel/components/SidePanelAddToNavigationDroppable';
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SidePanelAddToNavigationDroppable } from '@/side-panel/components/SidePanelAddToNavigationDroppable';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { SidePanelSubViewWithSearch } from '@/side-panel/components/SidePanelSubViewWithSearch';
|
||||
import { useSidePanelFilteredPickerItems } from '@/side-panel/hooks/useSidePanelFilteredPickerItems';
|
||||
import { SidePanelObjectPickerItem } from '@/side-panel/pages/navigation-menu-item/components/SidePanelObjectPickerItem';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
|
||||
type SidePanelObjectPickerSubViewProps = {
|
||||
@@ -27,6 +26,7 @@ type SidePanelObjectPickerSubViewProps = {
|
||||
) => void;
|
||||
objectMenuItemVariant?: 'add' | 'edit';
|
||||
emptyNoResultsText?: string;
|
||||
disableDrag?: boolean;
|
||||
};
|
||||
|
||||
export const SidePanelObjectPickerSubView = ({
|
||||
@@ -40,6 +40,7 @@ export const SidePanelObjectPickerSubView = ({
|
||||
onChangeObject,
|
||||
objectMenuItemVariant = 'edit',
|
||||
emptyNoResultsText,
|
||||
disableDrag = false,
|
||||
}: SidePanelObjectPickerSubViewProps) => {
|
||||
const { t } = useLingui();
|
||||
const { filteredItems, selectableItemIds, isEmpty, hasSearchQuery } =
|
||||
@@ -66,34 +67,19 @@ export const SidePanelObjectPickerSubView = ({
|
||||
onSelectObjectForViewEdit={onSelectObjectForViewEdit}
|
||||
onChangeObject={onChangeObject}
|
||||
objectMenuItemVariant={objectMenuItemVariant}
|
||||
dragIndex={isAddVariant ? index : undefined}
|
||||
dragIndex={isAddVariant && !disableDrag ? index : undefined}
|
||||
disableDrag={disableDrag}
|
||||
/>
|
||||
))}
|
||||
{isAddVariant ? (
|
||||
<SidePanelAddToNavigationDraggablePlaceholder
|
||||
index={filteredItems.length}
|
||||
>
|
||||
<SelectableListItem itemId="system" onEnter={onOpenSystemPicker}>
|
||||
<CommandMenuItem
|
||||
Icon={() => <NavigationMenuItemStyleIcon Icon={IconSettings} />}
|
||||
label={t`System objects`}
|
||||
id="system"
|
||||
hasSubMenu
|
||||
onClick={onOpenSystemPicker}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
</SidePanelAddToNavigationDraggablePlaceholder>
|
||||
) : (
|
||||
<SelectableListItem itemId="system" onEnter={onOpenSystemPicker}>
|
||||
<CommandMenuItem
|
||||
Icon={() => <NavigationMenuItemStyleIcon Icon={IconSettings} />}
|
||||
label={t`System objects`}
|
||||
id="system"
|
||||
hasSubMenu
|
||||
onClick={onOpenSystemPicker}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
<SelectableListItem itemId="system" onEnter={onOpenSystemPicker}>
|
||||
<CommandMenuItem
|
||||
Icon={() => <NavigationMenuItemStyleIcon Icon={IconSettings} />}
|
||||
label={t`System objects`}
|
||||
id="system"
|
||||
hasSubMenu
|
||||
onClick={onOpenSystemPicker}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
</SidePanelGroup>
|
||||
);
|
||||
|
||||
|
||||
+51
-21
@@ -1,11 +1,12 @@
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SidePanelAddToNavigationDroppable } from '@/side-panel/components/SidePanelAddToNavigationDroppable';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { SidePanelObjectPickerItem } from '@/side-panel/pages/navigation-menu-item/components/SidePanelObjectPickerItem';
|
||||
import { SidePanelSubViewWithSearch } from '@/side-panel/components/SidePanelSubViewWithSearch';
|
||||
import { useSidePanelFilteredPickerItems } from '@/side-panel/hooks/useSidePanelFilteredPickerItems';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SidePanelObjectPickerItem } from '@/side-panel/pages/navigation-menu-item/components/SidePanelObjectPickerItem';
|
||||
|
||||
type SidePanelSystemObjectPickerSubViewProps = {
|
||||
systemObjects: ObjectMetadataItem[];
|
||||
@@ -20,6 +21,7 @@ type SidePanelSystemObjectPickerSubViewProps = {
|
||||
) => void;
|
||||
objectMenuItemVariant?: 'add' | 'edit';
|
||||
emptyNoResultsText?: string;
|
||||
disableDrag?: boolean;
|
||||
};
|
||||
|
||||
export const SidePanelSystemObjectPickerSubView = ({
|
||||
@@ -32,6 +34,7 @@ export const SidePanelSystemObjectPickerSubView = ({
|
||||
onChangeObject,
|
||||
objectMenuItemVariant = 'edit',
|
||||
emptyNoResultsText,
|
||||
disableDrag = false,
|
||||
}: SidePanelSystemObjectPickerSubViewProps) => {
|
||||
const { t } = useLingui();
|
||||
const { filteredItems, selectableItemIds, isEmpty, hasSearchQuery } =
|
||||
@@ -45,6 +48,25 @@ export const SidePanelSystemObjectPickerSubView = ({
|
||||
? t`No results found`
|
||||
: (emptyNoResultsText ?? t`No system objects available`);
|
||||
|
||||
const isAddVariant = objectMenuItemVariant === 'add';
|
||||
|
||||
const listContent = (
|
||||
<SidePanelGroup heading={t`System objects`}>
|
||||
{filteredItems.map((objectMetadataItem, index) => (
|
||||
<SidePanelObjectPickerItem
|
||||
key={objectMetadataItem.id}
|
||||
objectMetadataItem={objectMetadataItem}
|
||||
isViewItem={isViewItem}
|
||||
onSelectObjectForViewEdit={onSelectObjectForViewEdit}
|
||||
onChangeObject={onChangeObject}
|
||||
objectMenuItemVariant={objectMenuItemVariant}
|
||||
dragIndex={isAddVariant && !disableDrag ? index : undefined}
|
||||
disableDrag={disableDrag}
|
||||
/>
|
||||
))}
|
||||
</SidePanelGroup>
|
||||
);
|
||||
|
||||
return (
|
||||
<SidePanelSubViewWithSearch
|
||||
backBarTitle={t`System objects`}
|
||||
@@ -53,25 +75,33 @@ export const SidePanelSystemObjectPickerSubView = ({
|
||||
searchValue={searchValue}
|
||||
onSearchChange={onSearchChange}
|
||||
>
|
||||
<SidePanelList
|
||||
commandGroups={[]}
|
||||
selectableItemIds={selectableItemIds}
|
||||
noResults={isEmpty}
|
||||
noResultsText={noResultsText}
|
||||
>
|
||||
<SidePanelGroup heading={t`System objects`}>
|
||||
{filteredItems.map((objectMetadataItem) => (
|
||||
<SidePanelObjectPickerItem
|
||||
key={objectMetadataItem.id}
|
||||
objectMetadataItem={objectMetadataItem}
|
||||
isViewItem={isViewItem}
|
||||
onSelectObjectForViewEdit={onSelectObjectForViewEdit}
|
||||
onChangeObject={onChangeObject}
|
||||
objectMenuItemVariant={objectMenuItemVariant}
|
||||
/>
|
||||
))}
|
||||
</SidePanelGroup>
|
||||
</SidePanelList>
|
||||
{isAddVariant ? (
|
||||
<SidePanelAddToNavigationDroppable>
|
||||
{({ innerRef, droppableProps, placeholder }) => (
|
||||
<SidePanelList
|
||||
commandGroups={[]}
|
||||
selectableItemIds={selectableItemIds}
|
||||
noResults={isEmpty}
|
||||
noResultsText={noResultsText}
|
||||
>
|
||||
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
|
||||
<div ref={innerRef} {...droppableProps}>
|
||||
{listContent}
|
||||
{placeholder}
|
||||
</div>
|
||||
</SidePanelList>
|
||||
)}
|
||||
</SidePanelAddToNavigationDroppable>
|
||||
) : (
|
||||
<SidePanelList
|
||||
commandGroups={[]}
|
||||
selectableItemIds={selectableItemIds}
|
||||
noResults={isEmpty}
|
||||
noResultsText={noResultsText}
|
||||
>
|
||||
{listContent}
|
||||
</SidePanelList>
|
||||
)}
|
||||
</SidePanelSubViewWithSearch>
|
||||
);
|
||||
};
|
||||
|
||||
+1
-5
@@ -7,7 +7,6 @@ import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/hooks/u
|
||||
import { useOpenNavigationMenuItemInSidePanel } from '@/navigation-menu-item/hooks/useOpenNavigationMenuItemInSidePanel';
|
||||
import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState';
|
||||
import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState';
|
||||
import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
|
||||
@@ -18,9 +17,6 @@ export const useAddFolderToNavigationMenu = () => {
|
||||
const navigationMenuItemsDraft = useAtomStateValue(
|
||||
navigationMenuItemsDraftState,
|
||||
);
|
||||
const setSelectedNavigationMenuItemInEditMode = useSetAtomState(
|
||||
selectedNavigationMenuItemInEditModeState,
|
||||
);
|
||||
const { openNavigationMenuItemInSidePanel } =
|
||||
useOpenNavigationMenuItemInSidePanel();
|
||||
const addMenuItemInsertionContext = useAtomStateValue(
|
||||
@@ -46,8 +42,8 @@ export const useAddFolderToNavigationMenu = () => {
|
||||
);
|
||||
|
||||
setAddMenuItemInsertionContext(null);
|
||||
setSelectedNavigationMenuItemInEditMode(itemId);
|
||||
openNavigationMenuItemInSidePanel({
|
||||
itemId,
|
||||
pageTitle: t`Edit folder`,
|
||||
pageIcon: IconFolder,
|
||||
focusTitleInput: true,
|
||||
|
||||
+1
-5
@@ -7,7 +7,6 @@ import { useNavigationMenuItemsDraftState } from '@/navigation-menu-item/hooks/u
|
||||
import { useOpenNavigationMenuItemInSidePanel } from '@/navigation-menu-item/hooks/useOpenNavigationMenuItemInSidePanel';
|
||||
import { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState';
|
||||
import { navigationMenuItemsDraftState } from '@/navigation-menu-item/states/navigationMenuItemsDraftState';
|
||||
import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
|
||||
@@ -18,9 +17,6 @@ export const useAddLinkToNavigationMenu = () => {
|
||||
const navigationMenuItemsDraft = useAtomStateValue(
|
||||
navigationMenuItemsDraftState,
|
||||
);
|
||||
const setSelectedNavigationMenuItemInEditMode = useSetAtomState(
|
||||
selectedNavigationMenuItemInEditModeState,
|
||||
);
|
||||
const { openNavigationMenuItemInSidePanel } =
|
||||
useOpenNavigationMenuItemInSidePanel();
|
||||
const addMenuItemInsertionContext = useAtomStateValue(
|
||||
@@ -47,8 +43,8 @@ export const useAddLinkToNavigationMenu = () => {
|
||||
);
|
||||
|
||||
setAddMenuItemInsertionContext(null);
|
||||
setSelectedNavigationMenuItemInEditMode(itemId);
|
||||
openNavigationMenuItemInSidePanel({
|
||||
itemId,
|
||||
pageTitle: t`Edit link`,
|
||||
pageIcon: IconLink,
|
||||
focusTitleInput: true,
|
||||
|
||||
+1
@@ -41,6 +41,7 @@ const getAddMenuItemInsertionContext = (
|
||||
return {
|
||||
targetFolderId,
|
||||
targetIndex: selectedIndexInFolder + offset,
|
||||
disableDrag: true,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -20,9 +20,9 @@ export const getAvailableObjectMetadataForNewSidebarItem = ({
|
||||
objectMetadataIdsWithIndexView,
|
||||
objectMetadataIdsWithDisplayableViews,
|
||||
}: GetAvailableObjectMetadataForNewSidebarItemProps): GetAvailableObjectMetadataForNewSidebarItemResult => {
|
||||
const availableObjectMetadataItems = [
|
||||
...activeNonSystemObjectMetadataItems,
|
||||
].sort((a, b) => a.labelPlural.localeCompare(b.labelPlural));
|
||||
const availableObjectMetadataItems = activeNonSystemObjectMetadataItems
|
||||
.filter((item) => objectMetadataIdsWithIndexView.has(item.id))
|
||||
.sort((a, b) => a.labelPlural.localeCompare(b.labelPlural));
|
||||
|
||||
const activeSystemObjectMetadataItems = objectMetadataItems
|
||||
.filter((item) => item.isActive && item.isSystem)
|
||||
|
||||
Reference in New Issue
Block a user