action_link 0.1.1
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 +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +34 -0
- data/app/assets/fonts/action_link/acticons.woff +0 -0
- data/app/assets/stylesheets/action_link/acticons.sass +9 -0
- data/app/assets/stylesheets/action_link/all.sass +4 -0
- data/app/assets/stylesheets/action_link/fonts.sass +5 -0
- data/app/assets/stylesheets/action_link/style.scss +42 -0
- data/app/assets/stylesheets/action_link/variables.scss +10 -0
- data/app/components/action_link/application_component.rb +39 -0
- data/app/components/action_link/base.rb +138 -0
- data/app/components/action_link/destroy.rb +51 -0
- data/app/components/action_link/edit.rb +21 -0
- data/app/components/action_link/new.rb +31 -0
- data/app/components/action_link/show.rb +21 -0
- data/config/locales/action_link_component.de.yml +12 -0
- data/config/locales/action_link_component.en.yml +12 -0
- data/lib/action_link/engine.rb +30 -0
- data/lib/action_link/model.rb +26 -0
- data/lib/action_link/title_subject_name.rb +30 -0
- data/lib/action_link/version.rb +5 -0
- data/lib/action_link.rb +16 -0
- metadata +125 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1fb82eefce04018119e077392dd55980535cb21407adcb14988605f199bd3e42
|
4
|
+
data.tar.gz: ea83ec0bf21af581e71ec2a79783adb97a3e65f8fe91ef43d1ef241f1ad56232
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b1f640474051d8720d8de893567ded1129277abde85b36f07d2c2d16932dd2d7a1c7b349dd9a9c23f274f67d4892f5b68ac14427f20c930887b996546a29e214
|
7
|
+
data.tar.gz: b142f701ff7b43541fb9a5d99c98ec297e1480701b0dfeab848b243662c5c05c5abcc2c42ced17333e615380064f5a8c10e34a88d219f1436b0188aeb21c93ec
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2023 halo
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# ActionLink
|
2
|
+
|
3
|
+
Intuitive ViewComponents for CRUD resource link actions in Rails.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
# In Rails view
|
9
|
+
= render ActionLink::Show.new(url: [:admin, @post], current_user:)
|
10
|
+
```
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Install the gem and add to the application's Gemfile by executing:
|
15
|
+
|
16
|
+
$ bundle add action_link
|
17
|
+
|
18
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
19
|
+
|
20
|
+
$ gem install action_link
|
21
|
+
|
22
|
+
## Development
|
23
|
+
|
24
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/halo/action_link.
|
29
|
+
|
30
|
+
## License
|
31
|
+
|
32
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
33
|
+
|
34
|
+
The icons are taken from the incredible [iconmonstr](https://iconmonstr.com/license/).
|
Binary file
|
@@ -0,0 +1,42 @@
|
|
1
|
+
// This file is autogenerated by `rake acticons:update`
|
2
|
+
|
3
|
+
.o-acticon--info-circle {
|
4
|
+
&:before {
|
5
|
+
content: $o-acticon--info-circle;
|
6
|
+
}
|
7
|
+
}
|
8
|
+
.o-acticon--questionmark {
|
9
|
+
&:before {
|
10
|
+
content: $o-acticon--questionmark;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
.o-acticon--arrow-down-circle {
|
14
|
+
&:before {
|
15
|
+
content: $o-acticon--arrow-down-circle;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
.o-acticon--pencil-circle {
|
19
|
+
&:before {
|
20
|
+
content: $o-acticon--pencil-circle;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
.o-acticon--check-circle {
|
24
|
+
&:before {
|
25
|
+
content: $o-acticon--check-circle;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
.o-acticon--chevron-circle-right {
|
29
|
+
&:before {
|
30
|
+
content: $o-acticon--chevron-circle-right;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
.o-acticon--plus-circle {
|
34
|
+
&:before {
|
35
|
+
content: $o-acticon--plus-circle;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
.o-acticon--times-circle {
|
39
|
+
&:before {
|
40
|
+
content: $o-acticon--times-circle;
|
41
|
+
}
|
42
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
// This file is autogenerated by `rake acticons:update`
|
2
|
+
|
3
|
+
$o-acticon--info-circle: "\e907";
|
4
|
+
$o-acticon--questionmark: "\2753";
|
5
|
+
$o-acticon--arrow-down-circle: "\e9af";
|
6
|
+
$o-acticon--pencil-circle: "\e9ae";
|
7
|
+
$o-acticon--check-circle: "\e93b";
|
8
|
+
$o-acticon--chevron-circle-right: "\e928";
|
9
|
+
$o-acticon--plus-circle: "\e919";
|
10
|
+
$o-acticon--times-circle: "\e91a";
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionLink
|
4
|
+
# A component that every other component inherits from in this gem.
|
5
|
+
# It adds convenience methods for initialization of a component.
|
6
|
+
class ApplicationComponent < ViewComponent::Base
|
7
|
+
extend Dry::Initializer
|
8
|
+
|
9
|
+
# By default, Dry::Initializer doesn't complain about invalid arguments.
|
10
|
+
# We want it to raise an error.
|
11
|
+
def initialize(...)
|
12
|
+
__check_for_unknown_options(...)
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def __check_for_unknown_options(*args, **kwargs)
|
19
|
+
return if __defined_options.empty?
|
20
|
+
|
21
|
+
# Checking params
|
22
|
+
opts = args.drop(__defined_params.length).first || kwargs
|
23
|
+
raise ArgumentError, "Unexpected argument #{opts}" unless opts.is_a? Hash
|
24
|
+
|
25
|
+
# Checking options
|
26
|
+
unknown_options = opts.keys - __defined_options
|
27
|
+
message = "Key(s) #{unknown_options} not found in #{__defined_options}"
|
28
|
+
raise KeyError, message if unknown_options.any?
|
29
|
+
end
|
30
|
+
|
31
|
+
def __defined_options
|
32
|
+
self.class.dry_initializer.options.map(&:source)
|
33
|
+
end
|
34
|
+
|
35
|
+
def __defined_params
|
36
|
+
self.class.dry_initializer.params.map(&:source)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionLink
|
4
|
+
# A component that every action link inherits from.
|
5
|
+
# It adds the API that all action links have in common.
|
6
|
+
class Base < ApplicationComponent
|
7
|
+
# The following options are common for all subclasses.
|
8
|
+
|
9
|
+
# Authorization
|
10
|
+
option :current_user # User passed to the policy
|
11
|
+
option :policy_library, as: :manual_policy_library, default: -> {}
|
12
|
+
option :policy_subject, as: :manual_policy_subject, default: -> {} # Record passed to the policy
|
13
|
+
|
14
|
+
# Visualization
|
15
|
+
option :icon, default: -> {}
|
16
|
+
|
17
|
+
# The following options may vary for different subclasses.
|
18
|
+
# Here, in the superclass, they're all defined as optional.
|
19
|
+
option :class, as: :css_class, default: -> {}
|
20
|
+
option :data, default: -> {}
|
21
|
+
option :model, as: :manual_model, default: -> {}
|
22
|
+
option :i18n_model, as: :manual_i18n_model, default: -> {}
|
23
|
+
option :title, as: :manual_title, default: -> {}
|
24
|
+
option :url, default: -> {}
|
25
|
+
|
26
|
+
def permission?
|
27
|
+
_policy.public_send(:"#{_action}?")
|
28
|
+
end
|
29
|
+
|
30
|
+
# Allows you to turn off the icon.
|
31
|
+
def icon?
|
32
|
+
icon != false
|
33
|
+
end
|
34
|
+
|
35
|
+
def icon_tag(name)
|
36
|
+
helpers.content_tag :i, nil,
|
37
|
+
class: "o-acticon o-acticon--#{name}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def options
|
41
|
+
{
|
42
|
+
title: _title,
|
43
|
+
class: _class,
|
44
|
+
data: _data,
|
45
|
+
target: _target,
|
46
|
+
method: http_method
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# May be accessed and/or overriden in subclasses
|
53
|
+
|
54
|
+
def i18n_title_key
|
55
|
+
"action_link_component.titles.#{_action}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def http_method; end
|
59
|
+
def confirmation; end
|
60
|
+
|
61
|
+
def default_confirmation_subject
|
62
|
+
_title_subject_name
|
63
|
+
end
|
64
|
+
|
65
|
+
# Below this point, strictly internal to this superclass.
|
66
|
+
# If you find yourself overwriting any of these methods, question the concept.
|
67
|
+
# Don't call these methods from the view, either.
|
68
|
+
|
69
|
+
# Options for `link_to`
|
70
|
+
|
71
|
+
def _title
|
72
|
+
t(i18n_title_key, subject: strip_tags(_title_subject_name))
|
73
|
+
end
|
74
|
+
|
75
|
+
def _data
|
76
|
+
(data || {}).merge(confirm: confirmation)
|
77
|
+
end
|
78
|
+
|
79
|
+
def _class
|
80
|
+
['c-action-link', css_class].join(' ').squish
|
81
|
+
end
|
82
|
+
|
83
|
+
def _target
|
84
|
+
:_blank if url.to_s.start_with?('http:') || url.to_s.start_with?('https:')
|
85
|
+
end
|
86
|
+
|
87
|
+
def _additional_data
|
88
|
+
{ confirm: confirmation }
|
89
|
+
end
|
90
|
+
|
91
|
+
# Helpers
|
92
|
+
|
93
|
+
def _model
|
94
|
+
@_model ||= ::ActionLink::Model.call(manual_model:, url:)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Converts a class like `::ActionLink::New` to the symbol `:new`.
|
98
|
+
def _action
|
99
|
+
@_action ||= self.class.name[12..].underscore.to_sym
|
100
|
+
end
|
101
|
+
|
102
|
+
def _title_subject_name
|
103
|
+
@_title_subject_name ||= ::ActionLink::TitleSubjectName.call(
|
104
|
+
manual_title:,
|
105
|
+
manual_i18n_model:,
|
106
|
+
model: _model
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
def _policy_subject
|
111
|
+
manual_policy_subject ||
|
112
|
+
_model ||
|
113
|
+
raise("Expected a policy subject #{self}")
|
114
|
+
end
|
115
|
+
|
116
|
+
def _policy_library
|
117
|
+
manual_policy_library || :auto
|
118
|
+
end
|
119
|
+
|
120
|
+
def _policy
|
121
|
+
if (_policy_library == :auto && defined?(::ActionPolicy)) || _policy_library == :action_policy
|
122
|
+
_policy_from_action_policy
|
123
|
+
elsif (_policy_library == :auto && defined?(::Pundit)) || _policy_library == :pundit
|
124
|
+
_policy_from_pundit
|
125
|
+
else
|
126
|
+
raise 'Implement me in a sane way, once it is actually needed'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def _policy_from_action_policy
|
131
|
+
::ActionPolicy.lookup(_policy_subject).new(_policy_subject, user: current_user)
|
132
|
+
end
|
133
|
+
|
134
|
+
def _policy_from_pundit
|
135
|
+
::Pundit.policy!(current_user, _policy_subject)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionLink
|
4
|
+
# An action link that indicates deleting a new record.
|
5
|
+
class Destroy < Base
|
6
|
+
ICON = 'times-circle'
|
7
|
+
|
8
|
+
erb_template <<~ERB.gsub("\n", '')
|
9
|
+
<% if permission? %>
|
10
|
+
<%= link_to(url, **options) do %>
|
11
|
+
<%= content %>
|
12
|
+
<% if icon? %><%= ' ' %><%= icon_tag ::ActionLink::Destroy::ICON %><% end %>
|
13
|
+
<% end %>
|
14
|
+
<% else %>
|
15
|
+
<%= content %>
|
16
|
+
<% end %>
|
17
|
+
ERB
|
18
|
+
|
19
|
+
option :url
|
20
|
+
option :confirmation, as: :manual_confirmation, default: -> {}
|
21
|
+
option :confirmation_subject, default: -> {}
|
22
|
+
option :associative, default: -> { false }
|
23
|
+
|
24
|
+
def i18n_title_key
|
25
|
+
return 'action_link_component.titles.unassign' if associative
|
26
|
+
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def confirmation
|
31
|
+
return manual_confirmation if manual_confirmation
|
32
|
+
|
33
|
+
I18n.t(i18n_confirmation_key,
|
34
|
+
subject: strip_tags(confirmation_subject || default_confirmation_subject))
|
35
|
+
end
|
36
|
+
|
37
|
+
def http_method
|
38
|
+
:delete
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def i18n_confirmation_key
|
44
|
+
if associative
|
45
|
+
'action_link_component.confirmations.unassign'
|
46
|
+
else
|
47
|
+
'action_link_component.confirmations.destroy'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionLink
|
4
|
+
# An action link that indicates editing an existing record.
|
5
|
+
class Edit < Base
|
6
|
+
ICON = 'pencil-circle'
|
7
|
+
|
8
|
+
erb_template <<~ERB.gsub("\n", '')
|
9
|
+
<% if permission? %>
|
10
|
+
<%= link_to(url, **options) do %>
|
11
|
+
<%= content %>
|
12
|
+
<% if icon? %><%= ' ' %><%= icon_tag ::ActionLink::Edit::ICON %><% end %>
|
13
|
+
<% end %>
|
14
|
+
<% else %>
|
15
|
+
<%= content %>
|
16
|
+
<% end %>
|
17
|
+
ERB
|
18
|
+
|
19
|
+
option :url
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionLink
|
4
|
+
# An action link that indicates adding a new record.
|
5
|
+
class New < Base
|
6
|
+
ICON = 'plus-circle'
|
7
|
+
|
8
|
+
erb_template <<~ERB.gsub("\n", '')
|
9
|
+
<% if permission? %>
|
10
|
+
<%= link_to(url, **options) do %>
|
11
|
+
<%= content %>
|
12
|
+
<% if icon? %><%= ' ' %><%= icon_tag ::ActionLink::New::ICON %><% end %>
|
13
|
+
<% end %>
|
14
|
+
<% else %>
|
15
|
+
<%= content %>
|
16
|
+
<% end %>
|
17
|
+
ERB
|
18
|
+
|
19
|
+
# `model:` is mandatory because `[:new, :admin, Klass]` would
|
20
|
+
# translate to the route `[:new, :admin, :klasses]` and that's incorrect (plural vs singular).
|
21
|
+
option :model, as: :manual_model
|
22
|
+
option :url
|
23
|
+
option :associative, default: -> { false }
|
24
|
+
|
25
|
+
def i18n_title_key
|
26
|
+
return 'action_link_component.titles.assign' if associative
|
27
|
+
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionLink
|
4
|
+
# An action link that indicates showing an existing record.
|
5
|
+
class Show < Base
|
6
|
+
ICON = 'chevron-circle-right'
|
7
|
+
|
8
|
+
erb_template <<~ERB.gsub("\n", '')
|
9
|
+
<% if permission? %>
|
10
|
+
<%= link_to(url, **options) do %>
|
11
|
+
<%= content %>
|
12
|
+
<% if icon? %><%= ' ' %><%= icon_tag ::ActionLink::Show::ICON %><% end %>
|
13
|
+
<% end %>
|
14
|
+
<% else %>
|
15
|
+
<%= content %>
|
16
|
+
<% end %>
|
17
|
+
ERB
|
18
|
+
|
19
|
+
option :url
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
de:
|
2
|
+
action_link_component:
|
3
|
+
confirmations:
|
4
|
+
destroy: "Möchtest du %{subject} löschen?"
|
5
|
+
unassign: "Möchtest du %{subject} entkoppeln? Bei dieser Aktion wird nichts gelöscht."
|
6
|
+
titles:
|
7
|
+
assign: "%{subject} zuweisen"
|
8
|
+
destroy: "%{subject} löschen"
|
9
|
+
edit: "%{subject} bearbeiten"
|
10
|
+
new: "%{subject} anlegen"
|
11
|
+
show: "%{subject} anzeigen"
|
12
|
+
unassign: "%{subject} entkoppeln"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
en:
|
2
|
+
action_link_component:
|
3
|
+
confirmations:
|
4
|
+
destroy: "Would you like to delete %{subject}?"
|
5
|
+
unassign: "Would you like to unassign %{subject}? This action does not delete."
|
6
|
+
titles:
|
7
|
+
assign: "Assign %{subject}"
|
8
|
+
destroy: "Delete %{subject}"
|
9
|
+
edit: "Edit %{subject}"
|
10
|
+
new: Add %{subject}
|
11
|
+
show: "Show %{subject}"
|
12
|
+
unassign: "Unassign %{subject}"
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/engine'
|
4
|
+
require 'dry-initializer'
|
5
|
+
|
6
|
+
module ActionLink
|
7
|
+
# :nodoc:
|
8
|
+
class Engine < ::Rails::Engine
|
9
|
+
isolate_namespace ActionLink
|
10
|
+
|
11
|
+
config.to_prepare do
|
12
|
+
# Our ActionLink components are subclasses of `ViewComponent::Base`.
|
13
|
+
# When `ViewComponent::Base` is subclassed, two things happen:
|
14
|
+
#
|
15
|
+
# 1. Rails routes are included into the component
|
16
|
+
# 2. The ViewComponent configuration is accessed
|
17
|
+
#
|
18
|
+
# So we can only require our components, once Rails has booted
|
19
|
+
# AND the view_component gem has been fully initialized (configured).
|
20
|
+
#
|
21
|
+
# That's right here and now.
|
22
|
+
require_relative '../../app/components/action_link/application_component'
|
23
|
+
require_relative '../../app/components/action_link/base'
|
24
|
+
require_relative '../../app/components/action_link/destroy'
|
25
|
+
require_relative '../../app/components/action_link/edit'
|
26
|
+
require_relative '../../app/components/action_link/new'
|
27
|
+
require_relative '../../app/components/action_link/show'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionLink
|
4
|
+
# Extracts a model from the provided model options.
|
5
|
+
class Model
|
6
|
+
include Calls
|
7
|
+
|
8
|
+
option :manual_model
|
9
|
+
option :url
|
10
|
+
|
11
|
+
def call
|
12
|
+
model.respond_to?(:model_name) ||
|
13
|
+
raise(MissingModelError, "Model `#{model.inspect}` must respond to #model_name")
|
14
|
+
|
15
|
+
model
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def model
|
21
|
+
return manual_model if manual_model
|
22
|
+
|
23
|
+
url.last if url.is_a?(Array)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionLink
|
4
|
+
# Extracts a model from the provided i18n options.
|
5
|
+
class TitleSubjectName
|
6
|
+
include Calls
|
7
|
+
|
8
|
+
option :manual_title
|
9
|
+
option :manual_i18n_model
|
10
|
+
option :model
|
11
|
+
|
12
|
+
def call
|
13
|
+
manual_title || compliant_model.model_name.human
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def compliant_model
|
19
|
+
compliant_manual_model || model
|
20
|
+
end
|
21
|
+
|
22
|
+
def compliant_manual_model
|
23
|
+
return unless manual_i18n_model
|
24
|
+
return manual_i18n_model if manual_i18n_model.respond_to?(:model_name)
|
25
|
+
|
26
|
+
raise ArgumentError,
|
27
|
+
"Expected `i18n_model:` `#{manual_i18n_model.inspect}` to respond to `#model_name`"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/action_link.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/initializer'
|
4
|
+
require 'calls'
|
5
|
+
|
6
|
+
require 'action_link/version'
|
7
|
+
require 'action_link/model'
|
8
|
+
require 'action_link/title_subject_name'
|
9
|
+
|
10
|
+
require 'action_link/engine' if defined?(Rails::Engine)
|
11
|
+
|
12
|
+
module ActionLink
|
13
|
+
class Error < ::StandardError; end
|
14
|
+
class MissingModelError < Error; end
|
15
|
+
class SubclassNameError < Error; end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: action_link
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- halo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-06-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: actionview
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: calls
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: dry-initializer
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: view_component
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Every action has an icon, such as a "plus-sign" for the "new" action
|
70
|
+
email:
|
71
|
+
- github@posteo.org
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- CHANGELOG.md
|
77
|
+
- LICENSE.txt
|
78
|
+
- README.md
|
79
|
+
- app/assets/fonts/action_link/acticons.woff
|
80
|
+
- app/assets/stylesheets/action_link/acticons.sass
|
81
|
+
- app/assets/stylesheets/action_link/all.sass
|
82
|
+
- app/assets/stylesheets/action_link/fonts.sass
|
83
|
+
- app/assets/stylesheets/action_link/style.scss
|
84
|
+
- app/assets/stylesheets/action_link/variables.scss
|
85
|
+
- app/components/action_link/application_component.rb
|
86
|
+
- app/components/action_link/base.rb
|
87
|
+
- app/components/action_link/destroy.rb
|
88
|
+
- app/components/action_link/edit.rb
|
89
|
+
- app/components/action_link/new.rb
|
90
|
+
- app/components/action_link/show.rb
|
91
|
+
- config/locales/action_link_component.de.yml
|
92
|
+
- config/locales/action_link_component.en.yml
|
93
|
+
- lib/action_link.rb
|
94
|
+
- lib/action_link/engine.rb
|
95
|
+
- lib/action_link/model.rb
|
96
|
+
- lib/action_link/title_subject_name.rb
|
97
|
+
- lib/action_link/version.rb
|
98
|
+
homepage: https://github.com/halo/action_link
|
99
|
+
licenses:
|
100
|
+
- MIT
|
101
|
+
metadata:
|
102
|
+
homepage_uri: https://github.com/halo/action_link
|
103
|
+
source_code_uri: https://github.com/halo/action_link
|
104
|
+
changelog_uri: https://github.com/halo/halo/blob/main/CHANGELOG.md
|
105
|
+
rubygems_mfa_required: 'true'
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: 3.2.0
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubygems_version: 3.5.6
|
122
|
+
signing_key:
|
123
|
+
specification_version: 4
|
124
|
+
summary: A set of ViewComponents for common links (show, edit, delete, etc.)
|
125
|
+
test_files: []
|