From 769fab5e84294dec13da501242b5de3df3b2bbfd Mon Sep 17 00:00:00 2001 From: Fabio Caccamo Date: Thu, 25 Aug 2022 12:03:39 +0200 Subject: [PATCH] Add `django-streamfield` compatibility. --- README.md | 1 + .../admin_interface/css/streamfield.css | 200 ++++++++++++++++++ .../related-modal/related-modal.js | 14 +- .../streamfield/js/admin_popup_response.js | 22 ++ .../templates/admin/base_site.html | 2 + 5 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 admin_interface/static/admin_interface/css/streamfield.css create mode 100644 admin_interface/static/streamfield/js/admin_popup_response.js diff --git a/README.md b/README.md index e235fc9..5c00ab4 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ django-admin-interface is a modern **responsive flat admin interface customizabl - `django-json-widget` - `django-modeltranslation` - `django-tabbed-admin` + - `django-streamfield` - `sorl-thumbnail` --- diff --git a/admin_interface/static/admin_interface/css/streamfield.css b/admin_interface/static/admin_interface/css/streamfield.css new file mode 100644 index 0000000..71ce2db --- /dev/null +++ b/admin_interface/static/admin_interface/css/streamfield.css @@ -0,0 +1,200 @@ +/* +django-streamfield support +https://github.com/raagin/django-streamfield/ +*/ + +.admin-interface .form-row.field-stream { + margin: 0; + padding: 0; + border-bottom: none; +} + +.admin-interface .form-row.field-stream label[for=id_stream] { + display: none; +} + +.admin-interface .streamfield_app { + clear: both; + width: 100%; +} + +.admin-interface .streamfield_app .stream-help-text { + margin-bottom: 15px; + display: flex; + flex-direction: column; + clear: both; +} + +.admin-interface .streamfield_app .stream-help-text .stream-help-text__title { + align-self: flex-end; + user-select: none; + padding: 8px; + padding-right: 0; + color: var(--admin-interface-generic-link-color); +} + +.admin-interface .streamfield_app .stream-help-text .stream-help-text__title:hover { + color: var(--admin-interface-generic-link-hover-color); +} + +.admin-interface .streamfield_app .stream-help-text .stream-help-text__content { + background: var(--admin-interface-module-background-selected-color); + border-radius: var(--admin-interface-module-border-radius); + border: 1px solid rgba(0,0,0,0.1); + padding: 15px; +} + +.admin-interface .streamfield_app .stream-help-text .stream-help-text__content > ul { + margin: 0; + padding: 0; +} + +.admin-interface .streamfield_app .collapse-handler { + user-select: none; + padding: 8px; + padding-right: 0; + margin: 0 0 5px 0; + color: var(--admin-interface-generic-link-color); + text-decoration: none; +} + +.admin-interface .streamfield_app .collapse-handler:hover { + color: var(--admin-interface-generic-link-hover-color); + text-decoration: none; +} + +.admin-interface .streamfield_app .stream-model-block { + position: relative; + box-shadow: none; + border: 1px solid rgba(0,0,0,0.1); + border-radius: var(--admin-interface-module-border-radius); + overflow: hidden; +} + +.admin-interface .streamfield_app .stream-model-block, +.admin-interface .streamfield_app .streamfield-models.collapsed .stream-model-block { + margin-bottom: 10px; +} + +.admin-interface .streamfield_app .stream-model-block .streamblock__block__title { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin: 0; + padding: 10px 10px 10px 20px; +} + +.admin-interface .streamfield_app .stream-model-block .streamblock__block__title span { + font-size: 18px; +} + +.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle { + position: static; + right: 0; + top: 0; + color: var(--admin-interface-generic-link-color); +} + +.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle:hover { + color: var(--admin-interface-generic-link-hover-color); +} + +.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle { + display: flex; + justify-content: center; + align-items: center; +} + +.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle .block-move, +.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle .block-delete { + display: flex; + justify-content: center; + align-items: center; + width: 40px; + height: 40px; + font-weight: normal; + background: none; + flex-shrink: 0; + color: inherit; + font-size: 16px; +} + +.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle .block-move { + cursor: move; /* fallback if grab cursor is unsupported */ + cursor: grab; + cursor: -moz-grab; + cursor: -webkit-grab; +} + +.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle .block-move:before { + content: "↕"; + + display: block; +} + +.admin-interface .streamfield_app .stream-model-block .streamblock__block__title .streamblock__block-handle .block-delete:before { + content: "×"; + display: block; + font-size: 18px; +} + +.admin-interface .streamfield_app .block-fields > div { + margin-bottom: 15px; +} + +.admin-interface .streamfield_app .stream-model-block .stream-model-block__content { + background-color: #f8f8f8; + padding: 20px; +} + +.admin-interface .streamfield_app .stream-model-block .stream-model-block__content.no-subblocks.abstract-block { + display: none; +} + +.admin-interface .streamfield_app .stream-insert-new-block { + margin-bottom: 20px; +} + +.admin-interface .streamfield_app .stream-insert-new-block .add-new-block-button { + color: var(--admin-interface-generic-link-color); + text-decoration: none; +} + +.admin-interface .streamfield_app .stream-insert-new-block .add-new-block-button:hover { + color: var(--admin-interface-generic-link-hover-color); + text-decoration: none; +} + +.admin-interface .streamfield_app .stream-insert-new-block ul { + display: block; + width: 100%; + margin: 10px 0 0 0; + padding: 0; + user-select: none; +} + +.admin-interface .streamfield_app .stream-insert-new-block ul li { + display: inline-block; + font-size: 12px; + margin: 0; + padding: 0; +} + +.admin-interface .streamfield_app .stream-btn { + font-weight: normal; + text-decoration: none; + background-color: var(--admin-interface-generic-link-color); + padding: 6px 12px; + border-radius: 4px; +} + +.admin-interface .streamfield_app .stream-btn:hover { + text-decoration: none; + background-color: var(--admin-interface-generic-link-hover-color); +} + +.admin-interface .streamfield_app .stream-insert-new-block ul li .stream-btn { + margin-top: 5px; + margin-left: 5px; +} diff --git a/admin_interface/static/admin_interface/related-modal/related-modal.js b/admin_interface/static/admin_interface/related-modal/related-modal.js index 6b02945..b3b9d32 100644 --- a/admin_interface/static/admin_interface/related-modal/related-modal.js +++ b/admin_interface/static/admin_interface/related-modal/related-modal.js @@ -148,8 +148,18 @@ if (typeof(django) !== 'undefined' && typeof(django.jQuery) !== 'undefined') // https://github.com/lincolnloop/django-dynamic-raw-id presentRelatedObjectModalOnClickOn('a.dynamic_raw_id-related-lookup', true); - // show_change_link=True support - presentRelatedObjectModalOnClickOn('a.inlinechangelink'); + // django-streamfield support + // https://github.com/raagin/django-streamfield/ + presentRelatedObjectModalOnClickOn('.streamfield_app a.stream-btn[href*="_popup=1"]'); + // Vanilla js for catching the click during capture phase for anticipating Vue.js listener. + document.addEventListener('click', function(event) { + // console.log('click intercepted before Vue.'); + if (event.target.matches('.streamfield_app a.stream-btn[href*="_popup=1"]')) { + event.stopImmediatePropagation(); + event.preventDefault(); + $(event.target).trigger('click'); + } + }, { capture: true }); }); })(django.jQuery); diff --git a/admin_interface/static/streamfield/js/admin_popup_response.js b/admin_interface/static/streamfield/js/admin_popup_response.js new file mode 100644 index 0000000..bd41559 --- /dev/null +++ b/admin_interface/static/streamfield/js/admin_popup_response.js @@ -0,0 +1,22 @@ +(function() { + + 'use strict'; + + var windowRef = window; + var openerRef = windowRef.parent; + + var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse); + switch (initData.action) { + case 'change': + openerRef.streamapps[initData.app_id].updateBlock(initData.block_id, initData.instance_id); + openerRef.dismissRelatedObjectModal(); + break; + case 'delete': + break; + default: + openerRef.streamapps[initData.app_id].updateBlock(initData.block_id, initData.instance_id); + openerRef.dismissRelatedObjectModal(); + break; + } + +})(); \ No newline at end of file diff --git a/admin_interface/templates/admin/base_site.html b/admin_interface/templates/admin/base_site.html index ec134cc..7614ba6 100644 --- a/admin_interface/templates/admin/base_site.html +++ b/admin_interface/templates/admin/base_site.html @@ -91,6 +91,8 @@ {% endif %} +