Skip to content
This repository was archived by the owner on Jan 30, 2024. It is now read-only.

Commit 0082984

Browse files
author
raubineau
committed
Merge branch 'devel' of github.com:ForestAdmin/forest-rails into devel
2 parents c08a391 + f4befd2 commit 0082984

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+858
-245
lines changed

CHANGELOG.md

+86
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,92 @@
22

33
## [Unreleased]
44

5+
## RELEASE 2.11.5 - 2018-07-31
6+
### Fixed
7+
- Search - Fix the broken search if the collection contains Array fields. [Regression introduced in 2.9.0]
8+
- Search - Highlight the records id if it matches with the search value.
9+
10+
## RELEASE 2.11.4 - 2018-07-31
11+
### Fixed
12+
- Search - Fix the search while typing single quotes in the search value.
13+
14+
## RELEASE 2.11.3 - 2018-07-30
15+
### Fixed
16+
- Records Display - Fix collections display for project using Ruby version inferior to 2.3.0. [Regression introduced in 2.10.1]
17+
18+
## RELEASE 2.11.2 - 2018-07-30
19+
### Fixed
20+
- Smart BelongsTo - Fix the reference field values display in the records list of collections using Smart BelongsTo relationships.
21+
22+
## RELEASE 2.11.1 - 2018-07-30
23+
### Fixed
24+
- Records Count - Fix list display error if the collection name is different from the class name (routing issue to compute the count).
25+
26+
## RELEASE 2.11.0 - 2018-07-19
27+
### Changed
28+
- Performance - Improve the speed of listing the records by executing their count into another request.
29+
30+
## RELEASE 2.10.5 - 2018-07-11
31+
### Fixed
32+
- HasMany Relationships - Fix the performance of the related data retrieval if the collection has hidden belongsTo associations in the list.
33+
34+
## RELEASE 2.10.4 - 2018-07-11
35+
### Fixed
36+
- Mixpanel Integration - Only retrieve events that are less than 60 days old to be compliant with the Mixpanel's API.
37+
38+
## RELEASE 2.10.3 - 2018-07-10
39+
### Fixed
40+
- ActiveStorage - Support ActiveStorage without having to set eager_load property to true in development environments.
41+
42+
## RELEASE 2.10.2 - 2018-07-10
43+
### Fixed
44+
- Smart Views - Fix associated data retrieval from Smart Views (where the fields to retrieve are not specified in the query params).
45+
46+
## RELEASE 2.10.1 - 2018-07-10
47+
### Fixed
48+
- Stripe Integration - Improve the error handling if the customer Stripe Id is not found.
49+
- Stripe Integration - Trial to prevent uninitialized constant errors with Stripe classes.
50+
51+
## RELEASE 2.10.0 - 2018-07-10
52+
### Added
53+
- Mixpanel Integration - Add the integration to display the last 100 Mixpanel events of a "user" record.
54+
55+
## RELEASE 2.9.2 - 2018-07-04
56+
### Fixed
57+
- Database Connection - If the database is not accessible on server start, the liana doesn't send an Apimap anymore (it was a "partial" Apimap in such case).
58+
59+
## RELEASE 2.9.1 - 2018-07-03
60+
### Changed
61+
- Technical - Use the "official" domain for the default server host.
62+
63+
### Fixed
64+
- Record Creation - Fix the search of belongsTo associated records in record creation forms if the belongsTo foreign key is a UUID.
65+
66+
## RELEASE 2.9.0 - 2018-06-28
67+
### Added
68+
- Search - Display highlighted matches on table view when searching.
69+
70+
## RELEASE 2.8.6 - 2018-06-27
71+
### Fixed
72+
- Intercom Integration - Users can now access to the Intercom Details page.
73+
74+
## RELEASE 2.8.5 - 2018-06-26
75+
### Fixed
76+
- Namespacing - Prevent a potential error on server start if a ResourcesController class already exists in another lib of the client project.
77+
- Filters - Filtering on 2 different belongsTo foreign keys referencing the same table now returns the expected records.
78+
79+
## RELEASE 2.8.4 - 2018-06-21
80+
### Changed
81+
- Onboarding - Improve the information message if the liana is properly setup and users run the "rails g forest_liana:install".
82+
83+
### Fixed
84+
- Permissions - Fix automated permission for projects having multiple teams.
85+
86+
## RELEASE 2.8.3 - 2018-06-20
87+
### Fixed
88+
- Onboarding - If the liana is properly setup and users run the "rails g forest_liana:install" command again, the task will be skipped.
89+
- Onboarding - The install generator now supports credentials.yml.enc file introduced in Rails 5.2.
90+
591
## RELEASE 2.8.2 - 2018-06-18
692
### Fixed
793
- Development Autoreload - Prevent "A copy of ForestLiana::ResourcesController has been removed from the module tree but is still active!" in development mode.

