rails_app_generator 0.1.3 → 0.1.4

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 +4 -4
  2. data/.builders/generators/project-plan.rb +2 -0
  3. data/CHANGELOG.md +7 -0
  4. data/after_templates/rag_tailwind_hotwire_form/application.html.erb +0 -1
  5. data/after_templates/rag_tailwind_hotwire_form.rb +4 -4
  6. data/after_templates/rag_tailwind_hotwire_form_search/_contact.html.erb +8 -0
  7. data/after_templates/rag_tailwind_hotwire_form_search/_count.html.erb +1 -0
  8. data/after_templates/rag_tailwind_hotwire_form_search/_flash.html.erb +6 -0
  9. data/after_templates/rag_tailwind_hotwire_form_search/_form.html.erb +16 -0
  10. data/after_templates/rag_tailwind_hotwire_form_search/_list.html.erb +19 -0
  11. data/after_templates/rag_tailwind_hotwire_form_search/_theme_changer.html.erb +35 -0
  12. data/after_templates/rag_tailwind_hotwire_form_search/application.html.erb +25 -0
  13. data/after_templates/rag_tailwind_hotwire_form_search/application.js +40 -0
  14. data/after_templates/rag_tailwind_hotwire_form_search/application.tailwind.css +111 -0
  15. data/after_templates/rag_tailwind_hotwire_form_search/application_helper.rb +15 -0
  16. data/after_templates/rag_tailwind_hotwire_form_search/contact.rb +13 -0
  17. data/after_templates/rag_tailwind_hotwire_form_search/contacts_controller.rb +72 -0
  18. data/after_templates/rag_tailwind_hotwire_form_search/create.turbo_stream.erb +4 -0
  19. data/after_templates/rag_tailwind_hotwire_form_search/edit.html.erb +12 -0
  20. data/after_templates/rag_tailwind_hotwire_form_search/index.html.erb +16 -0
  21. data/after_templates/rag_tailwind_hotwire_form_search/new.html.erb +12 -0
  22. data/after_templates/rag_tailwind_hotwire_form_search/show.html.erb +16 -0
  23. data/after_templates/rag_tailwind_hotwire_form_search/update.turbo_stream.erb +2 -0
  24. data/after_templates/rag_tailwind_hotwire_form_search.rb +66 -0
  25. data/docs/project-plan/project.drawio +38 -32
  26. data/docs/project-plan/project_done.svg +1 -1
  27. data/docs/project-plan/project_in_progress.svg +1 -1
  28. data/lib/rails_app_generator/app_generator.rb +13 -0
  29. data/lib/rails_app_generator/diff/processor.rb +4 -3
  30. data/lib/rails_app_generator/version.rb +1 -1
  31. data/package-lock.json +2 -2
  32. data/package.json +1 -1
  33. data/profiles/rag-tailwind-hotwire-form-search.json +13 -0
  34. data/profiles/rag-tailwind-hotwire-form.json +1 -1
  35. metadata +22 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1b9515cc01763f710f8f7461e0d8166d5192771ed45267be53c399fa4d0f9c8
4
- data.tar.gz: c2c4069a59328153fcab6e5f81c78e39f58a11f759103dda01d0c74571611ea5
3
+ metadata.gz: a3923e0f96f609acecc6345d2397de92c60129a3f56e23af16fe083ea7a74076
4
+ data.tar.gz: 7fa9a4b0c12572dd4c3de738793679a0d780bca7f32d5c8e58d194d6e305a170
5
5
  SHA512:
6
- metadata.gz: 3576c0c56cb8efaf50aab437e827a5e8ef973107537b9ae5f8362d91426161d0382b2bc463bae598419af396740eed71ba6720585b4d085f47051b64c3b0d4a0
7
- data.tar.gz: 84ee7ac005aa6715de7697ccc8d0a2650f9d49d6dff1bbbc4d0e71ce51337ebe185449612fd3ec4204623f9fed3571427f1f028c3c7e4426d8d1f96b68ccead1
6
+ metadata.gz: c8d843b2d84b1fe7690c1b333389f53777c2171d4ed3c6bccf2cce6420495aa12893fa503ebc9b0771d7dc010b3542d6a26cf5f2622a8505425b1969b6854440
7
+ data.tar.gz: 2e1425bce77a4008e481bb2f6988daeae58bbfe08f919641a2b3fe7d5220e52cfd978bdd94326e821dc03115015d1278ad027ceb152db5bbc9cd21c8fc6d0e73
@@ -7,6 +7,7 @@ KManager.action :project_plan do
7
7
  .page('In progress', theme: :style_03, margin_left: 0, margin_top: 0) do
8
8
  grid_layout(y: 90, direction: :horizontal, grid_h: 80, grid_w: 320, wrap_at: 3, grid: 0)
9
9
 
10
+ todo(title: 'add profile - tailwind_hotwire_form_search (FINISH of the stimulus controller + add stimulus controller for theme change')
10
11
  end
11
12
  .page('To Do', theme: :style_02, margin_left: 0, margin_top: 0) do
12
13
 
@@ -30,6 +31,7 @@ KManager.action :project_plan do
30
31
 
31
32
  grid_layout(y:90, direction: :horizontal, grid_h: 80, grid_w: 320, wrap_at: 3, grid: 0)
32
33
 
34
+ todo(title: 'add profile - tailwind_hotwire_form')
33
35
  todo(title: 'add profile - tailwind_hotwire')
34
36
  todo(title: 'add profile - import_map') # vs esbuild - import_map is a replacement for webpacker
35
37
  todo(title: 'profile - fix the bootstrap profile')
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [0.1.3](https://github.com/klueless-io/rails_app_generator/compare/v0.1.2...v0.1.3) (2022-07-27)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add profile tailwind_daisyui, tailwind_hotwire_form ([dcb227f](https://github.com/klueless-io/rails_app_generator/commit/dcb227fc9ccf0783d87049c4c6660f914e39fa97))
7
+
1
8
  ## [0.1.2](https://github.com/klueless-io/rails_app_generator/compare/v0.1.1...v0.1.2) (2022-07-26)
2
9
 
3
10
 
@@ -5,7 +5,6 @@
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <%= csrf_meta_tags %>
7
7
  <%= csp_meta_tag %>
8
- <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
9
8
 
10
9
  <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
11
10
  <%= javascript_importmap_tags %>
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # How to Start a Ruby on Rails 7 App With Hotwire and Tailwind CSS
4
- # https://www.youtube.com/watch?v=7G0oWn2Gn5c
4
+ # https://www.youtube.com/watch?v=-n7IbUFKjoM
5
5
 
6
6
  require 'pry'
7
7
 
@@ -45,9 +45,9 @@ after_bundle do
45
45
 
46
46
  rails_command('css:install:tailwind')
47
47
  run('npm install daisyui')
48
- # run('@tailwindcss/typography') , require(\"@tailwindcss/typography\")
49
-
50
- gsub_file 'tailwind.config.js', %(]\n}), "],\n plugins: [require(\"daisyui\")],\n}"
48
+ run('npm install -D @tailwindcss/typography')
49
+
50
+ gsub_file 'tailwind.config.js', %(]\n}), "],\n plugins: [require(\"daisyui\"), require(\"@tailwindcss/typography\")],\n}"
51
51
  copy_file 'application.tailwind.css' , 'app/assets/stylesheets/application.tailwind.css' , force: true
