Skip to content

Commit

Permalink
Merge pull request #141 from paviliondev/abstract_filters
Browse files Browse the repository at this point in the history
Abstract connection filters to make them re-usable
  • Loading branch information
angusmcleod authored Aug 15, 2024
2 parents 8d75f26 + 51827d8 commit 76dbdf0
Show file tree
Hide file tree
Showing 25 changed files with 274 additions and 198 deletions.
14 changes: 10 additions & 4 deletions app/controllers/discourse_events/connection_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def connection_params
:category_id,
:source_id,
:client,
filters: %i[id query_column query_value],
filters: %i[id query_column query_operator query_value],
)
.to_h

Expand Down Expand Up @@ -95,18 +95,24 @@ def create_or_update
if connection_params[:filters].present?
valid_filters =
connection_params[:filters].select do |filter|
has_keys = %i[id query_column query_value].all? { |key| filter.key?(key) }
has_keys =
%i[id query_column query_operator query_value].all? { |key| filter.key?(key) }
has_values = filter.values.all?(&:present?)
has_keys && has_values
end

saved_ids = []

valid_filters.each do |f|
params = f.slice(:query_column, :query_value)
params = f.slice(:query_column, :query_operator, :query_value)

if f[:id] === "new"
filter = @connection.filters.create(params)
filter =
DiscourseEvents::Filter.create(
model_id: @connection.id,
model_type: "DiscourseEvents::Connection",
**params,
)
else
filter = @connection.filters.update(f[:id].to_i, params)
end
Expand Down
4 changes: 2 additions & 2 deletions app/models/discourse_events/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def self.client_names
dependent: :destroy
has_many :events, through: :event_connections, source: :event
has_many :filters,
foreign_key: "connection_id",
class_name: "DiscourseEvents::ConnectionFilter",
foreign_key: "model_id",
class_name: "DiscourseEvents::Filter",
dependent: :destroy

belongs_to :user
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
# frozen_string_literal: true

module DiscourseEvents
class ConnectionFilter < ActiveRecord::Base
self.table_name = "discourse_events_connection_filters"
class Filter < ActiveRecord::Base
self.table_name = "discourse_events_filters"

belongs_to :connection, foreign_key: "connection_id", class_name: "DiscourseEvents::Connection"
MODEL_TYPES = %w[DiscourseEvents::Connection]

belongs_to :model, polymorphic: true

enum :query_column, %i[name], prefix: true
enum :query_operator, %i[like], prefix: true

OPERATORS = { name: "ILIKE" }
OPERATORS = { like: "ILIKE" }

validate :query_value_format
validates :model_type, inclusion: { in: MODEL_TYPES }

def sql_value
"%#{self.query_value}%" if sql_operator === "ILIKE"
"%#{self.query_value}%" if query_operator_like?
end

def sql_operator
OPERATORS[self.query_column.to_sym]
OPERATORS[self.query_operator.to_sym]
end

def sql_column
Expand All @@ -34,7 +38,7 @@ def query_value_format

# == Schema Information
#
# Table name: discourse_events_connection_filters
# Table name: discourse_events_filters
#
# id :bigint not null, primary key
# connection_id :bigint not null
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion app/serializers/discourse_events/connection_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module DiscourseEvents
class ConnectionSerializer < ApplicationSerializer
attributes :id, :user, :category_id, :source_id, :client

has_many :filters, serializer: ConnectionFilterSerializer, embed: :objects
has_many :filters, serializer: FilterSerializer, embed: :objects

def user
ConnectionUserSerializer.new(object.user, root: false).as_json
Expand Down
7 changes: 7 additions & 0 deletions app/serializers/discourse_events/filter_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module DiscourseEvents
class FilterSerializer < ApplicationSerializer
attributes :id, :query_column, :query_operator, :query_value
end
end
13 changes: 7 additions & 6 deletions assets/javascripts/discourse/components/events-connection-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { notEmpty, readOnly } from "@ember/object/computed";
import { service } from "@ember/service";
import discourseComputed from "discourse-common/utils/decorators";
import Connection from "../models/connection";
import EventsConnectionFilters from "./modal/events-connection-filters";
import EventsFilters from "./modal/events-filters";

