9
front/package-lock.json
generated
9
front/package-lock.json
generated
@ -24,6 +24,7 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-icons": "^4.8.0",
|
"react-icons": "^4.8.0",
|
||||||
"react-router-dom": "^6.4.4",
|
"react-router-dom": "^6.4.4",
|
||||||
|
"uuid": "^9.0.0",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -45,6 +46,7 @@
|
|||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"@types/jest": "^27.5.2",
|
"@types/jest": "^27.5.2",
|
||||||
"@types/react-datepicker": "^4.11.2",
|
"@types/react-datepicker": "^4.11.2",
|
||||||
|
"@types/uuid": "^9.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||||
"babel-plugin-named-exports-order": "^0.0.2",
|
"babel-plugin-named-exports-order": "^0.0.2",
|
||||||
"eslint": "^8.28.0",
|
"eslint": "^8.28.0",
|
||||||
@ -8883,6 +8885,12 @@
|
|||||||
"integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==",
|
"integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/ws": {
|
"node_modules/@types/ws": {
|
||||||
"version": "8.5.4",
|
"version": "8.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz",
|
||||||
@ -28338,7 +28346,6 @@
|
|||||||
"version": "9.0.0",
|
"version": "9.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
||||||
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
|
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
|
||||||
"dev": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"uuid": "dist/bin/uuid"
|
"uuid": "dist/bin/uuid"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-icons": "^4.8.0",
|
"react-icons": "^4.8.0",
|
||||||
"react-router-dom": "^6.4.4",
|
"react-router-dom": "^6.4.4",
|
||||||
|
"uuid": "^9.0.0",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -103,6 +104,7 @@
|
|||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"@types/jest": "^27.5.2",
|
"@types/jest": "^27.5.2",
|
||||||
"@types/react-datepicker": "^4.11.2",
|
"@types/react-datepicker": "^4.11.2",
|
||||||
|
"@types/uuid": "^9.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||||
"babel-plugin-named-exports-order": "^0.0.2",
|
"babel-plugin-named-exports-order": "^0.0.2",
|
||||||
"eslint": "^8.28.0",
|
"eslint": "^8.28.0",
|
||||||
|
|||||||
@ -99,7 +99,7 @@ function Table<TData extends { id: string }, SortField, FilterProperies>({
|
|||||||
onFiltersUpdate,
|
onFiltersUpdate,
|
||||||
onFilterSearch,
|
onFilterSearch,
|
||||||
}: OwnProps<TData, SortField, FilterProperies>) {
|
}: OwnProps<TData, SortField, FilterProperies>) {
|
||||||
const table = useReactTable({
|
const table = useReactTable<TData>({
|
||||||
data,
|
data,
|
||||||
columns,
|
columns,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
|||||||
@ -49,7 +49,7 @@ const StyledEditModeResultItem = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export type EditableRelationProps<RelationType, ChipComponentPropsType> = {
|
export type EditableRelationProps<RelationType, ChipComponentPropsType> = {
|
||||||
relation?: RelationType;
|
relation?: RelationType | null;
|
||||||
searchPlaceholder: string;
|
searchPlaceholder: string;
|
||||||
searchFilter: FilterType<People_Bool_Exp>;
|
searchFilter: FilterType<People_Bool_Exp>;
|
||||||
changeHandler: (relation: RelationType) => void;
|
changeHandler: (relation: RelationType) => void;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ export type Company = {
|
|||||||
employees: number;
|
employees: number;
|
||||||
address: string;
|
address: string;
|
||||||
opportunities: Opportunity[];
|
opportunities: Opportunity[];
|
||||||
accountOwner?: User;
|
accountOwner?: User | null;
|
||||||
creationDate: Date;
|
creationDate: Date;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,11 +39,14 @@ export type GraphqlMutationCompany = {
|
|||||||
employees: number;
|
employees: number;
|
||||||
address: string;
|
address: string;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
|
account_owner?: GraphqlQueryUser | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mapCompany = (company: GraphqlQueryCompany): Company => ({
|
export const mapCompany = (company: GraphqlQueryCompany): Company => ({
|
||||||
...company,
|
id: company.id,
|
||||||
|
employees: company.employees,
|
||||||
name: company.name,
|
name: company.name,
|
||||||
|
address: company.address,
|
||||||
domain_name: company.domain_name,
|
domain_name: company.domain_name,
|
||||||
accountOwner: company.account_owner
|
accountOwner: company.account_owner
|
||||||
? {
|
? {
|
||||||
@ -57,9 +60,19 @@ export const mapCompany = (company: GraphqlQueryCompany): Company => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const mapGqlCompany = (company: Company): GraphqlMutationCompany => ({
|
export const mapGqlCompany = (company: Company): GraphqlMutationCompany => ({
|
||||||
...company,
|
|
||||||
name: company.name,
|
name: company.name,
|
||||||
domain_name: company.domain_name,
|
domain_name: company.domain_name,
|
||||||
created_at: company.creationDate.toUTCString(),
|
created_at: company.creationDate.toUTCString(),
|
||||||
account_owner_id: company.accountOwner?.id,
|
account_owner_id: company.accountOwner?.id,
|
||||||
|
address: company.address,
|
||||||
|
employees: company.employees,
|
||||||
|
id: company.id,
|
||||||
|
account_owner: company.accountOwner
|
||||||
|
? {
|
||||||
|
id: company.accountOwner?.id,
|
||||||
|
email: company.accountOwner?.email,
|
||||||
|
displayName: company.accountOwner?.displayName,
|
||||||
|
__typename: 'users',
|
||||||
|
}
|
||||||
|
: null,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -6,6 +6,7 @@ type OwnProps = {
|
|||||||
children: JSX.Element;
|
children: JSX.Element;
|
||||||
title: string;
|
title: string;
|
||||||
icon: ReactNode;
|
icon: ReactNode;
|
||||||
|
onAddButtonClick?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
@ -34,10 +35,15 @@ const ContentSubContainer = styled.div`
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function FullWidthContainer({ children, title, icon }: OwnProps) {
|
function FullWidthContainer({
|
||||||
|
children,
|
||||||
|
title,
|
||||||
|
icon,
|
||||||
|
onAddButtonClick,
|
||||||
|
}: OwnProps) {
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<TopBar title={title} icon={icon} />
|
<TopBar title={title} icon={icon} onAddButtonClick={onAddButtonClick} />
|
||||||
<ContentContainer>
|
<ContentContainer>
|
||||||
<ContentSubContainer>{children}</ContentSubContainer>
|
<ContentSubContainer>{children}</ContentSubContainer>
|
||||||
</ContentContainer>
|
</ContentContainer>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
import { TbPlus } from 'react-icons/tb';
|
||||||
|
|
||||||
const TopBarContainer = styled.div`
|
const TopBarContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -17,19 +18,44 @@ const TitleContainer = styled.div`
|
|||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const AddButtonContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
justify-self: flex-end;
|
||||||
|
border: 1px solid ${(props) => props.theme.primaryBorder};
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: ${(props) => props.theme.text60};
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: ${(props) => props.theme.spacing(1)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
title: string;
|
title: string;
|
||||||
icon: ReactNode;
|
icon: ReactNode;
|
||||||
|
onAddButtonClick?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
function TopBar({ title, icon }: OwnProps) {
|
function TopBar({ title, icon, onAddButtonClick }: OwnProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TopBarContainer>
|
<TopBarContainer>
|
||||||
{icon}
|
{icon}
|
||||||
<TitleContainer data-testid="top-bar-title">{title}</TitleContainer>
|
<TitleContainer data-testid="top-bar-title">{title}</TitleContainer>
|
||||||
|
{onAddButtonClick && (
|
||||||
|
<AddButtonContainer
|
||||||
|
data-testid="add-button"
|
||||||
|
onClick={onAddButtonClick}
|
||||||
|
>
|
||||||
|
<TbPlus />
|
||||||
|
</AddButtonContainer>
|
||||||
|
)}
|
||||||
</TopBarContainer>
|
</TopBarContainer>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
import { FaRegBuilding, FaList } from 'react-icons/fa';
|
import { FaRegBuilding, FaList } from 'react-icons/fa';
|
||||||
import WithTopBarContainer from '../../layout/containers/WithTopBarContainer';
|
import WithTopBarContainer from '../../layout/containers/WithTopBarContainer';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback, useEffect } from 'react';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import {
|
import {
|
||||||
CompaniesSelectedSortType,
|
CompaniesSelectedSortType,
|
||||||
defaultOrderBy,
|
defaultOrderBy,
|
||||||
|
insertCompany,
|
||||||
useCompaniesQuery,
|
useCompaniesQuery,
|
||||||
} from '../../services/companies';
|
} from '../../services/companies';
|
||||||
import Table from '../../components/table/Table';
|
import Table from '../../components/table/Table';
|
||||||
import { mapCompany } from '../../interfaces/company.interface';
|
import { Company, mapCompany } from '../../interfaces/company.interface';
|
||||||
import {
|
import {
|
||||||
companiesColumns,
|
useCompaniesColumns,
|
||||||
availableFilters,
|
availableFilters,
|
||||||
availableSorts,
|
availableSorts,
|
||||||
} from './companies-table';
|
} from './companies-table';
|
||||||
@ -33,6 +35,7 @@ const StyledCompaniesContainer = styled.div`
|
|||||||
function Companies() {
|
function Companies() {
|
||||||
const [orderBy, setOrderBy] = useState<Companies_Order_By[]>(defaultOrderBy);
|
const [orderBy, setOrderBy] = useState<Companies_Order_By[]>(defaultOrderBy);
|
||||||
const [where, setWhere] = useState<Companies_Bool_Exp>({});
|
const [where, setWhere] = useState<Companies_Bool_Exp>({});
|
||||||
|
const [internalData, setInternalData] = useState<Array<Company>>([]);
|
||||||
|
|
||||||
const [filterSearchResults, setSearhInput, setFilterSearch] = useSearch();
|
const [filterSearchResults, setSearhInput, setFilterSearch] = useSearch();
|
||||||
|
|
||||||
@ -47,13 +50,43 @@ function Companies() {
|
|||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data } = useCompaniesQuery(orderBy, where);
|
const { data, loading, refetch } = useCompaniesQuery(orderBy, where);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!loading) {
|
||||||
|
if (data) {
|
||||||
|
setInternalData(data.companies.map(mapCompany));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [loading, setInternalData, data]);
|
||||||
|
|
||||||
|
const addEmptyRow = useCallback(() => {
|
||||||
|
const newCompany: Company = {
|
||||||
|
id: uuidv4(),
|
||||||
|
name: '',
|
||||||
|
domain_name: '',
|
||||||
|
employees: 0,
|
||||||
|
address: '',
|
||||||
|
opportunities: [],
|
||||||
|
creationDate: new Date(),
|
||||||
|
accountOwner: null,
|
||||||
|
};
|
||||||
|
insertCompany(newCompany);
|
||||||
|
setInternalData([newCompany, ...internalData]);
|
||||||
|
refetch();
|
||||||
|
}, [internalData, setInternalData, refetch]);
|
||||||
|
|
||||||
|
const companiesColumns = useCompaniesColumns();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithTopBarContainer title="Companies" icon={<FaRegBuilding />}>
|
<WithTopBarContainer
|
||||||
|
title="Companies"
|
||||||
|
icon={<FaRegBuilding />}
|
||||||
|
onAddButtonClick={addEmptyRow}
|
||||||
|
>
|
||||||
<StyledCompaniesContainer>
|
<StyledCompaniesContainer>
|
||||||
<Table
|
<Table
|
||||||
data={data ? data.companies.map(mapCompany) : []}
|
data={internalData}
|
||||||
columns={companiesColumns}
|
columns={companiesColumns}
|
||||||
viewName="All Companies"
|
viewName="All Companies"
|
||||||
viewIcon={<FaList />}
|
viewIcon={<FaList />}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ const mocks = [
|
|||||||
request: {
|
request: {
|
||||||
query: GET_COMPANIES,
|
query: GET_COMPANIES,
|
||||||
variables: {
|
variables: {
|
||||||
orderBy: [{ name: 'asc' }],
|
orderBy: [{ created_at: 'desc' }],
|
||||||
where: {},
|
where: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -115,3 +115,24 @@ it('Checks company address edit is updating data', async () => {
|
|||||||
expect(getByText('21 rue de clignancourt')).toBeInTheDocument();
|
expect(getByText('21 rue de clignancourt')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Checks insert data is appending a new line', async () => {
|
||||||
|
const { getByText, getByTestId, container } = render(<CompaniesDefault />);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(getByText('Airbnb')).toBeDefined();
|
||||||
|
});
|
||||||
|
const tableRows = container.querySelectorAll<HTMLElement>('table tbody tr');
|
||||||
|
|
||||||
|
expect(tableRows.length).toBe(6);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
fireEvent.click(getByTestId('add-button'));
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
const tableRows = container.querySelectorAll<HTMLElement>('table tbody tr');
|
||||||
|
|
||||||
|
expect(tableRows.length).toBe(7);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import {
|
|||||||
import EditableDate from '../../components/table/editable-cell/EditableDate';
|
import EditableDate from '../../components/table/editable-cell/EditableDate';
|
||||||
import EditableRelation from '../../components/table/editable-cell/EditableRelation';
|
import EditableRelation from '../../components/table/editable-cell/EditableRelation';
|
||||||
import { GraphqlQueryUser, PartialUser } from '../../interfaces/user.interface';
|
import { GraphqlQueryUser, PartialUser } from '../../interfaces/user.interface';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const availableSorts = [
|
export const availableSorts = [
|
||||||
{
|
{
|
||||||
@ -136,139 +137,150 @@ export const availableFilters = [
|
|||||||
] satisfies Array<FilterType<Companies_Bool_Exp>>;
|
] satisfies Array<FilterType<Companies_Bool_Exp>>;
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<Company>();
|
const columnHelper = createColumnHelper<Company>();
|
||||||
export const companiesColumns = [
|
|
||||||
columnHelper.accessor('id', {
|
export const useCompaniesColumns = () => {
|
||||||
header: () => (
|
return useMemo(() => {
|
||||||
<Checkbox id="company-select-all" name="company-select-all" />
|
return [
|
||||||
),
|
columnHelper.accessor('id', {
|
||||||
cell: (props) => (
|
header: () => (
|
||||||
<Checkbox
|
<Checkbox id="company-select-all" name="company-select-all" />
|
||||||
id={`company-selected-${props.row.original.id}`}
|
),
|
||||||
name={`company-selected-${props.row.original.id}`}
|
cell: (props) => (
|
||||||
/>
|
<Checkbox
|
||||||
),
|
id={`company-selected-${props.row.original.id}`}
|
||||||
}),
|
name={`company-selected-${props.row.original.id}`}
|
||||||
columnHelper.accessor('name', {
|
/>
|
||||||
header: () => <ColumnHead viewName="Name" viewIcon={<FaRegBuilding />} />,
|
),
|
||||||
cell: (props) => (
|
}),
|
||||||
<EditableChip
|
columnHelper.accessor('name', {
|
||||||
value={props.row.original.name}
|
header: () => (
|
||||||
placeholder="Name"
|
<ColumnHead viewName="Name" viewIcon={<FaRegBuilding />} />
|
||||||
picture={`https://www.google.com/s2/favicons?domain=${props.row.original.domain_name}&sz=256`}
|
),
|
||||||
changeHandler={(value: string) => {
|
cell: (props) => (
|
||||||
const company = props.row.original;
|
<EditableChip
|
||||||
company.name = value;
|
value={props.row.original.name}
|
||||||
updateCompany(company);
|
placeholder="Name"
|
||||||
}}
|
picture={`https://www.google.com/s2/favicons?domain=${props.row.original.domain_name}&sz=256`}
|
||||||
ChipComponent={CompanyChip}
|
changeHandler={(value: string) => {
|
||||||
/>
|
const company = props.row.original;
|
||||||
),
|
company.name = value;
|
||||||
}),
|
updateCompany(company);
|
||||||
columnHelper.accessor('employees', {
|
}}
|
||||||
header: () => <ColumnHead viewName="Employees" viewIcon={<FaUsers />} />,
|
ChipComponent={CompanyChip}
|
||||||
cell: (props) => (
|
/>
|
||||||
<EditableText
|
),
|
||||||
content={props.row.original.employees.toFixed(0)}
|
}),
|
||||||
changeHandler={(value) => {
|
columnHelper.accessor('employees', {
|
||||||
const company = props.row.original;
|
header: () => (
|
||||||
company.employees = parseInt(value);
|
<ColumnHead viewName="Employees" viewIcon={<FaUsers />} />
|
||||||
updateCompany(company);
|
),
|
||||||
}}
|
cell: (props) => (
|
||||||
/>
|
<EditableText
|
||||||
),
|
content={props.row.original.employees.toFixed(0)}
|
||||||
}),
|
changeHandler={(value) => {
|
||||||
columnHelper.accessor('domain_name', {
|
const company = props.row.original;
|
||||||
header: () => <ColumnHead viewName="URL" viewIcon={<FaLink />} />,
|
company.employees = parseInt(value);
|
||||||
cell: (props) => (
|
updateCompany(company);
|
||||||
<EditableText
|
}}
|
||||||
content={props.row.original.domain_name}
|
/>
|
||||||
changeHandler={(value) => {
|
),
|
||||||
const company = props.row.original;
|
}),
|
||||||
company.domain_name = value;
|
columnHelper.accessor('domain_name', {
|
||||||
updateCompany(company);
|
header: () => <ColumnHead viewName="URL" viewIcon={<FaLink />} />,
|
||||||
}}
|
cell: (props) => (
|
||||||
/>
|
<EditableText
|
||||||
),
|
content={props.row.original.domain_name}
|
||||||
}),
|
changeHandler={(value) => {
|
||||||
columnHelper.accessor('address', {
|
const company = props.row.original;
|
||||||
header: () => <ColumnHead viewName="Address" viewIcon={<FaMapPin />} />,
|
company.domain_name = value;
|
||||||
cell: (props) => (
|
updateCompany(company);
|
||||||
<EditableText
|
}}
|
||||||
content={props.row.original.address}
|
/>
|
||||||
changeHandler={(value) => {
|
),
|
||||||
const company = props.row.original;
|
}),
|
||||||
company.address = value;
|
columnHelper.accessor('address', {
|
||||||
updateCompany(company);
|
header: () => <ColumnHead viewName="Address" viewIcon={<FaMapPin />} />,
|
||||||
}}
|
cell: (props) => (
|
||||||
/>
|
<EditableText
|
||||||
),
|
content={props.row.original.address}
|
||||||
}),
|
changeHandler={(value) => {
|
||||||
columnHelper.accessor('creationDate', {
|
const company = props.row.original;
|
||||||
header: () => <ColumnHead viewName="Creation" viewIcon={<FaCalendar />} />,
|
company.address = value;
|
||||||
cell: (props) => (
|
updateCompany(company);
|
||||||
<EditableDate
|
}}
|
||||||
value={props.row.original.creationDate}
|
/>
|
||||||
changeHandler={(value: Date) => {
|
),
|
||||||
const company = props.row.original;
|
}),
|
||||||
company.creationDate = value;
|
columnHelper.accessor('creationDate', {
|
||||||
updateCompany(company);
|
header: () => (
|
||||||
}}
|
<ColumnHead viewName="Creation" viewIcon={<FaCalendar />} />
|
||||||
/>
|
),
|
||||||
),
|
cell: (props) => (
|
||||||
}),
|
<EditableDate
|
||||||
columnHelper.accessor('accountOwner', {
|
value={props.row.original.creationDate}
|
||||||
header: () => (
|
changeHandler={(value: Date) => {
|
||||||
<ColumnHead viewName="Account Owner" viewIcon={<FaRegUser />} />
|
const company = props.row.original;
|
||||||
),
|
company.creationDate = value;
|
||||||
cell: (props) => (
|
updateCompany(company);
|
||||||
<EditableRelation<PartialUser, PersonChipPropsType>
|
}}
|
||||||
relation={props.row.original.accountOwner}
|
/>
|
||||||
searchPlaceholder="Account Owner"
|
),
|
||||||
ChipComponent={PersonChip}
|
}),
|
||||||
chipComponentPropsMapper={(
|
columnHelper.accessor('accountOwner', {
|
||||||
accountOwner: PartialUser,
|
header: () => (
|
||||||
): PersonChipPropsType => {
|
<ColumnHead viewName="Account Owner" viewIcon={<FaRegUser />} />
|
||||||
return {
|
),
|
||||||
name: accountOwner.displayName,
|
cell: (props) => (
|
||||||
};
|
<EditableRelation<PartialUser, PersonChipPropsType>
|
||||||
}}
|
relation={props.row.original.accountOwner}
|
||||||
changeHandler={(relation: PartialUser) => {
|
searchPlaceholder="Account Owner"
|
||||||
const company = props.row.original;
|
ChipComponent={PersonChip}
|
||||||
if (company.accountOwner) {
|
chipComponentPropsMapper={(
|
||||||
company.accountOwner.id = relation.id;
|
accountOwner: PartialUser,
|
||||||
} else {
|
): PersonChipPropsType => {
|
||||||
company.accountOwner = {
|
return {
|
||||||
id: relation.id,
|
name: accountOwner.displayName,
|
||||||
email: relation.email,
|
};
|
||||||
displayName: relation.displayName,
|
}}
|
||||||
};
|
changeHandler={(relation: PartialUser) => {
|
||||||
}
|
const company = props.row.original;
|
||||||
updateCompany(company);
|
if (company.accountOwner) {
|
||||||
}}
|
company.accountOwner.id = relation.id;
|
||||||
searchFilter={
|
} else {
|
||||||
{
|
company.accountOwner = {
|
||||||
key: 'account_owner_name',
|
id: relation.id,
|
||||||
label: 'Account Owner',
|
email: relation.email,
|
||||||
icon: <FaUser />,
|
displayName: relation.displayName,
|
||||||
whereTemplate: () => {
|
};
|
||||||
return {};
|
}
|
||||||
},
|
updateCompany(company);
|
||||||
searchQuery: SEARCH_USER_QUERY,
|
}}
|
||||||
searchTemplate: (searchInput: string) => ({
|
searchFilter={
|
||||||
displayName: { _ilike: `%${searchInput}%` },
|
{
|
||||||
}),
|
key: 'account_owner_name',
|
||||||
searchResultMapper: (accountOwner: GraphqlQueryUser) => ({
|
label: 'Account Owner',
|
||||||
displayValue: accountOwner.displayName,
|
icon: <FaUser />,
|
||||||
value: {
|
whereTemplate: () => {
|
||||||
id: accountOwner.id,
|
return {};
|
||||||
email: accountOwner.email,
|
},
|
||||||
displayName: accountOwner.displayName,
|
searchQuery: SEARCH_USER_QUERY,
|
||||||
},
|
searchTemplate: (searchInput: string) => ({
|
||||||
}),
|
displayName: { _ilike: `%${searchInput}%` },
|
||||||
operands: [],
|
}),
|
||||||
} satisfies FilterType<Users_Bool_Exp>
|
searchResultMapper: (accountOwner: GraphqlQueryUser) => ({
|
||||||
}
|
displayValue: accountOwner.displayName,
|
||||||
/>
|
value: {
|
||||||
),
|
id: accountOwner.id,
|
||||||
}),
|
email: accountOwner.email,
|
||||||
];
|
displayName: accountOwner.displayName,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
operands: [],
|
||||||
|
} satisfies FilterType<Users_Bool_Exp>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
}, []);
|
||||||
|
};
|
||||||
|
|||||||
@ -44,10 +44,18 @@ function People() {
|
|||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const addEmptyRow = useCallback(() => {
|
||||||
|
console.log('add row');
|
||||||
|
}, []);
|
||||||
|
|
||||||
const { data } = usePeopleQuery(orderBy, where);
|
const { data } = usePeopleQuery(orderBy, where);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithTopBarContainer title="People" icon={<FaRegUser />}>
|
<WithTopBarContainer
|
||||||
|
title="People"
|
||||||
|
icon={<FaRegUser />}
|
||||||
|
onAddButtonClick={addEmptyRow}
|
||||||
|
>
|
||||||
<StyledPeopleContainer>
|
<StyledPeopleContainer>
|
||||||
{
|
{
|
||||||
<Table
|
<Table
|
||||||
|
|||||||
@ -41,6 +41,6 @@ export function useCompaniesQuery(
|
|||||||
|
|
||||||
export const defaultOrderBy: Companies_Order_By[] = [
|
export const defaultOrderBy: Companies_Order_By[] = [
|
||||||
{
|
{
|
||||||
name: Order_By.Asc,
|
created_at: Order_By.Desc,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -41,6 +41,40 @@ export const UPDATE_COMPANY = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const INSERT_COMPANY = gql`
|
||||||
|
mutation InsertCompany(
|
||||||
|
$id: uuid
|
||||||
|
$name: String
|
||||||
|
$domain_name: String
|
||||||
|
$account_owner_id: uuid
|
||||||
|
$created_at: timestamptz
|
||||||
|
$address: String
|
||||||
|
$employees: Int
|
||||||
|
) {
|
||||||
|
insert_companies(
|
||||||
|
objects: {
|
||||||
|
id: $id
|
||||||
|
name: $name
|
||||||
|
domain_name: $domain_name
|
||||||
|
account_owner_id: $account_owner_id
|
||||||
|
created_at: $created_at
|
||||||
|
address: $address
|
||||||
|
employees: $employees
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
affected_rows
|
||||||
|
returning {
|
||||||
|
address
|
||||||
|
created_at
|
||||||
|
domain_name
|
||||||
|
employees
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export async function updateCompany(
|
export async function updateCompany(
|
||||||
company: Company,
|
company: Company,
|
||||||
): Promise<FetchResult<Company>> {
|
): Promise<FetchResult<Company>> {
|
||||||
@ -50,3 +84,14 @@ export async function updateCompany(
|
|||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function insertCompany(
|
||||||
|
company: Company,
|
||||||
|
): Promise<FetchResult<Company>> {
|
||||||
|
const result = await apiClient.mutate({
|
||||||
|
mutation: INSERT_COMPANY,
|
||||||
|
variables: mapGqlCompany(company),
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
@ -20,6 +20,8 @@ insert_permissions:
|
|||||||
check:
|
check:
|
||||||
workspace_id:
|
workspace_id:
|
||||||
_eq: x-hasura-workspace-id
|
_eq: x-hasura-workspace-id
|
||||||
|
set:
|
||||||
|
workspace_id: x-hasura-Workspace-Id
|
||||||
columns:
|
columns:
|
||||||
- id
|
- id
|
||||||
- workspace_id
|
- workspace_id
|
||||||
|
|||||||
Reference in New Issue
Block a user