From 01c0eb201ebc3d9b41e2d8397350345c19612a1c Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Sun, 28 Jul 2024 13:07:00 +0300 Subject: [PATCH] F: Implement dev helper features --- README.md | 1 + rsconcept/frontend/package-lock.json | 15 + rsconcept/frontend/package.json | 1 + rsconcept/frontend/public/db_schema.svg | 1134 +++++++++++++++++ .../src/app/Navigation/UserDropdown.tsx | 28 + rsconcept/frontend/src/app/Router.tsx | 9 +- rsconcept/frontend/src/app/urls.ts | 7 +- rsconcept/frontend/src/components/Icons.tsx | 2 + .../frontend/src/pages/DatabaseSchemaPage.tsx | 31 + rsconcept/frontend/src/utils/constants.ts | 3 +- 10 files changed, 1226 insertions(+), 5 deletions(-) create mode 100644 rsconcept/frontend/public/db_schema.svg create mode 100644 rsconcept/frontend/src/pages/DatabaseSchemaPage.tsx diff --git a/README.md b/README.md index 65286a93..9d0f496d 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ This readme file is used mostly to document project dependencies and conventions - react-error-boundary - react-pdf - react-tooltip + - react-zoom-pan-pinch - reactflow - js-file-download - use-debounce diff --git a/rsconcept/frontend/package-lock.json b/rsconcept/frontend/package-lock.json index de3b4312..10688bac 100644 --- a/rsconcept/frontend/package-lock.json +++ b/rsconcept/frontend/package-lock.json @@ -29,6 +29,7 @@ "react-tabs": "^6.0.2", "react-toastify": "^10.0.5", "react-tooltip": "^5.27.1", + "react-zoom-pan-pinch": "^3.6.1", "reactflow": "^11.11.4", "reagraph": "^4.19.2", "use-debounce": "^10.0.1" @@ -10542,6 +10543,20 @@ "react-dom": ">=16.13" } }, + "node_modules/react-zoom-pan-pinch": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.6.1.tgz", + "integrity": "sha512-SdPqdk7QDSV7u/WulkFOi+cnza8rEZ0XX4ZpeH7vx3UZEg7DoyuAy3MCmm+BWv/idPQL2Oe73VoC0EhfCN+sZQ==", + "license": "MIT", + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, "node_modules/reactflow": { "version": "11.11.4", "resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.11.4.tgz", diff --git a/rsconcept/frontend/package.json b/rsconcept/frontend/package.json index 6dde647c..ad886ae9 100644 --- a/rsconcept/frontend/package.json +++ b/rsconcept/frontend/package.json @@ -33,6 +33,7 @@ "react-tabs": "^6.0.2", "react-toastify": "^10.0.5", "react-tooltip": "^5.27.1", + "react-zoom-pan-pinch": "^3.6.1", "reactflow": "^11.11.4", "reagraph": "^4.19.2", "use-debounce": "^10.0.1" diff --git a/rsconcept/frontend/public/db_schema.svg b/rsconcept/frontend/public/db_schema.svg new file mode 100644 index 00000000..5aae97d8 --- /dev/null +++ b/rsconcept/frontend/public/db_schema.svg @@ -0,0 +1,1134 @@ + + +model_graph + + +cluster_django_contrib_auth + +           +           +django.contrib.auth +           +           + + +cluster_django_contrib_admin + +           +           +django.contrib.admin +           +           + + +cluster_django_contrib_contenttypes + +           +           +django.contrib.contenttypes +           +           + + +cluster_django_contrib_sessions + +           +           +django.contrib.sessions +           +           + + +cluster_django_rest_passwordreset + +           +           +django_rest_passwordreset +           +           + + +cluster_apps_library + +           +           +apps.library +           +           + + +cluster_apps_rsform + +           +           +apps.rsform +           +           + + +cluster_apps_oss + +           +           +apps.oss +           +           + + + +django_contrib_admin_models_LogEntry + + +       +      LogEntry       +       +id +       +       +AutoField +       +       +content_type +       +       +ForeignKey (id) +       +       +user +       +       +ForeignKey (id) +       +       +action_flag +       +       +PositiveSmallIntegerField +       +       +action_time +       +       +DateTimeField +       +       +change_message +       +       +TextField +       +       +object_id +       +       +TextField +       +       +object_repr +       +       +CharField +       + + + + +django_contrib_auth_models_User + + +       +      User +< +AbstractUser +>       +       +id +       +       +AutoField +       +       +date_joined +       +       +DateTimeField +       +       +email +       +       +EmailField +       +       +first_name +       +       +CharField +       +       +is_active +       +       +BooleanField +       +       +is_staff +       +       +BooleanField +       +       +is_superuser +       +       +BooleanField +       +       +last_login +       +       +DateTimeField +       +       +last_name +       +       +CharField +       +       +password +       +       +CharField +       +       +username +       +       +CharField +       + + + + +django_contrib_admin_models_LogEntry->django_contrib_auth_models_User + + + user (logentry) + + + +django_contrib_contenttypes_models_ContentType + + +       +      ContentType       +       +id +       +       +AutoField +       +       +app_label +       +       +CharField +       +       +model +       +       +CharField +       + + + + +django_contrib_admin_models_LogEntry->django_contrib_contenttypes_models_ContentType + + + content_type (logentry) + + + +django_contrib_auth_models_AbstractUser + + +       +      AbstractUser +< +AbstractBaseUser,PermissionsMixin +>       +       +date_joined +       +       +DateTimeField +       +       +email +       +       +EmailField +       +       +first_name +       +       +CharField +       +       +is_active +       +       +BooleanField +       +       +is_staff +       +       +BooleanField +       +       +is_superuser +       +       +BooleanField +       +       +last_login +       +       +DateTimeField +       +       +last_name +       +       +CharField +       +       +password +       +       +CharField +       +       +username +       +       +CharField +       + + + + +django_contrib_auth_base_user_AbstractBaseUser + + +   +AbstractBaseUser +   + + + +django_contrib_auth_models_AbstractUser->django_contrib_auth_base_user_AbstractBaseUser + + + abstract +inheritance + + + +django_contrib_auth_models_PermissionsMixin + + +   +PermissionsMixin +   + + + +django_contrib_auth_models_AbstractUser->django_contrib_auth_models_PermissionsMixin + + + abstract +inheritance + + + +django_contrib_auth_models_Permission + + +       +      Permission       +       +id +       +       +AutoField +       +       +content_type +       +       +ForeignKey (id) +       +       +codename +       +       +CharField +       +       +name +       +       +CharField +       + + + + +django_contrib_auth_models_Permission->django_contrib_contenttypes_models_ContentType + + + content_type (permission) + + + +django_contrib_auth_models_Group + + +       +      Group       +       +id +       +       +AutoField +       +       +name +       +       +CharField +       + + + + +django_contrib_auth_models_Group->django_contrib_auth_models_Permission + + + + permissions (group) + + + +django_contrib_auth_models_User->django_contrib_auth_models_AbstractUser + + + abstract +inheritance + + + +django_contrib_auth_models_User->django_contrib_auth_models_Permission + + + + user_permissions (user) + + + +django_contrib_auth_models_User->django_contrib_auth_models_Group + + + + groups (user) + + + +django_contrib_sessions_base_session_AbstractBaseSession + + +       +      AbstractBaseSession       +       +expire_date +       +       +DateTimeField +       +       +session_data +       +       +TextField +       + + + + +django_contrib_sessions_models_Session + + +       +      Session +< +AbstractBaseSession +>       +       +session_key +       +       +CharField +       +       +expire_date +       +       +DateTimeField +       +       +session_data +       +       +TextField +       + + + + +django_contrib_sessions_models_Session->django_contrib_sessions_base_session_AbstractBaseSession + + + abstract +inheritance + + + +django_rest_passwordreset_models_ResetPasswordToken + + +       +      ResetPasswordToken       +       +id +       +       +AutoField +       +       +user +       +       +ForeignKey (id) +       +       +created_at +       +       +DateTimeField +       +       +ip_address +       +       +GenericIPAddressField +       +       +key +       +       +CharField +       +       +user_agent +       +       +CharField +       + + + + +django_rest_passwordreset_models_ResetPasswordToken->django_contrib_auth_models_User + + + user (password_reset_tokens) + + + +apps_library_models_Editor_Editor + + +       +      Editor       +       +id +       +       +BigAutoField +       +       +editor +       +       +ForeignKey (id) +       +       +item +       +       +ForeignKey (id) +       +       +time_create +       +       +DateTimeField +       + + + + +apps_library_models_Editor_Editor->django_contrib_auth_models_User + + + editor (editor) + + + +apps_library_models_LibraryItem_LibraryItem + + +       +      LibraryItem       +       +id +       +       +BigAutoField +       +       +owner +       +       +ForeignKey (id) +       +       +access_policy +       +       +CharField +       +       +alias +       +       +CharField +       +       +comment +       +       +TextField +       +       +item_type +       +       +CharField +       +       +location +       +       +TextField +       +       +read_only +       +       +BooleanField +       +       +time_create +       +       +DateTimeField +       +       +time_update +       +       +DateTimeField +       +       +title +       +       +TextField +       +       +visible +       +       +BooleanField +       + + + + +apps_library_models_Editor_Editor->apps_library_models_LibraryItem_LibraryItem + + + item (editor) + + + +apps_library_models_Subscription_Subscription + + +       +      Subscription       +       +id +       +       +BigAutoField +       +       +item +       +       +ForeignKey (id) +       +       +user +       +       +ForeignKey (id) +       + + + + +apps_library_models_Subscription_Subscription->django_contrib_auth_models_User + + + user (subscription) + + + +apps_library_models_Subscription_Subscription->apps_library_models_LibraryItem_LibraryItem + + + item (subscription) + + + +apps_library_models_Version_Version + + +       +      Version       +       +id +       +       +BigAutoField +       +       +item +       +       +ForeignKey (id) +       +       +data +       +       +JSONField +       +       +description +       +       +TextField +       +       +time_create +       +       +DateTimeField +       +       +version +       +       +CharField +       + + + + +apps_library_models_Version_Version->apps_library_models_LibraryItem_LibraryItem + + + item (version) + + + +apps_library_models_LibraryItem_LibraryItem->django_contrib_auth_models_User + + + owner (libraryitem) + + + +apps_library_models_LibraryTemplate_LibraryTemplate + + +       +      LibraryTemplate       +       +id +       +       +BigAutoField +       +       +lib_source +       +       +ForeignKey (id) +       + + + + +apps_library_models_LibraryTemplate_LibraryTemplate->apps_library_models_LibraryItem_LibraryItem + + + lib_source (librarytemplate) + + + +apps_rsform_models_Constituenta_Constituenta + + +       +      Constituenta       +       +id +       +       +BigAutoField +       +       +schema +       +       +ForeignKey (id) +       +       +alias +       +       +CharField +       +       +convention +       +       +TextField +       +       +cst_type +       +       +CharField +       +       +definition_formal +       +       +TextField +       +       +definition_raw +       +       +TextField +       +       +definition_resolved +       +       +TextField +       +       +order +       +       +PositiveIntegerField +       +       +term_forms +       +       +JSONField +       +       +term_raw +       +       +TextField +       +       +term_resolved +       +       +TextField +       + + + + +apps_rsform_models_Constituenta_Constituenta->apps_library_models_LibraryItem_LibraryItem + + + schema (constituenta) + + + +apps_oss_models_Argument_Argument + + +       +      Argument       +       +id +       +       +BigAutoField +       +       +argument +       +       +ForeignKey (id) +       +       +operation +       +       +ForeignKey (id) +       + + + + +apps_oss_models_Operation_Operation + + +       +      Operation       +       +id +       +       +BigAutoField +       +       +oss +       +       +ForeignKey (id) +       +       +result +       +       +ForeignKey (id) +       +       +alias +       +       +CharField +       +       +comment +       +       +TextField +       +       +operation_type +       +       +CharField +       +       +position_x +       +       +FloatField +       +       +position_y +       +       +FloatField +       +       +sync_text +       +       +BooleanField +       +       +title +       +       +TextField +       + + + + +apps_oss_models_Argument_Argument->apps_oss_models_Operation_Operation + + + operation (arguments) + + + +apps_oss_models_Argument_Argument->apps_oss_models_Operation_Operation + + + argument (descendants) + + + +apps_oss_models_Inheritance_Inheritance + + +       +      Inheritance       +       +id +       +       +BigAutoField +       +       +child +       +       +ForeignKey (id) +       +       +parent +       +       +ForeignKey (id) +       + + + + +apps_oss_models_Inheritance_Inheritance->apps_rsform_models_Constituenta_Constituenta + + + parent (as_parent) + + + +apps_oss_models_Inheritance_Inheritance->apps_rsform_models_Constituenta_Constituenta + + + child (as_child) + + + +apps_oss_models_Operation_Operation->apps_library_models_LibraryItem_LibraryItem + + + oss (items) + + + +apps_oss_models_Operation_Operation->apps_library_models_LibraryItem_LibraryItem + + + result (producer) + + + +apps_oss_models_Substitution_Substitution + + +       +      Substitution       +       +id +       +       +BigAutoField +       +       +operation +       +       +ForeignKey (id) +       +       +original +       +       +ForeignKey (id) +       +       +substitution +       +       +ForeignKey (id) +       +       +transfer_term +       +       +BooleanField +       + + + + +apps_oss_models_Substitution_Substitution->apps_rsform_models_Constituenta_Constituenta + + + original (as_original) + + + +apps_oss_models_Substitution_Substitution->apps_rsform_models_Constituenta_Constituenta + + + substitution (as_substitute) + + + +apps_oss_models_Substitution_Substitution->apps_oss_models_Operation_Operation + + + operation (substitution) + + + \ No newline at end of file diff --git a/rsconcept/frontend/src/app/Navigation/UserDropdown.tsx b/rsconcept/frontend/src/app/Navigation/UserDropdown.tsx index 8311fbb2..0e5fb7cb 100644 --- a/rsconcept/frontend/src/app/Navigation/UserDropdown.tsx +++ b/rsconcept/frontend/src/app/Navigation/UserDropdown.tsx @@ -3,11 +3,13 @@ import { IconAdminOff, IconDarkTheme, IconDatabase, + IconDBStructure, IconHelp, IconHelpOff, IconImage, IconLightTheme, IconLogout, + IconRESTapi, IconUser } from '@/components/Icons'; import { CProps } from '@/components/props'; @@ -49,6 +51,16 @@ function UserDropdown({ isOpen, hideDropdown }: UserDropdownProps) { router.push(urls.icons, event.ctrlKey || event.metaKey); } + function gotoRestApi() { + hideDropdown(); + router.push(urls.rest_api, true); + } + + function gotoDatabaseSchema(event: CProps.EventMouse) { + hideDropdown(); + router.push(urls.database_schema, event.ctrlKey || event.metaKey); + } + function handleToggleDarkMode() { hideDropdown(); toggleDarkMode(); @@ -82,6 +94,14 @@ function UserDropdown({ isOpen, hideDropdown }: UserDropdownProps) { onClick={toggleAdminMode} /> ) : null} + {user?.is_staff ? ( + } + className='border-t' + onClick={gotoRestApi} + /> + ) : null} {user?.is_staff ? ( ) : null} + {user?.is_staff ? ( + } + onClick={gotoDatabaseSchema} + className='border-b' + /> + ) : null} }, + { + path: routes.manuals, + element: + }, { path: `${routes.icons}`, element: }, { - path: routes.manuals, - element: + path: `${routes.database_schema}`, + element: } ] } diff --git a/rsconcept/frontend/src/app/urls.ts b/rsconcept/frontend/src/app/urls.ts index c7fc284d..d96a6759 100644 --- a/rsconcept/frontend/src/app/urls.ts +++ b/rsconcept/frontend/src/app/urls.ts @@ -19,7 +19,8 @@ export const routes = { help: 'manuals', rsforms: 'rsforms', oss: 'oss', - icons: 'icons' + icons: 'icons', + database_schema: 'database-schema' }; interface SchemaProps { @@ -39,11 +40,13 @@ interface OssProps { */ export const urls = { admin: `${buildConstants.backend}/admin`, + rest_api: `${buildConstants.backend}/`, home: '/', login: `/${routes.login}`, login_hint: (userName: string) => `/login?username=${userName}`, profile: `/${routes.profile}`, - icons: `/icons`, + icons: `/${routes.icons}`, + database_schema: `/${routes.database_schema}`, signup: `/${routes.signup}`, library: `/${routes.library}`, library_filter: (strategy: string) => `/library?filter=${strategy}`, diff --git a/rsconcept/frontend/src/components/Icons.tsx b/rsconcept/frontend/src/components/Icons.tsx index 4ae18681..34d41ae1 100644 --- a/rsconcept/frontend/src/components/Icons.tsx +++ b/rsconcept/frontend/src/components/Icons.tsx @@ -65,6 +65,8 @@ export { GiHoneycomb as IconOSS } from 'react-icons/gi'; export { RiHexagonLine as IconRSForm } from 'react-icons/ri'; export { LuArchive as IconArchive } from 'react-icons/lu'; export { LuDatabase as IconDatabase } from 'react-icons/lu'; +export { LuView as IconDBStructure } from 'react-icons/lu'; +export { LuPlaneTakeoff as IconRESTapi } from 'react-icons/lu'; export { LuImage as IconImage } from 'react-icons/lu'; export { TbColumns as IconList } from 'react-icons/tb'; export { ImStack as IconVersions } from 'react-icons/im'; diff --git a/rsconcept/frontend/src/pages/DatabaseSchemaPage.tsx b/rsconcept/frontend/src/pages/DatabaseSchemaPage.tsx new file mode 100644 index 00000000..26a20cbc --- /dev/null +++ b/rsconcept/frontend/src/pages/DatabaseSchemaPage.tsx @@ -0,0 +1,31 @@ +'use client'; + +import { useLayoutEffect, useMemo } from 'react'; +import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch'; + +import AnimateFade from '@/components/wrap/AnimateFade'; +import { useConceptOptions } from '@/context/ConceptOptionsContext'; +import { resources } from '@/utils/constants'; + +function DatabaseSchemaPage() { + const { calculateHeight, setNoFooter } = useConceptOptions(); + + const panelHeight = useMemo(() => calculateHeight('0px'), [calculateHeight]); + + useLayoutEffect(() => { + setNoFooter(true); + return () => setNoFooter(false); + }, [setNoFooter]); + + return ( + + + + Схема базы данных + + + + ); +} + +export default DatabaseSchemaPage; diff --git a/rsconcept/frontend/src/utils/constants.ts b/rsconcept/frontend/src/utils/constants.ts index fe71fa73..b2bd2936 100644 --- a/rsconcept/frontend/src/utils/constants.ts +++ b/rsconcept/frontend/src/utils/constants.ts @@ -54,7 +54,8 @@ export const patterns = { export const resources = { graph_font: '/DejaVu.ttf', privacy_policy: '/privacy.pdf', - logo: '/logo_full.svg' + logo: '/logo_full.svg', + db_schema: '/db_schema.svg' }; /**