Created
January 27, 2019 10:35
-
-
Save SohanChy/1840b77348d2a5d338a1cdee39e16235 to your computer and use it in GitHub Desktop.
ReactAdmin + Laravel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers\Api; | |
use App\Helpers\JsonRequest; | |
use App\Helpers\JsonReturn; | |
use App\Http\Controllers\Controller; | |
use App\Models\Reading; | |
use Illuminate\Http\Request; | |
use Illuminate\Support\Facades\DB; | |
use Illuminate\Validation\Rule; | |
class ExampleController extends Controller | |
{ | |
public function getReadingTypes(Request $request){ | |
return JsonReturn::successWithList(Reading::$readingTypes); | |
} | |
public function saveReadings(JsonRequest $request){ | |
list($fails, $messages) = make_api_json_arr_validator($request,Reading::getCreateUpdateValidationRules()); | |
if($fails){ | |
return JsonReturn::error($messages); | |
} | |
else { | |
$readingsList = []; | |
$messageList = []; | |
DB::transaction(function () use ($request, &$readingsList, &$messageList) { | |
foreach ($request->all() as $readingData){ | |
list($reading, $message) = Reading::createOrUpdate($readingData); | |
$readingsList[] = $reading; | |
$messageList[] = $message; | |
} | |
}); | |
return JsonReturn::successWithList( | |
$readingsList, | |
__("api.saved_readings_multiple", ['count' => count($readingsList)] | |
)); | |
} | |
} | |
public function getReadingList(Request $request){ | |
$validator = make_api_validator($request, | |
$rules = [ | |
'date' => 'required|date', | |
'reading_type' => [Rule::in(array_keys(Reading::$readingTypes))], | |
] | |
); | |
if ($validator->fails()) { | |
return JsonReturn::error($validator->messages()); | |
} | |
$readingList = Reading::date($request->date)->readingType($request->reading_type)->get(); | |
return JsonReturn::successWithList($readingList); | |
} | |
public function getReading(Reading $reading){ | |
return JsonReturn::successWithObject($reading); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
*/ | |
const laravelHttpClient = (url, options = {}) => { | |
let token = document.head.querySelector('meta[name="csrf-token"]'); | |
if (!options.headers) { | |
if (!options.headers) { | |
options.headers = new Headers({ Accept: 'application/json' }); | |
} | |
} | |
// add your own headers here | |
options.headers.set('X-CSRF-TOKEN', token.content); | |
return fetchUtils.fetchJson(url, options); | |
} | |
export default (apiUrl, httpClient = laravelHttpClient) => { | |
/** | |
* @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 = ''; | |
const options = {}; | |
switch (type) { | |
case GET_LIST: { | |
const { page, perPage } = params.pagination; | |
const { field, order } = params.sort; | |
const query = { | |
sort: JSON.stringify([field, order]), | |
page: JSON.stringify(page), | |
perPage: JSON.stringify(perPage), | |
filter: JSON.stringify(params.filter), | |
}; | |
url = `${apiUrl}/${resource}?${stringify(query)}`; | |
break; | |
} | |
case GET_ONE: | |
url = `${apiUrl}/${resource}/${params.id}`; | |
break; | |
case GET_MANY: { | |
const query = { | |
filter: JSON.stringify({ id: params.ids }), | |
}; | |
url = `${apiUrl}/${resource}?${stringify(query)}`; | |
break; | |
} | |
case GET_MANY_REFERENCE: { | |
const { page, perPage } = params.pagination; | |
const { field, order } = params.sort; | |
const query = { | |
sort: JSON.stringify([field, order]), | |
page: JSON.stringify(page), | |
perPage: JSON.stringify(perPage), | |
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: | |
case GET_MANY: | |
case GET_MANY_REFERENCE: | |
return { | |
data: json.data.map(x => x), | |
total: parseInt(json.total), | |
}; | |
case CREATE: | |
case UPDATE: | |
return { data: { ...json.data, id: json.data.id } }; | |
default: | |
return { data: json.data }; | |
} | |
}; | |
/** | |
* @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 => { | |
return 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 | |
); | |
return httpClient(url, options).then(response => | |
convertHTTPResponse(response, type, resource, params) | |
); | |
}; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Traits; | |
trait ReactAdminDataProviderDialect | |
{ | |
public function scopeFilter($query,$filter) | |
{ | |
$filters = json_decode($filter,true); | |
if(!$filters){ | |
return $query; | |
} | |
if(array_has($filters,"id")){ | |
$query->whereIn('id', $filters["id"]); | |
} | |
return $query; | |
} | |
public function scopeSort($query,$sort) | |
{ | |
if($sort){ | |
list($sortKey,$sortType) = json_decode($sort,true); | |
$query->orderBy(strtolower($sortKey), strtolower($sortType)); | |
} | |
return $query; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment