eventsimple 1.2.1 → 1.2.2

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: 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