adminterface 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +19 -109
  3. data/README.md +33 -27
  4. data/Rakefile +1 -1
  5. data/app/assets/stylesheets/adminterface/components/_form.scss +1 -0
  6. data/app/assets/stylesheets/adminterface/mixins/_utilities.scss +4 -0
  7. data/app/assets/stylesheets/adminterface/vendors/bootstrap/_all.scss +1 -0
  8. data/app/assets/stylesheets/adminterface/vendors/bootstrap/components/_breadcrumb.scss +1 -0
  9. data/app/assets/stylesheets/adminterface/vendors/flatpickr/{main.scss → _main.scss} +6 -0
  10. data/app/javascript/adminterface/initializers/header_toggler.js +1 -1
  11. data/app/javascript/adminterface/initializers/plugins/flatpickr.js +1 -1
  12. data/app/javascript/adminterface/initializers/plugins/input_counter.js +1 -1
  13. data/app/javascript/adminterface/initializers/plugins/password_visibility.js +1 -1
  14. data/app/javascript/adminterface/initializers/plugins/tom_select.js +1 -1
  15. data/app/javascript/adminterface/lib/__tests__/checkbox_toggler.html +5 -0
  16. data/app/javascript/adminterface/lib/__tests__/checkbox_toggler.spec.js +110 -0
  17. data/app/javascript/adminterface/lib/__tests__/detached_dropdown.spec.js +69 -70
  18. data/app/javascript/adminterface/lib/__tests__/filters.spec.js +0 -1
  19. data/app/javascript/adminterface/lib/__tests__/has_many.html +14 -0
  20. data/app/javascript/adminterface/lib/__tests__/has_many.spec.js +224 -0
  21. data/app/javascript/adminterface/lib/__tests__/header_toggler.html +2 -0
  22. data/app/javascript/adminterface/lib/__tests__/header_toggler.spec.js +212 -0
  23. data/app/javascript/adminterface/lib/__tests__/per_page.spec.js +75 -0
  24. data/app/javascript/adminterface/lib/__tests__/utils.spec.js +0 -1
  25. data/app/javascript/adminterface/lib/has_many.js +41 -38
  26. data/app/javascript/adminterface/lib/header_toggler.js +10 -8
  27. data/app/views/layouts/active_admin_logged_out.html.erb +1 -1
  28. data/lib/adminterface/configs.rb +5 -1
  29. data/lib/adminterface/engine.rb +0 -7
  30. data/lib/adminterface/extensions/base_controller.rb +16 -12
  31. data/lib/adminterface/extensions/namespace_settings.rb +3 -0
  32. data/lib/adminterface/extensions/view_helpers/alert_helper.rb +3 -1
  33. data/lib/adminterface/extensions/views/components/dropdown_menu.rb +4 -1
  34. data/lib/adminterface/extensions/views/components/menu_item.rb +8 -3
  35. data/lib/adminterface/extensions/views/components/tabs.rb +38 -13
  36. data/lib/adminterface/extensions/views/header.rb +2 -1
  37. data/lib/adminterface/extensions/views/pages/base.rb +4 -1
  38. data/lib/adminterface/initializers/configurations.rb +1 -1
  39. data/lib/adminterface/version.rb +1 -1
  40. data/lib/adminterface.rb +0 -31
  41. data/lib/generators/adminterface/comments/comments_generator.rb +4 -0
  42. data/lib/generators/adminterface/configs/configs_generator.rb +2 -2
  43. data/lib/generators/adminterface/install/install_generator.rb +21 -23
  44. data/lib/generators/adminterface/views/views_generator.rb +2 -2
  45. data/lib/generators/adminterface/webpacker/webpacker_generator.rb +20 -6
  46. metadata +16 -14
  47. data/lib/adminterface/encryption/encryptor.rb +0 -26
  48. data/lib/adminterface/license.rb +0 -18
  49. data/lib/adminterface/licensing/base.rb +0 -99
  50. data/lib/adminterface/licensing/commercial.rb +0 -7
  51. data/lib/adminterface/licensing/notice.rb +0 -54
  52. data/lib/adminterface/licensing/personal.rb +0 -13
  53. data/lib/adminterface/public.pem +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4069cfffd19de3ada098678538e0e7ca4f9a840c8477de55fe3612cd6f541572
4
- data.tar.gz: 7454d611f8fd759b502577cd30f1a00ee7f7c6587b2361155998ef1c2e29aff7
3
+ metadata.gz: 18beaba0b474654bab684cc576d19be2c8a7d4c1c956733196fd428ff127381c
4
+ data.tar.gz: 5fa18f21332acb4d428670e70923fdab7880172bfedcce2faf4f1a742b6426a0
5
5
  SHA512:
