Companies table (#79)
* Add columns to companies: * account_owner_id * employees * address Add foreign key constraint companies_account_owner_id_fkey to auth.users.id * Add select permissions to: * account_owner_id * employees * address Add relationship between companies and auth.users. * Update Companies interface to include: * account_owner_id * employees * address Opportunity is expected to be replace by actual opportunity in a separate PR. * Add GetCompanies query * Add initial companies table * Update test to use mock apollo provider * Update to match changed company column names * Add company interface mapping tests * Test entire object * Add test for companies being rendered in table. * Add test for sorting reduce. * Fix prettier errors
This commit is contained in:
68
front/src/interfaces/company.interface.test.ts
Normal file
68
front/src/interfaces/company.interface.test.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { mapGqlCompany, mapCompany } from './company.interface';
|
||||||
|
|
||||||
|
describe('mapCompany', () => {
|
||||||
|
it('should map company', () => {
|
||||||
|
const now = new Date();
|
||||||
|
now.setMilliseconds(0);
|
||||||
|
const company = mapCompany({
|
||||||
|
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
|
||||||
|
name: 'ACME',
|
||||||
|
domain_name: 'exmaple.com',
|
||||||
|
created_at: now.toUTCString(),
|
||||||
|
account_owner: {
|
||||||
|
id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87',
|
||||||
|
email: 'john@example.com',
|
||||||
|
displayName: 'John Doe',
|
||||||
|
},
|
||||||
|
employees: 10,
|
||||||
|
address: '1 Infinite Loop, 95014 Cupertino, California, USA',
|
||||||
|
});
|
||||||
|
expect(company.id).toBe('7dfbc3f7-6e5e-4128-957e-8d86808cdf6b');
|
||||||
|
expect(company.name).toBe('ACME');
|
||||||
|
expect(company.domain_name).toBe('exmaple.com');
|
||||||
|
expect(company.creationDate).toEqual(now);
|
||||||
|
expect(company.accountOwner.id).toBe(
|
||||||
|
'7af20dea-0412-4c4c-8b13-d6f0e6e09e87',
|
||||||
|
);
|
||||||
|
expect(company.accountOwner.email).toBe('john@example.com');
|
||||||
|
expect(company.accountOwner.first_name).toBe('John');
|
||||||
|
expect(company.accountOwner.last_name).toBe('Doe');
|
||||||
|
expect(company.employees).toBe(10);
|
||||||
|
expect(company.address).toBe(
|
||||||
|
'1 Infinite Loop, 95014 Cupertino, California, USA',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should map company back', () => {
|
||||||
|
const now = new Date();
|
||||||
|
now.setMilliseconds(0);
|
||||||
|
const company = mapGqlCompany({
|
||||||
|
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
|
||||||
|
name: 'ACME',
|
||||||
|
domain_name: 'exmaple.com',
|
||||||
|
employees: 10,
|
||||||
|
address: '1 Infinite Loop, 95014 Cupertino, California, USA',
|
||||||
|
opportunities: [],
|
||||||
|
accountOwner: {
|
||||||
|
id: '522d4ec4-c46b-4360-a0a7-df8df170be81',
|
||||||
|
email: 'john@example.com',
|
||||||
|
first_name: 'John',
|
||||||
|
last_name: 'Doe',
|
||||||
|
},
|
||||||
|
creationDate: now,
|
||||||
|
});
|
||||||
|
expect(company.id).toBe('7dfbc3f7-6e5e-4128-957e-8d86808cdf6b');
|
||||||
|
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(
|
||||||
|
'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',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -1,5 +1,59 @@
|
|||||||
|
import { User } from './user.interface';
|
||||||
|
|
||||||
|
export interface Opportunity {
|
||||||
|
name: string;
|
||||||
|
icon: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Company {
|
export interface Company {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
domain_name: string;
|
domain_name: string;
|
||||||
|
employees: number;
|
||||||
|
address: string;
|
||||||
|
opportunities: Opportunity[];
|
||||||
|
accountOwner: User;
|
||||||
|
creationDate: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type GraphqlQueryAccountOwner = {
|
||||||
|
id: string;
|
||||||
|
email: string;
|
||||||
|
displayName: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GraphqlQueryCompany = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
domain_name: string;
|
||||||
|
account_owner: GraphqlQueryAccountOwner;
|
||||||
|
employees: number;
|
||||||
|
address: string;
|
||||||
|
created_at: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mapCompany = (company: GraphqlQueryCompany): Company => ({
|
||||||
|
...company,
|
||||||
|
name: company.name,
|
||||||
|
domain_name: company.domain_name,
|
||||||
|
accountOwner: {
|
||||||
|
id: company.account_owner.id,
|
||||||
|
email: company.account_owner.email,
|
||||||
|
first_name: company.account_owner.displayName.split(' ').shift() || '',
|
||||||
|
last_name: company.account_owner.displayName.split(' ').slice(1).join(' '),
|
||||||
|
},
|
||||||
|
creationDate: new Date(company.created_at),
|
||||||
|
opportunities: [{ name: 'Sales Pipeline', icon: '' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const mapGqlCompany = (company: Company): GraphqlQueryCompany => ({
|
||||||
|
...company,
|
||||||
|
name: company.name,
|
||||||
|
domain_name: company.domain_name,
|
||||||
|
created_at: company.creationDate.toUTCString(),
|
||||||
|
account_owner: {
|
||||||
|
id: company.accountOwner.id,
|
||||||
|
email: company.accountOwner.email,
|
||||||
|
displayName: `${company.accountOwner.first_name} ${company.accountOwner.last_name}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
@ -6,7 +6,10 @@ export type Person = {
|
|||||||
fullName: string;
|
fullName: string;
|
||||||
picture?: string;
|
picture?: string;
|
||||||
email: string;
|
email: string;
|
||||||
company: Company;
|
company: Omit<
|
||||||
|
Company,
|
||||||
|
'employees' | 'address' | 'opportunities' | 'accountOwner' | 'creationDate'
|
||||||
|
>;
|
||||||
phone: string;
|
phone: string;
|
||||||
creationDate: Date;
|
creationDate: Date;
|
||||||
pipe: Pipe;
|
pipe: Pipe;
|
||||||
|
|||||||
@ -1,10 +1,45 @@
|
|||||||
import { faBuildings } from '@fortawesome/pro-regular-svg-icons';
|
import { faBuildings, faList } from '@fortawesome/pro-regular-svg-icons';
|
||||||
import WithTopBarContainer from '../../layout/containers/WithTopBarContainer';
|
import WithTopBarContainer from '../../layout/containers/WithTopBarContainer';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { useState, useCallback } from 'react';
|
||||||
|
import {
|
||||||
|
CompaniesSelectedSortType,
|
||||||
|
defaultOrderBy,
|
||||||
|
reduceSortsToOrderBy,
|
||||||
|
useCompaniesQuery,
|
||||||
|
} from '../../services/companies';
|
||||||
|
import Table from '../../components/table/Table';
|
||||||
|
import { mapCompany } from '../../interfaces/company.interface';
|
||||||
|
import { companiesColumns, sortsAvailable } from './companies-table';
|
||||||
|
|
||||||
|
const StyledCompaniesContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
function Companies() {
|
function Companies() {
|
||||||
|
const [, setSorts] = useState([] as Array<CompaniesSelectedSortType>);
|
||||||
|
const [orderBy, setOrderBy] = useState(defaultOrderBy);
|
||||||
|
|
||||||
|
const updateSorts = useCallback((sorts: Array<CompaniesSelectedSortType>) => {
|
||||||
|
setSorts(sorts);
|
||||||
|
setOrderBy(sorts.length ? reduceSortsToOrderBy(sorts) : defaultOrderBy);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const { data } = useCompaniesQuery(orderBy);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithTopBarContainer title="Companies" icon={faBuildings}>
|
<WithTopBarContainer title="Companies" icon={faBuildings}>
|
||||||
<></>
|
<StyledCompaniesContainer>
|
||||||
|
<Table
|
||||||
|
data={data ? data.companies.map(mapCompany) : []}
|
||||||
|
columns={companiesColumns}
|
||||||
|
viewName="All Companies"
|
||||||
|
viewIcon={faList}
|
||||||
|
onSortsUpdate={updateSorts}
|
||||||
|
availableSorts={sortsAvailable}
|
||||||
|
/>
|
||||||
|
</StyledCompaniesContainer>
|
||||||
</WithTopBarContainer>
|
</WithTopBarContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,9 @@ import { MemoryRouter } from 'react-router-dom';
|
|||||||
import Companies from '../Companies';
|
import Companies from '../Companies';
|
||||||
import { ThemeProvider } from '@emotion/react';
|
import { ThemeProvider } from '@emotion/react';
|
||||||
import { lightTheme } from '../../../layout/styles/themes';
|
import { lightTheme } from '../../../layout/styles/themes';
|
||||||
|
import { GET_COMPANIES } from '../../../services/companies';
|
||||||
|
import { defaultData } from './mock-data';
|
||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
|
||||||
const component = {
|
const component = {
|
||||||
title: 'Companies',
|
title: 'Companies',
|
||||||
@ -10,10 +13,28 @@ const component = {
|
|||||||
|
|
||||||
export default component;
|
export default component;
|
||||||
|
|
||||||
|
const mocks = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: GET_COMPANIES,
|
||||||
|
variables: {
|
||||||
|
orderBy: [{ name: 'asc' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: {
|
||||||
|
data: {
|
||||||
|
companies: defaultData,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export const CompaniesDefault = () => (
|
export const CompaniesDefault = () => (
|
||||||
<ThemeProvider theme={lightTheme}>
|
<MockedProvider mocks={mocks}>
|
||||||
<MemoryRouter>
|
<ThemeProvider theme={lightTheme}>
|
||||||
<Companies />
|
<MemoryRouter>
|
||||||
</MemoryRouter>
|
<Companies />
|
||||||
</ThemeProvider>
|
</MemoryRouter>
|
||||||
|
</ThemeProvider>
|
||||||
|
</MockedProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
17
front/src/pages/companies/__stories__/mock-data.ts
Normal file
17
front/src/pages/companies/__stories__/mock-data.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { GraphqlQueryCompany } from '../../../interfaces/company.interface';
|
||||||
|
|
||||||
|
export const defaultData: Array<GraphqlQueryCompany> = [
|
||||||
|
{
|
||||||
|
id: 'f121ab32-fac4-4b8c-9a3d-150c877319c2',
|
||||||
|
name: 'ACME',
|
||||||
|
domain_name: 'example.com',
|
||||||
|
account_owner: {
|
||||||
|
id: '91510aa5-ede6-451f-8029-a7fa69e4bad6',
|
||||||
|
email: 'john@example.com',
|
||||||
|
displayName: 'John Doe',
|
||||||
|
},
|
||||||
|
employees: 10,
|
||||||
|
address: '1 Infinity Loop, 95014 Cupertino, California',
|
||||||
|
created_at: new Date().toUTCString(),
|
||||||
|
},
|
||||||
|
];
|
||||||
@ -1,10 +1,15 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render, waitFor } from '@testing-library/react';
|
||||||
|
|
||||||
import { CompaniesDefault } from '../__stories__/Companies.stories';
|
import { CompaniesDefault } from '../__stories__/Companies.stories';
|
||||||
|
|
||||||
it('Checks the Companies page render', () => {
|
it('Checks the Companies page render', async () => {
|
||||||
const { getByTestId } = render(<CompaniesDefault />);
|
const { getByTestId } = render(<CompaniesDefault />);
|
||||||
|
|
||||||
const title = getByTestId('top-bar-title');
|
const title = getByTestId('top-bar-title');
|
||||||
expect(title).toHaveTextContent('Companies');
|
expect(title).toHaveTextContent('Companies');
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
const row = getByTestId('row-id-0');
|
||||||
|
expect(row).toBeDefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
116
front/src/pages/companies/companies-table.tsx
Normal file
116
front/src/pages/companies/companies-table.tsx
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import { createColumnHelper } from '@tanstack/react-table';
|
||||||
|
import { Company } from '../../interfaces/company.interface';
|
||||||
|
import { OrderByFields } 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 ClickableCell from '../../components/table/ClickableCell';
|
||||||
|
import PersonChip from '../../components/chips/PersonChip';
|
||||||
|
import { SortType } from '../../components/table/table-header/interface';
|
||||||
|
|
||||||
|
export const sortsAvailable = [
|
||||||
|
{
|
||||||
|
key: 'name',
|
||||||
|
label: 'Name',
|
||||||
|
icon: undefined,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'domain_name',
|
||||||
|
label: 'Domain',
|
||||||
|
icon: undefined,
|
||||||
|
},
|
||||||
|
] satisfies Array<SortType<OrderByFields>>;
|
||||||
|
|
||||||
|
const columnHelper = createColumnHelper<Company>();
|
||||||
|
export const companiesColumns = [
|
||||||
|
columnHelper.accessor('name', {
|
||||||
|
header: () => <ColumnHead viewName="Name" />,
|
||||||
|
cell: (props) => (
|
||||||
|
<HorizontalyAlignedContainer>
|
||||||
|
<Checkbox
|
||||||
|
id={`company-selected-${props.row.original.id}`}
|
||||||
|
name={`company-selected-${props.row.original.id}`}
|
||||||
|
/>
|
||||||
|
<CompanyChip
|
||||||
|
name={props.row.original.name}
|
||||||
|
picture={`https://www.google.com/s2/favicons?domain=${props.row.original.domain_name}&sz=256`}
|
||||||
|
/>
|
||||||
|
</HorizontalyAlignedContainer>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor('employees', {
|
||||||
|
header: () => <ColumnHead viewName="Employees" />,
|
||||||
|
cell: (props) => (
|
||||||
|
<EditableCell
|
||||||
|
content={props.row.original.employees.toFixed(0)}
|
||||||
|
changeHandler={(value) => {
|
||||||
|
const company = props.row.original;
|
||||||
|
company.employees = parseInt(value);
|
||||||
|
// TODO: update company
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor('domain_name', {
|
||||||
|
header: () => <ColumnHead viewName="URL" />,
|
||||||
|
cell: (props) => (
|
||||||
|
<EditableCell
|
||||||
|
content={props.row.original.domain_name}
|
||||||
|
changeHandler={(value) => {
|
||||||
|
const company = props.row.original;
|
||||||
|
company.domain_name = value;
|
||||||
|
// TODO: update company
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor('address', {
|
||||||
|
header: () => <ColumnHead viewName="Address" />,
|
||||||
|
cell: (props) => (
|
||||||
|
<EditableCell
|
||||||
|
content={props.row.original.address}
|
||||||
|
changeHandler={(value) => {
|
||||||
|
const company = props.row.original;
|
||||||
|
company.address = value;
|
||||||
|
// TODO: update company
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor('opportunities', {
|
||||||
|
header: () => <ColumnHead viewName="Opportunities" />,
|
||||||
|
cell: (props) => (
|
||||||
|
<HorizontalyAlignedContainer>
|
||||||
|
{props.row.original.opportunities.map((opportunity) => (
|
||||||
|
<PipeChip name={opportunity.name} picture={opportunity.icon} />
|
||||||
|
))}
|
||||||
|
</HorizontalyAlignedContainer>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor('creationDate', {
|
||||||
|
header: () => <ColumnHead viewName="Creation" viewIcon={faCalendar} />,
|
||||||
|
cell: (props) => (
|
||||||
|
<ClickableCell href="#">
|
||||||
|
{new Intl.DateTimeFormat(undefined, {
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
}).format(props.row.original.creationDate)}
|
||||||
|
</ClickableCell>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor('accountOwner', {
|
||||||
|
header: () => <ColumnHead viewName="Account Owner" />,
|
||||||
|
cell: (props) => (
|
||||||
|
<HorizontalyAlignedContainer>
|
||||||
|
<PersonChip
|
||||||
|
name={`${props.row.original.accountOwner.first_name} ${props.row.original.accountOwner.last_name}`}
|
||||||
|
/>
|
||||||
|
</HorizontalyAlignedContainer>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
];
|
||||||
1
front/src/services/companies/index.ts
Normal file
1
front/src/services/companies/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './select';
|
||||||
12
front/src/services/companies/select.test.ts
Normal file
12
front/src/services/companies/select.test.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { CompaniesSelectedSortType, reduceSortsToOrderBy } from './select';
|
||||||
|
|
||||||
|
describe('reduceSortsToOrderBy', () => {
|
||||||
|
it('should return an array of objects with the id as key and the order as value', () => {
|
||||||
|
const sorts = [
|
||||||
|
{ key: 'name', label: 'name', order: 'asc' },
|
||||||
|
{ key: 'domain_name', label: 'domain_name', order: 'desc' },
|
||||||
|
] satisfies CompaniesSelectedSortType[];
|
||||||
|
const result = reduceSortsToOrderBy(sorts);
|
||||||
|
expect(result).toEqual([{ name: 'asc', domain_name: 'desc' }]);
|
||||||
|
});
|
||||||
|
});
|
||||||
56
front/src/services/companies/select.ts
Normal file
56
front/src/services/companies/select.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import { QueryResult, gql, useQuery } from '@apollo/client';
|
||||||
|
import { Order_By, Companies_Order_By } from '../../generated/graphql';
|
||||||
|
import { GraphqlQueryCompany } from '../../interfaces/company.interface';
|
||||||
|
import { SelectedSortType } from '../../components/table/table-header/interface';
|
||||||
|
|
||||||
|
export type OrderByFields = keyof Companies_Order_By | 'domain_name' | 'name';
|
||||||
|
|
||||||
|
export type CompaniesSelectedSortType = SelectedSortType<OrderByFields>;
|
||||||
|
|
||||||
|
const mapOrder = (order: 'asc' | 'desc'): Order_By => {
|
||||||
|
return order === 'asc' ? Order_By.Asc : Order_By.Desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const reduceSortsToOrderBy = (
|
||||||
|
sorts: Array<CompaniesSelectedSortType>,
|
||||||
|
): Companies_Order_By[] => {
|
||||||
|
const mappedSorts = sorts.reduce((acc, sort) => {
|
||||||
|
const id = sort.key;
|
||||||
|
const order = mapOrder(sort.order);
|
||||||
|
acc[id] = order;
|
||||||
|
return acc;
|
||||||
|
}, {} as Companies_Order_By);
|
||||||
|
return [mappedSorts];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GET_COMPANIES = gql`
|
||||||
|
query GetCompanies($orderBy: [companies_order_by!]) {
|
||||||
|
companies(order_by: $orderBy) {
|
||||||
|
id
|
||||||
|
domain_name
|
||||||
|
name
|
||||||
|
created_at
|
||||||
|
address
|
||||||
|
employees
|
||||||
|
account_owner {
|
||||||
|
id
|
||||||
|
email
|
||||||
|
displayName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function useCompaniesQuery(
|
||||||
|
orderBy: Companies_Order_By[],
|
||||||
|
): QueryResult<{ companies: GraphqlQueryCompany[] }> {
|
||||||
|
return useQuery<{ companies: GraphqlQueryCompany[] }>(GET_COMPANIES, {
|
||||||
|
variables: { orderBy },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultOrderBy: Companies_Order_By[] = [
|
||||||
|
{
|
||||||
|
name: Order_By.Asc,
|
||||||
|
},
|
||||||
|
];
|
||||||
@ -129,6 +129,14 @@ array_relationships:
|
|||||||
table:
|
table:
|
||||||
name: user_providers
|
name: user_providers
|
||||||
schema: auth
|
schema: auth
|
||||||
|
select_permissions:
|
||||||
|
- role: user
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- display_name
|
||||||
|
- email
|
||||||
|
- id
|
||||||
|
filter: {}
|
||||||
event_triggers:
|
event_triggers:
|
||||||
- name: user-created
|
- name: user-created
|
||||||
definition:
|
definition:
|
||||||
|
|||||||
@ -2,6 +2,15 @@ table:
|
|||||||
name: companies
|
name: companies
|
||||||
schema: public
|
schema: public
|
||||||
object_relationships:
|
object_relationships:
|
||||||
|
- name: account_owner
|
||||||
|
using:
|
||||||
|
manual_configuration:
|
||||||
|
column_mapping:
|
||||||
|
account_owner_id: id
|
||||||
|
insertion_order: null
|
||||||
|
remote_table:
|
||||||
|
name: users
|
||||||
|
schema: auth
|
||||||
- name: workspace
|
- name: workspace
|
||||||
using:
|
using:
|
||||||
foreign_key_constraint_on: workspace_id
|
foreign_key_constraint_on: workspace_id
|
||||||
@ -14,6 +23,9 @@ insert_permissions:
|
|||||||
columns:
|
columns:
|
||||||
- id
|
- id
|
||||||
- workspace_id
|
- workspace_id
|
||||||
|
- account_owner_id
|
||||||
|
- address
|
||||||
|
- employees
|
||||||
- name
|
- name
|
||||||
- domain_name
|
- domain_name
|
||||||
- created_at
|
- created_at
|
||||||
@ -25,6 +37,9 @@ select_permissions:
|
|||||||
columns:
|
columns:
|
||||||
- domain_name
|
- domain_name
|
||||||
- name
|
- name
|
||||||
|
- account_owner_id
|
||||||
|
- address
|
||||||
|
- employees
|
||||||
- created_at
|
- created_at
|
||||||
- deleted_at
|
- deleted_at
|
||||||
- updated_at
|
- updated_at
|
||||||
@ -39,6 +54,9 @@ update_permissions:
|
|||||||
columns:
|
columns:
|
||||||
- domain_name
|
- domain_name
|
||||||
- name
|
- name
|
||||||
|
- employees
|
||||||
|
- address
|
||||||
|
- account_owner_id
|
||||||
- created_at
|
- created_at
|
||||||
- deleted_at
|
- deleted_at
|
||||||
- updated_at
|
- updated_at
|
||||||
|
|||||||
@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."companies" add column "account_owner_id" uuid
|
||||||
|
-- null;
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."companies" add column "account_owner_id" uuid
|
||||||
|
null;
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."companies" add column "employees" integer
|
||||||
|
-- not null default '1';
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."companies" add column "employees" integer
|
||||||
|
not null default '1';
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."companies" add column "address" text
|
||||||
|
-- null;
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."companies" add column "address" text
|
||||||
|
null;
|
||||||
@ -0,0 +1 @@
|
|||||||
|
alter table "public"."companies" drop constraint "companies_account_owner_id_fkey";
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
alter table "public"."companies"
|
||||||
|
add constraint "companies_account_owner_id_fkey"
|
||||||
|
foreign key ("account_owner_id")
|
||||||
|
references "auth"."users"
|
||||||
|
("id") on update set null on delete set null;
|
||||||
Reference in New Issue
Block a user