Gemfile.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
forest_liana (2.8.2)
4+
forest_liana (2.11.5)
55
arel-helpers
66
bcrypt
77
groupdate
@@ -154,4 +154,4 @@ DEPENDENCIES
154154
useragent
155155

156156
BUNDLED WITH
157-
1.16.1
157+
1.16.2

app/controllers/forest_liana/application_controller.rb

+17-10
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,17 @@ def serialize_model(record, options = {})
4040
force_utf8_encoding(json)
4141
end
4242

43-
def serialize_models(records, options = {})
43+
def serialize_models(records, options = {}, fields_searched = [])
4444
options[:is_collection] = true
4545
json = JSONAPI::Serializer.serialize(records, options)
4646

47-
if options[:count]
48-
json[:meta] = {} unless json[:meta]
49-
json[:meta][:count] = options[:count]
50-
end
51-
52-
if !options[:has_more].nil?
53-
json[:meta] = {} unless json[:meta]
54-
json[:meta][:has_more] = options[:has_more]
47+
if options[:params] && options[:params][:search]
48+
# NOTICE: Add the Smart Fields with a 'String' type.
49+
fields_searched.concat(get_collection.string_smart_fields_names).uniq!
50+
json['meta'] = {
51+
decorators: ForestLiana::DecorationHelper
52+
.decorate_for_search(json, fields_searched, options[:params][:search])
53+
}
5554
end
5655

5756
force_utf8_encoding(json)
@@ -68,6 +67,7 @@ def authenticate_user_from_jwt
6867

6968
@jwt_decoded_token = JWT.decode(token, ForestLiana.auth_secret, true,
7069
{ algorithm: 'HS256', leeway: 30 }).try(:first)
70+
@rendering_id = @jwt_decoded_token['data']['relationships']['renderings']['data'][0]['id']
7171
else
7272
head :unauthorized
7373
end
@@ -150,7 +150,14 @@ def fields_per_model(params_fields, model)
150150
if model_association
151151
model_name = model_association.class_name
152152
# NOTICE: Join fields in case of model with self-references.
153-
fields[model_name] = [fields[model_name], relation_fields].join(',')
153+
if fields[model_name]
154+
fields[model_name] = [
155+
fields[model_name],
156+
relation_fields
157+
].join(',').split(',').uniq.join(',')
158+
else
159+
fields[model_name] = relation_fields
160+
end
154161
end
155162
end
156163
fields

app/controllers/forest_liana/associations_controller.rb

+25-5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ def index
2323
end
2424
end
2525

26+
def count
27+
begin
28+
getter = HasManyGetter.new(@resource, @association, params)
29+
getter.count
30+
31+
render serializer: nil, json: { count: getter.records_count }
32+
rescue => error
33+
FOREST_LOGGER.error "Association Index Count error: #{error}\n#{format_stacktrace(error)}"
34+
internal_server_error
35+
end
36+
end
37+
2638
def update
2739
begin
2840
updater = BelongsToUpdater.new(@resource, @association, params)
@@ -105,20 +117,28 @@ def render_jsonapi getter
105117
records = getter.records.map { |record| get_record(record) }
106118