52
52
 
53
53
  rails_command('db:migrate')
@@ -0,0 +1,8 @@
1
+ <tr id="<%= dom_id(contact) %>" data-stream-enter-class="animate-item-in" data-stream-exit-class="animate-item-out">
2
+ <td><%= contact.id %></td>
3
+ <td><%= link_to contact.name, contact_path(contact), data: { turbo_frame: "_top" } %></td>
4
+ <td><%= contact.age %></td>
5
+ <td><%= contact.email %></td>
6
+ <td><%= link_to "Edit", edit_contact_path(contact), class: "btn btn-link btn-sm", data: { turbo_frame: "_top" } %></td>
7
+ <td><%= button_to "Delete", contact_path(contact), method: :delete, class: "btn btn-link btn-sm" %></td>
8
+ </tr>
@@ -0,0 +1 @@
1
+ <span data-stream-enter-class="animate-item-in" data-stream-exit-class="animate-item-out">Showing <%= contacts.length %> <%= "contact".pluralize(contacts.length) %></span>
@@ -0,0 +1,6 @@
1
+ <% flash.each do |type, msg| %>
2
+ <% alert_class = type == "notice" ? "success" : "error" %>
3
+ <div class="alert alert-<%= alert_class %> mb-8 text-white" data-stream-enter-class="animate-in" data-stream-exit-class="animate-out">
4
+ <%= msg %>
5
+ </div>
6
+ <% end %>
@@ -0,0 +1,16 @@
1
+ <%= form_for contact do |f| %>
2
+ <% if contact.errors.any? %>
3
+ <div class="form-errors">
4
+ <div class="alert shadow-lg alert-error text-white">
5
+ Your form's got some errors
6
+ </div>
7
+ </div>
8
+ <% end %>
9
+ <%= f.text_field :name, placeholder: "Your first name", class: "input input-bordered w-full max-w-xs my-5" %>
10
+ <%= inline_error_for(:name, contact) %>
11
+ <%= f.text_field :age, placeholder: "Your age", class: "input input-bordered w-full max-w-xs my-4" %>
12
+ <%= inline_error_for(:age, contact) %>
13
+ <%= f.text_field :email, placeholder: "Your email address", class: "input input-bordered w-full max-w-xs my-4" %>
14
+ <%= inline_error_for(:email, contact) %>
15
+ <%= f.submit "Save", class: "form-control btn btn-primary my-4" %>
16
+ <% end %>
@@ -0,0 +1,19 @@
1
+ <table class="table table-zebra mt-0 w-full">
2
+ <thead>
3
+ <tr class="w-full">
4
+ <th class="text-left">ID</th>
5
+ <th class="text-left">Name</th>
6
+ <th class="text-left">Age</th>
7
+ <th class="text-left">Email</th>
8
+ <th class="text-center" colspan="2">Actions</th>
9
+ </tr>
10
+ </thead>
11
+ <tbody id="contacts-list" data-controller="contacts" data-action="">
12
+ <% contacts.each do |contact| %>
13
+ <%= render partial: "contact", locals: { contact: contact } %>
14
+ <% end %>
15
+ </tbody>
16
+ </table>
17
+ <div class="text-gray-400 mt-4 text-xs text-right" id="contacts-count">
18
+ <%= render partial: "count", locals: { contacts: contacts } %>
19
+ </div>
@@ -0,0 +1,35 @@
1
+ <div class="dropdown">
2
+ <label tabindex="0" class="btn m-1">Select Theme</label>
3
+ <ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
4
+ <li data-value="">Default</li>
5
+ <li data-value="aqua">Aqua</li>
6
+ <li data-value="black">Black</li>
7
+ <li data-value="bumblebee">Bumblebee</li>
8
+ <li data-value="cmyk">Cmyk</li>
9
+ <li data-value="corporate">Corporate</li>
10
+ <li data-value="cupcake">Cupcake</li>
11
+ <li data-value="cyberpunk">Cyberpunk</li>
12
+ <li data-value="dark">Dark</li>
13
+ <li data-value="dracula">Dracula</li>
14
+ <li data-value="emerald">Emerald</li>
15
+ <li data-value="fantasy">Fantasy</li>
16
+ <li data-value="forest">Forest</li>
17
+ <li data-value="garden">Garden</li>
18
+ <li data-value="halloween">Halloween</li>
19
+ <li data-value="light">Light</li>
20
+ <li data-value="lofi">Lofi</li>
21
+ <li data-value="luxury">Luxury</li>
22
+ <li data-value="pastel">Pastel</li>
23
+ <li data-value="retro">Retro</li>
24
+ <li data-value="synthwave">Synthwave</li>
25
+ <li data-value="valentine">Valentine</li>
26
+ <li data-value="wireframe">Wireframe</li>
27
+ <li data-value="autumn">Autumn</li>
28
+ <li data-value="business">Business</li>
29
+ <li data-value="acid">Acid</li>
30
+ <li data-value="lemonade">Lemonade</li>
31
+ <li data-value="night">Night</li>
32
+ <li data-value="coffee">Coffee</li>
33
+ <li data-value="winter">Winter</li>
34
+ </select>
35
+ </div>
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html data-theme="retro">
3
+ <head>
4
+ <title>Tailwind Hotwire Form + Search</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <%= csrf_meta_tags %>
7
+ <%= csp_meta_tag %>
8
+
9
+ <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
10
+ <%= javascript_importmap_tags %>
11
+ </head>
12
+
13
+ <body>
14
+ <%= render partial: "shared/theme_changer" %>
15
+
16
+ <main class="container mx-auto">
17
+ <div class="py-8">
18
+ <div id="flash" class="flash">
19
+ <%= render partial: "shared/flash" %>
20
+ </div>
21
+ <%= yield %>
22
+ </div>
23
+ </main>
24
+ </body>
25
+ </html>
@@ -0,0 +1,40 @@
1
+ // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
2
+ import "@hotwired/turbo-rails"
3
+ import "controllers"
4
+
5
+ document.addEventListener("turbo:before-stream-render", function(event) {
6
+ // Add a class to an element we are about to add to the page
7
+ // as defined by its "data-stream-enter-class"
8
+ if (event.target.firstElementChild instanceof HTMLTemplateElement) {
9
+ var enterAnimationClass = event.target.templateContent.firstElementChild.dataset.streamEnterClass
10
+ if (enterAnimationClass) {
11
+ event.target.templateElement.content.firstElementChild.classList.add(enterAnimationClass)
12
+ }
13
+ }
14
+
15
+ // Add a class to an element we are about to remove from the page
16
+ // as defined by its "data-stream-exit-class"
17
+ var elementToRemove = document.getElementById(event.target.target)
18
+ if (elementToRemove) {
19
+ var streamExitClass = elementToRemove.dataset.streamExitClass
20
+ if (streamExitClass) {
21
+ // Intercept the removal of the element
22
+ event.preventDefault()
23
+ elementToRemove.classList.add(streamExitClass)
24
+ // Wait for its animation to end before removing the element
25
+ elementToRemove.addEventListener("animationend", function() {
26
+ event.target.performAction()
27
+ })
28
+ }
29
+ }
30
+ })
31
+
32
+ // FIX this using stimulus
33
+ // Add Theme Changer Event Listener
34
+ var items = Array.from(document.querySelector('.dropdown > ul').children);
35
+ items.forEach(item => {
36
+ item.addEventListener('click', event => {
37
+ var html = document.querySelector('html');
38
+ html.setAttribute("data-theme", event.target.getAttribute('data-value'));
39
+ })
40
+ })
@@ -0,0 +1,111 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ /*
6
+
7
+ @layer components {
8
+ .btn-primary {
9
+ @apply py-2 px-4 bg-blue-200;
10
+ }
11
+ }
12
+
13
+ */
14
+
15
+ html {
16
+ font-size: 20px
17
+ }
18
+
19
+ .form-errors {
20
+ color: red;
21
+ }
22
+
23
+ .field_with_errors .input-bordered {
24
+ border: 1px solid red;
25
+ margin-bottom: 0;
26
+ }
27
+
28
+ /* Animation */
29
+ /* */
30
+ /* Got it from here: */
31
+ /* https://edforshaw.co.uk/hotwire-turbo-stream-animations */
32
+ /* and here: */
33
+ /* https://stackoverflow.com/a/61306871/4072276 */
34
+
35
+ .animate-in {
36
+ animation: slide-in 0.25s ease-out;
37
+ }
38
+
39
+ .animate-out {
40
+ animation: slide-out 0.25s ease-out;
41
+ }
42
+
43
+ @keyframes slide-in {
44
+ from { transform: translateX(4rem); }
45
+ to { transform: translateX(0); }
46
+ }
47
+
48
+ @keyframes slide-out {
49
+ from { transform: translateX(0); }
50
+ to { transform: translateX(4rem); }
51
+ }
52
+
53
+ .animate-item-in {
54
+ transition-duration: 0.25s;
55
+ animation: addRow 0.25s ease-in;
56
+ transform-origin: top;
57
+ }
58
+
59
+ .animate-item-out {
60
+ transition-duration: 0.25s;
61
+ animation: removeRow 0.25s ease-in;
62
+ transform-origin: bottom;
63
+ }
64
+
65
+ @keyframes addRow {
66
+ 0% {
67
+ transform: scale(1, 0);
68
+ line-height: 0px;
69
+ background-color: #fff;
70
+ visibility: collapse;
71
+ }
72
+ 50% {
73
+ transform: scale(1, 1);
74
+ line-height: 20px;
75
+ visibility: visible;
76
+ }
77
+ 100% {
78
+ }
79
+ }
80
+
81
+ @keyframes removeRow {
82
+ 100% {
83
+ transform: scale(1, 1);
84
+ line-height: 20px;
85
+ visibility: visible;
86
+ }
87
+ 50% {
88
+ transform: scale(1, 0);
89
+ line-height: 0px;
90
+ background-color: #fff;
91
+ visibility: collapse;
92
+ }
93
+ 0% {
94
+ }
95
+ }
96
+ .flash {
97
+ height: 70px;
98
+ margin-bottom: 2rem;
99
+ }
100
+
101
+ .alert-success {
102
+ --tw-bg-opacity: 1;
103
+ background-color: hsl(var(--su)/var(--tw-bg-opacity));
104
+ --tw-text-opacity: 1;
105
+ color: hsl(var(--suc,var(--nc))/var(--tw-text-opacity));
106
+ }
107
+
108
+ .text-white {
109
+ --tw-text-opacity: 1;
110
+ color: rgb(255 255 255/var(--tw-text-opacity));
111
+ }
@@ -0,0 +1,15 @@
1
+ module ApplicationHelper
2
+
3
+ def inline_error_for(field, form_obj)
4
+ html = []
5
+
6
+ if form_obj.errors[field].any?
7
+ html << form_obj.errors[field].map do |msg|
8
+ tag.div(msg, class: "text-red-400 text-xs m-0 p-0 text-right mb-2")
9
+ end
10
+ end
11
+
12
+ html.join.html_safe
13
+ end
14
+
15
+ end
@@ -0,0 +1,13 @@
1
+ class Contact < ApplicationRecord
2
+ validates :name, presence: true
3
+ validates :age, presence: true, numericality: true, inclusion: { in: 20...100, message: "must be between 20 and 100" }
4
+ validates :email, presence: true, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i }
5
+
6
+ class << self
7
+ def search(params)
8
+ return all if params[:query].blank?
9
+
10
+ where("name LIKE ?", "%#{sanitize_sql_like(params[:query])}%")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,72 @@
1
+ class ContactsController < ApplicationController
2
+ include ActionView::RecordIdentifier
3
+
4
+ before_action :set_contact, only: %i[show edit update destroy]
5
+ before_action :all_contacts
6
+
7
+ # GET /contacts or /contacts.json
8
+ def index
9
+ @contacts = Contact.search(params)
10
+ end
11
+
12
+ # GET /contacts/1 or /contacts/1.json
13
+ def show
14
+ end
15
+
16
+ # GET /contacts/new
17
+ def new
18
+ @contact = Contact.new
19
+ end
20
+
21
+ # GET /contacts/1/edit
22
+ def edit
23
+ end
24
+
25
+ # POST /contacts or /contacts.json
26
+ def create
27
+ @contact = Contact.new(contact_params)
28
+
29
+ if @contact.save
30
+ flash[:notice] = 'Contact was successfully created.'
31
+ else
32
+ render :new, status: :unprocessable_entity
33
+ end
34
+ end
35
+
36
+ # PATCH/PUT /contacts/1 or /contacts/1.json
37
+ def update
38
+ if @contact.update(contact_params)
39
+ flash[:notice] = "Contact updated"
40
+ else
41
+ render :edit, status: :unprocessable_entity
42
+ end
43
+ end
44
+
45
+ def destroy
46
+ @contact.destroy
47
+ flash[:notice] = "Contact removed"
48
+ render turbo_stream: [
49
+ turbo_stream.update("flash", partial: "shared/flash"),
50
+ turbo_stream.remove(dom_id(@contact)),
51
+ turbo_stream.update("contacts-count", partial: "contacts/count", locals: { contacts: @contacts })
52
+ ]
53
+ end
54
+
55
+ private
56
+ # Use callbacks to share common setup or constraints between actions.
57
+ def set_contact
58
+ @contact = Contact.find(params.require(:id))
59
+ end
60
+
61
+ def contact_params
62
+ params.require(:contact).permit(:name, :age, :email)
63
+ end
64
+ # def contact_params
65
+ # params.require(:contact).permit!
66
+ # end
67
+
68
+ def all_contacts
69
+ @contacts = Contact.all
70
+ end
71
+
72
+ end
@@ -0,0 +1,4 @@
1
+ <%= turbo_stream.update("flash", partial: "shared/flash") %>
2
+ <%= turbo_stream.append("contacts-list", partial: "contacts/contact", locals: { contact: @contact }) %>
3
+ <%= turbo_stream.update("contacts-count", partial: "contacts/count", locals: { contacts: @contacts }) %>
4
+ <%= turbo_stream.update("contact-form", partial: "contacts/form", locals: { contact: Contact.new }) %>
@@ -0,0 +1,12 @@
1
+ <div class="prose lg:prose-xl">
2
+ <h1>Edit contact</h1>
3
+ </div>
4
+
5
+ <div class="grid grid-cols-2 gap-4 mt-8">
6
+ <div class="bg-gray-100 p-8">
7
+ <%= render partial: "list", locals: { contacts: @contacts } %>
8
+ </div>
9
+ <div class="form-control w-full max-w-xs">
10
+ <%= render partial: "form", locals: { contact: @contact } %>
11
+ </div>
12
+ </div>
@@ -0,0 +1,16 @@
1
+ <div class="prose lg:prose-xl">
2
+ <h1>Contacts list</h1>
3
+ <%= form_tag contacts_path, method: :get, data: { turbo_frame: "search-results", turbo_action: "advance", controller: "search", action: "input->search#submit" } do |f| %>
4
+ <%= text_field_tag "query", nil, placeholder: "Search ...", class: "input input.bordered w-full max-w-xs my-5" %>
5
+ <%= submit_tag "Search", class: "btn btn-primary" %>
6
+ <% end %>
7
+
8
+ </div>
9
+
10
+ <div class="bg-gray-100 p-8 col-span-5">
11
+ <%= turbo_frame_tag "search-results" do %>
12
+ <%= render partial: "list", locals: { contacts: @contacts } %>
13
+ <% end %>
14
+ </div>
15
+
16
+ <%= link_to "Add new contact", new_contact_path, class: "btn btn-primary mt-4" %>
@@ -0,0 +1,12 @@
1
+ <div class="prose lg:prose-xl">
2
+ <h1>New contact</h1>
3
+ </div>
4
+
5
+ <div class="grid grid-cols-2 gap-4 mt-8">
6
+ <div class="bg-gray-100 p-8">
7
+ <%= render partial: "list", locals: { contacts: @contacts } %>
8
+ </div>
9
+ <div class="form-control w-full max-w-xs" id="contact-form">
10
+ <%= render partial: "form", locals: { contact: @contact } %>
11
+ </div>
12
+ </div>
@@ -0,0 +1,16 @@
1
+ <div class="prose lg:prose-xl">
2
+ <h1>Contact details</h2>
3
+ </div>
4
+
5
+ <div class="w-1/2 mx-auto p-8 border-2 m-8 grid grid-cols-2 gap-4">
6
+ <div>
7
+ <div class="my-4">Name: <%= @contact.name %></div>
8
+ <hr />
9
+ <div class="my-4">Age: <%= @contact.age %></div>
10
+ <hr />
11
+ <div class="my-4">Email: <%= @contact.email %></div>
12
+ </div>
13
+ <div>
14
+ <img src="https://i.pravatar.cc/300" />
15
+ </div>
16
+ </div>
@@ -0,0 +1,2 @@
1
+ <%= turbo_stream.update("flash", partial: "shared/flash") %>
2
+ <%= turbo_stream.replace(dom_id(@contact), partial: "contacts/contact", locals: { contact: @contact }) %>
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ # How To Build a Powerful Search Form With Hotwire
4
+ # https://www.youtube.com/watch?v=4MUEQVxUbm4
5
+
6
+ # This builds on top of: Ruby on Rails Forms With Hotwire
7
+ # https://www.youtube.com/watch?v=-n7IbUFKjoM
8
+
9
+ require 'pry'
10
+
11
+ self.local_template_path = File.join(File.dirname(__FILE__), File.basename(__FILE__, '.*'))
12
+
13
+ puts '----------------------------------------------------------------------'
14
+ puts "Using template: #{self.local_template_path}"
15
+ puts '----------------------------------------------------------------------'
16
+
17
+ gac 'base rails 7 image created'
18
+
19
+ route("resources :contacts")
20
+ route("root 'contacts#index'")
21
+
22
+ after_bundle do
23
+ gsub_file 'app/views/layouts/application.html.erb', %(container mx-auto mt-28 px-5 flex), 'container mt-8 mx-auto'
24
+
25
+ # add_scaffold('contact', 'name', 'email')
26
+ add_migration('create_contacts', 'name', 'email', 'age:integer')
27
+ # rails generate migration CreateUsers name:string salary:decimal
28
+
29
+ copy_file 'contact.rb' , 'app/models/contact.rb'
30
+ copy_file 'contacts_controller.rb' , 'app/controllers/contacts_controller.rb'
31
+
32
+ copy_file '_contact.html.erb' , 'app/views/contacts/_contact.html.erb'
33
+ copy_file '_count.html.erb' , 'app/views/contacts/_count.html.erb'
34
+ copy_file '_form.html.erb' , 'app/views/contacts/_form.html.erb'
35
+ copy_file '_list.html.erb' , 'app/views/contacts/_list.html.erb'
36
+ copy_file 'edit.html.erb' , 'app/views/contacts/edit.html.erb'
37
+ copy_file 'index.html.erb' , 'app/views/contacts/index.html.erb'
38
+ copy_file 'new.html.erb' , 'app/views/contacts/new.html.erb'
39
+ copy_file 'show.html.erb' , 'app/views/contacts/show.html.erb'
40
+
41
+ copy_file 'application_helper.rb' , 'app/helpers/application_helper.rb' , force: true
42
+ copy_file 'application.html.erb' , 'app/views/layouts/application.html.erb' , force: true
43
+ copy_file 'create.turbo_stream.erb' , 'app/views/contacts/create.turbo_stream.erb'
44
+ copy_file 'update.turbo_stream.erb' , 'app/views/contacts/update.turbo_stream.erb'
45
+ copy_file 'application.js' , 'app/javascript/application.js' , force: true
46
+
47
+ copy_file '_flash.html.erb' , 'app/views/shared/_flash.html.erb'
48
+ copy_file '_theme_changer.html.erb' , 'app/views/shared/_theme_changer.html.erb'
49
+
50
+ add_stimulus('search')
51
+
52
+ # Install tailwind directly, instead of via the --css=tailwind option so that we can configure 3rd party plugins
53
+ # gem "jsbundling-rails"
54
+ gem "cssbundling-rails"
55
+
56
+ rails_command('css:install:tailwind')
57
+ run('npm i daisyui')
58
+ run('npm i -D @tailwindcss/typography')
59
+
60
+ gsub_file 'tailwind.config.js', %(]\n}), "],\n plugins: [require(\"daisyui\"), require(\"@tailwindcss/typography\")],\n}"
61
+ copy_file 'application.tailwind.css' , 'app/assets/stylesheets/application.tailwind.css' , force: true
62
+
63
+ pin_download("debounce")
64
+
65
+ rails_command('db:migrate')
66
+ end
@@ -1,91 +1,97 @@
1
- <mxfile host="hAT">
2
- <diagram id="EXU" name="In progress">
1
+ <mxfile host="Rmd">
2
+ <diagram id="65E" name="In progress">
3
3
  <mxGraphModel dx="0" dy="0" background="#FFFAFA" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
