lesli 5.0.15 → 5.0.17

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6139b8579dcd823c2ace74c59a1abb6bf0fa698e49ac12677dc722d7644418d
4
- data.tar.gz: 44d42590285bd4c34280023c8d2a10a35bc6f7dedada68e763d373273ac34a37
3
+ metadata.gz: ae810e2b4f383cfbbb6177f41376811fab4e2f44de2a64abccf760c35bf0582f
4
+ data.tar.gz: bfb3145090879a29edc68e0374fa14707d372f1c7df9bdc4943e9fb0935e35f3
5
5
  SHA512:
6
- metadata.gz: 24631fe19eff97530bfb697e64b4b108c652d678fab327455523b225ce1cfaa226e98d871219bfc7e5b9e17a3025883b249afdb28f896d094f1f32c7e210841c
7
- data.tar.gz: 8542f06c8685005965e492ec85ee0e220ecee747f7c257e24fe4c339f91499a2872761509c3f7bd3c59c4dca6ab93a4b610c48182fdd146e36aea2949fb0a73e
6
+ metadata.gz: e3e14171f1cfae0a81f22bdc3dc1d6098c68bd2dec371b4bb13523e62d8ebebd0b0c56d6bde9008fff978840850727073afa109130622c4c0061fa3b18cf030e
7
+ data.tar.gz: 82acbf8b22a68f05f1641e594a9bde2172328a1fa56d95205881d86bf5720ea64eede35b152fb3612202fc8e9a383cfce39b4b3273a844090a88b0b6985b976d
@@ -32,277 +32,285 @@ Building a better future, one line of code at a time.
32
32
  module Lesli
33
33
  module Shared
34
34
  class DashboardsController < ApplicationLesliController
35
- before_action :set_dashboard, only: [:show, :update, :destroy, :options]
36
-
37
- def index
38
- respond_to do |format|
39
- format.html {}
40
- format.json do
41
- dynamic_info = self.class.dynamic_info
42
- model = dynamic_info[:model]
43
-
44
- dashboards = model.list(current_user, @query)
45
- respond_with_successful(dashboards)
46
- end
47
- end
48
- end
49
-
50
- def show
51
- respond_to do |format|
52
- format.html {}
53
- format.json do
54
- return respond_with_not_found unless @dashboard
55
- respond_with_successful(@dashboard.show)
56
- end
57
- end
58
- end
35
+ #before_action :set_dashboard, only: [:show, :update, :destroy, :options]
59
36
 
60
- def new
37
+ def edit
61
38
  end
62
39
 
63
- def edit
40
+ def show
41
+ builder = LesliSystem::Klass.new(self)
42
+ @dashboard = builder.model.dashboard.first
64
43
  end
65
44
 
