diff --git a/client/package.json b/client/package.json
index de12b9f71852..86720d29ca7d 100644
--- a/client/package.json
+++ b/client/package.json
@@ -45,6 +45,8 @@
"@types/jest": "^29.5.12",
"@vueuse/core": "^10.5.0",
"@vueuse/math": "^10.9.0",
+ "ag-grid-community": "^30",
+ "ag-grid-vue": "^30",
"assert": "^2.1.0",
"axios": "^1.6.2",
"babel-runtime": "^6.26.0",
@@ -106,11 +108,13 @@
"vega-embed": "^6.26.0",
"vega-lite": "^5.21.0",
"vue": "^2.7.14",
+ "vue-class-component": "^7.2.6",
"vue-echarts": "^7.0.3",
"vue-infinite-scroll": "^2.0.2",
"vue-multiselect": "^2.1.7",
"vue-observe-visibility": "^1.0.0",
"vue-prismjs": "^1.2.0",
+ "vue-property-decorator": "^9.1.2",
"vue-router": "^3.6.5",
"vue-rx": "^6.2.0",
"vue-virtual-scroll-list": "^2.3.5",
diff --git a/client/src/components/RuleBuilder/RuleGrid.vue b/client/src/components/RuleBuilder/RuleGrid.vue
new file mode 100644
index 000000000000..bc0fbf6f5eaf
--- /dev/null
+++ b/client/src/components/RuleBuilder/RuleGrid.vue
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+
diff --git a/client/src/components/RuleCollectionBuilder.vue b/client/src/components/RuleCollectionBuilder.vue
index 2b452512a9d9..b190899e7403 100644
--- a/client/src/components/RuleCollectionBuilder.vue
+++ b/client/src/components/RuleCollectionBuilder.vue
@@ -452,12 +452,20 @@
+
@@ -576,6 +584,7 @@ import RegularExpressionInput from "components/RuleBuilder/RegularExpressionInpu
import RuleDefs from "components/RuleBuilder/rule-definitions";
import RuleComponent from "components/RuleBuilder/RuleComponent";
import RuleDisplay from "components/RuleBuilder/RuleDisplay";
+import RuleGrid from "components/RuleBuilder/RuleGrid";
import RuleModalFooter from "components/RuleBuilder/RuleModalFooter";
import RuleModalHeader from "components/RuleBuilder/RuleModalHeader";
import RuleModalMiddle from "components/RuleBuilder/RuleModalMiddle";
@@ -612,6 +621,7 @@ export default {
components: {
TooltipOnHover,
HotTable,
+ RuleGrid,
RuleComponent,
RuleTargetComponent,
SavedRulesSelector,
@@ -675,6 +685,11 @@ export default {
required: false,
default: null,
},
+ gridImplementation: {
+ type: String,
+ required: false,
+ default: "aggrid",
+ },
},
data: function () {
let orientation = "vertical";
diff --git a/client/src/composables/useAgGrid.ts b/client/src/composables/useAgGrid.ts
new file mode 100644
index 000000000000..693cbb292d76
--- /dev/null
+++ b/client/src/composables/useAgGrid.ts
@@ -0,0 +1,27 @@
+import "ag-grid-community/styles/ag-grid.min.css";
+import "ag-grid-community/styles/ag-theme-alpine.min.css";
+
+import { type ColumnApi, type GridApi, type GridReadyEvent } from "ag-grid-community";
+import { defineAsyncComponent, nextTick, ref } from "vue";
+
+export function useAgGrid(forceGridSize: () => void) {
+ const gridApi = ref(null);
+ const columnApi = ref(null);
+ const theme = "ag-theme-alpine";
+ function resizeOnNextTick() {
+ nextTick(forceGridSize);
+ }
+
+ function onGridReady(params: GridReadyEvent) {
+ gridApi.value = params.api;
+ columnApi.value = params.columnApi;
+ forceGridSize();
+ }
+
+ const AgGridVue = defineAsyncComponent(async () => {
+ const { AgGridVue } = await import(/* webpackChunkName: "agGrid" */ "ag-grid-vue");
+ return AgGridVue;
+ });
+
+ return { AgGridVue, gridApi, columnApi, resizeOnNextTick, onGridReady, theme };
+}
diff --git a/client/yarn.lock b/client/yarn.lock
index cd6c4bf5f55a..9f7eb64fc714 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -3183,6 +3183,16 @@ acorn@^8.1.0, acorn@^8.7.1, acorn@^8.8.0, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5"
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
+ag-grid-community@^30:
+ version "30.2.1"
+ resolved "https://registry.yarnpkg.com/ag-grid-community/-/ag-grid-community-30.2.1.tgz#a83d153ad1dbec46402ebe89f74ebb4b0710b3c7"
+ integrity sha512-1slonXskJbbI9ybhTx//4YKfJpZVAEnHL8dui1rQJRSXKByUi+/f7XtvkLsbgBkawoWbqvRAySjYtvz80+kBfA==
+
+ag-grid-vue@^30:
+ version "30.2.1"
+ resolved "https://registry.yarnpkg.com/ag-grid-vue/-/ag-grid-vue-30.2.1.tgz#56395cf053ca2df70107123cf589618ddc3f84b3"
+ integrity sha512-dnyltXrVUPk0ALQ1PfwnjBtYk/GDOjRjyOMy8LVAiWxVQA6Tmnb/dTnS1yjym1uggu+dDKof2zgPxVKayIHtWg==
+
agent-base@6:
version "6.0.2"
resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz"
@@ -12355,6 +12365,11 @@ vinyl@^2.0.0:
remove-trailing-separator "^1.0.1"
replace-ext "^1.0.0"
+vue-class-component@^7.2.6:
+ version "7.2.6"
+ resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-7.2.6.tgz#8471e037b8e4762f5a464686e19e5afc708502e4"
+ integrity sha512-+eaQXVrAm/LldalI272PpDe3+i4mPis0ORiMYxF6Ae4hyuCh15W8Idet7wPUEs4N4YptgFHGys4UrgNQOMyO6w==
+
vue-demi@>=0.14.5, vue-demi@>=0.14.6:
version "0.14.6"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.6.tgz#dc706582851dc1cdc17a0054f4fec2eb6df74c92"
@@ -12446,6 +12461,11 @@ vue-prismjs@^1.2.0:
dependencies:
prismjs "^1.6.0"
+vue-property-decorator@^9.1.2:
+ version "9.1.2"
+ resolved "https://registry.yarnpkg.com/vue-property-decorator/-/vue-property-decorator-9.1.2.tgz#266a2eac61ba6527e2e68a6933cfb98fddab5457"
+ integrity sha512-xYA8MkZynPBGd/w5QFJ2d/NM0z/YeegMqYTphy7NJQXbZcuU6FC6AOdUAcy4SXP+YnkerC6AfH+ldg7PDk9ESQ==
+
vue-router@^3.6.5:
version "3.6.5"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.6.5.tgz#95847d52b9a7e3f1361cb605c8e6441f202afad8"