Переглянути джерело

Merge branch 'develop' into fix/#803-align-core-service-logs

Jean-Robin 1 рік тому
батько
коміт
afc86ab277

+ 1 - 1
doc/gui/examples/charts/treemap-simple.py

@@ -21,7 +21,7 @@ fibonacci = [0, 1]
 for i in range(2, n_numbers):
     fibonacci.append(fibonacci[i - 1] + fibonacci[i - 2])
 
-data = {"index": [i for i in range(1, n_numbers + 1)], "fibonacci": fibonacci}
+data = {"index": list(range(1, n_numbers + 1)), "fibonacci": fibonacci}
 
 page = """
 # TreeMap - Simple

+ 1 - 1
frontend/taipy-gui/dom/package.json

@@ -1,6 +1,6 @@
 {
   "name": "taipy-gui-dom",
-  "version": "3.1.0",
+  "version": "3.2.0",
   "private": true,
   "dependencies": {
     "react": "^18.2.0",

+ 226 - 197
frontend/taipy-gui/package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "taipy-gui",
-  "version": "3.1.0",
+  "version": "3.2.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "taipy-gui",
-      "version": "3.1.0",
+      "version": "3.2.0",
       "dependencies": {
         "@emotion/react": "^11.10.0",
         "@emotion/styled": "^11.10.0",
@@ -121,13 +121,13 @@
       "dev": true
     },
     "node_modules/@ampproject/remapping": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
-      "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/gen-mapping": "^0.3.0",
-        "@jridgewell/trace-mapping": "^0.3.9"
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
       },
       "engines": {
         "node": ">=6.0.0"
@@ -219,9 +219,9 @@
       }
     },
     "node_modules/@babel/core": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz",
-      "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz",
+      "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==",
       "dev": true,
       "dependencies": {
         "@ampproject/remapping": "^2.2.0",
@@ -229,11 +229,11 @@
         "@babel/generator": "^7.23.6",
         "@babel/helper-compilation-targets": "^7.23.6",
         "@babel/helper-module-transforms": "^7.23.3",
-        "@babel/helpers": "^7.23.9",
-        "@babel/parser": "^7.23.9",
-        "@babel/template": "^7.23.9",
-        "@babel/traverse": "^7.23.9",
-        "@babel/types": "^7.23.9",
+        "@babel/helpers": "^7.24.0",
+        "@babel/parser": "^7.24.0",
+        "@babel/template": "^7.24.0",
+        "@babel/traverse": "^7.24.0",
+        "@babel/types": "^7.24.0",
         "convert-source-map": "^2.0.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
@@ -368,9 +368,9 @@
       }
     },
     "node_modules/@babel/helper-plugin-utils": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
-      "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
+      "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
@@ -426,14 +426,14 @@
       }
     },
     "node_modules/@babel/helpers": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz",
-      "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz",
+      "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==",
       "dev": true,
       "dependencies": {
-        "@babel/template": "^7.23.9",
-        "@babel/traverse": "^7.23.9",
-        "@babel/types": "^7.23.9"
+        "@babel/template": "^7.24.0",
+        "@babel/traverse": "^7.24.0",
+        "@babel/types": "^7.24.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -517,9 +517,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
-      "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
+      "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
       "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -706,9 +706,9 @@
       }
     },
     "node_modules/@babel/runtime": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
-      "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz",
+      "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==",
       "dependencies": {
         "regenerator-runtime": "^0.14.0"
       },
@@ -717,23 +717,23 @@
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz",
-      "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+      "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.23.5",
-        "@babel/parser": "^7.23.9",
-        "@babel/types": "^7.23.9"
+        "@babel/parser": "^7.24.0",
+        "@babel/types": "^7.24.0"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz",
-      "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz",
+      "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.23.5",
@@ -742,8 +742,8 @@
         "@babel/helper-function-name": "^7.23.0",
         "@babel/helper-hoist-variables": "^7.22.5",
         "@babel/helper-split-export-declaration": "^7.22.6",
-        "@babel/parser": "^7.23.9",
-        "@babel/types": "^7.23.9",
+        "@babel/parser": "^7.24.0",
+        "@babel/types": "^7.24.0",
         "debug": "^4.3.1",
         "globals": "^11.1.0"
       },
@@ -761,9 +761,9 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz",
-      "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
+      "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
       "dependencies": {
         "@babel/helper-string-parser": "^7.23.4",
         "@babel/helper-validator-identifier": "^7.22.20",
@@ -1529,14 +1529,14 @@
       }
     },
     "node_modules/@jridgewell/gen-mapping": {
-      "version": "0.3.4",
-      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz",
-      "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==",
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+      "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/set-array": "^1.0.1",
+        "@jridgewell/set-array": "^1.2.1",
         "@jridgewell/sourcemap-codec": "^1.4.10",
-        "@jridgewell/trace-mapping": "^0.3.9"
+        "@jridgewell/trace-mapping": "^0.3.24"
       },
       "engines": {
         "node": ">=6.0.0"
@@ -1552,9 +1552,9 @@
       }
     },
     "node_modules/@jridgewell/set-array": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
-      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
       "dev": true,
       "engines": {
         "node": ">=6.0.0"
@@ -1577,9 +1577,9 @@
       "dev": true
     },
     "node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.23",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz",
-      "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==",
+      "version": "0.3.25",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
       "dev": true,
       "dependencies": {
         "@jridgewell/resolve-uri": "^3.1.0",
@@ -1927,9 +1927,9 @@
       }
     },
     "node_modules/@mui/x-date-pickers": {
-      "version": "6.19.5",
-      "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.19.5.tgz",
-      "integrity": "sha512-WPi59ImgvGTEuAlJiCLnqNkEkbqPjgwUTrg8iqACFIb4qzg5tz4y8vNgmOKMnTXCwWDHjd+SoDdxiMlZJWT1hg==",
+      "version": "6.19.6",
+      "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.19.6.tgz",
+      "integrity": "sha512-QW9AFcPi0vLpkUhmquhhyhLaBvB0AZJuu3NTrE173qNKx3Z3n51aCLY9bc7c6i4ltZMMsVRHlvzQjsve04TC8A==",
       "dependencies": {
         "@babel/runtime": "^7.23.2",
         "@mui/base": "^5.0.0-beta.22",
@@ -2140,9 +2140,9 @@
       }
     },
     "node_modules/@remix-run/router": {
-      "version": "1.15.1",
-      "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz",
-      "integrity": "sha512-zcU0gM3z+3iqj8UX45AmWY810l3oUmXM7uH4dt5xtzvMhRtYVhKGOmgOd1877dOPPepfCjUv57w+syamWIYe7w==",
+      "version": "1.15.2",
+      "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.2.tgz",
+      "integrity": "sha512-+Rnav+CaoTE5QJc4Jcwh5toUpnVLKYbpU6Ys0zqbakqbaLQHeglLVHPfxOiQqdNmUy5C2lXz5dwC6tQNX2JW2Q==",
       "engines": {
         "node": ">=14.0.0"
       }
@@ -2438,9 +2438,9 @@
       }
     },
     "node_modules/@types/eslint": {
-      "version": "8.56.3",
-      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.3.tgz",
-      "integrity": "sha512-PvSf1wfv2wJpVIFUMSb+i4PvqNYkB9Rkp9ZDO3oaWzq4SKhsQk4mrMBr3ZH06I0hKrVGLBacmgl8JM4WVjb9dg==",
+      "version": "8.56.5",
+      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz",
+      "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==",
       "dev": true,
       "dependencies": {
         "@types/estree": "*",
@@ -2627,9 +2627,9 @@
       "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
     },
     "node_modules/@types/react": {
-      "version": "18.2.60",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.60.tgz",
-      "integrity": "sha512-dfiPj9+k20jJrLGOu9Nf6eqxm2EyJRrq2NvwOFsfbb7sFExZ9WELPs67UImHj3Ayxg8ruTtKtNnbjaF8olPq0A==",
+      "version": "18.2.63",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.63.tgz",
+      "integrity": "sha512-ppaqODhs15PYL2nGUOaOu2RSCCB4Difu4UFrP4I3NHLloXC/ESQzQMi9nvjfT1+rudd0d2L3fQPJxRSey+rGlQ==",
       "dependencies": {
         "@types/prop-types": "*",
         "@types/scheduler": "*",
@@ -2767,16 +2767,16 @@
       "dev": true
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.0.tgz",
-      "integrity": "sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.1.tgz",
+      "integrity": "sha512-zioDz623d0RHNhvx0eesUmGfIjzrk18nSBC8xewepKXbBvN/7c1qImV7Hg8TI1URTxKax7/zxfxj3Uph8Chcuw==",
       "dev": true,
       "dependencies": {
         "@eslint-community/regexpp": "^4.5.1",
-        "@typescript-eslint/scope-manager": "7.1.0",
-        "@typescript-eslint/type-utils": "7.1.0",
-        "@typescript-eslint/utils": "7.1.0",
-        "@typescript-eslint/visitor-keys": "7.1.0",
+        "@typescript-eslint/scope-manager": "7.1.1",
+        "@typescript-eslint/type-utils": "7.1.1",
+        "@typescript-eslint/utils": "7.1.1",
+        "@typescript-eslint/visitor-keys": "7.1.1",
         "debug": "^4.3.4",
         "graphemer": "^1.4.0",
         "ignore": "^5.2.4",
@@ -2802,15 +2802,15 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.0.tgz",
-      "integrity": "sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.1.tgz",
+      "integrity": "sha512-ZWUFyL0z04R1nAEgr9e79YtV5LbafdOtN7yapNbn1ansMyaegl2D4bL7vHoJ4HPSc4CaLwuCVas8CVuneKzplQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "7.1.0",
-        "@typescript-eslint/types": "7.1.0",
-        "@typescript-eslint/typescript-estree": "7.1.0",
-        "@typescript-eslint/visitor-keys": "7.1.0",
+        "@typescript-eslint/scope-manager": "7.1.1",
+        "@typescript-eslint/types": "7.1.1",
+        "@typescript-eslint/typescript-estree": "7.1.1",
+        "@typescript-eslint/visitor-keys": "7.1.1",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -2830,13 +2830,13 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.0.tgz",
-      "integrity": "sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.1.tgz",
+      "integrity": "sha512-cirZpA8bJMRb4WZ+rO6+mnOJrGFDd38WoXCEI57+CYBqta8Yc8aJym2i7vyqLL1vVYljgw0X27axkUXz32T8TA==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.1.0",
-        "@typescript-eslint/visitor-keys": "7.1.0"
+        "@typescript-eslint/types": "7.1.1",
+        "@typescript-eslint/visitor-keys": "7.1.1"
       },
       "engines": {
         "node": "^16.0.0 || >=18.0.0"
@@ -2847,13 +2847,13 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.0.tgz",
-      "integrity": "sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.1.tgz",
+      "integrity": "sha512-5r4RKze6XHEEhlZnJtR3GYeCh1IueUHdbrukV2KSlLXaTjuSfeVF8mZUVPLovidCuZfbVjfhi4c0DNSa/Rdg5g==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/typescript-estree": "7.1.0",
-        "@typescript-eslint/utils": "7.1.0",
+        "@typescript-eslint/typescript-estree": "7.1.1",
+        "@typescript-eslint/utils": "7.1.1",
         "debug": "^4.3.4",
         "ts-api-utils": "^1.0.1"
       },
@@ -2874,9 +2874,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.0.tgz",
-      "integrity": "sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.1.tgz",
+      "integrity": "sha512-KhewzrlRMrgeKm1U9bh2z5aoL4s7K3tK5DwHDn8MHv0yQfWFz/0ZR6trrIHHa5CsF83j/GgHqzdbzCXJ3crx0Q==",
       "dev": true,
       "engines": {
         "node": "^16.0.0 || >=18.0.0"
@@ -2887,13 +2887,13 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.0.tgz",
-      "integrity": "sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.1.tgz",
+      "integrity": "sha512-9ZOncVSfr+sMXVxxca2OJOPagRwT0u/UHikM2Rd6L/aB+kL/QAuTnsv6MeXtjzCJYb8PzrXarypSGIPx3Jemxw==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.1.0",
-        "@typescript-eslint/visitor-keys": "7.1.0",
+        "@typescript-eslint/types": "7.1.1",
+        "@typescript-eslint/visitor-keys": "7.1.1",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -2915,17 +2915,17 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.0.tgz",
-      "integrity": "sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.1.tgz",
+      "integrity": "sha512-thOXM89xA03xAE0lW7alstvnyoBUbBX38YtY+zAUcpRPcq9EIhXPuJ0YTv948MbzmKh6e1AUszn5cBFK49Umqg==",
       "dev": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
         "@types/json-schema": "^7.0.12",
         "@types/semver": "^7.5.0",
-        "@typescript-eslint/scope-manager": "7.1.0",
-        "@typescript-eslint/types": "7.1.0",
-        "@typescript-eslint/typescript-estree": "7.1.0",
+        "@typescript-eslint/scope-manager": "7.1.1",
+        "@typescript-eslint/types": "7.1.1",
+        "@typescript-eslint/typescript-estree": "7.1.1",
         "semver": "^7.5.4"
       },
       "engines": {
@@ -2940,12 +2940,12 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.0.tgz",
-      "integrity": "sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.1.tgz",
+      "integrity": "sha512-yTdHDQxY7cSoCcAtiBzVzxleJhkGB9NncSIyMYe2+OGON1ZsP9zOPws/Pqgopa65jvknOjlk/w7ulPlZ78PiLQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.1.0",
+        "@typescript-eslint/types": "7.1.1",
         "eslint-visitor-keys": "^3.4.1"
       },
       "engines": {
@@ -3508,6 +3508,25 @@
         "node": ">=8"
       }
     },
+    "node_modules/array.prototype.findlast": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.4.tgz",
+      "integrity": "sha512-BMtLxpV+8BD+6ZPFIWmnUBpQoy+A+ujcg4rhp2iwCRJYA7PEh2MS4NL3lz8EiDlLrJPp2hg9qWihr5pd//jcGw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.5",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.22.3",
+        "es-errors": "^1.3.0",
+        "es-shim-unscopables": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/array.prototype.flat": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
@@ -3544,6 +3563,18 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/array.prototype.toreversed": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz",
+      "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "es-shim-unscopables": "^1.0.0"
+      }
+    },
     "node_modules/array.prototype.tosorted": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz",
@@ -3594,9 +3625,9 @@
       "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
     },
     "node_modules/autoprefixer": {
-      "version": "10.4.17",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz",
-      "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==",
+      "version": "10.4.18",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.18.tgz",
+      "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==",
       "dev": true,
       "funding": [
         {
@@ -3613,8 +3644,8 @@
         }
       ],
       "dependencies": {
-        "browserslist": "^4.22.2",
-        "caniuse-lite": "^1.0.30001578",
+        "browserslist": "^4.23.0",
+        "caniuse-lite": "^1.0.30001591",
         "fraction.js": "^4.3.7",
         "normalize-range": "^0.1.2",
         "picocolors": "^1.0.0",
@@ -3963,9 +3994,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001591",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz",
-      "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
+      "version": "1.0.30001594",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz",
+      "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==",
       "funding": [
         {
           "type": "opencollective",
@@ -4756,12 +4787,15 @@
       "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
     },
     "node_modules/d": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
-      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
+      "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
       "dependencies": {
-        "es5-ext": "^0.10.50",
-        "type": "^1.0.1"
+        "es5-ext": "^0.10.64",
+        "type": "^2.7.2"
+      },
+      "engines": {
+        "node": ">=0.12"
       }
     },
     "node_modules/d3-array": {
@@ -5334,9 +5368,9 @@
       "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ=="
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.682",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.682.tgz",
-      "integrity": "sha512-oCglfs8yYKs9RQjJFOHonSnhikPK3y+0SvSYc/YpYJV//6rqc0/hbwd0c7vgK4vrl6y2gJAwjkhkSGWK+z4KRA=="
+      "version": "1.4.692",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.692.tgz",
+      "integrity": "sha512-d5rZRka9n2Y3MkWRN74IoAsxR0HK3yaAt7T50e3iT9VZmCCQDT3geXUO5ZRMhDToa1pkCeQXuNo+0g+NfDOVPA=="
     },
     "node_modules/element-size": {
       "version": "1.1.1",
@@ -5418,9 +5452,9 @@
       }
     },
     "node_modules/enhanced-resolve": {
-      "version": "5.15.0",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
-      "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+      "version": "5.15.1",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz",
+      "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.4",
@@ -5463,18 +5497,18 @@
       }
     },
     "node_modules/es-abstract": {
-      "version": "1.22.4",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz",
-      "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==",
+      "version": "1.22.5",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz",
+      "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==",
       "dev": true,
       "dependencies": {
         "array-buffer-byte-length": "^1.0.1",
         "arraybuffer.prototype.slice": "^1.0.3",
-        "available-typed-arrays": "^1.0.6",
+        "available-typed-arrays": "^1.0.7",
         "call-bind": "^1.0.7",
         "es-define-property": "^1.0.0",
         "es-errors": "^1.3.0",
-        "es-set-tostringtag": "^2.0.2",
+        "es-set-tostringtag": "^2.0.3",
         "es-to-primitive": "^1.2.1",
         "function.prototype.name": "^1.1.6",
         "get-intrinsic": "^1.2.4",
@@ -5482,15 +5516,15 @@
         "globalthis": "^1.0.3",
         "gopd": "^1.0.1",
         "has-property-descriptors": "^1.0.2",
-        "has-proto": "^1.0.1",
+        "has-proto": "^1.0.3",
         "has-symbols": "^1.0.3",
         "hasown": "^2.0.1",
         "internal-slot": "^1.0.7",
         "is-array-buffer": "^3.0.4",
         "is-callable": "^1.2.7",
-        "is-negative-zero": "^2.0.2",
+        "is-negative-zero": "^2.0.3",
         "is-regex": "^1.1.4",
-        "is-shared-array-buffer": "^1.0.2",
+        "is-shared-array-buffer": "^1.0.3",
         "is-string": "^1.0.7",
         "is-typed-array": "^1.1.13",
         "is-weakref": "^1.0.2",
@@ -5503,10 +5537,10 @@
         "string.prototype.trim": "^1.2.8",
         "string.prototype.trimend": "^1.0.7",
         "string.prototype.trimstart": "^1.0.7",
-        "typed-array-buffer": "^1.0.1",
-        "typed-array-byte-length": "^1.0.0",
-        "typed-array-byte-offset": "^1.0.0",
-        "typed-array-length": "^1.0.4",
+        "typed-array-buffer": "^1.0.2",
+        "typed-array-byte-length": "^1.0.1",
+        "typed-array-byte-offset": "^1.0.2",
+        "typed-array-length": "^1.0.5",
         "unbox-primitive": "^1.0.2",
         "which-typed-array": "^1.1.14"
       },
@@ -5631,9 +5665,9 @@
       }
     },
     "node_modules/es5-ext": {
-      "version": "0.10.63",
-      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.63.tgz",
-      "integrity": "sha512-hUCZd2Byj/mNKjfP9jXrdVZ62B8KuA/VoK7X8nUh5qT+AxDmcbvZz041oDVZdbIN1qW6XY9VDNwzkvKnZvK2TQ==",
+      "version": "0.10.64",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
+      "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
       "hasInstallScript": true,
       "dependencies": {
         "es6-iterator": "^2.0.3",
@@ -5656,12 +5690,15 @@
       }
     },
     "node_modules/es6-symbol": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
-      "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
+      "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
       "dependencies": {
-        "d": "^1.0.1",
-        "ext": "^1.1.2"
+        "d": "^1.0.2",
+        "ext": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.12"
       }
     },
     "node_modules/es6-weak-map": {
@@ -5779,27 +5816,29 @@
       }
     },
     "node_modules/eslint-plugin-react": {
-      "version": "7.33.2",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz",
-      "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==",
+      "version": "7.34.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.0.tgz",
+      "integrity": "sha512-MeVXdReleBTdkz/bvcQMSnCXGi+c9kvy51IpinjnJgutl3YTHWsDdke7Z1ufZpGfDG8xduBDKyjtB9JH1eBKIQ==",
       "dev": true,
       "dependencies": {
-        "array-includes": "^3.1.6",
-        "array.prototype.flatmap": "^1.3.1",
-        "array.prototype.tosorted": "^1.1.1",
+        "array-includes": "^3.1.7",
+        "array.prototype.findlast": "^1.2.4",
+        "array.prototype.flatmap": "^1.3.2",
+        "array.prototype.toreversed": "^1.1.2",
+        "array.prototype.tosorted": "^1.1.3",
         "doctrine": "^2.1.0",
-        "es-iterator-helpers": "^1.0.12",
+        "es-iterator-helpers": "^1.0.17",
         "estraverse": "^5.3.0",
         "jsx-ast-utils": "^2.4.1 || ^3.0.0",
         "minimatch": "^3.1.2",
-        "object.entries": "^1.1.6",
-        "object.fromentries": "^2.0.6",
-        "object.hasown": "^1.1.2",
-        "object.values": "^1.1.6",
+        "object.entries": "^1.1.7",
+        "object.fromentries": "^2.0.7",
+        "object.hasown": "^1.1.3",
+        "object.values": "^1.1.7",
         "prop-types": "^15.8.1",
-        "resolve": "^2.0.0-next.4",
+        "resolve": "^2.0.0-next.5",
         "semver": "^6.3.1",
-        "string.prototype.matchall": "^4.0.8"
+        "string.prototype.matchall": "^4.0.10"
       },
       "engines": {
         "node": ">=4"
@@ -5978,11 +6017,6 @@
         "node": ">=0.10"
       }
     },
-    "node_modules/esniff/node_modules/type": {
-      "version": "2.7.2",
-      "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
-      "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
-    },
     "node_modules/espree": {
       "version": "9.6.1",
       "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
@@ -6140,11 +6174,6 @@
         "type": "^2.7.2"
       }
     },
-    "node_modules/ext/node_modules/type": {
-      "version": "2.7.2",
-      "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
-      "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
-    },
     "node_modules/extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -10551,13 +10580,13 @@
       }
     },
     "node_modules/object-is": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
-      "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
+      "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3"
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1"
       },
       "engines": {
         "node": ">= 0.4"
@@ -11418,9 +11447,9 @@
       }
     },
     "node_modules/react-error-boundary": {
-      "version": "4.0.12",
-      "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.12.tgz",
-      "integrity": "sha512-kJdxdEYlb7CPC1A0SeUY38cHpjuu6UkvzKiAmqmOFL21VRfMhOcWxTCBgLVCO0VEMh9JhFNcVaXlV4/BTpiwOA==",
+      "version": "4.0.13",
+      "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.13.tgz",
+      "integrity": "sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==",
       "dependencies": {
         "@babel/runtime": "^7.12.5"
       },
@@ -11541,11 +11570,11 @@
       }
     },
     "node_modules/react-router": {
-      "version": "6.22.1",
-      "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.1.tgz",
-      "integrity": "sha512-0pdoRGwLtemnJqn1K0XHUbnKiX0S4X8CgvVVmHGOWmofESj31msHo/1YiqcJWK7Wxfq2a4uvvtS01KAQyWK/CQ==",
+      "version": "6.22.2",
+      "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.2.tgz",
+      "integrity": "sha512-YD3Dzprzpcq+tBMHBS822tCjnWD3iIZbTeSXMY9LPSG541EfoBGyZ3bS25KEnaZjLcmQpw2AVLkFyfgXY8uvcw==",
       "dependencies": {
-        "@remix-run/router": "1.15.1"
+        "@remix-run/router": "1.15.2"
       },
       "engines": {
         "node": ">=14.0.0"
@@ -11555,12 +11584,12 @@
       }
     },
     "node_modules/react-router-dom": {
-      "version": "6.22.1",
-      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.1.tgz",
-      "integrity": "sha512-iwMyyyrbL7zkKY7MRjOVRy+TMnS/OPusaFVxM2P11x9dzSzGmLsebkCvYirGq0DWB9K9hOspHYYtDz33gE5Duw==",
+      "version": "6.22.2",
+      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.2.tgz",
+      "integrity": "sha512-WgqxD2qySEIBPZ3w0sHH+PUAiamDeszls9tzqMPBDA1YYVucTBXLU7+gtRfcSnhe92A3glPnvSxK2dhNoAVOIQ==",
       "dependencies": {
-        "@remix-run/router": "1.15.1",
-        "react-router": "6.22.1"
+        "@remix-run/router": "1.15.2",
+        "react-router": "6.22.2"
       },
       "engines": {
         "node": ">=14.0.0"
@@ -12284,12 +12313,12 @@
       }
     },
     "node_modules/side-channel": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz",
-      "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==",
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+      "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.6",
+        "call-bind": "^1.0.7",
         "es-errors": "^1.3.0",
         "get-intrinsic": "^1.2.4",
         "object-inspect": "^1.13.1"
@@ -13250,9 +13279,9 @@
       "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
     },
     "node_modules/type": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
-      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+      "version": "2.7.2",
+      "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
+      "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
     },
     "node_modules/type-check": {
       "version": "0.4.0",
@@ -13375,9 +13404,9 @@
       }
     },
     "node_modules/typedoc": {
-      "version": "0.25.9",
-      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.9.tgz",
-      "integrity": "sha512-jVoGmfNw848iW0L313+jqHbsknepwDV6F9nzk1H30oWhKXkw65uaENgR6QtTw9a5KqRWEb6nwNd54KxffBJyWw==",
+      "version": "0.25.10",
+      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.10.tgz",
+      "integrity": "sha512-v10rtOFojrjW9og3T+6wAKeJaGMuojU87DXGZ33sfs+554wgPTRG+s07Ag1BjPZI85Y5QPVouPI63JQ6fcQM5w==",
       "dev": true,
       "dependencies": {
         "lunr": "^2.3.9",

+ 1 - 1
frontend/taipy-gui/package.json

@@ -1,6 +1,6 @@
 {
   "name": "taipy-gui",
-  "version": "3.1.0",
+  "version": "3.2.0",
   "private": true,
   "dependencies": {
     "@emotion/react": "^11.10.0",

+ 1 - 1
frontend/taipy-gui/packaging/package.json

@@ -1,6 +1,6 @@
 {
   "name": "taipy-gui",
-  "version": "3.1.0",
+  "version": "3.2.0",
   "private": true,
   "main": "./taipy-gui.js",
   "types": "./taipy-gui.d.ts"

+ 14 - 0
frontend/taipy-gui/public/stylekit/controls/chart.css

@@ -41,3 +41,17 @@
 .taipy-chart:not(.has-background) .main-svg {
   background: transparent !important;
 }
+
+.js-plotly-plot.full-screen {
+    position: fixed !important;
+    height: 99vh !important;
+    width: 99vw !important;
+    display: block !important;
+    left: 0;
+    top: 0;
+    z-index: 99999;
+    overflow: hidden;
+    background-color: var(--color-background);
+    box-shadow: 10px 5px 5px var(--color-contrast);
+    transition: left 1s ease, width 1s ease, top 1s ease, height 1s ease;
+}

+ 56 - 9
frontend/taipy-gui/src/components/Taipy/Chart.tsx

@@ -11,8 +11,27 @@
  * specific language governing permissions and limitations under the License.
  */
 
-import React, { CSSProperties, useCallback, useEffect, useMemo, useRef, useState, lazy, Suspense } from "react";
-import { Data, Layout, PlotDatum, PlotMarker, PlotRelayoutEvent, PlotSelectionEvent, ScatterLine } from "plotly.js";
+import React, {
+    CSSProperties,
+    useCallback,
+    useEffect,
+    useMemo,
+    useRef,
+    useState,
+    lazy,
+    Suspense,
+} from "react";
+import {
+    Config,
+    Data,
+    Layout,
+    ModeBarButtonAny,
+    PlotDatum,
+    PlotMarker,
+    PlotRelayoutEvent,
+    PlotSelectionEvent,
+    ScatterLine,
+} from "plotly.js";
 import Skeleton from "@mui/material/Skeleton";
 import Box from "@mui/material/Box";
 import Tooltip from "@mui/material/Tooltip";
@@ -196,6 +215,29 @@ const defaultConfig = {
 const emptyLayout = {} as Record<string, Record<string, unknown>>;
 const emptyData = {} as Record<string, TraceValueType>;
 
+const TaipyPlotlyButtons: ModeBarButtonAny[] = [
+    {
+        name: "Full screen",
+        title: "Full screen",
+        icon: {
+            height: 24,
+            width: 24,
+            path: "M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z",
+        },
+        click: function (gd: HTMLElement, evt: Event) {
+            const title = gd.classList.toggle("full-screen") ? "Exit Full screen" : "Full screen";
+            (evt.currentTarget as HTMLElement).setAttribute("data-title", title);
+            const {height} = gd.dataset;
+            if (height) {
+                gd.attributeStyleMap.set("height", height);
+            } else {
+                gd.setAttribute("data-height", getComputedStyle(gd.querySelector(".svg-container") || gd).height)
+            }
+            window.dispatchEvent(new Event('resize'));
+        },
+    },
+];
+
 const Chart = (props: ChartProp) => {
     const {
         title = "",
@@ -293,7 +335,7 @@ const Chart = (props: ChartProp) => {
     useDispatchRequestUpdateOnFirstRender(dispatch, id, module, updateVars);
 
     const layout = useMemo(() => {
-        const layout = {...baseLayout};
+        const layout = { ...baseLayout };
         let template = undefined;
         try {
             const tpl = props.template && JSON.parse(props.template);
@@ -320,6 +362,7 @@ const Chart = (props: ChartProp) => {
         }
         return {
             ...layout,
+            autosize: true,
             title: title || layout.title,
             xaxis: {
                 title:
@@ -446,7 +489,7 @@ const Chart = (props: ChartProp) => {
     }, [props.figure, selected, data, config, dataKey]);
 
     const plotConfig = useMemo(() => {
-        let plconf = {};
+        let plconf: Partial<Config> = {};
         if (props.plotConfig) {
             try {
                 plconf = JSON.parse(props.plotConfig);
@@ -458,11 +501,13 @@ const Chart = (props: ChartProp) => {
                 plconf = {};
             }
         }
-        if (active) {
-            return plconf;
-        } else {
-            return { ...plconf, staticPlot: true };
+        plconf.modeBarButtonsToAdd = TaipyPlotlyButtons;
+        plconf.responsive = true;
+        plconf.autosizable = true;
+        if (!active) {
+            plconf.staticPlot = true;
         }
+        return plconf;
     }, [active, props.plotConfig]);
 
     const onRelayout = useCallback(
@@ -558,7 +603,7 @@ const Chart = (props: ChartProp) => {
     );
 
     return render ? (
-        <Box id={id} key="div" data-testid={props.testId} className={className} ref={plotRef}>
+        <Box id={id} data-testid={props.testId} className={className} ref={plotRef}>
             <Tooltip title={hover || ""}>
                 <Suspense fallback={<Skeleton key="skeleton" sx={skelStyle} />}>
                     {Array.isArray(props.figure) && props.figure.length && props.figure[0].data !== undefined ? (
@@ -571,6 +616,7 @@ const Chart = (props: ChartProp) => {
                             onSelected={onSelect}
                             onDeselect={onSelect}
                             config={plotConfig}
+                            useResizeHandler
                         />
                     ) : (
                         <Plot
@@ -583,6 +629,7 @@ const Chart = (props: ChartProp) => {
                             onDeselect={isOnClick(config.types) ? undefined : onSelect}
                             onClick={isOnClick(config.types) ? onSelect : undefined}
                             config={plotConfig}
+                            useResizeHandler
                         />
                     )}
                 </Suspense>

+ 168 - 135
frontend/taipy/package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "taipy-gui-core",
-  "version": "3.1.0",
+  "version": "3.2.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "taipy-gui-core",
-      "version": "3.1.0",
+      "version": "3.2.0",
       "hasInstallScript": true,
       "dependencies": {
         "@emotion/react": "^11.10.6",
@@ -41,7 +41,7 @@
       }
     },
     "../../taipy/gui/webapp": {
-      "version": "3.1.0"
+      "version": "3.2.0"
     },
     "node_modules/@aashutoshrathi/word-wrap": {
       "version": "1.2.6",
@@ -595,14 +595,14 @@
       }
     },
     "node_modules/@jridgewell/gen-mapping": {
-      "version": "0.3.4",
-      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.4.tgz",
-      "integrity": "sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==",
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+      "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/set-array": "^1.0.1",
+        "@jridgewell/set-array": "^1.2.1",
         "@jridgewell/sourcemap-codec": "^1.4.10",
-        "@jridgewell/trace-mapping": "^0.3.9"
+        "@jridgewell/trace-mapping": "^0.3.24"
       },
       "engines": {
         "node": ">=6.0.0"
@@ -618,9 +618,9 @@
       }
     },
     "node_modules/@jridgewell/set-array": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
-      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
       "dev": true,
       "engines": {
         "node": ">=6.0.0"
@@ -643,9 +643,9 @@
       "dev": true
     },
     "node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.23",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.23.tgz",
-      "integrity": "sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==",
+      "version": "0.3.25",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
       "dev": true,
       "dependencies": {
         "@jridgewell/resolve-uri": "^3.1.0",
@@ -684,14 +684,14 @@
       }
     },
     "node_modules/@mui/base": {
-      "version": "5.0.0-beta.37",
-      "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.37.tgz",
-      "integrity": "sha512-/o3anbb+DeCng8jNsd3704XtmmLDZju1Fo8R2o7ugrVtPQ/QpcqddwKNzKPZwa0J5T8YNW3ZVuHyQgbTnQLisQ==",
+      "version": "5.0.0-beta.38",
+      "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.38.tgz",
+      "integrity": "sha512-AsjD6Y1X5A1qndxz8xCcR8LDqv31aiwlgWMPxFAX/kCKiIGKlK65yMeVZ62iQr/6LBz+9hSKLiD1i4TZdAHKcQ==",
       "dependencies": {
         "@babel/runtime": "^7.23.9",
         "@floating-ui/react-dom": "^2.0.8",
         "@mui/types": "^7.2.13",
-        "@mui/utils": "^5.15.11",
+        "@mui/utils": "^5.15.12",
         "@popperjs/core": "^2.11.8",
         "clsx": "^2.1.0",
         "prop-types": "^15.8.1"
@@ -715,18 +715,18 @@
       }
     },
     "node_modules/@mui/core-downloads-tracker": {
-      "version": "5.15.11",
-      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.11.tgz",
-      "integrity": "sha512-JVrJ9Jo4gyU707ujnRzmE8ABBWpXd6FwL9GYULmwZRtfPg89ggXs/S3MStQkpJ1JRWfdLL6S5syXmgQGq5EDAw==",
+      "version": "5.15.12",
+      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.12.tgz",
+      "integrity": "sha512-brRO+tMFLpGyjEYHrX97bzqeF6jZmKpqqe1rY0LyIHAwP6xRVzh++zSecOQorDOCaZJg4XkGT9xfD+RWOWxZBA==",
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/mui-org"
       }
     },
     "node_modules/@mui/icons-material": {
-      "version": "5.15.11",
-      "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.11.tgz",
-      "integrity": "sha512-R5ZoQqnKpd+5Ew7mBygTFLxgYsQHPhgR3TDXSgIHYIjGzYuyPLmGLSdcPUoMdi6kxiYqHlpPj4NJxlbaFD0UHA==",
+      "version": "5.15.12",
+      "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.12.tgz",
+      "integrity": "sha512-3BXiDlOd3AexZoEXa/VqpIpVIvosCzjLHsdMWzKMXbZdnBiJjmb9ECdqfjn5SpTClO49qvkKLhkTqdBH3fSFGw==",
       "dependencies": {
         "@babel/runtime": "^7.23.9"
       },
@@ -749,16 +749,16 @@
       }
     },
     "node_modules/@mui/material": {
-      "version": "5.15.11",
-      "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.11.tgz",
-      "integrity": "sha512-FA3eEuEZaDaxgN3CgfXezMWbCZ4VCeU/sv0F0/PK5n42qIgsPVD6q+j71qS7/62sp6wRFMHtDMpXRlN+tT/7NA==",
+      "version": "5.15.12",
+      "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.12.tgz",
+      "integrity": "sha512-vXJGg6KNKucsvbW6l7w9zafnpOp0CWc0Wx4mDykuABTpQ5QQBnZxP7+oB4yAS1hDZQ1WobbeIl0CjxK4EEahkA==",
       "dependencies": {
         "@babel/runtime": "^7.23.9",
-        "@mui/base": "5.0.0-beta.37",
-        "@mui/core-downloads-tracker": "^5.15.11",
-        "@mui/system": "^5.15.11",
+        "@mui/base": "5.0.0-beta.38",
+        "@mui/core-downloads-tracker": "^5.15.12",
+        "@mui/system": "^5.15.12",
         "@mui/types": "^7.2.13",
-        "@mui/utils": "^5.15.11",
+        "@mui/utils": "^5.15.12",
         "@types/react-transition-group": "^4.4.10",
         "clsx": "^2.1.0",
         "csstype": "^3.1.3",
@@ -793,12 +793,12 @@
       }
     },
     "node_modules/@mui/private-theming": {
-      "version": "5.15.11",
-      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.11.tgz",
-      "integrity": "sha512-jY/696SnSxSzO1u86Thym7ky5T9CgfidU3NFJjguldqK4f3Z5S97amZ6nffg8gTD0HBjY9scB+4ekqDEUmxZOA==",
+      "version": "5.15.12",
+      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.12.tgz",
+      "integrity": "sha512-cqoSo9sgA5HE+8vZClbLrq9EkyOnYysooepi5eKaKvJ41lReT2c5wOZAeDDM1+xknrMDos+0mT2zr3sZmUiRRA==",
       "dependencies": {
         "@babel/runtime": "^7.23.9",
-        "@mui/utils": "^5.15.11",
+        "@mui/utils": "^5.15.12",
         "prop-types": "^15.8.1"
       },
       "engines": {
@@ -850,15 +850,15 @@
       }
     },
     "node_modules/@mui/system": {
-      "version": "5.15.11",
-      "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.11.tgz",
-      "integrity": "sha512-9j35suLFq+MgJo5ktVSHPbkjDLRMBCV17NMBdEQurh6oWyGnLM4uhU4QGZZQ75o0vuhjJghOCA1jkO3+79wKsA==",
+      "version": "5.15.12",
+      "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.12.tgz",
+      "integrity": "sha512-/pq+GO6yN3X7r3hAwFTrzkAh7K1bTF5r8IzS79B9eyKJg7v6B/t4/zZYMR6OT9qEPtwf6rYN2Utg1e6Z7F1OgQ==",
       "dependencies": {
         "@babel/runtime": "^7.23.9",
-        "@mui/private-theming": "^5.15.11",
+        "@mui/private-theming": "^5.15.12",
         "@mui/styled-engine": "^5.15.11",
         "@mui/types": "^7.2.13",
-        "@mui/utils": "^5.15.11",
+        "@mui/utils": "^5.15.12",
         "clsx": "^2.1.0",
         "csstype": "^3.1.3",
         "prop-types": "^15.8.1"
@@ -902,9 +902,9 @@
       }
     },
     "node_modules/@mui/utils": {
-      "version": "5.15.11",
-      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.11.tgz",
-      "integrity": "sha512-D6bwqprUa9Stf8ft0dcMqWyWDKEo7D+6pB1k8WajbqlYIRA8J8Kw9Ra7PSZKKePGBGWO+/xxrX1U8HpG/aXQCw==",
+      "version": "5.15.12",
+      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.12.tgz",
+      "integrity": "sha512-8SDGCnO2DY9Yy+5bGzu00NZowSDtuyHP4H8gunhHGQoIlhlY2Z3w64wBzAOLpYw/ZhJNzksDTnS/i8qdJvxuow==",
       "dependencies": {
         "@babel/runtime": "^7.23.9",
         "@types/prop-types": "^15.7.11",
@@ -929,9 +929,9 @@
       }
     },
     "node_modules/@mui/x-date-pickers": {
-      "version": "6.19.5",
-      "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.19.5.tgz",
-      "integrity": "sha512-WPi59ImgvGTEuAlJiCLnqNkEkbqPjgwUTrg8iqACFIb4qzg5tz4y8vNgmOKMnTXCwWDHjd+SoDdxiMlZJWT1hg==",
+      "version": "6.19.6",
+      "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.19.6.tgz",
+      "integrity": "sha512-QW9AFcPi0vLpkUhmquhhyhLaBvB0AZJuu3NTrE173qNKx3Z3n51aCLY9bc7c6i4ltZMMsVRHlvzQjsve04TC8A==",
       "dependencies": {
         "@babel/runtime": "^7.23.2",
         "@mui/base": "^5.0.0-beta.22",
@@ -1147,9 +1147,9 @@
       "dev": true
     },
     "node_modules/@types/eslint": {
-      "version": "8.56.4",
-      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.4.tgz",
-      "integrity": "sha512-lG1GLUnL5vuRBGb3MgWUWLdGMH2Hps+pERuyQXCfWozuGKdnhf9Pbg4pkcrVUHjKrU7Rl+GCZ/299ObBXZFAxg==",
+      "version": "8.56.5",
+      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz",
+      "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==",
       "dev": true,
       "dependencies": {
         "@types/estree": "*",
@@ -1212,9 +1212,9 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "20.11.21",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.21.tgz",
-      "integrity": "sha512-/ySDLGscFPNasfqStUuWWPfL78jompfIoVzLJPVVAHBh6rpG68+pI2Gk+fNLeI8/f1yPYL4s46EleVIc20F1Ow==",
+      "version": "20.11.24",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz",
+      "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==",
       "dev": true,
       "dependencies": {
         "undici-types": "~5.26.4"
@@ -1231,9 +1231,9 @@
       "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
     },
     "node_modules/@types/react": {
-      "version": "18.2.60",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.60.tgz",
-      "integrity": "sha512-dfiPj9+k20jJrLGOu9Nf6eqxm2EyJRrq2NvwOFsfbb7sFExZ9WELPs67UImHj3Ayxg8ruTtKtNnbjaF8olPq0A==",
+      "version": "18.2.63",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.63.tgz",
+      "integrity": "sha512-ppaqODhs15PYL2nGUOaOu2RSCCB4Difu4UFrP4I3NHLloXC/ESQzQMi9nvjfT1+rudd0d2L3fQPJxRSey+rGlQ==",
       "dependencies": {
         "@types/prop-types": "*",
         "@types/scheduler": "*",
@@ -1275,16 +1275,16 @@
       "dev": true
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.0.tgz",
-      "integrity": "sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.1.tgz",
+      "integrity": "sha512-zioDz623d0RHNhvx0eesUmGfIjzrk18nSBC8xewepKXbBvN/7c1qImV7Hg8TI1URTxKax7/zxfxj3Uph8Chcuw==",
       "dev": true,
       "dependencies": {
         "@eslint-community/regexpp": "^4.5.1",
-        "@typescript-eslint/scope-manager": "7.1.0",
-        "@typescript-eslint/type-utils": "7.1.0",
-        "@typescript-eslint/utils": "7.1.0",
-        "@typescript-eslint/visitor-keys": "7.1.0",
+        "@typescript-eslint/scope-manager": "7.1.1",
+        "@typescript-eslint/type-utils": "7.1.1",
+        "@typescript-eslint/utils": "7.1.1",
+        "@typescript-eslint/visitor-keys": "7.1.1",
         "debug": "^4.3.4",
         "graphemer": "^1.4.0",
         "ignore": "^5.2.4",
@@ -1310,15 +1310,15 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.0.tgz",
-      "integrity": "sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.1.tgz",
+      "integrity": "sha512-ZWUFyL0z04R1nAEgr9e79YtV5LbafdOtN7yapNbn1ansMyaegl2D4bL7vHoJ4HPSc4CaLwuCVas8CVuneKzplQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "7.1.0",
-        "@typescript-eslint/types": "7.1.0",
-        "@typescript-eslint/typescript-estree": "7.1.0",
-        "@typescript-eslint/visitor-keys": "7.1.0",
+        "@typescript-eslint/scope-manager": "7.1.1",
+        "@typescript-eslint/types": "7.1.1",
+        "@typescript-eslint/typescript-estree": "7.1.1",
+        "@typescript-eslint/visitor-keys": "7.1.1",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -1338,13 +1338,13 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.0.tgz",
-      "integrity": "sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.1.tgz",
+      "integrity": "sha512-cirZpA8bJMRb4WZ+rO6+mnOJrGFDd38WoXCEI57+CYBqta8Yc8aJym2i7vyqLL1vVYljgw0X27axkUXz32T8TA==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.1.0",
-        "@typescript-eslint/visitor-keys": "7.1.0"
+        "@typescript-eslint/types": "7.1.1",
+        "@typescript-eslint/visitor-keys": "7.1.1"
       },
       "engines": {
         "node": "^16.0.0 || >=18.0.0"
@@ -1355,13 +1355,13 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.0.tgz",
-      "integrity": "sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.1.tgz",
+      "integrity": "sha512-5r4RKze6XHEEhlZnJtR3GYeCh1IueUHdbrukV2KSlLXaTjuSfeVF8mZUVPLovidCuZfbVjfhi4c0DNSa/Rdg5g==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/typescript-estree": "7.1.0",
-        "@typescript-eslint/utils": "7.1.0",
+        "@typescript-eslint/typescript-estree": "7.1.1",
+        "@typescript-eslint/utils": "7.1.1",
         "debug": "^4.3.4",
         "ts-api-utils": "^1.0.1"
       },
@@ -1382,9 +1382,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.0.tgz",
-      "integrity": "sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.1.tgz",
+      "integrity": "sha512-KhewzrlRMrgeKm1U9bh2z5aoL4s7K3tK5DwHDn8MHv0yQfWFz/0ZR6trrIHHa5CsF83j/GgHqzdbzCXJ3crx0Q==",
       "dev": true,
       "engines": {
         "node": "^16.0.0 || >=18.0.0"
@@ -1395,13 +1395,13 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.0.tgz",
-      "integrity": "sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.1.tgz",
+      "integrity": "sha512-9ZOncVSfr+sMXVxxca2OJOPagRwT0u/UHikM2Rd6L/aB+kL/QAuTnsv6MeXtjzCJYb8PzrXarypSGIPx3Jemxw==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.1.0",
-        "@typescript-eslint/visitor-keys": "7.1.0",
+        "@typescript-eslint/types": "7.1.1",
+        "@typescript-eslint/visitor-keys": "7.1.1",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -1423,17 +1423,17 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.0.tgz",
-      "integrity": "sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.1.tgz",
+      "integrity": "sha512-thOXM89xA03xAE0lW7alstvnyoBUbBX38YtY+zAUcpRPcq9EIhXPuJ0YTv948MbzmKh6e1AUszn5cBFK49Umqg==",
       "dev": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
         "@types/json-schema": "^7.0.12",
         "@types/semver": "^7.5.0",
-        "@typescript-eslint/scope-manager": "7.1.0",
-        "@typescript-eslint/types": "7.1.0",
-        "@typescript-eslint/typescript-estree": "7.1.0",
+        "@typescript-eslint/scope-manager": "7.1.1",
+        "@typescript-eslint/types": "7.1.1",
+        "@typescript-eslint/typescript-estree": "7.1.1",
         "semver": "^7.5.4"
       },
       "engines": {
@@ -1448,12 +1448,12 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.0.tgz",
-      "integrity": "sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.1.tgz",
+      "integrity": "sha512-yTdHDQxY7cSoCcAtiBzVzxleJhkGB9NncSIyMYe2+OGON1ZsP9zOPws/Pqgopa65jvknOjlk/w7ulPlZ78PiLQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.1.0",
+        "@typescript-eslint/types": "7.1.1",
         "eslint-visitor-keys": "^3.4.1"
       },
       "engines": {
@@ -1840,6 +1840,25 @@
         "node": ">=8"
       }
     },
+    "node_modules/array.prototype.findlast": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.4.tgz",
+      "integrity": "sha512-BMtLxpV+8BD+6ZPFIWmnUBpQoy+A+ujcg4rhp2iwCRJYA7PEh2MS4NL3lz8EiDlLrJPp2hg9qWihr5pd//jcGw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.5",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.22.3",
+        "es-errors": "^1.3.0",
+        "es-shim-unscopables": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/array.prototype.flat": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
@@ -1876,6 +1895,18 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/array.prototype.toreversed": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz",
+      "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "es-shim-unscopables": "^1.0.0"
+      }
+    },
     "node_modules/array.prototype.tosorted": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz",
@@ -2042,9 +2073,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001591",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz",
-      "integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
+      "version": "1.0.30001594",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz",
+      "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==",
       "dev": true,
       "funding": [
         {
@@ -2339,9 +2370,9 @@
       }
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.685",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.685.tgz",
-      "integrity": "sha512-yDYeobbTEe4TNooEzOQO6xFqg9XnAkVy2Lod1C1B2it8u47JNLYvl9nLDWBamqUakWB8Jc1hhS1uHUNYTNQdfw==",
+      "version": "1.4.693",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.693.tgz",
+      "integrity": "sha512-/if4Ueg0GUQlhCrW2ZlXwDAm40ipuKo+OgeHInlL8sbjt+hzISxZK949fZeJaVsheamrzANXvw1zQTvbxTvSHw==",
       "dev": true
     },
     "node_modules/enhanced-resolve": {
@@ -2378,18 +2409,18 @@
       }
     },
     "node_modules/es-abstract": {
-      "version": "1.22.4",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz",
-      "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==",
+      "version": "1.22.5",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz",
+      "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==",
       "dev": true,
       "dependencies": {
         "array-buffer-byte-length": "^1.0.1",
         "arraybuffer.prototype.slice": "^1.0.3",
-        "available-typed-arrays": "^1.0.6",
+        "available-typed-arrays": "^1.0.7",
         "call-bind": "^1.0.7",
         "es-define-property": "^1.0.0",
         "es-errors": "^1.3.0",
-        "es-set-tostringtag": "^2.0.2",
+        "es-set-tostringtag": "^2.0.3",
         "es-to-primitive": "^1.2.1",
         "function.prototype.name": "^1.1.6",
         "get-intrinsic": "^1.2.4",
@@ -2397,15 +2428,15 @@
         "globalthis": "^1.0.3",
         "gopd": "^1.0.1",
         "has-property-descriptors": "^1.0.2",
-        "has-proto": "^1.0.1",
+        "has-proto": "^1.0.3",
         "has-symbols": "^1.0.3",
         "hasown": "^2.0.1",
         "internal-slot": "^1.0.7",
         "is-array-buffer": "^3.0.4",
         "is-callable": "^1.2.7",
-        "is-negative-zero": "^2.0.2",
+        "is-negative-zero": "^2.0.3",
         "is-regex": "^1.1.4",
-        "is-shared-array-buffer": "^1.0.2",
+        "is-shared-array-buffer": "^1.0.3",
         "is-string": "^1.0.7",
         "is-typed-array": "^1.1.13",
         "is-weakref": "^1.0.2",
@@ -2418,10 +2449,10 @@
         "string.prototype.trim": "^1.2.8",
         "string.prototype.trimend": "^1.0.7",
         "string.prototype.trimstart": "^1.0.7",
-        "typed-array-buffer": "^1.0.1",
-        "typed-array-byte-length": "^1.0.0",
-        "typed-array-byte-offset": "^1.0.0",
-        "typed-array-length": "^1.0.4",
+        "typed-array-buffer": "^1.0.2",
+        "typed-array-byte-length": "^1.0.1",
+        "typed-array-byte-offset": "^1.0.2",
+        "typed-array-length": "^1.0.5",
         "unbox-primitive": "^1.0.2",
         "which-typed-array": "^1.1.14"
       },
@@ -2601,27 +2632,29 @@
       }
     },
     "node_modules/eslint-plugin-react": {
-      "version": "7.33.2",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz",
-      "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==",
+      "version": "7.34.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.0.tgz",
+      "integrity": "sha512-MeVXdReleBTdkz/bvcQMSnCXGi+c9kvy51IpinjnJgutl3YTHWsDdke7Z1ufZpGfDG8xduBDKyjtB9JH1eBKIQ==",
       "dev": true,
       "dependencies": {
-        "array-includes": "^3.1.6",
-        "array.prototype.flatmap": "^1.3.1",
-        "array.prototype.tosorted": "^1.1.1",
+        "array-includes": "^3.1.7",
+        "array.prototype.findlast": "^1.2.4",
+        "array.prototype.flatmap": "^1.3.2",
+        "array.prototype.toreversed": "^1.1.2",
+        "array.prototype.tosorted": "^1.1.3",
         "doctrine": "^2.1.0",
-        "es-iterator-helpers": "^1.0.12",
+        "es-iterator-helpers": "^1.0.17",
         "estraverse": "^5.3.0",
         "jsx-ast-utils": "^2.4.1 || ^3.0.0",
         "minimatch": "^3.1.2",
-        "object.entries": "^1.1.6",
-        "object.fromentries": "^2.0.6",
-        "object.hasown": "^1.1.2",
-        "object.values": "^1.1.6",
+        "object.entries": "^1.1.7",
+        "object.fromentries": "^2.0.7",
+        "object.hasown": "^1.1.3",
+        "object.values": "^1.1.7",
         "prop-types": "^15.8.1",
-        "resolve": "^2.0.0-next.4",
+        "resolve": "^2.0.0-next.5",
         "semver": "^6.3.1",
-        "string.prototype.matchall": "^4.0.8"
+        "string.prototype.matchall": "^4.0.10"
       },
       "engines": {
         "node": ">=4"
@@ -4929,12 +4962,12 @@
       }
     },
     "node_modules/side-channel": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz",
-      "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==",
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+      "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.6",
+        "call-bind": "^1.0.7",
         "es-errors": "^1.3.0",
         "get-intrinsic": "^1.2.4",
         "object-inspect": "^1.13.1"
@@ -5113,9 +5146,9 @@
       }
     },
     "node_modules/terser": {
-      "version": "5.28.1",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-5.28.1.tgz",
-      "integrity": "sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==",
+      "version": "5.29.1",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz",
+      "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==",
       "dev": true,
       "dependencies": {
         "@jridgewell/source-map": "^0.3.3",

+ 1 - 1
frontend/taipy/package.json

@@ -1,6 +1,6 @@
 {
   "name": "taipy-gui-core",
-  "version": "3.1.0",
+  "version": "3.2.0",
   "private": true,
   "devDependencies": {
     "@types/react": "^18.0.15",

+ 8 - 3
frontend/taipy/src/ScenarioDag.tsx

@@ -14,6 +14,7 @@ import { DisplayModel, TaskStatuses } from "./utils/types";
 import { addStatusToDisplayModel, createDagreEngine, initDiagram, populateModel, relayoutDiagram } from "./utils/diagram";
 import {
     createRequestUpdateAction,
+    createSendActionNameAction,
     createSendUpdateAction,
     getUpdateVar,
     useDispatch,
@@ -38,6 +39,8 @@ interface ScenarioDagProps {
     libClassName?: string;
     className?: string;
     dynamicClassName?: string;
+    onAction?: string;
+    onSelect?: string;
 }
 
 const titleSx = { ml: 2, flex: 1 };
@@ -67,7 +70,7 @@ const getValidScenario = (scenar: DisplayModel | DisplayModel[]) =>
         : undefined;
 
 const ScenarioDag = (props: ScenarioDagProps) => {
-    const { showToolbar = true } = props;
+    const { showToolbar = true, onSelect, onAction } = props;
     const [scenarioId, setScenarioId] = useState("");
     const [engine] = useState(createEngine);
     const [dagreEngine] = useState(createDagreEngine);
@@ -121,8 +124,10 @@ const ScenarioDag = (props: ScenarioDagProps) => {
 
     const zoomToFit = useCallback(() => engine.zoomToFit(), [engine]);
 
+    const onClick = useCallback((id: string) => onAction && dispatch(createSendActionNameAction(props.id, module, onSelect, id, onAction)), [props.id, onAction, onSelect, module, dispatch]);
+
     useEffect(() => {
-        const model = new TaipyDiagramModel();
+        const model = new TaipyDiagramModel(onClick);
         initDiagram(engine);
         let doLayout = false;
         if (displayModel) {
@@ -135,7 +140,7 @@ const ScenarioDag = (props: ScenarioDagProps) => {
         //engine.getActionEventBus().registerAction(new DeleteItemsAction({ keyCodes: [1] }));
         model.setLocked(true);
         doLayout && setTimeout(relayout, 500);
-    }, [displayModel, engine, relayout]);
+    }, [displayModel, engine, relayout, onClick]);
 
     useEffect(() => {
         const showVar = getUpdateVar(props.updateVars, "show");

+ 4 - 0
frontend/taipy/src/projectstorm/NodeWidget.tsx

@@ -86,6 +86,7 @@ namespace S {
 interface NodeProps {
     node: TaipyNodeModel;
     engine: DiagramEngine;
+    onAction?: string;
 }
 
 const getStatusLabel = (status?: TaskStatus) => status == TaskStatus.Running ? "Running" : status == TaskStatus.Pending ? "Pending" : undefined
@@ -110,6 +111,8 @@ const NodeWidget = ({ node, engine }: NodeProps) => {
         [engine]
     );
 
+    const onClick = useCallback(() => node.onClick && node.onClick(node.getID()), [node]);
+
     return (
         <S.Node
             data-default-node-name={node.getOptions().name}
@@ -117,6 +120,7 @@ const NodeWidget = ({ node, engine }: NodeProps) => {
             background={node.getOptions().color}
             title={getStatusLabel(node.status)}
             $status={node.status}
+            onClick={onClick}
         >
             <S.Title>
                 <S.TitleIcon className="icon" title={node.getType()}>

+ 13 - 4
frontend/taipy/src/projectstorm/models.ts

@@ -16,21 +16,30 @@ import { DefaultNodeModel, DefaultNodeModelOptions, DefaultPortModel, DefaultPor
 import { IN_PORT_NAME, OUT_PORT_NAME } from "../utils/diagram";
 import { getChildType } from "../utils/childtype";
 import { DataNode, Task } from "../utils/names";
-import { TaskStatus } from "../utils/types";
+import { OnClick, TaskStatus } from "../utils/types";
 
-export class TaipyDiagramModel extends DiagramModel {}
+export class TaipyDiagramModel extends DiagramModel {
+    onClick?: OnClick;
+    constructor(onClick?: OnClick) {
+        super();
+        this.onClick = onClick
+    }
+}
 
 export interface TaipyNodeModelOptions extends DefaultNodeModelOptions {
     subtype?: string;
     status?: TaskStatus;
+    onClick?: OnClick;
 }
 export class TaipyNodeModel extends DefaultNodeModel {
-    subtype: string | undefined;
-    status: TaskStatus | undefined;
+    subtype?: string;
+    status?: TaskStatus;
+    onClick?: OnClick;
     constructor(options?: TaipyNodeModelOptions) {
         super(options);
         this.subtype = options?.subtype;
         this.status = options?.status
+        this.onClick = options?.onClick;
     }
 }
 

+ 4 - 3
frontend/taipy/src/utils/diagram.ts

@@ -26,7 +26,7 @@ import { getNodeColor } from "./config";
 import { TaipyDiagramModel, TaipyNodeModel } from "../projectstorm/models";
 import { TaipyNodeFactory, TaipyPortFactory } from "../projectstorm/factories";
 import { nodeTypes } from "./config";
-import { DisplayModel, TaskStatus, TaskStatuses } from "./types";
+import { DisplayModel, OnClick, TaskStatus, TaskStatuses } from "./types";
 
 export const createDagreEngine = () =>
     new DagreEngine({
@@ -59,7 +59,7 @@ export const getLinkId = (link: LinkModel) =>
     )}`;
 export const getNodeId = (node: DefaultNodeModel) => `${node.getType()}.${node.getID()}`;
 
-export const createNode = (nodeType: string, id: string, name: string, subtype: string, status?: TaskStatus) =>
+export const createNode = (nodeType: string, id: string, name: string, subtype: string, status?: TaskStatus, onClick?: OnClick) =>
     new TaipyNodeModel({
         id: id,
         type: nodeType,
@@ -67,6 +67,7 @@ export const createNode = (nodeType: string, id: string, name: string, subtype:
         color: getNodeColor(nodeType),
         subtype: subtype,
         status: status,
+        onClick: onClick,
     });
 
 export const createLink = (outPort: DefaultPortModel, inPort: DefaultPortModel) =>
@@ -147,7 +148,7 @@ export const populateModel = (displayModel: DisplayModel, model: TaipyDiagramMod
     displayModel[1] &&
         Object.entries(displayModel[1]).forEach(([nodeType, n]) => {
             Object.entries(n).forEach(([id, detail]) => {
-                const node = createNode(nodeType, id, detail.name, detail.type, detail.status);
+                const node = createNode(nodeType, id, detail.name, detail.type, detail.status, model.onClick);
                 nodeModels[nodeType] = nodeModels[nodeType] || {};
                 nodeModels[nodeType][id] = node;
             });

+ 4 - 0
frontend/taipy/src/utils/types.ts

@@ -27,3 +27,7 @@ export enum TaskStatus {
 }
 
 export type TaskStatuses = Record<string, TaskStatus>;
+
+export interface OnClick {
+    (id: string): void;
+}

+ 0 - 2
pyproject.toml

@@ -27,11 +27,9 @@ select = [
     "I001", # isort import order
 ]
 ignore = [      # TODO: to be removed
-    "C401",  # Unnecessary generator (rewrite as a `set` comprehension)
     "C405",  # Unnecessary list literal - rewrite as a literal
     "C408",  # Unnecessary dict call - rewrite as a literal
     "C409",  # Unnecessary list passed to tuple() - rewrite as a tuple literal
-    "C416",  # Unnecessary `set` comprehension (rewrite using `set()`)
 ]
 
 # Allow fix for all enabled rules (when `--fix`) is provided.

+ 1 - 1
taipy/core/_entity/_dag.py

@@ -31,7 +31,7 @@ class _Edge:
 
 class _DAG:
     def __init__(self, dag: nx.DiGraph):
-        self._sorted_nodes = [nodes for nodes in nx.topological_generations(dag)]
+        self._sorted_nodes = list(nx.topological_generations(dag))
         self._length, self._width = self.__compute_size()
         self._grid_length, self._grid_width = self.__compute_grid_size()
         self._nodes = self.__compute_nodes()

+ 1 - 1
taipy/core/data/_abstract_sql.py

@@ -230,7 +230,7 @@ class _AbstractSQLDataNode(DataNode, _AbstractTabularDataNode):
 
             # On pandas 1.3.5 there's a bug that makes that the dataframe from sqlalchemy query is
             # created without headers
-            keys = [col for col in result.keys()]
+            keys = list(result.keys())
             if columns:
                 return pd.DataFrame(result, columns=keys)[columns]
             return pd.DataFrame(result, columns=keys)

+ 16 - 13
taipy/core/scenario/scenario.py

@@ -109,11 +109,9 @@ class Scenario(_Entity, Submittable, _Labeled):
         self._properties = _Properties(self, **properties)
         self._sequences: Dict[str, Dict] = sequences or {}
 
-        _scenario_task_ids = set(task.id if isinstance(task, Task) else task for task in self._tasks)
+        _scenario_task_ids = {task.id if isinstance(task, Task) else task for task in self._tasks}
         for sequence_name, sequence_data in self._sequences.items():
-            sequence_task_ids = set(
-                task.id if isinstance(task, Task) else task for task in sequence_data.get("tasks", [])
-            )
+            sequence_task_ids = {task.id if isinstance(task, Task) else task for task in sequence_data.get("tasks", [])}
             self.__check_sequence_tasks_exist_in_scenario_tasks(
                 sequence_name, sequence_task_ids, self.id, _scenario_task_ids
             )
@@ -233,10 +231,11 @@ class Scenario(_Entity, Submittable, _Labeled):
         subscribers: Optional[List[_Subscriber]] = None,
     ) -> Sequence:
         _scenario = _Reloader()._reload(self._MANAGER_NAME, self)
-        _scenario_task_ids = set(task.id if isinstance(task, Task) else task for task in _scenario._tasks)
-        _sequence_task_ids: Set[TaskId] = set(task.id if isinstance(task, Task) else task for task in tasks)
+        _scenario_task_ids = {task.id if isinstance(task, Task) else task for task in _scenario._tasks}
+        _sequence_task_ids: Set[TaskId] = {task.id if isinstance(task, Task) else task for task in tasks}
         self.__check_sequence_tasks_exist_in_scenario_tasks(name, _sequence_task_ids, self.id, _scenario_task_ids)
         from taipy.core.sequence._sequence_manager_factory import _SequenceManagerFactory
+
         seq_manager = _SequenceManagerFactory._build_manager()
         seq = seq_manager._create(name, tasks, subscribers or [], properties or {}, self.id, self.version)
         if not seq._is_consistent():
@@ -270,9 +269,9 @@ class Scenario(_Entity, Submittable, _Labeled):
             SequenceTaskDoesNotExistInScenario^: If a task in the sequence does not exist in the scenario.
         """
         _scenario = _Reloader()._reload(self._MANAGER_NAME, self)