66
- # @controller_action_param :name [String] The name of the new dashboard
67
- # @controller_action_param :default [Boolean] A flag that marks this dashboard as default or not. The default dashboard is the dashboard all users will have access to on the root page
68
- # @controller_action_param :main [Boolean] A flag that marks this dashboard as main. Since a user can have multiple dashboards, this is the one they will see on the root page when loging in
69
- # @controller_action_param :roles_id [Integer] The id of the role that will have access to this dashboard
70
- # @controller_action_param :user_main_id [Integer] The id of the user
71
- # @controller_action_param :component_attributes [Array] Array of hashes that represent the attributes of the dashboard components
72
- # @controller_action_param :component_attributes.name [String] The name of this component given to the user
73
- # @controller_action_param :component_attributes.component_id [String] An enum value, that indicates which component is being loaded
74
- # @controller_action_param :component_attributes.layout [Integer] Number from 1 to 12, bigger numbers default to 12, smallest numbers default to 1. The column size that the UI component will use
75
- # @controller_action_param :component_attributes.index [Integer] The position of the component in the layout
76
- # @controller_action_param :component_attributes.configuration [Hash] Specific filtering and configuration of the components
77
- # @return [Json] Json that contains wheter the creation of the dashboard was successful or not.
78
- # If it is not successful, it returns an error message
79
- # @description Creates a new dashboard associated to the *current_user*'s *account*
80
- # @example
81
- # # Executing this controller's action from javascript's frontend
82
- # let data = {
83
- # dashboard: {
84
- # name: "Sales Dashboard",
85
- # default: false,
86
- # roles_id: 3,
87
- # components_attributes: [
88
- # {
89
- # name: 'Projects Count',
90
- # component_id: projects_component,
91
- # layout: 4,
92
- # index: 3,
93
- # configuration: {}
94
- # }, {
95
- # name: 'New Customers Count',
96
- # component_id: new_customers_component,
97
- # layout: 4,
98
- # index: 3,
99
- # configuration: {}
100
- # }
101
- # ]
102
- # }
103
- # };
104
- # this.http.post('127.0.0.1/help/dashboards', data);
105
- def create
106
- dynamic_info = self.class.dynamic_info
107
- module_name = dynamic_info[:module_name]
108
- model = dynamic_info[:model]
109
- full_module_name = dynamic_info[:full_module_name].underscore
110
-
111
- dashboard = model.new(dashboard_params)
112
- dashboard["#{full_module_name}_account_id".to_sym] = current_user.account.id
113
- dashboard.user_creator = current_user
114
-
115
- if dashboard.save
116
- respond_with_successful(dashboard)
117
- else
118
- respond_with_error(dashboard.errors.full_messages.to_sentence)
119
- end
120
- end
121
-
122
- # @controller_action_param :name [String] The name of the new dashboard
123
- # @controller_action_param :default [Boolean] A flag that marks this dashboard as default or not. The default dashboard is the dashboard all users will have access to on the root page
124
- # @controller_action_param :main [Boolean] A flag that marks this dashboard as main. Since a user can have multiple dashboards, this is the one they will see on the root page when loging in
125
- # @controller_action_param :roles_id [Integer] The id of the role that will have access to this dashboard
126
- # @controller_action_param :user_main_id [Integer] The id of the user
127
- # @controller_action_param :component_attributes [Array] Array of hashes that represent the attributes of the dashboard components
128
- # @controller_action_param :component_attributes.name [String] The name of this component given to the user
129
- # @controller_action_param :component_attributes.component_id [String] An enum value, that indicates which component is being loaded
130
- # @controller_action_param :component_attributes.layout [Integer] Number from 1 to 12, bigger numbers default to 12, smallest numbers default to 1. The column size that the UI component will use
131
- # @controller_action_param :component_attributes.index [Integer] The position of the component in the layout
132
- # @controller_action_param :component_attributes.configuration [Hash] Specific filtering and configuration of the components
133
- # @return [Json] Json that contains wheter the dashboard was successfully updated or not.
134
- # If it it not successful, it returns an error message
135
- # @description Updates an existing dashboard associated to the *current_user*'s *account*.
136
- # @example
137
- # # Executing this controller's action from javascript's frontend
138
- # let dashboard_id = 4;
139
- # let data = {
140
- # dashboard: {
141
- # name: "Sales Dashboard",
142
- # default: false,
143
- # roles_id: 3,
45
+ # def index
46
+ # respond_to do |format|
47
+ # format.html {}
48
+ # format.json do
49
+ # dynamic_info = self.class.dynamic_info
50
+ # model = dynamic_info[:model]
51
+
52
+ # dashboards = model.list(current_user, @query)
53
+ # respond_with_successful(dashboards)
54
+ # end
55
+ # end
56
+ # end
57
+
58
+ # def show
59
+ # respond_to do |format|
60
+ # format.html {}
61
+ # format.json do
62
+ # return respond_with_not_found unless @dashboard
63
+ # respond_with_successful(@dashboard.show)
64
+ # end
65
+ # end
66
+ # end
67
+
68
+ # def new
69
+ # end
70
+
71
+ # def edit
72
+ # end
73
+
74
+ # # @controller_action_param :name [String] The name of the new dashboard
75
+ # # @controller_action_param :default [Boolean] A flag that marks this dashboard as default or not. The default dashboard is the dashboard all users will have access to on the root page
76
+ # # @controller_action_param :main [Boolean] A flag that marks this dashboard as main. Since a user can have multiple dashboards, this is the one they will see on the root page when loging in
77
+ # # @controller_action_param :roles_id [Integer] The id of the role that will have access to this dashboard
78
+ # # @controller_action_param :user_main_id [Integer] The id of the user
79
+ # # @controller_action_param :component_attributes [Array] Array of hashes that represent the attributes of the dashboard components
80
+ # # @controller_action_param :component_attributes.name [String] The name of this component given to the user
81
+ # # @controller_action_param :component_attributes.component_id [String] An enum value, that indicates which component is being loaded
82
+ # # @controller_action_param :component_attributes.layout [Integer] Number from 1 to 12, bigger numbers default to 12, smallest numbers default to 1. The column size that the UI component will use
83
+ # # @controller_action_param :component_attributes.index [Integer] The position of the component in the layout
84
+ # # @controller_action_param :component_attributes.configuration [Hash] Specific filtering and configuration of the components
85
+ # # @return [Json] Json that contains wheter the creation of the dashboard was successful or not.
86
+ # # If it is not successful, it returns an error message
87
+ # # @description Creates a new dashboard associated to the *current_user*'s *account*
88
+ # # @example
89
+ # # # Executing this controller's action from javascript's frontend
90
+ # # let data = {
91
+ # # dashboard: {
92
+ # # name: "Sales Dashboard",
93
+ # # default: false,
94
+ # # roles_id: 3,
95
+ # # components_attributes: [
96
+ # # {
97
+ # # name: 'Projects Count',
98
+ # # component_id: projects_component,
99
+ # # layout: 4,
100
+ # # index: 3,
101
+ # # configuration: {}
102
+ # # }, {
103
+ # # name: 'New Customers Count',
104
+ # # component_id: new_customers_component,
105
+ # # layout: 4,
106
+ # # index: 3,
107
+ # # configuration: {}
108
+ # # }
109
+ # # ]
110
+ # # }
111
+ # # };
112
+ # # this.http.post('127.0.0.1/help/dashboards', data);
113
+ # def create
114
+ # dynamic_info = self.class.dynamic_info
115
+ # module_name = dynamic_info[:module_name]
116
+ # model = dynamic_info[:model]
117
+ # full_module_name = dynamic_info[:full_module_name].underscore
118
+
119
+ # dashboard = model.new(dashboard_params)
120
+ # dashboard["#{full_module_name}_account_id".to_sym] = current_user.account.id
121
+ # dashboard.user_creator = current_user
122
+
123
+ # if dashboard.save
124
+ # respond_with_successful(dashboard)
125
+ # else
126
+ # respond_with_error(dashboard.errors.full_messages.to_sentence)
127
+ # end
128
+ # end
129
+
130
+ # # @controller_action_param :name [String] The name of the new dashboard
131
+ # # @controller_action_param :default [Boolean] A flag that marks this dashboard as default or not. The default dashboard is the dashboard all users will have access to on the root page
132
+ # # @controller_action_param :main [Boolean] A flag that marks this dashboard as main. Since a user can have multiple dashboards, this is the one they will see on the root page when loging in
133
+ # # @controller_action_param :roles_id [Integer] The id of the role that will have access to this dashboard
134
+ # # @controller_action_param :user_main_id [Integer] The id of the user
135
+ # # @controller_action_param :component_attributes [Array] Array of hashes that represent the attributes of the dashboard components
136
+ # # @controller_action_param :component_attributes.name [String] The name of this component given to the user
137
+ # # @controller_action_param :component_attributes.component_id [String] An enum value, that indicates which component is being loaded
138
+ # # @controller_action_param :component_attributes.layout [Integer] Number from 1 to 12, bigger numbers default to 12, smallest numbers default to 1. The column size that the UI component will use
139
+ # # @controller_action_param :component_attributes.index [Integer] The position of the component in the layout
140
+ # # @controller_action_param :component_attributes.configuration [Hash] Specific filtering and configuration of the components
141
+ # # @return [Json] Json that contains wheter the dashboard was successfully updated or not.
142
+ # # If it it not successful, it returns an error message
143
+ # # @description Updates an existing dashboard associated to the *current_user*'s *account*.
144
+ # # @example
145
+ # # # Executing this controller's action from javascript's frontend
146
+ # # let dashboard_id = 4;
147
+ # # let data = {
148
+ # # dashboard: {
149
+ # # name: "Sales Dashboard",
150
+ # # default: false,
151
+ # # roles_id: 3,
152
+ # # components_attributes: [
153
+ # # {
154
+ # # name: 'Projects Count',
155
+ # # component_id: projects_component,
156
+ # # layout: 4,
157
+ # # index: 3,
158
+ # # configuration: {}
159
+ # # }, {
160
+ # # name: 'New Customers Count',
161
+ # # component_id: new_customers_component,
162
+ # # layout: 4,
163
+ # # index: 3,
164
+ # # configuration: {}
165
+ # # }
166
+ # # ]
167
+ # # }
168
+ # # };
169
+ # # this.http.put(`127.0.0.1/help/dashboards/${dashboard_id}`, data);
170
+ # def update
171
+ # return respond_with_not_found unless @dashboard
172
+
173
+ # if @dashboard.update(dashboard_params)
174
+ # respond_with_successful(@dashboard.show)
175
+ # else
176
+ # respond_with_error(@dashboard.errors.full_messages.to_sentence)
177
+ # end
178
+ # end
179
+
180
+ # # @return [Json] Json that contains wheter the dashboard was successfully deleted or not.
181
+ # # If it it not successful, it returns an error message
182
+ # # @description Deletes an existing *dashboard* associated to the *current_user*'s *account*.
183
+ # # Since the dashboard has details, these are also deleted. However, if there
184
+ # # is an existing *cloud_object* associated to the *dashboard*, it cannot be deleted
185
+ # # @example
186
+ # # # Executing this controller's action from javascript's frontend
187
+ # # let dashboard_id = 4;
188
+ # # this.http.delete(`127.0.0.1/help/dashboards/${dashboard_id}`);
189
+ # def destroy
190
+ # return respond_with_not_found unless @dashboard
191
+
192
+ # if @dashboard.destroy
193
+ # respond_with_successful
194
+ # else
195
+ # respond_with_error(@dashboard.errors.full_messages.to_sentence)
196
+ # end
197
+ # end
198
+
199
+ # def options
200
+ # dynamic_info = self.class.dynamic_info
201
+ # model = dynamic_info[:module_model]
202
+
203
+ # respond_with_successful(model.options(current_user, @query))
204
+ # end
205
+
206
+ # def resource_component
207
+ # dynamic_info = self.class.dynamic_info
208
+ # component_model = dynamic_info[:component_model]
209
+
210
+ # component_id = sanitize(params[:component_id].to_sym)
211
+
212
+ # # We verify if the method exists, and if it is in the available component list
213
+ # if component_model.respond_to?(component_id) && component_model.component_ids[component_id]
214
+ # respond_with_successful(component_model.public_send(component_id, current_user, @query))
215
+ # else
216
+ # respond_with_not_found()
217
+ # end
218
+ # end
219
+
220
+ # private
221
+
222
+ # # @return [void]
223
+ # # @description Sets the variable @dashboard. The variable contains the *cloud_object* *dashboard*
224
+ # # to be handled by the controller action that called this method
225
+ # # @example
226
+ # # #suppose params[:id] = 1
227
+ # # puts @dashboard # will display nil
228
+ # # set_dashboard
229
+ # # puts @dashboard # will display an instance of CloudHelp:TicketDashboard
230
+ # def set_dashboard
231
+ # dynamic_info = self.class.dynamic_info
232
+
233
+ # model = dynamic_info[:module_model]
234
+ # module_name = dynamic_info[:module_name]
235
+ # module_name_full = dynamic_info[:module_name_full].underscore
236
+
237
+ # # When params[:id] is 'default' order of priority is:
238
+ # # Main dashboard for user goes first
239
+ # # Main dashboard for role goes second
240
+ # # Default dashboard goes third
241
+ # if params[:id] == "default"
242
+ # # Main dashboard for user
243
+ # @dashboard = model.find_by(
244
+ # #"#{full_module_name}_account_id".to_sym => current_user.account.id,
245
+ # account_id: current_user.account.id,
246
+ # main: true,
247
+ # #user_main_id: current_user.id
248
+ # )
249
+
250
+ # return if @dashboard
251
+
252
+ # # Main dashboard for role
253
+ # # @dashboard = model.find_by(
254
+ # # :account_id => current_user.account.id,
255
+ # # role_id: current_user.roles.first.id
256
+ # # )
257
+ # # return if @dashboard
258
+
259
+ # # Default dashboard
260
+ # @dashboard = model.find_by(
261
+ # account_id: current_user.account.id,
262
+ # default: true
263
+ # )
264
+ # else
265
+ # @dashboard = model.find_by(
266
+ # id: params[:id],
267
+ # :account_id => current_user.account.id,
268
+ # )
269
+ # end
270
+ # end
271
+
272
+ # def dashboard_params
273
+ # params.require(:dashboard).permit(
274
+ # :name,
275
+ # :default,
276
+ # :roles_id,
144
277
  # components_attributes: [