6
- metadata.gz: d04bd12439c118daedfb64958cdcf0a3a24a077331147bc98376ed0a8df5de9eada6dadb7de0eb066690a2d979c0277a357b42cead3ccf2b4a7e9a4c81bb5972
7
- data.tar.gz: dc004f3881b891829f647c813ec8025459a76be580276b9bcb54ff5eafcd91a35324169b099b0ffb1eb588ea4f34820d41621027bcdff5f3e7509696c81d02f1
6
+ metadata.gz: 9c48cbd82014ac58317f0d8a6c6d70cc2c05b24ff977deccfe4fe0cd23d42680e7ae5c7d009a1b27b5eab08f28a7123e087522fd608874a41e64e766e77ebfb7
7
+ data.tar.gz: 86f4704e4c64c1f62a66e70c4924183f558bf1f4f84550e94a48d04df9598f23e589764dd330cbdf7d029d007caa7d56f51b7dee7c263cf5c355eb72d491a42b
data/LICENSE.md CHANGED
@@ -1,109 +1,19 @@
1
- # Terms of Service
2
- This license is a legal agreement between you and CMDBrew Studio Inc. for the use of Active Admin Bootstrap (the “Software”). By downloading any Active Admin Bootstrap files, add-ons, or resources, you agree to be bound by the terms and conditions of this license. CMDBrew Studio Inc. reserves the right to alter this agreement at any time, for any reason, without notice.
3
-
4
- ## Definitions
5
- - **"Effective Date"** means the date and time you first download, copy, install, access, deploy or otherwise make use of the Software.
6
-
7
- - **"Entity"** means a sole proprietorship, corporation, partnership, joint venture, limited-liability company, governmental authority or agency, unincorporated organization, trust, or other legally-recognized association of two or more individuals and/or Entities.
8
-
9
- - **"Intellectual Property Rights"** means all rights in and to U.S., Canada, and/or foreign (a) copyrights or works of authorship (whether copyrightable or not), including computer programs and rights in and to data and databases, (b) trademarks, service marks, trade dress, trade names, logos, corporate names, or domain names, or other similar designations of source or origin, together with the goodwill symbolized by any of the foregoing, (c) patents, patent disclosures, or inventions (whether patentable or not), (d) trade secrets, know-how, or other confidential information, and (e) all other intellectual property rights, in each case whether registered or unregistered, and including all registrations and applications for, and renewals or extensions of, such rights, and all similar or equivalent rights or forms of protection in any part of the world.
10
-
11
- - **"Law"** means any statute, law, ordinance, regulation, rule, code, order, constitution, treaty, common law, judgment, decree, or other requirement of any federal, state, provincial, local, or foreign government or political subdivision thereof, or any court, arbitrator, or tribunal of competent jurisdiction.
12
-
13
- - **"Personal Purpose"** Personal use for research, experiment, and testing for the benefit of public
14
- knowledge, personal study, private entertainment, hobby projects, amateur
15
- pursuits, or religious observance, without any anticipated commercial
16
- application, doesn't count as use for a commercial purpose.
17
-
18
- - **"Non-Personal Purpose"** Use for purposes that are outside of Personal Purpose.
19
-
20
- - **"Repository"** means the GitHub repository located at https://github.com/CMDBrew/adminterface
21
-
22
- - **"Software"** means source code, object code, API's, and all works incorporated into each of the foregoing.
23
-
24
- - **"Territory"** means all countries not subject to U.S. and Canada export restrictions.
25
-
26
- - **"Third-Party Materials"** means items not owned by us, which may include Software (such as open-source software or third-party add-ons or extensions), content, data, information, or other materials.
27
-
28
- - **"Update"** means any change, patch, fix, upgrade, adaptation, alteration, translation, correction, revision, supplement, enhancement, improvement, or other modification of the Software that we may, in our sole discretion, release from time to time. An Update may consist, among other things, of modifications to the Software's features, functionality, or interfaces.
29
-
30
- ## Permitted Use
31
- One single project license grants the right to use the Software on one domain and unlimited development sites. Each additional domain using the Software requires an additional purchased license. Contact contact@cmdbrew.com for other types of project licenses.
32
-
33
- Provided that you remain at all times in compliance with the terms and conditions of this Agreement, we hereby grant to you a limited, non-exclusive, non-sub-licensable, non-transferable license to use the Software within the Territory for any purpose not prohibited by this Agreement or applicable Law (the "License"). All rights not expressly granted herein are reserved. You acknowledge that the License is adequate consideration for all your responsibilities, representations, and warranties hereunder.
34
-
35
- **If you're developing a product for a client, you should purchase a license on behalf of the customer and transfer ownership of the license to them.**
36
-
37
- ## Restrictions
38
- Unless you have been granted prior, written consent from CMDBrew Studio Inc., you may not:
39
- * Reproduce, distribute, or transfer the Software, or portions thereof, to any third party.
40
- * Sell, rent, lease, assign, or sublet the Software or portions thereof.
41
- * Bypass, block, or disable the Software's licensing-verification mechanisms.
42
- * Grant rights to any other person.
43
- * Dispute our ownership of the Software or any Intellectual Property Right therein.
44
- * Use the Software in violation of any U.S., Canada, and international law or regulation.
45
- * Develop or provide a competing product or service.
46
- * Use the Software for any purpose that is to our detriment or commercial disadvantage.
47
-
48
- ## Requirements
49
- You will:
50
-
51
- * Comply with all applicable Laws.
52
- * Promptly notify us if you become aware of any actual or suspected infringement or misuse of the Software or any claim that the Software infringes the rights of any Person.
53
- * Cooperate with and assist us in all reasonable ways to stop or prevent any actual or threatened infringement or misuse of the Software.
54
- * Retain (and not alter or obscure) this Agreement and all trademarks, copyright notices, and other notices of Intellectual Property Rights in connection with the Software; and for any Non-Personal Purpose that you control or operate directly or indirectly, including by way of a contractor or intermediary.
55
- * Notify us of the domain name utilized by the Software and the name and email of the individual(s) or organization that purchased the license.
56
- * Pay the fee set forth in Section "Fees".
57
-
58
- ## Fees and License
59
- Please refer to [Pricing](https://adminterface.io/pricing) for our license fees.
60
-
61
- * **Personal:** Free forever. The Software is free of charge for Personal Purposes.
62
-
63
- * **Commercial:** The software is being used for Non-Personal Purposes. Requires a yearly license subscription fee.
64
-
65
- * **Payment Terms:** The yearly license subscription fee, as paid at time of purchase or license renewal, (the "Subscription") for each domain operating a Non-Personal Purpose app, is due at the time of Licence purchase until your subscription expires.
66
- * All fees are exclusive of taxes. You are responsible for any taxes, duties, or other charges imposed by any governmental authority on amounts paid by you pursuant hereto (except for any taxes imposed on our income).
67
- * Payment must be made in U.S. dollars by Credit Card.
68
- * Interest will accrue on any past-due amount at the rate of 1.8% per month, compounded monthly, or the highest rate permitted by applicable Law, whichever is less. You will reimburse us immediately for all costs we incur in relation to any overdue amount, including attorney fees and collection-agency fees, whether or not a formal complaint is filed, and no notice of default is required.
69
- * In the event that any amount becomes overdue, we may, in our sole discretion, and in addition to any other remedy available at law, in equity, or hereunder: (i) suspend or revoke your License, (ii) withhold new licenses, or (iii) terminate this Agreement. You will pay all amounts due hereunder in full, without any setoff, deduction, or withholding for any reason, except as may be permitted by applicable Law. No refunds will be granted or paid.
70
-
71
- ## Making Copies
72
- You may make copies of the Software for back-up purposes, provided that you reproduce the Software in its original form and with all proprietary notices on the back-up copy.
73
-
74
- ## Software Modification
75
- You may alter, modify, or extend the Software for your own use, or commission a third-party to perform modifications for you, but you may not resell, redistribute or transfer the modified or derivative version without prior written consent from CMDBrew Studio Inc.. Components from the Software may not be extracted and used in other programs without prior written consent from CMDBrew Studio Inc..
76
-
77
- ## Technical Support
78
- CMDBrew Studio Inc. does not provide direct phone support at this time. No representations or guarantees are made regarding the response time in which e-mail support questions are answered, but we will do our best to respond quickly.
79
-
80
- ## Open-Source Components
81
- The Software makes use of certain [Open-Source Components or other licensing](https://adminterface.io/docs/start/dependencies/) that does not restrict commercial use. Your use of Open-Source Components, including those on which the Software relies, is subject to the terms and conditions of the applicable open-source licenses. A copy of each license can be found at https://choosealicense.com/licenses/.
82
-
83
- ## Ownership
84
- CMDBrew Studio Inc. is the sole and exclusive owner of all right, title, and interest in and to the Software, all Updates thereto, all Official Extensions based thereon, and all Intellectual Property Rights in each of the foregoing, subject only to the rights of third parties in Open-Source Components and the License granted hereunder. You acknowledge that you have no ownership interest in the Software and that, except for the License granted hereunder, nothing herein or elsewhere grants to you or any third party (by implication, waiver, estoppel or otherwise) any right, title, or interest (including any Intellectual Property Right) in or to the Software or any portion thereof.
85
-
86
- ## Contributions
87
- If you make a Contribution to the Software, you hereby automatically, immediately, unconditionally, and irrevocably assign the entirety of such Contribution to CMDBrew Studio Inc. for no additional consideration beyond the License granted hereunder. Similarly, in the event that you acquire (by any means) or have (at any time) any right, title, or interest (including any Intellectual Property Right) in or to the Software beyond the License granted hereunder, you hereby automatically, immediately, unconditionally, and irrevocably assign the entirety of such right, title, and interest to CMDBrew Studio Inc. for no additional consideration beyond the License granted hereunder. In the event of any assignment by you to us under this Section "Contributions", you hereby irrevocably waive, to the extent permitted by applicable law, any and all claims you may now or hereafter have in any jurisdiction to all rights of paternity, integrity, disclosure, and withdrawal and any other rights (which may be known as "moral rights") with respect to the subject matter of such assignment. For further information regarding how to contribute, please visit the the Software Repository.
88
-
89
- ## Refunds
90
- CMDBrew Studio Inc. offers limited refunds on software within 14 days of purchase. Contact contact@cmdbrew.com for assistance.
91
-
92
- ## Indemnity
93
- You agree to indemnify and hold harmless CMDBrew Studio Inc. for any third-party claims, actions or suits, as well as any related expenses, liabilities, damages, settlements or fees arising from your use or misuse of the Software, or a violation of any terms of this license.
94
-
95
- ## Term and Termination
96
- * **Term:** This Agreement takes effect as of the Effective Date and continues in effect until terminated as set forth below in Section "Term and Termination".
97
-
98
- * **Termination:** This Agreement may be terminated:
99
- * By us, at anytime, effective on written notice to you, if we, in our sole discretion, believe that you have breached this Agreement;
100
-
101
- * By you, at any time, effective immediately, when you cease to use the Software and permanently delete all copies;
102
-
103
- * Automatically, effective immediately and without notice, if you are a company, corporation, or other legal entity and you (A) are dissolved or liquidated or take any corporate action for such purpose; (B) become insolvent or are generally unable to pay your debts as they become due; (C) become the subject of any voluntary or involuntary bankruptcy proceeding under any domestic or foreign bankruptcy or insolvency Law; (D) make or seek to make a general assignment for the benefit of creditors; or (E) apply for, or consent to, the appointment of a trustee, receiver or custodian for a substantial part of your property.
104
-
105
- ## Disclaimer of Warranty
106
- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF QUALITY, PERFORMANCE, NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. FURTHER, CMDBREW STUDIO INC. DOES NOT WARRANT THAT THE SOFTWARE OR ANY RELATED SERVICE WILL ALWAYS BE AVAILABLE.
107
-
108
- ## Limitations of Liability
109
- YOU ASSUME ALL RISK ASSOCIATED WITH THE INSTALLATION AND USE OF THE SOFTWARE. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS OF THE SOFTWARE BE LIABLE FOR CLAIMS, DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE. LICENSE HOLDERS ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USE AND ASSUME ALL RISKS ASSOCIATED WITH ITS USE, INCLUDING BUT NOT LIMITED TO THE RISKS OF PROGRAM ERRORS, DAMAGE TO EQUIPMENT, LOSS OF DATA OR SOFTWARE PROGRAMS, OR UNAVAILABILITY OR INTERRUPTION OF OPERATIONS.
1
+ Copyright (c) 2021 I-Lung Lee, Richard Wang, Adminterface.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
19
+ OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,18 +1,39 @@
1
+ > ## ⛔️ DEPRECATED: THIS GEM IS NO LONGER BEING MAINTAINED
2
+ > Due to personal reasons, we can no longer continue to maintain this gem. As a result, we are no longer accepting or merging pull requests.
3
+ >
4
+ > To help with the transition, we've changed the license to MIT and removed the license verification for commercial uses. For alternatives, please check out other excellent solutions listed in the [ActiveAdmin Wiki](https://github.com/activeadmin/activeadmin/wiki).
5
+ >
6
+ > Thank you to all who contributed and who used Adminterface in their projects. We couldn't have made it this far without your support.
7
+ >
8
+ > Until next time.
9
+ >
10
+ > — I-Lung, Richard Wang, and the Adminterface team
11
+
1
12
  # Adminterface <!-- omit in toc -->
2
13
  [![CI](https://github.com/CMDBrew/adminterface/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/CMDBrew/adminterface/actions/workflows/ci.yml)
14
+ [![Maintainability](https://api.codeclimate.com/v1/badges/4dbedfdf21a2d675d2ca/maintainability)](https://codeclimate.com/github/CMDBrew/adminterface/maintainability)
15
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/4dbedfdf21a2d675d2ca/test_coverage)](https://codeclimate.com/github/CMDBrew/adminterface/test_coverage)
16
+ [![gem](https://img.shields.io/gem/v/adminterface?color=%23E9573F&label=rubygems.org)](https://rubygems.org/gems/adminterface)
17
+ [![npm](https://img.shields.io/npm/v/@cmdbrew/adminterface?color=%230273B4&label=npmjs.com)](https://www.npmjs.com/package/@cmdbrew/adminterface)
3
18
 
4
- An add-on that brings Bootstrap 5 and other goodies into ActiveAdmin.
19
+ A gem that brings Bootstrap 5, advanced customizability, and other goodies into ActiveAdmin
5
20
 
6
21
  [![](preview.jpg)](https://adminterface.io)
7
22
 
8
23
  ## Dependencies
9
- - Rails >= 6.0
10
- - Ruby >= 2.7
11
- - ActiveAdmin ~> 2.9
12
- - Bootstrap ~> 5
13
- - Webpacker >= 5.0
24
+ - [Ruby](https://www.ruby-lang.org/en/) >= 2.7
25
+ - [Rails](http://rubyonrails.org/) >= 6.0
26
+ - [ActiveAdmin](https://github.com/activeadmin/activeadmin) ~> 2.9
27
+ - [Bootstrap](https://getbootstrap.com/) ~> 5.1.3
28
+ - [Webpacker](https://github.com/rails/webpacker) ~> 5.0
29
+
30
+ ## Get Started
31
+ - [Documentation](https://adminterface.io/docs/intro)
32
+ - [Demo](https://demo.adminterface.io)
33
+ - [Issue tracker](https://github.com/CMDBrew/adminterface/issues)
34
+ - [Discussions and feature requests](https://github.com/CMDBrew/adminterface/discussions)
14
35
 
15
- ## Quick Start
36
+ ## Installation
16
37
  1. Add the following to your application's Gemfile:
17
38
  ```ruby
18
39
  gem "adminterface"
@@ -26,6 +47,10 @@ An add-on that brings Bootstrap 5 and other goodies into ActiveAdmin.
26
47
  $ rails g active_admin:install --use_webpacker
27
48
  ```
28
49
  4. Install Adminterface
50
+
51
+ > This command will ask for permissions to overwrite files generated by ActiveAdmin. Make sure to review the files carefully and accept them.
52
+ > We recommend you commit your files before running this command to ensure you are aware of the changes made.
53
+
29
54
  ```bash
30
55
  $ rails g adminterface:install
31
56
  ```
@@ -35,27 +60,8 @@ An add-on that brings Bootstrap 5 and other goodies into ActiveAdmin.
35
60
  $ rails server
36
61
  ```
37
62
 
38
- ## Documentation
39
- Check our [website](https://adminterface.io) to find in-depth documentation for everything that Adminterface offers.
40
-
41
63
  ## Contributing
42
64
  See [CONTRIBUTING.md](CONTRIBUTING.md).
43
65
 
44
66
  ## License
45
- Adminterface is free for personal and non-commercial use and with a yearly subscription for commercial purposes. See [our Terms of Service in full text](LICENSE.md) for more information.
46
-
47
- ### For Commerical License
48
- Get a license at https://adminterface.io/pricing, then create and add the `license_key` into the following file in your project:
49
- ```ruby
50
- # config/initializers/adminterface.rb
51
- Adminterface.setup do |config|
52
- config.license_key = "**********************"
53
-
54
- ## Use Rails credentials:
55
- ## doc: https://edgeguides.rubyonrails.org/security.html#custom-credentials
56
- # config.license_key = Rails.application.credentials.adminterface[:license_key]
57
-
58
- ## Or, use environment variables:
59
- # config.license_key = ENV["ADMINTERFACE_LICENSE_KEY"]
60
- end
61
- ```
67
+ The gem is available as open source under the terms of the [MIT License](LICENSE.md).
data/Rakefile CHANGED
@@ -18,7 +18,7 @@ task :prepare_assets do
18
18
  system "rm -rf test/dummy/public/packs"
19
19
  system "rm -rf test/dummy/public/packs-test"
20
20
  system "yarn install --frozen-lockfile"
21
- system "(cd test/dummy && yarn install --frozen-lockfile)"
21
+ system "cd test/dummy && yarn install --frozen-lockfile"
22
22
  end
23
23
 
24
24
  # Generate dependency licenses
@@ -119,6 +119,7 @@
119
119
  -webkit-box-align: end;
120
120
  -webkit-box-direction: reverse;
121
121
  flex-direction: row-reverse;
122
+ justify-content: flex-start;
122
123
  }
123
124
 
124
125
  li {
@@ -37,3 +37,7 @@
37
37
  -webkit-box-shadow: #{$value};
38
38
  -moz-box-shadow: #{$value};
39
39
  }
40
+
41
+ @mixin lang-dir-rtl {
42
+ @at-root { html[dir="rtl"] & { @content; } }
43
+ }
@@ -1,3 +1,4 @@
1
+ @import './components/breadcrumb';
1
2
  @import './components/buttons';
2
3
  @import './components/dropdowns';
3
4
  @import './components/form/labels';
@@ -0,0 +1 @@
1
+ ol.breadcrumb { padding-left: 0; }
@@ -6,6 +6,12 @@
6
6
  .flatpickr-next-month {
7
7
  padding: 5px 10px;
8
8
 
9
+ svg {
10
+ @include lang-dir-rtl {
11
+ @include transform(rotate(180deg));
12
+ }
13
+ }
14
+
9
15
  &:hover svg {
10
16
  fill: $flatpickr-ctrl-hover-bg;
11
17
  }
@@ -3,7 +3,7 @@ import HeaderToggler from '../lib/header_toggler'
3
3
  document.addEventListener('DOMContentLoaded', () => {
4
4
  const togglerTriggerList = [].slice.call(document.querySelectorAll('[data-aa-header-toggler]'))
5
5
  togglerTriggerList.map((el) => {
6
- const options = JSON.parse(el.dataset.aaHeaderToggler || {})
6
+ const options = JSON.parse(el.dataset.aaHeaderToggler || '{}')
7
7
 
8
8
  return new HeaderToggler(el, options)
9
9
  })
@@ -5,7 +5,7 @@ const initFlatpickr = (element) => {
5
5
  const flatpickrTriggerList = [].slice.call(element.querySelectorAll('[data-aa-flatpickr]'))
6
6
 
7
7
  flatpickrTriggerList.map((el) => {
8
- const options = JSON.parse(el.dataset.aaFlatpickr || {})
8
+ const options = JSON.parse(el.dataset.aaFlatpickr || '{}')
9
9
  const instance = flatpickr(el, options)
10
10
 
11
11
  adminterface.addObserver(el, instance, 'flatpickr')
@@ -4,7 +4,7 @@ const initInputCounter = function (element) {
4
4
  const inputCounterTriggerList = [].slice.call(element.querySelectorAll('[data-aa-input-counter]'))
5
5
 
6
6
  inputCounterTriggerList.map((el) => {
7
- const options = JSON.parse(el.dataset.aaInputCounter || {})
7
+ const options = JSON.parse(el.dataset.aaInputCounter || '{}')
8
8
 
9
9
  return new InputCounter(el, options)
10
10
  })
@@ -4,7 +4,7 @@ import initBootstrap from '../bootstrap'
4
4
  const initPasswordVisibility = function (element) {
5
5
  const visibilityTriggerList = [].slice.call(element.querySelectorAll('[data-aa-password-visibility]'))
6
6
  visibilityTriggerList.map((el) => {
7
- const options = JSON.parse(el.dataset.aaPasswordVisibility || {})
7
+ const options = JSON.parse(el.dataset.aaPasswordVisibility || '{}')
8
8
  const instance = new PasswordVisibility(el, options)
9
9
 
10
10
  initBootstrap(instance.eventTarget)
@@ -5,7 +5,7 @@ const initTomSelect = function (element) {
5
5
  const tomSelectTriggerList = [].slice.call(element.querySelectorAll('[data-aa-tom-select]'))
6
6
 
7
7
  tomSelectTriggerList.map((el) => {
8
- const options = JSON.parse(el.dataset.aaTomSelect || {})
8
+ const options = JSON.parse(el.dataset.aaTomSelect || '{}')
9
9
  const instance = new TomSelect(el, options)
10
10
 
11
11
  adminterface.addObserver(el, instance, instance.constructor.name)
@@ -0,0 +1,5 @@
1
+ <div id="find-me">
2
+ <input type="checkbox" class="toggle_all" checked>
3
+ <input type="checkbox" class="toggle_one" checked>
4
+ <input type="checkbox" class="toggle_two" checked>
5
+ </div>
@@ -0,0 +1,110 @@
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import CheckboxTogglerClass from '../checkbox_toggler'
4
+
5
+ describe('CheckboxToggler', () => {
6
+ const html = fs.readFileSync(path.resolve(__dirname, './checkbox_toggler.html'))
7
+ const container = '#find-me'
8
+ const options = 'options'
9
+
10
+ beforeEach(() => {
11
+ document.documentElement.innerHTML = html.toString()
12
+ })
13
+
14
+ afterEach(() => {
15
+ jest.restoreAllMocks()
16
+ })
17
+
18
+ test('constructor initiates correctly', () => {
19
+ const spyOnInit = jest.spyOn(CheckboxTogglerClass.prototype, '_init')
20
+ const spyOnBind = jest.spyOn(CheckboxTogglerClass.prototype, '_bind')
21
+
22
+ const CheckboxToggler = new CheckboxTogglerClass(container, options)
23
+
24
+ expect(CheckboxToggler.options).toStrictEqual(options)
25
+ expect(CheckboxToggler.container).toStrictEqual(container)
26
+
27
+ expect(spyOnInit).toHaveBeenCalledTimes(1)
28
+ expect(spyOnBind).toHaveBeenCalledTimes(1)
29
+ })
30
+
31
+ test('init throws error if container is null', () => {
32
+ expect(() => { new CheckboxTogglerClass(null, options) }).toThrow( // eslint-disable-line no-new
33
+ 'Container element not found'
34
+ )
35
+ })
36
+
37
+ test('init throws error if toggle checkbox missing', () => {
38
+ const element = document.createElement('div')
39
+ element.id = 'find-me'
40
+ document.documentElement.innerHTML = element.outerHTML
41
+
42
+ expect(() => { new CheckboxTogglerClass(container, options) }).toThrow( // eslint-disable-line no-new
43
+ '"toggle all" checkbox not found'
44
+ )
45
+ })
46
+
47
+ test('init sets $container, $toggleAllCheckbox, $checkboxes', () => {
48
+ const $container = document.querySelector(container)
49
+ const $toggleAllCheckbox = $container.querySelector('.toggle_all')
50
+ const $checkboxes = $container.querySelectorAll('input[type="checkbox"]:not(.toggle_all)')
51
+ const CheckboxToggler = new CheckboxTogglerClass(container, options)
52
+
53
+ expect(CheckboxToggler.$container).toStrictEqual($container)
54
+ expect(CheckboxToggler.$toggleAllCheckbox).toStrictEqual($toggleAllCheckbox)
55
+ expect(CheckboxToggler.$checkboxes).toStrictEqual($checkboxes)
56
+ })
57
+
58
+ test('bind triggers addEventListener', () => {
59
+ const CheckboxToggler = new CheckboxTogglerClass(container, options)
60
+ const spyOnCheckboxesAddEvent = jest.spyOn(
61
+ CheckboxToggler.$checkboxes[0], 'addEventListener'
62
+ )
63
+ const spyOnToggleAllCheckboxAddEvent = jest.spyOn(
64
+ CheckboxToggler.$toggleAllCheckbox, 'addEventListener'
65
+ )
66
+
67
+ CheckboxToggler._bind()
68
+
69
+ expect(spyOnCheckboxesAddEvent).toHaveBeenCalledTimes(1)
70
+ expect(spyOnCheckboxesAddEvent).toHaveBeenCalledWith(
71
+ 'change',
72
+ expect.any(Function)
73
+ )
74
+
75
+ expect(spyOnToggleAllCheckboxAddEvent).toHaveBeenCalledTimes(1)
76
+ expect(spyOnToggleAllCheckboxAddEvent).toHaveBeenCalledWith(
77
+ 'change',
78
+ expect.any(Function)
79
+ )
80
+ })
81
+
82
+ test('didChangeCheckbox sets toggleAllCheckbox checked to true when all checked', () => {
83
+ const CheckboxToggler = new CheckboxTogglerClass(container, options)
84
+ CheckboxToggler._didChangeCheckbox()
85
+
86
+ expect(CheckboxToggler.$toggleAllCheckbox.checked).toBeTruthy()
87
+ expect(CheckboxToggler.$toggleAllCheckbox.indeterminate).toBeFalsy()
88
+ })
89
+
90
+ test('didChangeCheckbox sets toggleAllCheckbox checked to false when some checked', () => {
91
+ const inputElementToggleTwo = document.querySelector('input.toggle_two')
92
+ inputElementToggleTwo.checked = false
93
+
94
+ const CheckboxToggler = new CheckboxTogglerClass(container, options)
95
+ CheckboxToggler._didChangeCheckbox()
96
+
97
+ expect(CheckboxToggler.$toggleAllCheckbox.checked).toBeFalsy()
98
+ expect(CheckboxToggler.$toggleAllCheckbox.indeterminate).toBeTruthy()
99
+ })
100
+
101
+ test('didChangeToggleAllCheckbox', () => {
102
+ const CheckboxToggler = new CheckboxTogglerClass(container, options)
103
+ const setting = CheckboxToggler._didChangeToggleAllCheckbox()
104
+
105
+ expect(setting).toBeTruthy()
106
+ CheckboxToggler.$checkboxes.forEach(el => {
107
+ expect(el.checked).toStrictEqual(setting)
108
+ })
109
+ })
110
+ })
@@ -1,70 +1,69 @@
1
- /* eslint-env jest */
2
- import DetachedDropdownClass from '../detached_dropdown'
3
-
4
- describe('DetachedDropdown', () => {
5
- const element = document.createElement('div')
6
- const options = {
7
- title: '.title-menu'
8
- }
9
-
10
- beforeEach(() => {
11
- global.adminterface = {
12
- addObserver: jest.fn()
13
- }
14
- })
15
-
16
- test('constructor initiates properties and call bind correctly', () => {
17
- const spyOnBind = jest.spyOn(DetachedDropdownClass.prototype, '_bind')
18
- spyOnBind.mockImplementation(() => {})
19
- const DetachedDropdown = new DetachedDropdownClass(element, options)
20
-
21
- expect(DetachedDropdown.element).toEqual(element)
22
- expect(DetachedDropdown.options).toEqual({
23
- menu: '.dropdown-menu',
24
- ...options
25
- })
26
- expect(spyOnBind).toHaveBeenCalledTimes(1)
27
- spyOnBind.mockRestore()
28
- })
29
-
30
- test('bind method calls adminterface correctly', () => {
31
- const DetachedDropdown = new DetachedDropdownClass(element, options)
32
-
33
- expect(global.adminterface.addObserver).toHaveBeenCalledWith(
34
- element,
35
- DetachedDropdown,
36
- DetachedDropdown.constructor.name
37
- )
38
- })
39
-
40
- test('bind method add event listener correctly', () => {
41
- const DetachedDropdown = new DetachedDropdownClass(element, options)
42
- const spyOnAddEventListener = jest.spyOn(
43
- DetachedDropdown.element,
44
- 'addEventListener'
45
- )
46
- DetachedDropdown._bind()
47
-
48
- expect(spyOnAddEventListener).toHaveBeenCalledTimes(2)
49
- expect(spyOnAddEventListener.mock.calls).toEqual([
50
- ['show.bs.dropdown', expect.any(Function)],
51
- ['hidden.bs.dropdown', expect.any(Function)]
52
- ])
53
- })
54
-
55
- test('append method calls native WEB API append correctly', () => {
56
- const testDiv = document.createElement('div')
57
- const testP = document.createElement('p')
58
- testDiv.append('Some text', testP)
59
-
60
- const DetachedDropdown = new DetachedDropdownClass(element, options)
61
- const spyOnAppend = jest.spyOn(document.body, 'append')
62
-
63
- DetachedDropdown._append(document.body, testP)
64
-
65
- expect(spyOnAppend).toHaveBeenCalledTimes(1)
66
- expect(spyOnAppend).toHaveBeenCalledWith(
67
- testP.parentElement.removeChild(testP)
68
- )
69
- })
70
- })
1
+ import DetachedDropdownClass from '../detached_dropdown'
2
+
3
+ describe('DetachedDropdown', () => {
4
+ const element = document.createElement('div')
5
+ const options = {
6
+ title: '.title-menu'
7
+ }
8
+
9
+ beforeEach(() => {
10
+ global.adminterface = {
11
+ addObserver: jest.fn()
12
+ }
13
+ })
14
+
15
+ test('constructor initiates properties and call bind correctly', () => {
16
+ const spyOnBind = jest.spyOn(DetachedDropdownClass.prototype, '_bind')
17
+ spyOnBind.mockImplementation(() => {})
18
+ const DetachedDropdown = new DetachedDropdownClass(element, options)
19
+
20
+ expect(DetachedDropdown.element).toEqual(element)
21
+ expect(DetachedDropdown.options).toEqual({
22
+ menu: '.dropdown-menu',
23
+ ...options
24
+ })
25
+ expect(spyOnBind).toHaveBeenCalledTimes(1)
26
+ spyOnBind.mockRestore()
27
+ })
28
+
29
+ test('bind method calls adminterface correctly', () => {
30
+ const DetachedDropdown = new DetachedDropdownClass(element, options)
31
+
32
+ expect(global.adminterface.addObserver).toHaveBeenCalledWith(
33
+ element,
34
+ DetachedDropdown,
35
+ DetachedDropdown.constructor.name
36
+ )
37
+ })
38
+
39
+ test('bind method add event listener correctly', () => {
40
+ const DetachedDropdown = new DetachedDropdownClass(element, options)
41
+ const spyOnAddEventListener = jest.spyOn(
42
+ DetachedDropdown.element,
43
+ 'addEventListener'
44
+ )
45
+ DetachedDropdown._bind()
46
+
47
+ expect(spyOnAddEventListener).toHaveBeenCalledTimes(2)
48
+ expect(spyOnAddEventListener.mock.calls).toEqual([
49
+ ['show.bs.dropdown', expect.any(Function)],
50
+ ['hidden.bs.dropdown', expect.any(Function)]
51
+ ])
52
+ })
53
+
54
+ test('append method calls native WEB API append correctly', () => {
55
+ const testDiv = document.createElement('div')
56
+ const testP = document.createElement('p')
57
+ testDiv.append('Some text', testP)
58
+
59
+ const DetachedDropdown = new DetachedDropdownClass(element, options)
60
+ const spyOnAppend = jest.spyOn(document.body, 'append')
61
+
62
+ DetachedDropdown._append(document.body, testP)
63
+
64
+ expect(spyOnAppend).toHaveBeenCalledTimes(1)
65
+ expect(spyOnAppend).toHaveBeenCalledWith(
66
+ testP.parentElement.removeChild(testP)
67
+ )
68
+ })
69
+ })
@@ -1,4 +1,3 @@
1
- /* eslint-env jest */
2
1
  import Filters from '../filters'
3
2
  import * as utilModule from '../utils'
4
3
 
@@ -0,0 +1,14 @@
1
+ <div data-sortable="address">
2
+ <form class="has-many-list">
3
+ <fieldset class="has_many_fields">
4
+ <input type="checkbox" name="[_destroy]" checked>
5
+ <input type="text" name="[address]" value="Tokyo">
6
+ <a class="button has_many_remove"></a>
7
+ <a
8
+ class="button has_many_add"
9
+ data-html="<div></div>"
10
+ data-placeholder="script"
11
+ ></a>
12
+ </fieldset>
13
+ </form>
14
+ </div>