Я пытаюсь использовать Cockpit CMS в качестве бэкенда для отдыха, однако мне не удается понять Logi c провайдера отдыха и ресурса. По-видимому, мы сначала вызываем GET_LIST - который работает нормально, параметры ресурса et c установлены. но он также вызывает GET_MANY с emtpy Resource. Как вы можете видеть, я заменил
url = `${apiUrl}/${resource}?${stringify(query)}`;
на
url = `${apiUrl}/collections/get/testing?token=SOMETOKEN&filter[_id]=5e2037a536383609f00001cc`;
, что не вызывает ошибок, но я не понимаю, почему ресурс вызывается emtpy / undefined при вызове get_many.
Приложение. js:
import React from 'react';
import authProvider from './cockpitAuthProvider';
import { Admin, Resource, ListGuesser } from 'react-admin';
import simpleRestProvider from './simpleRestProviderlistCollections';
const App = () => (
<Admin authProvider={authProvider} dataProvider={simpleRestProvider('http://someurl/cockpit-0.9.3/api')}>
<Resource name="testing" list={ListGuesser} />
</Admin>
);
export default App;
simpleRestProviderlistCollections. js:
import { stringify } from 'query-string';
import {
fetchUtils,
GET_LIST,
GET_ONE,
GET_MANY,
GET_MANY_REFERENCE,
CREATE,
UPDATE,
UPDATE_MANY,
DELETE,
DELETE_MANY,
} from 'react-admin';
**
* Maps react-admin queries to a simple REST API
*
* The REST dialect is similar to the one of FakeRest
* @see https://github.com/marmelab/FakeRest
* @example
* GET_LIST => GET http://my.api.url/posts?sort=['title','ASC']&range=[0, 24]
* GET_ONE => GET http://my.api.url/posts/123
* GET_MANY => GET http://my.api.url/posts?filter={ids:[123,456,789]}
* UPDATE => PUT http://my.api.url/posts/123
* CREATE => POST http://my.api.url/posts
* DELETE => DELETE http://my.api.url/posts/123
*/
export default (apiUrl, httpClient = fetchUtils.fetchJson) => {
/**
* @param {String} type One of the constants appearing at the top if this file, e.g. 'UPDATE'
* @param {String} resource Name of the resource to fetch, e.g. 'posts'
* @param {Object} params The data request params, depending on the type
* @returns {Object} { url, options } The HTTP request parameters
*/
const convertDataRequestToHTTP = (type, resource, params) => {
let url = '';
console.log(`convertDataRequestToHTTP ${resource}`);
const options = {};
switch (type) {
case GET_LIST: {
console.log(`convertDataRequestToHTTP GET_LIST ${resource}`);
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([
(page - 1) * perPage,
page * perPage - 1,
]),
filter: JSON.stringify(params.filter),
};
//added a / before ?
//url = `${apiUrl}/${resource}/get/?${stringify(query)}`;
url = `${apiUrl}/collections/get/${resource}?token=SOMETOKEN`;
break;
}
case GET_ONE:
url = `${apiUrl}/${resource}/${params.id}`;
break;
case GET_MANY: {
console.log(`convertDataRequestToHTTP GET_MANY ${resource}`);
const query = {
filter: JSON.stringify({ id: params.ids }),
};
//url = `${apiUrl}/${resource}?${stringify(query)}`;
url = `${apiUrl}/collections/get/testing?token=SOMETOKEN&filter[_id]=5e2037a536383609f00001cc`;
break;
}
case GET_MANY_REFERENCE: {
console.log("convertDataRequestToHTTP GET_MANY_REFERENCE");
const { page, perPage } = params.pagination;
const { field, order } = params.sort;
const query = {
sort: JSON.stringify([field, order]),
range: JSON.stringify([
(page - 1) * perPage,
page * perPage - 1,
]),
filter: JSON.stringify({
...params.filter,
[params.target]: params.id,
}),
};
url = `${apiUrl}/${resource}?${stringify(query)}`;
break;
}
case UPDATE:
url = `${apiUrl}/${resource}/${params.id}`;
options.method = 'PUT';
options.body = JSON.stringify(params.data);
break;
case CREATE:
url = `${apiUrl}/${resource}`;
options.method = 'POST';
options.body = JSON.stringify(params.data);
break;
case DELETE:
url = `${apiUrl}/${resource}/${params.id}`;
options.method = 'DELETE';
break;
default:
throw new Error(`Unsupported fetch action type ${type}`);
}
return { url, options };
};
/**
* @param {Object} response HTTP response from fetch()
* @param {String} type One of the constants appearing at the top if this file, e.g. 'UPDATE'
* @param {String} resource Name of the resource to fetch, e.g. 'posts'
* @param {Object} params The data request params, depending on the type
* @returns {Object} Data response
*/
const convertHTTPResponse = (response, type, resource, params) => {
const { headers, json } = response;
switch (type) {
case GET_LIST:
var jnew = json.entries
return {
data: jnew.map(resource => ({ ...resource, id: resource._id }) ),
total: 1,
};
case GET_MANY_REFERENCE:
var jnew = json.entries
console.log(json)
return {
data: jnew.map(resource => ({ ...resource, id: resource._id }) ),
total: 1,
};
case CREATE:
return { data: { ...params.data, id: json._id } };
default:
return { data: json };
}
};
/**
* @param {string} type Request type, e.g GET_LIST
* @param {string} resource Resource name, e.g. "posts"
* @param {Object} payload Request parameters. Depends on the request type
* @returns {Promise} the Promise for a data response
*/
return (type, resource, params) => {
// simple-rest doesn't handle filters on UPDATE route, so we fallback to calling UPDATE n times instead
if (type === UPDATE_MANY) {
return Promise.all(
params.ids.map(id =>
httpClient(`${apiUrl}/${resource}/${id}`, {
method: 'PUT',
body: JSON.stringify(params.data),
})
)
).then(responses => ({
data: responses.map(response => response.json),
}));
}
// simple-rest doesn't handle filters on DELETE route, so we fallback to calling DELETE n times instead
if (type === DELETE_MANY) {
return Promise.all(
params.ids.map(id =>
httpClient(`${apiUrl}/${resource}/${id}`, {
method: 'DELETE',
})
)
).then(responses => ({
data: responses.map(response => response.json),
}));
}
const { url, options } = convertDataRequestToHTTP(
type,
resource,
params
);
console.log(resource)
console.log(options)
console.log(url)
return httpClient(url, options).then(response =>
convertHTTPResponse(response, type, resource, params)
);
};
};
Это также кажется проблемой при решении / решении: Как правильный способ иметь несколько провайдеров данных в реакции-администратора?
Потому что, если я делаю это путем решения, я также получаю ошибку:
TypeError: dataProviderMapping.dataProvider is not a function
из-за emtpy resource.
Я также попробовал это: https://github.com/marmelab/react-admin/blob/master/packages/ra-data-json-server/src/index.ts реализация, которая должна работать так:
getList GET http://my.api.url/posts?_sort=title&_order=ASC&_start=0&_end=24&title=bar
getMany GET http://my.api.url/posts/123, GET http://my.api.url/posts/456, GET http://my.api.url/posts/789
однако в моем случае он производит http://my.api.url/s/123 (с, поскольку ресурс пуст)
Api Возвращает: http://192.168.0.163/cockpit-0.9.3/api/collections/get/testing?token=TOKEN
{"fields":{"bla":{"name":"bla","type":"text","localize":false,"options":[]},"blup":{"name":"blup","type":"text","localize":false,"options":[]}},"entries":[{"bla":"dgfhs","blup":"sdgfh","_mby":"5ddc222d36383611fa00025a","_by":"5ddc222d36383611fa00025a","_modified":1579169696,"_created":1579169696,"_id":"5e2037a036383609f0000270"},{"bla":"sgdf","blup":"sdfg","_mby":"5ddc222d36383611fa00025a","_by":"5ddc222d36383611fa00025a","_modified":1579169701,"_created":1579169701,"_id":"5e2037a536383609f00001cc"}],"total":2}
http://192.168.0.163/cockpit-0.9.3/api/collections/get/testing?token=TOKEN&filter [_ id ] = 5e2037a536383609f00001 cc
{
"fields": {
"bla": {
"name": "bla",
"type": "text",
"localize": false,
"options": []
},
"blup": {
"name": "blup",
"type": "text",
"localize": false,
"options": []
}
},
"entries": [
{
"bla": "sgdf",
"blup": "sdfg",
"_mby": "5ddc222d36383611fa00025a",
"_by": "5ddc222d36383611fa00025a",
"_modified": 1579169701,
"_created": 1579169701,
"_id": "5e2037a536383609f00001cc"
}
],
"total": 1
}