active_element 0.0.10 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +12 -2
- data/.strong_versions.yml +1 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +115 -75
- 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 +38 -27
- 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 +166 -33
- 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 +42 -24
- data/app/views/active_element/components/form/_text_area.html.erb +2 -1
- data/app/views/active_element/components/form/_text_search.html.erb +8 -4
- 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/_ungrouped_collection.html.erb +1 -0
- data/app/views/active_element/components/table/collection.html.erb +1 -1
- data/app/views/active_element/components/table/item.html.erb +6 -4
- data/app/views/active_element/default_views/edit.html.erb +5 -0
- data/app/views/active_element/default_views/forbidden.html.erb +7 -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 +16 -1
- data/config/brakeman.ignore +48 -0
- data/config/locales/en.yml +3 -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 +7 -0
- data/example_app/app/controllers/users_controller.rb +7 -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 +13 -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 +139 -10
- data/lib/active_element/components/util/form_value_mapping.rb +3 -3
- data/lib/active_element/components/util/i18n.rb +1 -1
- data/lib/active_element/components/util/numeric_field.rb +73 -0
- 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 +13 -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 +56 -18
- data/lib/active_element/controller_state.rb +44 -0
- data/lib/active_element/default_controller.rb +137 -0
- data/lib/active_element/default_record_params.rb +62 -0
- data/lib/active_element/default_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 +15 -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 +159 -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
@@ -0,0 +1,14 @@
|
|
1
|
+
<div class="d-flex">
|
2
|
+
<%= form.label(nil, class: 'me-2 mt-1') { 'Between' } %>
|
3
|
+
<%= form.datetime_field("#{field}[from]", name: "#{field}[from]",
|
4
|
+
value: component.value_for(field, :from),
|
5
|
+
class: "form-control #{component.valid?(field) ? nil : 'is-invalid'}",
|
6
|
+
tabindex: component.tabindex,
|
7
|
+
**options) %>
|
8
|
+
<%= form.label(nil, class: 'ms-2 mt-1 me-2') { 'and' } %>
|
9
|
+
<%= form.datetime_field("#{field}[to]", name: "#{field}[to]",
|
10
|
+
value: component.value_for(field, :to),
|
11
|
+
class: "form-control #{component.valid?(field) ? nil : 'is-invalid'}",
|
12
|
+
tabindex: component.tabindex,
|
13
|
+
**options) %>
|
14
|
+
</div>
|
@@ -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,52 +7,70 @@
|
|
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" step="any" class="form-control m-1 json-float-field" />
|
22
|
+
<input id="json-decimal-field-template" type="number" step="any" 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
|
-
<div id="form-search-field-
|
49
|
-
<div style="position: relative; float: right; width: auto; right: 0.5rem; top: -1.7rem;">
|
50
|
-
<i class="fa-solid fa-spinner fa-spin"></i>
|
68
|
+
<div id="form-search-field-icons-template" class="text-end">
|
69
|
+
<div data-item-class="spinner" class="invisible" style="position: relative; float: right; width: auto; right: 0.5rem; top: -1.7rem;">
|
70
|
+
<i class="fa-fw fa-solid fa-spinner fa-spin"></i>
|
51
71
|
</div>
|
52
|
-
|
53
|
-
|
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>
|
72
|
+
<div data-item-class="clear" class="invisible" style="position: relative; float: right; width: auto; right: 0.5rem; top: -1.7rem; cursor: pointer;">
|
73
|
+
<i class="fa-solid fa-fw fa-xmark"></i>
|
56
74
|
</div>
|
57
75
|
</div>
|
58
76
|
</div>
|
@@ -65,8 +83,8 @@
|
|
65
83
|
<div class="modal-content">
|
66
84
|
<div class="modal-header">
|
67
85
|
<h5 class="modal-title" data-field-type="modal-title"></h5>
|
68
|
-
<button type="button" class="btn-close
|
69
|
-
<i class="fa-
|
86
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
|
87
|
+
<i class="fa-solid fa-xmark"></i>
|
70
88
|
</button>
|
71
89
|
</div>
|
72
90
|
<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
|
-
placeholder: options[:placeholder].presence ||
|
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 %>
|
@@ -8,6 +8,7 @@
|
|
8
8
|
<button type="button"
|
9
9
|
style="background: none; border: none; outline: 0; position: absolute; margin-top: 0.3rem"
|
10
10
|
data-bs-toggle="popover"
|
11
|
+
data-bs-trigger="focus"
|
11
12
|
data-bs-content="<%= options[:description] %>">
|
12
13
|
<i class="text-secondary fa-solid fa-circle-info"></i>
|
13
14
|
</button>
|
@@ -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 %>">
|
@@ -20,6 +20,7 @@
|
|
20
20
|
<button type="button"
|
21
21
|
style="background: none; border: none; outline: 0; position: absolute; margin-top: 0.3rem"
|
22
22
|
data-bs-toggle="popover"
|
23
|
+
data-bs-trigger="focus"
|
23
24
|
data-bs-content="<%= options[:description] %>">
|
24
25
|
<i class="text-secondary fa-solid fa-circle-info"></i>
|
25
26
|
</button>
|
@@ -27,10 +28,11 @@
|
|
27
28
|
</th>
|
28
29
|
<td class="<%= class_mapper.call(item) %>">
|
29
30
|
<% if component.secret_field?(field) %>
|
30
|
-
<%=
|
31
|
-
|
31
|
+
<%= render partial: 'active_element/components/secret/field',
|
32
|
+
locals: { secret: value_mapper.call(item), label: label } %>
|
32
33
|
<% else %>
|
33
|
-
<%=
|
34
|
+
<%= render partial: 'active_element/components/table/field',
|
35
|
+
locals: { value: value_mapper.call(item) } %>
|
34
36
|
<% end %>
|
35
37
|
</td>
|
36
38
|
</tr>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<h1>Forbidden</h1>
|
2
|
+
|
3
|
+
<h2 class="text-danger">Access to this resource has not been configured</h2>
|
4
|
+
|
5
|
+
<p>The <span class="text-primary font-monospace"><%= type %></span> resource for <span class="text-primary font-monospace"><%= controller_name.titleize %></span> has not been configured, please contact your administrator.</p>
|
6
|
+
|
7
|
+
<hr/>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<% if active_element.state.searchable_fields.present? %>
|
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.searchable_fields %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<%= active_element.component.table new: active_element.state.creatable?,
|
11
|
+
show: active_element.state.viewable?,
|
12
|
+
edit: active_element.state.editable?,
|
13
|
+
destroy: active_element.state.deletable?,
|
14
|
+
collection: collection,
|
15
|
+
fields: active_element.state.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| %>
|
@@ -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
|
+
}
|