eras 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2d2f4cfffca1ebd81a5d5c4d942a60831848d0e08d3e0a3797485a4e8180103c
4
+ data.tar.gz: 76f580ebdaea0dda0a8bda34c86f0bd513c041e5c92d2b7fddd942731a5ce400
5
+ SHA512:
6
+ metadata.gz: 81e46b4c372456839dcbef202e18c5ab5f2c2833702b1818f4380410d57362de0accf26a1013f4795fae61c64ae15cca32a6994a9a3df11d2a466d34fb5e0519
7
+ data.tar.gz: 5b8fd890c3b4ed2cf4a621ac9e8b7bc78d201cc9e0c83a77b9e22b77163ac768c23cf6e68d51b6e905c4f089a56be7b1f8c845b54b08ed730fcc559944d581d2
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2022
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.md ADDED
@@ -0,0 +1,38 @@
1
+ # Eras
2
+ Error reporting services such as Bugsnag, Honeybadger, and Sentry are great, but they oftentimes leave us scratching our heads while developing locally. You're most likely not sending the errors in development environment, but the notifier caught it anyways, and now it's gone *poof*, missing. Eras takes advantage of Rails 7.0's [`ActiveSupport::ErrorReporter`](https://api.rubyonrails.org/classes/ActiveSupport/ErrorReporter.html)
3
+
4
+ ### Index
5
+ ![Index](./readme_assets/index.png)
6
+
7
+ ### Show
8
+ ![Show](./readme_assets/show.png)
9
+
10
+ ## Installation
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem "eras", group: :development
15
+ ```
16
+
17
+ And then execute:
18
+ ```bash
19
+ $ bundle
20
+ ```
21
+
22
+ mount the engine wherever you like (I prefer /eras)
23
+ ```ruby
24
+ # config/routes.rb
25
+ mount Eras::Engine => "/eras" if defined?(Eras::Engine) # We only require this in development
26
+ ```
27
+
28
+ ## Disclaimer
29
+
30
+ This gem is in active development, and delivered as-is.
31
+
32
+ ## Contributing
33
+ You must run the tailwindcss server while developing, and commit any changes to `app/assets/builds`
34
+ ```
35
+ rake tailwind_engine_watch
36
+ ```
37
+
38
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ /*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:Inter var,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}[multiple],[type=date],[type=datetime-local],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],select,textarea{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem}[multiple]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,select:focus,textarea:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em}::-webkit-datetime-edit,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple]{background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:1rem}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}[type=checkbox]:checked,[type=radio]:checked{background-color:currentColor;background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0z'/%3E%3C/svg%3E")}[type=radio]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E")}[type=checkbox]:checked:focus,[type=checkbox]:checked:hover,[type=checkbox]:indeterminate,[type=radio]:checked:focus,[type=radio]:checked:hover{background-color:currentColor;border-color:#0000}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:#0000}[type=file]{background:unset;border-color:inherit;border-radius:0;border-width:0;font-size:unset;line-height:inherit;padding:0}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.relative{position:relative}.mx-auto{margin-left:auto;margin-right:auto}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.mb-5{margin-bottom:1.25rem}.mt-4{margin-top:1rem}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.h-20{height:5rem}.w-full{width:100%}.w-3{width:.75rem}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.table-fixed{table-layout:fixed}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.bg-slate-900{--tw-bg-opacity:1;background-color:rgb(15 23 42/var(--tw-bg-opacity))}.bg-red-600{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity))}.bg-yellow-500{--tw-bg-opacity:1;background-color:rgb(234 179 8/var(--tw-bg-opacity))}.bg-blue-400{--tw-bg-opacity:1;background-color:rgb(96 165 250/var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-slate-500{--tw-bg-opacity:1;background-color:rgb(100 116 139/var(--tw-bg-opacity))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity))}.p-6{padding:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-4{padding-bottom:1rem;padding-top:1rem}.py-2\.5{padding-bottom:.625rem;padding-top:.625rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-extrabold{font-weight:800}.uppercase{text-transform:uppercase}.leading-tight{line-height:1.25}.tracking-wider{letter-spacing:.05em}.tracking-wide{letter-spacing:.025em}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-150,.transition{transition-duration:.15s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.hover\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity))}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:bg-blue-700:focus{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity))}.focus\:shadow-lg:focus{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\:outline-none:focus{outline:2px solid #0000;outline-offset:2px}.focus\:ring-0:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.active\:bg-blue-800:active{--tw-bg-opacity:1;background-color:rgb(30 64 175/var(--tw-bg-opacity))}.active\:shadow-lg:active{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}@media (prefers-color-scheme:dark){.dark\:divide-gray-700>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(55 65 81/var(--tw-divide-opacity))}.dark\:bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.dark\:text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.dark\:text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.dark\:hover\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}}
@@ -0,0 +1 @@
1
+ //= link_tree ../builds/ .css
@@ -0,0 +1,13 @@
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
+ */
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module Eras
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,11 @@
1
+ module Eras
2
+ class ErrorsController < ApplicationController
3
+ def index
4
+ @errors = Eras::Adapters::FileSystem.new.read_errors
5
+ end
6
+
7
+ def show
8
+ @error = Eras::Adapters::FileSystem.new.read_error(params[:id])
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ module Eras
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module Eras
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ <% case severity %>
2
+ <% when "error" %>
3
+ <td class="w-3 bg-red-600"></td>
4
+ <% when "warning" %>
5
+ <td class="w-3 bg-yellow-500"></td>
6
+ <% when "info" %>
7
+ <td class="w-3 bg-blue-400"></td>
8
+ <% end %>
@@ -0,0 +1,38 @@
1
+ <div class="max-w-2xl mx-auto">
2
+
3
+ <div class="flex flex-col">
4
+ <div class="overflow-x-auto shadow-md sm:rounded-lg">
5
+ <div class="inline-block min-w-full align-middle">
6
+ <div class="overflow-hidden ">
7
+ <table class="min-w-full divide-y divide-gray-200 table-fixed dark:divide-gray-700">
8
+ <thead class="bg-gray-100 dark:bg-gray-700">
9
+ <tr>
10
+ <th></th>
11
+ <th scope="col" class="py-3 px-6 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
12
+ Class
13
+ </th>
14
+ <th scope="col" class="py-3 px-6 text-xs font-medium tracking-wider text-left text-gray-700 uppercase dark:text-gray-400">
15
+ Message
16
+ </th>
17
+ <th></th>
18
+ </tr>
19
+ </thead>
20
+ <tbody data-controller="error-show" class="bg-white divide-y divide-gray-200 dark:bg-gray-800 dark:divide-gray-700">
21
+ <% @errors.each do |error| %>
22
+ <tr class="hover:bg-gray-100 dark:hover:bg-gray-700">
23
+ <%= render partial: "severity_cell", locals: { severity: error["severity"] } %>
24
+ <td class="py-4 px-6 text-sm font-medium text-gray-900 whitespace-nowrap dark:text-white"><%= error.dig("error", "class") %></td>
25
+ <td class="py-4 px-6 text-sm font-medium text-gray-500 whitespace-nowrap dark:text-white"><%= error.dig("error", "message") %></td>
26
+ <td>
27
+ <div class="flex space-x-2 justify-center">
28
+ <a href="<%= error_path(error['id'])%>" class="inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out">View</a>
29
+ </div>
30
+ </td>
31
+ </tr>
32
+ <% end %>
33
+ </tbody>
34
+ </table>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </div>
@@ -0,0 +1,14 @@
1
+ <div class="p-6 shadow-lg rounded-lg bg-gray-100 text-gray-700">
2
+ <h2 class="font-semibold text-3xl mb-5"><%= @error.dig('error', 'class') %></h2>
3
+ <p><%= @error.dig('error', 'message') %></p>
4
+ <hr class="my-6 border-gray-300" />
5
+ <p class="whitespace-pre-line text-xs"><%= @error.dig('error', 'backtrace').gsub('\n', '<br/>').html_safe %></p>
6
+ <a
7
+ href="<%= errors_path %>"
8
+ class="inline-block px-6 py-2.5 mt-4 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out"
9
+ data-mdb-ripple="true"
10
+ data-mdb-ripple-color="light"
11
+ >
12
+ Back
13
+ </a>
14
+ </div>
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Eras</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "eras", "data-turbo-track": "reload" %>
9
+ </head>
10
+ <%= render "shared/navbar" %>
11
+
12
+ <body class="bg-slate-500">
13
+
14
+ <div class="container mx-auto">
15
+ <%= yield %>
16
+ </div>
17
+
18
+ </body>
19
+ </html>
@@ -0,0 +1,7 @@
1
+ <nav class=" bg-slate-900 w-full flex relative justify-between items-center mx-auto px-8 h-20 mb-5">
2
+ <!-- logo -->
3
+ <div class="inline-flex">
4
+ <h1 class="text-xl text-white font-extrabold tracking-wider">Eras</h1>
5
+ </div>
6
+ <!-- end logo -->
7
+ </nav>
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ Eras::Engine.routes.draw do
2
+ root to: 'errors#index'
3
+ resources :errors, only: [:index, :show]
4
+ end
@@ -0,0 +1,22 @@
1
+ const defaultTheme = require('tailwindcss/defaultTheme')
2
+
3
+ module.exports = {
4
+ content: [
5
+ './public/*.html',
6
+ './app/helpers/**/*.rb',
7
+ './app/javascript/**/*.js',
8
+ './app/views/**/*.{erb,haml,html,slim}'
9
+ ],
10
+ theme: {
11
+ extend: {
12
+ fontFamily: {
13
+ sans: ['Inter var', ...defaultTheme.fontFamily.sans],
14
+ },
15
+ },
16
+ },
17
+ plugins: [
18
+ require('@tailwindcss/forms'),
19
+ require('@tailwindcss/aspect-ratio'),
20
+ require('@tailwindcss/typography'),
21
+ ]
22
+ }
@@ -0,0 +1,38 @@
1
+ module Eras
2
+ module Adapters
3
+ class FileSystem
4
+ def initialize(path = nil)
5
+ @path = Rails.root.join("tmp", "eras", "errors.json")
6
+ end
7
+
8
+ def write_error(data)
9
+ # Database adapters may have an id, but filesystem adapters don't
10
+ data['id'] = SecureRandom.uuid
11
+
12
+ # TODO: Large numbers of errors will cause this to grow unbounded, could have memory issues.
13
+ # Should we use file rotation, sqlite (separate adapter), or something else?
14
+ existing_errors = begin
15
+ JSON.parse(File.read(@path))
16
+ rescue Errno::ENOENT, JSON::ParserError
17
+ []
18
+ end
19
+
20
+ File.open(@path, "w") do |f|
21
+ errors = existing_errors
22
+ errors.unshift(data)
23
+ f.write(errors.to_json)
24
+ end
25
+ end
26
+
27
+ def read_errors
28
+ File.open(@path, "r") do |f|
29
+ JSON.parse(f.read)
30
+ end
31
+ end
32
+
33
+ def read_error(id)
34
+ read_errors.find { |e| e['id'] == id }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ require 'eras/error_reporter'
2
+
3
+ module Eras
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace Eras
6
+
7
+ initializer "eras.assets" do |app|
8
+ app.config.assets.precompile += %w[eras_manifest]
9
+ end
10
+
11
+ initializer "eras.error_subscriber" do |app|
12
+ app.executor.error_reporter.subscribe(Eras::ErrorReporter.new)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ module Eras
2
+ class ErrorReporter
3
+ def initialize(adapter: Eras::Adapters::FileSystem.new)
4
+ @adapter = adapter
5
+ end
6
+
7
+ def report(error, handled:, severity:, context:, source: nil)
8
+ data = {
9
+ error: {
10
+ class: error.class.name,
11
+ message: error.message,
12
+ backtrace: error.backtrace.join("\n")
13
+ },
14
+ handled: handled,
15
+ severity: severity,
16
+ context: context.transform_values(&:to_s), # ActionController.to_s causes stack overflow
17
+ source: source
18
+ }
19
+ @adapter.write_error(data)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Eras
2
+ VERSION = "0.1.0"
3
+ end
data/lib/eras.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "eras/version"
2
+ require "eras/engine"
3
+ require "eras/adapters/file_system"
4
+
5
+ module Eras
6
+ # Your code goes here...
7
+ end
@@ -0,0 +1,15 @@
1
+ # desc "Explaining what the task does"
2
+ # task :eras do
3
+ # # Task goes here
4
+ # end
5
+ task default: [:test, "standard:fix"]
6
+
7
+ task :tailwind_engine_watch do
8
+ require 'tailwindcss-rails'
9
+ # NOTE: tailwindcss-rails is an engine
10
+ system "#{Tailwindcss::Engine.root.join("exe/tailwindcss")} \
11
+ -i #{Eras::Engine.root.join("app/assets/stylesheets/application.tailwind.css")} \
12
+ -o #{Eras::Engine.root.join("app/assets/builds/eras.css")} \
13
+ -c #{Eras::Engine.root.join("config/tailwind.config.js")} \
14
+ --minify -w"
15
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eras
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Bobby McDonald
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-11-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 7.0.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 7.0.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: tailwindcss-rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: standard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Local error visibility for Rails' ActiveSupport::ErrorReporter
56
+ email:
57
+ - bobbymcwho@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - MIT-LICENSE
63
+ - README.md
64
+ - Rakefile
65
+ - app/assets/builds/eras.css
66
+ - app/assets/config/eras_manifest.js
67
+ - app/assets/stylesheets/application.tailwind.css
68
+ - app/assets/stylesheets/eras/application.css
69
+ - app/controllers/eras/application_controller.rb
70
+ - app/controllers/eras/errors_controller.rb
71
+ - app/helpers/eras/application_helper.rb
72
+ - app/models/eras/application_record.rb
73
+ - app/views/eras/errors/_severity_cell.html.erb
74
+ - app/views/eras/errors/index.html.erb
75
+ - app/views/eras/errors/show.html.erb
76
+ - app/views/layouts/eras/application.html.erb
77
+ - app/views/shared/_navbar.html.erb
78
+ - config/routes.rb
79
+ - config/tailwind.config.js
80
+ - lib/eras.rb
81
+ - lib/eras/adapters/file_system.rb
82
+ - lib/eras/engine.rb
83
+ - lib/eras/error_reporter.rb
84
+ - lib/eras/version.rb
85
+ - lib/tasks/eras_tasks.rake
86
+ homepage: https://github.com/bobbymcwho/eras
87
+ licenses:
88
+ - MIT
89
+ metadata:
90
+ allowed_push_host: https://rubygems.org
91
+ homepage_uri: https://github.com/bobbymcwho/eras
92
+ source_code_uri: https://github.com/bobbymcwho/eras
93
+ changelog_uri: https://github.com/bobbymcwho/eras
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubygems_version: 3.2.32
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Local error visibility for Rails' ActiveSupport::ErrorReporter
113
+ test_files: []