megatron 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: