Giter Site home page Giter Site logo

api-platform / admin Goto Github PK

View Code? Open in Web Editor NEW
469.0 34.0 127.0 10.65 MB

A beautiful and fully-featured administration interface builder for hypermedia APIs

Home Page: https://api-platform.com/docs/admin/

License: MIT License

JavaScript 0.87% TypeScript 94.52% Dockerfile 1.32% PHP 2.72% Shell 0.54% MDX 0.03%
admin react rest-api rest api-platform hydra json-ld hypermedia hypermedia-client hacktoberfest

admin's Introduction

API Platform

API Platform is a next-generation web framework designed to easily create API-first projects without compromising extensibility and flexibility:

The official project documentation is available on the API Platform website.

API Platform embraces open web standards and the Linked Data movement. Your API will automatically expose structured data. It means that your API Platform application is usable out of the box with technologies of the semantic web.

It also means that your SEO will be improved because Google leverages these formats.

Last but not least, the server component of API Platform is built on top of the Symfony framework, while client components leverage React (Vue.js flavors are also available). It means that you can:

  • Use thousands of Symfony bundles and React components with API Platform.
  • Integrate API Platform in any existing Symfony, React, or Vue application.
  • Reuse all your Symfony and JavaScript skills, and benefit from the incredible amount of documentation available.
  • Enjoy the popular Doctrine ORM (used by default, but fully optional: you can use the data provider you want, including but not limited to MongoDB and Elasticsearch)

Install

Read the official "Getting Started" guide.

Credits

Created by Kévin Dunglas. Commercial support is available at Les-Tilleuls.coop.

admin's People

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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

admin's Issues

Restricting Access to Fields and Inputs

hi,

I managed to configure "authProvider.js" by storing the token and the role of the user in this way:

import { AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_CHECK, AUTH_GET_PERMISSIONS } from 'react-admin';
import jwt_decode from 'jwt-decode';

// Change this to be your own login check route.
const login_uri = 'http://localhost/login_check';

export default (type, params) => {
    switch (type) {
        case AUTH_LOGIN:
            const {username, password} = params;
            const request = new Request(`${login_uri}`, {
                method: 'POST',
                body: JSON.stringify({username, password}),
                headers: new Headers({'Content-Type': 'application/json'}),
            });

            return fetch(request)
                .then(response => {
                    if (response.status < 200 || response.status >= 300) throw new Error(response.statusText);

                    return response.json();
                })
                .then(({token}) => {
                    localStorage.setItem('token', token); // The JWT token is stored in the browser's local storage
                    const decodedToken = jwt_decode(token);
                    localStorage.setItem('role', decodedToken.roles); // The Role is stored in the browser's local storage
                    window.location.replace('/');
                });

        case AUTH_LOGOUT:
            localStorage.removeItem('token');
            localStorage.removeItem('role');
            break;

        case AUTH_ERROR:
            if (401 === params.status || 403 === params.status) {
                localStorage.removeItem('token');

                return Promise.reject();
            }
            break;

        case AUTH_CHECK:
            return localStorage.getItem('token') ? Promise.resolve() : Promise.reject();

        case AUTH_GET_PERMISSIONS:
            return localStorage.getItem('role') ? Promise.resolve() : Promise.reject();

        default:
            return Promise.resolve();
    }
}

Now I want to inject "permissions" as indicated in the documentation into User and Version , but I can not!

Here is my "App.js" file :

import React from 'react';
import parseHydraDocumentation from '@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation';
import { HydraAdmin, hydraClient as hydra, fetchHydra as baseFetchHydra } from '@api-platform/admin';
import frenchMessages from 'ra-language-french';
import authProvider from './authProvider';
import { Redirect } from 'react-router-dom';
import { User } from './users/user';
import { Version } from './versions/version';

const messages = {
    fr: frenchMessages,
};
const i18nProvider = locale => messages[locale];
const entrypoint = 'http://localhost'; // Change this by your own entrypoint
const fetchHeaders = {'Authorization': `Bearer ${window.localStorage.getItem('token')}`};
const fetchHydra = (url, options = {}) => baseFetchHydra(url, {
    ...options,
    headers: new Headers(fetchHeaders),
});
const hydraClient = api => hydra(api, fetchHydra);
const apiDocumentationParser = entrypoint => parseHydraDocumentation(entrypoint, {headers: new Headers(fetchHeaders)})
    .then(
        ({api}) => {

            {User(api)} // inject permissions ?!
            {Version(api)} // inject permissions ?!

            return {api};
        },
        (result) => {
            switch (result.status) {
                case 401:
                    return Promise.resolve({
                        api: result.api,
                        customRoutes: [{
                            props: {
                                path: '/',
                                render: () => <Redirect to={`/login`} />,
                            },
                        }],
                    });

                default:
                    return Promise.reject(result);
            }
        },
    );

export default (props) => (
    <HydraAdmin
        apiDocumentationParser={apiDocumentationParser}
        authProvider={authProvider}
        entrypoint={entrypoint}
        dataProvider={hydraClient}
        locale="fr"
        i18nProvider={i18nProvider}
    />
);

And the "User.js" file :

import React from 'react';
import {
    TextField,
    Datagrid,
    EditButton,
    List,
    ShowButton,
    EmailField,
} from 'react-admin';

// Customize row with condition
const postRowStyle = (record, index) => ({
    backgroundColor: record.isBetaTester === true ? '#efe' : 'white',
});

export const User = (props) => {
    // Customize "Users" resource
    const users = props.resources.find(({name}) => 'users' === name);
    users.list = (props) => (
        <List {...props} filters={<UserFilter />} sort={{field: 'clientNumber', order: 'ASC'}}>
            <Datagrid rowStyle={postRowStyle}>
                <TextField source="id" />
                <TextField source="clientNumber" label="N° client" />
                <TextField source="company" label="Société" />
                <TextField source="address" label="Adresse" sortable={false} />
                <TextField source="zipCode" label="Code postal" />
                <TextField source="city" label="Ville" />
                <TextField source="phone" label="Tél" sortable={false} />
                <TextField source="fax" label="Fax" sortable={false} />
                <EmailField source="email" label="Email" sortable={false} />
                {props.hasShow && <ShowButton />}
                {props.hasEdit && <EditButton />}
            </Datagrid>
        </List>
    );
};

A little help would be welcome ;)

Convert code to Component

Hi,

Could someone help me convert a piece of code into a component?

I want to convert this part of code into a component:

const users = api.resources.find(({name}) => 'users' === name);
const address = users.fields.find(f => 'address' === f.name);

address.field = props => (
    <TextField   {...props} source="address"/>
);

address.input = props => (
    <TextInput   {...props} source="address"/>
);

address.input.defaultProps = {
    addField: true,
    label: "Adresse",
};

address.field.defaultProps = {
    addField: true,
    addLabel: true,
    label: "Adresse",
    sortable: false
};

from this:

import React from 'react';
import { TextInput, TextField } from 'react-admin';
import parseHydraDocumentation from '@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation';
import { HydraAdmin, hydraClient as hydra, fetchHydra as baseFetchHydra } from '@api-platform/admin';
import frenchMessages from 'ra-language-french';
import authProvider from './authProvider';
import { Redirect } from 'react-router-dom';

