megatron 0.0.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.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +24 -0
  5. data/app/controllers/megatron/errors_controller.rb +11 -0
  6. data/app/helpers/megatron/application_helper.rb +59 -0
  7. data/app/helpers/megatron/breadcrumb_helper.rb +19 -0
  8. data/app/helpers/megatron/button_helper.rb +42 -0
  9. data/app/helpers/megatron/example_helper.rb +111 -0
  10. data/app/helpers/megatron/form_helper.rb +29 -0
  11. data/app/helpers/megatron/grid_helper.rb +60 -0
  12. data/app/helpers/megatron/layout_helper.rb +66 -0
  13. data/app/helpers/megatron/navigation_helper.rb +68 -0
  14. data/app/helpers/megatron/tab_helper.rb +27 -0
  15. data/app/helpers/megatron/toggler_help.rb +7 -0
  16. data/app/views/layouts/megatron/application.html.slim +61 -0
  17. data/app/views/layouts/megatron/errors.html.slim +20 -0
  18. data/app/views/megatron/errors/bad_request.html.slim +2 -0
  19. data/app/views/megatron/errors/forbidden.html.slim +2 -0
  20. data/app/views/megatron/errors/internal_server_error.html.slim +2 -0
  21. data/app/views/megatron/errors/method_not_allowed.html.slim +2 -0
  22. data/app/views/megatron/errors/not_acceptable.html.slim +2 -0
  23. data/app/views/megatron/errors/not_found.html.slim +2 -0
  24. data/app/views/megatron/errors/not_implemented.html.slim +2 -0
  25. data/app/views/megatron/errors/unauthorized.html.slim +2 -0
  26. data/app/views/megatron/errors/unprocessable_entity.html.slim +2 -0
  27. data/app/views/megatron/shared/_main_content.html.slim +4 -0
  28. data/app/views/megatron/shared/_primary_nav.html.slim +6 -0
  29. data/config/routes.rb +2 -0
  30. data/lib/megatron.rb +9 -0
  31. data/lib/megatron/engine.rb +12 -0
  32. data/lib/megatron/form.rb +129 -0
  33. data/lib/megatron/version.rb +3 -0
  34. data/lib/tasks/megatron_tasks.rake +4 -0
  35. metadata +134 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c29978c3775d1ef4eacebb255c21e717d30e7baf