4
4
  <root>
5
- <mxCell id="page_root_EXU" parent="EXU"/>
6
- <mxCell id="node_root_EXU" parent="page_root_EXU"/>
5
+ <mxCell id="page_root_65E" parent="65E"/>
6
+ <mxCell id="node_root_65E" parent="page_root_65E"/>
7
+ <mxCell id="65E-2" value="add profile - tailwind_hotwire_form_search (FINISH of the stimulus controller + add stimulus controller for theme change" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#d5e8d4;strokeColor=#82b366;fontColor=#333333" vertex="1" parent="node_root_65E">
8
+ <mxGeometry x="10" y="10" width="300" height="60" as="geometry"/>
9
+ </mxCell>
7
10
  </root>
8
11
  </mxGraphModel>
9
12
  </diagram>
10
- <diagram id="c1l" name="To Do">
13
+ <diagram id="bpw" name="To Do">
11
14
  <mxGraphModel dx="0" dy="0" background="#FFFAFA" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
12
15
  <root>
13
- <mxCell id="page_root_c1l" parent="c1l"/>
14
- <mxCell id="node_root_c1l" parent="page_root_c1l"/>
15
- <mxCell id="c1l-2" value="add auto open flag to profile and command line" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
16
+ <mxCell id="page_root_bpw" parent="bpw"/>
17
+ <mxCell id="node_root_bpw" parent="page_root_bpw"/>
18
+ <mxCell id="bpw-2" value="add auto open flag to profile and command line" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
16
19
  <mxGeometry x="10" y="10" width="300" height="60" as="geometry"/>
17
20
  </mxCell>
18
- <mxCell id="c1l-3" value="add profile - stimulas" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
21
+ <mxCell id="bpw-3" value="add profile - stimulas" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
19
22
  <mxGeometry x="330" y="10" width="300" height="60" as="geometry"/>
20
23
  </mxCell>
21
- <mxCell id="c1l-4" value="add profile - hotwire" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
24
+ <mxCell id="bpw-4" value="add profile - hotwire" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
22
25
  <mxGeometry x="650" y="10" width="300" height="60" as="geometry"/>
23
26
  </mxCell>
24
- <mxCell id="c1l-5" value="add profile - turbo" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
27
+ <mxCell id="bpw-5" value="add profile - turbo" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
25
28
  <mxGeometry x="10" y="90" width="300" height="60" as="geometry"/>
26
29
  </mxCell>
27
- <mxCell id="c1l-6" value="add profile - vue" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
30
+ <mxCell id="bpw-6" value="add profile - vue" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
28
31
  <mxGeometry x="330" y="90" width="300" height="60" as="geometry"/>
29
32
  </mxCell>
30
- <mxCell id="c1l-7" value="add profile - svelte" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
33
+ <mxCell id="bpw-7" value="add profile - svelte" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
31
34
  <mxGeometry x="650" y="90" width="300" height="60" as="geometry"/>
