breeze_cms 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +24 -0
- data/Rakefile +6 -0
- data/app/assets/config/breeze_manifest.js +2 -0
- data/app/assets/images/breeze/breeze_logo.png +0 -0
- data/app/assets/images/breeze/card_preview/card_feature_box.png +0 -0
- data/app/assets/images/breeze/card_preview/card_feature_normal.png +0 -0
- data/app/assets/images/breeze/card_preview/card_full_image.png +0 -0
- data/app/assets/images/breeze/card_preview/card_gap_square.png +0 -0
- data/app/assets/images/breeze/card_preview/card_large_image.png +0 -0
- data/app/assets/images/breeze/card_preview/card_normal_round.png +0 -0
- data/app/assets/images/breeze/card_preview/card_normal_square.png +0 -0
- data/app/assets/images/breeze/card_preview/card_wide_square.png +0 -0
- data/app/assets/images/breeze/card_preview/form_field.png +0 -0
- data/app/assets/images/breeze/home.jpg +0 -0
- data/app/assets/images/breeze/section_preview/blog_header.png +0 -0
- data/app/assets/images/breeze/section_preview/form_section.png +0 -0
- data/app/assets/images/breeze/section_preview/section_cards.png +0 -0
- data/app/assets/images/breeze/section_preview/section_feature.png +0 -0
- data/app/assets/images/breeze/section_preview/section_full_image.png +0 -0
- data/app/assets/images/breeze/section_preview/section_full_up.png +0 -0
- data/app/assets/images/breeze/section_preview/section_half_image.png +0 -0
- data/app/assets/images/breeze/section_preview/section_large_image.png +0 -0
- data/app/assets/images/breeze/section_preview/section_news.png +0 -0
- data/app/assets/images/breeze/section_preview/section_slider.png +0 -0
- data/app/assets/images/breeze/section_preview/section_small_image.png +0 -0
- data/app/assets/images/breeze/section_preview/section_spacer.png +0 -0
- data/app/assets/images/breeze/section_preview/section_text.png +0 -0
- data/app/assets/javascript/breeze_application.js.rb +101 -0
- data/app/assets/javascript/marked.js +6 -0
- data/app/assets/stylesheets/breeze/breeze.css +3633 -0
- data/app/assets/stylesheets/breeze/breeze.email.css +1344 -0
- data/app/assets/stylesheets/breeze.tailwind.css +2 -0
- data/app/assets/stylesheets/breeze_tailwind_styles.css +21 -0
- data/app/assets/stylesheets/tailwind_base.css +3 -0
- data/app/controllers/breeze/application_controller.rb +4 -0
- data/app/controllers/breeze/breeze_controller.rb +16 -0
- data/app/controllers/breeze/cards_controller.rb +58 -0
- data/app/controllers/breeze/changes_controller.rb +45 -0
- data/app/controllers/breeze/form_controller.rb +67 -0
- data/app/controllers/breeze/images_controller.rb +100 -0
- data/app/controllers/breeze/pages_controller.rb +66 -0
- data/app/controllers/breeze/sections_controller.rb +96 -0
- data/app/controllers/breeze/styles_controller.rb +11 -0
- data/app/controllers/breeze/translations_controller.rb +56 -0
- data/app/controllers/breeze/view_controller.rb +10 -0
- data/app/helpers/breeze/breeze_helper.rb +54 -0
- data/app/helpers/breeze/cards_helper.rb +11 -0
- data/app/helpers/breeze/changes_helper.rb +29 -0
- data/app/helpers/breeze/form_helper.rb +5 -0
- data/app/helpers/breeze/images_helper.rb +57 -0
- data/app/helpers/breeze/options_helper.rb +120 -0
- data/app/helpers/breeze/pages_helper.rb +5 -0
- data/app/helpers/breeze/sections_helper.rb +14 -0
- data/app/helpers/breeze/styles_helper.rb +4 -0
- data/app/helpers/breeze/translations_helper.rb +14 -0
- data/app/helpers/breeze/view_helper.rb +74 -0
- data/app/jobs/breeze/application_job.rb +4 -0
- data/app/mailers/breeze/application_mailer.rb +6 -0
- data/app/models/breeze/active_base.rb +34 -0
- data/app/models/breeze/active_yaml.rb +143 -0
- data/app/models/breeze/card.rb +90 -0
- data/app/models/breeze/card_style.rb +12 -0
- data/app/models/breeze/change_set.rb +58 -0
- data/app/models/breeze/image.rb +104 -0
- data/app/models/breeze/option_definition.rb +43 -0
- data/app/models/breeze/page.rb +97 -0
- data/app/models/breeze/page_style.rb +12 -0
- data/app/models/breeze/section.rb +137 -0
- data/app/models/breeze/section_style.rb +17 -0
- data/app/models/breeze/shared_base.rb +20 -0
- data/app/models/breeze/style.rb +17 -0
- data/app/models/breeze/translation.rb +83 -0
- data/app/models/breeze/view_base.rb +134 -0
- data/app/views/breeze/cards/index.haml +84 -0
- data/app/views/breeze/changes/index.haml +52 -0
- data/app/views/breeze/form/_editor.haml +33 -0
- data/app/views/breeze/form/form.haml +8 -0
- data/app/views/breeze/images/_editor.haml +144 -0
- data/app/views/breeze/images/index.haml +83 -0
- data/app/views/breeze/images/new.haml +12 -0
- data/app/views/breeze/images/show.haml +60 -0
- data/app/views/breeze/pages/_sections.rabl +4 -0
- data/app/views/breeze/pages/index.haml +49 -0
- data/app/views/breeze/pages/show.haml +85 -0
- data/app/views/breeze/sections/_option_form_date.haml +4 -0
- data/app/views/breeze/sections/_option_form_select.haml +4 -0
- data/app/views/breeze/sections/_option_form_text.haml +4 -0
- data/app/views/breeze/sections/_overlay.haml +33 -0
- data/app/views/breeze/sections/_section.rabl +5 -0
- data/app/views/breeze/sections/_sections_pagination.haml +29 -0
- data/app/views/breeze/sections/index.haml +88 -0
- data/app/views/breeze/sections/new.haml +12 -0
- data/app/views/breeze/sections/select_card_template.haml +13 -0
- data/app/views/breeze/sections/select_template.haml +15 -0
- data/app/views/breeze/sections/show.haml +91 -0
- data/app/views/breeze/styles/_options.haml +9 -0
- data/app/views/breeze/styles/index.haml +84 -0
- data/app/views/breeze/translations/_row.haml +29 -0
- data/app/views/breeze/translations/show.haml +79 -0
- data/app/views/breeze/view/_blog_header.haml +13 -0
- data/app/views/breeze/view/_form_section.haml +21 -0
- data/app/views/breeze/view/_section_cards.haml +17 -0
- data/app/views/breeze/view/_section_feature.haml +13 -0
- data/app/views/breeze/view/_section_full_image.haml +10 -0
- data/app/views/breeze/view/_section_full_up.haml +11 -0
- data/app/views/breeze/view/_section_half_image.haml +13 -0
- data/app/views/breeze/view/_section_large_image.haml +13 -0
- data/app/views/breeze/view/_section_news.haml +16 -0
- data/app/views/breeze/view/_section_slider.haml +51 -0
- data/app/views/breeze/view/_section_small_image.haml +11 -0
- data/app/views/breeze/view/_section_spacer.haml +1 -0
- data/app/views/breeze/view/_section_text.haml +17 -0
- data/app/views/breeze/view/cards/_card_feature_box.haml +13 -0
- data/app/views/breeze/view/cards/_card_feature_normal.haml +7 -0
- data/app/views/breeze/view/cards/_card_full_image.haml +10 -0
- data/app/views/breeze/view/cards/_card_gap_square.haml +11 -0
- data/app/views/breeze/view/cards/_card_large_image.haml +6 -0
- data/app/views/breeze/view/cards/_card_normal_round.haml +8 -0
- data/app/views/breeze/view/cards/_card_normal_square.haml +9 -0
- data/app/views/breeze/view/cards/_card_wide_square.haml +8 -0
- data/app/views/breeze/view/cards/_form_field.haml +8 -0
- data/app/views/breeze/view/elements/_button.haml +4 -0
- data/app/views/breeze/view/page.haml +2 -0
- data/app/views/layouts/breeze/_header.haml +37 -0
- data/app/views/layouts/breeze/_messages.haml +28 -0
- data/app/views/layouts/breeze/application.haml +20 -0
- data/app/views/layouts/mailer.html.haml +8 -0
- data/app/views/layouts/mailer.text.erb +1 -0
- data/config/breeze/card_styles.yml +129 -0
- data/config/breeze/option_definitions.yml +129 -0
- data/config/breeze/page_styles.yml +12 -0
- data/config/breeze/section_styles.yml +199 -0
- data/config/initializers/breeze.rb +13 -0
- data/config/initializers/rabl.rb +31 -0
- data/config/initializers/simple_form.rb +212 -0
- data/config/routes.rb +40 -0
- data/config/tailwind.config.js +17 -0
- data/config/tailwind.email.js +14 -0
- data/lib/breeze/engine.rb +97 -0
- data/lib/breeze/shared_helper.rb +44 -0
- data/lib/breeze/version.rb +3 -0
- data/lib/breeze.rb +104 -0
- data/lib/generators/breeze/install/install_generator.rb +19 -0
- data/lib/generators/breeze/install/templates/empty.yml +1 -0
- data/lib/generators/breeze/install/templates/initializer.rb +70 -0
- data/lib/generators/breeze/update/update_generator.rb +11 -0
- data/lib/tasks/condense.rake +60 -0
- data/lib/tasks/consistency.rake +84 -0
- metadata +371 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
.mx-6.md:mx-12.mx-20.flex.h-16.items-center.gap-16
|
2
|
+
= render "breeze/sections/sections_pagination" , section: @section
|
3
|
+
.text-3xl.font-bold.text-gray-900
|
4
|
+
= @section.cards.length
|
5
|
+
Cards
|
6
|
+
= form_tag( breeze.card_new_path(@section.id) , method: :post ) do
|
7
|
+
%button.button.change.mr-3{type: :submit} New Card
|
8
|
+
.font-bold.text-xl Style
|
9
|
+
.text-xl #{@section.card_template}
|
10
|
+
= form_tag( breeze.section_select_card_template_path(@section.id), method: :post ) do
|
11
|
+
%button.button.action.mr-3{type: :submit} Change Card Style
|
12
|
+
|
13
|
+
.xl:mx-auto{class: "max-w-[1920px]"}
|
14
|
+
= render_section( @section )
|
15
|
+
|
16
|
+
- @section.cards.each_with_index do |card , index|
|
17
|
+
.flex.gap-10.px-20.pt-4.pb-2.mb-2.border.border-2.bg-neutral-50.border-slate-400{ id: "card_#{card.id}"}
|
18
|
+
.basis-60
|
19
|
+
%h3.mt-4.text-lg.font-bold Card #{index + 1}:#{card.header}
|
20
|
+
.flex.flex-wrap
|
21
|
+
.p-2
|
22
|
+
=link_to(breeze.card_move_path(card.id , dir: :down)) do
|
23
|
+
%svg.w-6.h-6{:fill => "none", :stroke => "currentColor", "stroke-width" => "1.5", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
24
|
+
%path{:d => "M15.75 17.25L12 21m0 0l-3.75-3.75M12 21V3", "stroke-linecap" => "round", "stroke-linejoin" => "round"}
|
25
|
+
.p-2
|
26
|
+
=link_to(breeze.card_move_path(card.id , dir: :up)) do
|
27
|
+
%svg.w-6.h-6{:fill => "none", :stroke => "currentColor", "stroke-width" => "1.5", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
28
|
+
%path{:d => "M8.25 6.75L12 3m0 0l3.75 3.75M12 3v18", "stroke-linecap" => "round", "stroke-linejoin" => "round"}
|
29
|
+
|
30
|
+
.mt-6
|
31
|
+
.basis-full.mt-3
|
32
|
+
Updated at:
|
33
|
+
= distance_of_time_in_words_to_now(card.updated_at)
|
34
|
+
.basis-full.mb-3
|
35
|
+
Updated by:
|
36
|
+
= updated_by(card)
|
37
|
+
.basis-full.mb-3
|
38
|
+
= form_for( card , {method: :delete } ) do
|
39
|
+
%button.button.remove.mt-4{type: :submit} Delete Card
|
40
|
+
.flex.justify-between.mt-4
|
41
|
+
= simple_form_for( card , method: :patch ) do |f|
|
42
|
+
= f.input :section_id , label: "move to section (on this page)" ,
|
43
|
+
include_blank: false ,
|
44
|
+
collection: card_section_select(card)
|
45
|
+
%button.button.change{type: :submit} Move
|
46
|
+
|
47
|
+
.basis-80
|
48
|
+
-if card.image
|
49
|
+
= link_to(breeze.images_path(card_id: card.id)) do
|
50
|
+
%h3.mt-4.text-lg.font-bold Image #{card.image.name}
|
51
|
+
.flex.align-center.justify-between.mb-4
|
52
|
+
.text-lg.font-bold.mt-2.mx-2
|
53
|
+
= card.image.size.to_s + "k"
|
54
|
+
%strong.inline-block.rounded.bg-slate-200.px-3.py-1.text-md.font-medium
|
55
|
+
= card.image.aspect_ratio
|
56
|
+
= image_for( card , "mb-4")
|
57
|
+
.flex.gap-3
|
58
|
+
= link_to breeze.images_path(card_id: card.id) do
|
59
|
+
%button.button.action Change Image
|
60
|
+
= link_to breeze.image_path(card.image.id) do
|
61
|
+
%button.button.change Edit Image
|
62
|
+
= link_to breeze.card_set_image_path( card.id , image: "") do
|
63
|
+
%button.button.remove Remove image
|
64
|
+
-else
|
65
|
+
%h3.mt-4.text-lg.font-bold No image
|
66
|
+
= link_to(breeze.images_path(card_id: card.id)) do
|
67
|
+
%button.button.my-3.change Add Image
|
68
|
+
.basis-72.grow
|
69
|
+
%label.block
|
70
|
+
%h4.text-lg.font-bold Texts
|
71
|
+
= simple_form_for( card , method: :patch) do |f|
|
72
|
+
= f.input :header
|
73
|
+
= f.input :text , as: :text , input_html: {rows: rows(card)}
|
74
|
+
%button.button.change.mt-4{type: :submit} Update Texts
|
75
|
+
|
76
|
+
.basis-72.grow
|
77
|
+
= form_for( card , {method: :patch }) do
|
78
|
+
- card.option_definitions.each do |option|
|
79
|
+
.grid.grid-cols-3
|
80
|
+
=render "breeze/sections/option_form_#{option.type}" , section: card , option: option
|
81
|
+
-if card.option_definitions.empty?
|
82
|
+
%p No options
|
83
|
+
-else
|
84
|
+
%button.button.change.mt-3{type: :submit} Update Options
|
@@ -0,0 +1,52 @@
|
|
1
|
+
.mx-6.md:mx-12.mx-20.flex.h-16.items-center.gap-16
|
2
|
+
.text-xl.font-bold.text-gray-900
|
3
|
+
Changes
|
4
|
+
.text-xl.text-gray-900
|
5
|
+
Branch
|
6
|
+
= branch
|
7
|
+
-if flash.notice
|
8
|
+
.m-20.rounded-xl.border.border-gray-100.p-4.shadow-xl
|
9
|
+
.flex-1
|
10
|
+
%strong.block.font-medium.text-gray-900 Ok
|
11
|
+
%p.mt-1.text-sm.text-gray-700
|
12
|
+
= markdown flash.notice
|
13
|
+
|
14
|
+
.overflow-hidden.overflow-x-auto.rounded-lg.border.border-gray-200.m-20
|
15
|
+
%table.min-w-full.divide-y.divide-gray-200.text-sm
|
16
|
+
%thead.bg-gray-100
|
17
|
+
%tr
|
18
|
+
%th.whitespace-nowrap.px-4.py-2.text-left.font-medium.text-gray-900
|
19
|
+
.flex.items-center.gap-2
|
20
|
+
Change
|
21
|
+
-[:Page , :Section , :Card , :Image].each do |element|
|
22
|
+
%th.whitespace-nowrap.px-4.py-2.text-left.font-medium.text-gray-900
|
23
|
+
.flex.items-center.gap-2
|
24
|
+
=element
|
25
|
+
%tbody.divide-y.divide-gray-200
|
26
|
+
-[:add , :edit , :delete].each do |type|
|
27
|
+
%tr
|
28
|
+
%td.whitespace-nowrap.px-4.py-2.text-gray-700
|
29
|
+
= type.to_s.capitalize
|
30
|
+
-[:Page , :Section , :Card , :Image].each do |element|
|
31
|
+
%td.px-4.py-2.text-gray-700
|
32
|
+
- changeset(type , element).each do |name|
|
33
|
+
=name.last
|
34
|
+
%br
|
35
|
+
|
36
|
+
.grid.grid-cols-3.bg-white
|
37
|
+
.items-center.justify-center.col-span-2
|
38
|
+
.max-w-xl.px-4.py-8.mx-auto.text-center.commit_changes
|
39
|
+
= form_tag( breeze.changes_commit_path() , {method: :post } ) do
|
40
|
+
%h1.text-2xl.font-bold.tracking-tight.text-gray-900.sm:text-4xl
|
41
|
+
Commit changes
|
42
|
+
%p.mt-4.text-gray-500
|
43
|
+
%label.block
|
44
|
+
%h4.text-lg.font-bold Message (short summary of changes)
|
45
|
+
= text_field_tag( :message , "", class: "block w-full rounded-lg border-gray-200 p-4 pr-12 text-sm shadow-sm")
|
46
|
+
%button.button.change.mt-3{type: :submit} Commit Changes
|
47
|
+
|
48
|
+
.max-w-xl.px-4.py-8.mx-auto.text-center.reset_changes
|
49
|
+
= form_tag( breeze.changes_reset_path() , {method: :post } ) do
|
50
|
+
%h1.text-2xl.font-bold.tracking-tight.text-gray-900.sm:text-4xl
|
51
|
+
Reset changes
|
52
|
+
%button.button.remove.mt-2{type: :submit} Reset
|
@@ -0,0 +1,33 @@
|
|
1
|
+
.editor.mt-4
|
2
|
+
You can use
|
3
|
+
=link_to "markdown" , "https://www.markdown-cheatsheet.com/" , class: :underline, target: :blank
|
4
|
+
for styling, use Preview tab to view rendered output. Remember to save!
|
5
|
+
-if object.errors and object.errors[field] and ! object.errors[field].blank?
|
6
|
+
.text-red-700= "#{field.to_s.capitalize} #{object.errors[field].join( ' ')}"
|
7
|
+
%ul.flex.text-center.mt-4.font-bold
|
8
|
+
%li.p-2.flex-1.border-t.border-l.border-r.rounded-lg.border-gray-200{"v-bind:class" => "{'bg-gray-50 border-b font-normal': tab == 2}"}
|
9
|
+
%a.text-sm{"@click" => "tab = 1"}
|
10
|
+
Write text
|
11
|
+
%li.p-2.flex-1.border-t.border-l.border-r.rounded-lg.border-gray-200{"v-bind:class" => "{'bg-gray-50 border-b font-normal': tab == 1}"}
|
12
|
+
%a.p-4.text-sm{"@click" => "tab = 2"}
|
13
|
+
Preview
|
14
|
+
|
15
|
+
.my-3{"v-bind:class" => "{hidden: tab == 2}"}
|
16
|
+
%textarea.w-full{ rows: rows(object.send(field)) ,
|
17
|
+
name: "#{object.class.name.downcase}[#{field}]",
|
18
|
+
id: "#{object.class.name.downcase}_#{field}" ,
|
19
|
+
"v-model": "markdown" }
|
20
|
+
|
21
|
+
.my-3.prose{"v-html" => "compiledMarkdown" , "v-bind:class" => "{hidden: tab == 1}"}
|
22
|
+
|
23
|
+
:ruby2js
|
24
|
+
class MarkdownEditor < Vue
|
25
|
+
options el: '.editor'
|
26
|
+
def initialize
|
27
|
+
@tab = 1
|
28
|
+
@markdown = "#{CGI::escapeHTML(sanitize object.send(field).to_s)}"
|
29
|
+
end
|
30
|
+
def compiledMarkdown
|
31
|
+
marked.parse(@markdown)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
.flex.flex-col.m-20
|
2
|
+
.flex.items-center.justify-center.flex-1
|
3
|
+
- @errors.each do |name , message|
|
4
|
+
.m-5.rounded.border-l-4.border-green-500.bg-red-50.p-4
|
5
|
+
%strong.font-medium.text-red-700= name.capitalize
|
6
|
+
.mt-2.text-sm.text-red-700= message
|
7
|
+
|
8
|
+
= render_section @section
|
@@ -0,0 +1,144 @@
|
|
1
|
+
%script{:src => "https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"}
|
2
|
+
|
3
|
+
%section.image
|
4
|
+
.flex.justify-between.mx-20
|
5
|
+
.flex.justify-between
|
6
|
+
%div.justify-self-start.ml-20.mr-10
|
7
|
+
%b Scale {{scaled_x}} x {{scaled_y}}
|
8
|
+
%br/
|
9
|
+
%input{":min": 20 , ":max": 100 , ":step": 0.1 , :type => "range",
|
10
|
+
"v-bind:value": "scale" , "v-on:input" => "handle_scale($event)"}/
|
11
|
+
|
12
|
+
= form_tag( breeze.image_scale_path(image_id: image.id) ) do
|
13
|
+
%input{ hidden: true , id: :scale_id , name: :scale , "v-bind:value": "scale" }
|
14
|
+
%button.my-3.button.change Scale {{scale}} %
|
15
|
+
|
16
|
+
%div.mt-2
|
17
|
+
%b.pr-2 Ratio
|
18
|
+
%br/
|
19
|
+
%em {{ratio}} : 1
|
20
|
+
|
21
|
+
= form_tag( breeze.image_crop_path(image_id: image.id) ) do
|
22
|
+
%input{ hidden: true , id: :width_id , name: :size_x , "v-bind:value": "size_x" }
|
23
|
+
%input{ hidden: true , id: :height_id , name: :size_y , "v-bind:value": "size_y" }
|
24
|
+
%input{ hidden: true , id: :off_x_id , name: :off_x , "v-bind:value": "off_x" }
|
25
|
+
%input{ hidden: true , id: :off_y_id , name: :off_y , "v-bind:value": "off_y" }
|
26
|
+
%button.my-3.button.change Crop
|
27
|
+
|
28
|
+
%div.mt-2.ml-32
|
29
|
+
%b.pr-2 Fix ratio to
|
30
|
+
%select{ "@change": "set_ratio"}
|
31
|
+
%option{value: "0" } Any Ratio
|
32
|
+
%option{value: "#{@image.ratio}" } Initial #{@image.ratio.round(2)} : 1
|
33
|
+
%option{"v-bind:value": "ratio" } Current {{ratio}} : 1
|
34
|
+
-[[4,1],[3,1],[21,9] ,[2,1] ,[16,9] ,[3,2] ,[4,3] ,[1,1] ,[3,4], [2,3],[1,2] ].each do |a|
|
35
|
+
%option{value: "#{a.first/a.last.to_f}" } #{a.first} : #{a.last}
|
36
|
+
|
37
|
+
.flex.justify-between.mb-5
|
38
|
+
%div.ml-20
|
39
|
+
%b Y Offset {{off_y}}
|
40
|
+
%br/
|
41
|
+
%input.horizontal{":min": 0 , ":max": "#{image.height}", ":step": 1 , :type => "range",
|
42
|
+
"v-bind:value": "off_y" , "v-on:input" => "handle_off_y($event)"}
|
43
|
+
%div
|
44
|
+
%b X Offset {{off_x}}
|
45
|
+
%br/
|
46
|
+
%input{":min": 0 , ":max": "#{image.width}", ":step": 1 , :type => "range",
|
47
|
+
"v-bind:value": "off_x" , "v-on:input" => "handle_off_x($event)"}
|
48
|
+
%div
|
49
|
+
%b X Size {{size_x.toFixed(0)}}
|
50
|
+
%br/
|
51
|
+
%input{":min": 0 , ":max": "#{image.width}", ":step": 1 , :type => "range",
|
52
|
+
"v-bind:value": "size_x" , "v-on:input" => "handle_size_x($event)"}
|
53
|
+
%div.mr-20
|
54
|
+
%b Y Size {{size_y.toFixed(0)}}
|
55
|
+
%br
|
56
|
+
%input.horizontal{":min": 0 , ":max": "#{image.height}", ":step": 1 , :type => "range",
|
57
|
+
"v-bind:value": "size_y" , "v-on:input" => "handle_size_y($event)"}
|
58
|
+
|
59
|
+
.flex.justify-center
|
60
|
+
.image-container.overflow-hidden.relative{ "v-bind:style": "{height: scaled_y + 'px' , width: scaled_x + 'px'} " }
|
61
|
+
= image_tag(image.asset_name , class: "")
|
62
|
+
.absolute.bg-transparent.border-4.border-black{ "v-bind:style": "{height: size_y + 'px' , width: size_x + 'px' , top: off_y + 'px', left: off_x + 'px' }" }
|
63
|
+
|
64
|
+
:ruby2js
|
65
|
+
class Images < Vue
|
66
|
+
options el: '.image'
|
67
|
+
def initialize
|
68
|
+
@image_data = #{@image_data.to_json.html_safe}
|
69
|
+
@off_x = 0
|
70
|
+
@off_y = 0
|
71
|
+
@scale = 100
|
72
|
+
@size_x = @image_data[:width]
|
73
|
+
@size_y = @image_data[:height]
|
74
|
+
@fixed_ratio = 0
|
75
|
+
end
|
76
|
+
def set_ratio(event)
|
77
|
+
@fixed_ratio = event.target.value.to_f
|
78
|
+
return if( @fixed_ratio < 0.1)
|
79
|
+
if( @fixed_ratio > ratio )
|
80
|
+
fix_y(@size_x)
|
81
|
+
else
|
82
|
+
fix_x(@size_y)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
def fix_x(new_y)
|
86
|
+
new_x = (new_y * @fixed_ratio)
|
87
|
+
return false if( @off_x + new_x > @image_data[:width])
|
88
|
+
@size_x = new_x
|
89
|
+
return true
|
90
|
+
end
|
91
|
+
def fix_y(new_x)
|
92
|
+
new_y = (new_x / @fixed_ratio)
|
93
|
+
return false if( @off_y + new_y > @image_data[:height])
|
94
|
+
@size_y = new_y
|
95
|
+
return true
|
96
|
+
end
|
97
|
+
|
98
|
+
def set_size_x( new_x )
|
99
|
+
return if( @off_x + new_x > @image_data[:width])
|
100
|
+
if (@fixed_ratio >= 0.1 )
|
101
|
+
return unless fix_y(new_x)
|
102
|
+
end
|
103
|
+
@size_x = new_x
|
104
|
+
end
|
105
|
+
|
106
|
+
def set_size_y(new_y)
|
107
|
+
return if( @off_y + new_y > @image_data[:height])
|
108
|
+
if (@fixed_ratio >= 0.1 )
|
109
|
+
return unless fix_x(new_y)
|
110
|
+
end
|
111
|
+
@size_y = new_y
|
112
|
+
end
|
113
|
+
|
114
|
+
def handle_size_x(event)
|
115
|
+
set_size_x(event.target.value.to_f)
|
116
|
+
end
|
117
|
+
def handle_size_y(event)
|
118
|
+
set_size_y( event.target.value.to_f )
|
119
|
+
end
|
120
|
+
def handle_off_y(event)
|
121
|
+
new_off = event.target.value.to_f
|
122
|
+
if( new_off + @size_y <= @image_data[:height])
|
123
|
+
@off_y = new_off
|
124
|
+
end
|
125
|
+
end
|
126
|
+
def handle_off_x(event)
|
127
|
+
new_off = event.target.value.to_f
|
128
|
+
if( new_off + @size_x <= @image_data[:width])
|
129
|
+
@off_x = new_off
|
130
|
+
end
|
131
|
+
end
|
132
|
+
def handle_scale(event)
|
133
|
+
@scale = event.target.value.to_f
|
134
|
+
end
|
135
|
+
def ratio
|
136
|
+
((@size_x / @size_y)*100).to_i / 100
|
137
|
+
end
|
138
|
+
def scaled_x
|
139
|
+
(@image_data[:width] * @scale / 100).to_i
|
140
|
+
end
|
141
|
+
def scaled_y
|
142
|
+
(@image_data[:height] * @scale / 100).to_i
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
%script{:src => "https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"}
|
2
|
+
|
3
|
+
.mx-6.md:mx-12.mx-20.flex.h-16.items-center.gap-16.justify-between
|
4
|
+
.flex.gap-20
|
5
|
+
.text-xl.font-bold.text-gray-900
|
6
|
+
= text_for_index
|
7
|
+
|
8
|
+
= link_to(breeze.new_image_path(new_link_params) ) do
|
9
|
+
.button.action New Image
|
10
|
+
= link_to(breeze.images_path(unused: true) ) do
|
11
|
+
.button.action Show unused Images
|
12
|
+
|
13
|
+
.images
|
14
|
+
.flex.justify-center.gap-4
|
15
|
+
|
16
|
+
%label.block
|
17
|
+
.mt-1.text-lg.font-bold Search:
|
18
|
+
%input.border.rounded{:category => "query", placeholder:"by name", "v-model" => "search_name" }
|
19
|
+
%input.border.rounded{:category => "query", placeholder:"by tag", "v-model" => "search_tag" }
|
20
|
+
|
21
|
+
- ["name" , "created" , "size" , "ratio"].each do |ruby_sort_key|
|
22
|
+
.rounded{":class" => "{'border': sort_by == '#{ruby_sort_key}'}"}
|
23
|
+
.mx-4.text-lg.font-bold= ruby_sort_key.capitalize
|
24
|
+
%a{ "@click" => "sort_by = '#{ruby_sort_key}';sort_dir = 1" , href: "#" ,
|
25
|
+
":class" => "{'bg-cyan-100': sort_dir == 1 && sort_by == '#{ruby_sort_key}'}"}
|
26
|
+
%svg.w-6.h-6.mt-1{:fill => "none", :stroke => "currentColor", "stroke-width" => "1.5", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
27
|
+
%path{:d => "M8.25 6.75L12 3m0 0l3.75 3.75M12 3v18", "stroke-linecap" => "round", "stroke-linejoin" => "round"}
|
28
|
+
%a{ "@click" => "sort_by = '#{ruby_sort_key}';sort_dir = -1" , href: "#" ,
|
29
|
+
":class" => "{'bg-cyan-100': sort_dir == -1 && sort_by == '#{ruby_sort_key}'}"}
|
30
|
+
%svg.w-6.h-6.mt-1{:fill => "none", :stroke => "currentColor", "stroke-width" => "1.5", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
31
|
+
%path{:d => "M15.75 17.25L12 21m0 0l-3.75-3.75M12 21V3", "stroke-linecap" => "round", "stroke-linejoin" => "round"}
|
32
|
+
|
33
|
+
.grid.grid-cols-2.lg:grid-cols-4.xl:grid-cols-6.gap-4.m-8
|
34
|
+
.flex.flex-col.border.border-gray-100.rounded.image_box{"v-for": "image in filter_and_sort"}
|
35
|
+
.flex.align-center.justify-between.mb-4
|
36
|
+
.text-lg.font-bold.mt-2.mx-2
|
37
|
+
{{image.name}}
|
38
|
+
%strong.inline-block.rounded.bg-slate-200.px-3.py-1.text-md.font-medium
|
39
|
+
{{image.aspect_ratio}}
|
40
|
+
%a.w-full.object-contain.h-72{":href" => "image.link" }
|
41
|
+
%img{ ":src": "image.url" , ":alt": "image.name" }
|
42
|
+
.flex.justify-between.mb-8
|
43
|
+
%strong.inline-block.rounded.bg-orange-50.px-3.py-1.text-md.font-medium
|
44
|
+
{{image.size}}k
|
45
|
+
%strong.inline-block.rounded.bg-orange-50.px-3.py-1.text-md.font-medium
|
46
|
+
{{image.updated_at}}
|
47
|
+
%strong.rounded.h-10.bg-orange-50.px-5.py-2.font-medium
|
48
|
+
{{image.tags}}
|
49
|
+
|
50
|
+
.hidden.list
|
51
|
+
-@images.each do |image|
|
52
|
+
= image_tag(image.asset_name , alt: image.name )
|
53
|
+
|
54
|
+
:ruby2js
|
55
|
+
class Images < Vue
|
56
|
+
options el: '.images'
|
57
|
+
def initialize
|
58
|
+
@image_data = #{@image_data.to_json.html_safe}
|
59
|
+
@search_name = ""
|
60
|
+
@search_tag = ""
|
61
|
+
@sort_by = "created"
|
62
|
+
@sort_dir = -1 # 1 up
|
63
|
+
end
|
64
|
+
def filter_and_sort
|
65
|
+
dat = @image_data
|
66
|
+
if(@search_name.length > 0)
|
67
|
+
dat = dat.filter do |item|
|
68
|
+
return item["name"].toLowerCase().indexOf(@search_name) > -1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
if(@search_tag.length > 0)
|
72
|
+
dat = dat.filter do |item|
|
73
|
+
return (item.tags.toLowerCase().indexOf(@search_tag) > -1)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
dat = dat.slice().sort do |a, b| #a, b image data hashes
|
77
|
+
aa = a[@sort_by]
|
78
|
+
bb = b[@sort_by]
|
79
|
+
return (aa === bb ? 0 : (aa > bb ? 1 : -1) ) * @sort_dir
|
80
|
+
end
|
81
|
+
dat
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
.grid.grid-cols-3.gap-4.m-8{":class" => "{'hidden': !show_new }"}
|
2
|
+
%div
|
3
|
+
= form_tag(breeze.images_path, multipart: true) do
|
4
|
+
.flex.flex-col.border.border-gray-100.rounded.p-4
|
5
|
+
%h3.my-4.text-xl.font-bold= text_for_new
|
6
|
+
= text_field_tag 'filename' ,nil, placeholder: "Optional name", class: "rounded mt-4"
|
7
|
+
%p.my-4 Name will be taken from uploaded file if not given
|
8
|
+
= text_field_tag 'tags' ,nil, placeholder: "Optional tags", class: "rounded mt-4"
|
9
|
+
%p.my-4 Tags describe the size or format
|
10
|
+
= hidden_for_select_image
|
11
|
+
= file_field_tag 'image_file' , class: "mb-8 w-full px-2 text-xl bg-clip-padding border border-solid border-gray-300 rounded"
|
12
|
+
%button.button.change{type: :submit} Submit
|
@@ -0,0 +1,60 @@
|
|
1
|
+
%script{:src => "https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"}
|
2
|
+
|
3
|
+
.mx-6.md:mx-12.mx-20.flex.h-16.items-center.gap-16
|
4
|
+
.text-xl.font-bold.text-gray-900
|
5
|
+
Image: #{@image.name}
|
6
|
+
|
7
|
+
= form_tag( breeze.image_copy_path(@image.id) , method: :post) do
|
8
|
+
%button.mx-40.button.change Copy
|
9
|
+
|
10
|
+
.flex.m-20
|
11
|
+
.left.flex.gap-2.mt-3
|
12
|
+
%p
|
13
|
+
.mr-2.font-bold Type
|
14
|
+
= @image.type
|
15
|
+
%p
|
16
|
+
.font-bold Size
|
17
|
+
= "#{@image.size}k"
|
18
|
+
%p
|
19
|
+
.font-bold Ratio
|
20
|
+
= @image.ratio.round(2)
|
21
|
+
= @image.aspect_ratio
|
22
|
+
= form_tag( breeze.image_path , class: "ml-20 flex" , method: :patch) do
|
23
|
+
.font-bold.mt-3.mx-4 Name:
|
24
|
+
= text_field_tag( "name" , @image.name, class: "rounded border-gray-200 text-sm shadow-sm")
|
25
|
+
.font-bold.mt-3.mx-4 Tags:
|
26
|
+
= text_field_tag( "tags" , @image.tags, class: "rounded border-gray-200 text-sm shadow-sm")
|
27
|
+
%button.mx-4.button.change Update
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
=render "editor" , image: @image
|
32
|
+
.flex.gap-10.m-20
|
33
|
+
-if @used
|
34
|
+
.grid.grid-cols-2.gap-10
|
35
|
+
.grid.grid-cols-3.gap-10
|
36
|
+
%p.col-span-3.font-bold
|
37
|
+
Sections using the image
|
38
|
+
-@sections.each do |section|
|
39
|
+
%p
|
40
|
+
= link_to section.header , breeze.section_path(section)
|
41
|
+
%p
|
42
|
+
%em on Page
|
43
|
+
%p
|
44
|
+
= link_to section.page.name , breeze.page_sections_path(section.page)
|
45
|
+
.grid.grid-cols-3.gap-10
|
46
|
+
%p.col-span-3.font-bold
|
47
|
+
Cards using the image
|
48
|
+
-@cards.each do |card|
|
49
|
+
%p
|
50
|
+
= link_to card.header , breeze.section_cards_path(card.section)
|
51
|
+
%p
|
52
|
+
%em on Page
|
53
|
+
%p
|
54
|
+
= link_to card.section.page.name , breeze.page_sections_path(card.section.page)
|
55
|
+
|
56
|
+
-else
|
57
|
+
%p.align-center Not used, you may delete
|
58
|
+
%p
|
59
|
+
= form_tag( breeze.image_path(@image.id) , {method: :delete } ) do
|
60
|
+
%button.button.remove{type: :submit} Delete
|
@@ -0,0 +1,49 @@
|
|
1
|
+
.mx-6.md:mx-12.mx-20.flex.h-16.items-center.gap-16
|
2
|
+
.text-xl.font-bold.text-gray-900
|
3
|
+
= link_to( "All" , breeze.pages_path(type: '') , class: "p-2 px-4 border border-gray-200 font-bold rounded-lg hover:bg-sky-100 #{params[:type].blank? ? 'bg-blue-200':''}")
|
4
|
+
- @page_styles.each do |style|
|
5
|
+
= link_to( "Only #{style.type.capitalize}s" , breeze.pages_path(type: style.type) , class: "p-2 px-4 border border-gray-200 font-bold rounded-lg hover:bg-sky-100 #{(params[:type] == style.type) ? 'bg-blue-200':''}")
|
6
|
+
|
7
|
+
.overflow-hidden.overflow-x-auto.rounded-lg.border.border-gray-200.mx-6.md:mx-12.mx-20.my-10
|
8
|
+
%table.min-w-full.divide-y.divide-gray-200.text-sm
|
9
|
+
%thead.bg-gray-100
|
10
|
+
%tr
|
11
|
+
-["Index", "Name","Sections" ,"Translations" ,"Edited by" ,
|
12
|
+
"Updated", "Sections by","Actions"].each do |header|
|
13
|
+
%th.whitespace-nowrap.px-4.py-2.text-left.font-medium.text-gray-900
|
14
|
+
.flex.items-center.gap-2
|
15
|
+
= header
|
16
|
+
%tbody.divide-y.divide-gray-200
|
17
|
+
- @pages.each do |page|
|
18
|
+
%tr{id: page.name}
|
19
|
+
%td.whitespace-nowrap.px-4.py-2.text-gray-700
|
20
|
+
= link_to page.id , breeze.page_path(page.id)
|
21
|
+
%td.whitespace-nowrap.px-4.py-2.text-gray-700
|
22
|
+
= link_to page.name , breeze.page_path(page.id)
|
23
|
+
%td.whitespace-nowrap.px-4.py-2.text-gray-700
|
24
|
+
= page.sections.length
|
25
|
+
%td.whitespace-nowrap.px-4.py-2.text-gray-700
|
26
|
+
= link_to page.missing_translations , breeze.translation_path(page.id)
|
27
|
+
%td.whitespace-nowrap.px-4.py-2.text-gray-700
|
28
|
+
=page.updated_by
|
29
|
+
- s = page.sections_update
|
30
|
+
%td.whitespace-nowrap.px-4.py-2.text-gray-700
|
31
|
+
=distance_of_time_in_words_to_now(s&.updated_at) if s
|
32
|
+
%td.whitespace-nowrap.px-4.py-2.text-gray-700
|
33
|
+
=s.updated_by if s
|
34
|
+
%td.whitespace-nowrap.px-4.py-2
|
35
|
+
%strong.rounded.bg-green-100.px-3.text-xs.font-medium.text-green-700{:class => "py-1.5"}
|
36
|
+
= link_to 'Sections', breeze.page_sections_path(page.id)
|
37
|
+
%strong.ml-2.rounded.bg-amber-100.px-3.text-xs.font-medium.text-amber-700{:class => "py-1.5"}
|
38
|
+
= link_to 'Edit', breeze.page_path(page.id)
|
39
|
+
%strong.ml-2.rounded.bg-blue-100.px-3.text-xs.font-medium.text-amber-700{:class => "py-1.5"}
|
40
|
+
=link_to "View live" , "/#{page.name}" , target: page.name
|
41
|
+
|
42
|
+
.flex.mx-6.md:mx-12.mx-20.new_page
|
43
|
+
= form_tag( breeze.pages_path , {method: :post } ) do
|
44
|
+
%label.block
|
45
|
+
%h4.text-lg.font-bold Name
|
46
|
+
= text_field_tag( :name , params[:name], class: "block w-full rounded-lg border-gray-200 p-4 pr-12 text-sm shadow-sm")
|
47
|
+
.flex.gap-3.mt-3.justify-between
|
48
|
+
- @page_styles.each do |page|
|
49
|
+
%button.button.change{name: :type , value: page.type}= "New #{page.type.capitalize}"
|
@@ -0,0 +1,85 @@
|
|
1
|
+
- @page.sections.each do |section|
|
2
|
+
= render_section( section )
|
3
|
+
|
4
|
+
.mx-6.md:mx-12.mx-20.flex.h-16.items-center.gap-16
|
5
|
+
.text-xl.font-bold.text-gray-900
|
6
|
+
= @page.type.capitalize
|
7
|
+
= ":"
|
8
|
+
.text-xl.font-bold.text-gray-900
|
9
|
+
=@page.name
|
10
|
+
%strong.rounded.bg-green-100.px-4.py-2.text-lg.font-medium.text-green-700{:class => "py-1.5"}
|
11
|
+
= link_to 'Section details', breeze.page_sections_path(@page.id)
|
12
|
+
|
13
|
+
= form_tag( breeze.section_new_path(@page.id), method: :post ) do
|
14
|
+
%button.button.change.mr-3{type: :submit} New Section
|
15
|
+
|
16
|
+
.text-xl
|
17
|
+
Edited
|
18
|
+
= distance_of_time_in_words_to_now(@page.updated_at)
|
19
|
+
ago
|
20
|
+
.flex.gap-4.justify-center.m-20
|
21
|
+
.grid.grid-cols-5
|
22
|
+
.text.font-bold Section
|
23
|
+
.text.font-bold Cards
|
24
|
+
.text.font-bold Translations
|
25
|
+
.text.font-bold Updated
|
26
|
+
.text.font-bold Actions
|
27
|
+
- @page.sections.each do |section |
|
28
|
+
.span
|
29
|
+
=link_to( breeze.section_path(section.id)) do
|
30
|
+
#{section.index} : #{section.header}
|
31
|
+
.text
|
32
|
+
=link_to breeze.section_cards_path(section.id) do
|
33
|
+
#{section.cards.length} Cards
|
34
|
+
.text
|
35
|
+
= link_to breeze.translation_path(@page.id) do
|
36
|
+
%button.button.action
|
37
|
+
=section.missing_translations
|
38
|
+
missing
|
39
|
+
.text
|
40
|
+
= updated_by(section)
|
41
|
+
.flex
|
42
|
+
= form_tag( breeze.section_new_path(@page.id), method: :post ) do
|
43
|
+
%button.button.change.mr-3{type: :submit} New
|
44
|
+
= link_to breeze.section_path(section.id) do
|
45
|
+
%button.button.action Edit
|
46
|
+
.p-2
|
47
|
+
=link_to(breeze.section_move_path(section.id , dir: :down)) do
|
48
|
+
%svg.w-6.h-6{:fill => "none", :stroke => "currentColor", "stroke-width" => "1.5", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
49
|
+
%path{:d => "M15.75 17.25L12 21m0 0l-3.75-3.75M12 21V3", "stroke-linecap" => "round", "stroke-linejoin" => "round"}
|
50
|
+
.p-2
|
51
|
+
=link_to(breeze.section_move_path(section.id , dir: :up)) do
|
52
|
+
%svg.w-6.h-6{:fill => "none", :stroke => "currentColor", "stroke-width" => "1.5", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"}
|
53
|
+
%path{:d => "M8.25 6.75L12 3m0 0l3.75 3.75M12 3v18", "stroke-linecap" => "round", "stroke-linejoin" => "round"}
|
54
|
+
|
55
|
+
.flex.flex-col
|
56
|
+
.basis-80
|
57
|
+
= form_tag( breeze.page_path(@page.id) , {method: :patch , class: "mx-auto mt-8 mb-0 max-w space-y-4" } ) do
|
58
|
+
%label.block
|
59
|
+
%h4.text-lg.font-bold Name
|
60
|
+
= text_field_tag( :name , @page.name, class: "w-full rounded-lg border-gray-200 p-4 pr-12 text-sm shadow-sm")
|
61
|
+
%button.button.change.mt-4{type: :submit} Update name
|
62
|
+
|
63
|
+
-unless @page.redirects.blank?
|
64
|
+
.mt-4
|
65
|
+
Page redirects from
|
66
|
+
= @page.redirects
|
67
|
+
|
68
|
+
.relative.block.delete_page.mt-8
|
69
|
+
= form_tag( breeze.page_path(@page.id) , {method: :delete } ) do
|
70
|
+
%button.button.remove{type: :submit} Delete Page
|
71
|
+
|
72
|
+
.basis-80.grow.options
|
73
|
+
%h3.mt-4.text-lg.font-bold Options
|
74
|
+
= form_tag( breeze.page_path(@page.id) , {method: :patch , class: "mx-auto mt-8 mb-0 max-w space-y-4" } ) do
|
75
|
+
- @page.option_definitions.each do |option|
|
76
|
+
=render "/breeze/sections/option_form_#{option.type}" , section: @page , option: option
|
77
|
+
-if @page.option_definitions.empty?
|
78
|
+
%p No options
|
79
|
+
-else
|
80
|
+
%button.button.change.mt-4{type: :submit} Update Options
|
81
|
+
|
82
|
+
:javascript
|
83
|
+
var sections = #{ render( partial: "sections" , formats: :json).html_safe }
|
84
|
+
|
85
|
+
= render partial: 'breeze/sections/overlay'
|