@sparklink-pro/apant
Version:
Apollo & Antd tools
272 lines (214 loc) • 14.8 kB
Markdown
# apant
Apollo & Antd tools
## Table of Contents
* [Installation](#installation)
* [Live demo](#live-demo)
* [Usage](#usage)
* [Working locally with apant](#working-locally-with-apant)
* [Tests](#tests)
## Usage
```ts
import { TypesContext, TypesRegistry, useTypeList } from "apant";
import client from "./apollo";
import operations from "./gql";
import types from "./types";
const typesRegistry = new TypesRegistry({ types, operations, apollo: client });
const Root = () => (
<TypesContext.Provider value={typesRegistry}>
<YourApp />
</TypesContext.Provider>
);
```
### [TypesRegistryConfiguration](./src/definitions.ts#TypesRegistryConfiguration)
| Property | Description | Type | Default |
| :-----------: | :-----------------------------: | :----------------------------------------------------------------: | :-----: |
| apollo | Apollo client instance | ApolloClient\<NormalizedCacheObject> | - |
| configuration | GraphQL Operation configuration | Partial<[TypeOperationConfiguration](#TypeOperationConfiguration)> | - |
| operations | GraphQL Operation file | { [name: string]: any }; | - |
| types | List of types configuration | { [type: string]: TypeConfiguration } | - |
#### example type
```ts
//types/index.ts
import { Foo } from "./Foo";
export default {
foo
};
// example/src/types/Book.ts
import { TypeConfiguration } from 'apant';
const Book: TypeConfiguration = {
label: 'title',
search: 'title',
admin: {
route: 'admin/Book',
searchable: true,
selectable: true,
filter(pattern: any) {
return pattern.rank >= 9;
},
columns: () => [
{
title: 'Title',
dataIndex: 'title',
link: true,
},
{
title: 'Description',
dataIndex: 'description',
},
{
title: 'Price',
dataIndex: 'price',
sorter: {
compare: (a: any, b: any) => a.price - b.price,
},
},
],
},
forms: {
default: {
props: {
layout: 'vertical',
},
fields: [
{ name: 'title', label: 'Title' },
{ name: 'description', label: 'Description' },
{ name: 'price', label: 'Price', widget:'number' },
{ name: 'rank', label: 'Rank' },
{ name: 'author', label: 'Author',widget: {widget:'select_type', expand:true , type: 'Author'}},
{ name: 'genres', label: 'Genre', widget: {widget:'select_types', expand:true, type: 'Genre'}},
],
},
},
};
export default Book;
```
### [TypeOperationConfiguration](./src/definitions.ts#TypeOperationConfiguration)
| Property | Description | Type | Default |
| :--------: | :---------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------: |
| admin | admin configuration | [TypeConfigurationAdmin](#TypeConfigurationAdmin) | - |
| forms | A list of configured forms for this types | { [formName: string]: <[FormConfigurationType](#FormConfigurationType) } | - |
| id | What is the id property for this type? | string | id |
| label | For selectType | string\|() =>string\|React.ReactNode) | '\_name' property |
| metadata | Additional configuration for this type | { [key: string]: any } | - |
| operations | Operation configuration for given type | Partial\<[TypeOperationConfiguration](./src/definitions.ts#TypeOperationConfiguration)> | - |
| order | For SelectType | order:string\| {[field:string]:'asc'\|'desc'} | 'asc' |
| search | search in type | string\|string[] \| ((object:[GraphQLObject](./src/definitions.ts#GraphQLObject),context?:any)=>string)\|{custom:(object:[GraphQLObject](./src/definitions.ts#GraphQLObject),search:string,context?:any)=>boolean} | - |
| select | Select type widget configuration | { label: any; fragment: any }; | - |
### [TypeConfigurationAdmin](./src/definitions.ts#TypeConfigurationAdmin)
| Property | Description | Type | Default |
| :-------------: | :--------------------------: | :--------------------------------------------------------------------------: | :-----: |
| columns | the configColumns | ()=>Promise<ColumnsType>\|<br>ColumnsType(see AntDesign) | - |
| creatable | allows to create new items | bool | true |
| filter | Filter items | (item:object)=>boolean | - |
| footerComponent | Custom footer | React.ComponentType<[AdminHeaderType](./src/definitions.ts#AdminFooterType)> | - |
| headerComponent | Custom header | React.ComponentType<[AdminHeaderType](./src/definitions.ts#AdminHeaderType)> | - |
| route | | string | - |
| searchable | Allow to search in this type | bool | true |
| selectable | Allow to select | bool | true |
| props | | TableProps<[GraphQLObject](./src/definitions.ts#GraphQLObject)> | - |
### [FormConfigurationType](./src/definitions.ts#FormConfigurationType)
| Property | Description | Type | Default |
| :------: | :---------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----: |
| fields | the fields | [FormEntryType](./src/definitions.ts#FormEntryType)[] \| ((context: [FormContextType](./src/definitions.ts#FormContextType)) => FormEntryType[]); | - |
| props | | props?: Omit\<FormProps, 'onFinish'> \| ((context: [FormContextType](./src/definitions.ts#FormContextType)) => Omit\<FormProps, 'onFinish'>); | - |
| mappers | | [FormFieldMapperType](./src/definitions.ts#FormFieldMapperType)[] \| ((context: [FormContextType](./src/definitions.ts#FormContextType)) => [FormFieldMapperType](./src/definitions.ts#FormFieldMapperType)[]) | - |
### [FormFieldExtraType](./src/definitions.ts#FormFieldExtraType)
| Property | Description | Type | Default |
| :----------: | :---------------------------------------------------------------------------: | :-------------------------------------------------------------------------------: | :-----: |
| auto | Should this field be display when the related form is diplayed automatically? | bool | false |
| group | Is the field parts of a group ? | bool | false |
| initialValue | What is the initial/default value of the field? | ((context:[FormContextType](./src/definitions.ts#FormContextType)) => any) \|any; | - |
| list | Is this field a list (ie. Form.List from antd) | bool | false |
| mapped | Should this field be removed before submitting? | boolean \| ((context: FormContextType) => boolean \| Promise<boolean>); | true |
| auto | Should this field be display when the related form is diplayed automatically? | boolean \| ((context: FormContextType) => boolean \| ); | true |
### Use [AdminType](./src/components/AdminType.tsx#AdminType)
```tsx
<AdminType
key={type}
type={type}
heights={{ offset: 16 }}
{...getDefaultTableProps()}
/>
```
### Use [Form](./src/components/Form.tsx#Form)
Basic use, if you want further customization, see our [demo](#live-demo).
```tsx
const formConfig = {
props: { layout: "vertical" },
fields: [
{
name: "name",
label: "Nom",
required: true,
rules: [{ required: true }],
initialValue: "Ode"
},
{ name: "firstname", label: "Prénom", initialValue: "Jack" },
{ name: ['position','name'], label: 'Position'},
]
};
const object = {
name: 'Doe',
city: 'Paris',
position:{
name: 'Software Engineer',
company: 'Google'
},
};
//...
<Form
config={formConfig}
onFinish={values => console.log(values)}
context={{ object }}
footer={
<div className="text-center">
<Button type="primary" htmlType="submit">
Sauvegarder
</Button>
</div>
}
/>
);
```
| Property | Description | Type | Default |
| :--------------------------------------: | :-----------------------------------: | :-----------------------------------------------------------------------------------------------------: | :-----: |
| children | | React.ReactNode \|((fields: FormEntryResolvedType[], form: FormInstance) => React ReactNode) | - |
| config | Configuration of the form | FormConfigurationType | - |
| context | Context of the form | Omit<[FormContextType](./src/definitions.ts#FormContextType), 'form'> | - |
| formProps | Additional form Props | Partial\<FormAntProps> | - |
| footer | the footer | React.ReactNode | - |
| header | the header | React.ReactNode | - |
| onValue | Process form values before submitting | (values: object, context: [FormContextType](./src/definitions.ts#FormContextType)) => Promise\<object>; | |
| & <b>Omit\<FormAntProps, 'children'></b> | | | |
## Working locally with apant
Working locally with apant relies on `yalc` and `yarn`.
First, you neeed to compile the project.
```bash
$ cd apant
$ yarn
$ yarn build
```
Then, you'll need to publish the project with `yalc`.
```bash
$ yalc publish
apant@xxx published in store.
```
The project is now in the yalc store and is available to use for other project.
### Use the `apant` in your project
To use the library in your local project, you need to link it with `yalc`.
```bash
$ cd myproject/
$ yalc link apant
```
`apant` is now linked to the project.
### Work in realtime
To work and use apant in realtime, we must watch `apant` for change, compile it and publish it the `yalc` store.
To do so, we use the npm command defined in the `package.json` by
```json
"watch-publish": "tsc-watch --onSuccess \"yalc push\""
```
```bash
$ cd apant/
$ yarn watch-publish
```
## Test