Coder Social home page Coder Social logo

frontier-forms's Introduction

Frontier forms npm version

Data-driven forms that let you focus on what matters: your application.

Provide a GraphQL mutation and <Frontier/> will do the rest for you.

Both fast to use and performant ⚡!

➡️ See all capabilites by watching the introduction talk from React Europe 2019!

import gql from "graphql-tag";
import { Frontier } from "frontier-forms";
import { myApplicationKit } from "./uiKit";
import { client } from "./apollo-client";

const mutation = gql`
    mutation($user: User!) {
      createUser(user: $user) { id }
    }
`;

<Frontier
  client={client}
  mutation={mutation}
  uiKit={myApplicationKit}
/>
  • Simple

    You already know how to use Frontier, because it works like other form libraries.
    More, Frontier will bring you the full data lifecycle management, with zero configuration.

  • Scalable

    Just define your Application Frontier UI-kit.
    Then, take advantage of the UI-kit full rendering feature to bring consistent UX to your users.

  • Iterative

    Choose your way to build forms, with or without Frontier UI-kit.
    Frontier will adapt to your needs.


Installation

In order to use Frontier, you will need:

  • react (^16.8.6)
  • apollo-client (^2.5.1)
  • graphql-tag (^2.10.1)

Then, install frontier-forms:

yarn add frontier-forms

OR

npm i frontier-forms

Links

frontier-forms's People

Contributors

charlypoly avatar chmelevskij avatar melvinkcx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

frontier-forms's Issues

Supporting other GraphQL clients

Just wondering what sort of graphql clients you support. The docs only demonstrate for Apollo Client.
We are using a mix of Apollo Client and Amplify GraphQL client.

import { client } from "./apollo-client";

const mutation = gql`
    mutation($user: User!) {
      createUser(user: $user) { id }
    }
`;

<Frontier
  client={client}
  mutation={mutation}
  uiKit={myApplicationKit}
/>

The Amplify Client

import API, { graphqlOperation } from "@aws-amplify/api";

const mutation = gql`
    mutation($user: User!) {
      createUser(user: $user) { id }
    }
`;

await API.graphql(graphqlOperation(mutation, { input: dd }));

How would I hook this up to frontier forms?

Error: Element type is invalid

I'm trying to get a barebone form up and running but I'm getting the following error when I try to use <Frontier />:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

If I remove the the <Frontier /> component the rest of the app renders correctly so everything else seem to be in order.

Has there maybe been changes to the project that is not reflected in the documentation?

This is the code that produces the error:

import withApolloClient from "../../../lib/with-apollo-client";
import gql from "graphql-tag";
import Frontier from "frontier-forms";
import { myApplicationKit } from "../formUiKit";

const CREATE_USER = gql`
  mutation($email: String!, $password: String!) {
    registerUser(user: { email: $email, password: $password }) {
      success
      message
      user {
        id
      }
    }
  }
`;

const UserForm = ({ apolloClient }) => {
  return (
    <div>
      <Frontier
        mutation={CREATE_USER}
        client={apolloClient}
        uiKit={myApplicationKit}
      />
    </div>
  );
};

export default withApolloClient(UserForm);

how to access apollo error in form

I have a situation where the resolver of a mutation can raise errors based on reasons not related to input fields.
The apollo mutation raises that error, but I seem to not have a way to access errors that are not related to fields.

Any idea how I can access those?

[SUGGESTION] Show error message/logs when Frontier/Apollo Client failed to connect to API endpoint

When I first added Frontier, I copied and paste the example code from the documentation, it works perfectly fine. However, when I changed the Apollo Client to point to another port in my localhost, the UI stopped being rendered, and no error messages are found.

After spending some time debugging, I realize my React proxy is not properly set up, thus I got a network error as such:
DeepinScreenshot_select-area_20191111115508

Suggestions for situation like this would be:

  1. writing some logs to the console when an error has occurred internally,
  2. render the components despite errors caused by Apollo Client

v1 API documentation

It's super important for us to stick to a target API design by writing a API documentation.
This should include:

  • available components (+ props for each)
  • other APIs

key missing

Two things came to my attention while inspecting the demo and playing around with an own instance:
https://codesandbox.io/s/7j3xo3qy26

console output:

Warning: Each child in a list should have a unique "key" prop.