145
- # {
146
- # name: 'Projects Count',
147
- # component_id: projects_component,
148
- # layout: 4,
149
- # index: 3,
150
- # configuration: {}
151
- # }, {
152
- # name: 'New Customers Count',
153
- # component_id: new_customers_component,
154
- # layout: 4,
155
- # index: 3,
156
- # configuration: {}
157
- # }
278
+ # :id,
279
+ # :name,
280
+ # :component_id,
281
+ # :layout,
282
+ # :index,
283
+ # {query_configuration: {}},
284
+ # {custom_configuration: {}},
285
+ # :_destroy
158
286
  # ]
159
- # }
160
- # };
161
- # this.http.put(`127.0.0.1/help/dashboards/${dashboard_id}`, data);
162
- def update
163
- return respond_with_not_found unless @dashboard
164
-
165
- if @dashboard.update(dashboard_params)
166
- respond_with_successful(@dashboard.show)
167
- else
168
- respond_with_error(@dashboard.errors.full_messages.to_sentence)
169
- end
170
- end
171
-
172
- # @return [Json] Json that contains wheter the dashboard was successfully deleted or not.
173
- # If it it not successful, it returns an error message
174
- # @description Deletes an existing *dashboard* associated to the *current_user*'s *account*.
175
- # Since the dashboard has details, these are also deleted. However, if there
176
- # is an existing *cloud_object* associated to the *dashboard*, it cannot be deleted
177
- # @example
178
- # # Executing this controller's action from javascript's frontend
179
- # let dashboard_id = 4;
180
- # this.http.delete(`127.0.0.1/help/dashboards/${dashboard_id}`);
181
- def destroy
182
- return respond_with_not_found unless @dashboard
183
-
184
- if @dashboard.destroy
185
- respond_with_successful
186
- else
187
- respond_with_error(@dashboard.errors.full_messages.to_sentence)
188
- end
189
- end
190
-
191
- def options
192
- dynamic_info = self.class.dynamic_info
193
- model = dynamic_info[:module_model]
194
-
195
- respond_with_successful(model.options(current_user, @query))
196
- end
197
-
198
- def resource_component
199
- dynamic_info = self.class.dynamic_info
200
- component_model = dynamic_info[:component_model]
201
-
202
- component_id = sanitize(params[:component_id].to_sym)
203
-
204
- # We verify if the method exists, and if it is in the available component list
205
- if component_model.respond_to?(component_id) && component_model.component_ids[component_id]
206
- respond_with_successful(component_model.public_send(component_id, current_user, @query))
207
- else
208
- respond_with_not_found()
209
- end
210
- end
211
-
212
- private
213
-
214
- # @return [void]
215
- # @description Sets the variable @dashboard. The variable contains the *cloud_object* *dashboard*
216
- # to be handled by the controller action that called this method
217
- # @example
218
- # #suppose params[:id] = 1
219
- # puts @dashboard # will display nil
220
- # set_dashboard
221
- # puts @dashboard # will display an instance of CloudHelp:TicketDashboard
222
- def set_dashboard
223
- dynamic_info = self.class.dynamic_info
224
-
225
- model = dynamic_info[:module_model]
226
- module_name = dynamic_info[:module_name]
227
- module_name_full = dynamic_info[:module_name_full].underscore
228
-
229
- # When params[:id] is 'default' order of priority is:
230
- # Main dashboard for user goes first
231
- # Main dashboard for role goes second
232
- # Default dashboard goes third
233
- if params[:id] == "default"
234
- # Main dashboard for user
235
- @dashboard = model.find_by(
236
- #"#{full_module_name}_account_id".to_sym => current_user.account.id,
237
- account_id: current_user.account.id,
238
- main: true,
239
- #user_main_id: current_user.id
240
- )
241
-
242
- return if @dashboard
243
-
244
- # Main dashboard for role
245
- # @dashboard = model.find_by(
246
- # :account_id => current_user.account.id,
247
- # role_id: current_user.roles.first.id
248
- # )
249
- # return if @dashboard
250
-
251
- # Default dashboard
252
- @dashboard = model.find_by(
253
- account_id: current_user.account.id,
254
- default: true
255
- )
256
- else
257
- @dashboard = model.find_by(
258
- id: params[:id],
259
- :account_id => current_user.account.id,
260
- )
261
- end
262
- end
263
-
264
- def dashboard_params
265
- params.require(:dashboard).permit(
266
- :name,
267
- :default,
268
- :roles_id,
269
- components_attributes: [
270
- :id,
271
- :name,
272
- :component_id,
273
- :layout,
274
- :index,
275
- {query_configuration: {}},
276
- {custom_configuration: {}},
277
- :_destroy
278
- ]
279
- )
280
- end
287
+ # )
288
+ # end
281
289
 
