reactive-resource

0.0.6-alpha.2.0 • Public • Published

ollieorder

WIP

Setup

nvm use 10.17
yarn
yarn run lerna bootstrap

Run Storybook

yarn lerna run story --stream

Run Tests

yarn test

Develop with another repo locally (assuming Rails)

  1. First make sure your app and reactive-resource are in same folder

  2. Add the following to your tsconfig.json, which will cause typescript to resolve imports from reactive-resource

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      ....
      "@reactive-resource/*": ["../reactive-resource/packages/*/src"]
      ...
    },

  1. Add the following to config/webpacker.yml which will cause webpack dev server to find reactive resource
default: &default
  ...
  resolved_paths:  ['../reactive-resource/packages']
  ...
  1. Add the following to your config/webpack/development.js, which will cause the paths you just added to tsconfig to work with webpack module resolution
module.exports = {
  ...
  resolve: {
    ...
    plugins: [
      ...
      new TsconfigPathsPlugin({
        extensions: environment.config.resolve.extensions,
        configFile: path.resolve(__dirname, "../../tsconfig.json")
      })
    ],
  },

Then make changes to RR and your other repo will be updated, tada!

Publish

yarn run lerna publish

Proposal

ReactiveResource's goal is to make it crazy-fast to build CRUD UI's by hooking up an API to a UI framework via a common schema format

// A connector is a generic function that connects reactive resourc to an API type (rest, gql, json API, etc)
// It's job is to make queries and mutations, provide data, and translate a schema into common RRSchema format

function createGraphqlConnector(options) {
  function useSchema(...) {
      ...
  }

  function useQuery(...) {
      ...
  }

  function useMutation(...) {
      ...
  }

  return {
    useeSchema: useSchema, // Generic function to provide GraphQLSchma whether by querying it or reading from a file
    useQuery: useQuery, // Genric query function
    useMutation: useMutation // Genric mutation funtion
  }
}

// Hook that UI framework specific packages can use to integrate with reactive resource tabls

function useRRCollection({ ...whateverConnectorProps }) {
  const [data, { loading, error } = useRRRequest({ ...whateverConnectorProps })
  const fields = useRRSchema()

  return {
    columns: mapFields,
    data: data
  }
}

// Example of an Ant adapter for a table component

function ReactiveResourceAntTable(props) {
  const { data, columns, onQuery } = useRRCollection()

  return <Table dataSource={data} columns={mapColumnsToAnt(columns, { onFilter: onQuery )} />
}

// Example app

function AppGql() {
  return (
    <ReactiveResourceProvider
      connector={createGraphqlConneector({
        apiUrl: '....'

      })}
      config={{
        BlogPost: {
          sorter: (a, b) => a.title > b.title ? 1 : -1
          components: {
            table: BlogPostCell
          }
        },
        Tag: {
          sorter: (a, b) => a.value > b.value ? 1 : -1
          components: {
            default: Tag
          }
        }
      }}
    >
      <Switch>
        <Route
          to='/'
          component={CollectionContainer}
          query={gql`
            query blogPosts {
              blogPosts {
                id
                title
                body
                tags {
                  value
                }
              }
            }
          `}
          layoutComponent={PageLayout}
        />
        <Route
          to='/:id'
          component={ResourceContainer}
          query={gql`
            query blogPost($id: ID) {
              blogPost(id: $id) {
                id
                title
                body
                tags {
                  value
                }
                author {
                  id
                  name
                }
              }
            }
          `}
          layoutComponent={PageLayout}
        />
        <Route
          to='/new'
          component={FormContainer}
          mutation={CREATE_BLOG_POST_MUTATION}
          layoutComponent={PageLayout}
          mutation={gql`
            mutation createBlogPost($input: CreateBlogPostInput) {
              blogPost(input: $input) {
                id
                title
                body
                tags {
                  value
                }
              }
            }
          `}
        />
        <Route
          to='/:id/edit'
          component={FormContainer}
          query={BLOG_POST_QUERY}
          mutation={UPDATE_BLOG_POST_MUTATION}
          layoutComponent={PageLayout}
          query={gql`
            query blogPost($id: ID) {
              blogPost(id: $id) {
                id
                title
                body
                tags {
                  value
                }
              }
            }
          `}
          mutation={gql`
            mutation createBlogPost($input: CreateBlogPostInput) {
              blogPost(input: $input) {
                id
                title
                body
                tags {
                  value
                }
              }
            }
          `}
        />
      </Switch>
    </ReactiveResourceProvider>
  )
}

# Reactive Resource UI

RR-UI is here to make the bridge between the connector and the view.

# API

## RRProvider

#### RRProvider Options
- `connector: RRConnectorType`: The connector expose all the methods to query/mutate the date and get the schema definition
- `children: ReactNode`: Render the childrens
- `rrConfig: RRUIConfig`: This object allows you to pass some default component for each graphql type. This will be use when we generate the table, form and details view. (ex: `rrComponents: [{Author: { table: AuthorCell, form: AuthorField }}]`)

#### RRProvider Value

- `rrComponents: RRUIComponents`: Default component config depending on the type
- `useQuery`: custom hook to query some remote date
- `useMutation`: custom hook to mutate some remote data

## useRRCollection

`useRRCollection` hook provides the basic data to build a table view. It creates the column based on a query definition or a fragment definition. It also provides the remote data.
To use it you need to pass a query definition or a fragment definition and the dataSource.

#### useRRCollection Options

- `queryOptions`: All the options about the remote data and query/fragment definition
  - `query: OperationDefinitionNode`: Query definition, if you pass a fragment this query will be use to get the refetch function to paginate, filter and sort. (if the query has these features enabled)
  - `fragment?: FragmentDefinitionNode`: Fragment definition
  - `dataSource?: T`: data source linked to the fragment definition
  - `variables?: T`: any variables needed for the query

- `tableOptions?:`: All the options about the list view
  - `columns?: OverrideRRColumn[]`: Used to override the default column generated by this hook.
  - `hiddenFields?: string[]`: Used to hide some columns. By default we display every field passed into the fragment

#### useRRCollection Result

- `rrColumns: RRColumn[]`: All the columns generated by the query or fragment definition
- `data: any[]`: The remote data
- `refetch?: (variables?: any) => Promise<any[]>`: Function to refetch the query

### RRColumns

- `attribute: string`: name of the column. Also use as an index
- `type: string`: Graphql type of the column attribute
- `render: React.Component`: View used to display the date
- `header: React.Component | String`: View to display the header cell of the column

# Reactive Resource Apollo Conncetor

TODO

# Reactive Resource GraphQL Utils

TODO

Readme

Keywords

none

Package Sidebar

Install

npm i reactive-resource

Weekly Downloads

1

Version

0.0.6-alpha.2.0

License

MIT

Unpacked Size

90.8 kB

Total Files

156

Last publish

Collaborators

  • mattvague