practical 3.0.0.pre.alpha1 → 3.0.0.pre.alpha4
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/app/components/practical/views/button_to_component.rb +23 -0
- data/app/components/practical/views/flash_messages_component.rb +15 -7
- data/app/components/practical/views/form/error_list_component.rb +1 -1
- data/app/components/practical/views/form/error_list_item_component.rb +2 -3
- data/app/components/practical/views/form/error_list_item_template_component.rb +1 -1
- data/app/components/practical/views/form/fallback_errors_section_component.html.erb +8 -5
- data/app/components/practical/views/form/fallback_errors_section_component.rb +1 -1
- data/app/components/practical/views/form/field_errors_component.html.erb +8 -0
- data/app/components/practical/views/form/field_errors_component.rb +14 -11
- data/app/components/practical/views/form/input_component.html.erb +1 -1
- data/app/components/practical/views/form/input_component.rb +15 -1
- data/app/components/practical/views/modal_dialog_component.html.erb +1 -1
- data/app/components/practical/views/modal_dialog_component.rb +1 -1
- data/app/components/practical/views/navigation/pagination/goto_form_component.html.erb +4 -10
- data/app/components/practical/views/navigation/pagination/goto_form_component.rb +17 -2
- data/app/components/practical/views/navigation/pagination_component.rb +17 -28
- data/app/components/practical/views/open_drawer_button_component.rb +16 -0
- data/app/components/practical/views/page_component.html.erb +13 -1
- data/app/components/practical/views/page_component.rb +2 -0
- data/app/components/practical/views/toast_component.html.erb +1 -1
- data/app/components/practical/views/toast_component.rb +1 -3
- data/app/concerns/practical/auth/passkeys/controllers/emergency_registrations.rb +1 -1
- data/app/lib/practical/loaders/base.rb +15 -7
- data/app/lib/practical/test/helpers/integration/assertions.rb +1 -1
- data/app/lib/practical/test/helpers/passkey/system/selenium.rb +3 -1
- data/app/lib/practical/test/helpers/setup/debug.rb +7 -4
- data/app/lib/practical/test/helpers/system/assertions.rb +1 -1
- data/app/lib/practical/test/shared/auth/passkeys/controllers/emergency_registration/base.rb +18 -18
- data/app/lib/practical/test/shared/auth/passkeys/controllers/emergency_registration/self_service.rb +2 -2
- data/app/lib/practical/test/shared/auth/passkeys/controllers/passkey_management/base.rb +2 -2
- data/app/lib/practical/test/shared/auth/passkeys/controllers/registrations/self_signup.rb +1 -1
- data/app/lib/practical/test/shared/auth/passkeys/controllers/registrations/update.rb +2 -2
- data/app/lib/practical/test/shared/auth/passkeys/controllers/sessions/base.rb +2 -2
- data/app/lib/practical/test/shared/auth/passkeys/controllers/sessions/cross_pollination.rb +1 -1
- data/app/lib/practical/test/shared/memberships/controllers/membership_invitations/base.rb +1 -1
- data/app/lib/practical/test/shared/memberships/controllers/membership_invitations/register_with_passkey.rb +3 -3
- data/app/lib/practical/test/shared/memberships/controllers/organization/membership.rb +13 -11
- data/app/lib/practical/test/shared/memberships/controllers/user/membership.rb +7 -5
- data/app/lib/practical/views/button/styling.rb +8 -0
- data/app/lib/practical/views/error_response.rb +2 -2
- data/app/lib/practical/views/form_builders/base.rb +1 -0
- data/app/lib/practical/views/icon_set.rb +18 -8
- data/app/lib/practical/views/web_awesome/style_utility/appearance_variant.rb +4 -0
- data/app/lib/practical/views/web_awesome/style_utility/base.rb +4 -0
- data/app/lib/practical/views/web_awesome/style_utility/color_variant.rb +1 -1
- data/app/lib/practical/views/web_awesome/style_utility/size.rb +19 -2
- data/lib/generators/practical/views/component/component_generator.rb +2 -2
- data/lib/practical/framework/engine.rb +1 -1
- data/lib/practical/pagy.rb +11 -0
- data/lib/practical/version.rb +1 -1
- data/lib/practical.rb +2 -1
- metadata +8 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9e7a07f1391054c9ea8b5743e39aa4a57cabc1da209f3b5d1fff81939f20d041
|
|
4
|
+
data.tar.gz: 6d8a26dc1d531ada515b79913137ff063f8ce0470b4e9cf3feb212bbd0188698
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 565c40aad6bf9c924c2941d27eb657994b22dc457ea0ccca2b54e9af3ee67db11f5a659403752e6ce085c864c0e1613d5536dc610206ffa0613d73f9f8e84086
|
|
7
|
+
data.tar.gz: b2d4c7c1d63b42edb948a5f99890eeaa253152a24af75d0fa8319c627fb1c6c07dc51254d396e6a20503fec304d488bed87604e62b1797c5626234a61bef88af
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Practical::Views::ButtonToComponent < Practical::Views::BaseComponent
|
|
4
|
+
include Practical::Views::Button::Styling
|
|
5
|
+
attr_accessor :url, :options, :appearance, :color_variant, :size, :html_options
|
|
6
|
+
|
|
7
|
+
def initialize(url:, options:, appearance: nil, color_variant: nil, size: nil, html_options: {})
|
|
8
|
+
self.url = url
|
|
9
|
+
self.options = options
|
|
10
|
+
self.html_options = html_options
|
|
11
|
+
initialize_style_utilities(appearance: appearance, color_variant: color_variant, size: size)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call
|
|
15
|
+
html_option_defaults = {
|
|
16
|
+
class: css_classes_from_style_utilities,
|
|
17
|
+
data: {disable: true}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
finalized_html_options = mix(html_option_defaults, html_options)
|
|
21
|
+
helpers.button_to(url, **options, **finalized_html_options) { content }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
class Practical::Views::FlashMessagesComponent < Practical::Views::BaseComponent
|
|
4
4
|
def call
|
|
5
|
+
messages = toasts
|
|
5
6
|
tag.aside(class: 'notification-messages wa-stack') do
|
|
6
|
-
safe_join(
|
|
7
|
-
alert_toast,
|
|
8
|
-
notice_toast,
|
|
9
|
-
success_toast,
|
|
10
|
-
])
|
|
7
|
+
safe_join(messages) if messages.present?
|
|
11
8
|
end
|
|
12
9
|
end
|
|
13
10
|
|
|
11
|
+
def toasts
|
|
12
|
+
[
|
|
13
|
+
alert_toast,
|
|
14
|
+
notice_toast,
|
|
15
|
+
success_toast,
|
|
16
|
+
].compact
|
|
17
|
+
end
|
|
18
|
+
|
|
14
19
|
def success_toast
|
|
15
20
|
render_toast(
|
|
16
21
|
color_variant: :success,
|
|
@@ -51,8 +56,11 @@ class Practical::Views::FlashMessagesComponent < Practical::Views::BaseComponent
|
|
|
51
56
|
component = Practical::Views::ToastComponent.new(color_variant: color_variant)
|
|
52
57
|
|
|
53
58
|
render component do |component|
|
|
54
|
-
if icon.present? && icon.is_a?(Hash)
|
|
55
|
-
icon
|
|
59
|
+
if icon.present? && (icon.is_a?(Hash) || icon.is_a?(ViewComponent::Base))
|
|
60
|
+
if icon.is_a?(Hash)
|
|
61
|
+
icon = Practical::Views::IconComponent.new(**icon.to_h.symbolize_keys)
|
|
62
|
+
end
|
|
63
|
+
|
|
56
64
|
component.with_icon do
|
|
57
65
|
render icon
|
|
58
66
|
end
|
|
@@ -8,7 +8,7 @@ class Practical::Views::Form::ErrorListComponent < Practical::Views::BaseCompone
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def call
|
|
11
|
-
tag.ul
|
|
11
|
+
tag.ul {
|
|
12
12
|
safe_join(errors.map{|error| render Practical::Views::Form::ErrorListItemComponent.new(error: error) })
|
|
13
13
|
}
|
|
14
14
|
end
|
|
@@ -12,9 +12,8 @@ class Practical::Views::Form::ErrorListItemComponent < Practical::Views::BaseCom
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def call
|
|
15
|
-
tag.li(
|
|
16
|
-
|
|
17
|
-
tag.span(error.message)
|
|
15
|
+
tag.li(data: {"pf-error-type": error.type, "pf-error-visible": true}) {
|
|
16
|
+
tag.span(error.message, data: { "pf-error-message": true })
|
|
18
17
|
}
|
|
19
18
|
end
|
|
20
19
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
class Practical::Views::Form::ErrorListItemTemplateComponent < Practical::Views::BaseComponent
|
|
4
4
|
def call
|
|
5
|
-
tag.template(id: 'error-list-item-template') {
|
|
5
|
+
tag.template(id: 'pf-error-list-item-template') {
|
|
6
6
|
render Practical::Views::Form::ErrorListItemComponent.new(error: ActiveModel::Error.new(nil, nil, nil))
|
|
7
7
|
}
|
|
8
8
|
end
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
<%= tag.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
<%= tag.wa_callout(variant: :danger) do %>
|
|
2
|
+
<%= render icon_set.error_callout_icon %>
|
|
3
|
+
<%= tag.section(**finalized_options) do %>
|
|
4
|
+
<header>
|
|
5
|
+
<strong><%= blurb %></strong>
|
|
6
|
+
</header>
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
<%= render Practical::Views::Form::ErrorListComponent.new(errors: remaining_errors) %>
|
|
9
|
+
<% end %>
|
|
7
10
|
<% end %>
|
|
@@ -11,7 +11,7 @@ class Practical::Views::Form::FallbackErrorsSectionComponent < Practical::Views:
|
|
|
11
11
|
|
|
12
12
|
def finalized_options
|
|
13
13
|
mix({
|
|
14
|
-
|
|
14
|
+
data: {"pf-error-container": true, "pf-fallback-error-section": true},
|
|
15
15
|
id: id
|
|
16
16
|
}, @options)
|
|
17
17
|
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<wa-callout variant="danger">
|
|
2
|
+
<%= render icon_set.error_callout_icon %>
|
|
3
|
+
|
|
4
|
+
<%= label(object_method, nil, finalized_options) do %>
|
|
5
|
+
<header data-pf-field-multiple-errors-blurb><strong><%= multiple_errors_blurb %></strong></header>
|
|
6
|
+
<%= render Practical::Views::Form::ErrorListComponent.new(errors: errors) %>
|
|
7
|
+
<% end %>
|
|
8
|
+
</wa-callout>
|
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Practical::Views::Form::FieldErrorsComponent < Practical::Views::BaseComponent
|
|
4
|
-
attr_reader :f, :object_method, :options
|
|
4
|
+
attr_reader :f, :object_method, :multiple_errors_blurb, :options
|
|
5
5
|
|
|
6
|
-
def initialize(f:, object_method:, options:)
|
|
6
|
+
def initialize(f:, object_method:, multiple_errors_blurb:, options:)
|
|
7
7
|
@f = f
|
|
8
8
|
@object_method = object_method
|
|
9
|
+
@multiple_errors_blurb = multiple_errors_blurb
|
|
9
10
|
@options = options
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
def
|
|
13
|
+
def errors
|
|
14
|
+
f.errors_for(object_method) || []
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def finalized_options
|
|
13
18
|
id = f.field_errors_id(object_method)
|
|
14
|
-
classes = ["error-section"
|
|
15
|
-
errors = f.errors_for(object_method)
|
|
19
|
+
classes = ["error-section"]
|
|
16
20
|
|
|
17
21
|
if errors.blank?
|
|
18
22
|
classes << ["no-server-errors"]
|
|
19
|
-
errors = []
|
|
20
23
|
end
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
25
|
+
return mix({
|
|
26
|
+
id: id,
|
|
27
|
+
class: classes,
|
|
28
|
+
data: {'pf-error-container': true}
|
|
29
|
+
}, options)
|
|
27
30
|
end
|
|
28
31
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Practical::Views::Form::InputComponent < Practical::Views::BaseComponent
|
|
4
|
+
class FieldOptionsNotCalledError < StandardError; end
|
|
4
5
|
attr_accessor :f, :object_method, :label_options
|
|
5
6
|
|
|
6
7
|
renders_one :label
|
|
@@ -17,6 +18,19 @@ class Practical::Views::Form::InputComponent < Practical::Views::BaseComponent
|
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def field_options(**options)
|
|
20
|
-
|
|
21
|
+
@_field_options_called = true
|
|
22
|
+
return mix({
|
|
23
|
+
"aria-describedby": field_errors_id,
|
|
24
|
+
"data": {"pf-initial-load-errors": f.errors_for(object_method)&.any? }
|
|
25
|
+
}, options)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def around_render
|
|
29
|
+
result = yield
|
|
30
|
+
unless @_field_options_called
|
|
31
|
+
raise FieldOptionsNotCalledError, "field_options was not called when rendering an InputComponent; which means this the input & its error container are not connected."
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
return result
|
|
21
35
|
end
|
|
22
36
|
end
|
|
@@ -11,6 +11,6 @@ class Practical::Views::ModalDialogComponent < Practical::Views::BaseComponent
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def finalized_options
|
|
14
|
-
mix({id: id, open: open, data: {ensure_modal: true}, class: 'wa-dialog-stack-patch'}, options)
|
|
14
|
+
mix({id: id, open: open, data: {ensure_modal: true}, class: 'wa-dialog-stack-patch wa-dialog-contents-patch'}, options)
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
<%= render Practical::Views::OpenDialogButtonComponent.new(dialog_id: dialog_id, appearance: "filled outlined", size: :small) do %>
|
|
2
|
-
<%=
|
|
2
|
+
<%= Pagy::I18n.translate('pagy.nav.gap').html_safe %>
|
|
3
3
|
<% end %>
|
|
4
4
|
|
|
5
5
|
<%= render Practical::Views::ModalDialogComponent.new(id: dialog_id) do |component| %>
|
|
6
6
|
|
|
7
7
|
<% component.with_header do %>
|
|
8
|
-
<%=
|
|
8
|
+
<%= Pagy::I18n.translate("pagy.nav.goto_page_form.legend") %>
|
|
9
9
|
<% end %>
|
|
10
10
|
<section class="wa-stack">
|
|
11
11
|
<p><%= page_detail_text %></p>
|
|
12
|
-
<%=
|
|
13
|
-
url: uri_parts.uri.to_s,
|
|
14
|
-
method: :get,
|
|
15
|
-
local: true,
|
|
16
|
-
builder: NewApplicationFormBuilder,
|
|
17
|
-
class: 'pagination-goto-form wa-size-s'
|
|
18
|
-
) do |f| %>
|
|
12
|
+
<%= form_wrapper do |f| %>
|
|
19
13
|
<% uri_parts.params.each do |key, value| %>
|
|
20
14
|
<%= hidden_field_for_goto_form(key: key, value: value) %>
|
|
21
15
|
<% end %>
|
|
@@ -23,7 +17,7 @@
|
|
|
23
17
|
<section class="wa-cluster">
|
|
24
18
|
<%= f.number_field :page, value: pagy.page, placeholder: pagy.page.to_s, required: true, min: 1, max: pagy.last %>
|
|
25
19
|
<%= f.button_component(type: :submit, color_variant: :neutral, appearance: :filled) do
|
|
26
|
-
|
|
20
|
+
Pagy::I18n.translate("pagy.nav.goto_page_form.button")
|
|
27
21
|
end %>
|
|
28
22
|
</section>
|
|
29
23
|
<% end %>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Practical::Views::Navigation::Pagination::GotoFormComponent < Practical::Views::BaseComponent
|
|
4
|
-
include
|
|
4
|
+
include Practical::Views::FormWrapper
|
|
5
5
|
attr_accessor :pagy, :dialog_id, :page_detail_text
|
|
6
6
|
|
|
7
7
|
URIParts = Data.define(:uri, :params)
|
|
@@ -13,7 +13,7 @@ class Practical::Views::Navigation::Pagination::GotoFormComponent < Practical::V
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def uri_parts
|
|
16
|
-
uri = URI.parse(
|
|
16
|
+
uri = URI.parse(pagy.page_url)
|
|
17
17
|
params = Rack::Utils.parse_query(uri.query)
|
|
18
18
|
params.delete("page")
|
|
19
19
|
uri.query = ""
|
|
@@ -31,4 +31,19 @@ class Practical::Views::Navigation::Pagination::GotoFormComponent < Practical::V
|
|
|
31
31
|
helpers.hidden_field_tag key, value
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
|
+
|
|
35
|
+
def generic_errors_id
|
|
36
|
+
"#{dialog_id}_pagination"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def form_wrapper(&block)
|
|
40
|
+
wrapped_form_with(
|
|
41
|
+
url: uri_parts.uri.to_s,
|
|
42
|
+
method: :get,
|
|
43
|
+
local: true,
|
|
44
|
+
builder: ApplicationFormBuilder,
|
|
45
|
+
class: 'pagination-goto-form wa-size-s',
|
|
46
|
+
&block
|
|
47
|
+
)
|
|
48
|
+
end
|
|
34
49
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Practical::Views::Navigation::PaginationComponent < ApplicationComponent
|
|
4
|
-
include Pagy::Frontend
|
|
5
4
|
attr_reader :request
|
|
6
5
|
attr_accessor :pagy, :item_name, :i18n_key
|
|
7
6
|
|
|
@@ -15,40 +14,35 @@ class Practical::Views::Navigation::PaginationComponent < ApplicationComponent
|
|
|
15
14
|
def page_detail_text
|
|
16
15
|
pagy_count = pagy.count
|
|
17
16
|
if pagy_count == 0
|
|
18
|
-
key = "pagy.
|
|
17
|
+
key = "pagy.info_tag.no_items"
|
|
19
18
|
elsif pagy.pages == 1
|
|
20
|
-
key = "pagy.
|
|
19
|
+
key = "pagy.info_tag.single_page"
|
|
21
20
|
else
|
|
22
|
-
key = "pagy.
|
|
21
|
+
key = "pagy.info_tag.multiple_pages"
|
|
23
22
|
end
|
|
24
23
|
|
|
25
|
-
item_name = item_name.presence ||
|
|
24
|
+
item_name = item_name.presence || Pagy::I18n.translate(i18n_key || pagy.vars[:i18n_key], count: pagy_count)
|
|
26
25
|
|
|
27
|
-
item_text =
|
|
26
|
+
item_text = Pagy::I18n.translate(key,
|
|
28
27
|
item_name: item_name,
|
|
29
28
|
count: pagy_count, from: pagy.from, to: pagy.to
|
|
30
29
|
)
|
|
31
30
|
|
|
32
|
-
page_count_text =
|
|
31
|
+
page_count_text = Pagy::I18n.translate("pagy.info_tag.page_count", page: pagy.page, count: pagy.pages)
|
|
33
32
|
|
|
34
|
-
return
|
|
33
|
+
return Pagy::I18n.translate("pagy.info_tag.page_detail_text", item_text: item_text, page_count_text: page_count_text)
|
|
35
34
|
end
|
|
36
35
|
|
|
37
36
|
def previous_item
|
|
38
|
-
classes = helpers.class_names(:page, :previous, disabled: !pagy.
|
|
39
|
-
|
|
40
|
-
text = icon_text(
|
|
41
|
-
icon: icon_set.previous_arrow,
|
|
42
|
-
text: pagy_t('pagy.nav.v2_prev')
|
|
43
|
-
)
|
|
37
|
+
classes = helpers.class_names(:page, :previous, disabled: !pagy.previous)
|
|
44
38
|
|
|
45
39
|
tag.div(class: classes, role: :listitem){
|
|
46
|
-
if pagy.
|
|
47
|
-
tag.a(href:
|
|
48
|
-
|
|
40
|
+
if pagy.previous
|
|
41
|
+
tag.a(href: pagy.page_url(pagy.previous), title: Pagy::I18n.translate("pagy.aria_label.previous")) {
|
|
42
|
+
render icon_set.previous_arrow
|
|
49
43
|
}
|
|
50
44
|
else
|
|
51
|
-
|
|
45
|
+
render icon_set.previous_arrow
|
|
52
46
|
end
|
|
53
47
|
}
|
|
54
48
|
end
|
|
@@ -56,18 +50,13 @@ class Practical::Views::Navigation::PaginationComponent < ApplicationComponent
|
|
|
56
50
|
def next_item
|
|
57
51
|
classes = helpers.class_names(:page, :next, disabled: !pagy.next)
|
|
58
52
|
|
|
59
|
-
text = icon_text(
|
|
60
|
-
icon: icon_set.next_arrow,
|
|
61
|
-
text: pagy_t('pagy.nav.v2_next')
|
|
62
|
-
)
|
|
63
|
-
|
|
64
53
|
tag.div(class: classes, role: :listitem){
|
|
65
54
|
if pagy.next
|
|
66
|
-
tag.a(href:
|
|
67
|
-
|
|
55
|
+
tag.a(href: pagy.page_url(pagy.next), title: Pagy::I18n.translate("pagy.aria_label.next")) {
|
|
56
|
+
render icon_set.next_arrow
|
|
68
57
|
}
|
|
69
58
|
else
|
|
70
|
-
|
|
59
|
+
render icon_set.next_arrow
|
|
71
60
|
end
|
|
72
61
|
}
|
|
73
62
|
end
|
|
@@ -80,12 +69,12 @@ class Practical::Views::Navigation::PaginationComponent < ApplicationComponent
|
|
|
80
69
|
case item
|
|
81
70
|
when Integer
|
|
82
71
|
tag.div(class: :page, role: :listitem) {
|
|
83
|
-
tag.a(item, href:
|
|
72
|
+
tag.a(item, href: pagy.page_url(item), title: Pagy::I18n.translate("pagy.nav.page_title", page_number: item))
|
|
84
73
|
}
|
|
85
74
|
when String
|
|
86
75
|
tag.div(
|
|
87
76
|
item,
|
|
88
|
-
class: "page current", role: :listitem, title:
|
|
77
|
+
class: "page current", role: :listitem, title: Pagy::I18n.translate("pagy.nav.current_page_title", page_number: item)
|
|
89
78
|
)
|
|
90
79
|
when :gap
|
|
91
80
|
render Practical::Views::Navigation::Pagination::GotoFormComponent.new(
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Practical::Views::OpenDrawerButtonComponent < Practical::Views::ButtonComponent
|
|
4
|
+
attr_accessor :drawer_id
|
|
5
|
+
|
|
6
|
+
def initialize(drawer_id:, appearance: nil, color_variant: nil, size: nil, options: {})
|
|
7
|
+
options = options.with_defaults(
|
|
8
|
+
onclick: self.class.inline_js_to_open_dialog(drawer_id: drawer_id)
|
|
9
|
+
)
|
|
10
|
+
super(type: :button, appearance: appearance, color_variant: color_variant, size: size, options: options)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.inline_js_to_open_dialog(drawer_id:)
|
|
14
|
+
return "document.getElementById(`#{drawer_id}`).open = true"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -41,10 +41,22 @@
|
|
|
41
41
|
</aside>
|
|
42
42
|
<% end %>
|
|
43
43
|
|
|
44
|
-
<main
|
|
44
|
+
<main>
|
|
45
45
|
<%= content %>
|
|
46
46
|
</main>
|
|
47
47
|
|
|
48
|
+
<% if aside? %>
|
|
49
|
+
<aside slot="aside">
|
|
50
|
+
<%= aside %>
|
|
51
|
+
</aside>
|
|
52
|
+
<% end %>
|
|
53
|
+
|
|
54
|
+
<% if main_footer? %>
|
|
55
|
+
<footer slot="main-footer">
|
|
56
|
+
<%= main_footer %>
|
|
57
|
+
</footer>
|
|
58
|
+
<% end %>
|
|
59
|
+
|
|
48
60
|
<% if footer? %>
|
|
49
61
|
<footer slot="footer">
|
|
50
62
|
<%= footer %>
|
|
@@ -6,7 +6,9 @@ class Practical::Views::PageComponent < Practical::Views::BaseComponent
|
|
|
6
6
|
renders_one :subheader
|
|
7
7
|
renders_one :footer
|
|
8
8
|
renders_one :main_header
|
|
9
|
+
renders_one :main_footer
|
|
9
10
|
renders_one :navigation
|
|
10
11
|
renders_one :navigation_header
|
|
11
12
|
renders_one :navigation_footer
|
|
13
|
+
renders_one :aside
|
|
12
14
|
end
|
|
@@ -12,8 +12,6 @@ class Practical::Views::ToastComponent < Practical::Views::BaseComponent
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def finalized_callout_options
|
|
15
|
-
mix(
|
|
16
|
-
class: class_names("wa-callout", css_classes_from_style_utilities)
|
|
17
|
-
}, options)
|
|
15
|
+
mix(attributes_from_style_utilities, options)
|
|
18
16
|
end
|
|
19
17
|
end
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Practical::Loaders::Base
|
|
4
|
-
include Pagy::
|
|
4
|
+
include Pagy::Method
|
|
5
5
|
|
|
6
|
-
attr_accessor :
|
|
6
|
+
attr_accessor :request, :base_relation, :datatable_form,
|
|
7
|
+
:relation_builder, :pagy_instance, :records
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
delegate :params, to: :request
|
|
10
|
+
|
|
11
|
+
def initialize(request:, base_relation:)
|
|
12
|
+
self.request = request
|
|
10
13
|
self.base_relation = base_relation
|
|
11
14
|
end
|
|
12
15
|
|
|
13
|
-
def self.load(
|
|
14
|
-
instance = self.new(
|
|
16
|
+
def self.load(request:, base_relation:)
|
|
17
|
+
instance = self.new(request: request, base_relation: base_relation)
|
|
15
18
|
instance.load
|
|
16
19
|
return instance
|
|
17
20
|
end
|
|
@@ -19,7 +22,7 @@ class Practical::Loaders::Base
|
|
|
19
22
|
def load
|
|
20
23
|
self.datatable_form = build_datatable_form
|
|
21
24
|
self.relation_builder = build_relation_builder
|
|
22
|
-
self.pagy_instance, self.records = pagy(relation_builder.applied_relation
|
|
25
|
+
self.pagy_instance, self.records = pagy(relation_builder.applied_relation)
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def datatable_payload
|
|
@@ -41,4 +44,9 @@ class Practical::Loaders::Base
|
|
|
41
44
|
def default_payload
|
|
42
45
|
raise NotImplementedError
|
|
43
46
|
end
|
|
47
|
+
|
|
48
|
+
def params
|
|
49
|
+
return request.params if request.params.kind_of?(ActionController::Parameters)
|
|
50
|
+
return ActionController::Parameters.new(request.params)
|
|
51
|
+
end
|
|
44
52
|
end
|
|
@@ -24,7 +24,9 @@ module Practical::Test::Helpers::Passkey::System::Selenium
|
|
|
24
24
|
|
|
25
25
|
driven_by :selenium, using: selenium_driver_key, screen_size: [1400, 1400] do |options|
|
|
26
26
|
options.accept_insecure_certs = true
|
|
27
|
-
|
|
27
|
+
if ENV.has_key?("HEADLESS_TESTS")
|
|
28
|
+
options.args << "--headless=new"
|
|
29
|
+
end
|
|
28
30
|
end
|
|
29
31
|
end
|
|
30
32
|
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Practical::Test::Helpers::Setup::Debug
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
included do
|
|
6
|
+
# rubocop:disable Rails/Output
|
|
7
|
+
puts "MINITEST_PARALLEL_EXECUTOR_SIZE: #{Minitest.parallel_executor.size}"
|
|
8
|
+
puts "PARALLEL_WORKERS: #{ENV["PARALLEL_WORKERS"]}"
|
|
9
|
+
# rubocop:enable Rails/Output
|
|
10
|
+
end
|
|
8
11
|
end
|