Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -13,3 +13,4 @@ htmlcov/
.python-version
!djangocms_versioning/static/djangocms_versioning/js/dist
docs/_build/
node_modules/
11 changes: 11 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -63,3 +63,14 @@ Run::

This should generate all html files from rst documents under `docs/_build` folder, which can be browsed.


Generating the Frontend distribution
====================================

Re-build static files: (always use a clean clone, make sure that node 6 on is used (use nvm to manage it). Order of commands is important

Run::

npm install -g gulp
npm install
gulp build
122 changes: 51 additions & 71 deletions djangocms_versioning/admin.py
Original file line number Diff line number Diff line change
@@ -617,16 +617,15 @@ def compare_versions(self, request, queryset):
return

# Build the link for the version comparison of the two selected versions
url = reverse(
"admin:{app}_{model}_compare".format(
app=self.model._meta.app_label, model=self.model._meta.model_name
),
args=(queryset[0].pk,),
url = add_url_parameters(
reverse('admin:{app}_{model}_compare'.format(
app=self.model._meta.app_label,
model=self.model._meta.model_name,
)),
left=queryset[0].pk,
right=queryset[1].pk,
)
url += "?compare_to=%d" % queryset[1].pk

return redirect(url)

compare_versions.short_description = _("Compare versions")

def grouper_form_view(self, request):
@@ -926,72 +925,53 @@ def discard_view(self, request, object_id):

return redirect(version_url)

def compare_view(self, request, object_id):
def compare_view(self, request):
"""Compares two versions
"""
# Get version 1 (the version we're comparing against)
v1 = self.get_object(request, unquote(object_id))
if v1 is None:
return self._get_obj_does_not_exist_redirect(
request, self.model._meta, object_id
)
versions = OrderedDict()

for side in ('left', 'right'):
if side in request.GET:
object_id = request.GET[side]
version = self.get_object(request, unquote(object_id))
if version is None:
return self._get_obj_does_not_exist_redirect(
request, self.model._meta, object_id)
versions[side] = version

if not versions:
raise Http404

context = {}
persist_params = {
get_cms_setting("CMS_TOOLBAR_URL__DISABLE"): 1,
get_cms_setting("CMS_TOOLBAR_URL__PERSIST"): 0,
}
v1_preview_url = add_url_parameters(
reverse(
"admin:cms_placeholder_render_object_preview",
args=(v1.content_type_id, v1.object_id),
),
**persist_params
)
# Get the list of versions for the grouper. This is for use
# in the dropdown to choose a version.
version_list = Version.objects.filter_by_content_grouping_values(
v1.content
).order_by("-number")
# Add the above to context
context = {
"version_list": version_list,
"v1": v1,
"v1_preview_url": v1_preview_url,
"v1_description": format_html(
'Version #{number} ({date})',
obj=v1,
number=v1.number,
date=localize(localtime(v1.created)),
),
"return_url": version_list_url(v1.content),
}

# Now check if version 2 has been specified and add to context
# if yes
if "compare_to" in request.GET:
v2 = self.get_object(request, unquote(request.GET["compare_to"]))
if v2 is None:
return self._get_obj_does_not_exist_redirect(
request, self.model._meta, request.GET["compare_to"]
)
else:
context.update(
{
"v2": v2,
"v2_preview_url": add_url_parameters(
reverse(
"admin:cms_placeholder_render_object_preview",
args=(v2.content_type_id, v2.object_id),
),
**persist_params
),
"v2_description": format_html(
'Version #{number} ({date})',
obj=v2,
number=v2.number,
date=localize(localtime(v2.created)),
),
}
# Get the list of versions for the grouper. This is for use
for side, version in versions.items():
context[side] = {
'obj': version,
'url': add_url_parameters(
reverse(
'admin:cms_placeholder_render_object_preview',
args=(version.content_type_id, version.object_id),
),
**persist_params
),
'description': format_html(
'{obj} (#{number}, {date})',
obj=version,
number=version.number,
date=localize(localtime(version.created)),
)
}

# Get the list of versions for grouping values. This is for use
# in the dropdown to choose a version.
version = next(iter(versions.values()))
context['versions'] = Version.objects.filter_by_content_grouping_values(
version.content)
return TemplateResponse(
request, "djangocms_versioning/admin/compare.html", context
)
@@ -1073,6 +1053,11 @@ def get_urls(self):
self.admin_site.admin_view(self.archive_view),
name="{}_{}_archive".format(*info),
),
url(
r"^compare/$",
self.admin_site.admin_view(self.compare_view),
name="{}_{}_compare".format(*info),
),
url(
r"^(.+)/publish/$",
self.admin_site.admin_view(self.publish_view),
@@ -1093,11 +1078,6 @@ def get_urls(self):
self.admin_site.admin_view(self.revert_view),
name="{}_{}_revert".format(*info),
),
url(
r"^(.+)/compare/$",
self.admin_site.admin_view(self.compare_view),
name="{}_{}_compare".format(*info),
),
url(
r"^(.+)/discard/$",
self.admin_site.admin_view(self.discard_view),
12 changes: 6 additions & 6 deletions djangocms_versioning/static/djangocms_versioning/js/base.js
Original file line number Diff line number Diff line change
@@ -39,12 +39,12 @@ const getOrAddFrame = () => {
const switchVersion = version => {
const url = window.location.href;

if (url.match(/compare_to=\d+/)) {
window.location.href = window.location.href.replace(/compare_to=\d+/, `compare_to=${version}`);
if (url.match(/right=\d+/)) {
window.location.href = window.location.href.replace(/right=\d+/, `right=${version}`);
} else if (url.match(/\?/)) {
window.location.href += `&compare_to=${version}`;
window.location.href += `&right=${version}`;
} else {
window.location.href += `?compare_to=${version}`;
window.location.href += `?right=${version}`;
}
};

@@ -155,9 +155,9 @@ const breakOutOfAnIframe = () => {
}, 0);
};

const showControls = () => $('.cms-versioning-controls .cms-toolbar-item-buttons .cms-btn-group').show();

$(function() {
const showControls = () => $('.cms-versioning-controls .cms-toolbar-item-buttons .cms-btn-group').show();

breakOutOfAnIframe();
initControls();

Large diffs are not rendered by default.

15,788 changes: 15,787 additions & 1 deletion djangocms_versioning/static/djangocms_versioning/js/dist/bundle.versioning.min.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -4,16 +4,16 @@
<head>
<meta charset="UTF-8">
<title>{% spaceless %}
{% if v1 and v2 %}
{% blocktrans with left=v1.description right=v1.description %}
{% if left and right %}
{% blocktrans with left=left.description right=right.description %}
Compare {{ left }} to {{ right }}
{% endblocktrans %}
{% elif v1 %}
{% blocktrans with left=v1.description %}
{% elif left %}
{% blocktrans with left=left.description %}
Compare {{ left }}
{% endblocktrans %}
{% elif right %}
{% blocktrans with right=v2.description %}
{% blocktrans with right=right.description %}
Compare {{ right }}
{% endblocktrans %}
{% endif %}{% endspaceless %}</title>
@@ -22,27 +22,27 @@
</head>
<body>
<div id="cms-top" class="cms cms-reset" data-compare='{
{% if v2_preview_url %}
"v2_url": "{{ v2_preview_url }}",
{% if left %}
"v1_url": "{{ left.url }}",
"v1_description": "{{ left.description }}"
{% endif %}
{% if v2 %}
"v2_description": "{{ v2_description }}",
{% if right %}
"v2_url": "{{ right.url }}",
"v2_description": "{{ right.description }}",
{% endif %}
"v1_url": "{{ v1_preview_url }}",
"v1_description": "{{ v1_description }}"
}'>
<div class="cms-toolbar">
<div class="cms-versioning-controls">
<a class="cms-btn" href="{{ return_url }}">{% trans "Back" %}</a> &nbsp;
<span class="cms-versioning-title">
{% blocktrans with left=v1_description %}
{% blocktrans with left=left.description %}
Comparing {{ left }} with
{% endblocktrans %}
</span>
<select class="js-cms-versioning-version cms-select">
<option disabled {% if not request.GET.compare_to %} selected{% endif %}>{% trans "Pick a version to compare to" %}</option>
{% for version in version_list %}
<option value="{{ version.pk }}" {% if v2 and v2.pk == version.pk %} selected{% endif %}>{% trans 'Version'%} #{{ version.number }}({{ version.created|date }})</option>
<option disabled {% if not request.GET.right %} selected{% endif %}>{% trans "Pick a version to compare to" %}</option>
{% for version in versions %}
<option value="{{ version.pk }}" {% if right and right.obj == version %} selected{% endif %}>{% trans 'Version'%} #{{ version.number }}({{ version.created|date }})</option>
{% endfor %}
</select>
<div class="cms-tooblar-item cms-toolbar-item-buttons">
93 changes: 51 additions & 42 deletions tests/test_admin.py
Original file line number Diff line number Diff line change
@@ -1851,12 +1851,14 @@ def setUp(self):
def test_compare_view_doesnt_allow_user_without_staff_permissions(self):
version = factories.PollVersionFactory()
url = self.get_admin_url(
self.versionable.version_model_proxy, "compare", version.pk
)
self.versionable.version_model_proxy, "compare")
url += '?left=%d' % version.pk
with self.login_user_context(self.get_standard_user()):
response = self.client.get(url)

self.assertRedirects(response, admin_reverse("login") + "?next=" + url)
parsed = urlparse(response.url)
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, admin_reverse('login') + "?next=" + url)

def test_compare_view_has_version_data_in_context_when_no_get_param(self):
"""When the url for the compare view has no additional params
@@ -1875,35 +1877,31 @@ def test_compare_view_has_version_data_in_context_when_no_get_param(self):
content__language="fr"
) # different grouper and different language
url = self.get_admin_url(
self.versionable.version_model_proxy, "compare", versions[0].pk
self.versionable.version_model_proxy, "compare"
)
url += '?left=%d' % versions[0].pk
user = self.get_staff_user_with_no_permissions()

with self.login_user_context(user):
response = self.client.get(url)

self.assertContains(response, "Version #{number} ({date})".format(
number=versions[0].number, date=localize(localtime(versions[0].created))))

context = response.context
self.assertIn("v1", context)
self.assertEqual(context["v1"], versions[0])
self.assertIn("v1_preview_url", context)
self.assertIn("left", context)
self.assertEqual(context["left"]["obj"], versions[0])
v1_preview_url = reverse(
"admin:cms_placeholder_render_object_preview",
args=(versions[0].content_type_id, versions[0].object_id),
)
parsed = urlparse(context["v1_preview_url"])
parsed = urlparse(context["left"]["url"])
self.assertEqual(parsed.path, v1_preview_url)
self.assertEqual(
{k: v[0] for k, v in parse_qs(parsed.query).items()},
self.disable_toolbar_params,
)
self.assertNotIn("v2", context)
self.assertNotIn("v2_preview_url", context)
self.assertIn("version_list", context)
self.assertNotIn("right", context)
self.assertIn("versions", context)
self.assertQuerysetEqual(
context["version_list"],
context["versions"],
[versions[0].pk, versions[1].pk],
transform=lambda o: o.pk,
ordered=False,
@@ -1924,10 +1922,8 @@ def test_compare_view_has_version_data_in_context_when_version2_in_get_param(sel
factories.PollVersionFactory(
content__language="fr"
) # different grouper and different language
url = self.get_admin_url(
self.versionable.version_model_proxy, "compare", versions[0].pk
)
url += "?compare_to=%d" % versions[1].pk
url = self.get_admin_url(self.versionable.version_model_proxy, "compare")
url += "?left=%d&right=%d" % (versions[0].pk, versions[1].pk)
user = self.get_staff_user_with_no_permissions()

with self.login_user_context(user):
@@ -1938,43 +1934,50 @@ def test_compare_view_has_version_data_in_context_when_version2_in_get_param(sel
self.assertContains(response, "Version #{}".format(versions[1].number))

context = response.context
self.assertIn("v1", context)
self.assertEqual(context["v1"], versions[0])
self.assertIn("v1_preview_url", context)
self.assertIn("left", context)
self.assertEqual(context["left"]["obj"], versions[0])
v1_preview_url = reverse(
"admin:cms_placeholder_render_object_preview",
args=(versions[0].content_type_id, versions[0].object_id),
)
parsed = urlparse(context["v1_preview_url"])
parsed = urlparse(context["left"]["url"])
self.assertEqual(parsed.path, v1_preview_url)
self.assertEqual(
{k: v[0] for k, v in parse_qs(parsed.query).items()},
self.disable_toolbar_params,
)
self.assertIn("v2", context)
self.assertEqual(context["v2"], versions[1])
self.assertIn("v2_preview_url", context)
self.assertIn("right", context)
self.assertEqual(context["right"]["obj"], versions[1])
v2_preview_url = reverse(
"admin:cms_placeholder_render_object_preview",
args=(versions[1].content_type_id, versions[1].object_id),
)
parsed = urlparse(context["v2_preview_url"])
parsed = urlparse(context["right"]["url"])
self.assertEqual(parsed.path, v2_preview_url)
self.assertEqual(
{k: v[0] for k, v in parse_qs(parsed.query).items()},
self.disable_toolbar_params,
)
self.assertIn("version_list", context)
self.assertIn("versions", context)
self.assertQuerysetEqual(
context["version_list"],
context["versions"],
[versions[0].pk, versions[1].pk, versions[2].pk],
transform=lambda o: o.pk,
ordered=False,
)

@patch("django.contrib.messages.add_message")
def test_edit_compare_view_handles_no_correct_object_provided(self):
url = self.get_admin_url(self.versionable.version_model_proxy, "compare")

with self.login_user_context(self.get_staff_user_with_no_permissions()):
response = self.client.post(url)

self.assertEqual(response.status_code, 404)

@patch('django.contrib.messages.add_message')
def test_edit_compare_view_handles_nonexistent_v1(self, mocked_messages):
url = self.get_admin_url(self.versionable.version_model_proxy, "compare", 89)
url = self.get_admin_url(self.versionable.version_model_proxy, "compare")
url += "?left=89"

with self.login_user_context(self.get_staff_user_with_no_permissions()):
response = self.client.post(url)
@@ -1991,9 +1994,8 @@ def test_edit_compare_view_handles_nonexistent_v1(self, mocked_messages):
def test_edit_compare_view_handles_nonexistent_v2(self, mocked_messages):
version = factories.PollVersionFactory()
url = self.get_admin_url(
self.versionable.version_model_proxy, "compare", version.pk
)
url += "?compare_to=134"
self.versionable.version_model_proxy, "compare")
url += "?left=" + str(version.pk) + "&right=134"

with self.login_user_context(self.get_staff_user_with_no_permissions()):
response = self.client.post(url)
@@ -2361,7 +2363,7 @@ def test_change_view_action_compare_versions_one_selected(self):

def test_change_view_action_compare_versions_two_selected(self):
"""
The user is redirectd to the compare view with two versions selected
The user is redirected to the compare view with two versions selected
"""
poll = factories.PollFactory()
factories.PollVersionFactory.create_batch(4, content__poll=poll)
@@ -2370,21 +2372,28 @@ def test_change_view_action_compare_versions_two_selected(self):
self.get_admin_url(self.versionable.version_model_proxy, "changelist")
+ querystring
)
success_redirect = self.get_admin_url(
self.versionable.version_model_proxy, "compare", 1
)
success_redirect += "?compare_to=2"

with self.login_user_context(self.superuser):
data = {
"action": "compare_versions",
admin.ACTION_CHECKBOX_NAME: ["1", "2"],
"post": "yes",
}
response = self.client.post(endpoint, data, follow=True)
response = self.client.post(endpoint, data)

self.assertNotContains(response, "Two versions have to be selected.")
self.assertRedirects(response, success_redirect, status_code=302)
parsed = urlparse(response.url)
self.assertEqual(response.status_code, 302)
self.assertEqual(
parsed.path,
self.get_admin_url(self.versionable.version_model_proxy, "compare"),
)
self.assertEqual(
{k: v[0] for k, v in parse_qs(parsed.query).items()},
{
"left": "1",
"right": "2",
},
)

def test_change_view_action_compare_versions_three_selected(self):
"""