potassium 6.5.0 → 6.6.0

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/README.md +30 -1
  4. data/docs/CONTRIBUTING.md +2 -2
  5. data/lib/potassium/assets/.circleci/config.yml.erb +11 -1
  6. data/lib/potassium/assets/.eslintrc.json +15 -9
  7. data/lib/potassium/assets/.rubocop.yml +1 -0
  8. data/lib/potassium/assets/Aptfile +5 -0
  9. data/lib/potassium/assets/README.yml +30 -6
  10. data/lib/potassium/assets/active_admin/admin-component.vue +22 -30
  11. data/lib/potassium/assets/app/javascript/{app.spec.js → components/app.spec.ts} +1 -1
  12. data/lib/potassium/assets/app/javascript/components/app.vue +9 -0
  13. data/lib/potassium/assets/app/javascript/types/vue.d.ts +5 -0
  14. data/lib/potassium/assets/app/jobs/shrine_promote_job.rb +14 -0
  15. data/lib/potassium/assets/app/mailers/application_mailer.rb +1 -1
  16. data/lib/potassium/assets/app/mailers/example_mailer.rb +6 -0
  17. data/lib/potassium/assets/app/serializers/base_serializer.rb +3 -0
  18. data/lib/potassium/assets/app/serializers/concerns/image_handling_attributes.rb +20 -0
  19. data/lib/potassium/assets/app/uploaders/cover_image_uploader.rb +52 -0
  20. data/lib/potassium/assets/app/views/example_mailer/example_mail.html.mjml +7 -0
  21. data/lib/potassium/assets/app/views/layouts/default_mail.html.mjml +49 -0
  22. data/lib/potassium/assets/config/initializers/shrine/plugins/image_handling_utilities.rb +143 -0
  23. data/lib/potassium/assets/config/mailer.rb.erb +0 -2
  24. data/lib/potassium/assets/config/shrine.rb +15 -0
  25. data/lib/potassium/assets/config/webpack/rules/css.js +5 -0
  26. data/lib/potassium/assets/config/webpack/rules/index.js +11 -0
  27. data/lib/potassium/assets/config/webpack/rules/jquery.js +11 -0
  28. data/lib/potassium/assets/config/webpack/rules/typescript.js +32 -0
  29. data/lib/potassium/assets/config/webpack/rules/vue.js +19 -0
  30. data/lib/potassium/assets/config/webpack/webpack.config.js +4 -0
  31. data/lib/potassium/assets/public/mails/platanus-logo.png +0 -0
  32. data/lib/potassium/assets/tsconfig.json +31 -0
  33. data/lib/potassium/cli/commands/create.rb +3 -1
  34. data/lib/potassium/cli_options.rb +15 -3
  35. data/lib/potassium/platanus_config.rb +20 -0
  36. data/lib/potassium/recipes/admin.rb +11 -0
  37. data/lib/potassium/recipes/api.rb +6 -85
  38. data/lib/potassium/recipes/coverage.rb +31 -0
  39. data/lib/potassium/recipes/file_storage.rb +50 -0
  40. data/lib/potassium/recipes/front_end.rb +82 -110
  41. data/lib/potassium/recipes/google_tag_manager.rb +1 -1
  42. data/lib/potassium/recipes/mailer.rb +22 -10
  43. data/lib/potassium/recipes/mjml.rb +31 -0
  44. data/lib/potassium/recipes/node.rb +11 -13
  45. data/lib/potassium/recipes/style.rb +9 -2
  46. data/lib/potassium/recipes/vue_admin.rb +38 -8
  47. data/lib/potassium/templates/application.rb +1 -0
  48. data/lib/potassium/version.rb +8 -3
  49. data/spec/features/api_spec.rb +6 -1
  50. data/spec/features/coverage_spec.rb +17 -0
  51. data/spec/features/file_storage_spec.rb +102 -26
  52. data/spec/features/front_end_spec.rb +14 -48
  53. data/spec/features/mailer_spec.rb +79 -33
  54. data/spec/features/mjml_spec.rb +53 -0
  55. data/spec/features/vue_admin_spec.rb +0 -10
  56. data/spec/support/shared_examples.rb +5 -0
  57. metadata +28 -21
  58. data/lib/potassium/assets/active_admin/admin_application.js +0 -14
  59. data/lib/potassium/assets/active_admin/init_activeadmin_vue.rb +0 -10
  60. data/lib/potassium/assets/app/graphql/graphql_controller.rb +0 -55
  61. data/lib/potassium/assets/app/graphql/mutations/login_mutation.rb +0 -23
  62. data/lib/potassium/assets/app/graphql/queries/base_query.rb +0 -4
  63. data/lib/potassium/assets/app/graphql/types/base/base_argument.rb +0 -4
  64. data/lib/potassium/assets/app/graphql/types/base/base_enum.rb +0 -4
  65. data/lib/potassium/assets/app/graphql/types/base/base_field.rb +0 -5
  66. data/lib/potassium/assets/app/graphql/types/base/base_input_object.rb +0 -5
  67. data/lib/potassium/assets/app/graphql/types/base/base_interface.rb +0 -7
  68. data/lib/potassium/assets/app/graphql/types/base/base_object.rb +0 -5
  69. data/lib/potassium/assets/app/graphql/types/base/base_scalar.rb +0 -4
  70. data/lib/potassium/assets/app/graphql/types/base/base_union.rb +0 -4
  71. data/lib/potassium/assets/app/graphql/types/mutation_type.rb +0 -10
  72. data/lib/potassium/assets/app/graphql/types/query_type.rb +0 -13
  73. data/lib/potassium/assets/config/graphql_playground.rb +0 -20
  74. data/spec/features/graphql_spec.rb +0 -71
