Merge pull request #234 from drawdb-io/share
Implement file sharing using gists
This commit is contained in:
commit
7b9d9c21ec
@ -1 +1,2 @@
|
|||||||
VITE_BACKEND_URL=http://backend.com
|
VITE_BACKEND_URL=http://backend.com
|
||||||
|
VITE_GITHUB_ACCESS_TOKEN=my_access_token
|
366
package-lock.json
generated
366
package-lock.json
generated
@ -29,6 +29,7 @@
|
|||||||
"jspdf": "^2.5.1",
|
"jspdf": "^2.5.1",
|
||||||
"lexical": "^0.12.5",
|
"lexical": "^0.12.5",
|
||||||
"node-sql-parser": "^5.3.1",
|
"node-sql-parser": "^5.3.1",
|
||||||
|
"octokit": "^4.0.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hotkeys-hook": "^4.4.1",
|
"react-hotkeys-hook": "^4.4.1",
|
||||||
@ -1519,6 +1520,326 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/app": {
|
||||||
|
"version": "15.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/app/-/app-15.1.0.tgz",
|
||||||
|
"integrity": "sha512-TkBr7QgOmE6ORxvIAhDbZsqPkF7RSqTY4pLTtUQCvr6dTXqvi2fFo46q3h1lxlk/sGMQjqyZ0kEahkD/NyzOHg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/auth-app": "^7.0.0",
|
||||||
|
"@octokit/auth-unauthenticated": "^6.0.0",
|
||||||
|
"@octokit/core": "^6.1.2",
|
||||||
|
"@octokit/oauth-app": "^7.0.0",
|
||||||
|
"@octokit/plugin-paginate-rest": "^11.0.0",
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"@octokit/webhooks": "^13.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-app": {
|
||||||
|
"version": "7.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-7.1.0.tgz",
|
||||||
|
"integrity": "sha512-cazGaJPSgeZ8NkVYeM/C5l/6IQ5vZnsI8p1aMucadCkt/bndI+q+VqwrlnWbASRmenjOkf1t1RpCKrif53U8gw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/auth-oauth-app": "^8.1.0",
|
||||||
|
"@octokit/auth-oauth-user": "^5.1.0",
|
||||||
|
"@octokit/request": "^9.1.1",
|
||||||
|
"@octokit/request-error": "^6.1.1",
|
||||||
|
"@octokit/types": "^13.4.1",
|
||||||
|
"lru-cache": "^10.0.0",
|
||||||
|
"universal-github-app-jwt": "^2.2.0",
|
||||||
|
"universal-user-agent": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-app/node_modules/lru-cache": {
|
||||||
|
"version": "10.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||||
|
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-oauth-app": {
|
||||||
|
"version": "8.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-8.1.1.tgz",
|
||||||
|
"integrity": "sha512-5UtmxXAvU2wfcHIPPDWzVSAWXVJzG3NWsxb7zCFplCWEmMCArSZV0UQu5jw5goLQXbFyOr5onzEH37UJB3zQQg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/auth-oauth-device": "^7.0.0",
|
||||||
|
"@octokit/auth-oauth-user": "^5.0.1",
|
||||||
|
"@octokit/request": "^9.0.0",
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-oauth-device": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-HWl8lYueHonuyjrKKIup/1tiy0xcmQCdq5ikvMO1YwkNNkxb6DXfrPjrMYItNLyCP/o2H87WuijuE+SlBTT8eg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/oauth-methods": "^5.0.0",
|
||||||
|
"@octokit/request": "^9.0.0",
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-oauth-user": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-rRkMz0ErOppdvEfnemHJXgZ9vTPhBuC6yASeFaB7I2yLMd7QpjfrL1mnvRPlyKo+M6eeLxrKanXJ9Qte29SRsw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/auth-oauth-device": "^7.0.1",
|
||||||
|
"@octokit/oauth-methods": "^5.0.0",
|
||||||
|
"@octokit/request": "^9.0.1",
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-token": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-unauthenticated": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-zPSmfrUAcspZH/lOFQnVnvjQZsIvmfApQH6GzJrkIunDooU1Su2qt2FfMTSVPRp7WLTQyC20Kd55lF+mIYaohQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/request-error": "^6.0.1",
|
||||||
|
"@octokit/types": "^13.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/core": {
|
||||||
|
"version": "6.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.2.tgz",
|
||||||
|
"integrity": "sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/auth-token": "^5.0.0",
|
||||||
|
"@octokit/graphql": "^8.0.0",
|
||||||
|
"@octokit/request": "^9.0.0",
|
||||||
|
"@octokit/request-error": "^6.0.1",
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"before-after-hook": "^3.0.2",
|
||||||
|
"universal-user-agent": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/endpoint": {
|
||||||
|
"version": "10.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.1.tgz",
|
||||||
|
"integrity": "sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^7.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/graphql": {
|
||||||
|
"version": "8.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.1.1.tgz",
|
||||||
|
"integrity": "sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/request": "^9.0.0",
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"universal-user-agent": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/oauth-app": {
|
||||||
|
"version": "7.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-7.1.3.tgz",
|
||||||
|
"integrity": "sha512-EHXbOpBkSGVVGF1W+NLMmsnSsJRkcrnVmDKt0TQYRBb6xWfWzoi9sBD4DIqZ8jGhOWO/V8t4fqFyJ4vDQDn9bg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/auth-oauth-app": "^8.0.0",
|
||||||
|
"@octokit/auth-oauth-user": "^5.0.1",
|
||||||
|
"@octokit/auth-unauthenticated": "^6.0.0-beta.1",
|
||||||
|
"@octokit/core": "^6.0.0",
|
||||||
|
"@octokit/oauth-authorization-url": "^7.0.0",
|
||||||
|
"@octokit/oauth-methods": "^5.0.0",
|
||||||
|
"@types/aws-lambda": "^8.10.83",
|
||||||
|
"universal-user-agent": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/oauth-authorization-url": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-ooXV8GBSabSWyhLUowlMIVd9l1s2nsOGQdlP2SQ4LnkEsGXzeCvbSbCPdZThXhEFzleGPwbapT0Sb+YhXRyjCA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/oauth-methods": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-C5lglRD+sBlbrhCUTxgJAFjWgJlmTx5bQ7Ch0+2uqRjYv7Cfb5xpX4WuSC9UgQna3sqRGBL9EImX9PvTpMaQ7g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/oauth-authorization-url": "^7.0.0",
|
||||||
|
"@octokit/request": "^9.1.0",
|
||||||
|
"@octokit/request-error": "^6.1.0",
|
||||||
|
"@octokit/types": "^13.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "22.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
|
||||||
|
"integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg=="
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/openapi-webhooks-types": {
|
||||||
|
"version": "8.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-webhooks-types/-/openapi-webhooks-types-8.3.0.tgz",
|
||||||
|
"integrity": "sha512-vKLsoR4xQxg4Z+6rU/F65ItTUz/EXbD+j/d4mlq2GW8TsA4Tc8Kdma2JTAAJ5hrKWUQzkR/Esn2fjsqiVRYaQg=="
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-paginate-graphql": {
|
||||||
|
"version": "5.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-5.2.2.tgz",
|
||||||
|
"integrity": "sha512-7znSVvlNAOJisCqAnjN1FtEziweOHSjPGAuc5W58NeGNAr/ZB57yCsjQbXDlWsVryA7hHQaEQPcBbJYFawlkyg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-paginate-rest": {
|
||||||
|
"version": "11.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.3.tgz",
|
||||||
|
"integrity": "sha512-o4WRoOJZlKqEEgj+i9CpcmnByvtzoUYC6I8PD2SA95M+BJ2x8h7oLcVOg9qcowWXBOdcTRsMZiwvM3EyLm9AfA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||||
|
"version": "13.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.2.4.tgz",
|
||||||
|
"integrity": "sha512-gusyAVgTrPiuXOdfqOySMDztQHv6928PQ3E4dqVGEtOvRXAKRbJR4b1zQyniIT9waqaWk/UDaoJ2dyPr7Bk7Iw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-retry": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-G9Ue+x2odcb8E1XIPhaFBnTTIrrUDfXN05iFXiqhR+SeeeDMMILcAnysOsxUpEWcQp2e5Ft397FCXTcPkiPkLw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/request-error": "^6.0.0",
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"bottleneck": "^2.15.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-throttling": {
|
||||||
|
"version": "9.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.3.1.tgz",
|
||||||
|
"integrity": "sha512-Qd91H4liUBhwLB2h6jZ99bsxoQdhgPk6TdwnClPyTBSDAdviGPceViEgUwj+pcQDmB/rfAXAXK7MTochpHM3yQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.0.0",
|
||||||
|
"bottleneck": "^2.15.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/request": {
|
||||||
|
"version": "9.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.1.3.tgz",
|
||||||
|
"integrity": "sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/endpoint": "^10.0.0",
|
||||||
|
"@octokit/request-error": "^6.0.1",
|
||||||
|
"@octokit/types": "^13.1.0",
|
||||||
|
"universal-user-agent": "^7.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/request-error": {
|
||||||
|
"version": "6.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.4.tgz",
|
||||||
|
"integrity": "sha512-VpAhIUxwhWZQImo/dWAN/NpPqqojR6PSLgLYAituLM6U+ddx9hCioFGwBr5Mi+oi5CLeJkcAs3gJ0PYYzU6wUg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^13.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/types": {
|
||||||
|
"version": "13.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz",
|
||||||
|
"integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^22.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/webhooks": {
|
||||||
|
"version": "13.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-13.3.0.tgz",
|
||||||
|
"integrity": "sha512-TUkJLtI163Bz5+JK0O+zDkQpn4gKwN+BovclUvCj6pI/6RXrFqQvUMRS2M+Rt8Rv0qR3wjoMoOPmpJKeOh0nBg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-webhooks-types": "8.3.0",
|
||||||
|
"@octokit/request-error": "^6.0.1",
|
||||||
|
"@octokit/webhooks-methods": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/webhooks-methods": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-yFZa3UH11VIxYnnoOYCVoJ3q4ChuSOk2IVBBQ0O3xtKX4x9bmKb/1t+Mxixv2iUhzMdOl1qeWJqEhouXXzB3rQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@remix-run/router": {
|
"node_modules/@remix-run/router": {
|
||||||
"version": "1.14.0",
|
"version": "1.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.0.tgz",
|
||||||
@ -1743,6 +2064,11 @@
|
|||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/aws-lambda": {
|
||||||
|
"version": "8.10.143",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.143.tgz",
|
||||||
|
"integrity": "sha512-u5vzlcR14ge/4pMTTMDQr3MF0wEe38B2F9o84uC4F43vN5DGTy63npRrB6jQhyt+C0lGv4ZfiRcRkqJoZuPnmg=="
|
||||||
|
},
|
||||||
"node_modules/@types/babel__core": {
|
"node_modules/@types/babel__core": {
|
||||||
"version": "7.20.5",
|
"version": "7.20.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||||
@ -2260,6 +2586,11 @@
|
|||||||
"node": ">= 0.6.0"
|
"node": ">= 0.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/before-after-hook": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="
|
||||||
|
},
|
||||||
"node_modules/bezier-easing": {
|
"node_modules/bezier-easing": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz",
|
||||||
@ -2282,6 +2613,11 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bottleneck": {
|
||||||
|
"version": "2.19.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
|
||||||
|
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
@ -4639,6 +4975,26 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/octokit": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/octokit/-/octokit-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-wbqF4uc1YbcldtiBFfkSnquHtECEIpYD78YUXI6ri1Im5OO2NLo6ZVpRdbJpdnpZ05zMrVPssNiEo6JQtea+Qg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/app": "^15.0.0",
|
||||||
|
"@octokit/core": "^6.0.0",
|
||||||
|
"@octokit/oauth-app": "^7.0.0",
|
||||||
|
"@octokit/plugin-paginate-graphql": "^5.0.0",
|
||||||
|
"@octokit/plugin-paginate-rest": "^11.0.0",
|
||||||
|
"@octokit/plugin-rest-endpoint-methods": "^13.0.0",
|
||||||
|
"@octokit/plugin-retry": "^7.0.0",
|
||||||
|
"@octokit/plugin-throttling": "^9.0.0",
|
||||||
|
"@octokit/request-error": "^6.0.0",
|
||||||
|
"@octokit/types": "^13.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/once": {
|
"node_modules/once": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
@ -5952,6 +6308,16 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/universal-github-app-jwt": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-G5o6f95b5BggDGuUfKDApKaCgNYy2x7OdHY0zSMF081O0EJobw+1130VONhrA7ezGSV2FNOGyM+KQpQZAr9bIQ=="
|
||||||
|
},
|
||||||
|
"node_modules/universal-user-agent": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="
|
||||||
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.0.13",
|
"version": "1.0.13",
|
||||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
"jspdf": "^2.5.1",
|
"jspdf": "^2.5.1",
|
||||||
"lexical": "^0.12.5",
|
"lexical": "^0.12.5",
|
||||||
"node-sql-parser": "^5.3.1",
|
"node-sql-parser": "^5.3.1",
|
||||||
|
"octokit": "^4.0.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hotkeys-hook": "^4.4.1",
|
"react-hotkeys-hook": "^4.4.1",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useState } from "react";
|
import { useContext, useState } from "react";
|
||||||
import {
|
import {
|
||||||
IconCaretdown,
|
IconCaretdown,
|
||||||
IconChevronRight,
|
IconChevronRight,
|
||||||
@ -9,6 +9,7 @@ import {
|
|||||||
IconUndo,
|
IconUndo,
|
||||||
IconRedo,
|
IconRedo,
|
||||||
IconEdit,
|
IconEdit,
|
||||||
|
IconShareStroked,
|
||||||
} from "@douyinfe/semi-icons";
|
} from "@douyinfe/semi-icons";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import icon from "../../assets/icon_dark_64.png";
|
import icon from "../../assets/icon_dark_64.png";
|
||||||
@ -71,6 +72,7 @@ import { databases } from "../../data/databases";
|
|||||||
import { jsonToMermaid } from "../../utils/exportAs/mermaid";
|
import { jsonToMermaid } from "../../utils/exportAs/mermaid";
|
||||||
import { isRtl } from "../../i18n/utils/rtl";
|
import { isRtl } from "../../i18n/utils/rtl";
|
||||||
import { jsonToDocumentation } from "../../utils/exportAs/documentation";
|
import { jsonToDocumentation } from "../../utils/exportAs/documentation";
|
||||||
|
import { IdContext } from "../Workspace";
|
||||||
|
|
||||||
export default function ControlPanel({
|
export default function ControlPanel({
|
||||||
diagramId,
|
diagramId,
|
||||||
@ -113,6 +115,7 @@ export default function ControlPanel({
|
|||||||
const { selectedElement, setSelectedElement } = useSelect();
|
const { selectedElement, setSelectedElement } = useSelect();
|
||||||
const { transform, setTransform } = useTransform();
|
const { transform, setTransform } = useTransform();
|
||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
|
const { setGistId } = useContext(IdContext);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const invertLayout = (component) =>
|
const invertLayout = (component) =>
|
||||||
@ -782,6 +785,7 @@ export default function ControlPanel({
|
|||||||
setEnums([]);
|
setEnums([]);
|
||||||
setUndoStack([]);
|
setUndoStack([]);
|
||||||
setRedoStack([]);
|
setRedoStack([]);
|
||||||
|
setGistId("");
|
||||||
})
|
})
|
||||||
.catch(() => Toast.error(t("oops_smth_went_wrong")));
|
.catch(() => Toast.error(t("oops_smth_went_wrong")));
|
||||||
},
|
},
|
||||||
@ -1080,7 +1084,7 @@ export default function ControlPanel({
|
|||||||
data: result,
|
data: result,
|
||||||
extension: "md",
|
extension: "md",
|
||||||
}));
|
}));
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
function: () => {},
|
function: () => {},
|
||||||
@ -1376,8 +1380,25 @@ export default function ControlPanel({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{layout.header && header()}
|
<div>
|
||||||
|
{layout.header && (
|
||||||
|
<div className="flex justify-between items-center me-7">
|
||||||
|
{header()}
|
||||||
|
{window.name.split(" ")[0] !== "t" && (
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
className="text-base me-2 pe-6 ps-5 py-[18px] rounded-md"
|
||||||
|
size="default"
|
||||||
|
icon={<IconShareStroked />}
|
||||||
|
onClick={() => setModal(MODAL.SHARE)}
|
||||||
|
>
|
||||||
|
{t("share")}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{layout.toolbar && toolbar()}
|
{layout.toolbar && toolbar()}
|
||||||
|
</div>
|
||||||
<Modal
|
<Modal
|
||||||
modal={modal}
|
modal={modal}
|
||||||
exportData={exportData}
|
exportData={exportData}
|
||||||
@ -1583,6 +1604,8 @@ export default function ControlPanel({
|
|||||||
return t("saving");
|
return t("saving");
|
||||||
case State.ERROR:
|
case State.ERROR:
|
||||||
return t("failed_to_save");
|
return t("failed_to_save");
|
||||||
|
case State.FAILED_TO_LOAD:
|
||||||
|
return t("failed_to_load");
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -1600,7 +1623,7 @@ export default function ControlPanel({
|
|||||||
width={54}
|
width={54}
|
||||||
src={icon}
|
src={icon}
|
||||||
alt="logo"
|
alt="logo"
|
||||||
className="ms-8 min-w-[54px]"
|
className="ms-7 min-w-[54px]"
|
||||||
/>
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
<div className="ms-1 mt-1">
|
<div className="ms-1 mt-1">
|
||||||
|
@ -33,6 +33,7 @@ import ImportDiagram from "./ImportDiagram";
|
|||||||
import ImportSource from "./ImportSource";
|
import ImportSource from "./ImportSource";
|
||||||
import SetTableWidth from "./SetTableWidth";
|
import SetTableWidth from "./SetTableWidth";
|
||||||
import Language from "./Language";
|
import Language from "./Language";
|
||||||
|
import Share from "./Share";
|
||||||
import CodeMirror from "@uiw/react-codemirror";
|
import CodeMirror from "@uiw/react-codemirror";
|
||||||
import { sql } from "@codemirror/lang-sql";
|
import { sql } from "@codemirror/lang-sql";
|
||||||
import { vscodeDark } from "@uiw/codemirror-theme-vscode";
|
import { vscodeDark } from "@uiw/codemirror-theme-vscode";
|
||||||
@ -319,7 +320,7 @@ export default function Modal({
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div className="text-center my-3">
|
<div className="text-center my-3 text-sky-600">
|
||||||
<Spin tip={t("loading")} size="large" />
|
<Spin tip={t("loading")} size="large" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -328,6 +329,8 @@ export default function Modal({
|
|||||||
return <SetTableWidth />;
|
return <SetTableWidth />;
|
||||||
case MODAL.LANGUAGE:
|
case MODAL.LANGUAGE:
|
||||||
return <Language />;
|
return <Language />;
|
||||||
|
case MODAL.SHARE:
|
||||||
|
return <Share title={title} />;
|
||||||
default:
|
default:
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
@ -371,7 +374,9 @@ export default function Modal({
|
|||||||
((modal === MODAL.IMG || modal === MODAL.CODE) && !exportData.data) ||
|
((modal === MODAL.IMG || modal === MODAL.CODE) && !exportData.data) ||
|
||||||
(modal === MODAL.SAVEAS && saveAsTitle === "") ||
|
(modal === MODAL.SAVEAS && saveAsTitle === "") ||
|
||||||
(modal === MODAL.IMPORT_SRC && importSource.src === ""),
|
(modal === MODAL.IMPORT_SRC && importSource.src === ""),
|
||||||
|
hidden: modal === MODAL.SHARE,
|
||||||
}}
|
}}
|
||||||
|
hasCancel={modal !== MODAL.SHARE}
|
||||||
cancelText={t("cancel")}
|
cancelText={t("cancel")}
|
||||||
width={getModalWidth(modal)}
|
width={getModalWidth(modal)}
|
||||||
bodyStyle={{
|
bodyStyle={{
|
||||||
|
152
src/components/EditorHeader/Modal/Share.jsx
Normal file
152
src/components/EditorHeader/Modal/Share.jsx
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import { Button, Input, Spin, Toast } from "@douyinfe/semi-ui";
|
||||||
|
import { useCallback, useContext, useEffect, useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { IdContext } from "../../Workspace";
|
||||||
|
import { IconLink } from "@douyinfe/semi-icons";
|
||||||
|
import {
|
||||||
|
useAreas,
|
||||||
|
useDiagram,
|
||||||
|
useEnums,
|
||||||
|
useNotes,
|
||||||
|
useTransform,
|
||||||
|
useTypes,
|
||||||
|
} from "../../../hooks";
|
||||||
|
import { databases } from "../../../data/databases";
|
||||||
|
import { octokit } from "../../../data/octokit";
|
||||||
|
|
||||||
|
export default function Share({ title }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { gistId, setGistId } = useContext(IdContext);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const { tables, relationships, database } = useDiagram();
|
||||||
|
const { notes } = useNotes();
|
||||||
|
const { areas } = useAreas();
|
||||||
|
const { types } = useTypes();
|
||||||
|
const { enums } = useEnums();
|
||||||
|
const { transform } = useTransform();
|
||||||
|
const url =
|
||||||
|
window.location.origin + window.location.pathname + "?shareId=" + gistId;
|
||||||
|
|
||||||
|
const diagramToString = useCallback(() => {
|
||||||
|
return JSON.stringify({
|
||||||
|
tables: tables,
|
||||||
|
relationships: relationships,
|
||||||
|
notes: notes,
|
||||||
|
subjectAreas: areas,
|
||||||
|
database: database,
|
||||||
|
...(databases[database].hasTypes && { types: types }),
|
||||||
|
...(databases[database].hasEnums && { enums: enums }),
|
||||||
|
title: title,
|
||||||
|
transform: transform,
|
||||||
|
});
|
||||||
|
}, [
|
||||||
|
areas,
|
||||||
|
notes,
|
||||||
|
tables,
|
||||||
|
relationships,
|
||||||
|
database,
|
||||||
|
title,
|
||||||
|
enums,
|
||||||
|
types,
|
||||||
|
transform,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const updateGist = useCallback(async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
await octokit.request(`PATCH /gists/${gistId}`, {
|
||||||
|
gist_id: gistId,
|
||||||
|
description: "drawDB diagram",
|
||||||
|
files: {
|
||||||
|
"share.json": {
|
||||||
|
content: diagramToString(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
"X-GitHub-Api-Version": "2022-11-28",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [gistId, diagramToString]);
|
||||||
|
|
||||||
|
const generateLink = useCallback(async () => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const res = await octokit.request("POST /gists", {
|
||||||
|
description: "drawDB diagram",
|
||||||
|
public: false,
|
||||||
|
files: {
|
||||||
|
"share.json": {
|
||||||
|
content: diagramToString(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
"X-GitHub-Api-Version": "2022-11-28",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
setGistId(res.data.id);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [setGistId, diagramToString]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const updateOrGenerateLink = async () => {
|
||||||
|
try {
|
||||||
|
if (!gistId || gistId === "") {
|
||||||
|
await generateLink();
|
||||||
|
} else {
|
||||||
|
await updateGist();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
updateOrGenerateLink();
|
||||||
|
}, [gistId, generateLink, updateGist]);
|
||||||
|
|
||||||
|
const copyLink = () => {
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(url)
|
||||||
|
.then(() => {
|
||||||
|
Toast.success(t("copied_to_clipboard"));
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
Toast.error(t("oops_smth_went_wrong"));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (loading)
|
||||||
|
return (
|
||||||
|
<div className="text-blue-500 text-center">
|
||||||
|
<Spin size="middle" />
|
||||||
|
<div>{t("loading")}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="flex gap-3">
|
||||||
|
<Input value={url} size="large" />
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
theme="solid"
|
||||||
|
icon={<IconLink />}
|
||||||
|
onClick={copyLink}
|
||||||
|
>
|
||||||
|
{t("copy_link")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<hr className="opacity-20 mt-3 mb-1" />
|
||||||
|
<div className="text-xs">{t("share_info")}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { useState, useEffect, useCallback } from "react";
|
import { useState, useEffect, useCallback, createContext } from "react";
|
||||||
import ControlPanel from "./EditorHeader/ControlPanel";
|
import ControlPanel from "./EditorHeader/ControlPanel";
|
||||||
import Canvas from "./EditorCanvas/Canvas";
|
import Canvas from "./EditorCanvas/Canvas";
|
||||||
import { CanvasContextProvider } from "../context/CanvasContext";
|
import { CanvasContextProvider } from "../context/CanvasContext";
|
||||||
@ -23,9 +23,15 @@ import { Modal } from "@douyinfe/semi-ui";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { databases } from "../data/databases";
|
import { databases } from "../data/databases";
|
||||||
import { isRtl } from "../i18n/utils/rtl";
|
import { isRtl } from "../i18n/utils/rtl";
|
||||||
|
import { useSearchParams } from "react-router-dom";
|
||||||
|
import { octokit } from "../data/octokit";
|
||||||
|
|
||||||
|
export const IdContext = createContext({ gistId: "" });
|
||||||
|
|
||||||
export default function WorkSpace() {
|
export default function WorkSpace() {
|
||||||
const [id, setId] = useState(0);
|
const [id, setId] = useState(0);
|
||||||
|
const [gistId, setGistId] = useState("");
|
||||||
|
const [loadedFromGistId, setLoadedFromGistId] = useState("");
|
||||||
const [title, setTitle] = useState("Untitled Diagram");
|
const [title, setTitle] = useState("Untitled Diagram");
|
||||||
const [resize, setResize] = useState(false);
|
const [resize, setResize] = useState(false);
|
||||||
const [width, setWidth] = useState(340);
|
const [width, setWidth] = useState(340);
|
||||||
@ -51,7 +57,7 @@ export default function WorkSpace() {
|
|||||||
} = useDiagram();
|
} = useDiagram();
|
||||||
const { undoStack, redoStack, setUndoStack, setRedoStack } = useUndoRedo();
|
const { undoStack, redoStack, setUndoStack, setRedoStack } = useUndoRedo();
|
||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
|
let [searchParams, setSearchParams] = useSearchParams();
|
||||||
const handleResize = (e) => {
|
const handleResize = (e) => {
|
||||||
if (!resize) return;
|
if (!resize) return;
|
||||||
const w = isRtl(i18n.language) ? window.innerWidth - e.clientX : e.clientX;
|
const w = isRtl(i18n.language) ? window.innerWidth - e.clientX : e.clientX;
|
||||||
@ -64,6 +70,8 @@ export default function WorkSpace() {
|
|||||||
const saveAsDiagram = window.name === "" || op === "d" || op === "lt";
|
const saveAsDiagram = window.name === "" || op === "d" || op === "lt";
|
||||||
|
|
||||||
if (saveAsDiagram) {
|
if (saveAsDiagram) {
|
||||||
|
searchParams.delete("shareId");
|
||||||
|
setSearchParams(searchParams);
|
||||||
if (
|
if (
|
||||||
(id === 0 && window.name === "") ||
|
(id === 0 && window.name === "") ||
|
||||||
window.name.split(" ")[0] === "lt"
|
window.name.split(" ")[0] === "lt"
|
||||||
@ -72,6 +80,7 @@ export default function WorkSpace() {
|
|||||||
.add({
|
.add({
|
||||||
database: database,
|
database: database,
|
||||||
name: title,
|
name: title,
|
||||||
|
gistId: gistId ?? "",
|
||||||
lastModified: new Date(),
|
lastModified: new Date(),
|
||||||
tables: tables,
|
tables: tables,
|
||||||
references: relationships,
|
references: relationships,
|
||||||
@ -80,6 +89,7 @@ export default function WorkSpace() {
|
|||||||
todos: tasks,
|
todos: tasks,
|
||||||
pan: transform.pan,
|
pan: transform.pan,
|
||||||
zoom: transform.zoom,
|
zoom: transform.zoom,
|
||||||
|
loadedFromGistId: loadedFromGistId,
|
||||||
...(databases[database].hasEnums && { enums: enums }),
|
...(databases[database].hasEnums && { enums: enums }),
|
||||||
...(databases[database].hasTypes && { types: types }),
|
...(databases[database].hasTypes && { types: types }),
|
||||||
})
|
})
|
||||||
@ -100,8 +110,10 @@ export default function WorkSpace() {
|
|||||||
notes: notes,
|
notes: notes,
|
||||||
areas: areas,
|
areas: areas,
|
||||||
todos: tasks,
|
todos: tasks,
|
||||||
|
gistId: gistId ?? "",
|
||||||
pan: transform.pan,
|
pan: transform.pan,
|
||||||
zoom: transform.zoom,
|
zoom: transform.zoom,
|
||||||
|
loadedFromGistId: loadedFromGistId,
|
||||||
...(databases[database].hasEnums && { enums: enums }),
|
...(databases[database].hasEnums && { enums: enums }),
|
||||||
...(databases[database].hasTypes && { types: types }),
|
...(databases[database].hasTypes && { types: types }),
|
||||||
})
|
})
|
||||||
@ -134,6 +146,8 @@ export default function WorkSpace() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
|
searchParams,
|
||||||
|
setSearchParams,
|
||||||
tables,
|
tables,
|
||||||
relationships,
|
relationships,
|
||||||
notes,
|
notes,
|
||||||
@ -146,6 +160,8 @@ export default function WorkSpace() {
|
|||||||
setSaveState,
|
setSaveState,
|
||||||
database,
|
database,
|
||||||
enums,
|
enums,
|
||||||
|
gistId,
|
||||||
|
loadedFromGistId,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const load = useCallback(async () => {
|
const load = useCallback(async () => {
|
||||||
@ -161,6 +177,8 @@ export default function WorkSpace() {
|
|||||||
setDatabase(DB.GENERIC);
|
setDatabase(DB.GENERIC);
|
||||||
}
|
}
|
||||||
setId(d.id);
|
setId(d.id);
|
||||||
|
setGistId(d.gistId);
|
||||||
|
setLoadedFromGistId(d.loadedFromGistId);
|
||||||
setTitle(d.name);
|
setTitle(d.name);
|
||||||
setTables(d.tables);
|
setTables(d.tables);
|
||||||
setRelationships(d.references);
|
setRelationships(d.references);
|
||||||
@ -196,6 +214,8 @@ export default function WorkSpace() {
|
|||||||
setDatabase(DB.GENERIC);
|
setDatabase(DB.GENERIC);
|
||||||
}
|
}
|
||||||
setId(diagram.id);
|
setId(diagram.id);
|
||||||
|
setGistId(diagram.gistId);
|
||||||
|
setLoadedFromGistId(diagram.loadedFromGistId);
|
||||||
setTitle(diagram.name);
|
setTitle(diagram.name);
|
||||||
setTables(diagram.tables);
|
setTables(diagram.tables);
|
||||||
setRelationships(diagram.references);
|
setRelationships(diagram.references);
|
||||||
@ -299,6 +319,61 @@ export default function WorkSpace() {
|
|||||||
selectedDb,
|
selectedDb,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const loadFromGist = useCallback(
|
||||||
|
async (shareId) => {
|
||||||
|
const existingDiagram = await db.diagrams.get({
|
||||||
|
loadedFromGistId: shareId,
|
||||||
|
});
|
||||||
|
if (existingDiagram) {
|
||||||
|
window.name = "d " + existingDiagram.id;
|
||||||
|
} else {
|
||||||
|
window.name = "";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const res = await octokit.request(`GET /gists/${shareId}`, {
|
||||||
|
gist_id: shareId,
|
||||||
|
headers: {
|
||||||
|
"X-GitHub-Api-Version": "2022-11-28",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const diagramSrc = res.data.files["share.json"].content;
|
||||||
|
const d = JSON.parse(diagramSrc);
|
||||||
|
setUndoStack([]);
|
||||||
|
setRedoStack([]);
|
||||||
|
setLoadedFromGistId(shareId);
|
||||||
|
setDatabase(d.database);
|
||||||
|
setTitle(d.title);
|
||||||
|
setTables(d.tables);
|
||||||
|
setRelationships(d.relationships);
|
||||||
|
setNotes(d.notes);
|
||||||
|
setAreas(d.subjectAreas);
|
||||||
|
setTransform(d.transform);
|
||||||
|
if (databases[d.database].hasTypes) {
|
||||||
|
setTypes(d.types ?? []);
|
||||||
|
}
|
||||||
|
if (databases[d.database].hasEnums) {
|
||||||
|
setEnums(d.enums ?? []);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
setSaveState(State.FAILED_TO_LOAD);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[
|
||||||
|
setAreas,
|
||||||
|
setDatabase,
|
||||||
|
setEnums,
|
||||||
|
setNotes,
|
||||||
|
setRelationships,
|
||||||
|
setTables,
|
||||||
|
setTypes,
|
||||||
|
setTransform,
|
||||||
|
setRedoStack,
|
||||||
|
setUndoStack,
|
||||||
|
setSaveState,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
tables?.length === 0 &&
|
tables?.length === 0 &&
|
||||||
@ -327,20 +402,32 @@ export default function WorkSpace() {
|
|||||||
setSaveState,
|
setSaveState,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (gistId && gistId !== "") {
|
||||||
|
setSaveState(State.SAVING);
|
||||||
|
}
|
||||||
|
}, [gistId, setSaveState]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (saveState !== State.SAVING) return;
|
if (saveState !== State.SAVING) return;
|
||||||
|
|
||||||
save();
|
save();
|
||||||
}, [id, saveState, save]);
|
}, [id, gistId, saveState, save]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = "Editor | drawDB";
|
document.title = "Editor | drawDB";
|
||||||
|
|
||||||
|
const shareId = searchParams.get("shareId");
|
||||||
|
if (shareId) {
|
||||||
|
loadFromGist(shareId);
|
||||||
|
} else {
|
||||||
load();
|
load();
|
||||||
}, [load]);
|
}
|
||||||
|
}, [load, searchParams, loadFromGist]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full flex flex-col overflow-hidden theme">
|
<div className="h-full flex flex-col overflow-hidden theme">
|
||||||
|
<IdContext.Provider value={{ gistId, setGistId }}>
|
||||||
<ControlPanel
|
<ControlPanel
|
||||||
diagramId={id}
|
diagramId={id}
|
||||||
setDiagramId={setId}
|
setDiagramId={setId}
|
||||||
@ -349,6 +436,7 @@ export default function WorkSpace() {
|
|||||||
lastSaved={lastSaved}
|
lastSaved={lastSaved}
|
||||||
setLastSaved={setLastSaved}
|
setLastSaved={setLastSaved}
|
||||||
/>
|
/>
|
||||||
|
</IdContext.Provider>
|
||||||
<div
|
<div
|
||||||
className="flex h-full overflow-y-auto"
|
className="flex h-full overflow-y-auto"
|
||||||
onPointerUp={(e) => e.isPrimary && setResize(false)}
|
onPointerUp={(e) => e.isPrimary && setResize(false)}
|
||||||
|
@ -77,6 +77,7 @@ export const State = {
|
|||||||
SAVED: 2,
|
SAVED: 2,
|
||||||
LOADING: 3,
|
LOADING: 3,
|
||||||
ERROR: 4,
|
ERROR: 4,
|
||||||
|
FAILED_TO_LOAD: 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MODAL = {
|
export const MODAL = {
|
||||||
@ -91,6 +92,7 @@ export const MODAL = {
|
|||||||
IMPORT_SRC: 8,
|
IMPORT_SRC: 8,
|
||||||
TABLE_WIDTH: 9,
|
TABLE_WIDTH: 9,
|
||||||
LANGUAGE: 10,
|
LANGUAGE: 10,
|
||||||
|
SHARE: 11,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const STATUS = {
|
export const STATUS = {
|
||||||
|
@ -3,8 +3,8 @@ import { templateSeeds } from "./seeds";
|
|||||||
|
|
||||||
export const db = new Dexie("drawDB");
|
export const db = new Dexie("drawDB");
|
||||||
|
|
||||||
db.version(5).stores({
|
db.version(6).stores({
|
||||||
diagrams: "++id, lastModified",
|
diagrams: "++id, lastModified, loadedFromGistId",
|
||||||
templates: "++id, custom",
|
templates: "++id, custom",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
5
src/data/octokit.js
Normal file
5
src/data/octokit.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { Octokit } from "octokit";
|
||||||
|
|
||||||
|
export const octokit = new Octokit({
|
||||||
|
auth: import.meta.env.VITE_GITHUB_ACCESS_TOKEN,
|
||||||
|
});
|
@ -236,7 +236,12 @@ const en = {
|
|||||||
empty_index_name: "Declared an index with no name in table '{{tableName}}'",
|
empty_index_name: "Declared an index with no name in table '{{tableName}}'",
|
||||||
didnt_find_diagram: "Oops! Didn't find the diagram.",
|
didnt_find_diagram: "Oops! Didn't find the diagram.",
|
||||||
unsigned: "Unsigned",
|
unsigned: "Unsigned",
|
||||||
|
share: "Share",
|
||||||
|
copy_link: "Copy link",
|
||||||
readme: "README",
|
readme: "README",
|
||||||
|
failed_to_load: "Failed to load. Make sure the link is correct.",
|
||||||
|
share_info:
|
||||||
|
"* Sharing this link will not create a live real-time collaboration session.",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,6 +58,10 @@
|
|||||||
background-color: rgba(var(--semi-blue-6), 1);
|
background-color: rgba(var(--semi-blue-6), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.semi-spin-wrapper{
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
|
@ -23,6 +23,8 @@ export const getModalTitle = (modal) => {
|
|||||||
return i18n.t("table_width");
|
return i18n.t("table_width");
|
||||||
case MODAL.LANGUAGE:
|
case MODAL.LANGUAGE:
|
||||||
return i18n.t("language");
|
return i18n.t("language");
|
||||||
|
case MODAL.SHARE:
|
||||||
|
return i18n.t("share");
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -55,6 +57,8 @@ export const getOkText = (modal) => {
|
|||||||
return i18n.t("save_as");
|
return i18n.t("save_as");
|
||||||
case MODAL.NEW:
|
case MODAL.NEW:
|
||||||
return i18n.t("create");
|
return i18n.t("create");
|
||||||
|
case MODAL.SHARE:
|
||||||
|
return i18n.t("share");
|
||||||
default:
|
default:
|
||||||
return i18n.t("confirm");
|
return i18n.t("confirm");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user