diff --git a/src/components/NavMenu.vue b/src/components/NavMenu.vue
index aa4a356..0a0dd73 100644
--- a/src/components/NavMenu.vue
+++ b/src/components/NavMenu.vue
@@ -34,6 +34,15 @@
API Keys
+
+
+
+
+
+ Analytics Rules
+
+
+
diff --git a/src/components/collection/CollectionCreate.vue b/src/components/collection/CollectionCreate.vue
index cdbb1b2..69739ad 100644
--- a/src/components/collection/CollectionCreate.vue
+++ b/src/components/collection/CollectionCreate.vue
@@ -32,6 +32,9 @@ export default defineComponent({
if (field.type !== 'float[]' || !field.num_dim) {
delete field.num_dim;
}
+ if (field.type.startsWith('object')) {
+ schema.enable_nested_fields = true;
+ }
}
void this.$store.dispatch('node/createCollection', schema);
},
diff --git a/src/components/collection/CollectionUi.vue b/src/components/collection/CollectionUi.vue
index c793bd0..8ada7e8 100644
--- a/src/components/collection/CollectionUi.vue
+++ b/src/components/collection/CollectionUi.vue
@@ -215,6 +215,8 @@ export default defineComponent({
'bool[]',
'geopoint',
'geopoint[]',
+ 'object',
+ 'object[]',
'string*',
'auto',
],
diff --git a/src/pages/AnalyticsRules.vue b/src/pages/AnalyticsRules.vue
new file mode 100644
index 0000000..4b9ae41
--- /dev/null
+++ b/src/pages/AnalyticsRules.vue
@@ -0,0 +1,235 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ isUpdate ? 'Update' : 'Add' }} Rule
+
+
+
+
+
+
+
+ Analytics Rules
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/router/routes.ts b/src/router/routes.ts
index 14e2c00..4673c51 100644
--- a/src/router/routes.ts
+++ b/src/router/routes.ts
@@ -8,6 +8,7 @@ const routes: RouteRecordRaw[] = [
{ path: '', component: () => import('pages/ServerStatus.vue') },
{ path: 'aliases', component: () => import('pages/Aliases.vue') },
{ path: 'apikeys', component: () => import('pages/ApiKeys.vue') },
+ { path: 'analyticsrules', component: () => import('pages/AnalyticsRules.vue') },
{ path: 'collections', component: () => import('pages/Collections.vue') },
{ path: 'collection/:name/document', component: () => import('pages/Document.vue') },
{ path: 'collection/:name/search', component: () => import('pages/Search.vue') },
diff --git a/src/shared/api.ts b/src/shared/api.ts
index 7464315..ab3e1af 100644
--- a/src/shared/api.ts
+++ b/src/shared/api.ts
@@ -8,6 +8,8 @@ import { SearchParams } from 'typesense/lib/Typesense/Documents';
import { KeyCreateSchema } from 'typesense/lib/Typesense/Key';
import { OverrideSchema } from 'typesense/lib/Typesense/Override';
import { SynonymSchema } from 'typesense/lib/Typesense/Synonym';
+import AnalyticsRule, { AnalyticsRuleCreateSchema } from 'typesense/lib/Typesense/AnalyticsRule';
+import AnalyticsRules from 'typesense/lib/Typesense/AnalyticsRules';
export class Api {
public axiosClient?: AxiosInstance;
@@ -78,6 +80,18 @@ export class Api {
}
}
+ public getAnalyticsRules() {
+ return this.typesenseClient?.analytics.rules().retrieve();
+ }
+
+ public upsertAnalyticsRule(name: string, rule: AnalyticsRuleCreateSchema) {
+ return (this.typesenseClient?.analytics.rules() as AnalyticsRules).upsert(name, rule);
+ }
+
+ public deleteAnalyticsRule(name: string) {
+ return (this.typesenseClient?.analytics.rules(name) as AnalyticsRule).delete();
+ }
+
public getSynonyms(collectionName: string) {
return this.typesenseClient?.collections(collectionName)
.synonyms()
diff --git a/src/store/node/actions.ts b/src/store/node/actions.ts
index b485f93..813959a 100644
--- a/src/store/node/actions.ts
+++ b/src/store/node/actions.ts
@@ -18,6 +18,7 @@ import { OverrideCreateSchema } from 'typesense/lib/Typesense/Overrides';
import { SearchParams } from 'typesense/lib/Typesense/Documents';
import { Api } from 'src/shared/api';
import { DebugResponseSchema } from 'typesense/lib/Typesense/Debug';
+import { AnalyticsRuleSchema } from 'typesense/lib/Typesense/AnalyticsRule';
const actions: ActionTree = {
connectionCheck(context) {
@@ -120,6 +121,32 @@ const actions: ActionTree = {
void context.dispatch('connectionCheck');
});
},
+ async getAnalyticsRules(context) {
+ await context.getters.api
+ .getAnalyticsRules()
+ .then((response: { rules: AnalyticsRuleSchema[] }) => {
+ context.commit('setData', {
+ analyticsRules: response.rules,
+ });
+ })
+ .catch((err: Error) => {
+ console.log(err);
+ void context.dispatch('connectionCheck');
+ });
+ },
+ async deleteAnalyticsRule(context, name: string) {
+ await context.getters.api.deleteAnalyticsRule(name);
+ void context.dispatch('getAnalyticsRules');
+ },
+ async createAnalyticsRule(context, rule: AnalyticsRuleSchema) {
+ try {
+ context.commit('setError', null);
+ await context.getters.api.upsertAnalyticsRule(rule.name, rule);
+ void context.dispatch('getAnalyticsRules');
+ } catch (error) {
+ context.commit('setError', (error as Error).message);
+ }
+ },
getSynonyms(context, collectionName: string) {
context.getters.api
.getSynonyms(collectionName)
diff --git a/src/store/node/state.ts b/src/store/node/state.ts
index d549108..94ac851 100644
--- a/src/store/node/state.ts
+++ b/src/store/node/state.ts
@@ -1,5 +1,6 @@
import { LocalStorage } from 'quasar';
import { CollectionAliasSchema } from 'typesense/lib/Typesense/Aliases';
+import { AnalyticsRuleSchema } from 'typesense/lib/Typesense/AnalyticsRule';
import { CollectionSchema } from 'typesense/lib/Typesense/Collection';
import { NodeConfiguration } from 'typesense/lib/Typesense/Configuration';
import { KeySchema } from 'typesense/lib/Typesense/Key';
@@ -17,6 +18,7 @@ export interface NodeDataInterface {
collections: CollectionSchema[];
aliases: CollectionAliasSchema[];
apiKeys: KeySchema[];
+ analyticsRules: AnalyticsRuleSchema[];
overrides: OverrideSchema[];
synonyms: SynonymSchema[];
}
@@ -67,6 +69,7 @@ function state(): NodeStateInterface {
collections: [],
aliases: [],
apiKeys: [],
+ analyticsRules: [],
overrides: [],
synonyms: [],
},