282
- private
290
+ # private
283
291
 
284
- # Build the Rails models and engine information for
285
- # the current engine implementing the shared dashboards
286
- # Example: For the LesliAudit engine
287
- # {
288
- # :module_name => "audit",
289
- # :module_name_full => "LesliAudit",
290
- # :module_model => "LesliAudit::Dashboard",
291
- # :module_model_component => "LesliAudit::Dashboard::Component"
292
- # }
293
- def self.dynamic_info
292
+ # # Build the Rails models and engine information for
293
+ # # the current engine implementing the shared dashboards
294
+ # # Example: For the LesliAudit engine
295
+ # # {
296
+ # # :module_name => "audit",
297
+ # # :module_name_full => "LesliAudit",
298
+ # # :module_model => "LesliAudit::Dashboard",
299
+ # # :module_model_component => "LesliAudit::Dashboard::Component"
300
+ # # }
301
+ # def self.dynamic_info
294
302
 
295
- module_info = self.name.split("::")
303
+ # module_info = self.name.split("::")
296
304
 
297
- module_name = module_info[0].sub("Lesli", "").downcase
305
+ # module_name = module_info[0].sub("Lesli", "").downcase
298
306
 
299
- {
300
- module_name: module_name,
301
- module_name_full: module_info[0],
302
- module_model: "#{ module_info[0] }::Dashboard".constantize,
303
- module_model_component: "#{ module_info[0] }::Dashboard::Component".constantize
304
- }
305
- end
307
+ # {
308
+ # module_name: module_name,
309
+ # module_name_full: module_info[0],
310
+ # module_model: "#{ module_info[0] }::Dashboard".constantize,
311
+ # module_model_component: "#{ module_info[0] }::Dashboard::Component".constantize
312
+ # }
313
+ # end
306
314
  end
