mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-15 14:03:27 +00:00
Add admin field application
This commit is contained in:

committed by
Romain Neutron

parent
7199d38ab3
commit
05dc3659af
@@ -17,6 +17,7 @@ use Silex\Application;
|
|||||||
use Silex\ControllerProviderInterface;
|
use Silex\ControllerProviderInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use PHPExiftool\Exception\TagUnknown;
|
||||||
|
|
||||||
class Fields implements ControllerProviderInterface
|
class Fields implements ControllerProviderInterface
|
||||||
{
|
{
|
||||||
@@ -27,10 +28,18 @@ class Fields implements ControllerProviderInterface
|
|||||||
$app['admin.fields.controller'] = $this;
|
$app['admin.fields.controller'] = $this;
|
||||||
|
|
||||||
$controllers->before(function(Request $request) use ($app) {
|
$controllers->before(function(Request $request) use ($app) {
|
||||||
$app['firewall']->requireAccessToModule('admin')
|
$app['firewall']
|
||||||
|
->requireAccessToModule('admin')
|
||||||
->requireRight('bas_modify_struct');
|
->requireRight('bas_modify_struct');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$controllers->get('/language.json', 'admin.fields.controller:getLanguage')
|
||||||
|
->bind('admin_fields_language');
|
||||||
|
|
||||||
|
$controllers->get('/{sbas_id}', 'admin.fields.controller:displayApp')
|
||||||
|
->assert('sbas_id', '\d+')
|
||||||
|
->bind('admin_fields');
|
||||||
|
|
||||||
$controllers->get('/{sbas_id}/fields', 'admin.fields.controller:listFields')
|
$controllers->get('/{sbas_id}/fields', 'admin.fields.controller:listFields')
|
||||||
->assert('sbas_id', '\d+')
|
->assert('sbas_id', '\d+')
|
||||||
->bind('admin_fields_list');
|
->bind('admin_fields_list');
|
||||||
@@ -75,9 +84,26 @@ class Fields implements ControllerProviderInterface
|
|||||||
return $controllers;
|
return $controllers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getLanguage(Application $app) {
|
||||||
|
return $app->json(array(
|
||||||
|
'something_wrong' => _('Something wrong happened, please try again or contact an admin if problem persists'),
|
||||||
|
'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'),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function displayApp(Application $app, $sbas_id) {
|
||||||
|
return $app['twig']->render('/admin/fields/index.html.twig', array(
|
||||||
|
'sbas_id' => $sbas_id,
|
||||||
|
'js' => ''
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
public function listDcFields(Application $app, Request $request)
|
public function listDcFields(Application $app, Request $request)
|
||||||
{
|
{
|
||||||
$data = $app['serializer']->serialize(\databox::get_available_dcfields(), 'json');
|
$data = $app['serializer']->serialize(array_values(\databox::get_available_dcfields()), 'json');
|
||||||
|
|
||||||
return new Response($data, 200, array('content-type' => 'application/json'));
|
return new Response($data, 200, array('content-type' => 'application/json'));
|
||||||
}
|
}
|
||||||
@@ -120,7 +146,7 @@ class Fields implements ControllerProviderInterface
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$res[] = array(
|
$res[$tagname] = array(
|
||||||
'id' => $namespace . '/' . $tagname,
|
'id' => $namespace . '/' . $tagname,
|
||||||
'label' => $datas['namespace'] . ' / ' . $datas['tagname'],
|
'label' => $datas['namespace'] . ' / ' . $datas['tagname'],
|
||||||
'value' => $datas['namespace'] . ':' . $datas['tagname'],
|
'value' => $datas['namespace'] . ':' . $datas['tagname'],
|
||||||
@@ -129,6 +155,8 @@ class Fields implements ControllerProviderInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ksort($res);
|
||||||
|
|
||||||
return $app->json($res);
|
return $app->json($res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,21 +169,40 @@ class Fields implements ControllerProviderInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function createField(Application $app, Request $request, $sbas_id) {
|
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);
|
$databox = $app['phraseanet.appbox']->get_databox((int) $sbas_id);
|
||||||
|
|
||||||
$data = $this->getFieldJsonFromRequest($app, $request);
|
$data = $this->getFieldJsonFromRequest($app, $request);
|
||||||
|
|
||||||
$field = \databox_field::create($app, $databox, $data['name'], $data['multi']);
|
try {
|
||||||
$this->updateFieldWithData($app, $field, $data);
|
$field = \databox_field::create($app, $databox, $data['name'], $data['multi']);
|
||||||
$field->save();
|
|
||||||
|
|
||||||
return $app->json($field->toArray(), 201, array(
|
$this->updateFieldWithData($app, $field, $data);
|
||||||
'Location' => $app->path('admin_fields_show_field', array(
|
$field->save();
|
||||||
'sbas_id' => $sbas_id,
|
|
||||||
'id' => $field->get_id(),
|
$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']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $app->json($json, 201, $headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function listFields(Application $app, $sbas_id) {
|
public function listFields(Application $app, $sbas_id) {
|
||||||
|
27
templates/web/admin/fields/index.html.twig
Normal file
27
templates/web/admin/fields/index.html.twig
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{# empty Twig template #}
|
||||||
|
<script type="text/javascript" src="/assets/i18n/i18next-1.6.0.min.js"></script>
|
||||||
|
|
||||||
|
{% include 'admin/fields/templates.html.twig' %}
|
||||||
|
|
||||||
|
<div id="admin-field-app" class="container-fluid">
|
||||||
|
<input type="hidden" name="current_sbas_id" value="{{ sbas_id }}">
|
||||||
|
<div class="row-fluid" style="min-height:60px; border-bottom: 1px solid #000">
|
||||||
|
<div class="span4">
|
||||||
|
<button type="button" class="btn btn-large btn-success"><i class="icon-hdd icon-white"></i> {% trans %}Save all changes{% endtrans %}</button>
|
||||||
|
</div>
|
||||||
|
<div class="span8">
|
||||||
|
<div class="block-alert well-small"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="left-block span4">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="right-block span8" style="border-left: 1px dashed #000">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/assets/requirejs/require.js"></script>
|
||||||
|
<script src="/scripts/apps/admin/fields/main.js"></script>
|
201
templates/web/admin/fields/templates.html.twig
Normal file
201
templates/web/admin/fields/templates.html.twig
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
<script type="text/template" id="alert_template">
|
||||||
|
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||||
|
<%= msg %>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/template" id="modal_delete_confirm_template">
|
||||||
|
<div class="modal-body">
|
||||||
|
<p><%= msg %></p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" data-dismiss="modal" class="btn cancel">{% trans %}Close{% endtrans %}</button>
|
||||||
|
<button type="button" class="btn btn-primary confirm">{% trans %}Ok{% endtrans %}</button>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/template" id="item_list_view_template">
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12">
|
||||||
|
|
||||||
|
<div style="margin:20px 0">
|
||||||
|
<button type="button" class="btn btn-success btn-add-field"><i class="icon-plus icon-white"></i>{% trans %}Add new field{% endtrans %}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin:20px 0">
|
||||||
|
<input class="input-block-level" type="text" id="live_search" placeholder="{% trans %}Live search{% endtrans %}"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="well well-small add-field-block" style="display:none">
|
||||||
|
<h3>{% trans %}Add a new field{% endtrans %}</h3>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="inputLabel">{% trans %}Label{% endtrans %}</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="new-name" class="input-block-level" placeholder="">
|
||||||
|
<span class="help-block"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="inputSource">{% trans %}Source{% endtrans %}</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="new-source" class="input-block-level" placeholder="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<div class="controls">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input id="new-multivalued" type="checkbox">{% trans %}Multivalued{% endtrans %}
|
||||||
|
</label>
|
||||||
|
<button type="button" class="btn btn-success btn-submit-field"><i class="icon-ok icon-white"></i>{% trans %}Add{% endtrans %}</button>
|
||||||
|
<button type="button" class="btn btn-cancel-field">{% trans %}Cancel{% endtrans %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12">
|
||||||
|
<ul id="collection-fields" class="unstyled" style="height:450px;overflow: auto;">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/template" id="edit_template">
|
||||||
|
<div style="padding: 5px 20px">
|
||||||
|
<table>
|
||||||
|
<tr style="height: 50px;">
|
||||||
|
<td>{% trans %}Order{% endtrans %}:</td>
|
||||||
|
<td><%= field.sorter %></td>
|
||||||
|
<td><button type="button" class="btn btn-danger delete-field pull-right"><i class="icon-trash icon-white"></i>delete</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr style="height: 60px;">
|
||||||
|
<td colspan="2"><input id="name" style="font-size:28px;color:#0080FF;height:42px;line-height:42px; font-weight:bold" value="<%= field.name %>" class="input-block-level"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{% trans %}Source{% endtrans %} : </td>
|
||||||
|
<td><input id="tag" type="text" val="<%= field.tag %>" class="input-block-level"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{% trans %}DCES{% endtrans %} : </td>
|
||||||
|
<td class="dc-fields-subview"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" class="dces-help-block"></td>
|
||||||
|
</tr>
|
||||||
|
<% if(field.multi == true) { %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<i class='icon-ok'></i> {% trans %}Multivalued{% endtrans %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% } %>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="edit-form">
|
||||||
|
<h4 style="padding: 10px 0;">{% trans %}Advanced field parameter{% endtrans %}</h4>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><label for="">{% trans %}Thesaurus branch{% endtrans %}</label></td>
|
||||||
|
<td><input id="tbranch" type="text" value="<%= field.tbranch %>"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="">{% trans %}Vocabulary type{% endtrans %}</label></td>
|
||||||
|
<td>
|
||||||
|
<select id="vocabulary-type" class="input-block-level">
|
||||||
|
<% _.each(vocabularyTypes, function(vocab) { %>
|
||||||
|
<option value="<%= vocab.type %>"><%= vocab.name %></option>
|
||||||
|
<% }); %>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="">{% trans %}Type{% endtrans %}</label></td>
|
||||||
|
<td>
|
||||||
|
<select id="type" class="input-block-level">
|
||||||
|
<option value=""></option>
|
||||||
|
<option <%= field.type == 'string' ? 'selected' : '' %> value="string">string</option>
|
||||||
|
<option <%= field.type == 'text' ? 'selected' : '' %> value="text">text</option>
|
||||||
|
<option <%= field.type == 'number' ? 'selected' : '' %> value="number">number</option>
|
||||||
|
<option <%= field.type == 'date' ? 'selected' : '' %> value="date">date</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><label for="" class="checkbox"><input id="business" type="checkbox" <%= field.business ? "checked='checked'" : "" %> />{% trans %}Business Fields{% endtrans %}</label></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><label for="" class="checkbox"><input id="vocabulary-restricted" type="checkbox" <%= field["vocavulary-restricted"] ? "checked='checked'" : "" %> />{% trans %}Limited vocabulary{% endtrans %}</label></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="">{% trans %}Separator{% endtrans %}</label></td>
|
||||||
|
<td><input id="separator" type="text" value="<%= field.separator %>" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<h4 style="padding: 10px 0;">{% trans %}display & action settings{% endtrans %}</h4>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><label for="" class="checkbox"><input id="required" type="checkbox" <%= field.required ? "checked='checked'" : "" %> />{% trans %}Mandatory{% endtrans %}</label></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><label for="" class="checkbox"><input id="indexable" type="checkbox" <%= field.indexable ? "checked='checked'" : "" %> />{% trans %}Indexable{% endtrans %}</label></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><label for="" class="checkbox"><input id="readonly" type="checkbox" <%= field.readonly ? "checked='checked'" : "" %> />{% trans %}Read only{% endtrans %}</label></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><label for="" class="checkbox"><input id="report" type="checkbox" <%= field.report ? "checked='checked'" : "" %> />{% trans %}Report{% endtrans %}</label></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><label for="">{% trans %}Display thumbnails{% endtrans %}</label></td>
|
||||||
|
<td>
|
||||||
|
<select id="thumbtitle" class="input-block-level">
|
||||||
|
<option value="1" <%= field.thumbtitle == "1" ? "selected" : "" %> >{% trans 'Tous' %}</option>
|
||||||
|
<option value="0" <%= field.thumbtitle == "0" ? "selected" : "" %> >{% trans 'Aucun' %}</option>
|
||||||
|
<option value="fr" <%= field.thumbtitle == "fr" ? "selected" : "" %> >{% trans 'Francais' %}</option>
|
||||||
|
<option value="nl" <%= field.thumbtitle == "nl" ? "selected" : "" %> >{% trans 'Dutch' %}</option>
|
||||||
|
<option value="de" <%= field.thumbtitle == "de" ? "selected" : "" %> >{% trans 'Allemand' %}</option>
|
||||||
|
<option value="en" <%= field.thumbtitle == "en" ? "selected" : "" %> >{% trans 'Anglais' %}</option>
|
||||||
|
<option value="ar" <%= field.thumbtitle == " r" ? "selected" : "" %> >{% trans 'Arabe' %}</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/template" id="list_row_template">
|
||||||
|
<table style="table-layout:fixed;width:100%;">
|
||||||
|
<tr>
|
||||||
|
<td class="handle" style="width: 10%; vertical-align:middle;text-align:center;cursor: move;">
|
||||||
|
<i class="icon-move"></i>
|
||||||
|
</td>
|
||||||
|
<td rowspan="2" class="trigger-click" style="padding:10px">
|
||||||
|
<div class="field-name"><%= name %></div>
|
||||||
|
<div class="field-tag"><%= tag %></div>
|
||||||
|
</td>
|
||||||
|
<td rowspan="2" class="trigger-click" style="width: 10%;padding:10px;">
|
||||||
|
<i class="icon-chevron-right"></i>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="position" style="width: 10%; vertical-align:bottom;text-align: center">
|
||||||
|
<%= position %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/template" id="dc_fields_template">
|
||||||
|
<select id="dces-element" val="" class="input-block-level">
|
||||||
|
<% _.each(dces_elements, function(el) { %>
|
||||||
|
<option value="<%= el.label %>">DC:<%= el.label %></option>
|
||||||
|
<% }); %>
|
||||||
|
</select>
|
||||||
|
<div class="help-block"></div>
|
||||||
|
</script>
|
@@ -8,7 +8,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block stylesheet %}
|
{% block stylesheet %}
|
||||||
<link type="text/css" rel="stylesheet" href="/include/minify/?f=include/jslibs/jquery-ui-1.8.17/css/ui-lightness/jquery-ui-1.8.17.custom.css,include/jslibs/jquery-treeview/jquery.treeview.css,include/jslibs/jquery.contextmenu.css,skins/account/geonames.css,skins/common/main.css,skins/admin/css/Main.css,skins/admin/css/Bases.css,skins/admin/css/Tables.css" />
|
<link type="text/css" rel="stylesheet" href="/include/minify/?f=include/jslibs/jquery-ui-1.8.17/css/ui-lightness/jquery-ui-1.8.17.custom.css,include/jslibs/jquery-treeview/jquery.treeview.css,include/jslibs/jquery.contextmenu.css,skins/account/geonames.css,skins/common/main.css,skins/admin/css/Main.css,skins/admin/css/Bases.css,skins/admin/css/Tables.css,skins/admin/css/fields.css " />
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -111,7 +111,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a target="right" href="/admin/description/{{ sbas_id }}/" class="ajax">
|
<a target="right" href="{{ path('admin_fields', {'sbas_id': sbas_id}) }}" class="ajax">
|
||||||
<img src="/skins/icons/miniadjust01.gif"/>
|
<img src="/skins/icons/miniadjust01.gif"/>
|
||||||
<span>{% trans 'CHAMPS' %}</span>
|
<span>{% trans 'CHAMPS' %}</span>
|
||||||
</a>
|
</a>
|
||||||
|
@@ -2,10 +2,48 @@ define([
|
|||||||
'jquery',
|
'jquery',
|
||||||
'underscore',
|
'underscore',
|
||||||
'backbone',
|
'backbone',
|
||||||
'apps/admin/fields/router'
|
'i18n',
|
||||||
], function($, _, Backbone, Router) {
|
'apps/admin/fields/collections/fields',
|
||||||
|
'apps/admin/fields/collections/vocabularies',
|
||||||
|
'apps/admin/fields/collections/dcFields',
|
||||||
|
'apps/admin/fields/views/list'
|
||||||
|
], function($, _, Backbone, i18n, FieldsCollection, VocabulariesCollection, DcFieldsCollection, FieldListView) {
|
||||||
var initialize = function() {
|
var initialize = function() {
|
||||||
Router.initialize();
|
window.AdminFieldApp = {};
|
||||||
|
|
||||||
|
window.AdminFieldApp.sbas_id = $('input[name=current_sbas_id]').val();
|
||||||
|
|
||||||
|
var fieldsCollection = new FieldsCollection(null, {
|
||||||
|
sbas_id : window.AdminFieldApp.sbas_id
|
||||||
|
});
|
||||||
|
|
||||||
|
var vocabulariesCollection = new VocabulariesCollection();
|
||||||
|
var dcFieldsCollection = new DcFieldsCollection();
|
||||||
|
|
||||||
|
// load strings synchronously
|
||||||
|
i18n.init({ resGetPath: '/admin/fields/language.json', getAsync: false });
|
||||||
|
|
||||||
|
var requests = [
|
||||||
|
fieldsCollection.fetch(),
|
||||||
|
vocabulariesCollection.fetch(),
|
||||||
|
dcFieldsCollection.fetch()
|
||||||
|
];
|
||||||
|
|
||||||
|
$.when.apply($, requests).done(
|
||||||
|
function() {
|
||||||
|
window.AdminFieldApp.vocabularyCollection = vocabulariesCollection;
|
||||||
|
window.AdminFieldApp.dcFieldsCollection = dcFieldsCollection;
|
||||||
|
|
||||||
|
window.AdminFieldApp.fieldListView = new FieldListView({
|
||||||
|
collection: fieldsCollection,
|
||||||
|
el: $('.left-block')[0]
|
||||||
|
});
|
||||||
|
|
||||||
|
window.AdminFieldApp.fieldListView.render();
|
||||||
|
// click on first item list
|
||||||
|
_.first(window.AdminFieldApp.fieldListView.itemViews).clickAction().animate();
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
17
www/scripts/apps/admin/fields/collections/dcFields.js
Normal file
17
www/scripts/apps/admin/fields/collections/dcFields.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
define([
|
||||||
|
'underscore',
|
||||||
|
'backbone',
|
||||||
|
'models/dcField'
|
||||||
|
], function(_, Backbone, DcFieldModel) {
|
||||||
|
var DcFieldCollection = Backbone.Collection.extend({
|
||||||
|
model: DcFieldModel,
|
||||||
|
url: function() {
|
||||||
|
return '/admin/fields/dc-fields';
|
||||||
|
},
|
||||||
|
comparator: function(item) {
|
||||||
|
return item.get("label");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return DcFieldCollection;
|
||||||
|
});
|
@@ -1,11 +1,58 @@
|
|||||||
define([
|
define([
|
||||||
'underscore',
|
'underscore',
|
||||||
'backbone',
|
'backbone',
|
||||||
'models/admin/field'
|
'models/field'
|
||||||
], function(_, Backbone, FieldModel) {
|
], function(_, Backbone, FieldModel) {
|
||||||
var FieldCollection = Backbone.Collection.extend({
|
var FieldCollection = Backbone.Collection.extend({
|
||||||
|
initialize: function(models, options) {
|
||||||
|
if (!"sbas_id" in options) {
|
||||||
|
throw "You must specify a sbasId option when creating a new field model"
|
||||||
|
}
|
||||||
|
this.sbasId = options.sbas_id;
|
||||||
|
},
|
||||||
model: FieldModel,
|
model: FieldModel,
|
||||||
url: '/admin/fields/1/fields'
|
url: function() {
|
||||||
|
return '/admin/fields/' + this.sbasId + '/fields';
|
||||||
|
},
|
||||||
|
search: function(letters) {
|
||||||
|
if (letters === "")
|
||||||
|
return this;
|
||||||
|
|
||||||
|
var pattern = new RegExp(letters, "gi");
|
||||||
|
|
||||||
|
return _(this.filter(function(data) {
|
||||||
|
return pattern.test(data.get("name"));
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
comparator: function(item) {
|
||||||
|
return item.get("sorter");
|
||||||
|
},
|
||||||
|
nextIndex: function(model) {
|
||||||
|
var index = this.indexOf(model);
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
|
throw "Model not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((index + 1) === this.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index + 1;
|
||||||
|
},
|
||||||
|
previousIndex: function(model) {
|
||||||
|
var index = this.indexOf(model);
|
||||||
|
|
||||||
|
if (index < 0) {
|
||||||
|
throw "Model not found"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index - 1;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return FieldCollection;
|
return FieldCollection;
|
||||||
|
17
www/scripts/apps/admin/fields/collections/vocabularies.js
Normal file
17
www/scripts/apps/admin/fields/collections/vocabularies.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
define([
|
||||||
|
'underscore',
|
||||||
|
'backbone',
|
||||||
|
'models/vocabulary'
|
||||||
|
], function(_, Backbone, VocabularyModel) {
|
||||||
|
var VocabularyCollection = Backbone.Collection.extend({
|
||||||
|
model: VocabularyModel,
|
||||||
|
url: function() {
|
||||||
|
return '/admin/fields/vocabularies';
|
||||||
|
},
|
||||||
|
comparator: function(item) {
|
||||||
|
return item.get("name");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return VocabularyCollection;
|
||||||
|
});
|
@@ -1,15 +1,21 @@
|
|||||||
require.config({
|
require.config({
|
||||||
baseUrl: "/scripts",
|
baseUrl: "/scripts",
|
||||||
paths: {
|
paths: {
|
||||||
jquery: '../assets/jquery/jquery',
|
jquery: '../include/minify/f=include/jslibs/jquery-1.7.1',
|
||||||
|
jqueryui: '../include/jslibs/jquery-ui-1.8.17/js/jquery-ui-1.8.17.custom.min',
|
||||||
underscore: '../assets/underscore-amd/underscore',
|
underscore: '../assets/underscore-amd/underscore',
|
||||||
backbone: '../assets/backbone-amd/backbone',
|
backbone: '../assets/backbone-amd/backbone',
|
||||||
twig: '../assets/twig/twig',
|
twig: '../assets/twig/twig',
|
||||||
i18n: '../assets/i18n/i18next.amd'
|
i18n: '../assets/i18n/i18next.amd',
|
||||||
|
bootstrap: ['//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min']
|
||||||
},
|
},
|
||||||
shim: {
|
shim: {
|
||||||
twig: {
|
twig: {
|
||||||
exports: 'Twig'
|
exports: 'Twig'
|
||||||
|
},
|
||||||
|
bootstrap : ['jquery'],
|
||||||
|
jqueryui: {
|
||||||
|
deps: [ 'jquery' ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -1,59 +0,0 @@
|
|||||||
define([
|
|
||||||
'jquery',
|
|
||||||
'underscore',
|
|
||||||
'backbone',
|
|
||||||
'models/admin/field',
|
|
||||||
'apps/admin/fields/views/edit',
|
|
||||||
'apps/admin/fields/views/list',
|
|
||||||
'apps/admin/fields/collections/fields'
|
|
||||||
], function($, _, Backbone, FieldModel, FieldEditView, FieldListView, FieldsCollection) {
|
|
||||||
var AppRouter = Backbone.Router.extend({
|
|
||||||
routes: {
|
|
||||||
'field/:id': "getField",
|
|
||||||
'fields': 'showFields',
|
|
||||||
'*actions': 'defaultAction'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var initialize = function() {
|
|
||||||
var app_router = new AppRouter();
|
|
||||||
|
|
||||||
app_router.on('route:getField', function (id) {
|
|
||||||
var field = new FieldModel({id: id});
|
|
||||||
|
|
||||||
field.fetch().done(function() {
|
|
||||||
var fieldEditView = new FieldEditView({
|
|
||||||
el: $('.right-block')[0],
|
|
||||||
model: field
|
|
||||||
});
|
|
||||||
|
|
||||||
fieldEditView.render();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
app_router.on('route:showFields', function() {
|
|
||||||
var fieldsCollection = new FieldsCollection();
|
|
||||||
fieldsCollection.fetch().done(function() {
|
|
||||||
var fieldListView = new FieldListView({
|
|
||||||
collection: fieldsCollection,
|
|
||||||
el: $('ul#collection-fields')[0]
|
|
||||||
});
|
|
||||||
|
|
||||||
fieldListView.render();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
app_router.on('route:defaultAction', function(actions) {
|
|
||||||
console.log('No route:', actions);
|
|
||||||
});
|
|
||||||
|
|
||||||
Backbone.history.start();
|
|
||||||
|
|
||||||
// Show fields on start up
|
|
||||||
app_router.navigate('fields', { trigger: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
initialize: initialize
|
|
||||||
};
|
|
||||||
});
|
|
51
www/scripts/apps/admin/fields/views/add.js
Normal file
51
www/scripts/apps/admin/fields/views/add.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
define([
|
||||||
|
'underscore',
|
||||||
|
'backbone',
|
||||||
|
'i18n'
|
||||||
|
], function( _, Backbone, i18n, bootstrap) {
|
||||||
|
var AddView = Backbone.View.extend({
|
||||||
|
tagName: "div",
|
||||||
|
className: "add-field-block",
|
||||||
|
style: "display:none;",
|
||||||
|
events: {
|
||||||
|
"click .btn-submit-field": "createAction"
|
||||||
|
},
|
||||||
|
initialize: function() {},
|
||||||
|
render: function() {
|
||||||
|
var template = _.template($("#alert_template").html(), {
|
||||||
|
msg: this.msg
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$el.after(template);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
createAction: function(event) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var field = new FieldModel({
|
||||||
|
"name": "AA" + new Date().getUTCMilliseconds(),
|
||||||
|
"tag": "IPTC:ObjectName"
|
||||||
|
}, {
|
||||||
|
sbas_id: AdminFieldApp.sbas_id
|
||||||
|
});
|
||||||
|
|
||||||
|
field.save(null, {
|
||||||
|
success: function(field) {
|
||||||
|
self.collection.add(field);
|
||||||
|
_.last(self.itemViews).clickAction().animate();
|
||||||
|
new AlertView({alert: 'success', message: 'A new field has been created'}).render();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
new AlertView({alert: 'error', message: 'Something wrong happened'}).render();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
destroy: function() {
|
||||||
|
this.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return AddView;
|
||||||
|
});
|
||||||
|
|
36
www/scripts/apps/admin/fields/views/alert.js
Normal file
36
www/scripts/apps/admin/fields/views/alert.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
define([
|
||||||
|
'underscore',
|
||||||
|
'backbone',
|
||||||
|
'i18n',
|
||||||
|
'bootstrap'
|
||||||
|
], function(_, Backbone, i18n, bootstrap) {
|
||||||
|
var AlertView = Backbone.View.extend({
|
||||||
|
tagName: "div",
|
||||||
|
className: "alert",
|
||||||
|
initialize: function(options) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
this.alert = options.alert || "info";
|
||||||
|
this.message = options.message || "";
|
||||||
|
}
|
||||||
|
// remove view when alert is closed
|
||||||
|
this.$el.bind('closed', function () {
|
||||||
|
self.remove();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
var template = _.template($("#alert_template").html(), {
|
||||||
|
msg: this.message
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$el.addClass("alert-" + this.alert).html(template).alert();
|
||||||
|
|
||||||
|
$('.block-alert').empty().append(this.$el);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return AlertView;
|
||||||
|
});
|
29
www/scripts/apps/admin/fields/views/dcField.js
Normal file
29
www/scripts/apps/admin/fields/views/dcField.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
define([
|
||||||
|
'underscore',
|
||||||
|
'backbone',
|
||||||
|
'i18n'
|
||||||
|
], function( _, Backbone, i18n, bootstrap) {
|
||||||
|
var DcFieldsView = Backbone.View.extend({
|
||||||
|
tagName: "div",
|
||||||
|
className: "input-append",
|
||||||
|
events: {
|
||||||
|
"change select": "onChange"
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
var template = _.template($("#dc_fields_template").html(), {
|
||||||
|
dces_elements: this.collection.toJSON()
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$el.html(template);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
onChange: function(e) {
|
||||||
|
var index = $(e.target)[0].selectedIndex;
|
||||||
|
this.$el.closest('table').find('.dces-help-block').empty().append(this.collection.at(index).get('definition'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return DcFieldsView;
|
||||||
|
});
|
||||||
|
|
@@ -1,19 +1,133 @@
|
|||||||
define([
|
define([
|
||||||
'jquery',
|
|
||||||
'underscore',
|
'underscore',
|
||||||
'backbone',
|
'backbone',
|
||||||
'i18n'
|
'i18n',
|
||||||
], function($, _, Backbone, i18n) {
|
'apps/admin/fields/views/alert',
|
||||||
|
'apps/admin/fields/views/modal',
|
||||||
|
'apps/admin/fields/views/dcField',
|
||||||
|
], function(_, Backbone, i18n, AlertView, ModalView, DcFieldView) {
|
||||||
var FieldEditView = Backbone.View.extend({
|
var FieldEditView = Backbone.View.extend({
|
||||||
tagName: "div",
|
tagName: "div",
|
||||||
className: "field-edit",
|
className: "field-edit",
|
||||||
|
initialize: function() {
|
||||||
|
this.model.on('change', this.render, this);
|
||||||
|
this.model.on('change:name', this.onFieldChange, this);
|
||||||
|
this.model.on('change:tag', this.onFieldChange, this);
|
||||||
|
|
||||||
|
this.dcFieldsSubView = new DcFieldView({
|
||||||
|
collection: window.AdminFieldApp.dcFieldsCollection
|
||||||
|
});
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
this.el.innerHTML = '';
|
var template = _.template($("#edit_template").html(), {
|
||||||
this.el.innerHTML = Twig.render(fieldsEdit, {
|
field: this.model.toJSON(),
|
||||||
field: this.model.attributes
|
vocabularyTypes: window.AdminFieldApp.vocabularyCollection.toJSON()
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$el.empty().html(template);
|
||||||
|
|
||||||
|
this.assign({
|
||||||
|
'.dc-fields-subview' : this.dcFieldsSubView
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#tag", this.$el).autocomplete({
|
||||||
|
source: function(request, response) {
|
||||||
|
$.ajax({
|
||||||
|
url: "/admin/fields/tags/search",
|
||||||
|
dataType: "json",
|
||||||
|
data: {
|
||||||
|
term: request.term
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
response($.map(data, function(item) {
|
||||||
|
return {
|
||||||
|
label: item.label,
|
||||||
|
value: item.value
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).val(this.model.get('tag')).autocomplete("widget").addClass("ui-autocomplete-admin-field");
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
events: {
|
||||||
|
"click .delete-field": "deleteAction",
|
||||||
|
"focusout input[type=text]": "fieldChanged",
|
||||||
|
"change input[type=checkbox]": "fieldChanged",
|
||||||
|
"change select": "selectionChanged"
|
||||||
|
},
|
||||||
|
selectionChanged: function(e) {
|
||||||
|
var field = $(e.currentTarget);
|
||||||
|
var value = $("option:selected", field).val();
|
||||||
|
var data = {};
|
||||||
|
data[field.attr('id')] = value;
|
||||||
|
this.model.set(data);
|
||||||
|
},
|
||||||
|
fieldChanged: function(e) {
|
||||||
|
console.log('field change');
|
||||||
|
var field = $(e.currentTarget);
|
||||||
|
var data = {};
|
||||||
|
data[field.attr('id')] = field.is(":checkbox") ? field.is(":checked") : field.val();
|
||||||
|
this.model.set(data);
|
||||||
|
},
|
||||||
|
deleteAction: function() {
|
||||||
|
var self = this;
|
||||||
|
var modalView = new ModalView({
|
||||||
|
model: this.model,
|
||||||
|
message: i18n.t("are_you_sure_delete", { postProcess: "sprintf", sprintf: [this.model.get('name')] })
|
||||||
|
});
|
||||||
|
var previousIndex = AdminFieldApp.fieldListView.collection.previousIndex(this.model);
|
||||||
|
var nextIndex = AdminFieldApp.fieldListView.collection.nextIndex(this.model);
|
||||||
|
var itemView;
|
||||||
|
|
||||||
|
if (previousIndex) {
|
||||||
|
itemView = AdminFieldApp.fieldListView.itemViews[previousIndex];
|
||||||
|
} else if (nextIndex) {
|
||||||
|
itemView = AdminFieldApp.fieldListView.itemViews[nextIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
modalView.render();
|
||||||
|
modalView.on('modal:confirm', function() {
|
||||||
|
self.model.destroy({
|
||||||
|
success: function(model, response) {
|
||||||
|
AdminFieldApp.fieldListView.collection.remove(self.model);
|
||||||
|
|
||||||
|
if (itemView) {
|
||||||
|
itemView.clickAction().animate();
|
||||||
|
}
|
||||||
|
|
||||||
|
new AlertView({alert: 'info', message: i18n.t("deleted_success", { postProcess: "sprintf", sprintf: [model.get('name')] })}).render();
|
||||||
|
},
|
||||||
|
error: function(model, xhr) {
|
||||||
|
new AlertView({alert: 'error', message: i18n.t("something_wrong")}).render();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
},
|
||||||
|
onFieldChange: function() {
|
||||||
|
console.log('on field changed');
|
||||||
|
AdminFieldApp.fieldListView.collection.remove(this.model, {silent: true});
|
||||||
|
AdminFieldApp.fieldListView.collection.add(this.model);
|
||||||
|
this.render();
|
||||||
|
},
|
||||||
|
assign: function(selector, view) {
|
||||||
|
var selectors;
|
||||||
|
if (_.isObject(selector)) {
|
||||||
|
selectors = selector;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selectors = {};
|
||||||
|
selectors[selector] = view;
|
||||||
|
}
|
||||||
|
if (!selectors)
|
||||||
|
return;
|
||||||
|
_.each(selectors, function(view, selector) {
|
||||||
|
view.setElement(this.$(selector)).render();
|
||||||
|
}, this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,30 +1,145 @@
|
|||||||
define([
|
define([
|
||||||
'jquery',
|
'jqueryui',
|
||||||
'underscore',
|
'underscore',
|
||||||
'backbone',
|
'backbone',
|
||||||
'apps/admin/fields/views/listRow'
|
'i18n',
|
||||||
], function($, _, Backbone, FieldListRowView) {
|
'apps/admin/fields/views/listRow',
|
||||||
|
'apps/admin/fields/views/alert',
|
||||||
|
'models/field'
|
||||||
|
], function(jqueryui, _, Backbone, i18n, FieldListRowView, AlertView, FieldModel) {
|
||||||
var FieldListView = Backbone.View.extend({
|
var FieldListView = Backbone.View.extend({
|
||||||
|
events: {
|
||||||
|
"keyup #live_search": "searchAction",
|
||||||
|
"click .btn-submit-field": "createAction",
|
||||||
|
"click .btn-add-field": "toggleCreateFormAction",
|
||||||
|
"click .btn-cancel-field": "toggleCreateFormAction",
|
||||||
|
"update-sort": "onUpdateSort"
|
||||||
|
},
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
var that = this;
|
// Store all single rendered views
|
||||||
this._fieldViews = [];
|
this.itemViews = [];
|
||||||
|
|
||||||
this.collection.each(function(field) {
|
_.bindAll(this, "render");
|
||||||
that._fieldViews.push(new FieldListRowView({
|
// rerender whenever there is a change on the collection
|
||||||
model: field
|
this.collection.bind("reset", this.render, this);
|
||||||
}));
|
this.collection.bind("add", this.render, this);
|
||||||
});
|
this.collection.bind("remove", this.render, this);
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var that = this;
|
var template = _.template($("#item_list_view_template").html(), {});
|
||||||
$(this.el).empty();
|
|
||||||
|
|
||||||
// Render each sub-view and append it to the parent view's element.
|
this.$el.empty().html(template);
|
||||||
_(this._fieldViews).each(function(singleView) {
|
|
||||||
$(that.el).append(singleView.render().el);
|
this.$listEl = $("ul#collection-fields", this.$el);
|
||||||
});
|
|
||||||
|
this._renderList(this.collection);
|
||||||
|
|
||||||
|
$("#new-source", this.$el).autocomplete({
|
||||||
|
source: function(request, response) {
|
||||||
|
$.ajax({
|
||||||
|
url: "/admin/fields/tags/search",
|
||||||
|
dataType: "json",
|
||||||
|
data: {
|
||||||
|
term: request.term
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
response($.map(data, function(item) {
|
||||||
|
return {
|
||||||
|
label: item.label,
|
||||||
|
value: item.value
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).autocomplete("widget").addClass("ui-autocomplete-admin-field");
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
},
|
||||||
|
_renderList: function(fields) {
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
this.$listEl.empty();
|
||||||
|
this.itemViews = [];
|
||||||
|
|
||||||
|
fields.each(function(field) {
|
||||||
|
var singleView = new FieldListRowView({
|
||||||
|
model: field,
|
||||||
|
id: 'field-' + field.get('id')
|
||||||
|
});
|
||||||
|
that.$listEl.append(singleView.render().el);
|
||||||
|
that.itemViews.push(singleView);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$listEl.sortable({
|
||||||
|
handle: ".handle",
|
||||||
|
start: function () {
|
||||||
|
console.log('start', AdminFieldApp.fieldEditView.model.get('id'));
|
||||||
|
},
|
||||||
|
stop: function(event, ui) {
|
||||||
|
ui.item.trigger('drop', ui.item.index());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$listEl.disableSelection();
|
||||||
|
|
||||||
|
this.$listEl.find('li:last').addClass('last');
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
searchAction: function(event) {
|
||||||
|
this._renderList(this.collection.search($("#live_search", this.$el).val()));
|
||||||
|
},
|
||||||
|
createAction: function(event) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var fieldName = $("#new-name", this.$el);
|
||||||
|
|
||||||
|
if ('' == fieldName.val()) {
|
||||||
|
fieldName.closest('.control-group').addClass('error').find('.help-block').empty().append(i18n.t('validation_blank'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var field = new FieldModel({
|
||||||
|
"sbas-id": AdminFieldApp.sbas_id,
|
||||||
|
"name": fieldName.val(),
|
||||||
|
"tag": $("#new-source", this.$el).val(),
|
||||||
|
"multi": $("#new-multivalued", this.$el).is(':checked')
|
||||||
|
});
|
||||||
|
|
||||||
|
field.save(null, {
|
||||||
|
success: function(field, response, options) {
|
||||||
|
if (response.success) {
|
||||||
|
self.collection.add(field);
|
||||||
|
_.last(self.itemViews).clickAction().animate();
|
||||||
|
new AlertView({alert: 'success', message: response.message }).render();
|
||||||
|
} else {
|
||||||
|
new AlertView({alert: 'warning', message: response.message}).render();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(model, xhr, options) {
|
||||||
|
new AlertView({alert: 'error', message: i18n.t("something_wrong")}).render();
|
||||||
|
self.toggleCreateFormAction();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
toggleCreateFormAction: function(event) {
|
||||||
|
$('.add-field-block', this.$el).toggle();
|
||||||
|
},
|
||||||
|
onUpdateSort: function(event, model, position) {
|
||||||
|
this.collection.remove(model, {silent: true});
|
||||||
|
|
||||||
|
this.collection.each(function(model, index) {
|
||||||
|
var ordinal = index;
|
||||||
|
if (index >= position) ordinal += 1;
|
||||||
|
model.set('sorter', ordinal);
|
||||||
|
});
|
||||||
|
|
||||||
|
model.set('sorter', position);
|
||||||
|
this.collection.add(model, {at: position});
|
||||||
|
|
||||||
|
// update edit view
|
||||||
|
AdminFieldApp.fieldEditView.model = this.collection.find(function(el) { return el.get('id') === AdminFieldApp.fieldEditView.model.get('id') });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,19 +1,67 @@
|
|||||||
define([
|
define([
|
||||||
'jquery',
|
|
||||||
'underscore',
|
'underscore',
|
||||||
'backbone'
|
'backbone',
|
||||||
], function($, _, Backbone) {
|
'apps/admin/fields/views/edit',
|
||||||
|
'apps/admin/fields/views/alert'
|
||||||
|
], function(_, Backbone, FieldEditView, AlertView) {
|
||||||
var FieldListRowView = Backbone.View.extend({
|
var FieldListRowView = Backbone.View.extend({
|
||||||
tagName: "li",
|
tagName: "li",
|
||||||
className: "field-row",
|
className: "field-row",
|
||||||
|
initialize: function() {
|
||||||
|
// destroy view is model is deleted
|
||||||
|
this.model.on('destroy', this.remove, this);
|
||||||
|
},
|
||||||
|
events : {
|
||||||
|
"click .trigger-click": "clickAction",
|
||||||
|
"drop" : "dropAction"
|
||||||
|
},
|
||||||
|
clickAction: function (e) {
|
||||||
|
this.select();
|
||||||
|
// first click create view else update model's view
|
||||||
|
if (typeof AdminFieldApp.fieldEditView === 'undefined') {
|
||||||
|
AdminFieldApp.fieldEditView = new FieldEditView({
|
||||||
|
el: $('.right-block')[0],
|
||||||
|
model: this.model
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
AdminFieldApp.fieldEditView.model = this.model;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdminFieldApp.fieldEditView.render();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
dropAction: function(event, index) {
|
||||||
|
this.$el.trigger('update-sort', [this.model, index]);
|
||||||
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
this.el.innerHTML = Twig.render(fieldsRow, {
|
var template = _.template($("#list_row_template").html(), {
|
||||||
id: this.model.get('id'),
|
id: this.model.get('id'),
|
||||||
|
position: this.model.get('sorter'),
|
||||||
name: this.model.get('name'),
|
name: this.model.get('name'),
|
||||||
tag: this.model.get('tag')
|
tag: this.model.get('tag')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.$el.empty().html(template);
|
||||||
|
|
||||||
|
if (AdminFieldApp.fieldEditView && AdminFieldApp.fieldEditView.model.get('id') === this.model.get('id')) {
|
||||||
|
this.select();
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
|
},
|
||||||
|
// set selected class
|
||||||
|
select: function () {
|
||||||
|
$("li", this.$el.closest('ul')).removeClass('selected');
|
||||||
|
this.$el.addClass('selected');
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
animate: function () {
|
||||||
|
var offset = this.$el.offset();
|
||||||
|
|
||||||
|
this.$el.closest('div').animate({
|
||||||
|
scrollTop: offset.top - 20
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
44
www/scripts/apps/admin/fields/views/modal.js
Normal file
44
www/scripts/apps/admin/fields/views/modal.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
define([
|
||||||
|
'underscore',
|
||||||
|
'backbone',
|
||||||
|
'i18n',
|
||||||
|
'bootstrap'
|
||||||
|
], function(_, Backbone, i18n, bootstrap) {
|
||||||
|
var ModalView = Backbone.View.extend({
|
||||||
|
tagName: "div",
|
||||||
|
className: "modal",
|
||||||
|
events: {
|
||||||
|
'click .confirm': 'confirmAction'
|
||||||
|
},
|
||||||
|
initialize: function (options) {
|
||||||
|
var self = this;
|
||||||
|
// remove view when modal is closed
|
||||||
|
this.$el.on('hidden', function() {
|
||||||
|
self.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
this.message = options.message;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
var template = _.template($("#modal_delete_confirm_template").html(), {
|
||||||
|
msg: this.message || ''
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$el.html(template).modal();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
confirmAction: function () {
|
||||||
|
this.trigger('modal:confirm');
|
||||||
|
this.$el.modal('hide');
|
||||||
|
this.remove();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return ModalView;
|
||||||
|
});
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
define([
|
|
||||||
'underscore',
|
|
||||||
'backbone'
|
|
||||||
], function(_, Backbone) {
|
|
||||||
var FieldModel = Backbone.Model.extend({
|
|
||||||
urlRoot: '/admin/fields/1/fields'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Return the model for the module
|
|
||||||
return FieldModel;
|
|
||||||
});
|
|
13
www/scripts/models/dcField.js
Normal file
13
www/scripts/models/dcField.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
define([
|
||||||
|
'underscore',
|
||||||
|
'backbone'
|
||||||
|
], function(_, Backbone) {
|
||||||
|
var DcFieldModel = Backbone.Model.extend({
|
||||||
|
urlRoot: function () {
|
||||||
|
return '/admin/fields/dc-fields';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return the model for the module
|
||||||
|
return DcFieldModel;
|
||||||
|
});
|
33
www/scripts/models/field.js
Normal file
33
www/scripts/models/field.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
define([
|
||||||
|
'underscore',
|
||||||
|
'backbone'
|
||||||
|
], function(_, Backbone) {
|
||||||
|
var FieldModel = Backbone.Model.extend({
|
||||||
|
initialize : function(attributes, options) {
|
||||||
|
if (attributes && ! "sbas-id" in attributes) {
|
||||||
|
throw "You must set a sbas id";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
urlRoot: function () {
|
||||||
|
return '/admin/fields/'+ this.get('sbas-id') +'/fields';
|
||||||
|
},
|
||||||
|
defaults: {
|
||||||
|
"business": false,
|
||||||
|
"type": "string",
|
||||||
|
"thumbtitle": "0",
|
||||||
|
"tbranch": "",
|
||||||
|
"separator": "",
|
||||||
|
"required": false,
|
||||||
|
"report": true,
|
||||||
|
"readonly": false,
|
||||||
|
"multi": false,
|
||||||
|
"indexable": true,
|
||||||
|
"dces-element": null,
|
||||||
|
"vocabulary-type": null,
|
||||||
|
"vocabulary-restricted": false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return the model for the module
|
||||||
|
return FieldModel;
|
||||||
|
});
|
13
www/scripts/models/vocabulary.js
Normal file
13
www/scripts/models/vocabulary.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
define([
|
||||||
|
'underscore',
|
||||||
|
'backbone'
|
||||||
|
], function(_, Backbone) {
|
||||||
|
var VocabularyModel = Backbone.Model.extend({
|
||||||
|
urlRoot: function () {
|
||||||
|
return '/admin/fields/vocabularies';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return the model for the module
|
||||||
|
return VocabularyModel;
|
||||||
|
});
|
73
www/skins/admin/css/fields.css
Normal file
73
www/skins/admin/css/fields.css
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#admin-field-app li {
|
||||||
|
background: #FFF;
|
||||||
|
border-top: 1px solid #ccc;
|
||||||
|
border-left: 1px solid #ccc;
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin-field-app li .field-name {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin-field-app li .handle, #admin-field-app li .position {
|
||||||
|
color: #ccc;
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin-field-app li.last {
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin-field-app li.selected {
|
||||||
|
border-top-color: #0080FF;
|
||||||
|
background: #FFF;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin-field-app li.selected + li {
|
||||||
|
border-top-color: #0080FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin-field-app li.selected .field-name {
|
||||||
|
color: #0080FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin-field-app .add-field-block .control-label {
|
||||||
|
width: 80px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin-field-app .add-field-block .controls {
|
||||||
|
margin-left: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin-field-app .edit-form label {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#admin-field-app .edit-form select {
|
||||||
|
min-width: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-autocomplete-admin-field {
|
||||||
|
list-style-type: none;
|
||||||
|
overflow-y: scroll;
|
||||||
|
height: 180px;
|
||||||
|
background: #FFF;
|
||||||
|
max-width: 300px;
|
||||||
|
-webkit-box-shadow: 0 10px 6px -6px #777;
|
||||||
|
-moz-box-shadow: 0 10px 6px -6px #777;
|
||||||
|
box-shadow: 0 10px 6px -6px #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-autocomplete-admin-field li{
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-autocomplete-admin-field li a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user