const messages = {
    fr: frenchMessages,
};
const i18nProvider = locale => messages[locale];
const entrypoint = 'http://api.localhost'; // Change this by your own entrypoint
const fetchHeaders = {'Authorization': `Bearer ${window.localStorage.getItem('token')}`};
const fetchHydra = (url, options = {}) => baseFetchHydra(url, {
    ...options,
    headers: new Headers(fetchHeaders),
});
const hydraClient = api => hydra(api, fetchHydra);
const apiDocumentationParser = entrypoint => parseHydraDocumentation(entrypoint, {headers: new Headers(fetchHeaders)})
    .then(
        ({api}) => {

            const users = api.resources.find(({name}) => 'users' === name);
            const address = users.fields.find(f => 'address' === f.name);

            address.field = props => (
                <TextField   {...props} source="address"/>
            );

            address.input = props => (
                <TextInput   {...props} source="address"/>
            );

            address.input.defaultProps = {
                addField: true,
                label: "Adresse",
            };

            address.field.defaultProps = {
                addField: true,
                addLabel: true,
                label: "Adresse",
                sortable: false
            };

            return {api};
        },
        (result) => {
            switch (result.status) {
                case 401:
                    return Promise.resolve({
                        api: result.api,
                        customRoutes: [{
                            props: {
                                path: '/',
                                render: () => <Redirect to={`/login`} />,
                            },
                        }],
                    });

                default:
                    return Promise.reject(result);
            }
        },
    );

export default (props) => (
    <HydraAdmin
        apiDocumentationParser={apiDocumentationParser}
        authProvider={authProvider}
        entrypoint={entrypoint}
        dataProvider={hydraClient}
        locale="fr"
        i18nProvider={i18nProvider}
    />
);

Best regards,

Error when using Api-admin

I have install ApiPlatform (with composer), and then install Api-Admin.

When I run the front (yarn start), I have several errors

Warning: Unknown prop `onTouchTap` on <button> tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop
    in button
    in EnhancedButton
    in IconButton
    in div
    in Paper
    in AppBar
    in AppBar
    in Connect(AppBar)
    in MuiComponent
    in div
    in div
    in MuiThemeProvider
    in Layout
    in EventListener
    in WithWidth
    in Connect(WithWidth)
    in Route
    in Switch
    in div
    in Router
    in ConnectedRouter
    in TranslationProvider
    in withContext(TranslationProvider)
    in Connect(withContext(TranslationProvider))
    in Provider
    in Admin
    in _class
    in _class (at App.js:6)
    in App (at index.js:7)
__stack_frame_overlay_proxy_console__ @ proxyConsole.js:56
printWarning @ warning.js:36
warning @ warning.js:60
warnUnknownProperties @ ReactDOMUnknownPropertyHook.js:86
handleElement @ ReactDOMUnknownPropertyHook.js:99
onBeforeMountComponent @ ReactDOMUnknownPropertyHook.js:104
callHook @ ReactDebugTool.js:27
emitEvent @ ReactDebugTool.js:39
onBeforeMountComponent @ ReactDebugTool.js:316
mountComponent @ ReactReconciler.js:42
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
mountChildren @ ReactMultiChild.js:236
_createInitialChildren @ ReactDOMComponent.js:703
mountComponent @ ReactDOMComponent.js:522
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
mountChildren @ ReactMultiChild.js:236
_createInitialChildren @ ReactDOMComponent.js:703
mountComponent @ ReactDOMComponent.js:522
mountComponent @ ReactReconciler.js:45
mountChildren @ ReactMultiChild.js:236
_createInitialChildren @ ReactDOMComponent.js:703
mountComponent @ ReactDOMComponent.js:522
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
performInitialMount @ ReactCompositeComponent.js:370
mountComponent @ ReactCompositeComponent.js:257
mountComponent @ ReactReconciler.js:45
_updateRenderedComponent @ ReactCompositeComponent.js:764
_performComponentUpdate @ ReactCompositeComponent.js:723
updateComponent @ ReactCompositeComponent.js:644
performUpdateIfNecessary @ ReactCompositeComponent.js:560
performUpdateIfNecessary @ ReactReconciler.js:156
runBatchedUpdates @ ReactUpdates.js:150
perform @ Transaction.js:143
perform @ Transaction.js:143
perform @ ReactUpdates.js:89
flushBatchedUpdates @ ReactUpdates.js:172
close @ ReactUpdates.js:47
closeAll @ Transaction.js:209
perform @ Transaction.js:156
perform @ ReactUpdates.js:89
flushBatchedUpdates @ ReactUpdates.js:172
closeAll @ Transaction.js:209
perform @ Transaction.js:156
batchedUpdates @ ReactDefaultBatchingStrategy.js:62
enqueueUpdate @ ReactUpdates.js:200
enqueueUpdate @ ReactUpdateQueue.js:24
enqueueSetState @ ReactUpdateQueue.js:218
../node_modules/react/lib/ReactComponent.js.ReactComponent.setState @ ReactComponent.js:63
(anonymous) @ HydraAdmin.js:30
invariant.js:44 Uncaught (in promise) Error: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).
    at invariant (invariant.js:44)
    at Object.addComponentAsRefTo (ReactOwner.js:68)
    at attachRef (ReactRef.js:23)
    at Object../node_modules/react-dom/lib/ReactRef.js.ReactRef.attachRefs (ReactRef.js:42)
    at ReactCompositeComponentWrapper.attachRefs (ReactReconciler.js:23)
    at CallbackQueue.notifyAll (CallbackQueue.js:76)
    at ReactReconcileTransaction.close (ReactReconcileTransaction.js:80)
    at ReactReconcileTransaction.closeAll (Transaction.js:209)
    at ReactReconcileTransaction.perform (Transaction.js:156)
    at ReactUpdatesFlushTransaction.perform (Transaction.js:143)
    at ReactUpdatesFlushTransaction.perform (ReactUpdates.js:89)
    at flushBatchedUpdates (ReactUpdates.js:172)
    at ReactUpdatesFlushTransaction.close (ReactUpdates.js:47)
    at ReactUpdatesFlushTransaction.closeAll (Transaction.js:209)
    at ReactUpdatesFlushTransaction.perform (Transaction.js:156)
    at ReactUpdatesFlushTransaction.perform (ReactUpdates.js:89)
    at flushBatchedUpdates (ReactUpdates.js:172)
    at ReactUpdatesFlushTransaction.close (ReactUpdates.js:47)
    at ReactUpdatesFlushTransaction.closeAll (Transaction.js:209)
    at ReactUpdatesFlushTransaction.perform (Transaction.js:156)
    at ReactUpdatesFlushTransaction.perform (ReactUpdates.js:89)
    at Object.flushBatchedUpdates (ReactUpdates.js:172)
    at ReactDefaultBatchingStrategyTransaction.closeAll (Transaction.js:209)
    at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:156)
    at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
    at Object.enqueueUpdate (ReactUpdates.js:200)
    at enqueueUpdate (ReactUpdateQueue.js:24)
    at Object.enqueueSetState (ReactUpdateQueue.js:218)
    at _class.../node_modules/react/lib/ReactComponent.js.ReactComponent.setState (ReactComponent.js:63)
    at HydraAdmin.js:30
    at <anonymous>