32
35
  </mxCell>
33
- <mxCell id="c1l-8" value="add profile - react" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
36
+ <mxCell id="bpw-8" value="add profile - react" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
34
37
  <mxGeometry x="10" y="170" width="300" height="60" as="geometry"/>
35
38
  </mxCell>
36
- <mxCell id="c1l-9" value="add profile - vite" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
39
+ <mxCell id="bpw-9" value="add profile - vite" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
37
40
  <mxGeometry x="330" y="170" width="300" height="60" as="geometry"/>
38
41
  </mxCell>
39
- <mxCell id="c1l-10" value="add profile - docker" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
42
+ <mxCell id="bpw-10" value="add profile - docker" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
40
43
  <mxGeometry x="650" y="170" width="300" height="60" as="geometry"/>
41
44
  </mxCell>
42
- <mxCell id="c1l-11" value="add encryption - https://youtu.be/ZmwNzod1trk?t=701" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
45
+ <mxCell id="bpw-11" value="add encryption - https://youtu.be/ZmwNzod1trk?t=701" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
43
46
  <mxGeometry x="10" y="250" width="300" height="60" as="geometry"/>
44
47
  </mxCell>
45
- <mxCell id="c1l-12" value="cli help support for diff" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
48
+ <mxCell id="bpw-12" value="cli help support for diff" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
46
49
  <mxGeometry x="330" y="250" width="300" height="60" as="geometry"/>