107119
includes = getter.includes_for_serialization
108-
if includes.length > 0
120+
if fields_to_serialize && includes.length > 0
109121
association_name = ForestLiana.name_for(@association.klass)
110122
fields_to_serialize[association_name] += ",#{includes.join(',')}"
111123
end
112124

113125
json = serialize_models(
114126
records,
115-
include: includes,
116-
fields: fields_to_serialize,
117-
count: getter.count,
118-
params: params
127+
{
128+
include: includes,
129+
fields: fields_to_serialize,
130+
params: params
131+
},
132+
getter.search_query_builder.fields_searched
119133
)
120134

121135
render serializer: nil, json: json
122136
end
137+
138+
def get_collection
139+
model_association = @resource.reflect_on_association(params[:association_name].to_sym).klass
140+
collection_name = ForestLiana.name_for(model_association)
141+
@collection ||= ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
142+
end
123143
end
124144
end

app/controllers/forest_liana/intercom_controller.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def conversations
66

77
render serializer: nil, json: serialize_models(getter.records, {
88
context: { type: get_serializer_type('intercom_conversations') },
9-
count: getter.count
9+
meta: { count: getter.count }
1010
})
1111
end
1212

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module ForestLiana
2+
class MixpanelController < ForestLiana::ApplicationController
3+
def last_events
4+
collection_name = params[:collection]
5+
mapping = ForestLiana.integrations[:mixpanel][:mapping]
6+
mapping_for_current_collection = mapping.find { |item| item.start_with?(collection_name) }
7+
field_name = mapping_for_current_collection.split('.')[1]
8+
id = params[:id]
9+
field_value = collection_name.constantize.find_by('id': id)[field_name]
10+
11+
getter = ForestLiana::MixpanelLastEventsGetter.new(params)
12+
getter.perform(field_name, field_value)
13+
14+
custom_properties = ForestLiana.integrations[:mixpanel][:custom_properties]
15+
MixpanelEventSerializer.attributes(*custom_properties)
16+
17+
render serializer: nil, json: serialize_models(getter.records, {
18+
context: { type: get_serializer_type('mixpanel_events') },
19+
count: getter.count,
20+
})
21+
end
22+
23+
def get_serializer_type(suffix)
24+
"#{params[:collection]}_#{suffix}"
25+
end
26+
end
27+
end

app/controllers/forest_liana/resources_controller.rb

+44-11
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@ class ResourcesController < ForestLiana::ApplicationController
1616
def index
1717
begin
1818
if request.format == 'csv'
19-
return head :forbidden unless ForestLiana::PermissionsChecker.new(@resource, 'export').is_authorized?
19+
checker = ForestLiana::PermissionsChecker.new(@resource, 'export', @rendering_id)
20+
return head :forbidden unless checker.is_authorized?
2021
elsif params.has_key?(:searchToEdit)
21-
return head :forbidden unless ForestLiana::PermissionsChecker.new(@resource, 'searchToEdit').is_authorized?
22+
checker = ForestLiana::PermissionsChecker.new(@resource, 'searchToEdit', @rendering_id)
23+
return head :forbidden unless checker.is_authorized?
2224
else
23-
return head :forbidden unless ForestLiana::PermissionsChecker.new(@resource, 'list').is_authorized?
25+
checker = ForestLiana::PermissionsChecker.new(@resource, 'list', @rendering_id)
26+
return head :forbidden unless checker.is_authorized?
2427
end
2528

2629
getter = ForestLiana::ResourcesGetter.new(@resource, params)
@@ -39,9 +42,29 @@ def index
3942
end
4043
end
4144

