Navbar customization improvements (#17863)
- Add folder icon editing support - And other navbar customization fixes/improvements. --------- 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: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
+37
-15
@@ -1,24 +1,32 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { IconFolder } from 'twenty-ui/display';
|
||||
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 { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { StyledNavigationMenuItemIconContainer } from '@/navigation-menu-item/components/NavigationMenuItemIconContainer';
|
||||
import { useUpdateFolderNameInDraft } from '@/navigation-menu-item/hooks/useUpdateFolderNameInDraft';
|
||||
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 { selectedNavigationMenuItemInEditModeStateV2 } from '@/navigation-menu-item/states/selectedNavigationMenuItemInEditModeStateV2';
|
||||
import { useRecoilValueV2 } from '@/ui/utilities/state/jotai/hooks/useRecoilValueV2';
|
||||
import { getNavigationMenuItemIconColors } from '@/navigation-menu-item/utils/getNavigationMenuItemIconColors';
|
||||
import { IconPicker } from '@/ui/input/components/IconPicker';
|
||||
import { TitleInput } from '@/ui/input/components/TitleInput';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
|
||||
const StyledClickableIconWrapper = styled.div`
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
export const CommandMenuFolderInfo = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useLingui();
|
||||
const { getIcon } = useIcons();
|
||||
const commandMenuPageInfo = useRecoilValue(commandMenuPageInfoState);
|
||||
const [shouldFocusTitleInput, setShouldFocusTitleInput] =
|
||||
useRecoilComponentState(
|
||||
@@ -29,7 +37,7 @@ export const CommandMenuFolderInfo = () => {
|
||||
selectedNavigationMenuItemInEditModeStateV2,
|
||||
);
|
||||
const items = useWorkspaceSectionItems();
|
||||
const { updateFolderNameInDraft } = useUpdateFolderNameInDraft();
|
||||
const { updateFolderInDraft } = useUpdateFolderInDraft();
|
||||
|
||||
const defaultLabel = t`New folder`;
|
||||
const placeholder = t`Folder name`;
|
||||
@@ -48,7 +56,7 @@ export const CommandMenuFolderInfo = () => {
|
||||
const itemName = selectedItem.name ?? defaultLabel;
|
||||
|
||||
const handleChange = (text: string) => {
|
||||
updateFolderNameInDraft(itemId, text);
|
||||
updateFolderInDraft(itemId, { name: text });
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
@@ -56,22 +64,36 @@ export const CommandMenuFolderInfo = () => {
|
||||
const finalName = trimmed.length > 0 ? trimmed : defaultLabel;
|
||||
|
||||
if (finalName !== itemName) {
|
||||
updateFolderNameInDraft(itemId, finalName);
|
||||
updateFolderInDraft(itemId, { name: finalName });
|
||||
}
|
||||
};
|
||||
|
||||
const selectedIconKey = selectedItem.icon ?? FOLDER_ICON_DEFAULT;
|
||||
const FolderIconComponent = getIcon(selectedIconKey);
|
||||
|
||||
return (
|
||||
<CommandMenuPageInfoLayout
|
||||
icon={
|
||||
<StyledNavigationMenuItemIconContainer
|
||||
$backgroundColor={getNavigationMenuItemIconColors(theme).folder}
|
||||
>
|
||||
<IconFolder
|
||||
size={theme.spacing(3.5)}
|
||||
color={theme.grayScale.gray1}
|
||||
stroke={theme.icon.stroke.md}
|
||||
/>
|
||||
</StyledNavigationMenuItemIconContainer>
|
||||
<IconPicker
|
||||
dropdownId="command-menu-folder-icon-picker"
|
||||
selectedIconKey={selectedIconKey}
|
||||
onChange={({ iconKey }) =>
|
||||
updateFolderInDraft(itemId, { icon: iconKey })
|
||||
}
|
||||
clickableComponent={
|
||||
<StyledClickableIconWrapper>
|
||||
<StyledNavigationMenuItemIconContainer
|
||||
$backgroundColor={getNavigationMenuItemIconColors(theme).folder}
|
||||
>
|
||||
<FolderIconComponent
|
||||
size={theme.spacing(3.5)}
|
||||
color={theme.grayScale.gray1}
|
||||
stroke={theme.icon.stroke.md}
|
||||
/>
|
||||
</StyledNavigationMenuItemIconContainer>
|
||||
</StyledClickableIconWrapper>
|
||||
}
|
||||
/>
|
||||
}
|
||||
title={
|
||||
<TitleInput
|
||||
|
||||
+10
-10
@@ -3,10 +3,9 @@ import { OverflowingTextWithTooltip } from 'twenty-ui/display';
|
||||
|
||||
import { CommandMenuPageInfoLayout } from '@/command-menu/components/CommandMenuPageInfoLayout';
|
||||
import { NavigationMenuItemIcon } from '@/navigation-menu-item/components/NavigationMenuItemIcon';
|
||||
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 { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { ViewKey } from '@/views/types/ViewKey';
|
||||
|
||||
export const CommandMenuObjectViewRecordInfo = () => {
|
||||
const { t } = useLingui();
|
||||
@@ -22,19 +21,20 @@ export const CommandMenuObjectViewRecordInfo = () => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isViewOrRecord =
|
||||
processedItem.itemType === NavigationMenuItemType.VIEW ||
|
||||
processedItem.itemType === NavigationMenuItemType.RECORD;
|
||||
const isViewOrRecord = [
|
||||
NavigationMenuItemType.VIEW,
|
||||
NavigationMenuItemType.RECORD,
|
||||
].includes(processedItem.itemType);
|
||||
|
||||
if (!isViewOrRecord) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label =
|
||||
processedItem.itemType === NavigationMenuItemType.RECORD
|
||||
const label = isViewOrRecord
|
||||
? processedItem.itemType === NavigationMenuItemType.RECORD
|
||||
? t`record`
|
||||
: processedItem.viewKey === ViewKey.Index
|
||||
? t`object`
|
||||
: t`view`;
|
||||
: t`view`
|
||||
: t`object`;
|
||||
|
||||
return (
|
||||
<CommandMenuPageInfoLayout
|
||||
|
||||
+16
-1
@@ -10,6 +10,7 @@ import { CommandMenuSubViewWithSearch } from '@/command-menu/components/CommandM
|
||||
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 { useNavigationMenuObjectMetadataFromDraft } from '@/navigation-menu-item/hooks/useNavigationMenuObjectMetadataFromDraft';
|
||||
@@ -110,7 +111,21 @@ export const CommandMenuNewSidebarItemViewPickerSubView = ({
|
||||
onEnter={() => handleSelectView(view)}
|
||||
>
|
||||
<CommandMenuItemWithAddToNavigationDrag
|
||||
icon={getIcon(view.icon)}
|
||||
customIconContent={
|
||||
selectedObjectMetadataItem ? (
|
||||
<ObjectIconWithViewOverlay
|
||||
ObjectIcon={getIcon(
|
||||
selectedObjectMetadataItem.icon,
|
||||
)}
|
||||
ViewIcon={getIcon(view.icon)}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
icon={
|
||||
selectedObjectMetadataItem
|
||||
? undefined
|
||||
: getIcon(view.icon)
|
||||
}
|
||||
label={view.name}
|
||||
id={view.id}
|
||||
onClick={() => handleSelectView(view)}
|
||||
|
||||
Reference in New Issue
Block a user