@@ -1,10 +1,15 @@
1
1
  class Recipes::FrontEnd < Rails::AppBuilder
2
2
  VUE_LOADER_VERSION = Potassium::VUE_LOADER_VERSION
3
+ VUE_VERSION = Potassium::VUE_VERSION
4
+ VUE_TEST_UTILS_VERSION = Potassium::VUE_TEST_UTILS_VERSION
5
+ POSTCSS_VERSION = Potassium::POSTCSS_VERSION
6
+ TAILWINDCSS_VERSION = Potassium::TAILWINDCSS_VERSION
7
+ AUTOPREFIXER_VERSION = Potassium::AUTOPREFIXER_VERSION
8
+ VUE_JEST_VERSION = Potassium::VUE_JEST_VERSION
3
9
 
4
10
  def ask
5
11
  frameworks = {
6
12
  vue: "Vue",
7
- angular: "Angular 2",
8
13
  none: "None"
9
14
  }
10
15
 
@@ -17,12 +22,16 @@ class Recipes::FrontEnd < Rails::AppBuilder
17
22
  end
18
23
 
19
24
  def create
25
+ gather_gem('shakapacker', '~> 6.2.0')
20
26
  recipe = self
21
- after(:gem_install) do
22
- value = get(:front_end)
27
+ after(:gem_install, wrap_in_action: :webpacker_install) do
23
28
  run "rails webpacker:install"
24
- run "rails webpacker:install:#{value}" unless [:none, :None].include? value.to_sym
25
-
29
+ end
30
+ after(:webpacker_install) do
31
+ value = get(:front_end)
32
+ recipe.copy_webpack_rules
33
+ recipe.add_assets_path
34
+ recipe.setup_typescript
26
35
  recipe.setup_vue if value == :vue
27
36
  recipe.add_responsive_meta_tag
28
37
  recipe.setup_tailwind
@@ -38,13 +47,37 @@ class Recipes::FrontEnd < Rails::AppBuilder
38
47
  def installed?
39
48
  package_file = 'package.json'
40
49
  return false unless file_exist?(package_file)
