diff --git a/front/src/__tests__/App.test.tsx b/front/src/__tests__/App.test.tsx
index d88a1017c..ca2633903 100644
--- a/front/src/__tests__/App.test.tsx
+++ b/front/src/__tests__/App.test.tsx
@@ -10,7 +10,6 @@ it('Checks the App component renders', async () => {
const { getByText } = render();
expect(getByText('Companies')).toBeDefined();
- expect(getByText('Opportunities')).toBeDefined();
await waitFor(() => {
expect(getByText('Twenty')).toBeDefined();
});
diff --git a/front/src/components/chips/PersonChip.tsx b/front/src/components/chips/PersonChip.tsx
index 963c6db1e..b037315dc 100644
--- a/front/src/components/chips/PersonChip.tsx
+++ b/front/src/components/chips/PersonChip.tsx
@@ -2,7 +2,7 @@ import * as React from 'react';
import styled from '@emotion/styled';
import PersonPlaceholder from './person-placeholder.png';
-type OwnProps = {
+export type PersonChipPropsType = {
name: string;
picture?: string;
};
@@ -28,7 +28,7 @@ const StyledContainer = styled.span`
}
`;
-function PersonChip({ name, picture }: OwnProps) {
+function PersonChip({ name, picture }: PersonChipPropsType) {
return (
}
- nonEditModeContent={}
+ nonEditModeContent={}
>
);
}
diff --git a/front/src/components/table/editable-cell/EditableRelation.tsx b/front/src/components/table/editable-cell/EditableRelation.tsx
index e93361189..794efd8f0 100644
--- a/front/src/components/table/editable-cell/EditableRelation.tsx
+++ b/front/src/components/table/editable-cell/EditableRelation.tsx
@@ -49,7 +49,7 @@ const StyledEditModeResultItem = styled.div`
`;
export type EditableRelationProps = {
- relation: RelationType;
+ relation?: RelationType;
searchPlaceholder: string;
searchFilter: FilterType;
changeHandler: (relation: RelationType) => void;
diff --git a/front/src/components/table/table-header/TableHeader.tsx b/front/src/components/table/table-header/TableHeader.tsx
index 6b6766818..9805dbb9d 100644
--- a/front/src/components/table/table-header/TableHeader.tsx
+++ b/front/src/components/table/table-header/TableHeader.tsx
@@ -1,5 +1,4 @@
import styled from '@emotion/styled';
-import DropdownButton from './DropdownButton';
import {
FilterType,
SelectedFilterType,
@@ -147,8 +146,6 @@ function TableHeader({
availableSorts={availableSorts || []}
onSortSelect={sortSelect}
/>
-
-
{sorts.length + filters.length > 0 && (
diff --git a/front/src/interfaces/user.interface.ts b/front/src/interfaces/user.interface.ts
index e64498cca..aaed906bd 100644
--- a/front/src/interfaces/user.interface.ts
+++ b/front/src/interfaces/user.interface.ts
@@ -18,6 +18,9 @@ export interface User {
workspace_member?: WorkspaceMember;
}
+export type PartialUser = Partial &
+ Pick;
+
export const mapUser = (user: GraphqlQueryUser): User => {
const mappedUser = {
id: user.id,
diff --git a/front/src/layout/navbar/Navbar.tsx b/front/src/layout/navbar/Navbar.tsx
index 10939c9b0..fbcf3e7d4 100644
--- a/front/src/layout/navbar/Navbar.tsx
+++ b/front/src/layout/navbar/Navbar.tsx
@@ -5,7 +5,7 @@ import { Workspace } from '../../interfaces/workspace.interface';
import NavItem from './NavItem';
import NavTitle from './NavTitle';
import WorkspaceContainer from './WorkspaceContainer';
-import { FaRegUser, FaRegBuilding, FaBullseye } from 'react-icons/fa';
+import { FaRegUser, FaRegBuilding } from 'react-icons/fa';
const NavbarContainer = styled.div`
display: flex;
@@ -55,17 +55,6 @@ function Navbar({ workspace }: OwnProps) {
})
}
/>
- }
- active={
- !!useMatch({
- path: useResolvedPath('/opportunities').pathname,
- end: true,
- })
- }
- />
>
diff --git a/front/src/pages/companies/__tests__/Companies.test.tsx b/front/src/pages/companies/__tests__/Companies.test.tsx
index c6f735c24..0a574fa42 100644
--- a/front/src/pages/companies/__tests__/Companies.test.tsx
+++ b/front/src/pages/companies/__tests__/Companies.test.tsx
@@ -1,15 +1,117 @@
-import { render, waitFor } from '@testing-library/react';
+import { fireEvent, render, waitFor } from '@testing-library/react';
import { CompaniesDefault } from '../__stories__/Companies.stories';
+import { act } from 'react-dom/test-utils';
+import {
+ GraphqlMutationCompany,
+ GraphqlQueryCompany,
+} from '../../../interfaces/company.interface';
-it('Checks the Companies page render', async () => {
- const { getByTestId } = render();
+jest.mock('../../../apollo', () => {
+ const companyInterface = jest.requireActual(
+ '../../../interfaces/company.interface',
+ );
+ return {
+ apiClient: {
+ mutate: (arg: {
+ mutation: unknown;
+ variables: GraphqlMutationCompany;
+ }) => {
+ const gqlCompany = arg.variables as unknown as GraphqlQueryCompany;
+ return { data: companyInterface.mapCompany(gqlCompany) };
+ },
+ },
+ };
+});
- const title = getByTestId('top-bar-title');
- expect(title).toHaveTextContent('Companies');
+it('Checks company name edit is updating data', async () => {
+ const { getByText, getByDisplayValue } = render();
await waitFor(() => {
- const row = getByTestId('row-id-0');
- expect(row).toBeDefined();
+ expect(getByText('Airbnb')).toBeDefined();
+ });
+
+ act(() => {
+ fireEvent.click(getByText('Airbnb'));
+ });
+
+ await waitFor(() => {
+ expect(getByDisplayValue('Airbnb')).toBeInTheDocument();
+ });
+
+ act(() => {
+ const nameInput = getByDisplayValue('Airbnb');
+
+ if (!nameInput) {
+ throw new Error('nameInput is null');
+ }
+ fireEvent.change(nameInput, { target: { value: 'Airbnbb' } });
+ fireEvent.click(getByText('All Companies')); // Click outside
+ });
+
+ await waitFor(() => {
+ expect(getByText('Airbnbb')).toBeDefined();
+ });
+});
+
+it('Checks company url edit is updating data', async () => {
+ const { getByText, getByDisplayValue } = render();
+
+ await waitFor(() => {
+ expect(getByText('airbnb.com')).toBeDefined();
+ });
+
+ act(() => {
+ fireEvent.click(getByText('airbnb.com'));
+ });
+
+ await waitFor(() => {
+ expect(getByDisplayValue('airbnb.com')).toBeInTheDocument();
+ });
+
+ act(() => {
+ const urlInput = getByDisplayValue('airbnb.com');
+
+ if (!urlInput) {
+ throw new Error('urlInput is null');
+ }
+ fireEvent.change(urlInput, { target: { value: 'airbnb.co' } });
+ fireEvent.click(getByText('All Companies')); // Click outside
+ });
+
+ await waitFor(() => {
+ expect(getByText('airbnb.co')).toBeInTheDocument();
+ });
+});
+
+it('Checks company address edit is updating data', async () => {
+ const { getByText, getByDisplayValue } = render();
+
+ await waitFor(() => {
+ expect(getByText('17 rue de clignancourt')).toBeDefined();
+ });
+
+ act(() => {
+ fireEvent.click(getByText('17 rue de clignancourt'));
+ });
+
+ await waitFor(() => {
+ expect(getByDisplayValue('17 rue de clignancourt')).toBeInTheDocument();
+ });
+
+ act(() => {
+ const addressInput = getByDisplayValue('17 rue de clignancourt');
+
+ if (!addressInput) {
+ throw new Error('addressInput is null');
+ }
+ fireEvent.change(addressInput, {
+ target: { value: '21 rue de clignancourt' },
+ });
+ fireEvent.click(getByText('All Companies')); // Click outside
+ });
+
+ await waitFor(() => {
+ expect(getByText('21 rue de clignancourt')).toBeInTheDocument();
});
});
diff --git a/front/src/pages/companies/companies-table.tsx b/front/src/pages/companies/companies-table.tsx
index 2b2771d75..888760320 100644
--- a/front/src/pages/companies/companies-table.tsx
+++ b/front/src/pages/companies/companies-table.tsx
@@ -8,19 +8,19 @@ import ColumnHead from '../../components/table/ColumnHead';
import Checkbox from '../../components/form/Checkbox';
import CompanyChip from '../../components/chips/CompanyChip';
import EditableText from '../../components/table/editable-cell/EditableText';
-import PipeChip from '../../components/chips/PipeChip';
import {
FaRegBuilding,
FaCalendar,
FaLink,
FaMapPin,
- FaStream,
FaRegUser,
FaUsers,
FaBuilding,
+ FaUser,
} from 'react-icons/fa';
-import ClickableCell from '../../components/table/ClickableCell';
-import PersonChip from '../../components/chips/PersonChip';
+import PersonChip, {
+ PersonChipPropsType,
+} from '../../components/chips/PersonChip';
import EditableChip from '../../components/table/editable-cell/EditableChip';
import {
FilterType,
@@ -29,8 +29,15 @@ import {
import {
Companies_Bool_Exp,
Companies_Order_By,
+ Users_Bool_Exp,
} from '../../generated/graphql';
-import { SEARCH_COMPANY_QUERY } from '../../services/search/search';
+import {
+ SEARCH_COMPANY_QUERY,
+ SEARCH_USER_QUERY,
+} from '../../services/search/search';
+import EditableDate from '../../components/table/editable-cell/EditableDate';
+import EditableRelation from '../../components/table/editable-cell/EditableRelation';
+import { GraphqlQueryUser, PartialUser } from '../../interfaces/user.interface';
export const availableSorts = [
{
@@ -151,7 +158,7 @@ export const companiesColumns = [
changeHandler={(value: string) => {
const company = props.row.original;
company.name = value;
- updateCompany(company).catch((error) => console.error(error));
+ updateCompany(company);
}}
ChipComponent={CompanyChip}
/>
@@ -165,7 +172,7 @@ export const companiesColumns = [
changeHandler={(value) => {
const company = props.row.original;
company.employees = parseInt(value);
- updateCompany(company).catch((error) => console.error(error));
+ updateCompany(company);
}}
/>
),
@@ -178,7 +185,7 @@ export const companiesColumns = [
changeHandler={(value) => {
const company = props.row.original;
company.domain_name = value;
- updateCompany(company).catch((error) => console.error(error));
+ updateCompany(company);
}}
/>
),
@@ -191,33 +198,22 @@ export const companiesColumns = [
changeHandler={(value) => {
const company = props.row.original;
company.address = value;
- updateCompany(company).catch((error) => console.error(error));
+ updateCompany(company);
}}
/>
),
}),
- columnHelper.accessor('opportunities', {
- header: () => (
- } />
- ),
- cell: (props) => (
-
- {props.row.original.opportunities.map((opportunity) => (
-
- ))}
-
- ),
- }),
columnHelper.accessor('creationDate', {
header: () => } />,
cell: (props) => (
-
- {new Intl.DateTimeFormat(undefined, {
- month: 'short',
- day: 'numeric',
- year: 'numeric',
- }).format(props.row.original.creationDate)}
-
+ {
+ const company = props.row.original;
+ company.creationDate = value;
+ updateCompany(company);
+ }}
+ />
),
}),
columnHelper.accessor('accountOwner', {
@@ -225,13 +221,54 @@ export const companiesColumns = [
} />
),
cell: (props) => (
-
- <>
- {props.row.original.accountOwner && (
-
- )}
- >
-
+
+ relation={props.row.original.accountOwner}
+ searchPlaceholder="Account Owner"
+ ChipComponent={PersonChip}
+ chipComponentPropsMapper={(
+ accountOwner: PartialUser,
+ ): PersonChipPropsType => {
+ return {
+ name: accountOwner.displayName,
+ };
+ }}
+ changeHandler={(relation: PartialUser) => {
+ const company = props.row.original;
+ if (company.accountOwner) {
+ company.accountOwner.id = relation.id;
+ } else {
+ company.accountOwner = {
+ id: relation.id,
+ email: relation.email,
+ displayName: relation.displayName,
+ };
+ }
+ updateCompany(company);
+ }}
+ searchFilter={
+ {
+ key: 'account_owner_name',
+ label: 'Account Owner',
+ icon: ,
+ whereTemplate: () => {
+ return {};
+ },
+ searchQuery: SEARCH_USER_QUERY,
+ searchTemplate: (searchInput: string) => ({
+ displayName: { _ilike: `%${searchInput}%` },
+ }),
+ searchResultMapper: (accountOwner: GraphqlQueryUser) => ({
+ displayValue: accountOwner.displayName,
+ value: {
+ id: accountOwner.id,
+ email: accountOwner.email,
+ displayName: accountOwner.displayName,
+ },
+ }),
+ operands: [],
+ } satisfies FilterType
+ }
+ />
),
}),
];
diff --git a/front/src/pages/people/people-table.tsx b/front/src/pages/people/people-table.tsx
index c55750c8f..b2766b864 100644
--- a/front/src/pages/people/people-table.tsx
+++ b/front/src/pages/people/people-table.tsx
@@ -5,19 +5,16 @@ import {
FaRegUser,
FaMapPin,
FaPhone,
- FaStream,
FaUser,
FaBuilding,
} from 'react-icons/fa';
import { createColumnHelper } from '@tanstack/react-table';
-import ClickableCell from '../../components/table/ClickableCell';
import ColumnHead from '../../components/table/ColumnHead';
import Checkbox from '../../components/form/Checkbox';
import CompanyChip, {
CompanyChipPropsType,
} from '../../components/chips/CompanyChip';
import { GraphqlQueryPerson, Person } from '../../interfaces/person.interface';
-import PipeChip from '../../components/chips/PipeChip';
import EditableText from '../../components/table/editable-cell/EditableText';
import {
FilterType,
@@ -361,14 +358,6 @@ export const peopleColumns = [
/>
),
}),
- columnHelper.accessor('pipe', {
- header: () => } />,
- cell: (props) => (
-
-
-
- ),
- }),
columnHelper.accessor('city', {
header: () => } />,
cell: (props) => (
diff --git a/front/src/services/companies/update.ts b/front/src/services/companies/update.ts
index 56b380f0a..604aabc75 100644
--- a/front/src/services/companies/update.ts
+++ b/front/src/services/companies/update.ts
@@ -8,6 +8,7 @@ export const UPDATE_COMPANY = gql`
$name: String
$domain_name: String
$account_owner_id: uuid
+ $created_at: timestamptz
$address: String
$employees: Int
) {
@@ -19,6 +20,7 @@ export const UPDATE_COMPANY = gql`
domain_name: $domain_name
employees: $employees
name: $name
+ created_at: $created_at
}
) {
affected_rows
diff --git a/front/src/services/search/search.ts b/front/src/services/search/search.ts
index 4086df5d2..4719f0589 100644
--- a/front/src/services/search/search.ts
+++ b/front/src/services/search/search.ts
@@ -18,6 +18,16 @@ export const SEARCH_PEOPLE_QUERY = gql`
}
`;
+export const SEARCH_USER_QUERY = gql`
+ query SearchQuery($where: users_bool_exp, $limit: Int) {
+ searchResults: users(where: $where, limit: $limit) {
+ id
+ email
+ displayName
+ }
+ }
+`;
+
const EMPTY_QUERY = gql`
query EmptyQuery {
_