Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract connection filters to make them re-usable #141

Merged
merged 3 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading