microservice 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/config/microservice_manifest.js +2 -0
  6. data/app/assets/images/microservice/favicon.ico +0 -0
  7. data/app/assets/images/microservice/logo.svg +51 -0
  8. data/app/assets/javascripts/microservice/application.js +21 -0
  9. data/app/assets/javascripts/microservice/microservice.js +0 -0
  10. data/app/assets/stylesheets/microservice/application.css +16 -0
  11. data/app/assets/stylesheets/microservice/microservice.css +0 -0
  12. data/app/controllers/microservice/application_controller.rb +58 -0
  13. data/app/controllers/microservice/entities_controller.rb +138 -0
  14. data/app/controllers/microservice/omniauth_callbacks_controller.rb +36 -0
  15. data/app/controllers/microservice/welcome_controller.rb +8 -0
  16. data/app/helpers/microservice/application_helper.rb +216 -0
  17. data/app/helpers/microservice/breadcrumbs_helper.rb +89 -0
  18. data/app/jobs/microservice/application_job.rb +5 -0
  19. data/app/mailers/microservice/application_mailer.rb +13 -0
  20. data/app/mailers/microservice/devise_mailer.rb +13 -0
  21. data/app/models/microservice/concerns/entity_cloneable.rb +40 -0
  22. data/app/models/microservice/concerns/entity_model.rb +118 -0
  23. data/app/models/microservice/concerns/entity_movable.rb +27 -0
  24. data/app/models/microservice/concerns/entity_naming.rb +95 -0
  25. data/app/models/microservice/concerns/user_model.rb +36 -0
  26. data/app/views/layouts/microservice/application.html.erb +26 -0
  27. data/app/views/layouts/microservice/mailer.html.erb +13 -0
  28. data/app/views/layouts/microservice/mailer.text.erb +1 -0
  29. data/app/views/microservice/common/_no_data.html.erb +6 -0
  30. data/app/views/microservice/common/error.html.erb +7 -0
  31. data/app/views/microservice/common/error.json.jbuilder +3 -0
  32. data/app/views/microservice/entities/_card.html.erb +17 -0
  33. data/app/views/microservice/entities/_form.html.erb +0 -0
  34. data/app/views/microservice/entities/edit.html.erb +16 -0
  35. data/app/views/microservice/entities/index.html.erb +7 -0
  36. data/app/views/microservice/entities/new.html.erb +19 -0
  37. data/app/views/microservice/entities/show.html.erb +3 -0
  38. data/app/views/microservice/welcome/index.html.erb +1 -0
  39. data/config/initializers/devise.rb +270 -0
  40. data/config/initializers/microservice.rb +5 -0
  41. data/config/initializers/sso.rb +78 -0
  42. data/config/locales/en.yml +55 -0
  43. data/config/routes.rb +5 -0
  44. data/db/migrate/20170618202500_create_users.rb +51 -0
  45. data/lib/microservice.rb +27 -0
  46. data/lib/microservice/engine.rb +16 -0
  47. data/lib/microservice/settings.rb +62 -0
  48. data/lib/microservice/version.rb +3 -0
  49. data/lib/tasks/microservice_tasks.rake +4 -0
  50. metadata +330 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 638eb468fd9aba630ab46f343f1e9128cff3b9a2
