Skip to content

Commit

Permalink
Add a Bootstrap layout to the CRUD add-on (#485)
Browse files Browse the repository at this point in the history
* [#483] Add the first version of the CRUD addon with a simple bootstrap layout

* [#483] Add tests to the CRUD layout

* [#483] Fix the check for slim and erb layout files

* Fix lint issues

* Makes error condition more explicit

* Fix rubocop issue
  • Loading branch information
malparty authored Mar 7, 2024
1 parent e62b869 commit cf33fad
Show file tree
Hide file tree
Showing 18 changed files with 335 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .template/addons/bootstrap/application.scss.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

insert_into_file 'app/assets/stylesheets/application.scss', after: %r{// Dependencies\n} do
<<~SCSS
@import './vendor';
@import 'vendor';
SCSS
end
2 changes: 1 addition & 1 deletion .template/addons/bootstrap/stylesheets/vendor/index.scss
Original file line number Diff line number Diff line change
@@ -1 +1 @@
@import './bootstrap';
@import 'bootstrap';
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}

.app {
display: flex;
flex-direction: row;
flex-grow: 1;

&__container {
display: flex;
flex-direction: column;
flex-grow: 1;
justify-content: space-between;
}

&__main {
padding: rem(16px);
margin: rem(16px);
}

&__footer {
grid-area: footer;
padding: rem(8px);
}

&__nav-bar-top {
grid-area: navBar;
border-bottom: solid var(--bs-border-width) var(--bs-gray-400);
}

&__side-bar {
grid-area: sideBar;
display: flex;
flex-flow: column;
padding: rem(32px);
background-color: var(--bs-light);
width: rem(280px);
height: 100%;

.dropdown-toggle {
outline: 0;
}

.btn-toggle {
padding: 0.25rem 0.5rem;
font-weight: 600;
color: var(--bs-emphasis-color);
background-color: transparent;

&:hover,
&:focus {
color: rgba(var(--bs-emphasis-color-rgb), 0.85);
background-color: var(--bs-tertiary-bg);
}

&::before {
width: 1.25em;
line-height: 0;
content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%280,0,0,.5%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");
transition: transform 0.35s ease;
transform-origin: 0.5em 50%;
}
}

[data-bs-theme="dark"] .btn-toggle::before {
content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%28255,255,255,.5%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");
}

.btn-toggle[aria-expanded="true"] {
color: rgba(var(--bs-emphasis-color-rgb), 0.85);
}
.btn-toggle[aria-expanded="true"]::before {
transform: rotate(90deg);
}

.btn-toggle-nav a {
padding: 0.1875rem 0.5rem;
margin-top: 0.125rem;
margin-left: 1.25rem;
}
.btn-toggle-nav a:hover,
.btn-toggle-nav a:focus {
background-color: var(--bs-tertiary-bg);
}

.scrollarea {
overflow-y: auto;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "application";
25 changes: 25 additions & 0 deletions .template/addons/crud/app/views/layouts/application.html.slim.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
doctype html
html lang=I18n.locale
head
meta charset="utf-8"
meta name="viewport" content="width=device-width, initial-scale=1.0"
title= content_for?(:title) ? yield(:title) : '<%= app_name %>'
= csrf_meta_tags
= csp_meta_tag
= stylesheet_link_tag 'application', :media => 'all'
= javascript_include_tag 'application'

body class=class_names(controller_name.dasherize, action_name.dasherize)
header
= render('layouts/application/nav_bar_top')
.app
.side-bar
= render('layouts/application/side_bar')
.app__container
main.app__main
= yield
footer.app__footer
p.text-center.text-muted
| &copy;
= ' <%= app_name %>'
= Date.today.year
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.app__nav-bar-top
nav.navbar.navbar-expand-lg.navbar-light.bg-light
.container-fluid
a.navbar-brand[href="#"]
| NavbarTop
button.navbar-toggler[type="button" data-bs-toggle="collapse" data-bs-target="#top_navbar_nav" aria-controls="top_navbar_nav" aria-expanded="false" aria-label="Toggle navigation"]
span.navbar-toggler-icon
#top_navbar_nav.collapse.navbar-collapse
ul.navbar-nav.me-auto.mb-2.mb-lg-0
li.nav-item
a.nav-link.active[aria-current="page" href="#"]
| Home
li.nav-item
a.nav-link[href="#"]
| Link
li.nav-item
a.nav-link.disabled[href="#" tabindex="-1" aria-disabled="true"]
| Disabled
li.nav-item.dropdown
a#dropdown09.nav-link.dropdown-toggle[href="#" data-bs-toggle="dropdown" aria-expanded="false"]
| Account
ul.dropdown-menu[aria-labelledby="dropdown09"]
li
a.dropdown-item[href="#"]
| Profile
li
a.dropdown-item[href="#"]
| Settings
li
a.dropdown-item[href="#"]
| Logout
form
input.form-control[type="text" placeholder="Search" aria-label="Search"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
.app__side-bar
a.d-flex.align-items-center.mb-3.mb-md-0.me-md-auto.link-dark.text-decoration-none[href="/"]
svg.bi.pe-none.me-2[width="40" height="32"]
use[xlink:href="#bootstrap"]
span.fs-4
| Sidebar
hr
ul.list-unstyled.ps-0
li.mb-1
button.btn.btn-toggle.d-inline-flex.align-items-center.rounded.border-0.collapsed[data-bs-toggle="collapse" data-bs-target="#home-collapse" aria-expanded="false"]
| Home
#home-collapse.collapse[style=""]
ul.btn-toggle-nav.list-unstyled.fw-normal.pb-1.small
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Overview
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Updates
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Reports
li.mb-1
button.btn.btn-toggle.d-inline-flex.align-items-center.rounded.border-0.collapsed[data-bs-toggle="collapse" data-bs-target="#dashboard-collapse" aria-expanded="false"]
| Dashboard
#dashboard-collapse.collapse[style=""]
ul.btn-toggle-nav.list-unstyled.fw-normal.pb-1.small
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Overview
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Weekly
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Monthly
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Annually
li.mb-1
button.btn.btn-toggle.d-inline-flex.align-items-center.rounded.border-0.collapsed[data-bs-toggle="collapse" data-bs-target="#orders-collapse" aria-expanded="false"]
| Orders
#orders-collapse.collapse[style=""]
ul.btn-toggle-nav.list-unstyled.fw-normal.pb-1.small
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| New
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Processed
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Shipped
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Returned
li.border-top.my-3
li.mb-1
button.btn.btn-toggle.d-inline-flex.align-items-center.rounded.border-0.collapsed[data-bs-toggle="collapse" data-bs-target="#account-collapse" aria-expanded="false"]
| Account
#account-collapse.collapse
ul.btn-toggle-nav.list-unstyled.fw-normal.pb-1.small
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| New...
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Profile
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Settings
li
a.link-body-emphasis.d-inline-flex.text-decoration-none.rounded[href="#"]
| Sign out
15 changes: 15 additions & 0 deletions .template/addons/crud/template.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

use_source_path __dir__

remove_file 'app/views/layouts/application.html.erb'
directory 'app/views/layouts/application'
template 'app/views/layouts/application.html.slim.tt'

# SCSS Layout
directory 'app/assets/stylesheets/layouts'
insert_into_file 'app/assets/stylesheets/application.scss', after: %r{// Layouts\n} do
<<~SCSS
@import 'layouts';
SCSS
end
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
subject { file('app/assets/stylesheets/application.scss') }

it 'imports vendor stylesheets' do
expect(subject).to contain("@import './vendor';")
expect(subject).to contain("@import 'vendor';")
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

describe 'CRUD Addon - application layout' do
it 'attaches the current locale to the html tag' do
expect(file('app/views/layouts/application.html.slim')).to contain('html lang=I18n.locale')
end

it 'loads the stylesheet entry file in the layout' do
expect(file('app/views/layouts/application.html.slim')).to contain("javascript_include_tag 'application'")
end

it 'loads the javascript entry file in the layout' do
expect(file('app/views/layouts/application.html.slim')).to contain("stylesheet_link_tag 'application'")
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

describe 'CRUD Addon - application.scss' do
subject { file('app/assets/stylesheets/application.scss') }

it 'imports layouts stylesheets' do
expect(subject).to contain("@import 'layouts';")
end
end
19 changes: 19 additions & 0 deletions .template/spec/addons/variants/web/crud/template_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

describe 'CRUD addon - template' do
it 'creates app/assets/stylesheets/layouts/index.scss' do
expect(file('app/assets/stylesheets/layouts/index.scss')).to exist
end

it 'removes app/views/layouts/application.html.erb' do
expect(file('app/views/layouts/application.html.erb')).not_to exist
end

it 'creates javascript/vendor/index.js' do
expect(file('app/javascript/vendor/index.js')).to exist
end

it 'creates app/views/layouts/application.html.slim' do
expect(file('app/views/layouts/application.html.slim')).to exist
end
end
8 changes: 0 additions & 8 deletions .template/spec/variants/web/app/template_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@
expect(file('app/javascript/application.js')).to exist
end

it 'loads the javascript entry file in the layout' do
expect(file('app/views/layouts/application.html.erb')).to contain('<%= javascript_include_tag "application"')
end

it 'imports necessary modules' do
expect(file('app/javascript/application.js')).to contain('import \'./translations/translations\';')

Expand Down Expand Up @@ -103,9 +99,5 @@
it 'includes the localization concern in the application controller' do
expect(file('app/controllers/application_controller.rb')).to contain('include Localization')
end

it 'modifies the html tag to attach the current locale' do
expect(file('app/views/layouts/application.html.erb')).to contain("<html lang='<%= I18n.locale %>'>")
end
end
end
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Variables
@import './variables';
@import 'variables';

// Dependencies

// Functions
@import './functions';
@import 'functions';

// Mixins

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
@import './sizing';
@import 'sizing';
23 changes: 17 additions & 6 deletions .template/variants/web/app/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@
# Javascript
directory 'app/javascript'

if File.exist?('app/views/layouts/application.html.erb')
insert_into_file 'app/views/layouts/application.html.erb', before: %r{</head>} do
erb_layout_file = 'app/views/layouts/application.html.erb'
slim_layout_file = 'app/views/layouts/application.html.slim'

erb_layout_exists = File.exist?(erb_layout_file)
slim_layout_exists = File.exist?(slim_layout_file)
layout_not_found = !erb_layout_exists && !slim_layout_exists

if erb_layout_exists
insert_into_file erb_layout_file, before: %r{</head>} do
<<~ERB.indent(2)
<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
ERB
end
else
end

if layout_not_found
@template_errors.add <<~ERROR
Cannot include javascript into `app/views/layouts/application.html.erb`
Content: <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
Expand All @@ -33,11 +42,13 @@
RUBY
end

if File.exist?('app/views/layouts/application.html.erb')
gsub_file 'app/views/layouts/application.html.erb', /<html>/ do
if erb_layout_exists
gsub_file erb_layout_file, /<html>/ do
"<html lang='<%= I18n.locale %>'>"
end
else
end

if layout_not_found
@template_errors.add <<~ERROR
Cannot insert the lang attribute into html tag into `app/views/layouts/application.html.erb`
Content: <html lang='<%= I18n.locale %>'>
Expand Down
Loading

0 comments on commit cf33fad

Please sign in to comment.