50
+
41
51
  package_content = read_file(package_file)
42
- package_content.include?("\"@angular/core\"") || package_content.include?("\"vue\"")
52
+ package_content.include?("\"vue\"")
53
+ end
54
+
55
+ def copy_webpack_rules
56
+ copy_file '../assets/config/webpack/webpack.config.js',
57
+ 'config/webpack/webpack.config.js',
58
+ force: true
59
+ copy_file '../assets/config/webpack/rules/index.js', 'config/webpack/rules/index.js'
60
+ copy_file '../assets/config/webpack/rules/css.js', 'config/webpack/rules/css.js'
61
+ copy_file '../assets/config/webpack/rules/vue.js', 'config/webpack/rules/vue.js'
62
+ copy_file '../assets/config/webpack/rules/jquery.js', 'config/webpack/rules/jquery.js'
63
+ copy_file '../assets/config/webpack/rules/typescript.js', 'config/webpack/rules/typescript.js'
64
+ end
65
+
66
+ def add_assets_path
67
+ gsub_file(
68
+ 'config/webpacker.yml',
69
+ 'additional_paths: []',
70
+ "additional_paths: ['app/assets']"
71
+ )
72
+ end
73
+
74
+ def setup_typescript
75
+ run "bin/yarn add typescript fork-ts-checker-webpack-plugin ts-loader @types/node"
76
+ copy_file '../assets/tsconfig.json', 'tsconfig.json'
43
77
  end
44
78
 
45
79
  def setup_vue_with_compiler_build
46
- application_js = 'app/javascript/packs/application.js'
47
- remove_file "app/javascript/packs/hello_vue.js"
80
+ application_js = 'app/javascript/application.js'
48
81
  create_file application_js, application_js_content, force: true
49
82
 
50
83
  layout_file = "app/views/layouts/application.html.erb"
@@ -63,55 +96,43 @@ class Recipes::FrontEnd < Rails::AppBuilder
63
96
  end
64
97
 
65
98
  def setup_tailwind
66
- run "bin/yarn add tailwindcss@#{Potassium::TAILWINDCSS}"
67
- specify_autoprefixer_postcss_compatibility_versions
99
+ run "bin/yarn add css-loader style-loader mini-css-extract-plugin @types/tailwindcss "\
100
+ "css-minimizer-webpack-plugin postcss@#{POSTCSS_VERSION} postcss-loader "\
101
+ "tailwindcss@#{TAILWINDCSS_VERSION} autoprefixer@#{AUTOPREFIXER_VERSION} sass sass-loader "\
102
+ "eslint-plugin-tailwindcss"
103
+ run "npx tailwindcss init -p"
68
104
  setup_client_css
69
105
  remove_server_css_requires
70
106
  setup_tailwind_requirements
71
107
  end
72
108
 
73
109
  def setup_jest
74
- run 'bin/yarn add jest vue-jest babel-jest @vue/test-utils jest-serializer-vue babel-core@^7.0.0-bridge.0 --dev'
110
+ run "bin/yarn add jest @vue/vue3-jest@#{VUE_JEST_VERSION} babel-jest "\
111
+ "@vue/test-utils@#{VUE_TEST_UTILS_VERSION} ts-jest"
75
112
  json_file = File.read(Pathname.new("package.json"))
76
113
  js_package = JSON.parse(json_file)
77
114
  js_package = js_package.merge(jest_config)
78
115
  json_string = JSON.pretty_generate(js_package)
79
116
  create_file 'package.json', json_string, force: true
80
117
 
