spina 2.7.0 → 2.9.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of spina might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +0 -2
- data/Rakefile +2 -1
- data/app/assets/builds/spina/tailwind.css +3480 -0
- data/app/assets/config/spina/manifest.js +3 -1
- data/app/assets/javascripts/spina/controllers/image_collection_controller.js +5 -3
- data/app/assets/javascripts/spina/controllers/infinite_scroll_controller.js +4 -2
- data/app/assets/stylesheets/spina/{_animate.css → animate.css} +0 -0
- data/app/assets/stylesheets/spina/{tailwind/custom.css → application.tailwind.css} +40 -46
- data/app/assets/stylesheets/spina/{_fonts.css.erb → fonts.css.erb} +0 -0
- data/app/components/spina/forms/trix_toolbar_component.html.erb +1 -1
- data/app/components/spina/media_picker/image_component.html.erb +1 -1
- data/app/components/spina/media_picker/modal_component.html.erb +4 -4
- data/app/components/spina/user_interface/tab_link_component.html.erb +1 -1
- data/app/components/spina/user_interface/translations_component.html.erb +21 -0
- data/app/components/spina/user_interface/translations_component.rb +26 -0
- data/app/controllers/concerns/spina/frontend.rb +1 -1
- data/app/controllers/spina/admin/images_controller.rb +3 -2
- data/app/controllers/spina/admin/layout_controller.rb +1 -1
- data/app/controllers/spina/admin/navigation_items_controller.rb +1 -1
- data/app/helpers/spina/images_helper.rb +15 -0
- data/app/models/concerns/spina/partable.rb +1 -1
- data/app/models/spina/parts/attachment.rb +1 -1
- data/app/models/spina/parts/base.rb +2 -1
- data/app/presenters/spina/menu_presenter.rb +26 -3
- data/app/views/layouts/spina/admin/admin.html.erb +1 -1
- data/app/views/layouts/spina/admin/application.html.erb +2 -2
- data/app/views/spina/admin/images/_image.html.erb +34 -26
- data/app/views/spina/admin/images/index.html.erb +1 -1
- data/app/views/spina/admin/images/show.html.erb +3 -1
- data/app/views/spina/admin/layout/edit.html.erb +2 -0
- data/app/views/spina/admin/media_folders/_media_folder.html.erb +5 -3
- data/app/views/spina/admin/navigation_items/_form.html.erb +5 -1
- data/app/views/spina/admin/navigations/edit.html.erb +1 -1
- data/app/views/spina/admin/pages/_form.html.erb +2 -2
- data/app/views/spina/admin/pages/index.html.erb +1 -1
- data/app/views/spina/admin/parts/attachments/_form.html.erb +2 -1
- data/app/views/spina/admin/parts/image_collections/_form.html.erb +1 -0
- data/app/views/spina/admin/parts/images/_form.html.erb +1 -0
- data/app/views/spina/admin/parts/lines/_form.html.erb +1 -0
- data/app/views/spina/admin/parts/options/_form.html.erb +2 -1
- data/app/views/spina/admin/parts/repeaters/_form.html.erb +2 -1
- data/app/views/spina/admin/parts/texts/_form.html.erb +1 -0
- data/app/views/spina/admin/resources/edit.html.erb +6 -1
- data/app/views/spina/admin/shared/_navigation.html.erb +1 -1
- data/config/locales/de.yml +63 -28
- data/config/locales/fr.yml +190 -152
- data/lib/generators/spina/install_generator.rb +8 -3
- data/lib/generators/spina/tailwind_config_generator.rb +10 -0
- data/{app/assets/config/spina/tailwind.config.js → lib/generators/spina/templates/app/assets/config/spina/tailwind.config.js.tt} +5 -7
- data/lib/generators/spina/templates/config/initializers/themes/default.rb +1 -1
- data/lib/generators/spina/templates/config/initializers/themes/demo.rb +2 -2
- data/lib/spina/version.rb +1 -1
- data/lib/spina.rb +22 -11
- data/lib/tasks/install.rake +45 -0
- data/lib/tasks/tailwind.rake +22 -0
- metadata +27 -11
- data/app/assets/stylesheets/spina/_tailwind.css +0 -203643
- data/app/assets/stylesheets/spina/application.css +0 -6
- data/lib/spina/tailwind_purger.rb +0 -147
- data/lib/tasks/spina_tasks.rake +0 -75
@@ -4,6 +4,8 @@
|
|
4
4
|
//= link_directory ../../javascripts/spina/controllers
|
5
5
|
//= link_directory ../../javascripts/spina/libraries
|
6
6
|
|
7
|
-
//= link spina/
|
7
|
+
//= link spina/animate.css
|
8
|
+
//= link spina/fonts.css
|
9
|
+
//= link spina/tailwind.css
|
8
10
|
|
9
11
|
//= link spina/application.js
|
@@ -7,9 +7,11 @@ export default class extends Controller {
|
|
7
7
|
}
|
8
8
|
|
9
9
|
connect() {
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
setTimeout(function() {
|
11
|
+
this.sortable = Sortable.create(this.collectionTarget, {
|
12
|
+
animation: 150
|
13
|
+
})
|
14
|
+
}.bind(this), 250)
|
13
15
|
}
|
14
16
|
|
15
17
|
removeImage(event) {
|
@@ -7,6 +7,7 @@ export default class extends Controller {
|
|
7
7
|
|
8
8
|
connect() {
|
9
9
|
this.scrollElement.addEventListener("scroll", this.load.bind(this))
|
10
|
+
this.load() // Initial load
|
10
11
|
}
|
11
12
|
|
12
13
|
disconnect() {
|
@@ -16,8 +17,9 @@ export default class extends Controller {
|
|
16
17
|
load() {
|
17
18
|
if (this.hasButtonTarget) {
|
18
19
|
let top = this.buttonTarget.getBoundingClientRect().top
|
19
|
-
if (top <
|
20
|
+
if (top < window.innerHeight + 500) {
|
20
21
|
this.buttonTarget.click()
|
22
|
+
this.buttonTarget.remove()
|
21
23
|
}
|
22
24
|
}
|
23
25
|
}
|
@@ -26,7 +28,7 @@ export default class extends Controller {
|
|
26
28
|
if (this.hasContainerTarget) {
|
27
29
|
return this.containerTarget
|
28
30
|
} else {
|
29
|
-
return
|
31
|
+
return document.getElementById("main")
|
30
32
|
}
|
31
33
|
}
|
32
34
|
|
File without changes
|
@@ -138,58 +138,52 @@
|
|
138
138
|
@apply border border-gray-400;
|
139
139
|
}
|
140
140
|
|
141
|
-
/* Trix */
|
142
|
-
.trix-toolbar {
|
143
|
-
|
144
|
-
|
145
|
-
}
|
141
|
+
/* Trix */
|
142
|
+
.trix-toolbar button[data-trix-active] {
|
143
|
+
@apply text-white bg-spina;
|
144
|
+
}
|
146
145
|
|
147
|
-
|
148
|
-
|
149
|
-
}
|
146
|
+
.trix-toolbar button[disabled] {
|
147
|
+
@apply bg-gray-100 text-gray-400;
|
150
148
|
}
|
151
149
|
|
152
|
-
trix-editor {
|
153
|
-
|
154
|
-
|
155
|
-
@apply select-none
|
156
|
-
}
|
157
|
-
|
158
|
-
figure.attachment {
|
159
|
-
@apply m-0 inline-block
|
160
|
-
}
|
161
|
-
|
162
|
-
figure.attachment[data-trix-content-type="Spina::Image"] {
|
163
|
-
max-height: 150px;
|
164
|
-
max-width: 200px;
|
165
|
-
}
|
166
|
-
|
167
|
-
figure.attachment[data-trix-content-type="Spina::Image"] img {
|
168
|
-
@apply m-0 rounded-md object-contain;
|
169
|
-
}
|
170
|
-
|
171
|
-
figure.attachment[data-trix-content-type="Spina::Image"] [data-label]:after {
|
172
|
-
content: attr(data-label);
|
173
|
-
@apply italic text-gray-500 h-8 flex items-center px-2 mt-1 text-sm;
|
174
|
-
}
|
175
|
-
|
176
|
-
figure[data-trix-mutable].attachment[data-trix-content-type="Spina::Image"] img {
|
177
|
-
@apply shadow-lg ring ring-spina-light
|
178
|
-
}
|
150
|
+
trix-editor [data-trix-mutable]:not(.attachment__captain-editor) {
|
151
|
+
@apply select-none
|
152
|
+
}
|
179
153
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
154
|
+
trix-editor figure.attachment {
|
155
|
+
@apply m-0 inline-block
|
156
|
+
}
|
157
|
+
|
158
|
+
trix-editor figure.attachment[data-trix-content-type="Spina::Image"] {
|
159
|
+
max-height: 150px;
|
160
|
+
max-width: 200px;
|
161
|
+
}
|
162
|
+
|
163
|
+
trix-editor figure.attachment[data-trix-content-type="Spina::Image"] img {
|
164
|
+
@apply m-0 rounded-md object-contain;
|
165
|
+
}
|
188
166
|
|
189
|
-
|
190
|
-
|
191
|
-
|
167
|
+
trix-editor figure.attachment[data-trix-content-type="Spina::Image"] [data-label]:after {
|
168
|
+
content: attr(data-label);
|
169
|
+
@apply italic text-gray-500 h-8 flex items-center px-2 mt-1 text-sm;
|
170
|
+
}
|
171
|
+
|
172
|
+
trix-editor figure[data-trix-mutable].attachment[data-trix-content-type="Spina::Image"] img {
|
173
|
+
@apply shadow-lg ring ring-spina-light
|
174
|
+
}
|
192
175
|
|
176
|
+
trix-editor figure[data-trix-mutable][data-trix-content-type="application/vnd+spina.embed+html"].attachment > spina-embed {
|
177
|
+
@apply block;
|
178
|
+
@apply shadow-lg ring ring-spina-light rounded-md;
|
179
|
+
}
|
180
|
+
|
181
|
+
trix-editor figure .attachment__caption {
|
182
|
+
@apply hidden
|
183
|
+
}
|
184
|
+
|
185
|
+
trix-editor figure .attachment__toolbar {
|
186
|
+
@apply hidden
|
193
187
|
}
|
194
188
|
|
195
189
|
trix-editor [data-trix-mutable]::-moz-selection,
|
File without changes
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div class="relative sticky top-0 pt-4 bg-white trix-toolbar" id="<%= @trix_id %>">
|
1
|
+
<div class="relative sticky z-10 top-0 pt-4 bg-white trix-toolbar" id="<%= @trix_id %>">
|
2
2
|
<div class="flex items-center flex-wrap" data-controller="reveal">
|
3
3
|
<div class="flex items-center bg-gray-200 rounded overflow-hidden mb-3 mr-3">
|
4
4
|
<button type="button" class="hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="bold" data-trix-key="b" title="${Trix.config.lang.bold}" tabindex="-1">
|
@@ -10,7 +10,7 @@
|
|
10
10
|
data-deselected-class="border-transparent"
|
11
11
|
class="w-full h-40 overflow-hidden rounded-md transform transition-transform duration-200 border-2 border-transparent hover:scale-105">
|
12
12
|
|
13
|
-
<%= image_tag helpers.
|
13
|
+
<%= image_tag helpers.large_thumbnail_url(@image), class: 'object-contain h-40 w-full', data: {controller: "image-fade-in"} %>
|
14
14
|
</button>
|
15
15
|
|
16
16
|
<div class="text-xs text-center text-gray-700 rounded p-1" data-selected-class="text-white bg-spina" data-deselected-class="text-gray-700"><%= @image.file.filename %></div>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<%= render(Spina::UserInterface::ModalComponent.new(size: "max-w-6xl h-full")) do |component| %>
|
2
2
|
<div class="h-full w-full" data-controller="infinite-scroll media-picker-modal" data-target="<%= @target %>">
|
3
|
-
<turbo-frame id="media_picker">
|
3
|
+
<turbo-frame id="media_picker" data-action= "turbo:frame-load->infinite-scroll#load">
|
4
4
|
<div class="flex flex-col md:flex-row h-full w-full">
|
5
5
|
<div class="flex-1 bg-white flex flex-col max-h-full relative overflow-hidden">
|
6
|
-
<div data-infinite-scroll-target="container" data-controller="selectable" class="p-6 h-full w-full overflow-scroll ">
|
6
|
+
<div data-infinite-scroll-target="container" data-controller="selectable" class="p-6 h-full w-full overflow-scroll" data-action="scroll->infinite-scroll#load">
|
7
7
|
|
8
8
|
<!-- Images are loaded using nested turbo-frame-tags -->
|
9
9
|
<!-- Only load images in multiples of 4 so that this grid -->
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
|
16
16
|
<% if @images.next_page %>
|
17
|
-
<turbo-frame id="images-<%= @images.next_page %>">
|
18
|
-
<%= link_to "
|
17
|
+
<turbo-frame id="images-<%= @images.next_page %>" data-action= "turbo:frame-load->infinite-scroll#load">
|
18
|
+
<%= link_to "Load more images", helpers.path_to_next_page(@images), class: "btn btn-default mt-6", data: {infinite_scroll_target: "button"} %>
|
19
19
|
</turbo-frame>
|
20
20
|
<% end %>
|
21
21
|
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= link_to @url, class: "block px-3 leading-relaxed py-1 hover:text-gray-800 rounded-md text-gray-400 font-medium text-sm flex items-center #{css_classes}" do %>
|
1
|
+
<%= link_to @url, class: "block px-3 leading-relaxed py-1 hover:text-gray-800 rounded-md text-gray-400 font-medium text-sm flex items-center whitespace-nowrap #{css_classes}" do %>
|
2
2
|
<%= content || @name %>
|
3
3
|
<% end %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<div class="relative" data-controller="reveal" data-reveal-away-value>
|
2
|
+
<button type="button" class="btn btn-default px-3" data-action="reveal#toggle">
|
3
|
+
<%= helpers.heroicon("chat-alt", style: :solid, class: 'w-4 h-4 text-gray-300') %>
|
4
|
+
|
5
|
+
<span class="ml-1 font-semibold"><%= @label %></span>
|
6
|
+
</button>
|
7
|
+
|
8
|
+
<div hidden data-reveal data-transition class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg border border-gray-200 z-20">
|
9
|
+
<div class="rounded-md bg-white shadow-xs">
|
10
|
+
<div class="py-1">
|
11
|
+
<% locales.each do |locale| %>
|
12
|
+
<%= link_to "?locale=#{locale}", class: "block px-3 py-2 text-sm leading-4 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900 font-medium" do %>
|
13
|
+
<div class="text-gray-700">
|
14
|
+
<%=t('spina.pages.edit_translation', language: '<span class="font-semibold">' + t("spina.languages.#{locale}") + '</span>').html_safe %>
|
15
|
+
</div>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Spina
|
2
|
+
module UserInterface
|
3
|
+
class TranslationsComponent < ApplicationComponent
|
4
|
+
|
5
|
+
def initialize(record, label: nil)
|
6
|
+
@record = record
|
7
|
+
@label = label
|
8
|
+
end
|
9
|
+
|
10
|
+
def render?
|
11
|
+
spina_locales.many?
|
12
|
+
end
|
13
|
+
|
14
|
+
def locales
|
15
|
+
spina_locales
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def spina_locales
|
21
|
+
Spina.config.locales.map(&:to_sym)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -5,7 +5,7 @@ module Spina
|
|
5
5
|
before_action :set_breadcrumbs
|
6
6
|
|
7
7
|
def index
|
8
|
-
@media_folders = MediaFolder.order(:name)
|
8
|
+
@media_folders = MediaFolder.order(:name).includes(:images)
|
9
9
|
@images = Image.sorted.where(media_folder: @media_folder).with_attached_file.page(params[:page]).per(25)
|
10
10
|
end
|
11
11
|
|
@@ -53,7 +53,8 @@ module Spina
|
|
53
53
|
if @image.saved_change_to_media_folder_id?
|
54
54
|
render :update
|
55
55
|
else
|
56
|
-
|
56
|
+
@media_folders = MediaFolder.order(:name)
|
57
|
+
render @image
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
@@ -11,7 +11,7 @@ module Spina::Admin
|
|
11
11
|
|
12
12
|
def update
|
13
13
|
if @account.update(layout_params)
|
14
|
-
redirect_to spina.edit_admin_layout_path, flash: {success: t('spina.layout.saved')}
|
14
|
+
redirect_to spina.edit_admin_layout_path(locale: @locale), flash: {success: t('spina.layout.saved')}
|
15
15
|
else
|
16
16
|
flash.now[:error] = t('spina.layout.couldnt_be_saved')
|
17
17
|
render partial: 'error', status: :unprocessable_entity
|
@@ -1,10 +1,25 @@
|
|
1
1
|
module Spina
|
2
2
|
module ImagesHelper
|
3
|
+
|
4
|
+
def original_url(image)
|
5
|
+
return "" if image.nil?
|
6
|
+
main_app.url_for(image.file)
|
7
|
+
end
|
3
8
|
|
4
9
|
def thumbnail_url(image)
|
5
10
|
return "" if image.nil?
|
6
11
|
main_app.url_for(image.variant(resize_to_fill: [400, 300]))
|
7
12
|
end
|
13
|
+
|
14
|
+
def large_thumbnail_url(image)
|
15
|
+
return "" if image.nil?
|
16
|
+
main_app.url_for(image.variant(resize_to_fit: [800, 600]))
|
17
|
+
end
|
18
|
+
|
19
|
+
def preview_url(image)
|
20
|
+
return "" if image.nil?
|
21
|
+
main_app.url_for(image.variant(resize_to_limit: [1600, 1200]))
|
22
|
+
end
|
8
23
|
|
9
24
|
def embedded_image_url(image)
|
10
25
|
return "" if image.nil?
|
@@ -10,7 +10,7 @@ module Spina
|
|
10
10
|
part = find_part(attributes[:name]) || attributes[:part_type].constantize.new
|
11
11
|
|
12
12
|
# Copy all attributes to part
|
13
|
-
%w(name title options).each do |attribute|
|
13
|
+
%w(name title hint options).each do |attribute|
|
14
14
|
part.public_send("#{attribute}=", attributes[attribute.to_sym]) if part.respond_to?(attribute)
|
15
15
|
end
|
16
16
|
|
@@ -8,9 +8,11 @@ module Spina
|
|
8
8
|
|
9
9
|
# Configuration
|
10
10
|
config_accessor :menu_tag, :menu_css,
|
11
|
-
:list_tag, :list_css,
|
12
|
-
:list_item_tag, :list_item_css,
|
11
|
+
:list_tag, :list_css,
|
12
|
+
:list_item_tag, :list_item_css,
|
13
13
|
:link_tag_css,
|
14
|
+
:active_list_item_css,
|
15
|
+
:current_list_item_css,
|
14
16
|
:include_drafts,
|
15
17
|
:depth # root nodes are at depth 0
|
16
18
|
|
@@ -51,9 +53,10 @@ module Spina
|
|
51
53
|
|
52
54
|
def render_item(item)
|
53
55
|
return nil unless item.materialized_path
|
56
|
+
|
54
57
|
children = scoped_collection(item.children)
|
55
58
|
|
56
|
-
content_tag(list_item_tag, class:
|
59
|
+
content_tag(list_item_tag, class: item_css(item), data: { page_id: item.page_id, draft: (true if item.draft?) }) do
|
57
60
|
buffer = ActiveSupport::SafeBuffer.new
|
58
61
|
buffer << link_to(item.menu_title, item.materialized_path, class: link_tag_css)
|
59
62
|
buffer << render_items(children) if render_children?(item) && children.any?
|
@@ -70,6 +73,26 @@ module Spina
|
|
70
73
|
return true unless depth
|
71
74
|
item.depth < depth
|
72
75
|
end
|
76
|
+
|
77
|
+
def item_css(item)
|
78
|
+
return current_list_item_css if apply_current_css?(item)
|
79
|
+
return active_list_item_css if apply_active_css?(item)
|
80
|
+
list_item_css
|
81
|
+
end
|
82
|
+
|
83
|
+
def apply_current_css?(item)
|
84
|
+
return false if current_list_item_css.nil?
|
85
|
+
Spina::Current.page == item
|
86
|
+
end
|
73
87
|
|
88
|
+
def apply_active_css?(item)
|
89
|
+
return false if apply_current_css?(item)
|
90
|
+
parent_of_current?(item)
|
91
|
+
end
|
92
|
+
|
93
|
+
def parent_of_current?(item)
|
94
|
+
return false if item.homepage?
|
95
|
+
Spina::Current.page.materialized_path.starts_with? item.materialized_path
|
96
|
+
end
|
74
97
|
end
|
75
98
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div class="flex flex-col md:flex-row md:h-screen min-h-screen w-full overflow-hidden">
|
3
3
|
<%= render partial: "spina/admin/shared/navigation" %>
|
4
4
|
|
5
|
-
<section class="w-full md:overflow-scroll">
|
5
|
+
<section id="main" class="w-full md:overflow-scroll">
|
6
6
|
<%= yield %>
|
7
7
|
|
8
8
|
<%= turbo_frame_tag "flash" do %>
|
@@ -10,8 +10,8 @@
|
|
10
10
|
|
11
11
|
<title>Spina CMS</title>
|
12
12
|
|
13
|
-
<!--
|
14
|
-
<%= stylesheet_link_tag
|
13
|
+
<!-- Stylesheets -->
|
14
|
+
<%= stylesheet_link_tag "spina/tailwind", "spina/fonts", "spina/animate", "data-turbo-track": "reload" %>
|
15
15
|
|
16
16
|
<!-- Spina's importmap -->
|
17
17
|
<%= spina_importmap_tags %>
|
@@ -1,7 +1,9 @@
|
|
1
1
|
<%= turbo_frame_tag dom_id(image) do %>
|
2
2
|
<div class="flex items-center h-12 border-b border-gray-200 px-8 hover:bg-white group">
|
3
3
|
<div class="w-8 mr-4 h-12 flex justify-center">
|
4
|
-
<%=
|
4
|
+
<%= link_to spina.admin_image_path(image), class: "flex items-center cursor-zoom-in", data: {turbo_frame: "modal"} do %>
|
5
|
+
<%= image_tag thumbnail_url(image), class: "object-contain" %>
|
6
|
+
<% end %>
|
5
7
|
</div>
|
6
8
|
|
7
9
|
<turbo-frame id="<%= dom_id(image) %>_filename" class="font-medium text-gray-800 h-full flex-1 w-56 text-sm flex items-center relative">
|
@@ -13,34 +15,36 @@
|
|
13
15
|
<%=t 'spina.ui.rename' %>
|
14
16
|
<% end %>
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
<% dropdown.menu do %>
|
24
|
-
<% if image.media_folder_id.present? %>
|
25
|
-
<%= form_with model: image, url: spina.admin_image_path(image) do |f| %>
|
26
|
-
<%= f.hidden_field :media_folder_id, value: nil %>
|
27
|
-
<%= render Spina::UserInterface::DropdownButtonComponent.new do %>
|
28
|
-
<%=t 'spina.media_library.no_folder' %>
|
29
|
-
<% end %>
|
30
|
-
<% end %>
|
18
|
+
<% if @media_folders.present? %>
|
19
|
+
<%= render Spina::UserInterface::DropdownComponent.new do |dropdown| %>
|
20
|
+
<% dropdown.button(classes: 'btn btn-default h-7 px-2 text-xs') do %>
|
21
|
+
<%= heroicon('folder', style: :solid, class: 'w-4 h-4 mr-1 text-gray-600') %>
|
22
|
+
<%=t 'spina.ui.move_to' %>
|
23
|
+
<%= heroicon('chevron-down', style: :solid, class: 'w-4 h-4') %>
|
31
24
|
<% end %>
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
<%= media_folder.name %>
|
36
|
-
<% end %>
|
37
|
-
<% else %>
|
25
|
+
|
26
|
+
<% dropdown.menu do %>
|
27
|
+
<% if image.media_folder_id.present? %>
|
38
28
|
<%= form_with model: image, url: spina.admin_image_path(image) do |f| %>
|
39
|
-
<%= f.hidden_field :media_folder_id, value:
|
40
|
-
|
29
|
+
<%= f.hidden_field :media_folder_id, value: nil %>
|
41
30
|
<%= render Spina::UserInterface::DropdownButtonComponent.new do %>
|
31
|
+
<%=t 'spina.media_library.no_folder' %>
|
32
|
+
<% end %>
|
33
|
+
<% end %>
|
34
|
+
<% end %>
|
35
|
+
<% @media_folders.each do |media_folder| %>
|
36
|
+
<% if media_folder.id == image.media_folder_id %>
|
37
|
+
<%= render Spina::UserInterface::DropdownButtonComponent.new(disabled: true) do %>
|
42
38
|
<%= media_folder.name %>
|
43
39
|
<% end %>
|
40
|
+
<% else %>
|
41
|
+
<%= form_with model: image, url: spina.admin_image_path(image) do |f| %>
|
42
|
+
<%= f.hidden_field :media_folder_id, value: media_folder.id %>
|
43
|
+
|
44
|
+
<%= render Spina::UserInterface::DropdownButtonComponent.new do %>
|
45
|
+
<%= media_folder.name %>
|
46
|
+
<% end %>
|
47
|
+
<% end %>
|
44
48
|
<% end %>
|
45
49
|
<% end %>
|
46
50
|
<% end %>
|
@@ -56,8 +60,12 @@
|
|
56
60
|
</div>
|
57
61
|
</div>
|
58
62
|
<div class="text-gray-500 text-xs w-32 text-right whitespace-nowrap"><%=l image.created_at, format: :short %></div>
|
59
|
-
<div class="">
|
60
|
-
<%=
|
63
|
+
<div class="flex items-center ml-2">
|
64
|
+
<%= link_to original_url(image), class: "block py-3 px-2 text-gray-500 hover:text-gray-900", download: image.file.filename do %>
|
65
|
+
<%= heroicon('download', class: 'w-5 h-5') %>
|
66
|
+
<% end %>
|
67
|
+
|
68
|
+
<%= button_to spina.admin_image_path(image), method: :delete, class: "block py-3 px-2 text-gray-500 hover:text-gray-900", form: {data: {controller: "confirm", confirm_message: t('spina.images.delete_confirmation_html')}} do %>
|
61
69
|
<%= heroicon('trash', class: "w-5 h-5") %>
|
62
70
|
<% end %>
|
63
71
|
</div>
|
@@ -64,7 +64,7 @@
|
|
64
64
|
|
65
65
|
<% if @images.next_page %>
|
66
66
|
<%= turbo_frame_tag "images-#{@images.next_page}", data: {action: "turbo:frame-load->infinite-scroll#load"} do %>
|
67
|
-
<%= link_to t('spina.ui.load_more'), path_to_next_page(@images), class:
|
67
|
+
<%= link_to t('spina.ui.load_more'), path_to_next_page(@images), class: "btn btn-default", data: {infinite_scroll_target: "button"} %>
|
68
68
|
<% end %>
|
69
69
|
<% end %>
|
70
70
|
<% end %>
|
@@ -1,5 +1,7 @@
|
|
1
1
|
<%= render Spina::UserInterface::HeaderComponent.new do |header| %>
|
2
2
|
<% header.actions do %>
|
3
|
+
<%= render Spina::UserInterface::TranslationsComponent.new(@account, label: @locale.upcase) %>
|
4
|
+
|
3
5
|
<% if Spina::Current.theme.layout_parts.any? %>
|
4
6
|
<%= button_tag type: :submit, form: dom_id(@account), class: 'btn btn-primary', data: {controller: "button hotkeys", hotkeys: "command+s, ctrl+s", hotkeys_target: "button", action: "button#loading", loading_message: t('spina.ui.saving')} do %>
|
5
7
|
<%= heroicon('check', style: :solid, class: 'w-5 h-5 mr-1 -ml-2') %>
|
@@ -11,8 +11,10 @@
|
|
11
11
|
</div>
|
12
12
|
<div class="text-gray-500 text-xs w-32 text-right"><%=l media_folder.created_at, format: :short %></div>
|
13
13
|
|
14
|
-
|
15
|
-
<%=
|
16
|
-
|
14
|
+
<div class="flex items-center ml-11">
|
15
|
+
<%= button_to spina.admin_media_folder_path(media_folder), method: :delete, class: "block py-3 px-2 text-gray-500 hover:text-gray-900", form: {data: {controller: "confirm", confirm_message: t('spina.media_library.media_folder_delete_confirmation_html')}} do %>
|
16
|
+
<%= heroicon('trash', class: 'w-5 h-5') %>
|
17
|
+
<% end %>
|
18
|
+
</div>
|
17
19
|
</div>
|
18
20
|
<% end %>
|
@@ -10,7 +10,11 @@
|
|
10
10
|
</h3>
|
11
11
|
|
12
12
|
<div class="mt-3">
|
13
|
-
|
13
|
+
|
14
|
+
<div class="border border-gray-300 rounded-md bg-white">
|
15
|
+
<%= render Spina::Pages::PageSelectComponent.new("navigation_item[page_id]", @pages, include_blank: t("spina.navigations.choose_page"), disabled: @navigation.navigation_items.pluck(:page_id)) %>
|
16
|
+
</div>
|
17
|
+
|
14
18
|
</div>
|
15
19
|
</div>
|
16
20
|
</div>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<%= render Spina::UserInterface::HeaderComponent.new do |header| %>
|
2
2
|
<% header.navigation do %>
|
3
3
|
<nav class="-mb-3 mt-4">
|
4
|
-
<ul class="inline-flex w-auto rounded-md bg-white">
|
4
|
+
<ul class="inline-flex flex-wrap w-auto rounded-md bg-white">
|
5
5
|
<% @navigations.each do |navigation| %>
|
6
6
|
<%= render Spina::UserInterface::TabLinkComponent.new(spina.edit_admin_navigation_path(navigation), active: @navigation == navigation) do %>
|
7
7
|
<%= heroicon('menu-alt-2', style: :solid, class: 'w-3 h-3 mr-1') %>
|
@@ -4,7 +4,7 @@
|
|
4
4
|
<% if @page.draft? %>
|
5
5
|
<span class="text-gray-400 ml-2 text-sm">(<%= Spina::Page.human_attribute_name(:draft) %>)</span>
|
6
6
|
<% end %>
|
7
|
-
<%= link_to @page.materialized_path, class: 'px-3 py-2 flex items-center text-gray-400 hover:text-gray-700', target: :blank, data: {turbo: false} do %>
|
7
|
+
<%= link_to @page.materialized_path(locale: @locale), class: 'px-3 py-2 flex items-center text-gray-400 hover:text-gray-700', target: :blank, data: {turbo: false} do %>
|
8
8
|
<%= heroicon("external-link", style: :solid, class: "w-4 h-4") %>
|
9
9
|
<% end %>
|
10
10
|
<% end %>
|
@@ -33,4 +33,4 @@
|
|
33
33
|
<% end %>
|
34
34
|
<% end %>
|
35
35
|
</div>
|
36
|
-
</div>
|
36
|
+
</div>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
<% header.navigation do %>
|
16
16
|
<nav class="-mb-1 md:-mb-3 mt-4">
|
17
|
-
<ul class="inline-flex w-auto rounded-md bg-white">
|
17
|
+
<ul class="inline-flex flex-wrap w-auto rounded-md bg-white">
|
18
18
|
<%= render Spina::UserInterface::TabLinkComponent.new(spina.admin_pages_path, active: @resource.nil?) do %>
|
19
19
|
<%= heroicon('collection', style: :solid, class: "h-4 w-4 mr-1 -ml-1 opacity-75") %>
|
20
20
|
<%=t 'spina.website.main' %>
|
@@ -1,8 +1,9 @@
|
|
1
1
|
<div class="mt-6" data-controller="attachment-picker">
|
2
2
|
<label for="price" class="block text-sm leading-5 font-medium text-gray-700"><%= f.object.title %></label>
|
3
|
+
<div class="text-gray-400 text-sm"><%= f.object.hint %></div>
|
3
4
|
|
4
5
|
<%= f.hidden_field :signed_blob_id, data: {attachment_picker_target: 'signedBlobId'} %>
|
5
6
|
<%= f.hidden_field :filename, data: {attachment_picker_target: 'filename'} %>
|
6
7
|
|
7
|
-
<%= f.select :attachment_id, Spina::Attachment.sorted.map{|attachment| [attachment.file&.filename, attachment.id, data: {signed_blob_id: attachment.file&.blob&.signed_id, filename: attachment.file&.filename}]}, {include_blank: t("spina.attachments.choose_attachment")}, {class: "form-select", data: {action: "attachment-picker#pick"}} %>
|
8
|
+
<%= f.select :attachment_id, Spina::Attachment.sorted.map{|attachment| [attachment.file&.filename, attachment.id, data: {signed_blob_id: attachment.file&.blob&.signed_id, filename: attachment.file&.filename}]}, {include_blank: t("spina.attachments.choose_attachment")}, {class: "form-select mt-1", data: {action: "attachment-picker#pick"}} %>
|
8
9
|
</div>
|
@@ -10,6 +10,7 @@
|
|
10
10
|
<label class="block text-sm leading-5 font-medium text-gray-700">
|
11
11
|
<%= f.object.title %>
|
12
12
|
</label>
|
13
|
+
<div class="text-gray-400 text-sm"><%= f.object.hint %></div>
|
13
14
|
|
14
15
|
<div class="flex items-start mt-1">
|
15
16
|
<div class="flex items-center" data-image-collection-target="collection">
|