diff --git a/front/src/modules/activities/components/TaskList.tsx b/front/src/modules/activities/components/TaskList.tsx index f2503273e..8d97f0d0f 100644 --- a/front/src/modules/activities/components/TaskList.tsx +++ b/front/src/modules/activities/components/TaskList.tsx @@ -20,6 +20,7 @@ const StyledContainer = styled.div` const StyledTitle = styled.h3` color: ${({ theme }) => theme.font.color.primary}; + font-weight: ${({ theme }) => theme.font.weight.semiBold}; margin-bottom: ${({ theme }) => theme.spacing(4)}; margin-top: ${({ theme }) => theme.spacing(4)}; `; diff --git a/front/src/modules/companies/components/CompanyTeam.tsx b/front/src/modules/companies/components/CompanyTeam.tsx index a65d7e081..ded54eddd 100644 --- a/front/src/modules/companies/components/CompanyTeam.tsx +++ b/front/src/modules/companies/components/CompanyTeam.tsx @@ -63,8 +63,12 @@ export function CompanyTeam({ company }: CompanyTeamPropsType) { Team - {data?.people?.map((person) => ( - + {data?.people?.map((person, id) => ( + ))} diff --git a/front/src/modules/favorites/components/Favorites.tsx b/front/src/modules/favorites/components/Favorites.tsx index 40c46eb62..a2da7c1b9 100644 --- a/front/src/modules/favorites/components/Favorites.tsx +++ b/front/src/modules/favorites/components/Favorites.tsx @@ -31,6 +31,7 @@ export function Favorites() { icon={ ; + hasBottomBorder?: boolean; }; -const StyledCard = styled.div` +const StyledCard = styled.div<{ hasBottomBorder: boolean }>` align-items: center; align-self: stretch; - border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; + border-bottom: 1px solid + ${({ theme, hasBottomBorder }) => + hasBottomBorder ? theme.border.color.light : 'transparent'}; display: flex; gap: ${({ theme }) => theme.spacing(2)}; height: ${({ theme }) => theme.spacing(8)}; @@ -49,10 +52,16 @@ const StyledJobTitle = styled.div` } `; -export function PeopleCard({ person }: PeopleCardPropsType) { +export function PeopleCard({ + person, + hasBottomBorder = true, +}: PeopleCardProps) { const navigate = useNavigate(); return ( - navigate(`/person/${person.id}`)}> + navigate(`/person/${person.id}`)} + hasBottomBorder={hasBottomBorder} + > {person.displayName} - {person.jobTitle ?? 'Add job title'} + {person.jobTitle && {person.jobTitle}} ); diff --git a/front/src/modules/people/constants/peopleViewFields.tsx b/front/src/modules/people/constants/peopleViewFields.tsx index 8fb872b82..fa539e845 100644 --- a/front/src/modules/people/constants/peopleViewFields.tsx +++ b/front/src/modules/people/constants/peopleViewFields.tsx @@ -123,7 +123,7 @@ export const peopleViewFields: ViewFieldDefinition[] = [ } satisfies ViewFieldDefinition, { id: 'x', - columnLabel: 'X', + columnLabel: 'Twitter', columnIcon: , columnSize: 150, columnOrder: 9, diff --git a/front/src/modules/people/editable-field/components/PeopleFullNameEditableField.tsx b/front/src/modules/people/editable-field/components/PeopleFullNameEditableField.tsx index 03292a566..28da420d1 100644 --- a/front/src/modules/people/editable-field/components/PeopleFullNameEditableField.tsx +++ b/front/src/modules/people/editable-field/components/PeopleFullNameEditableField.tsx @@ -48,8 +48,8 @@ export function PeopleFullNameEditableField({ people }: OwnProps) { return ( { if ( - /^(http|https):\/\/(?:www\.)?linkedin.com(\w+:{0,1}\w*@)?(\S+)(:([0-9])+)?(\/|\/([\w#!:.?+=&%@!\-/]))?$/.test( + /^(http|https):\/\/(?:www\.)?linkedin.com(\w+:{0,1}\w*@)?(\S+)(:([0-9])+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/.test( url, ) ) { return LinkType.LinkedIn; } - if (url.match(/^((http|https):\/\/)?(?:www\.)?twitter\.com\/(\w+)?$/i)) { + if (url.match(/^((http|https):\/\/)?(?:www\.)?twitter\.com\/(\w+)?/i)) { return LinkType.Twitter; } diff --git a/front/src/modules/ui/link/components/RoundedLink.tsx b/front/src/modules/ui/link/components/RoundedLink.tsx index 9e5a251c7..f9fa32851 100644 --- a/front/src/modules/ui/link/components/RoundedLink.tsx +++ b/front/src/modules/ui/link/components/RoundedLink.tsx @@ -30,7 +30,7 @@ export function RoundedLink({ children, href, onClick }: OwnProps) { diff --git a/front/src/modules/ui/table/editable-cell/components/EditableCell.tsx b/front/src/modules/ui/table/editable-cell/components/EditableCell.tsx index 1f41b6bd6..1c93f0584 100644 --- a/front/src/modules/ui/table/editable-cell/components/EditableCell.tsx +++ b/front/src/modules/ui/table/editable-cell/components/EditableCell.tsx @@ -9,7 +9,9 @@ import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope'; import { CellHotkeyScopeContext } from '../../states/CellHotkeyScopeContext'; import { TableHotkeyScope } from '../../types/TableHotkeyScope'; import { useCurrentCellEditMode } from '../hooks/useCurrentCellEditMode'; +import { useEditableCell } from '../hooks/useEditableCell'; import { useIsSoftFocusOnCurrentCell } from '../hooks/useIsSoftFocusOnCurrentCell'; +import { useSetSoftFocusOnCurrentCell } from '../hooks/useSetSoftFocusOnCurrentCell'; import { EditableCellDisplayMode } from './EditableCellDisplayMode'; import { EditableCellEditMode } from './EditableCellEditMode'; @@ -39,6 +41,7 @@ type OwnProps = { editHotkeyScope?: HotkeyScope; transparent?: boolean; maxContentWidth?: number; + useEditButton?: boolean; onSubmit?: () => void; onCancel?: () => void; }; @@ -55,27 +58,19 @@ export function EditableCell({ editHotkeyScope, transparent = false, maxContentWidth, + useEditButton, }: OwnProps) { - const { isCurrentCellInEditMode, setCurrentCellInEditMode } = - useCurrentCellEditMode(); + const { isCurrentCellInEditMode } = useCurrentCellEditMode(); const [isHovered, setIsHovered] = useState(false); - function isValidUrl(value: string) { - let testUrl = value; - if (testUrl && !testUrl.startsWith('http')) { - testUrl = 'http://' + testUrl; - } - try { - new URL(testUrl); - return true; - } catch (err) { - return false; - } - } + const setSoftFocusOnCurrentCell = useSetSoftFocusOnCurrentCell(); - const handleClick = () => { - setCurrentCellInEditMode(); - }; + const { openEditableCell } = useEditableCell(); + + function handlePenClick() { + setSoftFocusOnCurrentCell(); + openEditableCell(); + } function handleContainerMouseEnter() { setIsHovered(true); @@ -85,9 +80,7 @@ export function EditableCell({ setIsHovered(false); } - const value = nonEditModeContent.props.value; - const showEditButton = - !isCurrentCellInEditMode && isValidUrl(value) && isHovered; + const showEditButton = useEditButton && isHovered && !isCurrentCellInEditMode; const hasSoftFocus = useIsSoftFocusOnCurrentCell(); @@ -124,7 +117,7 @@ export function EditableCell({ } /> diff --git a/front/src/modules/ui/table/editable-cell/components/EditableCellEditMode.tsx b/front/src/modules/ui/table/editable-cell/components/EditableCellEditMode.tsx index 3bb37c9d1..8d6501f1c 100644 --- a/front/src/modules/ui/table/editable-cell/components/EditableCellEditMode.tsx +++ b/front/src/modules/ui/table/editable-cell/components/EditableCellEditMode.tsx @@ -16,9 +16,9 @@ export const EditableCellEditModeContainer = styled.div` margin-top: -1px; max-width: ${({ maxContentWidth }) => - maxContentWidth ? `${maxContentWidth}px` : 'auto'}; + maxContentWidth ? `${maxContentWidth}px` : 'none'}; min-height: 100%; - min-width: 100%; + min-width: ${({ maxContentWidth }) => (maxContentWidth ? `none` : '100%')}; position: absolute; right: ${(props) => diff --git a/front/src/modules/ui/table/editable-cell/type/components/GenericEditableRelationCell.tsx b/front/src/modules/ui/table/editable-cell/type/components/GenericEditableRelationCell.tsx index 97d0906d6..a3a3dbe9a 100644 --- a/front/src/modules/ui/table/editable-cell/type/components/GenericEditableRelationCell.tsx +++ b/front/src/modules/ui/table/editable-cell/type/components/GenericEditableRelationCell.tsx @@ -21,6 +21,7 @@ export function GenericEditableRelationCell({ }: OwnProps) { return ( } nonEditModeContent={ diff --git a/front/src/utils/__tests__/is-domain.test.ts b/front/src/utils/__tests__/is-domain.test.ts new file mode 100644 index 000000000..d77a9ddca --- /dev/null +++ b/front/src/utils/__tests__/is-domain.test.ts @@ -0,0 +1,35 @@ +import { isDomain } from '~/utils/is-domain'; + +describe('isDomain', () => { + it(`should return false if null`, () => { + expect(isDomain(null)).toBeFalsy(); + }); + + it(`should return false if undefined`, () => { + expect(isDomain(undefined)).toBeFalsy(); + }); + + it(`should return true if string google`, () => { + expect(isDomain('google')).toBeFalsy(); + }); + + it(`should return true if string google.com`, () => { + expect(isDomain('google.com')).toBeTruthy(); + }); + + it(`should return true if string bbc.co.uk`, () => { + expect(isDomain('bbc.co.uk')).toBeTruthy(); + }); + + it(`should return true if string web.io`, () => { + expect(isDomain('web.io')).toBeTruthy(); + }); + + it(`should return true if string x.com`, () => { + expect(isDomain('x.com')).toBeTruthy(); + }); + + it(`should return true if string 2.com`, () => { + expect(isDomain('2.com')).toBeTruthy(); + }); +}); diff --git a/front/src/utils/__tests__/is-url.test.ts b/front/src/utils/__tests__/is-url.test.ts index 2ee1e5429..a5ec5081c 100644 --- a/front/src/utils/__tests__/is-url.test.ts +++ b/front/src/utils/__tests__/is-url.test.ts @@ -32,4 +32,12 @@ describe('isURL', () => { it(`should return true if string 2.com`, () => { expect(isURL('2.com')).toBeTruthy(); }); + + it(`should return true if string https://2.com/test/`, () => { + expect(isURL('https://2.com/test/')).toBeTruthy(); + }); + + it(`should return false if string https://2.com/test/sldkfj!?`, () => { + expect(isURL('https://2.com/test/sldkfj!?')).toBeFalsy(); + }); }); diff --git a/front/src/utils/is-domain.ts b/front/src/utils/is-domain.ts new file mode 100644 index 000000000..000aea90a --- /dev/null +++ b/front/src/utils/is-domain.ts @@ -0,0 +1,10 @@ +import { isDefined } from './isDefined'; + +export function isDomain(url: string | undefined | null) { + return ( + isDefined(url) && + /^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$/.test( + url, + ) + ); +} diff --git a/front/src/utils/is-url.ts b/front/src/utils/is-url.ts index b6c1f01d5..c43b41870 100644 --- a/front/src/utils/is-url.ts +++ b/front/src/utils/is-url.ts @@ -1,10 +1,14 @@ import { isDefined } from './isDefined'; export function isURL(url: string | undefined | null) { - return ( - isDefined(url) && - /^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$/.test( - url, - ) + const pattern = new RegExp( + '^(https?:\\/\\/)?' + + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + + '((\\d{1,3}\\.){3}\\d{1,3}))' + + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + + '(\\?[;&a-z\\d%_.~+=-]*)?' + + '(\\#[-a-z\\d_]*)?$', + 'i', ); + return isDefined(url) && !!pattern.test(url); }