Check the render method of `Frontier`. See https://fb.me/react-warning-keys for more information.
    in Unknown
    in Frontier (created by App)
    in div (created by App)
    in div (created by App)
    in div (created by App)
    in App

You can also use "frontier-forms": "0.1.1" in package.json.

  1. What is the purpose of <Unknown/> ?
  2. key attribute seems to be missing for each item

image

0.1.0 roadmap

Hi everyone 👋

This issue will list the selected improvements and fixes for the next version.
Feel free to add feature request in comment!

Better callback React props

Many callbacks necessary to handle properly forms are missing or not well-implemented.
➡️ #24 , #18,

Improvements on GraphQL mutation parsing

The current version of Frontier rely on the mutation name in order to get the schema.
This leads to some hard-to-catch error when the provided mutation (gql mutation) does not match exactly the mutation defined on the API.

A backward-compatible refactoring that will rely on the provided mutation and use the remote schema for custom-types only will allow:

  • to have a more solid parsing of the GQL mutation
  • to dig into supporting variables subset #12

Internal architecture refactoring to welcome future flavours

A little backward-compatible refactoring of the internal architecture of the project is required in order to welcome more flavours on the Frontier project: Vue, React Native and Angular.

Bug fixes

The following bug need to be fixed:

  • Missing dependency graphql #15
  • Error handling doesn't work with input objects #13

Ability to work with mutations that includes fragments