81
- copy_file '../assets/app/javascript/app.spec.js', 'app/javascript/app.spec.js'
82
- end
83
-
84
- def setup_apollo
85
- run 'bin/yarn add vue-apollo graphql apollo-client apollo-link apollo-link-http apollo-cache-inmemory graphql-tag'
86
-
87
- inject_into_file(
88
- 'app/javascript/packs/application.js',
89
- apollo_imports,
90
- after: "import App from '../app.vue';"
91
- )
92
-
93
- inject_into_file(
94
- 'app/javascript/packs/application.js',
95
- apollo_loading,
96
- after: "import VueApollo from 'vue-apollo';"
97
- )
98
- inject_into_file(
99
- 'app/javascript/packs/application.js',
100
- "\n apolloProvider,",
101
- after: "components: { App },"
102
- )
103
- end
104
-
105
- def foce_vue_loader_version
106
- run "bin/yarn add vue-loader@#{VUE_LOADER_VERSION}"
118
+ copy_file '../assets/app/javascript/components/app.spec.ts',
119
+ 'app/javascript/components/app.spec.ts'
107
120
  end
108
121
 
109
122
  def setup_vue
110
- foce_vue_loader_version
123
+ run "bin/yarn add vue@#{VUE_VERSION} vue-loader@#{VUE_LOADER_VERSION} "\
124
+ "babel-preset-typescript-vue3"
125
+ gsub_file(
126
+ 'config/webpack/webpack.config.js',
127
+ ' merge(typescriptConfig, cssConfig, jQueryConfig, webpackConfig);',
128
+ ' merge(vueConfig, typescriptConfig, cssConfig, jQueryConfig, webpackConfig);'
129
+ )
130
+ copy_file '../assets/app/javascript/components/app.vue', 'app/javascript/components/app.vue'
131
+ copy_file '../assets/app/javascript/types/vue.d.ts', 'app/javascript/types/vue.d.ts'
111
132
  setup_vue_with_compiler_build
112
- setup_jest
113
- if get(:api) == :graphql
114
- setup_apollo
133
+ recipe = self
134
+ run_action(:setup_jest) do
135
+ recipe.setup_jest
115
136
  end
116
137
  end
117
138
 
@@ -120,45 +141,11 @@ class Recipes::FrontEnd < Rails::AppBuilder
120
141
  def frameworks(framework)
121
142
  frameworks = {
122
143
  vue: "vue",
123
- angular: "angular",
124
144
  none: nil
125
145
  }
126
146
  frameworks[framework]
127
147
  end
128
148
 
129
- def apollo_imports
130
- <<~JS
131
- \n
132
- import { ApolloClient } from 'apollo-client';
133
- import { createHttpLink } from 'apollo-link-http';
134
- import { InMemoryCache } from 'apollo-cache-inmemory';
135
- import VueApollo from 'vue-apollo';
136
- JS
137
- end
138
-
139
- def apollo_loading
140
- <<~JS
141
- \n
142
- const httpLink = createHttpLink({
143
- uri: `${window.location.origin}/graphql`,
144
- })
145
- const cache = new InMemoryCache()
146
- const apolloClient = new ApolloClient({
147
- link: httpLink,
148
- cache,
149
- })
150
-
151
- Vue.use(VueApollo)
152
- const apolloProvider = new VueApollo({
153
- defaultClient: apolloClient,
154
- })
155
- JS
156
- end
157
-
158
- def specify_autoprefixer_postcss_compatibility_versions
159
- run 'bin/yarn -D add postcss@^7 autoprefixer@^9'
160
- end
161
-
162
149
  def setup_client_css
163
150
  application_css = 'app/javascript/css/application.css'
164
151
  create_file application_css, "", force: true
@@ -167,14 +154,14 @@ class Recipes::FrontEnd < Rails::AppBuilder
167
154
  layout_file = "app/views/layouts/application.html.erb"
168
155
  insert_into_file layout_file, stylesheet_pack_tag, before: "</head>"
169
156
 
170
- application_js = 'app/javascript/packs/application.js'
157
+ application_js = 'app/javascript/application.js'
171
158
  if get(:front_end) != :vue
172
- create_file application_js, "import '../css/application.css';\n", force: true
159
+ create_file application_js, "import './css/application.css';\n", force: true
173
160
  else
