diff --git a/Plan/common/src/main/resources/assets/plan/web/js/filters.js b/Plan/common/src/main/resources/assets/plan/web/js/filters.js
new file mode 100644
index 000000000..813fe0cd3
--- /dev/null
+++ b/Plan/common/src/main/resources/assets/plan/web/js/filters.js
@@ -0,0 +1,172 @@
+class Filter {
+ constructor(kind) {
+ this.kind = kind;
+ }
+
+ render(filterCount) {
+ return 'Unimplemented render function'
+ }
+
+ toObject() {
+ return {kind: this.kind}
+ }
+}
+
+class MultipleChoiceFilter extends Filter {
+ constructor(
+ id, kind, label, options
+ ) {
+ super(kind);
+ this.id = id;
+ this.label = label;
+ this.options = options;
+ }
+
+ render(filterCount) {
+ const select = filterCount === 0 ? "of Players who " : "and ";
+ let html =
+ `
`;
+ return html;
+ }
+
+ toObject() {
+ let selected = [];
+ for (let option of document.querySelector('#' + this.id + " select").selectedOptions) {
+ selected.push(option.text);
+ }
+ selected = JSON.stringify(selected);
+
+ return {
+ kind: this.kind,
+ parameters: {selected}
+ }
+ }
+}
+
+class ActivityIndexFilter extends MultipleChoiceFilter {
+ constructor(
+ id, options
+ ) {
+ super(id, "activityIndexNow", `are in Activity Groups`, options);
+ }
+}
+
+class BannedFilter extends MultipleChoiceFilter {
+ constructor(
+ id, options
+ ) {
+ super(id, "banned", `are`, options);
+ }
+}
+
+class OperatorsFilter extends MultipleChoiceFilter {
+ constructor(
+ id, options
+ ) {
+ super(id, "operators", `are`, options);
+ }
+}
+
+class PluginGroupsFilter extends MultipleChoiceFilter {
+ constructor(
+ id, plugin, group, options
+ ) {
+ super(id, `pluginGroups: ${plugin} ${group}`, `are in ${plugin}'s ${group} Groups`, options);
+ }
+}
+
+class BetweenDateFilter extends Filter {
+ constructor(id, kind, label, options) {
+ super(kind);
+ this.id = id;
+ this.label = label;
+ this.afterDate = options.after[0];
+ this.afterTime = options.after[1];
+ this.beforeDate = options.before[0];
+ this.beforeTime = options.before[1];
+ }
+
+ render(filterCount) {
+ const id = this.id;
+ const select = filterCount === 0 ? "of Players who " : "and ";
+ return (
+ `` +
+ `
` +
+ `
`
+ );
+ }
+
+ toObject() {
+ return {
+ kind: this.kind,
+ parameters: {
+ afterDate: this.afterDate,
+ afterTime: this.afterTime,
+ beforeDate: this.beforeDate,
+ beforeTime: this.beforeTime
+ }
+ }
+ }
+}
+
+class PlayedBetweenFilter extends BetweenDateFilter {
+ constructor(id, options) {
+ super(id, "playedBetween", "Played between", options);
+ }
+}
+
+class RegisteredBetweenFilter extends BetweenDateFilter {
+ constructor(id, options) {
+ super(id, "registeredBetween", "Registered between", options);
+ }
+}
+
+function createFilter(filter, id) {
+ switch (filter.kind) {
+ case "activityIndexNow":
+ return new ActivityIndexFilter(id, filter.options);
+ case "banned":
+ return new BannedFilter(id, filter.options);
+ case "operators":
+ return new OperatorsFilter(id, filter.options);
+ case "pluginGroups":
+ return new PluginGroupsFilter(id, filter.plugin, filter.group, filter.options);
+ case "playedBetween":
+ return new PlayedBetweenFilter(id, filter.options);
+ case "registeredBetween":
+ return new RegisteredBetweenFilter(id, filter.options);
+ default:
+ throw new Error("Unsupported filter kind: '" + filter.kind + "'");
+ }
+}
\ No newline at end of file
diff --git a/Plan/common/src/main/resources/assets/plan/web/js/query.js b/Plan/common/src/main/resources/assets/plan/web/js/query.js
index dc12c4a03..1f6723866 100644
--- a/Plan/common/src/main/resources/assets/plan/web/js/query.js
+++ b/Plan/common/src/main/resources/assets/plan/web/js/query.js
@@ -93,160 +93,6 @@ function loadFilters(json) {
document.getElementById('filter-dropdown').innerHTML = filterElements;
}
-class Filter {
- constructor(kind) {
- this.kind = kind;
- }
-
- render(filterCount) {
- return 'Unimplemented render function'
- }
-
- toObject() {
- return {kind: this.kind}
- }
-}
-
-class MultipleChoiceFilter extends Filter {
- constructor(
- id, kind, label, options
- ) {
- super(kind);
- this.id = id;
- this.label = label;
- this.options = options;
- }
-
- render(filterCount) {
- const select = filterCount === 0 ? "of Players who " : "and ";
- let html =
- ``;
- return html;
- }
-
- toObject() {
- let selected = [];
- for (let option of document.querySelector('#' + this.id + " select").selectedOptions) {
- selected.push(option.text);
- }
- selected = JSON.stringify(selected);
-
- return {
- kind: this.kind,
- parameters: {selected}
- }
- }
-}
-
-class ActivityIndexFilter extends MultipleChoiceFilter {
- constructor(
- id, options
- ) {
- super(id, "activityIndexNow", `are in Activity Groups`, options);
- }
-}
-
-class BannedFilter extends MultipleChoiceFilter {
- constructor(
- id, options
- ) {
- super(id, "banned", `are`, options);
- }
-}
-
-class OperatorsFilter extends MultipleChoiceFilter {
- constructor(
- id, options
- ) {
- super(id, "operators", `are`, options);
- }
-}
-
-class PluginGroupsFilter extends MultipleChoiceFilter {
- constructor(
- id, plugin, group, options
- ) {
- super(id, `pluginGroups: ${plugin} ${group}`, `are in ${plugin}'s ${group} Groups`, options);
- }
-}
-
-class BetweenDateFilter extends Filter {
- constructor(id, kind, label, options) {
- super(kind);
- this.id = id;
- this.label = label;
- this.afterDate = options.after[0];
- this.afterTime = options.after[1];
- this.beforeDate = options.before[0];
- this.beforeTime = options.before[1];
- }
-
- render(filterCount) {
- const id = this.id;
- const select = filterCount === 0 ? "of Players who " : "and ";
- return (
- `` +
- `
` +
- `
`
- );
- }
-
- toObject() {
- return {
- kind: this.kind,
- parameters: {
- afterDate: this.afterDate,
- afterTime: this.afterTime,
- beforeDate: this.beforeDate,
- beforeTime: this.beforeTime
- }
- }
- }
-}
-
-class PlayedBetweenFilter extends BetweenDateFilter {
- constructor(id, options) {
- super(id, "playedBetween", "Played between", options);
- }
-}
-
-class RegisteredBetweenFilter extends BetweenDateFilter {
- constructor(id, options) {
- super(id, "registeredBetween", "Registered between", options);
- }
-}
-
function addFilter(parentSelector, filterIndex) {
const id = "f" + filterCount;
const filter = createFilter(filters[filterIndex], id);
@@ -261,25 +107,6 @@ function removeFilter(filterIndex) {
filterQuery = filterQuery.filter(f => f.id !== filterIndex);
}
-function createFilter(filter, id) {
- switch (filter.kind) {
- case "activityIndexNow":
- return new ActivityIndexFilter(id, filter.options);
- case "banned":
- return new BannedFilter(id, filter.options);
- case "operators":
- return new OperatorsFilter(id, filter.options);
- case "pluginGroups":
- return new PluginGroupsFilter(id, filter.plugin, filter.group, filter.options);
- case "playedBetween":
- return new PlayedBetweenFilter(id, filter.options);
- case "registeredBetween":
- return new RegisteredBetweenFilter(id, filter.options);
- default:
- throw new Error("Unsupported filter kind: '" + filter.kind + "'");
- }
-}
-
function createFilterSelector(parent, index, filter) {
return `${filter.kind}`;
}
diff --git a/Plan/common/src/main/resources/assets/plan/web/query.html b/Plan/common/src/main/resources/assets/plan/web/query.html
index 6a86aaae1..8012ebbf3 100644
--- a/Plan/common/src/main/resources/assets/plan/web/query.html
+++ b/Plan/common/src/main/resources/assets/plan/web/query.html
@@ -321,6 +321,7 @@
+