maglevcms 1.7.3 → 2.0.0.beta1
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.
- checksums.yaml +4 -4
- data/.yarn/install-state.gz +0 -0
- data/README.md +4 -4
- data/Rakefile +3 -1
- data/app/components/maglev/base_component.rb +6 -0
- data/app/components/maglev/block_component.rb +11 -1
- data/app/components/maglev/content/base.rb +9 -1
- data/app/components/maglev/content/link.rb +4 -0
- data/app/components/maglev/inspector.rb +18 -0
- data/app/components/maglev/page_component.rb +4 -0
- data/app/components/maglev/section_component.rb +6 -2
- data/app/controllers/concerns/maglev/fetchers_concern.rb +3 -1
- data/app/controllers/concerns/maglev/resource_id_concern.rb +10 -0
- data/app/controllers/concerns/maglev/standalone_sections_concern.rb +6 -0
- data/app/controllers/concerns/maglev/{ui_locale_concern.rb → user_interface_locale_concern.rb} +1 -1
- data/app/controllers/maglev/api/collection_items_controller.rb +7 -0
- data/app/controllers/maglev/api/page_clones_controller.rb +1 -2
- data/app/controllers/maglev/api_controller.rb +1 -1
- data/app/controllers/maglev/application_controller.rb +1 -5
- data/app/controllers/maglev/assets/active_storage_proxy_controller.rb +17 -0
- data/app/controllers/maglev/assets/proxy_controller.rb +21 -0
- data/app/controllers/maglev/editor_controller.rb +1 -1
- data/app/controllers/maglev/page_preview_controller.rb +3 -3
- data/app/frontend/admin/controllers/screenshot_controller.js +29 -1
- data/app/frontend/editor/assets/remixicons/clipboard-line.svg +1 -0
- data/app/frontend/editor/assets/remixicons/format-superscript.svg +1 -0
- data/app/frontend/editor/assets/remixicons/ri-draggable.svg +1 -0
- data/app/frontend/editor/assets/remixicons/ri-folders-line.svg +1 -0
- data/app/frontend/editor/assets/remixicons/ri-more-fill.svg +1 -0
- data/app/frontend/editor/assets/remixicons/ri-shadow-line.svg +1 -0
- data/app/frontend/editor/components/dynamic-form/dynamic-input.vue +1 -1
- data/app/frontend/editor/components/errors/forbidden.vue +24 -0
- data/app/frontend/editor/components/errors/stale-record.vue +2 -2
- data/app/frontend/editor/components/header-nav/device-toggler.vue +6 -3
- data/app/frontend/editor/components/header-nav/index.vue +13 -42
- data/app/frontend/editor/components/header-nav/locale-toggler/index.vue +1 -1
- data/app/frontend/editor/components/header-nav/page-info.vue +41 -0
- data/app/frontend/editor/components/header-nav/preview-button.vue +6 -1
- data/app/frontend/editor/components/header-nav/separator.vue +1 -1
- data/app/frontend/editor/components/image-library/index.vue +26 -29
- data/app/frontend/editor/components/kit/collection-item-input.vue +9 -0
- data/app/frontend/editor/components/kit/copy-paste-button.vue +26 -0
- data/app/frontend/editor/components/kit/dropdown.vue +5 -0
- data/app/frontend/editor/components/kit/icon-button.vue +24 -0
- data/app/frontend/editor/components/kit/icon.vue +2 -3
- data/app/frontend/editor/components/kit/index.js +4 -2
- data/app/frontend/editor/components/kit/link-input.vue +1 -1
- data/app/frontend/editor/components/kit/modal.vue +1 -1
- data/app/frontend/editor/components/kit/page-icon.vue +1 -1
- data/app/frontend/editor/components/kit/rich-text-input/extensions/marks/Superscript.js +43 -0
- data/app/frontend/editor/components/kit/rich-text-input/format-buttons.vue +9 -1
- data/app/frontend/editor/components/kit/rich-text-input/link-buttons.vue +1 -1
- data/app/frontend/editor/components/kit/rich-text-input.vue +11 -5
- data/app/frontend/editor/components/kit/select-input.vue +4 -2
- data/app/frontend/editor/components/link-picker/actions.vue +1 -1
- data/app/frontend/editor/components/link-picker/index.vue +1 -1
- data/app/frontend/editor/components/link-picker/page.vue +2 -0
- data/app/frontend/editor/components/page/form/main.vue +1 -1
- data/app/frontend/editor/components/page/list/actions-button.vue +159 -0
- data/app/frontend/editor/components/page/list/index.vue +15 -24
- data/app/frontend/editor/components/page/list/list-item.vue +10 -61
- data/app/frontend/editor/components/section-highlighter/index.vue +47 -46
- data/app/frontend/editor/components/section-list/add-button.vue +39 -0
- data/app/frontend/editor/components/section-list/index.vue +30 -15
- data/app/frontend/editor/components/section-list/list-item.vue +23 -8
- data/app/frontend/editor/components/section-pane/block-list/index.vue +1 -0
- data/app/frontend/editor/components/section-pane/block-list/list-item.vue +9 -6
- data/app/frontend/editor/components/section-pane/block-tree/new-nested-block-button.vue +2 -2
- data/app/frontend/editor/components/section-pane/block-tree/tree-node.vue +2 -2
- data/app/frontend/editor/components/sidebar-nav/index.vue +102 -0
- data/app/frontend/editor/components/sidebar-nav/link.vue +60 -0
- data/app/frontend/editor/components/theme-section-list/category.vue +47 -0
- data/app/frontend/editor/components/theme-section-list/index.vue +7 -31
- data/app/frontend/editor/components/theme-section-list/list-item.vue +10 -3
- data/app/frontend/editor/design/components/modal.scss +1 -1
- data/app/frontend/editor/design/components/tooltip.scss +6 -0
- data/app/frontend/editor/design/transitions.scss +1 -1
- data/app/frontend/editor/layouts/app.vue +1 -1
- data/app/frontend/editor/layouts/default.vue +2 -2
- data/app/frontend/editor/layouts/slide-pane.vue +1 -1
- data/app/frontend/editor/locales/editor.ar.json +265 -0
- data/app/frontend/editor/locales/editor.en.json +23 -15
- data/app/frontend/editor/locales/editor.es.json +18 -10
- data/app/frontend/editor/locales/editor.fr.json +28 -13
- data/app/frontend/editor/locales/editor.pt-BR.json +18 -10
- data/app/frontend/editor/locales/index.js +3 -0
- data/app/frontend/editor/mixins/error-modal.js +7 -2
- data/app/frontend/editor/mixins/preview-transformation.js +0 -1
- data/app/frontend/editor/plugins/i18n.js +2 -17
- data/app/frontend/editor/services/__tests__/section.spec.js +6 -0
- data/app/frontend/editor/services/collection-item.js +8 -0
- data/app/frontend/editor/services/page.js +1 -1
- data/app/frontend/editor/services/section.js +30 -0
- data/app/frontend/editor/services/site.js +4 -4
- data/app/frontend/editor/services/theme.js +1 -0
- data/app/frontend/editor/spec/__mocks__/page.js +3 -1
- data/app/frontend/editor/spec/__mocks__/services.js +1 -0
- data/app/frontend/editor/store/__tests__/getters.spec.js +56 -1
- data/app/frontend/editor/store/actions/index.js +1 -0
- data/app/frontend/editor/store/actions/site.js +8 -4
- data/app/frontend/editor/store/getters.js +11 -0
- data/app/frontend/editor/views/page-preview.vue +2 -1
- data/app/frontend/images/favicon.svg +11 -0
- data/app/frontend/images/logo.svg +14 -0
- data/app/frontend/live-preview-client/iframe-decorator.js +17 -15
- data/app/frontend/live-preview-client/rails.js +1 -1
- data/app/helpers/maglev/application_helper.rb +7 -2
- data/app/helpers/maglev/editor_helper.rb +12 -5
- data/app/models/concerns/maglev/sections_concern.rb +4 -0
- data/app/models/maglev/asset.rb +13 -14
- data/app/models/maglev/page/path_concern.rb +23 -8
- data/app/models/maglev/page.rb +17 -18
- data/app/models/maglev/page_path.rb +18 -18
- data/app/models/maglev/section/setting.rb +1 -1
- data/app/models/maglev/section.rb +18 -9
- data/app/models/maglev/setting_types/link.rb +1 -1
- data/app/models/maglev/site/locales_concern.rb +1 -1
- data/app/models/maglev/site.rb +13 -24
- data/app/services/maglev/app_container.rb +2 -2
- data/app/services/maglev/extract_locale.rb +3 -2
- data/app/services/maglev/fetch_page.rb +2 -0
- data/app/services/maglev/fetch_theme_layout.rb +2 -0
- data/app/services/maglev/get_page_fullpath.rb +1 -2
- data/app/services/maglev/remove_section_type.rb +50 -0
- data/app/services/maglev/rename_section_type.rb +57 -0
- data/app/services/maglev/search_pages.rb +2 -1
- data/app/views/layouts/maglev/admin/application.html.erb +1 -1
- data/app/views/maglev/admin/sections/previews/show.html.erb +16 -1
- data/app/views/maglev/api/collection_items/show.json.jbuilder +7 -0
- data/app/views/maglev/api/page_clones/create.json.jbuilder +3 -0
- data/app/views/maglev/editor/show.html.erb +6 -5
- data/config/locales/activerecord.ar.yml +13 -0
- data/config/locales/activerecord.en.yml +8 -2
- data/config/locales/activerecord.es.yml +4 -0
- data/config/locales/activerecord.fr.yml +6 -2
- data/config/locales/activerecord.pt-BR.yml +13 -0
- data/config/routes.rb +4 -5
- data/db/migrate/20200831101942_create_maglev_section_content.rb +10 -2
- data/db/migrate/20210819092740_switch_to_localized_page_fields.rb +13 -3
- data/db/migrate/20211008064437_add_locales_to_sites.rb +7 -1
- data/db/migrate/20211013210954_translate_section_content.rb +16 -2
- data/db/migrate/20211203224112_add_open_graph_tags_to_pages.rb +9 -3
- data/db/migrate/20220612092235_add_style_to_sites.rb +5 -1
- data/lib/commands/maglev/change_site_locales_command.rb +61 -0
- data/lib/commands/maglev/create_site_command.rb +28 -0
- data/lib/commands/maglev/sections/remove_command.rb +48 -0
- data/lib/commands/maglev/sections/rename_command.rb +49 -0
- data/lib/generators/maglev/templates/install/config/initializers/maglev.rb +4 -1
- data/lib/generators/maglev/templates/theme/app/views/theme/layout.html.erb.tt +8 -2
- data/lib/maglev/errors.rb +1 -0
- data/lib/maglev/preview_constraint.rb +6 -2
- data/lib/maglev/theme_filesystem_loader.rb +7 -0
- data/lib/maglev/version.rb +1 -1
- data/lib/maglev.rb +13 -3
- data/lib/tasks/maglev/icons.rake +123 -0
- data/lib/tasks/maglev/vite.rake +62 -0
- data/lib/tasks/maglev_tasks.rake +9 -112
- data/tailwind.config.js +2 -1
- metadata +54 -35
- data/app/controllers/maglev/assets_controller.rb +0 -10
- data/app/frontend/editor/components/kit/list-item-button.vue +0 -16
- data/app/frontend/editor/components/sidebar-nav.vue +0 -125
- data/app/frontend/images/favicon.png +0 -0
- data/app/frontend/images/logo.png +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82bc9958b22dec5a92e3f9e3fab438418f666479d868e9196c6c96fe350d082c
|
4
|
+
data.tar.gz: 975cf8a2f8b11ce2c2f3cfad7c38ba7db2c7ab351d1e5a83a1f563e903a9def2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a5ec523921178fdbecbec37ff7ddccab1fc9f1e26fd6d1fd270b7bf231ab28af1b111a7ecfc71b132abdce46f39ff785bc6630d6c98925c106bc266c6432037
|
7
|
+
data.tar.gz: 52b7d06da150eb80b06ec8006fa5960f8e77543cd7d054786a19d4875fed86b50946e2820567b402455df561b25fb1302e5e3a7be1adfa7b8f4b8b8d75dad417
|
data/.yarn/install-state.gz
CHANGED
Binary file
|
data/README.md
CHANGED
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
[](https://github.com/maglevhq/maglev-core/actions/workflows/verify.yml)
|
4
4
|
|
5
|
-
MaglevCMS is a website builder
|
5
|
+
MaglevCMS is a website builder/CMS that you can integrate into any Ruby on Rails application from version 7 up to version 8.
|
6
6
|
|
7
7
|
## Demo
|
8
8
|
|
9
|
-
Check out our [MaglevCMS
|
10
|
-
This demo showcases the full capabilities of MaglevCMS, including advanced features available in the
|
9
|
+
Check out our [MaglevCMS Saas Edition demo](https://demo-pro.maglev.dev) to see MaglevCMS in action.\
|
10
|
+
This demo showcases the full capabilities of MaglevCMS, including advanced features available in the SaaS version.
|
11
11
|
|
12
12
|
|
13
13
|
## Getting started / Documentation
|
@@ -17,7 +17,7 @@ This demo showcases the full capabilities of MaglevCMS, including advanced featu
|
|
17
17
|
|
18
18
|
## Interested in more power for your Rails SaaS?
|
19
19
|
|
20
|
-
If you're a Rails SaaS owner looking to offer advanced page-building and customization features to your clients, check out [MaglevCMS
|
20
|
+
If you're a Rails SaaS owner looking to offer advanced page-building and customization features to your clients, check out [MaglevCMS Saas Edition](https://www.maglev.dev/saas-edition). With MaglevCMS SaaS Edition, you get premium tools, enhanced customization options, and dedicated support to take your platform to the next level.\
|
21
21
|
Explore the full potential of MaglevCMS and see how it can transform your SaaS business.
|
22
22
|
|
23
23
|
## Testing
|
data/Rakefile
CHANGED
@@ -20,7 +20,9 @@ require 'vite_ruby'
|
|
20
20
|
ViteRuby.install_tasks
|
21
21
|
ViteRuby.config.root # Ensure the engine is set as the root.
|
22
22
|
|
23
|
-
|
23
|
+
rakefile_path = !defined?(Rails) || Rails::VERSION::MAJOR >= 8 ? 'spec/dummy/Rakefile' : 'spec/legacy_dummy/Rakefile'
|
24
|
+
APP_RAKEFILE = File.expand_path(rakefile_path, __dir__)
|
25
|
+
|
24
26
|
load 'rails/tasks/engine.rake'
|
25
27
|
load 'rails/tasks/statistics.rake'
|
26
28
|
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Maglev
|
4
4
|
class BaseComponent
|
5
|
+
include ::Maglev::Inspector
|
6
|
+
|
5
7
|
extend Forwardable
|
6
8
|
def_delegators :view_context, :render
|
7
9
|
|
@@ -50,5 +52,9 @@ module Maglev
|
|
50
52
|
rescue NoMethodError
|
51
53
|
raise "[Maglev] We're sorry but there is no '#{setting_id}' setting in your section/block."
|
52
54
|
end
|
55
|
+
|
56
|
+
def site_id
|
57
|
+
site.id
|
58
|
+
end
|
53
59
|
end
|
54
60
|
end
|
@@ -5,7 +5,7 @@ module Maglev
|
|
5
5
|
include TagHelper
|
6
6
|
|
7
7
|
extend Forwardable
|
8
|
-
def_delegators :section, :site, :config
|
8
|
+
def_delegators :section, :site, :page, :config
|
9
9
|
|
10
10
|
attr_reader :section, :id, :name, :type, :settings, :attributes, :definition
|
11
11
|
attr_accessor :children
|
@@ -42,5 +42,15 @@ module Maglev
|
|
42
42
|
def tag_data
|
43
43
|
{ maglev_block_id: id }
|
44
44
|
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def section_id
|
49
|
+
section.id
|
50
|
+
end
|
51
|
+
|
52
|
+
def inspect_fields
|
53
|
+
%w[id site_id section_id name type].map { |field| [field, send(field)] }
|
54
|
+
end
|
45
55
|
end
|
46
56
|
end
|
@@ -3,8 +3,10 @@
|
|
3
3
|
module Maglev
|
4
4
|
module Content
|
5
5
|
class Base
|
6
|
+
include ::Maglev::Inspector
|
7
|
+
|
6
8
|
extend Forwardable
|
7
|
-
def_delegators :scope, :site, :config
|
9
|
+
def_delegators :scope, :site, :config, :page
|
8
10
|
|
9
11
|
attr_accessor :scope, :content, :setting
|
10
12
|
|
@@ -47,6 +49,12 @@ module Maglev
|
|
47
49
|
instance_exec(site, &config.asset_host)
|
48
50
|
end
|
49
51
|
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def inspect_fields
|
56
|
+
%w[scope tag_id].map { |field| [field, send(field).inspect] }
|
57
|
+
end
|
50
58
|
end
|
51
59
|
end
|
52
60
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Maglev
|
4
|
+
module Inspector
|
5
|
+
def inspect
|
6
|
+
string = "#<#{self.class.name}:#{object_id} "
|
7
|
+
string << inspect_fields
|
8
|
+
.map { |(name, value)| "#{name}: #{value}" }
|
9
|
+
.join(', ') << '>'
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def inspect_fields
|
15
|
+
[]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -5,7 +5,7 @@ module Maglev
|
|
5
5
|
include TagHelper
|
6
6
|
|
7
7
|
extend Forwardable
|
8
|
-
def_delegators :parent, :site, :config
|
8
|
+
def_delegators :parent, :site, :page, :config
|
9
9
|
|
10
10
|
attr_reader :parent, :id, :type, :settings, :attributes, :definition, :templates_root_path, :rendering_mode
|
11
11
|
|
@@ -97,7 +97,7 @@ module Maglev
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def handle_error(exception)
|
100
|
-
|
100
|
+
raise exception if %i[live section].include?(rendering_mode) || Rails.env.test?
|
101
101
|
|
102
102
|
Rails.logger.error [
|
103
103
|
"⚠️ [Maglev] Error when rendering a \"#{type}\" type section ⚠️",
|
@@ -122,5 +122,9 @@ module Maglev
|
|
122
122
|
</div>
|
123
123
|
HTML
|
124
124
|
end
|
125
|
+
|
126
|
+
def inspect_fields
|
127
|
+
%w[id site_id type].map { |field| [field, send(field)] }
|
128
|
+
end
|
125
129
|
end
|
126
130
|
end
|
@@ -48,7 +48,9 @@ module Maglev
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def fetch_maglev_theme_layout
|
51
|
-
@fetch_maglev_theme_layout ||= maglev_services.fetch_theme_layout.call
|
51
|
+
@fetch_maglev_theme_layout ||= maglev_services.fetch_theme_layout.call(
|
52
|
+
page: fetch_maglev_page
|
53
|
+
)
|
52
54
|
end
|
53
55
|
|
54
56
|
def fetch_maglev_sections_path
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Maglev
|
4
|
+
module ResourceIdConcern
|
5
|
+
def resource_id
|
6
|
+
# A standard UUID code contains 32 hex digits along with 4 "-"" symbols
|
7
|
+
Maglev.uuid_as_primary_key? && params[:id] ? params[:id][0..35] : params[:id]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -4,8 +4,7 @@ module Maglev
|
|
4
4
|
module Api
|
5
5
|
class PageClonesController < ::Maglev::ApiController
|
6
6
|
def create
|
7
|
-
page = clone_page(resources.find(params[:page_id]))
|
8
|
-
head :created, location: api_page_path(page)
|
7
|
+
@page = clone_page(resources.find(params[:page_id]))
|
9
8
|
end
|
10
9
|
|
11
10
|
private
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module Maglev
|
4
4
|
class ApplicationController < ::ApplicationController
|
5
5
|
include Maglev::ServicesConcern
|
6
|
+
include Maglev::ResourceIdConcern
|
6
7
|
|
7
8
|
protect_from_forgery with: :exception
|
8
9
|
|
@@ -13,10 +14,5 @@ module Maglev
|
|
13
14
|
def use_engine_vite?
|
14
15
|
true
|
15
16
|
end
|
16
|
-
|
17
|
-
def resource_id
|
18
|
-
# A standard UUID code contains 32 hex digits along with 4 "-"" symbols
|
19
|
-
Maglev.uuid_as_primary_key? && params[:id] ? params[:id][0..35] : params[:id]
|
20
|
-
end
|
21
17
|
end
|
22
18
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Maglev
|
4
|
+
module Assets
|
5
|
+
class ActiveStorageProxyController < ::ActiveStorage::Blobs::ProxyController
|
6
|
+
include Maglev::ResourceIdConcern
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def set_blob
|
11
|
+
@blob = Maglev::Asset.find(resource_id).file
|
12
|
+
rescue ActiveRecord::RecordNotFound
|
13
|
+
head :not_found
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Maglev
|
4
|
+
module Assets
|
5
|
+
class ProxyController < ApplicationController
|
6
|
+
def show
|
7
|
+
@asset = Maglev::Asset.find(resource_id)
|
8
|
+
send_data @asset.download, filename: @asset.filename, type: @asset.content_type
|
9
|
+
response.headers['Cache-Control'] = cache_control_header
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def cache_control_header
|
15
|
+
# Rails 8+ uses :'cache-control' and Rails 7.x uses :'Cache-Control'
|
16
|
+
Rails.configuration.public_file_server.headers[:'cache-control'] ||
|
17
|
+
Rails.configuration.public_file_server.headers[:'Cache-Control']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -5,7 +5,7 @@ module Maglev
|
|
5
5
|
include Maglev::AuthenticationConcern
|
6
6
|
include Maglev::FetchersConcern
|
7
7
|
include Maglev::BackActionConcern
|
8
|
-
include Maglev::
|
8
|
+
include Maglev::UserInterfaceLocaleConcern
|
9
9
|
include Maglev::ContentLocaleConcern
|
10
10
|
|
11
11
|
before_action :fetch_maglev_site, only: :show
|
@@ -7,7 +7,7 @@ module Maglev
|
|
7
7
|
include Maglev::ContentLocaleConcern
|
8
8
|
|
9
9
|
before_action :fetch_maglev_site
|
10
|
-
|
10
|
+
around_action :extract_content_locale
|
11
11
|
|
12
12
|
def index
|
13
13
|
render_maglev_page
|
@@ -43,9 +43,9 @@ module Maglev
|
|
43
43
|
false
|
44
44
|
end
|
45
45
|
|
46
|
-
def extract_content_locale
|
46
|
+
def extract_content_locale(&block)
|
47
47
|
_, locale = maglev_services.extract_locale.call(params: params, locales: maglev_site.locale_prefixes)
|
48
|
-
::I18n.locale
|
48
|
+
::I18n.with_locale(locale, &block)
|
49
49
|
end
|
50
50
|
|
51
51
|
def fallback_to_default_locale
|
@@ -2,7 +2,7 @@ import { Controller } from 'stimulus'
|
|
2
2
|
import axios from '../utils/axios'
|
3
3
|
|
4
4
|
export default class extends Controller {
|
5
|
-
static targets = ['source', 'output']
|
5
|
+
static targets = ['source', 'output', 'fileInput']
|
6
6
|
static values = { url: String }
|
7
7
|
|
8
8
|
connect() {
|
@@ -38,4 +38,32 @@ export default class extends Controller {
|
|
38
38
|
.catch((error) => console.log('ERROR!', error))
|
39
39
|
})
|
40
40
|
}
|
41
|
+
|
42
|
+
triggerFileInput() {
|
43
|
+
this.fileInputTarget.click()
|
44
|
+
}
|
45
|
+
|
46
|
+
handleFileUpload(event) {
|
47
|
+
const file = event.target.files[0]
|
48
|
+
if (!file) return
|
49
|
+
|
50
|
+
const reader = new FileReader()
|
51
|
+
reader.onload = () => {
|
52
|
+
const base64Image = reader.result
|
53
|
+
this.outputTarget.src = base64Image
|
54
|
+
|
55
|
+
axios
|
56
|
+
.post(this.urlValue, {
|
57
|
+
screenshot: { base64_image: base64Image },
|
58
|
+
})
|
59
|
+
.then(() => {
|
60
|
+
alert('Screenshot uploaded!')
|
61
|
+
})
|
62
|
+
.catch((error) => console.log('ERROR!', error))
|
63
|
+
}
|
64
|
+
reader.readAsDataURL(file)
|
65
|
+
|
66
|
+
// Clear the input so the same file can be selected again
|
67
|
+
event.target.value = ''
|
68
|
+
}
|
41
69
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M7 4V2H17V4H20.0066C20.5552 4 21 4.44495 21 4.9934V21.0066C21 21.5552 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5551 3 21.0066V4.9934C3 4.44476 3.44495 4 3.9934 4H7ZM7 6H5V20H19V6H17V8H7V6ZM9 4V6H15V4H9Z"></path></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5.59567 5L10.5 10.9283L15.4043 5H18L11.7978 12.4971L18 19.9943V20H15.4091L10.5 14.0659L5.59092 20H3V19.9943L9.20216 12.4971L3 5H5.59567ZM21.5507 6.5803C21.7042 6.43453 21.8 6.22845 21.8 6C21.8 5.55817 21.4418 5.2 21 5.2C20.5582 5.2 20.2 5.55817 20.2 6C20.2 6.07624 20.2107 6.14999 20.2306 6.21983L19.0765 6.54958C19.0267 6.37497 19 6.1906 19 6C19 4.89543 19.8954 4 21 4C22.1046 4 23 4.89543 23 6C23 6.57273 22.7593 7.08923 22.3735 7.45384L20.7441 9H23V10H19V9L21.5507 6.5803V6.5803Z"></path></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8.5 7C9.32843 7 10 6.32843 10 5.5C10 4.67157 9.32843 4 8.5 4C7.67157 4 7 4.67157 7 5.5C7 6.32843 7.67157 7 8.5 7ZM8.5 13.5C9.32843 13.5 10 12.8284 10 12C10 11.1716 9.32843 10.5 8.5 10.5C7.67157 10.5 7 11.1716 7 12C7 12.8284 7.67157 13.5 8.5 13.5ZM10 18.5C10 19.3284 9.32843 20 8.5 20C7.67157 20 7 19.3284 7 18.5C7 17.6716 7.67157 17 8.5 17C9.32843 17 10 17.6716 10 18.5ZM15.5 7C16.3284 7 17 6.32843 17 5.5C17 4.67157 16.3284 4 15.5 4C14.6716 4 14 4.67157 14 5.5C14 6.32843 14.6716 7 15.5 7ZM17 12C17 12.8284 16.3284 13.5 15.5 13.5C14.6716 13.5 14 12.8284 14 12C14 11.1716 14.6716 10.5 15.5 10.5C16.3284 10.5 17 11.1716 17 12ZM15.5 20C16.3284 20 17 19.3284 17 18.5C17 17.6716 16.3284 17 15.5 17C14.6716 17 14 17.6716 14 18.5C14 19.3284 14.6716 20 15.5 20Z"></path></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M6 7V4C6 3.44772 6.44772 3 7 3H13.4142L15.4142 5H21C21.5523 5 22 5.44772 22 6V16C22 16.5523 21.5523 17 21 17H18V20C18 20.5523 17.5523 21 17 21H3C2.44772 21 2 20.5523 2 20V8C2 7.44772 2.44772 7 3 7H6ZM6 9H4V19H16V17H6V9ZM8 5V15H20V7H14.5858L12.5858 5H8Z"></path></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5 10C3.9 10 3 10.9 3 12C3 13.1 3.9 14 5 14C6.1 14 7 13.1 7 12C7 10.9 6.1 10 5 10ZM19 10C17.9 10 17 10.9 17 12C17 13.1 17.9 14 19 14C20.1 14 21 13.1 21 12C21 10.9 20.1 10 19 10ZM12 10C10.9 10 10 10.9 10 12C10 13.1 10.9 14 12 14C13.1 14 14 13.1 14 12C14 10.9 13.1 10 12 10Z"></path></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 2C2.44772 2 2 2.44772 2 3V17C2 17.5523 2.44772 18 3 18H6V21C6 21.5523 6.44772 22 7 22H21C21.5523 22 22 21.5523 22 21V7C22 6.44772 21.5523 6 21 6H18V3C18 2.44772 17.5523 2 17 2H3ZM18 11.5607L20 13.5607V16.4393L18 14.4393V11.5607ZM18 9.43934V8H20V11.4393L18 9.43934ZM18 17V16.5607L20 18.5607V20H18.5607L16.5607 18H17C17.5523 18 18 17.5523 18 17ZM14.4393 18L16.4393 20H13.5607L11.5607 18H14.4393ZM9.43934 18L11.4393 20H8V18H9.43934ZM4 16V4H16V16H4Z"></path></svg>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="pt-8 pb-4">
|
3
|
+
<p class="text-gray-600 text-justify">
|
4
|
+
{{ $t('errorModals.forbidden.message') }}
|
5
|
+
</p>
|
6
|
+
|
7
|
+
<div class="mt-4 text-center">
|
8
|
+
<button class="big-submit-button bg-editor-primary" @click="close">
|
9
|
+
{{ $t('errorModals.forbidden.button') }}
|
10
|
+
</button>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
</template>
|
14
|
+
|
15
|
+
<script>
|
16
|
+
export default {
|
17
|
+
name: 'ForbiddenError',
|
18
|
+
methods: {
|
19
|
+
close() {
|
20
|
+
this.closeModal()
|
21
|
+
},
|
22
|
+
},
|
23
|
+
}
|
24
|
+
</script>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<template>
|
2
|
-
<div class="pt-8 pb-4">
|
2
|
+
<div class="pt-8 pb-4 space-y-4">
|
3
3
|
<p class="text-gray-600 text-justify">
|
4
4
|
{{ $t('errorModals.staleRecord.message') }}
|
5
5
|
</p>
|
6
6
|
|
7
|
-
<div class="
|
7
|
+
<div class="text-center">
|
8
8
|
<button class="big-submit-button bg-editor-primary" @click="reloadPage">
|
9
9
|
{{ $t('errorModals.staleRecord.button') }}
|
10
10
|
</button>
|
@@ -5,9 +5,12 @@
|
|
5
5
|
:key="icon.device"
|
6
6
|
:name="icon.name"
|
7
7
|
:color="icon.color"
|
8
|
-
class="cursor-pointer"
|
9
|
-
:class="{
|
10
|
-
|
8
|
+
class="cursor-pointer hover:bg-editor-primary hover:bg-opacity-5 px-2"
|
9
|
+
:class="{
|
10
|
+
'mx-1': index === 1,
|
11
|
+
'bg-editor-primary bg-opacity-5': device === icon.device
|
12
|
+
}"
|
13
|
+
size="2.5rem"
|
11
14
|
@click.native="setDevice(icon.device)"
|
12
15
|
/>
|
13
16
|
</div>
|
@@ -7,54 +7,26 @@
|
|
7
7
|
<div class="h-6 bg-gray-200 rounded w-1/4 mx-6"></div>
|
8
8
|
<div class="h-6 bg-gray-200 rounded w-1/4 mx-6"></div>
|
9
9
|
</div>
|
10
|
-
<div class="
|
11
|
-
<div class="
|
12
|
-
<
|
13
|
-
:to="{ name: 'listPages' }"
|
14
|
-
class="flex items-center py-4 px-6 flex-row hover:bg-editor-primary hover:bg-opacity-5 transition-colors duration-200"
|
15
|
-
:class="{
|
16
|
-
'bg-white': !isListPagesActive,
|
17
|
-
'bg-editor-primary bg-opacity-5': isListPagesActive,
|
18
|
-
}"
|
19
|
-
>
|
20
|
-
<span>{{ $t('headerNav.pages') }}</span>
|
21
|
-
<uikit-page-icon class="ml-4" :page="currentPage" />
|
22
|
-
<span class="ml-2">{{ currentPage.title }}</span>
|
23
|
-
<uikit-icon name="arrow-down-s-line" class="ml-3" />
|
24
|
-
</router-link>
|
25
|
-
|
26
|
-
<separator />
|
27
|
-
|
28
|
-
<router-link
|
29
|
-
:to="{ name: 'editPageSettings' }"
|
30
|
-
class="flex items-center py-4 px-6 flex-row hover:bg-editor-primary hover:bg-opacity-5 transition-colors duration-200"
|
31
|
-
:class="{
|
32
|
-
'bg-white': !isEditPageActive,
|
33
|
-
'bg-editor-primary bg-opacity-5': isEditPageActive,
|
34
|
-
}"
|
35
|
-
>
|
36
|
-
<uikit-icon name="settings-4-line" size="1.25rem" />
|
37
|
-
<span class="ml-2">{{ $t('headerNav.pageSettings') }}</span>
|
38
|
-
</router-link>
|
39
|
-
|
40
|
-
<separator />
|
10
|
+
<div class="grid grid-cols-5 h-full w-full" v-else>
|
11
|
+
<div class="col-span-3 lg:col-span-2">
|
12
|
+
<page-info />
|
41
13
|
</div>
|
42
14
|
|
43
|
-
<div class="flex">
|
44
|
-
<
|
45
|
-
|
46
|
-
</div>
|
47
|
-
<separator />
|
15
|
+
<div class="col-span-1 hidden lg:flex justify-center">
|
16
|
+
<device-toggler />
|
17
|
+
</div>
|
48
18
|
|
19
|
+
<div class="col-span-2 flex justify-end h-full">
|
49
20
|
<div class="flex h-full relative" v-if="hasMultipleLocales">
|
50
21
|
<locale-toggler />
|
51
22
|
</div>
|
52
23
|
<separator v-if="hasMultipleLocales" />
|
53
24
|
|
54
25
|
<preview-toggler v-if="isSitePublishable" />
|
55
|
-
<preview-button v-else />
|
26
|
+
<preview-button v-else class="hidden lg:flex" />
|
56
27
|
|
57
28
|
<separator v-if="isSitePublishable" />
|
29
|
+
|
58
30
|
<div
|
59
31
|
class="flex items-center h-full relative space-x-1 pr-4"
|
60
32
|
v-if="isSitePublishable"
|
@@ -64,7 +36,7 @@
|
|
64
36
|
</div>
|
65
37
|
|
66
38
|
<div v-else>
|
67
|
-
<save-button
|
39
|
+
<save-button big />
|
68
40
|
</div>
|
69
41
|
</div>
|
70
42
|
</div>
|
@@ -79,6 +51,7 @@ import PreviewToggler from './preview-toggler.vue'
|
|
79
51
|
import PublishButton from './publish-button.vue'
|
80
52
|
import SaveButton from './save-button.vue'
|
81
53
|
import Separator from './separator.vue'
|
54
|
+
import PageInfo from './page-info.vue'
|
82
55
|
|
83
56
|
export default {
|
84
57
|
name: 'HeaderNav',
|
@@ -90,6 +63,7 @@ export default {
|
|
90
63
|
SaveButton,
|
91
64
|
Separator,
|
92
65
|
PreviewToggler,
|
66
|
+
PageInfo,
|
93
67
|
},
|
94
68
|
computed: {
|
95
69
|
isLoading() {
|
@@ -97,10 +71,7 @@ export default {
|
|
97
71
|
},
|
98
72
|
isListPagesActive() {
|
99
73
|
return this.$route.name === 'listPages'
|
100
|
-
},
|
101
|
-
isEditPageActive() {
|
102
|
-
return this.$route.name === 'editPageSettings'
|
103
|
-
},
|
74
|
+
},
|
104
75
|
},
|
105
76
|
}
|
106
77
|
</script>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<template>
|
2
2
|
<div>
|
3
|
-
<uikit-dropdown placement="bottom" ref="dropdown" class="h-full flex">
|
3
|
+
<uikit-dropdown placement="bottom" ref="dropdown" class="h-full flex" popoverClass="tooltip-menu">
|
4
4
|
<template v-slot:button>
|
5
5
|
<button
|
6
6
|
class="h-full w-full px-6 hover:bg-editor-primary hover:bg-opacity-5 transition-colors duration-200 flex items-center focus:outline-none focus:none"
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="flex flex-row items-center h-full w-full px-4 overflow-hidden">
|
3
|
+
<div class="flex flex-col leading-none overflow-hidden">
|
4
|
+
<div class="flex items-center">
|
5
|
+
<uikit-page-icon :page="currentPage" size="1.1rem" class="shrink-0 text-gray-900" />
|
6
|
+
<div class="text-base font-semibold truncate ml-1 mr-3">{{ currentPage.title }}</div>
|
7
|
+
|
8
|
+
<page-actions-button
|
9
|
+
:page="currentPage"
|
10
|
+
compact
|
11
|
+
@on-clone="goToClonedPage"
|
12
|
+
/>
|
13
|
+
</div>
|
14
|
+
<div class="text-xs text-gray-500 flex items-center space-x-1">
|
15
|
+
<p class="truncate text-gray-700">
|
16
|
+
<span class="text-gray-900 font-semibold">{{ currentPagePath[0] }}</span>{{ currentPagePath.slice(1) }}
|
17
|
+
</p>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</template>
|
22
|
+
|
23
|
+
<script>
|
24
|
+
import { mapGetters } from 'vuex'
|
25
|
+
import PageActionsButton from '../page/list/actions-button.vue'
|
26
|
+
|
27
|
+
export default {
|
28
|
+
name: 'PageInfo',
|
29
|
+
components: {
|
30
|
+
PageActionsButton,
|
31
|
+
},
|
32
|
+
computed: {
|
33
|
+
...mapGetters(['currentPagePath', 'currentPageUrl']),
|
34
|
+
},
|
35
|
+
methods: {
|
36
|
+
goToClonedPage(page) {
|
37
|
+
this.$router.push({ name: 'editPage', params: { pageId: page.path } })
|
38
|
+
},
|
39
|
+
},
|
40
|
+
}
|
41
|
+
</script>
|