174
161
  insert_into_file(
175
162
  application_js,
176
- "\nimport '../css/application.css';",
177
- after: "import App from '../app.vue';"
163
+ "\nimport './css/application.css';",
164
+ after: "import App from './components/app.vue';"
178
165
  )
179
166
  end
180
167
  end
@@ -185,9 +172,6 @@ class Recipes::FrontEnd < Rails::AppBuilder
185
172
 
186
173
  tailwind_config = 'tailwind.config.js'
187
174
  create_file tailwind_config, tailwind_config_content, force: true
188
-
189
- postcss_file = 'postcss.config.js'
190
- insert_into_file postcss_file, postcss_require_tailwind, after: "plugins: [\n"
191
175
  end
192
176
 
193
177
  def remove_server_css_requires
@@ -197,14 +181,14 @@ class Recipes::FrontEnd < Rails::AppBuilder
197
181
 
198
182
  def application_js_content
199
183
  <<~JS
200
- import Vue from 'vue/dist/vue.esm';
201
- import App from '../app.vue';
184
+ import { createApp } from 'vue';
185
+ import App from './components/app.vue';
202
186
 
203
187
  document.addEventListener('DOMContentLoaded', () => {
204
- const app = new Vue({
205
- el: '#vue-app',
188
+ const app = createApp({
206
189
  components: { App },
207
190
  });
191
+ app.mount('#vue-app');
208
192
 
209
193
  return app;
210
194
  });
@@ -213,9 +197,9 @@ class Recipes::FrontEnd < Rails::AppBuilder
213
197
 
214
198
  def tailwind_client_css
215
199
  <<~CSS
216
- @import 'tailwindcss/base';
217
- @import 'tailwindcss/components';
218
- @import 'tailwindcss/utilities';
200
+ @tailwind base;
201
+ @tailwind components;
202
+ @tailwind utilities;
219
203
  CSS
220
204
  end
221
205
 
@@ -228,26 +212,16 @@ class Recipes::FrontEnd < Rails::AppBuilder
228
212
  },
229
213
  variants: {},
230
214
  plugins: [],
231
- purge: {
232
- enabled: process.env.NODE_ENV === 'production',
233
- content: [
234
- './app/**/*.html',
235
- './app/**/*.vue',
236
- './app/**/*.js',
237
- './app/**/*.erb',
238
- ],
239
- }
215
+ content: [
216
+ './app/**/*.html',
217
+ './app/**/*.vue',
218
+ './app/**/*.js',
219
+ './app/**/*.erb',
220
+ ],
240
221
  };
241
222
  JS
242
223
  end
243
224
 
244
- def postcss_require_tailwind
245
- <<-JS.gsub(/^ {4}/, ' ')
246
- require('tailwindcss'),
247
- require('autoprefixer'),
248
- JS
249
- end
250
-
251
225
  def jest_config
252
226
  {
253
227
  "scripts": {
@@ -267,16 +241,14 @@ class Recipes::FrontEnd < Rails::AppBuilder
267
241
  },
268
242
  "moduleFileExtensions": [
269
243
  "js",
244
+ "ts",
270
245
  "json",
271
246
  "vue"
272
247
  ],
273
248
  "transform": {
274
- "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
275
- ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
249
+ "^.+\\.ts$": "ts-jest",
250
+ ".*\\.(vue)$": "@vue/vue3-jest"
276
251
  },
277
- "snapshotSerializers": [
278
- "<rootDir>/node_modules/jest-serializer-vue"
279
- ],
280
252
  "testEnvironment": "jsdom"
281
253
  }
282
254
  }
@@ -87,7 +87,7 @@ class Recipes::GoogleTagManager < Rails::AppBuilder
87
87
  'https://www.google-analytics.com',
88
88
  'https://ssl.google-analytics.com'
89
89
  )
90
- policy.img_src :self, :https, 'https://www.googletagmanager.com', 'https://www.google-analytics.com'
90
+ policy.img_src :self, 'data:', :https, 'https://www.googletagmanager.com', 'https://www.google-analytics.com'
91
91
  end
92
92
  HERE
93
93
  end
@@ -63,20 +63,32 @@ class Recipes::Mailer < Rails::AppBuilder
63
63
  gather_gem 'recipient_interceptor'
64
64
  end
65
65
 
66
+ def config_environments
67
+ gsub_file 'config/environments/production.rb', /$\s*config.action_mailer.*/, ''
68
+ asset_host_dev = <<~RUBY
69
+ config.action_mailer.asset_host = "http://\#{ENV.fetch('APPLICATION_HOST')}"
70
+ RUBY
71
+ application asset_host_dev, env: "development"
72
+ asset_host_prod = <<~RUBY
73
+ config.action_mailer.asset_host = "https://\#{ENV.fetch('APPLICATION_HOST')}"
74
+ RUBY
75
+ application asset_host_prod, env: "production"
76
+ mailer_config = <<~RUBY
77
+ require Rails.root.join("config", "mailer")
78
+ RUBY
79
+
80
+ prepend_file "config/environments/production.rb", mailer_config
81
+ end
82
+
66
83
  def config(service)
67
84
  template "../assets/config/mailer.rb.erb", 'config/mailer.rb'
68
- gsub_file 'config/environments/production.rb', /$\s*config.action_mailer.*/, ''
85
+
69
86
  append_to_file '.env.development', "APPLICATION_HOST=localhost:3000\n"
70
87
  append_to_file '.env.development', "EMAIL_RECIPIENTS=\n"
71
88
 
72
- mailer_config =
73
- <<~RUBY
74
- require Rails.root.join("config", "mailer")
75
- RUBY
76
-
77
- prepend_file "config/environments/production.rb", mailer_config
78
- copy_file '../assets/app/mailers/application_mailer.rb', 'app/mailers/application_mailer.rb', force: true
79
-
89
+ copy_file '../assets/app/mailers/application_mailer.rb', 'app/mailers/application_mailer.rb',
90
+ force: true
91
+ config_environments
80
92
  send(service[:name])
81
93
  end
82
94
 
@@ -88,7 +100,7 @@ class Recipes::Mailer < Rails::AppBuilder
88
100
  }
89
101
  RUBY
90
102
  inject_into_file 'config/mailer.rb', sendgrid_settings,
91
- after: "Rails.application.config.action_mailer.delivery_method = :sendgrid\n"
103
+ after: "Rails.application.config.action_mailer.delivery_method = :sendgrid\n"
92
104
  sendgrid_dev_settings = <<~RUBY