307
315
  end
308
316
  end
@@ -140,7 +140,7 @@ module Lesli
140
140
  end
141
141
 
142
142
  # 03.06 Dashboard engine
143
- def navigation_engine_dashboard(title: "Dashboard", subtitle: "Smart business assistant")
143
+ def navigation_engine_dashboard(title: "Dashboard", subtitle: "Dashboard Manager")
144
144
  return unless defined? LesliDashboard
145
145
  navigation_engine_item(title,subtitle,"dashboard",lesli_dashboard.root_path,controller_path.include?("lesli_dashboard"))
146
146
  end
@@ -59,6 +59,8 @@ module AccountInitializer
59
59
  Lesli::RoleOperator.new(owner).add_owner_actions
60
60
  Lesli::RoleOperator.new(admin).add_owner_actions
61
61
  Lesli::RoleOperator.new(limited).add_profile_privileges
62
+
63
+
62
64
  end
63
65
 
64
66
 
@@ -34,7 +34,7 @@ module Lesli
34
34
  class Role::Action < ApplicationLesliRecord
35
35
  belongs_to :role
36
36
 
37
- after_commit :synchronize_privileges
37
+ after_save :synchronize_privileges
38
38
  after_destroy :synchronize_privileges
39
39
 
40
40
  belongs_to :action, class_name: "SystemController::Action"
@@ -2,7 +2,7 @@
2
2
 
3
3
  Lesli
4
4
 
5
- Copyright (c) 2023, Lesli Technologies, S. A.
5
+ Copyright (c) 2025, Lesli Technologies, S. A.
6
6
 
7
7
  This program is free software: you can redistribute it and/or modify
8
8
  it under the terms of the GNU General Public License as published by
@@ -17,157 +17,31 @@ GNU General Public License for more details.
17
17
  You should have received a copy of the GNU General Public License
18
18
  along with this program. If not, see http://www.gnu.org/licenses/.
19
19
 
20
- Lesli · Your Smart Business Assistant.
20
+ Lesli · Ruby on Rails SaaS Development Framework.
21
21
 
22
- Made with ♥ by https://www.lesli.tech
22
+ Made with ♥ by LesliTech
23
23
  Building a better future, one line of code at a time.
24
24
 
25
25
  @contact hello@lesli.tech
26
- @website https://lesli.tech
26
+ @website https://www.lesli.tech
27
27
  @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
28
28
 
29
- // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
30
- // ·
31
-
29
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
30
+ // ·
32
31
  =end
33
32
 
34
33
  module Lesli
35
34
  module Shared
