diff --git a/package-lock.json b/package-lock.json
index c34a6fd60..88b774b26 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,6 +17,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
+ "@radix-ui/react-popover": "^1.1.0",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
@@ -72,7 +73,6 @@
"react-quill": "^2.0.0",
"react-select": "^5.3.2",
"react-simple-code-editor": "^0.11.0",
- "react-tooltip": "^5.7.4",
"react-use": "^17.4.0",
"redis": "^4.4.0",
"styled-components": "^6.1.8",
@@ -6302,6 +6302,418 @@
}
}
},
+ "node_modules/@radix-ui/react-popover": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.0.tgz",
+ "integrity": "sha512-2wdgj6eKNVoFNFtYv2xwkzhIJPlJ5L2aV0eKTZHi5dUVrGy+MhgoV8IyyeFpkZQrwwFzbFlnWl1bwyjVBCNapQ==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-focus-guards": "1.1.0",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.0",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "aria-hidden": "^1.1.1",
+ "react-remove-scroll": "2.5.7"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA=="
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-arrow": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz",
+ "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-context": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz",
+ "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-escape-keydown": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz",
+ "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz",
+ "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-id": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-popper": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
+ "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==",
+ "dependencies": {
+ "@floating-ui/react-dom": "^2.0.0",
+ "@radix-ui/react-arrow": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0",
+ "@radix-ui/react-use-rect": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0",
+ "@radix-ui/rect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-portal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.0.tgz",
+ "integrity": "sha512-0tXZ5O6qAVvuN9SWP0X+zadHf9hzHiMf/vxOU+kXO+fbtS8lS57MXa6EmikDxk9s/Bmkk80+dcxgbvisIyeqxg==",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz",
+ "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-escape-keydown": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
+ "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-rect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
+ "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
+ "dependencies": {
+ "@radix-ui/rect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-size": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
+ "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/rect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
+ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/react-remove-scroll": {
+ "version": "2.5.7",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz",
+ "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.4",
+ "react-style-singleton": "^2.2.1",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.0",
+ "use-sidecar": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-popper": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz",
@@ -31118,19 +31530,6 @@
}
}
},
- "node_modules/react-tooltip": {
- "version": "5.15.0",
- "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.15.0.tgz",
- "integrity": "sha512-OiH870zteP4T5B/J7cUGz37aY8C0Cny/i1qcLXevL+wZlW09mfjdcQ6FKP9OMMsRlszRwieOqAPT9l8rWz+BtA==",
- "dependencies": {
- "@floating-ui/dom": "^1.0.0",
- "classnames": "^2.3.0"
- },
- "peerDependencies": {
- "react": ">=16.14.0",
- "react-dom": ">=16.14.0"
- }
- },
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
@@ -41990,6 +42389,202 @@
"react-remove-scroll": "2.5.5"
}
},
+ "@radix-ui/react-popover": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.0.tgz",
+ "integrity": "sha512-2wdgj6eKNVoFNFtYv2xwkzhIJPlJ5L2aV0eKTZHi5dUVrGy+MhgoV8IyyeFpkZQrwwFzbFlnWl1bwyjVBCNapQ==",
+ "requires": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-focus-guards": "1.1.0",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.0",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "aria-hidden": "^1.1.1",
+ "react-remove-scroll": "2.5.7"
+ },
+ "dependencies": {
+ "@radix-ui/primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA=="
+ },
+ "@radix-ui/react-arrow": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz",
+ "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==",
+ "requires": {
+ "@radix-ui/react-primitive": "2.0.0"
+ }
+ },
+ "@radix-ui/react-compose-refs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
+ "requires": {}
+ },
+ "@radix-ui/react-context": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
+ "requires": {}
+ },
+ "@radix-ui/react-dismissable-layer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz",
+ "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==",
+ "requires": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-escape-keydown": "1.1.0"
+ }
+ },
+ "@radix-ui/react-focus-guards": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz",
+ "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==",
+ "requires": {}
+ },
+ "@radix-ui/react-focus-scope": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz",
+ "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==",
+ "requires": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ }
+ },
+ "@radix-ui/react-id": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
+ "requires": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ }
+ },
+ "@radix-ui/react-popper": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
+ "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==",
+ "requires": {
+ "@floating-ui/react-dom": "^2.0.0",
+ "@radix-ui/react-arrow": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0",
+ "@radix-ui/react-use-rect": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0",
+ "@radix-ui/rect": "1.1.0"
+ }
+ },
+ "@radix-ui/react-portal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.0.tgz",
+ "integrity": "sha512-0tXZ5O6qAVvuN9SWP0X+zadHf9hzHiMf/vxOU+kXO+fbtS8lS57MXa6EmikDxk9s/Bmkk80+dcxgbvisIyeqxg==",
+ "requires": {
+ "@radix-ui/react-primitive": "2.0.0"
+ }
+ },
+ "@radix-ui/react-presence": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz",
+ "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==",
+ "requires": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ }
+ },
+ "@radix-ui/react-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
+ "requires": {
+ "@radix-ui/react-slot": "1.1.0"
+ }
+ },
+ "@radix-ui/react-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+ "requires": {
+ "@radix-ui/react-compose-refs": "1.1.0"
+ }
+ },
+ "@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "requires": {}
+ },
+ "@radix-ui/react-use-controllable-state": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
+ "requires": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ }
+ },
+ "@radix-ui/react-use-escape-keydown": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
+ "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
+ "requires": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ }
+ },
+ "@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "requires": {}
+ },
+ "@radix-ui/react-use-rect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
+ "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
+ "requires": {
+ "@radix-ui/rect": "1.1.0"
+ }
+ },
+ "@radix-ui/react-use-size": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
+ "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
+ "requires": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ }
+ },
+ "@radix-ui/rect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
+ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="
+ },
+ "react-remove-scroll": {
+ "version": "2.5.7",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz",
+ "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==",
+ "requires": {
+ "react-remove-scroll-bar": "^2.3.4",
+ "react-style-singleton": "^2.2.1",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.0",
+ "use-sidecar": "^1.1.2"
+ }
+ }
+ }
+ },
"@radix-ui/react-popper": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz",
@@ -60321,15 +60916,6 @@
"tslib": "^2.0.0"
}
},
- "react-tooltip": {
- "version": "5.15.0",
- "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.15.0.tgz",
- "integrity": "sha512-OiH870zteP4T5B/J7cUGz37aY8C0Cny/i1qcLXevL+wZlW09mfjdcQ6FKP9OMMsRlszRwieOqAPT9l8rWz+BtA==",
- "requires": {
- "@floating-ui/dom": "^1.0.0",
- "classnames": "^2.3.0"
- }
- },
"react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
diff --git a/package.json b/package.json
index 117b60815..904f89590 100644
--- a/package.json
+++ b/package.json
@@ -42,6 +42,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
+ "@radix-ui/react-popover": "^1.1.0",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
@@ -97,7 +98,6 @@
"react-quill": "^2.0.0",
"react-select": "^5.3.2",
"react-simple-code-editor": "^0.11.0",
- "react-tooltip": "^5.7.4",
"react-use": "^17.4.0",
"redis": "^4.4.0",
"styled-components": "^6.1.8",
diff --git a/src/__tests__/_/setupGlobals.ts b/src/__tests__/_/setupGlobals.ts
index 05cccad34..8f8aff59a 100644
--- a/src/__tests__/_/setupGlobals.ts
+++ b/src/__tests__/_/setupGlobals.ts
@@ -16,3 +16,14 @@ Object.defineProperty(window, "matchMedia", {
});
export {};
+
+window.ResizeObserver =
+ window.ResizeObserver ||
+ jest.fn().mockImplementation(() => ({
+ disconnect: jest.fn(),
+ observe: jest.fn(),
+ unobserve: jest.fn(),
+ }));
+
+const scrollIntoViewMock = jest.fn();
+window.HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;
diff --git a/src/__tests__/account/logout.spec.tsx b/src/__tests__/account/logout.spec.tsx
index d0f5e68fc..efab03982 100644
--- a/src/__tests__/account/logout.spec.tsx
+++ b/src/__tests__/account/logout.spec.tsx
@@ -29,7 +29,7 @@ describe("pages/account/logout", () => {
);
await userEvent.click(
- await screen.findByRole("button", { name: "Log Out" })
+ await screen.findByRole("option", { name: "Log Out" })
);
await waitFor(() => {
diff --git a/src/components/app/button/soft.tsx b/src/components/app/button/soft.tsx
index e9650b220..feae1d4ac 100644
--- a/src/components/app/button/soft.tsx
+++ b/src/components/app/button/soft.tsx
@@ -34,7 +34,9 @@ export function SoftButton({
) : (
- {labelString}
+
+ {labelString}
+
);
diff --git a/src/components/app/button/types.d.ts b/src/components/app/button/types.d.ts
index f19e089c9..e92c3018f 100644
--- a/src/components/app/button/types.d.ts
+++ b/src/components/app/button/types.d.ts
@@ -23,4 +23,6 @@ export interface IGroupActionButton extends IActionButton {
export interface IMenuActionItem extends IGroupActionButton {
subtle?: boolean;
destructive?: boolean;
+ active?: boolean;
+ secondaryAction?: () => void;
}
diff --git a/src/components/app/content-layout/index.tsx b/src/components/app/content-layout/index.tsx
index 2764097c0..aeeb64ba1 100644
--- a/src/components/app/content-layout/index.tsx
+++ b/src/components/app/content-layout/index.tsx
@@ -1,20 +1,9 @@
import { ReactElement, ReactNode } from "react";
-import styled from "styled-components";
-import { BREAKPOINTS } from "@/frontend/design-system/constants";
interface IProps {
children: ReactNode;
}
-export const GridRoot = styled.div`
- display: grid;
- grid-gap: 16px;
- grid-template-columns: 2fr 8fr;
- @media (max-width: ${BREAKPOINTS.md}) {
- grid-template-columns: 1fr;
- }
-`;
-
type TContentLayout = ((params: IProps) => ReactElement) & {
Left: (params: IProps) => ReactElement;
Right: (params: IProps) => ReactElement;
@@ -23,16 +12,20 @@ type TContentLayout = ((params: IProps) => ReactElement) & {
// eslint-disable-next-line react/function-component-definition
export const ContentLayout: TContentLayout = ({ children }: IProps) => {
- return {children};
+ return (
+
+ {children}
+
+ );
};
ContentLayout.Left = function SectionLeft({ children }: IProps) {
- return {children}
;
+ return {children}
;
};
ContentLayout.Right = function SectionRight({ children }: IProps) {
return (
-
+
{children}
);
diff --git a/src/components/app/drop-drop-menu/index.tsx b/src/components/app/drop-drop-menu/index.tsx
index cc0811d70..11df3435b 100644
--- a/src/components/app/drop-drop-menu/index.tsx
+++ b/src/components/app/drop-drop-menu/index.tsx
@@ -1,6 +1,5 @@
import { useState, useEffect, useMemo } from "react";
import { ChevronDown, MoreVertical } from "react-feather";
-
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
@@ -11,12 +10,14 @@ import { useToggle } from "@/frontend/hooks/state/useToggleState";
import { MenuSection } from "@/components/app/menu-section";
import { IMenuActionItem } from "../button/types";
import { SoftButton } from "../button/soft";
+import { cn } from "@/lib/utils";
export interface IProps {
menuItems: IMenuActionItem[];
ariaLabel: string;
disabled?: boolean;
ellipsis?: true;
+ contentClassName?: string;
className?: string;
}
@@ -24,18 +25,28 @@ export function DropDownMenu({
menuItems: menuItems$1,
ellipsis,
ariaLabel,
+ contentClassName,
className,
}: IProps) {
- const menuItems = useMemo(() => {
- return [...menuItems$1].sort((a, b) => {
- return (a.order || 0) - (b.order || 0);
- });
- }, [menuItems$1]);
-
const [currentMenuItem, setCurrentMenuItem] = useState
(
- menuItems?.[0]
+ menuItems$1[0]
);
+ const menuItems: IMenuActionItem[] = useMemo(() => {
+ return [...menuItems$1]
+ .sort((a, b) => {
+ return (a.order || 0) - (b.order || 0);
+ })
+ .map((menuItem) => {
+ return {
+ ...menuItem,
+ secondaryAction: () => {
+ setCurrentMenuItem(menuItem);
+ },
+ };
+ });
+ }, [menuItems$1]);
+
useEffect(() => {
setCurrentMenuItem(menuItems[0]);
}, [JSON.stringify(menuItems)]);
@@ -48,12 +59,6 @@ export function DropDownMenu({
return ;
}
- // TODO
- // const onMenuItemClick = (menuIndex: number) => {
- // const menuItem = menuItems[menuIndex];
- // setCurrentMenuItem(menuItem);
- // };
-
const { isOn: isOpen, toggle } = useToggle(false);
return (
@@ -81,8 +86,11 @@ export function DropDownMenu({
)}
-
-
+
+
diff --git a/src/components/app/form/input/Stories.tsx b/src/components/app/form/input/Stories.tsx
index ba434e950..2dea3dded 100644
--- a/src/components/app/form/input/Stories.tsx
+++ b/src/components/app/form/input/Stories.tsx
@@ -9,7 +9,6 @@ import { TestProviders } from "__tests__/_/Provider";
import { FormInput } from "./text";
import { FormNumberInput } from "./number";
import { FormRichTextArea } from "../../../../frontend/design-system/components/Form/RichText";
-import { FormDateInput } from "../../../../frontend/design-system/components/Form/Date";
import { FormTextArea } from "./textarea";
import {
FormMultiSelect,
@@ -24,6 +23,7 @@ import { DELETE_BUTTON_PROPS } from "../../button/constants";
import { FormPasswordInput } from "./password";
import { FormButton } from "../../button/form";
import { ActionButtons } from "../../button/action";
+import { FormDateInput } from "./date";
function DemoForm() {
return (
diff --git a/src/components/app/form/input/date.tsx b/src/components/app/form/input/date.tsx
new file mode 100644
index 000000000..5e774acbc
--- /dev/null
+++ b/src/components/app/form/input/date.tsx
@@ -0,0 +1,138 @@
+import { FieldMetaState } from "react-final-form";
+import * as React from "react";
+import { format } from "date-fns";
+import { Calendar as CalendarIcon } from "react-feather";
+import { Trans, msg } from "@lingui/macro";
+import {
+ LabelAndError,
+ generateClassNames,
+ generateFormArias,
+} from "@/components/app/form/input/label-and-error";
+import { ISharedFormInput } from "@/components/app/form/input/types";
+import { cn } from "@/lib/utils";
+import { Button } from "@/components/ui/button";
+import { Calendar } from "@/components/ui/calendar";
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@/components/ui/popover";
+import { SoftButton } from "@/components/app/button/soft";
+import { useToggle } from "@/frontend/hooks/state/useToggleState";
+
+interface IFormDateInput extends ISharedFormInput {
+ minDate?: Date;
+ maxDate?: Date;
+}
+
+interface IProps {
+ minDate?: Date;
+ maxDate?: Date;
+ onChange: (value: Date | null) => void;
+ value: Date;
+ id?: string;
+ disabled?: boolean;
+ className?: string;
+ meta?: FieldMetaState;
+}
+
+export const dateWithoutTimezone = (date: Date) => {
+ const tzoffset = date.getTimezoneOffset() * 60000; // offset in milliseconds
+ const withoutTimezone = new Date(date.valueOf() - tzoffset)
+ .toISOString()
+ .slice(0, -1);
+ return new Date(withoutTimezone);
+};
+
+export function ControlledFormDateInput({
+ minDate,
+ maxDate,
+ onChange,
+ value,
+ id,
+ disabled,
+ className,
+ meta,
+}: IProps) {
+ const isOpen = useToggle();
+
+ const onChangeRemoveTimeZone = (inputValue: Date | null) => {
+ onChange(dateWithoutTimezone(inputValue));
+ };
+
+ return (
+
+
+
+
+
+ onChange(null)}
+ label={msg`Clear`}
+ className="w-full mt-3"
+ size="sm"
+ disabled={!value}
+ />
+ }
+ />
+
+
+ );
+}
+// TODO fix date
+export function FormDateInput(formInput: IFormDateInput) {
+ const { input, disabled, meta, minDate, maxDate } = formInput;
+ let { value } = input;
+ if (value && typeof value === "string") {
+ value = new Date(value);
+ input.onChange(value);
+ }
+ return (
+
+
+
+ );
+}
diff --git a/src/components/app/form/schema/_RenderFormInput.tsx b/src/components/app/form/schema/_RenderFormInput.tsx
index ec7569cff..8bd45eee0 100644
--- a/src/components/app/form/schema/_RenderFormInput.tsx
+++ b/src/components/app/form/schema/_RenderFormInput.tsx
@@ -1,5 +1,4 @@
import { FormSelect } from "frontend/design-system/components/Form/Select";
-import { FormDateInput } from "frontend/design-system/components/Form/Date";
import { AsyncFormSelect } from "frontend/design-system/components/Form/Select/Async";
import { FormCodeEditor } from "frontend/design-system/components/Form/CodeEditor";
import { FormFileInput } from "frontend/design-system/components/Form/File";
@@ -13,6 +12,7 @@ import { FormSelectButton } from "../input/select-button";
import { FormPasswordInput } from "../input/password";
import { FormTextArea } from "../input/textarea";
import { FormSwitch } from "../input/switch";
+import { FormDateInput } from "../input/date";
export function RenderFormInput(props: IRenderFormInputProps) {
const {
diff --git a/src/components/app/form/schema/form-grid.tsx b/src/components/app/form/schema/form-grid.tsx
index a1c71fb21..5237b44e1 100644
--- a/src/components/app/form/schema/form-grid.tsx
+++ b/src/components/app/form/schema/form-grid.tsx
@@ -1,14 +1,8 @@
-import { gridItem, gridRoot } from "frontend/design-system/constants/grid";
+import { gridItem } from "frontend/design-system/constants/grid";
import { ReactNode } from "react";
import { GridSpanSizes } from "shared/types/ui";
import styled from "styled-components";
-const Root = styled.div`
- ${gridRoot}
- grid-auto-rows: auto;
- align-items: center;
-`;
-
// TOOD fix
const Container = styled.div`
// container-type: inline-size;
@@ -17,7 +11,7 @@ const Container = styled.div`
export const FormGrid = {
Root: ({ children }: { children: ReactNode }) => (
- {children}
+ {children}
),
Item: styled.div<{
diff --git a/src/components/app/menu-section.tsx b/src/components/app/menu-section.tsx
index 78f5b17fa..52718696d 100644
--- a/src/components/app/menu-section.tsx
+++ b/src/components/app/menu-section.tsx
@@ -2,6 +2,7 @@ import { useLingui } from "@lingui/react";
import Link from "next/link";
import { Loader } from "react-feather";
import { VariantProps } from "class-variance-authority";
+import { useRouter } from "next/router";
import { Card } from "@/components/ui/card";
import { CommandItem, Command, CommandList } from "@/components/ui/command";
import { cn } from "@/lib/utils";
@@ -12,16 +13,14 @@ import { SystemIcon } from "./system-icons";
export interface IProps {
menuItems: IMenuActionItem[];
- currentMenuItem?: string;
size?: VariantProps["size"];
}
-export function MenuSection({
- menuItems,
- currentMenuItem,
- size = "lg",
-}: IProps) {
+export function MenuSection({ menuItems, size = "lg" }: IProps) {
const { _ } = useLingui();
+ const router = useRouter();
+
+ const currentPath = router.asPath.split("?")[0];
const confirmAlert = useConfirmAlert();
@@ -41,7 +40,9 @@ export function MenuSection({
({
label,
action,
+ active,
systemIcon,
+ secondaryAction,
subtle,
id,
variant = "ghost",
@@ -50,9 +51,9 @@ export function MenuSection({
isMakingRequest,
shouldConfirmAlert,
}) => {
- const active = (
- typeof action === "string" ? action : ""
- ).includes(currentMenuItem);
+ const isActive =
+ active ||
+ (typeof action === "string" ? action : "") === currentPath;
const content = (
<>
@@ -61,7 +62,7 @@ export function MenuSection({
) : (
{
+ secondaryAction?.();
if (shouldConfirmAlert) {
return confirmAlert({
title: shouldConfirmAlert,
diff --git a/src/components/app/system-icons.tsx b/src/components/app/system-icons.tsx
index 8a5400b28..e9c688035 100644
--- a/src/components/app/system-icons.tsx
+++ b/src/components/app/system-icons.tsx
@@ -14,6 +14,10 @@ export function SystemIcon({ icon, label, strokeWidth, className }: IProps) {
return null;
}
+ if (icon === "none") {
+ return null;
+ }
+
const iconSvg = systemIconToSVG(icon, strokeWidth);
return (
{new Date(filterValue?.value || "").toString() !== "Invalid Date" ? (
<>
+ {/* TODO date not changing */}
{
setFilter({
diff --git a/src/components/app/table/filters/_FilterWrapper.tsx b/src/components/app/table/filters/_FilterWrapper.tsx
index 7f697010b..4e31b0de9 100644
--- a/src/components/app/table/filters/_FilterWrapper.tsx
+++ b/src/components/app/table/filters/_FilterWrapper.tsx
@@ -40,36 +40,38 @@ export function FilterWrapper({
const { systemIcon, label: filterLabel } = FILTER_TYPE_CONFIG[filterType];
return (
-
- e.stopPropagation()}>
+
+
+
+ }
+ >
+
+
{children}
+
{
+ clearFilter(undefined);
+ }}
+ size="sm"
+ systemIcon="Close"
+ label={msg`Reset`}
/>
- }
- >
-
-
{children}
-
{
- clearFilter(undefined);
- }}
- size="sm"
- systemIcon="Close"
- label={msg`Reset`}
- />
-
-
+
+
);
}
diff --git a/src/components/app/table/filters/index.tsx b/src/components/app/table/filters/index.tsx
index ababed3ea..42a4b8bc0 100644
--- a/src/components/app/table/filters/index.tsx
+++ b/src/components/app/table/filters/index.tsx
@@ -69,12 +69,14 @@ export function TableFilter({
columnLabel={view}
filterType={type._type}
>
- {operators.length > 1 && (
-
+ {operators.length > 0 && (
+
+
+
)}
;
-function Calendar({
- className,
- classNames,
- showOutsideDays = true,
- ...props
-}: CalendarProps) {
+function Calendar({ className, classNames, ...props }: CalendarProps) {
return (
.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md"
: "[&:has([aria-selected])]:rounded-md"
),
day: cn(
buttonVariants({ variant: "ghost" }),
- "h-8 w-8 p-0 font-normal aria-selected:opacity-100"
+ "h-8 w-8 p-0 font-normal hover:bg-primary-shade-light hover:text-primary hover:shadow aria-selected:opacity-100"
),
day_range_start: "day-range-start",
day_range_end: "day-range-end",
day_selected:
- "bg-primary text-primary-text hover:bg-primary hover:text-primary-text focus:bg-primary focus:text-primary",
- day_today: "bg-primary text-primary-text",
+ "bg-primary text-primary-text hover:bg-primary hover:text-primary-text focus:bg-primary focus:text-primary-text",
+ day_today: "shadow-lg bg-hover",
day_outside:
- "day-outside text-muted opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted aria-selected:opacity-30",
+ "day-outside text-muted opacity-50 aria-selected:bg-primary/50 aria-selected:text-muted aria-selected:opacity-30",
day_disabled: "text-muted opacity-50",
day_range_middle:
"aria-selected:bg-primary aria-selected:text-primary-text",
@@ -69,47 +65,3 @@ function Calendar({
Calendar.displayName = "Calendar";
export { Calendar };
-
-// "use client"
-
-// import * as React from "react"
-// import { format } from "date-fns"
-// import { Calendar as CalendarIcon } from "lucide-react"
-
-// import { cn } from "@/lib/utils"
-// import { Button } from "@/components/ui/button"
-// import { Calendar } from "@/components/ui/calendar"
-// import {
-// Popover,
-// PopoverContent,
-// PopoverTrigger,
-// } from "@/components/ui/popover"
-
-// export function DatePickerDemo() {
-// const [date, setDate] = React.useState()
-
-// return (
-//
-//
-//
-//
-//
-//
-//
-//
-// )
-// }
diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx
new file mode 100644
index 000000000..a1ca4e817
--- /dev/null
+++ b/src/components/ui/popover.tsx
@@ -0,0 +1,32 @@
+/* eslint-disable react/prop-types */
+import * as React from "react";
+import * as PopoverPrimitive from "@radix-ui/react-popover";
+
+import { cn } from "@/lib/utils";
+
+const Popover = PopoverPrimitive.Root;
+
+const PopoverTrigger = PopoverPrimitive.Trigger;
+
+const PopoverAnchor = PopoverPrimitive.Anchor;
+
+const PopoverContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
+
+
+
+));
+PopoverContent.displayName = PopoverPrimitive.Content.displayName;
+
+export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
diff --git a/src/frontend/design-system/components/Form/CodeEditor/index.tsx b/src/frontend/design-system/components/Form/CodeEditor/index.tsx
index 6ad8bd511..5373b7dce 100644
--- a/src/frontend/design-system/components/Form/CodeEditor/index.tsx
+++ b/src/frontend/design-system/components/Form/CodeEditor/index.tsx
@@ -13,14 +13,13 @@ import {
generateClassNames,
} from "@/components/app/form/input/label-and-error";
import { PrismTokenStyles } from "@/components/app/render-code/styles";
+import { cn } from "@/lib/utils";
interface IFormCodeEditor extends ISharedFormInput {
language?: "javascript";
}
const Wrapper = styled.div`
- border: 1px solid ${USE_ROOT_COLOR("border-color")};
-
&.invalid {
border-color: ${SYSTEM_COLORS.danger} !important;
}
@@ -57,7 +56,13 @@ export function FormCodeEditor(formInput: IFormCodeEditor) {
return (
-
+
void;
- value: Date;
- id?: string;
- isClearable?: boolean;
- disabled?: boolean;
- className?: string;
- meta?: FieldMetaState;
-}
-
-export function ControlledFormDateInput({
- minDate,
- maxDate,
- onChange,
- value,
- isClearable,
- id,
- disabled,
- className,
- meta,
-}: IProps) {
- return (
-
- {
- onChange(value$1);
- }}
- {...generateFormArias(meta)}
- showTwoColumnMonthYearPicker
- isClearable={isClearable}
- selected={value}
- id={id}
- minDate={minDate}
- maxDate={maxDate}
- className={className}
- disabled={disabled}
- />
-
- );
-}
-
-export function FormDateInput(formInput: IFormDateInput) {
- const { input, disabled, meta, required, minDate, maxDate } = formInput;
- let { value } = input;
- if (value && typeof value === "string") {
- value = new Date(value);
- input.onChange(value);
- }
- return (
-
- {
- input.onChange(value$1);
- }}
- isClearable={!required}
- value={value}
- id={input.name}
- minDate={minDate}
- maxDate={maxDate}
- meta={meta}
- disabled={disabled}
- />
-
- );
-}
diff --git a/src/frontend/design-system/components/IntermediateCheckBox/index.tsx b/src/frontend/design-system/components/IntermediateCheckBox/index.tsx
index 1559843fb..96271ee18 100644
--- a/src/frontend/design-system/components/IntermediateCheckBox/index.tsx
+++ b/src/frontend/design-system/components/IntermediateCheckBox/index.tsx
@@ -1,28 +1,10 @@
-import styled from "styled-components";
-
import {
CheckSquare,
Icon as IconType,
MinusSquare,
Square,
} from "react-feather";
-import { USE_ROOT_COLOR } from "frontend/design-system/theme/root";
-
-const IconWrapper = styled.span<{ $disabled?: boolean }>`
- align-self: center;
- width: 16px;
- height: 16px;
- border-radius: 2px;
- cursor: ${(props) => (props.$disabled ? "not-allowed" : "pointer")};
- color: ${(props) =>
- props.$disabled
- ? USE_ROOT_COLOR("muted-text")
- : USE_ROOT_COLOR("primary-color")};
-`;
-
-const Icon = styled.i`
- height: 18px;
-`;
+import { cn } from "@/lib/utils";
type CheckboxState = "checked" | "unchecked" | "partial";
@@ -35,11 +17,11 @@ export interface IProps {
const IconPerState: Record<
IProps["state"],
- { IconCmp: IconType; label: boolean | "mixed" }
+ { IconCmp: IconType; ariaChecked: boolean | "mixed" }
> = {
- checked: { IconCmp: CheckSquare, label: true },
- partial: { IconCmp: MinusSquare, label: "mixed" },
- unchecked: { IconCmp: Square, label: false },
+ checked: { IconCmp: CheckSquare, ariaChecked: true },
+ partial: { IconCmp: MinusSquare, ariaChecked: "mixed" },
+ unchecked: { IconCmp: Square, ariaChecked: false },
};
export function IntermediateCheckBox({
@@ -48,20 +30,26 @@ export function IntermediateCheckBox({
disabled,
label,
}: IProps) {
+ const { IconCmp, ariaChecked } = IconPerState[state];
return (
- {
e.stopPropagation();
onClick(state);
}}
>
-
-
+
+
);
}
diff --git a/src/frontend/design-system/constants/grid.ts b/src/frontend/design-system/constants/grid.ts
index 164c1a652..9505f9d97 100644
--- a/src/frontend/design-system/constants/grid.ts
+++ b/src/frontend/design-system/constants/grid.ts
@@ -16,15 +16,6 @@ export const mapToUnitOptions = (values: number[]) => {
export const gridHeightToPx = (unit: GridHeightSizes) => +unit * 100;
-export const gridRoot = css`
- display: grid;
- column-gap: 16px;
- grid-template-columns: repeat(12, 1fr);
- @container (width < ${BREAKPOINTS.md}) {
- grid-template-columns: 1fr;
- }
-`;
-
export const gridItem = css<{
$span: GridSpanSizes;
}>`
diff --git a/src/frontend/views/Dashboard/List/_BaseDashboard.tsx b/src/frontend/views/Dashboard/List/_BaseDashboard.tsx
index 0f9b0b1ea..6820ea43d 100644
--- a/src/frontend/views/Dashboard/List/_BaseDashboard.tsx
+++ b/src/frontend/views/Dashboard/List/_BaseDashboard.tsx
@@ -7,14 +7,9 @@ import { useDomainMessages } from "frontend/lib/crud-config";
import { LANG_DOMAINS } from "frontend/lib/crud-config/lang-domains";
import { ViewStateMachine } from "@/components/app/view-state-machine";
import { useDashboardWidgets } from "../dashboard.store";
-import { dashboardGridRoot } from "../styles";
import { DashboardSkeleton } from "../Skeleton";
import { DashboardWidget } from "../Widget";
-const Root = styled.div`
- ${dashboardGridRoot};
-`;
-
const Container = styled.div`
container-type: inline-size;
`;
@@ -53,11 +48,11 @@ export function BaseDashboard({ dashboardId, manageLink }: IProps) {
loader={}
>
-
+
{widgets.data.map((config) => (
))}
-
+
diff --git a/src/frontend/views/Dashboard/Manage/_BaseManageDashboard.tsx b/src/frontend/views/Dashboard/Manage/_BaseManageDashboard.tsx
index a19e7591b..636d5003f 100644
--- a/src/frontend/views/Dashboard/Manage/_BaseManageDashboard.tsx
+++ b/src/frontend/views/Dashboard/Manage/_BaseManageDashboard.tsx
@@ -16,15 +16,11 @@ import {
useDashboardWidgets,
useDeleteDashboardWidgetMutation,
} from "../dashboard.store";
-import { dashboardGridRoot } from "../styles";
import { DashboardSkeleton } from "../Skeleton";
import { DashboardWidget } from "../Widget";
const Root = styled.div`
container-type: inline-size;
- .list {
- ${dashboardGridRoot};
- }
`;
interface IProps {
@@ -85,7 +81,7 @@ export function BaseManageDashboard({ dashboardId, doneLink, title }: IProps) {
diff --git a/src/frontend/views/Dashboard/Skeleton.tsx b/src/frontend/views/Dashboard/Skeleton.tsx
index f941ace98..1e6200310 100644
--- a/src/frontend/views/Dashboard/Skeleton.tsx
+++ b/src/frontend/views/Dashboard/Skeleton.tsx
@@ -1,28 +1,23 @@
-import styled from "styled-components";
import { TableSkeleton } from "@/components/app/skeleton/table";
-import { dashboardGridRoot, WidgetRoot } from "./styles";
+import { WidgetRoot } from "./styles";
import { Card } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
-const Root = styled.div`
- ${dashboardGridRoot};
-`;
-
export function DashboardSkeleton() {
return (
-
+
{[1, 2, 3, 4, 5, 6, 7, 8].map((i) => (
))}
-
-
+
+
);
}
diff --git a/src/frontend/views/Dashboard/Widget/_components/WidgetHeader/index.tsx b/src/frontend/views/Dashboard/Widget/_components/WidgetHeader/index.tsx
index a2017bd67..39bbb697f 100644
--- a/src/frontend/views/Dashboard/Widget/_components/WidgetHeader/index.tsx
+++ b/src/frontend/views/Dashboard/Widget/_components/WidgetHeader/index.tsx
@@ -35,7 +35,7 @@ export function WidgetHeader({
return (
-
+
{setting && (
@@ -67,10 +67,11 @@ export function WidgetHeader({
{hasRelativeDate && !isPreview && (
({
id: value,
label,
- systemIcon: null,
+ systemIcon: "Filter",
action: () => {
setWidgetRelativeDate({
widgetId,
diff --git a/src/frontend/views/Dashboard/styles.ts b/src/frontend/views/Dashboard/styles.ts
index 89ec1294c..291233b79 100644
--- a/src/frontend/views/Dashboard/styles.ts
+++ b/src/frontend/views/Dashboard/styles.ts
@@ -1,13 +1,6 @@
-import { gridItem, gridRoot } from "frontend/design-system/constants/grid";
+import { gridItem } from "frontend/design-system/constants/grid";
import { GridSpanSizes } from "shared/types/ui";
-import styled, { css } from "styled-components";
-
-export const dashboardGridRoot = css`
- ${gridRoot}
- user-select: none;
- row-gap: 16px;
- grid-auto-rows: minmax(110px, auto);
-`;
+import styled from "styled-components";
export const WidgetRoot = styled.div<{
$span: GridSpanSizes;
diff --git a/src/frontend/views/account/_Base.tsx b/src/frontend/views/account/_Base.tsx
index 3b451fab7..13e5c6b06 100644
--- a/src/frontend/views/account/_Base.tsx
+++ b/src/frontend/views/account/_Base.tsx
@@ -1,4 +1,3 @@
-import { useRouter } from "next/router";
import { ReactNode } from "react";
import { AppLayout } from "frontend/_layouts/app";
import { NAVIGATION_LINKS } from "frontend/lib/routing/links";
@@ -14,7 +13,6 @@ interface IProps {
}
export function BaseAccountLayout({ children }: IProps) {
- const router = useRouter();
const portalAccountMenu = usePortalAccountMenu();
const baseMenuItems: IMenuActionItem[] = [
@@ -55,10 +53,7 @@ export function BaseAccountLayout({ children }: IProps) {
-
+
{children}
diff --git a/src/frontend/views/data/Details/_Layout.tsx b/src/frontend/views/data/Details/_Layout.tsx
index 4bcb758d9..89b8a96fa 100644
--- a/src/frontend/views/data/Details/_Layout.tsx
+++ b/src/frontend/views/data/Details/_Layout.tsx
@@ -10,14 +10,15 @@ import { NAVIGATION_LINKS } from "frontend/lib/routing/links";
import { useEntityDictionPlurals } from "frontend/hooks/entity/entity.queries";
import { DataStates } from "frontend/lib/data/types";
import { ContentLayout } from "@/components/app/content-layout";
-import { ListManager } from "@/components/app/list-manager";
-import { IListMangerItemProps } from "@/components/app/list-manager/list-manager-item";
-
import { useEntityViewStateMachine } from "../hooks/useEntityViewStateMachine";
import { getEntitiesRelationsCount } from "./utils";
import { useEntityActionMenuItems } from "../../entity/constants";
-import { Card, CardContent } from "@/components/ui/card";
import { IMenuActionItem } from "@/components/app/button/types";
+import { MenuSection } from "@/components/app/menu-section";
+import { ViewStateMachine } from "@/components/app/view-state-machine";
+import { ListSkeleton } from "@/components/app/skeleton/list";
+import { fakeMessageDescriptor } from "@/translations/fake";
+import { Card, CardContent } from "@/components/ui/card";
export const DETAILS_LAYOUT_KEY = "___DETAILS_KEY__";
@@ -82,17 +83,6 @@ export function DetailsLayout({
...relatedEntities,
];
- const relatedEntitiesLabelMap = Object.fromEntries(
- listItems.map((relatedEntity) => [
- relatedEntity.name,
- relatedEntity.referencelabel ||
- getEntitiesDictionPlurals(
- relatedEntity.name,
- relatedEntitiesMap[relatedEntity.name].type === "toOne"
- ),
- ])
- );
-
const { isLoading, error } = referenceFields;
const viewState = useEntityViewStateMachine({
@@ -106,52 +96,63 @@ export function DetailsLayout({
-
-
- relatedEntitiesLabelMap[name]}
- render={(menuItem) => {
- if (menuItem.name === DETAILS_LAYOUT_KEY) {
- const props: IListMangerItemProps = {
- label: menuItem.label,
- active: menuKey === DETAILS_LAYOUT_KEY,
- action: NAVIGATION_LINKS.ENTITY.DETAILS(entity, entityId),
- };
- return props;
- }
- const entityType =
- relatedEntitiesMap[menuItem.name]?.type || "toOne";
- const entityCount = getEntitiesRelationsCount(
- entityType,
- relatedEntitiesCounts.data[menuItem.name]
+
+
+
+
+
+ }
+ >
+ {
+ const label =
+ menuItem.referencelabel ||
+ getEntitiesDictionPlurals(
+ menuItem.name,
+ relatedEntitiesMap[menuItem.name].type === "toOne"
);
-
- const props: IListMangerItemProps = {
- label: `${menuItem.label} ${entityCount}`,
- active: menuKey === menuItem.name,
- action: NAVIGATION_LINKS.ENTITY.RELATION_TABLE(
- entity,
- entityId,
- menuItem.name,
- entityType === "toOne" ? "one" : "many"
- ),
+ if (menuItem.name === DETAILS_LAYOUT_KEY) {
+ const props: IMenuActionItem = {
+ id: "details",
+ systemIcon: "none",
+ label: fakeMessageDescriptor(label),
+ active: menuKey === DETAILS_LAYOUT_KEY,
+ action: NAVIGATION_LINKS.ENTITY.DETAILS(entity, entityId),
};
-
return props;
- }}
- />
-
-
+ }
+ const entityType =
+ relatedEntitiesMap[menuItem.name]?.type || "toOne";
+ const entityCount = getEntitiesRelationsCount(
+ entityType,
+ relatedEntitiesCounts.data[menuItem.name]
+ );
+
+ const props: IMenuActionItem = {
+ label: fakeMessageDescriptor(`${label} ${entityCount}`),
+ id: menuItem.name,
+ systemIcon: "none",
+ active: menuKey === menuItem.name,
+ action: NAVIGATION_LINKS.ENTITY.RELATION_TABLE(
+ entity,
+ entityId,
+ menuItem.name,
+ entityType === "toOne" ? "one" : "many"
+ ),
+ };
+
+ return props;
+ })}
+ />
+
{children}
diff --git a/src/frontend/views/data/Table/portal/main.tsx b/src/frontend/views/data/Table/portal/main.tsx
index f0547073d..69377017e 100644
--- a/src/frontend/views/data/Table/portal/main.tsx
+++ b/src/frontend/views/data/Table/portal/main.tsx
@@ -22,12 +22,12 @@ export const useSyncPaginatedDataState = () => {};
export function TableViewComponent({ entity }: { entity: string }) {
noop(entity);
- return ;
+ return null;
}
export function TableTopComponent({ entity }: { entity: string }) {
noop(entity);
- return ;
+ return null;
}
export const usePortalTableColumns = (entity: string) => {
diff --git a/src/frontend/views/entity/_Base.tsx b/src/frontend/views/entity/_Base.tsx
index 4e63c8a66..97792c5b0 100644
--- a/src/frontend/views/entity/_Base.tsx
+++ b/src/frontend/views/entity/_Base.tsx
@@ -1,5 +1,4 @@
import { useNavigationStack } from "frontend/lib/routing/useNavigationStack";
-import { useRouter } from "next/router";
import { ReactNode } from "react";
import { useEntitySlug } from "frontend/hooks/entity/entity.config";
import { NAVIGATION_LINKS } from "frontend/lib/routing/links";
@@ -86,7 +85,6 @@ interface IProps {
export function BaseEntitySettingsLayout({ children, actionItems }: IProps) {
const entity = useEntitySlug();
const { canGoBack, goBack } = useNavigationStack();
- const router = useRouter();
const menuItems = useMutateBaseEntitySettingsMenu(
entity,
@@ -108,10 +106,7 @@ export function BaseEntitySettingsLayout({ children, actionItems }: IProps) {
)}
-
+
{children}
diff --git a/src/frontend/views/integrations/_Base.tsx b/src/frontend/views/integrations/_Base.tsx
index c218e2749..52dd1fe8b 100644
--- a/src/frontend/views/integrations/_Base.tsx
+++ b/src/frontend/views/integrations/_Base.tsx
@@ -1,5 +1,4 @@
import { useRouteParam } from "frontend/lib/routing/useRouteParam";
-import { useRouter } from "next/router";
import { ReactNode } from "react";
import { AppLayout } from "frontend/_layouts/app";
import { NAVIGATION_LINKS } from "frontend/lib/routing/links";
@@ -13,6 +12,9 @@ import {
} from "./actions/actions.store";
import { fakeMessageDescriptor } from "@/translations/fake";
import { MenuSection } from "@/components/app/menu-section";
+import { ListSkeleton } from "@/components/app/skeleton/list";
+import { ViewStateMachine } from "@/components/app/view-state-machine";
+import { Card, CardContent } from "@/components/ui/card";
interface IProps {
children: ReactNode;
@@ -28,26 +30,35 @@ export function BaseActionsLayout({ children }: IProps) {
const integrationsList = useIntegrationsList();
const activeIntegrations = useActiveIntegrations();
- const router = useRouter();
-
return (
- {
- const isActive = activeIntegrations.data.includes(menuitem.key);
- return {
- id: menuitem.key,
- action: NAVIGATION_LINKS.INTEGRATIONS.ACTIONS(menuitem.key),
- label: fakeMessageDescriptor(menuitem.title),
- subtle: !isActive,
- active: menuitem.key === currentKey,
- systemIcon: isActive ? "Zap" : "ZapOff",
- };
- })}
- currentMenuItem={router.asPath.split("?")[0]}
- />
+
+
+
+
+
+ }
+ >
+ {
+ const isActive = activeIntegrations.data.includes(menuitem.key);
+ return {
+ id: menuitem.key,
+ action: NAVIGATION_LINKS.INTEGRATIONS.ACTIONS(menuitem.key),
+ label: fakeMessageDescriptor(menuitem.title),
+ subtle: !isActive,
+ active: menuitem.key === currentKey,
+ systemIcon: isActive ? "Zap" : "ZapOff",
+ };
+ })}
+ />
+
{children}
diff --git a/src/frontend/views/settings/_Base.tsx b/src/frontend/views/settings/_Base.tsx
index da690afc8..75ea73927 100644
--- a/src/frontend/views/settings/_Base.tsx
+++ b/src/frontend/views/settings/_Base.tsx
@@ -1,6 +1,4 @@
-import { useRouter } from "next/router";
import { ReactNode } from "react";
-
import { AppLayout } from "frontend/_layouts/app";
import { NAVIGATION_LINKS } from "frontend/lib/routing/links";
import { msg } from "@lingui/macro";
@@ -66,16 +64,12 @@ const baseMenuItems: IMenuActionItem[] = [
];
export function BaseSettingsLayout({ children }: IProps) {
- const router = useRouter();
const menuItems = useMutateBaseSettingsMenu(baseMenuItems);
return (
-
+
{children}
diff --git a/src/shared/constants/Icons.tsx b/src/shared/constants/Icons.tsx
index 1a63b0e9c..c36adb4f0 100644
--- a/src/shared/constants/Icons.tsx
+++ b/src/shared/constants/Icons.tsx
@@ -92,11 +92,11 @@ export const SystemIcons = {
Sliders: ``,
};
-export type SystemIconsKeys = keyof typeof SystemIcons;
+export type SystemIconsKeys = keyof typeof SystemIcons | "none";
export const SystemIconsList = typescriptSafeObjectDotKeys(SystemIcons).sort(
(a, b) => a.localeCompare(b)
-);
+) as unknown as SystemIconsKeys[];
export const systemIconToSVG = (icon: string, strokeWidth = 2) => {
let iconPath = SystemIcons[icon];
diff --git a/src/styles/globals.css b/src/styles/globals.css
index b37382c65..406977885 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -66,4 +66,10 @@
@apply focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary;
@apply disabled:cursor-not-allowed disabled:bg-soft disabled:opacity-70;
}
+ .grid-root {
+ @apply grid gap-4 grid-cols-1 md:grid-cols-12;
+ }
+ .dashboard-grid-root {
+ @apply grid-root select-none auto-rows-[minmax(100px,auto)];
+ }
}