tybo 0.0.1 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -0
- data/README.md +23 -0
- data/Rakefile +8 -0
- data/app/assets/config/tybo_manifest.js +1 -0
- data/app/assets/stylesheets/tybo/application.css +15 -0
- data/{lib/app → app}/components/attachment_card_component.html.erb +0 -0
- data/{lib/app → app}/components/attachment_card_component.rb +0 -0
- data/{lib/app → app}/components/attachments_list_component.html.erb +0 -0
- data/{lib/app → app}/components/attachments_list_component.rb +0 -0
- data/{lib/app → app}/components/current_user_mini_card_component.html.erb +2 -2
- data/{lib/app → app}/components/current_user_mini_card_component.rb +0 -0
- data/{lib/app → app}/components/form_component.html.erb +1 -1
- data/{lib/app → app}/components/form_component.rb +0 -0
- data/{lib/app → app}/components/forms/breadcrumb_component.html.erb +0 -0
- data/{lib/app → app}/components/forms/breadcrumb_component.rb +0 -0
- data/{lib/app → app}/components/forms/delete_button_component.html.erb +0 -0
- data/{lib/app → app}/components/forms/delete_button_component.rb +0 -0
- data/{lib/app → app}/components/forms/divider_component.html.erb +0 -0
- data/{lib/app → app}/components/forms/divider_component.rb +0 -0
- data/{lib/app → app}/components/forms/submit_button_component.html.erb +0 -0
- data/{lib/app → app}/components/forms/submit_button_component.rb +0 -0
- data/app/components/forms/subtitle_component.html.erb +5 -0
- data/{lib/app → app}/components/forms/subtitle_component.rb +0 -0
- data/{lib/app → app}/components/forms/title_component.html.erb +0 -0
- data/{lib/app → app}/components/forms/title_component.rb +0 -0
- data/{lib/app → app}/components/icons/collection_component.html.erb +0 -0
- data/{lib/app → app}/components/icons/collection_component.rb +0 -0
- data/{lib/app → app}/components/icons/home_component.html.erb +0 -0
- data/{lib/app → app}/components/icons/home_component.rb +0 -0
- data/{lib/app → app}/components/icons/mic_component.html.erb +0 -0
- data/{lib/app → app}/components/icons/mic_component.rb +0 -0
- data/{lib/app → app}/components/icons/news_paper_component.html.erb +0 -0
- data/{lib/app → app}/components/icons/news_paper_component.rb +0 -0
- data/{lib/app → app}/components/icons/office_building_component.html.erb +0 -0
- data/{lib/app → app}/components/icons/office_building_component.rb +0 -0
- data/{lib/app → app}/components/icons/question_mark_circle_component.html.erb +0 -0
- data/{lib/app → app}/components/icons/question_mark_circle_component.rb +0 -0
- data/{lib/app → app}/components/icons/trash_component.html.erb +0 -0
- data/{lib/app → app}/components/icons/trash_component.rb +0 -0
- data/{lib/app → app}/components/icons/users_component.html.erb +0 -0
- data/{lib/app → app}/components/icons/users_component.rb +0 -0
- data/{lib/app → app}/components/index_component.html.erb +0 -0
- data/{lib/app → app}/components/index_component.rb +0 -0
- data/app/components/index_header_add_component.html.erb +3 -0
- data/{lib/app → app}/components/index_header_add_component.rb +0 -0
- data/{lib/app → app}/components/index_header_component.html.erb +0 -0
- data/{lib/app → app}/components/index_header_component.rb +0 -0
- data/{lib/app → app}/components/input/file_component.html.erb +0 -0
- data/{lib/app → app}/components/input/file_component.rb +0 -0
- data/{lib/app → app}/components/sidebar_component.html.erb +2 -2
- data/{lib/app → app}/components/sidebar_component.rb +0 -0
- data/{lib/app → app}/components/sidebar_item_component.html.erb +0 -0
- data/{lib/app → app}/components/sidebar_item_component.rb +0 -0
- data/{lib/app → app}/components/sign_out_button_component.html.erb +1 -1
- data/{lib/app → app}/components/sign_out_button_component.rb +3 -0
- data/app/components/tables/active_record_th_component.html.erb +3 -0
- data/app/components/tables/active_record_th_component.rb +18 -0
- data/{lib/app → app}/components/tables/table_component.html.erb +0 -0
- data/{lib/app → app}/components/tables/table_component.rb +0 -0
- data/{lib/app → app}/components/tables/tbody_component.html.erb +0 -0
- data/{lib/app → app}/components/tables/tbody_component.rb +0 -0
- data/{lib/app → app}/components/tables/td_component.html.erb +1 -1
- data/{lib/app → app}/components/tables/td_component.rb +0 -0
- data/{lib/app → app}/components/tables/th_component.html.erb +0 -0
- data/{lib/app → app}/components/tables/th_component.rb +0 -0
- data/{lib/app → app}/components/tables/thead_component.html.erb +3 -0
- data/{lib/app → app}/components/tables/thead_component.rb +1 -0
- data/{lib/app → app}/components/tables/tr_component.html.erb +0 -0
- data/{lib/app → app}/components/tables/tr_component.rb +0 -0
- data/app/controllers/tybo/application_controller.rb +4 -0
- data/app/controllers/tybo/login_controller.rb +8 -0
- data/app/helpers/tybo/application_helper.rb +5 -0
- data/app/helpers/tybo/flash_helper.rb +12 -0
- data/app/jobs/tybo/application_job.rb +4 -0
- data/app/mailers/tybo/application_mailer.rb +6 -0
- data/app/models/tybo/application_record.rb +5 -0
- data/app/views/devise/confirmations/new.html.erb +20 -0
- data/app/views/devise/login/home.html.erb +20 -0
- data/app/views/devise/mailer/_reset_password_instructions.html.erb +8 -0
- data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
- data/app/views/devise/mailer/email_changed.html.erb +7 -0
- data/app/views/devise/mailer/password_change.html.erb +3 -0
- data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
- data/app/views/devise/passwords/edit.html.erb +36 -0
- data/app/views/devise/passwords/new.html.erb +34 -0
- data/app/views/devise/registrations/edit.html.erb +35 -0
- data/app/views/devise/registrations/new.html.erb +25 -0
- data/app/views/devise/sessions/new.html.erb +50 -0
- data/app/views/devise/shared/_devise_errors.html.erb +26 -0
- data/app/views/devise/shared/_error_messages.html.erb +15 -0
- data/app/views/devise/shared/_links.html.erb +65 -0
- data/app/views/devise/unlocks/new.html.erb +19 -0
- data/app/views/layouts/_errors.html.erb +22 -0
- data/app/views/layouts/_flash.html.erb +24 -0
- data/app/views/layouts/devise_admin.html.erb +16 -0
- data/app/views/layouts/tybo/application.html.erb +14 -0
- data/app/views/login/home.html.erb +19 -0
- data/app/views/shared/_pagination.html.erb +36 -0
- data/config/initializers/devise.rb +311 -0
- data/config/initializers/pagy.rb +246 -0
- data/config/initializers/ransack.rb +13 -0
- data/config/locales/devise.en.yml +65 -0
- data/config/routes.rb +3 -0
- data/lib/generators/bo/USAGE +12 -0
- data/lib/generators/bo/bo_generator.rb +88 -0
- data/lib/generators/bo/templates/_form.html.erb +32 -0
- data/lib/generators/bo/templates/_search_bar.html.erb +96 -0
- data/lib/generators/bo/templates/_table.html.erb +29 -0
- data/lib/generators/bo/templates/controller.rb +66 -0
- data/lib/generators/bo/templates/index.html.erb +19 -0
- data/lib/generators/bo/templates/item.html.erb +17 -0
- data/lib/generators/bo/templates/new.html.erb +1 -0
- data/lib/generators/bo/templates/show.html.erb +1 -0
- data/lib/generators/bo/utils/files/fr.json +19 -0
- data/lib/generators/bo/utils/translations.rb +47 -0
- data/lib/generators/bo_namespace/USAGE +11 -0
- data/lib/generators/bo_namespace/bo_namespace_generator.rb +50 -0
- data/lib/generators/bo_namespace/templates/admin.html.erb +27 -0
- data/lib/generators/bo_namespace/templates/admin_controller.rb +7 -0
- data/lib/generators/bo_namespace/templates/seeds.rb +9 -0
- data/lib/generators/bo_namespace/templates/side_bar.html.erb +4 -0
- data/lib/generators/tybo_install/templates/application.tailwind.css +112 -0
- data/lib/generators/tybo_install/templates/simple_form_tailwind.rb +147 -0
- data/lib/generators/tybo_install/templates/tailwind.config.js +40 -0
- data/lib/generators/tybo_install/templates/tom-select.css +458 -0
- data/lib/generators/tybo_install/tybo_install_generator.rb +44 -0
- data/lib/tybo/engine.rb +19 -0
- data/lib/tybo/version.rb +3 -0
- data/lib/tybo.rb +4 -43
- metadata +186 -89
- data/lib/app/components/forms/subtitle_component.html.erb +0 -5
- data/lib/app/components/index_header_add_component.html.erb +0 -3
- data/lib/app/helpers/application_helper.rb +0 -5
- data/lib/app/helpers/flash_helper.rb +0 -16
- data/lib/app/javascript/controllers/flash_controller.js +0 -7
@@ -0,0 +1,19 @@
|
|
1
|
+
<%%= render(IndexComponent.new) do |index| %>
|
2
|
+
<!-- Header -->
|
3
|
+
<%%= index.with_header(
|
4
|
+
title: I18n.t('bo.<%= class_name.underscore %>.others').capitalize,
|
5
|
+
subtitle: I18n.t('bo.<%= class_name.underscore %>.subtitle').capitalize,
|
6
|
+
) do |header| %>
|
7
|
+
<%%= header.with_add_button(path: <%="new_#{options[:namespace]}_#{class_name.underscore}_path" %>) %>
|
8
|
+
<%% end %>
|
9
|
+
|
10
|
+
<!-- Search Bar -->
|
11
|
+
<%%= render('search_bar') %>
|
12
|
+
<!-- Table -->
|
13
|
+
<%%= turbo_frame_tag "<%= class_name.underscore.pluralize %>", class: "shadow overflow-hidden rounded border-b border-gray-200" do %>
|
14
|
+
<%%= render('table') %>
|
15
|
+
<div class="py-2">
|
16
|
+
<%%== render partial: 'shared/pagination', locals: { pagy: @pagy } %>
|
17
|
+
</div>
|
18
|
+
<%% end %>
|
19
|
+
<%% end %>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%%= render(FormComponent.new(item: <%= class_name.underscore %>)) do |form| %>
|
2
|
+
<%%
|
3
|
+
current_page = if <%= class_name.underscore
|
4
|
+
%>.persisted?
|
5
|
+
{ label: "Détails", path: <%= "#{options[:namespace]}_#{class_name.underscore}_path(#{class_name.underscore})"%> }
|
6
|
+
else
|
7
|
+
{ label: "Nouvelle <%= class_name.underscore %>", path: <%= "new_#{options[:namespace]}_#{class_name.underscore}_path" %> }
|
8
|
+
end
|
9
|
+
form.with_title(<%= class_name.underscore %>.persisted? ? <%= class_name.underscore %>.<%=bo_model_title(bo_model)%> : 'Nouvelle <%= class_name.underscore %>')
|
10
|
+
form.with_breadcrumb([
|
11
|
+
{ label: I18n.t('bo.<%= class_name.underscore %>.others').capitalize, path: <%= "#{options[:namespace]}_#{class_name.pluralize.underscore}_path"%> },
|
12
|
+
current_page
|
13
|
+
])
|
14
|
+
%>
|
15
|
+
<br>
|
16
|
+
<%%= render "form", <%= class_name.underscore %>: @<%= class_name.underscore %> %>
|
17
|
+
<%% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%%= render "<%= class_name.underscore %>", <%= class_name.underscore %>: @<%= class_name.underscore %> %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%%= render "<%= class_name.underscore %>", <%= class_name.underscore %>: @<%= class_name.underscore %> %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"id": "identifiant",
|
3
|
+
"email": "email",
|
4
|
+
"password": "mot de passe",
|
5
|
+
"created_at": "date de création",
|
6
|
+
"updated_at": "date de modification",
|
7
|
+
"title": "titre",
|
8
|
+
"content": "contenu",
|
9
|
+
"description": "description",
|
10
|
+
"name": "nom",
|
11
|
+
"position": "position",
|
12
|
+
"first_name": "prénom",
|
13
|
+
"last_name": "nom",
|
14
|
+
"full_name": "nom complet",
|
15
|
+
"updated": "modification effectuée",
|
16
|
+
"created": "création effectuée",
|
17
|
+
"destroyed": "suppression effectuée",
|
18
|
+
"filters": "filtres"
|
19
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
def create_translations
|
4
|
+
%w[en fr].each do |local|
|
5
|
+
locale_file = "config/locales/bo.#{local}.yml"
|
6
|
+
unless File.exist?(locale_file)
|
7
|
+
File.write(locale_file, {
|
8
|
+
local => {
|
9
|
+
'bo' => {
|
10
|
+
'filters' => find_existing_translation('filters', local),
|
11
|
+
'record' => {
|
12
|
+
'created' => find_existing_translation('created', local),
|
13
|
+
'updated' => find_existing_translation('updated', local),
|
14
|
+
'destroyed' => find_existing_translation('destroyed', local)
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}.to_yaml)
|
19
|
+
end
|
20
|
+
|
21
|
+
yaml_string = File.open locale_file
|
22
|
+
data = YAML.load yaml_string
|
23
|
+
data[local]['bo'][file_name.underscore.to_s] = {
|
24
|
+
'one' => find_existing_translation(bo_model.to_s.downcase, local),
|
25
|
+
'others' => find_existing_translation(bo_model.to_s.pluralize.downcase, local),
|
26
|
+
'subtitle' => find_existing_translation("list of #{bo_model.to_s.pluralize.downcase}", local),
|
27
|
+
'attributes' => model_attributes(local)
|
28
|
+
}
|
29
|
+
output = YAML.dump data
|
30
|
+
File.write(locale_file, output)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def model_attributes(local)
|
35
|
+
hash = {}
|
36
|
+
model_columns.each do |col|
|
37
|
+
hash[col.to_s] = find_existing_translation(col, local)
|
38
|
+
end
|
39
|
+
hash
|
40
|
+
end
|
41
|
+
|
42
|
+
def find_existing_translation(col, local)
|
43
|
+
return col.to_s.humanize.downcase if local == 'en'
|
44
|
+
|
45
|
+
json = JSON.parse(File.read("#{__dir__}/files/#{local}.json"))
|
46
|
+
json[col.to_s]
|
47
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Description:
|
2
|
+
Explain the generator
|
3
|
+
Example:
|
4
|
+
rails g bo_namespace Employer
|
5
|
+
This will create:
|
6
|
+
- a models Employer
|
7
|
+
- devise routes and namespace `employers`
|
8
|
+
- a base controller employer (base controller for this namespace)
|
9
|
+
- a controllers employers ( manage employers )
|
10
|
+
- a namespace for views
|
11
|
+
- a namespace for controllers
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class BoNamespaceGenerator < Rails::Generators::NamedBase
|
2
|
+
source_root File.expand_path("templates", __dir__)
|
3
|
+
|
4
|
+
def create_bo_namespace_files
|
5
|
+
run "bundle exec rails g devise #{file_name.capitalize}"
|
6
|
+
run 'bundle exec rails db:migrate'
|
7
|
+
create_routes_and_views
|
8
|
+
template 'admin.html.erb', File.join('app/views/layouts/', "#{singular_name}.html.erb")
|
9
|
+
template 'admin_controller.rb', File.join('app/controllers/', "#{singular_name}_controller.rb")
|
10
|
+
template 'seeds.rb', File.join('db/seeds/', "#{plural_name}.rb")
|
11
|
+
template 'side_bar.html.erb', File.join('app/views/', "#{plural_name}/layouts/_side_bar.html.erb")
|
12
|
+
#remove_devise_registration
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_directories
|
16
|
+
["app/views/#{plural_name}", "app/controllers/#{plural_name}"].each do |dir|
|
17
|
+
FileUtils.mkdir(dir) unless File.directory?(dir)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_seed_file
|
22
|
+
inject_into_file 'db/seeds.rb' do
|
23
|
+
"require_relative 'seeds/#{plural_name}.rb'\n"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def plural_name
|
30
|
+
singular_name.pluralize
|
31
|
+
end
|
32
|
+
|
33
|
+
def singular_name
|
34
|
+
file_name.underscore
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_routes_and_views
|
38
|
+
run "rails g bo #{singular_name.camelize} --namespace #{plural_name}"
|
39
|
+
# devise_route = "devise_for :#{singular_name},\n path: '#{plural_name}',\n controllers: {\n sessions: 'custom_devise/sessions',\n passwords: 'custom_devise/passwords',\n registrations: 'custom_devise/registrations'\n }"
|
40
|
+
gsub_file('config/routes.rb', /devise_for :#{plural_name}/, "devise_for :#{plural_name}, path: '#{plural_name}'")
|
41
|
+
# route devise_route
|
42
|
+
route "# #{plural_name.capitalize}\nnamespace :#{plural_name} do\n root to: '#{plural_name}#index'\n resources :#{plural_name}\nend"
|
43
|
+
end
|
44
|
+
|
45
|
+
def remove_devise_registration
|
46
|
+
file = "app/models/#{singular_name}.rb"
|
47
|
+
gsub_file(file, / :registerable,/, '')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>BO-<%= class_name %></title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<%%= csrf_meta_tags %>
|
7
|
+
<%%= csp_meta_tag %>
|
8
|
+
<%%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
9
|
+
<%%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
|
10
|
+
<%%= javascript_importmap_tags %>
|
11
|
+
<%%= hotwire_livereload_tags if Rails.env.development? %>
|
12
|
+
</head>
|
13
|
+
|
14
|
+
<body class="h-full bg-home">
|
15
|
+
<%% if <%= class_name.underscore %>_signed_in? %>
|
16
|
+
<%%= render('<%= class_name.underscore.pluralize %>/layouts/side_bar') %>
|
17
|
+
<%% end %>
|
18
|
+
<div class="<%%= 'md:pl-64' if <%= class_name.underscore %>_signed_in? %> flex flex-col flex-1">
|
19
|
+
<main>
|
20
|
+
<div class="py-6">
|
21
|
+
<%%= render('layouts/flash') %>
|
22
|
+
<%%= yield %>
|
23
|
+
</div>
|
24
|
+
</main>
|
25
|
+
</div>
|
26
|
+
</body>
|
27
|
+
</html>
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<%%= render(SidebarComponent.new) do |sidebar| %>
|
2
|
+
<%%= sidebar.with_item(path: <%="#{plural_name}_#{plural_name}_path"%>, icon: Icons::UsersComponent, label: I18n.t('bo.<%= singular_name %>.others').capitalize) %>
|
3
|
+
<%%= sidebar.with_current_user_card(user: current_<%= singular_name %>) %>
|
4
|
+
<%% end %>
|
@@ -0,0 +1,112 @@
|
|
1
|
+
@tailwind base;
|
2
|
+
@tailwind components;
|
3
|
+
@tailwind utilities;
|
4
|
+
@import 'actiontext.css';
|
5
|
+
|
6
|
+
/* pagination */
|
7
|
+
.pagy-nav,
|
8
|
+
.pagy-nav-js {
|
9
|
+
@apply flex space-x-2;
|
10
|
+
}
|
11
|
+
|
12
|
+
.pagy-nav .page a,
|
13
|
+
.pagy-nav .page.active,
|
14
|
+
.pagy-nav .page.prev.disabled,
|
15
|
+
.pagy-nav .page.next.disabled,
|
16
|
+
.pagy-nav-js .page a,
|
17
|
+
.pagy-nav-js .page.active,
|
18
|
+
.pagy-nav-js .page.prev.disabled,
|
19
|
+
.pagy-nav-js .page.next.disabled {
|
20
|
+
@apply block rounded-lg px-3 py-1 text-sm text-indigo-500 font-semibold bg-indigo-200 shadow-md;
|
21
|
+
|
22
|
+
&:hover {
|
23
|
+
@apply bg-indigo-300;
|
24
|
+
}
|
25
|
+
|
26
|
+
&:active {
|
27
|
+
@apply bg-indigo-400 text-white;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
.pagy-nav .page.prev.disabled,
|
32
|
+
.pagy-nav .page.next.disabled,
|
33
|
+
.pagy-nav-js .page.prev.disabled,
|
34
|
+
.pagy-nav-js .page.next.disabled {
|
35
|
+
@apply text-indigo-400 cursor-default;
|
36
|
+
|
37
|
+
&:hover {
|
38
|
+
@apply text-indigo-400 bg-indigo-200;
|
39
|
+
}
|
40
|
+
|
41
|
+
&:active {
|
42
|
+
@apply text-indigo-400 bg-indigo-200;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
.pagy-nav .page.active,
|
47
|
+
.pagy-nav-js .page.active {
|
48
|
+
@apply text-white cursor-default bg-indigo-400;
|
49
|
+
|
50
|
+
&:hover {
|
51
|
+
@apply text-white bg-indigo-400;
|
52
|
+
}
|
53
|
+
|
54
|
+
&:active {
|
55
|
+
@apply bg-indigo-400 text-white;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
.pagy-combo-nav-js {
|
61
|
+
@apply flex max-w-max rounded-full px-3 py-1 text-sm text-indigo-500 font-semibold bg-indigo-200 shadow-md;
|
62
|
+
}
|
63
|
+
|
64
|
+
.pagy-combo-nav-js .pagy-combo-input {
|
65
|
+
@apply bg-white px-2 rounded-sm
|
66
|
+
}
|
67
|
+
|
68
|
+
.pagy-combo-nav-js .page.prev,
|
69
|
+
.pagy-combo-nav-js .page.next {
|
70
|
+
&:hover {
|
71
|
+
@apply text-indigo-800;
|
72
|
+
}
|
73
|
+
|
74
|
+
&:active {
|
75
|
+
@apply text-indigo-800;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
.pagy-combo-nav-js .page.prev.disabled,
|
80
|
+
.pagy-combo-nav-js .page.next.disabled {
|
81
|
+
@apply text-indigo-400 cursor-default;
|
82
|
+
}
|
83
|
+
|
84
|
+
/* tom-select */
|
85
|
+
ts-wrapper {
|
86
|
+
@apply w-full !ml-0;
|
87
|
+
}
|
88
|
+
|
89
|
+
.ts-control {
|
90
|
+
@apply shadow-sm rounded-lg my-5 border-indigo-300 bg-white py-2 px-3 text-base;
|
91
|
+
}
|
92
|
+
|
93
|
+
.ts-dropdown {
|
94
|
+
@apply rounded-md border border-solid border-t border-indigo-300 text-base;
|
95
|
+
}
|
96
|
+
|
97
|
+
.ts-dropdown [data-selectable].option:first-child {
|
98
|
+
@apply rounded-t-lg;
|
99
|
+
}
|
100
|
+
|
101
|
+
.ts-dropdown [data-selectable].option:last-child {
|
102
|
+
@apply rounded-b-lg;
|
103
|
+
}
|
104
|
+
|
105
|
+
.ts-dropdown .create:hover,
|
106
|
+
.ts-dropdown .option:hover {
|
107
|
+
@apply bg-sky-50 text-sky-900;
|
108
|
+
}
|
109
|
+
|
110
|
+
.ts-dropdown .active {
|
111
|
+
@apply bg-indigo-100 text-indigo-900;
|
112
|
+
}
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Use this setup block to configure all options available in SimpleForm.
|
4
|
+
SimpleForm.setup do |config|
|
5
|
+
# Default class for buttons
|
6
|
+
config.button_class = 'my-2 bg-blue-500 hover:bg-blue-700 text-white font-bold text-sm py-2 px-4 rounded'
|
7
|
+
|
8
|
+
# Define the default class of the input wrapper of the boolean input.
|
9
|
+
config.boolean_label_class = ''
|
10
|
+
|
11
|
+
# How the label text should be generated altogether with the required text.
|
12
|
+
config.label_text = ->(label, required, _explicit_label) { "#{label} #{required}" }
|
13
|
+
|
14
|
+
# Define the way to render check boxes / radio buttons with labels.
|
15
|
+
config.boolean_style = :inline
|
16
|
+
|
17
|
+
# You can wrap each item in a collection of radio/check boxes with a tag
|
18
|
+
config.item_wrapper_tag = :div
|
19
|
+
|
20
|
+
# Defines if the default input wrapper class should be included in radio
|
21
|
+
# collection wrappers.
|
22
|
+
config.include_default_input_wrapper_class = false
|
23
|
+
|
24
|
+
# CSS class to add for error notification helper.
|
25
|
+
config.error_notification_class = 'text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-400'
|
26
|
+
|
27
|
+
# Method used to tidy up errors. Specify any Rails Array method.
|
28
|
+
# :first lists the first message for each field.
|
29
|
+
# :to_sentence to list all errors for each field.
|
30
|
+
config.error_method = :to_sentence
|
31
|
+
|
32
|
+
# add validation classes to `input_field`
|
33
|
+
config.input_field_error_class = 'border-red-500'
|
34
|
+
config.input_field_valid_class = 'border-green-400'
|
35
|
+
config.label_class = 'text-sm font-medium text-gray-600'
|
36
|
+
|
37
|
+
# vertical forms
|
38
|
+
#
|
39
|
+
# vertical default_wrapper
|
40
|
+
config.wrappers :vertical_form, tag: 'div', class: 'my-5' do |b|
|
41
|
+
b.use :html5
|
42
|
+
b.use :placeholder
|
43
|
+
b.optional :maxlength
|
44
|
+
b.optional :minlength
|
45
|
+
b.optional :pattern
|
46
|
+
b.optional :min_max
|
47
|
+
b.optional :readonly
|
48
|
+
b.use :label, class: 'block text-sm font-medium text-gray-700', error_class: 'text-red-500'
|
49
|
+
b.use :input,
|
50
|
+
class: 'mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm', error_class: 'border-red-500', valid_class: 'border-green-400'
|
51
|
+
b.use :full_error, wrap_with: { tag: 'p', class: 'mt-2 text-red-500 text-xs italic' }
|
52
|
+
b.use :hint, wrap_with: { tag: 'p', class: 'mt-2 text-grey-700 text-xs italic' }
|
53
|
+
end
|
54
|
+
|
55
|
+
# vertical input for boolean (aka checkboxes)
|
56
|
+
config.wrappers :vertical_boolean, tag: 'div', class: 'mb-4 flex items-start', error_class: '' do |b|
|
57
|
+
b.use :html5
|
58
|
+
b.optional :readonly
|
59
|
+
b.wrapper tag: 'div', class: 'flex items-center h-5' do |ba|
|
60
|
+
ba.use :input,
|
61
|
+
class: 'focus:ring-2 focus:ring-indigo-500:focus ring-offset-2 h-4 w-4 text-indigo-600 border-gray-300 rounded'
|
62
|
+
end
|
63
|
+
b.wrapper tag: 'div', class: 'ml-3 text-sm' do |bb|
|
64
|
+
bb.use :label, class: 'block', error_class: 'text-red-500'
|
65
|
+
bb.use :hint, wrap_with: { tag: 'p', class: 'block text-grey-700 text-xs italic' }
|
66
|
+
bb.use :full_error, wrap_with: { tag: 'p', class: 'block text-red-500 text-xs italic' }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# vertical input for radio buttons and check boxes
|
71
|
+
config.wrappers :vertical_collection, item_wrapper_class: 'flex items-center',
|
72
|
+
item_label_class: 'my-1 ml-3 block text-sm font-medium text-gray-400', tag: 'div', class: 'my-4' do |b|
|
73
|
+
b.use :html5
|
74
|
+
b.optional :readonly
|
75
|
+
b.wrapper :legend_tag, tag: 'legend', class: 'text-sm font-medium text-gray-600',
|
76
|
+
error_class: 'text-red-500' do |ba|
|
77
|
+
ba.use :label_text
|
78
|
+
end
|
79
|
+
b.use :input,
|
80
|
+
class: 'focus:ring-2 focus:ring-indigo-500 ring-offset-2 h-4 w-4 text-indigo-600 border-gray-300 rounded', error_class: 'text-red-500', valid_class: 'text-green-400'
|
81
|
+
b.use :full_error, wrap_with: { tag: 'p', class: 'block mt-2 text-red-500 text-xs italic' }
|
82
|
+
b.use :hint, wrap_with: { tag: 'p', class: 'mt-2 text-grey-700 text-xs italic' }
|
83
|
+
end
|
84
|
+
|
85
|
+
# vertical file input
|
86
|
+
config.wrappers :vertical_file, tag: 'div', class: '' do |b|
|
87
|
+
b.use :html5
|
88
|
+
b.use :placeholder
|
89
|
+
b.optional :maxlength
|
90
|
+
b.optional :minlength
|
91
|
+
b.optional :readonly
|
92
|
+
b.use :label, class: 'text-sm font-medium text-gray-600 block', error_class: 'text-red-500'
|
93
|
+
b.use :input, class: 'w-full text-gray-500 px-3 py-2 border rounded', error_class: 'text-red-500 border-red-500',
|
94
|
+
valid_class: 'text-green-400'
|
95
|
+
b.use :full_error, wrap_with: { tag: 'p', class: 'mt-2 text-red-500 text-xs italic' }
|
96
|
+
b.use :hint, wrap_with: { tag: 'p', class: 'mt-2 text-grey-700 text-xs italic' }
|
97
|
+
end
|
98
|
+
|
99
|
+
# vertical multi select
|
100
|
+
config.wrappers :vertical_multi_select, tag: 'div', class: 'my-4', error_class: 'f', valid_class: '' do |b|
|
101
|
+
b.use :html5
|
102
|
+
b.optional :readonly
|
103
|
+
b.wrapper :legend_tag, tag: 'legend', class: 'text-sm font-medium text-gray-600',
|
104
|
+
error_class: 'text-red-500' do |ba|
|
105
|
+
ba.use :label_text
|
106
|
+
end
|
107
|
+
b.wrapper tag: 'div', class: 'inline-flex space-x-1' do |ba|
|
108
|
+
# ba.use :input, class: 'flex w-auto w-auto text-gray-500 text-sm border-gray-300 rounded p-2', error_class: 'text-red-500', valid_class: 'text-green-400'
|
109
|
+
ba.use :input,
|
110
|
+
class: 'flex w-auto w-auto shadow appearance-none border border-gray-300 rounded w-full p-2 bg-white focus:outline-none focus:border-blue-500 text-gray-400 leading-4 transition-colors duration-200 ease-in-out'
|
111
|
+
end
|
112
|
+
b.use :full_error, wrap_with: { tag: 'p', class: 'mt-2 text-red-500 text-xs italic' }
|
113
|
+
b.use :hint, wrap_with: { tag: 'p', class: 'mt-2 text-grey-700 text-xs italic' }
|
114
|
+
end
|
115
|
+
|
116
|
+
# vertical range input
|
117
|
+
config.wrappers :vertical_range, tag: 'div', class: 'my-4', error_class: 'text-red-500',
|
118
|
+
valid_class: 'text-green-400' do |b|
|
119
|
+
b.use :html5
|
120
|
+
b.use :placeholder
|
121
|
+
b.optional :readonly
|
122
|
+
b.optional :step
|
123
|
+
b.use :label, class: 'text-sm font-medium text-gray-600 block', error_class: 'text-red-500'
|
124
|
+
b.wrapper tag: 'div', class: 'flex items-center h-5 my-100' do |ba|
|
125
|
+
ba.use :input, class: 'rounded-lg overflow-hidden appearance-none bg-gray-400 h-3 w-full text-gray-300',
|
126
|
+
error_class: 'text-red-500', valid_class: 'text-green-400'
|
127
|
+
end
|
128
|
+
b.use :full_error, wrap_with: { tag: 'p', class: 'mt-2 text-red-500 text-xs italic' }
|
129
|
+
b.use :hint, wrap_with: { tag: 'p', class: 'mt-2 text-grey-700 text-xs italic' }
|
130
|
+
end
|
131
|
+
|
132
|
+
# The default wrapper to be used by the FormBuilder.
|
133
|
+
config.default_wrapper = :vertical_form
|
134
|
+
|
135
|
+
# Custom wrappers for input types. This should be a hash containing an input
|
136
|
+
# type as key and the wrapper that will be used for all inputs with specified type.
|
137
|
+
config.wrapper_mappings = {
|
138
|
+
boolean: :vertical_boolean,
|
139
|
+
check_boxes: :vertical_collection,
|
140
|
+
date: :vertical_multi_select,
|
141
|
+
datetime: :vertical_multi_select,
|
142
|
+
file: :vertical_file,
|
143
|
+
radio_buttons: :vertical_collection,
|
144
|
+
range: :vertical_range,
|
145
|
+
time: :vertical_multi_select
|
146
|
+
}
|
147
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
const defaultTheme = require('tailwindcss/defaultTheme')
|
2
|
+
const execSync = require('child_process').execSync;
|
3
|
+
const output = execSync('bundle show tybo', { encoding: 'utf-8' });
|
4
|
+
|
5
|
+
|
6
|
+
module.exports = {
|
7
|
+
content: [
|
8
|
+
'./app/helpers/**/*.rb',
|
9
|
+
'./app/javascript/**/*.js',
|
10
|
+
'./app/views/**/*.{erb,haml,html,slim}',
|
11
|
+
'./app/components/**/*.html.erb',
|
12
|
+
output.trim() + '/app/**/*.{erb,haml,html,rb}'
|
13
|
+
],
|
14
|
+
theme: {
|
15
|
+
extend: {
|
16
|
+
fontFamily: {
|
17
|
+
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
|
18
|
+
},
|
19
|
+
colors: {
|
20
|
+
sidebar: {
|
21
|
+
DEFAULT: '#11072C',
|
22
|
+
50: 'rgba(255, 255, 255, 0.5)',
|
23
|
+
200: 'rgba(255, 255, 255, 0.2)',
|
24
|
+
900: 'rgba(0, 0, 0, 0.2)',
|
25
|
+
},
|
26
|
+
custom: {
|
27
|
+
DEFAULT: '#11072C',
|
28
|
+
},
|
29
|
+
home: {
|
30
|
+
DEFAULT: '#F5F5F5'
|
31
|
+
}
|
32
|
+
}
|
33
|
+
},
|
34
|
+
},
|
35
|
+
plugins: [
|
36
|
+
require('@tailwindcss/forms'),
|
37
|
+
require('@tailwindcss/aspect-ratio'),
|
38
|
+
require('@tailwindcss/typography'),
|
39
|
+
]
|
40
|
+
}
|