Hi! First of all I would like to say that I really like this package and it would be glad if it will continue developing.
Unfortunately my mutations includes fragments and I get a warning "please provide 1 mutation document" in console. I dig a little bit in this, and found out that this is caused by "getMutationNameFromDocumentNode" function in this if-else case:
if (mutation.definitions.length > 1) {
so I think it is better firstly to filter all mutation definitions that they will match that their type is exactly mutation.

Improvements on GraphQL mutation parsing

The current version of Frontier rely on the mutation name in order to get the schema.
This leads to some hard-to-catch error when the provided mutation (gql mutation) does not match exactly the mutation defined on the API.

A backward-compatible refactoring that will rely on the provided mutation and use the remote schema for custom-types only will allow:

  • to have a more solid parsing of the GQL mutation
  • Improve handling of input objects with variable subset #12

TypeError: modifiers.save is not a function

Hi I'm trying to make a minimal version of this work. schema loads OK from the server and I get a form rendered but clicking the submit button doesn't work. What am I missing?

import "semantic-ui-css/semantic.min.css";
import React from 'react';
import ApolloClient from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { createHttpLink } from "apollo-link-http";
import { Frontier } from "frontier-forms";
import { Form, Button } from "semantic-ui-react";
import gql from "graphql-tag";

let backend = "http://localhost:4000/graphql";

console.log('using backend', backend);

const client = new ApolloClient({
link: createHttpLink({
// read-only endpoint
uri: backend
}),
cache: new InMemoryCache()
});

function ApplicationForm({ name, oga_no }) {

const mutation = gqlmutation($a:String!, $n:Int) { addBoat(name:$a, oga_no:$n) { name oga_no id } };

return (
<div style={{ paddingLeft: "50px", paddingTop: "50px" }}>
<div style={{ width: "245px" }}>

Add a Boat




<Frontier
initialValues={{ name: "a", oga_no: "1" }}
client={client}
mutation={mutation}
>
{({ state, modifiers }) => {
return (
<Form onSubmit={() => modifiers.save()}>
<Form.Input label="name" onChange={modifiers.name.change}/>
<Form.Input label="number" onChange={modifiers.oga_no.change}/>
Submit

);
}}



);
}
export default ApplicationForm;

=============
TypeError: modifiers.save is not a function
onSubmit
src/ApplicationForm.js:48
45 | >
46 | {({ state, modifiers }) => {
47 | return (

48 | <Form onSubmit={() => modifiers.save()}>
| ^ 49 | <Form.Input label="name" onChange={modifiers.name.change}/>
50 | <Form.Input label="number" onChange={modifiers.oga_no.change}/>
51 | Submit
View compiled
▼ 27 stack frames were expanded.
apply
node_modules/lodash/_apply.js:15
baseInvoke
node_modules/lodash/_baseInvoke.js:21
apply
node_modules/lodash/_apply.js:16
(anonymous function)
node_modules/lodash/_overRest.js:32
(anonymous function)
node_modules/semantic-ui-react/dist/es/collections/Form/Form.js:64
HTMLUnknownElement.callCallback
node_modules/react-dom/cjs/react-dom.development.js:336
invokeGuardedCallbackDev
node_modules/react-dom/cjs/react-dom.development.js:385
invokeGuardedCallback
node_modules/react-dom/cjs/react-dom.development.js:440
invokeGuardedCallbackAndCatchFirstError
node_modules/react-dom/cjs/react-dom.development.js:454
executeDispatch
node_modules/react-dom/cjs/react-dom.development.js:584
executeDispatchesInOrder
node_modules/react-dom/cjs/react-dom.development.js:609
executeDispatchesAndRelease
node_modules/react-dom/cjs/react-dom.development.js:713
executeDispatchesAndReleaseTopLevel
node_modules/react-dom/cjs/react-dom.development.js:722
forEachAccumulated
node_modules/react-dom/cjs/react-dom.development.js:694
runEventsInBatch
node_modules/react-dom/cjs/react-dom.development.js:739
runExtractedPluginEventsInBatch
node_modules/react-dom/cjs/react-dom.development.js:880
handleTopLevel
node_modules/react-dom/cjs/react-dom.development.js:5803
batchedEventUpdates$1
node_modules/react-dom/cjs/react-dom.development.js:24401
batchedEventUpdates
node_modules/react-dom/cjs/react-dom.development.js:1415
dispatchEventForPluginEventSystem
node_modules/react-dom/cjs/react-dom.development.js:5894
attemptToDispatchEvent
node_modules/react-dom/cjs/react-dom.development.js:6010
dispatchEvent
node_modules/react-dom/cjs/react-dom.development.js:5914
unstable_runWithPriority
node_modules/scheduler/cjs/scheduler.development.js:697
runWithPriority$2
node_modules/react-dom/cjs/react-dom.development.js:12149
discreteUpdates$1
node_modules/react-dom/cjs/react-dom.development.js:24417
discreteUpdates
node_modules/react-dom/cjs/react-dom.development.js:1438
dispatchDiscreteEvent
node_modules/react-dom/cjs/react-dom.development.js:5881
▲ 27 stack frames were expanded.
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this erro

Broken documentation links

Hey there! I've been wanting to use this one for a personal project but haven't been able to do so because all the documentation links are broken - not sure if they're under a new domain or something like that. It's been almost 72 hours since the last time I tried and the site is still down.

https://frontier-forms.dev/what-is-frontier

UI-kit render props missing `save` modifier

Is it possible that the save modifier to submit the form is not being provided as expected? I only get the individual field modifiers (change etc.), and could only find those in the code as well.

Return resolved data after form.submit() / saveData()

After calling form.submit(), which underlyingly called saveData(). However, in saveData(), the response from ApolloClient is now relayed back to form.submit(). It is useful to consume response from Mutation is some cases.

DeepinScreenshot_select-area_20191114150102

P/S: I am willing to work on this, I'm using a patched version of frontier-forms for our project now.

Improve handling of input objects with variable subset

#11 (comment)

Do you plan on sticking to the JSON schema from introspection query for the form fields? I was hoping to be able to specify the fields as variables for the mutation instead.

mutation CreateObjectWithName($name: String!) {
    createObject(input: {name: $name}) {
        object {
            id
            name
        }
    }
}

This generates fields for all properties of input, not just name.

It also will not pass the values correctly when submitting the form, meaning that it will never work!

UIKit gets type undefined for custom scalar types (DateTime)

Custom Scalar type Datetime is taken as type undefined in Frontier UI Kit. Also error handling breaks for undefined type?

schema for reference

input CreateLeaveEntry {
  startDate: DateTime!
  endDate: DateTime!
  remarks: String!
}

scalar DateTime

mutation

mutation($leaveEntry: CreateLeaveEntry!) {
  applyForLeave(leaveEntry: $leaveEntry) {
     id
     startDate
     endDate
     status
   }
}

What Could be the issue here?

Add onCompleted prop to Frontier component

Wonderful project! An addition that would be very handy, at least for my use case, would be to add an onCompleted prop to the Frontier component like the one in react-apollo's Mutation:

onCompleted: (data: TData) => void
A callback executed once your mutation successfully completes

That would allow users to do something similar to the below (adapted from the Apollo client tutorial):

<Frontier
  onCompleted={({ login }) => {
    localStorage.setItem('token', login);
    client.writeData({ data: { isLoggedIn: true } });
  }}
  mutation={LOGIN_MUTATION}
  client={client}
  uiKit={applicationKit}
/>

I could try my hand at submitting a pull request if you are interested in adding this feature.

1.0 roadmap

Fixes

Fix API inconsistencies

  • Show error message/logs when Frontier/Apollo Client failed to connect to API endpoint #43
  • TypeError: modifiers.save is not a function #50
  • Return resolved data after form.submit() / saveData() #46
  • Fire event after Frontier is rendered or introspected schema #45
  • how to access apollo error in form #31
  • Add onCompleted prop to Frontier component #24
  • Allow passing props to individual fields in full-rendering mode #21
  • UI-kit render props missing save modifier #18

Bugs

  • UIKit gets type undefined for custom scalar types (DateTime) #40
  • Missing dependency graphql #15
  • Error handling doesn't work with input objects #13

Refactoring

Improvements on GraphQL mutation parsing

Upgrade dependencies

  • Deprecate componentWillMount in Frontier #42
  • React renderer migrate to hooks (internal) #53

Features

  • Support other GraphQL clients #39, #30

[SUGGESTION] Fixing error in code examples

From the code examples for building your own UI kit, a bunch of error are created when onChange is triggered.
DeepinScreenshot_select-area_20191111124016

I spent some time looking into this problem and noticed the code is trying to convert an "uncontrolled component" to a controlled. I'm not sure exactly, which part of the Frontier inner code makes the components "uncontrolled". However, since the inner code assumed input elements are uncontrolled and if we were to preserve such behavior, we should remove value attributes from all the input elements.

I tested the solution of removing value attributes, it works fine and no errors are produced.

Here is a good reference for understanding the differences between both types of components.

Support introspection custom MutationType name

Root mutation can have a "custom name", ex:

{
	"data": {
		"__schema": {
			"__typename": "__Schema",
			"directives": [
                            / * ... */
			],
			"mutationType": {
				"__typename": "__Type",
				"name": "RootMutation"
			},
			"queryType": {
				"__typename": "__Type",
				"name": "RootQuery"
			},
			"subscriptionType": {
				"__typename": "__Type",
				"name": "RootSubscription"
			},
			"types": [
                             / * ... */
			]
		}
	}
}

Change to do here: https://github.com/frontier-forms/frontier-forms/blob/master/lib/data/graphql.ts#L209

email

Any way to annotate specific paths to add some information for Strings that are emails given that this isn't something captured in graphql?

Deprecated React.SFC in documentation

Awesome project! It basically does what I wanted for my project.

I'm just flagging a minor issue in this page and more specifically here. The snippets use React.SFC, which is now deprecated.

frontier-forms-graphql

Context

frontier-forms-graphql package has the following responsibilities:

  • Consume GraphQL schemas and return JSON Schema
  • Provide constraints support

TODO

  • write API doc
  • write API
  • write specs

Validation rule combining two fields (eg. password validation)

I have an api that accepts a password string but I'd like to have a second field on the client side to ensure that the user types it correctly twice.

I'm not very familiar with Ajv. In Yup you can do:

const ResetSchema = Yup.object().shape({
  newPassword: Yup.string()
    .min(8, 'Password must be longer than 8 characters')
    .required('Password is required'),
  newPasswordDuplicate: Yup.string()
    .oneOf([Yup.ref('newPassword')], 'Passwords must match')
    .required('Password confirmation is required')
});

Would creating a client only field even work in the first place or will the graphql api have to accept both a password and password confirmation field?

Fire event after Frontier is rendered or introspected schema

In my case, sometimes it takes more than 500ms for the server to respond to introspection. I'd like to add a loading indicator when Frontier is trying to get the schema. However, there's no event or callback that can be used to indicate "schema introspection" is done.

I suggest:

<Frontier 
    client={/**/}
    mutation={/**/}
    onReady={/* Invoke the callback when schema is introspected */}
    uiKit={/**/}
/>

P/S: I am willing to work on this, I'm using a patched version of frontier-forms for my project now.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.