mirror of
https://github.com/twentyhq/twenty.git
synced 2024-11-30 03:43:02 +03:00
Feat/open comment drawer from comment chip (#187)
* wip * Can open comment right drawer from company name cell
This commit is contained in:
parent
69c1095055
commit
a2fe159c2c
@ -16,6 +16,9 @@ const StyledContainer = styled.span`
|
||||
padding: ${(props) => props.theme.spacing(1)};
|
||||
gap: ${(props) => props.theme.spacing(1)};
|
||||
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
:hover {
|
||||
filter: brightness(95%);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { CommentChip, CommentChipProps } from './CommentChip';
|
||||
const StyledCellWrapper = styled.div`
|
||||
position: relative;
|
||||
right: 38px;
|
||||
top: -14px;
|
||||
top: -13px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
`;
|
||||
|
@ -3,7 +3,7 @@ import { IconComment } from '../icons';
|
||||
|
||||
export type CommentChipProps = {
|
||||
count: number;
|
||||
onClick?: () => void;
|
||||
onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
|
||||
};
|
||||
|
||||
const StyledChip = styled.div`
|
||||
|
@ -1,9 +1,13 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { RightDrawerBody } from '../../layout/right-drawer/RightDrawerBody';
|
||||
import { RightDrawerPage } from '../../layout/right-drawer/RightDrawerPage';
|
||||
import { RightDrawerTopBar } from '../../layout/right-drawer/RightDrawerTopBar';
|
||||
import { CommentTextInput } from './CommentTextInput';
|
||||
import { commentableEntityArrayState } from '../../modules/comments/states/commentableEntityArrayState';
|
||||
|
||||
export function RightDrawerComments() {
|
||||
const [commentableEntityArray] = useRecoilState(commentableEntityArrayState);
|
||||
|
||||
function handleSendComment(text: string) {
|
||||
console.log(text);
|
||||
}
|
||||
@ -12,6 +16,11 @@ export function RightDrawerComments() {
|
||||
<RightDrawerPage>
|
||||
<RightDrawerTopBar title="Comments" />
|
||||
<RightDrawerBody>
|
||||
{commentableEntityArray.map((commentableEntity) => (
|
||||
<div key={commentableEntity.id}>
|
||||
{commentableEntity.type} - {commentableEntity.id}
|
||||
</div>
|
||||
))}
|
||||
<CommentTextInput onSend={handleSendComment} />
|
||||
</RightDrawerBody>
|
||||
</RightDrawerPage>
|
||||
|
40
front/src/components/companies/CompanyEditableNameCell.tsx
Normal file
40
front/src/components/companies/CompanyEditableNameCell.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import { Company } from '../../interfaces/entities/company.interface';
|
||||
import { useOpenCommentRightDrawer } from '../../modules/comments/hooks/useOpenCommentRightDrawer';
|
||||
import { updateCompany } from '../../services/api/companies';
|
||||
import { getLogoUrlFromDomainName } from '../../services/utils';
|
||||
import CompanyChip from '../chips/CompanyChip';
|
||||
import EditableChip from '../editable-cell/EditableChip';
|
||||
|
||||
type OwnProps = {
|
||||
company: Company;
|
||||
};
|
||||
|
||||
export function CompanyEditableNameChipCell({ company }: OwnProps) {
|
||||
const openCommentRightDrawer = useOpenCommentRightDrawer();
|
||||
|
||||
function handleCommentClick() {
|
||||
openCommentRightDrawer([
|
||||
{
|
||||
type: 'Company',
|
||||
id: company.id,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
return (
|
||||
<EditableChip
|
||||
value={company.name || ''}
|
||||
placeholder="Name"
|
||||
picture={getLogoUrlFromDomainName(company.domainName)}
|
||||
changeHandler={(value: string) => {
|
||||
updateCompany({
|
||||
...company,
|
||||
name: value,
|
||||
});
|
||||
}}
|
||||
ChipComponent={CompanyChip}
|
||||
commentCount={12}
|
||||
onCommentClick={handleCommentClick}
|
||||
/>
|
||||
);
|
||||
}
|
@ -3,7 +3,7 @@ import styled from '@emotion/styled';
|
||||
export const CellNormalModeContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: calc(100% - ${(props) => props.theme.spacing(5)});
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
|
@ -47,7 +47,9 @@ export function EditableCell({
|
||||
onOutsideClick={onOutsideClick}
|
||||
/>
|
||||
) : (
|
||||
<CellNormalModeContainer>{nonEditModeContent}</CellNormalModeContainer>
|
||||
<CellNormalModeContainer>
|
||||
<>{nonEditModeContent}</>
|
||||
</CellNormalModeContainer>
|
||||
)}
|
||||
</CellBaseContainer>
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ import styled from '@emotion/styled';
|
||||
import { ChangeEvent, ComponentType, useRef, useState } from 'react';
|
||||
import { EditableCell } from './EditableCell';
|
||||
import { textInputStyle } from '../../layout/styles/themes';
|
||||
import { CellCommentChip } from '../comments/CellCommentChip';
|
||||
|
||||
export type EditableChipProps = {
|
||||
placeholder?: string;
|
||||
@ -10,6 +11,8 @@ export type EditableChipProps = {
|
||||
changeHandler: (updated: string) => void;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
ChipComponent: ComponentType<{ name: string; picture: string }>;
|
||||
commentCount?: number;
|
||||
onCommentClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
|
||||
};
|
||||
|
||||
// TODO: refactor
|
||||
@ -23,8 +26,7 @@ const StyledInplaceInput = styled.input`
|
||||
|
||||
const StyledInplaceShow = styled.div`
|
||||
display: flex;
|
||||
padding-left: ${(props) => props.theme.spacing(1)};
|
||||
padding-right: ${(props) => props.theme.spacing(1)};
|
||||
width: 100%;
|
||||
|
||||
&::placeholder {
|
||||
font-weight: 'bold';
|
||||
@ -39,11 +41,22 @@ function EditableChip({
|
||||
picture,
|
||||
editModeHorizontalAlign,
|
||||
ChipComponent,
|
||||
commentCount,
|
||||
onCommentClick,
|
||||
}: EditableChipProps) {
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const [inputValue, setInputValue] = useState(value);
|
||||
const [isEditMode, setIsEditMode] = useState(false);
|
||||
|
||||
const showComment = commentCount ? commentCount > 0 : false;
|
||||
|
||||
function handleCommentClick(event: React.MouseEvent<HTMLDivElement>) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
onCommentClick?.(event);
|
||||
}
|
||||
|
||||
return (
|
||||
<EditableCell
|
||||
onOutsideClick={() => setIsEditMode(false)}
|
||||
@ -63,9 +76,17 @@ function EditableChip({
|
||||
/>
|
||||
}
|
||||
nonEditModeContent={
|
||||
<StyledInplaceShow>
|
||||
<ChipComponent name={inputValue} picture={picture} />
|
||||
</StyledInplaceShow>
|
||||
<>
|
||||
<StyledInplaceShow>
|
||||
<ChipComponent name={inputValue} picture={picture} />
|
||||
</StyledInplaceShow>
|
||||
{showComment && (
|
||||
<CellCommentChip
|
||||
count={commentCount ?? 0}
|
||||
onClick={handleCommentClick}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
></EditableCell>
|
||||
);
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { useState } from 'react';
|
||||
import PersonChip from '../chips/PersonChip';
|
||||
import { EditableDoubleText } from '../editable-cell/EditableDoubleText';
|
||||
import { CellCommentChip } from '../comments/CellCommentChip';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
type OwnProps = {
|
||||
firstname: string;
|
||||
@ -8,6 +10,13 @@ type OwnProps = {
|
||||
onChange: (firstname: string, lastname: string) => void;
|
||||
};
|
||||
|
||||
const StyledDiv = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
export function EditablePeopleFullName({
|
||||
firstname,
|
||||
lastname,
|
||||
@ -26,6 +35,12 @@ export function EditablePeopleFullName({
|
||||
onChange(firstValue, secondValue);
|
||||
}
|
||||
|
||||
function handleCommentClick(event: React.MouseEvent<HTMLDivElement>) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
console.log('comment clicked');
|
||||
}
|
||||
|
||||
return (
|
||||
<EditableDoubleText
|
||||
firstValue={firstnameValue}
|
||||
@ -33,7 +48,14 @@ export function EditablePeopleFullName({
|
||||
firstValuePlaceholder="First name"
|
||||
secondValuePlaceholder="Last name"
|
||||
onChange={handleDoubleTextChange}
|
||||
nonEditModeContent={<PersonChip name={firstname + ' ' + lastname} />}
|
||||
nonEditModeContent={
|
||||
<>
|
||||
<StyledDiv>
|
||||
<PersonChip name={firstname + ' ' + lastname} />
|
||||
</StyledDiv>
|
||||
<CellCommentChip count={12} onClick={handleCommentClick} />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ import { EntityTableActionBarButton } from './EntityTableActionBarButton';
|
||||
import { useOpenRightDrawer } from '../../../modules/ui/layout/right-drawer/hooks/useOpenRightDrawer';
|
||||
|
||||
export function TableActionBarButtonToggleComments() {
|
||||
// TODO: here it would be nice to access the table context
|
||||
// But let's see when we have custom entities and properties
|
||||
const openRightDrawer = useOpenRightDrawer();
|
||||
|
||||
async function handleButtonClick() {
|
||||
|
@ -0,0 +1,18 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useOpenRightDrawer } from '../../ui/layout/right-drawer/hooks/useOpenRightDrawer';
|
||||
import { CommentableEntity } from '../types/CommentableEntity';
|
||||
import { commentableEntityArrayState } from '../states/commentableEntityArrayState';
|
||||
|
||||
export function useOpenCommentRightDrawer() {
|
||||
const openRightDrawer = useOpenRightDrawer();
|
||||
const [, setCommentableEntityArray] = useRecoilState(
|
||||
commentableEntityArrayState,
|
||||
);
|
||||
|
||||
return function openCommentRightDrawer(
|
||||
commentableEntityArray: CommentableEntity[],
|
||||
) {
|
||||
setCommentableEntityArray(commentableEntityArray);
|
||||
openRightDrawer('comments');
|
||||
};
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
import { atom } from 'recoil';
|
||||
import { CommentableEntity } from '../types/CommentableEntity';
|
||||
|
||||
export const commentableEntityArrayState = atom<CommentableEntity[]>({
|
||||
key: 'comments/commentable-entity-array',
|
||||
default: [],
|
||||
});
|
6
front/src/modules/comments/types/CommentableEntity.ts
Normal file
6
front/src/modules/comments/types/CommentableEntity.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { CommentableType } from '../../../generated/graphql';
|
||||
|
||||
export type CommentableEntity = {
|
||||
type: keyof typeof CommentableType;
|
||||
id: string;
|
||||
};
|
@ -12,12 +12,10 @@ import ColumnHead from '../../components/table/ColumnHead';
|
||||
import { SelectAllCheckbox } from '../../components/table/SelectAllCheckbox';
|
||||
import EditableDate from '../../components/editable-cell/EditableDate';
|
||||
import EditableRelation from '../../components/editable-cell/EditableRelation';
|
||||
import EditableChip from '../../components/editable-cell/EditableChip';
|
||||
import EditableText from '../../components/editable-cell/EditableText';
|
||||
import PersonChip, {
|
||||
PersonChipPropsType,
|
||||
} from '../../components/chips/PersonChip';
|
||||
import CompanyChip from '../../components/chips/CompanyChip';
|
||||
import {
|
||||
TbBuilding,
|
||||
TbCalendar,
|
||||
@ -27,8 +25,8 @@ import {
|
||||
TbUser,
|
||||
} from 'react-icons/tb';
|
||||
import { QueryMode } from '../../generated/graphql';
|
||||
import { getLogoUrlFromDomainName } from '../../services/utils';
|
||||
import { CheckboxCell } from '../../components/table/CheckboxCell';
|
||||
import { CompanyEditableNameChipCell } from '../../components/companies/CompanyEditableNameCell';
|
||||
|
||||
const columnHelper = createColumnHelper<Company>();
|
||||
|
||||
@ -59,17 +57,7 @@ export const useCompaniesColumns = () => {
|
||||
<ColumnHead viewName="Name" viewIcon={<TbBuilding size={16} />} />
|
||||
),
|
||||
cell: (props) => (
|
||||
<EditableChip
|
||||
value={props.row.original.name || ''}
|
||||
placeholder="Name"
|
||||
picture={getLogoUrlFromDomainName(props.row.original.domainName)}
|
||||
changeHandler={(value: string) => {
|
||||
const company = props.row.original;
|
||||
company.name = value;
|
||||
updateCompany(company);
|
||||
}}
|
||||
ChipComponent={CompanyChip}
|
||||
/>
|
||||
<CompanyEditableNameChipCell company={props.row.original} />
|
||||
),
|
||||
size: 120,
|
||||
}),
|
||||
|
@ -49,16 +49,18 @@ export const usePeopleColumns = () => {
|
||||
<ColumnHead viewName="People" viewIcon={<TbUser size={16} />} />
|
||||
),
|
||||
cell: (props) => (
|
||||
<EditablePeopleFullName
|
||||
firstname={props.row.original.firstname || ''}
|
||||
lastname={props.row.original.lastname || ''}
|
||||
onChange={async (firstName: string, lastName: string) => {
|
||||
const person = props.row.original;
|
||||
person.firstname = firstName;
|
||||
person.lastname = lastName;
|
||||
await updatePerson(person);
|
||||
}}
|
||||
/>
|
||||
<>
|
||||
<EditablePeopleFullName
|
||||
firstname={props.row.original.firstname || ''}
|
||||
lastname={props.row.original.lastname || ''}
|
||||
onChange={async (firstName: string, lastName: string) => {
|
||||
const person = props.row.original;
|
||||
person.firstname = firstName;
|
||||
person.lastname = lastName;
|
||||
await updatePerson(person);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
size: 210,
|
||||
}),
|
||||
|
Loading…
Reference in New Issue
Block a user