Navbar customization v2 (#18026)
Adds color support for navigation menu items. --------- Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> Co-authored-by: Devessier <baptiste@devessier.fr> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
+7
-14
@@ -1,4 +1,3 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
@@ -6,24 +5,22 @@ import { useIcons } from 'twenty-ui/display';
|
||||
import { CommandMenuPageInfoLayout } from '@/command-menu/components/CommandMenuPageInfoLayout';
|
||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||
import { commandMenuShouldFocusTitleInputComponentState } from '@/command-menu/states/commandMenuShouldFocusTitleInputComponentState';
|
||||
import { StyledNavigationMenuItemIconContainer } from '@/navigation-menu-item/components/NavigationMenuItemIconContainer';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { FOLDER_ICON_DEFAULT } from '@/navigation-menu-item/constants/FolderIconDefault';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { useUpdateFolderInDraft } from '@/navigation-menu-item/hooks/useUpdateFolderInDraft';
|
||||
import { useWorkspaceSectionItems } from '@/navigation-menu-item/hooks/useWorkspaceSectionItems';
|
||||
import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors';
|
||||
import { IconPicker } from '@/ui/input/components/IconPicker';
|
||||
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';
|
||||
|
||||
const StyledClickableIconWrapper = styled.div`
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
export const CommandMenuFolderInfo = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
const commandMenuPageInfo = useAtomStateValue(commandMenuPageInfoState);
|
||||
@@ -83,15 +80,10 @@ export const CommandMenuFolderInfo = () => {
|
||||
}
|
||||
clickableComponent={
|
||||
<StyledClickableIconWrapper>
|
||||
<StyledNavigationMenuItemIconContainer
|
||||
$backgroundColor={getNavigationMenuItemIconColors(theme).folder}
|
||||
>
|
||||
<FolderIconComponent
|
||||
size={theme.spacing(3.5)}
|
||||
color={theme.grayScale.gray1}
|
||||
stroke={theme.icon.stroke.md}
|
||||
/>
|
||||
</StyledNavigationMenuItemIconContainer>
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={FolderIconComponent}
|
||||
color={selectedItem.color}
|
||||
/>
|
||||
</StyledClickableIconWrapper>
|
||||
}
|
||||
/>
|
||||
@@ -112,6 +104,7 @@ export const CommandMenuFolderInfo = () => {
|
||||
onFocus={() => setCommandMenuShouldFocusTitleInput(false)}
|
||||
/>
|
||||
}
|
||||
label={t`Folder`}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -67,7 +67,7 @@ export const CommandMenuItem = ({
|
||||
})
|
||||
: undefined
|
||||
}
|
||||
focused={isSelectedItemId}
|
||||
focused={!disabled && isSelectedItemId}
|
||||
RightComponent={RightComponent}
|
||||
hasSubMenu={hasSubMenu}
|
||||
isSubMenuOpened={isSubMenuOpened}
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconLink } from 'twenty-ui/display';
|
||||
|
||||
import { CommandMenuPageInfoLayout } from '@/command-menu/components/CommandMenuPageInfoLayout';
|
||||
import { commandMenuPageInfoState } from '@/command-menu/states/commandMenuPageInfoState';
|
||||
import { commandMenuShouldFocusTitleInputComponentState } from '@/command-menu/states/commandMenuShouldFocusTitleInputComponentState';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { StyledNavigationMenuItemIconContainer } from '@/navigation-menu-item/components/NavigationMenuItemIconContainer';
|
||||
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 { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors';
|
||||
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';
|
||||
|
||||
export const CommandMenuLinkInfo = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useLingui();
|
||||
const commandMenuPageInfo = useAtomStateValue(commandMenuPageInfoState);
|
||||
const [
|
||||
@@ -64,15 +61,10 @@ export const CommandMenuLinkInfo = () => {
|
||||
return (
|
||||
<CommandMenuPageInfoLayout
|
||||
icon={
|
||||
<StyledNavigationMenuItemIconContainer
|
||||
$backgroundColor={getNavigationMenuItemIconColors(theme).link}
|
||||
>
|
||||
<IconLink
|
||||
size={theme.spacing(3.5)}
|
||||
color={theme.grayScale.gray1}
|
||||
stroke={theme.icon.stroke.md}
|
||||
/>
|
||||
</StyledNavigationMenuItemIconContainer>
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={IconLink}
|
||||
color={selectedItem.color}
|
||||
/>
|
||||
}
|
||||
title={
|
||||
<TitleInput
|
||||
@@ -90,7 +82,7 @@ export const CommandMenuLinkInfo = () => {
|
||||
onFocus={() => setCommandMenuShouldFocusTitleInput(false)}
|
||||
/>
|
||||
}
|
||||
label={t`link`}
|
||||
label={t`Link`}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+10
-5
@@ -6,11 +6,15 @@ import { NavigationMenuItemIcon } from '@/navigation-menu-item/components/Naviga
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { useSelectedNavigationMenuItemEditItem } from '@/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItem';
|
||||
import { useSelectedNavigationMenuItemEditItemLabel } from '@/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItemLabel';
|
||||
import { useSelectedNavigationMenuItemEditItemObjectMetadata } from '@/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItemObjectMetadata';
|
||||
import { ViewKey } from '@/views/types/ViewKey';
|
||||
|
||||
export const CommandMenuObjectViewRecordInfo = () => {
|
||||
const { t } = useLingui();
|
||||
const { selectedItem } = useSelectedNavigationMenuItemEditItem();
|
||||
const { selectedItemLabel } = useSelectedNavigationMenuItemEditItemLabel();
|
||||
const { selectedItemObjectMetadata } =
|
||||
useSelectedNavigationMenuItemEditItemObjectMetadata();
|
||||
|
||||
const processedItem =
|
||||
selectedItem && selectedItem.itemType !== NavigationMenuItemType.FOLDER
|
||||
@@ -30,11 +34,12 @@ export const CommandMenuObjectViewRecordInfo = () => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = isViewOrRecord
|
||||
? processedItem.itemType === NavigationMenuItemType.RECORD
|
||||
? t`record`
|
||||
: t`view`
|
||||
: t`object`;
|
||||
const label =
|
||||
processedItem.itemType === NavigationMenuItemType.RECORD
|
||||
? selectedItemObjectMetadata?.labelSingular
|
||||
: processedItem.viewKey === ViewKey.Index
|
||||
? t`Object`
|
||||
: t`View`;
|
||||
|
||||
return (
|
||||
<CommandMenuPageInfoLayout
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { OverflowingTextWithTooltip } from 'twenty-ui/display';
|
||||
import {
|
||||
IconColumnInsertRight,
|
||||
OverflowingTextWithTooltip,
|
||||
} from 'twenty-ui/display';
|
||||
|
||||
import { CommandMenuAskAIInfo } from '@/command-menu/components/CommandMenuAskAIInfo';
|
||||
import { CommandMenuFolderInfo } from '@/command-menu/components/CommandMenuFolderInfo';
|
||||
import { CommandMenuLinkInfo } from '@/command-menu/components/CommandMenuLinkInfo';
|
||||
import { CommandMenuMultipleRecordsInfo } from '@/command-menu/components/CommandMenuMultipleRecordsInfo';
|
||||
import { CommandMenuObjectViewRecordInfo } from '@/command-menu/components/CommandMenuObjectViewRecordInfo';
|
||||
import { CommandMenuPageInfoLayout } from '@/command-menu/components/CommandMenuPageInfoLayout';
|
||||
import { CommandMenuPageLayoutInfo } from '@/command-menu/components/CommandMenuPageLayoutInfo';
|
||||
import { CommandMenuRecordInfo } from '@/command-menu/components/CommandMenuRecordInfo';
|
||||
import { CommandMenuWorkflowStepInfo } from '@/command-menu/components/CommandMenuWorkflowStepInfo';
|
||||
@@ -16,6 +20,7 @@ import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-ite
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { type CommandMenuContextChipProps } from './CommandMenuContextChip';
|
||||
|
||||
const StyledPageTitle = styled.div`
|
||||
@@ -29,6 +34,7 @@ type CommandMenuPageInfoProps = {
|
||||
};
|
||||
|
||||
export const CommandMenuPageInfo = ({ pageChip }: CommandMenuPageInfoProps) => {
|
||||
const theme = useTheme();
|
||||
const selectedNavigationMenuItemInEditMode = useAtomStateValue(
|
||||
selectedNavigationMenuItemInEditModeState,
|
||||
);
|
||||
@@ -121,6 +127,20 @@ export const CommandMenuPageInfo = ({ pageChip }: CommandMenuPageInfoProps) => {
|
||||
return <CommandMenuAskAIInfo />;
|
||||
}
|
||||
|
||||
if (pageChip.page?.page === CommandMenuPages.NavigationMenuAddItem) {
|
||||
return (
|
||||
<CommandMenuPageInfoLayout
|
||||
icon={
|
||||
<IconColumnInsertRight
|
||||
size={theme.icon.size.md}
|
||||
color={theme.font.color.tertiary}
|
||||
/>
|
||||
}
|
||||
title={<OverflowingTextWithTooltip text={pageChip.text ?? ''} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledPageTitle>
|
||||
<OverflowingTextWithTooltip text={pageChip.text ?? ''} />
|
||||
|
||||
+5
-3
@@ -12,9 +12,12 @@ const StyledSubViewContainer = styled.div`
|
||||
`;
|
||||
|
||||
const StyledSearchContainer = styled.div`
|
||||
align-items: center;
|
||||
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
display: flex;
|
||||
height: ${({ theme }) => theme.spacing(10)};
|
||||
min-width: 0;
|
||||
padding: ${({ theme }) => theme.spacing(2, 3)};
|
||||
padding-inline: ${({ theme }) => theme.spacing(3)};
|
||||
`;
|
||||
|
||||
const StyledSearchInput = styled.input`
|
||||
@@ -22,8 +25,7 @@ const StyledSearchInput = styled.input`
|
||||
border: none;
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
box-sizing: border-box;
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
font-size: ${({ theme }) => theme.font.size.md};
|
||||
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
|
||||
@@ -4,14 +4,17 @@ import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchS
|
||||
import { isCommandMenuClosingState } from '@/command-menu/states/isCommandMenuClosingState';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { addToNavPayloadRegistryState } from '@/navigation-menu-item/states/addToNavPayloadRegistryState';
|
||||
import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/states/isNavigationMenuInEditModeState';
|
||||
import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeState';
|
||||
import { useCloseAnyOpenDropdown } from '@/ui/layout/dropdown/hooks/useCloseAnyOpenDropdown';
|
||||
import { emitSidePanelOpenEvent } from '@/ui/layout/right-drawer/utils/emitSidePanelOpenEvent';
|
||||
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useStore } from 'jotai';
|
||||
import { useCallback } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconDotsVertical } from 'twenty-ui/display';
|
||||
import { useStore } from 'jotai';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconColumnInsertRight, IconDotsVertical } from 'twenty-ui/display';
|
||||
|
||||
export const useCommandMenu = () => {
|
||||
const store = useStore();
|
||||
@@ -38,13 +41,35 @@ export const useCommandMenu = () => {
|
||||
const openCommandMenu = useCallback(() => {
|
||||
emitSidePanelOpenEvent();
|
||||
closeAnyOpenDropdown();
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.Root,
|
||||
pageTitle: t`Command Menu`,
|
||||
pageIcon: IconDotsVertical,
|
||||
resetNavigationStack: true,
|
||||
});
|
||||
}, [closeAnyOpenDropdown, navigateCommandMenu]);
|
||||
const isNavigationMenuInEditMode = store.get(
|
||||
isNavigationMenuInEditModeState.atom,
|
||||
);
|
||||
const selectedNavigationItemId = store.get(
|
||||
selectedNavigationMenuItemInEditModeState.atom,
|
||||
);
|
||||
if (isNavigationMenuInEditMode && isDefined(selectedNavigationItemId)) {
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.NavigationMenuItemEdit,
|
||||
pageTitle: t`Edit`,
|
||||
pageIcon: IconDotsVertical,
|
||||
resetNavigationStack: true,
|
||||
});
|
||||
} else if (isNavigationMenuInEditMode) {
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.NavigationMenuAddItem,
|
||||
pageTitle: t`New sidebar item`,
|
||||
pageIcon: IconColumnInsertRight,
|
||||
resetNavigationStack: true,
|
||||
});
|
||||
} else {
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.Root,
|
||||
pageTitle: t`Command Menu`,
|
||||
pageIcon: IconDotsVertical,
|
||||
resetNavigationStack: true,
|
||||
});
|
||||
}
|
||||
}, [closeAnyOpenDropdown, navigateCommandMenu, store]);
|
||||
|
||||
const toggleCommandMenu = useCallback(() => {
|
||||
const isCommandMenuOpened = store.get(isCommandMenuOpenedState.atom);
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
import { CommandMenuItemDropdown } from '@/command-menu/components/CommandMenuItemDropdown';
|
||||
import { useUpdateNavigationMenuItemInDraft } from '@/navigation-menu-item/hooks/useUpdateNavigationMenuItemInDraft';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useState } from 'react';
|
||||
import { capitalize } from 'twenty-shared/utils';
|
||||
import { IconColorSwatch } from 'twenty-ui/display';
|
||||
import {
|
||||
DEFAULT_COLOR_LABELS,
|
||||
MenuItemSelectColor,
|
||||
} from 'twenty-ui/navigation';
|
||||
import { MAIN_COLOR_NAMES, type ThemeColor } from 'twenty-ui/theme';
|
||||
|
||||
const NAVIGATION_MENU_ITEM_COLOR_DROPDOWN_ID = 'navigation-menu-item-color';
|
||||
|
||||
const StyledMenuStyleText = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
font-size: 13px;
|
||||
`;
|
||||
|
||||
type CommandMenuEditColorOptionProps = {
|
||||
navigationMenuItemId: string;
|
||||
color: ThemeColor;
|
||||
};
|
||||
|
||||
export const CommandMenuEditColorOption = ({
|
||||
navigationMenuItemId,
|
||||
color,
|
||||
}: CommandMenuEditColorOptionProps) => {
|
||||
const { t } = useLingui();
|
||||
const { updateNavigationMenuItemInDraft } =
|
||||
useUpdateNavigationMenuItemInDraft();
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const themeColor = color ?? 'gray';
|
||||
const colorLabel = DEFAULT_COLOR_LABELS[themeColor] ?? capitalize(themeColor);
|
||||
|
||||
const query = searchValue.trim().toLowerCase();
|
||||
|
||||
const filteredColorNames = isNonEmptyString(query)
|
||||
? MAIN_COLOR_NAMES.filter(
|
||||
(colorName) =>
|
||||
colorName.toLowerCase().includes(query) ||
|
||||
(DEFAULT_COLOR_LABELS[colorName] ?? '').toLowerCase().includes(query),
|
||||
)
|
||||
: MAIN_COLOR_NAMES;
|
||||
|
||||
const handleSelectColor = (selectedColor: ThemeColor) => {
|
||||
updateNavigationMenuItemInDraft(navigationMenuItemId, {
|
||||
color: selectedColor,
|
||||
});
|
||||
closeDropdown(NAVIGATION_MENU_ITEM_COLOR_DROPDOWN_ID);
|
||||
};
|
||||
|
||||
return (
|
||||
<CommandMenuItemDropdown
|
||||
id="edit-navigation-menu-item-color"
|
||||
label={t`Color`}
|
||||
Icon={IconColorSwatch}
|
||||
dropdownId={NAVIGATION_MENU_ITEM_COLOR_DROPDOWN_ID}
|
||||
dropdownPlacement="bottom-start"
|
||||
RightComponent={<StyledMenuStyleText>{colorLabel}</StyledMenuStyleText>}
|
||||
dropdownComponents={
|
||||
<DropdownContent>
|
||||
<DropdownMenuSearchInput
|
||||
placeholder={t`Search colors...`}
|
||||
value={searchValue}
|
||||
onChange={(event) => setSearchValue(event.target.value)}
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{filteredColorNames.map((colorName) => (
|
||||
<MenuItemSelectColor
|
||||
key={colorName}
|
||||
onClick={() => handleSelectColor(colorName)}
|
||||
color={colorName}
|
||||
selected={colorName === themeColor}
|
||||
colorLabels={DEFAULT_COLOR_LABELS}
|
||||
/>
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownContent>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
+30
-16
@@ -1,12 +1,15 @@
|
||||
import { useState } from 'react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconFolderPlus } from 'twenty-ui/display';
|
||||
import { useState } from 'react';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
import { CommandGroup } from '@/command-menu/components/CommandGroup';
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
|
||||
import { CommandMenuSubViewWithSearch } from '@/command-menu/components/CommandMenuSubViewWithSearch';
|
||||
import { useFolderPickerSelectionData } from '@/command-menu/pages/navigation-menu-item/hooks/useFolderPickerSelectionData';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { FOLDER_ICON_DEFAULT } from '@/navigation-menu-item/constants/FolderIconDefault';
|
||||
import { DEFAULT_NAVIGATION_MENU_ITEM_COLOR_FOLDER } from '@/navigation-menu-item/constants/NavigationMenuItemDefaultColorFolder';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
|
||||
|
||||
@@ -18,6 +21,7 @@ export const CommandMenuEditFolderPickerSubView = ({
|
||||
onBack,
|
||||
}: CommandMenuEditFolderPickerSubViewProps) => {
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const { foldersToShow, includeNoFolderOption, handleSelectFolder } =
|
||||
useFolderPickerSelectionData({ onCloseSubView: onBack });
|
||||
@@ -64,20 +68,30 @@ export const CommandMenuEditFolderPickerSubView = ({
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{filteredFolders.map((folder) => (
|
||||
<SelectableListItem
|
||||
key={folder.id}
|
||||
itemId={folder.id}
|
||||
onEnter={() => handleSelectFolder(folder.id)}
|
||||
>
|
||||
<CommandMenuItem
|
||||
Icon={IconFolderPlus}
|
||||
label={folder.name}
|
||||
id={folder.id}
|
||||
onClick={() => handleSelectFolder(folder.id)}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
))}
|
||||
{filteredFolders.map((folder) => {
|
||||
const FolderIcon = getIcon(folder.icon ?? FOLDER_ICON_DEFAULT);
|
||||
const folderColor =
|
||||
folder.color ?? DEFAULT_NAVIGATION_MENU_ITEM_COLOR_FOLDER;
|
||||
return (
|
||||
<SelectableListItem
|
||||
key={folder.id}
|
||||
itemId={folder.id}
|
||||
onEnter={() => handleSelectFolder(folder.id)}
|
||||
>
|
||||
<CommandMenuItem
|
||||
LeftComponent={
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={FolderIcon}
|
||||
color={folderColor}
|
||||
/>
|
||||
}
|
||||
label={folder.name}
|
||||
id={folder.id}
|
||||
onClick={() => handleSelectFolder(folder.id)}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
);
|
||||
})}
|
||||
</CommandGroup>
|
||||
</CommandMenuList>
|
||||
</CommandMenuSubViewWithSearch>
|
||||
|
||||
+7
-1
@@ -5,13 +5,15 @@ import { getAbsoluteUrl } from 'twenty-shared/utils';
|
||||
|
||||
import { CommandGroup } from '@/command-menu/components/CommandGroup';
|
||||
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
|
||||
import { CommandMenuEditColorOption } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuEditColorOption';
|
||||
import {
|
||||
type OrganizeActionsProps,
|
||||
CommandMenuEditOrganizeActions,
|
||||
} from '@/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions';
|
||||
import { getOrganizeActionsSelectableItemIds } from '@/command-menu/pages/navigation-menu-item/utils/getOrganizeActionsSelectableItemIds';
|
||||
import { CommandMenuEditOwnerSection } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuEditOwnerSection';
|
||||
import { getOrganizeActionsSelectableItemIds } from '@/command-menu/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 CommandMenuEditLinkItemViewProps = OrganizeActionsProps & {
|
||||
@@ -40,6 +42,10 @@ export const CommandMenuEditLinkItemView = ({
|
||||
return (
|
||||
<CommandMenuList commandGroups={[]} selectableItemIds={selectableItemIds}>
|
||||
<CommandGroup heading={t`Customize`}>
|
||||
<CommandMenuEditColorOption
|
||||
navigationMenuItemId={selectedItem.id}
|
||||
color={parseThemeColor(selectedItem.color)}
|
||||
/>
|
||||
<TextInput
|
||||
fullWidth
|
||||
placeholder="www.google.com"
|
||||
|
||||
+18
-1
@@ -1,12 +1,18 @@
|
||||
import { CommandGroup } from '@/command-menu/components/CommandGroup';
|
||||
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
|
||||
import { CommandMenuEditColorOption } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuEditColorOption';
|
||||
import {
|
||||
type OrganizeActionsProps,
|
||||
CommandMenuEditOrganizeActions,
|
||||
} from '@/command-menu/pages/navigation-menu-item/components/CommandMenuEditOrganizeActions';
|
||||
import { getOrganizeActionsSelectableItemIds } from '@/command-menu/pages/navigation-menu-item/utils/getOrganizeActionsSelectableItemIds';
|
||||
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
|
||||
import { useSelectedNavigationMenuItemEditItem } from '@/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItem';
|
||||
import { parseThemeColor } from '@/navigation-menu-item/utils/parseThemeColor';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
|
||||
type CommandMenuEditObjectViewBaseProps = OrganizeActionsProps & {
|
||||
onOpenFolderPicker: () => void;
|
||||
showColorOption?: boolean;
|
||||
};
|
||||
|
||||
export const CommandMenuEditObjectViewBase = ({
|
||||
@@ -18,11 +24,22 @@ export const CommandMenuEditObjectViewBase = ({
|
||||
onRemove,
|
||||
onAddBefore,
|
||||
onAddAfter,
|
||||
showColorOption = false,
|
||||
}: CommandMenuEditObjectViewBaseProps) => {
|
||||
const { t } = useLingui();
|
||||
const { selectedItem } = useSelectedNavigationMenuItemEditItem();
|
||||
const selectableItemIds = getOrganizeActionsSelectableItemIds(true);
|
||||
|
||||
return (
|
||||
<CommandMenuList commandGroups={[]} selectableItemIds={selectableItemIds}>
|
||||
{showColorOption && selectedItem && (
|
||||
<CommandGroup heading={t`Customize`}>
|
||||
<CommandMenuEditColorOption
|
||||
navigationMenuItemId={selectedItem.id}
|
||||
color={parseThemeColor(selectedItem.color)}
|
||||
/>
|
||||
</CommandGroup>
|
||||
)}
|
||||
<CommandMenuEditOrganizeActions
|
||||
canMoveUp={canMoveUp}
|
||||
canMoveDown={canMoveDown}
|
||||
|
||||
+72
-6
@@ -1,4 +1,7 @@
|
||||
import { CommandGroup } from '@/command-menu/components/CommandGroup';
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
|
||||
import { CommandMenuEditColorOption } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuEditColorOption';
|
||||
import { CommandMenuEditFolderPickerSubView } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuEditFolderPickerSubView';
|
||||
import { CommandMenuEditLinkItemView } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuEditLinkItemView';
|
||||
import { CommandMenuEditObjectViewBase } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuEditObjectViewBase';
|
||||
@@ -7,16 +10,24 @@ import { CommandMenuEditOwnerSection } from '@/command-menu/pages/navigation-men
|
||||
import { useNavigationMenuItemEditOrganizeActions } from '@/command-menu/pages/navigation-menu-item/hooks/useNavigationMenuItemEditOrganizeActions';
|
||||
import { getOrganizeActionsSelectableItemIds } from '@/command-menu/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';
|
||||
import { useSelectedNavigationMenuItemEditItem } from '@/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItem';
|
||||
import { useSelectedNavigationMenuItemEditItemLabel } from '@/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItemLabel';
|
||||
import { useSelectedNavigationMenuItemEditItemObjectMetadata } from '@/navigation-menu-item/hooks/useSelectedNavigationMenuItemEditItemObjectMetadata';
|
||||
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 { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { ViewKey } from '@/views/types/ViewKey';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { IconPlus } from 'twenty-ui/display';
|
||||
|
||||
const ADD_ITEM_TO_FOLDER_ACTION_ID = 'add-item-to-folder';
|
||||
|
||||
const StyledCommandMenuPlaceholder = styled.p`
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
@@ -40,7 +51,7 @@ export const CommandMenuNavigationMenuItemEditPage = () => {
|
||||
const selectedItemType = selectedItem?.itemType ?? null;
|
||||
|
||||
const [isFolderPickerOpen, setIsFolderPickerOpen] = useState(false);
|
||||
const setFolderPicker = () => setIsFolderPickerOpen(true);
|
||||
const openFolderPicker = () => setIsFolderPickerOpen(true);
|
||||
|
||||
const {
|
||||
canMoveUp,
|
||||
@@ -53,6 +64,25 @@ export const CommandMenuNavigationMenuItemEditPage = () => {
|
||||
} = useNavigationMenuItemEditOrganizeActions();
|
||||
|
||||
const { updateLinkInDraft } = useUpdateLinkInDraft();
|
||||
const { openAddItemToFolderPage } = useOpenAddItemToFolderPage();
|
||||
const { workspaceNavigationMenuItems } = useNavigationMenuItemsDraftState();
|
||||
|
||||
const handleAddItemToFolder = () => {
|
||||
if (
|
||||
!selectedItem ||
|
||||
selectedItem.itemType !== NavigationMenuItemType.FOLDER
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const folderItemCount = workspaceNavigationMenuItems.filter(
|
||||
(item) => (item.folderId ?? null) === selectedItem.id,
|
||||
).length;
|
||||
openAddItemToFolderPage({
|
||||
targetFolderId: selectedItem.id,
|
||||
targetIndex: folderItemCount,
|
||||
resetNavigationStack: false,
|
||||
});
|
||||
};
|
||||
|
||||
if (!selectedNavigationMenuItemInEditMode || !selectedItemLabel) {
|
||||
return (
|
||||
@@ -77,7 +107,7 @@ export const CommandMenuNavigationMenuItemEditPage = () => {
|
||||
if (!selectedItemObjectMetadata) return null;
|
||||
return (
|
||||
<CommandMenuEditObjectViewBase
|
||||
onOpenFolderPicker={setFolderPicker}
|
||||
onOpenFolderPicker={openFolderPicker}
|
||||
canMoveUp={canMoveUp}
|
||||
canMoveDown={canMoveDown}
|
||||
onMoveUp={onMoveUp}
|
||||
@@ -85,6 +115,11 @@ export const CommandMenuNavigationMenuItemEditPage = () => {
|
||||
onRemove={onRemove}
|
||||
onAddBefore={onAddBefore}
|
||||
onAddAfter={onAddAfter}
|
||||
showColorOption={
|
||||
selectedItem &&
|
||||
'viewKey' in selectedItem &&
|
||||
selectedItem.viewKey === ViewKey.Index
|
||||
}
|
||||
/>
|
||||
);
|
||||
case NavigationMenuItemType.LINK:
|
||||
@@ -97,7 +132,7 @@ export const CommandMenuNavigationMenuItemEditPage = () => {
|
||||
key={selectedItem.id}
|
||||
selectedItem={selectedItem}
|
||||
onUpdateLink={(linkId, link) => updateLinkInDraft(linkId, { link })}
|
||||
onOpenFolderPicker={setFolderPicker}
|
||||
onOpenFolderPicker={openFolderPicker}
|
||||
canMoveUp={canMoveUp}
|
||||
canMoveDown={canMoveDown}
|
||||
onMoveUp={onMoveUp}
|
||||
@@ -113,8 +148,31 @@ export const CommandMenuNavigationMenuItemEditPage = () => {
|
||||
return (
|
||||
<CommandMenuList
|
||||
commandGroups={[]}
|
||||
selectableItemIds={getOrganizeActionsSelectableItemIds(false)}
|
||||
selectableItemIds={[
|
||||
ADD_ITEM_TO_FOLDER_ACTION_ID,
|
||||
...getOrganizeActionsSelectableItemIds(false),
|
||||
]}
|
||||
>
|
||||
{selectedItem && (
|
||||
<CommandGroup heading={t`Customize`}>
|
||||
<SelectableListItem
|
||||
itemId={ADD_ITEM_TO_FOLDER_ACTION_ID}
|
||||
onEnter={handleAddItemToFolder}
|
||||
>
|
||||
<CommandMenuItem
|
||||
Icon={IconPlus}
|
||||
label={t`Add item to folder`}
|
||||
id={ADD_ITEM_TO_FOLDER_ACTION_ID}
|
||||
onClick={handleAddItemToFolder}
|
||||
hasSubMenu
|
||||
/>
|
||||
</SelectableListItem>
|
||||
<CommandMenuEditColorOption
|
||||
navigationMenuItemId={selectedItem.id}
|
||||
color={parseThemeColor(selectedItem.color)}
|
||||
/>
|
||||
</CommandGroup>
|
||||
)}
|
||||
<CommandMenuEditOrganizeActions
|
||||
canMoveUp={canMoveUp}
|
||||
canMoveDown={canMoveDown}
|
||||
@@ -133,6 +191,14 @@ export const CommandMenuNavigationMenuItemEditPage = () => {
|
||||
commandGroups={[]}
|
||||
selectableItemIds={getOrganizeActionsSelectableItemIds(true)}
|
||||
>
|
||||
{selectedItem && (
|
||||
<CommandGroup heading={t`Customize`}>
|
||||
<CommandMenuEditColorOption
|
||||
navigationMenuItemId={selectedItem.id}
|
||||
color={parseThemeColor(selectedItem.color)}
|
||||
/>
|
||||
</CommandGroup>
|
||||
)}
|
||||
<CommandMenuEditOrganizeActions
|
||||
canMoveUp={canMoveUp}
|
||||
canMoveDown={canMoveDown}
|
||||
@@ -142,7 +208,7 @@ export const CommandMenuNavigationMenuItemEditPage = () => {
|
||||
onAddBefore={onAddBefore}
|
||||
onAddAfter={onAddAfter}
|
||||
showMoveToFolder
|
||||
onMoveToFolder={setFolderPicker}
|
||||
onMoveToFolder={openFolderPicker}
|
||||
/>
|
||||
</CommandMenuList>
|
||||
);
|
||||
|
||||
+26
-7
@@ -1,10 +1,11 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import {
|
||||
IconAddressBook,
|
||||
IconCube,
|
||||
Avatar,
|
||||
IconBuildingSkyscraper,
|
||||
IconFolder,
|
||||
IconLink,
|
||||
IconList,
|
||||
IconTable,
|
||||
} from 'twenty-ui/display';
|
||||
|
||||
import { CommandGroup } from '@/command-menu/components/CommandGroup';
|
||||
@@ -15,8 +16,9 @@ import { CommandMenuItemWithAddToNavigationDrag } from '@/command-menu/component
|
||||
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
|
||||
import { useAddFolderToNavigationMenu } from '@/command-menu/pages/navigation-menu-item/hooks/useAddFolderToNavigationMenu';
|
||||
import { useAddLinkToNavigationMenu } from '@/command-menu/pages/navigation-menu-item/hooks/useAddLinkToNavigationMenu';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
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';
|
||||
|
||||
type CommandMenuNewSidebarItemMainMenuProps = {
|
||||
onSelectObject: () => void;
|
||||
@@ -30,6 +32,7 @@ export const CommandMenuNewSidebarItemMainMenu = ({
|
||||
onSelectRecord,
|
||||
}: CommandMenuNewSidebarItemMainMenuProps) => {
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
const { handleAddFolder } = useAddFolderToNavigationMenu();
|
||||
const { handleAddLink } = useAddLinkToNavigationMenu();
|
||||
|
||||
@@ -46,7 +49,12 @@ export const CommandMenuNewSidebarItemMainMenu = ({
|
||||
<CommandMenuAddToNavDraggablePlaceholder index={0}>
|
||||
<SelectableListItem itemId="object" onEnter={onSelectObject}>
|
||||
<CommandMenuItem
|
||||
Icon={IconCube}
|
||||
Icon={() => (
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={IconBuildingSkyscraper}
|
||||
color="blue"
|
||||
/>
|
||||
)}
|
||||
label={t`Object`}
|
||||
id="object"
|
||||
hasSubMenu={true}
|
||||
@@ -57,7 +65,12 @@ export const CommandMenuNewSidebarItemMainMenu = ({
|
||||
<CommandMenuAddToNavDraggablePlaceholder index={1}>
|
||||
<SelectableListItem itemId="view" onEnter={onSelectView}>
|
||||
<CommandMenuItem
|
||||
Icon={IconList}
|
||||
Icon={() => (
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={IconTable}
|
||||
color="gray"
|
||||
/>
|
||||
)}
|
||||
label={t`View`}
|
||||
id="view"
|
||||
hasSubMenu={true}
|
||||
@@ -68,7 +81,13 @@ export const CommandMenuNewSidebarItemMainMenu = ({
|
||||
<CommandMenuAddToNavDraggablePlaceholder index={2}>
|
||||
<SelectableListItem itemId="record" onEnter={onSelectRecord}>
|
||||
<CommandMenuItem
|
||||
Icon={IconAddressBook}
|
||||
Icon={() => (
|
||||
<Avatar
|
||||
placeholder="L"
|
||||
type="rounded"
|
||||
backgroundColor={theme.color.green4}
|
||||
/>
|
||||
)}
|
||||
label={t`Record`}
|
||||
id="record"
|
||||
hasSubMenu={true}
|
||||
|
||||
+10
-2
@@ -6,6 +6,7 @@ import { CommandMenuObjectPickerSubView } from '@/command-menu/pages/navigation-
|
||||
import { CommandMenuSystemObjectPickerSubView } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuSystemObjectPickerSubView';
|
||||
import { getAvailableObjectMetadataForNewSidebarItem } from '@/command-menu/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 { addMenuItemInsertionContextState } from '@/navigation-menu-item/states/addMenuItemInsertionContextState';
|
||||
@@ -40,8 +41,11 @@ export const CommandMenuNewSidebarItemObjectFlow = ({
|
||||
const setAddMenuItemInsertionContext = useSetAtomState(
|
||||
addMenuItemInsertionContextState,
|
||||
);
|
||||
const { views, objectMetadataIdsWithIndexView } =
|
||||
useNavigationMenuObjectMetadataFromDraft(currentDraft);
|
||||
const {
|
||||
views,
|
||||
objectMetadataIdsWithIndexView,
|
||||
objectMetadataIdsInWorkspace,
|
||||
} = useNavigationMenuObjectMetadataFromDraft(currentDraft);
|
||||
|
||||
const objectMetadataIdsWithDisplayableViews = new Set(
|
||||
views
|
||||
@@ -61,12 +65,16 @@ export const CommandMenuNewSidebarItemObjectFlow = ({
|
||||
objectMetadataItem: ObjectMetadataItem,
|
||||
defaultViewId: string,
|
||||
) => {
|
||||
if (objectMetadataIdsInWorkspace.has(objectMetadataItem.id)) {
|
||||
return;
|
||||
}
|
||||
addObjectToDraft(
|
||||
objectMetadataItem.id,
|
||||
defaultViewId,
|
||||
currentDraft,
|
||||
addMenuItemInsertionContext?.targetFolderId,
|
||||
addMenuItemInsertionContext?.targetIndex,
|
||||
getStandardObjectIconColor(objectMetadataItem.nameSingular),
|
||||
);
|
||||
setAddMenuItemInsertionContext(null);
|
||||
closeCommandMenu();
|
||||
|
||||
+8
-11
@@ -1,4 +1,3 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconSettings, useIcons } from 'twenty-ui/display';
|
||||
|
||||
@@ -7,8 +6,8 @@ import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
|
||||
import { CommandMenuSubViewWithSearch } from '@/command-menu/components/CommandMenuSubViewWithSearch';
|
||||
import { useFilteredPickerItems } from '@/command-menu/hooks/useFilteredPickerItems';
|
||||
import { IconWithBackground } from '@/navigation-menu-item/components/IconWithBackground';
|
||||
import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors';
|
||||
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 { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
|
||||
@@ -32,9 +31,7 @@ export const CommandMenuNewSidebarItemViewObjectPickerSubView = ({
|
||||
showSystemObjectsOption = true,
|
||||
}: CommandMenuNewSidebarItemViewObjectPickerSubViewProps) => {
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
const { getIcon } = useIcons();
|
||||
const iconColors = getNavigationMenuItemIconColors(theme);
|
||||
const { filteredItems, selectableItemIds, isEmpty, hasSearchQuery } =
|
||||
useFilteredPickerItems({
|
||||
items: objects,
|
||||
@@ -68,12 +65,12 @@ export const CommandMenuNewSidebarItemViewObjectPickerSubView = ({
|
||||
onEnter={() => onSelectObject(objectMetadataItem)}
|
||||
>
|
||||
<CommandMenuItem
|
||||
Icon={({ size, stroke }) => (
|
||||
<IconWithBackground
|
||||
Icon={() => (
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={getIcon(objectMetadataItem.icon)}
|
||||
backgroundColor={iconColors.object}
|
||||
size={size}
|
||||
stroke={stroke}
|
||||
color={getStandardObjectIconColor(
|
||||
objectMetadataItem.nameSingular,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
label={objectMetadataItem.labelPlural}
|
||||
@@ -86,7 +83,7 @@ export const CommandMenuNewSidebarItemViewObjectPickerSubView = ({
|
||||
{showSystemObjectsOption && (
|
||||
<SelectableListItem itemId="system" onEnter={onOpenSystemPicker}>
|
||||
<CommandMenuItem
|
||||
Icon={IconSettings}
|
||||
Icon={() => <NavigationMenuItemStyleIcon Icon={IconSettings} />}
|
||||
label={t`System objects`}
|
||||
id="system"
|
||||
hasSubMenu={true}
|
||||
|
||||
+14
-7
@@ -1,7 +1,3 @@
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
import { CommandGroup } from '@/command-menu/components/CommandGroup';
|
||||
import { CommandMenuAddToNavDroppable } from '@/command-menu/components/CommandMenuAddToNavDroppable';
|
||||
import { CommandMenuItemWithAddToNavigationDrag } from '@/command-menu/components/CommandMenuItemWithAddToNavigationDrag';
|
||||
@@ -9,18 +5,23 @@ import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
|
||||
import { CommandMenuSubViewWithSearch } from '@/command-menu/components/CommandMenuSubViewWithSearch';
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { useFilteredPickerItems } from '@/command-menu/hooks/useFilteredPickerItems';
|
||||
import { useDraftNavigationMenuItems } from '@/navigation-menu-item/hooks/useDraftNavigationMenuItems';
|
||||
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 { 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 { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
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 { useLingui } from '@lingui/react/macro';
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
type CommandMenuNewSidebarItemViewPickerSubViewProps = {
|
||||
selectedObjectMetadataIdForView: string;
|
||||
@@ -80,6 +81,9 @@ export const CommandMenuNewSidebarItemViewPickerSubView = ({
|
||||
currentDraft,
|
||||
addMenuItemInsertionContext?.targetFolderId ?? null,
|
||||
addMenuItemInsertionContext?.targetIndex,
|
||||
isDefined(selectedObjectMetadataItem)
|
||||
? getStandardObjectIconColor(selectedObjectMetadataItem.nameSingular)
|
||||
: undefined,
|
||||
);
|
||||
setAddMenuItemInsertionContext(null);
|
||||
closeCommandMenu();
|
||||
@@ -118,6 +122,9 @@ export const CommandMenuNewSidebarItemViewPickerSubView = ({
|
||||
selectedObjectMetadataItem.icon,
|
||||
)}
|
||||
ViewIcon={getIcon(view.icon)}
|
||||
objectColor={getStandardObjectIconColor(
|
||||
selectedObjectMetadataItem.nameSingular,
|
||||
)}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
|
||||
+7
-10
@@ -1,4 +1,3 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
@@ -6,9 +5,9 @@ import { CommandGroup } from '@/command-menu/components/CommandGroup';
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
|
||||
import { CommandMenuSubViewWithSearch } from '@/command-menu/components/CommandMenuSubViewWithSearch';
|
||||
import { IconWithBackground } from '@/navigation-menu-item/components/IconWithBackground';
|
||||
import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors';
|
||||
import { useFilteredPickerItems } from '@/command-menu/hooks/useFilteredPickerItems';
|
||||
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 { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
|
||||
@@ -28,9 +27,7 @@ export const CommandMenuNewSidebarItemViewSystemSubView = ({
|
||||
onSelectObject,
|
||||
}: CommandMenuNewSidebarItemViewSystemSubViewProps) => {
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
const { getIcon } = useIcons();
|
||||
const iconColors = getNavigationMenuItemIconColors(theme);
|
||||
const {
|
||||
filteredItems: filteredSystemObjectMetadataItems,
|
||||
selectableItemIds,
|
||||
@@ -67,12 +64,12 @@ export const CommandMenuNewSidebarItemViewSystemSubView = ({
|
||||
onEnter={() => onSelectObject(objectMetadataItem)}
|
||||
>
|
||||
<CommandMenuItem
|
||||
Icon={({ size, stroke }) => (
|
||||
<IconWithBackground
|
||||
Icon={() => (
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={getIcon(objectMetadataItem.icon)}
|
||||
backgroundColor={iconColors.object}
|
||||
size={size}
|
||||
stroke={stroke}
|
||||
color={getStandardObjectIconColor(
|
||||
objectMetadataItem.nameSingular,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
label={objectMetadataItem.labelPlural}
|
||||
|
||||
+22
-16
@@ -1,12 +1,14 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { CommandMenuItemWithAddToNavigationDrag } from '@/command-menu/components/CommandMenuItemWithAddToNavigationDrag';
|
||||
import { IconWithBackground } from '@/navigation-menu-item/components/IconWithBackground';
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors';
|
||||
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 { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
|
||||
@@ -28,28 +30,38 @@ export const CommandMenuObjectMenuItem = ({
|
||||
variant,
|
||||
dragIndex,
|
||||
}: CommandMenuObjectMenuItemProps) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
const iconColors = getNavigationMenuItemIconColors(theme);
|
||||
const { currentDraft } = useDraftNavigationMenuItems();
|
||||
const { objectMetadataIdsInWorkspace } =
|
||||
useNavigationMenuObjectMetadataFromDraft(currentDraft);
|
||||
const isAlreadyInNavbar = objectMetadataIdsInWorkspace.has(
|
||||
objectMetadataItem.id,
|
||||
);
|
||||
const defaultViewId = useAtomFamilySelectorValue(
|
||||
coreIndexViewIdFromObjectMetadataItemFamilySelector,
|
||||
{ objectMetadataItemId: objectMetadataItem.id },
|
||||
);
|
||||
const Icon = getIcon(objectMetadataItem.icon);
|
||||
const isDisabled = !isDefined(defaultViewId);
|
||||
const iconColor = getStandardObjectIconColor(objectMetadataItem.nameSingular);
|
||||
const isDisabled = isAlreadyInNavbar || !isDefined(defaultViewId);
|
||||
|
||||
const handleClick = () => {
|
||||
if (!defaultViewId) {
|
||||
if (isDisabled || !defaultViewId) {
|
||||
return;
|
||||
}
|
||||
onSelect(objectMetadataItem, defaultViewId);
|
||||
};
|
||||
|
||||
const styledIcon = () => (
|
||||
<NavigationMenuItemStyleIcon Icon={Icon} color={iconColor} />
|
||||
);
|
||||
|
||||
return (
|
||||
<SelectableListItem itemId={objectMetadataItem.id} onEnter={handleClick}>
|
||||
{variant === 'add' && !isDisabled ? (
|
||||
<CommandMenuItemWithAddToNavigationDrag
|
||||
icon={Icon}
|
||||
icon={styledIcon}
|
||||
label={objectMetadataItem.labelPlural}
|
||||
id={objectMetadataItem.id}
|
||||
onClick={handleClick}
|
||||
@@ -63,18 +75,12 @@ export const CommandMenuObjectMenuItem = ({
|
||||
/>
|
||||
) : (
|
||||
<CommandMenuItem
|
||||
Icon={({ size, stroke }) => (
|
||||
<IconWithBackground
|
||||
Icon={Icon}
|
||||
backgroundColor={iconColors.object}
|
||||
size={size}
|
||||
stroke={stroke}
|
||||
/>
|
||||
)}
|
||||
Icon={styledIcon}
|
||||
label={objectMetadataItem.labelPlural}
|
||||
id={objectMetadataItem.id}
|
||||
onClick={handleClick}
|
||||
disabled={isDisabled}
|
||||
description={isAlreadyInNavbar ? t`Already in navbar` : undefined}
|
||||
/>
|
||||
)}
|
||||
</SelectableListItem>
|
||||
|
||||
+7
-10
@@ -1,11 +1,10 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { CommandMenuObjectMenuItem } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuObjectMenuItem';
|
||||
import { IconWithBackground } from '@/navigation-menu-item/components/IconWithBackground';
|
||||
import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors';
|
||||
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 { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
|
||||
@@ -29,9 +28,7 @@ export const CommandMenuObjectPickerItem = ({
|
||||
objectMenuItemVariant = 'edit',
|
||||
dragIndex,
|
||||
}: CommandMenuObjectPickerItemProps) => {
|
||||
const theme = useTheme();
|
||||
const { getIcon } = useIcons();
|
||||
const iconColors = getNavigationMenuItemIconColors(theme);
|
||||
|
||||
if (isViewItem && isDefined(onSelectObjectForViewEdit)) {
|
||||
return (
|
||||
@@ -40,12 +37,12 @@ export const CommandMenuObjectPickerItem = ({
|
||||
onEnter={() => onSelectObjectForViewEdit(objectMetadataItem)}
|
||||
>
|
||||
<CommandMenuItem
|
||||
Icon={({ size, stroke }) => (
|
||||
<IconWithBackground
|
||||
Icon={() => (
|
||||
<NavigationMenuItemStyleIcon
|
||||
Icon={getIcon(objectMetadataItem.icon)}
|
||||
backgroundColor={iconColors.object}
|
||||
size={size}
|
||||
stroke={stroke}
|
||||
color={getStandardObjectIconColor(
|
||||
objectMetadataItem.nameSingular,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
label={objectMetadataItem.labelPlural}
|
||||
|
||||
+5
-4
@@ -9,6 +9,7 @@ import { CommandMenuList } from '@/command-menu/components/CommandMenuList';
|
||||
import { CommandMenuSubViewWithSearch } from '@/command-menu/components/CommandMenuSubViewWithSearch';
|
||||
import { useFilteredPickerItems } from '@/command-menu/hooks/useFilteredPickerItems';
|
||||
import { CommandMenuObjectPickerItem } from '@/command-menu/pages/navigation-menu-item/components/CommandMenuObjectPickerItem';
|
||||
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';
|
||||
|
||||
@@ -72,10 +73,10 @@ export const CommandMenuObjectPickerSubView = ({
|
||||
<CommandMenuAddToNavDraggablePlaceholder index={filteredItems.length}>
|
||||
<SelectableListItem itemId="system" onEnter={onOpenSystemPicker}>
|
||||
<CommandMenuItem
|
||||
Icon={IconSettings}
|
||||
Icon={() => <NavigationMenuItemStyleIcon Icon={IconSettings} />}
|
||||
label={t`System objects`}
|
||||
id="system"
|
||||
hasSubMenu={true}
|
||||
hasSubMenu
|
||||
onClick={onOpenSystemPicker}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
@@ -83,10 +84,10 @@ export const CommandMenuObjectPickerSubView = ({
|
||||
) : (
|
||||
<SelectableListItem itemId="system" onEnter={onOpenSystemPicker}>
|
||||
<CommandMenuItem
|
||||
Icon={IconSettings}
|
||||
Icon={() => <NavigationMenuItemStyleIcon Icon={IconSettings} />}
|
||||
label={t`System objects`}
|
||||
id="system"
|
||||
hasSubMenu={true}
|
||||
hasSubMenu
|
||||
onClick={onOpenSystemPicker}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import { NavigationMenuItemType } from '@/navigation-menu-item/constants/Navigat
|
||||
type FolderOption = {
|
||||
id: string;
|
||||
name: string;
|
||||
folderId?: string;
|
||||
folderId?: string | null;
|
||||
};
|
||||
|
||||
const getDescendantFolderIds = (
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconPlus } from 'twenty-ui/display';
|
||||
import { IconColumnInsertRight } from 'twenty-ui/display';
|
||||
|
||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||
import { useNavigateCommandMenu } from '@/command-menu/hooks/useNavigateCommandMenu';
|
||||
@@ -119,7 +119,7 @@ export const useNavigationMenuItemEditOrganizeActions =
|
||||
navigateCommandMenu({
|
||||
page: CommandMenuPages.NavigationMenuAddItem,
|
||||
pageTitle: t`New sidebar item`,
|
||||
pageIcon: IconPlus,
|
||||
pageIcon: IconColumnInsertRight,
|
||||
resetNavigationStack: true,
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user