Pārlūkot izejas kodu

Merge pull request #1470 from bmsuisse/aggrid-func

feat: Implement Ag Grid Dynamic Functions
Falko Schindler 1 gadu atpakaļ
vecāks
revīzija
06f7ce5ba5

+ 3 - 0
nicegui/elements/aggrid.js

@@ -1,3 +1,5 @@
+import { recursive_convert_dynamic } from "../../static/utils/dynamic_obj.js";
+
 export default {
   template: "<div></div>",
   mounted() {
@@ -15,6 +17,7 @@ export default {
           this.gridOptions.columnDefs[column].cellRenderer = (params) => (params.value ? params.value : "");
         }
       }
+      this.gridOptions = recursive_convert_dynamic(this.gridOptions);
 
       // Code for CheckboxRenderer https://blog.ag-grid.com/binding-boolean-values-to-checkboxes-in-ag-grid/
       function CheckboxRenderer() {}

+ 34 - 0
nicegui/static/utils/dynamic_obj.js

@@ -0,0 +1,34 @@
+export function recursive_has_dynamic(obj) {
+  if (typeof obj !== "object" || obj === null) return false;
+  if (Array.isArray(obj)) {
+    return obj.some((v) => recursive_has_dynamic(v));
+  }
+  for (const [key, value] of Object.entries(obj)) {
+    if (key.startsWith(":")) return true;
+    if (recursive_has_dynamic(value)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+export function recursive_convert_dynamic(obj) {
+  if (!recursive_has_dynamic(obj)) return obj; // double-loop hierarchy is probably safer and uses less RAM if dynamic not used
+  if (typeof obj !== "object" || obj === null) return obj;
+  if (Array.isArray(obj)) {
+    return obj.map((v) => recursive_convert_dynamic(v));
+  }
+  const targetObj = {};
+  for (const [attr, value] of Object.entries(obj)) {
+    if (attr.startsWith(":")) {
+      try {
+        targetObj[attr.slice(1)] = new Function("return " + value)();
+      } catch (e) {
+        console.error(`Error while converting ${attr} attribute to function:`, e);
+      }
+    } else {
+      targetObj[attr] = recursive_convert_dynamic(value);
+    }
+  }
+  return targetObj;
+}

+ 16 - 0
tests/test_aggrid.py

@@ -71,6 +71,22 @@ def test_html_columns(screen: Screen):
     assert 'text-bold' in screen.find('Alice').get_attribute('class')
 
 
+def test_dynamic_method(screen: Screen):
+    grid = ui.aggrid({
+        'columnDefs': [{'field': 'name'}, {'field': 'age'}],
+        'rowData': [{'name': 'Alice', 'age': '18'}, {'name': 'Bob', 'age': '21'}, {'name': 'Carol', 'age': '42'}],
+        ':getRowHeight': 'params=>params.data.age>35 ? 40:25'
+    })
+    screen.open('/')
+    trs = screen.find_all_by_class("ag-row")
+    assert len(trs) == 3
+    heights = [int(tr.get_attribute("clientHeight")) for tr in trs]
+    # we allow for some margin since there are borders etc
+    assert heights[0] <= 25 and heights[0] >= 23
+    assert heights[1] <= 25 and heights[1] >= 23
+    assert heights[2] <= 40 and heights[2] >= 38
+
+
 def test_call_api_method_with_argument(screen: Screen):
     grid = ui.aggrid({
         'columnDefs': [{'field': 'name', 'filter': True}],