spina 2.3.5 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of spina might be problematic. Click here for more details.

Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -3
  3. data/app/assets/javascripts/spina/application.js +1 -1
  4. data/app/assets/javascripts/spina/controllers/application.js +11 -0
  5. data/app/assets/javascripts/spina/controllers/embed_controller.js +16 -0
  6. data/app/assets/javascripts/spina/controllers/embed_tag_controller.js +16 -0
  7. data/app/assets/javascripts/spina/controllers/index.js +5 -0
  8. data/app/assets/javascripts/spina/controllers/trix_controller.js +12 -2
  9. data/app/assets/stylesheets/spina/_fonts.css.erb +114 -0
  10. data/app/assets/stylesheets/spina/_tailwind.css +18 -5
  11. data/app/assets/stylesheets/spina/application.css +6 -0
  12. data/app/assets/stylesheets/spina/tailwind/custom.css +13 -5
  13. data/app/components/spina/forms/trix_toolbar_component.html.erb +26 -15
  14. data/app/components/spina/media_picker/image_component.html.erb +1 -1
  15. data/app/components/spina/pages/new_page_button_component.html.erb +32 -0
  16. data/app/components/spina/pages/new_page_button_component.rb +19 -0
  17. data/app/controllers/concerns/spina/frontend.rb +1 -1
  18. data/app/controllers/spina/admin/embeds_controller.rb +36 -0
  19. data/app/controllers/spina/admin/pages_controller.rb +1 -2
  20. data/app/controllers/spina/admin/password_resets_controller.rb +2 -4
  21. data/app/helpers/spina/admin/icons_helper.rb +2 -2
  22. data/app/helpers/spina/images_helper.rb +1 -1
  23. data/app/helpers/spina/spina_helper.rb +3 -2
  24. data/app/mailers/spina/application_mailer.rb +7 -0
  25. data/app/mailers/spina/user_mailer.rb +6 -14
  26. data/app/models/spina/embeds/base.rb +7 -0
  27. data/app/models/spina/embeds/button.rb +13 -0
  28. data/app/models/spina/embeds/vimeo.rb +39 -0
  29. data/app/models/spina/embeds/youtube.rb +39 -0
  30. data/app/models/spina/page.rb +10 -3
  31. data/app/models/spina/user.rb +6 -0
  32. data/app/presenters/spina/content_presenter.rb +1 -1
  33. data/app/presenters/spina/rich_text_presenter.rb +45 -0
  34. data/app/views/layouts/spina/admin/application.html.erb +1 -1
  35. data/app/views/layouts/spina/mail.html.erb +476 -1
  36. data/app/views/spina/admin/embeds/new.html.erb +47 -0
  37. data/app/views/spina/admin/pages/edit_template.html.erb +1 -1
  38. data/app/views/spina/admin/pages/index.html.erb +1 -21
  39. data/app/views/spina/admin/shared/_flash.html.erb +2 -2
  40. data/app/views/spina/embeds/buttons/_button.html.erb +3 -0
  41. data/app/views/spina/embeds/buttons/_button_fields.html.erb +14 -0
  42. data/app/views/spina/embeds/buttons/_trix_button.html.erb +3 -0
  43. data/app/views/spina/embeds/vimeos/_thumbnail.html.erb +6 -0
  44. data/app/views/spina/embeds/vimeos/_vimeo.html.erb +1 -0
  45. data/app/views/spina/embeds/vimeos/_vimeo_fields.html.erb +9 -0
  46. data/app/views/spina/embeds/youtubes/_thumbnail.html.erb +6 -0
  47. data/app/views/spina/embeds/youtubes/_youtube.html.erb +1 -0
  48. data/app/views/spina/embeds/youtubes/_youtube_fields.html.erb +9 -0
  49. data/app/views/spina/user_mailer/forgot_password.html.erb +57 -1
  50. data/app/views/spina/user_mailer/forgot_password.text.erb +9 -0
  51. data/config/initializers/importmap.rb +12 -0
  52. data/config/locales/en.yml +30 -0
  53. data/config/locales/nl.yml +1 -0
  54. data/config/routes.rb +5 -2
  55. data/lib/generators/spina/embed_generator.rb +18 -0
  56. data/lib/generators/spina/install_generator.rb +36 -14
  57. data/lib/generators/spina/templates/app/models/spina/embeds/embed.rb.tt +18 -0
  58. data/lib/generators/spina/templates/app/views/default/pages/homepage.html.erb +1 -1
  59. data/lib/generators/spina/templates/app/views/spina/embeds/_fields.html.erb +13 -0
  60. data/lib/generators/spina/templates/app/views/spina/embeds/_partial.html.erb +2 -0
  61. data/lib/generators/spina/templates/config/initializers/spina.rb +7 -0
  62. data/lib/generators/spina/templates/config/initializers/themes/default.rb +3 -0
  63. data/lib/generators/spina/templates/config/initializers/themes/demo.rb +4 -1
  64. data/lib/spina/embeddable.rb +48 -0
  65. data/lib/spina/embeds/trix_conversion.rb +41 -0
  66. data/lib/spina/embeds.rb +11 -0
  67. data/lib/spina/engine.rb +7 -21
  68. data/lib/spina/part.rb +10 -2
  69. data/lib/spina/railtie.rb +10 -0
  70. data/lib/spina/theme.rb +16 -3
  71. data/lib/spina/theme_reloader.rb +20 -0
  72. data/lib/spina/version.rb +1 -1
  73. data/lib/spina.rb +11 -0
  74. data/lib/tasks/spina_tasks.rake +19 -2
  75. metadata +66 -34
  76. data/app/assets/stylesheets/spina/_fonts.scss +0 -114
  77. data/app/assets/stylesheets/spina/application.sass +0 -3
  78. data/app/views/spina/user_mailer/forgot_password.txt.erb +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d723b3ba40909c360cc1b6ddcf6f78064278f08911415db9852b38c53efa4064
4
- data.tar.gz: 8057a9dab62bb7806f041ec07ecd48c4e91e3f63683c4192df625785a49eecfc
3
+ metadata.gz: e70d3196cc16222f90924b746b202242787e03daf752c1b3cef304b61b4aef4d
4
+ data.tar.gz: 2b2c875191d2b8e55ed189b844385480fba298433915e6b11bde1505ecd9edb3
5
5
  SHA512:
6
- metadata.gz: 1e41c59c9ce94f638f51ae647ce1d92bde5c930123ada0ca766e02c79725ccb7bbc3b8a667508e813f386770762b16608b94132521faba55a3d2aaaa30133fb8
7
- data.tar.gz: 6391ea4c0b0be38de86fa46cee4057302be8be655044d33784bcdd7e5774221004ae1f1d8e9570e8e05f673fbbbff8ed586b8f47923119f9f6405586a691a8e3
6
+ metadata.gz: fd5b9fcd7feb30583c09ad0972b72b521e36749eaa549ee62eed545c913ebe184b8b9521656d46a589609aa779c04c4b2464c3301b1427b8bf506a79727238d2
7
+ data.tar.gz: ccf2e511b18083b14bdb330d9470fe2f2c2030956d9a77f533d73bf047e25095ee06ea205363dbdd3337af4a73c0146f4f400e57057fe89500cd543c1d5bc404
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![Ruby](https://github.com/SpinaCMS/Spina/actions/workflows/ruby.yml/badge.svg)](https://github.com/SpinaCMS/Spina/actions/workflows/ruby.yml)
6
6
  [![Code Climate](https://codeclimate.com/github/SpinaCMS/Spina/badges/gpa.svg)](https://codeclimate.com/github/SpinaCMS/Spina)
7
7
  [![Test Coverage](https://codeclimate.com/github/SpinaCMS/Spina/badges/coverage.svg)](https://codeclimate.com/github/SpinaCMS/Spina/coverage)
8
- [![Slack](https://slack-spinacms.herokuapp.com/badge.svg)](https://slack-spinacms.herokuapp.com)
8
+ [![Discord](https://img.shields.io/discord/811903407525986304?label=Discord)](https://discord.gg/bv5Mu4XYcN)
9
9
 
10
10
  ## Getting Started
11
11
  [Read the guide](https://www.spinacms.com/docs) to learn more about how to use Spina. If you just want to get started, create a new Ruby on Rails app and follow these instructions:
@@ -18,12 +18,17 @@ gem 'spina'
18
18
 
19
19
  Run the installer to start the setup process:
20
20
 
21
- rails g spina:install
21
+ rails g spina:install [--silent] [--first-deploy]
22
22
 
23
- The installer will help you create your first user.
23
+ The installer will help you create your first user interactively, unless you choose the optional `--silent` flag : in this case, defaults will apply.
24
24
 
25
25
  Then start `rails s` and access Spina at `/admin`.
26
26
 
27
+ ## Browser support
28
+ Spina's admin UI requires Chrome/Edge 89+, or any other browser with basic ESM support (Safari/Firefox). This is due to a recent browser feature called `import maps` and will be used in Rails 7 as the default way to deploy javascript assets.
29
+
30
+ Browser support for websites built with Spina is entirely up to the developer. Spina doesn't force you to build your frontend a certain way.
31
+
27
32
  ## Contributing
28
33
 
29
34
  Check our [Contributing Guide](CONTRIBUTING.md) for instructions on how to help the project.
@@ -63,6 +68,8 @@ Icons were designed by [@steveschoger](https://twitter.com/steveschoger) - [Hero
63
68
 
64
69
  HotKeys support via [Hotkeys.js](https://wangchujiang.com/hotkeys/)
65
70
 
71
+ Email templates based on Wildbit's [Postmark Templates](https://github.com/wildbit/postmark-templates)
72
+
66
73
  The font used in Spina's admin panel is called Metropolis and was created by Chris Simpson [Metropolis](https://github.com/chrismsimpson/Metropolis)
67
74
 
68
75
  Copyright (c) 2015, Chris Simpson <chris@victoryonemedia.com>.
@@ -1,3 +1,3 @@
1
1
  import "@hotwired/turbo-rails"
2
- import "@hotwired/stimulus-autoloader"
3
2
  import "libraries/trix"
3
+ import "controllers"
@@ -0,0 +1,11 @@
1
+ import { Application } from "@hotwired/stimulus"
2
+
3
+ const application = Application.start()
4
+
5
+ // Configure Stimulus
6
+ application.warnings = true
7
+ application.debug = false
8
+ window.Stimulus = application
9
+
10
+ export { application }
11
+
@@ -0,0 +1,16 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ static get targets() {
5
+ return [ "html" ]
6
+ }
7
+
8
+ insertEmbeddable(event) {
9
+ this.trixEditor.insertEmbeddable(event.detail.html)
10
+ }
11
+
12
+ get trixEditor() {
13
+ return document.getElementById(this.element.dataset.trixTarget).trix
14
+ }
15
+
16
+ }
@@ -0,0 +1,16 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+
5
+ connect() {
6
+ let event = new CustomEvent("embed-tag:embedded", this.eventOptions)
7
+ this.element.dispatchEvent(event)
8
+ }
9
+
10
+ get eventOptions() {
11
+ let clone = this.element.cloneNode(true)
12
+ clone.removeAttribute("data-controller")
13
+ return {bubbles: true, detail: {html: clone.outerHTML}}
14
+ }
15
+
16
+ }
@@ -0,0 +1,5 @@
1
+ import { application } from "controllers/application"
2
+
3
+ // Eager load all Stimulus controllers
4
+ import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
5
+ eagerLoadControllersFrom("controllers", application)
@@ -5,11 +5,13 @@ export default class extends Controller {
5
5
  return [ "editor", "imageFields", "altField" ]
6
6
  }
7
7
 
8
- connect() {
8
+ connect() {
9
+ this.element[this.identifier] = this
10
+
9
11
  this.editorTarget.addEventListener("trix-selection-change", function(event) {
10
12
  if (this.mutableImageAttachment) {
11
13
  this.imageFieldsTarget.classList.remove("hidden")
12
- let position = this.mutableImageAttachment.querySelector("img").offsetTop + this.mutableImageAttachment.querySelector("img").offsetHeight - 16
14
+ let position = this.mutableImageAttachment.querySelector("img").offsetTop + this.mutableImageAttachment.querySelector("img").offsetHeight
13
15
  this.imageFieldsTarget.style.top = `${position}px`
14
16
  this.altFieldTarget.value = this.currentAltText
15
17
  } else {
@@ -18,6 +20,14 @@ export default class extends Controller {
18
20
  }.bind(this))
19
21
  }
20
22
 
23
+ insertEmbeddable(html) {
24
+ let embeddable = new Trix.Attachment({
25
+ content: html,
26
+ contentType: "application/vnd+spina.embed+html"})
27
+
28
+ this.editor.insertAttachment(embeddable)
29
+ }
30
+
21
31
  preventSubmission(event) {
22
32
  if (event.key === 'Enter') event.preventDefault() // Prevent form submit from alt text fields
23
33
  }
@@ -0,0 +1,114 @@
1
+ @font-face {
2
+ font-family: "Metropolis";
3
+ font-weight: 400;
4
+ src: url('<%= asset_path "spina/Metropolis-Regular.woff2" %>') format("woff2");
5
+ }
6
+
7
+ @font-face {
8
+ font-family: "Metropolis";
9
+ font-style: italic;
10
+ src: url('<%= asset_path "spina/Metropolis-RegularItalic.woff2" %>') format("woff2");
11
+ }
12
+
13
+ @font-face {
14
+ font-family: "Metropolis";
15
+ font-weight: 100;
16
+ src: url('<%= asset_path "spina/Metropolis-Thin.woff2" %>') format("woff2");
17
+ }
18
+
19
+ @font-face {
20
+ font-family: "Metropolis";
21
+ font-weight: 100;
22
+ font-style: italic;
23
+ src: url('<%= asset_path "spina/Metropolis-ThinItalic.woff2" %>') format("woff2");
24
+ }
25
+
26
+ @font-face {
27
+ font-family: "Metropolis";
28
+ font-weight: 200;
29
+ src: url('<%= asset_path "spina/Metropolis-ExtraLight.woff2" %>') format("woff2");
30
+ }
31
+
32
+ @font-face {
33
+ font-family: "Metropolis";
34
+ font-weight: 200;
35
+ src: url('<%= asset_path "spina/Metropolis-ExtraLightItalic.woff2" %>') format("woff2");
36
+ }
37
+
38
+ @font-face {
39
+ font-family: "Metropolis";
40
+ font-weight: 300;
41
+ src: url('<%= asset_path "spina/Metropolis-Light.woff2" %>') format("woff2");
42
+ }
43
+
44
+ @font-face {
45
+ font-family: "Metropolis";
46
+ font-weight: 300;
47
+ font-style: italic;
48
+ src: url('<%= asset_path "spina/Metropolis-LightItalic.woff2" %>') format("woff2");
49
+ }
50
+
51
+ @font-face {
52
+ font-family: "Metropolis";
53
+ font-weight: 500;
54
+ src: url('<%= asset_path "spina/Metropolis-Medium.woff2" %>') format("woff2");
55
+ }
56
+
57
+ @font-face {
58
+ font-family: "Metropolis";
59
+ font-weight: 500;
60
+ font-style: italic;
61
+ src: url('<%= asset_path "spina/Metropolis-MediumItalic.woff2" %>') format("woff2");
62
+ }
63
+
64
+ @font-face {
65
+ font-family: "Metropolis";
66
+ font-weight: 600;
67
+ src: url('<%= asset_path "spina/Metropolis-SemiBold.woff2" %>') format("woff2");
68
+ }
69
+
70
+ @font-face {
71
+ font-family: "Metropolis";
72
+ font-weight: 600;
73
+ font-style: italic;
74
+ src: url('<%= asset_path "spina/Metropolis-SemiBoldItalic.woff2" %>') format("woff2");
75
+ }
76
+
77
+ @font-face {
78
+ font-family: "Metropolis";
79
+ font-weight: 700;
80
+ src: url('<%= asset_path "spina/Metropolis-Bold.woff2" %>') format("woff2");
81
+ }
82
+
83
+ @font-face {
84
+ font-family: "Metropolis";
85
+ font-weight: 700;
86
+ font-style: italic;
87
+ src: url('<%= asset_path "spina/Metropolis-BoldItalic.woff2" %>') format("woff2");
88
+ }
89
+
90
+ @font-face {
91
+ font-family: "Metropolis";
92
+ font-weight: 800;
93
+ src: url('<%= asset_path "spina/Metropolis-ExtraBold.woff2" %>') format("woff2");
94
+ }
95
+
96
+ @font-face {
97
+ font-family: "Metropolis";
98
+ font-weight: 800;
99
+ font-style: italic;
100
+ src: url('<%= asset_path "spina/Metropolis-ExtraBoldItalic.woff2" %>') format("woff2");
101
+ }
102
+
103
+ @font-face {
104
+ font-family: "Metropolis";
105
+ font-weight: 900;
106
+ src: url('<%= asset_path "spina/Metropolis-Black.woff2" %>') format("woff2");
107
+ }
108
+
109
+ @font-face {
110
+ font-family: "Metropolis";
111
+ font-weight: 900;
112
+ font-style: italic;
113
+ src: url('<%= asset_path "spina/Metropolis-BlackItalic.woff2" %>') format("woff2");
114
+ }
@@ -2342,18 +2342,20 @@ trix-editor {
2342
2342
  user-select: none
2343
2343
  }
2344
2344
  figure.attachment {
2345
+ margin: 0px;
2346
+ display: inline-block
2347
+ }
2348
+ figure.attachment[data-trix-content-type="Spina::Image"] {
2345
2349
  max-height: 150px;
2346
2350
  max-width: 200px;
2347
- margin: 0px;
2348
- display: inline-block;
2349
2351
  }
2350
- figure.attachment img {
2352
+ figure.attachment[data-trix-content-type="Spina::Image"] img {
2351
2353
  margin: 0px;
2352
2354
  border-radius: 0.375rem;
2353
2355
  -o-object-fit: contain;
2354
2356
  object-fit: contain;
2355
2357
  }
2356
- figure.attachment [data-label]:after {
2358
+ figure.attachment[data-trix-content-type="Spina::Image"] [data-label]:after {
2357
2359
  content: attr(data-label);
2358
2360
  margin-top: 0.25rem;
2359
2361
  display: flex;
@@ -2367,7 +2369,7 @@ trix-editor {
2367
2369
  --tw-text-opacity: 1;
2368
2370
  color: rgba(107, 114, 128, var(--tw-text-opacity));
2369
2371
  }
2370
- figure[data-trix-mutable].attachment img {
2372
+ figure[data-trix-mutable].attachment[data-trix-content-type="Spina::Image"] img {
2371
2373
  --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
2372
2374
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
2373
2375
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
@@ -2376,6 +2378,17 @@ trix-editor {
2376
2378
  --tw-ring-opacity: 1;
2377
2379
  --tw-ring-color: rgba(121, 122, 184, var(--tw-ring-opacity))
2378
2380
  }
2381
+ figure[data-trix-mutable][data-trix-content-type="application/vnd+spina.embed+html"].attachment > spina-embed {
2382
+ display: block;
2383
+ border-radius: 0.375rem;
2384
+ --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
2385
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
2386
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
2387
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
2388
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
2389
+ --tw-ring-opacity: 1;
2390
+ --tw-ring-color: rgba(121, 122, 184, var(--tw-ring-opacity));
2391
+ }
2379
2392
  figure .attachment__caption {
2380
2393
  display: none
2381
2394
  }
@@ -0,0 +1,6 @@
1
+ /*
2
+ *= require spina/_animate
3
+ *= require spina/_fonts
4
+ *= require spina/_tailwind
5
+ *= require_self
6
+ */
@@ -154,25 +154,33 @@
154
154
  [data-trix-mutable]:not(.attachment__captain-editor) {
155
155
  @apply select-none
156
156
  }
157
-
157
+
158
158
  figure.attachment {
159
+ @apply m-0 inline-block
160
+ }
161
+
162
+ figure.attachment[data-trix-content-type="Spina::Image"] {
159
163
  max-height: 150px;
160
164
  max-width: 200px;
161
- @apply m-0 inline-block;
162
165
  }
163
166
 
164
- figure.attachment img {
167
+ figure.attachment[data-trix-content-type="Spina::Image"] img {
165
168
  @apply m-0 rounded-md object-contain;
166
169
  }
167
170
 
168
- figure.attachment [data-label]:after {
171
+ figure.attachment[data-trix-content-type="Spina::Image"] [data-label]:after {
169
172
  content: attr(data-label);
170
173
  @apply italic text-gray-500 h-8 flex items-center px-2 mt-1 text-sm;
171
174
  }
172
175
 
173
- figure[data-trix-mutable].attachment img {
176
+ figure[data-trix-mutable].attachment[data-trix-content-type="Spina::Image"] img {
174
177
  @apply shadow-lg ring ring-spina-light
175
178
  }
179
+
180
+ figure[data-trix-mutable][data-trix-content-type="application/vnd+spina.embed+html"].attachment > spina-embed {
181
+ @apply block;
182
+ @apply shadow-lg ring ring-spina-light rounded-md;
183
+ }
176
184
 
177
185
  figure .attachment__caption {
178
186
  @apply hidden
@@ -1,57 +1,68 @@
1
1
  <div class="relative sticky 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
- <button type="button" class="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">
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">
5
5
  <svg class="w-4 h-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M333.49 238a122 122 0 0 0 27-65.21C367.87 96.49 308 32 233.42 32H34a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h31.87v288H34a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h209.32c70.8 0 134.14-51.75 141-122.4 4.74-48.45-16.39-92.06-50.83-119.6zM145.66 112h87.76a48 48 0 0 1 0 96h-87.76zm87.76 288h-87.76V288h87.76a56 56 0 0 1 0 112z"/></svg>
6
6
  </button>
7
- <button type="button" class="text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="italic" data-trix-key="i" title="${Trix.config.lang.italic}" tabindex="-1">
7
+ <button type="button" class="hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="italic" data-trix-key="i" title="${Trix.config.lang.italic}" tabindex="-1">
8
8
  <svg class="w-4 h-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M320 48v32a16 16 0 0 1-16 16h-62.76l-80 320H208a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h62.76l80-320H112a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h192a16 16 0 0 1 16 16z"/></svg>
9
9
  </button>
10
- <button type="button" class="text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="href" data-trix-action="link" data-trix-key="k" title="<%=t 'spina.wysiwyg.link' %>" tabindex="-1" data-action="reveal#toggle">
10
+ <button type="button" class="hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="href" data-trix-action="link" data-trix-key="k" title="<%=t 'spina.wysiwyg.link' %>" tabindex="-1" data-action="reveal#toggle">
11
11
  <svg class="w-4 h-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M326.612 185.391c59.747 59.809 58.927 155.698.36 214.59-.11.12-.24.25-.36.37l-67.2 67.2c-59.27 59.27-155.699 59.262-214.96 0-59.27-59.26-59.27-155.7 0-214.96l37.106-37.106c9.84-9.84 26.786-3.3 27.294 10.606.648 17.722 3.826 35.527 9.69 52.721 1.986 5.822.567 12.262-3.783 16.612l-13.087 13.087c-28.026 28.026-28.905 73.66-1.155 101.96 28.024 28.579 74.086 28.749 102.325.51l67.2-67.19c28.191-28.191 28.073-73.757 0-101.83-3.701-3.694-7.429-6.564-10.341-8.569a16.037 16.037 0 0 1-6.947-12.606c-.396-10.567 3.348-21.456 11.698-29.806l21.054-21.055c5.521-5.521 14.182-6.199 20.584-1.731a152.482 152.482 0 0 1 20.522 17.197zM467.547 44.449c-59.261-59.262-155.69-59.27-214.96 0l-67.2 67.2c-.12.12-.25.25-.36.37-58.566 58.892-59.387 154.781.36 214.59a152.454 152.454 0 0 0 20.521 17.196c6.402 4.468 15.064 3.789 20.584-1.731l21.054-21.055c8.35-8.35 12.094-19.239 11.698-29.806a16.037 16.037 0 0 0-6.947-12.606c-2.912-2.005-6.64-4.875-10.341-8.569-28.073-28.073-28.191-73.639 0-101.83l67.2-67.19c28.239-28.239 74.3-28.069 102.325.51 27.75 28.3 26.872 73.934-1.155 101.96l-13.087 13.087c-4.35 4.35-5.769 10.79-3.783 16.612 5.864 17.194 9.042 34.999 9.69 52.721.509 13.906 17.454 20.446 27.294 10.606l37.106-37.106c59.271-59.259 59.271-155.699.001-214.959z"/></svg>
12
12
  </button>
13
13
  </div>
14
14
 
15
15
  <div class="flex items-center bg-gray-200 rounded overflow-hidden mr-3 mb-3" data-trix-button-group="block-tools">
16
- <button type="button" class="text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="heading1" title="${Trix.config.lang.heading1}" tabindex="-1">
16
+ <button type="button" class="hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="heading1" title="${Trix.config.lang.heading1}" tabindex="-1">
17
17
  <svg class="w-4 h-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M304 96h-98.94A13.06 13.06 0 0 0 192 109.06v21.88A13.06 13.06 0 0 0 205.06 144H232v88H88v-88h26.94A13.06 13.06 0 0 0 128 130.94V112a16 16 0 0 0-16-16H16a16 16 0 0 0-16 16v18.94A13.06 13.06 0 0 0 13.06 144H40v224H13.06A13.06 13.06 0 0 0 0 381.06V400a16 16 0 0 0 16 16h98.94A13.06 13.06 0 0 0 128 402.94v-21.88A13.06 13.06 0 0 0 114.94 368H88v-88h144v88h-26.94A13.06 13.06 0 0 0 192 381.06V400a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-18.94A13.06 13.06 0 0 0 306.94 368H280V144h26.94A13.06 13.06 0 0 0 320 130.94V112a16 16 0 0 0-16-16zm256 272h-56V120a24 24 0 0 0-24-24h-24a24 24 0 0 0-21.44 13.26l-24 48A24 24 0 0 0 432 192h24v176h-56a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h160a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z"/></svg>
18
18
  </button>
19
- <button type="button" class="text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="heading2" title="${Trix.config.lang.heading2}" tabindex="-1">
19
+ <button type="button" class="hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="heading2" title="${Trix.config.lang.heading2}" tabindex="-1">
20
20
  <svg class="w-4 h-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M304 96h-98.94A13.06 13.06 0 0 0 192 109.06v21.88A13.06 13.06 0 0 0 205.06 144H232v88H88v-88h26.94A13.06 13.06 0 0 0 128 130.94V112a16 16 0 0 0-16-16H16a16 16 0 0 0-16 16v18.94A13.06 13.06 0 0 0 13.06 144H40v224H13.06A13.06 13.06 0 0 0 0 381.06V400a16 16 0 0 0 16 16h98.94A13.06 13.06 0 0 0 128 402.94v-21.88A13.06 13.06 0 0 0 114.94 368H88v-88h144v88h-26.94A13.06 13.06 0 0 0 192 381.06V400a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-18.94A13.06 13.06 0 0 0 306.94 368H280V144h26.94A13.06 13.06 0 0 0 320 130.94V112a16 16 0 0 0-16-16zm244.14 272.13H410.82c8.52-60.35 146-79.28 146-179.31C556.8 134.17 515 96 455.05 96a114.71 114.71 0 0 0-97.92 55.05 11.81 11.81 0 0 0 3.58 15.95L382 181.23a11.89 11.89 0 0 0 16.27-3c13-18.23 31.58-31.35 53.72-31.35 29.57 0 49.43 18.08 49.43 45 0 67-149.45 84-149.45 195.49a137.14 137.14 0 0 0 1.39 18.42 12.18 12.18 0 0 0 11.8 10.21h183A11.85 11.85 0 0 0 560 404.18V380a11.85 11.85 0 0 0-11.86-11.87z"/></svg>
21
21
  </button>
22
- <button type="button" class="text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="heading3" title="${Trix.config.lang.heading3}" tabindex="-1">
22
+ <button type="button" class="hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="heading3" title="${Trix.config.lang.heading3}" tabindex="-1">
23
23
  <svg class="w-4 h-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M480.07 219.78l75.39-85.88a11.82 11.82 0 0 0 2.93-7.76v-18.32A11.89 11.89 0 0 0 546.44 96H379.87a11.88 11.88 0 0 0-11.94 11.82V132a11.88 11.88 0 0 0 11.94 11.83s102.44-.11 106-.25c-2.77 2.88-74.12 85.58-74.12 85.58a11.67 11.67 0 0 0-1.86 12.38l6.71 15.3a12.94 12.94 0 0 0 10.93 7.16h17.08c48.61 0 65.85 27.23 65.85 50.56 0 28.57-24.58 50.13-57.17 50.13-24 0-46.88-10.46-65.29-26.89a12 12 0 0 0-17.76 1.81l-16 22a11.73 11.73 0 0 0 1.4 15.41c24.6 23.34 60.62 39 99.38 39 64.2 0 109.86-46.22 109.86-103.17.01-51.1-36.73-84.17-84.81-93.07zM304 96h-98.94A13.06 13.06 0 0 0 192 109.06v21.88A13.06 13.06 0 0 0 205.06 144H232v88H88v-88h26.94A13.06 13.06 0 0 0 128 130.94V112a16 16 0 0 0-16-16H16a16 16 0 0 0-16 16v18.94A13.06 13.06 0 0 0 13.06 144H40v224H13.06A13.06 13.06 0 0 0 0 381.06V400a16 16 0 0 0 16 16h98.94A13.06 13.06 0 0 0 128 402.94v-21.88A13.06 13.06 0 0 0 114.94 368H88v-88h144v88h-26.94A13.06 13.06 0 0 0 192 381.06V400a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-18.94A13.06 13.06 0 0 0 306.94 368H280V144h26.94A13.06 13.06 0 0 0 320 130.94V112a16 16 0 0 0-16-16z"/></svg>
24
24
  </button>
25
- <button type="button" class="text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="heading4" title="${Trix.config.lang.heading4}" tabindex="-1">
25
+ <button type="button" class="hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="heading4" title="${Trix.config.lang.heading4}" tabindex="-1">
26
26
  <svg class="w-4 h-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M304 96h-98.94A13.06 13.06 0 0 0 192 109.06v21.88A13.06 13.06 0 0 0 205.06 144H232v88H88v-88h26.94A13.06 13.06 0 0 0 128 130.94V112a16 16 0 0 0-16-16H16a16 16 0 0 0-16 16v18.94A13.06 13.06 0 0 0 13.06 144H40v224H13.06A13.06 13.06 0 0 0 0 381.06V400a16 16 0 0 0 16 16h98.94A13.06 13.06 0 0 0 128 402.94v-21.88A13.06 13.06 0 0 0 114.94 368H88v-88h144v88h-26.94A13.06 13.06 0 0 0 192 381.06V400a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-18.94A13.06 13.06 0 0 0 306.94 368H280V144h26.94A13.06 13.06 0 0 0 320 130.94V112a16 16 0 0 0-16-16zm256 136h-16V112a16 16 0 0 0-16-16h-16a16 16 0 0 0-16 16v120h-96V112a16 16 0 0 0-16-16h-16a16 16 0 0 0-16 16v136a32 32 0 0 0 32 32h112v120a16 16 0 0 0 16 16h16a16 16 0 0 0 16-16V280h16a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z"/></svg>
27
27
  </button>
28
28
  </div>
29
29
 
30
- <div class="flex items-center bg-gray-200 rounded overflow-hidden mr-3 mb-3">
31
- <%= link_to helpers.spina.admin_media_picker_path(target: "insert_#{@trix_id}"), class: "text-gray-700 w-9 h-9 flex items-center justify-center", data: {turbo_frame: "modal"} do %>
30
+ <div class="flex items-center bg-gray-200 rounded overflow-hidden mr-3 mb-3">
31
+
32
+ <%= link_to helpers.spina.admin_media_picker_path(target: "insert_#{@trix_id}"), class: "hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center", data: {turbo_frame: "modal"} do %>
32
33
  <svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
33
34
  <path fill-rule="evenodd" d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm12 12H4l4-8 3 6 2-4 3 6z" clip-rule="evenodd" />
34
35
  </svg>
35
36
  <% end %>
36
37
 
37
- <button type="button" class="text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="quote" title="${Trix.config.lang.quote}" tabindex="-1">
38
+ <% if helpers.current_theme.embeds.any? %>
39
+ <%= link_to helpers.spina.new_admin_embed_path(target: "insert_#{@trix_id}"), class: "hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center", data: {turbo_frame: "modal"} do %>
40
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
41
+ <path d="M5 3a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2V5a2 2 0 00-2-2H5zM5 11a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2v-2a2 2 0 00-2-2H5zM11 5a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V5zM14 11a1 1 0 011 1v1h1a1 1 0 110 2h-1v1a1 1 0 11-2 0v-1h-1a1 1 0 110-2h1v-1a1 1 0 011-1z" />
42
+ </svg>
43
+ <% end %>
44
+ <% end %>
45
+ </div>
46
+
47
+ <div class="flex items-center bg-gray-200 rounded overflow-hidden mr-3 mb-3">
48
+ <button type="button" class="hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="quote" title="${Trix.config.lang.quote}" tabindex="-1">
38
49
  <svg class="w-4 h-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M464 32H336c-26.5 0-48 21.5-48 48v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48zm-288 0H48C21.5 32 0 53.5 0 80v128c0 26.5 21.5 48 48 48h80v64c0 35.3-28.7 64-64 64h-8c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h8c88.4 0 160-71.6 160-160V80c0-26.5-21.5-48-48-48z"/></svg>
39
50
  </button>
40
- <button type="button" class="text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="code" title="${Trix.config.lang.code}" tabindex="-1">
51
+ <button type="button" class="hover:bg-gray-300 text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="code" title="${Trix.config.lang.code}" tabindex="-1">
41
52
  <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
42
53
  <path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd" />
43
54
  </svg>
44
55
  </button>
45
- <button type="button" class="trix-button trix-button--icon trix-button--icon-bullet-list text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="bullet" title="${Trix.config.lang.bullets}" tabindex="-1">
56
+ <button type="button" class="hover:bg-gray-300 trix-button trix-button--icon trix-button--icon-bullet-list text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="bullet" title="${Trix.config.lang.bullets}" tabindex="-1">
46
57
  <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 512 512"><path d="M48 368a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0-160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0-160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm448 24H176a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V88a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z"/></svg>
47
58
  </button>
48
- <button type="button" class="trix-button trix-button--icon trix-button--icon-number-list text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="number" title="${Trix.config.lang.numbers}" tabindex="-1">
59
+ <button type="button" class="hover:bg-gray-300 trix-button trix-button--icon trix-button--icon-number-list text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-attribute="number" title="${Trix.config.lang.numbers}" tabindex="-1">
49
60
  <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 512 512"><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.84a154.82 154.82 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.3 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.73 6.13-3.2 11.72 2.62 15.94 7.71 4.69 20.39 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 392H176a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V88a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.9 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.33c3.28-10.29 48.33-18.68 48.33-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.45 18.75-4.38 5.59-3 10.84 2.79 15.37l8.58 6.88c5.61 4.56 11 2.47 16.13-2.44a13.4 13.4 0 0 1 9.45-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.1 320z"/></svg>
50
61
  </button>
51
- <button type="button" class="trix-button trix-button--icon trix-button--icon-decrease-nesting-level text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-action="decreaseNestingLevel" title="${Trix.config.lang.outdent}" tabindex="-1">
62
+ <button type="button" class="hover:bg-gray-300 trix-button trix-button--icon trix-button--icon-decrease-nesting-level text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-action="decreaseNestingLevel" title="${Trix.config.lang.outdent}" tabindex="-1">
52
63
  <svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 448 512"><path d="M100.69 363.29c10 10 27.31 2.93 27.31-11.31V160c0-14.32-17.33-21.31-27.31-11.31l-96 96a16 16 0 0 0 0 22.62zM432 424H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zm3.17-128H204.83A12.82 12.82 0 0 0 192 308.83v22.34A12.82 12.82 0 0 0 204.83 344h230.34A12.82 12.82 0 0 0 448 331.17v-22.34A12.82 12.82 0 0 0 435.17 296zM432 40H16A16 16 0 0 0 0 56v16a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V56a16 16 0 0 0-16-16zm3.17 128H204.83A12.82 12.82 0 0 0 192 180.83v22.34A12.82 12.82 0 0 0 204.83 216h230.34A12.82 12.82 0 0 0 448 203.17v-22.34A12.82 12.82 0 0 0 435.17 168z"/></svg>
53
64
  </button>
54
- <button type="button" class="trix-button trix-button--icon trix-button--icon-increase-nesting-level text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-action="increaseNestingLevel" title="${Trix.config.lang.indent}" tabindex="-1">
65
+ <button type="button" class="hover:bg-gray-300 trix-button trix-button--icon trix-button--icon-increase-nesting-level text-gray-700 w-9 h-9 flex items-center justify-center" data-trix-action="increaseNestingLevel" title="${Trix.config.lang.indent}" tabindex="-1">
55
66
  <svg class="w-4 h-4" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M432 424H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zM27.31 363.3l96-96a16 16 0 0 0 0-22.62l-96-96C17.27 138.66 0 145.78 0 160v192c0 14.31 17.33 21.3 27.31 11.3zM435.17 168H204.83A12.82 12.82 0 0 0 192 180.83v22.34A12.82 12.82 0 0 0 204.83 216h230.34A12.82 12.82 0 0 0 448 203.17v-22.34A12.82 12.82 0 0 0 435.17 168zM432 48H16A16 16 0 0 0 0 64v16a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V64a16 16 0 0 0-16-16zm3.17 248H204.83A12.82 12.82 0 0 0 192 308.83v22.34A12.82 12.82 0 0 0 204.83 344h230.34A12.82 12.82 0 0 0 448 331.17v-22.34A12.82 12.82 0 0 0 435.17 296z"/></svg>
56
67
  </button>
57
68
  </div>
@@ -2,7 +2,7 @@
2
2
  <button type="button"
3
3
  data-action="media-picker-modal#selectImage selectable#select dblclick->media-picker-modal#instantInsert"
4
4
  data-image-id="<%= @image.id %>"
5
- data-signed-blob-id="<%= @image.file.blob.signed_id %>"
5
+ data-signed-blob-id="<%= @image.file.blob&.signed_id %>"
6
6
  data-filename="<%= @image.file.filename %>"
7
7
  data-thumbnail="<%= helpers.thumbnail_url(@image) %>"
8
8
  data-embedded-url="<%= helpers.embedded_image_url(@image) %>"
@@ -0,0 +1,32 @@
1
+ <% if view_templates.many? %>
2
+
3
+ <%= render Spina::UserInterface::DropdownComponent.new do |dropdown| %>
4
+ <% dropdown.button(classes: "btn btn-primary w-full") do %>
5
+ <%= helpers.heroicon("plus", style: :solid, class: "w-7 h-7 -ml-2") %>
6
+ <%=t 'spina.pages.new' %>
7
+ <% end %>
8
+
9
+ <% dropdown.menu do %>
10
+ <% view_templates.each do |template| %>
11
+ <%= link_to helpers.spina.new_admin_page_path(view_template: template.name, resource_id: @resource&.id), class: "block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900", data: {turbo_frame: "modal", action: "reveal#hide"} do %>
12
+ <div class="font-medium text-gray-700">
13
+ <%= template.title %>
14
+
15
+ <% if template.recommended %>
16
+ <span class="text-green-500 text-xs"><%=t 'spina.pages.recommended' %></span>
17
+ <% end %>
18
+ </div>
19
+ <div class="text-gray-400"><%= template.description %></div>
20
+ <% end %>
21
+ <% end %>
22
+ <% end %>
23
+ <% end %>
24
+
25
+ <% else %>
26
+
27
+ <%= link_to helpers.spina.new_admin_page_path(view_template: view_template.name, resource_id: resource&.id), class: "btn btn-primary w-full", data: {turbo_frame: "modal"} do %>
28
+ <%= helpers.heroicon("plus", style: :solid, class: "w-7 h-7 -ml-2") %>
29
+ <%=t 'spina.pages.new' %>
30
+ <% end %>
31
+
32
+ <% end %>
@@ -0,0 +1,19 @@
1
+ module Spina::Pages
2
+ class NewPageButtonComponent < Spina::ApplicationComponent
3
+ attr_reader :view_templates, :resource
4
+
5
+ def initialize(view_templates = [], resource: nil)
6
+ @view_templates = view_templates
7
+ @resource = resource
8
+ end
9
+
10
+ def view_template
11
+ view_templates.first
12
+ end
13
+
14
+ def render?
15
+ view_templates.any?
16
+ end
17
+
18
+ end
19
+ end
@@ -53,7 +53,7 @@ module Spina
53
53
  end
54
54
 
55
55
  def spina_request_path
56
- segments = ['/', params[:locale], params[:id]].compact
56
+ segments = [Spina.mounted_at, params[:locale], params[:id]].compact
57
57
  File.join(*segments)
58
58
  end
59
59
 
@@ -0,0 +1,36 @@
1
+ module Spina
2
+ module Admin
3
+ class EmbedsController < AdminController
4
+
5
+ def new
6
+ @embeddable = (Spina::Embeds.constantize(embed_type) || embeddables.first).new
7
+ end
8
+
9
+ def create
10
+ @embeddable = Spina::Embeds.constantize(embed_type).new(embed_params)
11
+
12
+ if @embeddable.valid?
13
+ render turbo_stream: turbo_stream.update(:trix_attachment_html, @embeddable.to_trix_attachment)
14
+ else
15
+ render :new, status: :unprocessable_entity
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def embeddables
22
+ @embeddables ||= current_theme.embeddables
23
+ end
24
+ helper_method :embeddables
25
+
26
+ def embed_type
27
+ params[:embed_type]
28
+ end
29
+
30
+ def embed_params
31
+ params.require(:embeddable).permit!
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -8,10 +8,9 @@ module Spina
8
8
  def index
9
9
  add_breadcrumb I18n.t('spina.website.pages'), spina.admin_pages_path
10
10
 
11
-
12
11
  if params[:resource_id]
13
12
  @resource = Resource.find(params[:resource_id])
14
- @page_templates = Spina::Current.theme.new_page_templates(recommended: @resource.view_template)
13
+ @page_templates = Spina::Current.theme.new_page_templates(resource: @resource)
15
14
  @pages = @resource.pages.active.roots.includes(:translations)
16
15
  else
17
16
  @pages = Page.active.sorted.roots.main.includes(:translations)
@@ -11,10 +11,8 @@ module Spina
11
11
  def create
12
12
  user = User.find_by(email: params[:email])
13
13
 
14
- if user.present?
15
- user.regenerate_password_reset_token
16
- user.touch(:password_reset_sent_at)
17
- UserMailer.forgot_password(user).deliver_now
14
+ if user&.reset_passord!
15
+ UserMailer.forgot_password(user, request.user_agent).deliver_later
18
16
  redirect_to admin_login_path, flash: {success: t('spina.forgot_password.instructions_sent')}
19
17
  else
20
18
  flash.now[:alert] = t('spina.forgot_password.unknown_user')
@@ -8,7 +8,7 @@ module Spina::Admin
8
8
 
9
9
  def heroicon(name, style: :outline, **options)
10
10
  file = read_file(Spina::Engine.root.join("app/assets/icons/heroicons", style.to_s, "#{name}.svg"))
11
-
11
+ return "" if file.nil?
12
12
  doc = Nokogiri::XML(file)
13
13
  svg = doc.root
14
14
  svg[:class] = options[:class]
@@ -18,7 +18,7 @@ module Spina::Admin
18
18
  private
19
19
 
20
20
  def read_file(path)
21
- File.exist?(path) || raise(FileNotFound, "File #{path} not found")
21
+ return nil unless File.exist?(path)
22
22
  File.read(path)
23
23
  end
24
24
 
@@ -32,7 +32,7 @@ module Spina
32
32
  end
33
33
 
34
34
  def content_type(image)
35
- image.file.content_type.split("/").last
35
+ image.file.content_type&.split("/")&.last || I18n.t("spina.images.missing_image")
36
36
  end
37
37
 
38
38
  end