-        _sc_task_ids = set(task.id if isinstance(task, Task) else task for task in _scenario._tasks)
+        _sc_task_ids = {task.id if isinstance(task, Task) else task for task in _scenario._tasks}
         for name, tasks in sequences.items():
-            _seq_task_ids: Set[TaskId] = set(task.id if isinstance(task, Task) else task for task in tasks)
+            _seq_task_ids: Set[TaskId] = {task.id if isinstance(task, Task) else task for task in tasks}
             self.__check_sequence_tasks_exist_in_scenario_tasks(name, _seq_task_ids, self.id, _sc_task_ids)
         # Need to parse twice the sequences to avoid adding some sequences and not others in case of exception
         for name, tasks in sequences.items():
@@ -327,11 +326,15 @@ class Scenario(_Entity, Submittable, _Labeled):
         self._sequences[new_name] = self._sequences[old_name]
         del self._sequences[old_name]
         self.sequences = self._sequences  # type: ignore
-        Notifier.publish(Event(EventEntityType.SCENARIO,
-                               EventOperation.UPDATE,
-                               entity_id=self.id,
-                               attribute_name="sequences",
-                               attribute_value=self._sequences))
+        Notifier.publish(
+            Event(
+                EventEntityType.SCENARIO,
+                EventOperation.UPDATE,
+                entity_id=self.id,
+                attribute_name="sequences",
+                attribute_value=self._sequences,
+            )
+        )
 
     @staticmethod
     def __check_sequence_tasks_exist_in_scenario_tasks(

+ 18 - 2
taipy/gui/gui.py

@@ -31,7 +31,17 @@ from urllib.parse import unquote, urlencode, urlparse
 
 import markdown as md_lib
 import tzlocal
-from flask import Blueprint, Flask, g, has_app_context, jsonify, request, send_file, send_from_directory
+from flask import (
+    Blueprint,
+    Flask,
+    g,
+    has_app_context,
+    has_request_context,
+    jsonify,
+    request,
+    send_file,
+    send_from_directory,
+)
 from werkzeug.utils import secure_filename
 
 import __main__  # noqa: F401
@@ -1002,7 +1012,13 @@ class Gui:
                 elif isinstance(newvalue, _TaipyToJson):
                     newvalue = newvalue.get()
                 if isinstance(newvalue, (dict, _MapDict)):
-                    continue  # this var has no transformer
+                    # Skip in taipy-gui, available in custom frontend
+                    resource_handler_id = None
+                    with contextlib.suppress(Exception):
+                        if has_request_context():
+                            resource_handler_id = request.cookies.get(_Server._RESOURCE_HANDLER_ARG, None)
+                    if resource_handler_id is None:
+                        continue  # this var has no transformer
                 if isinstance(newvalue, float) and math.isnan(newvalue):
                     # do not let NaN go through json, it is not handle well (dies silently through websocket)
                     newvalue = None

+ 2 - 0
taipy/gui_core/_GuiCoreLib.py

@@ -99,9 +99,11 @@ class _GuiCore(ElementLibrary):
                 "width": ElementProperty(PropertyType.string),
                 "height": ElementProperty(PropertyType.string),
                 "class_name": ElementProperty(PropertyType.dynamic_string),
+                "on_action": ElementProperty(PropertyType.function),
             },
             inner_properties={
                 "core_changed": ElementProperty(PropertyType.broadcast, _GuiCoreContext._CORE_CHANGED_NAME),
+                "on_select": ElementProperty(PropertyType.function, f"{{{__CTX_VAR_NAME}.on_dag_select}}"),
             },
         ),
         "data_node_selector": Element(

+ 21 - 2
taipy/gui_core/_context.py

@@ -124,7 +124,7 @@ class _GuiCoreContext(CoreEventConsumerBase):
                     if sequence and hasattr(sequence, "parent_ids") and sequence.parent_ids:  # type: ignore
                         self.gui._broadcast(
                             _GuiCoreContext._CORE_CHANGED_NAME,
-                            {"scenario": [x for x in sequence.parent_ids]},  # type: ignore
+                            {"scenario": list(sequence.parent_ids)},  # type: ignore
                         )
             except Exception as e:
                 _warn(f"Access to sequence {event.entity_id} failed", e)
@@ -650,7 +650,7 @@ class _GuiCoreContext(CoreEventConsumerBase):
             if isinstance(ent, Scenario):
                 tags = data.get(_GuiCoreContext.__PROP_SCENARIO_TAGS)
                 if isinstance(tags, (list, tuple)):
-                    ent.tags = {t for t in tags}
+                    ent.tags = dict(tags)
             name = data.get(_GuiCoreContext.__PROP_ENTITY_NAME)
             if isinstance(name, str):
                 if hasattr(ent, _GuiCoreContext.__PROP_ENTITY_NAME):
@@ -939,3 +939,22 @@ class _GuiCoreContext(CoreEventConsumerBase):
             state.assign(_GuiCoreContext._DATANODE_VIZ_DATA_ID_VAR, data_id)
         elif chart_id := data.get("chart_id"):
             state.assign(_GuiCoreContext._DATANODE_VIZ_DATA_CHART_ID_VAR, chart_id)
+
+    def on_dag_select(self, state: State, id: str, payload: t.Dict[str, str]):
+        args = payload.get("args")
+        if args is None or not isinstance(args, list) or len(args) < 2:
+            return
+        on_action_function = self.gui._get_user_function(args[1]) if args[1] else None
+        if callable(on_action_function):
+            try:
+                entity = core_get(args[0]) if is_readable(args[0]) else f"unredable({args[0]})"
+                self.gui._call_function_with_state(
+                    on_action_function,
+                    [entity],
+                )
+            except Exception as e:
+                if not self.gui._call_on_exception(args[1], e):
+                    _warn(f"dag.on_action(): Exception raised in '{args[1]}()' with '{args[0]}'", e)
+        elif args[1]:
+            _warn(f"dag.on_action(): Invalid function '{args[1]}()'.")
+

+ 6 - 0
taipy/gui_core/viselements.json

@@ -207,6 +207,12 @@
                         "type": "str",
                         "default_value": "\"100%\"",
                         "doc": "The maximum width, in CSS units, of the control."
+                    },
+                    {
+                        "name": "on_action",
+                        "type": "Callback",
+                        "doc": "The name of the function that is triggered when a a node is selected.<br/><br/>All the parameters of that function are optional:\n<ul>\n<li>state (<code>State^</code>): the state instance.</li>\n<li>entity (DataNode | Task): the entity (DataNode or Task) that was selected.</li>\n</ul>",
+                        "signature": [["state", "State"], ["entity", "Task | DataNode"]]
                     }
                 ]
             }