47
50
  </mxCell>
48
- <mxCell id="c1l-13" value="cli support for rails new (rag new should work like rails new) - buggy, need to work through" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
51
+ <mxCell id="bpw-13" value="cli support for rails new (rag new should work like rails new) - buggy, need to work through" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
49
52
  <mxGeometry x="650" y="250" width="300" height="60" as="geometry"/>
50
53
  </mxCell>
51
- <mxCell id="c1l-14" value="need an option for deleting target project path" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_c1l">
54
+ <mxCell id="bpw-14" value="need an option for deleting target project path" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontColor=#333333" vertex="1" parent="node_root_bpw">
52
55
  <mxGeometry x="10" y="330" width="300" height="60" as="geometry"/>
53
56
  </mxCell>
54
57
  </root>
55
58
  </mxGraphModel>
56
59
  </diagram>
57
- <diagram id="oP6" name="Done">
60
+ <diagram id="nkw" name="Done">
58
61
  <mxGraphModel dx="0" dy="0" background="#FFFAFA" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
59
62
  <root>
60
- <mxCell id="page_root_oP6" parent="oP6"/>
61
- <mxCell id="node_root_oP6" parent="page_root_oP6"/>
62
- <mxCell id="oP6-2" value="add profile - tailwind_hotwire" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_oP6">
63
+ <mxCell id="page_root_nkw" parent="nkw"/>
64
+ <mxCell id="node_root_nkw" parent="page_root_nkw"/>
65
+ <mxCell id="nkw-2" value="add profile - tailwind_hotwire_form" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_nkw">
63
66
  <mxGeometry x="10" y="10" width="300" height="60" as="geometry"/>
64
67
  </mxCell>
65
- <mxCell id="oP6-3" value="add profile - import_map" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_oP6">
68
+ <mxCell id="nkw-3" value="add profile - tailwind_hotwire" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_nkw">
66
69
  <mxGeometry x="330" y="10" width="300" height="60" as="geometry"/>
67
70
  </mxCell>
68
- <mxCell id="oP6-4" value="profile - fix the bootstrap profile" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_oP6">
71
+ <mxCell id="nkw-4" value="add profile - import_map" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_nkw">
69
72
  <mxGeometry x="650" y="10" width="300" height="60" as="geometry"/>
70
73
  </mxCell>
71
- <mxCell id="oP6-5" value="cli support for profile" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_oP6">
74
+ <mxCell id="nkw-5" value="profile - fix the bootstrap profile" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_nkw">
72
75
  <mxGeometry x="10" y="90" width="300" height="60" as="geometry"/>
73
76
  </mxCell>
74
- <mxCell id="oP6-6" value="separate CLI methods into include modules" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_oP6">
77
+ <mxCell id="nkw-6" value="cli support for profile" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_nkw">
75
78
  <mxGeometry x="330" y="90" width="300" height="60" as="geometry"/>
76
79
  </mxCell>
77
- <mxCell id="oP6-7" value="cli support for diff" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_oP6">
80
+ <mxCell id="nkw-7" value="separate CLI methods into include modules" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_nkw">
78
81
  <mxGeometry x="650" y="90" width="300" height="60" as="geometry"/>
79
82
  </mxCell>
80
- <mxCell id="oP6-8" value="add diff tool - open in editor" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_oP6">
83
+ <mxCell id="nkw-8" value="cli support for diff" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_nkw">
81
84
  <mxGeometry x="10" y="170" width="300" height="60" as="geometry"/>
82
85
  </mxCell>
83
- <mxCell id="oP6-9" value="add diff tool supporting lhs only, rhs only, same and different" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_oP6">
86
+ <mxCell id="nkw-9" value="add diff tool - open in editor" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_nkw">
84
87
  <mxGeometry x="330" y="170" width="300" height="60" as="geometry"/>
85
88
  </mxCell>
86
- <mxCell id="oP6-10" value="add project plan to do list" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_oP6">
89
+ <mxCell id="nkw-10" value="add diff tool supporting lhs only, rhs only, same and different" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_nkw">
87
90
  <mxGeometry x="650" y="170" width="300" height="60" as="geometry"/>
88
91
  </mxCell>
92
+ <mxCell id="nkw-11" value="add project plan to do list" style="whiteSpace=wrap;html=1;rounded=1;glass=1;fillColor=#f8cecc;strokeColor=#b85450;fontColor=#333333" vertex="1" parent="node_root_nkw">
93
+ <mxGeometry x="10" y="250" width="300" height="60" as="geometry"/>
94
+ </mxCell>
89
95
  </root>
90
96
  </mxGraphModel>
91
97
  </diagram>
