├── .env ├── .flake8 ├── .gitignore ├── .isort.cfg ├── LICENSE ├── Makefile ├── README.md ├── application ├── Dockerfile ├── __init__.py ├── alembic.ini ├── api │ ├── __init__.py │ └── v1 │ │ ├── __init__.py │ │ ├── api.py │ │ ├── endpoints │ │ ├── __init__.py │ │ ├── access_tokens.py │ │ ├── applications.py │ │ ├── authorization.py │ │ ├── dashboard.py │ │ ├── events.py │ │ ├── helm.py │ │ ├── invitations.py │ │ ├── kubernetes.py │ │ ├── organizations.py │ │ ├── rules.py │ │ ├── services.py │ │ ├── templates.py │ │ └── users.py │ │ └── schemas │ │ ├── __init__.py │ │ ├── access_tokens.py │ │ ├── applications.py │ │ ├── common.py │ │ ├── events.py │ │ ├── helm.py │ │ ├── invitations.py │ │ ├── organization.py │ │ ├── rules.py │ │ ├── services.py │ │ ├── templates.py │ │ └── users.py ├── constants │ ├── __init__.py │ ├── access_tokens.py │ ├── applications.py │ ├── base_enum.py │ ├── common.py │ ├── events.py │ ├── helm.py │ ├── http.py │ ├── invitations.py │ ├── kubernetes.py │ ├── roles.py │ ├── rules.py │ ├── services.py │ └── templates.py ├── core │ ├── __init__.py │ ├── authentication.py │ └── configuration.py ├── crud │ ├── __init__.py │ ├── access_tokens.py │ ├── applications.py │ ├── base.py │ ├── events.py │ ├── invitations.py │ ├── organizations.py │ ├── rules.py │ ├── services.py │ ├── templates.py │ └── users.py ├── db │ ├── __init__.py │ ├── base_class.py │ ├── fields.py │ └── session.py ├── exceptions │ ├── __init__.py │ ├── application.py │ ├── base.py │ ├── common.py │ ├── db.py │ ├── helm.py │ ├── http.py │ ├── kubernetes.py │ ├── organization.py │ ├── rule.py │ ├── service.py │ ├── shell.py │ └── templates.py ├── instance.py ├── managers │ ├── __init__.py │ ├── access_tokens.py │ ├── applications.py │ ├── events.py │ ├── helm │ │ ├── __init__.py │ │ ├── manager.py │ │ └── schemas.py │ ├── http │ │ ├── __init__.py │ │ └── manager.py │ ├── invitations.py │ ├── kubernetes.py │ ├── organizations │ │ ├── __init__.py │ │ └── manager.py │ ├── rules │ │ ├── __init__.py │ │ ├── actions │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ └── manager.py │ │ ├── conditions │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── contains.py │ │ │ ├── equal.py │ │ │ ├── not_equal.py │ │ │ └── regex.py │ │ ├── manager.py │ │ └── schemas.py │ ├── services │ │ ├── __init__.py │ │ ├── manager.py │ │ └── schemas.py │ ├── templates.py │ └── users.py ├── migrations │ ├── README │ ├── env.py │ ├── script.py.mako │ └── versions │ │ ├── 2022-08-12_1453_initial_migration.py │ │ ├── 2022-08-16_1635_added_userinvitation_model.py │ │ ├── 2022-08-22_0823_optional_user_in_all_models.py │ │ ├── 2022-10-04_1902_added_role_field_to_user_model.py │ │ ├── 2022-10-04_1924_set_admin_role_to_all_users.py │ │ ├── 2022-10-17_1639_drop_old_templates.py │ │ ├── 2022-10-25_0821_create_procrastination_entities.py │ │ ├── 2022-10-26_1332_added_health_field_to_application_model.py │ │ ├── 2022-11-15_1028_added_event_model.py │ │ ├── 2022-11-17_1243_rename_application_statuses.py │ │ ├── 2022-11-18_1528_altered_event_enums.py │ │ ├── 2022-11-28_1606_added_application_ttl_property.py │ │ ├── 2022-12-21_1641_added_user_access_token_model.py │ │ └── 2022-12-23_1328_removed_creator_from_accesstoken_model.py ├── models │ ├── __init__.py │ ├── access_token.py │ ├── application.py │ ├── event.py │ ├── invitation.py │ ├── organization.py │ ├── rule.py │ ├── service.py │ ├── template.py │ └── user.py ├── pytest.ini ├── requirements.dev.txt ├── requirements.txt ├── schemas │ ├── __init__.py │ ├── access_tokens.py │ ├── common_types.py │ ├── events.py │ ├── kubernetes.py │ ├── organizations.py │ ├── templates │ │ ├── __init__.py │ │ ├── components.py │ │ ├── hooks.py │ │ ├── inputs.py │ │ ├── outputs.py │ │ ├── template.py │ │ └── validators.py │ └── users.py ├── services │ ├── __init__.py │ ├── helm │ │ ├── __init__.py │ │ ├── facade.py │ │ ├── schemas.py │ │ └── subcommands │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── dependency.py │ │ │ ├── get.py │ │ │ ├── history.py │ │ │ ├── install.py │ │ │ ├── list.py │ │ │ ├── release.py │ │ │ ├── repositories.py │ │ │ ├── rollback.py │ │ │ ├── search.py │ │ │ ├── show.py │ │ │ ├── uninstall.py │ │ │ └── upgrade.py │ ├── kubernetes │ │ ├── __init__.py │ │ ├── cli │ │ │ ├── __init__.py │ │ │ ├── facade.py │ │ │ └── subcommands │ │ │ │ ├── __init__.py │ │ │ │ ├── base.py │ │ │ │ ├── cluster_info.py │ │ │ │ ├── configuration.py │ │ │ │ └── logs.py │ │ ├── client.py │ │ └── schemas.py │ └── procrastinate │ │ ├── __init__.py │ │ ├── application.py │ │ └── tasks │ │ ├── __init__.py │ │ └── application │ │ ├── __init__.py │ │ ├── health_check.py │ │ ├── install_flow.py │ │ ├── terminate_flow.py │ │ ├── ttl_check.py │ │ ├── upgrade_flow.py │ │ └── utils.py ├── start-task-executor.sh ├── start.sh ├── tests │ ├── __init__.py │ ├── api │ │ ├── __init__.py │ │ └── v1 │ │ │ ├── __init__.py │ │ │ ├── test_helm.py │ │ │ ├── test_organization.py │ │ │ └── test_users.py │ ├── conftest.py │ └── fixtures │ │ ├── __init__.py │ │ ├── cluster_configuration.py │ │ └── k8s_deployment.py └── utils │ ├── __init__.py │ ├── achive.py │ ├── email.py │ ├── helm.py │ ├── invitation.py │ ├── kubernetes.py │ ├── paths.py │ ├── shell.py │ ├── template.py │ ├── temporary_file.py │ └── user.py ├── cli ├── Dockerfile ├── __init__.py ├── requirements.txt ├── schemas │ ├── __init__.py │ ├── applications.py │ ├── common.py │ └── templates.py ├── service-hub ├── service-hub.spec └── settings.py ├── credentials └── .gitignore ├── docker-compose-dev.yaml ├── docker-compose.yaml ├── docker-data └── .gitignore ├── documentation ├── JovianX_Service_Hub_Getting_Started.gif ├── README.md ├── helm-manager.md ├── service-hub-banner.png ├── service-hub-getting-started.mp4 ├── service_hub-vs-alternatives.md ├── signup.md └── templates.md ├── examples ├── 00-hello-world.yaml ├── 01-basic_example.yaml ├── 02-advanced-example.yaml └── redis.yaml └── frontend ├── .dockerignore ├── .env ├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .gitignore ├── .npmrc ├── CREDITS ├── Dockerfile ├── README.md ├── aliases.js ├── config-overrides.js ├── jsconfig.json ├── nginx.conf ├── package-lock.json ├── package.json ├── public ├── assets │ ├── fonts │ │ ├── inter │ │ │ ├── Inter-italic.var.woff2 │ │ │ ├── Inter-roman.var.woff2 │ │ │ └── inter.css │ │ ├── material-design-icons │ │ │ ├── MaterialIcons-Regular.woff2 │ │ │ ├── MaterialIcons.css │ │ │ ├── MaterialIconsOutlined-Regular.woff2 │ │ │ ├── MaterialIconsOutlined.css │ │ │ ├── MaterialIconsRound-Regular.woff2 │ │ │ ├── MaterialIconsRound.css │ │ │ ├── MaterialIconsSharp-Regular.woff2 │ │ │ ├── MaterialIconsSharp.css │ │ │ ├── MaterialIconsTwoTone-Regular.woff2 │ │ │ └── MaterialIconsTwoTone.css │ │ └── meteocons │ │ │ ├── Read Me.txt │ │ │ ├── demo-files │ │ │ ├── demo.css │ │ │ └── demo.js │ │ │ ├── demo.html │ │ │ ├── fonts │ │ │ ├── meteocons.svg │ │ │ ├── meteocons.ttf │ │ │ └── meteocons.woff │ │ │ ├── liga.js │ │ │ ├── selection.json │ │ │ └── style.css │ ├── icons │ │ ├── feather.svg │ │ ├── heroicons-outline.svg │ │ ├── heroicons-solid.svg │ │ ├── material-outline.svg │ │ ├── material-solid.svg │ │ └── material-twotone.svg │ ├── images │ │ ├── apps │ │ │ ├── contacts │ │ │ │ └── flags.png │ │ │ ├── ecommerce │ │ │ │ ├── a-walk-amongst-friends.jpg │ │ │ │ ├── braies-lake.jpg │ │ │ │ ├── fall-glow.jpg │ │ │ │ ├── first-snow.jpg │ │ │ │ ├── lago-di-braies.jpg │ │ │ │ ├── lago-di-sorapis.jpg │ │ │ │ ├── morain-lake.jpg │ │ │ │ ├── never-stop-changing.jpg │ │ │ │ ├── product-image-placeholder.png │ │ │ │ ├── reaching.jpg │ │ │ │ └── yosemite.jpg │ │ │ ├── help-center │ │ │ │ └── image-1.jpg │ │ │ ├── mailbox │ │ │ │ ├── birds-eye-sydney_preview.jpg │ │ │ │ ├── lake-of-carrezza_preview.png │ │ │ │ ├── mystery-forest_preview.jpg │ │ │ │ └── yosemite-national-park_preview.png │ │ │ ├── profile │ │ │ │ ├── a-walk-amongst-friends-small.jpg │ │ │ │ ├── braies-lake-small.jpg │ │ │ │ ├── fall-glow-small.jpg │ │ │ │ ├── first-snow-small.jpg │ │ │ │ ├── lago-di-braies-small.jpg │ │ │ │ ├── lago-di-sorapis-small.jpg │ │ │ │ ├── morain-lake-small.jpg │ │ │ │ ├── morain-lake.jpg │ │ │ │ ├── never-stop-changing-small.jpg │ │ │ │ ├── never-stop-changing.jpg │ │ │ │ ├── reaching-small.jpg │ │ │ │ └── yosemite-small.jpg │ │ │ └── scrumboard │ │ │ │ ├── calendar.jpg │ │ │ │ ├── header-1.jpg │ │ │ │ ├── header-2.jpg │ │ │ │ └── mail.jpg │ │ ├── avatars │ │ │ ├── brian-hughes.jpg │ │ │ ├── female-01.jpg │ │ │ ├── female-02.jpg │ │ │ ├── female-03.jpg │ │ │ ├── female-04.jpg │ │ │ ├── female-05.jpg │ │ │ ├── female-06.jpg │ │ │ ├── female-07.jpg │ │ │ ├── female-08.jpg │ │ │ ├── female-09.jpg │ │ │ ├── female-10.jpg │ │ │ ├── female-11.jpg │ │ │ ├── female-12.jpg │ │ │ ├── female-13.jpg │ │ │ ├── female-14.jpg │ │ │ ├── female-15.jpg │ │ │ ├── female-16.jpg │ │ │ ├── female-17.jpg │ │ │ ├── female-18.jpg │ │ │ ├── female-19.jpg │ │ │ ├── female-20.jpg │ │ │ ├── male-01.jpg │ │ │ ├── male-02.jpg │ │ │ ├── male-03.jpg │ │ │ ├── male-04.jpg │ │ │ ├── male-05.jpg │ │ │ ├── male-06.jpg │ │ │ ├── male-07.jpg │ │ │ ├── male-08.jpg │ │ │ ├── male-09.jpg │ │ │ ├── male-10.jpg │ │ │ ├── male-11.jpg │ │ │ ├── male-12.jpg │ │ │ ├── male-13.jpg │ │ │ ├── male-14.jpg │ │ │ ├── male-15.jpg │ │ │ ├── male-16.jpg │ │ │ ├── male-17.jpg │ │ │ ├── male-18.jpg │ │ │ ├── male-19.jpg │ │ │ ├── male-20.jpg │ │ │ └── user-default.png │ │ ├── cards │ │ │ ├── 01-320x200.jpg │ │ │ ├── 02-320x200.jpg │ │ │ ├── 03-320x200.jpg │ │ │ ├── 04-320x200.jpg │ │ │ ├── 05-320x200.jpg │ │ │ ├── 06-320x200.jpg │ │ │ ├── 07-320x200.jpg │ │ │ ├── 08-320x200.jpg │ │ │ ├── 09-320x200.jpg │ │ │ ├── 10-320x200.jpg │ │ │ ├── 11-512x512.jpg │ │ │ ├── 12-512x512.jpg │ │ │ ├── 13-160x160.jpg │ │ │ ├── 14-640x480.jpg │ │ │ ├── 15-640x480.jpg │ │ │ ├── 16-640x480.jpg │ │ │ ├── 17-640x480.jpg │ │ │ ├── 18-640x480.jpg │ │ │ ├── 19-640x480.jpg │ │ │ ├── 20-640x480.jpg │ │ │ ├── 21-640x480.jpg │ │ │ ├── 22-640x480.jpg │ │ │ ├── 23-640x480.jpg │ │ │ ├── 24-640x480.jpg │ │ │ ├── 25-640x480.jpg │ │ │ ├── 26-640x480.jpg │ │ │ ├── 27-640x480.jpg │ │ │ ├── 28-640x480.jpg │ │ │ ├── 29-640x480.jpg │ │ │ ├── 30-640x480.jpg │ │ │ ├── 31-640x480.jpg │ │ │ ├── 32-640x480.jpg │ │ │ ├── 33-640x480.jpg │ │ │ ├── 34-640x480.jpg │ │ │ ├── 35-640x480.jpg │ │ │ ├── 36-640x480.jpg │ │ │ ├── avatar-400x400.jpg │ │ │ ├── coffee-shop-01-320x200.jpg │ │ │ ├── coffee-shop-02-512x512.jpg │ │ │ ├── coffee-shop-03-320x320.jpg │ │ │ ├── mansion-01-320x200.jpg │ │ │ ├── product-01-224x256.jpg │ │ │ ├── sneakers-01-320x200.jpg │ │ │ ├── sneakers-02-448x560.jpg │ │ │ └── sneakers-03-448x560.jpg │ │ ├── demo-content │ │ │ └── morain-lake.jpg │ │ ├── etc │ │ │ ├── directory-structure.png │ │ │ └── sample-file-preview.jpg │ │ ├── flags │ │ │ ├── SA.svg │ │ │ ├── TR.svg │ │ │ ├── US.svg │ │ │ └── where-to-find-other-flags.txt │ │ ├── logo-mini-white.png │ │ ├── logo-mini-white1.png │ │ ├── logo-mini.png │ │ ├── logo-white.png │ │ ├── logo.png │ │ ├── logo │ │ │ ├── logo-text-on-dark.svg │ │ │ ├── logo-text.svg │ │ │ └── logo.svg │ │ └── pages │ │ │ ├── help-center │ │ │ └── image-1.jpg │ │ │ └── profile │ │ │ └── cover.jpg │ └── tailwind-base.css ├── env │ └── env_vars.example.js ├── favicon.ico ├── index.html ├── manifest.json └── material-ui-static │ ├── brand.png │ ├── carbon.png │ ├── favicon.ico │ ├── icons │ ├── 150x150.png │ ├── 152x152.png │ ├── 192x192.png │ ├── 256x256.png │ ├── 310x310.png │ ├── 384x384.png │ ├── 48x48.png │ ├── 512x512.png │ ├── 70x70.png │ └── 96x96.png │ ├── images │ ├── avatar │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ └── 7.jpg │ ├── blokt.jpg │ ├── cards │ │ ├── contemplative-reptile.jpg │ │ ├── live-from-space.jpg │ │ └── paella.jpg │ ├── color │ │ └── colorTool.png │ ├── customization │ │ └── dev-tools.png │ ├── font-size.gif │ ├── grid-list │ │ ├── bike.jpg │ │ ├── breakfast.jpg │ │ ├── burgers.jpg │ │ ├── camera.jpg │ │ ├── hats.jpg │ │ ├── honey.jpg │ │ ├── morning.jpg │ │ ├── mushroom.jpg │ │ ├── olive.jpg │ │ ├── plant.jpg │ │ ├── star.jpg │ │ └── vegetables.jpg │ ├── grid │ │ └── complex.jpg │ ├── icons │ │ └── icons.png │ ├── material-ui-logo.svg │ ├── misc │ │ └── circle.png │ ├── progress │ │ └── heavy-load.gif │ ├── showcase │ │ ├── aexdownloadcenter.jpg │ │ ├── arkoclub.jpg │ │ ├── audionodes.jpg │ │ ├── barks.jpg │ │ ├── bethesda.jpg │ │ ├── bitcambio.jpg │ │ ├── builderbook.jpg │ │ ├── cityads.jpg │ │ ├── cloudhealth.jpg │ │ ├── code-typing-tutor.png │ │ ├── codementor.jpg │ │ ├── collegeai.jpg │ │ ├── comet.jpg │ │ ├── commitswimming.jpg │ │ ├── cryptoverview.jpg │ │ ├── dropdesk.jpg │ │ ├── eostoolkit.jpg │ │ ├── eq3.jpg │ │ ├── eventhi.jpg │ │ ├── fizix.jpg │ │ ├── flink.jpg │ │ ├── fluxguard.jpg │ │ ├── forex.jpg │ │ ├── govx.jpg │ │ ├── hijup.jpg │ │ ├── hkn.jpg │ │ ├── housecall.jpg │ │ ├── icebergfinder.jpg │ │ ├── ifit.jpg │ │ ├── johnnymetrics.jpg │ │ ├── learnseeker.jpg │ │ ├── leroymerlin.jpg │ │ ├── lesswrong.jpg │ │ ├── localinsights.jpg │ │ ├── localmonero.jpg │ │ ├── magicmondayz.jpg │ │ ├── manty.jpg │ │ ├── melbournemint.jpg │ │ ├── metafact.jpg │ │ ├── modole.jpg │ │ ├── mqtt-explorer.png │ │ ├── neotracker.jpg │ │ ├── npm-registry-browser.jpg │ │ ├── numerai.jpg │ │ ├── odigeo.jpg │ │ ├── oneplanetcrowd.jpg │ │ ├── oneshotmove.jpg │ │ ├── openclassrooms.jpg │ │ ├── persona.jpg │ │ ├── photoutils.jpg │ │ ├── pilcro.jpg │ │ ├── planalyze.jpg │ │ ├── pointer.jpg │ │ ├── posters-galore.jpg │ │ ├── quintoandar.png │ │ ├── rarebits.jpg │ │ ├── roast.jpg │ │ ├── rung.jpg │ │ ├── selfeducationapp.jpg │ │ ├── sfrpresse.jpg │ │ ├── slidesup.jpg │ │ ├── snippets.jpg │ │ ├── sweek.jpg │ │ ├── swimmy.jpg │ │ ├── tentu.jpg │ │ ├── themediaant.jpg │ │ ├── trafikito-monitoring.jpg │ │ ├── tree.jpg │ │ ├── tudiscovery.jpg │ │ ├── typekev.jpg │ │ └── venuemob.jpg │ ├── templates │ │ ├── album.png │ │ ├── blog.png │ │ ├── checkout.png │ │ ├── dashboard.png │ │ ├── pricing.png │ │ ├── sign-in-side.png │ │ ├── sign-in.png │ │ ├── sign-up.png │ │ └── sticky-footer.png │ ├── text-fields │ │ └── shrink.png │ ├── themes-dark.jpg │ ├── themes-light.jpg │ └── users │ │ ├── bethesda.png │ │ ├── capgemini.png │ │ ├── nasa.png │ │ ├── uniqlo.png │ │ └── walmart-labs.png │ ├── logo.png │ └── manifest.json ├── src ├── @fuse │ ├── colors │ │ ├── fuseDark.js │ │ ├── index.js │ │ └── skyBlue.js │ ├── core │ │ ├── BrowserRouter │ │ │ ├── BrowserRouter.js │ │ │ └── index.js │ │ ├── DemoContent │ │ │ ├── DemoContent.js │ │ │ └── index.js │ │ ├── DemoSidebarContent │ │ │ ├── DemoSidebarContent.js │ │ │ └── index.js │ │ ├── FuseAuthorization │ │ │ ├── FuseAuthorization.js │ │ │ └── index.js │ │ ├── FuseCountdown │ │ │ ├── FuseCountdown.js │ │ │ └── index.js │ │ ├── FuseDialog │ │ │ ├── FuseDialog.js │ │ │ └── index.js │ │ ├── FuseExample │ │ │ ├── DemoFrame.js │ │ │ ├── FuseExample.js │ │ │ └── index.js │ │ ├── FuseHighlight │ │ │ ├── FuseHighlight.js │ │ │ ├── index.js │ │ │ └── prism-languages.js │ │ ├── FuseLayout │ │ │ ├── FuseLayout.js │ │ │ └── index.js │ │ ├── FuseLoading │ │ │ ├── FuseLoading.js │ │ │ └── index.js │ │ ├── FuseMessage │ │ │ ├── FuseMessage.js │ │ │ └── index.js │ │ ├── FuseNavigation │ │ │ ├── FuseNavBadge.js │ │ │ ├── FuseNavItem.js │ │ │ ├── FuseNavigation.js │ │ │ ├── horizontal │ │ │ │ ├── FuseNavHorizontalLayout1.js │ │ │ │ └── types │ │ │ │ │ ├── FuseNavHorizontalCollapse.js │ │ │ │ │ ├── FuseNavHorizontalGroup.js │ │ │ │ │ ├── FuseNavHorizontalItem.js │ │ │ │ │ └── FuseNavHorizontalLink.js │ │ │ ├── index.js │ │ │ └── vertical │ │ │ │ ├── FuseNavVerticalLayout1.js │ │ │ │ ├── FuseNavVerticalLayout2.js │ │ │ │ └── types │ │ │ │ ├── FuseNavVerticalCollapse.js │ │ │ │ ├── FuseNavVerticalGroup.js │ │ │ │ ├── FuseNavVerticalItem.js │ │ │ │ ├── FuseNavVerticalLink.js │ │ │ │ └── FuseNavVerticalTab.js │ │ ├── FusePageCarded │ │ │ ├── FusePageCarded.js │ │ │ ├── FusePageCardedHeader.js │ │ │ ├── FusePageCardedSidebar.js │ │ │ ├── FusePageCardedSidebarContent.js │ │ │ └── index.js │ │ ├── FusePageSimple │ │ │ ├── FusePageSimple.js │ │ │ ├── FusePageSimpleHeader.js │ │ │ ├── FusePageSimpleSidebar.js │ │ │ ├── FusePageSimpleSidebarContent.js │ │ │ └── index.js │ │ ├── FuseScrollbars │ │ │ ├── FuseScrollbars.js │ │ │ └── index.js │ │ ├── FuseSearch │ │ │ ├── FuseSearch.js │ │ │ └── index.js │ │ ├── FuseSettings │ │ │ ├── FuseSettings.js │ │ │ ├── index.js │ │ │ └── palette-generator │ │ │ │ ├── PalettePreview.js │ │ │ │ ├── PaletteSelector.js │ │ │ │ └── SectionPreview.js │ │ ├── FuseShortcuts │ │ │ ├── FuseShortcuts.js │ │ │ └── index.js │ │ ├── FuseSidePanel │ │ │ ├── FuseSidePanel.js │ │ │ └── index.js │ │ ├── FuseSplashScreen │ │ │ ├── FuseSplashScreen.js │ │ │ └── index.js │ │ ├── FuseSuspense │ │ │ ├── FuseSuspense.js │ │ │ └── index.js │ │ ├── FuseSvgIcon │ │ │ ├── FuseSvgIcon.js │ │ │ └── index.js │ │ ├── FuseTheme │ │ │ ├── FuseTheme.js │ │ │ └── index.js │ │ ├── FuseThemeSchemes │ │ │ ├── FuseThemeSchemes.js │ │ │ └── index.js │ │ ├── NavLinkAdapter │ │ │ ├── NavLinkAdapter.js │ │ │ └── index.js │ │ ├── withRouter │ │ │ ├── index.js │ │ │ └── withRouter.js │ │ └── withRouterAndRef │ │ │ ├── index.js │ │ │ └── withRouterAndRef.js │ ├── default-settings │ │ ├── FuseDefaultSettings.js │ │ └── index.js │ ├── hooks │ │ ├── index.js │ │ ├── useDebounce.js │ │ ├── useDeepCompareEffect.js │ │ ├── useEventListener.js │ │ ├── useForm.js │ │ ├── usePrevious.js │ │ ├── useThemeMediaQuery.js │ │ ├── useTimeout.js │ │ └── useUpdateEffect.js │ ├── tailwind │ │ └── plugins │ │ │ └── icon-size.js │ └── utils │ │ ├── FuseUtils.js │ │ └── index.js ├── @history │ ├── @history.js │ └── index.js ├── @lodash │ ├── @lodash.js │ └── index.js ├── @mock-api │ ├── api │ │ ├── auth-api.js │ │ └── notifications-api.js │ ├── index.js │ ├── mock-api.json │ └── mock.js ├── app │ ├── App.js │ ├── AppContext.js │ ├── api │ │ ├── accessTokens.js │ │ ├── applications.js │ │ ├── charts.js │ │ ├── clusters.js │ │ ├── dashboard.js │ │ ├── events.js │ │ ├── index.js │ │ ├── invitations.js │ │ ├── kubernetes.js │ │ ├── releases.js │ │ ├── repositories.js │ │ ├── services.js │ │ ├── templates.js │ │ └── users.js │ ├── auth │ │ ├── AuthContext.js │ │ ├── authRoles.js │ │ ├── index.js │ │ └── services │ │ │ └── jwtService │ │ │ ├── index.js │ │ │ ├── jwtService.js │ │ │ └── jwtServiceConfig.js │ ├── configs │ │ ├── navigation-i18n │ │ │ ├── ar.js │ │ │ ├── en.js │ │ │ └── tr.js │ │ ├── navigationConfig.js │ │ ├── routesConfig.js │ │ ├── settingsConfig.js │ │ └── themesConfig.js │ ├── constants │ │ ├── API.js │ │ ├── auth.js │ │ ├── categoriesOfEvents.js │ │ ├── kubeconfigUrl.js │ │ └── paths.js │ ├── hooks │ │ └── useGetMe.js │ ├── main │ │ ├── 404 │ │ │ └── Error404Page.js │ │ ├── access-tokens │ │ │ ├── AccessTokenStatusModal.js │ │ │ ├── AccessTokens.js │ │ │ ├── AccessTokensConfig.js │ │ │ ├── AccessTokensPage.js │ │ │ ├── AccessTokensTable.js │ │ │ ├── CreateAccessTokenModal.js │ │ │ ├── DeleteAccessTokenModal.js │ │ │ └── TokenTooltip.js │ │ ├── applications │ │ │ ├── ApplicationDetails │ │ │ │ ├── Application.js │ │ │ │ ├── ApplicationDetailsConfig.js │ │ │ │ ├── ApplicationItem.js │ │ │ │ ├── ApplicationTable.js │ │ │ │ ├── ApplicationTabs │ │ │ │ │ ├── ApplicationTabs.js │ │ │ │ │ └── TabValues │ │ │ │ │ │ ├── ApplicationEvents.js │ │ │ │ │ │ └── ApplicationValues.js │ │ │ │ └── index.js │ │ │ ├── ApplicationTtl.js │ │ │ ├── Applications.js │ │ │ ├── ApplicationsConfig.js │ │ │ ├── ApplicationsModal.js │ │ │ ├── ApplicationsTable.js │ │ │ ├── DeleteApplicationModal.js │ │ │ ├── NamespacesSelect.js │ │ │ ├── TemplateInputs │ │ │ │ ├── TemplateInputs.js │ │ │ │ ├── TypeCheckbox.js │ │ │ │ ├── TypeNumber.js │ │ │ │ ├── TypePassword.js │ │ │ │ ├── TypeRadio.js │ │ │ │ ├── TypeSelect.js │ │ │ │ ├── TypeSlider.js │ │ │ │ ├── TypeSwitch.js │ │ │ │ ├── TypeText.js │ │ │ │ └── TypeTextarea.js │ │ │ └── index.js │ │ ├── charts │ │ │ ├── Charts.js │ │ │ ├── ChartsConfig.js │ │ │ ├── ChartsFilters.js │ │ │ ├── ChartsModal.js │ │ │ ├── ChartsTable.js │ │ │ ├── NamespacesSelect.js │ │ │ ├── VersionsSelect.js │ │ │ └── index.js │ │ ├── clusters │ │ │ ├── ClusterModal.js │ │ │ ├── Clusters.js │ │ │ ├── ClustersBlocks.js │ │ │ ├── ClustersConfig.js │ │ │ └── index.js │ │ ├── dashboard │ │ │ ├── Dashboard.js │ │ │ ├── DashboardConfig.js │ │ │ ├── DashboardHeader.js │ │ │ ├── DashboardModal │ │ │ │ ├── ModalStepper.js │ │ │ │ └── WelcomeModal.js │ │ │ └── SummaryWidget.js │ │ ├── example │ │ │ ├── Example.js │ │ │ ├── ExampleConfig.js │ │ │ └── i18n │ │ │ │ ├── ar.js │ │ │ │ ├── en.js │ │ │ │ └── tr.js │ │ ├── forgot-password │ │ │ ├── ForgotPasswordConfig.js │ │ │ └── ForgotPasswordPage.js │ │ ├── releases │ │ │ ├── ReleaseDetails │ │ │ │ ├── ReleaseDetails.js │ │ │ │ ├── ReleaseDetailsConfig.js │ │ │ │ ├── ReleaseItem.js │ │ │ │ ├── ReleaseTable.js │ │ │ │ ├── ReleaseTabs │ │ │ │ │ ├── HelmHistory.js │ │ │ │ │ ├── HelmReleaseDetails.js │ │ │ │ │ ├── ReleaseTabs.js │ │ │ │ │ ├── RollbackRelease.js │ │ │ │ │ └── TabValues │ │ │ │ │ │ ├── ComputedValue.js │ │ │ │ │ │ ├── HelmHooksValue.js │ │ │ │ │ │ ├── ManifestsValue.js │ │ │ │ │ │ ├── NotesValue.js │ │ │ │ │ │ └── UserSuppliedValue.js │ │ │ │ └── index.js │ │ │ ├── ReleaseTtl.js │ │ │ ├── Releases.js │ │ │ ├── ReleasesConfig.js │ │ │ ├── ReleasesDeleteModal.js │ │ │ ├── ReleasesFilters.js │ │ │ ├── ReleasesTable.js │ │ │ └── index.js │ │ ├── repositories │ │ │ ├── Repositories.js │ │ │ ├── RepositoriesConfig.js │ │ │ ├── RepositoriesTable.js │ │ │ └── index.js │ │ ├── reset-password │ │ │ ├── ResetPasswordConfig.js │ │ │ └── ResetPasswordPage.js │ │ ├── services │ │ │ ├── ServiceCreate.js │ │ │ ├── Services.js │ │ │ ├── ServicesConfig.js │ │ │ ├── ServicesFilters.js │ │ │ ├── ServicesTable.js │ │ │ └── index.js │ │ ├── sign-in │ │ │ ├── SignInConfig.js │ │ │ ├── SignInPage.js │ │ │ └── utils.js │ │ ├── sign-out │ │ │ ├── SignOutConfig.js │ │ │ └── SignOutPage.js │ │ ├── sign-up │ │ │ ├── SignUpConfig.js │ │ │ └── SignUpPage.js │ │ ├── templates │ │ │ ├── CatalogList │ │ │ │ └── CatalogList.js │ │ │ ├── TemplateModal │ │ │ │ ├── TemplateBuilder │ │ │ │ │ ├── ComponentsBuilder │ │ │ │ │ │ ├── ComponentItem.js │ │ │ │ │ │ ├── ComponentSelectors │ │ │ │ │ │ │ ├── ChartSelector.js │ │ │ │ │ │ │ ├── TypeSelector.js │ │ │ │ │ │ │ ├── ValuesInputs.js │ │ │ │ │ │ │ └── VersionSelector.js │ │ │ │ │ │ └── ComponentsBuilder.js │ │ │ │ │ ├── HooksBuilder │ │ │ │ │ │ ├── HookFields.js │ │ │ │ │ │ ├── HookItem.js │ │ │ │ │ │ ├── HookSelectors │ │ │ │ │ │ │ ├── CreateAdditionalField.js │ │ │ │ │ │ │ ├── SelectorOfHookEnabled.js │ │ │ │ │ │ │ ├── SelectorOfHookOnFailure.js │ │ │ │ │ │ │ └── SelectorOfHookType.js │ │ │ │ │ │ ├── HookTypes.js │ │ │ │ │ │ └── HooksBuilder.js │ │ │ │ │ ├── InputsBuilder │ │ │ │ │ │ ├── InputFields │ │ │ │ │ │ │ ├── InputTypeCheckbox.js │ │ │ │ │ │ │ ├── InputTypeNumber.js │ │ │ │ │ │ │ ├── InputTypeSelect.js │ │ │ │ │ │ │ ├── InputTypeSlider.js │ │ │ │ │ │ │ ├── InputTypeSwitch.js │ │ │ │ │ │ │ ├── InputTypeText.js │ │ │ │ │ │ │ └── InputTypes.js │ │ │ │ │ │ ├── InputItem.js │ │ │ │ │ │ └── InputsBuilder.js │ │ │ │ │ └── TemplateBuilder.js │ │ │ │ ├── TemplatesItem.js │ │ │ │ └── TemplatesModal.js │ │ │ ├── TemplateProvider.js │ │ │ ├── Templates.js │ │ │ ├── TemplatesConfig.js │ │ │ ├── TemplatesList.js │ │ │ ├── TemplatesListItem.js │ │ │ └── index.js │ │ └── users │ │ │ ├── ChangeRoleSelect.js │ │ │ ├── InvitationsTable.js │ │ │ ├── UserDialogModal.js │ │ │ ├── Users.js │ │ │ ├── UsersConfig.js │ │ │ └── UsersTable.js │ ├── shared-components │ │ ├── DialogModal.js │ │ ├── Snackbar.js │ │ ├── TableDropdownFilter.js │ │ ├── TableHeader.js │ │ ├── TemplateBuilderInput.js │ │ ├── TtlModal │ │ │ ├── DatePicker.js │ │ │ └── TtlModal.js │ │ └── WYSIWYGEditor.js │ ├── store │ │ ├── accessTokensSlice.js │ │ ├── applicationsSlice.js │ │ ├── chartsSlice.js │ │ ├── clustersSlice.js │ │ ├── dashboardSlice.js │ │ ├── fuse │ │ │ ├── dialogSlice.js │ │ │ ├── index.js │ │ │ ├── messageSlice.js │ │ │ ├── navbarSlice.js │ │ │ ├── navigationSlice.js │ │ │ └── settingsSlice.js │ │ ├── i18nSlice.js │ │ ├── index.js │ │ ├── invitationsSlice.js │ │ ├── releaseSlice.js │ │ ├── releasesSlice.js │ │ ├── repositorySlice.js │ │ ├── rootReducer.js │ │ ├── servicesSlice.js │ │ ├── templatesSlice.js │ │ ├── userSlice.js │ │ ├── usersSlice.js │ │ └── withReducer.js │ ├── theme-layouts │ │ ├── layout1 │ │ │ ├── Layout1.js │ │ │ ├── Layout1Config.js │ │ │ └── components │ │ │ │ ├── FooterLayout1.js │ │ │ │ ├── LeftSideLayout1.js │ │ │ │ ├── NavbarWrapperLayout1.js │ │ │ │ ├── RightSideLayout1.js │ │ │ │ ├── ToolbarLayout1.js │ │ │ │ └── navbar │ │ │ │ ├── style-1 │ │ │ │ ├── NavbarStyle1.js │ │ │ │ └── NavbarStyle1Content.js │ │ │ │ ├── style-2 │ │ │ │ ├── NavbarStyle2.js │ │ │ │ └── NavbarStyle2Content.js │ │ │ │ └── style-3 │ │ │ │ ├── NavbarStyle3.js │ │ │ │ └── NavbarStyle3Content.js │ │ ├── layout2 │ │ │ ├── Layout2.js │ │ │ ├── Layout2Config.js │ │ │ └── components │ │ │ │ ├── FooterLayout2.js │ │ │ │ ├── LeftSideLayout2.js │ │ │ │ ├── NavbarLayout2.js │ │ │ │ ├── NavbarMobileLayout2.js │ │ │ │ ├── NavbarWrapperLayout2.js │ │ │ │ ├── RightSideLayout2.js │ │ │ │ └── ToolbarLayout2.js │ │ ├── layout3 │ │ │ ├── Layout3.js │ │ │ ├── Layout3Config.js │ │ │ └── components │ │ │ │ ├── FooterLayout3.js │ │ │ │ ├── LeftSideLayout3.js │ │ │ │ ├── NavbarLayout3.js │ │ │ │ ├── NavbarMobileLayout3.js │ │ │ │ ├── NavbarWrapperLayout3.js │ │ │ │ ├── RightSideLayout3.js │ │ │ │ └── ToolbarLayout3.js │ │ ├── shared-components │ │ │ ├── AdjustFontSize.js │ │ │ ├── DocumentationButton.js │ │ │ ├── FullScreenToggle.js │ │ │ ├── FuseSettingsViewerDialog.js │ │ │ ├── LanguageSwitcher.js │ │ │ ├── Logo.js │ │ │ ├── NavbarToggleButton.js │ │ │ ├── NavbarToggleFab.js │ │ │ ├── Navigation.js │ │ │ ├── NavigationSearch.js │ │ │ ├── NavigationShortcuts.js │ │ │ ├── PoweredByLinks.js │ │ │ ├── PurchaseButton.js │ │ │ ├── SettingsPanel.js │ │ │ ├── UserMenu.js │ │ │ ├── UserNavbarHeader.js │ │ │ ├── chatPanel │ │ │ │ ├── Chat.js │ │ │ │ ├── ChatPanel.js │ │ │ │ ├── ChatPanelToggleButton.js │ │ │ │ ├── ContactButton.js │ │ │ │ ├── ContactList.js │ │ │ │ └── store │ │ │ │ │ ├── chatSlice.js │ │ │ │ │ ├── chatsSlice.js │ │ │ │ │ ├── contactsSlice.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── stateSlice.js │ │ │ │ │ └── userSlice.js │ │ │ ├── notificationPanel │ │ │ │ ├── NotificationCard.js │ │ │ │ ├── NotificationIcon.js │ │ │ │ ├── NotificationPanel.js │ │ │ │ ├── NotificationPanelToggleButton.js │ │ │ │ ├── NotificationTemplate.js │ │ │ │ ├── model │ │ │ │ │ └── NotificationModel.js │ │ │ │ └── store │ │ │ │ │ ├── dataSlice.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── stateSlice.js │ │ │ └── quickPanel │ │ │ │ ├── QuickPanel.js │ │ │ │ ├── QuickPanelToggleButton.js │ │ │ │ └── store │ │ │ │ ├── dataSlice.js │ │ │ │ ├── index.js │ │ │ │ └── stateSlice.js │ │ ├── themeLayoutConfigs.js │ │ └── themeLayouts.js │ ├── uitls │ │ ├── color.js │ │ ├── data.js │ │ ├── date.js │ │ ├── formattedNamespace.js │ │ ├── formattingTemplateValues.js │ │ ├── index.js │ │ └── strings.js │ └── withAppProviders.js ├── i18n.js ├── index.js ├── reportWebVitals.js ├── serviceWorker.js └── styles │ ├── app-base.css │ ├── app-components.css │ ├── app-utilities.css │ ├── custom.css │ ├── print.css │ ├── prism.css │ └── tables.css ├── tailwind.config.js └── yarn.lock /.env: -------------------------------------------------------------------------------- 1 | DATABASE_URL=postgresql+asyncpg://postgres_user:super_secret_password@localhost/service_hub 2 | TEST_DATABASE_URL=postgresql+asyncpg://postgres_user:super_secret_password@localhost/test 3 | FILE_STORAGE_ROOT=../.venv/tmp/storage 4 | HELM_VERSION=v3.9.0 5 | KUBECTL_VERSION=v1.24.1 6 | SECRETS_DIRECTORY=../credentials 7 | ENV_FILE=../.env 8 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [pycodestyle] 2 | statistics = true 3 | max_line_length = 120 4 | max_doc_length = 80 5 | aggressive = 3 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #Logs files 2 | *.log 3 | 4 | # Commonly Python ignored resources 5 | __pycache__ 6 | *.pyc 7 | 8 | # Project resources 9 | ./frontend/.idea 10 | .idea 11 | .venv 12 | application/.env 13 | cli/build/ 14 | cli/dist/ 15 | 16 | 17 | # Local desktop resoruces 18 | .DS_Store -------------------------------------------------------------------------------- /.isort.cfg: -------------------------------------------------------------------------------- 1 | [settings] 2 | force_single_line = true 3 | line_length = 120 4 | lines_after_imports = 2 5 | src_paths = application 6 | -------------------------------------------------------------------------------- /application/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/__init__.py -------------------------------------------------------------------------------- /application/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/api/__init__.py -------------------------------------------------------------------------------- /application/api/v1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/api/v1/__init__.py -------------------------------------------------------------------------------- /application/api/v1/endpoints/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/api/v1/endpoints/__init__.py -------------------------------------------------------------------------------- /application/api/v1/schemas/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/api/v1/schemas/__init__.py -------------------------------------------------------------------------------- /application/api/v1/schemas/events.py: -------------------------------------------------------------------------------- 1 | """ 2 | Events related API schemas. 3 | """ 4 | 5 | from pydantic import BaseModel 6 | from pydantic import Field 7 | 8 | 9 | class ObjectIdentifiersQuerySchema(BaseModel): 10 | """ 11 | Query parameters for filtering event for specific object. 12 | """ 13 | application_id: int | None = Field(description='ID of application.') 14 | organization_id: int | None = Field(description='ID of organization.') 15 | repository_name: str | None = Field(description='Name of Helm repository.') 16 | context: str | None = Field(description='Name of Kubernetes context.') 17 | namespace: str | None = Field(description='Name of Kubernetes namespace.') 18 | release_name: str | None = Field(description='Name of Helm release.') 19 | -------------------------------------------------------------------------------- /application/api/v1/schemas/users.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from pydantic import Field 3 | 4 | from constants.roles import Roles 5 | 6 | 7 | class SetUserRoleRequestSchema(BaseModel): 8 | """ 9 | Change user role request schema. 10 | """ 11 | user_id: str = Field(description='ID of user role of which is being set.') 12 | role: Roles = Field(description='Role that should be set.') 13 | -------------------------------------------------------------------------------- /application/constants/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/constants/__init__.py -------------------------------------------------------------------------------- /application/constants/access_tokens.py: -------------------------------------------------------------------------------- 1 | """ 2 | User access token constants. 3 | """ 4 | from .base_enum import StrEnum 5 | 6 | 7 | class AccessTokenStatuses(StrEnum): 8 | """ 9 | User access token statuses. 10 | """ 11 | active = 'active' 12 | disabled = 'disabled' 13 | -------------------------------------------------------------------------------- /application/constants/base_enum.py: -------------------------------------------------------------------------------- 1 | """ 2 | Base enum classes. 3 | """ 4 | from enum import Enum 5 | from enum import EnumMeta 6 | 7 | 8 | class MetaEnum(EnumMeta): 9 | def __contains__(cls, item): 10 | try: 11 | cls(item) 12 | except ValueError: 13 | return False 14 | return True 15 | 16 | 17 | class StrEnum(str, Enum, metaclass=MetaEnum): 18 | """ 19 | Base string enum class. 20 | """ 21 | pass 22 | -------------------------------------------------------------------------------- /application/constants/common.py: -------------------------------------------------------------------------------- 1 | """ 2 | Common project constants. 3 | """ 4 | from .base_enum import StrEnum 5 | 6 | 7 | UNRECOGNIZED_CLOUD_PROVIDER_REGION = 'unrecognized' 8 | 9 | 10 | class HTTPMethods(StrEnum): 11 | """ 12 | HTTP methods. 13 | """ 14 | connect = 'connect' 15 | delete = 'delete' 16 | get = 'get' 17 | head = 'head' 18 | options = 'options' 19 | patch = 'patch' 20 | post = 'post' 21 | put = 'put' 22 | trace = 'trace' 23 | 24 | 25 | class CloudProviders(StrEnum): 26 | """ 27 | Supported cloud providers. 28 | """ 29 | aws = 'aws' 30 | azure = 'azure' 31 | gcp = 'gcp' 32 | unrecognized = 'unrecognized' 33 | -------------------------------------------------------------------------------- /application/constants/events.py: -------------------------------------------------------------------------------- 1 | """ 2 | Event related constants. 3 | """ 4 | from .base_enum import StrEnum 5 | 6 | 7 | class EventCategory(StrEnum): 8 | """ 9 | Event severity levels. 10 | """ 11 | access_token = 'access_token' 12 | application = 'application' 13 | helm = 'helm' 14 | hook = 'hook' 15 | organization = 'organization' 16 | 17 | 18 | class EventSeverityLevel(StrEnum): 19 | """ 20 | Event severity levels. 21 | """ 22 | debug = 'debug' 23 | info = 'info' 24 | warning = 'warning' 25 | error = 'error' 26 | -------------------------------------------------------------------------------- /application/constants/invitations.py: -------------------------------------------------------------------------------- 1 | """ 2 | Contants related to user invitations. 3 | """ 4 | 5 | from .base_enum import StrEnum 6 | 7 | 8 | class InvitationStatuses(StrEnum): 9 | """ 10 | User invitation statuses. 11 | """ 12 | pending = 'pending' 13 | used = 'used' 14 | -------------------------------------------------------------------------------- /application/constants/roles.py: -------------------------------------------------------------------------------- 1 | """ 2 | Roles constants. 3 | """ 4 | from .base_enum import StrEnum 5 | 6 | 7 | class Roles(StrEnum): 8 | """ 9 | User roles. 10 | """ 11 | admin = 'admin' 12 | operator = 'operator' 13 | -------------------------------------------------------------------------------- /application/constants/services.py: -------------------------------------------------------------------------------- 1 | from .base_enum import StrEnum 2 | 3 | 4 | class ServiceTypes(StrEnum): 5 | """ 6 | Types of services in Service catalog. 7 | """ 8 | http_endpoint = 'http_endpoint' 9 | kubernetes_ingress = 'kubernetes_ingress' 10 | kubernetes_service = 'kubernetes_service' 11 | 12 | 13 | class ServiceHealthStatuses(StrEnum): 14 | """ 15 | Operability status of service from service catalog. 16 | """ 17 | healthy = 'healthy' 18 | unhealthy = 'unhealthy' 19 | -------------------------------------------------------------------------------- /application/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/core/__init__.py -------------------------------------------------------------------------------- /application/crud/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/crud/__init__.py -------------------------------------------------------------------------------- /application/crud/access_tokens.py: -------------------------------------------------------------------------------- 1 | """ 2 | Classes responsible for interaction with user access token database entities. 3 | """ 4 | from fastapi import Depends 5 | from sqlalchemy.ext.asyncio import AsyncSession 6 | 7 | from db.session import get_session 8 | from models.access_token import AccessToken 9 | 10 | from .base import BaseDatabase 11 | 12 | 13 | class AccessTokenDatabase(BaseDatabase): 14 | """ 15 | CRUD operation for models.AccessToken instances. 16 | """ 17 | session: AsyncSession 18 | table: AccessToken = AccessToken 19 | 20 | 21 | async def get_access_token_db(session=Depends(get_session)): 22 | yield AccessTokenDatabase(session) 23 | -------------------------------------------------------------------------------- /application/crud/applications.py: -------------------------------------------------------------------------------- 1 | """ 2 | Classes responsible for interaction with application database entities. 3 | """ 4 | from fastapi import Depends 5 | from sqlalchemy.ext.asyncio import AsyncSession 6 | 7 | from db.session import get_session 8 | from models.application import Application 9 | 10 | from .base import BaseDatabase 11 | 12 | 13 | class ApplicationDatabase(BaseDatabase): 14 | """ 15 | CRUD operation for models.Application instances. 16 | """ 17 | session: AsyncSession 18 | table: Application = Application 19 | 20 | 21 | async def get_application_db(session=Depends(get_session)): 22 | yield ApplicationDatabase(session) 23 | -------------------------------------------------------------------------------- /application/crud/invitations.py: -------------------------------------------------------------------------------- 1 | """ 2 | Classes responsible for interaction with user invitations database entities. 3 | """ 4 | from fastapi import Depends 5 | from sqlalchemy.ext.asyncio import AsyncSession 6 | 7 | from db.session import get_session 8 | from models.invitation import UserInvitation 9 | 10 | from .base import BaseDatabase 11 | 12 | 13 | class InvitationDatabase(BaseDatabase): 14 | """ 15 | CRUD operation for models.UserInvitation instances. 16 | """ 17 | session: AsyncSession 18 | table: UserInvitation = UserInvitation 19 | 20 | 21 | async def get_invitation_db(session=Depends(get_session)): 22 | yield InvitationDatabase(session) 23 | -------------------------------------------------------------------------------- /application/crud/organizations.py: -------------------------------------------------------------------------------- 1 | """ 2 | Classes responsible for interaction with organization database entities. 3 | """ 4 | from fastapi import Depends 5 | from sqlalchemy.ext.asyncio import AsyncSession 6 | 7 | from db.session import get_session 8 | from models.organization import Organization 9 | 10 | from .base import BaseDatabase 11 | 12 | 13 | class OrganizationDatabase(BaseDatabase): 14 | """ 15 | CRUD operation for models.Organization instances. 16 | """ 17 | session: AsyncSession 18 | table: Organization = Organization 19 | 20 | 21 | async def get_organization_db(session=Depends(get_session)): 22 | yield OrganizationDatabase(session) 23 | -------------------------------------------------------------------------------- /application/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/db/__init__.py -------------------------------------------------------------------------------- /application/db/base_class.py: -------------------------------------------------------------------------------- 1 | import re 2 | from typing import Any 3 | 4 | from sqlalchemy.ext.declarative import as_declarative 5 | from sqlalchemy.ext.declarative import declared_attr 6 | 7 | from .session import engine 8 | 9 | 10 | camel_case_pattern = re.compile(r'(? str: 20 | """ 21 | Generate __tablename__ automatically. Converts class camel case to snake 22 | case. 23 | """ 24 | return camel_case_pattern.sub('_', cls.__name__).lower() 25 | -------------------------------------------------------------------------------- /application/db/fields.py: -------------------------------------------------------------------------------- 1 | from enum import Enum as PyEnum 2 | 3 | from sqlalchemy import JSON 4 | from sqlalchemy import Enum 5 | from sqlalchemy.ext.mutable import MutableDict 6 | 7 | 8 | MutableJSON = MutableDict.as_mutable(JSON) 9 | 10 | 11 | def enum_column(enum: PyEnum) -> Enum: 12 | return Enum(enum, values_callable=lambda enum: [item.value for item in enum]) 13 | -------------------------------------------------------------------------------- /application/exceptions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/exceptions/__init__.py -------------------------------------------------------------------------------- /application/exceptions/base.py: -------------------------------------------------------------------------------- 1 | """ 2 | Bases for all project exceptions. 3 | """ 4 | 5 | 6 | class ServiceHubException(Exception): 7 | pass 8 | -------------------------------------------------------------------------------- /application/exceptions/common.py: -------------------------------------------------------------------------------- 1 | """ 2 | General project exceptions. 3 | """ 4 | from fastapi import status 5 | 6 | from .base import ServiceHubException 7 | 8 | 9 | class CommonException(ServiceHubException): 10 | """ 11 | Common Service Hub exception. 12 | 13 | Message of this class and all classes that inherited from this will be 14 | delivered to front-end with settled status code. 15 | """ 16 | message: str 17 | status_code: int 18 | 19 | def __init__(self, message: str, status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR): 20 | self.message = message 21 | self.status_code = status_code 22 | super().__init__(message) 23 | -------------------------------------------------------------------------------- /application/exceptions/http.py: -------------------------------------------------------------------------------- 1 | """ 2 | Http related exceptions. 3 | """ 4 | from fastapi import status 5 | 6 | from .common import CommonException 7 | 8 | 9 | class HttpException(CommonException): 10 | """ 11 | Base Http exception. 12 | """ 13 | 14 | 15 | class HttpNotOk(HttpException): 16 | """ 17 | Raised when the response status code is not 200. 18 | """ 19 | 20 | def __init__(self, status_code: int, message: str = None): 21 | super().__init__( 22 | status_code=status_code, 23 | message=f"Unexpected status code: {status_code}. Expected status code between 200 and 299." 24 | ) 25 | -------------------------------------------------------------------------------- /application/exceptions/rule.py: -------------------------------------------------------------------------------- 1 | """ 2 | Rules related exceptions. 3 | """ 4 | from fastapi import status 5 | 6 | from .common import CommonException 7 | 8 | 9 | class RuleDoesNotExistException(CommonException): 10 | """ 11 | Raised when operation can not be completed due non existing rule. 12 | """ 13 | message: str 14 | status_code: int = status.HTTP_404_NOT_FOUND 15 | 16 | def __init__(self, message: str): 17 | self.message = message 18 | super().__init__(self.message, self.status_code) 19 | -------------------------------------------------------------------------------- /application/exceptions/service.py: -------------------------------------------------------------------------------- 1 | """ 2 | Service catalog related exceptions. 3 | """ 4 | from fastapi import status 5 | 6 | from .common import CommonException 7 | 8 | 9 | class ServiceDoesNotExistException(CommonException): 10 | """ 11 | Raised when operation can not be completed due non existing service from 12 | service catalog. 13 | """ 14 | message: str 15 | status_code: int = status.HTTP_404_NOT_FOUND 16 | 17 | def __init__(self, message: str): 18 | self.message = message 19 | super().__init__(self.message, self.status_code) 20 | -------------------------------------------------------------------------------- /application/exceptions/shell.py: -------------------------------------------------------------------------------- 1 | """ 2 | Exceptions related with execution shell commands. 3 | """ 4 | from .base import ServiceHubException 5 | 6 | 7 | class NonZeroStatusException(ServiceHubException): 8 | """ 9 | Returned when shell command execution finished with non zero status. 10 | """ 11 | 12 | def __init__(self, command: str, stderr_message: str, status_code: int) -> None: 13 | self.command = command 14 | self.stderr_message = stderr_message 15 | self.status_code = status_code 16 | super().__init__(stderr_message) 17 | -------------------------------------------------------------------------------- /application/managers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/managers/__init__.py -------------------------------------------------------------------------------- /application/managers/helm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/managers/helm/__init__.py -------------------------------------------------------------------------------- /application/managers/http/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/managers/http/__init__.py -------------------------------------------------------------------------------- /application/managers/organizations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/managers/organizations/__init__.py -------------------------------------------------------------------------------- /application/managers/rules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/managers/rules/__init__.py -------------------------------------------------------------------------------- /application/managers/rules/actions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/managers/rules/actions/__init__.py -------------------------------------------------------------------------------- /application/managers/rules/conditions/__init__.py: -------------------------------------------------------------------------------- 1 | from .base import Condition 2 | from .contains import ContainsCondition 3 | from .equal import EqualCondition 4 | from .not_equal import NotEqualCondition 5 | from .regex import RegexCondition 6 | -------------------------------------------------------------------------------- /application/managers/rules/conditions/contains.py: -------------------------------------------------------------------------------- 1 | """ 2 | Condition to check that one sequence contains another. 3 | """ 4 | from constants.rules import RuleComparisonStatements 5 | 6 | from .base import Condition 7 | 8 | 9 | class ContainsCondition(Condition): 10 | """ 11 | Checks that one sequence contains another. 12 | """ 13 | 14 | statement = RuleComparisonStatements.contains 15 | 16 | def compare(self) -> bool: 17 | attribute_value = self.values[self.attribute] 18 | return self.value in attribute_value 19 | -------------------------------------------------------------------------------- /application/managers/rules/conditions/equal.py: -------------------------------------------------------------------------------- 1 | """ 2 | Condition to check for equality. 3 | """ 4 | from constants.rules import RuleComparisonStatements 5 | 6 | from .base import Condition 7 | 8 | 9 | class EqualCondition(Condition): 10 | """ 11 | Checks that value attribute is equal to defined value. 12 | """ 13 | 14 | statement = RuleComparisonStatements.equal 15 | 16 | def compare(self) -> bool: 17 | attribute_value = self.values[self.attribute] 18 | return self.value == attribute_value 19 | -------------------------------------------------------------------------------- /application/managers/rules/conditions/not_equal.py: -------------------------------------------------------------------------------- 1 | """ 2 | Condition to check for inequality. 3 | """ 4 | from constants.rules import RuleComparisonStatements 5 | 6 | from .base import Condition 7 | 8 | 9 | class NotEqualCondition(Condition): 10 | """ 11 | Checks that value attribute is not equal to defined value. 12 | """ 13 | 14 | statement = RuleComparisonStatements.not_equal 15 | 16 | def compare(self) -> bool: 17 | attribute_value = self.values[self.attribute] 18 | return self.value != attribute_value 19 | -------------------------------------------------------------------------------- /application/managers/rules/conditions/regex.py: -------------------------------------------------------------------------------- 1 | """ 2 | Condition to check that string matches pattern. 3 | """ 4 | import re 5 | 6 | from constants.rules import RuleComparisonStatements 7 | 8 | from .base import Condition 9 | 10 | 11 | class RegexCondition(Condition): 12 | """ 13 | Checks that value attribute is matches defined regular expression. 14 | """ 15 | 16 | statement = RuleComparisonStatements.regex 17 | 18 | def compare(self) -> bool: 19 | attribute_value = self.values[self.attribute] 20 | match = re.search(self.value, attribute_value) 21 | if match: 22 | return True 23 | 24 | return False 25 | -------------------------------------------------------------------------------- /application/managers/services/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/managers/services/__init__.py -------------------------------------------------------------------------------- /application/migrations/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration with an async dbapi. 2 | -------------------------------------------------------------------------------- /application/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """ 2 | ${message} 3 | 4 | Revision ID: ${up_revision} 5 | Revises: ${down_revision | comma,n} 6 | Create Date: ${create_date} 7 | """ 8 | import sqlalchemy as sa 9 | from alembic import op 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade() -> None: 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade() -> None: 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /application/migrations/versions/2022-10-04_1924_set_admin_role_to_all_users.py: -------------------------------------------------------------------------------- 1 | """ 2 | Set admin role to all users. 3 | 4 | Revision ID: 69b38d90ab50 5 | Revises: 9ee2947cff15 6 | Create Date: 2022-10-04 19:24:52.838679 7 | """ 8 | from alembic import op 9 | 10 | 11 | # revision identifiers, used by Alembic. 12 | revision = '69b38d90ab50' 13 | down_revision = '9ee2947cff15' 14 | branch_labels = None 15 | depends_on = None 16 | 17 | 18 | def upgrade() -> None: 19 | op.execute("UPDATE public.user SET role = 'admin'") 20 | 21 | 22 | def downgrade() -> None: 23 | op.execute('UPDATE public.user SET role = NULL') 24 | -------------------------------------------------------------------------------- /application/migrations/versions/2022-10-17_1639_drop_old_templates.py: -------------------------------------------------------------------------------- 1 | """ 2 | Drop old templates. 3 | 4 | Revision ID: c5f94e6d60ea 5 | Revises: 69b38d90ab50 6 | Create Date: 2022-10-17 16:39:59.985370 7 | """ 8 | from alembic import op 9 | 10 | 11 | # revision identifiers, used by Alembic. 12 | revision = 'c5f94e6d60ea' 13 | down_revision = '69b38d90ab50' 14 | branch_labels = None 15 | depends_on = None 16 | 17 | 18 | def upgrade() -> None: 19 | op.execute('delete from application') 20 | op.execute('delete from template_revision') 21 | 22 | 23 | def downgrade() -> None: 24 | pass 25 | -------------------------------------------------------------------------------- /application/migrations/versions/2022-11-28_1606_added_application_ttl_property.py: -------------------------------------------------------------------------------- 1 | """ 2 | Added Application.ttl property. 3 | 4 | Revision ID: 17ba98259c52 5 | Revises: 488fbe744acd 6 | Create Date: 2022-11-28 16:06:05.282750 7 | """ 8 | import sqlalchemy as sa 9 | from alembic import op 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = '17ba98259c52' 14 | down_revision = '488fbe744acd' 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade() -> None: 20 | op.add_column('application', sa.Column('ttl', sa.DateTime(), nullable=True)) 21 | 22 | 23 | def downgrade() -> None: 24 | op.drop_column('application', 'ttl') 25 | -------------------------------------------------------------------------------- /application/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import access_token 2 | from . import application 3 | from . import event 4 | from . import invitation 5 | from . import organization 6 | from . import rule 7 | from . import service 8 | from . import template 9 | from . import user 10 | -------------------------------------------------------------------------------- /application/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | asyncio_mode = strict 3 | -------------------------------------------------------------------------------- /application/requirements.dev.txt: -------------------------------------------------------------------------------- 1 | -r ./requirements.txt 2 | 3 | autopep8 4 | isort 5 | pytest 6 | pytest-asyncio 7 | -------------------------------------------------------------------------------- /application/requirements.txt: -------------------------------------------------------------------------------- 1 | aiosmtplib==3.0.1 2 | alembic==1.13.1 3 | asyncpg==0.29.0 4 | chevron==0.14.0 5 | deepdiff==6.7.1 6 | email-validator==2.0.0.post2 7 | Faker==24.1.0 # This dependency temporary must be in production requirements until Organization title change will be implemented. 8 | fastapi==0.110.0 9 | fastapi-users[sqlalchemy]==11.0.0 10 | httpx==0.26.0 11 | httpx-oauth==0.13.2 12 | kubernetes==29.0.0 13 | kubernetes_asyncio==22.6.5 # Version locked because of issue https://github.com/kubernetes-client/python/issues/1718 and https://github.com/kubernetes-client/python/issues/1751 14 | mergedeep==1.3.4 15 | procrastinate < 1.0.0 16 | pydantic[dotenv]==1.10.13 17 | pyyaml==6.0.1 18 | sqlalchemy[asyncio]==1.4.46 19 | uvicorn[standard]==0.28.0 20 | -------------------------------------------------------------------------------- /application/schemas/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/schemas/__init__.py -------------------------------------------------------------------------------- /application/schemas/common_types.py: -------------------------------------------------------------------------------- 1 | from pydantic import constr 2 | 3 | 4 | # RFC 1123 compliant string. 5 | K8sSubdomainNameString = constr(regex=r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', max_length=253) 6 | -------------------------------------------------------------------------------- /application/schemas/templates/__init__.py: -------------------------------------------------------------------------------- 1 | from .template import TemplateSchema 2 | 3 | 4 | __all__ = [ 5 | 'TemplateSchema', 6 | ] 7 | -------------------------------------------------------------------------------- /application/schemas/templates/outputs.py: -------------------------------------------------------------------------------- 1 | """ 2 | Template Outputs schema. 3 | """ 4 | from pydantic import BaseModel 5 | from pydantic import Extra 6 | from pydantic import Field 7 | 8 | 9 | class Outputs(BaseModel): 10 | """ 11 | Outputs for Application consumer. 12 | """ 13 | notes: str = Field(description='Message for Application consumer.', example='We hope you enjoy it.') 14 | 15 | class Config: 16 | extra = Extra.forbid 17 | -------------------------------------------------------------------------------- /application/schemas/users.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | 3 | from fastapi_users import schemas 4 | 5 | 6 | class UserRead(schemas.BaseUser[uuid.UUID]): 7 | pass 8 | 9 | 10 | class UserCreate(schemas.BaseUserCreate): 11 | pass 12 | 13 | 14 | class UserUpdate(schemas.BaseUserUpdate): 15 | pass 16 | -------------------------------------------------------------------------------- /application/services/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/services/__init__.py -------------------------------------------------------------------------------- /application/services/helm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/services/helm/__init__.py -------------------------------------------------------------------------------- /application/services/helm/subcommands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/services/helm/subcommands/__init__.py -------------------------------------------------------------------------------- /application/services/helm/subcommands/show.py: -------------------------------------------------------------------------------- 1 | from .base import HelmBase 2 | 3 | 4 | class HelmShow(HelmBase): 5 | """ 6 | Class responsible for working with `show` helm subcommand. 7 | """ 8 | 9 | subcommand = 'show' 10 | 11 | async def values(self, chart_name: str) -> str: 12 | """ 13 | Gets chart default values(the values.yaml file). 14 | 15 | Full description: https://helm.sh/docs/helm/helm_show_values/ 16 | """ 17 | command = self._formup_command('values', chart_name) 18 | values_file_yaml = await self._run_command(command) 19 | 20 | return values_file_yaml 21 | -------------------------------------------------------------------------------- /application/services/kubernetes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/services/kubernetes/__init__.py -------------------------------------------------------------------------------- /application/services/kubernetes/cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/services/kubernetes/cli/__init__.py -------------------------------------------------------------------------------- /application/services/kubernetes/cli/subcommands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/services/kubernetes/cli/subcommands/__init__.py -------------------------------------------------------------------------------- /application/services/procrastinate/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/services/procrastinate/__init__.py -------------------------------------------------------------------------------- /application/services/procrastinate/application.py: -------------------------------------------------------------------------------- 1 | from procrastinate import AiopgConnector 2 | from procrastinate import App 3 | 4 | from core.configuration import settings 5 | 6 | 7 | procrastinate = App( 8 | connector=AiopgConnector( 9 | user=settings.DATABASE_URL.user, 10 | password=settings.DATABASE_URL.password, 11 | host=settings.DATABASE_URL.host, 12 | port=settings.DATABASE_URL.port, 13 | database=settings.DATABASE_URL.path.strip('/') 14 | ), 15 | import_paths=['services.procrastinate.tasks.application'] 16 | ) 17 | -------------------------------------------------------------------------------- /application/services/procrastinate/tasks/__init__.py: -------------------------------------------------------------------------------- 1 | # from . import applicaton 2 | 3 | # __all__ = [ 4 | # 'applicaton' 5 | # ] 6 | -------------------------------------------------------------------------------- /application/start-task-executor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | i=0 3 | while [ $i -le 5 ]; do 4 | 5 | procrastinate --app=services.procrastinate.application.procrastinate worker --concurrency=6 && break 6 | 7 | let i=i+1 8 | sleep 2 9 | done 10 | -------------------------------------------------------------------------------- /application/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ $* == *--sync-db* ]] 3 | then 4 | i=0 5 | while [ $i -le 5 ]; do 6 | 7 | alembic upgrade head && break 8 | 9 | let i=i+1 10 | sleep 2 11 | done 12 | fi 13 | if [[ $* == *--reload* ]] 14 | then 15 | OPTIONAL_ARGS="--reload" 16 | fi 17 | echo "Starting server" 18 | echo "OPTIONAL_ARGS: $OPTIONAL_ARGS" 19 | 20 | uvicorn $OPTIONAL_ARGS instance:instance --host 0.0.0.0 --port 8000 21 | -------------------------------------------------------------------------------- /application/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/tests/__init__.py -------------------------------------------------------------------------------- /application/tests/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/tests/api/__init__.py -------------------------------------------------------------------------------- /application/tests/api/v1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/tests/api/v1/__init__.py -------------------------------------------------------------------------------- /application/tests/fixtures/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/tests/fixtures/__init__.py -------------------------------------------------------------------------------- /application/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/application/utils/__init__.py -------------------------------------------------------------------------------- /application/utils/invitation.py: -------------------------------------------------------------------------------- 1 | """ 2 | Invitations related helpers. 3 | """ 4 | from datetime import datetime 5 | from datetime import timedelta 6 | 7 | 8 | def is_invitation_expired(created_at: datetime, expiration_period: int) -> bool: 9 | """ 10 | Returns `True` if invitation is expired. 11 | """ 12 | if expiration_period == 0: 13 | # Period equal to zero means that invitation can be active unlimited 14 | # time. 15 | return False 16 | 17 | now = datetime.now() 18 | expiration_date = created_at + timedelta(hours=expiration_period) 19 | 20 | return expiration_date <= now 21 | -------------------------------------------------------------------------------- /application/utils/paths.py: -------------------------------------------------------------------------------- 1 | """ 2 | Project paths. 3 | """ 4 | from pathlib import Path 5 | 6 | from core.configuration import settings 7 | from models.organization import Organization 8 | 9 | 10 | def organization_home(organization: Organization) -> Path: 11 | """ 12 | Organization home directory. 13 | """ 14 | return Path(settings.FILE_STORAGE_ROOT) / str(organization.id) 15 | -------------------------------------------------------------------------------- /application/utils/temporary_file.py: -------------------------------------------------------------------------------- 1 | """ 2 | Utilites related with temporary files usage. 3 | """ 4 | from tempfile import NamedTemporaryFile 5 | from tempfile import _TemporaryFileWrapper 6 | 7 | from core.configuration import settings 8 | 9 | 10 | def yaml_temporary_file() -> _TemporaryFileWrapper: 11 | """ 12 | Returns YAML temporary file. 13 | """ 14 | return NamedTemporaryFile(mode='w', suffix='.yaml', dir=settings.FILE_STORAGE_ROOT) 15 | -------------------------------------------------------------------------------- /cli/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.10-slim 2 | 3 | ENV DEBIAN_FRONTEND noninteractive 4 | 5 | WORKDIR /run/service_hub/build 6 | 7 | RUN apt-get update \ 8 | && apt-get install --yes binutils \ 9 | && apt-get clean \ 10 | && pip install --upgrade pip \ 11 | && pip install --no-cache-dir --upgrade pyinstaller 12 | 13 | CMD pip install --upgrade pip \ 14 | && pip install --no-cache-dir --upgrade -r requirements.txt \ 15 | && pyinstaller --clean service-hub.spec 16 | -------------------------------------------------------------------------------- /cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/cli/__init__.py -------------------------------------------------------------------------------- /cli/requirements.txt: -------------------------------------------------------------------------------- 1 | fire==0.5.0 2 | pydantic[dotenv]==1.10.2 3 | requests==2.28.1 4 | rich==13.0.0 5 | -------------------------------------------------------------------------------- /cli/schemas/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/cli/schemas/__init__.py -------------------------------------------------------------------------------- /cli/settings.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseSettings 2 | from pathlib import Path 3 | 4 | SERVICE_HUB_SETTINGS_HOME = Path.home() / '.service_hub' 5 | SERVICE_HUB_SETTINGS_FILE = SERVICE_HUB_SETTINGS_HOME / 'settings.ini' 6 | 7 | 8 | class Settings(BaseSettings): 9 | access_token: str = '' 10 | api_host: str = 'https://api.hub.jovianx.app/' 11 | 12 | class Config: 13 | env_file = SERVICE_HUB_SETTINGS_FILE 14 | case_sensitive = True 15 | 16 | 17 | settings = Settings() 18 | -------------------------------------------------------------------------------- /credentials/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /docker-data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /documentation/JovianX_Service_Hub_Getting_Started.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/documentation/JovianX_Service_Hub_Getting_Started.gif -------------------------------------------------------------------------------- /documentation/helm-manager.md: -------------------------------------------------------------------------------- 1 | ```shell 2 | JovianX 3 | _____ _ _ _ _ 4 | / ____| (_) | | | | | | 5 | | (___ ___ _ __ __ __ _ ___ ___ | |__| | _ _ | |__ 6 | \___ \ / _ \ | '__| \ \ / / | | / __| / _ \ | __ | | | | | | '_ \ 7 | ____) | | __/ | | \ V / | | | (__ | __/ | | | | | |_| | | |_) | 8 | |_____/ \___| |_| \_/ |_| \___| \___| |_| |_| \__,_| |_.__/ 9 | 10 | Create X-as-a-Service on Kubernetes with Helm 11 | ``` 12 | 13 | [\<\< Back to the documentation](README.md) 14 | 15 | # Helm Manager 16 | -------------------------------------------------------------------------------- /documentation/service-hub-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/documentation/service-hub-banner.png -------------------------------------------------------------------------------- /documentation/service-hub-getting-started.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/documentation/service-hub-getting-started.mp4 -------------------------------------------------------------------------------- /examples/00-hello-world.yaml: -------------------------------------------------------------------------------- 1 | # Template reference and documentation at 2 | # https://github.com/JovianX/Service-Hub/blob/main/documentation/templates.md 3 | 4 | name: hello-world-redis 5 | 6 | components: # Required. Application components list. 7 | - name: redis # Required. Component name. 8 | type: helm_chart # Required. Component type. 9 | chart: bitnami/redis # Required. Chart name in format `/`. 10 | -------------------------------------------------------------------------------- /examples/redis.yaml: -------------------------------------------------------------------------------- 1 | name: redis 2 | inputs: 3 | - name: password 4 | type: password 5 | label: Password 6 | default: '' 7 | description: Choose a password or Redis 8 | components: 9 | - name: redis 10 | type: helm_chart 11 | chart: bitnami/redis 12 | version: 17.0.6 13 | values: 14 | - auth: 15 | password: '{{ inputs.password }}' 16 | - master: 17 | service: 18 | type: LoadBalancer 19 | outputs: 20 | notes: > 21 | Connect using Redis CLI: $ redis-cli -u redis://'{{ inputs.password 22 | }}'@'{{components.redis.manifest.Service.redis-master.status.loadBalancer.ingress.0.ip}}' 23 | -------------------------------------------------------------------------------- /frontend/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /frontend/.env: -------------------------------------------------------------------------------- 1 | FAST_REFRESH='false' 2 | REACT_APP_MAP_KEY= 3 | ESLINT_NO_DEV_ERRORS='true' 4 | DISABLE_ESLINT_PLUGIN=true 5 | -------------------------------------------------------------------------------- /frontend/.eslintignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules/ 3 | .yarn/ 4 | 5 | # production 6 | build/ 7 | public/ 8 | 9 | # ide 10 | .vscode/ 11 | 12 | # external docs 13 | src/app/main/documentation/material-ui-components/components/* 14 | src/app/main/documentation/third-party-components/*/examples/* 15 | 16 | src/@fake-db/db/* 17 | -------------------------------------------------------------------------------- /frontend/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.yarn 6 | 7 | # testing 8 | /coverage 9 | 10 | # production 11 | /build 12 | 13 | # misc 14 | .DS_Store 15 | .env.local 16 | .env.development.local 17 | .env.test.local 18 | .env.production.local 19 | .eslintcache 20 | 21 | /.idea 22 | /.vscode 23 | 24 | /src/styles/tailwind.css 25 | env_vars.js 26 | 27 | npm-debug.log* 28 | yarn-debug.log* 29 | yarn-error.log* 30 | 31 | .yarn/* 32 | !.yarn/patches 33 | !.yarn/releases 34 | !.yarn/plugins 35 | !.yarn/sdks 36 | !.yarn/versions 37 | .pnp.* 38 | -------------------------------------------------------------------------------- /frontend/.npmrc: -------------------------------------------------------------------------------- 1 | legacy-peer-deps=true 2 | engine-strict=false 3 | -------------------------------------------------------------------------------- /frontend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine as builder 2 | # Set the working directory to /app inside the container 3 | WORKDIR /app 4 | # Copy app files 5 | COPY . . 6 | # Install dependencies (npm ci makes sure the exact versions in the lockfile gets installed) 7 | RUN npm ci 8 | # Build the app 9 | RUN npm run build 10 | 11 | # Bundle static assets with nginx 12 | FROM nginx:1.23.1-alpine as production 13 | ENV NODE_ENV production 14 | # Copy built assets from `builder` image 15 | COPY --from=builder /app/build /usr/share/nginx/html 16 | # Add your nginx.conf 17 | COPY nginx.conf /etc/nginx/conf.d/default.conf 18 | # Expose port 19 | EXPOSE 80 20 | # Start nginx 21 | CMD ["nginx", "-g", "daemon off;"] -------------------------------------------------------------------------------- /frontend/aliases.js: -------------------------------------------------------------------------------- 1 | const aliases = (prefix = `src`) => ({ 2 | '@fuse': `${prefix}/@fuse`, 3 | '@history': `${prefix}/@history`, 4 | '@lodash': `${prefix}/@lodash`, 5 | '@mock-api': `${prefix}/@mock-api`, 6 | 'app/store': `${prefix}/app/store`, 7 | 'app/shared-components': `${prefix}/app/shared-components`, 8 | 'app/configs': `${prefix}/app/configs`, 9 | 'app/theme-layouts': `${prefix}/app/theme-layouts`, 10 | 'app/AppContext': `${prefix}/app/AppContext`, 11 | }); 12 | 13 | module.exports = aliases; 14 | -------------------------------------------------------------------------------- /frontend/config-overrides.js: -------------------------------------------------------------------------------- 1 | const path = require(`path`); 2 | const alias = require(`./aliases`); 3 | const { aliasWebpack } = require('react-app-alias'); 4 | 5 | const SRC = `./src`; 6 | const aliases = alias(SRC); 7 | 8 | const resolvedAliases = Object.fromEntries( 9 | Object.entries(aliases).map(([key, value]) => [key, path.resolve(__dirname, value)]) 10 | ); 11 | 12 | const options = { 13 | alias: resolvedAliases, 14 | }; 15 | 16 | module.exports = function override(config) { 17 | config.ignoreWarnings = [{ message: /Failed to parse source map/ }]; 18 | 19 | return aliasWebpack(options)(config); 20 | }; 21 | -------------------------------------------------------------------------------- /frontend/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "@fuse/*": ["./src/@fuse/*"], 6 | "@history*": ["./src/@history"], 7 | "@lodash": ["./src/@lodash"], 8 | "@mock-api": ["./src/@mock-api"], 9 | "app/store/*": ["./src/app/store/*"], 10 | "app/shared-components/*": ["./src/app/shared-components/*"], 11 | "app/configs/*": ["./src/app/configs/*"], 12 | "app/theme-layouts/*": ["./src/app/theme-layouts/*"], 13 | "app/AppContext": ["./src/app/AppContext"] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /frontend/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80; 3 | 4 | location / { 5 | root /usr/share/nginx/html/; 6 | include /etc/nginx/mime.types; 7 | try_files $uri $uri/ /index.html; 8 | } 9 | } -------------------------------------------------------------------------------- /frontend/public/assets/fonts/inter/Inter-italic.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/fonts/inter/Inter-italic.var.woff2 -------------------------------------------------------------------------------- /frontend/public/assets/fonts/inter/Inter-roman.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/fonts/inter/Inter-roman.var.woff2 -------------------------------------------------------------------------------- /frontend/public/assets/fonts/inter/inter.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Inter var'; 3 | font-weight: 100 900; 4 | font-display: swap; 5 | font-style: normal; 6 | font-named-instance: 'Regular'; 7 | src: url("Inter-roman.var.woff2?v=3.18") format("woff2"); 8 | } 9 | 10 | @font-face { 11 | font-family: 'Inter var'; 12 | font-weight: 100 900; 13 | font-display: swap; 14 | font-style: italic; 15 | font-named-instance: 'Italic'; 16 | src: url("Inter-italic.var.woff2?v=3.18") format("woff2"); 17 | } 18 | -------------------------------------------------------------------------------- /frontend/public/assets/fonts/material-design-icons/MaterialIcons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/fonts/material-design-icons/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /frontend/public/assets/fonts/material-design-icons/MaterialIconsOutlined-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/fonts/material-design-icons/MaterialIconsOutlined-Regular.woff2 -------------------------------------------------------------------------------- /frontend/public/assets/fonts/material-design-icons/MaterialIconsRound-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/fonts/material-design-icons/MaterialIconsRound-Regular.woff2 -------------------------------------------------------------------------------- /frontend/public/assets/fonts/material-design-icons/MaterialIconsSharp-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/fonts/material-design-icons/MaterialIconsSharp-Regular.woff2 -------------------------------------------------------------------------------- /frontend/public/assets/fonts/material-design-icons/MaterialIconsTwoTone-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/fonts/material-design-icons/MaterialIconsTwoTone-Regular.woff2 -------------------------------------------------------------------------------- /frontend/public/assets/fonts/meteocons/fonts/meteocons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/fonts/meteocons/fonts/meteocons.ttf -------------------------------------------------------------------------------- /frontend/public/assets/fonts/meteocons/fonts/meteocons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/fonts/meteocons/fonts/meteocons.woff -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/contacts/flags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/contacts/flags.png -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/a-walk-amongst-friends.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/a-walk-amongst-friends.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/braies-lake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/braies-lake.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/fall-glow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/fall-glow.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/first-snow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/first-snow.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/lago-di-braies.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/lago-di-braies.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/lago-di-sorapis.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/lago-di-sorapis.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/morain-lake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/morain-lake.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/never-stop-changing.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/never-stop-changing.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/product-image-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/product-image-placeholder.png -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/reaching.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/reaching.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/ecommerce/yosemite.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/ecommerce/yosemite.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/help-center/image-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/help-center/image-1.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/mailbox/birds-eye-sydney_preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/mailbox/birds-eye-sydney_preview.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/mailbox/lake-of-carrezza_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/mailbox/lake-of-carrezza_preview.png -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/mailbox/mystery-forest_preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/mailbox/mystery-forest_preview.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/mailbox/yosemite-national-park_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/mailbox/yosemite-national-park_preview.png -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/a-walk-amongst-friends-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/a-walk-amongst-friends-small.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/braies-lake-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/braies-lake-small.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/fall-glow-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/fall-glow-small.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/first-snow-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/first-snow-small.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/lago-di-braies-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/lago-di-braies-small.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/lago-di-sorapis-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/lago-di-sorapis-small.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/morain-lake-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/morain-lake-small.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/morain-lake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/morain-lake.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/never-stop-changing-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/never-stop-changing-small.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/never-stop-changing.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/never-stop-changing.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/reaching-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/reaching-small.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/profile/yosemite-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/profile/yosemite-small.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/scrumboard/calendar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/scrumboard/calendar.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/scrumboard/header-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/scrumboard/header-1.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/scrumboard/header-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/scrumboard/header-2.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/apps/scrumboard/mail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/apps/scrumboard/mail.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/brian-hughes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/brian-hughes.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-01.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-02.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-03.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-04.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-05.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-06.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-07.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-08.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-09.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-10.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-11.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-12.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-13.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-14.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-15.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-16.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-17.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-18.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-19.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/female-20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/female-20.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-01.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-02.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-03.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-04.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-05.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-06.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-07.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-08.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-09.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-09.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-10.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-11.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-12.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-13.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-14.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-15.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-16.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-17.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-18.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-19.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/male-20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/male-20.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/avatars/user-default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/avatars/user-default.png -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/01-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/01-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/02-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/02-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/03-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/03-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/04-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/04-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/05-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/05-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/06-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/06-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/07-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/07-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/08-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/08-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/09-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/09-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/10-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/10-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/11-512x512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/11-512x512.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/12-512x512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/12-512x512.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/13-160x160.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/13-160x160.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/14-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/14-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/15-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/15-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/16-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/16-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/17-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/17-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/18-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/18-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/19-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/19-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/20-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/20-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/21-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/21-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/22-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/22-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/23-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/23-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/24-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/24-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/25-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/25-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/26-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/26-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/27-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/27-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/28-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/28-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/29-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/29-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/30-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/30-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/31-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/31-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/32-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/32-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/33-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/33-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/34-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/34-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/35-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/35-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/36-640x480.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/36-640x480.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/avatar-400x400.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/avatar-400x400.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/coffee-shop-01-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/coffee-shop-01-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/coffee-shop-02-512x512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/coffee-shop-02-512x512.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/coffee-shop-03-320x320.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/coffee-shop-03-320x320.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/mansion-01-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/mansion-01-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/product-01-224x256.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/product-01-224x256.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/sneakers-01-320x200.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/sneakers-01-320x200.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/sneakers-02-448x560.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/sneakers-02-448x560.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/cards/sneakers-03-448x560.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/cards/sneakers-03-448x560.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/demo-content/morain-lake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/demo-content/morain-lake.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/etc/directory-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/etc/directory-structure.png -------------------------------------------------------------------------------- /frontend/public/assets/images/etc/sample-file-preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/etc/sample-file-preview.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/flags/where-to-find-other-flags.txt: -------------------------------------------------------------------------------- 1 | ### Main repository of the flags ### 2 | https://github.com/Yummygum/flagpack-core 3 | 4 | ### We used the medium (m) detailed SVGs which are located here ### 5 | https://github.com/Yummygum/flagpack-core/tree/main/svg/m 6 | -------------------------------------------------------------------------------- /frontend/public/assets/images/logo-mini-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/logo-mini-white.png -------------------------------------------------------------------------------- /frontend/public/assets/images/logo-mini-white1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/logo-mini-white1.png -------------------------------------------------------------------------------- /frontend/public/assets/images/logo-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/logo-mini.png -------------------------------------------------------------------------------- /frontend/public/assets/images/logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/logo-white.png -------------------------------------------------------------------------------- /frontend/public/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/logo.png -------------------------------------------------------------------------------- /frontend/public/assets/images/pages/help-center/image-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/pages/help-center/image-1.jpg -------------------------------------------------------------------------------- /frontend/public/assets/images/pages/profile/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/assets/images/pages/profile/cover.jpg -------------------------------------------------------------------------------- /frontend/public/env/env_vars.example.js: -------------------------------------------------------------------------------- 1 | // create env_vars.js file with the desired values for the fields 2 | // 3 | // window.___env_vars___ = { 4 | // API_URL: 'http://localhost:8000' 5 | // }; 6 | 7 | -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /frontend/public/material-ui-static/brand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/brand.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/carbon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/carbon.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/favicon.ico -------------------------------------------------------------------------------- /frontend/public/material-ui-static/icons/150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/icons/150x150.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/icons/152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/icons/152x152.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/icons/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/icons/192x192.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/icons/256x256.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/icons/310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/icons/310x310.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/icons/384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/icons/384x384.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/icons/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/icons/48x48.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/icons/512x512.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/icons/70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/icons/70x70.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/icons/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/icons/96x96.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/avatar/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/avatar/1.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/avatar/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/avatar/2.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/avatar/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/avatar/3.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/avatar/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/avatar/4.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/avatar/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/avatar/5.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/avatar/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/avatar/6.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/avatar/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/avatar/7.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/blokt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/blokt.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/cards/contemplative-reptile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/cards/contemplative-reptile.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/cards/live-from-space.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/cards/live-from-space.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/cards/paella.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/cards/paella.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/color/colorTool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/color/colorTool.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/customization/dev-tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/customization/dev-tools.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/font-size.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/font-size.gif -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/bike.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/bike.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/breakfast.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/breakfast.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/burgers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/burgers.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/camera.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/camera.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/hats.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/hats.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/honey.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/honey.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/morning.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/morning.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/mushroom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/mushroom.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/olive.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/olive.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/plant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/plant.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/star.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/star.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid-list/vegetables.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid-list/vegetables.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/grid/complex.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/grid/complex.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/icons/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/icons/icons.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/material-ui-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/misc/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/misc/circle.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/progress/heavy-load.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/progress/heavy-load.gif -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/aexdownloadcenter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/aexdownloadcenter.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/arkoclub.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/arkoclub.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/audionodes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/audionodes.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/barks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/barks.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/bethesda.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/bethesda.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/bitcambio.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/bitcambio.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/builderbook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/builderbook.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/cityads.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/cityads.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/cloudhealth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/cloudhealth.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/code-typing-tutor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/code-typing-tutor.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/codementor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/codementor.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/collegeai.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/collegeai.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/comet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/comet.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/commitswimming.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/commitswimming.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/cryptoverview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/cryptoverview.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/dropdesk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/dropdesk.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/eostoolkit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/eostoolkit.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/eq3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/eq3.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/eventhi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/eventhi.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/fizix.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/fizix.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/flink.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/flink.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/fluxguard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/fluxguard.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/forex.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/forex.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/govx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/govx.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/hijup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/hijup.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/hkn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/hkn.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/housecall.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/housecall.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/icebergfinder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/icebergfinder.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/ifit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/ifit.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/johnnymetrics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/johnnymetrics.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/learnseeker.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/learnseeker.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/leroymerlin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/leroymerlin.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/lesswrong.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/lesswrong.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/localinsights.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/localinsights.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/localmonero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/localmonero.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/magicmondayz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/magicmondayz.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/manty.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/manty.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/melbournemint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/melbournemint.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/metafact.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/metafact.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/modole.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/modole.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/mqtt-explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/mqtt-explorer.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/neotracker.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/neotracker.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/npm-registry-browser.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/npm-registry-browser.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/numerai.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/numerai.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/odigeo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/odigeo.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/oneplanetcrowd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/oneplanetcrowd.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/oneshotmove.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/oneshotmove.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/openclassrooms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/openclassrooms.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/persona.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/persona.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/photoutils.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/photoutils.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/pilcro.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/pilcro.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/planalyze.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/planalyze.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/pointer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/pointer.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/posters-galore.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/posters-galore.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/quintoandar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/quintoandar.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/rarebits.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/rarebits.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/roast.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/roast.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/rung.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/rung.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/selfeducationapp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/selfeducationapp.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/sfrpresse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/sfrpresse.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/slidesup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/slidesup.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/snippets.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/snippets.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/sweek.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/sweek.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/swimmy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/swimmy.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/tentu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/tentu.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/themediaant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/themediaant.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/trafikito-monitoring.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/trafikito-monitoring.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/tree.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/tree.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/tudiscovery.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/tudiscovery.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/typekev.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/typekev.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/showcase/venuemob.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/showcase/venuemob.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/templates/album.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/templates/album.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/templates/blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/templates/blog.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/templates/checkout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/templates/checkout.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/templates/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/templates/dashboard.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/templates/pricing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/templates/pricing.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/templates/sign-in-side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/templates/sign-in-side.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/templates/sign-in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/templates/sign-in.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/templates/sign-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/templates/sign-up.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/templates/sticky-footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/templates/sticky-footer.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/text-fields/shrink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/text-fields/shrink.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/themes-dark.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/themes-dark.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/themes-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/themes-light.jpg -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/users/bethesda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/users/bethesda.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/users/capgemini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/users/capgemini.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/users/nasa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/users/nasa.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/users/uniqlo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/users/uniqlo.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/images/users/walmart-labs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/images/users/walmart-labs.png -------------------------------------------------------------------------------- /frontend/public/material-ui-static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JovianX/Service-Hub/be1889850c6bd9e9271350a1298c3fa6cff59b8d/frontend/public/material-ui-static/logo.png -------------------------------------------------------------------------------- /frontend/src/@fuse/colors/fuseDark.js: -------------------------------------------------------------------------------- 1 | const fuseDark = { 2 | 50: '#e5e6e8', 3 | 100: '#bec1c5', 4 | 200: '#92979f', 5 | 300: '#666d78', 6 | 400: '#464e5b', 7 | 500: '#252f3e', 8 | 600: '#212a38', 9 | 700: '#1b2330', 10 | 800: '#161d28', 11 | 900: '#0d121b', 12 | A100: '#5d8eff', 13 | A200: '#2a6aff', 14 | A400: '#004af6', 15 | A700: '#0042dd', 16 | contrastDefaultColor: 'light', 17 | }; 18 | 19 | export default fuseDark; 20 | -------------------------------------------------------------------------------- /frontend/src/@fuse/colors/index.js: -------------------------------------------------------------------------------- 1 | export { default as fuseDark } from './fuseDark'; 2 | export { default as skyBlue } from './skyBlue'; 3 | -------------------------------------------------------------------------------- /frontend/src/@fuse/colors/skyBlue.js: -------------------------------------------------------------------------------- 1 | const skyBlue = { 2 | 50: '#e4fafd', 3 | 100: '#bdf2fa', 4 | 200: '#91e9f7', 5 | 300: '#64e0f3', 6 | 400: '#43daf1', 7 | 500: '#22d3ee', 8 | 600: '#1eceec', 9 | 700: '#19c8e9', 10 | 800: '#14c2e7', 11 | 900: '#0cb7e2', 12 | A100: '#ffffff', 13 | A200: '#daf7ff', 14 | A400: '#a7ecff', 15 | A700: '#8de6ff', 16 | contrastDefaultColor: 'dark', 17 | }; 18 | 19 | export default skyBlue; 20 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/BrowserRouter/BrowserRouter.js: -------------------------------------------------------------------------------- 1 | import { useLayoutEffect, useState } from 'react'; 2 | import history from '@history'; 3 | import { Router } from 'react-router-dom'; 4 | 5 | function BrowserRouter({ basename, children, window }) { 6 | const [state, setState] = useState({ 7 | action: history.action, 8 | location: history.location, 9 | }); 10 | 11 | useLayoutEffect(() => history.listen(setState), [history]); 12 | 13 | return ( 14 | 20 | {children} 21 | 22 | ); 23 | } 24 | 25 | export default BrowserRouter; 26 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/BrowserRouter/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './BrowserRouter'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/DemoContent/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './DemoContent'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/DemoSidebarContent/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './DemoSidebarContent'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseAuthorization/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseAuthorization'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseCountdown/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseCountdown'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseDialog/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseDialog'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseExample/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseExample'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseHighlight/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseHighlight'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseLayout/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseLayout'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseLoading/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseLoading'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseMessage/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseMessage'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseNavigation/FuseNavItem.js: -------------------------------------------------------------------------------- 1 | const components = {}; 2 | 3 | export function registerComponent(name, Component) { 4 | components[name] = Component; 5 | } 6 | 7 | export default function FuseNavItem(props) { 8 | const C = components[props.type]; 9 | return C ? : null; 10 | } 11 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseNavigation/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseNavigation'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FusePageCarded/FusePageCardedHeader.js: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx'; 2 | 3 | function FusePageCardedHeader(props) { 4 | return ( 5 |
{props.header && props.header}
6 | ); 7 | } 8 | 9 | export default FusePageCardedHeader; 10 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FusePageCarded/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FusePageCarded'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FusePageSimple/FusePageSimpleHeader.js: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx'; 2 | 3 | function FusePageSimpleHeader(props) { 4 | return ( 5 |
6 |
{props.header && props.header}
7 |
8 | ); 9 | } 10 | 11 | export default FusePageSimpleHeader; 12 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FusePageSimple/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FusePageSimple'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseScrollbars/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseScrollbars'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseSearch/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseSearch'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseSettings/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseSettings'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseShortcuts/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseShortcuts'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseSidePanel/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseSidePanel'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseSplashScreen/FuseSplashScreen.js: -------------------------------------------------------------------------------- 1 | import Box from '@mui/material/Box'; 2 | import { memo } from 'react'; 3 | 4 | function FuseSplashScreen() { 5 | return ( 6 |
7 |
8 | logo 9 |
10 | div': { 14 | backgroundColor: 'palette.secondary.light', 15 | }, 16 | }} 17 | > 18 |
19 |
20 |
21 | 22 |
23 | ); 24 | } 25 | 26 | export default memo(FuseSplashScreen); 27 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseSplashScreen/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseSplashScreen'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseSuspense/FuseSuspense.js: -------------------------------------------------------------------------------- 1 | import FuseLoading from '@fuse/core/FuseLoading'; 2 | import PropTypes from 'prop-types'; 3 | import { Suspense } from 'react'; 4 | 5 | /** 6 | * React Suspense defaults 7 | * For to Avoid Repetition 8 | */ function FuseSuspense(props) { 9 | return }>{props.children}; 10 | } 11 | 12 | FuseSuspense.propTypes = { 13 | loadingProps: PropTypes.object, 14 | }; 15 | 16 | FuseSuspense.defaultProps = { 17 | loadingProps: { 18 | delay: 0, 19 | }, 20 | }; 21 | 22 | export default FuseSuspense; 23 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseSuspense/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseSuspense'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseSvgIcon/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseSvgIcon'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseTheme/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseTheme'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/FuseThemeSchemes/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseThemeSchemes'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/NavLinkAdapter/NavLinkAdapter.js: -------------------------------------------------------------------------------- 1 | import { forwardRef } from 'react'; 2 | import { NavLink as BaseNavLink } from 'react-router-dom'; 3 | 4 | const NavLinkAdapter = forwardRef(({ activeClassName, activeStyle, ...props }, ref) => { 5 | return ( 6 | [props.className, isActive ? activeClassName : null].filter(Boolean).join(' ')} 10 | style={({ isActive }) => ({ 11 | ...props.style, 12 | ...(isActive ? activeStyle : null), 13 | })} 14 | /> 15 | ); 16 | }); 17 | 18 | export default NavLinkAdapter; 19 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/NavLinkAdapter/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './NavLinkAdapter'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/withRouter/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './withRouter'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/withRouter/withRouter.js: -------------------------------------------------------------------------------- 1 | import { useLocation, useNavigate } from 'react-router-dom'; 2 | 3 | function withRouter(Child) { 4 | return (props) => { 5 | const location = useLocation(); 6 | const navigate = useNavigate(); 7 | return ; 8 | }; 9 | } 10 | 11 | export default withRouter; 12 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/withRouterAndRef/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './withRouterAndRef'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/core/withRouterAndRef/withRouterAndRef.js: -------------------------------------------------------------------------------- 1 | import { Component, forwardRef } from 'react'; 2 | import withRouter from '@fuse/core/withRouter'; 3 | 4 | const withRouterAndRef = (WrappedComponent) => { 5 | class InnerComponentWithRef extends Component { 6 | render() { 7 | const { forwardRef: _forwardRef, ...rest } = this.props; 8 | return ; 9 | } 10 | } 11 | 12 | const ComponentWithRouter = withRouter(InnerComponentWithRef, { withRef: true }); 13 | return forwardRef((props, ref) => ); 14 | }; 15 | 16 | export default withRouterAndRef; 17 | -------------------------------------------------------------------------------- /frontend/src/@fuse/default-settings/index.js: -------------------------------------------------------------------------------- 1 | export * from './FuseDefaultSettings'; 2 | -------------------------------------------------------------------------------- /frontend/src/@fuse/hooks/index.js: -------------------------------------------------------------------------------- 1 | export { default as useForm } from './useForm'; 2 | export { default as useDebounce } from './useDebounce'; 3 | export { default as useTimeout } from './useTimeout'; 4 | export { default as usePrevious } from './usePrevious'; 5 | export { default as useUpdateEffect } from './useUpdateEffect'; 6 | export { default as useDeepCompareEffect } from './useDeepCompareEffect'; 7 | export { default as useThemeMediaQuery } from './useThemeMediaQuery'; 8 | export { default as useEventListener } from './useEventListener'; 9 | -------------------------------------------------------------------------------- /frontend/src/@fuse/hooks/useDebounce.js: -------------------------------------------------------------------------------- 1 | import _ from '@lodash'; 2 | import { useRef } from 'react'; 3 | 4 | function useDebounce(func, wait, options) { 5 | return useRef(_.debounce(func, wait, options)).current; 6 | } 7 | 8 | export default useDebounce; 9 | -------------------------------------------------------------------------------- /frontend/src/@fuse/hooks/usePrevious.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | 3 | function usePrevious(value) { 4 | // The ref object is a generic container whose current property is mutable ... 5 | // ... and can hold any value, similar to an instance property on a class 6 | const ref = useRef(); 7 | 8 | // Store current value in ref 9 | useEffect(() => { 10 | ref.current = value; 11 | }, [value]); // Only re-run if value changes 12 | 13 | // Return previous value (happens before update in useEffect above) 14 | return ref.current; 15 | } 16 | 17 | export default usePrevious; 18 | -------------------------------------------------------------------------------- /frontend/src/@fuse/hooks/useTimeout.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | 3 | function useTimeout(callback, delay) { 4 | const callbackRef = useRef(callback); 5 | 6 | useEffect(() => { 7 | callbackRef.current = callback; 8 | }, [callback]); 9 | 10 | useEffect(() => { 11 | let timer; 12 | 13 | if (delay && callback && typeof callback === 'function') { 14 | timer = setTimeout(callbackRef.current, delay || 0); 15 | } 16 | 17 | return () => { 18 | if (timer) { 19 | clearTimeout(timer); 20 | } 21 | }; 22 | }, [callback, delay]); 23 | } 24 | 25 | export default useTimeout; 26 | -------------------------------------------------------------------------------- /frontend/src/@fuse/hooks/useUpdateEffect.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | 3 | const useUpdateEffect = (effect, deps) => { 4 | const isInitialMount = useRef(true); 5 | // eslint-disable-next-line 6 | useEffect( 7 | isInitialMount.current 8 | ? () => { 9 | isInitialMount.current = false; 10 | } 11 | : effect, 12 | deps 13 | ); 14 | }; 15 | 16 | export default useUpdateEffect; 17 | -------------------------------------------------------------------------------- /frontend/src/@fuse/utils/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './FuseUtils'; 2 | -------------------------------------------------------------------------------- /frontend/src/@history/@history.js: -------------------------------------------------------------------------------- 1 | import * as history from 'history'; 2 | 3 | export default history.createBrowserHistory(); 4 | -------------------------------------------------------------------------------- /frontend/src/@history/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './@history'; 2 | -------------------------------------------------------------------------------- /frontend/src/@lodash/@lodash.js: -------------------------------------------------------------------------------- 1 | import __ from 'lodash'; 2 | 3 | /** 4 | * You can extend Lodash with mixins 5 | * And use it as below 6 | * import _ from '@lodash' 7 | */ 8 | const _ = __.runInContext(); 9 | 10 | _.mixin({ 11 | // Immutable Set for setting state 12 | setIn: (state, name, value) => { 13 | return _.setWith(_.clone(state), name, value, _.clone); 14 | }, 15 | }); 16 | 17 | export default _; 18 | -------------------------------------------------------------------------------- /frontend/src/@lodash/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './@lodash'; 2 | -------------------------------------------------------------------------------- /frontend/src/@mock-api/index.js: -------------------------------------------------------------------------------- 1 | import './api/auth-api'; 2 | import './api/notifications-api'; 3 | import history from '@history'; 4 | import mock from './mock'; 5 | 6 | mock.onAny().passThrough(); 7 | 8 | if (module?.hot?.status() === 'apply') { 9 | const { pathname } = history.location; 10 | history.push('/loading'); 11 | history.push({ pathname }); 12 | } 13 | -------------------------------------------------------------------------------- /frontend/src/@mock-api/mock.js: -------------------------------------------------------------------------------- 1 | const MockAdapter = require('axios-mock-adapter'); 2 | const axios = require('axios'); 3 | 4 | const mock = new MockAdapter(axios, { delayResponse: 0 }); 5 | export default mock; 6 | -------------------------------------------------------------------------------- /frontend/src/app/AppContext.js: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | const AppContext = createContext({}); 4 | 5 | export default AppContext; 6 | -------------------------------------------------------------------------------- /frontend/src/app/api/accessTokens.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const ACCESS_TOKENS_API_PATH = '/api/v1/access-token'; 4 | 5 | export const getAccessTokensList = async () => await axios.get(`${ACCESS_TOKENS_API_PATH}/list`); 6 | 7 | export const createAccessToken = async (tokenData) => axios.post(`${ACCESS_TOKENS_API_PATH}/`, tokenData); 8 | 9 | export const changeAccessTokenStatus = async (token, status) => 10 | await axios.post(`${ACCESS_TOKENS_API_PATH}/${token}/status`, status); 11 | 12 | export const deleteAccessToken = async (token) => await axios.delete(`${ACCESS_TOKENS_API_PATH}/${token}`); 13 | -------------------------------------------------------------------------------- /frontend/src/app/api/applications.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const APPLICATIONS_API_PATH = '/api/v1/application'; 4 | 5 | export const getApplicationsList = async () => await axios.get(`${APPLICATIONS_API_PATH}/list`); 6 | export const applicationInstall = async (application) => 7 | await axios.post(`${APPLICATIONS_API_PATH}/install`, application); 8 | export const deleteApplication = async (id) => await axios.delete(`${APPLICATIONS_API_PATH}/${id}`); 9 | 10 | export const createApplicationTtl = async (id, hours) => await axios.post(`${APPLICATIONS_API_PATH}/${id}/ttl`, hours); 11 | export const getApplicationOutputs = async (id) => await axios.get(`${APPLICATIONS_API_PATH}/${id}/outputs`); 12 | -------------------------------------------------------------------------------- /frontend/src/app/api/clusters.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const CLUSTERS_API_PATH = '/api/v1/organization'; 4 | 5 | export const getClusterList = async () => await axios.get(`${CLUSTERS_API_PATH}/kubernetes-configuration`); 6 | 7 | export const deleteContext = async (contextName) => 8 | await axios.delete(`${CLUSTERS_API_PATH}/kubernetes-configuration/context`, { 9 | params: { 10 | 'context-name': contextName, 11 | }, 12 | }); 13 | 14 | export const uploadConfiguration = async (configuration) => 15 | await axios.post(`${CLUSTERS_API_PATH}/kubernetes-configuration`, configuration); 16 | -------------------------------------------------------------------------------- /frontend/src/app/api/dashboard.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const DASHBOARD_API_PATH = '/api/v1/dashboard/'; 4 | 5 | export const getReleaseCount = async () => await axios.get(`${DASHBOARD_API_PATH}release-count`); 6 | export const getRepositoryCount = async () => await axios.get(`${DASHBOARD_API_PATH}repository-count`); 7 | export const getChartCount = async () => await axios.get(`${DASHBOARD_API_PATH}chart-count`); 8 | export const getContextCount = async () => await axios.get(`${DASHBOARD_API_PATH}context-count`); 9 | export const getUnhealthyCount = async () => await axios.get(`${DASHBOARD_API_PATH}unhealthy-count`); 10 | export const getServiceCount = async () => await axios.get(`${DASHBOARD_API_PATH}services-count`); 11 | -------------------------------------------------------------------------------- /frontend/src/app/api/events.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const EVENTS_API_PATH = '/api/v1/event/list'; 4 | 5 | export const getApplicationEventsList = async (category, application_id) => 6 | await axios.get(`${EVENTS_API_PATH}/${category}?application_id=${application_id}`); 7 | -------------------------------------------------------------------------------- /frontend/src/app/api/index.js: -------------------------------------------------------------------------------- 1 | export * from './releases'; 2 | export * from './dashboard'; 3 | export * from './charts'; 4 | export * from './repositories'; 5 | export * from './services'; 6 | export * from './clusters'; 7 | export * from './kubernetes'; 8 | export * from './invitations'; 9 | export * from './users'; 10 | export * from './applications'; 11 | export * from './templates'; 12 | export * from './accessTokens'; 13 | -------------------------------------------------------------------------------- /frontend/src/app/api/invitations.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const INVITE_API_PATH = '/api/v1/invitation'; 4 | 5 | export const getInvitationsList = async () => await axios.get(`${INVITE_API_PATH}/list`); 6 | export const addInvitation = async (user) => await axios.post(`${INVITE_API_PATH}/`, user); 7 | export const deleteInvitation = async (id) => await axios.delete(`${INVITE_API_PATH}/${id}`); 8 | export const sendInvitation = async (id) => await axios.post(`${INVITE_API_PATH}/${id}/send-email`); 9 | export const getInvitedUserEmail = async (id) => await axios.get(`${INVITE_API_PATH}/${id}/email`); 10 | -------------------------------------------------------------------------------- /frontend/src/app/api/kubernetes.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const KUBERNETES_API_PATH = '/api/v1/dashboard/'; 4 | 5 | export const getNamespaceList = async () => await axios.get(`${KUBERNETES_API_PATH}/namespace/list`); 6 | 7 | export const getIngressList = async () => await axios.get(`${KUBERNETES_API_PATH}/ingress/list`); 8 | 9 | export const getKubernetesServiceList = async () => await axios.get(`${KUBERNETES_API_PATH}/service/list`); 10 | -------------------------------------------------------------------------------- /frontend/src/app/api/repositories.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const REPOSITORY_API_PATH = '/api/v1/helm/repository'; 4 | 5 | export const getRepositoryList = async () => await axios.get(`${REPOSITORY_API_PATH}/list`); 6 | export const createRepository = async (repository) => await axios.post(`${REPOSITORY_API_PATH}/add`, repository); 7 | export const deleteRepository = async (repository) => await axios.delete(`${REPOSITORY_API_PATH}/${repository}`); 8 | -------------------------------------------------------------------------------- /frontend/src/app/api/services.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const SERVICE_API_PATH = '/api/v1/service'; 4 | 5 | export const getServiceList = async () => await axios.get(`${SERVICE_API_PATH}/list`); 6 | -------------------------------------------------------------------------------- /frontend/src/app/api/templates.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const TEMPLATES_API_PATH = '/api/v1/template'; 4 | 5 | export const getTemplatesList = async () => await axios.get(`${TEMPLATES_API_PATH}/list`); 6 | export const makeTemplateDefault = async (id) => await axios.post(`${TEMPLATES_API_PATH}/${id}/make-default`); 7 | export const createTemplate = async (template) => await axios.post(`${TEMPLATES_API_PATH}/`, template); 8 | export const deleteTemplate = async (id) => await axios.delete(`${TEMPLATES_API_PATH}/${id}`); 9 | export const editTemplate = async (id, template) => await axios.patch(`${TEMPLATES_API_PATH}/${id}`, template); 10 | -------------------------------------------------------------------------------- /frontend/src/app/api/users.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | const USERS_API_PATH = '/api/v1/user'; 4 | 5 | export const getUsersList = async () => await axios.get(`${USERS_API_PATH}/list`); 6 | export const activateUser = async (id) => await axios.post(`${USERS_API_PATH}/${id}/activate`); 7 | export const deactivateUser = async (id) => await axios.post(`${USERS_API_PATH}/${id}/deactivate`); 8 | export const deleteUser = async (id) => await axios.delete(`${USERS_API_PATH}/${id}`); 9 | export const changeUserRole = async (userData) => await axios.post(`${USERS_API_PATH}/role/set`, userData); 10 | -------------------------------------------------------------------------------- /frontend/src/app/auth/authRoles.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Authorization Roles 3 | */ 4 | const authRoles = { 5 | admin: ['admin'], 6 | staff: ['admin', 'operator'], 7 | user: ['admin', 'staff', 'user'], 8 | onlyGuest: [], 9 | }; 10 | 11 | export default authRoles; 12 | -------------------------------------------------------------------------------- /frontend/src/app/auth/index.js: -------------------------------------------------------------------------------- 1 | export { default as authRoles } from './authRoles'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/auth/services/jwtService/index.js: -------------------------------------------------------------------------------- 1 | import JwtService from './jwtService'; 2 | 3 | export default JwtService; 4 | -------------------------------------------------------------------------------- /frontend/src/app/auth/services/jwtService/jwtServiceConfig.js: -------------------------------------------------------------------------------- 1 | const authApiPath = 'api/v1/auth'; 2 | 3 | const jwtServiceConfig = { 4 | signIn: `${authApiPath}/jwt/login`, 5 | logout: `${authApiPath}/jwt/logout`, 6 | signUp: (id) => (id ? `${authApiPath}/register?invite_id=${id}` : `${authApiPath}/register`), 7 | forgotPassword: `${authApiPath}/forgot-password`, 8 | resetPassword: `${authApiPath}/reset-password`, 9 | signInWithGithub: `${authApiPath}/github/authorize`, 10 | getTokenWithGithubCode: `${authApiPath}/github/callback`, 11 | userMe: 'api/v1/user/me', 12 | }; 13 | 14 | export default jwtServiceConfig; 15 | -------------------------------------------------------------------------------- /frontend/src/app/configs/navigation-i18n/ar.js: -------------------------------------------------------------------------------- 1 | const locale = { 2 | APPLICATIONS: 'تطبيقات', 3 | EXAMPLE: 'مثال', 4 | }; 5 | 6 | export default locale; 7 | -------------------------------------------------------------------------------- /frontend/src/app/configs/navigation-i18n/en.js: -------------------------------------------------------------------------------- 1 | const locale = { 2 | APPLICATIONS: 'SERVICES', 3 | EXAMPLE: 'Example', 4 | }; 5 | 6 | export default locale; 7 | -------------------------------------------------------------------------------- /frontend/src/app/configs/navigation-i18n/tr.js: -------------------------------------------------------------------------------- 1 | const locale = { 2 | APPLICATIONS: 'Programlar', 3 | EXAMPLE: 'Örnek Sayfa', 4 | }; 5 | 6 | export default locale; 7 | -------------------------------------------------------------------------------- /frontend/src/app/constants/API.js: -------------------------------------------------------------------------------- 1 | export const ABSOLUTE_API_HOST = window?.___env_vars___?.API_URL || 'http://localhost:8000'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/constants/auth.js: -------------------------------------------------------------------------------- 1 | export const AUTH_ERROR_CODES = { 2 | REGISTER_INVALID_PASSWORD: 'Invalid password', 3 | REGISTER_USER_ALREADY_EXISTS: 'User already exists', 4 | OAUTH_USER_ALREADY_EXISTS: 'User already exists', 5 | LOGIN_BAD_CREDENTIALS: 'Wrong email or password', 6 | LOGIN_USER_NOT_VERIFIED: 'User is not verified', 7 | RESET_PASSWORD_BAD_TOKEN: 'Bad token', 8 | RESET_PASSWORD_INVALID_PASSWORD: 'Invalid password', 9 | VERIFY_USER_BAD_TOKEN: 'Bad token', 10 | VERIFY_USER_ALREADY_VERIFIED: 'User is already verified', 11 | UPDATE_USER_EMAIL_ALREADY_EXISTS: 'Email already exists', 12 | UPDATE_USER_INVALID_PASSWORD: 'Invalid password', 13 | }; 14 | -------------------------------------------------------------------------------- /frontend/src/app/constants/categoriesOfEvents.js: -------------------------------------------------------------------------------- 1 | export const CATEGORIES_OF_EVENTS = { 2 | APPLICATION: 'application', 3 | HOOK: 'hook', 4 | ORGANIZATION: 'organization', 5 | HELM: 'helm', 6 | }; 7 | -------------------------------------------------------------------------------- /frontend/src/app/constants/kubeconfigUrl.js: -------------------------------------------------------------------------------- 1 | import { ABSOLUTE_API_HOST } from './API'; 2 | 3 | const jwtAccessToken = localStorage.getItem('jwt_access_token'); 4 | export const kubeconfigUrl = `curl -s https://kubeconfig.jovianx.app/install | bash -s -- --jwt-token ${jwtAccessToken} --jovianx-url ${ABSOLUTE_API_HOST}`; 5 | -------------------------------------------------------------------------------- /frontend/src/app/constants/paths.js: -------------------------------------------------------------------------------- 1 | export const PATHS = { 2 | ACCESS_TOKENS: 'access-tokens', 3 | APPLICATIONS: 'applications', 4 | APPLICATION_DETAILS: 'applications/:id', 5 | SERVICES: 'services', 6 | SERVICE_CREATE: 'services/create', 7 | CHARTS: 'charts', 8 | CLUSTERS: 'clusters', 9 | DASHBOARD: 'dashboard', 10 | RELEASES: 'releases', 11 | RELEASE_DETAILS: 'releases/:id', 12 | REPOSITORIES: 'repositories', 13 | TEMPLATES: 'templates', 14 | SIGN_IN: 'sign-in', 15 | SIGN_UP: 'sign-up', 16 | SIGN_OUT: 'sign-out', 17 | FORGOT_PASSWORD: 'forgot-password', 18 | RESET_PASSWORD: 'reset-password', 19 | }; 20 | -------------------------------------------------------------------------------- /frontend/src/app/hooks/useGetMe.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from 'react-redux'; 2 | 3 | import { selectUser } from 'app/store/userSlice'; 4 | 5 | export const useGetMe = () => { 6 | const user = useSelector(selectUser); 7 | return user; 8 | }; 9 | -------------------------------------------------------------------------------- /frontend/src/app/main/access-tokens/AccessTokens.js: -------------------------------------------------------------------------------- 1 | import FusePageCarded from '@fuse/core/FusePageCarded'; 2 | import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery'; 3 | import TableHeader from 'app/shared-components/TableHeader'; 4 | 5 | import AccessTokensPage from './AccessTokensPage'; 6 | 7 | const AccessTokens = () => { 8 | const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg')); 9 | 10 | return ( 11 | } 13 | content={} 14 | scroll={isMobile ? 'normal' : 'content'} 15 | className='px-24' 16 | /> 17 | ); 18 | }; 19 | 20 | export default AccessTokens; 21 | -------------------------------------------------------------------------------- /frontend/src/app/main/access-tokens/AccessTokensConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../constants/paths'; 4 | 5 | const AccessTokens = lazy(() => import('./AccessTokens')); 6 | 7 | const AccessTokensConfig = { 8 | settings: { 9 | layout: { 10 | config: {}, 11 | }, 12 | }, 13 | routes: [ 14 | { 15 | path: PATHS.ACCESS_TOKENS, 16 | element: , 17 | }, 18 | ], 19 | }; 20 | 21 | export default AccessTokensConfig; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/applications/ApplicationDetails/Application.js: -------------------------------------------------------------------------------- 1 | import FusePageCarded from '@fuse/core/FusePageCarded'; 2 | import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery'; 3 | 4 | import ApplicationItem from './ApplicationItem'; 5 | 6 | const Application = () => { 7 | const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg')); 8 | 9 | return ( 10 | } 12 | scroll={isMobile ? 'normal' : 'content'} 13 | className='px-24 pt-[34px]' 14 | /> 15 | ); 16 | }; 17 | 18 | export default Application; 19 | -------------------------------------------------------------------------------- /frontend/src/app/main/applications/ApplicationDetails/ApplicationDetailsConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../../constants/paths'; 4 | 5 | const ApplicationDetails = lazy(() => import('./Application')); 6 | 7 | const ApplicationDetailsConfig = { 8 | settings: { 9 | layout: { 10 | config: {}, 11 | }, 12 | }, 13 | routes: [ 14 | { 15 | path: PATHS.APPLICATION_DETAILS, 16 | element: , 17 | }, 18 | ], 19 | }; 20 | 21 | export default ApplicationDetailsConfig; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/applications/ApplicationDetails/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Application'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/main/applications/Applications.js: -------------------------------------------------------------------------------- 1 | import FusePageCarded from '@fuse/core/FusePageCarded'; 2 | import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery'; 3 | import TableHeader from 'app/shared-components/TableHeader'; 4 | 5 | import ApplicationsTable from './ApplicationsTable'; 6 | 7 | const Application = () => { 8 | const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg')); 9 | 10 | return ( 11 | } 13 | content={} 14 | scroll={isMobile ? 'normal' : 'content'} 15 | className='px-24' 16 | /> 17 | ); 18 | }; 19 | 20 | export default Application; 21 | -------------------------------------------------------------------------------- /frontend/src/app/main/applications/ApplicationsConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../constants/paths'; 4 | 5 | const Applications = lazy(() => import('./Applications')); 6 | 7 | const ApplicationsConfig = { 8 | settings: { 9 | layout: { 10 | config: {}, 11 | }, 12 | }, 13 | routes: [ 14 | { 15 | path: PATHS.APPLICATIONS, 16 | element: , 17 | }, 18 | ], 19 | }; 20 | 21 | export default ApplicationsConfig; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/applications/TemplateInputs/TypeCheckbox.js: -------------------------------------------------------------------------------- 1 | import { Checkbox, FormControl, FormHelperText } from '@mui/material'; 2 | import FormControlLabel from '@mui/material/FormControlLabel'; 3 | 4 | const TypeCheckbox = ({ item, onChangeInputs }) => { 5 | return ( 6 | 7 | } 9 | label={item.label} 10 | labelPlacement='end' 11 | onChange={(e) => onChangeInputs(e, item)} 12 | /> 13 | {item?.description} 14 | 15 | ); 16 | }; 17 | 18 | export default TypeCheckbox; 19 | -------------------------------------------------------------------------------- /frontend/src/app/main/applications/TemplateInputs/TypeSwitch.js: -------------------------------------------------------------------------------- 1 | import { FormControl, FormHelperText } from '@mui/material'; 2 | import FormControlLabel from '@mui/material/FormControlLabel'; 3 | import Switch from '@mui/material/Switch'; 4 | import { Box } from '@mui/system'; 5 | 6 | const TypeSwitch = ({ item, onChangeInputs }) => { 7 | return ( 8 | 9 | 10 | } 12 | label={item.label} 13 | onChange={(e) => onChangeInputs(e, item)} 14 | /> 15 | {item?.description} 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default TypeSwitch; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/applications/TemplateInputs/TypeText.js: -------------------------------------------------------------------------------- 1 | import { FormHelperText } from '@mui/material'; 2 | import FormControl from '@mui/material/FormControl'; 3 | import TextField from '@mui/material/TextField'; 4 | 5 | const TypeText = ({ item, onChangeInputs }) => { 6 | return ( 7 | 8 | onChangeInputs(e, item)} 15 | /> 16 | {item?.description} 17 | 18 | ); 19 | }; 20 | 21 | export default TypeText; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/applications/TemplateInputs/TypeTextarea.js: -------------------------------------------------------------------------------- 1 | import { FormHelperText } from '@mui/material'; 2 | import FormControl from '@mui/material/FormControl'; 3 | import TextField from '@mui/material/TextField'; 4 | 5 | const TypeTextarea = ({ item, onChangeInputs }) => { 6 | return ( 7 | 8 | onChangeInputs(e, item)} 16 | /> 17 | {item?.description} 18 | 19 | ); 20 | }; 21 | 22 | export default TypeTextarea; 23 | -------------------------------------------------------------------------------- /frontend/src/app/main/applications/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Applications'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/main/charts/Charts.js: -------------------------------------------------------------------------------- 1 | import FusePageCarded from '@fuse/core/FusePageCarded'; 2 | import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery'; 3 | import TableHeader from 'app/shared-components/TableHeader'; 4 | 5 | import ChartsTable from './ChartsTable'; 6 | 7 | const Charts = () => { 8 | const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg')); 9 | 10 | return ( 11 | } 13 | content={} 14 | scroll={isMobile ? 'normal' : 'content'} 15 | className='px-24' 16 | /> 17 | ); 18 | }; 19 | 20 | export default Charts; 21 | -------------------------------------------------------------------------------- /frontend/src/app/main/charts/ChartsConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../constants/paths'; 4 | 5 | const Charts = lazy(() => import('./Charts')); 6 | 7 | const ChartsConfig = { 8 | settings: { 9 | layout: { 10 | config: {}, 11 | }, 12 | }, 13 | routes: [ 14 | { 15 | path: PATHS.CHARTS, 16 | element: , 17 | }, 18 | ], 19 | }; 20 | 21 | export default ChartsConfig; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/charts/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Charts'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/main/clusters/Clusters.js: -------------------------------------------------------------------------------- 1 | import FusePageCarded from '@fuse/core/FusePageCarded'; 2 | import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery'; 3 | import TableHeader from 'app/shared-components/TableHeader'; 4 | 5 | import ClustersBlocks from './ClustersBlocks'; 6 | 7 | const Clusters = () => { 8 | const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg')); 9 | 10 | return ( 11 | } 13 | content={} 14 | scroll={isMobile ? 'normal' : 'content'} 15 | className='px-24' 16 | /> 17 | ); 18 | }; 19 | 20 | export default Clusters; 21 | -------------------------------------------------------------------------------- /frontend/src/app/main/clusters/ClustersConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../constants/paths'; 4 | 5 | const Clusters = lazy(() => import('./Clusters')); 6 | 7 | const ClustersConfig = { 8 | settings: { 9 | layout: { 10 | config: {}, 11 | }, 12 | }, 13 | routes: [ 14 | { 15 | path: PATHS.CLUSTERS, 16 | element: , 17 | }, 18 | ], 19 | }; 20 | 21 | export default ClustersConfig; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/clusters/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Clusters'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/main/dashboard/DashboardConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../constants/paths'; 4 | 5 | const Dashboard = lazy(() => import('./Dashboard')); 6 | 7 | const DashboardConfig = { 8 | settings: { 9 | layout: { 10 | config: {}, 11 | }, 12 | }, 13 | routes: [ 14 | { 15 | path: PATHS.DASHBOARD, 16 | element: , 17 | }, 18 | ], 19 | }; 20 | 21 | export default DashboardConfig; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/dashboard/DashboardModal/ModalStepper.js: -------------------------------------------------------------------------------- 1 | import Box from '@mui/material/Box'; 2 | import Step from '@mui/material/Step'; 3 | import StepLabel from '@mui/material/StepLabel'; 4 | import Stepper from '@mui/material/Stepper'; 5 | 6 | const steps = ['Create Account', 'Add Kubernetes Cluster']; 7 | 8 | const ModalStepper = () => { 9 | return ( 10 | 11 | 12 | {steps.map((label) => ( 13 | 14 | {label} 15 | 16 | ))} 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default ModalStepper; 23 | -------------------------------------------------------------------------------- /frontend/src/app/main/example/i18n/ar.js: -------------------------------------------------------------------------------- 1 | const locale = { TITLE: 'مثال على الصفحة' }; 2 | 3 | export default locale; 4 | -------------------------------------------------------------------------------- /frontend/src/app/main/example/i18n/en.js: -------------------------------------------------------------------------------- 1 | const locale = { TITLE: 'Example Page' }; 2 | 3 | export default locale; 4 | -------------------------------------------------------------------------------- /frontend/src/app/main/example/i18n/tr.js: -------------------------------------------------------------------------------- 1 | const locale = { TITLE: 'Örnek Sayfa' }; 2 | 3 | export default locale; 4 | -------------------------------------------------------------------------------- /frontend/src/app/main/releases/ReleaseDetails/ReleaseDetails.js: -------------------------------------------------------------------------------- 1 | import FusePageCarded from '@fuse/core/FusePageCarded'; 2 | import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery'; 3 | 4 | import ReleaseItem from './ReleaseItem'; 5 | 6 | const Releases = () => { 7 | const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg')); 8 | 9 | return ( 10 | } 12 | scroll={isMobile ? 'normal' : 'content'} 13 | className='px-24 pt-[34px]' 14 | /> 15 | ); 16 | }; 17 | 18 | export default Releases; 19 | -------------------------------------------------------------------------------- /frontend/src/app/main/releases/ReleaseDetails/ReleaseDetailsConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../../constants/paths'; 4 | 5 | const ReleaseDetails = lazy(() => import('./ReleaseDetails')); 6 | 7 | const ReleasesConfig = { 8 | settings: { 9 | layout: { 10 | config: {}, 11 | }, 12 | }, 13 | routes: [ 14 | { 15 | path: PATHS.RELEASE_DETAILS, 16 | element: , 17 | }, 18 | ], 19 | }; 20 | 21 | export default ReleasesConfig; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/releases/ReleaseDetails/ReleaseTabs/TabValues/NotesValue.js: -------------------------------------------------------------------------------- 1 | import MonacoEditor from '@uiw/react-monacoeditor'; 2 | 3 | const NotesValue = ({ notes }) => { 4 | return ( 5 | 11 | ); 12 | }; 13 | 14 | export default NotesValue; 15 | -------------------------------------------------------------------------------- /frontend/src/app/main/releases/ReleaseDetails/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './ReleaseDetails'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/main/releases/Releases.js: -------------------------------------------------------------------------------- 1 | import FusePageCarded from '@fuse/core/FusePageCarded'; 2 | import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery'; 3 | import TableHeader from 'app/shared-components/TableHeader'; 4 | 5 | import ReleasesTable from './ReleasesTable'; 6 | 7 | const Releases = () => { 8 | const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg')); 9 | 10 | return ( 11 | } 13 | content={} 14 | scroll={isMobile ? 'normal' : 'content'} 15 | className='px-24' 16 | /> 17 | ); 18 | }; 19 | 20 | export default Releases; 21 | -------------------------------------------------------------------------------- /frontend/src/app/main/releases/ReleasesConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../constants/paths'; 4 | 5 | const Releases = lazy(() => import('./Releases')); 6 | 7 | const ReleasesConfig = { 8 | settings: { 9 | layout: { 10 | config: {}, 11 | }, 12 | }, 13 | routes: [ 14 | { 15 | path: PATHS.RELEASES, 16 | element: , 17 | }, 18 | ], 19 | }; 20 | 21 | export default ReleasesConfig; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/releases/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Releases'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/main/repositories/Repositories.js: -------------------------------------------------------------------------------- 1 | import FusePageCarded from '@fuse/core/FusePageCarded'; 2 | import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery'; 3 | import TableHeader from 'app/shared-components/TableHeader'; 4 | 5 | import RepositoriesTable from './RepositoriesTable'; 6 | 7 | const Repositories = () => { 8 | const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg')); 9 | 10 | return ( 11 | } 13 | content={} 14 | scroll={isMobile ? 'normal' : 'content'} 15 | className='px-24' 16 | /> 17 | ); 18 | }; 19 | 20 | export default Repositories; 21 | -------------------------------------------------------------------------------- /frontend/src/app/main/repositories/RepositoriesConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../constants/paths'; 4 | 5 | const Repositories = lazy(() => import('./Repositories')); 6 | 7 | const RepositoriesConfig = { 8 | settings: { 9 | layout: { 10 | config: {}, 11 | }, 12 | }, 13 | routes: [ 14 | { 15 | path: PATHS.REPOSITORIES, 16 | element: , 17 | }, 18 | ], 19 | }; 20 | 21 | export default RepositoriesConfig; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/repositories/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Repositories'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/main/services/Services.js: -------------------------------------------------------------------------------- 1 | import FusePageCarded from '@fuse/core/FusePageCarded'; 2 | import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery'; 3 | import TableHeader from 'app/shared-components/TableHeader'; 4 | 5 | import ServicesTable from './ServicesTable'; 6 | 7 | const Services = () => { 8 | const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg')); 9 | 10 | return ( 11 | } 13 | content={} 14 | scroll={isMobile ? 'normal' : 'content'} 15 | className='px-24' 16 | /> 17 | ); 18 | }; 19 | 20 | export default Services; 21 | -------------------------------------------------------------------------------- /frontend/src/app/main/services/ServicesConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../constants/paths'; 4 | 5 | const Services = lazy(() => import('./Services')); 6 | const ServiceCreate = lazy(() => import('./ServiceCreate')); 7 | 8 | const ServicesConfig = { 9 | settings: { 10 | layout: { 11 | config: {}, 12 | }, 13 | }, 14 | routes: [ 15 | { 16 | path: PATHS.SERVICES, 17 | element: , 18 | }, 19 | { 20 | path: PATHS.SERVICE_CREATE, 21 | element: , 22 | }, 23 | ], 24 | }; 25 | 26 | export default ServicesConfig; 27 | -------------------------------------------------------------------------------- /frontend/src/app/main/services/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Services'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/main/sign-in/SignInConfig.js: -------------------------------------------------------------------------------- 1 | import authRoles from '../../auth/authRoles'; 2 | import { PATHS } from '../../constants/paths'; 3 | 4 | import SignInPage from './SignInPage'; 5 | 6 | const SignInConfig = { 7 | settings: { 8 | layout: { 9 | config: { 10 | navbar: { display: false }, 11 | toolbar: { display: false }, 12 | footer: { display: false }, 13 | leftSidePanel: { display: false }, 14 | rightSidePanel: { display: false }, 15 | }, 16 | }, 17 | }, 18 | auth: authRoles.onlyGuest, 19 | routes: [ 20 | { 21 | path: PATHS.SIGN_IN, 22 | element: , 23 | }, 24 | ], 25 | }; 26 | 27 | export default SignInConfig; 28 | -------------------------------------------------------------------------------- /frontend/src/app/main/sign-in/utils.js: -------------------------------------------------------------------------------- 1 | import { AUTH_ERROR_CODES } from '../../constants/auth'; 2 | 3 | export const getErrorMessage = (error) => { 4 | if (error?.response?.status === 500) { 5 | return 'Server error'; 6 | } 7 | 8 | return AUTH_ERROR_CODES[error?.response?.data?.detail] || 'Error while signing in'; 9 | }; 10 | -------------------------------------------------------------------------------- /frontend/src/app/main/sign-out/SignOutConfig.js: -------------------------------------------------------------------------------- 1 | import { PATHS } from '../../constants/paths'; 2 | 3 | import SignOutPage from './SignOutPage'; 4 | 5 | const SignOutConfig = { 6 | settings: { 7 | layout: { 8 | config: { 9 | navbar: { display: false }, 10 | toolbar: { display: false }, 11 | footer: { display: false }, 12 | leftSidePanel: { display: false }, 13 | rightSidePanel: { display: false }, 14 | }, 15 | }, 16 | }, 17 | auth: null, 18 | routes: [ 19 | { 20 | path: PATHS.SIGN_OUT, 21 | element: , 22 | }, 23 | ], 24 | }; 25 | 26 | export default SignOutConfig; 27 | -------------------------------------------------------------------------------- /frontend/src/app/main/sign-up/SignUpConfig.js: -------------------------------------------------------------------------------- 1 | import authRoles from '../../auth/authRoles'; 2 | import { PATHS } from '../../constants/paths'; 3 | 4 | import SignUpPage from './SignUpPage'; 5 | 6 | const SignUpConfig = { 7 | settings: { 8 | layout: { 9 | config: { 10 | navbar: { display: false }, 11 | toolbar: { display: false }, 12 | footer: { display: false }, 13 | leftSidePanel: { display: false }, 14 | rightSidePanel: { display: false }, 15 | }, 16 | }, 17 | }, 18 | auth: authRoles.onlyGuest, 19 | routes: [ 20 | { 21 | path: PATHS.SIGN_UP, 22 | element: , 23 | }, 24 | ], 25 | }; 26 | 27 | export default SignUpConfig; 28 | -------------------------------------------------------------------------------- /frontend/src/app/main/templates/Templates.js: -------------------------------------------------------------------------------- 1 | import FusePageCarded from '@fuse/core/FusePageCarded'; 2 | import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery'; 3 | import TableHeader from 'app/shared-components/TableHeader'; 4 | 5 | import TemplatesList from './TemplatesList'; 6 | 7 | const Templates = () => { 8 | const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg')); 9 | 10 | return ( 11 | } 13 | content={} 14 | scroll={isMobile ? 'normal' : 'content'} 15 | className='px-24' 16 | /> 17 | ); 18 | }; 19 | 20 | export default Templates; 21 | -------------------------------------------------------------------------------- /frontend/src/app/main/templates/TemplatesConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import { PATHS } from '../../constants/paths'; 4 | 5 | const Templates = lazy(() => import('./Templates')); 6 | 7 | const TemplatesConfig = { 8 | settings: { 9 | layout: { 10 | config: {}, 11 | }, 12 | }, 13 | routes: [ 14 | { 15 | path: PATHS.TEMPLATES, 16 | element: , 17 | }, 18 | ], 19 | }; 20 | 21 | export default TemplatesConfig; 22 | -------------------------------------------------------------------------------- /frontend/src/app/main/templates/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './Templates'; 2 | -------------------------------------------------------------------------------- /frontend/src/app/main/users/UsersConfig.js: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | const Users = lazy(() => import('./Users')); 4 | 5 | const UsersConfig = { 6 | settings: { 7 | layout: { 8 | config: {}, 9 | }, 10 | }, 11 | routes: [ 12 | { 13 | path: 'users', 14 | element: , 15 | }, 16 | ], 17 | }; 18 | 19 | export default UsersConfig; 20 | -------------------------------------------------------------------------------- /frontend/src/app/shared-components/Snackbar.js: -------------------------------------------------------------------------------- 1 | import { Alert } from '@mui/material'; 2 | import Snackbar from '@mui/material/Snackbar'; 3 | 4 | const SnackbarMessage = ({ status, message, showMessage, setShowMessage }) => { 5 | const handleClose = () => { 6 | setShowMessage(false); 7 | }; 8 | 9 | return ( 10 | 11 | 12 | {message} 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default SnackbarMessage; 19 | -------------------------------------------------------------------------------- /frontend/src/app/shared-components/TableHeader.js: -------------------------------------------------------------------------------- 1 | import Typography from '@mui/material/Typography'; 2 | import { motion } from 'framer-motion'; 3 | 4 | const TableHeader = ({ title }) => { 5 | return ( 6 |
7 | 14 | {title} 15 | 16 |
17 | ); 18 | }; 19 | 20 | export default TableHeader; 21 | -------------------------------------------------------------------------------- /frontend/src/app/shared-components/TemplateBuilderInput.js: -------------------------------------------------------------------------------- 1 | import TextField from '@mui/material/TextField'; 2 | 3 | const TemplateBuilderInput = ({ value, disabled, onChangeTemplate, label, required }) => { 4 | return ( 5 | 16 | ); 17 | }; 18 | 19 | export default TemplateBuilderInput; 20 | -------------------------------------------------------------------------------- /frontend/src/app/store/fuse/dialogSlice.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const dialogSlice = createSlice({ 4 | name: 'dialog', 5 | initialState: { 6 | state: false, 7 | options: { children: 'Hi' }, 8 | }, 9 | reducers: { 10 | openDialog: (state, action) => { 11 | state.state = true; 12 | state.options = action.payload; 13 | }, 14 | closeDialog: (state, action) => { 15 | state.state = false; 16 | }, 17 | }, 18 | }); 19 | 20 | export const { openDialog, closeDialog } = dialogSlice.actions; 21 | 22 | export const selectFuseDialogState = ({ fuse }) => fuse.dialog.state; 23 | 24 | export const selectFuseDialogOptions = ({ fuse }) => fuse.dialog.options; 25 | 26 | export default dialogSlice.reducer; 27 | -------------------------------------------------------------------------------- /frontend/src/app/store/fuse/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from '@reduxjs/toolkit'; 2 | 3 | import dialog from './dialogSlice'; 4 | import message from './messageSlice'; 5 | import navbar from './navbarSlice'; 6 | import navigation from './navigationSlice'; 7 | import settings from './settingsSlice'; 8 | 9 | const fuseReducers = combineReducers({ 10 | navigation, 11 | settings, 12 | navbar, 13 | message, 14 | dialog, 15 | }); 16 | 17 | export default fuseReducers; 18 | -------------------------------------------------------------------------------- /frontend/src/app/store/withReducer.js: -------------------------------------------------------------------------------- 1 | import { injectReducer } from 'app/store/index'; 2 | 3 | const withReducer = (key, reducer) => (WrappedComponent) => { 4 | injectReducer(key, reducer); 5 | 6 | return (props) => ; 7 | }; 8 | 9 | export default withReducer; 10 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/layout1/components/LeftSideLayout1.js: -------------------------------------------------------------------------------- 1 | import { memo } from 'react'; 2 | 3 | function LeftSideLayout1() { 4 | return <>; 5 | } 6 | 7 | export default memo(LeftSideLayout1); 8 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/layout1/components/RightSideLayout1.js: -------------------------------------------------------------------------------- 1 | import { memo } from 'react'; 2 | 3 | import NotificationPanel from '../../shared-components/notificationPanel/NotificationPanel'; 4 | import QuickPanel from '../../shared-components/quickPanel/QuickPanel'; 5 | 6 | function RightSideLayout1(props) { 7 | return ( 8 | <> 9 | 10 | 11 | 12 | 13 | ); 14 | } 15 | 16 | export default memo(RightSideLayout1); 17 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/layout2/components/LeftSideLayout2.js: -------------------------------------------------------------------------------- 1 | import { memo } from 'react'; 2 | 3 | function LeftSideLayout2() { 4 | return <>; 5 | } 6 | 7 | export default memo(LeftSideLayout2); 8 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/layout2/components/RightSideLayout2.js: -------------------------------------------------------------------------------- 1 | import { memo } from 'react'; 2 | 3 | import NotificationPanel from '../../shared-components/notificationPanel/NotificationPanel'; 4 | import QuickPanel from '../../shared-components/quickPanel/QuickPanel'; 5 | 6 | function RightSideLayout2() { 7 | return ( 8 | <> 9 | 10 | 11 | 12 | 13 | ); 14 | } 15 | 16 | export default memo(RightSideLayout2); 17 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/layout3/components/LeftSideLayout3.js: -------------------------------------------------------------------------------- 1 | import { memo } from 'react'; 2 | 3 | import FuseSidePanel from '@fuse/core/FuseSidePanel'; 4 | 5 | import NavigationShortcuts from '../../shared-components/NavigationShortcuts'; 6 | 7 | function LeftSideLayout3() { 8 | return ( 9 | <> 10 | 11 | 12 | 13 | 14 | ); 15 | } 16 | 17 | export default memo(LeftSideLayout3); 18 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/layout3/components/RightSideLayout3.js: -------------------------------------------------------------------------------- 1 | import { memo } from 'react'; 2 | 3 | import NotificationPanel from '../../shared-components/notificationPanel/NotificationPanel'; 4 | import QuickPanel from '../../shared-components/quickPanel/QuickPanel'; 5 | 6 | function RightSideLayout3() { 7 | return ( 8 | <> 9 | 10 | 11 | 12 | 13 | ); 14 | } 15 | 16 | export default memo(RightSideLayout3); 17 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/DocumentationButton.js: -------------------------------------------------------------------------------- 1 | import Button from '@mui/material/Button'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | import FuseSvgIcon from '@fuse/core/FuseSvgIcon'; 5 | 6 | function DocumentationButton({ className }) { 7 | return ( 8 | 21 | ); 22 | } 23 | 24 | export default DocumentationButton; 25 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/NavigationSearch.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from 'react-redux'; 2 | 3 | import FuseSearch from '@fuse/core/FuseSearch'; 4 | import { selectFlatNavigation } from 'app/store/fuse/navigationSlice'; 5 | 6 | function NavigationSearch(props) { 7 | const { variant, className } = props; 8 | const navigation = useSelector(selectFlatNavigation); 9 | 10 | return ( 11 | 16 | ); 17 | } 18 | 19 | export default NavigationSearch; 20 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/PurchaseButton.js: -------------------------------------------------------------------------------- 1 | import Button from '@mui/material/Button'; 2 | import clsx from 'clsx'; 3 | 4 | import FuseSvgIcon from '@fuse/core/FuseSvgIcon'; 5 | 6 | function PurchaseButton({ className }) { 7 | return ( 8 | 23 | ); 24 | } 25 | 26 | export default PurchaseButton; 27 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/chatPanel/store/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from '@reduxjs/toolkit'; 2 | 3 | import chat from './chatSlice'; 4 | import chats from './chatsSlice'; 5 | import contacts from './contactsSlice'; 6 | import state from './stateSlice'; 7 | import user from './userSlice'; 8 | 9 | const reducer = combineReducers({ 10 | user, 11 | contacts, 12 | chat, 13 | chats, 14 | state, 15 | }); 16 | 17 | export default reducer; 18 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/chatPanel/store/stateSlice.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const stateSlice = createSlice({ 4 | name: 'chatPanel/state', 5 | initialState: false, 6 | reducers: { 7 | toggleChatPanel: (state, action) => !state, 8 | openChatPanel: (state, action) => true, 9 | closeChatPanel: (state, action) => false, 10 | }, 11 | extraReducers: {}, 12 | }); 13 | 14 | export const { toggleChatPanel, openChatPanel, closeChatPanel } = 15 | stateSlice.actions; 16 | 17 | export const selectChatPanelState = ({ chatPanel }) => chatPanel.state; 18 | 19 | export default stateSlice.reducer; 20 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/notificationPanel/NotificationTemplate.js: -------------------------------------------------------------------------------- 1 | import { SnackbarContent } from 'notistack'; 2 | import { forwardRef } from 'react'; 3 | 4 | import NotificationCard from './NotificationCard'; 5 | 6 | const NotificationTemplate = forwardRef((props, ref) => { 7 | const { item } = props; 8 | 9 | return ( 10 | 14 | 15 | 16 | ); 17 | }); 18 | 19 | export default NotificationTemplate; 20 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/notificationPanel/model/NotificationModel.js: -------------------------------------------------------------------------------- 1 | import FuseUtils from '@fuse/utils'; 2 | import _ from '@lodash'; 3 | 4 | function NotificationModel(data) { 5 | data = data || {}; 6 | 7 | return _.defaults(data, { 8 | id: FuseUtils.generateGUID(), 9 | icon: 'heroicons-solid:star', 10 | title: '', 11 | description: '', 12 | time: new Date().toISOString(), 13 | read: false, 14 | variant: 'default', 15 | }); 16 | } 17 | 18 | export default NotificationModel; 19 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/notificationPanel/store/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from '@reduxjs/toolkit'; 2 | 3 | import data from './dataSlice'; 4 | import state from './stateSlice'; 5 | 6 | const reducer = combineReducers({ 7 | data, 8 | state, 9 | }); 10 | export default reducer; 11 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/notificationPanel/store/stateSlice.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const stateSlice = createSlice({ 4 | name: 'notificationPanel/state', 5 | initialState: false, 6 | reducers: { 7 | toggleNotificationPanel: (state, action) => !state, 8 | openNotificationPanel: (state, action) => true, 9 | closeNotificationPanel: (state, action) => false, 10 | }, 11 | }); 12 | 13 | export const { 14 | toggleNotificationPanel, 15 | openNotificationPanel, 16 | closeNotificationPanel, 17 | } = stateSlice.actions; 18 | 19 | export const selectNotificationPanelState = ({ notificationPanel }) => 20 | notificationPanel.state; 21 | 22 | export default stateSlice.reducer; 23 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/quickPanel/store/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from '@reduxjs/toolkit'; 2 | 3 | import data from './dataSlice'; 4 | import state from './stateSlice'; 5 | 6 | const reducer = combineReducers({ 7 | data, 8 | state, 9 | }); 10 | export default reducer; 11 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/shared-components/quickPanel/store/stateSlice.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from '@reduxjs/toolkit'; 2 | 3 | const stateSlice = createSlice({ 4 | name: 'quickPanel/state', 5 | initialState: false, 6 | reducers: { 7 | toggleQuickPanel: (state, action) => !state, 8 | openQuickPanel: (state, action) => true, 9 | closeQuickPanel: (state, action) => false, 10 | }, 11 | }); 12 | 13 | export const { toggleQuickPanel, openQuickPanel, closeQuickPanel } = 14 | stateSlice.actions; 15 | 16 | export const selectQuickPanelState = ({ quickPanel }) => quickPanel.state; 17 | 18 | export default stateSlice.reducer; 19 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/themeLayoutConfigs.js: -------------------------------------------------------------------------------- 1 | import layout1 from './layout1/Layout1Config'; 2 | import layout2 from './layout2/Layout2Config'; 3 | import layout3 from './layout3/Layout3Config'; 4 | 5 | const themeLayoutConfigs = { 6 | layout1, 7 | layout2, 8 | layout3, 9 | }; 10 | 11 | export default themeLayoutConfigs; 12 | -------------------------------------------------------------------------------- /frontend/src/app/theme-layouts/themeLayouts.js: -------------------------------------------------------------------------------- 1 | import layout1 from './layout1/Layout1'; 2 | import layout2 from './layout2/Layout2'; 3 | import layout3 from './layout3/Layout3'; 4 | 5 | const themeLayouts = { 6 | layout1, 7 | layout2, 8 | layout3, 9 | }; 10 | 11 | export default themeLayouts; 12 | -------------------------------------------------------------------------------- /frontend/src/app/uitls/data.js: -------------------------------------------------------------------------------- 1 | import _ from '@lodash'; 2 | 3 | export const getUniqueKeysFromTableData = (data, key) => { 4 | const values = data?.map((el) => _.get(el, key)).filter(Boolean); 5 | 6 | const uniqueItems = new Set(values); 7 | 8 | return Array.from(uniqueItems); 9 | }; 10 | 11 | export const getSelectItemsFromArray = (arr) => 12 | arr.map((el) => ({ 13 | value: el, 14 | text: el, 15 | })); 16 | -------------------------------------------------------------------------------- /frontend/src/app/uitls/formattedNamespace.js: -------------------------------------------------------------------------------- 1 | export const formattedNamespace = (namespace) => { 2 | return namespace.replaceAll(/[^@a-z0-9]/gi, '-').replaceAll(/[@]/g, '--'); 3 | }; 4 | -------------------------------------------------------------------------------- /frontend/src/app/uitls/formattingTemplateValues.js: -------------------------------------------------------------------------------- 1 | export const formattingTemplateValues = (value) => { 2 | let formattedValue = value.replaceAll('{{', '\'{{').replaceAll('}}', '}}\''); 3 | formattedValue = formattedValue.replaceAll('\'\'{{', '\'{{').replaceAll('}}\'\'', '}}\''); 4 | return formattedValue; 5 | }; 6 | -------------------------------------------------------------------------------- /frontend/src/app/uitls/index.js: -------------------------------------------------------------------------------- 1 | export * from './date'; 2 | export * from './strings'; 3 | export * from './data'; 4 | export * from './color' 5 | -------------------------------------------------------------------------------- /frontend/src/app/uitls/strings.js: -------------------------------------------------------------------------------- 1 | export const checkTrimString = (string = '', limit = 50, chunkSize = 15) => { 2 | if (string?.length > limit) { 3 | return `${string.slice(0, chunkSize)}...${string.slice(-chunkSize)}`; 4 | } 5 | 6 | return string; 7 | }; 8 | -------------------------------------------------------------------------------- /frontend/src/i18n.js: -------------------------------------------------------------------------------- 1 | import i18n from 'i18next'; 2 | import { initReactI18next } from 'react-i18next'; 3 | 4 | // the translations 5 | // (tip move them in a JSON file and import them) 6 | const resources = { 7 | en: { 8 | translation: { 9 | 'Welcome to React': 'Welcome to React and react-i18next', 10 | }, 11 | }, 12 | }; 13 | 14 | i18n 15 | .use(initReactI18next) // passes i18n down to react-i18next 16 | .init({ 17 | resources, 18 | lng: 'en', 19 | 20 | keySeparator: false, // we do not use keys in form messages.welcome 21 | 22 | interpolation: { 23 | escapeValue: false, // react already safes from xss 24 | }, 25 | }); 26 | 27 | export default i18n; 28 | -------------------------------------------------------------------------------- /frontend/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = (onPerfEntry) => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /frontend/src/styles/app-components.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Component classes registered by plugins. 3 | * 4 | */ 5 | 6 | @import 'print.css'; 7 | 8 | @import 'tables.css'; 9 | 10 | @import 'prism.css'; 11 | 12 | @import 'custom.css'; 13 | 14 | @tailwind components; 15 | -------------------------------------------------------------------------------- /frontend/src/styles/app-utilities.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Tailwind's utility classes, generated based on your config file. 3 | */ 4 | 5 | @tailwind utilities; 6 | -------------------------------------------------------------------------------- /frontend/src/styles/custom.css: -------------------------------------------------------------------------------- 1 | .dropdown-filter label { 2 | background: white; 3 | } 4 | 5 | .spinner-container #spinner { 6 | margin: 0; 7 | height: 100%; 8 | } 9 | 10 | .monaco-editor.no-user-select { 11 | padding-top: 12px; 12 | } 13 | 14 | .custom-date-picker .MuiFormControl-root{ 15 | width: 100%; 16 | } 17 | 18 | .template-builder .MuiFormControl-root { 19 | background-color: #fff; 20 | } 21 | --------------------------------------------------------------------------------