+ 3 - 6
tests/core/config/test_core_version.py

@@ -9,7 +9,7 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 
-from unittest.mock import patch
+from unittest import mock
 
 import pytest
 
@@ -24,18 +24,15 @@ _MOCK_CORE_VERSION = "3.1.1"
 
 @pytest.fixture(scope="function", autouse=True)
 def mock_core_version():
-    with patch("taipy.core.config.core_section._read_version") as mock_read_version:
+    with mock.patch("taipy.core.config.core_section._read_version") as mock_read_version:
         mock_read_version.return_value = _MOCK_CORE_VERSION
         CoreSection._CURRENT_CORE_VERSION = _MOCK_CORE_VERSION
         Config.unique_sections[CoreSection.name] = CoreSection.default_config()
         Config._default_config._unique_sections[CoreSection.name] = CoreSection.default_config()
+        Config._python_config._unique_sections[CoreSection.name] = CoreSection.default_config()
 
         yield
 
-
-@pytest.fixture(scope="session", autouse=True)
-def reset_core_version():
-    yield
     CoreSection._CURRENT_CORE_VERSION = _read_version()
 
 

+ 1 - 1
tests/core/data/test_filter_data_node.py

@@ -244,7 +244,7 @@ def test_filter_by_get_item(default_data_frame):
     filtered_custom_dn = custom_dn["a"]
     assert isinstance(filtered_custom_dn, List)
     assert len(filtered_custom_dn) == 10
