yarii-editor 0.4.0

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.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +31 -0
  4. data/Rakefile +32 -0
  5. data/app/assets/images/yarii_editor/butterfly-small.png +0 -0
  6. data/app/controllers/concerns/yarii_editor/controller_authorization.rb +22 -0
  7. data/app/controllers/concerns/yarii_editor/repository_pullable.rb +11 -0
  8. data/app/controllers/yarii_editor/application_controller.rb +22 -0
  9. data/app/controllers/yarii_editor/dashboard_controller.rb +17 -0
  10. data/app/controllers/yarii_editor/documents_controller.rb +147 -0
  11. data/app/controllers/yarii_editor/publish_controller.rb +24 -0
  12. data/app/helpers/yarii_editor/application_helper.rb +9 -0
  13. data/app/helpers/yarii_editor/document_helper.rb +15 -0
  14. data/app/helpers/yarii_editor/editor_helper.rb +19 -0
  15. data/app/javascript/controllers/building_controller.js +28 -0
  16. data/app/javascript/controllers/card_controller.js +49 -0
  17. data/app/javascript/controllers/commit_modal_controller.js +55 -0
  18. data/app/javascript/controllers/editor_modal_controller.js +76 -0
  19. data/app/javascript/controllers/index.js +85 -0
  20. data/app/javascript/controllers/list_loading_controller.js +33 -0
  21. data/app/javascript/controllers/markdown_editor_controller.js +157 -0
  22. data/app/javascript/controllers/new_document_controller.js +16 -0
  23. data/app/javascript/controllers/push_to_public_controller.js +17 -0
  24. data/app/javascript/controllers/testengine_controller.js +7 -0
  25. data/app/javascript/lib/utils.js +45 -0
  26. data/app/javascript/packs/application.js +4 -0
  27. data/app/jobs/yarii/application_job.rb +4 -0
  28. data/app/mailers/yarii/application_mailer.rb +6 -0
  29. data/app/models/concerns/yarii_editor/model_callbacks.rb +26 -0
  30. data/app/models/concerns/yarii_editor/previewing.rb +18 -0
  31. data/app/models/page.rb +13 -0
  32. data/app/models/post.rb +29 -0
  33. data/app/models/yarii/application_record.rb +5 -0
  34. data/app/models/yarii/repository.rb +50 -0
  35. data/app/models/yarii/site.rb +107 -0
  36. data/app/styles/FiraGO/FiraGO-Bold.woff +0 -0
  37. data/app/styles/FiraGO/FiraGO-BoldItalic.woff +0 -0
  38. data/app/styles/FiraGO/FiraGO-Book.woff +0 -0
  39. data/app/styles/FiraGO/FiraGO-BookItalic.woff +0 -0
  40. data/app/styles/FiraGO/FiraGO-HeavyItalic.woff +0 -0
  41. data/app/styles/FiraGO/FiraGO-SemiBold.woff +0 -0
  42. data/app/styles/FiraGO/FiraGO-SemiBoldItalic.woff +0 -0
  43. data/app/styles/FiraGO/FiraGO.scss +48 -0
  44. data/app/styles/Vidaloka/Vidaloka-Regular.woff +0 -0
  45. data/app/styles/Vidaloka/Vidaloka.scss +6 -0
  46. data/app/styles/application.scss +141 -0
  47. data/app/styles/dashboard.scss +139 -0
  48. data/app/styles/editor.scss +70 -0
  49. data/app/styles/helpers.scss +45 -0
  50. data/app/views/application/yarii_extra_head.html.erb +3 -0
  51. data/app/views/layouts/yarii_editor/application.html.erb +21 -0
  52. data/app/views/yarii_editor/application/render_engine_stylesheet_tag.html.erb +1 -0
  53. data/app/views/yarii_editor/dashboard/_card.html.erb +3 -0
  54. data/app/views/yarii_editor/dashboard/_extras.html.erb +1 -0
  55. data/app/views/yarii_editor/dashboard/_inner_list.html.erb +42 -0
  56. data/app/views/yarii_editor/dashboard/_list.html.erb +34 -0
  57. data/app/views/yarii_editor/dashboard/index.html.erb +18 -0
  58. data/app/views/yarii_editor/documents/modal.html.erb +78 -0
  59. data/app/views/yarii_editor/editor/_dropdown.html.erb +14 -0
  60. data/app/views/yarii_editor/editor/_markdown.html.erb +13 -0
  61. data/app/views/yarii_editor/editor/_text.html.erb +13 -0
  62. data/app/views/yarii_editor/editor/_textarea.html.erb +13 -0
  63. data/app/views/yarii_editor/model_cards/_hashtags.html.erb +5 -0
  64. data/app/views/yarii_editor/model_cards/_page.html.erb +18 -0
  65. data/app/views/yarii_editor/model_cards/_post.html.erb +17 -0
  66. data/app/views/yarii_editor/model_cards/_standard_footer_buttons.html.erb +20 -0
  67. data/app/views/yarii_editor/publish/commit.html.erb +45 -0
  68. data/app/views/yarii_editor/shared/_navbar.html.erb +38 -0
  69. data/app/views/yarii_editor/shared/_publishing_menu.html.erb +42 -0
  70. data/config/initializers/assets.rb +1 -0
  71. data/config/routes.rb +16 -0
  72. data/config/webpack/development.js +5 -0
  73. data/config/webpack/environment.js +3 -0
  74. data/config/webpack/production.js +5 -0
  75. data/config/webpack/staging.js +5 -0
  76. data/config/webpack/test.js +5 -0
  77. data/config/webpacker.yml +109 -0
  78. data/db/migrate/20190923000809_create_yarii_sites.rb +12 -0
  79. data/db/migrate/20191014203116_add_git_repo_path_to_yarii_sites.rb +5 -0
  80. data/db/migrate/20200420221048_add_preview_build_command_to_yarii_sites.rb +5 -0
  81. data/lib/tasks/yarii_editor_tasks.rake +66 -0
  82. data/lib/yarii-editor.rb +24 -0
  83. data/lib/yarii-editor/engine.rb +22 -0
  84. data/lib/yarii-editor/setup_current_site.rb +20 -0
  85. data/lib/yarii-editor/setup_current_user.rb +13 -0
  86. data/lib/yarii-editor/version.rb +3 -0
  87. metadata +172 -0
