motor-admin 0.1.62 → 0.1.67

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: 2b1e931dc58724b3ae9e207d86d4ca7a9c68d7cfeae0e0c482a7cd21d23c4258
4
- data.tar.gz: d11ea5ce285bf4c44f6e772970b26bc7deede0b055e7c264c3039833c3d29534
3
+ metadata.gz: 33a7b2555fe1a052dc108c562080e56bc1f7850cde53bfcd94958a1f1254d867
4
+ data.tar.gz: 3f3bdf80802854525a0115ed8bdf404657f59e486a43d0ad171f4a55e3b2d3de
5
5
  SHA512:
6
- metadata.gz: 05bef6829304b10adab88dc9860ad2b97c44a50cce1017cba21efcbc8799a7b996125bcc21abc8dbda3d333e4fd0aaa4200c03a565e51393d9d5c3018b00cd62
7
- data.tar.gz: 40041861d8e1d81e76065862db59ab88713e799b9859867e91979f1e5ccc73bf6eeab77c3130108ac063da128d3a7d41db1da600c5c50f2301a4ddbefd15a29e
6
+ metadata.gz: 4708009ff1464c24214afac7fc9711c5f0a50c153e75a1ca4fedf60a78d8a72567eb4ba8bc7c3228ae5569590b638b4fb89d839418512eb00a26e79b0ba424c8
7
+ data.tar.gz: c0af8ed7425f902438a29ebc41dab4ca52c55def49e505e9e18416bbaecfd58e318631e64f3b63090610d22fe37d0886a2c30dcc3a6f957fd78ac5c99dc38d2e
data/README.md CHANGED
@@ -34,6 +34,7 @@ $ rails motor:install && rake db:migrate
34
34
  * [Email alerts](#email-alerts)
35
35
  * [Authorization](#authorization)
36
36
  * [Intelligence search](#intelligence-search)
37
+ * [I18n](#i18n)
37
38
  * [Optimized for mobile](#optimized-for-mobile)
38
39
  * [Configurations sync between environments](#configurations-sync)
39
40
 
@@ -57,7 +58,8 @@ Custom resource actions can be added via Active Record method call, API endpoint
57
58
 
58
59
  ![Custom form](https://user-images.githubusercontent.com/5418788/119264008-1391dd80-bbea-11eb-9f14-cb405e77fb60.png)
59
60
 
60
- Values from the form fields can be used in API path via `{field_name}` syntax: `/api/some-endpoint/{resource_id}/apply`
61
+ Values from the form fields can be used in API path via `{field_name}` syntax: `/api/some-endpoint/{resource_id}/apply`.<br>
62
+ [Learn more about custom forms builder](https://github.com/omohokcoj/motor-admin/blob/master/guides/building_custom_forms.md).
61
63
 
62
64
  ### SQL Queries
63
65
 
@@ -95,6 +97,25 @@ Intelligence search can be opened via the top right corner button or using <kbd>
95
97
 
96
98
  Motor Admin allows to set row-level and column-level permissions via [cancan](https://github.com/CanCanCommunity/cancancan) gem. Admin UI permissions should be defined in `app/models/motor/ability.rb` file in `Motor::Ability` class. See [Motor Admin guide](https://github.com/omohokcoj/motor-admin/blob/master/guides/defining_permissions.md) and [CanCan documentation](https://github.com/CanCanCommunity/cancancan/blob/develop/docs/Defining-Abilities.md) to learn how to define user permissions.
97
99
 
100
+ ### I18n
101
+
102
+ Motor Admin can use Rails ActiveRecord i18n keys to render resource translations:
103
+
104
+ ```yml
105
+ es:
106
+ activerecord:
107
+ models:
108
+ customer:
109
+ one: Cliente
110
+ other: Clientes
111
+ attributes:
112
+ customer:
113
+ name: Nombre
114
+ scopes:
115
+ customer:
116
+ enabled: Activado
117
+ ```
118
+
98
119
  ### Optimized for Mobile
99
120
 
100
121
  ![motor-mobile](https://user-images.githubusercontent.com/5418788/119269566-03392d00-bc01-11eb-9e9d-1f6a58fe0749.png)
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="<%= I18n.locale %>">
3
3
  <head>
4
4
  <title>Motor Admin</title>
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
@@ -0,0 +1,216 @@
1
+ en:
2
+ motor:
3
+ action_has_been_applied: Action has been applied!
4
+ action_has_failed_with_code: Action failed with code
5
+ action_type: Action type
6
+ actions: Actions
7
+ add: Add
8
+ add_action: Add Action
9
+ add_alert: Add Alert
10
+ add_column: Add Column
11
+ add_dashboard: Add Dashboard
12
+ add_field: Add Field
13
+ add_filter: Add Filter
14
+ add_form: Add Form
15
+ add_group: Add Group
16
+ add_item: Add Item
17
+ add_link: Add Link
18
+ add_query: Add Query
19
+ add_scope: Add Scope
20
+ add_tab: Add Tab
21
+ alert_email_has_been_sent: Alert email has been sent!
22
+ alert_has_been_activated: Alert has been activated
23
+ alert_has_been_disabled: Alert has been disabled
24
+ alert_has_been_saved: Alert has been saved!
25
+ alert_name: Alert name
26
+ alerts: Alerts
27
+ all: All
28
+ all_resources: All Resources
29
+ and: And
30
+ api: API
31
+ api_path: API path
32
+ api_request: API request
33
+ apply: Apply
34
+ are_you_sure: Are you sure?
35
+ associations: Associations
36
+ bar_chart: Bar chart
37
+ base: Base
38
+ boolean: Boolean
39
+ cancel: Cancel
40
+ cents: Cents
41
+ checkbox: Checkbox
42
+ clear_all: Clear All
43
+ clear_selection: Clear selection
44
+ close: Close
45
+ close_editor: Close editor
46
+ close_settings: Close Settings
47
+ close_variables: Close Variables
48
+ columns: Columns
49
+ contains: Contains
50
+ create: Create
51
+ currency: Currency
52
+ dashboard: Dashboard
53
+ dashboard_has_been_saved: Dashboard has been saved!
54
+ dashboard_title: Dashboard title
55
+ dashboards: Dashboards
56
+ date: Date
57
+ date_and_time: Date and Time
58
+ decimal: Decimal
59
+ default: Default
60
+ default_value: Default value
61
+ describe_this_alert_optional: Describe this alert (optional)
62
+ describe_your_dashboard_optional: Describe your dashboard (optional)
63
+ describe_your_form_optional: Describe your form (optional)
64
+ describe_your_query_optional: Describe your query (optional)
65
+ description: Description
66
+ deselect_all: Deselect All
67
+ details: Details
68
+ disable: Disable
69
+ display_as: Display as
70
+ edit: Edit
71
+ edit_sql: Edit SQL
72
+ emails: Emails
73
+ ends_with: Ends with
74
+ equal_to: Equal to
75
+ every_day_at_hh_mm: every day at HH:mm PM...
76
+ excludes: excludes
77
+ field_is_not_a_number: '%{field} is not a number'
78
+ field_is_required: '%{field} is required'
79
+ field_list_cant_be_empty: "%{field} list can't be empty"
80
+ field_must_be_exactly_in_length: '%{field} must be exactly %{length} in length'
81
+ field_name: Field name
82
+ field_value_does_not_match_pattern: '%{field} value does not match %{pattern}'
83
+ file: File
84
+ filters: Filters
85
+ form: Form
86
+ form_has_been_saved: Form has been saved!
87
+ form_has_been_submitted_successfully: Form has been submitted successfully!
88
+ form_name: Form name
89
+ forms: Forms
90
+ funnel: Funnel
91
+ greater_or_equal: Greater or equal
92
+ greater_than: Greater than
93
+ greater_than_or_equal_to: Greater than or equal to
94
+ group_name: Group name
95
+ has_been_created: has been created
96
+ has_been_removed_succesfully: has been removed succesfully
97
+ has_been_updated: has been updated
98
+ hello_admin: Hello Admin 👋
99
+ hidden: Hidden
100
+ image: Image
101
+ includes: Includes
102
+ input_type: Input type
103
+ integer: Integer
104
+ interval: Interval
105
+ is: Is
106
+ is_not: Is not
107
+ items_has_been_removed: items has been removed
108
+ items_will_be_removed: '%{count} items will be removed'
109
+ json: JSON
110
+ label: Currency
111
+ less_or_equal: Less or equal
112
+ less_than: Less than
113
+ less_than_or_equal_to: Less than or equal to
114
+ line_chart: Line chart
115
+ link_name: Link name
116
+ links: Links
117
+ load_initial_data: Load initial data
118
+ loading: Loading...
119
+ looks_like_you_are_new_here: Looks like you are new here 🙃
120
+ markdown: Markdown
121
+ method: Method
122
+ method_call: Method call
123
+ multiple: Multiple
124
+ name: Name
125
+ new_alert: New alert
126
+ new_dashboard: New dashboard
127
+ new_form: New form
128
+ new_query: New query
129
+ no_data: No data
130
+ not_found: Not Found
131
+ number: Number
132
+ ok: OK
133
+ options_separated_with_new_line_or_comma: Options separated with new line or comma
134
+ or: Or
135
+ other_than: Other than
136
+ param_name: Param name
137
+ path: Path
138
+ percent: Percent
139
+ pie_chart: Pie chart
140
+ queries: Queries
141
+ query: Query
142
+ query_has_been_saved: Query has been saved!
143
+ query_name: Query name
144
+ query_not_selected: Query not selected
145
+ query_revisions: Query Revisions
146
+ read_only: Read-Only
147
+ read_write: Read-Write
148
+ reference: Reference
149
+ reference_resource: Reference resource
150
+ remove: Remove
151
+ reports: Reports
152
+ request_param: Request param
153
+ required: Required
154
+ resource_filters: '%{resource} Filters'
155
+ resource_settings: '%{resource} Settings'
156
+ resources: Resources
157
+ resubmit: Resubmit
158
+ revert: Revert
159
+ revision_has_been_applied: Revision has been applied
160
+ revisions: Revisions
161
+ row_chart: Row chart
162
+ save: Save
163
+ save_and_create_new: Save and Create New
164
+ save_as_new: Save as new
165
+ save_dashboard: Save dashboard
166
+ save_form: Save form
167
+ save_query: Save query
168
+ scopes: Scopes
169
+ search: Search
170
+ search_placeholder: Search...
171
+ search_query: Search Query
172
+ select: Select
173
+ select_alert_tags: Select alert tags
174
+ select_dashboard: Select dashboard
175
+ select_dashboard_tags: Select dashboard tags
176
+ select_form: Select form
177
+ select_form_tags: Select dashform tags
178
+ select_options: Select options
179
+ select_placeholder: Select...
180
+ select_query: Select query
181
+ select_query_tags: Select query tags
182
+ select_resource_placeholder: Select resource...
183
+ selected_item_has_been_removed: Selected item has been removed
184
+ selected_item_will_be_removed: Selected item will be removed
185
+ selected_item_will_be_removed_are_you_sure: Selected item will be removed. Are you sure?
186
+ send_empty: Send empty?
187
+ send_now: Send Now
188
+ send_to: Send to
189
+ set_tags: Set tags
190
+ settings: Settings
191
+ should_be_a_valid_json: Should be a valid JSON
192
+ should_be_error_constraint: 'Should be %{error} %{constraint}'
193
+ stacked_bars: Stacked bars
194
+ starts_with: Starts with
195
+ submit: Submit
196
+ tab_type: Tab type
197
+ table: Table
198
+ tabs: Tabs
199
+ tags: Tags
200
+ text: Text
201
+ textarea: Textarea
202
+ timezone: Timezone
203
+ title: Title
204
+ type: Type
205
+ unable_to_load_form_data: Unable to load form data
206
+ unable_to_remove_item: Unable to remove item
207
+ unable_to_remove_items: Unable to remove items
208
+ unable_to_send_email: Unable to send email
209
+ unable_to_submit_form: Unable to submit form
210
+ unit: Unit
211
+ value: Value
212
+ values_axis: Values axis
213
+ variables: Variables
214
+ visibility: Visibility
215
+ visualization: Visualization
216
+ write_only: Write-Only
@@ -0,0 +1,301 @@
1
+ es:
2
+ motor:
3
+ action_has_been_applied: ¡Acción aplicada!
4
+ action_has_failed_with_code: La acción falló con código
5
+ action_type: Tipo de acción
6
+ actions: Acciones
7
+ add: Añadir
8
+ add_action: Añadir Acción
9
+ add_alert: Añadir Alerta
10
+ add_column: Añadir Columna
11
+ add_dashboard: Añadir Dashboard
12
+ add_field: Añadir Campo
13
+ add_filter: Añadir Filtro
14
+ add_form: Añadir Formulario
15
+ add_group: Añadir Grupo
16
+ add_item: Añadir Elemento
17
+ add_link: Añadir Link
18
+ add_query: Añadir Consulta
19
+ add_scope: Añadir Alcance
20
+ add_tab: Añadir Pestaña
21
+ alert_email_has_been_sent: ¡Email de alerta enviado!
22
+ alert_has_been_activated: Alerta activada
23
+ alert_has_been_disabled: Alerta desactivada
24
+ alert_has_been_saved: ¡Alerta guardada!
25
+ alert_name: Nombre de la alerta
26
+ all_resources: Todos los Recursos
27
+ and: Y
28
+ api_path: Dirección en API
29
+ apply: Aplicar
30
+ are_you_sure: ¿Estás seguro?
31
+ associations: Asociaciones
32
+ bar_chart: Gráfico de barras
33
+ base: Base
34
+ cancel: Cancelar
35
+ clear_all: Quitar todos
36
+ clear_selection: Quitar selección
37
+ close: Cerrar
38
+ close_editor: Cerrar editor
39
+ close_settings: Cerrar Configuración
40
+ close_variables: Cerrar Variables
41
+ columns: Columnas
42
+ create: Crear
43
+ currency: Moneda
44
+ dashboard_has_been_saved: ¡Dashboard guardado!
45
+ dashboard_title: Título del dashboard
46
+ decimal: Decimal
47
+ default_value: Valor por defecto
48
+ describe_this_alert_optional: Describe esta alerta (opcional)
49
+ describe_your_dashboard_optional: Describe tu dashboard (opcional)
50
+ describe_your_form_optional: Describe tu formulario (opcional)
51
+ describe_your_query_optional: Describe tu consulta (opcional)
52
+ description: Descripción
53
+ deselect_all: Deseleccionar todo
54
+ disable: Desactivar
55
+ display_as: Mostrar como
56
+ edit: Editar
57
+ edit_sql: Editar SQL
58
+ emails: Emails
59
+ every_day_at_hh_mm: todos los días a las HH:mm PM...
60
+ field_name: Nombre del campo
61
+ filters: Filtros
62
+ form: Formulario
63
+ form_has_been_saved: ¡Formulario guardado!
64
+ form_has_been_submitted_successfully: ¡Formulario enviado con éxito!
65
+ form_name: Nombre del formulario
66
+ forms: Formularios
67
+ funnel: Embudo
68
+ group_name: Nombre del grupo
69
+ has_been_created: creado
70
+ has_been_removed_succesfully: eliminado con éxito
71
+ has_been_updated: actualizado
72
+ hello_admin: Hola Admin 👋
73
+ input_type: Tipo de campo
74
+ interval: Intervalo
75
+ items_has_been_removed: elementos fueron eliminados
76
+ label: Moneda
77
+ line_chart: Gráfico de líneas
78
+ link_name: Nombre del link
79
+ links: Links
80
+ load_initial_data: Cargar datos iniciales
81
+ loading: Cargando...
82
+ looks_like_you_are_new_here: Parece que eres nuevo aquí 🙃
83
+ markdown: Markdown
84
+ method: Método
85
+ multiple: Múltiple
86
+ name: Nombre
87
+ new_alert: Nueva alerta
88
+ new_dashboard: Nuevo dashboard
89
+ new_form: Nuevo formulario
90
+ new_query: Nueva consulta
91
+ no_data: Sin datos
92
+ not_found: Sin resultados
93
+ ok: OK
94
+ options_separated_with_new_line_or_comma: Las opciones van separadas con una nueva línea o una coma
95
+ param_name: Nombre del parámetro
96
+ path: Dirección
97
+ percent: Porcentaje
98
+ pie_chart: Gráfico circular
99
+ query: Consulta
100
+ query_has_been_saved: ¡Consulta guardada!
101
+ query_name: Nombre de la consulta
102
+ query_not_selected: Consulta no seleccionada
103
+ query_revisions: Revisiones de la consulta
104
+ reference: Referencia
105
+ reference_resource: Recurso de referencia
106
+ remove: Eliminar
107
+ reports: Reportes
108
+ request_param: Parametro de request
109
+ resources: Recursos
110
+ resubmit: Reenviar
111
+ revert: Revertir
112
+ revision_has_been_applied: Revisión aplicada
113
+ revisions: Revisiones
114
+ row_chart: Gráfico de filas
115
+ save: Guardar
116
+ save_and_create_new: Guardar y crear otro
117
+ save_as_new: Guardar como nuevo
118
+ save_dashboard: Guardar dashboard
119
+ save_form: Guardar formulario
120
+ save_query: Guardar consulta
121
+ scopes: Alcances
122
+ search: Buscar
123
+ search_placeholder: Buscar...
124
+ select_alert_tags: Etiquetas de alerta
125
+ select_dashboard: Seleccionar dashboard
126
+ select_dashboard_tags: Etiquetas de dashboard
127
+ select_form: Seleccionar formulario
128
+ select_form_tags: Etiquetas de formulario
129
+ select_options: Seleccionar opciones
130
+ select_placeholder: Seleccionar...
131
+ select_query: Seleccionar consulta
132
+ select_query_tags: Etiquetas de consulta
133
+ select_resource_placeholder: Seleccionar recurso...
134
+ selected_item_has_been_removed: El elemento seleccionado fue eliminado
135
+ selected_item_will_be_removed_are_you_sure: El elemento seleccionado será eliminado. ¿Estás seguro?
136
+ send_empty: ¿Enviar sin contenido?
137
+ send_now: Enviar ahora
138
+ send_to: Enviar a
139
+ set_tags: Seleccionar etiquetas
140
+ settings: Configuración
141
+ stacked_bars: Barras apiladas
142
+ submit: Enviar
143
+ tab_type: Tipo de pestaña
144
+ table: Tabla
145
+ tabs: Pestañas
146
+ tags: Etiquetas
147
+ timezone: Zona horaria
148
+ title: Título
149
+ type: Tipo
150
+ unable_to_load_form_data: No se pudieron cargar los datos del formulario
151
+ unable_to_remove_item: No se pudo eliminar el elemento
152
+ unable_to_remove_items: No se pudieron eliminar los elementos
153
+ unable_to_send_email: No se pudo enviar el email
154
+ unable_to_submit_form: No se pudo enviar el formulario
155
+ value: Valor
156
+ values_axis: Eje de valores
157
+ variables: Variables
158
+ visibility: Visibilidad
159
+ visualization: Visualización
160
+ alerts: Alertas
161
+ all: Todo
162
+ api: API
163
+ api_request: Request a una API
164
+ boolean: Booleano
165
+ cents: Centavos
166
+ checkbox: Checkbox
167
+ contains: Contiene
168
+ dashboard: Dashboard
169
+ dashboards: Dashboards
170
+ date: Fecha
171
+ date_and_time: Fecha y hora
172
+ default: Por defecto
173
+ details: Detalles
174
+ ends_with: Termina con
175
+ equal_to: Igual a
176
+ excludes: no contiene
177
+ field_is_not_a_number: '%{field} no es un número'
178
+ field_is_required: '%{field} es obligatorio'
179
+ field_list_cant_be_empty: "La lista %{field} no puede estar vacía"
180
+ field_must_be_exactly_in_length: '%{field} debe tener un largo de %{length} caracteres'
181
+ field_value_does_not_match_pattern: 'El valor de %{field} no coincide con %{pattern}'
182
+ file: Archivo
183
+ greater_or_equal: Mayor o igual
184
+ greater_than: Mayor que
185
+ greater_than_or_equal_to: Mayor o igual a
186
+ hidden: Esconder
187
+ image: Imagen
188
+ includes: Incluye
189
+ integer: Entero
190
+ is: Es
191
+ is_not: No es
192
+ items_will_be_removed: 'Se eliminarán %{count} elementos'
193
+ json: JSON
194
+ less_or_equal: Menor o igual
195
+ less_than: Menor que
196
+ less_than_or_equal_to: Menor o igual a
197
+ method_call: Llamado a método
198
+ number: Número
199
+ or: O
200
+ other_than: Otro que no sea
201
+ queries: Consultas
202
+ read_only: Sólo lectura
203
+ read_write: Lectura y escritura
204
+ required: Obligatorio
205
+ resource_filters: 'Filtros de %{resource}'
206
+ resource_settings: 'Configuración de %{resource}'
207
+ search_query: Buscar consulta
208
+ select: Selección
209
+ selected_item_will_be_removed: El elemento seleccionado será eliminado
210
+ should_be_a_valid_json: Debe ser un JSON válido
211
+ should_be_error_constraint: 'Debe ser %{error} %{constraint}'
212
+ starts_with: Empieza con
213
+ text: Texto
214
+ textarea: Área de texto
215
+ unit: Unidad
216
+ write_only: Sólo escritura
217
+ i:
218
+ locale: es
219
+ select:
220
+ placeholder: Seleccionar
221
+ noMatch: Sin coincidencias
222
+ loading: Cargando
223
+ table:
224
+ noDataText: Sin Datos
225
+ noFilteredDataText: Sin Datos para el filtro
226
+ confirmFilter: Aceptar
227
+ resetFilter: Quitar filtro
228
+ clearFilter: Todos
229
+ sumText: Suma
230
+ datepicker:
231
+ selectDate: Seleccionar fecha
232
+ selectTime: Seleccionar hora
233
+ startTime: Hora de inicio
234
+ endTime: Hora de fin
235
+ clear: Limpiar
236
+ ok: Aceptar
237
+ datePanelLabel: "[mmmm] [yyyy]"
238
+ month: Mes
239
+ month1: Enero
240
+ month2: Febrero
241
+ month3: Marzo
242
+ month4: Abril
243
+ month5: Mayo
244
+ month6: Junio
245
+ month7: Julio
246
+ month8: Augosto
247
+ month9: Septiembre
248
+ month10: Octubre
249
+ month11: Noviembre
250
+ month12: Diciembre
251
+ year: Año
252
+ weekStartDay: '1'
253
+ weeks:
254
+ sun: Dom
255
+ mon: Lun
256
+ tue: Mar
257
+ wed: Mié
258
+ thu: Jue
259
+ fri: Vie
260
+ sat: Sáb
261
+ months:
262
+ m1: Ene
263
+ m2: Feb
264
+ m3: Mar
265
+ m4: Abr
266
+ m5: May
267
+ m6: Jun
268
+ m7: Jul
269
+ m8: Ago
270
+ m9: Sep
271
+ m10: Oct
272
+ m11: Nov
273
+ m12: Dic
274
+ transfer:
275
+ titles:
276
+ source: Origen
277
+ target: Destino
278
+ filterPlaceholder: Buscar aquí
279
+ notFoundText: Sin resultados
280
+ modal:
281
+ okText: Aceptar
282
+ cancelText: Cancelar
283
+ poptip:
284
+ okText: Aceptar
285
+ cancelText: Cancelar
286
+ page:
287
+ prev: Página Anterior
288
+ next: Página Siguiente
289
+ total: Total
290
+ item: Elemento
291
+ items: Elementos
292
+ prev5: 5 Páginas Anteriores
293
+ next5: 5 Páginas Siguientes
294
+ page: "/page"
295
+ goto: Ir a
296
+ p: ''
297
+ rate:
298
+ star: Estrella
299
+ stars: Estrellas
300
+ tree:
301
+ emptyText: Sin Datos
@@ -10,4 +10,5 @@ ActiveRecord::ConnectionAdapters::Column.class_eval do
10
10
  def array
11
11
  false
12
12
  end
13
+ alias_method :array?, :array
13
14
  end
@@ -4,7 +4,7 @@ module Motor
4
4
  module ApiQuery
5
5
  module Filter
6
6
  LIKE_FILTER_VALUE_REGEXP = /\A%?(.*?)%?\z/.freeze
7
- DISTINCT_DESTRICTED_COLUMN_TYPES = %i[json point].freeze
7
+ DISTINCT_RESTRICTED_COLUMN_TYPES = %i[json point].freeze
8
8
 
9
9
  module_function
10
10
 
@@ -53,7 +53,7 @@ module Motor
53
53
 
54
54
  def can_apply_distinct?(rel)
55
55
  rel.columns.none? do |column|
56
- DISTINCT_DESTRICTED_COLUMN_TYPES.include?(column.type)
56
+ DISTINCT_RESTRICTED_COLUMN_TYPES.include?(column.type)
57
57
  end
58
58
  end
59
59
 
@@ -22,40 +22,6 @@ module Motor
22
22
 
23
23
  DEFAULT_SCOPE_TYPE = 'default'
24
24
 
25
- DEFAULT_ACTIONS = [
26
- {
27
- name: 'create',
28
- display_name: 'Create',
29
- action_type: 'default',
30
- preferences: {},
31
- visible: true
32
- },
33
- {
34
- name: 'edit',
35
- display_name: 'Edit',
36
- action_type: 'default',
37
- preferences: {},
38
- visible: true
39
- },
40
- {
41
- name: 'remove',
42
- display_name: 'Remove',
43
- action_type: 'default',
44
- preferences: {},
45
- visible: true
46
- }
47
- ].freeze
48
-
49
- DEFAULT_TABS = [
50
- {
51
- name: 'details',
52
- display_name: 'Details',
53
- tab_type: 'default',
54
- preferences: {},
55
- visible: true
56
- }
57
- ].freeze
58
-
59
25
  module_function
60
26
 
61
27
  def call(cache_keys = {}, current_ability = nil)
@@ -78,3 +44,4 @@ require_relative './build_schema/reorder_schema'
78
44
  require_relative './build_schema/merge_schema_configs'
79
45
  require_relative './build_schema/apply_permissions'
80
46
  require_relative './build_schema/utils'
47
+ require_relative './build_schema/defaults'
@@ -2,113 +2,123 @@
2
2
 
3
3
  module Motor
4
4
  module BuildSchema
5
- ACTIVE_STORAGE_ATTACHMENT_SCHEMA = {
6
- name: 'active_storage/attachment',
7
- slug: 'active_storage__attachments',
8
- class_name: 'ActiveStorage::Attachment',
9
- table_name: 'active_storage_attachments',
10
- primary_key: 'id',
11
- display_name: 'Attachments',
12
- display_column: 'filename',
13
- icon: 'paperclip',
14
- columns: [
15
- {
16
- name: 'id',
17
- display_name: 'ID',
18
- column_type: 'integer',
19
- access_type: 'read_only',
20
- default_value: nil,
21
- validators: [],
22
- format: {},
23
- is_array: false,
24
- reference: nil,
25
- virtual: false
26
- },
27
- {
28
- name: 'path',
29
- display_name: 'Path',
30
- column_type: 'string',
31
- access_type: 'read_only',
32
- default_value: nil,
33
- validators: [],
34
- format: {},
35
- is_array: false,
36
- reference: nil,
37
- virtual: true
38
- },
39
- {
40
- name: 'name',
41
- display_name: 'Name',
42
- column_type: 'string',
43
- access_type: 'read_write',
44
- default_value: nil,
45
- validators: [],
46
- format: {},
47
- is_array: false,
48
- reference: nil,
49
- virtual: false
50
- },
51
- {
52
- name: 'record_type',
53
- display_name: 'Record type',
54
- column_type: 'string',
55
- access_type: 'read_write',
56
- default_value: nil,
57
- validators: [],
58
- format: {},
59
- is_array: false,
60
- reference: nil,
61
- virtual: false
62
- },
63
- {
64
- name: 'record_id',
65
- display_name: 'Record',
66
- column_type: 'integer',
67
- access_type: 'read_write',
68
- default_value: nil,
69
- validators: [],
70
- format: {},
71
- is_array: false,
72
- reference: {
73
- name: 'record',
74
- display_name: 'Record',
75
- model_name: nil,
76
- reference_type: 'belongs_to',
77
- foreign_key: 'record_id',
78
- polymorphic: true
79
- },
80
- virtual: false
81
- },
82
- {
83
- name: 'file',
84
- display_name: 'File',
85
- column_type: 'file',
86
- access_type: 'write_only',
87
- default_value: nil,
88
- validators: [],
89
- format: {},
90
- is_array: false,
91
- reference: nil,
92
- virtual: false
93
- },
5
+ module ActiveStorageAttachmentSchema
6
+ module_function
7
+
8
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
9
+ def call
10
+ model = ActiveStorage::Attachment
11
+
94
12
  {
95
- name: 'created_at',
96
- display_name: 'Created at',
97
- column_type: 'datetime',
98
- access_type: 'read_only',
99
- default_value: nil,
100
- validators: [],
101
- format: {},
102
- is_array: false,
103
- reference: nil,
104
- virtual: false
105
- }
106
- ],
107
- associations: [],
108
- scopes: [],
109
- actions: Motor::BuildSchema::DEFAULT_ACTIONS.reject { |e| e[:name] == 'edit' },
110
- tabs: Motor::BuildSchema::DEFAULT_TABS,
111
- visible: true
112
- }.with_indifferent_access
13
+ name: model.name.underscore,
14
+ slug: Utils.slugify(model),
15
+ class_name: model.class.name,
16
+ table_name: model.table_name,
17
+ primary_key: model.primary_key,
18
+ display_name: model.model_name.human(count: 2, default: 'Attachments'),
19
+ display_column: 'filename',
20
+ icon: 'paperclip',
21
+ columns: [
22
+ {
23
+ name: 'id',
24
+ display_name: 'ID',
25
+ column_type: 'integer',
26
+ access_type: 'read_only',
27
+ default_value: nil,
28
+ validators: [],
29
+ format: {},
30
+ is_array: false,
31
+ reference: nil,
32
+ virtual: false
33
+ },
34
+ {
35
+ name: 'path',
36
+ display_name: model.human_attribute_name(:path),
37
+ column_type: 'string',
38
+ access_type: 'read_only',
39
+ default_value: nil,
40
+ validators: [],
41
+ format: {},
42
+ is_array: false,
43
+ reference: nil,
44
+ virtual: true
45
+ },
46
+ {
47
+ name: 'name',
48
+ display_name: model.human_attribute_name(:name),
49
+ column_type: 'string',
50
+ access_type: 'read_write',
51
+ default_value: nil,
52
+ validators: [],
53
+ format: {},
54
+ is_array: false,
55
+ reference: nil,
56
+ virtual: false
57
+ },
58
+ {
59
+ name: 'record_type',
60
+ display_name: model.human_attribute_name(:record_type),
61
+ column_type: 'string',
62
+ access_type: 'read_write',
63
+ default_value: nil,
64
+ validators: [],
65
+ format: {},
66
+ is_array: false,
67
+ reference: nil,
68
+ virtual: false
69
+ },
70
+ {
71
+ name: 'record_id',
72
+ display_name: model.human_attribute_name(:record),
73
+ column_type: 'integer',
74
+ access_type: 'read_write',
75
+ default_value: nil,
76
+ validators: [],
77
+ format: {},
78
+ is_array: false,
79
+ reference: {
80
+ name: 'record',
81
+ display_name: model.human_attribute_name(:record),
82
+ model_name: nil,
83
+ reference_type: 'belongs_to',
84
+ foreign_key: 'record_id',
85
+ polymorphic: true
86
+ },
87
+ virtual: false
88
+ },
89
+ {
90
+ name: 'file',
91
+ display_name: model.human_attribute_name(:file),
92
+ column_type: 'file',
93
+ access_type: 'write_only',
94
+ default_value: nil,
95
+ validators: [],
96
+ format: {},
97
+ is_array: false,
98
+ reference: nil,
99
+ virtual: false
100
+ },
101
+ {
102
+ name: 'created_at',
103
+ display_name: model.human_attribute_name(:created_at),
104
+ column_type: 'datetime',
105
+ access_type: 'read_only',
106
+ default_value: nil,
107
+ validators: [],
108
+ format: {},
109
+ is_array: false,
110
+ reference: nil,
111
+ virtual: false
112
+ }
113
+ ],
114
+ associations: [],
115
+ scopes: [],
116
+ actions: Motor::BuildSchema::Defaults.actions.reject { |e| e[:name] == 'edit' },
117
+ tabs: Motor::BuildSchema::Defaults.tabs,
118
+ visible: true
119
+ }.with_indifferent_access
120
+ end
121
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
122
+ end
113
123
  end
114
124
  end
@@ -47,7 +47,7 @@ module Motor
47
47
  def add_password_column!(columns)
48
48
  columns << {
49
49
  name: 'password',
50
- display_name: 'Password',
50
+ display_name: I18n.t('motor.password'),
51
51
  column_type: 'string',
52
52
  access_type: 'write_only',
53
53
  default_value: nil,
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Motor
4
+ module BuildSchema
5
+ module Defaults
6
+ module_function
7
+
8
+ # rubocop:disable Metrics/MethodLength
9
+ def actions
10
+ [
11
+ {
12
+ name: 'create',
13
+ display_name: I18n.t('motor.create'),
14
+ action_type: 'default',
15
+ preferences: {},
16
+ visible: true
17
+ },
18
+ {
19
+ name: 'edit',
20
+ display_name: I18n.t('motor.edit'),
21
+ action_type: 'default',
22
+ preferences: {},
23
+ visible: true
24
+ },
25
+ {
26
+ name: 'remove',
27
+ display_name: I18n.t('motor.remove'),
28
+ action_type: 'default',
29
+ preferences: {},
30
+ visible: true
31
+ }
32
+ ].freeze
33
+ end
34
+ # rubocop:enable Metrics/MethodLength
35
+
36
+ def tabs
37
+ [
38
+ {
39
+ name: 'details',
40
+ display_name: I18n.t('motor.details'),
41
+ tab_type: 'default',
42
+ preferences: {},
43
+ visible: true
44
+ }
45
+ ].freeze
46
+ end
47
+ end
48
+ end
49
+ end
@@ -6,6 +6,8 @@ module Motor
6
6
  MUTEX = Mutex.new
7
7
  UNIFIED_TYPES = ActiveRecordUtils::Types::UNIFIED_TYPES
8
8
 
9
+ I18N_SCOPES_KEY = 'activerecord.scopes'
10
+
9
11
  module_function
10
12
 
11
13
  def call
@@ -46,7 +48,7 @@ module Motor
46
48
  def build_model_schema(model)
47
49
  model_name = model.name
48
50
 
49
- return Motor::BuildSchema::ACTIVE_STORAGE_ATTACHMENT_SCHEMA if model_name == 'ActiveStorage::Attachment'
51
+ return Motor::BuildSchema::ActiveStorageAttachmentSchema.call if model_name == 'ActiveStorage::Attachment'
50
52
 
51
53
  {
52
54
  name: model_name.underscore,
@@ -54,14 +56,14 @@ module Motor
54
56
  table_name: model.table_name,
55
57
  class_name: model.name,
56
58
  primary_key: model.primary_key,
57
- display_name: model_name.titleize.pluralize,
59
+ display_name: model.model_name.human(count: :many, default: model_name.titleize.pluralize),
58
60
  display_column: FindDisplayColumn.call(model),
59
61
  columns: fetch_columns(model),
60
62
  associations: fetch_associations(model),
61
- icon: Motor::FindIcon.call(model.name.titleize),
63
+ icon: Motor::FindIcon.call(model_name),
62
64
  scopes: fetch_scopes(model),
63
- actions: DEFAULT_ACTIONS,
64
- tabs: DEFAULT_TABS,
65
+ actions: BuildSchema::Defaults.actions,
66
+ tabs: BuildSchema::Defaults.tabs,
65
67
  visible: true
66
68
  }.with_indifferent_access
67
69
  end
@@ -74,7 +76,9 @@ module Motor
74
76
 
75
77
  {
76
78
  name: scope_name,
77
- display_name: scope_name.humanize,
79
+ display_name: I18n.t(scope_name,
80
+ scope: [I18N_SCOPES_KEY, model.name.underscore].join('.'),
81
+ default: scope_name.humanize),
78
82
  scope_type: DEFAULT_SCOPE_TYPE,
79
83
  visible: true,
80
84
  preferences: {}
@@ -102,9 +106,9 @@ module Motor
102
106
 
103
107
  {
104
108
  name: column.name,
105
- display_name: Utils.humanize_column_name(column.name),
109
+ display_name: Utils.humanize_column_name(model.human_attribute_name(column.name)),
106
110
  column_type: is_enum ? 'string' : UNIFIED_TYPES[column.type.to_s] || column.type.to_s,
107
- is_array: column.respond_to?(:array?) && column.array?,
111
+ is_array: column.array?,
108
112
  access_type: COLUMN_NAME_ACCESS_TYPES.fetch(column.name, ColumnAccessTypes::READ_WRITE),
109
113
  default_value: default_attrs[column.name],
110
114
  validators: fetch_validators(model, column.name),
@@ -141,21 +145,21 @@ module Motor
141
145
 
142
146
  {
143
147
  name: column_name,
144
- display_name: column_name.humanize,
148
+ display_name: model.human_attribute_name(name),
145
149
  column_type: is_attachment ? 'file' : 'integer',
146
150
  access_type: access_type,
147
151
  default_value: default_attrs[column_name],
148
152
  validators: fetch_validators(model, column_name, ref),
149
153
  format: {},
150
- reference: build_reference(name, ref),
154
+ reference: build_reference(model, name, ref),
151
155
  virtual: false
152
156
  }
153
157
  end
154
158
 
155
- def build_reference(name, reflection)
159
+ def build_reference(model, name, reflection)
156
160
  {
157
161
  name: name,
158
- display_name: name.humanize,
162
+ display_name: model.human_attribute_name(name),
159
163
  model_name: reflection.polymorphic? ? nil : reflection.klass.name.underscore,
160
164
  reference_type: reflection.belongs_to? ? 'belongs_to' : 'has_one',
161
165
  foreign_key: reflection.foreign_key,
@@ -175,7 +179,7 @@ module Motor
175
179
 
176
180
  {
177
181
  name: name,
178
- display_name: name.humanize,
182
+ display_name: model.human_attribute_name(name),
179
183
  slug: name.underscore,
180
184
  model_name: model_class.name.underscore,
181
185
  foreign_key: ref.foreign_key,
@@ -29,7 +29,7 @@ module Motor
29
29
  updated_model = model.merge(configs.slice(*RESOURCE_ATTRS))
30
30
 
31
31
  merge_actions!(updated_model, configs)
32
- merge_assiciations!(updated_model, configs)
32
+ merge_associations!(updated_model, configs)
33
33
  merge_columns!(updated_model, configs)
34
34
  merge_tabs!(updated_model, configs)
35
35
  merge_scopes!(updated_model, configs)
@@ -40,7 +40,7 @@ module Motor
40
40
  # @param model [HashWithIndifferentAccess]
41
41
  # @param configs [HashWithIndifferentAccess]
42
42
  # @return [HashWithIndifferentAccess]
43
- def merge_assiciations!(model, configs)
43
+ def merge_associations!(model, configs)
44
44
  model[:associations] = merge_by_name(
45
45
  model[:associations],
46
46
  configs[:associations],
@@ -4,12 +4,12 @@ module Motor
4
4
  module BuildSchema
5
5
  module Utils
6
6
  ABBREVIATIONS = {
7
- 'id' => 'ID',
8
- 'url' => 'URL',
9
- 'iso' => 'ISO',
7
+ 'Id' => 'ID',
8
+ 'Url' => 'URL',
9
+ 'Iso' => 'ISO',
10
10
  'vip' => 'VIP',
11
- 'ip' => 'IP',
12
- 'zip' => 'ZIP'
11
+ 'Ip' => 'IP',
12
+ 'Zip' => 'ZIP'
13
13
  }.freeze
14
14
 
15
15
  module_function
@@ -15,7 +15,7 @@ module Motor
15
15
  def call(current_user = nil, current_ability = nil)
16
16
  cache_keys = LoadFromCache.load_cache_keys
17
17
 
18
- CACHE_STORE.fetch("#{cache_keys.hash}#{current_user&.id}") do
18
+ CACHE_STORE.fetch("#{I18n.locale}#{cache_keys.hash}#{current_user&.id}") do
19
19
  CACHE_STORE.clear
20
20
 
21
21
  data = build_data(cache_keys, current_user, current_ability)
@@ -29,6 +29,7 @@ module Motor
29
29
  current_user: current_user&.as_json(only: %i[id email]),
30
30
  current_rules: current_ability.serialized_rules,
31
31
  audits_count: Motor::Audit.count,
32
+ i18n: i18n_data,
32
33
  base_path: Motor::Admin.routes.url_helpers.motor_path,
33
34
  schema: Motor::BuildSchema.call(cache_keys, current_ability),
34
35
  header_links: header_links_data_hash(cache_keys[:configs]),
@@ -42,6 +43,10 @@ module Motor
42
43
  }
43
44
  end
44
45
 
46
+ def i18n_data
47
+ I18n.t('motor', default: I18n.t('motor', locale: :en))
48
+ end
49
+
45
50
  # @return [String]
46
51
  def build_cache_key(cache_keys, key, current_user, current_ability)
47
52
  "#{cache_keys[key].hash}#{current_user&.id}#{current_ability&.rules_hash}"
data/lib/motor/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Motor
4
- VERSION = '0.1.62'
4
+ VERSION = '0.1.67'
5
5
  end
@@ -2068,11 +2068,11 @@
2068
2068
  "mail-opened.svg": "icons/mail-opened.svg",
2069
2069
  "mail.svg": "icons/mail.svg",
2070
2070
  "mailbox.svg": "icons/mailbox.svg",
2071
- "main-fd0f75f789196ce24ffd.css.gz": "main-fd0f75f789196ce24ffd.css.gz",
2072
- "main-fd0f75f789196ce24ffd.js.LICENSE.txt": "main-fd0f75f789196ce24ffd.js.LICENSE.txt",
2073
- "main-fd0f75f789196ce24ffd.js.gz": "main-fd0f75f789196ce24ffd.js.gz",
2074
- "main.css": "main-fd0f75f789196ce24ffd.css",
2075
- "main.js": "main-fd0f75f789196ce24ffd.js",
2071
+ "main-8ec599650b99734d9348.css.gz": "main-8ec599650b99734d9348.css.gz",
2072
+ "main-8ec599650b99734d9348.js.LICENSE.txt": "main-8ec599650b99734d9348.js.LICENSE.txt",
2073
+ "main-8ec599650b99734d9348.js.gz": "main-8ec599650b99734d9348.js.gz",
2074
+ "main.css": "main-8ec599650b99734d9348.css",
2075
+ "main.js": "main-8ec599650b99734d9348.js",
2076
2076
  "man.svg": "icons/man.svg",
2077
2077
  "manual-gearbox.svg": "icons/manual-gearbox.svg",
2078
2078
  "map-2.svg": "icons/map-2.svg",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motor-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.62
4
+ version: 0.1.67
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pete Matsyburka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-21 00:00:00.000000000 Z
11
+ date: 2021-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord-filter
@@ -162,6 +162,8 @@ files:
162
162
  - app/views/layouts/motor/application.html.erb
163
163
  - app/views/motor/alerts_mailer/alert_email.html.erb
164
164
  - app/views/motor/ui/show.html.erb
165
+ - config/locales/en.yml
166
+ - config/locales/es.yml
165
167
  - config/routes.rb
166
168
  - lib/generators/motor/install_generator.rb
167
169
  - lib/generators/motor/migration.rb
@@ -194,6 +196,7 @@ files:
194
196
  - lib/motor/build_schema/active_storage_attachment_schema.rb
195
197
  - lib/motor/build_schema/adjust_devise_model_schema.rb
196
198
  - lib/motor/build_schema/apply_permissions.rb
199
+ - lib/motor/build_schema/defaults.rb
197
200
  - lib/motor/build_schema/find_display_column.rb
198
201
  - lib/motor/build_schema/find_icon.rb
199
202
  - lib/motor/build_schema/load_from_rails.rb
@@ -1491,8 +1494,8 @@ files:
1491
1494
  - ui/dist/icons/zoom-money.svg.gz
1492
1495
  - ui/dist/icons/zoom-out.svg.gz
1493
1496
  - ui/dist/icons/zoom-question.svg.gz
1494
- - ui/dist/main-fd0f75f789196ce24ffd.css.gz
1495
- - ui/dist/main-fd0f75f789196ce24ffd.js.gz
1497
+ - ui/dist/main-8ec599650b99734d9348.css.gz
1498
+ - ui/dist/main-8ec599650b99734d9348.js.gz
1496
1499
  - ui/dist/manifest.json
1497
1500
  homepage:
1498
1501
  licenses: