potassium 6.5.0 → 6.6.0

Sign up to get free protection for your applications and to get access to all the features.
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