@@ -0,0 +1,139 @@
1
+ html {
2
+ overflow: hidden;
3
+ }
4
+
5
+ .carousel-frame {
6
+ // background: #fafafa;
7
+ padding: 0px;
8
+ // border-radius: 3px;
9
+ // border: 1px solid #ddd;
10
+ width: 100vw;
11
+
12
+ /* .level {
13
+ border-bottom: 4px solid #363636;
14
+ padding-bottom: 8px;
15
+ } */
16
+ .scroll-item > .level {
17
+ padding: 0 10px;
18
+ }
19
+ @supports (-webkit-filter: blur(0)) and (not (-moz-transform: translate(0,0))) {
20
+ .scroll-item > .level {
21
+ padding-right: 18px;
22
+ }
23
+ }
24
+ .level .title {
25
+ text-shadow: 2px 5px 2px rgba(0,0,0,0.1);
26
+ line-height: 1;
27
+ }
28
+ }
29
+
30
+ .scroll {
31
+ display: flex;
32
+ // align-items: top;
33
+ overflow-x: auto;
34
+ overflow-y: hidden;
35
+ width: 100%;
36
+ -webkit-overflow-scrolling: touch;
37
+
38
+ height: calc(100vh - 64px);
39
+ }
40
+
41
+ ul.scroll {
42
+ margin: 0;
43
+ list-style-type: none;
44
+ }
45
+
46
+ .scroll-item {
47
+ flex: 0 0 49vw;
48
+ @media (min-width: 1000px) {
49
+ flex: 0 0 32.5vw;
50
+ }
51
+ @media (min-width: 1600px) {
52
+ flex: 0 0 24.5vw;
53
+ }
54
+ height: 100%;
55
+ position: relative;
56
+ .vertical-scroll {
57
+ position: absolute;
58
+ top: 3rem;
59
+ right: 0;
60
+ bottom: 2px;
61
+ left: 0;
62
+ padding: 10px;
63
+ padding-top: 0;
64
+ padding-bottom: 20vh;
65
+ overflow-y: auto;
66
+ }
67
+ }
68
+
69
+ .vertical-scroll::-webkit-scrollbar {
70
+ width: 8px;
71
+ height: auto;
72
+ background-color: $beige-lighter;
73
+ border-radius: 4px;
74
+ }
75
+
76
+ /* Add a thumb */
77
+ .vertical-scroll::-webkit-scrollbar-thumb {
78
+ background-color: $beige-medium;
79
+ border-radius: 4px;
80
+ box-shadow: 0px 1px 1px rgba(0,0,0,0.15);
81
+ }
82
+
83
+ @media (max-width: 600px) {
84
+ .scroll-item {
85
+ flex: 0 0 99vw;
86
+ }
87
+ }
88
+
89
+ img {
90
+ object-fit: contain;
91
+ width: 100%;
92
+ height: 100%;
93
+ }
94
+
95
+ .scroll-item .card {
96
+ margin-bottom: 15px;
97
+ }
98
+ .card time {
99
+ color: $green;
100
+ font-size: 0.85em;
101
+ }
102
+
103
+ .card {
104
+ border-top-left-radius: 5px;
105
+ border-top-right-radius: 5px;
106
+ word-break: break-word;
107
+
108
+ &.tagged-draft {
109
+ border-top: 10px solid $orange;
110
+ }
111
+ &.tagged-queued {
112
+ border-top: 10px solid lighten($blue, 20%);
113
+ }
114
+ &.tagged-published {
115
+ border-top: 10px solid $green;
116
+ }
117
+ &.dimmed {
118
+ opacity: 0.4;
119
+ pointer-events: none;
120
+ }
121
+
122
+ .card-image {
123
+ border-bottom: $card-header-border-bottom;
124
+ }
125
+ }
126
+
127
+ @supports (scroll-snap-align: start) {
128
+ /* modern scroll snap points */
129
+ .scroll {
130
+ scroll-snap-type: x mandatory;
131
+ }
132
+ .scroll-item {
133
+ scroll-snap-align: start;
134
+ }
135
+ }
136
+
137
+ .carousel-frame {
138
+ margin-top: 4em;
139
+ }
@@ -0,0 +1,70 @@
1
+ .editor-toolbar button {
2
+ font-size: 0.85em;
3
+ color: $beige-dark;
4
+ }
5
+
6
+ .CodeMirror-fullscreen:not(.CodeMirror-sided) {
7
+ padding-top: 30px;
8
+ padding-left: 20vw;
9
+ padding-right: 20vw;
10
+ background: lighten($lightgreen, 4%);
11
+ .CodeMirror-scroll {
12
+ padding: 20px;
13
+ background: $white;
14
+ box-shadow: 0px 15px 40px rgba(0,0,0,0.13);
15
+ }
16
+
17
+ @media (max-width: 767px) {
18
+ padding-left: 10vw;
19
+ padding-right: 10vw;
20
+ }
21
+ @media (max-width: 415px) {
22
+ padding-left: 5vw;
23
+ padding-right: 5vw;
24
+ }
25
+ }
26
+
27
+ .CodeMirror:not(.CodeMirror-fullscreen) .CodeMirror-scroll {
28
+ max-height: 42vh;
29
+ }
30
+
31
+ .CodeMirror-placeholder {
32
+ opacity: 0.2;
33
+ }
34
+
35
+ .cm-s-easymde {
36
+ .cm-header {
37
+ color: $green;
38
+ }
39
+ .cm-strong, .cm-em {
40
+ color: $darkgreen;
41
+ }
42
+ .cm-link, .cm-url {
43
+ color: $darkorange;
44
+ }
45
+ .cm-quote {
46
+ color: $blue;
47
+ }
48
+ }
49
+
50
+ .modal-card-body > form.dimmed {
51
+ opacity: 0.3;
52
+ pointer-events: none;
53
+ }
54
+
55
+ @keyframes pulsate {
56
+ 0% {opacity: 0.5;}
57
+ 50% {opacity: 1.0;}
58
+ 100% {opacity: 0.5;}
59
+ }
60
+
61
+ .modal-foot-status {
62
+ flex-grow: 1;
63
+ color: $white;
64
+ font-style: italic;
65
+ font-weight: bold;
66
+ &.in-progress {
67
+ animation: pulsate 1.2s ease-in-out;
68
+ animation-iteration-count: infinite;
69
+ }
70
+ }
@@ -0,0 +1,45 @@
1
+ /* Add Tailwindcss-ish margin and padding helpers */
2
+
3
+ $sizes:
4
+ 0 0,
5
+ 1 0.25,
6
+ 2 0.5,
7
+ 3 0.75,
8
+ 4 1,
9
+ 5 1.25,
10
+ 6 1.5,
11
+ 8 2,
12
+ 10 2.5,
13
+ 12 3,
14
+ 16 4,
15
+ 20 5,
16
+ 24 6,
17
+ 32 8,
18
+ 40 10,
19
+ 48 12,
20
+ 56 14,
21
+ 64 16;
22
+ $positions: ('top','left','bottom','right');
23
+
24
+ @each $index, $size in $sizes {
25
+ @each $position in $positions {
26
+ .m#{str-slice($position, 0, 1)}-#{$index} {
27
+ margin-#{$position}: $size + rem;
28
+ }
29
+ .p#{str-slice($position, 0, 1)}-#{$index} {
30
+ padding-#{$position}: $size + rem;
31
+ }
32
+ .-m#{str-slice($position, 0, 1)}-#{$index} {
33
+ margin-#{$position}: -$size + rem;
34
+ }
35
+ }
36
+ }
37
+
38
+ .m-auto {
39
+ margin: auto;
40
+ }
41
+ .mx-auto {
42
+ margin-left: auto;
43
+ margin-right: auto;
44
+ }
45
+
@@ -0,0 +1,3 @@
1
+ <%
2
+ # Copy this file to your main Rails views folder and add customizations there
3
+ %>
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Yarii</title>
7
+ <%= csrf_meta_tags %>
8
+ <%= csp_meta_tag %>
9
+
10
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.1.7/css/fork-awesome.min.css" integrity="sha256-gsmEoJAws/Kd3CjuOQzLie5Q3yshhvmo7YNtBG7aaEY=" crossorigin="anonymous" />
11
+ <link type="text/css" rel="stylesheet" href="//fast.fonts.net/cssapi/6fded4e3-4758-4bb9-b529-f0ebadd8eb84.css"/>
12
+ <%= ::ApplicationController.render :yarii_extra_head, layout: nil %>
13
+ <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
14
+ <%= stylesheet_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
15
+ </head>
16
+
17
+ <body>
18
+ <%= render 'yarii_editor/shared/navbar' %>
19
+ <%= yield %>
20
+ </body>
21
+ </html>
@@ -0,0 +1 @@
1
+ <%= stylesheet_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
@@ -0,0 +1,3 @@
1
+ <div data-controller="card" data-card-publishing-menu-path="<%= yarii_editor.publishing_menu_path %>" id="<%= content_model_type %>-<%= model.id %>" class="card <%= "tagged-#{status_of_document(model)}" %>">
2
+ <%= render 'yarii_editor/model_cards/' + model_class.name.underscore, model: model, content_model_type: content_model_type %>
3
+ </div>
@@ -0,0 +1 @@
1
+ <!-- Host app can overwrite this partial to include plugin extras -->
@@ -0,0 +1,42 @@
1
+ <%
2
+ model_type = local_assigns[:model_type]
3
+ model_details = local_assigns[:model_details]
4
+ model_class = model_details[:class_name].constantize
5
+
6
+ current_page = (params[:page] || 1).to_i
7
+ pagination = 15
8
+ page_start = pagination * (current_page - 1)
9
+ page_end = pagination * current_page
10
+
11
+ models = if model_details[:datafile]
12
+ model_class.all(model_details[:datafile])[page_start...page_end]
13
+ else
14
+ order_by = model_details[:order_by]&.to_sym || :posted_datetime
15
+ order_direction = model_details[:order_direction]&.to_sym || :desc
16
+ if model_details[:filter] and model_details[:filter][:hashtags]
17
+ model_class.all(order_by: order_by, order_direction: order_direction).select do |model|
18
+ if model.respond_to?(:tags) and model.tags.present?
19
+ tags = model.tags.is_a?(Array) ? model.tags : model.tags.split(' ')
20
+ (tags & model_details[:filter][:hashtags]).present?
21
+ end
22
+ end[page_start...page_end]
23
+ elsif model_details[:filter] and model_details[:filter][:categories]
24
+ model_class.all(order_by: order_by, order_direction: order_direction).select do |model|
25
+ categories = model.as_json['category'] || model.as_json['categories']
26
+ if categories.present?
27
+ categories = categories.is_a?(Array) ? categories : categories.split(' ')
28
+ (categories & model_details[:filter][:categories]).present?
29
+ end
30
+ end[page_start...page_end]
31
+ else
32
+ model_class.all(order_by: order_by, order_direction: order_direction)[page_start...page_end]
33
+ end
34
+ end
35
+ if models.present?
36
+ models.each do |model| %>
37
+ <%= render 'yarii_editor/dashboard/card', model_class: model_class, model: model, content_model_type: model_type %>
38
+ <%
39
+ end
40
+ else %>
41
+ <p class="has-text-centered" data-list-done="true"><em>All done!</em></p>
42
+ <% end %>
@@ -0,0 +1,34 @@
1
+ <%
2
+ model_type = local_assigns[:model_type]
3
+ model_details = local_assigns[:model_details]
4
+ model_class = model_details[:class_name].constantize
5
+ model_title = model_details.fetch(:title, model_class.name.titleize).pluralize
6
+
7
+ current_page = (params[:page] || 1).to_i
8
+ %>
9
+ <li class="scroll-item">
10
+ <div class="level is-mobile">
11
+ <div class="level-left">
12
+ <h3 class="title level-item"><%= model_title %></h3>
13
+ </div>
14
+ <div class="level-right">
15
+ <button data-controller="new-document" data-action="new-document#open" data-new-document-path="<%= yarii_editor.new_document_path(content_model: model_type) %>" class="level-item button is-primary">
16
+ <span class="icon"><i class="fa fa-plus"></i></span>
17
+ <span>New</span>
18
+ </button>
19
+ </div>
20
+ </div>
21
+
22
+ <div class="vertical-scroll">
23
+ <div id="list-<%= model_type %>">
24
+ <%= render 'inner_list', model_type: model_type, model_details: model_details %>
25
+
26
+ <div data-controller="list-loading" id="loadmore-<%= model_type %>" class="has-text-centered">
27
+ <%= link_to dashboard_list_path(model_type: model_type, page: current_page + 1), data: {action: 'list-loading#more'}, class: 'button is-primary' do %>
28
+ <span>Load More</span>
29
+ <span class="icon"><i class="fa fa-chevron-circle-down" aria-hidden="true"></i></span>
30
+ <% end %>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ </li>
@@ -0,0 +1,18 @@
1
+ <!-- <div data-controller="testengine"></div> -->
2
+ <div class="carousel-frame">
3
+ <ul class="scroll">
4
+ <% @custom_lists.each do |model_details| %>
5
+ <%= render 'list', model_type: model_details[:model_type], model_details: model_details %>
6
+ <% end %>
7
+ <% current_site.content_models.each do |model_type, model_details| %>
8
+ <%= render 'list', model_type: model_type, model_details: model_details %>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+
13
+ <div id="editor-modal-wrapper">
14
+ </div>
15
+ <div id="commit-modal-wrapper">
16
+ </div>
17
+
18
+ <%= render 'extras' %>
@@ -0,0 +1,78 @@
1
+ <%-
2
+ path = nil
3
+ if action_name == "new"
4
+ path = yarii_editor.create_document_path(content_model: params[:content_model])
5
+ http_method = "post"
6
+ else
7
+ if params[:key_path]
8
+ path = yarii_editor.update_document_path(@doc, content_model: params[:content_model], key_path: params[:key_path])
9
+ else
10
+ path = yarii_editor.update_document_path(@doc, content_model: params[:content_model])
11
+ end
12
+ http_method = "put"
13
+ end
14
+ %>
15
+ <div
16
+ data-controller="editor-modal"
17
+ data-editor-modal-http-method="<%= http_method %>"
18
+ data-editor-modal-path="<%= path %>"
19
+ data-editor-modal-content-model="<%= params[:content_model] %>"
20
+ data-editor-modal-model-id="<%= params[:id] %>"
21
+ data-editor-modal-publishing-menu-path="<%= yarii_editor.publishing_menu_path %>"
22
+ id="editor-modal"
23
+ class="modal is-active"
24
+ >
25
+ <div class="modal-background"></div>
26
+ <div class="modal-card">
27
+ <header class="modal-card-head">
28
+ <p class="modal-card-title"><%= @doc_heading %></p>
29
+ <button data-action="editor-modal#cancel" class="delete" aria-label="close"></button>
30
+ </header>
31
+ <section class="modal-card-body">
32
+ <%= form_tag do %>
33
+ <% current_site.content_models[params[:content_model].to_sym][:primary_fields].each do |field| %>
34
+ <%= add_field field[:field_type], {
35
+ variable: field[:field_name],
36
+ label: field[:label],
37
+ placeholder: field[:placeholder],
38
+ class_name: field[:class_names]
39
+ } %>
40
+ <% end %>
41
+
42
+ <div class="mb-2 has-text-right"><button data-action="editor-modal#showAdditionalFields" class="button is-text is-small">Additional Fields…</button></div>
43
+ <div data-target="editor-modal.additionalFields" class="is-hidden mb-4">
44
+ <div class="field">
45
+ <label class="label">Publish to Public?</label>
46
+ <div class="control">
47
+ <%= hidden_field_tag "#{params[:content_model]}[published]", false %>
48
+ <%= check_box_tag "#{params[:content_model]}[published]", true, @doc.published %>
49
+ </div>
50
+ </div>
51
+ <% current_site.content_models[params[:content_model].to_sym][:additional_fields].each do |field| %>
52
+ <%= add_field field[:field_type], {
53
+ variable: field[:field_name],
54
+ label: field[:label],
55
+ placeholder: field[:placeholder],
56
+ class_name: field[:class_names]
57
+ } %>
58
+ <% end %>
59
+ </div>
60
+
61
+ <% current_site.content_models[params[:content_model].to_sym][:content_fields].each do |field| %>
62
+ <%= add_field field[:field_type], {
63
+ variable: field[:field_name],
64
+ label: field[:label],
65
+ placeholder: field[:placeholder],
66
+ class_name: field[:class_names]
67
+ } %>
68
+ <% end %>
69
+ <% end %>
70
+ </section>
71
+ <footer class="modal-card-foot">
72
+ <div data-target="editor-modal.status" class="modal-foot-status"></div>
73
+ <button data-action="editor-modal#cancel" class="button is-dark is-text">Cancel</button>
74
+ &nbsp;
75
+ <button data-action="editor-modal#save" class="button is-success">Save Changes</button>
76
+ </footer>
77
+ </div>
78
+ </div>