36
- class Dashboard < ::Lesli::ApplicationLesliRecord
35
+ class DashboardFallback < ::Lesli::ApplicationLesliRecord
37
36
  self.abstract_class = true
38
-
39
- belongs_to :user_creator, class_name: "User", foreign_key: "users_id", optional: true
40
-
41
- after_update :verify_default_dashboard
42
- after_create :verify_default_dashboard
43
-
44
- #enum component_ids: {}
45
-
46
- # @return [void]
47
- # @param account [LesliEngine::Account]
48
- # @description Initializes a default dummy dashboard for the account. This guarantees that the users
49
- # will be able to access the dashboard page. Even if it's empty.
50
- # @example
51
- # # Imagine you are adding a new engine to your instance (CloudProposal)
52
- # # To execute this function, you must only do
53
- # my_account = Account.first
54
- # my_account.proposal = CloudProposal::Account.new
55
- def self.initialize_dashboard(modelo, account, components)
56
-
57
- components.unshift({
58
- name: "Engine version",
59
- component_id: "engine-version",
60
- layout: 2,
61
- query_configuration: {},
62
- custom_configuration: {}
63
- })
64
-
65
- modelo.create_with(
66
- default: true,
67
- main: false,
68
- components_attributes: components
69
- ).find_or_create_by!(
70
- account: account,
71
- name: "Default Dashboard"
72
- )
73
- end
74
-
75
- # @return [Hash] Hash of containing the information of the dashboard and its components.
76
- # @description Returns a hash with information about the dashboard and all its *components*.
77
- # Each component is returned in the configuration view, not the render view. This means that
78
- # this method is ment to be used when updating the dashboard
79
- # @example
80
- # respond_with_successful(CloudHelp::Dashboard.first.show)
81
- def show
82
- attributes.merge({
83
- components: components.order(index: :asc)
84
- # components: [{
85
- # name: "ticket",
86
- # component_id: "ticket"
87
- # },{
88
- # name: "ticket",
89
- # component_id: "ticket"
90
- # }]
91
- })
37
+ def self.initialize_dashboard(account)
92
38
  end
39
+ end
93
40
 
94
- # @return [Hash] Hash containing the options to create and manage dashboards
95
- # @param current_user [User] The user that made this request
96
- # @param query [Hash] Query containing filters. Currently unused, but required
97
- # @descriptions Returns a list of options needed to create and manage dashboard components. For now,
98
- # the returned options are: A list of roles, the enoun containing the component_ids, generic configuration options
99
- # for all dashboad components and a descriptions hash, that contains brief descriptions for each component to help
100
- # the user understand what each component does. Any class that inherits from this one can send a block to add extra
101
- # functionality. For example, the descriptions must be implemented directly from the engine.
102
- # @example
103
- # CloudHouse::Dashboard.options(User.find(2), nil)
104
- def self.options(current_user, query)
105
- dynamic_info = self.dynamic_info
106
- component_model = dynamic_info[:module_model_component]
107
-
108
- component_ids = component_model.component_ids.map do |comp|
109
- {
110
- value: comp,
111
- text: comp
112
- }
113
- end
114
-
115
- options = {
116
- component_ids: component_ids,
117
- #components_configuration_options: component_model.configuration_options,
118
- descriptions: {}
119
- }
120
-
121
- if block_given?
122
- yield(options)
123
- else
124
- return options
125
- end
126
- end
127
-
128
- private
129
-
130
- # @return [void]
131
- # @descriptions This is an after_updated and after_create method that validates that at any moment in time, there is only
132
- # one default dashboard in the engine. If there is another default dashboard, it's *default* field is set to false
133
- # before committing the changes
134
- # @example
135
- # CloudFocus::Dasbhoard.where(default: false).first.update!(default: true)
136
- # # This will automatically trigger this function and remove the *default* field from the old default dashboard
137
- def verify_default_dashboard
138
- if default
139
- dashboards = self.class.where.not(id: id).where(account: account)
140
- self.class.where.not(id: id).where(account: account).update_all(default: false)
141
- end
142
-
143
- unless self.class.where(account: account).find_by(default: true)
144
- errors.add(:base, I18n.t("core.dashboards.messages_danger_default_dashboard_must_exist"))
145
- raise ActiveRecord::Rollback
146
- end
147
- end
148
-
149
- # Build the Rails models and engine information for
150
- # the current engine implementing the shared dashboards
151
- # Example: For the LesliAudit engine
152
- # {
153
- # :module_name => "audit",
154
- # :module_name_full => "LesliAudit",
155
- # :module_model => "LesliAudit::Dashboard",
156
- # :module_model_component => "LesliAudit::Dashboard::Component"
157
- # }
158
- def self.dynamic_info
159
-
160
- module_info = self.name.split("::")
41
+ base_class = "::LesliDashboard::Shared::Dashboard".safe_constantize || DashboardFallback
161
42
 
162
- module_name = module_info[0].sub("Lesli", "").downcase
163
-
164
- {
165
- module_name: module_name,
166
- module_name_full: module_info[0],
167
- module_model: "#{ module_info[0] }::Dashboard".constantize,
168
- module_model_component: "#{ module_info[0] }::Dashboard::Component".constantize
169
- }
170
- end
43
+ class Dashboard < DashboardFallback
44
+ self.abstract_class = true
171
45
  end
