Skip to content

Commit 51c4d72

Browse files
authored
Merge pull request #89 from bfritscher/88-accept-aliases-as-analytics-rule-source-collection
feat: add json mode to analytics rules and allow to select aliases fixes #88
2 parents bcad30d + 06d9b02 commit 51c4d72

File tree

1 file changed

+121
-64
lines changed

1 file changed

+121
-64
lines changed

src/pages/AnalyticsRules.vue

Lines changed: 121 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,99 @@
11
<template>
22
<q-page padding>
3-
<q-expansion-item
4-
v-model="state.expanded"
5-
expand-separator
6-
icon="sym_s_add_circle"
7-
expand-icon="sym_s_unfold_more"
8-
expanded-icon="sym_s_unfold_less"
9-
:label="`${isUpdate ? 'Update' : 'Add'} Analytics Rule`"
10-
header-class="bg-primary text-white"
11-
>
12-
<q-card class="bg-surface column">
13-
<q-card-section class="row q-col-gutter-md">
14-
<q-input
15-
v-model="state.rule.name"
16-
class="col-12 col-sm-6"
17-
label="Rule Name"
18-
filled
19-
:rules="[(val) => !!val || 'Field is required']"
20-
/>
21-
22-
<q-input
23-
v-model="state.rule.type"
24-
class="col-12 col-sm-6"
25-
label="Rule Type"
26-
filled
27-
:rules="[(val) => !!val || 'Field is required']"
28-
/>
29-
</q-card-section>
30-
<q-card-section class="row q-col-gutter-md">
31-
<q-select
32-
v-model="state.rule.params.source.collections"
33-
class="col-12 col-sm-6"
34-
label="Source Collection(s)"
35-
filled
36-
:options="collectionNames"
37-
multiple
38-
hint="Track searches sent to these collections"
39-
></q-select>
40-
41-
<q-select
42-
v-model="state.rule.params.destination.collection"
43-
class="col-12 col-sm-6"
44-
label="Destination Collection"
45-
filled
46-
:options="collectionNames"
47-
></q-select>
48-
</q-card-section>
49-
<q-card-section class="row q-col-gutter-md">
50-
<q-input
51-
v-model="state.rule.params.limit"
52-
class="col-12 col-sm-6"
53-
label="Limit"
54-
filled
55-
type="number"
56-
min="0"
57-
/>
58-
</q-card-section>
59-
60-
<q-card-actions align="right" class="bg-primary">
61-
<q-btn size="md" padding="sm lg" unelevated color="primary" @click="createRule()"
62-
>{{ isUpdate ? 'Update' : 'Add' }} Rule</q-btn
3+
<q-list bordered class="rounded-borders">
4+
<q-expansion-item
5+
v-model="state.expanded"
6+
expand-separator
7+
icon="sym_s_add_circle"
8+
expand-icon="sym_s_unfold_more"
9+
expanded-icon="sym_s_unfold_less"
10+
:label="`${isUpdate ? 'Update' : 'Add'} Analytics Rule`"
11+
header-class="bg-primary text-white"
12+
>
13+
<q-card>
14+
<q-tabs
15+
v-model="tab"
16+
dense
17+
class="text-grey"
18+
active-color="primary"
19+
indicator-color="primary"
20+
align="justify"
21+
narrow-indicator
6322
>
64-
</q-card-actions>
65-
</q-card>
66-
</q-expansion-item>
23+
<q-tab name="form" label="Form Mode" />
24+
<q-tab name="json" label="JSON Mode" />
25+
</q-tabs>
26+
<q-separator />
27+
<q-tab-panels v-model="tab" animated class="bg-surface">
28+
<q-tab-panel name="form">
29+
<q-card-section class="row q-col-gutter-md">
30+
<q-input
31+
v-model="state.rule.name"
32+
class="col-12 col-sm-6"
33+
label="Rule Name"
34+
filled
35+
:rules="[(val) => !!val || 'Field is required']"
36+
/>
37+
<q-select
38+
v-model="state.rule.type"
39+
:options="typeOptions"
40+
class="col-12 col-sm-6"
41+
label="Rule Type"
42+
filled
43+
:rules="[(val) => !!val || 'Field is required']"
44+
/>
45+
</q-card-section>
46+
<q-card-section class="row q-col-gutter-md">
47+
<q-select
48+
v-model="state.rule.params.source.collections"
49+
class="col-12 col-sm-6"
50+
label="Source Collection(s)"
51+
filled
52+
:options="sourceOptions"
53+
multiple
54+
hint="Track searches sent to these collections or aliases"
55+
></q-select>
56+
<q-select
57+
v-model="state.rule.params.destination.collection"
58+
class="col-12 col-sm-6"
59+
label="Destination Collection"
60+
filled
61+
:options="sourceOptions"
62+
></q-select>
63+
</q-card-section>
64+
<q-card-section class="row q-col-gutter-md">
65+
<q-input
66+
v-model="state.rule.params.limit"
67+
class="col-12 col-sm-6"
68+
label="Limit"
69+
filled
70+
type="number"
71+
min="0"
72+
/>
73+
<q-checkbox
74+
v-model="state.rule.params.expand_query"
75+
class="col-12 col-sm-6"
76+
label="Expand Query"
77+
filled
78+
/>
79+
</q-card-section>
80+
</q-tab-panel>
81+
<q-tab-panel name="json" class="q-pa-none">
82+
<monaco-editor v-model="ruleJson" style="height: 60vh"></monaco-editor>
83+
<q-banner v-if="jsonError" inline-actions class="text-white bg-red">
84+
Invalid Format: {{ jsonError }}
85+
</q-banner>
86+
</q-tab-panel>
87+
</q-tab-panels>
88+
<q-separator />
89+
<q-card-actions align="right" class="bg-primary">
90+
<q-btn size="md" padding="sm lg" unelevated color="primary" @click="createRule()">
91+
{{ isUpdate ? 'Update' : 'Add' }} Rule
92+
</q-btn>
93+
</q-card-actions>
94+
</q-card>
95+
</q-expansion-item>
96+
</q-list>
6797

6898
<q-table
6999
class="q-mt-md"
@@ -105,9 +135,10 @@
105135
<script setup lang="ts">
106136
import { useNodeStore } from 'src/stores/node';
107137
import type { AnalyticsRuleSchema } from 'typesense/lib/Typesense/AnalyticsRule';
108-
import { computed, onMounted, reactive } from 'vue';
138+
import { computed, onMounted, reactive, ref } from 'vue';
109139
import type { QTableProps } from 'quasar';
110140
import { useQuasar } from 'quasar';
141+
import MonacoEditor from 'src/components/MonacoEditor.vue';
111142
112143
const $q = useQuasar();
113144
const store = useNodeStore();
@@ -123,6 +154,7 @@ function initialData(): AnalyticsRuleSchema {
123154
destination: {
124155
collection: '',
125156
},
157+
expand_query: false,
126158
limit: 100,
127159
},
128160
};
@@ -177,10 +209,35 @@ const state = reactive({
177209
});
178210
179211
const collectionNames = computed(() => store.data.collections.map((collection) => collection.name));
212+
const aliasNames = computed(() => store.data.aliases.map((alias) => alias.name));
213+
// Combine and sort collections and aliases for dropdowns
214+
const sourceOptions = computed(() => {
215+
const options = [...collectionNames.value, ...aliasNames.value];
216+
return options.sort();
217+
});
218+
219+
const typeOptions = ref(['popular_queries', 'nohits_queries', 'counter']);
220+
180221
const isUpdate = computed(() =>
181222
store.data.analyticsRules.map((a) => a.name).includes(state.rule.name),
182223
);
183224
225+
const tab = ref('form');
226+
const ruleJson = computed({
227+
get() {
228+
return JSON.stringify(state.rule, null, 2);
229+
},
230+
set(json: string) {
231+
try {
232+
state.rule = JSON.parse(json);
233+
jsonError.value = null;
234+
} catch (e) {
235+
jsonError.value = (e as Error).message;
236+
}
237+
},
238+
});
239+
const jsonError = ref<string | null>(null);
240+
184241
async function createRule() {
185242
await store.createAnalyticsRule(state.rule);
186243
state.expanded = false;

0 commit comments

Comments
 (0)