active_element 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +12 -2
- data/.strong_versions.yml +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +111 -78
- data/Makefile +10 -0
- data/active_element.gemspec +1 -1
- data/app/assets/javascripts/active_element/application.js +1 -0
- data/app/assets/javascripts/active_element/form.js +16 -32
- data/app/assets/javascripts/active_element/json_field.js +391 -135
- data/app/assets/javascripts/active_element/setup.js +13 -8
- data/app/assets/javascripts/active_element/text_search_field.js +27 -28
- data/app/assets/javascripts/active_element/theme.js +1 -1
- data/app/assets/javascripts/active_element/timezones.js +6 -0
- data/app/assets/stylesheets/active_element/_dark.scss +86 -0
- data/app/assets/stylesheets/active_element/_variables.scss +2 -1
- data/app/assets/stylesheets/active_element/application.scss +170 -31
- data/app/controllers/active_element/application_controller.rb +5 -0
- data/app/controllers/concerns/active_element/default_controller_actions.rb +38 -0
- data/app/views/active_element/_user.html.erb +20 -0
- data/app/views/active_element/components/fields/_json.html.erb +24 -0
- data/app/views/active_element/components/form/_check_box.html.erb +1 -0
- data/app/views/active_element/components/form/_check_boxes.html.erb +1 -1
- data/app/views/active_element/components/form/_datetime_range_field.html.erb +14 -0
- data/app/views/active_element/components/form/_field.html.erb +10 -7
- data/app/views/active_element/components/form/_generic_field.html.erb +1 -0
- data/app/views/active_element/components/form/_json.html.erb +10 -2
- data/app/views/active_element/components/form/_label.html.erb +12 -1
- data/app/views/active_element/components/form/_select.html.erb +4 -1
- data/app/views/active_element/components/form/_summary.html.erb +11 -1
- data/app/views/active_element/components/form/_templates.html.erb +37 -22
- data/app/views/active_element/components/form/_text_area.html.erb +2 -1
- data/app/views/active_element/components/form/_text_search.html.erb +7 -3
- data/app/views/active_element/components/form.html.erb +20 -17
- data/app/views/active_element/components/json.html.erb +1 -0
- data/app/views/active_element/components/navbar.html.erb +26 -0
- data/app/views/active_element/components/table/_collection_row.html.erb +2 -1
- data/app/views/active_element/components/table/_field.html.erb +8 -0
- data/app/views/active_element/components/table/collection.html.erb +1 -1
- data/app/views/active_element/components/table/item.html.erb +5 -4
- data/app/views/active_element/default_views/edit.html.erb +5 -0
- data/app/views/active_element/default_views/index.html.erb +15 -0
- data/app/views/active_element/default_views/new.html.erb +4 -0
- data/app/views/active_element/default_views/show.html.erb +7 -0
- data/app/views/active_element/navbar/_menu.html.erb +1 -30
- data/app/views/active_element/theme/_select.html.erb +1 -1
- data/app/views/layouts/active_element.html.erb +17 -2
- data/config/brakeman.ignore +48 -0
- data/example_app/.gitattributes +7 -0
- data/example_app/.gitignore +35 -0
- data/example_app/.ruby-version +1 -0
- data/example_app/Gemfile +34 -0
- data/example_app/Gemfile.lock +296 -0
- data/example_app/README.md +24 -0
- data/example_app/Rakefile +6 -0
- data/example_app/app/assets/config/manifest.js +4 -0
- data/example_app/app/assets/images/.keep +0 -0
- data/example_app/app/assets/stylesheets/application.css +15 -0
- data/example_app/app/channels/application_cable/channel.rb +4 -0
- data/example_app/app/channels/application_cable/connection.rb +4 -0
- data/example_app/app/controllers/application_controller.rb +12 -0
- data/example_app/app/controllers/concerns/.keep +0 -0
- data/example_app/app/controllers/pets_controller.rb +6 -0
- data/example_app/app/controllers/users_controller.rb +6 -0
- data/example_app/app/helpers/application_helper.rb +2 -0
- data/example_app/app/javascript/application.js +3 -0
- data/example_app/app/javascript/controllers/application.js +9 -0
- data/example_app/app/javascript/controllers/hello_controller.js +7 -0
- data/example_app/app/javascript/controllers/index.js +11 -0
- data/example_app/app/jobs/application_job.rb +7 -0
- data/example_app/app/mailers/application_mailer.rb +4 -0
- data/example_app/app/models/application_record.rb +3 -0
- data/example_app/app/models/concerns/.keep +0 -0
- data/example_app/app/models/pet.rb +3 -0
- data/example_app/app/models/user.rb +8 -0
- data/example_app/app/views/layouts/application.html.erb +16 -0
- data/example_app/app/views/layouts/mailer.html.erb +13 -0
- data/example_app/app/views/layouts/mailer.text.erb +1 -0
- data/example_app/app/views/pets/index.html.erb +3 -0
- data/example_app/app/views/users/show.html.erb +3 -0
- data/example_app/bin/bundle +109 -0
- data/example_app/bin/importmap +4 -0
- data/example_app/bin/rails +4 -0
- data/example_app/bin/rake +4 -0
- data/example_app/bin/setup +33 -0
- data/example_app/config/application.rb +22 -0
- data/example_app/config/boot.rb +4 -0
- data/example_app/config/cable.yml +10 -0
- data/example_app/config/credentials.yml.enc +1 -0
- data/example_app/config/database.yml +25 -0
- data/example_app/config/environment.rb +5 -0
- data/example_app/config/environments/development.rb +70 -0
- data/example_app/config/environments/production.rb +93 -0
- data/example_app/config/environments/test.rb +60 -0
- data/example_app/config/importmap.rb +7 -0
- data/example_app/config/initializers/assets.rb +12 -0
- data/example_app/config/initializers/content_security_policy.rb +25 -0
- data/example_app/config/initializers/devise.rb +16 -0
- data/example_app/config/initializers/filter_parameter_logging.rb +8 -0
- data/example_app/config/initializers/inflections.rb +16 -0
- data/example_app/config/initializers/permissions_policy.rb +11 -0
- data/example_app/config/locales/devise.en.yml +65 -0
- data/example_app/config/locales/en.yml +33 -0
- data/example_app/config/puma.rb +43 -0
- data/example_app/config/routes.rb +8 -0
- data/example_app/config/storage.yml +34 -0
- data/example_app/config.ru +6 -0
- data/example_app/db/migrate/20230616210539_create_pet.rb +12 -0
- data/example_app/db/migrate/20230616211328_devise_create_users.rb +46 -0
- data/example_app/db/schema.rb +37 -0
- data/example_app/db/seeds.rb +33 -0
- data/example_app/lib/assets/.keep +0 -0
- data/example_app/lib/tasks/.keep +0 -0
- data/example_app/log/.keep +0 -0
- data/example_app/public/404.html +67 -0
- data/example_app/public/422.html +67 -0
- data/example_app/public/500.html +66 -0
- data/example_app/public/apple-touch-icon-precomposed.png +0 -0
- data/example_app/public/apple-touch-icon.png +0 -0
- data/example_app/public/favicon.ico +0 -0
- data/example_app/public/robots.txt +1 -0
- data/example_app/storage/.keep +0 -0
- data/example_app/test/application_system_test_case.rb +5 -0
- data/example_app/test/channels/application_cable/connection_test.rb +11 -0
- data/example_app/test/controllers/.keep +0 -0
- data/example_app/test/fixtures/files/.keep +0 -0
- data/example_app/test/fixtures/users.yml +11 -0
- data/example_app/test/helpers/.keep +0 -0
- data/example_app/test/integration/.keep +0 -0
- data/example_app/test/mailers/.keep +0 -0
- data/example_app/test/models/.keep +0 -0
- data/example_app/test/models/user_test.rb +7 -0
- data/example_app/test/system/.keep +0 -0
- data/example_app/test/test_helper.rb +13 -0
- data/example_app/tmp/.keep +0 -0
- data/example_app/tmp/pids/.keep +0 -0
- data/example_app/tmp/storage/.keep +0 -0
- data/example_app/vendor/.keep +0 -0
- data/example_app/vendor/javascript/.keep +0 -0
- data/lib/active_element/component.rb +9 -2
- data/lib/active_element/components/collection_table.rb +9 -2
- data/lib/active_element/components/email_fields.rb +14 -0
- data/lib/active_element/components/form.rb +48 -17
- data/lib/active_element/components/navbar.rb +64 -0
- data/lib/active_element/components/phone_fields.rb +14 -0
- data/lib/active_element/components/text_search/authorization.rb +9 -6
- data/lib/active_element/components/text_search/component.rb +4 -2
- data/lib/active_element/components/text_search.rb +4 -0
- data/lib/active_element/components/util/association_mapping.rb +74 -19
- data/lib/active_element/components/util/display_value_mapping.rb +13 -4
- data/lib/active_element/components/util/form_field_mapping.rb +127 -10
- data/lib/active_element/components/util/form_value_mapping.rb +3 -7
- data/lib/active_element/components/util/i18n.rb +1 -1
- data/lib/active_element/components/util/record_mapping.rb +43 -11
- data/lib/active_element/components/util/record_path.rb +21 -4
- data/lib/active_element/components/util.rb +12 -5
- data/lib/active_element/components.rb +3 -0
- data/lib/active_element/controller_action.rb +8 -2
- data/lib/active_element/controller_interface.rb +47 -5
- data/lib/active_element/default_controller.rb +93 -0
- data/lib/active_element/default_record_params.rb +62 -0
- data/lib/active_element/default_text_search.rb +110 -0
- data/lib/active_element/json_field_schema.rb +59 -0
- data/lib/active_element/pre_render_processors/json.rb +98 -0
- data/lib/active_element/pre_render_processors.rb +11 -0
- data/lib/active_element/route.rb +12 -0
- data/lib/active_element/routes.rb +2 -1
- data/lib/active_element/version.rb +1 -1
- data/lib/active_element.rb +14 -32
- data/lib/tasks/active_element.rake +12 -1
- data/rspec-documentation/_head.html.erb +34 -0
- data/rspec-documentation/pages/000-Introduction.md +18 -0
- data/rspec-documentation/pages/005-Setup.md +75 -0
- data/rspec-documentation/pages/010-Components/Form Fields/Check Boxes.md +1 -0
- data/rspec-documentation/pages/010-Components/Form Fields/JSON/Controller Params.md +97 -0
- data/rspec-documentation/pages/010-Components/Form Fields/JSON/Schema.md +283 -0
- data/rspec-documentation/pages/010-Components/Form Fields/JSON/Types.md +36 -0
- data/rspec-documentation/pages/010-Components/Form Fields/JSON.md +70 -0
- data/rspec-documentation/pages/010-Components/Form Fields/Text Search.md +133 -0
- data/rspec-documentation/pages/010-Components/Form Fields.md +46 -0
- data/rspec-documentation/pages/010-Components/Forms.md +44 -0
- data/rspec-documentation/pages/010-Components/JSON Data.md +23 -0
- data/rspec-documentation/pages/010-Components/Navbar.md +56 -0
- data/rspec-documentation/pages/010-Components/Page Section Title.md +13 -0
- data/rspec-documentation/pages/010-Components/Page Subtitle.md +11 -0
- data/rspec-documentation/pages/010-Components/Page Title.md +11 -0
- data/rspec-documentation/pages/010-Components/Tables/Collection Table.md +29 -0
- data/rspec-documentation/pages/010-Components/Tables/Item Table.md +18 -0
- data/rspec-documentation/pages/010-Components/Tables/Options.md +19 -0
- data/rspec-documentation/pages/010-Components/Tables.md +29 -0
- data/rspec-documentation/pages/010-Components.md +15 -0
- data/rspec-documentation/pages/020-Access Control/010-Authentication.md +20 -0
- data/rspec-documentation/pages/020-Access Control/020-Authorization/Environments.md +9 -0
- data/rspec-documentation/pages/020-Access Control/020-Authorization/Permissions/Custom Routes.md +41 -0
- data/rspec-documentation/pages/020-Access Control/020-Authorization/Permissions.md +58 -0
- data/rspec-documentation/pages/020-Access Control/020-Authorization/Setup.md +27 -0
- data/rspec-documentation/pages/020-Access Control/020-Authorization.md +11 -0
- data/rspec-documentation/pages/020-Access Control.md +31 -0
- data/rspec-documentation/pages/040-Decorators/Inline Decorators.md +24 -0
- data/rspec-documentation/pages/040-Decorators/View Decorators.md +55 -0
- data/rspec-documentation/pages/040-Decorators.md +12 -0
- data/rspec-documentation/pages/300-Alternatives.md +21 -0
- data/rspec-documentation/pages/900-License.md +11 -0
- data/rspec-documentation/spec_helper.rb +53 -16
- data/rspec-documentation/support.rb +84 -0
- metadata +155 -14
- data/rspec-documentation/pages/Components/Forms.md +0 -1
- data/rspec-documentation/pages/Components/Tables.md +0 -47
- data/rspec-documentation/pages/Components.md +0 -1
- data/rspec-documentation/pages/Decorators/Inline Decorators.md +0 -1
- data/rspec-documentation/pages/Decorators/View Decorators.md +0 -1
- data/rspec-documentation/pages/Index.md +0 -3
- data/rspec-documentation/pages/Util/I18n.md +0 -1
- /data/rspec-documentation/pages/{Components → 010-Components}/Tabs.md +0 -0
@@ -1,24 +1,27 @@
|
|
1
1
|
<% if type == :select %>
|
2
2
|
<%= render partial: 'active_element/components/form/select',
|
3
|
-
locals: { form: form, field: field, options: options, component: component } %>
|
3
|
+
locals: { form_id: id, form: form, field: field, options: options, component: component } %>
|
4
4
|
<% elsif type == :check_boxes %>
|
5
5
|
<%= render partial: 'active_element/components/form/check_boxes',
|
6
|
-
locals: {
|
6
|
+
locals: { form_id: id, form: form, field: field, options: options, component: component } %>
|
7
7
|
<% elsif type == :json_field %>
|
8
8
|
<%= render partial: 'active_element/components/form/json',
|
9
|
-
locals: {
|
9
|
+
locals: { form_id: id, form: form, field: field, field_id: ActiveElement.element_id, options: options, component: component } %>
|
10
10
|
<% elsif type == :text_search_field %>
|
11
11
|
<%= render partial: 'active_element/components/form/text_search',
|
12
|
-
locals: { form_id: id,
|
12
|
+
locals: { form_id: id, form: form, field: field, options: options, component: component } %>
|
13
13
|
<% elsif type == :check_box %>
|
14
14
|
<%= render partial: 'active_element/components/form/check_box',
|
15
|
-
locals: {
|
15
|
+
locals: { form_id: id, form: form, field: field, type: type, options: options, component: component } %>
|
16
16
|
<% elsif type == :text_area %>
|
17
17
|
<%= render partial: 'active_element/components/form/text_area',
|
18
|
-
locals: {
|
18
|
+
locals: { form_id: id, form: form, field: field, type: type, options: options, component: component } %>
|
19
|
+
<% elsif type == :datetime_range_field %>
|
20
|
+
<%= render partial: 'active_element/components/form/datetime_range_field',
|
21
|
+
locals: { form_id: id, form: form, field: field, type: type, options: options, component: component } %>
|
19
22
|
<% else %>
|
20
23
|
<%= render partial: 'active_element/components/form/generic_field',
|
21
|
-
locals: {
|
24
|
+
locals: { form_id: id, form: form, field: field, type: type, options: options, component: component } %>
|
22
25
|
<% end %>
|
23
26
|
|
24
27
|
<% unless component.valid?(field) %>
|
@@ -1,12 +1,20 @@
|
|
1
1
|
<div class="col-sm-10 json-field form-group"
|
2
2
|
data-data-key="<%= ActiveElement::Components::Util.json_name("#{form.object_name}.#{field}") %>"
|
3
|
+
data-field-name="<%= field %>"
|
4
|
+
data-form-id="<%= form_id %>"
|
5
|
+
data-field-id="<%= field_id %>"
|
6
|
+
data-schema-field-id="<%= field_id %>-schema"
|
3
7
|
>
|
4
8
|
|
5
9
|
</div>
|
6
10
|
|
11
|
+
<%= form.hidden_field field, name: "#{form.object_name}[#{field}]", value: '', id: field_id %>
|
12
|
+
<%= form.hidden_field field, name: "__json_field_schemas[#{form.object_name}][#{field}]", value: '', id: "#{field_id}-schema" %>
|
13
|
+
<%= form.hidden_field field, name: '__json_fields[]', value: "#{form.object_name}.#{field}" %>
|
14
|
+
|
7
15
|
<%=
|
8
|
-
component.json(
|
16
|
+
active_element.component.json(
|
9
17
|
ActiveElement::Components::Util.json_name("#{form.object_name}.#{field}"),
|
10
|
-
{ data: component.value_for(field, options), schema: component.schema_for(field, options) }
|
18
|
+
{ data: component.value_for(field, default: options), schema: component.schema_for(field, options) }
|
11
19
|
)
|
12
20
|
%>
|
@@ -1,9 +1,20 @@
|
|
1
1
|
<%= form.label field do %>
|
2
2
|
<%= options[:label] %>
|
3
|
-
<% if options[:
|
3
|
+
<% if options[:required] %>
|
4
4
|
<button type="button"
|
5
5
|
style="background: none; border: none; outline: 0; position: absolute; margin-top: 0.3rem"
|
6
|
+
data-bs-trigger="focus"
|
7
|
+
data-bs-toggle="popover"
|
8
|
+
title="Required"
|
9
|
+
data-bs-content="<%= "#{options.fetch(:label)} is a required field." %>"
|
10
|
+
<i class="text-secondary fa-solid fa-star-of-life"></i>
|
11
|
+
</button>
|
12
|
+
<% end %>
|
13
|
+
<% if options[:description].present? %>
|
14
|
+
<button type="button"
|
15
|
+
style="background: none; border: none; outline: 0; position: absolute; <%= options[:required] ? 'margin-left: 1.4rem;' : nil %> margin-top: 0.3rem"
|
6
16
|
data-bs-toggle="popover"
|
17
|
+
data-bs-trigger="focus"
|
7
18
|
title="<%= options.fetch(:label) %>"
|
8
19
|
data-bs-content="<%= options[:description] %>">
|
9
20
|
<i class="text-secondary fa-solid fa-circle-info"></i>
|
@@ -1,4 +1,7 @@
|
|
1
1
|
<%= form.select field,
|
2
2
|
component.options_for_select(field, options),
|
3
3
|
{ selected: component.value_for(field) },
|
4
|
-
{
|
4
|
+
{
|
5
|
+
tabindex: component.tabindex,
|
6
|
+
class: "form-select #{component.valid?(field) ? nil : 'is-invalid'}"
|
7
|
+
} %>
|
@@ -21,7 +21,17 @@
|
|
21
21
|
<span class="ms-1"><%= value %></span>
|
22
22
|
</div>
|
23
23
|
<% end %>
|
24
|
-
<% elsif
|
24
|
+
<% elsif type == :datetime_range_field %>
|
25
|
+
<% next unless value.present? %>
|
26
|
+
|
27
|
+
<% values << value %>
|
28
|
+
<div class="d-inline me-3">
|
29
|
+
<span class="text-secondary"><%= options.fetch(:label) %>:</span>
|
30
|
+
<span class="ms-1 text-primary"><%= value[:from] %></span>
|
31
|
+
<span class="text-secondary">→</span>
|
32
|
+
<span class="ms-1 text-primary"><%= value[:to] %></span>
|
33
|
+
</div>
|
34
|
+
<% elsif value.class && value.present? %>
|
25
35
|
<%# TODO: Handle other field types %>
|
26
36
|
|
27
37
|
<% values << value %>
|
@@ -7,42 +7,62 @@
|
|
7
7
|
<label id="json-form-check-label-template" class="form-check-label"></label>
|
8
8
|
<label id="json-label-template" class="mb-4 fw-bold"></label>
|
9
9
|
|
10
|
-
<div id="json-form-group-template" class="form-group
|
11
|
-
<div id="json-form-group-floating-template" class="form-floating m-3 text-wrap"></div>
|
10
|
+
<div id="json-form-group-template" class="form-group text-wrap m-3"></div>
|
11
|
+
<div id="json-form-group-floating-template" class="form-floating m-3 text-wrap collapsed"></div>
|
12
12
|
<div id="json-form-check-template" class="form-check m-3"></div>
|
13
13
|
|
14
14
|
<input id="json-checkbox-field-template" type="checkbox" class="form-check-input json-checkbox-field" />
|
15
15
|
|
16
16
|
<input id="json-text-field-template" type="text" class="form-control m-1 json-text-field" />
|
17
|
+
<input id="json-date-field-template" type="date" class="form-control m-1 d-inline-block json-date-field" />
|
18
|
+
<input id="json-time-field-template" type="time" class="form-control m-1 d-inline-block json-time-field" />
|
19
|
+
<input id="json-datetime-field-template" type="datetime-local" class="form-control m-1 d-inline-block json-datetime-field" />
|
20
|
+
<input id="json-integer-field-template" type="number" class="form-control m-1 json-integer-field" />
|
21
|
+
<input id="json-float-field-template" type="number" class="form-control m-1 json-float-field" />
|
22
|
+
<input id="json-decimal-field-template" type="number" class="form-control m-1 json-decimal-field" />
|
17
23
|
|
18
24
|
<select id="json-select-template" class="form-select m-1 json-select-field"></select>
|
19
25
|
|
20
26
|
<%= active_element.component.destroy_button id: 'json-delete-button-template',
|
21
|
-
class: '
|
27
|
+
class: 'btn-sm json-delete-button', data: { 'confirm-action': 'false' } %>
|
22
28
|
|
23
29
|
<%= active_element.component.button 'Delete Item', type: 'danger', id: 'json-delete-object-button-template',
|
24
|
-
|
30
|
+
style: 'z-index: 1500',
|
31
|
+
class: 'btn-sm json-delete-button float-end json-delete-object-button' %>
|
25
32
|
|
26
33
|
<%= active_element.component.button id: 'json-append-button-template',
|
27
|
-
class: 'btn-sm
|
34
|
+
class: 'btn-sm json-add-field-button' %>
|
28
35
|
|
29
36
|
<%= active_element.component.button 'Hide', id: 'json-expand-collapse-button-template',
|
30
37
|
class: 'float-end expand-collapse-button' %>
|
31
38
|
|
39
|
+
<div id="json-focus-template" class="focus m-1"></div>
|
40
|
+
<i id="json-focus-expand-template" class="fa-solid fa-fw fa-plus"></i>
|
41
|
+
<i id="json-focus-collapse-template" class="fa-solid fa-fw fa-minus d-none"></i>
|
42
|
+
<div id="json-modal-template"
|
43
|
+
class="modal fade"
|
44
|
+
tabindex="-1"
|
45
|
+
aria-hidden="true">
|
46
|
+
<div class="modal-dialog modal-dialog-centered modal-xl modal-dialog-scrollable json-field-modal">
|
47
|
+
<div class="modal-content">
|
48
|
+
<div class="modal-header">
|
49
|
+
<h5 class="modal-title" data-field-type="modal-title"></h5>
|
50
|
+
<div class="modal-buttons">
|
51
|
+
<button type="button" class="btn btn-primary btn-sm me-2" data-bs-dismiss="modal" aria-label="Finish Editing">
|
52
|
+
Finish Editing
|
53
|
+
</button>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
<div class="modal-body" data-field-type="modal-body"></div>
|
57
|
+
<div class="modal-footer" data-field-type="modal-footer"></div>
|
58
|
+
</div>
|
59
|
+
</div>
|
60
|
+
</div>
|
32
61
|
</div>
|
33
62
|
|
34
|
-
<%= active_element.component.button 'Expand Form', id: 'form-expand-button-template', class: 'mb-1 btn-sm' do %>
|
35
|
-
<i class="fa-solid fa-fw fa-up-right-and-down-left-from-center"></i>
|
36
|
-
<% end %>
|
37
|
-
|
38
|
-
<%= active_element.component.button 'Collapse Form', id: 'form-collapse-button-template', class: 'mb-1 btn-sm' do %>
|
39
|
-
<i class="fa-solid fa-fw fa-down-left-and-up-right-to-center"></i>
|
40
|
-
<% end %>
|
41
|
-
|
42
63
|
|
43
64
|
<div id="form-search-field-templates">
|
44
|
-
<
|
45
|
-
<p id="form-search-field-response-error-template" class="text-danger position-absolute validation-error-message pt-1 m-0"></p>
|
65
|
+
<p id="form-search-field-response-error-template" class="text-danger validation-error-message pt-1 m-0"></p>
|
46
66
|
<div id="form-search-field-results-template" class="search-field-results d-none border border-top-0"></div>
|
47
67
|
<div id="form-search-field-results-item-template" class="search-field-result p-2"></div>
|
48
68
|
<div id="form-search-field-spinner-template" class="invisible text-end">
|
@@ -50,11 +70,6 @@
|
|
50
70
|
<i class="fa-solid fa-spinner fa-spin"></i>
|
51
71
|
</div>
|
52
72
|
</div>
|
53
|
-
<div id="form-search-field-clear-button-template" class="invisible text-end">
|
54
|
-
<div style="position: relative; float: right; width: auto; right: 0.5rem; top: -1.7rem;">
|
55
|
-
<i class="fa-solid fa-delete-left" style="cursor: pointer;"></i>
|
56
|
-
</div>
|
57
|
-
</div>
|
58
73
|
</div>
|
59
74
|
|
60
75
|
<div id="form-modal-template"
|
@@ -65,8 +80,8 @@
|
|
65
80
|
<div class="modal-content">
|
66
81
|
<div class="modal-header">
|
67
82
|
<h5 class="modal-title" data-field-type="modal-title"></h5>
|
68
|
-
<button type="button" class="btn-close
|
69
|
-
<i class="fa-
|
83
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
|
84
|
+
<i class="fa-solid fa-xmark"></i>
|
70
85
|
</button>
|
71
86
|
</div>
|
72
87
|
<div class="modal-body" data-field-type="modal-body"></div>
|
@@ -1,16 +1,20 @@
|
|
1
1
|
<%=
|
2
|
-
form.text_field field, value: component.value_for(field),
|
2
|
+
form.text_field field, value: options.fetch(:display_value) { component.value_for(field) },
|
3
3
|
id: "#{form_id}-#{field}-text-search",
|
4
4
|
class: "form-control #{component.valid?(field) ? nil : 'is-invalid'}",
|
5
5
|
autocomplete: 'off',
|
6
6
|
placeholder: options[:placeholder].presence || 'Search...',
|
7
|
+
tabindex: component.tabindex,
|
7
8
|
data: {
|
8
9
|
field_type: 'text-search',
|
9
10
|
form_id: form_id,
|
10
11
|
search_attributes: (
|
11
|
-
options.dig(:search, :
|
12
|
+
options.dig(:search, :with) || [options.dig(:search, :with)]
|
12
13
|
)&.to_json,
|
13
|
-
search_value: options.dig(:search, :
|
14
|
+
search_value: options.dig(:search, :providing),
|
14
15
|
search_model: options.dig(:search, :model)
|
15
16
|
}
|
16
17
|
%>
|
18
|
+
|
19
|
+
<%= form.hidden_field field, id: "#{form_id}-#{field}-text-search-hidden-value",
|
20
|
+
value: component.value_for(field) %>
|
@@ -1,5 +1,7 @@
|
|
1
1
|
<% if destroy %>
|
2
|
-
|
2
|
+
<div class="container w-100 text-end">
|
3
|
+
<%= active_element.component.destroy_button(record) %>
|
4
|
+
</div>
|
3
5
|
<% end %>
|
4
6
|
|
5
7
|
<% if modal %>
|
@@ -20,32 +22,32 @@
|
|
20
22
|
|
21
23
|
</div>
|
22
24
|
|
23
|
-
<% elsif title.present? && expanded == false %>
|
24
|
-
|
25
|
-
<div data-field-type="form-expand" data-form-id="<%= id %>" class="mb-3">
|
26
|
-
<span class="fs-4 align-bottom"><%= title %></span>
|
27
|
-
</div>
|
28
|
-
|
29
|
-
<% elsif title.blank? && expanded == false %>
|
30
|
-
|
31
|
-
<div data-field-type="form-expand" data-form-id="<%= id %>" class="mb-3"></div>
|
32
|
-
|
33
25
|
<% elsif title.present? %>
|
34
26
|
|
35
27
|
<span class="fs-4 align-bottom"><%= title %></span>
|
36
28
|
|
37
29
|
<% end %>
|
38
30
|
|
39
|
-
|
40
|
-
|
31
|
+
<% unless component.valid? %>
|
32
|
+
<p class="text-danger pt-1 m-0 validation-error-message">
|
33
|
+
<%= component.full_error_message %>
|
34
|
+
</p>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
<div class="form <%= modal ? 'd-none' : 'pb-3' %>" id="form-wrapper-<%= id %>">
|
38
|
+
<%= form_with local: true, action: action, method: method, id: id, class: "#{class_name} m-3", **kwargs do |form| %>
|
41
39
|
<% if %i[top both].include?(submit_position) %>
|
42
|
-
<div class="form-group sticky-top" style="top: 0.5rem;">
|
43
|
-
|
40
|
+
<div class="row mb-3 form-group sticky-top" style="top: 0.5rem;">
|
41
|
+
<div class="col-sm-3"></div>
|
42
|
+
<div class="col pb-3">
|
43
|
+
<%= form.submit submit_label, name: '', class: "btn btn-#{method == :post ? 'success' : 'primary'} ms-2 float-end" %>
|
44
|
+
<%= active_element.component.button 'Clear Form', class: 'btn-secondary float-end', data: { 'form-input-type': 'clear' } %>
|
45
|
+
</div>
|
44
46
|
</div>
|
45
47
|
<% end %>
|
46
48
|
|
47
49
|
<% fields.each_slice(columns) do |field_group| %>
|
48
|
-
<div class="row mb-3">
|
50
|
+
<div class="row form-fields mb-3">
|
49
51
|
<% field_group.each do |field, type, options| %>
|
50
52
|
<div class="col-sm-3">
|
51
53
|
<%= render partial: 'active_element/components/form/label',
|
@@ -71,7 +73,8 @@
|
|
71
73
|
|
72
74
|
<% if %i[bottom both].include?(submit_position) %>
|
73
75
|
<div class="form-group">
|
74
|
-
<%= form.submit submit_label, class: "btn btn-#{method == :post ? 'success' : 'primary'}" %>
|
76
|
+
<%= form.submit submit_label, name: '', class: "btn btn-#{method == :post ? 'success' : 'primary'}" %>
|
77
|
+
<%= active_element.component.button 'Clear Form', class: 'btn-secondary ms-2', data: { 'form-input-type': 'clear' } %>
|
75
78
|
</div>
|
76
79
|
<% end %>
|
77
80
|
<% end %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<div class="application-menu <%= fixed ? 'position-fixed' : nil %> w-100 navbar navbar-dark bg-dark navbar-expand-lg">
|
2
|
+
<div class="container">
|
3
|
+
<a class="navbar-brand" href="#"><%= ActiveElement.application_title %></a>
|
4
|
+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
5
|
+
<span class="navbar-toggler-icon"></span>
|
6
|
+
</button>
|
7
|
+
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
8
|
+
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
9
|
+
<% items.each do |navbar_item| %>
|
10
|
+
<li class="nav-item">
|
11
|
+
<%=
|
12
|
+
link_to navbar_item.fetch(:title) { navbar_item.fetch(:label) },
|
13
|
+
navbar_item.fetch(:path),
|
14
|
+
class: "nav-link #{component.active_path_class(current_navbar_item: navbar_item)}"
|
15
|
+
%>
|
16
|
+
</li>
|
17
|
+
<% end %>
|
18
|
+
</li>
|
19
|
+
</ul>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<div class="d-flex icon-menu p-3">
|
23
|
+
<%= render partial: 'active_element/user' %>
|
24
|
+
<%= render partial: 'active_element/theme/select' %>
|
25
|
+
</div>
|
26
|
+
</div>
|
@@ -5,7 +5,8 @@
|
|
5
5
|
<%= controller.helpers.render partial: 'active_element/components/secret/field',
|
6
6
|
locals: { secret: value_mapper.call(item), label: label } %>
|
7
7
|
<% else %>
|
8
|
-
<%=
|
8
|
+
<%= controller.helpers.render partial: 'active_element/components/table/field',
|
9
|
+
locals: { value: value_mapper.call(item) } %>
|
9
10
|
<% end %>
|
10
11
|
</td>
|
11
12
|
<% end %>
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<% end %>
|
8
8
|
|
9
9
|
<% if new %>
|
10
|
-
<%= active_element.component.new_button(
|
10
|
+
<%= active_element.component.new_button(component.model, float: 'end', class: 'mb-3') %>
|
11
11
|
<% end %>
|
12
12
|
|
13
13
|
<table class="<%= class_name %> table" style="<%= style %>">
|
@@ -27,10 +27,11 @@
|
|
27
27
|
</th>
|
28
28
|
<td class="<%= class_mapper.call(item) %>">
|
29
29
|
<% if component.secret_field?(field) %>
|
30
|
-
<%=
|
31
|
-
|
30
|
+
<%= render partial: 'active_element/components/secret/field',
|
31
|
+
locals: { secret: value_mapper.call(item), label: label } %>
|
32
32
|
<% else %>
|
33
|
-
<%=
|
33
|
+
<%= render partial: 'active_element/components/table/field',
|
34
|
+
locals: { value: value_mapper.call(item) } %>
|
34
35
|
<% end %>
|
35
36
|
</td>
|
36
37
|
</tr>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<% if active_element.state.key?(:searchable_fields) %>
|
2
|
+
<%= active_element.component.form title: 'Search Filters',
|
3
|
+
submit: 'Search',
|
4
|
+
modal: true,
|
5
|
+
search: true,
|
6
|
+
item: search_filters,
|
7
|
+
fields: active_element.state.fetch(:searchable_fields) %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<%= active_element.component.table new: true,
|
11
|
+
show: true,
|
12
|
+
edit: true,
|
13
|
+
destroy: true,
|
14
|
+
collection: collection,
|
15
|
+
fields: active_element.state.fetch(:listable_fields, []) %>
|
@@ -1,30 +1 @@
|
|
1
|
-
|
2
|
-
<%= render partial: 'active_element/theme/select' %>
|
3
|
-
<div class="container p-0">
|
4
|
-
<a class="navbar-brand" href="#"><%= ActiveElement.application_title %></a>
|
5
|
-
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
6
|
-
<span class="navbar-toggler-icon"></span>
|
7
|
-
</button>
|
8
|
-
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
9
|
-
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
10
|
-
<% ActiveElement.navbar_items(active_element.current_user).each do |navbar_item| %>
|
11
|
-
<li class="nav-item">
|
12
|
-
<%=
|
13
|
-
link_to navbar_item.fetch(:title) { navbar_item.fetch(:label) },
|
14
|
-
navbar_item.fetch(:path),
|
15
|
-
class: "nav-link #{
|
16
|
-
ActiveElement.active_path_class(
|
17
|
-
user: active_element.current_user,
|
18
|
-
current_navbar_item: navbar_item,
|
19
|
-
current_path: request.path,
|
20
|
-
controller_path: controller_path,
|
21
|
-
action_name: action_name)
|
22
|
-
}"
|
23
|
-
%>
|
24
|
-
</li>
|
25
|
-
<% end %>
|
26
|
-
</li>
|
27
|
-
</ul>
|
28
|
-
</div>
|
29
|
-
</div>
|
30
|
-
</div>
|
1
|
+
<%= ActiveElement.component.navbar(items: ActiveElement.navbar_items) %>
|
@@ -1 +1 @@
|
|
1
|
-
<div id="theme-select"></div>
|
1
|
+
<div class="ms-2" id="theme-select"></div>
|
@@ -2,6 +2,21 @@
|
|
2
2
|
<head>
|
3
3
|
<%= render_active_element_hook 'active_element/before_head' %>
|
4
4
|
|
5
|
+
<style>
|
6
|
+
<%= Rouge::Theme.find('tulip').render(scope: '.json-highlight') %>
|
7
|
+
.json-highlight .p {
|
8
|
+
color: #7e4b6f;
|
9
|
+
}
|
10
|
+
|
11
|
+
.json-highlight .s2 {
|
12
|
+
color: #6b7399
|
13
|
+
}
|
14
|
+
|
15
|
+
.json-highlight {
|
16
|
+
background-color: transparent;
|
17
|
+
}
|
18
|
+
</style>
|
19
|
+
|
5
20
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
6
21
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js" integrity="sha512-fD9DI5bZwQxOi7MhYWnnNPlvXdp/2Pj3XSTRrFs5FQa4mizyGLnJcN6tuvUS6LbmgN1ut+XGSABKvjN0H6Aoow==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
7
22
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.2/umd/popper.min.js" integrity="sha512-2rNj2KJ+D8s1ceNasTIex6z4HWyOnEYLVC3FigGOmyQCZc2eBXKgOxQmo3oKLHyfcj53uz4QMsRCWNbLd32Q1g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
@@ -25,7 +40,7 @@
|
|
25
40
|
|
26
41
|
<body>
|
27
42
|
<%= render_active_element_hook 'active_element/before_navbar' %>
|
28
|
-
<%=
|
43
|
+
<%= active_element.component.navbar(items: ActiveElement.navbar_items) %>
|
29
44
|
<%= render_active_element_hook 'active_element/after_navbar' %>
|
30
45
|
|
31
46
|
<% flash.each do |type, message| %>
|
@@ -49,7 +64,7 @@
|
|
49
64
|
|
50
65
|
<%= render_active_element_hook 'active_element/before_content' %>
|
51
66
|
|
52
|
-
<div class="content
|
67
|
+
<div class="main content position-relative ms-5 me-5">
|
53
68
|
<%= yield %>
|
54
69
|
</div>
|
55
70
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
{
|
2
|
+
"ignored_warnings": [
|
3
|
+
{
|
4
|
+
"warning_type": "SQL Injection",
|
5
|
+
"warning_code": 0,
|
6
|
+
"fingerprint": "7d17f93e2d87d1f9dc0fbf6e4ce46856e4fb0e1f99a7e0ce4ea3ed73be68efc4",
|
7
|
+
"check_name": "SQL",
|
8
|
+
"message": "Possible SQL injection",
|
9
|
+
"file": "lib/active_element/json_field_schema.rb",
|
10
|
+
"line": 21,
|
11
|
+
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
12
|
+
"code": "ActiveRecord::Base.connection.execute(\"select #{column} from #{table}\")",
|
13
|
+
"render_path": null,
|
14
|
+
"location": {
|
15
|
+
"type": "method",
|
16
|
+
"class": "ActiveElement::JsonFieldSchema",
|
17
|
+
"method": "data"
|
18
|
+
},
|
19
|
+
"user_input": "column",
|
20
|
+
"confidence": "Medium",
|
21
|
+
"cwe_id": [
|
22
|
+
89
|
23
|
+
],
|
24
|
+
"note": ""
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"warning_type": "Unmaintained Dependency",
|
28
|
+
"warning_code": 121,
|
29
|
+
"fingerprint": "edf687f759ec9765bd5db185dbc615c80af77d6e7e19386fc42934e7a80307af",
|
30
|
+
"check_name": "EOLRuby",
|
31
|
+
"message": "Support for Ruby 2.7.8 ended on 2023-03-31",
|
32
|
+
"file": ".ruby-version",
|
33
|
+
"line": 1,
|
34
|
+
"link": "https://brakemanscanner.org/docs/warning_types/unmaintained_dependency/",
|
35
|
+
"code": null,
|
36
|
+
"render_path": null,
|
37
|
+
"location": null,
|
38
|
+
"user_input": null,
|
39
|
+
"confidence": "High",
|
40
|
+
"cwe_id": [
|
41
|
+
1104
|
42
|
+
],
|
43
|
+
"note": ""
|
44
|
+
}
|
45
|
+
],
|
46
|
+
"updated": "2023-06-10 13:50:20 +0100",
|
47
|
+
"brakeman_version": "5.4.1"
|
48
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile '~/.gitignore_global'
|
6
|
+
|
7
|
+
# Ignore bundler config.
|
8
|
+
/.bundle
|
9
|
+
|
10
|
+
# Ignore the default SQLite database.
|
11
|
+
/db/*.sqlite3
|
12
|
+
/db/*.sqlite3-*
|
13
|
+
|
14
|
+
# Ignore all logfiles and tempfiles.
|
15
|
+
/log/*
|
16
|
+
/tmp/*
|
17
|
+
!/log/.keep
|
18
|
+
!/tmp/.keep
|
19
|
+
|
20
|
+
# Ignore pidfiles, but keep the directory.
|
21
|
+
/tmp/pids/*
|
22
|
+
!/tmp/pids/
|
23
|
+
!/tmp/pids/.keep
|
24
|
+
|
25
|
+
# Ignore uploaded files in development.
|
26
|
+
/storage/*
|
27
|
+
!/storage/.keep
|
28
|
+
/tmp/storage/*
|
29
|
+
!/tmp/storage/
|
30
|
+
!/tmp/storage/.keep
|
31
|
+
|
32
|
+
/public/assets
|
33
|
+
|
34
|
+
# Ignore master key for decrypting credentials and more.
|
35
|
+
/config/master.key
|
@@ -0,0 +1 @@
|
|
1
|
+
2.7.8
|