feat: set primary link in Links field (#5429)
Closes #5375 <img width="381" alt="image" src="https://github.com/twentyhq/twenty/assets/3098428/d87773df-c685-466b-ae35-a8349f79df48"> _____ ~~Note that I ugraded `@apollo/client` to v3.10.4 because current version is causing an error when trying to write the Links field in the cache in `updateRecordFromCache` (`TypeError: Cannot convert object to primitive value`). After upgrade, the error is gone but console still prints a warning (here the custom object name is `Listing` and the Links field name is `website`):~~ <img width="964" alt="image" src="https://github.com/twentyhq/twenty/assets/3098428/834b8909-e8dc-464a-8c5a-6b7e4c964a7f"> ~~It might be because the Links field seems to somehow have a `__typename` property in Apollo's cache, so Apollo considers it as a record and tries to match the object's cache with an id, but the Links field value has no id so it can't find it. We might want to find where this `__typename` is added and remove it from the Links object in the cache.~~ Edit: will fix this in another PR as upgrading `@apollo/client` + `apollo-upload-client` seems to break types and/or tests. Related issue: [#5437](https://github.com/twentyhq/twenty/issues/5437)
This commit is contained in:
@ -14,6 +14,7 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { moveArrayItem } from '~/utils/array/moveArrayItem';
|
||||
import { toSpliced } from '~/utils/array/toSpliced';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
@ -86,6 +87,19 @@ export const LinksFieldInput = ({
|
||||
);
|
||||
};
|
||||
|
||||
const handleSetPrimaryLink = (index: number) => {
|
||||
const nextLinks = moveArrayItem(links, { fromIndex: index, toIndex: 0 });
|
||||
const [nextPrimaryLink, ...nextSecondaryLinks] = nextLinks;
|
||||
|
||||
onSubmit?.(() =>
|
||||
persistLinksField({
|
||||
primaryLinkUrl: nextPrimaryLink.url ?? '',
|
||||
primaryLinkLabel: nextPrimaryLink.label ?? '',
|
||||
secondaryLinks: nextSecondaryLinks,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const handleDeleteLink = (index: number) => {
|
||||
onSubmit?.(() =>
|
||||
persistLinksField({
|
||||
@ -110,6 +124,7 @@ export const LinksFieldInput = ({
|
||||
dropdownId={`${hotkeyScope}-links-${index}`}
|
||||
isPrimary={index === 0}
|
||||
label={label}
|
||||
onSetAsPrimary={() => handleSetPrimaryLink(index)}
|
||||
onDelete={() => handleDeleteLink(index)}
|
||||
url={url}
|
||||
/>
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import { useEffect } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import {
|
||||
IconBookmark,
|
||||
IconBookmarkPlus,
|
||||
IconComponent,
|
||||
IconDotsVertical,
|
||||
IconTrash,
|
||||
@ -16,6 +18,7 @@ type LinksFieldMenuItemProps = {
|
||||
dropdownId: string;
|
||||
isPrimary?: boolean;
|
||||
label: string;
|
||||
onSetAsPrimary: () => void;
|
||||
onDelete: () => void;
|
||||
url: string;
|
||||
};
|
||||
@ -30,10 +33,18 @@ export const LinksFieldMenuItem = ({
|
||||
dropdownId,
|
||||
isPrimary,
|
||||
label,
|
||||
onSetAsPrimary,
|
||||
onDelete,
|
||||
url,
|
||||
}: LinksFieldMenuItemProps) => {
|
||||
const { isDropdownOpen } = useDropdown(dropdownId);
|
||||
const { isDropdownOpen, closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
// Make sure dropdown closes on unmount.
|
||||
useEffect(() => {
|
||||
if (isDropdownOpen) {
|
||||
return () => closeDropdown();
|
||||
}
|
||||
}, [closeDropdown, isDropdownOpen]);
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
@ -55,6 +66,11 @@ export const LinksFieldMenuItem = ({
|
||||
clickableComponent={iconButton}
|
||||
dropdownComponents={
|
||||
<DropdownMenuItemsContainer>
|
||||
<MenuItem
|
||||
LeftIcon={IconBookmarkPlus}
|
||||
text="Set as Primary"
|
||||
onClick={onSetAsPrimary}
|
||||
/>
|
||||
<MenuItem
|
||||
accent="danger"
|
||||
LeftIcon={IconTrash}
|
||||
|
||||
@ -20,6 +20,7 @@ export {
|
||||
IconBolt,
|
||||
IconBook2,
|
||||
IconBookmark,
|
||||
IconBookmarkPlus,
|
||||
IconBox,
|
||||
IconBrandGithub,
|
||||
IconBrandGoogle,
|
||||
|
||||
Reference in New Issue
Block a user