diff --git a/src/_main_/config/build/deployConfig.json b/src/_main_/config/build/deployConfig.json index cd42ea39a..af119da7d 100644 --- a/src/_main_/config/build/deployConfig.json +++ b/src/_main_/config/build/deployConfig.json @@ -1,6 +1,6 @@ { "IS_PROD": false, "IS_CANARY": false, - "BUILD_VERSION": "5.2.14", + "BUILD_VERSION": "5.2.15", "BUILD_VERSION_NOTES": "Jan 31, 2024: Campaigns initial prod deployment\n" } \ No newline at end of file diff --git a/src/api/handlers/misc.py b/src/api/handlers/misc.py index 8ed1ecb19..b5fc03bd2 100644 --- a/src/api/handlers/misc.py +++ b/src/api/handlers/misc.py @@ -18,6 +18,7 @@ def __init__(self): def registerRoutes(self) -> None: self.add("/menus.remake", self.remake_navigation_menu) self.add("/menus.list", self.navigation_menu_list) + self.add("/user.portal.menu.list", self.load_menu_items) self.add("/data.backfill", self.backfill) self.add("/data.carbonEquivalency.create", self.create_carbon_equivalency) self.add("/data.carbonEquivalency.update", self.update_carbon_equivalency) @@ -157,3 +158,19 @@ def authenticateFrontendInTestMode(self, request): "token", value=token, max_age=24 * 60 * 60, samesite="Strict" ) return response + + def load_menu_items(self, request): + context: Context = request.context + args: dict = context.args + + self.validator.expect("community_id", is_required=False) + self.validator.expect("subdomain", is_required=False) + + args, err = self.validator.verify(args, strict=True) + if err: + return MassenergizeResponse(error=err) + + data, err = self.service.load_menu_items(context, args) + if err: + return err + return MassenergizeResponse(data=data) diff --git a/src/api/services/misc.py b/src/api/services/misc.py index f1fa894f6..1cf7a1a7c 100644 --- a/src/api/services/misc.py +++ b/src/api/services/misc.py @@ -141,3 +141,10 @@ def authenticateFrontendInTestMode(self, args): return None, CustomMassenergizeError(str(err)) client = Client() return signinAs(client, user), None + + def load_menu_items(self,context, args): + res, err = self.store.load_menu_items(context,args) + if err: + return None, err + + return res, None diff --git a/src/api/store/misc.py b/src/api/store/misc.py index 81088471e..63905b1a4 100644 --- a/src/api/store/misc.py +++ b/src/api/store/misc.py @@ -28,9 +28,10 @@ from _main_.utils.context import Context from database.utils.common import json_loader from database.models import CarbonEquivalency -from .utils import find_reu_community, split_location_string, check_location +from .utils import find_reu_community, split_location_string, check_location,get_community from sentry_sdk import capture_message from typing import Tuple +from api.utils.api_utils import get_viable_menu_items class MiscellaneousStore: @@ -492,3 +493,21 @@ def list_commonly_used_icons(self): sorted_keys = sorted(common_icons, key=common_icons.get, reverse=True) for key in sorted_keys: print(str(key) + ": " + str(common_icons[key])) + + def load_menu_items(self, context, args): + try: + subdomain = args.get("subdomain", None) + community_id = args.get("community_id", None) + + if not subdomain and not community_id: + return None, CustomMassenergizeError("No community or subdomain provided") + + community, _ = get_community(community_id=community_id, subdomain=subdomain) + if not community: + return None, CustomMassenergizeError("Community not found") + + menu = get_viable_menu_items(community) + + return menu, None + except Exception as e: + return None, CustomMassenergizeError(e) \ No newline at end of file diff --git a/src/api/utils/api_utils.py b/src/api/utils/api_utils.py index 14e7500e4..62a59f220 100644 --- a/src/api/utils/api_utils.py +++ b/src/api/utils/api_utils.py @@ -1,5 +1,8 @@ from math import atan2, cos, radians, sin, sqrt -from database.models import Community, CommunityAdminGroup, Media, UserProfile +from database.models import AboutUsPageSettings, ActionsPageSettings, Community, CommunityAdminGroup, \ + ContactUsPageSettings, EventsPageSettings, ImpactPageSettings, Media, Menu, \ + TeamsPageSettings, TestimonialsPageSettings, UserProfile, \ + VendorsPageSettings import pyshorteners @@ -98,3 +101,85 @@ def create_media_file(file, name): media = Media.objects.create(name=name, file=file) media.save() return media + +# -------------------------- Menu Utils -------------------------- + + +def prepend_prefix_to_links(menu_item: object, prefix: object) -> object: + if not menu_item: + return None + if "link" in menu_item: + menu_item["link"] = "/" + prefix + menu_item["link"] + if "children" in menu_item: + for child in menu_item["children"]: + prepend_prefix_to_links(child, prefix) + return menu_item + + +def modify_menu_items_if_published(menu_items, page_settings, prefix): + if not menu_items or not page_settings or not prefix: + return [] + + main_menu = [] + + for item in menu_items: + if not item.get("children"): + name = item.get("link", "").strip("/") + if name in page_settings and not page_settings[name]: + main_menu.remove(item) + else: + for child in item["children"]: + name = child.get("link", "").strip("/") + if name in page_settings and not page_settings[name]: + item["children"].remove(child) + + for item in menu_items: + f = prepend_prefix_to_links(item, prefix) + main_menu.append(f) + + return main_menu + + +def get_viable_menu_items(community): + about_us_page_settings = AboutUsPageSettings.objects.filter(community=community).first() + events_page_settings = EventsPageSettings.objects.filter(community=community).first() + impact_page_settings = ImpactPageSettings.objects.filter(community=community).first() + actions_page_settings = ActionsPageSettings.objects.filter(community=community).first() + contact_us_page_settings = ContactUsPageSettings.objects.filter(community=community).first() + teams_page_settings = TeamsPageSettings.objects.filter(community=community).first() + testimonial_page_settings = TestimonialsPageSettings.objects.filter(community=community).first() + vendors_page_settings = VendorsPageSettings.objects.filter(community=community).first() + + + menu_items = {} + all_menu = Menu.objects.all() + + nav_menu = all_menu.get(name="PortalMainNavLinks") + + portal_main_nav_links = modify_menu_items_if_published(nav_menu.content, { + "impact": impact_page_settings.is_published, + "aboutus": about_us_page_settings.is_published, + "contactus": contact_us_page_settings.is_published, + "actions": actions_page_settings.is_published, + "services": vendors_page_settings.is_published, + "testimonials": testimonial_page_settings.is_published, + "teams": teams_page_settings.is_published, + "events": events_page_settings.is_published, + }, community.subdomain) + + footer_menu_content = all_menu.get(name='PortalFooterQuickLinks') + + portal_footer_quick_links = [ + {**item, "link": "/"+community.subdomain + "/" + item["link"]} + if not item.get("children") and item.get("navItemId", None) != "footer-report-a-bug-id" + else item + for item in footer_menu_content.content["links"] + ] + portal_footer_contact_info = all_menu.get(name='PortalFooterContactInfo') + return [ + {**nav_menu.simple_json(), "content": portal_main_nav_links}, + {**footer_menu_content.simple_json(), "content": {"links": portal_footer_quick_links}}, + portal_footer_contact_info.simple_json() + + ] +# -------------------------- Menu Utils -------------------------- diff --git a/src/api_version_dev.txt b/src/api_version_dev.txt index ba678f2d2..c95ed737b 100644 --- a/src/api_version_dev.txt +++ b/src/api_version_dev.txt @@ -1 +1 @@ -5.2.14 \ No newline at end of file +5.2.15 \ No newline at end of file diff --git a/src/deployment/build.json b/src/deployment/build.json index b65db6d46..9b3982f07 100644 --- a/src/deployment/build.json +++ b/src/deployment/build.json @@ -1,5 +1,5 @@ { - "dev": "5.2.14", + "dev": "5.2.15", "prod": "5.1.10", "canary": "5.2.13" } \ No newline at end of file diff --git a/src/docker-compose.yml b/src/docker-compose.yml index 3c02915e3..9e4b5124d 100644 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -8,28 +8,21 @@ services: ports: - "80:8000" # for deployed version - "8000:8000" # for localhost testing - image: 202758212688.dkr.ecr.us-east-2.amazonaws.com/massenergize/api-canary + image: 202758212688.dkr.ecr.us-east-2.amazonaws.com/massenergize/api-dev restart: on-failure - env_file: - - canary.env celery_worker: command: sh -c "celery -A _main_.celery.app worker -l info" depends_on: - app hostname: celery_worker - image: 202758212688.dkr.ecr.us-east-2.amazonaws.com/massenergize/api-canary + image: 202758212688.dkr.ecr.us-east-2.amazonaws.com/massenergize/api-dev restart: on-failure - env_file: - - canary.env - celery_beat: command: sh -c "celery -A _main_.celery.app beat -l info" depends_on: - app hostname: celery_beat - image: 202758212688.dkr.ecr.us-east-2.amazonaws.com/massenergize/api-canary + image: 202758212688.dkr.ecr.us-east-2.amazonaws.com/massenergize/api-dev restart: on-failure - env_file: - - canary.env