mirror of
https://github.com/Dokploy/templates
synced 2025-06-26 18:16:07 +00:00
feat: Integrate CodeMirror for enhanced code viewing with syntax highlighting
This commit is contained in:
parent
f2be84585e
commit
df6f80cc59
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2024 Dokploy
|
Copyright (c) 2024 Dokploy and Carlos Ortiz
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -25,7 +25,15 @@
|
|||||||
"tailwind-merge": "^3.0.2",
|
"tailwind-merge": "^3.0.2",
|
||||||
"tailwindcss": "^4.0.12",
|
"tailwindcss": "^4.0.12",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"vite-plugin-static-copy": "2.3.0"
|
"vite-plugin-static-copy": "2.3.0",
|
||||||
|
"@codemirror/autocomplete": "^6.18.6",
|
||||||
|
"@codemirror/lang-json": "^6.0.1",
|
||||||
|
"@codemirror/lang-yaml": "^6.1.1",
|
||||||
|
"@codemirror/language": "^6.10.1",
|
||||||
|
"@codemirror/legacy-modes": "6.4.0",
|
||||||
|
"@codemirror/view": "6.29.0",
|
||||||
|
"@uiw/codemirror-theme-github": "^4.22.1",
|
||||||
|
"@uiw/react-codemirror": "^4.22.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.8.2",
|
"@types/node": "^20.8.2",
|
||||||
|
@ -8,6 +8,24 @@ importers:
|
|||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@codemirror/autocomplete':
|
||||||
|
specifier: ^6.18.6
|
||||||
|
version: 6.18.6
|
||||||
|
'@codemirror/lang-json':
|
||||||
|
specifier: ^6.0.1
|
||||||
|
version: 6.0.1
|
||||||
|
'@codemirror/lang-yaml':
|
||||||
|
specifier: ^6.1.1
|
||||||
|
version: 6.1.2
|
||||||
|
'@codemirror/language':
|
||||||
|
specifier: ^6.10.1
|
||||||
|
version: 6.10.8
|
||||||
|
'@codemirror/legacy-modes':
|
||||||
|
specifier: 6.4.0
|
||||||
|
version: 6.4.0
|
||||||
|
'@codemirror/view':
|
||||||
|
specifier: 6.29.0
|
||||||
|
version: 6.29.0
|
||||||
'@radix-ui/react-dialog':
|
'@radix-ui/react-dialog':
|
||||||
specifier: ^1.1.6
|
specifier: ^1.1.6
|
||||||
version: 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
version: 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
@ -20,6 +38,12 @@ importers:
|
|||||||
'@tailwindcss/vite':
|
'@tailwindcss/vite':
|
||||||
specifier: ^4.0.12
|
specifier: ^4.0.12
|
||||||
version: 4.0.12(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2))
|
version: 4.0.12(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2))
|
||||||
|
'@uiw/codemirror-theme-github':
|
||||||
|
specifier: ^4.22.1
|
||||||
|
version: 4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)
|
||||||
|
'@uiw/react-codemirror':
|
||||||
|
specifier: ^4.22.1
|
||||||
|
version: 4.23.10(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.29.0)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||||
class-variance-authority:
|
class-variance-authority:
|
||||||
specifier: ^0.7.1
|
specifier: ^0.7.1
|
||||||
version: 0.7.1
|
version: 0.7.1
|
||||||
@ -152,6 +176,10 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
|
|
||||||
|
'@babel/runtime@7.26.9':
|
||||||
|
resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@babel/template@7.26.9':
|
'@babel/template@7.26.9':
|
||||||
resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==}
|
resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@ -164,6 +192,42 @@ packages:
|
|||||||
resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==}
|
resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@codemirror/autocomplete@6.18.6':
|
||||||
|
resolution: {integrity: sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==}
|
||||||
|
|
||||||
|
'@codemirror/commands@6.8.0':
|
||||||
|
resolution: {integrity: sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ==}
|
||||||
|
|
||||||
|
'@codemirror/lang-json@6.0.1':
|
||||||
|
resolution: {integrity: sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==}
|
||||||
|
|
||||||
|
'@codemirror/lang-yaml@6.1.2':
|
||||||
|
resolution: {integrity: sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw==}
|
||||||
|
|
||||||
|
'@codemirror/language@6.10.8':
|
||||||
|
resolution: {integrity: sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw==}
|
||||||
|
|
||||||
|
'@codemirror/legacy-modes@6.4.0':
|
||||||
|
resolution: {integrity: sha512-5m/K+1A6gYR0e+h/dEde7LoGimMjRtWXZFg4Lo70cc8HzjSdHe3fLwjWMR0VRl5KFT1SxalSap7uMgPKF28wBA==}
|
||||||
|
|
||||||
|
'@codemirror/lint@6.8.4':
|
||||||
|
resolution: {integrity: sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==}
|
||||||
|
|
||||||
|
'@codemirror/search@6.5.10':
|
||||||
|
resolution: {integrity: sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==}
|
||||||
|
|
||||||
|
'@codemirror/state@6.5.2':
|
||||||
|
resolution: {integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==}
|
||||||
|
|
||||||
|
'@codemirror/theme-one-dark@6.1.2':
|
||||||
|
resolution: {integrity: sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==}
|
||||||
|
|
||||||
|
'@codemirror/view@6.29.0':
|
||||||
|
resolution: {integrity: sha512-ED4ims4fkf7eOA+HYLVP8VVg3NMllt1FPm9PEJBfYFnidKlRITBaua38u68L1F60eNtw2YNcDN5jsIzhKZwWQA==}
|
||||||
|
|
||||||
|
'@codemirror/view@6.36.4':
|
||||||
|
resolution: {integrity: sha512-ZQ0V5ovw/miKEXTvjgzRyjnrk9TwriUB1k4R5p7uNnHR9Hus+D1SXHGdJshijEzPFjU25xea/7nhIeSqYFKdbA==}
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.25.1':
|
'@esbuild/aix-ppc64@0.25.1':
|
||||||
resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==}
|
resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@ -347,6 +411,24 @@ packages:
|
|||||||
'@jridgewell/trace-mapping@0.3.25':
|
'@jridgewell/trace-mapping@0.3.25':
|
||||||
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
|
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
|
||||||
|
|
||||||
|
'@lezer/common@1.2.3':
|
||||||
|
resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==}
|
||||||
|
|
||||||
|
'@lezer/highlight@1.2.1':
|
||||||
|
resolution: {integrity: sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==}
|
||||||
|
|
||||||
|
'@lezer/json@1.0.3':
|
||||||
|
resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==}
|
||||||
|
|
||||||
|
'@lezer/lr@1.4.2':
|
||||||
|
resolution: {integrity: sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==}
|
||||||
|
|
||||||
|
'@lezer/yaml@1.0.3':
|
||||||
|
resolution: {integrity: sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA==}
|
||||||
|
|
||||||
|
'@marijn/find-cluster-break@1.0.2':
|
||||||
|
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@ -828,6 +910,38 @@ packages:
|
|||||||
'@types/react@19.0.10':
|
'@types/react@19.0.10':
|
||||||
resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==}
|
resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==}
|
||||||
|
|
||||||
|
'@uiw/codemirror-extensions-basic-setup@4.23.10':
|
||||||
|
resolution: {integrity: sha512-zpbmSeNs3OU/f/Eyd6brFnjsBUYwv2mFjWxlAsIRSwTlW+skIT60rQHFBSfsj/5UVSxSLWVeUYczN7AyXvgTGQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@codemirror/autocomplete': '>=6.0.0'
|
||||||
|
'@codemirror/commands': '>=6.0.0'
|
||||||
|
'@codemirror/language': '>=6.0.0'
|
||||||
|
'@codemirror/lint': '>=6.0.0'
|
||||||
|
'@codemirror/search': '>=6.0.0'
|
||||||
|
'@codemirror/state': '>=6.0.0'
|
||||||
|
'@codemirror/view': '>=6.0.0'
|
||||||
|
|
||||||
|
'@uiw/codemirror-theme-github@4.23.10':
|
||||||
|
resolution: {integrity: sha512-jTg2sHAcU1d+8x0O+EBDI71rtJ8PWKIW8gzy+SW4wShQTAdsqGHk5y1ynt3KIeoaUkqngLqAK4SkhPaUKlqZqg==}
|
||||||
|
|
||||||
|
'@uiw/codemirror-themes@4.23.10':
|
||||||
|
resolution: {integrity: sha512-dU0UgEEgEXCAYpxuVDQ6fovE82XsqgHZckTJOH6Bs8xCi3Z7dwBKO4pXuiA8qGDwTOXOMjSzfi+pRViDm7OfWw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@codemirror/language': '>=6.0.0'
|
||||||
|
'@codemirror/state': '>=6.0.0'
|
||||||
|
'@codemirror/view': '>=6.0.0'
|
||||||
|
|
||||||
|
'@uiw/react-codemirror@4.23.10':
|
||||||
|
resolution: {integrity: sha512-AbN4eVHOL4ckRuIXpZxkzEqL/1ChVA+BSdEnAKjIB68pLQvKsVoYbiFP8zkXkYc4+Fcgq5KbAjvYqdo4ewemKw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/runtime': '>=7.11.0'
|
||||||
|
'@codemirror/state': '>=6.0.0'
|
||||||
|
'@codemirror/theme-one-dark': '>=6.0.0'
|
||||||
|
'@codemirror/view': '>=6.0.0'
|
||||||
|
codemirror: '>=6.0.0'
|
||||||
|
react: '>=16.8.0'
|
||||||
|
react-dom: '>=16.8.0'
|
||||||
|
|
||||||
'@vitejs/plugin-react@4.3.4':
|
'@vitejs/plugin-react@4.3.4':
|
||||||
resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==}
|
resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==}
|
||||||
engines: {node: ^14.18.0 || >=16.0.0}
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
@ -869,12 +983,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
|
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
codemirror@6.0.1:
|
||||||
|
resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==}
|
||||||
|
|
||||||
convert-source-map@2.0.0:
|
convert-source-map@2.0.0:
|
||||||
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
||||||
|
|
||||||
copy-to-clipboard@3.3.3:
|
copy-to-clipboard@3.3.3:
|
||||||
resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==}
|
resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==}
|
||||||
|
|
||||||
|
crelt@1.0.6:
|
||||||
|
resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
|
||||||
|
|
||||||
csstype@3.1.3:
|
csstype@3.1.3:
|
||||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||||
|
|
||||||
@ -1155,6 +1275,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
||||||
engines: {node: '>=8.10.0'}
|
engines: {node: '>=8.10.0'}
|
||||||
|
|
||||||
|
regenerator-runtime@0.14.1:
|
||||||
|
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
|
||||||
|
|
||||||
reusify@1.1.0:
|
reusify@1.1.0:
|
||||||
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
|
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
|
||||||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
||||||
@ -1184,6 +1307,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
style-mod@4.1.2:
|
||||||
|
resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
|
||||||
|
|
||||||
tailwind-merge@3.0.2:
|
tailwind-merge@3.0.2:
|
||||||
resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==}
|
resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==}
|
||||||
|
|
||||||
@ -1293,6 +1419,9 @@ packages:
|
|||||||
yaml:
|
yaml:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
w3c-keyname@2.2.8:
|
||||||
|
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
|
||||||
|
|
||||||
yallist@3.1.1:
|
yallist@3.1.1:
|
||||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||||
|
|
||||||
@ -1390,6 +1519,10 @@ snapshots:
|
|||||||
'@babel/core': 7.26.9
|
'@babel/core': 7.26.9
|
||||||
'@babel/helper-plugin-utils': 7.26.5
|
'@babel/helper-plugin-utils': 7.26.5
|
||||||
|
|
||||||
|
'@babel/runtime@7.26.9':
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime: 0.14.1
|
||||||
|
|
||||||
'@babel/template@7.26.9':
|
'@babel/template@7.26.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.26.2
|
'@babel/code-frame': 7.26.2
|
||||||
@ -1413,6 +1546,83 @@ snapshots:
|
|||||||
'@babel/helper-string-parser': 7.25.9
|
'@babel/helper-string-parser': 7.25.9
|
||||||
'@babel/helper-validator-identifier': 7.25.9
|
'@babel/helper-validator-identifier': 7.25.9
|
||||||
|
|
||||||
|
'@codemirror/autocomplete@6.18.6':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.10.8
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.29.0
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
|
||||||
|
'@codemirror/commands@6.8.0':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.10.8
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.29.0
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
|
||||||
|
'@codemirror/lang-json@6.0.1':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.10.8
|
||||||
|
'@lezer/json': 1.0.3
|
||||||
|
|
||||||
|
'@codemirror/lang-yaml@6.1.2':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.18.6
|
||||||
|
'@codemirror/language': 6.10.8
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
'@lezer/lr': 1.4.2
|
||||||
|
'@lezer/yaml': 1.0.3
|
||||||
|
|
||||||
|
'@codemirror/language@6.10.8':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.29.0
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
'@lezer/lr': 1.4.2
|
||||||
|
style-mod: 4.1.2
|
||||||
|
|
||||||
|
'@codemirror/legacy-modes@6.4.0':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.10.8
|
||||||
|
|
||||||
|
'@codemirror/lint@6.8.4':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.36.4
|
||||||
|
crelt: 1.0.6
|
||||||
|
|
||||||
|
'@codemirror/search@6.5.10':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.29.0
|
||||||
|
crelt: 1.0.6
|
||||||
|
|
||||||
|
'@codemirror/state@6.5.2':
|
||||||
|
dependencies:
|
||||||
|
'@marijn/find-cluster-break': 1.0.2
|
||||||
|
|
||||||
|
'@codemirror/theme-one-dark@6.1.2':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.10.8
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.29.0
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
|
||||||
|
'@codemirror/view@6.29.0':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
style-mod: 4.1.2
|
||||||
|
w3c-keyname: 2.2.8
|
||||||
|
|
||||||
|
'@codemirror/view@6.36.4':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
style-mod: 4.1.2
|
||||||
|
w3c-keyname: 2.2.8
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.25.1':
|
'@esbuild/aix-ppc64@0.25.1':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@ -1522,6 +1732,30 @@ snapshots:
|
|||||||
'@jridgewell/resolve-uri': 3.1.2
|
'@jridgewell/resolve-uri': 3.1.2
|
||||||
'@jridgewell/sourcemap-codec': 1.5.0
|
'@jridgewell/sourcemap-codec': 1.5.0
|
||||||
|
|
||||||
|
'@lezer/common@1.2.3': {}
|
||||||
|
|
||||||
|
'@lezer/highlight@1.2.1':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
|
||||||
|
'@lezer/json@1.0.3':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
'@lezer/lr': 1.4.2
|
||||||
|
|
||||||
|
'@lezer/lr@1.4.2':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
|
||||||
|
'@lezer/yaml@1.0.3':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
'@lezer/lr': 1.4.2
|
||||||
|
|
||||||
|
'@marijn/find-cluster-break@1.0.2': {}
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nodelib/fs.stat': 2.0.5
|
'@nodelib/fs.stat': 2.0.5
|
||||||
@ -1941,6 +2175,47 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
csstype: 3.1.3
|
csstype: 3.1.3
|
||||||
|
|
||||||
|
'@uiw/codemirror-extensions-basic-setup@4.23.10(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.18.6
|
||||||
|
'@codemirror/commands': 6.8.0
|
||||||
|
'@codemirror/language': 6.10.8
|
||||||
|
'@codemirror/lint': 6.8.4
|
||||||
|
'@codemirror/search': 6.5.10
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.29.0
|
||||||
|
|
||||||
|
'@uiw/codemirror-theme-github@4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)':
|
||||||
|
dependencies:
|
||||||
|
'@uiw/codemirror-themes': 4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@codemirror/language'
|
||||||
|
- '@codemirror/state'
|
||||||
|
- '@codemirror/view'
|
||||||
|
|
||||||
|
'@uiw/codemirror-themes@4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.10.8
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.29.0
|
||||||
|
|
||||||
|
'@uiw/react-codemirror@4.23.10(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.29.0)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.26.9
|
||||||
|
'@codemirror/commands': 6.8.0
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/theme-one-dark': 6.1.2
|
||||||
|
'@codemirror/view': 6.29.0
|
||||||
|
'@uiw/codemirror-extensions-basic-setup': 4.23.10(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)
|
||||||
|
codemirror: 6.0.1
|
||||||
|
react: 19.0.0
|
||||||
|
react-dom: 19.0.0(react@19.0.0)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@codemirror/autocomplete'
|
||||||
|
- '@codemirror/language'
|
||||||
|
- '@codemirror/lint'
|
||||||
|
- '@codemirror/search'
|
||||||
|
|
||||||
'@vitejs/plugin-react@4.3.4(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2))':
|
'@vitejs/plugin-react@4.3.4(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.26.9
|
'@babel/core': 7.26.9
|
||||||
@ -1994,12 +2269,24 @@ snapshots:
|
|||||||
|
|
||||||
clsx@2.1.1: {}
|
clsx@2.1.1: {}
|
||||||
|
|
||||||
|
codemirror@6.0.1:
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.18.6
|
||||||
|
'@codemirror/commands': 6.8.0
|
||||||
|
'@codemirror/language': 6.10.8
|
||||||
|
'@codemirror/lint': 6.8.4
|
||||||
|
'@codemirror/search': 6.5.10
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.29.0
|
||||||
|
|
||||||
convert-source-map@2.0.0: {}
|
convert-source-map@2.0.0: {}
|
||||||
|
|
||||||
copy-to-clipboard@3.3.3:
|
copy-to-clipboard@3.3.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
toggle-selection: 1.0.6
|
toggle-selection: 1.0.6
|
||||||
|
|
||||||
|
crelt@1.0.6: {}
|
||||||
|
|
||||||
csstype@3.1.3: {}
|
csstype@3.1.3: {}
|
||||||
|
|
||||||
debug@4.4.0:
|
debug@4.4.0:
|
||||||
@ -2239,6 +2526,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
picomatch: 2.3.1
|
picomatch: 2.3.1
|
||||||
|
|
||||||
|
regenerator-runtime@0.14.1: {}
|
||||||
|
|
||||||
reusify@1.1.0: {}
|
reusify@1.1.0: {}
|
||||||
|
|
||||||
rollup@4.35.0:
|
rollup@4.35.0:
|
||||||
@ -2281,6 +2570,8 @@ snapshots:
|
|||||||
|
|
||||||
source-map-js@1.2.1: {}
|
source-map-js@1.2.1: {}
|
||||||
|
|
||||||
|
style-mod@4.1.2: {}
|
||||||
|
|
||||||
tailwind-merge@3.0.2: {}
|
tailwind-merge@3.0.2: {}
|
||||||
|
|
||||||
tailwindcss-animate@1.0.7(tailwindcss@4.0.12):
|
tailwindcss-animate@1.0.7(tailwindcss@4.0.12):
|
||||||
@ -2346,4 +2637,6 @@ snapshots:
|
|||||||
jiti: 2.4.2
|
jiti: 2.4.2
|
||||||
lightningcss: 1.29.2
|
lightningcss: 1.29.2
|
||||||
|
|
||||||
|
w3c-keyname@2.2.8: {}
|
||||||
|
|
||||||
yallist@3.1.1: {}
|
yallist@3.1.1: {}
|
||||||
|
@ -12,6 +12,7 @@ import { Button } from './ui/button';
|
|||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import copy from 'copy-to-clipboard';
|
import copy from 'copy-to-clipboard';
|
||||||
import { ModeToggle } from '../mode-toggle';
|
import { ModeToggle } from '../mode-toggle';
|
||||||
|
import { CodeEditor } from './ui/code-editor';
|
||||||
interface Template {
|
interface Template {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@ -223,7 +224,7 @@ const TemplateGrid: React.FC = () => {
|
|||||||
<div>
|
<div>
|
||||||
<DialogTitle className="text-2xl">{selectedTemplate?.name}</DialogTitle>
|
<DialogTitle className="text-2xl">{selectedTemplate?.name}</DialogTitle>
|
||||||
<div className="flex items-center gap-2 mt-1">
|
<div className="flex items-center gap-2 mt-1">
|
||||||
<span className="text-sm text-gray-500">v{selectedTemplate?.version}</span>
|
<span className="text-sm text-gray-500">{selectedTemplate?.version}</span>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
{selectedTemplate?.links.github && (
|
{selectedTemplate?.links.github && (
|
||||||
<a
|
<a
|
||||||
@ -245,6 +246,15 @@ const TemplateGrid: React.FC = () => {
|
|||||||
Docs
|
Docs
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<a
|
||||||
|
href={`https://github.com/Dokploy/templates/tree/main/blueprints/${selectedTemplate?.id}`}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-gray-600 hover:text-gray-900"
|
||||||
|
>
|
||||||
|
Edit Template
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -277,9 +287,11 @@ const TemplateGrid: React.FC = () => {
|
|||||||
Docker Compose
|
Docker Compose
|
||||||
<span className="text-xs font-normal text-gray-500">docker-compose.yml</span>
|
<span className="text-xs font-normal text-gray-500">docker-compose.yml</span>
|
||||||
</h3>
|
</h3>
|
||||||
<pre className="bg-card border border-border p-6 rounded-lg overflow-x-auto text-sm">
|
<CodeEditor
|
||||||
<code className="font-mono">{templateFiles.dockerCompose}</code>
|
value={templateFiles.dockerCompose || ''}
|
||||||
</pre>
|
language="yaml"
|
||||||
|
className='font-mono'
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
toast.success('Copied to clipboard')
|
toast.success('Copied to clipboard')
|
||||||
@ -297,9 +309,11 @@ const TemplateGrid: React.FC = () => {
|
|||||||
Configuration
|
Configuration
|
||||||
<span className="text-xs font-normal text-gray-500">template.yml</span>
|
<span className="text-xs font-normal text-gray-500">template.yml</span>
|
||||||
</h3>
|
</h3>
|
||||||
<pre className="bg-card border border-border p-6 rounded-lg overflow-x-auto text-sm">
|
<CodeEditor
|
||||||
<code className="font-mono">{templateFiles.config}</code>
|
value={templateFiles.config || ''}
|
||||||
</pre>
|
language="yaml"
|
||||||
|
className='font-mono'
|
||||||
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -319,10 +333,10 @@ const TemplateGrid: React.FC = () => {
|
|||||||
<span className="text-xs font-normal text-gray-500">Encoded template files</span>
|
<span className="text-xs font-normal text-gray-500">Encoded template files</span>
|
||||||
</h3>
|
</h3>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<textarea
|
<CodeEditor
|
||||||
readOnly
|
|
||||||
className="w-full h-32 p-4 bg-card border border-border rounded-lg font-mono text-sm resize-none focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
||||||
value={getBase64Config()}
|
value={getBase64Config()}
|
||||||
|
language="properties"
|
||||||
|
className='font-mono'
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
176
app/src/components/ui/code-editor.tsx
Normal file
176
app/src/components/ui/code-editor.tsx
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { json } from "@codemirror/lang-json";
|
||||||
|
import { yaml } from "@codemirror/lang-yaml";
|
||||||
|
import { StreamLanguage } from "@codemirror/language";
|
||||||
|
|
||||||
|
import { properties } from "@codemirror/legacy-modes/mode/properties";
|
||||||
|
import { shell } from "@codemirror/legacy-modes/mode/shell";
|
||||||
|
import { EditorView } from "@codemirror/view";
|
||||||
|
import { githubDark, githubLight } from "@uiw/codemirror-theme-github";
|
||||||
|
import CodeMirror, { type ReactCodeMirrorProps } from "@uiw/react-codemirror";
|
||||||
|
import {
|
||||||
|
autocompletion,
|
||||||
|
type CompletionContext,
|
||||||
|
type CompletionResult,
|
||||||
|
type Completion,
|
||||||
|
} from "@codemirror/autocomplete";
|
||||||
|
import { useTheme } from "@/theme-provider";
|
||||||
|
// Docker Compose completion options
|
||||||
|
const dockerComposeServices = [
|
||||||
|
{ label: "services", type: "keyword", info: "Define services" },
|
||||||
|
{ label: "version", type: "keyword", info: "Specify compose file version" },
|
||||||
|
{ label: "volumes", type: "keyword", info: "Define volumes" },
|
||||||
|
{ label: "networks", type: "keyword", info: "Define networks" },
|
||||||
|
{ label: "configs", type: "keyword", info: "Define configuration files" },
|
||||||
|
{ label: "secrets", type: "keyword", info: "Define secrets" },
|
||||||
|
].map((opt) => ({
|
||||||
|
...opt,
|
||||||
|
apply: (view: EditorView, completion: Completion) => {
|
||||||
|
const insert = `${completion.label}:`;
|
||||||
|
view.dispatch({
|
||||||
|
changes: {
|
||||||
|
from: view.state.selection.main.from,
|
||||||
|
to: view.state.selection.main.to,
|
||||||
|
insert,
|
||||||
|
},
|
||||||
|
selection: { anchor: view.state.selection.main.from + insert.length },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const dockerComposeServiceOptions = [
|
||||||
|
{
|
||||||
|
label: "image",
|
||||||
|
type: "keyword",
|
||||||
|
info: "Specify the image to start the container from",
|
||||||
|
},
|
||||||
|
{ label: "build", type: "keyword", info: "Build configuration" },
|
||||||
|
{ label: "command", type: "keyword", info: "Override the default command" },
|
||||||
|
{ label: "container_name", type: "keyword", info: "Custom container name" },
|
||||||
|
{
|
||||||
|
label: "depends_on",
|
||||||
|
type: "keyword",
|
||||||
|
info: "Express dependency between services",
|
||||||
|
},
|
||||||
|
{ label: "environment", type: "keyword", info: "Add environment variables" },
|
||||||
|
{
|
||||||
|
label: "env_file",
|
||||||
|
type: "keyword",
|
||||||
|
info: "Add environment variables from a file",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "expose",
|
||||||
|
type: "keyword",
|
||||||
|
info: "Expose ports without publishing them",
|
||||||
|
},
|
||||||
|
{ label: "ports", type: "keyword", info: "Expose ports" },
|
||||||
|
{
|
||||||
|
label: "volumes",
|
||||||
|
type: "keyword",
|
||||||
|
info: "Mount host paths or named volumes",
|
||||||
|
},
|
||||||
|
{ label: "restart", type: "keyword", info: "Restart policy" },
|
||||||
|
{ label: "networks", type: "keyword", info: "Networks to join" },
|
||||||
|
].map((opt) => ({
|
||||||
|
...opt,
|
||||||
|
apply: (view: EditorView, completion: Completion) => {
|
||||||
|
const insert = `${completion.label}: `;
|
||||||
|
view.dispatch({
|
||||||
|
changes: {
|
||||||
|
from: view.state.selection.main.from,
|
||||||
|
to: view.state.selection.main.to,
|
||||||
|
insert,
|
||||||
|
},
|
||||||
|
selection: { anchor: view.state.selection.main.from + insert.length },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
function dockerComposeComplete(
|
||||||
|
context: CompletionContext,
|
||||||
|
): CompletionResult | null {
|
||||||
|
const word = context.matchBefore(/\w*/);
|
||||||
|
if (!word) return null;
|
||||||
|
|
||||||
|
if (!word.text && !context.explicit) return null;
|
||||||
|
|
||||||
|
// Check if we're at the root level
|
||||||
|
const line = context.state.doc.lineAt(context.pos);
|
||||||
|
const indentation = /^\s*/.exec(line.text)?.[0].length || 0;
|
||||||
|
|
||||||
|
if (indentation === 0) {
|
||||||
|
return {
|
||||||
|
from: word.from,
|
||||||
|
options: dockerComposeServices,
|
||||||
|
validFor: /^\w*$/,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're inside a service definition
|
||||||
|
if (indentation === 4) {
|
||||||
|
return {
|
||||||
|
from: word.from,
|
||||||
|
options: dockerComposeServiceOptions,
|
||||||
|
validFor: /^\w*$/,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props extends ReactCodeMirrorProps {
|
||||||
|
wrapperClassName?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
language?: "yaml" | "json" | "properties" | "shell";
|
||||||
|
lineWrapping?: boolean;
|
||||||
|
lineNumbers?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CodeEditor = ({
|
||||||
|
className,
|
||||||
|
wrapperClassName,
|
||||||
|
language = "yaml",
|
||||||
|
lineNumbers = true,
|
||||||
|
...props
|
||||||
|
}: Props) => {
|
||||||
|
const { theme } = useTheme();
|
||||||
|
return (
|
||||||
|
<div className={cn("relative overflow-auto", wrapperClassName)}>
|
||||||
|
<CodeMirror
|
||||||
|
basicSetup={{
|
||||||
|
lineNumbers,
|
||||||
|
foldGutter: true,
|
||||||
|
highlightSelectionMatches: true,
|
||||||
|
highlightActiveLine: !props.disabled,
|
||||||
|
allowMultipleSelections: true,
|
||||||
|
}}
|
||||||
|
theme={theme === "dark" ? githubDark : githubLight}
|
||||||
|
extensions={[
|
||||||
|
language === "yaml"
|
||||||
|
? yaml()
|
||||||
|
: language === "json"
|
||||||
|
? json()
|
||||||
|
: language === "shell"
|
||||||
|
? StreamLanguage.define(shell)
|
||||||
|
: StreamLanguage.define(properties),
|
||||||
|
props.lineWrapping ? EditorView.lineWrapping : [],
|
||||||
|
language === "yaml"
|
||||||
|
? autocompletion({
|
||||||
|
override: [dockerComposeComplete],
|
||||||
|
})
|
||||||
|
: [],
|
||||||
|
]}
|
||||||
|
{...props}
|
||||||
|
editable={!props.disabled}
|
||||||
|
className={cn(
|
||||||
|
"w-full h-full text-sm leading-relaxed",
|
||||||
|
`cm-theme-${theme}`,
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{props.disabled && (
|
||||||
|
<div className="absolute top-0 rounded-md left-0 w-full h-full flex items-center justify-center z-[10] [background:var(--overlay)] h-full" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user