function filtersMatch(filters1, filters2) {
if ((filters1 && !filters2) || (!filters1 && filters2)) {
Expand All @@ -21,7 +21,9 @@ function filtersMatch(filters1, filters2) {
return filters1.every((f1) =>
filters2.some((f2) => {
return (
f2.query_column === f1.query_column && f2.query_value === f1.query_value
f2.query_column === f1.query_column &&
f2.query_operator === f2.query_operator &&
f2.query_value === f1.query_value
);
})
);
Expand Down Expand Up @@ -57,6 +59,7 @@ export default Component.extend({
"connection.to_time",
"connection.filters.[]",
"[email protected]_column",
"[email protected]_operator",
"[email protected]_value"
)
connectionChanged(
Expand Down Expand Up @@ -130,10 +133,8 @@ export default Component.extend({
},

openFilters() {
this.modal.show(EventsConnectionFilters, {
model: {
connection: this.get("connection"),
},
this.modal.show(EventsFilters, {
model: this.get("connection"),
});
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@
@action={{action "saveProvider"}}
@icon="save"
@class={{this.saveClass}}
@label="admin.events.connection.filters.add.label"
@title="admin.events.provider.save.title"
@disabled={{this.saveDisabled}}
/>
Expand Down

This file was deleted.

This file was deleted.

64 changes: 64 additions & 0 deletions assets/javascripts/discourse/components/modal/events-filters.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<DModal
class="events-filters-modal"
@title={{i18n "admin.events.filters.title"}}
>
<:body>
{{#if hasFilters}}
<table class="filters">
<thead>
<th>{{i18n "admin.events.filter.query_column.label"}}</th>
<th>{{i18n "admin.events.filter.query_operator.label"}}</th>
<th>{{i18n "admin.events.filter.query_value.label"}}</th>
<th></th>
</thead>
<tbody>
{{#each model.filters as |filter|}}
<tr class="filter">
<td>
<ComboBox
@content={{queryColumns}}
@value={{filter.query_column}}
@onChange={{action (mut filter.query_column)}}
class="filter-column"
/>
</td>
<td>
<ComboBox
@content={{queryOperators}}
@value={{filter.query_operator}}
@onChange={{action (mut filter.query_operator)}}
class="filter-operator"
/>
</td>
<td>
<Input @value={{filter.query_value}} class="filter-value" />
</td>
<td>
<DButton
@action={{action "removeFilter" filter}}
@icon="times"
@title="admin.events.filter.remove.title"
/>
</td>
</tr>
{{/each}}
</tbody>
</table>
{{/if}}
<DButton
@action={{action "addFilter"}}
@icon="plus"
@class="add-filter"
@label="admin.events.filters.add.label"
@title="admin.events.filters.add.title"
/>
</:body>
<:footer>
<DButton
@class="btn-primary"
@action={{@closeModal}}
@label="admin.events.filters.done.label"
@title="admin.events.filters.done.title"
/>
</:footer>
</DModal>
52 changes: 52 additions & 0 deletions assets/javascripts/discourse/components/modal/events-filters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { A } from "@ember/array";
import Component from "@ember/component";
import { notEmpty } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
import Filter from "../../models/filter";

const QUERY_COLUMNS = [
{
name: "Event Name",
id: "name",
},
];

const QUERY_OPERATORS = [
{
name: "Like",
id: "like",
},
];

export default Component.extend({
hasFilters: notEmpty("model.filters"),

@discourseComputed
queryColumns() {
return QUERY_COLUMNS;
},

@discourseComputed
queryOperators() {
return QUERY_OPERATORS;
},

didInsertElement() {
this._super(...arguments);

if (!this.model.filters) {
this.model.set("filters", A());
}
},

actions: {
addFilter() {
const filter = Filter.create({ id: "new" });
this.model.get("filters").pushObject(filter);
},

removeFilter(filter) {
this.model.get("filters").removeObject(filter);
},
},
});
5 changes: 0 additions & 5 deletions assets/javascripts/discourse/models/connection-filter.js

This file was deleted.

5 changes: 5 additions & 0 deletions assets/javascripts/discourse/models/filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import EmberObject from "@ember/object";

const Filter = EmberObject.extend();

export default Filter;
Loading

0 comments on commit 76dbdf0

Please sign in to comment.