@@ -1,3 +1,3 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="942px" height="222px" viewBox="-0.5 -0.5 942 222"><defs><linearGradient x1="0%" y1="0%" x2="0%" y2="100%" id="mx-gradient-ffffff-0.9-ffffff-0.1-s-0"><stop offset="0%" style="stop-color: rgb(255, 255, 255); stop-opacity: 0.9;"/><stop offset="100%" style="stop-color: rgb(255, 255, 255); stop-opacity: 0.1;"/></linearGradient></defs><g><rect x="0" y="0" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 10.15 -1 Q -1 -1 -1 10.15 L -1 24 Q 150 42 301 24 L 301 10.15 Q 301 -1 289.85 -1 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 30px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add profile - tailwind_hotwire</div></div></div></foreignObject><text x="150" y="34" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add profile - tailwind_hotwire</text></switch></g><rect x="320" y="0" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 330.15 -1 Q 319 -1 319 10.15 L 319 24 Q 470 42 621 24 L 621 10.15 Q 621 -1 609.85 -1 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 30px; margin-left: 321px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add profile - import_map</div></div></div></foreignObject><text x="470" y="34" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add profile - import_map</text></switch></g><rect x="640" y="0" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 650.15 -1 Q 639 -1 639 10.15 L 639 24 Q 790 42 941 24 L 941 10.15 Q 941 -1 929.85 -1 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 30px; margin-left: 641px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">profile - fix the bootstrap profile</div></div></div></foreignObject><text x="790" y="34" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">profile - fix the bootstrap profile</text></switch></g><rect x="0" y="80" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 10.15 79 Q -1 79 -1 90.15 L -1 104 Q 150 122 301 104 L 301 90.15 Q 301 79 289.85 79 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 110px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">cli support for profile</div></div></div></foreignObject><text x="150" y="114" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">cli support for profile</text></switch></g><rect x="320" y="80" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 330.15 79 Q 319 79 319 90.15 L 319 104 Q 470 122 621 104 L 621 90.15 Q 621 79 609.85 79 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 110px; margin-left: 321px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">separate CLI methods into include modules</div></div></div></foreignObject><text x="470" y="114" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">separate CLI methods into include modules</text></switch></g><rect x="640" y="80" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 650.15 79 Q 639 79 639 90.15 L 639 104 Q 790 122 941 104 L 941 90.15 Q 941 79 929.85 79 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 110px; margin-left: 641px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">cli support for diff</div></div></div></foreignObject><text x="790" y="114" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">cli support for diff</text></switch></g><rect x="0" y="160" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 10.15 159 Q -1 159 -1 170.15 L -1 184 Q 150 202 301 184 L 301 170.15 Q 301 159 289.85 159 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 190px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add diff tool - open in editor</div></div></div></foreignObject><text x="150" y="194" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add diff tool - open in editor</text></switch></g><rect x="320" y="160" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 330.15 159 Q 319 159 319 170.15 L 319 184 Q 470 202 621 184 L 621 170.15 Q 621 159 609.85 159 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 190px; margin-left: 321px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add diff tool supporting lhs only, rhs only, same and different</div></div></div></foreignObject><text x="470" y="194" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add diff tool supporting lhs only, rhs only, same...</text></switch></g><rect x="640" y="160" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 650.15 159 Q 639 159 639 170.15 L 639 184 Q 790 202 941 184 L 941 170.15 Q 941 159 929.85 159 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 190px; margin-left: 641px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add project plan to do list</div></div></div></foreignObject><text x="790" y="194" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add project plan to do list</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
3
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="942px" height="302px" viewBox="-0.5 -0.5 942 302"><defs><linearGradient x1="0%" y1="0%" x2="0%" y2="100%" id="mx-gradient-ffffff-0.9-ffffff-0.1-s-0"><stop offset="0%" style="stop-color: rgb(255, 255, 255); stop-opacity: 0.9;"/><stop offset="100%" style="stop-color: rgb(255, 255, 255); stop-opacity: 0.1;"/></linearGradient></defs><g><rect x="0" y="0" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 10.15 -1 Q -1 -1 -1 10.15 L -1 24 Q 150 42 301 24 L 301 10.15 Q 301 -1 289.85 -1 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 30px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add profile - tailwind_hotwire_form</div></div></div></foreignObject><text x="150" y="34" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add profile - tailwind_hotwire_form</text></switch></g><rect x="320" y="0" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 330.15 -1 Q 319 -1 319 10.15 L 319 24 Q 470 42 621 24 L 621 10.15 Q 621 -1 609.85 -1 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 30px; margin-left: 321px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add profile - tailwind_hotwire</div></div></div></foreignObject><text x="470" y="34" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add profile - tailwind_hotwire</text></switch></g><rect x="640" y="0" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 650.15 -1 Q 639 -1 639 10.15 L 639 24 Q 790 42 941 24 L 941 10.15 Q 941 -1 929.85 -1 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 30px; margin-left: 641px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add profile - import_map</div></div></div></foreignObject><text x="790" y="34" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add profile - import_map</text></switch></g><rect x="0" y="80" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 10.15 79 Q -1 79 -1 90.15 L -1 104 Q 150 122 301 104 L 301 90.15 Q 301 79 289.85 79 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 110px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">profile - fix the bootstrap profile</div></div></div></foreignObject><text x="150" y="114" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">profile - fix the bootstrap profile</text></switch></g><rect x="320" y="80" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 330.15 79 Q 319 79 319 90.15 L 319 104 Q 470 122 621 104 L 621 90.15 Q 621 79 609.85 79 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 110px; margin-left: 321px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">cli support for profile</div></div></div></foreignObject><text x="470" y="114" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">cli support for profile</text></switch></g><rect x="640" y="80" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 650.15 79 Q 639 79 639 90.15 L 639 104 Q 790 122 941 104 L 941 90.15 Q 941 79 929.85 79 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 110px; margin-left: 641px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">separate CLI methods into include modules</div></div></div></foreignObject><text x="790" y="114" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">separate CLI methods into include modules</text></switch></g><rect x="0" y="160" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 10.15 159 Q -1 159 -1 170.15 L -1 184 Q 150 202 301 184 L 301 170.15 Q 301 159 289.85 159 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 190px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">cli support for diff</div></div></div></foreignObject><text x="150" y="194" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">cli support for diff</text></switch></g><rect x="320" y="160" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 330.15 159 Q 319 159 319 170.15 L 319 184 Q 470 202 621 184 L 621 170.15 Q 621 159 609.85 159 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 190px; margin-left: 321px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add diff tool - open in editor</div></div></div></foreignObject><text x="470" y="194" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add diff tool - open in editor</text></switch></g><rect x="640" y="160" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 650.15 159 Q 639 159 639 170.15 L 639 184 Q 790 202 941 184 L 941 170.15 Q 941 159 929.85 159 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 190px; margin-left: 641px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add diff tool supporting lhs only, rhs only, same and different</div></div></div></foreignObject><text x="790" y="194" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add diff tool supporting lhs only, rhs only, same...</text></switch></g><rect x="0" y="240" width="300" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><path d="M 10.15 239 Q -1 239 -1 250.15 L -1 264 Q 150 282 301 264 L 301 250.15 Q 301 239 289.85 239 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 270px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add project plan to do list</div></div></div></foreignObject><text x="150" y="274" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add project plan to do list</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
@@ -1,3 +1,3 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="302px" height="62px" viewBox="-0.5 -0.5 302 62"><defs><linearGradient x1="0%" y1="0%" x2="0%" y2="100%" id="mx-gradient-ffffff-0.9-ffffff-0.1-s-0"><stop offset="0%" style="stop-color: rgb(255, 255, 255); stop-opacity: 0.9;"/><stop offset="100%" style="stop-color: rgb(255, 255, 255); stop-opacity: 0.1;"/></linearGradient></defs><g><rect x="0" y="0" width="300" height="60" rx="9" ry="9" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><path d="M 10.15 -1 Q -1 -1 -1 10.15 L -1 24 Q 150 42 301 24 L 301 10.15 Q 301 -1 289.85 -1 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 30px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add profile - import maps</div></div></div></foreignObject><text x="150" y="34" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add profile - import maps</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
3
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="302px" height="62px" viewBox="-0.5 -0.5 302 62"><defs><linearGradient x1="0%" y1="0%" x2="0%" y2="100%" id="mx-gradient-ffffff-0.9-ffffff-0.1-s-0"><stop offset="0%" style="stop-color: rgb(255, 255, 255); stop-opacity: 0.9;"/><stop offset="100%" style="stop-color: rgb(255, 255, 255); stop-opacity: 0.1;"/></linearGradient></defs><g><rect x="0" y="0" width="300" height="60" rx="9" ry="9" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><path d="M 10.15 -1 Q -1 -1 -1 10.15 L -1 24 Q 150 42 301 24 L 301 10.15 Q 301 -1 289.85 -1 Z" fill="url(#mx-gradient-ffffff-0.9-ffffff-0.1-s-0)" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 30px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">add profile - tailwind_hotwire_form_search (FINISH of the stimulus controller + add stimulus controller for theme change</div></div></div></foreignObject><text x="150" y="34" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">add profile - tailwind_hotwire_form_search (FINISH...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
@@ -208,10 +208,23 @@ module RailsAppGenerator
208
208
  generate(:migration, name, *args)
209
209
  end
210
210
 
211
+ def add_stimulus(name, *args)
212
+ generate(:stimulus, name, *args)
213
+ end
214
+
211
215
  def bundle_add(name)
212
216
  run("bundle add #{name}")
213
217
  end
214
218
 
219
+ def pin(name, *args)
220
+ run("bin/importmap pin #{name} #{args.join(' ')}")
221
+ end
222
+
223
+ def pin_download(name, *args)
224
+ args << '--download' unless args.include?('--download')
225
+ pin(name, *args)
226
+ end
227
+
215
228
  def read_template(template_file)
216
229
  path = find_in_source_paths(template_file)
217
230
 
@@ -13,9 +13,10 @@ module RailsAppGenerator
13
13
  relative_file.start_with?('log') ||
14
14
  relative_file.start_with?('db') ||
15
15
  relative_file.start_with?('app/assets/builds') ||
16
- relative_file == 'Gemfile.lock' ||
17
- relative_file == 'Package.lock' ||
18
- relative_file == 'Yarn.lock' ||
16
+ relative_file.casecmp?('gemfile.lock') ||
17
+ relative_file.casecmp?('package.lock') ||
18
+ relative_file.casecmp?('package-lock.json') ||
19
+ relative_file.casecmp?('yarn.lock') ||
19
20
  relative_file == 'config/master.key' ||
20
21
  relative_file == 'config/credentials.yml.enc'
21
22
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsAppGenerator
4
- VERSION = '0.1.3'
4
+ VERSION = '0.1.4'
5
5
  end
data/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "rails_app_generator",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "rails_app_generator",
9
- "version": "0.1.3",
9
+ "version": "0.1.4",
10
10
  "dependencies": {
11
11
  "daisyui": "^2.20.0"
12
12
  },
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rails_app_generator",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Create new Rails Application with custom opinions",
5
5
  "scripts": {
6
6
  "release": "semantic-release"
@@ -0,0 +1,13 @@
1
+ {
2
+ "args": {
3
+ "app_path": "tailwind_hotwire_form_search",
4
+ "destination_root": "/Users/davidcruwys/dev/kgems/rails_app_generator/a/rag"
5
+ },
6
+ "opts": {
7
+ "skip_test": true,
8
+ "template": "/Users/davidcruwys/dev/kgems/rails_app_generator/after_templates/rag_tailwind_hotwire_form_search.rb",
9
+ "note": "tailwind needs to be installed manually because of the custom tailwind plugins",
10
+ "XXX-css": "tailwind",
11
+ "javascript": "esbuild"
12
+ }
13
+ }
@@ -6,7 +6,7 @@
6
6
  "opts": {
7
7
  "skip_test": true,
8
8
  "template": "/Users/davidcruwys/dev/kgems/rails_app_generator/after_templates/rag_tailwind_hotwire_form.rb",
9
- "note": "tailwind needed to be installed manually",
9
+ "note": "tailwind needs to be installed manually because of the custom tailwind plugins",
10
10
  "XXX-css": "tailwind",
11
11
  "javascript": "esbuild"
12
12
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_app_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-27 00:00:00.000000000 Z
11
+ date: 2022-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bootsnap
@@ -200,6 +200,25 @@ files:
200
200
  - after_templates/rag_tailwind_hotwire_form/new.html.erb
201
201
  - after_templates/rag_tailwind_hotwire_form/show.html.erb
202
202
  - after_templates/rag_tailwind_hotwire_form/update.turbo_stream.erb
203
+ - after_templates/rag_tailwind_hotwire_form_search.rb
204
+ - after_templates/rag_tailwind_hotwire_form_search/_contact.html.erb
205
+ - after_templates/rag_tailwind_hotwire_form_search/_count.html.erb
206
+ - after_templates/rag_tailwind_hotwire_form_search/_flash.html.erb
207
+ - after_templates/rag_tailwind_hotwire_form_search/_form.html.erb
208
+ - after_templates/rag_tailwind_hotwire_form_search/_list.html.erb
209
+ - after_templates/rag_tailwind_hotwire_form_search/_theme_changer.html.erb
210
+ - after_templates/rag_tailwind_hotwire_form_search/application.html.erb
211
+ - after_templates/rag_tailwind_hotwire_form_search/application.js
212
+ - after_templates/rag_tailwind_hotwire_form_search/application.tailwind.css
213
+ - after_templates/rag_tailwind_hotwire_form_search/application_helper.rb
214
+ - after_templates/rag_tailwind_hotwire_form_search/contact.rb
215
+ - after_templates/rag_tailwind_hotwire_form_search/contacts_controller.rb
216
+ - after_templates/rag_tailwind_hotwire_form_search/create.turbo_stream.erb
217
+ - after_templates/rag_tailwind_hotwire_form_search/edit.html.erb
218
+ - after_templates/rag_tailwind_hotwire_form_search/index.html.erb
219
+ - after_templates/rag_tailwind_hotwire_form_search/new.html.erb
220
+ - after_templates/rag_tailwind_hotwire_form_search/show.html.erb
221
+ - after_templates/rag_tailwind_hotwire_form_search/update.turbo_stream.erb
203
222
  - bin/console
204
223
  - bin/setup
205
224
  - docs/project-plan.md
@@ -275,6 +294,7 @@ files:
275
294
  - profiles/rag-import-map.json
276
295
  - profiles/rag-simple.json
277
296
  - profiles/rag-tailwind-daisyui.json
297
+ - profiles/rag-tailwind-hotwire-form-search.json
278
298
  - profiles/rag-tailwind-hotwire-form.json
279
299
  - profiles/rag-tailwind-hotwire.json
280
300
  - profiles/rag-tailwind.json