93
105
  Rails.application.config.action_mailer.sendgrid_dev_settings = {
94
106
  api_key: ENV['SENDGRID_API_KEY']
@@ -0,0 +1,31 @@
1
+ class Recipes::Mjml < Rails::AppBuilder
2
+ def create
3
+ return if get(:email_service).to_s.downcase.to_sym == :none
4
+
5
+ gather_gem 'mjml-rails'
6
+ after(:gem_install) do
7
+ run 'bin/yarn add mjml'
8
+ mjml_config
9
+ end
10
+ end
11
+
12
+ def installed?
13
+ gem_exists?(/mjml-rails/)
14
+ end
15
+
16
+ def install
17
+ create
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def mjml_config
24
+ copy_file '../assets/app/views/layouts/default_mail.html.mjml',
25
+ 'app/views/layouts/default_mail.html.mjml', force: true
26
+ copy_file '../assets/app/mailers/example_mailer.rb', 'app/mailers/example_mailer.rb', force: true
27
+ copy_file '../assets/app/views/example_mailer/example_mail.html.mjml',
28
+ 'app/views/example_mailer/example_mail.html.mjml', force: true
29
+ copy_file '../assets/public/mails/platanus-logo.png',
30
+ 'public/mails/platanus-logo.png', force: true
31
+ end
@@ -3,19 +3,17 @@ require 'semantic'
3
3
  require 'json'
4
4
 
5
5
  class Recipes::Node < Rails::AppBuilder
6
- def create
7
- info "Using node version LTS #{version}"
8
- create_file '.node-version', version, force: true
9
- json_file = File.read(Pathname.new("package.json"))
10
- js_package = JSON.parse(json_file)
11
- js_package["engines"] = { "node" => "#{version}.x" }
12
- json_string = JSON.pretty_generate(js_package)
13
- create_file 'package.json', json_string, force: true
14
- end
6
+ NODE_VERSION = Potassium::NODE_VERSION
15
7
 
16
- private
17
-
18
- def version
19
- Potassium::NODE_VERSION
8
+ def create
9
+ info "Using node version LTS #{NODE_VERSION}"
10
+ create_file '.node-version', NODE_VERSION, force: true
11
+ after(:webpacker_install) do
12
+ json_file = File.read(Pathname.new("package.json"))
13
+ js_package = JSON.parse(json_file)
14
+ js_package["engines"] = { "node" => "#{NODE_VERSION}.x" }
15
+ json_string = JSON.pretty_generate(js_package)
16
+ create_file 'package.json', json_string, force: true
17
+ end
20
18
  end
21
19
  end
@@ -17,9 +17,16 @@ class Recipes::Style < Rails::AppBuilder
17
17
  gather_gem 'rubocop-performance'
18
18
  gather_gem 'rubocop-rails'
19
19
  gather_gem 'rubocop-rspec', Potassium::RUBOCOP_RSPEC_VERSION
20
+ gather_gem 'rubocop-platanus'
21
+ end
22
+
23
+ after(:webpacker_install) do
24
+ run "yarn add --dev stylelint eslint eslint-plugin-import "\
25
+ "@typescript-eslint/eslint-plugin @types/jest @typescript-eslint/parser eslint-plugin-jest"
26
+ if selected?(:front_end, :vue)
27
+ run 'yarn add --dev eslint-plugin-vue @vue/eslint-config-typescript'
28
+ end
20
29
  end
21
- run 'bin/yarn add --dev stylelint eslint eslint-plugin-import'
22
- run 'bin/yarn add --dev eslint-plugin-vue' if selected?(:front_end, :vue)
23
30
  end
24
31
 
25
32
  def add_config_files
@@ -35,15 +35,18 @@ class Recipes::VueAdmin < Rails::AppBuilder
35
35
  def add_vue_admin
36
36
  add_vue_component_library
37
37
  add_component_integration
38
- copy_file '../assets/active_admin/init_activeadmin_vue.rb',
39
- 'config/initializers/init_activeadmin_vue.rb'
40
- copy_file '../assets/active_admin/admin_application.js',
41
- 'app/javascript/packs/admin_application.js',
42
- force: true
43
- empty_directory 'app/javascript/components'
38
+ js_line = 'import "activeadmin_addons"'
39
+ gsub_file(
40
+ 'app/javascript/active_admin.js',
41
+ js_line,
42
+ <<~HERE
43
+ #{js_line}
44
+ #{active_admin_js}
45
+ HERE
46
+ )
44
47
  copy_file '../assets/active_admin/admin-component.vue',
45
- 'app/javascript/components/admin-component.vue',
46
- force: true
48
+ 'app/javascript/components/admin-component.vue',
49
+ force: true
47
50
  end
48
51
 
49
52
  def add_component_integration
@@ -121,4 +124,31 @@ class Recipes::VueAdmin < Rails::AppBuilder
121
124
  end
122
125
  HERE
123
126
  end
127
+
128
+ def active_admin_js
129
+ <<~HERE
130
+ import { createApp } from 'vue';
131
+ import AdminComponent from './components/admin-component.vue';
132
+
133
+ function onLoad() {
134
+ if (document.getElementById('wrapper') !== null) {
135
+ const app = createApp({
136
+ mounted() {
137
+ // We need to re-trigger DOMContentLoaded for ArcticAdmin after Vue replaces DOM elements
138
+ window.document.dispatchEvent(new Event('DOMContentLoaded', {
139
+ bubbles: true,
140
+ cancelable: true,
141
+ }));
142
+ },
143
+ });
144
+ app.component('AdminComponent', AdminComponent);
145
+ app.mount('#wrapper');
146
+ }
147
+
148
+ return null;
149
+ }
150
+
151
+ document.addEventListener('DOMContentLoaded', onLoad, { once: true });
152
+ HERE
153
+ end
124
154
  end
@@ -81,6 +81,7 @@ run_action(:recipe_loading) do
81
81
  create :admin
82
82
  create :vue_admin
83
83
  create :google_tag_manager
84
+ create :mjml
84
85
  end
85
86
 
86
87
  info "Gathered enough information. Applying the template. Wait a minute."
@@ -1,5 +1,5 @@
1
1
  module Potassium
2
- VERSION = "6.5.0"
2
+ VERSION = "6.6.0"
3
3
  RUBY_VERSION = "2.7.0"
4
4
  RAILS_VERSION = "~> 6.1.4.4"
5
5
  RUBOCOP_VERSION = "~> 1.9"
@@ -7,6 +7,11 @@ module Potassium
7
7
  POSTGRES_VERSION = "11.3"
8
8
  MYSQL_VERSION = "5.7"
9
9
  NODE_VERSION = "14"
10
- TAILWINDCSS = "npm:@tailwindcss/postcss7-compat"
11
- VUE_LOADER_VERSION = "^15.9.7"
10
+ TAILWINDCSS_VERSION = "^3"
11
+ POSTCSS_VERSION = "^8"
12
+ AUTOPREFIXER_VERSION = "^10"
13
+ VUE_VERSION = "^3"
14
+ VUE_LOADER_VERSION = "^16"
15
+ VUE_TEST_UTILS_VERSION = "^2.0.0-rc.18"
16
+ VUE_JEST_VERSION = "^27.0.0-alpha.1"
12
17
  end
@@ -4,7 +4,7 @@ RSpec.describe "Api" do
4
4
  before :all do
5
5
  drop_dummy_database
6
6
  remove_project_directory
7
- create_dummy_project("api" => :rest)
7
+ create_dummy_project("api" => true)
8
8
  end
9
9
 
10
10
  it "adds power_api related gems to Gemfile" do
@@ -22,4 +22,9 @@ RSpec.describe "Api" do
22
22
  content = IO.read("#{project_path}/app/controllers/api/base_controller.rb")
23
23
  expect(content).to include("Api::BaseController < PowerApi::BaseController")
24
24
  end
25
+
26
+ it "installs internal API mode" do
27
+ content = IO.read("#{project_path}/app/controllers/api/internal/base_controller.rb")
28
+ expect(content).to include("Api::Internal::BaseController < Api::BaseController")
29
+ end
25
30
  end
@@ -23,4 +23,21 @@ RSpec.describe "Coverage" do
23
23
  content = IO.read("#{project_path}/spec/simplecov_config.rb")
24
24
  expect(content).to include("SimpleCov.start 'rails'")
25
25
  end
26
+
27
+ context "with vue" do
28
+ let(:node_modules_file) { IO.read("#{project_path}/package.json") }
29
+
30
+ before(:all) do
31
+ remove_project_directory
32
+ create_dummy_project("front_end" => "vue")
33
+ end
34
+
35
+ it "adds jest coverage configuration" do
36
+ expect(node_modules_file).to include('"collectCoverage": true')
37
+ end
38
+
39
+ it "adds jest text formatter package" do
40
+ expect(node_modules_file).to include('jest-text-formatter')
41
+ end
42
+ end
26
43
  end