web47core 2.0.1 → 2.2.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +111 -41
- data/app/controllers/status_controller.rb +8 -3
- data/app/helpers/core_form_helper.rb +6 -6
- data/app/helpers/core_helper.rb +1 -1
- data/app/helpers/core_link_helper.rb +47 -8
- data/app/helpers/core_nav_bar_helper.rb +5 -4
- data/app/helpers/core_table_helper.rb +80 -0
- data/app/helpers/model_modal_helper.rb +3 -3
- data/app/views/common/_create_actions.html.haml +12 -0
- data/app/views/common/_update_actions.html.haml +10 -0
- data/app/views/cron/_edit.html.haml +15 -17
- data/app/views/cron/_index.html.haml +74 -67
- data/app/views/delayed_job_metrics/_index.html.haml +27 -0
- data/app/views/delayed_job_metrics/index.html.haml +1 -0
- data/app/views/delayed_job_workers/_index.html.haml +27 -0
- data/app/views/delayed_job_workers/index.html.haml +1 -0
- data/app/views/delayed_jobs/_index.html.haml +47 -52
- data/app/views/delayed_jobs/_show.html.haml +15 -13
- data/app/views/system_configurations/_edit.html.haml +14 -9
- data/app/views/system_configurations/_show.html.haml +18 -12
- data/config/brakeman.ignore +26 -0
- data/config/brakeman.yml +2 -0
- data/config/locales/en.yml +21 -3
- data/lib/app/controllers/concerns/core_delayed_job_metrics_controller.rb +35 -0
- data/lib/app/controllers/concerns/core_delayed_job_workers_controller.rb +35 -0
- data/lib/app/controllers/concerns/core_delayed_jobs_controller.rb +2 -3
- data/lib/app/jobs/cron/command.rb +1 -4
- data/lib/app/jobs/cron/record_delayed_job_metrics.rb +25 -0
- data/lib/app/jobs/cron/restart_orphaned_delayed_jobs.rb +44 -0
- data/lib/app/jobs/cron/server.rb +32 -15
- data/lib/app/jobs/cron/switchboard_sync_configuration.rb +2 -0
- data/lib/app/jobs/cron/switchboard_sync_models.rb +2 -0
- data/lib/app/jobs/cron/trim_collection.rb +1 -1
- data/lib/app/jobs/cron/trim_delayed_job_metrics.rb +29 -0
- data/lib/app/jobs/cron/trim_delayed_job_workers.rb +39 -0
- data/lib/app/jobs/cron/trim_failed_delayed_jobs.rb +2 -0
- data/lib/app/models/api_token.rb +9 -0
- data/lib/app/models/command_job.rb +12 -11
- data/lib/app/models/concerns/api_tokenable.rb +38 -0
- data/lib/app/models/concerns/aws_configuration.rb +65 -0
- data/lib/app/models/concerns/cdn_url.rb +7 -0
- data/lib/app/models/concerns/core_smtp_configuration.rb +65 -0
- data/lib/app/models/concerns/core_system_configuration.rb +18 -201
- data/lib/app/models/concerns/delayed_job_configuration.rb +24 -0
- data/lib/app/models/concerns/email_able.rb +6 -2
- data/lib/app/models/concerns/google_sso_configuration.rb +32 -0
- data/lib/app/models/concerns/search_able.rb +16 -0
- data/lib/app/models/concerns/server_process_able.rb +69 -0
- data/lib/app/models/concerns/slack_configuration.rb +38 -0
- data/lib/app/models/concerns/standard_model.rb +5 -2
- data/lib/app/models/concerns/switchboard_configuration.rb +43 -0
- data/lib/app/models/concerns/twilio_configuration.rb +37 -0
- data/lib/app/models/concerns/zendesk_configuration.rb +92 -0
- data/lib/app/models/{delayed_job.rb → delayed/backend/delayed_job.rb} +41 -0
- data/lib/app/models/delayed/jobs/metric.rb +61 -0
- data/lib/app/models/delayed/jobs/run.rb +40 -0
- data/lib/app/models/delayed/jobs/worker.rb +43 -0
- data/lib/app/models/delayed/plugins/time_keeper.rb +33 -0
- data/lib/app/models/delayed/worker.rb +24 -0
- data/lib/app/models/email_notification.rb +2 -1
- data/lib/app/models/email_template.rb +5 -6
- data/lib/app/models/notification.rb +12 -2
- data/lib/app/models/sms_notification.rb +9 -6
- data/lib/app/models/template.rb +12 -12
- data/lib/web47core/version.rb +1 -1
- data/lib/web47core.rb +33 -9
- metadata +114 -69
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e3b62063f81c04f52de1b3c56a36801555c8294f69e677142754897ec64fd6e
|
4
|
+
data.tar.gz: e2cad54d84e6155e83819d8ea5691df3f4eeba9625f60ffd52ad9ac996967b97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f080ed702713ff2258b811d91de55e53e92e1fe9e3a04ab762ef9a870f4eceda71e048e80440be2efa709bd2c5768e3f0f47070dce2fdbc0c89ea2be97fc9a0d
|
7
|
+
data.tar.gz: 62e0a0483e20b47b5c48370f1643a76ad5abc77075033bf76b17b21fdf2642359ff8fb2336c1ab24aadc29e8855dd194e38c65b71376656c0d61869fe66248dd
|
data/README.md
CHANGED
@@ -3,29 +3,29 @@ Core components used commonly among all web apps for both App47 and RedMonocle
|
|
3
3
|
|
4
4
|
## We don't need no sticking badges
|
5
5
|
|
6
|
-
*
|
7
|
-
*
|
8
|
-
*
|
9
|
-
*
|
6
|
+
* [![Codacy Badge](https://api.codacy.com/project/badge/Grade/acc591f31c214849959f71e210e7edbd)](https://www.codacy.com?utm_source=github.com&utm_medium=referral&utm_content=App47/web47core&utm_campaign=Badge_Grade)
|
7
|
+
* [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/acc591f31c214849959f71e210e7edbd)](https://www.codacy.com?utm_source=github.com&utm_medium=referral&utm_content=App47/web47core&utm_campaign=Badge_Coverage)
|
8
|
+
* Develop: [![CircleCI](https://circleci.com/gh/App47/web47core/tree/develop.svg?style=svg&circle-token=9999e0634dd96ad5414f4f3e56c39ba6d3e0e4e6)](https://circleci.com/gh/App47/web47core/tree/develop)
|
9
|
+
* Master: [![CircleCI](https://circleci.com/gh/App47/web47core/tree/master.svg?style=svg&circle-token=9999e0634dd96ad5414f4f3e56c39ba6d3e0e4e6)](https://circleci.com/gh/App47/web47core/tree/master)
|
10
10
|
|
11
11
|
## Requirements
|
12
12
|
|
13
|
-
*
|
13
|
+
* Ruby 2.7.0
|
14
14
|
|
15
|
-
### Working with Bundler and
|
15
|
+
### Working with Bundler and RBENV
|
16
16
|
|
17
|
-
This project manages
|
17
|
+
This project manages [RBENV](https://github.com/rbenv/rbenv) and manages dependencies via [Bundler](http://gembundler.com/).
|
18
18
|
|
19
|
-
You must first [install
|
20
|
-
Then install Ruby 2.7.0
|
19
|
+
You must first [install RBENV](https://github.com/rbenv/rbenv#installation).
|
20
|
+
Then install Ruby 2.7.0 via RBENV
|
21
21
|
``` shell script
|
22
|
-
|
22
|
+
rbenv install 2.7.0
|
23
23
|
```
|
24
|
-
You'll now notice that this project (as well as other App47 ones) contains a .
|
24
|
+
You'll now notice that this project (as well as other App47 ones) contains a .ruby-version file, which is executed upon opening the project's root directory in a terminal (and IDE's like RubyMine). The .ruby-version file simply states `2.7.0` which tells RBENV to ensure the Ruby version to use for this project is 2.7.0.
|
25
25
|
|
26
26
|
Please note, your Ruby `2.7.0` version might need bundler installed:
|
27
27
|
``` shell script
|
28
|
-
gem install bundler -v 2.
|
28
|
+
gem install bundler -v 2.1.4
|
29
29
|
```
|
30
30
|
|
31
31
|
To set up this project's dependencies, which are defined in the file, `Gemfile`, you should first run
|
@@ -43,29 +43,28 @@ bundle exec rake test
|
|
43
43
|
## Deployment
|
44
44
|
The `web47core` project is a gem that will be deployed via [Ruby Gems](https://rubygems.org). When an update is ready, the following steps should be followed
|
45
45
|
|
46
|
-
1.
|
47
|
-
2.
|
48
|
-
3. There may be a delay when using the gem file
|
46
|
+
1. Build the gem `gem build web47core.gemspec`
|
47
|
+
2. Post the gem to the DevOps channel in slack, ask for it to be added to the S3 repo.
|
49
48
|
|
50
49
|
## Usage
|
51
50
|
### Importing the gem
|
52
|
-
To use the `
|
51
|
+
To use the `web47core` gem in a project, first add the gem to your Gemfile in one of two ways
|
53
52
|
|
54
53
|
Using the gem from [Ruby Gems](https://rubygems.org)
|
55
|
-
```rbenv-gemsets
|
54
|
+
``` rbenv-gemsets
|
56
55
|
gem 'web47core'
|
57
56
|
```
|
58
57
|
|
59
58
|
If you need the gem immediately or need to pull from development branch, you can use the git repo
|
60
|
-
```rbenv-gemsets
|
59
|
+
``` rbenv-gemsets
|
61
60
|
gem 'web47core', git: 'git@github.com:App47/web47core.git', branch: :master
|
62
61
|
```
|
63
62
|
or from the develop branch
|
64
|
-
```rbenv-gemsets
|
63
|
+
``` rbenv-gemsets
|
65
64
|
gem 'web47core', git: 'git@github.com:App47/web47core.git', branch: :develop
|
66
65
|
```
|
67
66
|
|
68
|
-
|
67
|
+
Please do not ship to production code using the git repo, as the production servers will not have keys to pull from the web47core repo.
|
69
68
|
|
70
69
|
### Remove the following files
|
71
70
|
1. `StandardModel` - Includes the common set of includes, Mongoid, Auditable, AutoClearCache, etc.
|
@@ -77,18 +76,21 @@ _Please do not ship to production code using the git repo, as the production ser
|
|
77
76
|
7. `Notification`
|
78
77
|
8. `NotificationTemplate`
|
79
78
|
9. `SlackNotification`
|
80
|
-
10.
|
81
|
-
11.
|
82
|
-
12.
|
83
|
-
13.
|
84
|
-
14.
|
85
|
-
15.
|
86
|
-
16.
|
87
|
-
17.
|
88
|
-
18.
|
89
|
-
19.
|
90
|
-
20.
|
91
|
-
|
79
|
+
10. `SmsNotification`
|
80
|
+
11. `Template`
|
81
|
+
12. `App47Logger` and `App47LoggerTest`
|
82
|
+
13. `Emailable` or `EmailAble` and `EamailbleTest`, be sure to change `Emailable` to `EmailAble`
|
83
|
+
14. `RedisConfiguration` and `RedisConfgurationTest`
|
84
|
+
15. `Searchable` and `SearchableTest`, be sure to change `Searchable` to `SearchAble`
|
85
|
+
16. `TimezoneAble` and `TimezoneAbleTest`
|
86
|
+
17. `CronJobServer` and `CronJobServerTest`
|
87
|
+
18. `JobCronTab` and `JobCronTabTest`
|
88
|
+
19. `CronTab`
|
89
|
+
20. `SecureFields`
|
90
|
+
21. `Job`
|
91
|
+
22. `JobLog`
|
92
|
+
23. `CommandLogLog`
|
93
|
+
24. `TrimJobs`
|
92
94
|
#### Models
|
93
95
|
##### Concerns
|
94
96
|
1. `StandardModel` - Includes the common set of includes, Mongoid, etc.
|
@@ -106,6 +108,21 @@ class SystemConfiguration
|
|
106
108
|
field :google_sso_client_id, type: String
|
107
109
|
end
|
108
110
|
```
|
111
|
+
|
112
|
+
Configuration has been broken out, or modularized as of 2.0.10, so if the project uses `AWS`, `SMTP`, `Slack`, `Switchboard`, `Twilio` or `Zendesk` within `SystemConfiguration`, then you will also need to include those configurations in the Project's SystemConfiguration, for example
|
113
|
+
```ruby
|
114
|
+
class SystemConfiguration
|
115
|
+
include StandardModel
|
116
|
+
include CoreSystemConfiguration
|
117
|
+
include ZendeskConfiguration
|
118
|
+
include TwilioConfiguration
|
119
|
+
include SwitchboardConfiguration
|
120
|
+
include DelayedJobConfiguration
|
121
|
+
|
122
|
+
# Include your additional system configuration fields and methods
|
123
|
+
field :google_sso_client_id, type: String
|
124
|
+
end
|
125
|
+
```
|
109
126
|
##### Account
|
110
127
|
Define a `Account` class in your project and import the core concern.
|
111
128
|
|
@@ -134,19 +151,19 @@ module Cron
|
|
134
151
|
end
|
135
152
|
```
|
136
153
|
Allowed values of cron_tab_entry are
|
137
|
-
*
|
138
|
-
*
|
139
|
-
*
|
140
|
-
*
|
141
|
-
*
|
142
|
-
*
|
154
|
+
* `:always` Run every minute
|
155
|
+
* `:hourly` Run every hour
|
156
|
+
* `:daily` Run every day
|
157
|
+
* `:weekly` Run every week on Sunday
|
158
|
+
* `:monthly` Run every month on the first day of the month
|
159
|
+
* `'*/5 1,3 * 2 *'` Run according to unix crontab entry format. This would run every tuesday on the 1st and 3rd hour, for any minute divisible by 5, so 0, 5, 10, 15, etc..
|
143
160
|
|
144
161
|
Before starting the server, you need to run the database command
|
145
162
|
```mongo
|
146
163
|
db.cron_tabs.updateMany({_type: 'JobCronTab'}, {$set: {_type: 'Cron::JobTab'}});
|
147
164
|
```
|
148
165
|
|
149
|
-
####
|
166
|
+
#### Abilities
|
150
167
|
Update abilities to new class names
|
151
168
|
CronTab, JobCronTab, CronJobServer to Cron::Tab, Cron::JobTab, Cron::Server
|
152
169
|
|
@@ -203,8 +220,12 @@ end
|
|
203
220
|
```
|
204
221
|
|
205
222
|
To start or stop the cron server, run the bundler command:
|
223
|
+
```bash
|
224
|
+
bundle exec cron_server start
|
206
225
|
```
|
207
|
-
|
226
|
+
or
|
227
|
+
```bash
|
228
|
+
bundle exec cron_server stop
|
208
229
|
```
|
209
230
|
|
210
231
|
##### DelayedJobController
|
@@ -223,10 +244,59 @@ end
|
|
223
244
|
```
|
224
245
|
|
225
246
|
To start or stop the delayed jobs, run the bundler command:
|
247
|
+
```bash
|
248
|
+
bundle exec delayed_job start
|
249
|
+
```
|
250
|
+
or
|
251
|
+
```bash
|
252
|
+
bundle exec delayed_job stop
|
253
|
+
```
|
254
|
+
|
255
|
+
##### Delayed Job Management
|
256
|
+
Since 2.1.0, there is now a built in Delayed Job monitor that will monitor delayed jobs and auto restart them if they
|
257
|
+
exceed the max allowed time for a job to run. To configure this, update the delayed job initializer to add the `TimeKeeper` plugin.
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
Delayed::Worker.plugins += [Delayed::Plugins::TimeKeeper]
|
261
|
+
```
|
262
|
+
|
263
|
+
This will add a few now cron jobs as well as objects to the project, you can view these by adding the following routes near the delayed jobs area
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
resources :delayed_job_workers, only: %i[index destroy]
|
267
|
+
resources :delayed_job_metrics, only: %i[index destroy]
|
226
268
|
```
|
227
|
-
|
269
|
+
with the following two controllers
|
270
|
+
|
271
|
+
```ruby
|
272
|
+
# frozen_string_literal: true
|
273
|
+
|
274
|
+
#
|
275
|
+
# Manage access to metrics
|
276
|
+
#
|
277
|
+
class DelayedJobMetricsController < BaseStackUiController
|
278
|
+
rescue_from Mongoid::Errors::DocumentNotFound, with: :document_not_found_error
|
279
|
+
include ::CoreDelayedJobMetricsController
|
280
|
+
end
|
228
281
|
```
|
282
|
+
and
|
283
|
+
```ruby
|
284
|
+
# frozen_string_literal: true
|
229
285
|
|
286
|
+
#
|
287
|
+
# Manage access to workers
|
288
|
+
#
|
289
|
+
class DelayedJobWorkersController < BaseStackUiController
|
290
|
+
rescue_from Mongoid::Errors::DocumentNotFound, with: :document_not_found_error
|
291
|
+
include ::CoreDelayedJobWorkersController
|
292
|
+
end
|
293
|
+
```
|
294
|
+
lastly, add the following three objects to ability to allow access
|
295
|
+
```ruby
|
296
|
+
Delayed::Jobs::Worker,
|
297
|
+
Delayed::Jobs::Metric,
|
298
|
+
Delayed::Jobs::Run
|
299
|
+
```
|
230
300
|
##### StatusController
|
231
301
|
Remove controller, views and localizations
|
232
302
|
##### SystemConfigurationsController
|
@@ -73,13 +73,18 @@ class StatusController < ActionController::Base
|
|
73
73
|
report_error error, count: 0
|
74
74
|
end
|
75
75
|
|
76
|
+
def pid
|
77
|
+
@pid ||= Process.pid
|
78
|
+
end
|
79
|
+
|
76
80
|
#
|
77
81
|
# Redis DB Status
|
78
82
|
#
|
79
83
|
def redis_status
|
80
|
-
value = Time.now.
|
81
|
-
|
82
|
-
|
84
|
+
value = Time.now.to_i
|
85
|
+
key = "redis-status-check-#{pid}"
|
86
|
+
Rails.cache.write key, value, expires_in: 5.seconds
|
87
|
+
raise 'Redis not available' unless value.eql?(Rails.cache.fetch(key))
|
83
88
|
|
84
89
|
report_success 'Redis Available', count: 1
|
85
90
|
rescue StandardError => error
|
@@ -40,7 +40,7 @@ module CoreFormHelper
|
|
40
40
|
def form_text_field(model, field, options = {})
|
41
41
|
classes = options[:classes] || %w[s12 m6 l4 xl3]
|
42
42
|
value = model.send(field)
|
43
|
-
options[:type]
|
43
|
+
options[:type] ||= :text
|
44
44
|
options[:value] = value
|
45
45
|
options[:disabled] ||= false
|
46
46
|
tag_options = text_field_options(model, field, options)
|
@@ -88,7 +88,7 @@ module CoreFormHelper
|
|
88
88
|
classes = options[:classes] || %w[s12 m6 l4 xl3]
|
89
89
|
value = model.send(field)
|
90
90
|
options[:type] = :password
|
91
|
-
options[:place_holder]
|
91
|
+
options[:place_holder] ||= mask_value(value)
|
92
92
|
tag_options = text_field_options(model, field, options)
|
93
93
|
content_tag(:div, class: (%w[input-field col] + classes).join(' ')) do
|
94
94
|
concat(tag(:input, tag_options))
|
@@ -111,7 +111,7 @@ module CoreFormHelper
|
|
111
111
|
base_classes = %w[input-field col]
|
112
112
|
data = {}
|
113
113
|
end
|
114
|
-
classes = (base_classes + (options[:classes] || %w[s12 m6 l4])).join(' ')
|
114
|
+
classes = (base_classes + (options[:classes] || %w[s12 m6 l4 xl3])).join(' ')
|
115
115
|
content_tag(:div, class: classes, data: data) do
|
116
116
|
concat(form_select_tag(model, field, options))
|
117
117
|
concat(form_label_tag(model, field, value, options))
|
@@ -175,8 +175,8 @@ module CoreFormHelper
|
|
175
175
|
options[:disabled] ||= false
|
176
176
|
properties = {
|
177
177
|
class: 'validate',
|
178
|
-
id: form_field_id(model, field),
|
179
|
-
name: form_field_name(model, field),
|
178
|
+
id: form_field_id(model, field, options),
|
179
|
+
name: form_field_name(model, field, options),
|
180
180
|
type: :checkbox,
|
181
181
|
disabled: options[:disabled]
|
182
182
|
}
|
@@ -247,7 +247,7 @@ module CoreFormHelper
|
|
247
247
|
options['data-error'] = error.join(', ') if error.present?
|
248
248
|
content_tag(:label, options) do
|
249
249
|
concat(I18n.exists?(key) ? I18n.t(key) : field.to_s.humanize)
|
250
|
-
concat(
|
250
|
+
concat(" #{error.join(', ')}") if error.present?
|
251
251
|
end
|
252
252
|
end
|
253
253
|
|
data/app/helpers/core_helper.rb
CHANGED
@@ -54,11 +54,15 @@ module CoreLinkHelper
|
|
54
54
|
#
|
55
55
|
# Add a favorite tag
|
56
56
|
#
|
57
|
-
def favorite_tag(favorite)
|
57
|
+
def favorite_tag(favorite, options = {})
|
58
|
+
data = {}
|
59
|
+
link_classes = tooltip_data(options, data, I18n.t('ui_form.actions.favorite'))
|
60
|
+
link_classes += %w[material-icons pointer favorite]
|
58
61
|
content_tag(:i,
|
59
|
-
class: '
|
62
|
+
class: link_classes.join(' '),
|
63
|
+
data: data,
|
60
64
|
id: favorite.id.to_s,
|
61
|
-
type: favorite.favorite_type) { concat('favorite_border') }
|
65
|
+
type: favorite.favorite_type) { concat(icon_name(options, 'favorite_border')) }
|
62
66
|
end
|
63
67
|
|
64
68
|
#
|
@@ -126,6 +130,7 @@ module CoreLinkHelper
|
|
126
130
|
return unless can? :edit, obj
|
127
131
|
|
128
132
|
data = {}
|
133
|
+
options[:icon_name] ||= 'replay'
|
129
134
|
confirmation_data(options, data, t('links.replay_confirmation', name: obj.class.to_s.underscore.humanize))
|
130
135
|
link_classes = tooltip_data(options, data)
|
131
136
|
content_tag(:a, href: path, data: data, class: link_classes.join(' ')) do
|
@@ -146,6 +151,23 @@ module CoreLinkHelper
|
|
146
151
|
end
|
147
152
|
end
|
148
153
|
|
154
|
+
#
|
155
|
+
# Restart a thingy
|
156
|
+
#
|
157
|
+
def replay_button_tag(obj, path, options = {})
|
158
|
+
return unless can? :edit, obj
|
159
|
+
|
160
|
+
data = {}
|
161
|
+
options[:icon_name] ||= 'replay'
|
162
|
+
confirmation_data(options, data, t('links.replay_confirmation', name: obj.class.to_s.underscore.humanize))
|
163
|
+
link_classes = tooltip_data(options, data)
|
164
|
+
link_classes << 'btn' unless link_classes.include?('btn')
|
165
|
+
content_tag(:a, href: path, data: data, class: link_classes) do
|
166
|
+
concat(materialize_icon(icon_name(options), options))
|
167
|
+
concat(options[:label]) if options[:label].present?
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
149
171
|
#
|
150
172
|
# Details of a thingy in a pull down list
|
151
173
|
#
|
@@ -163,8 +185,9 @@ module CoreLinkHelper
|
|
163
185
|
return unless can? :read, obj
|
164
186
|
|
165
187
|
data = {}
|
188
|
+
confirmation_data(options, data)
|
166
189
|
link_classes = tooltip_data(options, data)
|
167
|
-
content_tag(:a, href: path,
|
190
|
+
content_tag(:a, href: path, class: link_classes, data: data) do
|
168
191
|
concat(materialize_icon(icon_name(options, 'info'), options))
|
169
192
|
concat(options[:label]) if options[:label].present?
|
170
193
|
end
|
@@ -218,13 +241,29 @@ module CoreLinkHelper
|
|
218
241
|
|
219
242
|
data = { method: :delete }
|
220
243
|
confirmation_data(options, data, t('links.deletion_confirmation', name: obj.class.to_s.underscore.humanize))
|
221
|
-
link_classes = tooltip_data(options, data)
|
244
|
+
link_classes = tooltip_data(options, data, I18n.t('ui_form.actions.delete'))
|
222
245
|
content_tag(:a, href: path, class: link_classes, data: data) do
|
223
246
|
concat(materialize_icon(icon_name(options, 'delete'), options))
|
224
247
|
concat(options[:label]) if options[:label].present?
|
225
248
|
end
|
226
249
|
end
|
227
250
|
|
251
|
+
#
|
252
|
+
# Delete an thingy
|
253
|
+
#
|
254
|
+
def delete_button_tag(obj, path, options = {})
|
255
|
+
return unless can? :destroy, obj
|
256
|
+
|
257
|
+
data = { method: :delete }
|
258
|
+
confirmation_data(options, data, t('links.deletion_confirmation', name: obj.class.to_s.underscore.humanize))
|
259
|
+
link_classes = tooltip_data(options, data)
|
260
|
+
%w[btn red].each { |c| link_classes << c unless link_classes.include?(c) }
|
261
|
+
content_tag(:a, class: link_classes, href: path, data: data) do
|
262
|
+
concat(materialize_icon(icon_name(options, 'delete'), options))
|
263
|
+
concat(options[:label]) if options[:label].present?
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
228
267
|
#
|
229
268
|
# Create a thingy in a pull-down list
|
230
269
|
#
|
@@ -244,9 +283,9 @@ module CoreLinkHelper
|
|
244
283
|
return unless can? :create, obj
|
245
284
|
|
246
285
|
data = {}
|
247
|
-
confirmation_data(options, data, t('links.
|
286
|
+
confirmation_data(options, data, t('links.creation_confirmation', name: obj.class.to_s.underscore.humanize))
|
248
287
|
link_classes = tooltip_data(options, data)
|
249
|
-
content_tag(:a, href: path, class: link_classes, data:
|
288
|
+
content_tag(:a, href: path, class: link_classes, data: data) do
|
250
289
|
concat(materialize_icon(icon_name(options, 'add'), options))
|
251
290
|
concat(options[:label]) if options[:label].present?
|
252
291
|
end
|
@@ -410,7 +449,7 @@ module CoreLinkHelper
|
|
410
449
|
end
|
411
450
|
|
412
451
|
def tooltip_data(options, data, default = nil)
|
413
|
-
link_classes = options[:link_classes] || []
|
452
|
+
link_classes = Array.wrap(options[:link_classes]) || []
|
414
453
|
tooltip = options[:tooltip] || default
|
415
454
|
if tooltip.present?
|
416
455
|
link_classes << 'tooltipped'
|
@@ -18,12 +18,13 @@ module CoreNavBarHelper
|
|
18
18
|
states << 'read-only' if read_only
|
19
19
|
states << 'locked' unless feature_enabled
|
20
20
|
states << 'hidden' unless feature_visible
|
21
|
-
|
21
|
+
case names
|
22
|
+
when String
|
22
23
|
states << 'active' if names.eql?(controller.controller_name)
|
23
|
-
|
24
|
-
states << 'active' if names.to_s.eql?(controller.controller_name)
|
25
|
-
elsif names.is_a? Array
|
24
|
+
when Array
|
26
25
|
states << 'active' if names.include?(controller.controller_name)
|
26
|
+
else
|
27
|
+
states << 'active' if names.to_s.eql?(controller.controller_name)
|
27
28
|
end
|
28
29
|
states.join(' ')
|
29
30
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Methods useful for building out tables
|
5
|
+
#
|
6
|
+
module CoreTableHelper
|
7
|
+
#
|
8
|
+
# Format the table header
|
9
|
+
# @param name - Name of the header, either the text or a localized value
|
10
|
+
# @param classes - Additional classes to apply to the header
|
11
|
+
# @param priority - Priority to show the column when the screen gets small, the lower value is higher priority
|
12
|
+
# @param visible - This column should be visible
|
13
|
+
#
|
14
|
+
def table_header_actions_tag(name: :actions, classes: %w[actions], priority: 2, visible: true)
|
15
|
+
return unless visible
|
16
|
+
|
17
|
+
table_header_tag(name, classes: classes, priority: priority, visible: visible)
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Format the table header
|
22
|
+
# @param name - Name of the header, either the text or a localized value
|
23
|
+
# @param classes - Additional classes to apply to the header
|
24
|
+
# @param priority - Priority to show the column when the screen gets small, the lower value is higher priority
|
25
|
+
# @param visible - This column should be visible
|
26
|
+
#
|
27
|
+
def table_header_tag(name, classes: [], priority: 1, visible: true)
|
28
|
+
return unless visible
|
29
|
+
|
30
|
+
options = { data: { priority: priority } }
|
31
|
+
options[:class] = classes if classes.present?
|
32
|
+
content_tag(:th, options) { table_header_text(name) }
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# First look to see if a localized string was passed in,
|
37
|
+
# then try to look in table.headers....
|
38
|
+
# lastly return the titleized string
|
39
|
+
# @param name - Name of the header, either the text or a localized value
|
40
|
+
#
|
41
|
+
def table_header_text(name)
|
42
|
+
if I18n.exists?(name)
|
43
|
+
t(name)
|
44
|
+
elsif I18n.exists?("table.headers.#{name}")
|
45
|
+
t("table.headers.#{name}")
|
46
|
+
elsif I18n.exists?("core_table.headers.#{name}")
|
47
|
+
t("core_table.headers.#{name}")
|
48
|
+
else
|
49
|
+
name.to_s.titleize
|
50
|
+
end
|
51
|
+
rescue StandardError
|
52
|
+
name
|
53
|
+
end
|
54
|
+
|
55
|
+
def dynamic_custom_modal(anchor, label, title, view_endpoint, _options = {})
|
56
|
+
datum = { view_url: view_endpoint }
|
57
|
+
content_tag(:span) do
|
58
|
+
concat(content_tag(:a, href: "##{anchor}", class: 'modal-trigger') do
|
59
|
+
concat(materialize_icon(label))
|
60
|
+
end)
|
61
|
+
concat(content_tag(:div, id: anchor, class: 'modal modal-fixed-footer', data: datum) do
|
62
|
+
concat(content_tag(:div, class: 'modal-content') do
|
63
|
+
concat(content_tag(:h2, class: 'center') do
|
64
|
+
concat(content_tag(:span, title))
|
65
|
+
end)
|
66
|
+
concat(content_tag(:div, class: 'center-align') do
|
67
|
+
concat(content_tag(:div, class: 'progress red lighten-4') do
|
68
|
+
tag(:div, class: 'indeterminate red')
|
69
|
+
end)
|
70
|
+
end)
|
71
|
+
end)
|
72
|
+
concat(content_tag(:div, class: 'modal-footer') do
|
73
|
+
concat(content_tag(:a, href: '#', class: 'modal-action modal-close btn btn-flat') do
|
74
|
+
concat('Close')
|
75
|
+
end)
|
76
|
+
end)
|
77
|
+
end)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -70,7 +70,7 @@ module ModelModalHelper
|
|
70
70
|
|
71
71
|
def model_modal_action(model, _options = {})
|
72
72
|
content_tag(:a, class: 'modal-trigger', href: "#modal-#{model.id}") do
|
73
|
-
concat(model.name
|
73
|
+
concat(model.name)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -92,7 +92,7 @@ module ModelModalHelper
|
|
92
92
|
concat(model_modal_tabs(model, options))
|
93
93
|
concat(model_modal_fields_tab(model, options))
|
94
94
|
concat(model_modal_standard_tab(model, options))
|
95
|
-
concat(model_modal_logs_tab(model, options)) if model.respond_to?(:logs)
|
95
|
+
concat(model_modal_logs_tab(model, options)) if model.respond_to?(:logs) && options[:show_audit_logs]
|
96
96
|
end)
|
97
97
|
end
|
98
98
|
end
|
@@ -172,7 +172,7 @@ module ModelModalHelper
|
|
172
172
|
def model_modal_field(model, field_name)
|
173
173
|
content_tag(:tr) do
|
174
174
|
concat(content_tag(:th, class: 'right-align') do
|
175
|
-
field_name
|
175
|
+
field_name
|
176
176
|
end)
|
177
177
|
concat(content_tag(:td) do
|
178
178
|
model_modal_field_value(model, field_name)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
- create_label ||= t('ui_form.actions.create')
|
2
|
+
- cancel_label ||= t('ui_form.actions.cancel')
|
3
|
+
.card-action
|
4
|
+
.row
|
5
|
+
.col.s6.center-align
|
6
|
+
%a.btn-large.waves-effect.waves-light.grey{href: form_cancel_path}
|
7
|
+
= cancel_label
|
8
|
+
%i.material-icons.right cancel
|
9
|
+
.col.s6.center-align
|
10
|
+
%button.btn-large.waves-effect.waves-light{type: :submit}
|
11
|
+
= create_label
|
12
|
+
%i.material-icons.right save
|
@@ -0,0 +1,10 @@
|
|
1
|
+
.card-action
|
2
|
+
.row
|
3
|
+
.col.s6.center-align
|
4
|
+
%a.btn-large.waves-effect.waves-light.grey{href: form_cancel_path}
|
5
|
+
= t('ui_form.actions.cancel')
|
6
|
+
%i.material-icons.right cancel
|
7
|
+
.col.s6.center-align
|
8
|
+
%button.btn-large.waves-effect.waves-light{type: :submit}
|
9
|
+
= t('ui_form.actions.update')
|
10
|
+
%i.material-icons.right save
|
@@ -1,21 +1,19 @@
|
|
1
1
|
- title t('.title', name: @cron_tab.name)
|
2
2
|
|
3
|
-
|
4
|
-
%
|
5
|
-
%
|
6
|
-
|
7
|
-
.container
|
8
|
-
%form{action: model_path(@cron_tab), method: :post}
|
9
|
-
%input{type: :hidden, value: form_authenticity_token, name: 'authenticity_token'}
|
10
|
-
%input{type: :hidden, name: '_method', value: 'put'}
|
3
|
+
%form{action: model_path(@cron_tab), method: :post}
|
4
|
+
%input{type: :hidden, value: form_authenticity_token, name: :authenticity_token}
|
5
|
+
%input{type: :hidden, name: '_method', value: :put}
|
6
|
+
.container
|
11
7
|
.row
|
12
8
|
.col.s12
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
9
|
+
.card
|
10
|
+
.card-content
|
11
|
+
.card-title= t('.title', name: @cron_tab.name)
|
12
|
+
.row
|
13
|
+
= form_text_field(@cron_tab, :min)
|
14
|
+
= form_text_field(@cron_tab, :hour)
|
15
|
+
= form_text_field(@cron_tab, :mday)
|
16
|
+
= form_text_field(@cron_tab, :month)
|
17
|
+
= form_text_field(@cron_tab, :wday)
|
18
|
+
= form_checkbox(@cron_tab, :enabled)
|
19
|
+
= render 'common/update_actions', form_cancel_path: index_path
|