Consistently set 'id' in FormSchema

The URL to request the schema representation is the unique identifier.
We can't default to $request->getURL() since that's different for form submissions.

The schema.schema_url key is redundant, since the identifier is already contained on the top level 'id' key.
Keeping schema_url in a schema itself makes it less portable, particularly once we transition into
generic schemas which are not reliant on a particular record context (that's only contained in the schema_url)

This also fixes the issue of form schemas not refreshing after submit,
e.g. when form fields are added or removed.
This commit is contained in:
Ingo Schommer 2016-10-10 10:46:19 +13:00
parent 840f275235
commit 1e478a5378
6 changed files with 20 additions and 17 deletions

View File

@ -26,7 +26,6 @@ class FormSchema {
'id' => $form->FormName(),
'action' => $form->FormAction(),
'method' => $form->FormMethod(),
'schema_url' => $schemaLink,
'attributes' => $form->getAttributes(),
'data' => [],
'fields' => [],

View File

@ -7,8 +7,7 @@ export default function schemaReducer(state = initialState, action = null) {
switch (action.type) {
case ACTION_TYPES.SET_SCHEMA: {
const id = action.payload.schema.schema_url;
return deepFreeze(Object.assign({}, state, { [id]: action.payload }));
return deepFreeze(Object.assign({}, state, { [action.payload.id]: action.payload }));
}
default:

View File

@ -11,14 +11,17 @@ describe('schemaReducer', () => {
describe('SET_SCHEMA', () => {
it('should create a new form', () => {
const initialState = { };
const serverResponse = { id: 'TestForm', schema_url: 'URL' };
const schema = {
id: 'MySchema',
schema: { id: 'TestForm' },
};
const nextState = schemaReducer(initialState, {
type: ACTION_TYPES.SET_SCHEMA,
payload: { schema: serverResponse },
payload: schema,
});
expect(nextState.URL.schema.id).toBe('TestForm');
expect(nextState.MySchema).toBe(schema);
});
});
});

View File

@ -98,13 +98,12 @@ class CampaignAdmin extends LeftAndMain implements PermissionProvider {
$adminURL = Convert::raw2js(AdminRootController::admin_url());
$json = <<<JSON
{
"id": "Form_EditForm",
"id": "{$adminURL}campaigns\/schema\/EditForm",
"schema": {
"name": "EditForm",
"id": "Form_EditForm",
"action": "schema",
"method": "GET",
"schema_url": "{$adminURL}campaigns\/schema\/EditForm",
"attributes": {
"id": "Form_EditForm",
"action": "{$adminURL}campaigns\/EditForm",
@ -539,8 +538,9 @@ JSON;
// Configure form to respond to validation errors with form schema
// if requested via react.
$form->setValidationResponseCallback(function() use ($form) {
return $this->getSchemaResponse($form);
$form->setValidationResponseCallback(function() use ($form, $record) {
$schemaId = Controller::join_links($this->Link('schema/DetailEditForm'), $record->exists() ? $record->ID : '');
return $this->getSchemaResponse($form, $schemaId);
});
return $form;

View File

@ -333,12 +333,13 @@ class LeftAndMain extends Controller implements PermissionProvider {
* schema if X-Formschema-Request header is set.
*
* @param Form $form
* @param String $id Optional, will default to the current request URL
* @return HTTPResponse
*/
protected function getSchemaResponse($form) {
protected function getSchemaResponse($form, $id = null) {
$request = $this->getRequest();
if($request->getHeader('X-Formschema-Request')) {
$data = $this->getSchemaForForm($form);
$data = $this->getSchemaForForm($form, $id);
$response = new HTTPResponse(Convert::raw2json($data));
$response->addHeader('Content-Type', 'application/json');
@ -355,10 +356,12 @@ class LeftAndMain extends Controller implements PermissionProvider {
* based on the request data.
*
* @param Form $form
* @param String $id Optional, will default to the current request URL
* @return array
*/
protected function getSchemaForForm(Form $form) {
protected function getSchemaForForm(Form $form, $id = null) {
$request = $this->getRequest();
$id = $id ? $id : $request->getURL();
$return = null;
// Valid values for the "X-Formschema-Request" header are "schema" and "state".
@ -373,7 +376,7 @@ class LeftAndMain extends Controller implements PermissionProvider {
$schemaParts = ['schema'];
}
$return = ['id' => $form->FormName()];
$return = ['id' => $id];
if (in_array('schema', $schemaParts)) {
$schemaLink = $this->getSchemaLinkForForm($form);
@ -1302,10 +1305,11 @@ class LeftAndMain extends Controller implements PermissionProvider {
$message = _t('LeftAndMain.SAVEDUP', 'Saved.');
if($request->getHeader('X-Formschema-Request')) {
$schemaId = Controller::join_links($this->Link('schema/DetailEditForm'), $id);
// Ensure that newly created records have all their data loaded back into the form.
$form->loadDataFrom($record);
$form->setMessage($message, 'good');
$data = $this->getSchemaForForm($form);
$data = $this->getSchemaForForm($form, $schemaId);
$response = new HTTPResponse(Convert::raw2json($data));
$response->addHeader('Content-Type', 'application/json');
} else {

View File

@ -20,7 +20,6 @@ class FormSchemaTest extends SapphireTest {
'id' => 'Form_TestForm',
'action' => 'Controller/TestForm',
'method' => 'POST',
'schema_url' => 'admin/mysection/schema',
'attributes' => [
'id' => 'Form_TestForm',
'action' => 'Controller/TestForm',
@ -171,7 +170,6 @@ class FormSchemaTest extends SapphireTest {
'id' => 'Form_TestForm',
'action' => 'Controller/TestForm',
'method' => 'POST',
'schema_url' => 'admin/mysection/schema',
'attributes' => [
'id' => 'Form_TestForm',
'action' => 'Controller/TestForm',