172
46
  end
173
47
  end
@@ -1,58 +1,76 @@
1
1
  module Lesli
2
2
  class Role::ActionService < Lesli::ApplicationLesliService
3
3
 
4
- def index params
5
-
6
- role_actions = {}
7
-
8
- Lesli::Role::Action.joins(system_controller_action: :system_controller)
9
- .select(
10
- :id,
11
- :role_id,
12
- :action_id,
13
- :deleted_at,
14
- "lesli_system_controllers.id as controller_id",
15
- "lesli_system_controllers.name as controller_name",
16
- "lesli_system_controller_actions.name as controller_action_name",
17
- "case when lesli_role_actions.deleted_at is null then TRUE else FALSE end active"
18
- ).each do |action|
19
- unless role_actions.has_key?(action[:controller_name])
20
- role_actions[action[:controller_name]] = {
21
- list:nil,
22
- index: nil,
23
- show:nil,
24
- create:nil,
25
- update:nil,
26
- destroy:nil
27
- }
28
- end
29
-
30
- if action[:controller_action_name] == "list"
31
- role_actions[action[:controller_name]][:list] = action
32
- end
33
-
34
- if action[:controller_action_name] == "index"
35
- role_actions[action[:controller_name]][:index] = action
36
- end
37
-
38
- if action[:controller_action_name] == "show"
39
- role_actions[action[:controller_name]][:show] = action
40
- end
41
-
42
- if action[:controller_action_name] == "create"
43
- role_actions[action[:controller_name]][:create] = action
44
- end
45
-
46
- if action[:controller_action_name] == "update"
47
- role_actions[action[:controller_name]][:update] = action
48
- end
49
-
50
- if action[:controller_action_name] == "destroy"
51
- role_actions[action[:controller_name]][:destroy] = action
52
- end
4
+ def find id
5
+ #super(current_user.account.users.joins(:detail).find_by(id: id))
6
+ super(Lesli::Role::Action.with_deleted.find(id))
7
+ end
8
+
9
+ def index params
10
+
11
+ def clean action
12
+ {
13
+ :id => action.id,
14
+ :role_id => action.role_id,
15
+ :action_id => action.action_id,
16
+ :deleted_at => action.deleted_at,
17
+ :active => action.active
18
+ }
19
+ end
20
+
21
+ role_actions = {}
22
+
23
+ Lesli::Role::Action.with_deleted.joins(system_controller_action: :system_controller)
24
+ .select(
25
+ :id,
26
+ :role_id,
27
+ :action_id,
28
+ :deleted_at,
29
+ "lesli_system_controllers.id as controller_id",
30
+ "lesli_system_controllers.name as controller_name",
31
+ "lesli_system_controller_actions.name as controller_action_name",
32
+ "case when lesli_role_actions.deleted_at is null then TRUE else FALSE end active"
33
+ ).each do |action|
34
+
35
+ unless role_actions.has_key?(action[:controller_name])
36
+ role_actions[action[:controller_name]] = {
37
+ list:nil,
38
+ index: nil,
39
+ show:nil,
40
+ create:nil,
41
+ update:nil,
42
+ destroy:nil
43
+ }
44
+ end
45
+
46
+ if action[:controller_action_name] == "list"
47
+ role_actions[action[:controller_name]][:list] = clean(action)
48
+ end
49
+
50
+ if action[:controller_action_name] == "index"
51
+ role_actions[action[:controller_name]][:index] = clean(action)
53
52
  end
54
53
 
55
- role_actions
54
+ if action[:controller_action_name] == "show"
55
+ role_actions[action[:controller_name]][:show] = clean(action)
56
+ end
57
+
58
+ if action[:controller_action_name] == "create"
59
+ role_actions[action[:controller_name]][:create] = clean(action)
60
+ end
61
+
62
+ if action[:controller_action_name] == "update"
63
+ role_actions[action[:controller_name]][:update] = clean(action)
64
+ end
65
+
66
+ if action[:controller_action_name] == "destroy"
67
+ role_actions[action[:controller_name]][:destroy] = clean(action)
68
+ end
56
69
  end
70
+
71
+
72
+
73
+ role_actions
57
74
  end
75
+ end
58
76
  end