4
+ data.tar.gz: 596acec8c262a2f155bc624185727a8d221ca7c6
5
+ SHA512:
6
+ metadata.gz: eb0c1505b3782bcf2b6f2cffe6c8fe4c0cfda5f4b4d13f0598c8db6df5e197eec1c99e34efedd90a17efbd9c9f0199fd6c622070ce89696aa95de47c4e2826d4
7
+ data.tar.gz: 153f235601841477756ab8885f7cf4a6b53a51e750ebf66a4987bccfc37b909560d0a7b8627f914b308bd6f84582605fcdfa0ca33ea0291ba06fe2437029be0a
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Jerome Gravel-Niquet
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = Megatron
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Megatron'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+ load 'rails/tasks/statistics.rake'
20
+
21
+
22
+
23
+ Bundler::GemHelper.install_tasks
24
+
@@ -0,0 +1,11 @@
1
+ class Megatron::ErrorsController < ApplicationController
2
+ include Gaffe::Errors
3
+ layout 'megatron/errors'
4
+
5
+ # Render the correct template based on the exception “standard” code.
6
+ # Eg. For a 404 error, the `errors/not_found` template will be rendered.
7
+ def show
8
+ # Here, the `@exception` variable contains the original raised error
9
+ render "megatron/errors/#{@rescue_response}", status: @status_code
10
+ end
11
+ end
@@ -0,0 +1,59 @@
1
+ module Megatron
2
+ module ApplicationHelper
3
+ def megatron_asset_path(asset)
4
+ url = Rails.env.production? && !ENV['LOCAL_MEGATRON'] ? "https://app.compose.io/assets/megatron/#{asset}" : "/assets/megatron/#{asset}"
5
+ end
6
+
7
+ def megatron_assets_tags
8
+ favicon_link_tag(megatron_asset_path('favicon.ico')) +
9
+ stylesheet_link_tag(megatron_asset_path('megatron')) +
10
+ javascript_include_tag(megatron_asset_path('megatron'))
11
+ end
12
+
13
+ def icon(name)
14
+ content_tag(:span, class: "#{name}_icon", 'aria-hidden' => true) { }
15
+ end
16
+
17
+ def options_from_args(args)
18
+ if args.last.is_a? Hash
19
+ args.pop
20
+ else
21
+ {}
22
+ end
23
+ end
24
+
25
+ def embed_svg(filename, options = {})
26
+ group = 0
27
+ file = File.read(Engine.root.join('app', 'assets', 'images', filename))
28
+ .gsub(/<!--.+-->/, '')
29
+ .gsub(/^\t{2,}\s*<\/?g>/, '')
30
+ .gsub(/width=".+?"/, 'width="312"')
31
+ .gsub(/\sheight.+$/, '')
32
+ .gsub(/\t/, ' ')
33
+ .gsub(/\n{3,}/m, "\n")
34
+ .gsub(/^\s{2}<g>.+?^\s{2}<\/g>/m) { |g|
35
+ g.gsub(/^\s{4,}\s+/, ' ')
36
+ }
37
+ .gsub(/^<g>.+?^<\/g>/m) { |g|
38
+ group += 1
39
+ count = 0
40
+ g.gsub(/^\s{2}<g>/) { |g|
41
+ count += 1
42
+ %Q{ <g id="group-#{group}-cube-#{count}">}
43
+ }
44
+ }
45
+ # doc = Nokogiri::HTML::DocumentFragment.parse file
46
+ # svg = doc.at_css 'svg'
47
+ # if options[:class].present?
48
+ # svg['class'] = options[:class]
49
+ # end
50
+ file.html_safe
51
+ end
52
+
53
+ def add_class(string, *classes)
54
+ string ||= ''
55
+ string << " #{classes.join(' ')}"
56
+ string
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,19 @@
1
+ module Megatron
2
+ module BreadcrumbHelper
3
+ class Breadcrumbs < BlockHelpers::Base
4
+ def crumb(text, href = nil, options={})
5
+ options[:class] = add_class(options[:class], 'breadcrumb')
6
+
7
+ if href.nil?
8
+ content_tag(:span, options) { text }
9
+ else
10
+ link_to(href, options){ text }
11
+ end
12
+ end
13
+
14
+ def display(body)
15
+ content_tag(:nav, class: 'breadcrumbs') { body }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,42 @@
1
+ module Megatron
2
+ module ButtonHelper
3
+ def button(text, options = {})
4
+ tag_name = options[:href].present? ? :a : :button
5
+ opts = {
6
+ class: button_classes(options)
7
+ }
8
+ opts[:href] = options[:href] if options[:href]
9
+ content_tag tag_name, opts do
10
+ if options[:icon]
11
+ concat icon(options[:icon])
12
+ concat ' '
13
+ end
14
+ concat text
15
+ end
16
+ end
17
+
18
+ def primary_button(text, options = {})
19
+ button(text, options.merge(type: :primary))
20
+ end
21
+
22
+ def destroy_button(text, options = {})
23
+ button(text, options.merge(type: :destroy))
24
+ end
25
+
26
+ def primary_destroy_button(text, options={})
27
+ button(text, options.merge(type: :primary_destroy))
28
+ end
29
+
30
+ def text_button(text, options = {})
31
+ button(text, options.merge(type: :text))
32
+ end
33
+
34
+ def button_classes(options)
35
+ button_type = options[:type] || options[:color]
36
+ classes = button_type.present? ? ["#{button_type.to_s.gsub('_','-')}-btn"] : ["btn"]
37
+ classes << options[:size].to_s.gsub(/xlarge/, 'x-large') if options[:size]
38
+ classes << 'disabled' if options[:disabled]
39
+ classes
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,111 @@
1
+ module Megatron
2
+ module ExampleHelper
3
+
4
+ DEMO_DEFAULTS = {
5
+ type: :slim,
6
+ class: 'demo',
7
+ tag: :div
8
+ }
9
+
10
+ def demo(title=nil, options={}, &block)
11
+ if title.is_a? Hash
12
+ options = title
13
+ title = nil
14
+ end
15
+
16
+ options = DEMO_DEFAULTS.merge(options)
17
+
18
+ content_tag options[:tag], class: options[:class] do
19
+ rand = SecureRandom.hex(5)
20
+
21
+ concat content_tag(:header, class: 'demo-header') {
22
+ if title
23
+ concat content_tag(:h3, class: 'demo-heading', id: heading_id(title)){ title }
24
+ end
25
+
26
+ if options[:toggle]
27
+ concat content_tag(:a, href: '#', class: 'demo-source-toggle', 'data-toggle' => "#source-#{rand}, #demo-#{rand}"){ 'source' }
28
+ else
29
+ concat content_tag(:a, href: '#', class: 'demo-source-toggle', 'data-toggle' => "#source-#{rand}"){ 'source' }
30
+ end
31
+ }
32
+
33
+ concat code(options[:type], id: "source-#{rand}", class: 'hidden') {
34
+ lines = extract_code(block)
35
+ }
36
+ concat content_tag(:div, id: "demo-#{rand}", &block)
37
+ end
38
+ end
39
+
40
+ def demo_box(title, options={}, &block)
41
+ options[:class] = "#{options[:class]} demo-box"
42
+ options[:class] << ' padded' unless options[:padded] == false
43
+ options[:toggle] = true
44
+ demo(title, options, &block)
45
+ end
46
+
47
+ def strip_description(lines)
48
+ start = lines.find_index{|x| x=~/=\s*demo_description/}
49
+ if start
50
+ spaces = spaces_at_beginning(lines[start])
51
+ count = lines[start+1 .. -1].take_while { |line|
52
+ spaces_at_beginning(line) > spaces
53
+ }.size
54
+
55
+ lines.slice!(start..start+count)
56
+ end
57
+ lines
58
+ end
59
+
60
+ # Ouptut a linkable heading
61
+ #
62
+ def heading(*args)
63
+ content = args.pop
64
+
65
+ # Default to h3
66
+ tag = args.pop || :h3
67
+ content_tag(tag.to_sym, class: 'link-heading', id: heading_id(content)) do
68
+ concat content
69
+ end
70
+ end
71
+
72
+ def heading_id(title)
73
+ title.gsub(/\W/, '-').downcase
74
+ end
75
+
76
+ def demo_description(&block)
77
+ content_tag :div, class: 'demo-description', &block
78
+ end
79
+
80
+ def code(lang, options = {}, &block)
81
+ classes = ["language-#{lang}"]
82
+ classes << options.delete(:class) if options[:class]
83
+ content_tag(:pre, options.merge(class: classes), &block)
84
+ end
85
+
86
+ def extract_code(block)
87
+ filename, start_line = block.source_location
88
+ lines = File.readlines(filename)
89
+
90
+ start_line -= 1
91
+
92
+ until lines[start_line] =~ /demo_box/
93
+ start_line += 1
94
+ end
95
+
96
+ spaces = spaces_at_beginning(lines[start_line])
97
+
98
+ lines = lines[start_line + 1 .. -1]
99
+
100
+ lines = lines.take_while { |line|
101
+ spaces_at_beginning(line) > spaces || line.match(/^\n\s*$/)
102
+ }
103
+ .map { |line| line.sub(%r{^\s{#{spaces + 2}}}, '') }
104
+ strip_description(lines).join("")
105
+ end
106
+
107
+ def spaces_at_beginning(str)
108
+ str[/\A */].size
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,29 @@
1
+ module Megatron
2
+ module FormHelper
3
+ def table_form_for(record, options = {}, &block)
4
+ form_for record, options do |f|
5
+ table_form_tag f, &block
6
+ end
7
+ end
8
+
9
+ def table_form_tag(form = nil)
10
+ form.style = 'table' if form
11
+ content_tag :div, class: ['table', 'table-form'] do
12
+ yield form if block_given?
13
+ end
14
+ end
15
+
16
+ def stacked_form_for(record, options = {}, &block)
17
+ form_for record, options do |f|
18
+ stacked_form_tag f, &block
19
+ end
20
+ end
21
+
22
+ def stacked_form_tag(form = nil)
23
+ form.style = 'stacked' if form
24
+ content_tag :div, class: 'stacked-form' do
25
+ yield form if block_given?
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,60 @@
1
+ module Megatron
2
+ module GridHelper
3
+ class Grid < BlockHelpers::Base
4
+
5
+ DEFAULTS = {
6
+ tag: :div,
7
+ match_gutters: false
8
+ }
9
+
10
+ def initialize(options = {})
11
+ @options = DEFAULTS.merge(options)
12
+ end
13
+
14
+ def display(body)
15
+ content_tag(@options[:tag], class: grid_classes) { body }
16
+ end
17
+
18
+ def cell(*args, &block)
19
+ options = options_from_args(args)
20
+ options[:tag] ||= :div
21
+ content_tag options[:tag], class: cell_classes(args, options), &block
22
+ end
23
+
24
+ def cell_classes(args, options={})
25
+ classes = ['grid-cell']
26
+ if !args.empty? or !options.empty?
27
+ classes << width(*args) if !args.empty?
28
+ classes << options[:class] if options[:class]
29
+
30
+ classes << add_media_classes(:xsmall, options[:xsmall]) if options[:xsmall]
31
+ classes << add_media_classes(:small, options[:small]) if options[:small]
32
+ classes << add_media_classes(:medium, options[:medium]) if options[:medium]
33
+ classes << add_media_classes(:large, options[:large]) if options[:large]
34
+ classes << add_media_classes(:xlarge, options[:xlarge]) if options[:xlarge]
35
+ end
36
+ classes
37
+ end
38
+
39
+ def add_media_classes(breakpoint, sizes)
40
+ sizes.empty? ? '' : width(*[breakpoint, *sizes])
41
+ end
42
+
43
+ def grid_classes
44
+ classes = ['grid']
45
+ classes << "align-#{@options[:valign]}" if @options[:valign]
46
+ classes << "align-#{@options[:align]}" if @options[:align]
47
+ classes << 'match-gutters' if @options[:match_gutters]
48
+ if @options[:gutters]
49
+ if @options[:gutters].to_s == 'none'
50
+ @options[:gutters] = 'no'
51
+ end
52
+ classes << "#{@options[:gutters]}-gutter" unless @options[:gutters].to_s == 'medium'
53
+ end
54
+ classes << @options[:class] if @options[:class]
55
+ classes
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,66 @@
1
+ module Megatron
2
+ module LayoutHelper
3
+
4
+ def megatron_layout(layout='application', options={}, &block)
5
+ @custom_nav = options[:custom_nav]
6
+ yield
7
+ render template: "layouts/megatron/#{layout}"
8
+ end
9
+
10
+ def page_header(title = nil, &block)
11
+ header :page_header, title, &block
12
+ end
13
+
14
+ def main_header(title = nil, &block)
15
+ header :main_header, title, &block
16
+ end
17
+
18
+ def header(type, title = nil, &block)
19
+ if title
20
+ content_for(type) { content_tag :h2, title }
21
+ elsif !title && block_given?
22
+ content_for type, &block
23
+ end
24
+ end
25
+
26
+ def main(options={}, &block)
27
+ @wide_layout = options[:wide]
28
+ content_for :main, &block
29
+ end
30
+
31
+ def sidebar(&block)
32
+ content_for :sidebar, &block
33
+ end
34
+
35
+ def javascripts(&block)
36
+ content_for :javascripts, &block
37
+ end
38
+
39
+ def stylesheets(&block)
40
+ content_for :stylesheets, &block
41
+ end
42
+
43
+ def size(*args, &block)
44
+ options = options_from_args(args)
45
+ tag = options[:tag] || :div
46
+ content_tag tag, class: [width(*args), options[:class]], &block
47
+ end
48
+
49
+ def width(*sizes)
50
+ media = ''
51
+ sizes.flatten!
52
+ if sizes.first.is_a?(Symbol) || sizes.first.is_a?(String)
53
+ media = "#{sizes.shift.to_s.sub(/^x/, 'x-')}-"
54
+ end
55
+
56
+ classes = "#{media}#{sizes[0].to_words}-of-#{sizes[1].to_words}"
57
+
58
+ if sizes.last.is_a? Hash
59
+ classes << " #{sizes.last[:class]}"
60
+ end
61
+
62
+ classes
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,68 @@
1
+ module Megatron
2
+ module NavigationHelper
3
+ class Nav < BlockHelpers::Base
4
+ def item(text, href, options = {})
5
+ options[:class] = add_class(options[:class], "#{nav_class}-item")
6
+ nav_icon = options.delete(:icon)
7
+ link_to href, options do
8
+ concat icon(nav_icon)
9
+ concat ' '
10
+ if options[:link_label] == false
11
+ concat icon_label(text)
12
+ else
13
+ concat link_label(text)
14
+ end
15
+ end
16
+ end
17
+
18
+ def link_label(text)
19
+ content_tag(:span, class: 'link_label icon_label') { text }
20
+ end
21
+
22
+ def icon_label(text)
23
+ content_tag(:span, class: 'icon_label') { text }
24
+ end
25
+ end
26
+
27
+ class PrimaryNav < Nav
28
+ def nav_class
29
+ 'primary_nav'
30
+ end
31
+
32
+ def display(body)
33
+ content_for(:primary_nav) { body }
34
+ end
35
+
36
+ def sign_out(href='/session/destroy', options={})
37
+ content_tag :div, class: 'primary_nav-top' do
38
+ options[:data] = {
39
+ trigger: 'dialog',
40
+ title: 'Are you sure you want to sign out?',
41
+ message: 'Click cancel if you want to stay',
42
+ continue: 'Sign out',
43
+ close: 'Cancel',
44
+ follow: href,
45
+ }.merge(options[:data] || {})
46
+
47
+ options[:text] ||= 'Sign out'
48
+ options[:icon] ||= :power
49
+ options[:link_label] = false
50
+
51
+ concat item(options[:text], '#', options)
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ class SecondaryNav < Nav
58
+ def nav_class
59
+ 'secondary_nav'
60
+ end
61
+
62
+ def display(body)
63
+ content_for(:secondary_nav) { body }
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,27 @@
1
+ module Megatron
2
+ module TabHelper
3
+ class Tabs < BlockHelpers::Base
4
+ def tab(text, href)
5
+ content_tag :a, class: 'tab', href: href do
6
+ text
7
+ end
8
+ end
9
+
10
+ def tab_button(text, href)
11
+ content_tag :a, class: %w{tab-btn btn medium}, href: href do
12
+ text
13
+ end
14
+ end
15
+
16
+ def display(body)
17
+ content_tag(:nav, class: 'tabs') { body }
18
+ end
19
+ end
20
+
21
+ class BoxTabs < Tabs
22
+ def display(body)
23
+ content_tag(:nav, class: 'box-tabs') { body }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ module Megatron
2
+ module TogglerHelper
3
+ class Toggler < BlockHelpers::Base
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,61 @@
1
+ <!DOCTYPE html>
2
+ html
3
+ head
4
+ - if @title.present?
5
+ title #{@title} | Compose
6
+ - else
7
+ title Compose
8
+ meta name="viewport" content="width=device-width,initial-scale=1"
9
+ meta charset="utf-8"
10
+ = csrf_meta_tags
11
+ = megatron_assets_tags
12
+ = yield :stylesheets
13
+ = yield :javascripts
14
+ body
15
+ - if flash[:notice]
16
+ .form-flash.hidden data-type="action"= flash[:notice]
17
+ - if flash[:success]
18
+ .form-flash.hidden data-type="success"= flash[:success]
19
+ - if flash[:error]
20
+ .form-flash.hidden data-type="error"= flash[:error]
21
+
22
+ .site
23
+ header.site-header role="banner" data-no-turbolink=true
24
+ button.nav_toggle onclick="toggleNav(); this.blur()"
25
+ span.icon
26
+ span.hidden_label View Navigation
27
+ a.header_logo.logo_icon href="/"
28
+ span.hidden_label Compose
29
+ .site-content
30
+ - if !@custom_nav
31
+ = render 'megatron/shared/primary_nav'
32
+ - if content_for?(:primary_nav)
33
+ nav.primary_nav role="navigation" data-no-turbolink=true
34
+ = yield :primary_nav
35
+ .page
36
+ = yield
37
+ - if content_for?(:main)
38
+ header.page-header
39
+ = yield :page_header
40
+ .page-content
41
+ - if content_for?(:secondary_nav)
42
+ nav.secondary_nav
43
+ = yield :secondary_nav
44
+ - if content_for?(:sidebar)
45
+ .main.with-sidebar
46
+ .main-content
47
+ - if @wide_layout
48
+ .wide
49
+ = render 'megatron/shared/main_content'
50
+ - else
51
+ = render 'megatron/shared/main_content'
52
+ .main-sidebar
53
+ = yield :sidebar
54
+ - else
55
+ .main
56
+ .main-content
57
+ - if @wide_layout
58
+ .wide
59
+ = render 'megatron/shared/main_content'
60
+ - else
61
+ = render 'megatron/shared/main_content'
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ html.error-layout
3
+ head
4
+ title Error #{@status_code}: #{@rescue_response.to_s.humanize} - Compose
5
+ meta name="viewport" content="width=device-width,initial-scale=1"
6
+ meta charset="utf-8"
7
+ = favicon_link_tag(megatron_asset_path('favicon.ico'))
8
+ = stylesheet_link_tag(megatron_asset_path('error-pages'))
9
+
10
+ body
11
+ .error-page class="error-#{@status_code} #{('reverse-stack' if @status_code == 404)}"
12
+ = embed_svg("megatron/errors/#{@status_code}.svg")
13
+ .error-message
14
+ = yield
15
+ footer.support-links
16
+ nav
17
+ a href='mailto:support@compose.io' Contact Support
18
+ a href='https://status.compose.io' Compose Status
19
+ a.compose-logo href='https://compose.io'
20
+ span.hidden_label Compose
@@ -0,0 +1,2 @@
1
+ h1 Bad Request
2
+ h2 Sorry, our server cannot process this request.
@@ -0,0 +1,2 @@
1
+ h1 Forbidden
2
+ p Ah, ah, ah. You didn't say the magic word.
@@ -0,0 +1,2 @@
1
+ h1 Internal Server Error
2
+ p But don't worry, this shouldn't affect your databases.
@@ -0,0 +1,2 @@
1
+ h1 Method Not Allowed
2
+ p This endpoint does not support the method you used.
@@ -0,0 +1,2 @@
1
+ h1 Not Acceptable
2
+ p That's... not acceptable.
@@ -0,0 +1,2 @@
1
+ h1 data-alt-message="On the bright side, you found" Page Not Found
2
+ p data-alt-message="THE PARTY!" This page does not exist
@@ -0,0 +1,2 @@
1
+ h1 Not Implemented
2
+ p We don't implement this method here.
@@ -0,0 +1,2 @@
1
+ h1 Unauthorized
2
+ p You are not authorized here.
@@ -0,0 +1,2 @@
1
+ h1 Invalid request
2
+ p You may not have access to make this change.
@@ -0,0 +1,4 @@
1
+ - if content_for?(:main_header)
2
+ header.main-header
3
+ = yield :main_header
4
+ = yield :main
@@ -0,0 +1,6 @@
1
+ - primary_nav do |nav|
2
+ = nav.item 'Deployments', "/#{current_account.slug}/deployments", icon: 'deployments'
3
+ = nav.item 'Account', "/account", icon: 'account_circle'
4
+ = nav.item 'Alerts', "/#{current_account.slug}/alerts", icon: 'alerts'
5
+ = nav.item 'Support', "/#{current_account.slug}/tickets", icon: 'question_line'
6
+ = nav.sign_out
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Megatron::Engine.routes.draw do
2
+ end
data/lib/megatron.rb ADDED
@@ -0,0 +1,9 @@
1
+ Gem.loaded_specs['megatron'].dependencies.each do |d|
2
+ require d.name
3
+ end
4
+
5
+ require "megatron/form"
6
+ require "megatron/engine"
7
+
8
+ module Megatron
9
+ end
@@ -0,0 +1,12 @@
1
+ module Megatron
2
+ class Engine < ::Rails::Engine
3
+ config.generators do |g|
4
+ g.assets false
5
+ g.helper false
6
+ end
7
+
8
+ initializer 'megatron.form_builder' do |app|
9
+ ActionView::Base.default_form_builder = Megatron::Form
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,129 @@
1
+ module Megatron
2
+ class Form < ActionView::Helpers::FormBuilder
3
+
4
+ attr_accessor :style
5
+
6
+ def initialize(object_name, object, template, options)
7
+ super
8
+ @style = options.delete(:style) || "table"
9
+ end
10
+
11
+ def stacked_form(&block)
12
+ content_tag :div, class: 'stacked-form', &block
13
+ end
14
+
15
+ def table_form(&block)
16
+ content_tag :div, class: ['table', 'table-form'], &block
17
+ end
18
+
19
+ def text_field(method, options = {})
20
+ if errors_on?(method)
21
+ options[:class] ||= ""
22
+ options[:class] += " error"
23
+ end
24
+
25
+ wrapper method, options.delete(:label) || method.to_s.humanize, super(method, options)
26
+ end
27
+
28
+ def password_field(method, options = {})
29
+ if errors_on?(method)
30
+ options[:class] ||= ""
31
+ options[:class] += " error"
32
+ end
33
+
34
+ wrapper method, options.delete(:label) || method.to_s.humanize, super(method, options)
35
+ end
36
+
37
+ def text_area(method, options = {})
38
+ if errors_on?(method)
39
+ options[:class] ||= ""
40
+ options[:class] += " error"
41
+ end
42
+
43
+ wrapper method, options.delete(:label) || method.to_s.humanize, super(method, options)
44
+ end
45
+
46
+ def select(method, choices = nil, options = {}, html_options = {}, &block)
47
+ if errors_on?(method)
48
+ html_options[:class] ||= ""
49
+ html_options[:class] += " error"
50
+ end
51
+
52
+ field = content_tag(:div, class: 'select_box') { super(method, choices, options, html_options, &block) }
53
+
54
+ wrapper method, options.delete(:label) || method.to_s.humanize, field
55
+ end
56
+
57
+ def submit(btn_text, args = {})
58
+ text = "<footer class='form-footer'>".html_safe
59
+ text << button(btn_text, {class: "primary-btn"}.merge(args))
60
+ text << "</footer>".html_safe
61
+
62
+ text
63
+ end
64
+
65
+ def method_missing(method, *args, &block)
66
+ @template.send(method, *args, &block)
67
+ end
68
+
69
+ private
70
+
71
+ def wrapper(*args)
72
+ send("#{@style}_wrapper".to_sym, *args)
73
+ rescue NoMethodError
74
+ Bugsnag.notify($!)
75
+ raise "Could not find Megatron::Form form style '#{@style}'."
76
+ end
77
+
78
+ def table_row(&block)
79
+ content_tag(:div, class: 'table-row', &block)
80
+ end
81
+
82
+ def table_cell(&block)
83
+ content_tag(:div, class: 'table-cell', &block)
84
+ end
85
+
86
+ def table_wrapper(method, label, field)
87
+ concat(table_row {
88
+ concat(table_cell {
89
+ label(method, label, class: [('red-text' if errors_on?(method))])
90
+ })
91
+ concat(table_cell { field })
92
+ })
93
+
94
+ if errors_on?(method)
95
+ concat(table_row {
96
+ concat(table_cell { ' ' })
97
+ concat(table_cell {
98
+ content_tag :p, class: 'red-text' do
99
+ @object.errors[method].to_sentence
100
+ end
101
+ })
102
+ })
103
+ end
104
+ end
105
+
106
+ def errors_on?(method)
107
+ @object.present? && @object.errors[method].present?
108
+ end
109
+
110
+ def stacked_row(&block)
111
+ content_tag :div, class: 'form-row', &block
112
+ end
113
+
114
+ def stacked_wrapper(method, label, field)
115
+ concat(stacked_row {
116
+ concat label(method, label, class: [('red-text' if errors_on?(method))])
117
+ concat field
118
+ })
119
+
120
+ if errors_on?(method)
121
+ concat(stacked_row {
122
+ content_tag :span, class: ['red-text', 'small-text'] do
123
+ @object.errors[method].to_sentence
124
+ end
125
+ })
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,3 @@
1
+ module Megatron
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :megatron do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: megatron
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jerome Gravel-Niquet
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: block_helpers
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: to_words
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: slim-rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 4.2.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 4.2.3
69
+ description: Hotness.
70
+ email:
71
+ - jeromegn@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - MIT-LICENSE
77
+ - README.rdoc
78
+ - Rakefile
79
+ - app/controllers/megatron/errors_controller.rb
80
+ - app/helpers/megatron/application_helper.rb
81
+ - app/helpers/megatron/breadcrumb_helper.rb
82
+ - app/helpers/megatron/button_helper.rb
83
+ - app/helpers/megatron/example_helper.rb
84
+ - app/helpers/megatron/form_helper.rb
85
+ - app/helpers/megatron/grid_helper.rb
86
+ - app/helpers/megatron/layout_helper.rb
87
+ - app/helpers/megatron/navigation_helper.rb
88
+ - app/helpers/megatron/tab_helper.rb
89
+ - app/helpers/megatron/toggler_help.rb
90
+ - app/views/layouts/megatron/application.html.slim
91
+ - app/views/layouts/megatron/errors.html.slim
92
+ - app/views/megatron/errors/bad_request.html.slim
93
+ - app/views/megatron/errors/forbidden.html.slim
94
+ - app/views/megatron/errors/internal_server_error.html.slim
95
+ - app/views/megatron/errors/method_not_allowed.html.slim
96
+ - app/views/megatron/errors/not_acceptable.html.slim
97
+ - app/views/megatron/errors/not_found.html.slim
98
+ - app/views/megatron/errors/not_implemented.html.slim
99
+ - app/views/megatron/errors/unauthorized.html.slim
100
+ - app/views/megatron/errors/unprocessable_entity.html.slim
101
+ - app/views/megatron/shared/_main_content.html.slim
102
+ - app/views/megatron/shared/_primary_nav.html.slim
103
+ - config/routes.rb
104
+ - lib/megatron.rb
105
+ - lib/megatron/engine.rb
106
+ - lib/megatron/form.rb
107
+ - lib/megatron/version.rb
108
+ - lib/tasks/megatron_tasks.rake
109
+ homepage: https://www.compose.io
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.4.7
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Megatron view helpers
133
+ test_files: []
134
+ has_rdoc: