backoffice: link to related card (#73690) #87
|
@ -1330,10 +1330,16 @@ def test_carddata_add_edit_related(pub):
|
|||
assert '/backoffice/data/child/add/?_popup=1' in resp
|
||||
assert resp.pyquery('select#form_f1').attr('data-initial-edit-related-url') == ''
|
||||
assert resp.pyquery('#edit_form_f1.edit-related')
|
||||
assert resp.pyquery('select#form_f1').attr('data-initial-view-related-url') == ''
|
||||
assert resp.pyquery('#view_form_f1.view-related')
|
||||
assert resp.pyquery('select#form_f2').attr('data-initial-edit-related-url') == ''
|
||||
assert resp.pyquery('#edit_form_f2.edit-related')
|
||||
assert resp.pyquery('select#form_f2').attr('data-initial-view-related-url') == ''
|
||||
assert resp.pyquery('#view_form_f2.view-related')
|
||||
assert resp.pyquery('select#form_f3__element0__f1').attr('data-initial-edit-related-url') == ''
|
||||
assert resp.pyquery('#edit_form_f3__element0__f1.edit-related')
|
||||
assert resp.pyquery('select#form_f3__element0__f1').attr('data-initial-view-related-url') == ''
|
||||
assert resp.pyquery('#view_form_f3__element0__f1.view-related')
|
||||
resp_popup = app.get('/backoffice/data/adult/add/?_popup=1')
|
||||
assert 'select2.min.js' in resp_popup.text
|
||||
|
||||
|
@ -1348,10 +1354,16 @@ def test_carddata_add_edit_related(pub):
|
|||
assert '/backoffice/data/child/add/?_popup=1' in resp
|
||||
assert resp.pyquery('select#form_f1').attr('data-initial-edit-related-url') is None
|
||||
assert not resp.pyquery('#edit_form_f1.edit-related')
|
||||
assert resp.pyquery('select#form_f1').attr('data-initial-view-related-url') is None
|
||||
assert not resp.pyquery('#view_form_f1.view-related')
|
||||
assert resp.pyquery('select#form_f2').attr('data-initial-edit-related-url') == ''
|
||||
assert resp.pyquery('#edit_form_f2.edit-related')
|
||||
assert resp.pyquery('select#form_f2').attr('data-initial-view-related-url') == ''
|
||||
assert resp.pyquery('#view_form_f2.view-related')
|
||||
assert resp.pyquery('select#form_f3__element0__f1').attr('data-initial-edit-related-url') == ''
|
||||
assert resp.pyquery('#edit_form_f3__element0__f1.edit-related')
|
||||
assert resp.pyquery('select#form_f3__element0__f1').attr('data-initial-view-related-url') == ''
|
||||
assert resp.pyquery('#view_form_f3__element0__f1.view-related')
|
||||
|
||||
# check creation and edition in popup
|
||||
resp = app.get('/backoffice/data/child/add/?_popup=1')
|
||||
|
@ -1411,16 +1423,28 @@ def test_carddata_add_edit_related(pub):
|
|||
assert '/backoffice/data/child/add/?_popup=1' in resp
|
||||
assert resp.pyquery('select#form_f1').attr('data-initial-edit-related-url') is None
|
||||
assert not resp.pyquery('#edit_form_f1.edit-related')
|
||||
assert resp.pyquery('select#form_f1').attr('data-initial-view-related-url') is None
|
||||
assert not resp.pyquery('#view_form_f1.view-related')
|
||||
assert (
|
||||
resp.pyquery('select#form_f2').attr('data-initial-edit-related-url')
|
||||
== 'http://example.net/backoffice/data/adult/%s/wfedit-_editable' % adultdata2.id
|
||||
)
|
||||
assert resp.pyquery('#edit_form_f2.edit-related')
|
||||
assert (
|
||||
resp.pyquery('select#form_f2').attr('data-initial-view-related-url')
|
||||
== 'http://example.net/backoffice/data/adult/%s/' % adultdata2.id
|
||||
)
|
||||
assert resp.pyquery('#view_form_f2.view-related')
|
||||
assert (
|
||||
resp.pyquery('select#form_f3__element0__f1').attr('data-initial-edit-related-url')
|
||||
== 'http://example.net/backoffice/data/child/%s/wfedit-_editable' % childdata.id
|
||||
)
|
||||
assert resp.pyquery('#edit_form_f3__element0__f1.edit-related')
|
||||
assert (
|
||||
resp.pyquery('select#form_f3__element0__f1').attr('data-initial-view-related-url')
|
||||
== 'http://example.net/backoffice/data/child/%s/' % childdata.id
|
||||
)
|
||||
assert resp.pyquery('#view_form_f3__element0__f1.view-related')
|
||||
|
||||
# check autocomplete result
|
||||
# no query, no edit url
|
||||
|
@ -1443,11 +1467,13 @@ def test_carddata_add_edit_related(pub):
|
|||
'id': 1,
|
||||
'text': 'foo bar 1',
|
||||
'edit_related_url': 'http://example.net/backoffice/data/adult/1/wfedit-_editable',
|
||||
'view_related_url': 'http://example.net/backoffice/data/adult/1/',
|
||||
},
|
||||
{
|
||||
'id': 2,
|
||||
'text': 'foo bar 2',
|
||||
'edit_related_url': 'http://example.net/backoffice/data/adult/2/wfedit-_editable',
|
||||
'view_related_url': 'http://example.net/backoffice/data/adult/2/',
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -1459,19 +1485,21 @@ def test_carddata_add_edit_related(pub):
|
|||
assert 'Add another Child' not in resp
|
||||
assert '/backoffice/data/child/add/?_popup=1' not in resp
|
||||
|
||||
# user has no edit rights on adult
|
||||
# user has no edit and no view rights on adult
|
||||
adult.workflow_roles = {}
|
||||
adult.store()
|
||||
resp = app.get('/backoffice/data/family/%s/wfedit-_editable' % familydata.id)
|
||||
assert resp.pyquery('select#form_f2').attr('data-initial-edit-related-url') == ''
|
||||
assert resp.pyquery('#edit_form_f2.edit-related')
|
||||
assert resp.pyquery('select#form_f2').attr('data-initial-view-related-url') == ''
|
||||
assert resp.pyquery('#view_form_f2.view-related')
|
||||
autocomplete_resp = app.get(
|
||||
resp.pyquery('select#form_f2').attr('data-select2-url') + '?q=foo&page_limit=10'
|
||||
)
|
||||
assert autocomplete_resp.json == {
|
||||
'data': [
|
||||
{'id': 1, 'text': 'foo bar 1', 'edit_related_url': ''},
|
||||
{'id': 2, 'text': 'foo bar 2', 'edit_related_url': ''},
|
||||
{'id': 1, 'text': 'foo bar 1', 'edit_related_url': '', 'view_related_url': ''},
|
||||
{'id': 2, 'text': 'foo bar 2', 'edit_related_url': '', 'view_related_url': ''},
|
||||
]
|
||||
}
|
||||
|
||||
|
|
10
wcs/api.py
10
wcs/api.py
|
@ -1211,18 +1211,18 @@ class AutocompleteDirectory(Directory):
|
|||
custom_view.filters = info['dynamic_custom_view_filters']
|
||||
query = get_request().form.get('q', '')
|
||||
limit = get_request().form.get('page_limit')
|
||||
edit_related = info.get('edit_related')
|
||||
with_edit_related_url = query and limit and edit_related
|
||||
with_related = info.get('with_related')
|
||||
with_related_urls = query and limit and with_related
|
||||
values = CardDef.get_data_source_items(
|
||||
carddef_ref,
|
||||
custom_view=custom_view,
|
||||
query=query,
|
||||
limit=limit,
|
||||
with_edit_related_url=with_edit_related_url,
|
||||
with_related_urls=with_related_urls,
|
||||
)
|
||||
keys = ['id', 'text']
|
||||
if with_edit_related_url:
|
||||
keys.append('edit_related_url')
|
||||
if with_related_urls:
|
||||
keys += ['edit_related_url', 'view_related_url']
|
||||
return json.dumps({'data': [{key: x.get(key, '') for key in keys} for x in values]})
|
||||
|
||||
|
||||
|
|
|
@ -371,6 +371,7 @@ class CardFillPage(FormFillPage):
|
|||
'value': str(filled.id),
|
||||
'obj': str(filled.default_digest),
|
||||
'edit_related_url': filled.get_edit_related_url() or '',
|
||||
'view_related_url': filled.get_view_related_url() or '',
|
||||
}
|
||||
)
|
||||
return template.QommonTemplateResponse(
|
||||
|
|
|
@ -36,7 +36,7 @@ class CardData(FormData):
|
|||
|
||||
formdef = property(get_formdef)
|
||||
|
||||
def get_data_source_structured_item(self, digest_key='default', with_edit_related_url=False):
|
||||
def get_data_source_structured_item(self, digest_key='default', with_related_urls=False):
|
||||
if self.digests is None:
|
||||
if digest_key == 'default':
|
||||
summary = _('Digest (default) not defined')
|
||||
|
@ -48,10 +48,13 @@ class CardData(FormData):
|
|||
'id': self.id,
|
||||
'text': (self.digests or {}).get(digest_key) or '',
|
||||
}
|
||||
if with_edit_related_url:
|
||||
if with_related_urls:
|
||||
edit_related_url = self.get_edit_related_url()
|
||||
if edit_related_url:
|
||||
item['edit_related_url'] = edit_related_url
|
||||
view_related_url = self.get_view_related_url()
|
||||
if view_related_url:
|
||||
item['view_related_url'] = view_related_url
|
||||
for field in self.formdef.get_all_fields():
|
||||
if not field.varname or field.varname in ('id', 'text'):
|
||||
continue
|
||||
|
@ -76,6 +79,11 @@ class CardData(FormData):
|
|||
+ 'wfedit-%s' % _item.id
|
||||
)
|
||||
|
||||
def get_view_related_url(self):
|
||||
if not self.formdef.is_user_allowed_read(get_request().user, self):
|
||||
return
|
||||
return self.get_url(backoffice=True)
|
||||
|
||||
def get_display_label(self, digest_key='default'):
|
||||
return (self.digests or {}).get(digest_key) or self.get_display_name()
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ class CardDef(FormDef):
|
|||
custom_view=None,
|
||||
get_by_id=None,
|
||||
get_by_text=None,
|
||||
with_edit_related_url=False,
|
||||
with_related_urls=False,
|
||||
):
|
||||
assert data_source_id.startswith('carddef:')
|
||||
parts = data_source_id.split(':')
|
||||
|
@ -251,9 +251,7 @@ class CardDef(FormDef):
|
|||
criterias.append(ElementEqual('digests', digest_key, get_by_text))
|
||||
|
||||
items = [
|
||||
x.get_data_source_structured_item(
|
||||
digest_key=digest_key, with_edit_related_url=with_edit_related_url
|
||||
)
|
||||
x.get_data_source_structured_item(digest_key=digest_key, with_related_urls=with_related_urls)
|
||||
for x in carddef.data_class().select(clause=criterias, order_by=order_by, limit=limit)
|
||||
]
|
||||
if order_by is None:
|
||||
|
|
|
@ -2249,7 +2249,7 @@ class ItemFieldMixin:
|
|||
carddef = self.get_carddef()
|
||||
url_kwargs = {}
|
||||
if self.key == 'item' and get_request().is_in_backoffice() and carddef:
|
||||
url_kwargs['edit_related'] = True
|
||||
url_kwargs['with_related'] = True
|
||||
# store display value in session to be used by select2
|
||||
url = data_source.get_jsonp_url(**url_kwargs)
|
||||
if not session.jsonp_display_values:
|
||||
|
@ -2355,8 +2355,8 @@ class ItemField(WidgetField, MapOptionsMixin, ItemFieldMixin):
|
|||
if get_request().is_in_backoffice() and carddef:
|
||||
if carddef.can_user_add_cards(get_request().user):
|
||||
kwargs['add_related_url'] = carddef.get_backoffice_submission_url()
|
||||
kwargs['edit_related'] = True
|
||||
url_kwargs['edit_related'] = True
|
||||
kwargs['with_related'] = True
|
||||
url_kwargs['with_related'] = True
|
||||
self.url = kwargs['url'] = data_source.get_jsonp_url(**url_kwargs)
|
||||
self.widget_class = JsonpSingleSelectWidget
|
||||
return
|
||||
|
|
|
@ -1844,6 +1844,7 @@ class FormPage(FormdefDirectoryBase, FormTemplateMixin):
|
|||
'value': str(self.edited_data.id),
|
||||
'obj': str(self.edited_data.default_digest),
|
||||
'edit_related_url': self.edited_data.get_edit_related_url() or '',
|
||||
'view_related_url': self.edited_data.get_view_related_url() or '',
|
||||
}
|
||||
)
|
||||
return template.QommonTemplateResponse(
|
||||
|
|
|
@ -2967,11 +2967,11 @@ class RankedItemsWidget(CompositeWidget):
|
|||
class JsonpSingleSelectWidget(Widget):
|
||||
template_name = 'qommon/forms/widgets/select_jsonp.html'
|
||||
|
||||
def __init__(self, name, value=None, url=None, add_related_url=None, edit_related=False, **kwargs):
|
||||
def __init__(self, name, value=None, url=None, add_related_url=None, with_related=False, **kwargs):
|
||||
super().__init__(name, value=value, **kwargs)
|
||||
self.url = url
|
||||
self.add_related_url = add_related_url
|
||||
self.edit_related = edit_related
|
||||
self.with_related = with_related
|
||||
|
||||
def add_media(self):
|
||||
get_response().add_javascript(['select2.js'])
|
||||
|
@ -2995,9 +2995,7 @@ class JsonpSingleSelectWidget(Widget):
|
|||
|
||||
return get_session().jsonp_display_values.get(key)
|
||||
|
||||
def get_edit_related_url(self):
|
||||
if not self.edit_related:
|
||||
return
|
||||
def _get_carddata(self):
|
||||
if self.value is None:
|
||||
value = None
|
||||
else:
|
||||
|
@ -3011,11 +3009,26 @@ class JsonpSingleSelectWidget(Widget):
|
|||
if not carddef:
|
||||
return
|
||||
try:
|
||||
carddata = carddef.data_class().get(value)
|
||||
return carddef.data_class().get(value)
|
||||
except KeyError:
|
||||
return
|
||||
|
||||
def get_edit_related_url(self):
|
||||
if not self.with_related:
|
||||
return
|
||||
carddata = self._get_carddata()
|
||||
if not carddata:
|
||||
return
|
||||
return carddata.get_edit_related_url()
|
||||
|
||||
def get_view_related_url(self):
|
||||
if not self.with_related:
|
||||
return
|
||||
carddata = self._get_carddata()
|
||||
if not carddata:
|
||||
return
|
||||
return carddata.get_view_related_url()
|
||||
|
||||
def get_select2_url(self):
|
||||
if Template.is_template_string(self.url):
|
||||
vars = get_publisher().substitutions.get_context_variables(mode='lazy')
|
||||
|
|
|
@ -2359,7 +2359,7 @@ div.timetable-widget {
|
|||
|
||||
.wcs-widget-select2-container {
|
||||
display: flex;
|
||||
.add-related, .edit-related {
|
||||
.add-related, .edit-related, .view-related {
|
||||
margin-top: 2px; // == margin-top of span.select2-container
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
@ -2374,6 +2374,10 @@ div.timetable-widget {
|
|||
background-image: url(/static/css/icons/action-edit.hover.png);
|
||||
}
|
||||
}
|
||||
.view-related {
|
||||
line-height: 2em;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.wcs-block-with-remove-button {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(function() {
|
||||
var initData = JSON.parse(document.getElementById('popup-response-constants').dataset.popupResponse);
|
||||
opener.dismissRelatedObjectPopup(window, initData.value, initData.obj, initData.edit_related_url);
|
||||
opener.dismissRelatedObjectPopup(window, initData.value, initData.obj, initData.edit_related_url, initData.view_related_url);
|
||||
})();
|
||||
|
|
|
@ -399,7 +399,7 @@ $(function() {
|
|||
return showPopup(triggeringLink, /^(edit|add)_/);
|
||||
}
|
||||
|
||||
function dismissRelatedObjectPopup(win, newId, newRepr, edit_related_url) {
|
||||
function dismissRelatedObjectPopup(win, newId, newRepr, edit_related_url, view_related_url) {
|
||||
var name = windowname_to_id(win.name);
|
||||
var elem = document.getElementById(name);
|
||||
if (elem) {
|
||||
|
@ -409,6 +409,9 @@ $(function() {
|
|||
if (edit_related_url) {
|
||||
$option.attr('data-edit-related-url', edit_related_url);
|
||||
}
|
||||
if (view_related_url) {
|
||||
$option.attr('data-view-related-url', view_related_url);
|
||||
}
|
||||
$(elem).append($option);
|
||||
}
|
||||
// Trigger a change event to update related links if required.
|
||||
|
|
|
@ -348,6 +348,9 @@ $(function() {
|
|||
if (data.edit_related_url) {
|
||||
$(data.element).attr('data-edit-related-url', data.edit_related_url);
|
||||
}
|
||||
if (data.view_related_url) {
|
||||
$(data.element).attr('data-view-related-url', data.view_related_url);
|
||||
}
|
||||
return data.text;
|
||||
}
|
||||
};
|
||||
|
@ -389,11 +392,15 @@ $(function() {
|
|||
var $selected = $(elem).find(':selected').first();
|
||||
var text = $selected.text();
|
||||
$input_display_value.val(text);
|
||||
// update edit-related button href
|
||||
// update edit-related button and view-related link href
|
||||
$(elem).siblings('.edit-related').attr('href', '').hide();
|
||||
$(elem).siblings('.view-related').attr('href', '').hide();
|
||||
if ($selected.attr('data-edit-related-url')) {
|
||||
$(elem).siblings('.edit-related').attr('href', $selected.attr('data-edit-related-url') + '?_popup=1').show();
|
||||
}
|
||||
if ($selected.attr('data-view-related-url')) {
|
||||
$(elem).siblings('.view-related').attr('href', $selected.attr('data-view-related-url')).show();
|
||||
}
|
||||
});
|
||||
if ($input_display_value.val()) {
|
||||
// if the _display hidden field was created with an initial value take it
|
||||
|
@ -405,6 +412,9 @@ $(function() {
|
|||
if ($(elem).data('initial-edit-related-url')) {
|
||||
option.attr('data-edit-related-url', $(elem).data('initial-edit-related-url'));
|
||||
}
|
||||
if ($(elem).data('initial-view-related-url')) {
|
||||
option.attr('data-view-related-url', $(elem).data('initial-view-related-url'));
|
||||
}
|
||||
select2.val($(elem).data('value')).trigger('change');
|
||||
$(elem).select2('data', {id: $(elem).data('value'), text: $(elem).data('initial-display-value')});
|
||||
}
|
||||
|
|
|
@ -7,18 +7,21 @@
|
|||
{% if widget.value %}data-value="{{ widget.value }}"{% endif %}
|
||||
data-required="{% if widget.is_required %}true{% endif %}"
|
||||
data-initial-display-value="{{widget.get_display_value|default_if_none:''}}"
|
||||
{% if widget.edit_related %}data-initial-edit-related-url="{{widget.get_edit_related_url|default_if_none:''}}"{% endif %}>
|
||||
{% if widget.with_related %}data-initial-edit-related-url="{{widget.get_edit_related_url|default_if_none:''}}"{% endif %}
|
||||
{% if widget.with_related %}data-initial-view-related-url="{{widget.get_view_related_url|default_if_none:''}}"{% endif %}>
|
||||
</select>
|
||||
{% if widget.add_related_url %}
|
||||
<a class="add-related pk-button" id="add_form_{{ widget.get_name_for_id }}"
|
||||
href="{{ widget.add_related_url }}?_popup=1"
|
||||
title="{% blocktrans with card=widget.get_title %}Add another {{ card }}{% endblocktrans %}">+</a>
|
||||
{% endif %}
|
||||
{% if widget.edit_related %}
|
||||
{% if widget.with_related %}
|
||||
<a class="edit-related pk-button" id="edit_form_{{ widget.get_name_for_id }}"
|
||||
style="display: none"
|
||||
title="{% blocktrans with card=widget.get_title %}Edit selected {{ card }}{% endblocktrans %}"
|
||||
>{% blocktrans with card=widget.get_title %}Edit selected {{ card }}{% endblocktrans %}</a>
|
||||
<a class="view-related" id="view_form_{{ widget.get_name_for_id }}"
|
||||
style="display: none">{% blocktrans with card=widget.get_title %}See selected {{ card }}{% endblocktrans %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
Loading…
Reference in New Issue