eventsimple 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 985c47a587ea7f6476248e8c5b6257d51482f41832bb6055e6da514e4dbd8914
4
- data.tar.gz: 809b1c8d0b3f21b4d4765cd06530e4dedea076ebd3c07b5a027d7822f5bb226f
3
+ metadata.gz: 73a860de275fa7998ed8048ee53ac70ec2b7b5872456bd1c03422cb4218847cb
4
+ data.tar.gz: 0aee5f6d22f2630d1a513f3847441fb8e1f28399512f9046be161c65c4cb49f2
5
5
  SHA512:
6
- metadata.gz: 86d4bb8d7a529d14f287ad54242b2e3c7b305fb6092981e84412b9854bc8c76566d781e122147f9522a7a40da77d57d82a60757e441bedf307a8b72697f36727
7
- data.tar.gz: 0e18b342e6ad42462e35101ff10a9890962cd540a3142c8d7cd8d9f87e2ee862d89fb8d9e52a01695728099f526caf14331a2ab4d9b1dd87bc517cb77af42821
6
+ metadata.gz: a92575ecbabbbf572beb4c61c7f46fff241e339b737d224ee93bf78b24df6dbedeab28a8fa7721d3a213b833e5f799b0a31e76234b41f7c903ea208ff04db2f9
7
+ data.tar.gz: 358feb4234563044b7609e46130913c161cdd2fa555cbfba7be4faea1e5e3bf3e26b83f546da72ab46142b1de5097976e13dfec56b44105077e80e33609e1f8e
data/CHANGELOG.md CHANGED
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 1.2.2 - 2023-11-29
10
+ ### Changed
11
+ - Add support for filtering events by aggregate model attributes.
12
+
9
13
  ## 1.2.1 - 2023-11-18
10
14
  ### Changed
11
15
  - Allow timestamp data in events to override default timestamps update.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- eventsimple (1.2.1)
4
+ eventsimple (1.2.2)
5
5
  dry-struct (~> 1.6)
6
6
  dry-types (~> 1.7)
7
7
  pg (~> 1.4)
@@ -158,7 +158,7 @@ GEM
158
158
  mini_mime (1.1.5)
159
159
  minitest (5.20.0)
160
160
  nenv (0.3.0)
161
- net-imap (0.4.5)
161
+ net-imap (0.4.7)
162
162
  date
163
163
  net-protocol
164
164
  net-pop (0.1.2)
@@ -8,6 +8,10 @@ module Eventsimple
8
8
  @event_id = params[:e] || -1
9
9
  @tab_id = (params[:t] == 'event') ? 'event' : 'entity'
10
10
 
11
+ filter_columns = @model_class._filter_attributes
12
+ params_filters = params.permit(filters: {})[:filters] || {}
13
+ @filters = filter_columns.to_h { |column| [column, params_filters[column]] }
14
+
11
15
  primary_key = @model_class.event_class._aggregate_id
12
16
  @entity = @model_class.find_by!(primary_key => @aggregate_id)
13
17
  @entity_event_history = @entity.events.reverse
@@ -2,9 +2,44 @@ module Eventsimple
2
2
  class ModelsController < ApplicationController
3
3
  def show
4
4
  @model_name = params[:name]
5
+ model_class = event_classes.find { |d| d.name == @model_name }
5
6
 
6
- model_event_class = event_classes.find { |d| d.name == @model_name }.event_class
7
- @latest_entities = model_event_class.last(20).reverse
7
+ scope = apply_filter(model_class, model_class.event_class)
8
+
9
+ @latest_entities = scope.last(20).reverse
10
+
11
+ check_redirect_to_entity
12
+ end
13
+
14
+ private
15
+
16
+ def apply_filter(model_class, model_event_class)
17
+ filter_columns = model_class._filter_attributes
18
+
19
+ params_filters = params.permit(filters: {})[:filters] || {}
20
+ @filters = filter_columns.to_h { |column| [column, params_filters[column]] }
21
+
22
+ return model_event_class unless @filters.any?
23
+
24
+ aggregate_class_symbol = model_event_class._aggregate_klass.model_name.element.to_sym
25
+ model_event_class = model_event_class.joins(aggregate_class_symbol)
26
+ @filters.each do |key, value|
27
+ next if value.blank?
28
+ key = model_event_class._aggregate_id if key == :aggregate_id
29
+ model_event_class = model_event_class.where({ aggregate_class_symbol => { key => value } })
30
+ end
31
+
32
+ model_event_class
33
+ end
34
+
35
+ def check_redirect_to_entity
36
+ return unless @latest_entities.any?
37
+
38
+ first_aggregate_id = @latest_entities.first.aggregate_id
39
+
40
+ return unless @latest_entities.all? { |entity| entity.aggregate_id == first_aggregate_id }
41
+
42
+ redirect_to model_entity_path(@model_name, first_aggregate_id, filters: @filters)
8
43
  end