4
+ data.tar.gz: 4014d8e0f312404981ff47b7f80e4ec04ea833d2
5
+ SHA512:
6
+ metadata.gz: 97c6f72ba6ee6e9c67f9bca810513d9bf48c52494d719d77a0556b3e56c4772a82adc6f96b9332016cb179047a860e2a7e2fd3f5277f64433b959a1393b2cef6
7
+ data.tar.gz: a20a736752df28fa1888735b65e0c80cbbd28dd36c8f6ce73ed9a34445fb31d9397bae0bbd3105770f107ff3303c8bf6293362002329471482dd630beeb1dbae
@@ -0,0 +1,20 @@
1
+ Copyright 2017 petr
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ # Microservice
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'microservice'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install microservice
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,37 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Microservice'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ require 'bundler/gem_tasks'
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+
37
+ task default: :test
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/microservice .js
2
+ //= link_directory ../stylesheets/microservice .css
@@ -0,0 +1,51 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
6
+ xmlns:cc="http://creativecommons.org/ns#"
7
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
+ xmlns:svg="http://www.w3.org/2000/svg"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ version="1.1"
11
+ width="35"
12
+ height="35"
13
+ id="svg2"
14
+ style="enable-background:new">
15
+ <defs
16
+ id="defs3213" />
17
+ <metadata
18
+ id="metadata3216">
19
+ <rdf:RDF>
20
+ <cc:Work
21
+ rdf:about="">
22
+ <dc:format>image/svg+xml</dc:format>
23
+ <dc:type
24
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
25
+ <dc:title></dc:title>
26
+ </cc:Work>
27
+ </rdf:RDF>
28
+ </metadata>
29
+ <g
30
+ transform="translate(0,-1017.3622)"
31
+ id="layer1">
32
+
33
+ <path
34
+ d="m 9.3358801,1034.7872 c 0,3.2684 2.0625189,5.8776 5.4121419,6.774 l 0,-13.3562 c -3.427268,0.9314 -5.4121419,3.3487 -5.4121419,6.5822"
35
+ id="path3092"
36
+ style="fill:#00adef;fill-opacity:1;fill-rule:nonzero;stroke:none" />
37
+ <path
38
+ d="m 24.482915,1042.5344 c -2.064648,1.9848 -4.946437,3.115 -7.749637,3.115 -2.959922,0 -5.529727,-1.0151 -7.6324309,-2.9615 -2.2975551,-2.0999 -3.4271301,-4.7474 -3.4271301,-7.7891 0,-3.659 1.751864,-6.9693 4.867779,-9.0308 1.908552,-1.2488 4.127903,-1.793 7.009026,-1.793 l 0.585385,0 0,17.6049 c 3.542517,-0.6279 5.878894,-3.4324 5.878894,-6.8578 0,-2.4941 -1.245626,-4.6323 -3.426712,-5.8392 l 0,-4.2451 c 4.672687,1.9464 7.165335,5.5287 7.165335,10.0843 0,3.08 -1.090751,5.6473 -3.270509,7.7123 z m -7.768438,-21.1418 c -7.4272229,0 -13.4695365,6.0415 -13.4695365,13.4679 0,7.4263 6.0423136,13.4678 13.4695365,13.4678 7.425898,0 13.467761,-6.0415 13.467761,-13.4678 0,-7.4264 -6.041863,-13.4679 -13.467761,-13.4679"
39
+ id="path3094"
40
+ style="fill:#00adef;fill-opacity:1;fill-rule:nonzero;stroke:none" />
41
+ <path
42
+ d="m 16.714477,1048.3283 c -7.4272229,0 -13.4695365,-6.0415 -13.4695365,-13.4678 0,-7.4264 6.0423136,-13.4679 13.4695365,-13.4679 7.425898,0 13.467761,6.0415 13.467761,13.4679 0,7.4263 -6.041863,13.4678 -13.467761,13.4678 z m 0,-30.1797 c -9.2166887,0 -16.7144779481173,7.4961 -16.7144779481173,16.7119 0,9.2157 7.4977892481173,16.7153 16.7144779481173,16.7153 9.215679,0 16.711761,-7.4996 16.711761,-16.7153 0,-9.2158 -7.496082,-16.7119 -16.711761,-16.7119"
43
+ id="path3096"
44
+ style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" />
45
+ <path
46
+ d="M 14.733063,28.092289 C 12.447643,27.690017 10.345657,26.570887 8.725703,24.893878 7.7594131,23.893556 7.3214289,23.283478 6.7759417,22.178014 5.1940816,18.972275 5.3977445,14.945377 7.296731,11.880771 8.3247656,10.221718 9.9124261,8.7781985 11.639471,7.9323021 13.149721,7.1925905 14.639655,6.8588338 16.788092,6.7789715 l 1.347922,-0.050105 0,8.8090145 0,8.809015 0.243068,-0.05368 c 3.059836,-0.675748 5.155351,-2.899105 5.593554,-5.934801 0.174469,-1.208652 -0.105858,-2.899266 -0.66457,-4.007942 -0.434183,-0.861564 -1.44221,-1.947392 -2.321527,-2.500705 l -0.375651,-0.236379 0,-2.0819735 0,-2.0819736 0.198874,0.061739 c 0.782137,0.242811 2.527085,1.3252913 3.432375,2.1292773 2.33842,2.0767458 3.445966,4.5865178 3.445966,7.8087788 0,2.98076 -0.865851,5.210388 -2.821421,7.265358 -1.707753,1.794557 -3.884455,2.95599 -6.343718,3.384849 -0.945796,0.164934 -2.832458,0.161372 -3.789901,-0.0072 l 0,4e-6 z m 0.04419,-10.604814 0,-6.679276 -0.198874,0.06014 c -1.370943,0.414598 -2.540847,1.090252 -3.434225,1.983364 -0.537314,0.537155 -0.754424,0.83951 -1.082664,1.50776 -0.5845202,1.189997 -0.7152898,1.761272 -0.7072758,3.089771 0.0077,1.276318 0.1871789,2.086659 0.6780658,3.061431 0.593308,1.178151 1.29514,1.953624 2.467482,2.726388 0.524104,0.34547 1.850849,0.925594 2.122812,0.928209 0.145962,0.0014 0.154679,-0.374934 0.154679,-6.67779 l 0,0 z"
47
+ transform="translate(0,1017.3622)"
48
+ id="path4463"
49
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.08838835;stroke-opacity:1" />
50
+ </g>
51
+ </svg>
@@ -0,0 +1,21 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require jquery-ui
16
+ //= require turbolinks
17
+ //= require i18n
18
+ //= require i18n/translations
19
+ //= require cocoon
20
+ //= require js-routes
21
+ //= require_tree .
@@ -0,0 +1,16 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_self
14
+ *= require jquery-ui
15
+ *= require_tree .
16
+ */
@@ -0,0 +1,58 @@
1
+ module Microservice
2
+ class ApplicationController < ActionController::Base
3
+
4
+ protect_from_forgery with: :exception
5
+
6
+ layout 'microservice/application'
7
+
8
+ class_attribute :allow_custom_type
9
+ class_attribute :entity_class_for_link
10
+
11
+ around_action :set_current_user
12
+
13
+ protected
14
+
15
+ def render_403(options = {})
16
+ render_error({message: :notice_not_authorized, status: 403}.merge(options))
17
+ return false
18
+ end
19
+
20
+ def render_404(options = {})
21
+ render_error({message: :notice_entity_not_found, status: 404}.merge(options))
22
+ return false
23
+ end
24
+
25
+ def render_validation_errors(errors)
26
+ @errors = errors
27
+ render template: 'mini_easy/common/error', formats: params[:format]
28
+ end
29
+
30
+ def render_entity_validation_errors(entity)
31
+ render_validation_errors(entity.errors.full_messages)
32
+ end
33
+
34
+ def render_error(arg)
35
+ arg = {message: arg} if !arg.is_a?(Hash)
36
+
37
+ message = arg[:message]
38
+ message = I18n.t(message) if message.is_a?(Symbol)
39
+
40
+ @errors = [message]
41
+ @status = arg[:status] || 500
42
+
43
+ render template: 'common/error', status: @status, formats: params[:format]
44
+ end
45
+
46
+ def set_current_user
47
+ User.current = current_user
48
+ yield
49
+ ensure
50
+ User.current = nil
51
+ end
52
+
53
+ def current_user_ip
54
+ request.env['HTTP_X_FORWARDED_FOR'].blank? ? request.remote_ip : request.env['HTTP_X_FORWARDED_FOR'].to_s.split(',').first
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,138 @@
1
+ module Microservice
2
+ class ApplicationController < ::Microservice::ApplicationController
3
+
4
+ class_attribute :entity_class
5
+
6
+ before_action :find_entity_class, only: [:new, :create]
7
+ before_action :find_entity, only: [:show, :edit, :update, :destroy]
8
+ before_action :find_copy_from, only: [:new, :create]
9
+ before_action :create_entity, only: [:new, :create]
10
+ before_action :find_parent_entity, only: [:index, :show, :new, :create, :edit, :update, :destroy]
11
+ before_action :load_entities, only: [:index]
12
+ before_action :assign_attributes, only: [:new, :create, :edit, :update]
13
+
14
+ def index
15
+ render layout: !request.xhr?
16
+ end
17
+
18
+ def show
19
+ render layout: !request.xhr?
20
+ end
21
+
22
+ def new
23
+ render layout: !request.xhr?
24
+ end
25
+
26
+ def create
27
+ if @entity.save
28
+ respond_to do |format|
29
+ format.html {
30
+ flash[:notice] = t(:notice_successful_create)
31
+ redirect_to polymorphic_path(@entity.model_route_array)
32
+ }
33
+ format.js
34
+ end
35
+ else
36
+ respond_to do |format|
37
+ format.html {render action: 'new', layout: !request.xhr?}
38
+ format.js
39
+ end
40
+ end
41
+ end
42
+
43
+ def edit
44
+ render layout: !request.xhr?
45
+ end
46
+
47
+ def update
48
+ if @entity.save
49
+ respond_to do |format|
50
+ format.html {
51
+ flash[:notice] = t(:notice_successful_update)
52
+ redirect_to polymorphic_path(@entity.model_route_array)
53
+ }
54
+ format.js
55
+ end
56
+ else
57
+ respond_to do |format|
58
+ format.html {render action: 'edit', layout: !request.xhr?}
59
+ format.js
60
+ end
61
+ end
62
+ end
63
+
64
+ def destroy
65
+ @entity.destroy
66
+
67
+ respond_to do |format|
68
+ format.html {
69
+ flash[:notice] = t(:notice_successful_delete)
70
+ redirect_to polymorphic_path(entity_class.class_route_array)
71
+ }
72
+ format.js
73
+ end
74
+ end
75
+
76
+ def search
77
+ render json: self.entity_class.search(params[:q])
78
+ end
79
+
80
+ protected
81
+
82
+ def find_entity_class
83
+ @current_entity_class ||=
84
+ if allow_custom_type && params[:type]
85
+ params[:type].safe_constantize
86
+ elsif !allow_custom_type
87
+ self.entity_class
88
+ end
89
+ render_404 if !@current_entity_class
90
+ rescue NameError
91
+ render_404
92
+ end
93
+
94
+ def entity_symbol
95
+ self.entity_class.name.underscore.to_sym
96
+ end
97
+
98
+ def find_entity
99
+ @entity = self.entity_class.find(params[:id])
100
+ @parent_entity = @entity.parent_entity
101
+ rescue ActiveRecord::RecordNotFound
102
+ render_404
103
+ end
104
+
105
+ def find_parent_entity
106
+ @parent_entity = self.entity_class.parent_entity_class.find(params[self.entity_class.parent_entity_id_symbol]) if self.entity_class.parent_entity_class
107
+ rescue ActiveRecord::RecordNotFound
108
+ render_404
109
+ end
110
+
111
+ def find_copy_from
112
+ @copy_from = @current_entity_class.find(params[:copy_from]) if params[:copy_from]
113
+ rescue ActiveRecord::RecordNotFound
114
+ render_404
115
+ end
116
+
117
+ def create_entity
118
+ @entity = @current_entity_class.copy_from(@copy_from) if @copy_from
119
+ @entity ||= @current_entity_class.new
120
+ end
121
+
122
+ def load_entities
123
+ @entities = self.entity_class.sorted
124
+ end
125
+
126
+ def entity_params
127
+ params.require(entity_symbol).permit([])
128
+ end
129
+
130
+ def assign_attributes
131
+ @entity.parent_entity ||= @parent_entity if @parent_entity
132
+ @entity.attributes = entity_params if params[entity_symbol]
133
+ @entity.author = current_user if @entity.respond_to?(:author_id) && @entity.new_record?
134
+ @entity.updated_by = current_user if @entity.respond_to?(:updated_by_id) && !@entity.new_record?
135
+ end
136
+
137
+ end
138
+ end
@@ -0,0 +1,36 @@
1
+ module Microservice
2
+ class OmniauthCallbacksController < ::Microservice::ApplicationController
3
+
4
+ def sso
5
+ @user = User.find_or_initialize_by(uuid: request.env['omniauth.auth']['uid'])
6
+
7
+ update_user_from_omniauth(request.env['omniauth.auth'])
8
+
9
+ if @user.new_record?
10
+ @user.password = Devise.friendly_token[0, 20]
11
+ @user.skip_confirmation!
12
+ end
13
+
14
+ if @user.save
15
+ flash[:notice] = t('devise.omniauth_callbacks.success', kind: 'SSO')
16
+ sign_in_and_redirect @user, event: :authentication
17
+ else
18
+ Rails.logger.error @user.errors.full_messages
19
+ redirect_to root_url, alert: t(:notice_cannot_create_account)
20
+ end
21
+ end
22
+
23
+ protected
24
+
25
+ def update_user_from_omniauth(omniauth_attrs)
26
+ @user.first_name = omniauth_attrs['info']['first_name']
27
+ @user.last_name = omniauth_attrs['info']['last_name']
28
+ @user.username = omniauth_attrs['info']['username']
29
+ @user.name = omniauth_attrs['info']['name']
30
+ @user.email = omniauth_attrs['info']['email']
31
+ @user.image = omniauth_attrs['info']['image']
32
+ @user.status = omniauth_attrs['info']['status']
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,8 @@
1
+ module Microservice
2
+ class WelcomeController < ::Microservice::ApplicationController
3
+
4
+ def index
5
+ end
6
+
7
+ end
8
+ end
@@ -0,0 +1,216 @@
1
+ module Microservice
2
+ module ApplicationHelper
3
+
4
+ def application_name
5
+ Microservice::Settings.application_name
6
+ end
7
+
8
+ def render_flash_messages
9
+ s = ''
10
+ flash.each do |k, v|
11
+ case k
12
+ when 'alert'
13
+ message_css = 'warning'
14
+ icon_css = 'warning'
15
+ else
16
+ message_css = 'success'
17
+ icon_css = 'info'
18
+ end
19
+ s << "<div class=\"ui icon #{message_css} message\">"
20
+ s << '<i class="close icon"></i>'
21
+ s << "<i class=\"#{icon_css} icon\"></i>"
22
+ s << '<div class=\"content\"></div>'
23
+ s << "<div class=\"header\">#{v}</div>"
24
+ s << '</div>'
25
+ end
26
+ s.html_safe
27
+ end
28
+
29
+ def html_title(*args)
30
+ if args.empty?
31
+ title = [application_name]
32
+ title.concat(@html_title || [])
33
+ title.reject(&:blank?).join(' - ')
34
+ else
35
+ @html_title ||= []
36
+ @html_title += args
37
+ end
38
+ end
39
+
40
+ def title(*args)
41
+ strings = args.map do |arg|
42
+ if arg.is_a?(Array) && arg.size >= 2
43
+ link_to(*arg)
44
+ else
45
+ h(arg.to_s)
46
+ end
47
+ end
48
+
49
+ html_title(args.reverse.map {|s| (s.is_a?(Array) ? s.first : s).to_s})
50
+
51
+ content_tag('h1', strings.join(' &#187; ').html_safe, class: 'ui header')
52
+ end
53
+
54
+ def favicon_path
55
+ image_path('microservice/favicon.ico')
56
+ end
57
+
58
+ def html_title_from_entity
59
+ if @entity
60
+ case action_name
61
+ when 'show'
62
+ html_title @entity.heading_show
63
+ when 'new', 'create'
64
+ html_title @entity.heading_new
65
+ when 'edit', 'update'
66
+ html_title @entity.heading_edit
67
+ else
68
+ html_title
69
+ end
70
+ elsif controller.respond_to?(:entity_class) && controller.entity_class
71
+ html_title controller.entity_class.heading_index
72
+ else
73
+ html_title
74
+ end
75
+ end
76
+
77
+ def format_date(date)
78
+ return nil unless date
79
+
80
+ ::I18n.l(date.to_date, {format: '%d.%m.%Y'})
81
+ end
82
+
83
+ def format_time(time, include_date = true)
84
+ return nil unless time
85
+ options = {}
86
+ options[:format] = '%H:%M'
87
+ time = time.to_time if time.is_a?(String)
88
+ local = (time.utc? ? time.localtime : time)
89
+ (include_date ? "#{format_date(local)} " : '') + ::I18n.l(local, options)
90
+ end
91
+
92
+ def css_active_menu_item(identificator)
93
+ css = ['item']
94
+ css << 'active' if active_link?(identificator)
95
+ css.join(' ')
96
+ end
97
+
98
+ def link_to_entity(klass_or_entity, action = nil, options = {})
99
+ entity_class = klass_or_entity.is_a?(ActiveRecord::Base) ? klass_or_entity.class : klass_or_entity
100
+ entity = klass_or_entity.is_a?(ActiveRecord::Base) ? klass_or_entity : nil
101
+ options, action = action, nil if action.is_a?(Hash) && action.extractable_options?
102
+
103
+ action ||= (entity ? :show : :index)
104
+
105
+ if options[:css_item]
106
+ css = css_active_menu_item(entity_class)
107
+ options[:class] ||= ''
108
+ options[:class] << (' ' + css) if css.present?
109
+
110
+ options[:no_icon] = true if !options.key?(:no_icon)
111
+ end
112
+
113
+ case action
114
+ when :index
115
+ # if @entity && entity_class.parent_entity_class == @entity.class && @parent_entity.nil?
116
+ # route_array = entity_class.class_route_array(@entity)
117
+ # else
118
+ # route_array = entity_class.class_route_array(@parent_entity)
119
+ # end
120
+
121
+ link_to(polymorphic_path(entity_class.class_route_array(@parent_entity)), class: options[:class], title: entity_class.title_index, data: options[:data]) do
122
+ content_tag(:i, '', class: (options[:no_icon] ? '' : 'icon ' + entity_class.css_class)) + entity_class.button_index
123
+ end
124
+ when :show
125
+ link_to(polymorphic_path(entity.model_route_array), class: options[:class], title: entity.title_show, data: options[:data]) do
126
+ content_tag(:i, '', class: (options[:no_icon] ? '' : 'info icon')) + (options[:no_label] ? '' : entity.button_show)
127
+ end
128
+ when :new
129
+ link_to(new_polymorphic_path(entity_class.class_route_array(@parent_entity)), class: options[:class], title: entity_class.title_new, data: options[:data]) do
130
+ content_tag(:i, '', class: (options[:no_icon] ? '' : 'add icon')) + entity_class.button_new
131
+ end
132
+ when :edit
133
+ link_to(edit_polymorphic_path(entity.model_route_array), class: options[:class], title: entity.title_edit, data: options[:data]) do
134
+ content_tag(:i, '', class: (options[:no_icon] ? '' : 'edit icon')) + (options[:no_label] ? '' : entity.button_edit)
135
+ end
136
+ when :delete
137
+ link_to(polymorphic_path(entity.model_route_array), class: options[:class], title: entity.title_delete, data: {confirm: t(:text_are_you_sure), method: :delete}) do
138
+ content_tag(:i, '', class: (options[:no_icon] ? '' : 'trash icon'))
139
+ end
140
+ end
141
+ end
142
+
143
+ def link_to_function(name, function = nil, html_options = {}, &block)
144
+ if block_given?
145
+ content_tag(:a, {href: '#', onclick: "#{name}; return false;"}.merge(function || {}), &block)
146
+ else
147
+ content_tag(:a, name, {href: '#', onclick: "#{function}; return false;"}.merge(html_options))
148
+ end
149
+ end
150
+
151
+ def markdown(text)
152
+ options = {
153
+ filter_html: true,
154
+ hard_wrap: true,
155
+ link_attributes: {rel: 'nofollow', target: '_blank'},
156
+ space_after_headers: true,
157
+ fenced_code_blocks: true
158
+ }
159
+
160
+ extensions = {
161
+ autolink: true,
162
+ superscript: true,
163
+ disable_indented_code_blocks: true
164
+ }
165
+
166
+ renderer = Redcarpet::Render::HTML.new(options)
167
+ markdown = Redcarpet::Markdown.new(renderer, extensions)
168
+
169
+ markdown.render(text.to_s).html_safe
170
+ end
171
+
172
+ def show_top_menu_new?
173
+ controller.respond_to?(:entity_class) && controller.entity_class && !controller.entity_class.hide_top_menu_new
174
+ end
175
+
176
+ def show_top_menu_search?
177
+ controller.respond_to?(:entity_class) && controller.entity_class && !controller.entity_class.hide_top_menu_search
178
+ end
179
+
180
+ def home_link(namespace = nil, options = {})
181
+ options = namespace if namespace.is_a?(Hash)
182
+
183
+ if namespace == :admin
184
+ link_to(t(:button_administration), main_app.admin_path, {title: t(:title_administration), class: css_active_menu_item(:administration), data: {turbolinks: false}}.merge(options))
185
+ else
186
+ link_to(t(:button_home), main_app.root_path, {title: t(:title_home), class: css_active_menu_item(:home), data: {turbolinks: false}}.merge(options))
187
+ end
188
+ end
189
+
190
+ def login_link(options = {})
191
+ css = ['item']
192
+ css << 'active' if controller_name == 'UsersController'
193
+
194
+ link_to(t(:button_log_in), main_app.new_user_session_path, {title: t(:title_log_in), class: css.join(' '), data: {turbolinks: false}}.merge(options))
195
+ end
196
+
197
+ def sso_login_link(options = {})
198
+ css = ['item']
199
+
200
+ link_to(t(:button_log_in), main_app.user_sso_omniauth_authorize_path, {title: t(:title_log_in), class: css.join(' '), data: {turbolinks: false}}.merge(options))
201
+ end
202
+
203
+ def signup_link(options = {})
204
+ css = ['item']
205
+
206
+ link_to(t(:button_sign_up), 'https://www.easysoftware.com', {title: t(:title_sign_up), class: css.join(' '), data: {turbolinks: false}}.merge(options))
207
+ end
208
+
209
+ def logout_link(options = {})
210
+ css = ['item']
211
+
212
+ link_to(t(:button_log_out), main_app.destroy_user_session_path, {title: t(:title_log_out), class: css.join(' '), method: :delete, data: {turbolinks: false}}.merge(options))
213
+ end
214
+
215
+ end
216
+ end