45+
def count
46+
begin
47+
checker = ForestLiana::PermissionsChecker.new(@resource, 'list', @rendering_id)
48+
return head :forbidden unless checker.is_authorized?
49+
50+
getter = ForestLiana::ResourcesGetter.new(@resource, params)
51+
getter.count
52+
53+
render serializer: nil, json: { count: getter.records_count }
54+
55+
rescue ForestLiana::Errors::LiveQueryError => error
56+
render json: { errors: [{ status: 422, detail: error.message }] },
57+
status: :unprocessable_entity, serializer: nil
58+
rescue => error
59+
FOREST_LOGGER.error "Records Index Count error: #{error}\n#{format_stacktrace(error)}"
60+
internal_server_error
61+
end
62+
end
63+
4264
def show
4365
begin
44-
return head :forbidden unless ForestLiana::PermissionsChecker.new(@resource, 'show').is_authorized?
66+
checker = ForestLiana::PermissionsChecker.new(@resource, 'show', @rendering_id)
67+
return head :forbidden unless checker.is_authorized?
4568

4669
getter = ForestLiana::ResourceGetter.new(@resource, params)
4770
getter.perform
@@ -56,7 +79,8 @@ def show
5679

5780
def create
5881
begin
59-
return head :forbidden unless ForestLiana::PermissionsChecker.new(@resource, 'create').is_authorized?
82+
checker = ForestLiana::PermissionsChecker.new(@resource, 'create', @rendering_id)
83+
return head :forbidden unless checker.is_authorized?
6084

6185
creator = ForestLiana::ResourceCreator.new(@resource, params)
6286
creator.perform
@@ -79,7 +103,8 @@ def create
79103

80104
def update
81105
begin
82-
return head :forbidden unless ForestLiana::PermissionsChecker.new(@resource, 'update').is_authorized?
106+
checker = ForestLiana::PermissionsChecker.new(@resource, 'update', @rendering_id)
107+
return head :forbidden unless checker.is_authorized?
83108

84109
updater = ForestLiana::ResourceUpdater.new(@resource, params)
85110
updater.perform
@@ -102,7 +127,8 @@ def update
102127

103128
def destroy
104129
begin
105-
return head :forbidden unless ForestLiana::PermissionsChecker.new(@resource, 'delete').is_authorized?
130+
checker = ForestLiana::PermissionsChecker.new(@resource, 'delete', @rendering_id)
131+
return head :forbidden unless checker.is_authorized?
106132

107133
@resource.destroy(params[:id])
108134
head :no_content
@@ -152,13 +178,20 @@ def render_jsonapi getter
152178

153179
json = serialize_models(
154180
records,
155-
include: includes(getter),
156-
fields: fields_to_serialize,
157-
count: getter.count,
158-
params: params
181+
{
182+
include: includes(getter),
183+
fields: fields_to_serialize,
184+
params: params
185+
},
186+
getter.search_query_builder.fields_searched
159187
)
160188

161189
render serializer: nil, json: json
162190
end
191+
192+
def get_collection
193+
collection_name = ForestLiana.name_for(@resource)
194+
@collection ||= ForestLiana.apimap.find { |collection| collection.name.to_s == collection_name }
195+
end
163196
end
164197
end

app/controllers/forest_liana/router.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
class ForestLiana::Router
22
def call(env)
33
params = env['action_dispatch.request.path_parameters']
4-
resource = ForestLiana::SchemaUtils.find_model_from_collection_name(params[:collection])
4+
collection_name = params[:collection]
5+
resource = ForestLiana::SchemaUtils.find_model_from_collection_name(collection_name)
56

67
begin
78
component_prefix = ForestLiana.component_prefix(resource)
@@ -14,6 +15,8 @@ def call(env)
1415
when 'GET'
1516
if params[:id]
1617
action = 'show'
18+
elsif env['PATH_INFO'] == "/#{collection_name}/count"
19+
action = 'count'
1720
else
1821
action = 'index'
1922
end

0 commit comments

Comments
 (0)