9
44
  end
10
45
  end
@@ -1,26 +1,20 @@
1
1
  <!-- Header Search Start -->
2
2
  <header class="container mb-4">
3
- <div class="row">
4
- <div class="col col-sm-3">
5
- <select id="form-search-model-name" class="form-select" aria-label="Model select" onchange="document.location.href=this.value" required>
6
- <option value="">Choose event source model</option>
7
- <% event_class_names.each do |klass| %>
8
- <% is_active = klass === @model_name ? 'selected' : '' %>
9
- <option value="<%= model_path(klass) %>" <%= is_active %>><%= klass %></option>
10
- <% end %>
11
- </select>
12
- </div>
13
-
14
- <% if @model_name %>
15
- <div class="col col-sm-7">
16
- <%= form_with url: model_entity_path(@model_name, ''), id: 'model-search' do |f| %>
17
- <%= f.search_field :event_id, class: 'form-control', placeholder: 'Canonical identifier', value: @aggregate_id, required: true, aria: { label: 'Entity canonical identifier' } %>
3
+ <% if @model_name %>
4
+ <%= form_with scope: :filters, url: model_path(@model_name), method: :get, id: 'model-filter' do |f| %>
5
+ <div class="row">
6
+ <label for="filters_keys[keys]" class="col-sm-2 col-form-label">Filter attribute</label>
7
+ <div class="form-group col-sm-3">
8
+ <%= select :filters_keys, :keys, @filters.keys, { selected: @filters.compact.keys&.first }, { class:"form-select", onchange: "document.getElementById('model-filter-value').name=`filters[${this.value}]`" } %>
18
9
  </div>
19
- <div class="col col-sm-2">
10
+ <div class="form-group col-sm-5">
11
+ <%= f.search_field @filters.compact.keys&.first || @filters.keys.first, id: 'model-filter-value', value: @filters.compact.values&.first, class:"form-control", placeholder: "Filter value" %>
12
+ </div>
13
+ <div class="form-group col-sm-2">
20
14
  <%= f.submit 'Search', class: 'btn btn-primary' %>
21
- <% end %>
15
+ </div>
22
16
  </div>
23
17
  <% end %>
24
- </div>
18
+ <% end %>
25
19
  </header>
26
20
  <!-- Header Search End -->
@@ -62,12 +62,6 @@
62
62
  query.set(param, value);
63
63
  link.attr("href",window.location.pathname + '?' + query.toString());
64
64
  });
65
-
66
- $('#model-search').on('submit', (event) => {
67
- event.preventDefault();
68
- const form = $(event.currentTarget);
69
- window.location = form.attr('action') + form.children('#event_id').val();
70
- });
71
65
  });
72
66
  </script>
73
67
 
@@ -2,7 +2,7 @@ module Eventsimple
2
2
  module Entity
3
3
  DEFAULT_IGNORE_PROPS = %w[id lock_version].freeze
4
4
 
5
- def event_driven_by(event_klass, aggregate_id:)
5
+ def event_driven_by(event_klass, aggregate_id:, filter_attributes: [])
6
6
  has_many :events, class_name: event_klass.name.to_s,
7
7
  foreign_key: :aggregate_id,
8
8
  primary_key: aggregate_id,
@@ -13,6 +13,9 @@ module Eventsimple
13
13
 
14
14
  class_attribute :ignored_for_projection, default: []
15
15
 
16
+ class_attribute :_filter_attributes
17
+ self._filter_attributes = [aggregate_id] | Array.wrap(filter_attributes)
18
+
16
19
  # disable automatic timestamp updates
17
20
  self.record_timestamps = false
18
21
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Eventsimple
4
- VERSION = '1.2.1'
4
+ VERSION = '1.2.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eventsimple
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zulfiqar Ali
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-18 00:00:00.000000000 Z
11
+ date: 2023-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-struct