invariant @ invariant.js:44
addComponentAsRefTo @ ReactOwner.js:68
attachRef @ ReactRef.js:23
./node_modules/react-dom/lib/ReactRef.js.ReactRef.attachRefs @ ReactRef.js:42
attachRefs @ ReactReconciler.js:23
notifyAll @ CallbackQueue.js:76
close @ ReactReconcileTransaction.js:80
closeAll @ Transaction.js:209
perform @ Transaction.js:156
perform @ Transaction.js:143
perform @ ReactUpdates.js:89
flushBatchedUpdates @ ReactUpdates.js:172
close @ ReactUpdates.js:47
closeAll @ Transaction.js:209
perform @ Transaction.js:156
perform @ ReactUpdates.js:89
flushBatchedUpdates @ ReactUpdates.js:172
close @ ReactUpdates.js:47
closeAll @ Transaction.js:209
perform @ Transaction.js:156
perform @ ReactUpdates.js:89
flushBatchedUpdates @ ReactUpdates.js:172
closeAll @ Transaction.js:209
perform @ Transaction.js:156
batchedUpdates @ ReactDefaultBatchingStrategy.js:62
enqueueUpdate @ ReactUpdates.js:200
enqueueUpdate @ ReactUpdateQueue.js:24
enqueueSetState @ ReactUpdateQueue.js:218
../node_modules/react/lib/ReactComponent.js.ReactComponent.setState @ ReactComponent.js:63
(anonymous) @ HydraAdmin.js:30
proxyConsole.js:56 uncaught at handleFetch Invariant Violation: removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).
    at invariant (http://localhost:3000/static/js/bundle.js:120583:15)
    at Object.removeComponentAsRefFrom (http://localhost:3000/static/js/bundle.js:142112:36)
    at detachRef (http://localhost:3000/static/js/bundle.js:142596:16)
    at Object../node_modules/react-dom/lib/ReactRef.js.ReactRef.detachRefs (http://localhost:3000/static/js/bundle.js:142648:5)
    at Object.unmountComponent (http://localhost:3000/static/js/bundle.js:142464:14)
    at Object.unmountChildren (http://localhost:3000/static/js/bundle.js:135292:25)
    at ReactDOMComponent.unmountChildren (http://localhost:3000/static/js/bundle.js:141893:28)
    at ReactDOMComponent.unmountComponent (http://localhost:3000/static/js/bundle.js:137428:10)
    at Object.unmountComponent (http://localhost:3000/static/js/bundle.js:142465:22)
    at ReactCompositeComponentWrapper.unmountComponent (http://localhost:3000/static/js/bundle.js:135822:23)
    at Object.unmountComponent (http://localhost:3000/static/js/bundle.js:142465:22)
    at Object.updateChildren (http://localhost:3000/static/js/bundle.js:135276:25)
    at ReactDOMComponent._reconcilerUpdateChildren (http://localhost:3000/static/js/bundle.js:141728:32)
    at ReactDOMComponent._updateChildren (http://localhost:3000/static/js/bundle.js:141832:31)
    at ReactDOMComponent.updateChildren (http://localhost:3000/static/js/bundle.js:141819:12)
    at ReactDOMComponent._updateDOMChildren (http://localhost:3000/static/js/bundle.js:137380:12)
    at ReactDOMComponent.updateComponent (http://localhost:3000/static/js/bundle.js:137198:10)
    at ReactDOMComponent.receiveComponent (http://localhost:3000/static/js/bundle.js:137160:10)
    at Object.receiveComponent (http://localhost:3000/static/js/bundle.js:142511:22)
    at Object.updateChildren (http://localhost:3000/static/js/bundle.js:135255:25)
    at ReactDOMComponent._reconcilerUpdateChildren (http://localhost:3000/static/js/bundle.js:141728:32)
    at ReactDOMComponent._updateChildren (http://localhost:3000/static/js/bundle.js:141832:31)
    at ReactDOMComponent.updateChildren (http://localhost:3000/static/js/bundle.js:141819:12)
    at ReactDOMComponent._updateDOMChildren (http://localhost:3000/static/js/bundle.js:137380:12)
    at ReactDOMComponent.updateComponent (http://localhost:3000/static/js/bundle.js:137198:10)
    at ReactDOMComponent.receiveComponent (http://localhost:3000/static/js/bundle.js:137160:10)
    at Object.receiveComponent (http://localhost:3000/static/js/bundle.js:142511:22)
    at ReactCompositeComponentWrapper._updateRenderedComponent (http://localhost:3000/static/js/bundle.js:136158:23)
    at ReactCompositeComponentWrapper._performComponentUpdate (http://localhost:3000/static/js/bundle.js:136128:10)
    at ReactCompositeComponentWrapper.updateComponent (http://localhost:3000/static/js/bundle.js:136049:12)
    at ReactCompositeComponentWrapper.receiveComponent (http://localhost:3000/static/js/bundle.js:135951:10)
    at Object.receiveComponent (http://localhost:3000/static/js/bundle.js:142511:22)
    at ReactCompositeComponentWrapper._updateRenderedComponent (http://localhost:3000/static/js/bundle.js:136158:23)
    at ReactCompositeComponentWrapper._performComponentUpdate (http://localhost:3000/static/js/bundle.js:136128:10)
    at ReactCompositeComponentWrapper.updateComponent (http://localhost:3000/static/js/bundle.js:136049:12)
    at ReactCompositeComponentWrapper.receiveComponent (http://localhost:3000/static/js/bundle.js:135951:10)
    at Object.receiveComponent (http://localhost:3000/static/js/bundle.js:142511:22)
    at ReactCompositeComponentWrapper._updateRenderedComponent (http://localhost:3000/static/js/bundle.js:136158:23)
    at ReactCompositeComponentWrapper._performComponentUpdate (http://localhost:3000/static/js/bundle.js:136128:10)
    at ReactCompositeComponentWrapper.updateComponent (http://localhost:3000/static/js/bundle.js:136049:12)
    at ReactCompositeComponentWrapper.receiveComponent (http://localhost:3000/static/js/bundle.js:135951:10)
    at Object.receiveComponent (http://localhost:3000/static/js/bundle.js:142511:22)
    at ReactCompositeComponentWrapper._updateRenderedComponent (http://localhost:3000/static/js/bundle.js:136158:23)
    at ReactCompositeComponentWrapper._performComponentUpdate (http://localhost:3000/static/js/bundle.js:136128:10)
    at ReactCompositeComponentWrapper.updateComponent (http://localhost:3000/static/js/bundle.js:136049:12)
    at ReactCompositeComponentWrapper.receiveComponent (http://localhost:3000/static/js/bundle.js:135951:10)
    at Object.receiveComponent (http://localhost:3000/static/js/bundle.js:142511:22)
    at ReactCompositeComponentWrapper._updateRenderedComponent (http://localhost:3000/static/js/bundle.js:136158:23)
    at ReactCompositeComponentWrapper._performComponentUpdate (http://localhost:3000/static/js/bundle.js:136128:10)
    at ReactCompositeComponentWrapper.updateComponent (http://localhost:3000/static/js/bundle.js:136049:12)
__stack_frame_overlay_proxy_console__ @ proxyConsole.js:56
log @ utils.js:216
(anonymous) @ proc.js:473
exec @ scheduler.js:20
flush @ scheduler.js:61
asap @ scheduler.js:34
runPutEffect @ proc.js:466
runEffect @ proc.js:421
next @ proc.js:302
currCb @ proc.js:375

If I click, nothing append. But If I load the direct URL, It's OK.
Communication with API is also OK (data are saved in the database).

Can't hide autogenerated id field

By creating a new entity I have to pass an id(required field), but my ids are auto-generated and so I don't need to pass an id by creating a new entity.

Here is a screenshot:
image

Here is the model for the location entity and as you can see the id is defined optional for the POST operation:
image

Admin component structure and roadmap?

Hi there, first of all, thanks for this great tool that is the api-platform. We are studying it as a good candidate to use on our projects. We are a small agency focused on digital products, web and mobile that use a lot of React and React Native. And we are looking for something to use on the backend in two moments: fast prototyping and production. The api-platform seems to be a good fit.

The fast frontend prototyping is also a very good bonus here and I like a lot the idea of the very loose integration where the frontend only reads the api definitions. Please allow me to make some questions and observations on the overall structure of the project, so that your answers might help me on our decision.

But, looking on your docs, my impressions are that you have put more effort on the backend. And I can't tell what are your plans to the frontend. At a first glimpse my impression is that both the admin component and the client generator are each one very distinct projects from the platform. It seems that they should have their own site and docs and be able to work with multiple backends as they do.

I can't understand how much the Admin Component differs itself from the Admin on Rest and why can't I just use "AOR" instead of it. I imagine it has to do with the rest client over hydra or something like that. But, I can't be sure.

Regarding the Client Generator component, it is also a little confusing to me. What is the roadmap or what are the goals of this component? I see you have multiple components and new pull requests. Do you wish to increase the amount of clients supported? Or to increase the quality of the ones you already have? Is there a way of generating code based on a previous Admin Component configuration?

If we decide on moving along with this idea, we are willing to work on a starter boilerplate code with a web admin, api-platform and react native client and a lot of transversal services like auth, image upload and so on. So, count on us with that and also to help on improving the docs.

Pagination is not rendered

Hi,

Pagination works correctly in the Hydra parsing but she isn't rendered in listing view.

image

In ApiPlatform, I specify pagination config like that :

api_platform:
    collection:
        pagination:
            items_per_page: 3

It seems that React props stay to 30 (default).

Can you confirm this report ?

Nicolas

Json-Ld to Json

Hi guys, its possible to change request json-ld => json? I have problem with ids and urls.
When I use only json this fix my issue.

Using api-platform + admin

Wrong routes

Hello,

I have the newest version of Api Platform and just start with admin.
Everything is very nice, but sometimes there are 404 errors. Like on show.

There route is
http://localhost/symfony/api_platform/public/api/books/1
but for show the route is
http://localhost/symfony/api_platform/public/api/symfony/api_platform/public/api/books/1

also the translation does not work. Attached a picture, with the admin
calls.

is this a bug? everything else works so far ... I copied everything from the manual and made no own changes

Best Regards, thanks for the great work
Simon
error

Error: The response has no "Link" HTTP header.

Hello,
It's my first project using Symfony framework and i'am new with api-platform & admin-on-rest.
So for now, i have entities and i build my api with api-platform. Now, i want integrate an admin interface in my project. So i followed the getting starting introduction here https://github.com/api-platform/admin and i replaced entrypoint with my own local api url 'http://localhost:8000/api/v2'.

1st i was that error :
Fetch API cannot load http://localhost:8000/api/v2. Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains the invalid value 'null'. Origin 'http://localhost:3000' is therefore not allowed access. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

So i added the nelmio-cors bundle in my project and i added this in my parameter.yml file :

nelmio_cors:
    defaults:
        allow_credentials: false
        allow_origin: []
        allow_headers: []
        allow_methods: []
        expose_headers: []
        max_age: 0
        hosts: []
        origin_regex: false
        forced_allow_origin_value: ~
    paths:
        '^/api/':
            allow_origin: ['*']
            allow_headers: ['X-Custom-Auth', 'Content-Type', 'Link']
            allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
            max_age: 3600
        '^/':
            origin_regex: true
            allow_origin: ['^http://localhost:[0-9]+']
            allow_headers: ['X-Custom-Auth', 'Content-Type', 'Link']
            allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
            max_age: 3600
            hosts: ['^api\.']

After, i have that error:

Uncaught (in promise) Error: The response has no "Link" HTTP header.
    at getDocumentationUrlFromHeaders (parseHydraDocumentation.js:71)
    at parseHydraDocumentation.js:92
    at <anonymous>
         getDocumentationUrlFromHeaders @ parseHydraDocumentation.js:71
         (anonymous) @ parseHydraDocumentation.js:92

How can i fix that ?

License situation

Hello,

as we plan to use the api-platform admin in a project of ours, but I cannot find any licensing information here on github or in the sourcecode - could you kindly let us know under which license you are releasing api-platform-admin?

NPM is stating MIT: https://www.npmjs.com/package/api-platform-admin

Thanks

REST response must contain a data key

I am using the hydraClient with an admin on rest app.
The thing is when referencing from another resource like this

<ReferenceField source="productType" reference="product_types">
  <TextField source="name" />
</ReferenceField>

There is an error : REST response must contain a data key

How to create a select with option groups

I have a product that has a category and a category has a family.

In the product form I currently have a selector for the category that show only the category name.

I would like to have it show the categories grouped by family.

Can someone help?

Admin uses [object%20Object] in URL

Hi, can you explain why admin component uses object in URL. This leads to an error, and no entity can be edited. Thanks

screen shot 2018-01-07 at 12 29 59

This is Users get request

screen shot 2018-01-07 at 12 34 46

and my User entity:

/**
 * User Entity
 * @ApiResource(
 *   collectionOperations={
 *     "get"={"method"="GET"},
 *     "post"={"route_name"="api_users_post_collection"}
 *   },
 *   itemOperations={
 *     "get"={"method"="GET"},
 *   },
 *   attributes={
 *     "normalization_context"={"groups"={"read"}},
 *     "denormalization_context"={"groups"={"write"}}
 *   }
 * )
 * @ORM\Entity
 */
class User implements UserInterface, \Serializable

Wrong url for item operations

Hello,
The url used to get/put/delete a ressource in api-platform/admin is a wrong one : the main path is mentioned twice (see pictures below).
image
image

I only have this porblem for item operations. Collection operations work fine.

I am not sure if the problem comes from the writing of docs.jsonld in api-platform/api-platform or its reading in api-platform/admin.

Below is my docs.jsonld. It has been made with api-platform/demo using composer for installation.
Thanks for your help,

{
  "@context": {
    "@vocab": "http://localhost/demo/web/app_dev.php/docs.jsonld#",
    "hydra": "http://www.w3.org/ns/hydra/core#",
    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "xmls": "http://www.w3.org/2001/XMLSchema#",
    "owl": "http://www.w3.org/2002/07/owl#",
    "domain": {
      "@id": "rdfs:domain",
      "@type": "@id"
    },
    "range": {
      "@id": "rdfs:range",
      "@type": "@id"
    },
    "subClassOf": {
      "@id": "rdfs:subClassOf",
      "@type": "@id"
    },
    "expects": {
      "@id": "hydra:expects",
      "@type": "@id"
    },
    "returns": {
      "@id": "hydra:returns",
      "@type": "@id"
    }
  },
  "@id": "../demo/web/app_dev.php/docs.jsonld",
  "hydra:description": "This is a demo application of the [API Platform](https://api-platform.com) framework.\n[Its source code](https://github.com/api-platform/demo) includes various examples, check it out!\n",
  "hydra:entrypoint": "/demo/web/app_dev.php/",
  "hydra:supportedClass": [
    {
      "@id": "http://schema.org/Book",
      "@type": "hydra:Class",
      "rdfs:label": "Book",
      "hydra:supportedOperation": [
        {
          "@type": "hydra:Operation",
          "rdfs:label": "Retrieves Book resource.",
          "hydra:method": "GET",
          "returns": "http://schema.org/Book",
          "hydra:title": "Retrieves Book resource."
        },
        {
          "@type": "hydra:ReplaceResourceOperation",
          "rdfs:label": "Replaces the Book resource.",
          "expects": "http://schema.org/Book",
          "hydra:method": "PUT",
          "returns": "http://schema.org/Book",
          "hydra:title": "Replaces the Book resource."
        },
        {
          "@type": "hydra:Operation",
          "rdfs:label": "Deletes the Book resource.",
          "hydra:method": "DELETE",
          "returns": "owl:Nothing",
          "hydra:title": "Deletes the Book resource."
        }
      ],
      "hydra:supportedProperty": [
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "#Book/id",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Book",
            "rdfs:label": "id",
            "range": "xmls:integer"
          },
          "hydra:readable": true,
          "hydra:required": false,
          "hydra:title": "id",
          "hydra:writable": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "The ISBN of the book",
          "hydra:property": {
            "@id": "http://schema.org/isbn",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Book",
            "rdfs:label": "isbn",
            "range": "xmls:string"
          },
          "hydra:readable": true,
          "hydra:required": false,
          "hydra:title": "isbn",
          "hydra:writable": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "A description of the item",
          "hydra:property": {
            "@id": "http://schema.org/description",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Book",
            "rdfs:label": "description",
            "range": "xmls:string"
          },
          "hydra:readable": true,
          "hydra:required": true,
          "hydra:title": "description",
          "hydra:writable": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "The author of this content or rating. Please note that author is special in that HTML 5 provides a special mechanism for indicating authorship via the rel tag. That is equivalent to this and may be used interchangeably",
          "hydra:property": {
            "@id": "http://schema.org/author",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Book",
            "rdfs:label": "author",
            "range": "xmls:string"
          },
          "hydra:readable": true,
          "hydra:required": true,
          "hydra:title": "author",
          "hydra:writable": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "The title of the book",
          "hydra:property": {
            "@id": "http://schema.org/name",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Book",
            "rdfs:label": "title",
            "range": "xmls:string"
          },
          "hydra:readable": true,
          "hydra:required": true,
          "hydra:title": "title",
          "hydra:writable": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "The date on which the CreativeWork was created or the item was added to a DataFeed",
          "hydra:property": {
            "@id": "http://schema.org/dateCreated",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Book",
            "rdfs:label": "publicationDate",
            "range": "xmls:dateTime"
          },
          "hydra:readable": true,
          "hydra:required": true,
          "hydra:title": "publicationDate",
          "hydra:writable": true
        }
      ],
      "hydra:title": "Book"
    },
    {
      "@id": "http://schema.org/Review",
      "@type": "hydra:Class",
      "rdfs:label": "Review",
      "hydra:supportedOperation": [
        {
          "@type": "hydra:Operation",
          "rdfs:label": "Retrieves Review resource.",
          "hydra:method": "GET",
          "returns": "http://schema.org/Review",
          "hydra:title": "Retrieves Review resource."
        },
        {
          "@type": "hydra:ReplaceResourceOperation",
          "rdfs:label": "Replaces the Review resource.",
          "expects": "http://schema.org/Review",
          "hydra:method": "PUT",
          "returns": "http://schema.org/Review",
          "hydra:title": "Replaces the Review resource."
        },
        {
          "@type": "hydra:Operation",
          "rdfs:label": "Deletes the Review resource.",
          "hydra:method": "DELETE",
          "returns": "owl:Nothing",
          "hydra:title": "Deletes the Review resource."
        }
      ],
      "hydra:supportedProperty": [
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "#Review/id",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Review",
            "rdfs:label": "id",
            "range": "xmls:integer"
          },
          "hydra:readable": true,
          "hydra:required": false,
          "hydra:title": "id",
          "hydra:writable": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "#Review/rating",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Review",
            "rdfs:label": "rating",
            "range": "xmls:integer"
          },
          "hydra:readable": true,
          "hydra:required": false,
          "hydra:title": "rating",
          "hydra:writable": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "The actual body of the review",
          "hydra:property": {
            "@id": "http://schema.org/reviewBody",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Review",
            "rdfs:label": "body",
            "range": "xmls:string"
          },
          "hydra:readable": true,
          "hydra:required": false,
          "hydra:title": "body",
          "hydra:writable": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "The item that is being reviewed/rated",
          "hydra:property": {
            "@id": "http://schema.org/itemReviewed",
            "@type": "hydra:Link",
            "domain": "http://schema.org/Review",
            "rdfs:label": "book",
            "range": "http://schema.org/Book"
          },
          "hydra:readable": true,
          "hydra:required": true,
          "hydra:title": "book",
          "hydra:writable": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "Author the author of the review",
          "hydra:property": {
            "@id": "http://schema.org/author",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Review",
            "rdfs:label": "author",
            "range": "xmls:string"
          },
          "hydra:readable": true,
          "hydra:required": false,
          "hydra:title": "author",
          "hydra:writable": true
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "Author the author of the review",
          "hydra:property": {
            "@id": "#Review/publicationDate",
            "@type": "rdf:Property",
            "domain": "http://schema.org/Review",
            "rdfs:label": "publicationDate",
            "range": "xmls:dateTime"
          },
          "hydra:readable": true,
          "hydra:required": false,
          "hydra:title": "publicationDate",
          "hydra:writable": true
        }
      ],
      "hydra:title": "Review"
    },
    {
      "@id": "#Entrypoint",
      "@type": "hydra:Class",
      "hydra:supportedOperation": {
        "@type": "hydra:Operation",
        "rdfs:label": "The API entrypoint.",
        "hydra:method": "GET",
        "returns": "#EntryPoint"
      },
      "hydra:supportedProperty": [
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "#Entrypoint/book",
            "@type": "hydra:Link",
            "domain": "#Entrypoint",
            "rdfs:label": "The collection of Book resources",
            "range": "hydra:PagedCollection",
            "hydra:supportedOperation": [
              {
                "@type": "hydra:Operation",
                "rdfs:label": "Retrieves the collection of Book resources.",
                "hydra:method": "GET",
                "returns": "hydra:PagedCollection",
                "hydra:title": "Retrieves the collection of Book resources."
              },
              {
                "@type": "hydra:CreateResourceOperation",
                "rdfs:label": "Creates a Book resource.",
                "expects": "http://schema.org/Book",
                "hydra:method": "POST",
                "returns": "http://schema.org/Book",
                "hydra:title": "Creates a Book resource."
              }
            ]
          },
          "hydra:readable": true,
          "hydra:title": "The collection of Book resources",
          "hydra:writable": false
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:property": {
            "@id": "#Entrypoint/review",
            "@type": "hydra:Link",
            "domain": "#Entrypoint",
            "rdfs:label": "The collection of Review resources",
            "range": "hydra:PagedCollection",
            "hydra:supportedOperation": [
              {
                "@type": "hydra:Operation",
                "rdfs:label": "Retrieves the collection of Review resources.",
                "hydra:method": "GET",
                "returns": "hydra:PagedCollection",
                "hydra:title": "Retrieves the collection of Review resources."
              },
              {
                "@type": "hydra:CreateResourceOperation",
                "rdfs:label": "Creates a Review resource.",
                "expects": "http://schema.org/Review",
                "hydra:method": "POST",
                "returns": "http://schema.org/Review",
                "hydra:title": "Creates a Review resource."
              }
            ]
          },
          "hydra:readable": true,
          "hydra:title": "The collection of Review resources",
          "hydra:writable": false
        }
      ],
      "hydra:title": "The API entrypoint"
    },
    {
      "@id": "#ConstraintViolation",
      "@type": "hydra:Class",
      "hydra:supportedProperty": [
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "The property path of the violation",
          "hydra:property": {
            "@id": "#ConstraintViolation/propertyPath",
            "@type": "rdf:Property",
            "domain": "#ConstraintViolation",
            "rdfs:label": "propertyPath",
            "range": "xmls:string"
          },
          "hydra:readable": true,
          "hydra:title": "propertyPath",
          "hydra:writable": false
        },
        {
          "@type": "hydra:SupportedProperty",
          "hydra:description": "The message associated with the violation",
          "hydra:property": {
            "@id": "#ConstraintViolation/message",
            "@type": "rdf:Property",
            "domain": "#ConstraintViolation",
            "rdfs:label": "message",
            "range": "xmls:string"
          },
          "hydra:readable": true,
          "hydra:title": "message",
          "hydra:writable": false
        }
      ],
      "hydra:title": "A constraint violation"
    },
    {
      "@id": "#ConstraintViolationList",
      "@type": "hydra:Class",
      "subClassOf": "hydra:Error",
      "hydra:supportedProperty": {
        "@type": "hydra:SupportedProperty",
        "hydra:description": "The violations",
        "hydra:property": {
          "@id": "#ConstraintViolationList/violations",
          "@type": "rdf:Property",
          "domain": "#ConstraintViolationList",
          "rdfs:label": "violations",
          "range": "#ConstraintViolation"
        },
        "hydra:readable": true,
        "hydra:title": "violations",
        "hydra:writable": false
      },
      "hydra:title": "A constraint violation list"
    }
  ],
  "hydra:title": "API Platform's demo"
}

FEATURE: Parse Hydra supportedOperations to disable/enable Buttons

Parse collectionOperations and itemOperations to disable/enable CREATE/DELETE/EDIT Buttons.
docs.jsonld currently returns supported itemOperations and collectionOperations for each resource. parseHydraDocumentation should be extended to parse these operations, and HydraAdmin should use this to determine which buttons to enable.
If, for example, DELETE itemOperation is disabled on a resource, then the DELETE button should not appear on the edit form. If PUT is disabled, then EDIT button should not appear.
I believe you get the idea.

Adding Jwt authentification

Hi, i'm trying to implement jwt authentification to my admin system but i detected some troubles.
Following this documentation : "https://api-platform.com/docs/admin/authentication-support", I have to open security on many url of my API like :
-"url_api/"
-"url_api/docs.jsonld/"
-"url_api/contexts/Entrypoint/"

Then the system works perfectly ( redicrection to login page, store and use a JWT ...), but it's a bit weird to open some routes, even if it's only documentation, of a securised API.

So i tried to follow this : "#51 ". In this case i can securise all routes of the API but after login Many To One and Many to Many relations are not supported.

Is it possible to combine both ways ?

Thanks a lot ;)

Non required fields required in admin ?

Hello,

I've got an entity with many non required fields.

It looks like the generated admin requires every fields and won't allow submission until we set a value for each field.

Maybe the inputFactory could look at input.required property before setting a validate method which require a value ?

Thanks

Authentication Example from Docs not Working

Hello, Everyone.
I was following the authentication example from the README when I discovered that it wasn't working. I screamed HAAAAAAA!!!, then I determined to figure out what was wrong.
Hence, I discovered that

  1. hydraClient had been updated, and the first parameter is now a JSON array of parameters. (Before; After)
    I think we can all agree that the documentation needs an update.

  2. I made the correction in my code, then I got another error in my browser.
    screenshot from 2017-08-25 17-16-34
    I decided to figure out, again, what was happening. Well, I don't quite know how to describe this but the error disappeared after I changed this line from
    restClient={this.props.restClient(this.state.api)}
    to
    restClient={this.props.restClient}

I gotta tell you, it's a bug. I probably wasn't clear enough here but if you got any more questions, I'll be glad to answer.
Great job, people.

PS: I'm not really a JS developer, you know.
PPS: I'm ready to get my hands dirty in this baby, just give me some pointers and I'll send in PRs.

Autocomplete on ManyToOne relations?

Hello,

I have ManyToOne relations with lot of options and in admin there's problem that not all options are in list (only first 30). Is there a easy way to use same component as on OneToMany relations with autocomplete/search functionality?

Thanks.

Trying to get started

Hello,

I tried to follow the Getting started instructions, but I got the following in the term :
export 'default' (imported as 'HydraAdmin') was not found in 'api-platform-admin'

In the JS console, I also have :
Warning: React.createElement: 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. Check your code at App.js:6. in App (at index.js:7) Error: 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. Check the render method of App.

Does someone have a solution ?

ManyToMany relation

HI,

I've a problem with a ManyToMany relation, I take a look at the PR api-platform/core#1189, normally it's seem to be fixed, but I can't add a new entry from the select.

api-platform/admin : 0.2.0
api-platform/core : 2.1.x-dev

In the list view all items are displayed.
In the edit view all items are displayed, but I can't add another one.

=======================
/**
* @var Item
*
* @Orm\ManyToMany(targetEntity="Item")
* @Orm\JoinTable(name="catalog_items",
* joinColumns={@Orm\JoinColumn(name="catalog_id", referencedColumnName="id")},
* inverseJoinColumns={@Orm\JoinColumn(name="item_id", referencedColumnName="id", unique=true)}
* )
* @ApiProperty(iri="http://schema.org/Item")
* @groups({"editor"})
*/
private $items;

With postam all work well I can add another items to my collection, so the problem seem to be come the Admin interface...

Difference between ADMIN vs CLIENT (in React) ?

Hello,
I just want to know the difference in api-platform between ADMIN part in React and the CLIENT part in React (except that one use Material Design, the other Bootstrap and that ADMIN is generated dynamically, CLIENT need command to generate) ?

Thanks !

HydraAdmin component isn't working with no entrypoint props

Hi,

I followed the docs to implement the admin with JWT Authentication support. Here is the code :

// authClient.js
import { AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_CHECK } from 'admin-on-rest';

export default (type, params) => {
  if (type === AUTH_LOGIN) {
    const { username, password } = params;
    const request = new Request(`${process.env.REACT_APP_ENTRYPOINT}/login_check`, {
      method: 'POST',
      body: JSON.stringify({ username, password }),
      headers: new Headers({ 'Content-Type': 'application/json' }),
    });

    return fetch(request)
      .then(response => {
        if (response.status < 200 || response.status >= 300) {
          throw new Error(response.statusText);
        }

        return response.json();
      })
      .then(({ token }) => {
        localStorage.setItem('token', token);
      });
  }

  if (type === AUTH_LOGOUT) {
    localStorage.removeItem('token');

    return Promise.resolve();
  }

  if (type === AUTH_ERROR) {
    const { status } = params;
    if (status === 401 || status === 403) {
      localStorage.removeItem('token');

      return Promise.reject();
    }

    return Promise.resolve();
  }

  if (type === AUTH_CHECK) {
    return localStorage.getItem('token') ? Promise.resolve() : Promise.reject();
  }

  return Promise.reject('Unknown method.');
};
// App.js
import React, { Component } from 'react';
import { HydraAdmin, hydraClient, fetchHydra } from 'api-platform-admin';
import authClient from './authClient';

const fetchWithAuth = (url, options = {}) => {
  if (!options.headers) {
    options.headers = new Headers({ Accept: 'application/ld+json' });
  }

  options.headers.set(
    'Authorization',
    `Bearer ${localStorage.getItem('token')}`
  );
  return fetchHydra(url, options);
};

class App extends Component {
  render() {
    return (
      <HydraAdmin
        restClient={hydraClient(
          process.env.REACT_APP_ENTRYPOINT,
          fetchWithAuth
        )}
        authClient={authClient}
      />
    );
  }
}

export default App;

Problem is that HydraAdmin component requires entrypoint prop to be set as it passes it to parseHydraDocumentation() in componentDidMount(). But the doc says that it is not required in this case.

So, I added it to my App's render method :

// App.js
// ...
class App extends Component {
  render() {
    return (
      <HydraAdmin
        entrypoint={process.env.REACT_APP_ENTRYPOINT}
        restClient={hydraClient(
          process.env.REACT_APP_ENTRYPOINT,
          fetchWithAuth
        )}
        authClient={authClient}
      />
    );
  }
}

Now, it hits my API backend but the login page still doesn't show up and I got this error in the console :

capture d ecran de 2017-07-12 12-32-42

OneToMany from the Books / Reviews sample does not work

Fro sure I am missing something obvious here. I followed the Creating the model guide and I was able to create a book and two reviews:

curl -X GET "http://localhost/app_dev.php/books?page=1" -H "accept: application/ld+json"

returns

{
  "@context": "/app_dev.php/contexts/Book",
  "@id": "/app_dev.php/books",
  "@type": "hydra:Collection",
  "hydra:member": [
    {
      "@id": "/app_dev.php/books/1",
      "@type": "Book",
      "id": 1,
      "isbn": "AAAA",
      "title": "empty",
      "description": "desc",
      "author": "author",
      "publicationDate": "2017-09-27T18:19:05+02:00",
      "reviews": [
        "/app_dev.php/reviews/1",
        "/app_dev.php/reviews/2"
      ]
    }
  ],
  "hydra:totalItems": 1
}

However if I try to use this admin application, the reviews are not displayed on the book detail and in the console I see an attempt to GET http://127.0.0.1/reviews/1,/reviews/2 that ends in 404 and the reviews are not displayed.

screenshot from 2017-10-16 12-15-25

The schema returned from the server looks quite OK to me:

screenshot from 2017-10-16 12-13-43

What did I wrong? Thanks!

Admin Does Not Require authentication for docs.jsonld request

I noticed that when the whole symfony project is under a security layer, the Admin won't load because docs.jsonld returns 403 error. Normally, the 403 error should take you to the login page, but it doesn't in the case of docs.jsonld.
The only workaround for now is to open up docs.jsonld to anonymous users, which isn't good from a security perspective.

REST response must contain a data key after DELETE request

I am using the hydraClient with a "react-admin": "2.1.1".
also, I used:

"@api-platform/admin": "0.5.0",
"@api-platform/api-doc-parser": "0.4.0",

When I DELETE something (api-platform return HTTP Code: 204) and I see the error:

"REST response must contain a data key"

this error is reported, however, by the react-admin

https://github.com/marmelab/react-admin/blob/master/packages/ra-core/src/sideEffect/fetch.js#L42-L44

but it's the hydra parser that could actually handle it somehow in the api-platform admin?

Can't customize List and Show views independently

Hello,

I am using custom components to display readableFields in the 'Show' view for my Resource.
However, I don't want these fields to appear in the 'List' view but I haven't found a way to customize these views separately.

Do you confirm that this is not possible as of now, or did I miss the way to do it ?

Thank you.
Anouk

Uncaught SyntaxError: Unexpected token import

After i edit the src/App.js with the example in the Getting Started, i get this error : Uncaught SyntaxError: Unexpected token import

It originates from the line import _AdminBuilder from './AdminBuilder';

Seen here :

/* 268 */
/*!*******************************************!*\
  !*** ./~/api-platform-admin/lib/index.js ***!
  \*******************************************/
/***/ function(module, exports) {

	import _AdminBuilder from './AdminBuilder';
	export { _AdminBuilder as AdminBuilder };
	import _Create from './Create';
	export { _Create as Create };
	import _Edit from './Edit';
	export { _Edit as Edit };
	import _fieldFactory from './fieldFactory';
	export { _fieldFactory as fieldFactory };
	import _inputFactory from './inputFactory';
	export { _inputFactory as inputFactory };
	import _List from './List';
	export { _List as List };
	import _Show from './Show';
	export { _Show as Show };

	export * from './hydra';

I also get several warnings from the yarn add api-platform-admin command :

 yarn add api-platform-admin
yarn add v0.27.5
[1/4] Resolving packages...
warning api-platform-admin > [email protected]: This package is deprecated. Use Array.isArray.
[2/4] Fetching packages...
warning [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
warning [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 66 new dependencies.

Could it come from these ?

Regards,

Create and Edit button doesn't work : "RangeError: Maximum call stack in ReactCompositeComponent.js:793"

When I click on "Create" or "Edit" on Chrome on Ubuntu, I got this error : "RangeError: Maximum call stack in ReactCompositeComponent.js:793"

I did a fresh install with https://github.com/api-platform/api-platform/releases/tag/v2.2.0
but the 2 buttons not working.

I update my package.json to this value : https://github.com/api-platform/api-platform/blob/master/admin/package.json
but the 2 buttons not working again :(

Someone has an idea or the same problem ?

api_platform_admin_react_error

Server side validation errors not displaying on input form

When entering invalid data on an input field, I can see the following API response…

{
  "@context":          "\/app_dev.php\/contexts\/ConstraintViolationList",
  "@type":             "ConstraintViolationList",
  "hydra:title":       "An error occurred",
  "hydra:description": "name: This value should not be null.\nemail: This value is not a valid email address.\nlogo: This value is not a valid URL.",
  "violations":        [
    {
      "propertyPath": "name",
      "message":      "This value should not be null."
    },
    {
      "propertyPath": "email",
      "message":      "This value is not a valid email address."
    },
    {
      "propertyPath": "logo",
      "message":      "This value is not a valid URL."
    }
  ]
}

… however the admin page simply reports "Server communication error" rather than displaying nice error messages. The feature set lists nice validation errors, so I expected this to work. Have I missed something?

Make collections fields sortable, only when api doc shows support for it

Hi,

By default all resources have sorting enabled in admin component, regardless if api supports it.
Would be cool to show sorting on columns only if those api endpoints support it.

Plus I'm not sure if important, but for order_filter correct querystring should be ?order[field]=asc, but admin generates ?order=DESC&sort=field. Still works though.

Cheers.

Required input field

Hi,

I would like to add a parameter to indicate that the field is mandatory (the small ***** next to the label).
I did not find this information in the documentation, so I was seeing the documentation of "react-admin".

And in this last one can put it up in this way:

<TextInput source="title" validate={required()} />

But i got this error message:

Failed to compile
Line 110: 'required' is not defined no-undef

How can I manually add this setting?

Best regards,

How to avoid triggering dot notation in filters input source and use it as string

Hi,

I would like to use nested properties filters https://api-platform.com/docs/core/filters/#filtering-on-nested-properties
but in order to do so I need to provide querystring like this endpoint?city.name=search
which I cannot do because react-admin filter will generate endpoint?city[name]=search out of next example due to dot notation thing.

<Filter {...props}>
    <TextInput label='City' source='city.name' alwaysOn />
</Filter>

It looks like it goes into redux-form and jsx feature set, but how do I escape dot in this case?

Cheers.

Using Custom Components doesn't work

Hi,

I try to add a "RichTextField" & "RichTextInput" on a "description" field.
I follow the guide from doc. It's seems that tutorial is outdated.

Here is the new code (fixed new import, fixed key to access resources, minors refactors) :

import React from 'react';
import { RichTextField } from 'admin-on-rest';
import RichTextInput from 'aor-rich-text-input';
import { HydraAdmin } from '@api-platform/admin';
import parseHydraDocumentation from '@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation';

const entrypoint = 'https://demo.api-platform.com';

const apiDocumentationParser = entrypoint => parseHydraDocumentation(entrypoint)
 .then(parsedApi => {

  parsedApi.api.resources.map(resource => {

   if ('books' === resource.name) {
    resource.fields.find(f => 'description' === f.name).fieldComponent = <RichTextField source="description" key="description" /> ;
    resource.fields.find(f => 'description' === f.name).inputComponent = <RichTextInput source="description" key="description" /> ;
   }

   return resource;
  });

  return parsedApi;
 });

export default () => <HydraAdmin apiDocumentationParser={apiDocumentationParser} entrypoint={entrypoint} />;

The RichTextInput is installed :

yarn add aor-rich-text-input

With this configuration, the RichTextInput & RichTextField are not displayed on admin.
If I inspect the element with a console.log('PARSED API', parsedApi); on the "apiDocumentationParser" function, the field type is correct (Type : RichTextInput).

What I have missed ?

When it's fixed for me, I'll make a PR to update doc.

Thank's for your help.

Nico

Unable to retrieve API documentation.

I am using the latest Symfony 4, api-platform bundle, and following the documentation to setup api and admin

the api works(screenshot):

image

the admin(screenshot):
image

And I disable the cors in chrome, but still not work

And I try to remove react and react-dom in package.json and yarn install agin, it still not work

React and Admin On Rest support

See https://github.com/dunglas/admin/tree/react

TODO:

  • Create a Hydra parser
  • Create an intermediate representation for the API client
  • Create a Hydra client
  • Add a bridge with Admin On Rest
  • Add pagination support
  • Allow to decorate the Field and Input factory
  • Add support filters
  • Extract the Hydra parser in a separate repository
  • Add tests
  • Add a generator for Redux Form (react and react native)

ping @meyerbaptiste

Unable to retrieve API documentation.

Hi I am having a issue.

I follow the steps below:

In my project folder

  1. create-react-app my-admin
  2. cd my-admin
    yarn add @api-platform/admin
  3. edit the src/App.js by the way in the official website the https://api-platform.com/docs/admin/getting-started @api-platform-admin is incorrect you should update to @api-platform/admin
    import React, { Component } from 'react';
    import { HydraAdmin } from '@api-platform/admin';

class App extends Component {
render() {
return // Replace with your own API entrypoint
}
}

export default App;

  1. yarn start

  2. it opens my google chrome and I get .... Unable to retrieve API documentation.

I use postman to retrieve https://demo.api-platform.com and I get the usual book and review objects... I get the same result if I use my local end-point.

Can you please shed some light on this one... Maybe it is related to this project https://github.com/api-platform/api-platform-doc-parsing-check ?
Thanks

'name conversion' and admin component issue

When I turn on name_convertion to name_converter: 'Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter' as documentation says (https://api-platform.com/docs/core/serialization#name-conversion), in api response I see properies like that: person_name, instead defined in entity: personName but admin component won't show that fields:(

When I turned off, in api response I see personName and admin comnponent show that fields

where/or how I can configure admin to show that fields?

React app does not work

Hello I have followed a guide, I have a tiny simple API build with api-platform but when I try to run Admin I have error in this line:

var range = supportedProperty['http://www.w3.org/ns/hydra/core#property'][0]['http://www.w3.org/2000/01/rdf-schema#range'][0]['@id'];

https://www.dropbox.com/s/9f5muw1ns0wkghv/%D0%A1%D0%BA%D1%80%D0%B8%D0%BD%D1%88%D0%BE%D1%82%202017-05-08%2008.53.59.png?dl=0

API entry point is correct, what else should I do to run this admin interface
@dunglas

Request causes error when an order filter is present on a resource

Hi!

First and foremost, thanks for your amazing work. You simplify the life of a lot of developers with your project.

I have an api-platform app and just initialized an admin spa using this repository.

I have a Contact resource configured like this:

/**
 * Entity/Contact.php
 * 
 * @ApiResource(
 *     attributes={
 *         "filters"={"contact.order"},
 *         "normalization_context"={"groups"={"contact.get"}}
 *     }
 */
# services.yml
services:
    contact.api.order_filter:
        autowire: false
        autoconfigure: false
        public: false
        parent: 'api_platform.doctrine.orm.order_filter'
        arguments: [{ createdAt: ~, updatedAt: ~, name: ~, email: ~, city: ~, country: ~, groups.group.name: ~ }]
        tags:
            - { name: 'api_platform.filter', id: 'contact.order' }

Fetching contacts from the /api endpoints works perfectly. However, the default admin client sends a request looking like this:
http://localhost:8080/app_dev.php/api/contacts?sort=id&order=DESC&page=1

which cause this error to happen:

Type error: Return value of 
ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\OrderFilter::extractProperties()
must be of the type array, string returned

Two issues here:

  1. I believe the query parameter should be something like order[id]=DESC.
  2. Also, as I use UUID, I don't want id to be the default sort field. How can I tell the admin to sort by default on another field (like createdAt) ?

Can't fetch linked entities

Hi,

I'm facing a problem with, I guess, linked entities: I got the error "http://my.awesome.api[object Object] is not a valid URL." on Firefox / "Failed to execute 'fetch' on 'Window': Failed to parse URL from http://my.awesome.api[object Object]" on Chrome

  • it happens both in list mode and in view mode: an indeterminate progress bar is still shown ('cause linked entities can't be retrieved, I guess)
  • in edit mode, the field(s) corresponding to linked entities are not pre-filled; but I can fill the field(s) (a list of entities urls is shown); I didn't tried to save changes

With the console:

  • I got only this: "Warning: Missing translation for key: "http://my.awesome.api[object Object] is not a valid URL."
  • There are not network requests to see what URL has been called
  • With the extension "React Developer Tools", I can see that the corresponding data (json) is attached to the cell where there is the indeterminate progress bar

Comparing to the admin-on-rest demo:

  • my api data are returned with hydra context

  • entities id are integer, like the demo

  • property @id refer to the relative endpoint of entities

  • Except the entry point and my webserver CORS configuration, I've not configured anything else for the admin parts

  • Other lists of entities that don't have relations works correctly (right now, my doctrines entities relations are Unidirectional)

I will take a look to "reactjs" part... But it's totally new for me!

Thanks for your help,

Regards

admin doesn't work against demo.api-platform.com

The exact error:

Fetch API cannot load http://demo.api-platform.com/docs.jsonld. Response for preflight is invalid (redirect)

image

How to reproduce:

  1. I'm using https://demo.api-platform.com as an api endpoint
    image
    OPTIONS response contains LINK header which refers to http://demo.api-platform.com/docs.jsonld (although I specified https).

  2. It is requesting http://demo.api-platform.com/docs.jsonld and receives 301 Moved Permanently and Location:https://demo.api-platform.com/docs.jsonld
    image

Also notice that first response is HTTP/2 and second one is HTTP 1.1

[FieldFactory] Handle *to many* references

The FieldFactory does'nt support to many references.
ReferenceManyField should be used instead of a ReferenceField.

Apparently, there is no facts in a doc to disguinsh a property referencing many resources from a property referencing only one resource.

Still, the plural form of a property name could be detected, but that would still be a wild guess...

Another approach would be a higher order component which will choose between a ReferenceField and a ReferenceManyField once populated by data: the data would be an array or not.

But this feels dodgy as well, there must be a way to find the right field before data population.

What's your toughts on this?

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.