administrate-field-lazy_has_many 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c52ef6f020f9a6ebe97cfbaf55bc989c47b295d86528c5ddc8594e164a0f80f0
4
+ data.tar.gz: 0dc0efd9692215d81171b7212cb545fc00605b29e35cdc9bdb1e3a1e43c619b7
5
+ SHA512:
6
+ metadata.gz: 25729b85a7ee139a00c87e43922f20f941de234d2fc258d5b35b1122f1da7af6d008315e681f049cb8669543bff2e2b38e984c5f36b301dd93367af3839d55ac
7
+ data.tar.gz: 031b6ad09db90bfa7b483d75095bd7adab9915c10a9104c282d33d7e2e40f7ba1687f0d554190d57fe41ce5a584c25fea3b42aab07b633e9da1c5de04ce45f7f
data/.gitattributes ADDED
@@ -0,0 +1,2 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # CHANGELOG
2
+
3
+ ## 0.1.0
4
+
5
+ :baby: Initial version
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Aftab Akram
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # Administrate::Field::LazyHasMany
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/administrate-field-lazy_has_many)](http://badge.fury.io/rb/administrate-field-lazy_has_many) [![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)
4
+
5
+ An input field that shows search results of has many association, lazily from a custom endpoint.
6
+
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'administrate-field-lazy_has_many'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install administrate-field-lazy_has_many
23
+
24
+ ## Usage
25
+
26
+ ### Controller
27
+ You need to have a route that does the following:
28
+ 1. yields an array of objects with at least the value and text you want to show i.e `[{value: 1, text: option1}]`
29
+ 2. Respond to `search` attribute
30
+ 3. Limit result `result_limit`
31
+
32
+ The best way is to re-use everything administrate search feature.
33
+ You must define this action in administrate related entity controller
34
+ ```ruby
35
+ def books_data
36
+ result_limit = params[:result_limit] || 10
37
+ search_term = params[:search].to_s.strip
38
+ resources = Administrate::Search.new(scoped_resource, dashboard_class, search_term).run
39
+ resources = resources.limit(result_limit).map do |resource|
40
+ { value: resource.id, text: dashboard.display_resource(resource) }
41
+ end
42
+ if resources.blank?
43
+ render_empty_array
44
+ else
45
+ render json: resources
46
+ end
47
+ end
48
+ ```
49
+ Above example action that could work for every model, but you can change the implementation as per need.
50
+ The only catch is it must return the comply with above conditions.
51
+
52
+ ### Field
53
+ Field is pretty easy and it does support all the features of administrate has_many field. You can provide all has_many options as per your use case.
54
+ The only require attribute is `action` which must be rails path helper.
55
+ ```ruby
56
+ require "administrate/base_dashboard"
57
+
58
+ class PostDashboard < Administrate::BaseDashboard
59
+ # ATTRIBUTE_TYPES
60
+ # a hash that describes the type of each of the model's fields.
61
+ #
62
+ # Each different type represents an Administrate::Field object,
63
+ # which determines how the attribute is displayed
64
+ # on pages throughout the dashboard.
65
+ ATTRIBUTE_TYPES = {
66
+ id: Field::String,
67
+ title: Field::String,
68
+ contributors: Field::LazyHasMany.with_options(
69
+ action: 'admin_form_contributors_data_path', result_limit: 10
70
+ ),
71
+ created_at: Field::DateTime,
72
+ updated_at: Field::DateTime
73
+ }.freeze
74
+
75
+ # ...
76
+ end
77
+ ```
78
+ i.e `result_limit` attribute maximum result value the field will post to action endpoint with `search` paramter
79
+
80
+ ## Contributing
81
+
82
+ 1. Fork it ( https://github.com/Aftab-Akram/administrate-field-lazy_has_many )
83
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
84
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
85
+ 4. Push to the branch (`git push origin my-new-feature`)
86
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,29 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'administrate/field/lazy_has_many/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'administrate-field-lazy_has_many'
7
+ spec.version = Administrate::Field::LazyHasManyVersion::VERSION
8
+ spec.authors = ['Aftab Akram']
9
+ spec.email = ['aftabakram04@gmail.com']
10
+
11
+ spec.summary = 'A has many to-like field that lazily loads candidates from a custom endpoint.'
12
+ spec.homepage = 'https://github.com/Aftab-Akram/administrate-field-lazy_has_many'
13
+ spec.license = 'MIT'
14
+
15
+ # Specify which files should be added to the gem when it is released.
16
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
17
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ end
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_development_dependency 'administrate', '>= 0.11.0'
25
+ spec.add_development_dependency 'bundler', '~> 2.0'
26
+ spec.add_development_dependency 'minitest', '~> 5.0'
27
+ spec.add_development_dependency 'rails'
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ end
@@ -0,0 +1,4 @@
1
+ /*
2
+ *= require_self
3
+ *= require_tree .
4
+ */
@@ -0,0 +1,26 @@
1
+ .selectize-control::before{
2
+ -moz-transition: opacity 0.2s;
3
+ -webkit-transition: opacity 0.2s;
4
+ transition: opacity 0.2s;
5
+ content: " ";
6
+ z-index: 2;
7
+ position: absolute;
8
+ display: block;
9
+ top: 50%;
10
+ right: 34px;
11
+ width: 16px;
12
+ height: 16px;
13
+ margin: -8px 0 0 0;
14
+ border: 10px solid #f3f3f3;
15
+ border-top: 10px solid #5e5858;
16
+ border-radius: 50%;
17
+ opacity: 0;
18
+ animation: spin 2s linear infinite;
19
+ }
20
+ .selectize-control.loading::before{
21
+ opacity: 0.4;
22
+ }
23
+ @keyframes spin {
24
+ 0% { transform: rotate(0deg); }
25
+ 100% { transform: rotate(360deg); }
26
+ }
@@ -0,0 +1,35 @@
1
+ <div class="field-unit__label">
2
+ <%= f.label field.attribute, for: "#{f.object_name}_#{field.attribute_key}" %>
3
+ </div>
4
+ <div class="field-unit__field">
5
+ <%= f.select(field.attribute_key, nil, {}, multiple: true) do %>
6
+ <%= options_for_select(field.associated_resource_options, field.selected_options) %>
7
+ <% end %>
8
+ </div>
9
+
10
+ <script>
11
+ $(document).ready(function() {
12
+ let xhr;
13
+ let select_filed = $("#<%= field.custom_attribute_id%>").selectize({
14
+ load: function (query, callback) {
15
+ if (!query.length) return callback();
16
+ $.ajax({
17
+ url: "<%= field.action%>",
18
+ type: "GET",
19
+ dataType: "json",
20
+ data: {
21
+ search: query,
22
+ result_limit: "<%= field.result_limit%>"
23
+ },
24
+ error: function () {
25
+ callback();
26
+ },
27
+ success: function (res) {
28
+ callback(res);
29
+ },
30
+ });
31
+ },
32
+ });
33
+ });
34
+ </script>
35
+
@@ -0,0 +1,13 @@
1
+ <%#
2
+ # HasMany Index Partial
3
+ This partial renders a has_many relationship,
4
+ to be displayed on a resource's index page.
5
+ By default, the relationship is rendered
6
+ as a count of how many objects are associated through the relationship.
7
+ ## Local variables:
8
+ - `field`:
9
+ An instance of [Administrate::Field::HasMany][1].
10
+ A wrapper around the has_many relationship pulled from the database.
11
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/HasMany
12
+ %>
13
+ <%= pluralize(field.data.size, field.attribute.to_s.humanize.downcase.singularize) %>
@@ -0,0 +1,31 @@
1
+ <%#
2
+ # HasMany Show Partial
3
+ This partial renders a has_many relationship,
4
+ to be displayed on a resource's show page.
5
+ By default, the relationship is rendered
6
+ as a table of the first few associated resources.
7
+ The columns of the table are taken
8
+ from the associated resource class's dashboard.
9
+ ## Local variables:
10
+ - `field`:
11
+ An instance of [Administrate::Field::HasMany][1].
12
+ Contains methods to help display a table of associated resources.
13
+ [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/HasMany
14
+ %>
15
+ <% if field.resources.any? %>
16
+ <% order = field.order_from_params(params.fetch(field.name, {})) %>
17
+ <% page_number = params.fetch(field.name, {}).fetch(:page, nil) %>
18
+ <%= render(
19
+ "collection",
20
+ collection_presenter: field.associated_collection(order),
21
+ collection_field_name: field.name,
22
+ page: page,
23
+ resources: field.resources(page_number, order),
24
+ table_title: field.name,
25
+ ) %>
26
+ <% if field.more_than_limit? %>
27
+ <%= paginate field.resources(page_number), param_name: "#{field.name}[page]" %>
28
+ <% end %>
29
+ <% else %>
30
+ <%= t("administrate.fields.has_many.none", default: "–") %>
31
+ <% end %>
@@ -0,0 +1,7 @@
1
+ module Administrate
2
+ module Field
3
+ module LazyHasManyVersion
4
+ VERSION = '0.1.0'.freeze
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,45 @@
1
+ require 'administrate/field/has_many'
2
+ require 'administrate/field/lazy_has_many/version'
3
+ require 'rails/engine'
4
+ require 'administrate/engine'
5
+
6
+ module Administrate
7
+ module Field
8
+ class LazyHasMany < Administrate::Field::HasMany
9
+ include LazyHasManyVersion
10
+
11
+ class Engine < ::Rails::Engine
12
+ Administrate::Engine.add_stylesheet 'administrate-field-lazy_belongs_to/application'
13
+
14
+ isolate_namespace Administrate
15
+ end
16
+
17
+ def candidate_resources
18
+ if options.key?(:includes)
19
+ includes = options.fetch(:includes)
20
+ associated_class.includes(*includes).where(id: data.map(&:id))
21
+ else
22
+ associated_class.where(id: data.map(&:id))
23
+ end
24
+ end
25
+
26
+ def custom_attribute_id
27
+ "#{resource.class.name.underscore}_#{attribute_key}"
28
+ end
29
+
30
+ def to_s
31
+ data.map { |v| display_candidate_resource(v) }
32
+ end
33
+
34
+ def action
35
+ raise StandardError.new 'action is missing' if options[:action].blank?
36
+
37
+ Rails.application.routes.url_helpers.send(options[:action])
38
+ end
39
+
40
+ def result_limit
41
+ options[:result_limit] || 10
42
+ end
43
+ end
44
+ end
45
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: administrate-field-lazy_has_many
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Aftab Akram
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-10-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: administrate
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.11.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.11.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ description:
84
+ email:
85
+ - aftabakram04@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitattributes"
91
+ - ".gitignore"
92
+ - CHANGELOG.md
93
+ - Gemfile
94
+ - LICENSE
95
+ - README.md
96
+ - Rakefile
97
+ - administrate-field-lazy_has_many.gemspec
98
+ - app/assets/stylesheets/administrate-field-lazy_has_many/application.css
99
+ - app/assets/stylesheets/administrate-field-lazy_has_many/components/lazy_has_many.css
100
+ - app/views/fields/lazy_belongs_to/_form.html.erb
101
+ - app/views/fields/lazy_belongs_to/_index.html.erb
102
+ - app/views/fields/lazy_belongs_to/_show.html.erb
103
+ - lib/administrate/field/lazy_has_many.rb
104
+ - lib/administrate/field/lazy_has_many/version.rb
105
+ homepage: https://github.com/Aftab-Akram/administrate-field-lazy_has_many
106
+ licenses:
107
+ - MIT
108
+ metadata: {}
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubygems_version: 3.1.4
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: A has many to-like field that lazily loads candidates from a custom endpoint.
128
+ test_files: []