mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-10 11:33:17 +00:00
Address PR comment's
Fix tests
This commit is contained in:

committed by
Romain Neutron

parent
848413dead
commit
b52e4ee8c0
@@ -17,7 +17,7 @@ use Silex\Application;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use PHPExiftool\Exception\TagUnknown;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
|
||||
class Fields implements ControllerProviderInterface
|
||||
{
|
||||
@@ -90,85 +90,51 @@ class Fields implements ControllerProviderInterface
|
||||
|
||||
public function updateFields(Application $app, Request $request, $sbas_id)
|
||||
{
|
||||
$json = array(
|
||||
'success' => false,
|
||||
// use to store the updated collection
|
||||
'fields' => array(),
|
||||
'messages' => array()
|
||||
);
|
||||
|
||||
$fields = array();
|
||||
$databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id);
|
||||
$metaStructure = $databox->get_meta_structure();
|
||||
$connection = $databox->get_connection();
|
||||
$data = $this->getFieldsJsonFromRequest($app, $request);
|
||||
|
||||
// calculate max position
|
||||
try {
|
||||
$stmt = $connection->prepare('SELECT MAX(sorter) as max_position FROM metadatas_structure');
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
$maxPosition = $row['max_position'] + 1;
|
||||
} catch (\PDOException $e) {
|
||||
$app->abort(500);
|
||||
}
|
||||
|
||||
$connection->beginTransaction();
|
||||
$i = 0;
|
||||
|
||||
foreach ($data as $jsonField) {
|
||||
try {
|
||||
$jsonField['sorter'] = $jsonField['sorter'] + $maxPosition;
|
||||
$field = \databox_field::get_instance($app, $databox, $jsonField['id']);
|
||||
$this->updateFieldWithData($app, $field, $jsonField);
|
||||
$field->save();
|
||||
$json['fields'][] = $field->toArray();
|
||||
$i++;
|
||||
} catch (\PDOException $e) {
|
||||
if ($e->errorInfo[1] == 1062) {
|
||||
$json['messages'][] = _(sprintf('Field name %s already exists', $jsonField['name']));
|
||||
} else {
|
||||
$json['messages'][] = _(sprintf('Field %s could not be saved, please retry or contact an administrator if problem persists', $jsonField['name']));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \Exception_Databox_metadataDescriptionNotFound || $e->getPrevious() instanceof TagUnknown) {
|
||||
$json['messages'][] = _(sprintf('Provided tag %s is unknown', $jsonField['tag']));
|
||||
} else {
|
||||
$json['messages'][] = _(sprintf('Field %s could not be saved, please retry or contact an administrator if problem persists', $jsonField['name']));
|
||||
}
|
||||
}
|
||||
|
||||
if ($field->get_name() !== $jsonField['name']) {
|
||||
$this->validateNameField($metaStructure, $jsonField);
|
||||
}
|
||||
|
||||
if ($i === count($data)) {
|
||||
// update field position in database, this query forces to update all fields each time
|
||||
$stmt = $connection->prepare(sprintf('UPDATE metadatas_structure SET sorter = (sorter - %s)', $maxPosition));
|
||||
$row = $stmt->execute();
|
||||
$stmt->closeCursor();
|
||||
$this->validateTagField($jsonField);
|
||||
|
||||
$this->updateFieldWithData($app, $field, $jsonField);
|
||||
$field->save();
|
||||
$fields[] = $field->toArray();
|
||||
} catch (\Exception $e) {
|
||||
$connection->rollback();
|
||||
$app->abort(500, _(sprintf('Field %s could not be saved, please try again or contact an admin', $jsonField['name'])));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$connection->commit();
|
||||
|
||||
$json['success'] = true;
|
||||
$json['messages'][] = _('Fields configuration has been saved');
|
||||
|
||||
// update field position in array
|
||||
array_walk($json['fields'], function(&$field) use ($maxPosition) {
|
||||
$field['sorter'] = $field['sorter'] - $maxPosition;
|
||||
});
|
||||
} else {
|
||||
$connection->rollback();
|
||||
}
|
||||
|
||||
return $app->json($json);
|
||||
return $app->json($fields);
|
||||
}
|
||||
|
||||
public function getLanguage(Application $app, Request $request)
|
||||
{
|
||||
return $app->json(array(
|
||||
'something_wrong' => _('Something wrong happened, please try again or contact an admin if problem persists'),
|
||||
'something_wrong' => _('Something wrong happened, please try again or contact an admin'),
|
||||
'created_success' => _('%s field has been created with success'),
|
||||
'deleted_success' => _('%s field has been deleted with success'),
|
||||
'are_you_sure_delete' => _('Do you really want to delete the field %s ?'),
|
||||
'validation_blank' => _('Field can not be blank'),
|
||||
'validation_name_exists' => _('Field name already exists'),
|
||||
'validation_tag_invalid' => _('Field source is not valid'),
|
||||
'field_error' => _('Field %s contains errors'),
|
||||
'fields_save' => _('Your configuration has been successfuly saved'),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -245,40 +211,26 @@ class Fields implements ControllerProviderInterface
|
||||
}
|
||||
|
||||
public function createField(Application $app, Request $request, $sbas_id) {
|
||||
$json = array(
|
||||
'success' => false,
|
||||
'message' => _('Something wrong happened, please try again or contact an admin if problem persists'),
|
||||
'field' => array()
|
||||
);
|
||||
$headers = array();
|
||||
|
||||
$databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id);
|
||||
$data = $this->getFieldJsonFromRequest($app, $request);
|
||||
|
||||
$metaStructure = $databox->get_meta_structure();
|
||||
$this->validateNameField($metaStructure, $data);
|
||||
$this->validateTagField($data);
|
||||
|
||||
try {
|
||||
$field = \databox_field::create($app, $databox, $data['name'], $data['multi']);
|
||||
|
||||
$this->updateFieldWithData($app, $field, $data);
|
||||
$field->save();
|
||||
|
||||
$json['success'] = true;
|
||||
$headers['location'] = $app->path('admin_fields_show_field', array(
|
||||
'sbas_id' => $sbas_id,
|
||||
'id' => $field->get_id(),
|
||||
));
|
||||
$json['message'] = _(sprintf('Tag name %s has been created successfully', $data['name']));
|
||||
$json['field'] = $field->toArray();
|
||||
} catch (\PDOException $e) {
|
||||
if ($e->errorInfo[1] == 1062) {
|
||||
$json['message'] = _(sprintf('Field name %s already exists', $data['name']));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \Exception_Databox_metadataDescriptionNotFound || $e->getPrevious() instanceof TagUnknown) {
|
||||
$json['message'] = _(sprintf('Provided tag %s is unknown', $data['tag']));
|
||||
}
|
||||
$app->abort(500, _(sprintf('Field %s could not be created, please try again or contact an admin', $data['name'])));
|
||||
}
|
||||
|
||||
return $app->json($json, 201, $headers);
|
||||
return $app->json($field->toArray(), 201, array(
|
||||
'location' => $app->path('admin_fields_show_field', array(
|
||||
'sbas_id' => $sbas_id,
|
||||
'id' => $field->get_id()
|
||||
))));
|
||||
}
|
||||
|
||||
public function listFields(Application $app, $sbas_id) {
|
||||
@@ -301,6 +253,13 @@ class Fields implements ControllerProviderInterface
|
||||
$field = \databox_field::get_instance($app, $databox, $id);
|
||||
$data = $this->getFieldJsonFromRequest($app, $request);
|
||||
|
||||
$this->validateTagField($data);
|
||||
|
||||
if ($field->get_name() !== $data['name']) {
|
||||
$metaStructure = $databox->get_meta_structure();
|
||||
$this->validateNameField($metaStructure, $data);
|
||||
}
|
||||
|
||||
$this->updateFieldWithData($app, $field, $data);
|
||||
$field->save();
|
||||
|
||||
@@ -317,13 +276,7 @@ class Fields implements ControllerProviderInterface
|
||||
|
||||
private function getFieldJsonFromRequest(Application $app, Request $request)
|
||||
{
|
||||
$body = $request->getContent();
|
||||
$data = @json_decode($body, true);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
$app->abort(400, 'Body must contain a valid JSON payload');
|
||||
}
|
||||
|
||||
$data = $this->requestBodyToJson($request);
|
||||
$required = $this->getMandatoryFieldProperties();
|
||||
|
||||
foreach ($required as $key) {
|
||||
@@ -337,13 +290,7 @@ class Fields implements ControllerProviderInterface
|
||||
|
||||
private function getFieldsJsonFromRequest(Application $app, Request $request)
|
||||
{
|
||||
$body = $request->getContent();
|
||||
$data = @json_decode($body, true);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
$app->abort(400, 'Body must contain a valid JSON payload');
|
||||
}
|
||||
|
||||
$data = $this->requestBodyToJson($request);
|
||||
$required = $this->getMandatoryFieldProperties();
|
||||
|
||||
foreach($data as $field) {
|
||||
@@ -386,14 +333,15 @@ class Fields implements ControllerProviderInterface
|
||||
|
||||
}
|
||||
|
||||
$dces_element = null;
|
||||
if ('' !== $dcesElement = (string) $data['dces-element']) {
|
||||
$class = sprintf('\databox_Field_DCES_%s', $dcesElement);
|
||||
|
||||
$class = '\databox_Field_DCES_' . $data['dces-element'];
|
||||
if (class_exists($class)) {
|
||||
$dces_element = new $class();
|
||||
if (!class_exists($class)) {
|
||||
throw new BadRequestHttpException(sprintf('DCES element %s does not exist', $dcesElement));
|
||||
}
|
||||
|
||||
$field->set_dces_element($dces_element);
|
||||
$field->set_dces_element(new $class());
|
||||
}
|
||||
}
|
||||
|
||||
private function getMandatoryFieldProperties()
|
||||
@@ -404,4 +352,32 @@ class Fields implements ControllerProviderInterface
|
||||
'vocabulary-type', 'vocabulary-restricted', 'dces-element'
|
||||
);
|
||||
}
|
||||
|
||||
private function validateNameField(\databox_descriptionStructure $metaStructure, array $field)
|
||||
{
|
||||
if (null !== $metaStructure->get_element_by_name($field['name'])) {
|
||||
throw new BadRequestHttpException(_(sprintf('Field %s already exists', $field['name'])));
|
||||
}
|
||||
}
|
||||
|
||||
private function validateTagField(array $field)
|
||||
{
|
||||
try {
|
||||
\databox_field::loadClassFromTagName($field['tag']);
|
||||
} catch(\Exception_Databox_metadataDescriptionNotFound $e) {
|
||||
throw new BadRequestHttpException(_(sprintf('Provided tag %s is unknown', $field['tag'])));
|
||||
}
|
||||
}
|
||||
|
||||
private function requestBodyToJson(Request $request)
|
||||
{
|
||||
$body = $request->getContent();
|
||||
$data = @json_decode($body, true);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
throw new BadRequestHttpException('Body must contain a valid JSON payload');
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@
|
||||
* @license http://opensource.org/licenses/gpl-3.0 GPLv3
|
||||
* @link www.phraseanet.com
|
||||
*/
|
||||
class databox_descriptionStructure implements IteratorAggregate
|
||||
class databox_descriptionStructure implements IteratorAggregate, Countable
|
||||
{
|
||||
/**
|
||||
*
|
||||
@@ -138,4 +138,13 @@ class databox_descriptionStructure implements IteratorAggregate
|
||||
return $element->toArray();
|
||||
}, array_values($this->elements));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->elements);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -175,7 +175,11 @@ class databox_field implements cache_cacheableInterface
|
||||
|
||||
$connbas = $this->get_connection();
|
||||
|
||||
$sql = "SELECT * FROM metadatas_structure WHERE id=:id";
|
||||
$sql = "SELECT `thumbtitle`, `separator`, `dces_element`, `tbranch`,
|
||||
`type`, `report`, `multi`, `required`, `readonly`, `indexable`,
|
||||
`name`, `src`, `business`, `VocabularyControlType`,
|
||||
`RestrictToVocabularyControl`, `sorter`
|
||||
FROM metadatas_structure WHERE id=:id";
|
||||
|
||||
$stmt = $connbas->prepare($sql);
|
||||
$stmt->execute(array(':id' => $id));
|
||||
@@ -805,21 +809,21 @@ class databox_field implements cache_cacheableInterface
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_position()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
@@ -859,7 +863,7 @@ class databox_field implements cache_cacheableInterface
|
||||
'readonly' => $this->readonly,
|
||||
'multi' => $this->multi,
|
||||
'indexable' => $this->indexable,
|
||||
'dces-element' => $this->dces_element ? $this->dces_element->get_label(): null,
|
||||
'dces-element' => $this->dces_element ? $this->dces_element->get_label() : null,
|
||||
'vocabulary-type' => $this->Vocabulary ? $this->Vocabulary->getType() : null,
|
||||
'vocabulary-restricted' => $this->VocabularyRestriction,
|
||||
);
|
||||
|
@@ -4748,13 +4748,6 @@
|
||||
<field>required</field>
|
||||
</fields>
|
||||
</index>
|
||||
<index>
|
||||
<name>sorter</name>
|
||||
<type>UNIQUE</type>
|
||||
<fields>
|
||||
<field>sorter</field>
|
||||
</fields>
|
||||
</index>
|
||||
</indexes>
|
||||
<engine>InnoDB</engine>
|
||||
</table>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<div class="span4 save-block">
|
||||
{# set loading state, this will be removed once backbone application is fully loaded #}
|
||||
<img src="/skins/icons/loaderFFF.gif"/>
|
||||
{% trans %}Loading database documentary fields ...{% endtrans %}
|
||||
{% trans %}Loading database documentary structure ...{% endtrans %}
|
||||
</div>
|
||||
<div class="span8">
|
||||
<div class="block-alert"></div>
|
||||
@@ -21,5 +21,4 @@
|
||||
</div>
|
||||
|
||||
{# bootstrap admin field backbone application #}
|
||||
<script src="/assets/requirejs/require.js"></script>
|
||||
<script src="/scripts/apps/admin/fields/main.js"></script>
|
||||
<script type="text/javascript" src="/include/minify/f=/assets/requirejs/require.js,/scripts/apps/admin/fields/main.js"></script>
|
||||
|
@@ -198,12 +198,10 @@ class ControllerFieldsTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
|
||||
|
||||
$data = json_decode($response, true);
|
||||
|
||||
$this->assertArrayHasKey('success', $data);
|
||||
$this->assertArrayHasKey('messages', $data);
|
||||
$this->assertArrayHasKey('fields', $data);
|
||||
$this->assertTrue(is_array($data));
|
||||
|
||||
// expect last 2 fields from body equals last 2 fields from response
|
||||
$this->assertEquals(array_splice($body, -2), array_splice($data['fields'], -2));
|
||||
$this->assertEquals(array_splice($body, -2), array_splice($data, -2));
|
||||
|
||||
// delete created fields
|
||||
foreach($fieldObjects as $field) {
|
||||
@@ -242,17 +240,15 @@ class ControllerFieldsTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
|
||||
|
||||
$data = json_decode($response, true);
|
||||
|
||||
$this->assertArrayHasKey('success', $data);
|
||||
$this->assertArrayHasKey('message', $data);
|
||||
$this->assertArrayHasKey('field', $data);
|
||||
$this->assertTrue(is_array($data));
|
||||
|
||||
$dataWithoutIds = $data['field'];
|
||||
$dataWithoutIds = $data;
|
||||
unset($dataWithoutIds['id']);
|
||||
unset($dataWithoutIds['sorter']);
|
||||
|
||||
$this->assertEquals(json_decode($body, true), $dataWithoutIds);
|
||||
|
||||
$field = \databox_field::get_instance(self::$DI['app'], $databox, $data['field']['id']);
|
||||
$field = \databox_field::get_instance(self::$DI['app'], $databox, $data['id']);
|
||||
$field->delete();
|
||||
}
|
||||
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"underscore",
|
||||
"backbone",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"underscore",
|
||||
"backbone",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"underscore",
|
||||
"backbone",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore"
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore"
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// configure AMD loading
|
||||
require.config({
|
||||
baseUrl: "/scripts",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
|
@@ -1,10 +1,19 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"backbone",
|
||||
"i18n",
|
||||
"bootstrap",
|
||||
"apps/admin/fields/views/create",
|
||||
"apps/admin/fields/views/alert",
|
||||
"models/field"
|
||||
], function($, _, Backbone, i18n, bootstrap, AlertView, FieldModel) {
|
||||
var CreateView = Backbone.View.extend({
|
||||
@@ -105,18 +114,18 @@ define([
|
||||
|
||||
field.save(null, {
|
||||
success: function(field, response, options) {
|
||||
if (response.success) {
|
||||
AdminFieldApp.fieldsCollection.add(field);
|
||||
_.last(self.itemViews).clickAction().animate();
|
||||
}
|
||||
_.last(AdminFieldApp.fieldListView.itemViews).clickAction().animate();
|
||||
|
||||
new AlertView({
|
||||
alert: response.success ? "success" : "error", message: response.message
|
||||
new AlertView({alert: "info", message: i18n.t("created_success", {
|
||||
postProcess: "sprintf",
|
||||
sprintf: [field.get("name")]
|
||||
})
|
||||
}).render();
|
||||
},
|
||||
error: function(model, xhr, options) {
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
new AlertView({
|
||||
alert: "error", message: i18n.t("something_wrong")}
|
||||
alert: "error", message: '' !== xhr.responseText ? xhr.responseText : i18n.t("something_wrong")}
|
||||
).render();
|
||||
|
||||
self.toggleCreateFormAction();
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
@@ -64,31 +73,6 @@ define([
|
||||
var fieldTagId = fieldTag.attr("id");
|
||||
var fieldTagValue = fieldTag.val();
|
||||
|
||||
// check for format tag
|
||||
if ("" !== fieldTagValue && false === /[a-z]+:[a-z0-9]+/i.test(fieldTagValue)) {
|
||||
fieldTag
|
||||
.closest(".control-group")
|
||||
.addClass("error")
|
||||
.find(".help-block")
|
||||
.empty()
|
||||
.append(i18n.t("validation_tag_invalid"));
|
||||
// add error
|
||||
AdminFieldApp.errorManager.addModelFieldError(new Error(
|
||||
self.model, fieldTagId, i18n.t("validation_tag_invalid")
|
||||
));
|
||||
} else if (fieldTag.closest(".control-group").hasClass("error")) {
|
||||
// remove error
|
||||
AdminFieldApp.errorManager.removeModelFieldError(
|
||||
self.model, fieldTagId
|
||||
);
|
||||
|
||||
fieldTag
|
||||
.closest(".control-group")
|
||||
.removeClass("error")
|
||||
.find(".help-block")
|
||||
.empty();
|
||||
}
|
||||
|
||||
var data = {};
|
||||
data[fieldTagId] = fieldTagValue;
|
||||
self.model.set(data);
|
||||
@@ -109,6 +93,7 @@ define([
|
||||
"click .delete-field": "deleteAction",
|
||||
"keyup #name": "changeNameAction",
|
||||
"focusout input[type=text]": "fieldChangedAction",
|
||||
"focusout input#tag": "tagFieldChangedAction",
|
||||
"change input[type=checkbox]": "fieldChangedAction",
|
||||
"change select": "selectionChangedAction"
|
||||
},
|
||||
@@ -170,6 +155,38 @@ define([
|
||||
|
||||
return this;
|
||||
},
|
||||
tagFieldChangedAction: function(e) {
|
||||
var fieldTag = $(e.target);
|
||||
var fieldTagId = fieldTag.attr("id");
|
||||
var fieldTagValue = fieldTag.val();
|
||||
|
||||
// check for format tag
|
||||
if ("" !== fieldTagValue && false === /[a-z]+:[a-z0-9]+/i.test(fieldTagValue)) {
|
||||
fieldTag
|
||||
.closest(".control-group")
|
||||
.addClass("error")
|
||||
.find(".help-block")
|
||||
.empty()
|
||||
.append(i18n.t("validation_tag_invalid"));
|
||||
// add error
|
||||
AdminFieldApp.errorManager.addModelFieldError(new Error(
|
||||
this.model, fieldTagId, i18n.t("validation_tag_invalid")
|
||||
));
|
||||
} else if (fieldTag.closest(".control-group").hasClass("error")) {
|
||||
// remove error
|
||||
AdminFieldApp.errorManager.removeModelFieldError(
|
||||
this.model, fieldTagId
|
||||
);
|
||||
|
||||
fieldTag
|
||||
.closest(".control-group")
|
||||
.removeClass("error")
|
||||
.find(".help-block")
|
||||
.empty();
|
||||
}
|
||||
|
||||
this.fieldChangedAction(e);
|
||||
},
|
||||
deleteAction: function() {
|
||||
var self = this;
|
||||
var modalView = new ModalView({
|
||||
@@ -200,9 +217,9 @@ define([
|
||||
})
|
||||
}).render();
|
||||
},
|
||||
error: function(model, xhr) {
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
new AlertView({
|
||||
alert: "error", message: i18n.t("something_wrong")
|
||||
alert: "error", message: '' !== xhr.responseText ? xhr.responseText : i18n.t("something_wrong")
|
||||
}).render();
|
||||
}
|
||||
});
|
||||
@@ -213,12 +230,13 @@ define([
|
||||
_onModelChange: function() {
|
||||
AdminFieldApp.fieldListView.collection.remove(this.model, {silent: true});
|
||||
AdminFieldApp.fieldListView.collection.add(this.model);
|
||||
|
||||
var index = AdminFieldApp.fieldListView.collection.indexOf(this.model);
|
||||
|
||||
this._selectModelView(index);
|
||||
|
||||
this.render();
|
||||
|
||||
AdminFieldApp.saveView.updateStateButton();
|
||||
},
|
||||
// select temView by index in itemList
|
||||
_selectModelView: function(index) {
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"jqueryui",
|
||||
@@ -85,7 +94,6 @@ define([
|
||||
placeholder: "item-list-placeholder",
|
||||
start: function(event, ui) {
|
||||
ui.item.addClass("border-bottom");
|
||||
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
ui.firstItemPosition = $("li:first", $(this).sortable('widget')).position().top;
|
||||
@@ -105,18 +113,18 @@ define([
|
||||
return this;
|
||||
},
|
||||
updateSortAction: function(event, model, ui) {
|
||||
var position = ui.item.index();
|
||||
this.collection.remove(model, {silent: true});
|
||||
var newPosition = ui.item.index();
|
||||
var curPosition = this.collection.indexOf(model);
|
||||
|
||||
// reorder all collection model
|
||||
this.collection.each(function(model, index) {
|
||||
var ordinal = index;
|
||||
if (index >= position) ordinal += 1;
|
||||
model.set("sorter", ordinal);
|
||||
this.collection.each(function(el, index) {
|
||||
if (newPosition > curPosition && (index > curPosition && index <= curPosition)) index -= 1;
|
||||
else if (newPosition < curPosition && (index >= curPosition && index < curPosition)) index += 1;
|
||||
|
||||
el.set("sorter", index);
|
||||
});
|
||||
|
||||
model.set("sorter", position);
|
||||
this.collection.add(model, {at: position});
|
||||
this.render();
|
||||
|
||||
this.itemViews[0].animate(Math.abs(ui.firstItemPosition));
|
||||
|
||||
@@ -125,6 +133,8 @@ define([
|
||||
return el.get("id") === AdminFieldApp.fieldEditView.model.get("id");
|
||||
});
|
||||
|
||||
AdminFieldApp.saveView.updateStateButton();
|
||||
|
||||
return this;
|
||||
}
|
||||
}));
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
@@ -29,20 +38,18 @@ define([
|
||||
if (this._isModelDesync()) {
|
||||
this._loadingState(true);
|
||||
AdminFieldApp.fieldsCollection.save({
|
||||
success: function(response) {
|
||||
success: function(fields) {
|
||||
// reset collection with new one
|
||||
if (response.success) {
|
||||
AdminFieldApp.fieldsCollection.reset(response.fields);
|
||||
}
|
||||
AdminFieldApp.fieldsCollection.reset(fields);
|
||||
|
||||
new AlertView({
|
||||
alert: response.success ? "success" : "error",
|
||||
message: response.messages.join("<br />")
|
||||
alert: "success",
|
||||
message: i18n.t("fields_save")
|
||||
}).render();
|
||||
},
|
||||
error: function(model, xhr, options) {
|
||||
error: function(xhr, textStatus, errorThrown) {
|
||||
new AlertView({
|
||||
alert: "error", message: i18n.t("something_wrong")
|
||||
alert: "error", message: '' !== xhr.responseText ? xhr.responseText : i18n.t("something_wrong")
|
||||
}).render();
|
||||
}
|
||||
}).done(function() {
|
||||
@@ -55,9 +62,13 @@ define([
|
||||
render: function () {
|
||||
var template = _.template($("#save_template").html());
|
||||
this.$el.html(template);
|
||||
this.updateStateButton();
|
||||
|
||||
return this;
|
||||
},
|
||||
updateStateButton: function() {
|
||||
this._disableSaveButton(!this._isModelDesync());
|
||||
},
|
||||
// check whether model has changed or not
|
||||
_isModelDesync: function () {
|
||||
return "undefined" !== typeof AdminFieldApp.fieldsCollection.find(function(model) {
|
||||
@@ -86,7 +97,7 @@ define([
|
||||
$(".save-block", AdminFieldApp.$top).removeClass("loading");
|
||||
}
|
||||
|
||||
this._disableSaveButton(active);
|
||||
this.updateStateButton();
|
||||
this._overlay(active);
|
||||
}
|
||||
});
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"underscore",
|
||||
"backbone"
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"underscore",
|
||||
"backbone"
|
||||
|
@@ -1,3 +1,12 @@
|
||||
/*
|
||||
* This file is part of Phraseanet
|
||||
*
|
||||
* (c) 2005-2013 Alchemy
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
define([
|
||||
"underscore",
|
||||
"backbone"
|
||||
|
@@ -287,6 +287,14 @@ define([
|
||||
AdminFieldApp.fieldListView.render();
|
||||
});
|
||||
|
||||
it("should update collection when model change", function() {
|
||||
AdminFieldApp.fieldListView.itemViews[0].clickAction();
|
||||
AdminFieldApp.fieldEditView.model.set({
|
||||
"name": "new name"
|
||||
});
|
||||
assert.equal(AdminFieldApp.fieldListView.itemViews[0].model.get('name'), "new name", 'model is updated');
|
||||
});
|
||||
|
||||
it("should update edit view when clicking on single element", function() {
|
||||
AdminFieldApp.fieldListView.itemViews[0].clickAction();
|
||||
should.exist(AdminFieldApp.fieldEditView);
|
||||
@@ -296,15 +304,7 @@ define([
|
||||
it("should reorder collection on drop action", function() {
|
||||
var ui = {item: {index: function() {return 2;}}};
|
||||
AdminFieldApp.fieldListView.itemViews[0].dropAction({},ui);
|
||||
assert.equal(AdminFieldApp.fieldListView.collection.last().get('sorter'), 2, 'model is updated');
|
||||
});
|
||||
|
||||
it("should update collection when model change", function() {
|
||||
AdminFieldApp.fieldListView.itemViews[0].clickAction();
|
||||
AdminFieldApp.fieldEditView.model.set({
|
||||
"name": "new name"
|
||||
});
|
||||
assert.equal(AdminFieldApp.fieldListView.collection.first().get('name'), "new name", 'model is updated');
|
||||
assert.equal(AdminFieldApp.fieldListView.collection.last().get('sorter'), 3, 'model is updated');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user