Setup GraphQL Code Generator (#74)
* chore: add types of schema * Ease codegen use on FE * chore: ignore prettier in generated files * lint: generated files * feature: strongly type filter of query * chore: ignore generated files in prettier * chore: eslint ignore generated files --------- Co-authored-by: Sammy Teillet <sammy.teillet@gmail.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
1
.prettierignore
Normal file
1
.prettierignore
Normal file
@ -0,0 +1 @@
|
||||
**/generated/*
|
||||
@ -17,7 +17,8 @@ module.exports = {
|
||||
node: true,
|
||||
jest: true,
|
||||
},
|
||||
ignorePatterns: ['.eslintrc.js'],
|
||||
|
||||
ignorePatterns: ['.eslintrc.js', 'codegen.js', '**/generated/*'],
|
||||
rules: {
|
||||
'@typescript-eslint/interface-name-prefix': 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
|
||||
28
front/codegen.js
Normal file
28
front/codegen.js
Normal file
@ -0,0 +1,28 @@
|
||||
module.exports = {
|
||||
schema: [
|
||||
{
|
||||
[process.env.HASURA_GRAPHQL_ENDPOINT]: {
|
||||
headers: {
|
||||
'x-hasura-admin-secret': process.env.HASURA_GRAPHQL_ADMIN_SECRET,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
documents: ['./src/**/*.tsx', './src/**/*.ts'],
|
||||
overwrite: true,
|
||||
generates: {
|
||||
'./src/generated/graphql.tsx': {
|
||||
plugins: [
|
||||
'typescript',
|
||||
'typescript-operations',
|
||||
'typescript-react-apollo',
|
||||
],
|
||||
config: {
|
||||
skipTypename: false,
|
||||
withHooks: true,
|
||||
withHOC: false,
|
||||
withComponent: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
5279
front/graphql.schema.json
Normal file
5279
front/graphql.schema.json
Normal file
File diff suppressed because it is too large
Load Diff
2732
front/package-lock.json
generated
2732
front/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -33,7 +33,8 @@
|
||||
"storybook": "storybook dev -p 6006 -s public",
|
||||
"build-storybook": "storybook build -s public",
|
||||
"coverage": "react-scripts test --coverage --watchAll",
|
||||
"coverage-ci": "react-scripts test --coverage --watchAll=false"
|
||||
"coverage-ci": "react-scripts test --coverage --watchAll=false",
|
||||
"graphql-generate": "REACT_APP_GRAPHQL_ADMIN_SECRET=$REACT_APP_GRAPHQL_ADMIN_SECRET graphql-codegen --config codegen.js"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
@ -80,6 +81,10 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/cli": "^3.3.1",
|
||||
"@graphql-codegen/typescript": "^3.0.4",
|
||||
"@graphql-codegen/typescript-operations": "^3.0.4",
|
||||
"@graphql-codegen/typescript-react-apollo": "^3.3.7",
|
||||
"@storybook/addon-actions": "^7.0.2",
|
||||
"@storybook/addon-essentials": "^7.0.2",
|
||||
"@storybook/addon-interactions": "^7.0.2",
|
||||
|
||||
5397
front/src/generated/graphql.tsx
Normal file
5397
front/src/generated/graphql.tsx
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,8 +6,8 @@ import { peopleColumns, sortsAvailable } from './people-table';
|
||||
import { mapPerson } from '../../interfaces/person.interface';
|
||||
import { useCallback, useState } from 'react';
|
||||
import {
|
||||
OrderBy,
|
||||
PeopleSelectedSortType,
|
||||
defaultOrderBy,
|
||||
reduceSortsToOrderBy,
|
||||
usePeopleQuery,
|
||||
} from '../../services/people';
|
||||
@ -17,12 +17,6 @@ const StyledPeopleContainer = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const defaultOrderBy: OrderBy[] = [
|
||||
{
|
||||
created_at: 'desc',
|
||||
},
|
||||
];
|
||||
|
||||
function People() {
|
||||
const [, setSorts] = useState([] as Array<PeopleSelectedSortType>);
|
||||
const [orderBy, setOrderBy] = useState(defaultOrderBy);
|
||||
|
||||
@ -1,36 +1,32 @@
|
||||
import { QueryResult, gql, useQuery } from '@apollo/client';
|
||||
import { GraphqlQueryPerson } from '../../interfaces/person.interface';
|
||||
import { SelectedSortType } from '../../components/table/table-header/SortAndFilterBar';
|
||||
import { Order_By, People_Order_By } from '../../generated/graphql';
|
||||
|
||||
export type OrderByFields =
|
||||
| keyof GraphqlQueryPerson
|
||||
| 'fullname'
|
||||
| 'company_name';
|
||||
|
||||
export type OrderBy = Partial<{
|
||||
[key in keyof GraphqlQueryPerson]:
|
||||
| 'asc'
|
||||
| 'desc'
|
||||
| { [key in string]: 'asc' | 'desc' };
|
||||
}>;
|
||||
export type OrderByFields = keyof People_Order_By | 'fullname' | 'company_name';
|
||||
|
||||
export type PeopleSelectedSortType = SelectedSortType<OrderByFields>;
|
||||
|
||||
const mapOrder = (order: 'asc' | 'desc'): Order_By => {
|
||||
return order === 'asc' ? Order_By.Asc : Order_By.Desc;
|
||||
};
|
||||
|
||||
export const reduceSortsToOrderBy = (
|
||||
sorts: Array<PeopleSelectedSortType>,
|
||||
): OrderBy[] => {
|
||||
): People_Order_By[] => {
|
||||
const mappedSorts = sorts.reduce((acc, sort) => {
|
||||
const id = sort.id;
|
||||
const order = mapOrder(sort.order);
|
||||
if (id === 'fullname') {
|
||||
acc['firstname'] = sort.order;
|
||||
acc['lastname'] = sort.order;
|
||||
acc['firstname'] = order;
|
||||
acc['lastname'] = order;
|
||||
} else if (id === 'company_name') {
|
||||
acc['company'] = { company_name: sort.order };
|
||||
acc['company'] = { company_name: order };
|
||||
} else {
|
||||
acc[id] = sort.order;
|
||||
acc[id] = order;
|
||||
}
|
||||
return acc;
|
||||
}, {} as OrderBy);
|
||||
}, {} as People_Order_By);
|
||||
return [mappedSorts];
|
||||
};
|
||||
|
||||
@ -54,9 +50,15 @@ export const GET_PEOPLE = gql`
|
||||
`;
|
||||
|
||||
export function usePeopleQuery(
|
||||
orderBy: OrderBy[],
|
||||
orderBy: People_Order_By[],
|
||||
): QueryResult<{ people: GraphqlQueryPerson[] }> {
|
||||
return useQuery<{ people: GraphqlQueryPerson[] }>(GET_PEOPLE, {
|
||||
variables: { orderBy },
|
||||
});
|
||||
}
|
||||
|
||||
export const defaultOrderBy: People_Order_By[] = [
|
||||
{
|
||||
created_at: Order_By.Desc,
|
||||
},
|
||||
];
|
||||
|
||||
@ -12,6 +12,7 @@ HASURA_AUTH_GRAPHQL_URL: http://twenty-hasura:8080/v1/graphql
|
||||
|
||||
FRONT_REACT_APP_API_URL=http://localhost:8080
|
||||
FRONT_REACT_APP_AUTH_URL=http://localhost:4000
|
||||
FRONT_HASURA_GRAPHQL_ENDPOINT=http://twenty-hasura:8080/v1/graphql
|
||||
|
||||
SERVER_HASURA_EVENT_HANDLER_SECRET_HEADER: secret
|
||||
SERVER_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/default
|
||||
|
||||
@ -27,6 +27,9 @@ front-coverage: ##
|
||||
front-storybook: ##
|
||||
@docker-compose exec twenty-front sh -c "npm run storybook"
|
||||
|
||||
front-graphql-generate: ##
|
||||
@docker-compose exec twenty-front sh -c "npm run graphql-generate"
|
||||
|
||||
## Hasura
|
||||
|
||||
hasura-logs: ##
|
||||
|
||||
@ -8,8 +8,10 @@ services:
|
||||
- "3001:3001"
|
||||
- "6006:6006"
|
||||
environment:
|
||||
- REACT_APP_API_URL=${FRONT_REACT_APP_API_URL}
|
||||
- REACT_APP_AUTH_URL=${FRONT_REACT_APP_AUTH_URL}
|
||||
REACT_APP_API_URL: ${FRONT_REACT_APP_API_URL}
|
||||
REACT_APP_AUTH_URL: ${FRONT_REACT_APP_AUTH_URL}
|
||||
HASURA_GRAPHQL_ENDPOINT: ${FRONT_HASURA_GRAPHQL_ENDPOINT}
|
||||
HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET}
|
||||
volumes:
|
||||
- ../../front:/app/front
|
||||
- twenty_node_modules_front:/app/front/node_modules
|
||||
|
||||
@ -2,7 +2,10 @@ FROM node:18.16.0-alpine as front
|
||||
|
||||
RUN apk update && apk upgrade && \
|
||||
apk add --no-cache bash git openssh && \
|
||||
apk add libc6-compat
|
||||
apk add libc6-compat \
|
||||
apk add python3 \
|
||||
apk add make \
|
||||
apk add g++
|
||||
|
||||
WORKDIR /app/front
|
||||
|
||||
|
||||
Reference in New Issue
Block a user