DEV: Split the Query Listing and Query Editing code (#356)
The code for listing all of the defined queries is mixed together with the code for editing a single query. Notably, this results in large amounts of unnecessary data being loaded for the list view, which causes substantial rendering slowdowns. To address this issue, we now only load the necessary data for the list view, and load the full data when it's actually needed (any endpoint that returns a single query). The primary changes that achieve this are: - Create a new `QueryDetailsSerializer` serialiser, which includes all of the query info, and change the existing `QuerySerializer` serialiser to only include the necessary attributes of each query for generating a list of them all. - Split the monolith `/plugins/explorer` route into `/plugins/explorer` for showing just the list of queries, and `/plugins/explorer/queries/:query_id`, for showing/editing/running a specific query.
This commit is contained in:
@@ -88,44 +88,22 @@ acceptance("Data Explorer Plugin | List Queries", function (needs) {
|
||||
queries: [
|
||||
{
|
||||
id: -5,
|
||||
sql: "-- [params]\n-- int :months_ago = 1\n\nWITH query_period AS\n(SELECT date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' AS period_start,\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' + INTERVAL '1 month' - INTERVAL '1 second' AS period_end)\nSELECT t.id AS topic_id,\n t.category_id,\n COUNT(p.id) AS reply_count\nFROM topics t\nJOIN posts p ON t.id = p.topic_id\nJOIN query_period qp ON p.created_at >= qp.period_start\nAND p.created_at <= qp.period_end\nWHERE t.archetype = 'regular'\nAND t.user_id > 0\nGROUP BY t.id\nORDER BY COUNT(p.id) DESC, t.score DESC\nLIMIT 100\n",
|
||||
name: "Top 100 Active Topics",
|
||||
description:
|
||||
"based on the number of replies, it accepts a ‘months_ago’ parameter, defaults to 1 to give results for the last calendar month.",
|
||||
param_info: [
|
||||
{
|
||||
identifier: "months_ago",
|
||||
type: "int",
|
||||
default: "1",
|
||||
nullable: false,
|
||||
},
|
||||
],
|
||||
created_at: "2021-02-05T16:42:45.572Z",
|
||||
username: "system",
|
||||
group_ids: [],
|
||||
last_run_at: "2021-02-08T15:37:49.188Z",
|
||||
hidden: false,
|
||||
user_id: -1,
|
||||
},
|
||||
{
|
||||
id: -6,
|
||||
sql: "-- [params]\n-- int :months_ago = 1\n\nWITH query_period AS (\n SELECT\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' as period_start,\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' + INTERVAL '1 month' - INTERVAL '1 second' as period_end\n )\n\n SELECT\n ua.user_id,\n count(1) AS like_count\n FROM user_actions ua\n INNER JOIN query_period qp\n ON ua.created_at >= qp.period_start\n AND ua.created_at <= qp.period_end\n WHERE ua.action_type = 1\n GROUP BY ua.user_id\n ORDER BY like_count DESC\n LIMIT 100\n",
|
||||
name: "Top 100 Likers",
|
||||
description:
|
||||
"returns the top 100 likers for a given monthly period ordered by like_count. It accepts a ‘months_ago’ parameter, defaults to 1 to give results for the last calendar month.",
|
||||
param_info: [
|
||||
{
|
||||
identifier: "months_ago",
|
||||
type: "int",
|
||||
default: "1",
|
||||
nullable: false,
|
||||
},
|
||||
],
|
||||
created_at: "2021-02-02T12:21:11.449Z",
|
||||
username: "system",
|
||||
group_ids: [],
|
||||
last_run_at: "2021-02-11T08:29:59.337Z",
|
||||
hidden: false,
|
||||
user_id: -1,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -46,6 +46,32 @@ acceptance("Data Explorer Plugin | New Query", function (needs) {
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
server.get("/admin/plugins/explorer/queries/-15", () => {
|
||||
return helper.response({
|
||||
query: {
|
||||
id: -15,
|
||||
sql: "-- [params]\n-- int :months_ago = 1\n\nWITH query_period AS\n(SELECT date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' AS period_start,\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' + INTERVAL '1 month' - INTERVAL '1 second' AS period_end)\nSELECT t.id AS topic_id,\n t.category_id,\n COUNT(p.id) AS reply_count\nFROM topics t\nJOIN posts p ON t.id = p.topic_id\nJOIN query_period qp ON p.created_at >= qp.period_start\nAND p.created_at <= qp.period_end\nWHERE t.archetype = 'regular'\nAND t.user_id > 0\nGROUP BY t.id\nORDER BY COUNT(p.id) DESC, t.score DESC\nLIMIT 100\n",
|
||||
name: "foo",
|
||||
description:
|
||||
"based on the number of replies, it accepts a ‘months_ago’ parameter, defaults to 1 to give results for the last calendar month.",
|
||||
param_info: [
|
||||
{
|
||||
identifier: "months_ago",
|
||||
type: "int",
|
||||
default: "1",
|
||||
nullable: false,
|
||||
},
|
||||
],
|
||||
created_at: "2021-02-05T16:42:45.572Z",
|
||||
username: "system",
|
||||
group_ids: [],
|
||||
last_run_at: "2021-02-08T15:37:49.188Z",
|
||||
hidden: false,
|
||||
user_id: -1,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("creates a new query", async function (assert) {
|
||||
@@ -57,6 +83,6 @@ acceptance("Data Explorer Plugin | New Query", function (needs) {
|
||||
// select create new query button
|
||||
await click(".query-create button");
|
||||
|
||||
assert.strictEqual(currentURL(), "/admin/plugins/explorer?id=-15");
|
||||
assert.strictEqual(currentURL(), "/admin/plugins/explorer/queries/-15");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -91,62 +91,62 @@ acceptance("Data Explorer Plugin | Param Input", function (needs) {
|
||||
queries: [
|
||||
{
|
||||
id: -6,
|
||||
sql: "-- [params]\n-- int :months_ago = 1\n\nWITH query_period AS (\n SELECT\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' as period_start,\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' + INTERVAL '1 month' - INTERVAL '1 second' as period_end\n )\n\n SELECT\n ua.user_id,\n count(1) AS like_count\n FROM user_actions ua\n INNER JOIN query_period qp\n ON ua.created_at >= qp.period_start\n AND ua.created_at <= qp.period_end\n WHERE ua.action_type = 1\n GROUP BY ua.user_id\n ORDER BY like_count DESC\n LIMIT 100\n",
|
||||
name: "Top 100 Likers",
|
||||
description:
|
||||
"returns the top 100 likers for a given monthly period ordered by like_count. It accepts a ‘months_ago’ parameter, defaults to 1 to give results for the last calendar month.",
|
||||
param_info: [
|
||||
{
|
||||
identifier: "months_ago",
|
||||
type: "int",
|
||||
default: "1",
|
||||
nullable: false,
|
||||
},
|
||||
],
|
||||
created_at: "2021-02-02T12:21:11.449Z",
|
||||
username: "system",
|
||||
group_ids: [],
|
||||
last_run_at: "2021-02-11T08:29:59.337Z",
|
||||
hidden: false,
|
||||
user_id: -1,
|
||||
},
|
||||
{
|
||||
id: -7,
|
||||
sql: "-- [params]\n-- user_id :user\n\nSELECT :user_id\n\n",
|
||||
name: "Invalid Query",
|
||||
description: "",
|
||||
param_info: [
|
||||
{
|
||||
identifier: "user",
|
||||
type: "user_id",
|
||||
default: null,
|
||||
nullable: false,
|
||||
},
|
||||
],
|
||||
created_at: "2022-01-14T16:40:05.458Z",
|
||||
username: "bianca",
|
||||
group_ids: [],
|
||||
last_run_at: "2022-01-14T16:47:34.244Z",
|
||||
hidden: false,
|
||||
user_id: 1,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
sql: "SELECT 1",
|
||||
name: "Params test",
|
||||
description: "test for params.",
|
||||
param_info: [],
|
||||
created_at: "2021-02-02T12:21:11.449Z",
|
||||
username: "system",
|
||||
group_ids: [41],
|
||||
last_run_at: "2021-02-11T08:29:59.337Z",
|
||||
hidden: false,
|
||||
user_id: -1,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
server.get("/admin/plugins/explorer/queries/-6", () => {
|
||||
return helper.response({
|
||||
query: {
|
||||
id: -6,
|
||||
sql: "-- [params]\n-- int :months_ago = 1\n\nWITH query_period AS (\n SELECT\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' as period_start,\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' + INTERVAL '1 month' - INTERVAL '1 second' as period_end\n )\n\n SELECT\n ua.user_id,\n count(1) AS like_count\n FROM user_actions ua\n INNER JOIN query_period qp\n ON ua.created_at >= qp.period_start\n AND ua.created_at <= qp.period_end\n WHERE ua.action_type = 1\n GROUP BY ua.user_id\n ORDER BY like_count DESC\n LIMIT 100\n",
|
||||
name: "Top 100 Likers",
|
||||
description:
|
||||
"returns the top 100 likers for a given monthly period ordered by like_count. It accepts a ‘months_ago’ parameter, defaults to 1 to give results for the last calendar month.",
|
||||
param_info: [
|
||||
{
|
||||
identifier: "months_ago",
|
||||
type: "int",
|
||||
default: "1",
|
||||
nullable: false,
|
||||
},
|
||||
],
|
||||
created_at: "2021-02-02T12:21:11.449Z",
|
||||
username: "system",
|
||||
group_ids: [],
|
||||
last_run_at: "2021-02-11T08:29:59.337Z",
|
||||
hidden: false,
|
||||
user_id: -1,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
server.put("/admin/plugins/explorer/queries/-6", () => {
|
||||
return helper.response({
|
||||
success: true,
|
||||
@@ -244,6 +244,31 @@ acceptance("Data Explorer Plugin | Param Input", function (needs) {
|
||||
});
|
||||
});
|
||||
|
||||
server.get("/admin/plugins/explorer/queries/-7", () => {
|
||||
return helper.response({
|
||||
query: {
|
||||
id: -7,
|
||||
sql: "-- [params]\n-- user_id :user\n\nSELECT :user_id\n\n",
|
||||
name: "Invalid Query",
|
||||
description: "",
|
||||
param_info: [
|
||||
{
|
||||
identifier: "user",
|
||||
type: "user_id",
|
||||
default: null,
|
||||
nullable: false,
|
||||
},
|
||||
],
|
||||
created_at: "2022-01-14T16:40:05.458Z",
|
||||
username: "bianca",
|
||||
group_ids: [],
|
||||
last_run_at: "2022-01-14T16:47:34.244Z",
|
||||
hidden: false,
|
||||
user_id: 1,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
server.post("/admin/plugins/explorer/queries/-7/run", () => {
|
||||
return helper.response({
|
||||
success: true,
|
||||
@@ -351,7 +376,7 @@ acceptance("Data Explorer Plugin | Param Input", function (needs) {
|
||||
});
|
||||
|
||||
test("puts params for the query into the url", async function (assert) {
|
||||
await visit("/admin/plugins/explorer?id=-6");
|
||||
await visit("/admin/plugins/explorer/queries/-6");
|
||||
const monthsAgoValue = "2";
|
||||
await fillIn(".query-params input", monthsAgoValue);
|
||||
await click("form.query-run button");
|
||||
@@ -373,7 +398,7 @@ acceptance("Data Explorer Plugin | Param Input", function (needs) {
|
||||
});
|
||||
|
||||
test("loads the page if one of the parameter is null", async function (assert) {
|
||||
await visit('/admin/plugins/explorer?id=-7¶ms={"user":null}');
|
||||
await visit('/admin/plugins/explorer/queries/-7?params={"user":null}');
|
||||
assert.dom(".query-params .user-chooser").exists();
|
||||
assert.dom(".query-run .btn.btn-primary").exists();
|
||||
});
|
||||
@@ -393,7 +418,7 @@ acceptance("Data Explorer Plugin | Param Input", function (needs) {
|
||||
});
|
||||
|
||||
test("creates input boxes if has parameters when save", async function (assert) {
|
||||
await visit("/admin/plugins/explorer?id=3");
|
||||
await visit("/admin/plugins/explorer/queries/3");
|
||||
assert.dom(".query-params input").doesNotExist();
|
||||
await click(".query-edit .btn-edit-query");
|
||||
await click(".query-editor .ace_text-input");
|
||||
|
||||
@@ -88,42 +88,71 @@ acceptance("Data Explorer Plugin | Run Query", function (needs) {
|
||||
queries: [
|
||||
{
|
||||
id: -6,
|
||||
sql: "-- [params]\n-- int :months_ago = 1\n\nWITH query_period AS (\n SELECT\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' as period_start,\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' + INTERVAL '1 month' - INTERVAL '1 second' as period_end\n )\n\n SELECT\n ua.user_id,\n count(1) AS like_count\n FROM user_actions ua\n INNER JOIN query_period qp\n ON ua.created_at >= qp.period_start\n AND ua.created_at <= qp.period_end\n WHERE ua.action_type = 1\n GROUP BY ua.user_id\n ORDER BY like_count DESC\n LIMIT 100\n",
|
||||
name: "Top 100 Likers",
|
||||
description:
|
||||
"returns the top 100 likers for a given monthly period ordered by like_count. It accepts a ‘months_ago’ parameter, defaults to 1 to give results for the last calendar month.",
|
||||
param_info: [
|
||||
{
|
||||
identifier: "months_ago",
|
||||
type: "int",
|
||||
default: "1",
|
||||
nullable: false,
|
||||
},
|
||||
],
|
||||
created_at: "2021-02-02T12:21:11.449Z",
|
||||
username: "system",
|
||||
group_ids: [],
|
||||
last_run_at: "2021-02-11T08:29:59.337Z",
|
||||
hidden: false,
|
||||
user_id: -1,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
sql: 'SELECT 0 zero, null "null", false "false"',
|
||||
name: "What about 0?",
|
||||
description: "",
|
||||
param_info: [],
|
||||
created_at: "2023-05-04T22:16:06.007Z",
|
||||
username: "system",
|
||||
group_ids: [],
|
||||
last_run_at: "2023-05-04T22:16:23.858Z",
|
||||
hidden: false,
|
||||
user_id: 1,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
server.get("/admin/plugins/explorer/queries/-6", () => {
|
||||
return helper.response({
|
||||
query: {
|
||||
id: -6,
|
||||
sql: "-- [params]\n-- int :months_ago = 1\n\nWITH query_period AS (\n SELECT\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' as period_start,\n date_trunc('month', CURRENT_DATE) - INTERVAL ':months_ago months' + INTERVAL '1 month' - INTERVAL '1 second' as period_end\n )\n\n SELECT\n ua.user_id,\n count(1) AS like_count\n FROM user_actions ua\n INNER JOIN query_period qp\n ON ua.created_at >= qp.period_start\n AND ua.created_at <= qp.period_end\n WHERE ua.action_type = 1\n GROUP BY ua.user_id\n ORDER BY like_count DESC\n LIMIT 100\n",
|
||||
name: "Top 100 Likers",
|
||||
description:
|
||||
"returns the top 100 likers for a given monthly period ordered by like_count. It accepts a ‘months_ago’ parameter, defaults to 1 to give results for the last calendar month.",
|
||||
param_info: [
|
||||
{
|
||||
identifier: "months_ago",
|
||||
type: "int",
|
||||
default: "1",
|
||||
nullable: false,
|
||||
},
|
||||
],
|
||||
created_at: "2021-02-02T12:21:11.449Z",
|
||||
username: "system",
|
||||
group_ids: [],
|
||||
last_run_at: "2021-02-11T08:29:59.337Z",
|
||||
hidden: false,
|
||||
user_id: -1,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
server.get("/admin/plugins/explorer/queries/2", () => {
|
||||
return helper.response({
|
||||
query: {
|
||||
id: 2,
|
||||
sql: 'SELECT 0 zero, null "null", false "false"',
|
||||
name: "What about 0?",
|
||||
description: "",
|
||||
param_info: [],
|
||||
created_at: "2023-05-04T22:16:06.007Z",
|
||||
username: "system",
|
||||
group_ids: [],
|
||||
last_run_at: "2023-05-04T22:16:23.858Z",
|
||||
hidden: false,
|
||||
user_id: 1,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
server.post("/admin/plugins/explorer/queries/-6/run", () => {
|
||||
return helper.response({
|
||||
success: true,
|
||||
@@ -177,7 +206,7 @@ acceptance("Data Explorer Plugin | Run Query", function (needs) {
|
||||
});
|
||||
|
||||
test("runs query and renders data and a chart", async function (assert) {
|
||||
await visit("/admin/plugins/explorer?id=-6");
|
||||
await visit("/admin/plugins/explorer/queries/-6");
|
||||
|
||||
assert
|
||||
.dom("div.name h1")
|
||||
@@ -205,7 +234,7 @@ acceptance("Data Explorer Plugin | Run Query", function (needs) {
|
||||
});
|
||||
|
||||
test("runs query and renders 0, false, and NULL values correctly", async function (assert) {
|
||||
await visit("/admin/plugins/explorer?id=2");
|
||||
await visit("/admin/plugins/explorer/queries/2");
|
||||
|
||||
assert
|
||||
.dom("div.name h1")
|
||||
|
||||
Reference in New Issue
Block a user