-    assert filtered_custom_dn == [i for i in range(10)]
+    assert filtered_custom_dn == list(range(10))
 
     filtered_custom_dn = custom_dn[0:5]
     assert isinstance(filtered_custom_dn, List)

+ 2 - 2
tests/core/data/test_generic_data_node.py

@@ -46,11 +46,11 @@ def read_fct_modify_data_node_name(data_node_id: DataNodeId, name: str):
 
 
 def reset_data():
-    TestGenericDataNode.data = [i for i in range(10)]
+    TestGenericDataNode.data = list(range(10))
 
 
 class TestGenericDataNode:
-    data = [i for i in range(10)]
+    data = list(range(10))
 
     def test_create(self):
         dn = GenericDataNode(

+ 7 - 5
tests/core/job/test_job_manager.py

@@ -411,10 +411,12 @@ def test_cancel_subsequent_jobs():
     assert_true_after_time(job_4.is_canceled)
     assert_true_after_time(job_5.is_abandoned)
     assert_true_after_time(job_6.is_abandoned)
-    assert_true_after_time(lambda: all(
-        not _OrchestratorFactory._orchestrator._is_blocked(job)
-        for job in [job_1, job_2, job_3, job_4, job_5, job_6]
-    ))
+    assert_true_after_time(
+        lambda: all(
+            not _OrchestratorFactory._orchestrator._is_blocked(job)
+            for job in [job_1, job_2, job_3, job_4, job_5, job_6]
+        )
+    )
     assert_true_after_time(lambda: _OrchestratorFactory._orchestrator.jobs_to_run.qsize() == 0)
 
 
@@ -474,7 +476,7 @@ def _create_task(function, nb_outputs=1, name=None):
     output_dn_configs = [
         Config.configure_data_node(f"output{i}", "pickle", Scope.SCENARIO, default_data=0) for i in range(nb_outputs)
     ]
-    _DataManager._bulk_get_or_create({cfg for cfg in output_dn_configs})
+    _DataManager._bulk_get_or_create(output_dn_configs)
     name = name or "".join(random.choice(string.ascii_lowercase) for _ in range(10))
     task_config = Config.configure_task(
         id=name,

+ 1 - 1
tests/core/job/test_job_manager_with_sql_repo.py

@@ -245,7 +245,7 @@ def _create_task(function, nb_outputs=1, name=None):
     output_dn_configs = [
         Config.configure_data_node(f"output{i}", scope=Scope.SCENARIO, default_data=0) for i in range(nb_outputs)
     ]
-    _DataManager._bulk_get_or_create({cfg for cfg in output_dn_configs})
+    _DataManager._bulk_get_or_create(output_dn_configs)
     name = name or "".join(random.choice(string.ascii_lowercase) for _ in range(10))
     task_config = Config.configure_task(
         id=name,

+ 1 - 1
tests/core/scenario/test_scenario_manager.py

@@ -559,7 +559,7 @@ def test_scenario_manager_only_creates_data_node_once():
     scenario_1_sorted_tasks = scenario_1._get_sorted_tasks()
     expected = [{task_mult_by_2_config.id, task_mult_by_4_config.id}, {task_mult_by_3_config.id}]
     for i, list_tasks_by_level in enumerate(scenario_1_sorted_tasks):
-        assert set(t.config_id for t in list_tasks_by_level) == expected[i]
+        assert {t.config_id for t in list_tasks_by_level} == expected[i]
     assert scenario_1.cycle.frequency == Frequency.DAILY
 
     _ScenarioManager._create(scenario_config)

+ 1 - 1
tests/core/scenario/test_scenario_manager_with_sql_repo.py

@@ -371,7 +371,7 @@ def test_scenario_manager_only_creates_data_node_once(init_sql_repo):
     scenario_1_sorted_tasks = scenario_1._get_sorted_tasks()
     expected = [{task_mult_by_2_config.id, task_mult_by_4_config.id}, {task_mult_by_3_config.id}]
     for i, list_tasks_by_level in enumerate(scenario_1_sorted_tasks):
-        assert set(t.config_id for t in list_tasks_by_level) == expected[i]
+        assert {t.config_id for t in list_tasks_by_level} == expected[i]
     assert scenario_1.cycle.frequency == Frequency.DAILY
 
     _ScenarioManager._create(scenario_config)