@@ -125,20 +125,10 @@ html, body, * {
125
125
  Getting started
126
126
  </a>
127
127
  </div>
128
+ <%= link_to("Apps", "/lesli/apps") unless defined?(LesliDashboard) %>
128
129
  <% if defined?(LesliShield) %>
129
130
  <%= link_to("Dashboard", "/dashboard") if user_signed_in? && defined?(LesliDashboard) %>
130
131
  <%= link_to("Logout", "/logout") if user_signed_in? %>
131
132
  <%= link_to("Login", "/login") unless user_signed_in? %>
132
133
  <% end %>
133
134
  </section>
134
-
135
- <% if Rails.env.production? %>
136
- <!-- Google tag (gtag.js) -->
137
- <script async src="https://www.googletagmanager.com/gtag/js?id=G-LJRTGWVRCC"></script>
138
- <script>
139
- window.dataLayer = window.dataLayer || [];
140
- function gtag(){dataLayer.push(arguments);}
141
- gtag('js', new Date());
142
- gtag('config', 'G-LJRTGWVRCC');
143
- </script>
144
- <% end %>
@@ -25,6 +25,7 @@ document.addEventListener('turbo:load', () => {
25
25
 
26
26
  <%# 03. Productivity & Teamwork%>
27
27
  <%= navigation_engine_calendar %>
28
+ <%= navigation_engine_dashboard %>
28
29
  <%= navigation_engine_bell %>
29
30
  <%= navigation_engine_papers %>
30
31
 
@@ -0,0 +1,33 @@
1
+ <%#
2
+
3
+ Lesli
4
+
5
+ Copyright (c) 2023, Lesli Technologies, S. A.
6
+
7
+ This program is free software: you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License as published by
9
+ the Free Software Foundation, either version 3 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License
18
+ along with this program. If not, see http://www.gnu.org/licenses/.
19
+
20
+ Lesli · Ruby on Rails SaaS Development Framework.
21
+
22
+ Made with ♥ by https://www.lesli.tech
23
+ Building a better future, one line of code at a time.
24
+
25
+ @contact hello@lesli.tech
26
+ @website https://www.lesli.tech
27
+ @license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
28
+
29
+ // · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
30
+ // ·
31
+ %>
32
+
33
+ <%= render("lesli_dashboard/dashboards/shared/edit") if defined?(LesliDashboard) %>
@@ -30,34 +30,4 @@ Building a better future, one line of code at a time.
30
30
  // ·
31
31
  %>
32
32
 
33
- <%
34
- hour = Date2.new.date.get.hour # Returns the hour (0–23) based on the app's timezone
35
- welcome_options = ["Good morning", "Good afternoon", "Good evening"]
36
- welcome_text = ""
37
-
38
- if hour < 12
39
- welcome_text = welcome_options.first
40
- elsif hour < 18
41
- welcome_text = welcome_options.second
42
- else
43
- welcome_text = welcome_options.third
44
- end
45
- %>
46
-
47
- <%= render(LesliView::Layout::Container.new("dashboards-show", :dashboard => true)) do %>
48
-
49
- <section class="lesli-element-header is-flex mt-6 mb-6 pb-6 container">
50
- <div class="lesli-element-header-title">
51
- <h1 class="subtitle is-size-3 mb-0"><%= welcome_text %>, <%= current_user.full_name %>.</h1>
52
- <p class=""><%= Date2.new.date_words_day %>.</p>
53
- </div>
54
- </section>
55
-
56
- <%= render(LesliView::Elements::Empty.new(text: "Empty dashboard")) if @dashboard[:components].blank? %>
57
-
58
- <div class="columns is-multiline is-variable is-4 dashboard-components">
59
- <% @dashboard[:components].each do |component| %>
60
- <%= render("#{controller.controller_path}/component-#{component}", { :component => component }) %>
61
- <% end %>
62
- </div>
63
- <% end %>
33
+ <%= render("lesli_dashboard/dashboards/shared/show") if defined?(LesliDashboard) %>
data/lib/lesli/routing.rb CHANGED
@@ -74,7 +74,10 @@ module Lesli
74
74
  root to: "dashboards#show"
75
75
 
76
76
  # Dashboard management
77
- resource :dashboard, only: [:show]
77
+ resource :dashboard, only: [:show, :edit]
78
+
79
+ # uncomment this to enable multiple dashboards
80
+ #resources :dashboards, only: [:show, :edit]
78
81
  # resources :dashboards do
79
82
  # collection do
80
83
  # post "list" => :index
data/lib/lesli/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Lesli
2
- VERSION = "5.0.15"
3
- BUILD = "1751335357"
2
+ VERSION = "5.0.17"
3
+ BUILD = "1752157715"
4
4
  end
@@ -43,24 +43,9 @@ namespace :lesli do
43
43
  # Seed database (development only)
44
44
  def welcome
45
45
 
46
- # do not execute this task if we are at production level
47
- return if Rails.env.production?
48
-
49
46
  L2.br(4)
50
47
 
51
48
  # print the lesli gems
52
49
  Rake::Task['lesli:status'].invoke
53
-
54
- password = Lesli.config.security.dig(:password)
55
- password = password + Time.now.year.to_s + "$"
56
- user = Lesli::User.first
57
-
58
- L2.line
59
- L2.m(" Owner user credentials (demo):")
60
- L2.m(" username: #{ user.email }")
61
- L2.m(" password: #{ password }")
62
- L2.line
63
-
64
- L2.cow "Enjoy your Lesli demo"
65
50
  end
66
51
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lesli
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.15
4
+ version: 5.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Lesli Development Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-01 00:00:00.000000000 Z
11
+ date: 2025-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n-js
@@ -80,20 +80,6 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 1.2.2
83
- - !ruby/object:Gem::Dependency
84
- name: ancestry
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 4.3.3
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 4.3.3
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: lesli_date
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -270,6 +256,7 @@ files:
270
256
  - app/views/lesli/partials/_application-public-footer.html.erb
271
257
  - app/views/lesli/partials/_application-public-javascript.html.erb
272
258
  - app/views/lesli/partials/_application-public-scss.html.erb
259
+ - app/views/lesli/shared/dashboards/_edit.html.erb
273
260
  - app/views/lesli/shared/dashboards/_show.html.erb
274
261
  - app/views/lesli/wrappers/_application-devise-simple.erb
275
262
  - app/views/lesli/wrappers/_application-devise.html.erb