In place edit company info (#90)

* Add update company functionality

* Fix padding in cells with chips

* Add icons to table headers
This commit is contained in:
Anders Borch
2023-04-28 08:50:04 +02:00
committed by GitHub
parent d5c1bd6365
commit 27070b374e
6 changed files with 92 additions and 26 deletions

1
.gitignore vendored
View File

@@ -2,3 +2,4 @@
**/**/.env
**/**/.npmrc
.DS_Store
node_modules

View File

@@ -48,6 +48,7 @@ describe('mapCompany', () => {
expect(company.name).toBe('ACME');
expect(company.domain_name).toBe('exmaple.com');
expect(company.creationDate).toEqual(now);
expect(company.accountOwner).toBeUndefined();
expect(company.employees).toBe(10);
expect(company.address).toBe(
'1 Infinite Loop, 95014 Cupertino, California, USA',
@@ -76,11 +77,9 @@ describe('mapCompany', () => {
expect(company.name).toBe('ACME');
expect(company.domain_name).toBe('exmaple.com');
expect(company.created_at).toEqual(now.toUTCString());
expect(company.account_owner?.id).toBe(
expect(company.account_owner_id).toBe(
'522d4ec4-c46b-4360-a0a7-df8df170be81',
);
expect(company.account_owner?.email).toBe('john@example.com');
expect(company.account_owner?.displayName).toBe('John Doe');
expect(company.employees).toBe(10);
expect(company.address).toBe(
'1 Infinite Loop, 95014 Cupertino, California, USA',
@@ -103,6 +102,7 @@ describe('mapCompany', () => {
expect(company.name).toBe('ACME');
expect(company.domain_name).toBe('exmaple.com');
expect(company.created_at).toEqual(now.toUTCString());
expect(company.account_owner_id).toBeUndefined();
expect(company.employees).toBe(10);
expect(company.address).toBe(
'1 Infinite Loop, 95014 Cupertino, California, USA',

View File

@@ -32,6 +32,16 @@ export type GraphqlQueryCompany = {
created_at: string;
};
export type GraphqlMutationCompany = {
id: string;
name: string;
domain_name: string;
account_owner_id?: string;
employees: number;
address: string;
created_at: string;
};
export const mapCompany = (company: GraphqlQueryCompany): Company => ({
...company,
name: company.name,
@@ -51,16 +61,10 @@ export const mapCompany = (company: GraphqlQueryCompany): Company => ({
opportunities: [{ name: 'Sales Pipeline', icon: '' }],
});
export const mapGqlCompany = (company: Company): GraphqlQueryCompany => ({
export const mapGqlCompany = (company: Company): GraphqlMutationCompany => ({
...company,
name: company.name,
domain_name: company.domain_name,
created_at: company.creationDate.toUTCString(),
account_owner: company.accountOwner
? {
id: company.accountOwner.id,
email: company.accountOwner.email,
displayName: `${company.accountOwner.first_name} ${company.accountOwner.last_name}`,
}
: undefined,
account_owner_id: company.accountOwner?.id,
});

View File

@@ -1,13 +1,21 @@
import { createColumnHelper } from '@tanstack/react-table';
import { Company } from '../../interfaces/company.interface';
import { OrderByFields } from '../../services/companies';
import { OrderByFields, updateCompany } from '../../services/companies';
import ColumnHead from '../../components/table/ColumnHead';
import HorizontalyAlignedContainer from '../../layout/containers/HorizontalyAlignedContainer';
import Checkbox from '../../components/form/Checkbox';
import CompanyChip from '../../components/chips/CompanyChip';
import EditableCell from '../../components/table/EditableCell';
import PipeChip from '../../components/chips/PipeChip';
import { faCalendar } from '@fortawesome/pro-regular-svg-icons';
import {
faBuildings,
faCalendar,
faLinkSimple,
faMapPin,
faRectangleHistory,
faSigma,
faUser,
} from '@fortawesome/pro-regular-svg-icons';
import ClickableCell from '../../components/table/ClickableCell';
import PersonChip from '../../components/chips/PersonChip';
import { SortType } from '../../components/table/table-header/interface';
@@ -28,7 +36,7 @@ export const sortsAvailable = [
const columnHelper = createColumnHelper<Company>();
export const companiesColumns = [
columnHelper.accessor('name', {
header: () => <ColumnHead viewName="Name" />,
header: () => <ColumnHead viewName="Name" viewIcon={faBuildings} />,
cell: (props) => (
<HorizontalyAlignedContainer>
<Checkbox
@@ -43,52 +51,54 @@ export const companiesColumns = [
),
}),
columnHelper.accessor('employees', {
header: () => <ColumnHead viewName="Employees" />,
header: () => <ColumnHead viewName="Employees" viewIcon={faSigma} />,
cell: (props) => (
<EditableCell
content={props.row.original.employees.toFixed(0)}
changeHandler={(value) => {
const company = props.row.original;
company.employees = parseInt(value);
// TODO: update company
updateCompany(company).catch((error) => console.error(error));
}}
/>
),
}),
columnHelper.accessor('domain_name', {
header: () => <ColumnHead viewName="URL" />,
header: () => <ColumnHead viewName="URL" viewIcon={faLinkSimple} />,
cell: (props) => (
<EditableCell
content={props.row.original.domain_name}
changeHandler={(value) => {
const company = props.row.original;
company.domain_name = value;
// TODO: update company
updateCompany(company).catch((error) => console.error(error));
}}
/>
),
}),
columnHelper.accessor('address', {
header: () => <ColumnHead viewName="Address" />,
header: () => <ColumnHead viewName="Address" viewIcon={faMapPin} />,
cell: (props) => (
<EditableCell
content={props.row.original.address}
changeHandler={(value) => {
const company = props.row.original;
company.address = value;
// TODO: update company
updateCompany(company).catch((error) => console.error(error));
}}
/>
),
}),
columnHelper.accessor('opportunities', {
header: () => <ColumnHead viewName="Opportunities" />,
header: () => (
<ColumnHead viewName="Opportunities" viewIcon={faRectangleHistory} />
),
cell: (props) => (
<HorizontalyAlignedContainer>
<ClickableCell href="#">
{props.row.original.opportunities.map((opportunity) => (
<PipeChip name={opportunity.name} picture={opportunity.icon} />
))}
</HorizontalyAlignedContainer>
</ClickableCell>
),
}),
columnHelper.accessor('creationDate', {
@@ -104,9 +114,9 @@ export const companiesColumns = [
),
}),
columnHelper.accessor('accountOwner', {
header: () => <ColumnHead viewName="Account Owner" />,
header: () => <ColumnHead viewName="Account Owner" viewIcon={faUser} />,
cell: (props) => (
<HorizontalyAlignedContainer>
<ClickableCell href="#">
<>
{props.row.original.accountOwner && (
<PersonChip
@@ -116,7 +126,7 @@ export const companiesColumns = [
/>
)}
</>
</HorizontalyAlignedContainer>
</ClickableCell>
),
}),
];

View File

@@ -1 +1,2 @@
export * from './select';
export * from './update';

View File

@@ -0,0 +1,50 @@
import { FetchResult, gql } from '@apollo/client';
import { Company, mapGqlCompany } from '../../interfaces/company.interface';
import { apiClient } from '../../apollo';
export const UPDATE_COMPANY = gql`
mutation UpdateCompany(
$id: uuid
$name: String
$domain_name: String
$account_owner_id: uuid
$address: String
$employees: Int
) {
update_companies(
where: { id: { _eq: $id } }
_set: {
account_owner_id: $account_owner_id
address: $address
domain_name: $domain_name
employees: $employees
name: $name
}
) {
affected_rows
returning {
account_owner {
id
email
displayName
}
address
created_at
domain_name
employees
id
name
}
}
}
`;
export async function updateCompany(
company: Company,
): Promise<FetchResult<Company>> {
const result = await apiClient.mutate({
mutation: UPDATE_COMPANY,
variables: mapGqlCompany(company),
});
return result;
}