From e6c7828118b7c467db61bf3ad65e8cc61b403fff Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Tue, 22 Oct 2024 14:27:01 -0700 Subject: [PATCH 01/18] generates static urls #11567 --- .../app/utils/frontend_configuration_utils.py | 94 +++++++++++++++++++ arches/app/utils/index_database.py | 3 - arches/settings_utils.py | 1 - 3 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 arches/app/utils/frontend_configuration_utils.py diff --git a/arches/app/utils/frontend_configuration_utils.py b/arches/app/utils/frontend_configuration_utils.py new file mode 100644 index 00000000000..54aa2ea2fda --- /dev/null +++ b/arches/app/utils/frontend_configuration_utils.py @@ -0,0 +1,94 @@ +import json +import os +import re + +from collections import OrderedDict +from django.conf import settings +from django.urls import get_resolver, URLPattern, URLResolver +from django.urls.resolvers import RegexPattern, RoutePattern, LocalePrefixPattern + + +def get_base_path(): + return ( + os.path.realpath(settings.ROOT_DIR) + if settings.APP_NAME == "Arches" + else os.path.realpath(settings.APP_ROOT) + ) + + +def generate_frontend_configuration_directory(): + destination_dir = os.path.realpath( + os.path.join(get_base_path(), "..", "frontend_configuration") + ) + + os.makedirs(destination_dir, exist_ok=True) + + +def generate_urls_json(): + resolver = get_resolver() + human_readable_urls = _generate_human_readable_urls(resolver.url_patterns) + + destination_path = os.path.realpath( + os.path.join(get_base_path(), "..", "frontend_configuration", "urls.json") + ) + + with open(destination_path, "w") as file: + json.dump( + { + url_name: human_readable_urls[url_name] + for url_name in sorted(human_readable_urls) + }, + file, + indent=4, + ) + + +def _generate_human_readable_urls(patterns, prefix="", namespace="", result={}): + def join_paths(*args): + return "/".join(filter(None, (arg.strip("/") for arg in args))) + + def interpolate_route(pattern): + if isinstance(pattern, RoutePattern): + return re.sub(r"<(?:[^:]+:)?([^>]+)>", r"{\1}", pattern._route) + elif isinstance(pattern, RegexPattern): + regex = pattern._regex.lstrip("^").rstrip("$") + + # Replace named capture groups (e.g., (?P)) with {param} + regex = re.sub(r"\(\?P<(\w+)>[^)]+\)", r"{\1}", regex) + + # Remove non-capturing groups (e.g., (?:...)) + regex = re.sub(r"\(\?:[^\)]+\)", "", regex) + + # Remove character sets (e.g., [0-9]) + regex = re.sub(r"\[[^\]]+\]", "", regex) + + # Remove backslashes (used to escape special characters in regex) + regex = regex.replace("\\", "") + + # Remove regex-specific special characters (^, $, +, *, ?, (), etc.) + regex = re.sub(r"[\^\$\+\*\?\(\)]", "", regex) + + return regex.strip("/") + + for pattern in patterns: + if isinstance(pattern, URLPattern): + if pattern.name: + result[f"{namespace}{pattern.name}"] = "/" + join_paths( + prefix, interpolate_route(pattern.pattern) + ) + elif isinstance(pattern, URLResolver): + current_namespace = namespace + ( + f":{pattern.namespace}:" if pattern.namespace else "" + ) + + if isinstance( + pattern.pattern, LocalePrefixPattern + ): # handles i18n_patterns + new_prefix = join_paths(prefix, "{language_code}") + else: + new_prefix = join_paths(prefix, interpolate_route(pattern.pattern)) + + _generate_human_readable_urls( + pattern.url_patterns, new_prefix, current_namespace, result + ) + return result diff --git a/arches/app/utils/index_database.py b/arches/app/utils/index_database.py index 81fdae83450..69a6616d1cc 100644 --- a/arches/app/utils/index_database.py +++ b/arches/app/utils/index_database.py @@ -5,9 +5,6 @@ import uuid import pyprind import sys -import django - -django.setup() from datetime import datetime from django.db import connection, connections diff --git a/arches/settings_utils.py b/arches/settings_utils.py index d8ceb934996..53e89ebe3d4 100644 --- a/arches/settings_utils.py +++ b/arches/settings_utils.py @@ -2,7 +2,6 @@ import os import site import sys -from contextlib import contextmanager from django.apps import apps from django.conf import settings From 4535a9be074cada32ea652c8b233795752d502a3 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Tue, 22 Oct 2024 16:09:10 -0700 Subject: [PATCH 02/18] moves frontend staticfile gneration to siloed util #11567 --- .gitignore | 3 +- .../app/utils/frontend_configuration_utils.py | 197 +++++++--- arches/apps.py | 4 +- arches/install/arches-templates/.gitignore | 3 +- .../arches-templates/project_name/apps.py-tpl | 2 +- arches/settings_utils.py | 87 ----- frontend_configuration/tsconfig-paths.json | 13 + frontend_configuration/urls.json | 343 ++++++++++++++++++ frontend_configuration/webpack-metadata.json | 11 + 9 files changed, 517 insertions(+), 146 deletions(-) create mode 100644 frontend_configuration/tsconfig-paths.json create mode 100644 frontend_configuration/urls.json create mode 100644 frontend_configuration/webpack-metadata.json diff --git a/.gitignore b/.gitignore index 56854b48cb4..9784ae57cde 100644 --- a/.gitignore +++ b/.gitignore @@ -43,5 +43,4 @@ pip-wheel-metadata webpack-stats.json .DS_STORE CACHE -.tsconfig-paths.json -.frontend-configuration-settings.json +frontend_configuration \ No newline at end of file diff --git a/arches/app/utils/frontend_configuration_utils.py b/arches/app/utils/frontend_configuration_utils.py index 54aa2ea2fda..7b96852c0bf 100644 --- a/arches/app/utils/frontend_configuration_utils.py +++ b/arches/app/utils/frontend_configuration_utils.py @@ -1,35 +1,86 @@ import json import os import re +import site -from collections import OrderedDict from django.conf import settings from django.urls import get_resolver, URLPattern, URLResolver from django.urls.resolvers import RegexPattern, RoutePattern, LocalePrefixPattern +from arches.settings_utils import list_arches_app_names, list_arches_app_paths -def get_base_path(): - return ( - os.path.realpath(settings.ROOT_DIR) - if settings.APP_NAME == "Arches" - else os.path.realpath(settings.APP_ROOT) - ) + +def generate_frontend_configuration(): + _generate_frontend_configuration_directory() + _generate_urls_json() + _generate_webpack_configuration() + _generate_tsconfig_paths() -def generate_frontend_configuration_directory(): +def _generate_frontend_configuration_directory(): destination_dir = os.path.realpath( - os.path.join(get_base_path(), "..", "frontend_configuration") + os.path.join(_get_base_path(), "..", "frontend_configuration") ) os.makedirs(destination_dir, exist_ok=True) -def generate_urls_json(): +def _generate_urls_json(): + def generate_human_readable_urls(patterns, prefix="", namespace="", result={}): + def join_paths(*args): + return "/".join(filter(None, (arg.strip("/") for arg in args))) + + def interpolate_route(pattern): + if isinstance(pattern, RoutePattern): + return re.sub(r"<(?:[^:]+:)?([^>]+)>", r"{\1}", pattern._route) + elif isinstance(pattern, RegexPattern): + regex = pattern._regex.lstrip("^").rstrip("$") + + # Replace named capture groups (e.g., (?P)) with {param} + regex = re.sub(r"\(\?P<(\w+)>[^)]+\)", r"{\1}", regex) + + # Remove non-capturing groups (e.g., (?:...)) + regex = re.sub(r"\(\?:[^\)]+\)", "", regex) + + # Remove character sets (e.g., [0-9]) + regex = re.sub(r"\[[^\]]+\]", "", regex) + + # Remove backslashes (used to escape special characters in regex) + regex = regex.replace("\\", "") + + # Remove regex-specific special characters (^, $, +, *, ?, (), etc.) + regex = re.sub(r"[\^\$\+\*\?\(\)]", "", regex) + + return regex.strip("/") + + for pattern in patterns: + if isinstance(pattern, URLPattern): + if pattern.name: + result[f"{namespace}{pattern.name}"] = "/" + join_paths( + prefix, interpolate_route(pattern.pattern) + ) + elif isinstance(pattern, URLResolver): + current_namespace = namespace + ( + f":{pattern.namespace}:" if pattern.namespace else "" + ) + + if isinstance( + pattern.pattern, LocalePrefixPattern + ): # handles i18n_patterns + new_prefix = join_paths(prefix, "{language_code}") + else: + new_prefix = join_paths(prefix, interpolate_route(pattern.pattern)) + + generate_human_readable_urls( + pattern.url_patterns, new_prefix, current_namespace, result + ) + return result + resolver = get_resolver() - human_readable_urls = _generate_human_readable_urls(resolver.url_patterns) + human_readable_urls = generate_human_readable_urls(resolver.url_patterns) destination_path = os.path.realpath( - os.path.join(get_base_path(), "..", "frontend_configuration", "urls.json") + os.path.join(_get_base_path(), "..", "frontend_configuration", "urls.json") ) with open(destination_path, "w") as file: @@ -43,52 +94,92 @@ def generate_urls_json(): ) -def _generate_human_readable_urls(patterns, prefix="", namespace="", result={}): - def join_paths(*args): - return "/".join(filter(None, (arg.strip("/") for arg in args))) +def _generate_webpack_configuration(): + app_root_path = os.path.realpath(settings.APP_ROOT) + root_dir_path = os.path.realpath(settings.ROOT_DIR) + + arches_app_names = list_arches_app_names() + arches_app_paths = list_arches_app_paths() + + destination_path = os.path.realpath( + os.path.join( + _get_base_path(), "..", "frontend_configuration", "webpack-metadata.json" + ) + ) - def interpolate_route(pattern): - if isinstance(pattern, RoutePattern): - return re.sub(r"<(?:[^:]+:)?([^>]+)>", r"{\1}", pattern._route) - elif isinstance(pattern, RegexPattern): - regex = pattern._regex.lstrip("^").rstrip("$") + with open(destination_path, "w") as file: + json.dump( + { + "_comment": "This is a generated file. Do not edit directly.", + "APP_ROOT": app_root_path, + "ARCHES_APPLICATIONS": arches_app_names, + "ARCHES_APPLICATIONS_PATHS": dict( + zip(arches_app_names, arches_app_paths, strict=True) + ), + "SITE_PACKAGES_DIRECTORY": site.getsitepackages()[0], + "PUBLIC_SERVER_ADDRESS": settings.PUBLIC_SERVER_ADDRESS, + "ROOT_DIR": root_dir_path, + "STATIC_URL": settings.STATIC_URL, + "WEBPACK_DEVELOPMENT_SERVER_PORT": settings.WEBPACK_DEVELOPMENT_SERVER_PORT, + }, + file, + indent=4, + ) - # Replace named capture groups (e.g., (?P)) with {param} - regex = re.sub(r"\(\?P<(\w+)>[^)]+\)", r"{\1}", regex) - # Remove non-capturing groups (e.g., (?:...)) - regex = re.sub(r"\(\?:[^\)]+\)", "", regex) +def _generate_tsconfig_paths(): + base_path = _get_base_path() + root_dir_path = os.path.realpath(settings.ROOT_DIR) - # Remove character sets (e.g., [0-9]) - regex = re.sub(r"\[[^\]]+\]", "", regex) + path_lookup = dict( + zip(list_arches_app_names(), list_arches_app_paths(), strict=True) + ) - # Remove backslashes (used to escape special characters in regex) - regex = regex.replace("\\", "") + tsconfig_paths_data = { + "_comment": "This is a generated file. Do not edit directly.", + "compilerOptions": { + "paths": { + "@/arches/*": [ + os.path.join( + ".", + os.path.relpath( + root_dir_path, + os.path.join(base_path, ".."), + ), + "app", + "src", + "arches", + "*", + ) + ], + **{ + os.path.join("@", path_name, "*"): [ + os.path.join( + ".", + os.path.relpath(path, os.path.join(base_path, "..")), + "src", + path_name, + "*", + ) + ] + for path_name, path in path_lookup.items() + }, + "*": ["./node_modules/*"], + } + }, + } - # Remove regex-specific special characters (^, $, +, *, ?, (), etc.) - regex = re.sub(r"[\^\$\+\*\?\(\)]", "", regex) + destination_path = os.path.realpath( + os.path.join(base_path, "..", "frontend_configuration", "tsconfig-paths.json") + ) - return regex.strip("/") + with open(destination_path, "w") as file: + json.dump(tsconfig_paths_data, file, indent=4) - for pattern in patterns: - if isinstance(pattern, URLPattern): - if pattern.name: - result[f"{namespace}{pattern.name}"] = "/" + join_paths( - prefix, interpolate_route(pattern.pattern) - ) - elif isinstance(pattern, URLResolver): - current_namespace = namespace + ( - f":{pattern.namespace}:" if pattern.namespace else "" - ) - - if isinstance( - pattern.pattern, LocalePrefixPattern - ): # handles i18n_patterns - new_prefix = join_paths(prefix, "{language_code}") - else: - new_prefix = join_paths(prefix, interpolate_route(pattern.pattern)) - - _generate_human_readable_urls( - pattern.url_patterns, new_prefix, current_namespace, result - ) - return result + +def _get_base_path(): + return ( + os.path.realpath(settings.ROOT_DIR) + if settings.APP_NAME == "Arches" + else os.path.realpath(settings.APP_ROOT) + ) diff --git a/arches/apps.py b/arches/apps.py index 7f7a7ce81e2..277ae579689 100644 --- a/arches/apps.py +++ b/arches/apps.py @@ -11,7 +11,9 @@ from semantic_version import SimpleSpec, Version from arches import __version__ -from arches.settings_utils import generate_frontend_configuration +from arches.app.utils.frontend_configuration_utils import ( + generate_frontend_configuration, +) class ArchesAppConfig(AppConfig): diff --git a/arches/install/arches-templates/.gitignore b/arches/install/arches-templates/.gitignore index c90cc0d864c..4544ee7d887 100644 --- a/arches/install/arches-templates/.gitignore +++ b/arches/install/arches-templates/.gitignore @@ -15,5 +15,4 @@ webpack-stats.json *.egg-info .DS_STORE CACHE -.tsconfig-paths.json -.frontend-configuration-settings.json +frontend_configuration \ No newline at end of file diff --git a/arches/install/arches-templates/project_name/apps.py-tpl b/arches/install/arches-templates/project_name/apps.py-tpl index 6d933396a45..6588c66c61d 100644 --- a/arches/install/arches-templates/project_name/apps.py-tpl +++ b/arches/install/arches-templates/project_name/apps.py-tpl @@ -1,7 +1,7 @@ from django.apps import AppConfig from django.conf import settings -from arches.settings_utils import generate_frontend_configuration +from arches.app.utils.frontend_configuration_utils import generate_frontend_configuration class {{ project_name_title_case }}Config(AppConfig): diff --git a/arches/settings_utils.py b/arches/settings_utils.py index 53e89ebe3d4..23c39d3e0a0 100644 --- a/arches/settings_utils.py +++ b/arches/settings_utils.py @@ -133,90 +133,3 @@ def build_templates_config( # Ensures error message is shown if error encountered in webpack build sys.stdout.write(str(e)) raise e - - -def generate_frontend_configuration(): - try: - app_root_path = os.path.realpath(settings.APP_ROOT) - root_dir_path = os.path.realpath(settings.ROOT_DIR) - - arches_app_names = list_arches_app_names() - arches_app_paths = list_arches_app_paths() - path_lookup = dict(zip(arches_app_names, arches_app_paths, strict=True)) - - frontend_configuration_settings_data = { - "_comment": "This is a generated file. Do not edit directly.", - "APP_ROOT": app_root_path, - "ARCHES_APPLICATIONS": arches_app_names, - "ARCHES_APPLICATIONS_PATHS": path_lookup, - "SITE_PACKAGES_DIRECTORY": site.getsitepackages()[0], - "PUBLIC_SERVER_ADDRESS": settings.PUBLIC_SERVER_ADDRESS, - "ROOT_DIR": root_dir_path, - "STATIC_URL": settings.STATIC_URL, - "WEBPACK_DEVELOPMENT_SERVER_PORT": settings.WEBPACK_DEVELOPMENT_SERVER_PORT, - } - - if settings.APP_NAME == "Arches": - base_path = root_dir_path - else: - base_path = app_root_path - - frontend_configuration_settings_path = os.path.realpath( - os.path.join(base_path, "..", ".frontend-configuration-settings.json") - ) - sys.stdout.write( - f"Writing frontend configuration to: {frontend_configuration_settings_path} \n" - ) - - with open( - frontend_configuration_settings_path, - "w", - ) as file: - json.dump(frontend_configuration_settings_data, file, indent=4) - - tsconfig_paths_data = { - "_comment": "This is a generated file. Do not edit directly.", - "compilerOptions": { - "paths": { - "@/arches/*": [ - os.path.join( - ".", - os.path.relpath( - root_dir_path, - os.path.join(base_path, ".."), - ), - "app", - "src", - "arches", - "*", - ) - ], - **{ - os.path.join("@", path_name, "*"): [ - os.path.join( - ".", - os.path.relpath(path, os.path.join(base_path, "..")), - "src", - path_name, - "*", - ) - ] - for path_name, path in path_lookup.items() - }, - "*": ["./node_modules/*"], - } - }, - } - - tsconfig_path = os.path.realpath( - os.path.join(base_path, "..", ".tsconfig-paths.json") - ) - sys.stdout.write(f"Writing tsconfig path data to: {tsconfig_path} \n") - - with open(tsconfig_path, "w") as file: - json.dump(tsconfig_paths_data, file, indent=4) - - except Exception as e: - # Ensures error message is shown if error encountered - sys.stderr.write(str(e)) - raise e diff --git a/frontend_configuration/tsconfig-paths.json b/frontend_configuration/tsconfig-paths.json new file mode 100644 index 00000000000..4f3cbd0276c --- /dev/null +++ b/frontend_configuration/tsconfig-paths.json @@ -0,0 +1,13 @@ +{ + "_comment": "This is a generated file. Do not edit directly.", + "compilerOptions": { + "paths": { + "@/arches/*": [ + "./arches/app/src/arches/*" + ], + "*": [ + "./node_modules/*" + ] + } + } +} \ No newline at end of file diff --git a/frontend_configuration/urls.json b/frontend_configuration/urls.json new file mode 100644 index 00000000000..0997b4f4c12 --- /dev/null +++ b/frontend_configuration/urls.json @@ -0,0 +1,343 @@ +{ + ":admin:app_list": "/admin/{app_label}", + ":admin:auth_group_add": "/admin/auth/group/add", + ":admin:auth_group_change": "/admin/auth/group/{object_id}/change", + ":admin:auth_group_changelist": "/admin/auth/group", + ":admin:auth_group_delete": "/admin/auth/group/{object_id}/delete", + ":admin:auth_group_history": "/admin/auth/group/{object_id}/history", + ":admin:auth_user_add": "/admin/auth/user/add", + ":admin:auth_user_change": "/admin/auth/user/{object_id}/change", + ":admin:auth_user_changelist": "/admin/auth/user", + ":admin:auth_user_delete": "/admin/auth/user/{object_id}/delete", + ":admin:auth_user_history": "/admin/auth/user/{object_id}/history", + ":admin:auth_user_password_change": "/admin/auth/user/{id}/password", + ":admin:autocomplete": "/admin/autocomplete", + ":admin:django_celery_results_groupresult_add": "/admin/django_celery_results/groupresult/add", + ":admin:django_celery_results_groupresult_change": "/admin/django_celery_results/groupresult/{object_id}/change", + ":admin:django_celery_results_groupresult_changelist": "/admin/django_celery_results/groupresult", + ":admin:django_celery_results_groupresult_delete": "/admin/django_celery_results/groupresult/{object_id}/delete", + ":admin:django_celery_results_groupresult_history": "/admin/django_celery_results/groupresult/{object_id}/history", + ":admin:django_celery_results_taskresult_add": "/admin/django_celery_results/taskresult/add", + ":admin:django_celery_results_taskresult_change": "/admin/django_celery_results/taskresult/{object_id}/change", + ":admin:django_celery_results_taskresult_changelist": "/admin/django_celery_results/taskresult", + ":admin:django_celery_results_taskresult_delete": "/admin/django_celery_results/taskresult/{object_id}/delete", + ":admin:django_celery_results_taskresult_history": "/admin/django_celery_results/taskresult/{object_id}/history", + ":admin:index": "/admin", + ":admin:jsi18n": "/admin/jsi18n", + ":admin:login": "/admin/login", + ":admin:logout": "/admin/logout", + ":admin:models_ddatatype_add": "/admin/models/ddatatype/add", + ":admin:models_ddatatype_change": "/admin/models/ddatatype/{object_id}/change", + ":admin:models_ddatatype_changelist": "/admin/models/ddatatype", + ":admin:models_ddatatype_delete": "/admin/models/ddatatype/{object_id}/delete", + ":admin:models_ddatatype_history": "/admin/models/ddatatype/{object_id}/history", + ":admin:models_etlmodule_add": "/admin/models/etlmodule/add", + ":admin:models_etlmodule_change": "/admin/models/etlmodule/{object_id}/change", + ":admin:models_etlmodule_changelist": "/admin/models/etlmodule", + ":admin:models_etlmodule_delete": "/admin/models/etlmodule/{object_id}/delete", + ":admin:models_etlmodule_history": "/admin/models/etlmodule/{object_id}/history", + ":admin:models_etlmodule_permissions": "/admin/models/etlmodule/{object_pk}/permissions", + ":admin:models_etlmodule_permissions_manage_group": "/admin/models/etlmodule/{object_pk}/permissions/group-manage/{group_id}", + ":admin:models_etlmodule_permissions_manage_user": "/admin/models/etlmodule/{object_pk}/permissions/user-manage/{user_id}", + ":admin:models_geocoder_add": "/admin/models/geocoder/add", + ":admin:models_geocoder_change": "/admin/models/geocoder/{object_id}/change", + ":admin:models_geocoder_changelist": "/admin/models/geocoder", + ":admin:models_geocoder_delete": "/admin/models/geocoder/{object_id}/delete", + ":admin:models_geocoder_history": "/admin/models/geocoder/{object_id}/history", + ":admin:models_graphmodel_add": "/admin/models/graphmodel/add", + ":admin:models_graphmodel_change": "/admin/models/graphmodel/{object_id}/change", + ":admin:models_graphmodel_changelist": "/admin/models/graphmodel", + ":admin:models_graphmodel_delete": "/admin/models/graphmodel/{object_id}/delete", + ":admin:models_graphmodel_history": "/admin/models/graphmodel/{object_id}/history", + ":admin:models_groupmapsettings_add": "/admin/models/groupmapsettings/add", + ":admin:models_groupmapsettings_change": "/admin/models/groupmapsettings/{object_id}/change", + ":admin:models_groupmapsettings_changelist": "/admin/models/groupmapsettings", + ":admin:models_groupmapsettings_delete": "/admin/models/groupmapsettings/{object_id}/delete", + ":admin:models_groupmapsettings_history": "/admin/models/groupmapsettings/{object_id}/history", + ":admin:models_iiifmanifest_add": "/admin/models/iiifmanifest/add", + ":admin:models_iiifmanifest_change": "/admin/models/iiifmanifest/{object_id}/change", + ":admin:models_iiifmanifest_changelist": "/admin/models/iiifmanifest", + ":admin:models_iiifmanifest_delete": "/admin/models/iiifmanifest/{object_id}/delete", + ":admin:models_iiifmanifest_history": "/admin/models/iiifmanifest/{object_id}/history", + ":admin:models_language_add": "/admin/models/language/add", + ":admin:models_language_change": "/admin/models/language/{object_id}/change", + ":admin:models_language_changelist": "/admin/models/language", + ":admin:models_language_delete": "/admin/models/language/{object_id}/delete", + ":admin:models_language_history": "/admin/models/language/{object_id}/history", + ":admin:models_maplayer_add": "/admin/models/maplayer/add", + ":admin:models_maplayer_change": "/admin/models/maplayer/{object_id}/change", + ":admin:models_maplayer_changelist": "/admin/models/maplayer", + ":admin:models_maplayer_delete": "/admin/models/maplayer/{object_id}/delete", + ":admin:models_maplayer_history": "/admin/models/maplayer/{object_id}/history", + ":admin:models_maplayer_permissions": "/admin/models/maplayer/{object_pk}/permissions", + ":admin:models_maplayer_permissions_manage_group": "/admin/models/maplayer/{object_pk}/permissions/group-manage/{group_id}", + ":admin:models_maplayer_permissions_manage_user": "/admin/models/maplayer/{object_pk}/permissions/user-manage/{user_id}", + ":admin:models_mapmarker_add": "/admin/models/mapmarker/add", + ":admin:models_mapmarker_change": "/admin/models/mapmarker/{object_id}/change", + ":admin:models_mapmarker_changelist": "/admin/models/mapmarker", + ":admin:models_mapmarker_delete": "/admin/models/mapmarker/{object_id}/delete", + ":admin:models_mapmarker_history": "/admin/models/mapmarker/{object_id}/history", + ":admin:models_mapsource_add": "/admin/models/mapsource/add", + ":admin:models_mapsource_change": "/admin/models/mapsource/{object_id}/change", + ":admin:models_mapsource_changelist": "/admin/models/mapsource", + ":admin:models_mapsource_delete": "/admin/models/mapsource/{object_id}/delete", + ":admin:models_mapsource_history": "/admin/models/mapsource/{object_id}/history", + ":admin:models_nodegroup_add": "/admin/models/nodegroup/add", + ":admin:models_nodegroup_change": "/admin/models/nodegroup/{object_id}/change", + ":admin:models_nodegroup_changelist": "/admin/models/nodegroup", + ":admin:models_nodegroup_delete": "/admin/models/nodegroup/{object_id}/delete", + ":admin:models_nodegroup_history": "/admin/models/nodegroup/{object_id}/history", + ":admin:models_plugin_add": "/admin/models/plugin/add", + ":admin:models_plugin_change": "/admin/models/plugin/{object_id}/change", + ":admin:models_plugin_changelist": "/admin/models/plugin", + ":admin:models_plugin_delete": "/admin/models/plugin/{object_id}/delete", + ":admin:models_plugin_history": "/admin/models/plugin/{object_id}/history", + ":admin:models_plugin_permissions": "/admin/models/plugin/{object_pk}/permissions", + ":admin:models_plugin_permissions_manage_group": "/admin/models/plugin/{object_pk}/permissions/group-manage/{group_id}", + ":admin:models_plugin_permissions_manage_user": "/admin/models/plugin/{object_pk}/permissions/user-manage/{user_id}", + ":admin:models_resourceinstancelifecycle_add": "/admin/models/resourceinstancelifecycle/add", + ":admin:models_resourceinstancelifecycle_change": "/admin/models/resourceinstancelifecycle/{object_id}/change", + ":admin:models_resourceinstancelifecycle_changelist": "/admin/models/resourceinstancelifecycle", + ":admin:models_resourceinstancelifecycle_delete": "/admin/models/resourceinstancelifecycle/{object_id}/delete", + ":admin:models_resourceinstancelifecycle_history": "/admin/models/resourceinstancelifecycle/{object_id}/history", + ":admin:models_resourceinstancelifecyclestate_add": "/admin/models/resourceinstancelifecyclestate/add", + ":admin:models_resourceinstancelifecyclestate_change": "/admin/models/resourceinstancelifecyclestate/{object_id}/change", + ":admin:models_resourceinstancelifecyclestate_changelist": "/admin/models/resourceinstancelifecyclestate", + ":admin:models_resourceinstancelifecyclestate_delete": "/admin/models/resourceinstancelifecyclestate/{object_id}/delete", + ":admin:models_resourceinstancelifecyclestate_history": "/admin/models/resourceinstancelifecyclestate/{object_id}/history", + ":admin:models_searchcomponent_add": "/admin/models/searchcomponent/add", + ":admin:models_searchcomponent_change": "/admin/models/searchcomponent/{object_id}/change", + ":admin:models_searchcomponent_changelist": "/admin/models/searchcomponent", + ":admin:models_searchcomponent_delete": "/admin/models/searchcomponent/{object_id}/delete", + ":admin:models_searchcomponent_history": "/admin/models/searchcomponent/{object_id}/history", + ":admin:models_spatialview_add": "/admin/models/spatialview/add", + ":admin:models_spatialview_change": "/admin/models/spatialview/{object_id}/change", + ":admin:models_spatialview_changelist": "/admin/models/spatialview", + ":admin:models_spatialview_delete": "/admin/models/spatialview/{object_id}/delete", + ":admin:models_spatialview_history": "/admin/models/spatialview/{object_id}/history", + ":admin:models_userprofile_add": "/admin/models/userprofile/add", + ":admin:models_userprofile_change": "/admin/models/userprofile/{object_id}/change", + ":admin:models_userprofile_changelist": "/admin/models/userprofile", + ":admin:models_userprofile_delete": "/admin/models/userprofile/{object_id}/delete", + ":admin:models_userprofile_history": "/admin/models/userprofile/{object_id}/history", + ":admin:models_widget_add": "/admin/models/widget/add", + ":admin:models_widget_change": "/admin/models/widget/{object_id}/change", + ":admin:models_widget_changelist": "/admin/models/widget", + ":admin:models_widget_delete": "/admin/models/widget/{object_id}/delete", + ":admin:models_widget_history": "/admin/models/widget/{object_id}/history", + ":admin:oauth2_provider_accesstoken_add": "/admin/oauth2_provider/accesstoken/add", + ":admin:oauth2_provider_accesstoken_change": "/admin/oauth2_provider/accesstoken/{object_id}/change", + ":admin:oauth2_provider_accesstoken_changelist": "/admin/oauth2_provider/accesstoken", + ":admin:oauth2_provider_accesstoken_delete": "/admin/oauth2_provider/accesstoken/{object_id}/delete", + ":admin:oauth2_provider_accesstoken_history": "/admin/oauth2_provider/accesstoken/{object_id}/history", + ":admin:oauth2_provider_application_add": "/admin/oauth2_provider/application/add", + ":admin:oauth2_provider_application_change": "/admin/oauth2_provider/application/{object_id}/change", + ":admin:oauth2_provider_application_changelist": "/admin/oauth2_provider/application", + ":admin:oauth2_provider_application_delete": "/admin/oauth2_provider/application/{object_id}/delete", + ":admin:oauth2_provider_application_history": "/admin/oauth2_provider/application/{object_id}/history", + ":admin:oauth2_provider_grant_add": "/admin/oauth2_provider/grant/add", + ":admin:oauth2_provider_grant_change": "/admin/oauth2_provider/grant/{object_id}/change", + ":admin:oauth2_provider_grant_changelist": "/admin/oauth2_provider/grant", + ":admin:oauth2_provider_grant_delete": "/admin/oauth2_provider/grant/{object_id}/delete", + ":admin:oauth2_provider_grant_history": "/admin/oauth2_provider/grant/{object_id}/history", + ":admin:oauth2_provider_idtoken_add": "/admin/oauth2_provider/idtoken/add", + ":admin:oauth2_provider_idtoken_change": "/admin/oauth2_provider/idtoken/{object_id}/change", + ":admin:oauth2_provider_idtoken_changelist": "/admin/oauth2_provider/idtoken", + ":admin:oauth2_provider_idtoken_delete": "/admin/oauth2_provider/idtoken/{object_id}/delete", + ":admin:oauth2_provider_idtoken_history": "/admin/oauth2_provider/idtoken/{object_id}/history", + ":admin:oauth2_provider_refreshtoken_add": "/admin/oauth2_provider/refreshtoken/add", + ":admin:oauth2_provider_refreshtoken_change": "/admin/oauth2_provider/refreshtoken/{object_id}/change", + ":admin:oauth2_provider_refreshtoken_changelist": "/admin/oauth2_provider/refreshtoken", + ":admin:oauth2_provider_refreshtoken_delete": "/admin/oauth2_provider/refreshtoken/{object_id}/delete", + ":admin:oauth2_provider_refreshtoken_history": "/admin/oauth2_provider/refreshtoken/{object_id}/history", + ":admin:password_change": "/admin/password_change", + ":admin:password_change_done": "/admin/password_change/done", + ":admin:view_on_site": "/admin/r/{content_type_id}/{object_id}", + ":oauth2:authorize": "/o/authorize", + ":oauth2:authorized-token-delete": "/o/authorized_tokens/{pk}/delete", + ":oauth2:authorized-token-list": "/o/authorized_tokens", + ":oauth2:delete": "/o/applications/{pk}/delete", + ":oauth2:detail": "/o/applications/{pk}", + ":oauth2:introspect": "/o/introspect", + ":oauth2:jwks-info": "/o/.well-known/jwks.json", + ":oauth2:list": "/o/applications", + ":oauth2:oidc-connect-discovery-info": "/o/.well-known/openid-configuration", + ":oauth2:register": "/o/applications/register", + ":oauth2:revoke-token": "/o/revoke_token", + ":oauth2:token": "/o/token", + ":oauth2:update": "/o/applications/{pk}/update", + ":oauth2:user-info": "/o/userinfo", + "add_resource": "/add-resource/{graphid}", + "api_404": "/api", + "api_bulk_disambiguated_resource_instance": "/api/bulk_disambiguated_resource_instance", + "api_bulk_resource_report": "/api/bulk_resource_report", + "api_card": "/cards/{resourceid}", + "api_export_results": "/api/search/export_results", + "api_get_nodegroup_tree": "/api/get_nodegroup_tree", + "api_instance_permissions": "/api/instance_permissions", + "api_login": "/api/login", + "api_logout": "/api/logout", + "api_node_value": "/api/node_value", + "api_nodegroup": "/api/nodegroup/{nodegroupid}", + "api_nodes": "/api/nodes/{nodeid}", + "api_plugins": "/api/plugins/{pluginid}", + "api_resource_instance_lifecycle_state": "/api/resource_instance_lifecycle_state/{resourceid}", + "api_resource_instance_lifecycle_states": "/api/resource_instance_lifecycle", + "api_resource_report": "/api/resource_report/{resourceid}", + "api_search_component_data": "/search_component_data/{componentname}", + "api_tiles": "/api/tiles/{tileid}", + "api_user": "/api/user", + "api_user_incomplete_workflows": "/api/user_incomplete_workflows", + "append_branch": "/graph/{graphid}/append_branch", + "append_node": "/graph/{graphid}/append_node", + "apply_functions": "/graph/{graphid}/apply_functions", + "as_stream_collection": "/history", + "as_stream_page": "/history/{page}", + "auth": "/auth", + "buffer": "/buffer", + "card": "/card/{cardid}", + "change_password": "/auth/password", + "clear_user_permission_cache": "/clear-user-permission-cache", + "clone_graph": "/graph/{graphid}/clone", + "concept": "/concepts/{conceptid}", + "concept_manage_parents": "/concepts/{conceptid}/manage_parents", + "concept_search": "/concepts/search", + "concept_tree": "/concepts/tree/{mode}", + "concept_value": "/conceptvalue", + "concepts": "/rdm/concepts/{conceptid}", + "config": "/settings", + "confirm_delete": "/concepts/{conceptid}/confirm_delete", + "confirm_signup": "/auth/confirm_signup", + "datatype_template": "/components/datatypes/{template}", + "delete_graph": "/graph/{graphid}/delete", + "delete_instances": "/graph/{graphid}/delete_instances", + "delete_node": "/graph/{graphid}/delete_node", + "delete_provisional_tile": "/tiles/delete_provisional_tile", + "delete_published_graph": "/graph/{graphid}/delete_published_graph", + "dismiss_notifications": "/notifications/dismiss", + "download_files": "/tiles/download_files", + "dropdown": "/concepts/dropdown", + "edit_history": "/resource/history", + "etl_manager": "/etl-manager", + "export_branch": "/graph/{graphid}/export_branch", + "export_concept": "/concepts/export/{conceptid}", + "export_concept_collections": "/concepts/export/collections", + "export_graph": "/graph/{graphid}/export", + "export_mapping_file": "/graph/{graphid}/export_mapping_file", + "export_results": "/search/export_results", + "external_oauth_callback": "/auth/eoauth_cb", + "external_oauth_start": "/auth/eoauth_start", + "feature_popup_content": "/feature_popup_content", + "file_access": "/files/{fileid}", + "from_sparql_endpoint": "/concepts/{conceptid}/from_sparql_endpoint", + "function-templates": "/function-templates/{template}", + "function_manager": "/graph/{graphid}/function_manager", + "geojson": "/geojson", + "get_client_id": "/auth/get_client_id", + "get_concept_collections": "/concepts/collections", + "get_dev_token": "/auth/get_dev_token", + "get_domain_connections": "/graph/{graphid}/get_domain_connections", + "get_dsl": "/search/get_dsl", + "get_export_file": "/search/get_export_file", + "get_frontend_i18n_data": "/api/get_frontend_i18n_data", + "get_graph_models_api": "/graphs", + "get_notification_types": "/notifications/get_types", + "get_notifications": "/notifications", + "get_pref_label": "/concepts/get_pref_label", + "get_related_nodes": "/graph/{graphid}/get_related_nodes/{nodeid}", + "get_user_names": "/user/get_user_names", + "get_valid_domain_nodes": "/graph/{graphid}/get_valid_domain_nodes/{nodeid}", + "graph": "/graph/{graphid}", + "graph_designer": "/graph_designer/{graphid}", + "graph_has_unpublished_changes_api": "/graph_has_unpublished_changes/{graph_id}", + "graph_is_active_api": "/graph_is_active/{graph_id}", + "graph_nodes": "/graph/{graphid}/nodes", + "graph_settings": "/graph_settings/{graphid}", + "graphs_api": "/graphs/{graph_id}", + "help_templates": "/help-templates", + "home": "/index.htm", + "icons": "/icons", + "iiifannotationnodes": "/iiifannotationnodes", + "iiifannotations": "/iiifannotations", + "iiifmanifest": "/iiifmanifest", + "images": "/images", + "import_graph": "/graph/import", + "language": "/language", + "make_collection": "/concepts/{conceptid}/make_collection", + "manifest": "/manifest/{id}", + "manifest_manager": "/image-service-manager", + "map_layer_manager": "/map_layer_manager", + "map_layer_update": "/map_layer_manager/{maplayerid}", + "model_history": "/graph/{graphid}/model_history", + "move_node": "/graph/{graphid}/move_node", + "mvt": "/mvt/{nodeid}/{zoom}/{x}/{y}.pbf", + "new_graph": "/graph/new", + "node": "/node/{graphid}", + "node_layer": "/node_layer/{graphid}", + "nodegroup": "/nodegroup", + "ontology_properties": "/ontology_properties", + "paged_dropdown": "/concepts/paged_dropdown", + "password_reset": "/password_reset", + "password_reset_complete": "/reset/done", + "password_reset_confirm": "/reset/{uidb64}/{token}", + "password_reset_done": "/password_reset/done", + "permission_data": "/graph/permissions", + "permission_manager_data": "/graph/permissions/permission_manager_data", + "plugins": "/plugins/{slug}/{path}", + "publish_graph": "/graph/{graphid}/publish", + "rdm": "/rdm/{conceptid}", + "reindex": "/admin/reindex/resources", + "relatable_resources": "/resource/related/relatable", + "related_resource_candidates": "/resource/related/candidates", + "related_resources": "/resource/related/{resourceid}", + "remove_functions": "/graph/{graphid}/remove_functions", + "reorder_cards": "/reorder_cards", + "reorder_nodes": "/graph/reorder_nodes", + "reorder_tiles": "/tiles/reorder_tiles", + "report-templates": "/report-templates/{template}", + "resource": "/resource", + "resource_cards": "/resource/{resourceid}/cards", + "resource_copy": "/resource/{resourceid}/copy", + "resource_data": "/resource/{resourceid}/data/{formid}", + "resource_descriptors": "/resource/descriptors/{resourceid}", + "resource_edit_log": "/resource/{resourceid}/history", + "resource_editor": "/resource/{resourceid}", + "resource_permission_data": "/resource/permissions", + "resource_report": "/report/{resourceid}", + "resource_tiles": "/resource/{resourceid}/tiles", + "resources": "/resources/{resourceid}", + "resources_graphid": "/resources/{graphid}/{resourceid}", + "resources_slug": "/resources/{slug}/{resourceid}", + "restore_state_from_serialized_graph": "/graph/{graphid}/restore_state_from_serialized_graph", + "revert_graph": "/graph/{graphid}/revert", + "root": "/", + "search_home": "/search", + "search_results": "/search/resources", + "search_sparql_endpoint": "/concepts/search_sparql_endpoint", + "search_terms": "/search/terms", + "server_settings": "/auth/server_settings", + "set_language": "/i18n/setlang", + "signup": "/auth/signup", + "spatialview_api": "/api/spatialview/{identifier}", + "temp_file": "/temp_file", + "templates": "/templates/{template}", + "thumbnail": "/thumbnail/{resource_id}", + "tile": "/tile", + "tile_history": "/tiles/tile_history", + "time_wheel_config": "/search/time_wheel_config", + "transaction_reverse": "/transaction/{transactionid}/reverse", + "transform_edtf_for_tile": "/transform-edtf-for-tile", + "two-factor-authentication-login": "/two-factor-authentication-login", + "two-factor-authentication-reset": "/two-factor-authentication-reset", + "two-factor-authentication-settings": "/two-factor-authentication-settings", + "update_node": "/graph/{graphid}/update_node", + "update_notification_types": "/notifications/update_types", + "update_published_graph": "/graph/{graphid}/update_published_graph", + "update_published_graphs": "/graph/{graphid}/update_published_graphs", + "user_profile": "/auth/user_profile", + "user_profile_manager": "/user", + "validate": "/validate/{itemtype}/{itemid}", + "validatejson": "/validate/{itemtype}", + "widgets": "/widgets/{template}", + "workflow_history": "/workflow_history/{workflowid}" +} \ No newline at end of file diff --git a/frontend_configuration/webpack-metadata.json b/frontend_configuration/webpack-metadata.json new file mode 100644 index 00000000000..2a871e4e0ae --- /dev/null +++ b/frontend_configuration/webpack-metadata.json @@ -0,0 +1,11 @@ +{ + "_comment": "This is a generated file. Do not edit directly.", + "APP_ROOT": "/Users/christopherbyrd/Projects/arches-lingo/arches/arches/app", + "ARCHES_APPLICATIONS": [], + "ARCHES_APPLICATIONS_PATHS": {}, + "SITE_PACKAGES_DIRECTORY": "/Users/christopherbyrd/Projects/arches-lingo/ENV/lib/python3.12/site-packages", + "PUBLIC_SERVER_ADDRESS": "http://localhost:8000/", + "ROOT_DIR": "/Users/christopherbyrd/Projects/arches-lingo/arches/arches", + "STATIC_URL": "/static/", + "WEBPACK_DEVELOPMENT_SERVER_PORT": 9000 +} \ No newline at end of file From f4fd1fef34e31b4d88d6d3c53142f98a4aca4818 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 23 Oct 2024 09:06:04 -0700 Subject: [PATCH 03/18] nit 11567 --- .../app/utils/frontend_configuration_utils.py | 25 ++++++++++++++----- arches/settings_utils.py | 3 --- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/arches/app/utils/frontend_configuration_utils.py b/arches/app/utils/frontend_configuration_utils.py index 7b96852c0bf..810dd90a8e1 100644 --- a/arches/app/utils/frontend_configuration_utils.py +++ b/arches/app/utils/frontend_configuration_utils.py @@ -2,6 +2,7 @@ import os import re import site +import sys from django.conf import settings from django.urls import get_resolver, URLPattern, URLResolver @@ -11,10 +12,15 @@ def generate_frontend_configuration(): - _generate_frontend_configuration_directory() - _generate_urls_json() - _generate_webpack_configuration() - _generate_tsconfig_paths() + try: + _generate_frontend_configuration_directory() + _generate_urls_json() + _generate_webpack_configuration() + _generate_tsconfig_paths() + except Exception as e: + # Ensures error message is shown if error encountered + sys.stderr.write(str(e)) + raise e def _generate_frontend_configuration_directory(): @@ -79,6 +85,10 @@ def interpolate_route(pattern): resolver = get_resolver() human_readable_urls = generate_human_readable_urls(resolver.url_patterns) + # manual additions + human_readable_urls["static_url"] = settings.STATIC_URL + human_readable_urls["media_url"] = settings.MEDIA_URL + destination_path = os.path.realpath( os.path.join(_get_base_path(), "..", "frontend_configuration", "urls.json") ) @@ -86,8 +96,11 @@ def interpolate_route(pattern): with open(destination_path, "w") as file: json.dump( { - url_name: human_readable_urls[url_name] - for url_name in sorted(human_readable_urls) + "_comment": "This is a generated file. Do not edit directly.", + **{ + url_name: human_readable_urls[url_name] + for url_name in sorted(human_readable_urls) + }, }, file, indent=4, diff --git a/arches/settings_utils.py b/arches/settings_utils.py index 23c39d3e0a0..9ad59295116 100644 --- a/arches/settings_utils.py +++ b/arches/settings_utils.py @@ -1,10 +1,7 @@ -import json import os -import site import sys from django.apps import apps -from django.conf import settings from django.contrib.staticfiles.finders import AppDirectoriesFinder From e8a1171ca283fa7fa01bd412ba439cc10d1fc8a6 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 23 Oct 2024 13:54:41 -0700 Subject: [PATCH 04/18] adds util to generate frontend URLs #11567 --- .../media/js/utils/create-vue-application.js | 6 +++-- .../src/arches/utils/generate-arches-url.ts | 27 +++++++++++++++++++ arches/app/templates/base-root.htm | 3 +-- arches/app/templates/base.htm | 10 +------ arches/install/arches-templates/tsconfig.json | 2 +- tsconfig.json | 2 +- 6 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 arches/app/src/arches/utils/generate-arches-url.ts diff --git a/arches/app/media/js/utils/create-vue-application.js b/arches/app/media/js/utils/create-vue-application.js index 2f1620adc48..21bd78507ac 100644 --- a/arches/app/media/js/utils/create-vue-application.js +++ b/arches/app/media/js/utils/create-vue-application.js @@ -10,8 +10,9 @@ import Tooltip from 'primevue/tooltip'; import { createApp } from 'vue'; import { createGettext } from "vue3-gettext"; -import arches from 'arches'; import { DEFAULT_THEME } from "@/arches/themes/default.ts"; +import generateArchesURL from '@/arches/utils/generate-arches-url.ts'; + export default async function createVueApplication(vueComponent, themeConfiguration) { /** @@ -27,7 +28,8 @@ export default async function createVueApplication(vueComponent, themeConfigurat * TODO: cbyrd #10501 - we should add an event listener that will re-fetch i18n data * and rebuild the app when a specific event is fired from the LanguageSwitcher component. **/ - return fetch(arches.urls.api_get_frontend_i18n_data).then(function(resp) { + + return fetch(generateArchesURL("get_frontend_i18n_data")).then(function(resp) { if (!resp.ok) { throw new Error(resp.statusText); } diff --git a/arches/app/src/arches/utils/generate-arches-url.ts b/arches/app/src/arches/utils/generate-arches-url.ts new file mode 100644 index 00000000000..1c5098d8975 --- /dev/null +++ b/arches/app/src/arches/utils/generate-arches-url.ts @@ -0,0 +1,27 @@ +export default function ( + urlName: string, + languageCode: string | null = null, + urlParams = {}, +) { + // @ts-expect-error ARCHES_URLS is defined globally + let url = ARCHES_URLS[urlName]; + + if (!url) { + throw new Error(`Key '${urlName}' not found in JSON object`); + } + + if (url.includes("{language_code}")) { + if (!languageCode) { + const htmlLang = document.documentElement.lang; + languageCode = htmlLang.split("-")[0]; + } + + url = url.replace("{language_code}", languageCode); + } + + Object.entries(urlParams).forEach((key, value) => { + url = url.replace(new RegExp(`{${key}}`, "g"), value); + }); + + return url; +} diff --git a/arches/app/templates/base-root.htm b/arches/app/templates/base-root.htm index 0413379c6b1..d85e6a13f40 100644 --- a/arches/app/templates/base-root.htm +++ b/arches/app/templates/base-root.htm @@ -22,7 +22,7 @@ - + {% block head %} @@ -77,7 +77,6 @@ {% endblock pre_require_js %} {% block arches_modules %} - {% include "arches_urls.htm" %} {% endblock arches_modules %} {% if main_script %} diff --git a/arches/app/templates/base.htm b/arches/app/templates/base.htm index 990736c20e3..d6c2651623f 100644 --- a/arches/app/templates/base.htm +++ b/arches/app/templates/base.htm @@ -17,16 +17,9 @@ --> {% extends "base-root.htm" %} -{% load static %} {% load i18n %} -{% load webpack_static from webpack_loader %} {% load render_bundle from webpack_loader %} - - - - - {% if use_livereload %} {% endif %} @@ -61,5 +54,4 @@ {% block arches_modules %} {% include 'javascript.htm' %} -{% endblock arches_modules %} - +{% endblock arches_modules %} \ No newline at end of file diff --git a/arches/install/arches-templates/tsconfig.json b/arches/install/arches-templates/tsconfig.json index c223f2c6ad0..67e112fd782 100644 --- a/arches/install/arches-templates/tsconfig.json +++ b/arches/install/arches-templates/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "./.tsconfig-paths.json", + "extends": "./frontend_configuration/tsconfig-paths.json", "compilerOptions": { "target": "ESNext", "module": "ESNext", diff --git a/tsconfig.json b/tsconfig.json index c223f2c6ad0..67e112fd782 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "./.tsconfig-paths.json", + "extends": "./frontend_configuration/tsconfig-paths.json", "compilerOptions": { "target": "ESNext", "module": "ESNext", From 23a65c4d1cb32d3ee1b282fa675fe8e7c78dd411 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 23 Oct 2024 13:57:49 -0700 Subject: [PATCH 05/18] updates webpack #11567 --- .../webpack/webpack.common.js | 25 ++++++++++++------- .../webpack/webpack.config.dev.js | 11 +++++++- webpack/webpack.common.js | 25 ++++++++++++------- webpack/webpack.config.dev.js | 11 +++++++- 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/arches/install/arches-templates/webpack/webpack.common.js b/arches/install/arches-templates/webpack/webpack.common.js index cb62dd40ed7..fa4a5e69590 100644 --- a/arches/install/arches-templates/webpack/webpack.common.js +++ b/arches/install/arches-templates/webpack/webpack.common.js @@ -14,13 +14,13 @@ const { buildFilepathLookup } = require('./webpack-utils/build-filepath-lookup') module.exports = () => { return new Promise((resolve, _reject) => { - // BEGIN get data from `.frontend-configuration-settings.json` + // BEGIN get data from `webpack-metadata.json` - const rawData = fs.readFileSync(Path.join(__dirname, "..", '.frontend-configuration-settings.json'), 'utf-8'); + const rawData = fs.readFileSync(Path.join(__dirname, "..", "frontend_configuration", 'webpack-metadata.json'), 'utf-8'); const parsedData = JSON.parse(rawData); - console.log('Data imported from .frontend-configuration-settings.json:', parsedData); - + console.log('Data imported from webpack-metadata.json:', parsedData); + global.APP_ROOT = parsedData['APP_ROOT']; global.ARCHES_APPLICATIONS = parsedData['ARCHES_APPLICATIONS']; global.ARCHES_APPLICATIONS_PATHS = parsedData['ARCHES_APPLICATIONS_PATHS']; @@ -30,7 +30,7 @@ module.exports = () => { global.PUBLIC_SERVER_ADDRESS = parsedData['PUBLIC_SERVER_ADDRESS']; global.WEBPACK_DEVELOPMENT_SERVER_PORT = parsedData['WEBPACK_DEVELOPMENT_SERVER_PORT']; - // END get data from `.frontend-configuration-settings.json` + // END get data from `webpack-metadata.json` // BEGIN workaround for handling node_modules paths in arches-core vs projects let PROJECT_RELATIVE_NODE_MODULES_PATH; @@ -242,8 +242,8 @@ module.exports = () => { const universalConstants = { APP_ROOT_DIRECTORY: JSON.stringify(APP_ROOT).replace(/\\/g, '/'), - ARCHES_CORE_DIRECTORY: JSON.stringify(ROOT_DIR).replace(/\\/g, '/'), ARCHES_APPLICATIONS: JSON.stringify(ARCHES_APPLICATIONS), + ARCHES_CORE_DIRECTORY: JSON.stringify(ROOT_DIR).replace(/\\/g, '/'), SITE_PACKAGES_DIRECTORY: JSON.stringify(SITE_PACKAGES_DIRECTORY).replace(/\\/g, '/'), }; @@ -279,6 +279,12 @@ module.exports = () => { plugins: [ new CleanWebpackPlugin(), new webpack.DefinePlugin(universalConstants), + new webpack.DefinePlugin({ + ARCHES_URLS: webpack.DefinePlugin.runtimeValue( + () => fs.readFileSync(Path.resolve(__dirname, APP_ROOT, '..', 'frontend_configuration', 'urls.json'), 'utf-8'), + true // should be re-evaluated on rebuild + ), + }), new webpack.DefinePlugin({ __VUE_OPTIONS_API__: 'true', __VUE_PROD_DEVTOOLS__: 'false', @@ -290,9 +296,9 @@ module.exports = () => { jquery: Path.resolve(__dirname, PROJECT_RELATIVE_NODE_MODULES_PATH, 'jquery', 'dist', 'jquery.min') }), new MiniCssExtractPlugin(), - new BundleTracker({ + new BundleTracker({ path: Path.resolve(__dirname), - filename: 'webpack-stats.json' + filename: 'webpack-stats.json' }), new VueLoaderPlugin(), ], @@ -351,6 +357,7 @@ module.exports = () => { { test: /\.css$/, exclude: [ + /node_modules/, Path.resolve(__dirname, APP_ROOT, 'media', 'css'), Path.resolve(__dirname, ROOT_DIR, 'app', 'media', 'css'), ...archesApplicationsCSSFilepaths @@ -450,7 +457,7 @@ module.exports = () => { if (serverAddress.charAt(serverAddress.length - 1) === '/') { serverAddress = serverAddress.slice(0, -1) } - + resp = await fetch(serverAddress + templatePath); if (resp.status === 500) { diff --git a/arches/install/arches-templates/webpack/webpack.config.dev.js b/arches/install/arches-templates/webpack/webpack.config.dev.js index 2e3da3f6c00..50b98bc30df 100644 --- a/arches/install/arches-templates/webpack/webpack.config.dev.js +++ b/arches/install/arches-templates/webpack/webpack.config.dev.js @@ -43,7 +43,16 @@ module.exports = () => { }), new StylelintPlugin({ files: Path.join('src', '**/*.s?(a|c)ss'), - }) + }), + { + apply: (compiler) => { + compiler.hooks.afterCompile.tap('WatchArchesUrlsPlugin', (compilation) => { + compilation.fileDependencies.add( + Path.resolve(__dirname, APP_ROOT, '..', 'frontend_configuration', 'urls.json') + ); + }); + }, + }, ], })); }); diff --git a/webpack/webpack.common.js b/webpack/webpack.common.js index cb62dd40ed7..fa4a5e69590 100644 --- a/webpack/webpack.common.js +++ b/webpack/webpack.common.js @@ -14,13 +14,13 @@ const { buildFilepathLookup } = require('./webpack-utils/build-filepath-lookup') module.exports = () => { return new Promise((resolve, _reject) => { - // BEGIN get data from `.frontend-configuration-settings.json` + // BEGIN get data from `webpack-metadata.json` - const rawData = fs.readFileSync(Path.join(__dirname, "..", '.frontend-configuration-settings.json'), 'utf-8'); + const rawData = fs.readFileSync(Path.join(__dirname, "..", "frontend_configuration", 'webpack-metadata.json'), 'utf-8'); const parsedData = JSON.parse(rawData); - console.log('Data imported from .frontend-configuration-settings.json:', parsedData); - + console.log('Data imported from webpack-metadata.json:', parsedData); + global.APP_ROOT = parsedData['APP_ROOT']; global.ARCHES_APPLICATIONS = parsedData['ARCHES_APPLICATIONS']; global.ARCHES_APPLICATIONS_PATHS = parsedData['ARCHES_APPLICATIONS_PATHS']; @@ -30,7 +30,7 @@ module.exports = () => { global.PUBLIC_SERVER_ADDRESS = parsedData['PUBLIC_SERVER_ADDRESS']; global.WEBPACK_DEVELOPMENT_SERVER_PORT = parsedData['WEBPACK_DEVELOPMENT_SERVER_PORT']; - // END get data from `.frontend-configuration-settings.json` + // END get data from `webpack-metadata.json` // BEGIN workaround for handling node_modules paths in arches-core vs projects let PROJECT_RELATIVE_NODE_MODULES_PATH; @@ -242,8 +242,8 @@ module.exports = () => { const universalConstants = { APP_ROOT_DIRECTORY: JSON.stringify(APP_ROOT).replace(/\\/g, '/'), - ARCHES_CORE_DIRECTORY: JSON.stringify(ROOT_DIR).replace(/\\/g, '/'), ARCHES_APPLICATIONS: JSON.stringify(ARCHES_APPLICATIONS), + ARCHES_CORE_DIRECTORY: JSON.stringify(ROOT_DIR).replace(/\\/g, '/'), SITE_PACKAGES_DIRECTORY: JSON.stringify(SITE_PACKAGES_DIRECTORY).replace(/\\/g, '/'), }; @@ -279,6 +279,12 @@ module.exports = () => { plugins: [ new CleanWebpackPlugin(), new webpack.DefinePlugin(universalConstants), + new webpack.DefinePlugin({ + ARCHES_URLS: webpack.DefinePlugin.runtimeValue( + () => fs.readFileSync(Path.resolve(__dirname, APP_ROOT, '..', 'frontend_configuration', 'urls.json'), 'utf-8'), + true // should be re-evaluated on rebuild + ), + }), new webpack.DefinePlugin({ __VUE_OPTIONS_API__: 'true', __VUE_PROD_DEVTOOLS__: 'false', @@ -290,9 +296,9 @@ module.exports = () => { jquery: Path.resolve(__dirname, PROJECT_RELATIVE_NODE_MODULES_PATH, 'jquery', 'dist', 'jquery.min') }), new MiniCssExtractPlugin(), - new BundleTracker({ + new BundleTracker({ path: Path.resolve(__dirname), - filename: 'webpack-stats.json' + filename: 'webpack-stats.json' }), new VueLoaderPlugin(), ], @@ -351,6 +357,7 @@ module.exports = () => { { test: /\.css$/, exclude: [ + /node_modules/, Path.resolve(__dirname, APP_ROOT, 'media', 'css'), Path.resolve(__dirname, ROOT_DIR, 'app', 'media', 'css'), ...archesApplicationsCSSFilepaths @@ -450,7 +457,7 @@ module.exports = () => { if (serverAddress.charAt(serverAddress.length - 1) === '/') { serverAddress = serverAddress.slice(0, -1) } - + resp = await fetch(serverAddress + templatePath); if (resp.status === 500) { diff --git a/webpack/webpack.config.dev.js b/webpack/webpack.config.dev.js index 2e3da3f6c00..50b98bc30df 100644 --- a/webpack/webpack.config.dev.js +++ b/webpack/webpack.config.dev.js @@ -43,7 +43,16 @@ module.exports = () => { }), new StylelintPlugin({ files: Path.join('src', '**/*.s?(a|c)ss'), - }) + }), + { + apply: (compiler) => { + compiler.hooks.afterCompile.tap('WatchArchesUrlsPlugin', (compilation) => { + compilation.fileDependencies.add( + Path.resolve(__dirname, APP_ROOT, '..', 'frontend_configuration', 'urls.json') + ); + }); + }, + }, ], })); }); From dae3bff789af6f47c30645bbc723e53009e36998 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 23 Oct 2024 14:02:36 -0700 Subject: [PATCH 06/18] nit #11567 --- frontend_configuration/tsconfig-paths.json | 13 - frontend_configuration/urls.json | 343 ------------------- frontend_configuration/webpack-metadata.json | 11 - 3 files changed, 367 deletions(-) delete mode 100644 frontend_configuration/tsconfig-paths.json delete mode 100644 frontend_configuration/urls.json delete mode 100644 frontend_configuration/webpack-metadata.json diff --git a/frontend_configuration/tsconfig-paths.json b/frontend_configuration/tsconfig-paths.json deleted file mode 100644 index 4f3cbd0276c..00000000000 --- a/frontend_configuration/tsconfig-paths.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "_comment": "This is a generated file. Do not edit directly.", - "compilerOptions": { - "paths": { - "@/arches/*": [ - "./arches/app/src/arches/*" - ], - "*": [ - "./node_modules/*" - ] - } - } -} \ No newline at end of file diff --git a/frontend_configuration/urls.json b/frontend_configuration/urls.json deleted file mode 100644 index 0997b4f4c12..00000000000 --- a/frontend_configuration/urls.json +++ /dev/null @@ -1,343 +0,0 @@ -{ - ":admin:app_list": "/admin/{app_label}", - ":admin:auth_group_add": "/admin/auth/group/add", - ":admin:auth_group_change": "/admin/auth/group/{object_id}/change", - ":admin:auth_group_changelist": "/admin/auth/group", - ":admin:auth_group_delete": "/admin/auth/group/{object_id}/delete", - ":admin:auth_group_history": "/admin/auth/group/{object_id}/history", - ":admin:auth_user_add": "/admin/auth/user/add", - ":admin:auth_user_change": "/admin/auth/user/{object_id}/change", - ":admin:auth_user_changelist": "/admin/auth/user", - ":admin:auth_user_delete": "/admin/auth/user/{object_id}/delete", - ":admin:auth_user_history": "/admin/auth/user/{object_id}/history", - ":admin:auth_user_password_change": "/admin/auth/user/{id}/password", - ":admin:autocomplete": "/admin/autocomplete", - ":admin:django_celery_results_groupresult_add": "/admin/django_celery_results/groupresult/add", - ":admin:django_celery_results_groupresult_change": "/admin/django_celery_results/groupresult/{object_id}/change", - ":admin:django_celery_results_groupresult_changelist": "/admin/django_celery_results/groupresult", - ":admin:django_celery_results_groupresult_delete": "/admin/django_celery_results/groupresult/{object_id}/delete", - ":admin:django_celery_results_groupresult_history": "/admin/django_celery_results/groupresult/{object_id}/history", - ":admin:django_celery_results_taskresult_add": "/admin/django_celery_results/taskresult/add", - ":admin:django_celery_results_taskresult_change": "/admin/django_celery_results/taskresult/{object_id}/change", - ":admin:django_celery_results_taskresult_changelist": "/admin/django_celery_results/taskresult", - ":admin:django_celery_results_taskresult_delete": "/admin/django_celery_results/taskresult/{object_id}/delete", - ":admin:django_celery_results_taskresult_history": "/admin/django_celery_results/taskresult/{object_id}/history", - ":admin:index": "/admin", - ":admin:jsi18n": "/admin/jsi18n", - ":admin:login": "/admin/login", - ":admin:logout": "/admin/logout", - ":admin:models_ddatatype_add": "/admin/models/ddatatype/add", - ":admin:models_ddatatype_change": "/admin/models/ddatatype/{object_id}/change", - ":admin:models_ddatatype_changelist": "/admin/models/ddatatype", - ":admin:models_ddatatype_delete": "/admin/models/ddatatype/{object_id}/delete", - ":admin:models_ddatatype_history": "/admin/models/ddatatype/{object_id}/history", - ":admin:models_etlmodule_add": "/admin/models/etlmodule/add", - ":admin:models_etlmodule_change": "/admin/models/etlmodule/{object_id}/change", - ":admin:models_etlmodule_changelist": "/admin/models/etlmodule", - ":admin:models_etlmodule_delete": "/admin/models/etlmodule/{object_id}/delete", - ":admin:models_etlmodule_history": "/admin/models/etlmodule/{object_id}/history", - ":admin:models_etlmodule_permissions": "/admin/models/etlmodule/{object_pk}/permissions", - ":admin:models_etlmodule_permissions_manage_group": "/admin/models/etlmodule/{object_pk}/permissions/group-manage/{group_id}", - ":admin:models_etlmodule_permissions_manage_user": "/admin/models/etlmodule/{object_pk}/permissions/user-manage/{user_id}", - ":admin:models_geocoder_add": "/admin/models/geocoder/add", - ":admin:models_geocoder_change": "/admin/models/geocoder/{object_id}/change", - ":admin:models_geocoder_changelist": "/admin/models/geocoder", - ":admin:models_geocoder_delete": "/admin/models/geocoder/{object_id}/delete", - ":admin:models_geocoder_history": "/admin/models/geocoder/{object_id}/history", - ":admin:models_graphmodel_add": "/admin/models/graphmodel/add", - ":admin:models_graphmodel_change": "/admin/models/graphmodel/{object_id}/change", - ":admin:models_graphmodel_changelist": "/admin/models/graphmodel", - ":admin:models_graphmodel_delete": "/admin/models/graphmodel/{object_id}/delete", - ":admin:models_graphmodel_history": "/admin/models/graphmodel/{object_id}/history", - ":admin:models_groupmapsettings_add": "/admin/models/groupmapsettings/add", - ":admin:models_groupmapsettings_change": "/admin/models/groupmapsettings/{object_id}/change", - ":admin:models_groupmapsettings_changelist": "/admin/models/groupmapsettings", - ":admin:models_groupmapsettings_delete": "/admin/models/groupmapsettings/{object_id}/delete", - ":admin:models_groupmapsettings_history": "/admin/models/groupmapsettings/{object_id}/history", - ":admin:models_iiifmanifest_add": "/admin/models/iiifmanifest/add", - ":admin:models_iiifmanifest_change": "/admin/models/iiifmanifest/{object_id}/change", - ":admin:models_iiifmanifest_changelist": "/admin/models/iiifmanifest", - ":admin:models_iiifmanifest_delete": "/admin/models/iiifmanifest/{object_id}/delete", - ":admin:models_iiifmanifest_history": "/admin/models/iiifmanifest/{object_id}/history", - ":admin:models_language_add": "/admin/models/language/add", - ":admin:models_language_change": "/admin/models/language/{object_id}/change", - ":admin:models_language_changelist": "/admin/models/language", - ":admin:models_language_delete": "/admin/models/language/{object_id}/delete", - ":admin:models_language_history": "/admin/models/language/{object_id}/history", - ":admin:models_maplayer_add": "/admin/models/maplayer/add", - ":admin:models_maplayer_change": "/admin/models/maplayer/{object_id}/change", - ":admin:models_maplayer_changelist": "/admin/models/maplayer", - ":admin:models_maplayer_delete": "/admin/models/maplayer/{object_id}/delete", - ":admin:models_maplayer_history": "/admin/models/maplayer/{object_id}/history", - ":admin:models_maplayer_permissions": "/admin/models/maplayer/{object_pk}/permissions", - ":admin:models_maplayer_permissions_manage_group": "/admin/models/maplayer/{object_pk}/permissions/group-manage/{group_id}", - ":admin:models_maplayer_permissions_manage_user": "/admin/models/maplayer/{object_pk}/permissions/user-manage/{user_id}", - ":admin:models_mapmarker_add": "/admin/models/mapmarker/add", - ":admin:models_mapmarker_change": "/admin/models/mapmarker/{object_id}/change", - ":admin:models_mapmarker_changelist": "/admin/models/mapmarker", - ":admin:models_mapmarker_delete": "/admin/models/mapmarker/{object_id}/delete", - ":admin:models_mapmarker_history": "/admin/models/mapmarker/{object_id}/history", - ":admin:models_mapsource_add": "/admin/models/mapsource/add", - ":admin:models_mapsource_change": "/admin/models/mapsource/{object_id}/change", - ":admin:models_mapsource_changelist": "/admin/models/mapsource", - ":admin:models_mapsource_delete": "/admin/models/mapsource/{object_id}/delete", - ":admin:models_mapsource_history": "/admin/models/mapsource/{object_id}/history", - ":admin:models_nodegroup_add": "/admin/models/nodegroup/add", - ":admin:models_nodegroup_change": "/admin/models/nodegroup/{object_id}/change", - ":admin:models_nodegroup_changelist": "/admin/models/nodegroup", - ":admin:models_nodegroup_delete": "/admin/models/nodegroup/{object_id}/delete", - ":admin:models_nodegroup_history": "/admin/models/nodegroup/{object_id}/history", - ":admin:models_plugin_add": "/admin/models/plugin/add", - ":admin:models_plugin_change": "/admin/models/plugin/{object_id}/change", - ":admin:models_plugin_changelist": "/admin/models/plugin", - ":admin:models_plugin_delete": "/admin/models/plugin/{object_id}/delete", - ":admin:models_plugin_history": "/admin/models/plugin/{object_id}/history", - ":admin:models_plugin_permissions": "/admin/models/plugin/{object_pk}/permissions", - ":admin:models_plugin_permissions_manage_group": "/admin/models/plugin/{object_pk}/permissions/group-manage/{group_id}", - ":admin:models_plugin_permissions_manage_user": "/admin/models/plugin/{object_pk}/permissions/user-manage/{user_id}", - ":admin:models_resourceinstancelifecycle_add": "/admin/models/resourceinstancelifecycle/add", - ":admin:models_resourceinstancelifecycle_change": "/admin/models/resourceinstancelifecycle/{object_id}/change", - ":admin:models_resourceinstancelifecycle_changelist": "/admin/models/resourceinstancelifecycle", - ":admin:models_resourceinstancelifecycle_delete": "/admin/models/resourceinstancelifecycle/{object_id}/delete", - ":admin:models_resourceinstancelifecycle_history": "/admin/models/resourceinstancelifecycle/{object_id}/history", - ":admin:models_resourceinstancelifecyclestate_add": "/admin/models/resourceinstancelifecyclestate/add", - ":admin:models_resourceinstancelifecyclestate_change": "/admin/models/resourceinstancelifecyclestate/{object_id}/change", - ":admin:models_resourceinstancelifecyclestate_changelist": "/admin/models/resourceinstancelifecyclestate", - ":admin:models_resourceinstancelifecyclestate_delete": "/admin/models/resourceinstancelifecyclestate/{object_id}/delete", - ":admin:models_resourceinstancelifecyclestate_history": "/admin/models/resourceinstancelifecyclestate/{object_id}/history", - ":admin:models_searchcomponent_add": "/admin/models/searchcomponent/add", - ":admin:models_searchcomponent_change": "/admin/models/searchcomponent/{object_id}/change", - ":admin:models_searchcomponent_changelist": "/admin/models/searchcomponent", - ":admin:models_searchcomponent_delete": "/admin/models/searchcomponent/{object_id}/delete", - ":admin:models_searchcomponent_history": "/admin/models/searchcomponent/{object_id}/history", - ":admin:models_spatialview_add": "/admin/models/spatialview/add", - ":admin:models_spatialview_change": "/admin/models/spatialview/{object_id}/change", - ":admin:models_spatialview_changelist": "/admin/models/spatialview", - ":admin:models_spatialview_delete": "/admin/models/spatialview/{object_id}/delete", - ":admin:models_spatialview_history": "/admin/models/spatialview/{object_id}/history", - ":admin:models_userprofile_add": "/admin/models/userprofile/add", - ":admin:models_userprofile_change": "/admin/models/userprofile/{object_id}/change", - ":admin:models_userprofile_changelist": "/admin/models/userprofile", - ":admin:models_userprofile_delete": "/admin/models/userprofile/{object_id}/delete", - ":admin:models_userprofile_history": "/admin/models/userprofile/{object_id}/history", - ":admin:models_widget_add": "/admin/models/widget/add", - ":admin:models_widget_change": "/admin/models/widget/{object_id}/change", - ":admin:models_widget_changelist": "/admin/models/widget", - ":admin:models_widget_delete": "/admin/models/widget/{object_id}/delete", - ":admin:models_widget_history": "/admin/models/widget/{object_id}/history", - ":admin:oauth2_provider_accesstoken_add": "/admin/oauth2_provider/accesstoken/add", - ":admin:oauth2_provider_accesstoken_change": "/admin/oauth2_provider/accesstoken/{object_id}/change", - ":admin:oauth2_provider_accesstoken_changelist": "/admin/oauth2_provider/accesstoken", - ":admin:oauth2_provider_accesstoken_delete": "/admin/oauth2_provider/accesstoken/{object_id}/delete", - ":admin:oauth2_provider_accesstoken_history": "/admin/oauth2_provider/accesstoken/{object_id}/history", - ":admin:oauth2_provider_application_add": "/admin/oauth2_provider/application/add", - ":admin:oauth2_provider_application_change": "/admin/oauth2_provider/application/{object_id}/change", - ":admin:oauth2_provider_application_changelist": "/admin/oauth2_provider/application", - ":admin:oauth2_provider_application_delete": "/admin/oauth2_provider/application/{object_id}/delete", - ":admin:oauth2_provider_application_history": "/admin/oauth2_provider/application/{object_id}/history", - ":admin:oauth2_provider_grant_add": "/admin/oauth2_provider/grant/add", - ":admin:oauth2_provider_grant_change": "/admin/oauth2_provider/grant/{object_id}/change", - ":admin:oauth2_provider_grant_changelist": "/admin/oauth2_provider/grant", - ":admin:oauth2_provider_grant_delete": "/admin/oauth2_provider/grant/{object_id}/delete", - ":admin:oauth2_provider_grant_history": "/admin/oauth2_provider/grant/{object_id}/history", - ":admin:oauth2_provider_idtoken_add": "/admin/oauth2_provider/idtoken/add", - ":admin:oauth2_provider_idtoken_change": "/admin/oauth2_provider/idtoken/{object_id}/change", - ":admin:oauth2_provider_idtoken_changelist": "/admin/oauth2_provider/idtoken", - ":admin:oauth2_provider_idtoken_delete": "/admin/oauth2_provider/idtoken/{object_id}/delete", - ":admin:oauth2_provider_idtoken_history": "/admin/oauth2_provider/idtoken/{object_id}/history", - ":admin:oauth2_provider_refreshtoken_add": "/admin/oauth2_provider/refreshtoken/add", - ":admin:oauth2_provider_refreshtoken_change": "/admin/oauth2_provider/refreshtoken/{object_id}/change", - ":admin:oauth2_provider_refreshtoken_changelist": "/admin/oauth2_provider/refreshtoken", - ":admin:oauth2_provider_refreshtoken_delete": "/admin/oauth2_provider/refreshtoken/{object_id}/delete", - ":admin:oauth2_provider_refreshtoken_history": "/admin/oauth2_provider/refreshtoken/{object_id}/history", - ":admin:password_change": "/admin/password_change", - ":admin:password_change_done": "/admin/password_change/done", - ":admin:view_on_site": "/admin/r/{content_type_id}/{object_id}", - ":oauth2:authorize": "/o/authorize", - ":oauth2:authorized-token-delete": "/o/authorized_tokens/{pk}/delete", - ":oauth2:authorized-token-list": "/o/authorized_tokens", - ":oauth2:delete": "/o/applications/{pk}/delete", - ":oauth2:detail": "/o/applications/{pk}", - ":oauth2:introspect": "/o/introspect", - ":oauth2:jwks-info": "/o/.well-known/jwks.json", - ":oauth2:list": "/o/applications", - ":oauth2:oidc-connect-discovery-info": "/o/.well-known/openid-configuration", - ":oauth2:register": "/o/applications/register", - ":oauth2:revoke-token": "/o/revoke_token", - ":oauth2:token": "/o/token", - ":oauth2:update": "/o/applications/{pk}/update", - ":oauth2:user-info": "/o/userinfo", - "add_resource": "/add-resource/{graphid}", - "api_404": "/api", - "api_bulk_disambiguated_resource_instance": "/api/bulk_disambiguated_resource_instance", - "api_bulk_resource_report": "/api/bulk_resource_report", - "api_card": "/cards/{resourceid}", - "api_export_results": "/api/search/export_results", - "api_get_nodegroup_tree": "/api/get_nodegroup_tree", - "api_instance_permissions": "/api/instance_permissions", - "api_login": "/api/login", - "api_logout": "/api/logout", - "api_node_value": "/api/node_value", - "api_nodegroup": "/api/nodegroup/{nodegroupid}", - "api_nodes": "/api/nodes/{nodeid}", - "api_plugins": "/api/plugins/{pluginid}", - "api_resource_instance_lifecycle_state": "/api/resource_instance_lifecycle_state/{resourceid}", - "api_resource_instance_lifecycle_states": "/api/resource_instance_lifecycle", - "api_resource_report": "/api/resource_report/{resourceid}", - "api_search_component_data": "/search_component_data/{componentname}", - "api_tiles": "/api/tiles/{tileid}", - "api_user": "/api/user", - "api_user_incomplete_workflows": "/api/user_incomplete_workflows", - "append_branch": "/graph/{graphid}/append_branch", - "append_node": "/graph/{graphid}/append_node", - "apply_functions": "/graph/{graphid}/apply_functions", - "as_stream_collection": "/history", - "as_stream_page": "/history/{page}", - "auth": "/auth", - "buffer": "/buffer", - "card": "/card/{cardid}", - "change_password": "/auth/password", - "clear_user_permission_cache": "/clear-user-permission-cache", - "clone_graph": "/graph/{graphid}/clone", - "concept": "/concepts/{conceptid}", - "concept_manage_parents": "/concepts/{conceptid}/manage_parents", - "concept_search": "/concepts/search", - "concept_tree": "/concepts/tree/{mode}", - "concept_value": "/conceptvalue", - "concepts": "/rdm/concepts/{conceptid}", - "config": "/settings", - "confirm_delete": "/concepts/{conceptid}/confirm_delete", - "confirm_signup": "/auth/confirm_signup", - "datatype_template": "/components/datatypes/{template}", - "delete_graph": "/graph/{graphid}/delete", - "delete_instances": "/graph/{graphid}/delete_instances", - "delete_node": "/graph/{graphid}/delete_node", - "delete_provisional_tile": "/tiles/delete_provisional_tile", - "delete_published_graph": "/graph/{graphid}/delete_published_graph", - "dismiss_notifications": "/notifications/dismiss", - "download_files": "/tiles/download_files", - "dropdown": "/concepts/dropdown", - "edit_history": "/resource/history", - "etl_manager": "/etl-manager", - "export_branch": "/graph/{graphid}/export_branch", - "export_concept": "/concepts/export/{conceptid}", - "export_concept_collections": "/concepts/export/collections", - "export_graph": "/graph/{graphid}/export", - "export_mapping_file": "/graph/{graphid}/export_mapping_file", - "export_results": "/search/export_results", - "external_oauth_callback": "/auth/eoauth_cb", - "external_oauth_start": "/auth/eoauth_start", - "feature_popup_content": "/feature_popup_content", - "file_access": "/files/{fileid}", - "from_sparql_endpoint": "/concepts/{conceptid}/from_sparql_endpoint", - "function-templates": "/function-templates/{template}", - "function_manager": "/graph/{graphid}/function_manager", - "geojson": "/geojson", - "get_client_id": "/auth/get_client_id", - "get_concept_collections": "/concepts/collections", - "get_dev_token": "/auth/get_dev_token", - "get_domain_connections": "/graph/{graphid}/get_domain_connections", - "get_dsl": "/search/get_dsl", - "get_export_file": "/search/get_export_file", - "get_frontend_i18n_data": "/api/get_frontend_i18n_data", - "get_graph_models_api": "/graphs", - "get_notification_types": "/notifications/get_types", - "get_notifications": "/notifications", - "get_pref_label": "/concepts/get_pref_label", - "get_related_nodes": "/graph/{graphid}/get_related_nodes/{nodeid}", - "get_user_names": "/user/get_user_names", - "get_valid_domain_nodes": "/graph/{graphid}/get_valid_domain_nodes/{nodeid}", - "graph": "/graph/{graphid}", - "graph_designer": "/graph_designer/{graphid}", - "graph_has_unpublished_changes_api": "/graph_has_unpublished_changes/{graph_id}", - "graph_is_active_api": "/graph_is_active/{graph_id}", - "graph_nodes": "/graph/{graphid}/nodes", - "graph_settings": "/graph_settings/{graphid}", - "graphs_api": "/graphs/{graph_id}", - "help_templates": "/help-templates", - "home": "/index.htm", - "icons": "/icons", - "iiifannotationnodes": "/iiifannotationnodes", - "iiifannotations": "/iiifannotations", - "iiifmanifest": "/iiifmanifest", - "images": "/images", - "import_graph": "/graph/import", - "language": "/language", - "make_collection": "/concepts/{conceptid}/make_collection", - "manifest": "/manifest/{id}", - "manifest_manager": "/image-service-manager", - "map_layer_manager": "/map_layer_manager", - "map_layer_update": "/map_layer_manager/{maplayerid}", - "model_history": "/graph/{graphid}/model_history", - "move_node": "/graph/{graphid}/move_node", - "mvt": "/mvt/{nodeid}/{zoom}/{x}/{y}.pbf", - "new_graph": "/graph/new", - "node": "/node/{graphid}", - "node_layer": "/node_layer/{graphid}", - "nodegroup": "/nodegroup", - "ontology_properties": "/ontology_properties", - "paged_dropdown": "/concepts/paged_dropdown", - "password_reset": "/password_reset", - "password_reset_complete": "/reset/done", - "password_reset_confirm": "/reset/{uidb64}/{token}", - "password_reset_done": "/password_reset/done", - "permission_data": "/graph/permissions", - "permission_manager_data": "/graph/permissions/permission_manager_data", - "plugins": "/plugins/{slug}/{path}", - "publish_graph": "/graph/{graphid}/publish", - "rdm": "/rdm/{conceptid}", - "reindex": "/admin/reindex/resources", - "relatable_resources": "/resource/related/relatable", - "related_resource_candidates": "/resource/related/candidates", - "related_resources": "/resource/related/{resourceid}", - "remove_functions": "/graph/{graphid}/remove_functions", - "reorder_cards": "/reorder_cards", - "reorder_nodes": "/graph/reorder_nodes", - "reorder_tiles": "/tiles/reorder_tiles", - "report-templates": "/report-templates/{template}", - "resource": "/resource", - "resource_cards": "/resource/{resourceid}/cards", - "resource_copy": "/resource/{resourceid}/copy", - "resource_data": "/resource/{resourceid}/data/{formid}", - "resource_descriptors": "/resource/descriptors/{resourceid}", - "resource_edit_log": "/resource/{resourceid}/history", - "resource_editor": "/resource/{resourceid}", - "resource_permission_data": "/resource/permissions", - "resource_report": "/report/{resourceid}", - "resource_tiles": "/resource/{resourceid}/tiles", - "resources": "/resources/{resourceid}", - "resources_graphid": "/resources/{graphid}/{resourceid}", - "resources_slug": "/resources/{slug}/{resourceid}", - "restore_state_from_serialized_graph": "/graph/{graphid}/restore_state_from_serialized_graph", - "revert_graph": "/graph/{graphid}/revert", - "root": "/", - "search_home": "/search", - "search_results": "/search/resources", - "search_sparql_endpoint": "/concepts/search_sparql_endpoint", - "search_terms": "/search/terms", - "server_settings": "/auth/server_settings", - "set_language": "/i18n/setlang", - "signup": "/auth/signup", - "spatialview_api": "/api/spatialview/{identifier}", - "temp_file": "/temp_file", - "templates": "/templates/{template}", - "thumbnail": "/thumbnail/{resource_id}", - "tile": "/tile", - "tile_history": "/tiles/tile_history", - "time_wheel_config": "/search/time_wheel_config", - "transaction_reverse": "/transaction/{transactionid}/reverse", - "transform_edtf_for_tile": "/transform-edtf-for-tile", - "two-factor-authentication-login": "/two-factor-authentication-login", - "two-factor-authentication-reset": "/two-factor-authentication-reset", - "two-factor-authentication-settings": "/two-factor-authentication-settings", - "update_node": "/graph/{graphid}/update_node", - "update_notification_types": "/notifications/update_types", - "update_published_graph": "/graph/{graphid}/update_published_graph", - "update_published_graphs": "/graph/{graphid}/update_published_graphs", - "user_profile": "/auth/user_profile", - "user_profile_manager": "/user", - "validate": "/validate/{itemtype}/{itemid}", - "validatejson": "/validate/{itemtype}", - "widgets": "/widgets/{template}", - "workflow_history": "/workflow_history/{workflowid}" -} \ No newline at end of file diff --git a/frontend_configuration/webpack-metadata.json b/frontend_configuration/webpack-metadata.json deleted file mode 100644 index 2a871e4e0ae..00000000000 --- a/frontend_configuration/webpack-metadata.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "_comment": "This is a generated file. Do not edit directly.", - "APP_ROOT": "/Users/christopherbyrd/Projects/arches-lingo/arches/arches/app", - "ARCHES_APPLICATIONS": [], - "ARCHES_APPLICATIONS_PATHS": {}, - "SITE_PACKAGES_DIRECTORY": "/Users/christopherbyrd/Projects/arches-lingo/ENV/lib/python3.12/site-packages", - "PUBLIC_SERVER_ADDRESS": "http://localhost:8000/", - "ROOT_DIR": "/Users/christopherbyrd/Projects/arches-lingo/arches/arches", - "STATIC_URL": "/static/", - "WEBPACK_DEVELOPMENT_SERVER_PORT": 9000 -} \ No newline at end of file From 5d3ddf0beba4953409346b34fc5d5d2a89428597 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 23 Oct 2024 14:11:30 -0700 Subject: [PATCH 07/18] nit #11567 --- arches/install/arches-templates/webpack/webpack.common.js | 5 ++++- webpack/webpack.common.js | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arches/install/arches-templates/webpack/webpack.common.js b/arches/install/arches-templates/webpack/webpack.common.js index fa4a5e69590..79886fcbc22 100644 --- a/arches/install/arches-templates/webpack/webpack.common.js +++ b/arches/install/arches-templates/webpack/webpack.common.js @@ -281,7 +281,10 @@ module.exports = () => { new webpack.DefinePlugin(universalConstants), new webpack.DefinePlugin({ ARCHES_URLS: webpack.DefinePlugin.runtimeValue( - () => fs.readFileSync(Path.resolve(__dirname, APP_ROOT, '..', 'frontend_configuration', 'urls.json'), 'utf-8'), + () => fs.readFileSync( + Path.resolve(__dirname, PROJECT_RELATIVE_NODE_MODULES_PATH, '..', 'frontend_configuration', 'urls.json'), + 'utf-8' + ), true // should be re-evaluated on rebuild ), }), diff --git a/webpack/webpack.common.js b/webpack/webpack.common.js index fa4a5e69590..79886fcbc22 100644 --- a/webpack/webpack.common.js +++ b/webpack/webpack.common.js @@ -281,7 +281,10 @@ module.exports = () => { new webpack.DefinePlugin(universalConstants), new webpack.DefinePlugin({ ARCHES_URLS: webpack.DefinePlugin.runtimeValue( - () => fs.readFileSync(Path.resolve(__dirname, APP_ROOT, '..', 'frontend_configuration', 'urls.json'), 'utf-8'), + () => fs.readFileSync( + Path.resolve(__dirname, PROJECT_RELATIVE_NODE_MODULES_PATH, '..', 'frontend_configuration', 'urls.json'), + 'utf-8' + ), true // should be re-evaluated on rebuild ), }), From 3b72327682a292411613f26dce017e12f7958d9c Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 23 Oct 2024 14:14:02 -0700 Subject: [PATCH 08/18] nit #11567 --- arches/install/arches-templates/vitest.config.mts | 2 +- vitest.config.mts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arches/install/arches-templates/vitest.config.mts b/arches/install/arches-templates/vitest.config.mts index 4dda8725d1a..3ba9be8b2bb 100644 --- a/arches/install/arches-templates/vitest.config.mts +++ b/arches/install/arches-templates/vitest.config.mts @@ -19,7 +19,7 @@ function generateConfig(): Promise { '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*', ]; - const rawData = fs.readFileSync(path.join(__dirname, '.frontend-configuration-settings.json'), 'utf-8'); + const rawData = fs.readFileSync(path.join(__dirname, 'frontend-configuration', 'webpack-metadata.json'), 'utf-8'); const parsedData = JSON.parse(rawData); const alias: { [key: string]: string } = { diff --git a/vitest.config.mts b/vitest.config.mts index 4cf706fa8c1..e707af3b6b8 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -19,7 +19,7 @@ function generateConfig(): Promise { '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*', ]; - const rawData = fs.readFileSync(path.join(__dirname, '.frontend-configuration-settings.json'), 'utf-8'); + const rawData = fs.readFileSync(path.join(__dirname, 'frontend-configuration', 'webpack-metadata.json'), 'utf-8'); const parsedData = JSON.parse(rawData); const alias: { [key: string]: string } = { From ba7215000773dda0fd9cc3c611b26e29bb0e2e3a Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 23 Oct 2024 14:16:54 -0700 Subject: [PATCH 09/18] nit #11567 --- arches/install/arches-templates/vitest.config.mts | 2 +- vitest.config.mts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arches/install/arches-templates/vitest.config.mts b/arches/install/arches-templates/vitest.config.mts index 3ba9be8b2bb..dd171bcf69b 100644 --- a/arches/install/arches-templates/vitest.config.mts +++ b/arches/install/arches-templates/vitest.config.mts @@ -19,7 +19,7 @@ function generateConfig(): Promise { '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*', ]; - const rawData = fs.readFileSync(path.join(__dirname, 'frontend-configuration', 'webpack-metadata.json'), 'utf-8'); + const rawData = fs.readFileSync(path.join(__dirname, 'frontend_configuration', 'webpack-metadata.json'), 'utf-8'); const parsedData = JSON.parse(rawData); const alias: { [key: string]: string } = { diff --git a/vitest.config.mts b/vitest.config.mts index e707af3b6b8..c1e36b0fe1c 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -19,7 +19,7 @@ function generateConfig(): Promise { '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*', ]; - const rawData = fs.readFileSync(path.join(__dirname, 'frontend-configuration', 'webpack-metadata.json'), 'utf-8'); + const rawData = fs.readFileSync(path.join(__dirname, 'frontend_configuration', 'webpack-metadata.json'), 'utf-8'); const parsedData = JSON.parse(rawData); const alias: { [key: string]: string } = { From fbed86e249361b565cee08db12ad22ed1ebe509b Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 23 Oct 2024 14:30:00 -0700 Subject: [PATCH 10/18] nit #11567 --- .../arches/utils/generate-arches-url.test.ts | 43 +++++++++++++++++++ .../src/arches/utils/generate-arches-url.ts | 2 +- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 arches/app/src/arches/utils/generate-arches-url.test.ts diff --git a/arches/app/src/arches/utils/generate-arches-url.test.ts b/arches/app/src/arches/utils/generate-arches-url.test.ts new file mode 100644 index 00000000000..af4a55059da --- /dev/null +++ b/arches/app/src/arches/utils/generate-arches-url.test.ts @@ -0,0 +1,43 @@ +import { describe, it, expect } from "vitest"; +import generateArchesURL from "@/arches/utils/generate-arches-url.ts"; + +// @ts-expect-error ARCHES_URLS is defined globally +global.ARCHES_URLS = { + example_url: "/admin/{language_code}/example/{id}", + another_url: "/admin/another/{id}", +}; + +describe("generateArchesURL", () => { + it("should return a valid URL with language code and parameters", () => { + const result = generateArchesURL("example_url", "fr", { id: "123" }); + expect(result).toBe("/admin/fr/example/123"); + }); + + it("should use the lang attribute when no language code is provided", () => { + Object.defineProperty(document.documentElement, "lang", { + value: "de", + configurable: true, + }); + + const result = generateArchesURL("example_url", null, { id: "123" }); + expect(result).toBe("/admin/de/example/123"); + }); + + it("should throw an error if the URL name is not found", () => { + expect(() => + generateArchesURL("invalid_url", "fr", { id: "123" }), + ).toThrowError("Key 'invalid_url' not found in JSON object"); + }); + + it("should replace URL parameters correctly", () => { + const result = generateArchesURL("another_url", null, { id: "456" }); + expect(result).toBe("/admin/another/456"); + }); + + it("should handle missing language code and parameter placeholders", () => { + const result = generateArchesURL("another_url", "es", { id: "789" }); + + console.log(result); + expect(result).toBe("/admin/another/789"); + }); +}); diff --git a/arches/app/src/arches/utils/generate-arches-url.ts b/arches/app/src/arches/utils/generate-arches-url.ts index 1c5098d8975..a95bd18aed0 100644 --- a/arches/app/src/arches/utils/generate-arches-url.ts +++ b/arches/app/src/arches/utils/generate-arches-url.ts @@ -19,7 +19,7 @@ export default function ( url = url.replace("{language_code}", languageCode); } - Object.entries(urlParams).forEach((key, value) => { + Object.entries(urlParams).forEach(([key, value]) => { url = url.replace(new RegExp(`{${key}}`, "g"), value); }); From 29516bd6d320905e116753e24fc149300760a212 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 23 Oct 2024 14:42:08 -0700 Subject: [PATCH 11/18] nit #11567 --- .../arches/utils/generate-arches-url.test.ts | 37 +++++++++++++------ .../src/arches/utils/generate-arches-url.ts | 2 +- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/arches/app/src/arches/utils/generate-arches-url.test.ts b/arches/app/src/arches/utils/generate-arches-url.test.ts index af4a55059da..68fab4bf889 100644 --- a/arches/app/src/arches/utils/generate-arches-url.test.ts +++ b/arches/app/src/arches/utils/generate-arches-url.test.ts @@ -3,14 +3,16 @@ import generateArchesURL from "@/arches/utils/generate-arches-url.ts"; // @ts-expect-error ARCHES_URLS is defined globally global.ARCHES_URLS = { - example_url: "/admin/{language_code}/example/{id}", + example_url: "/{language_code}/admin/example/{id}", another_url: "/admin/another/{id}", + multi_interpolation_url: + "/{language_code}/resource/{resource_id}/edit/{field_id}/version/{version_id}", }; describe("generateArchesURL", () => { - it("should return a valid URL with language code and parameters", () => { - const result = generateArchesURL("example_url", "fr", { id: "123" }); - expect(result).toBe("/admin/fr/example/123"); + it("should return a valid URL with specified language code and parameters", () => { + const result = generateArchesURL("example_url", { id: "123" }, "fr"); + expect(result).toBe("/fr/admin/example/123"); }); it("should use the lang attribute when no language code is provided", () => { @@ -19,25 +21,36 @@ describe("generateArchesURL", () => { configurable: true, }); - const result = generateArchesURL("example_url", null, { id: "123" }); - expect(result).toBe("/admin/de/example/123"); + const result = generateArchesURL("example_url", { id: "123" }); + expect(result).toBe("/de/admin/example/123"); }); it("should throw an error if the URL name is not found", () => { expect(() => - generateArchesURL("invalid_url", "fr", { id: "123" }), + generateArchesURL("invalid_url", { id: "123" }, "fr"), ).toThrowError("Key 'invalid_url' not found in JSON object"); }); it("should replace URL parameters correctly", () => { - const result = generateArchesURL("another_url", null, { id: "456" }); + const result = generateArchesURL("another_url", { id: "456" }); expect(result).toBe("/admin/another/456"); }); - it("should handle missing language code and parameter placeholders", () => { - const result = generateArchesURL("another_url", "es", { id: "789" }); - - console.log(result); + it("should handle URLs without language code placeholder", () => { + const result = generateArchesURL("another_url", { id: "789" }); expect(result).toBe("/admin/another/789"); }); + + it("should handle multiple interpolations in the URL", () => { + const result = generateArchesURL( + "multi_interpolation_url", + { + resource_id: "42", + field_id: "name", + version_id: "7", + }, + "es", + ); + expect(result).toBe("/es/resource/42/edit/name/version/7"); + }); }); diff --git a/arches/app/src/arches/utils/generate-arches-url.ts b/arches/app/src/arches/utils/generate-arches-url.ts index a95bd18aed0..148272868bc 100644 --- a/arches/app/src/arches/utils/generate-arches-url.ts +++ b/arches/app/src/arches/utils/generate-arches-url.ts @@ -1,7 +1,7 @@ export default function ( urlName: string, - languageCode: string | null = null, urlParams = {}, + languageCode?: string, ) { // @ts-expect-error ARCHES_URLS is defined globally let url = ARCHES_URLS[urlName]; From d1eed5c7b9c2bc0a40d8bc6dbd4d21c0a95fdfae Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Thu, 24 Oct 2024 10:07:37 -0700 Subject: [PATCH 12/18] adds project update path #11567 --- arches/management/commands/updateproject.py | 48 ++++++++++++++++++++- releases/8.0.0.md | 28 ++++++++---- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/arches/management/commands/updateproject.py b/arches/management/commands/updateproject.py index eadff5409d3..1ac119043f7 100644 --- a/arches/management/commands/updateproject.py +++ b/arches/management/commands/updateproject.py @@ -1,5 +1,10 @@ +import os +import shutil + from django.core.management.base import BaseCommand +from arches.app.models.system_settings import settings + class Command(BaseCommand): # pragma: no cover """ @@ -18,4 +23,45 @@ def handle(self, *args, **options): self.stdout.write("Operation aborted.") def update_to_v8(self): - pass + # Removes unnecessary files + self.stdout.write("Removing unnecessary files...") + + for file_to_delete in [ + ".frontend-configuration-settings.json", + ".tsconfig-paths.json", + ]: + if os.path.exists(os.path.join(settings.APP_ROOT, "..", file_to_delete)): + self.stdout.write("Deleting {}".format(file_to_delete)) + os.remove(os.path.join(settings.APP_ROOT, "..", file_to_delete)) + + self.stdout.write("Done!") + + # Updates webpack + self.stdout.write("Creating updated webpack directory...") + + if os.path.isdir(os.path.join(settings.APP_ROOT, "..", "webpack")): + shutil.rmtree( + os.path.join(settings.APP_ROOT, "..", "webpack"), ignore_errors=True + ) + + shutil.copytree( + os.path.join(settings.ROOT_DIR, "install", "arches-templates", "webpack"), + os.path.join(settings.APP_ROOT, "..", "webpack"), + ) + + self.stdout.write("Done!") + + # Replaces tsconfig.json + self.stdout.write("Updating tsconfig.json...") + + if os.path.exists(os.path.join(settings.APP_ROOT, "..", "tsconfig.json")): + os.remove(os.path.join(settings.APP_ROOT, "..", "tsconfig.json")) + + shutil.copy2( + os.path.join( + settings.ROOT_DIR, "install", "arches-templates", "tsconfig.json" + ), + os.path.join(settings.APP_ROOT, "..", "tsconfig.json"), + ) + + self.stdout.write("Done!") diff --git a/releases/8.0.0.md b/releases/8.0.0.md index d8e203ec284..7c908cc753b 100644 --- a/releases/8.0.0.md +++ b/releases/8.0.0.md @@ -21,6 +21,7 @@ Arches 8.0.0 Release Notes - Improve handling of longer model names [#11317](https://github.com/archesproject/arches/issues/11317) - Support more expressive plugin URLs [#11320](https://github.com/archesproject/arches/issues/11320) - Concepts API no longer responds with empty body for error conditions [#11519](https://github.com/archesproject/arches/issues/11519) +- Generates static `urls.json` file for frontend consumption [#11567](https://github.com/archesproject/arches/issues/11567) ### Dependency changes ``` @@ -69,9 +70,9 @@ JavaScript: 1. In settings.py, add the following key to `DATABASES` to [improve indexing performance](https://github.com/archesproject/arches/issues/11382): ``` - "OPTIONS": { - "options": "-c cursor_tuple_fraction=1", - }, + "OPTIONS": { + "options": "-c cursor_tuple_fraction=1", + }, ``` 1. Update your frontend dependencies: @@ -80,21 +81,32 @@ JavaScript: npm install ``` -2. Within your project, with your Python 3 virtual environment activated: +1. Replace the `generate_frontend_configuration` import statement in `apps.py`: + ``` + from arches.settings_utils import generate_frontend_configuration + ``` + + Should be updated to: + + ``` + from arches.app.utils.frontend_configuration_utils import generate_frontend_configuration + ``` + +1. Within your project, with your Python 3 virtual environment activated: ``` python manage.py migrate ``` -3. Create editable_future_graphs for your Resource Models using the command `python manage.py graph create_editable_future_graphs`. This will publish new versions of each Graph. +1. Create editable_future_graphs for your Resource Models using the command `python manage.py graph create_editable_future_graphs`. This will publish new versions of each Graph. -4. Update your Graph publications and Resource instances to point to the newly published Graphs by running `python manage.py graph publish --update -ui` +1. Update your Graph publications and Resource instances to point to the newly published Graphs by running `python manage.py graph publish --update -ui` -5. Within your project with your Python 3 virtual environment activated: +1. Within your project with your Python 3 virtual environment activated: ``` python manage.py es reindex_database ``` -6. Run `npm start` or `npm run build_development` to rebuild your static asset bundle: +1. Run `npm start` or `npm run build_development` to rebuild your static asset bundle: - If running your project in development: - `npm start` will build the frontend of the application and then start a webpack development server - `npm run build_development` will build a development bundle for the frontend assests of the application -- this should complete in less than 2 minutes From 8e9e7cc6a26878d62e10d3d71949f16556b8165a Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Thu, 24 Oct 2024 10:10:12 -0700 Subject: [PATCH 13/18] nit #11567 --- releases/8.0.0.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/releases/8.0.0.md b/releases/8.0.0.md index 7c908cc753b..90ff782a261 100644 --- a/releases/8.0.0.md +++ b/releases/8.0.0.md @@ -81,6 +81,10 @@ JavaScript: npm install ``` +1. Update `.gitignore`: + 1. Remove `.tsconfig-paths.json` and `.frontend-configuration-settings.json` + 2. Add `frontend_configuration` + 1. Replace the `generate_frontend_configuration` import statement in `apps.py`: ``` from arches.settings_utils import generate_frontend_configuration From 0452c6fa7253a09df2078096c66e22f2e1014adf Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Thu, 24 Oct 2024 10:10:52 -0700 Subject: [PATCH 14/18] nit #11567 --- .gitignore | 2 +- arches/install/arches-templates/.gitignore | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 9784ae57cde..227652838cc 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,4 @@ pip-wheel-metadata webpack-stats.json .DS_STORE CACHE -frontend_configuration \ No newline at end of file +frontend_configuration diff --git a/arches/install/arches-templates/.gitignore b/arches/install/arches-templates/.gitignore index 4544ee7d887..89a6e0398d5 100644 --- a/arches/install/arches-templates/.gitignore +++ b/arches/install/arches-templates/.gitignore @@ -15,4 +15,4 @@ webpack-stats.json *.egg-info .DS_STORE CACHE -frontend_configuration \ No newline at end of file +frontend_configuration From 5639958c26b8b215cc61891ad0784a2b2144fd75 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Thu, 24 Oct 2024 10:16:13 -0700 Subject: [PATCH 15/18] nit #11567 --- releases/8.0.0.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/releases/8.0.0.md b/releases/8.0.0.md index 90ff782a261..46c52b5af18 100644 --- a/releases/8.0.0.md +++ b/releases/8.0.0.md @@ -58,6 +58,8 @@ JavaScript: - `ensure_userprofile_exists()` was removed from the `Tile` model. +- The `arches` object is no longer available in frontend components that exist outside of defined Arches patterns. If your project contains Vue components that are mounted on templates that inherit directly from `base-root.htm`, they will need to be updated to use `generateArchesURL` and the settings API instead. + ### Upgrading Arches 1. You must be upgraded to at least version before proceeding. If you are on an earlier version, please refer to the upgrade process in the []() From 2ff2e4074bff58beb8f75f61ce904d1cd320e2da Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Mon, 4 Nov 2024 15:47:50 -0800 Subject: [PATCH 16/18] nit #11567 --- arches/app/utils/frontend_configuration_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/arches/app/utils/frontend_configuration_utils.py b/arches/app/utils/frontend_configuration_utils.py index 810dd90a8e1..2c13b2bed8c 100644 --- a/arches/app/utils/frontend_configuration_utils.py +++ b/arches/app/utils/frontend_configuration_utils.py @@ -124,6 +124,7 @@ def _generate_webpack_configuration(): json.dump( { "_comment": "This is a generated file. Do not edit directly.", + "APP_RELATIVE_PATH": os.path.relpath(app_root_path), "APP_ROOT": app_root_path, "ARCHES_APPLICATIONS": arches_app_names, "ARCHES_APPLICATIONS_PATHS": dict( From 80a48e1fbe44edb109a5e0db60143d05fec825b3 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Mon, 4 Nov 2024 16:16:03 -0800 Subject: [PATCH 17/18] update function to not remove trailing slashes if declared #11567 --- .../app/utils/frontend_configuration_utils.py | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/arches/app/utils/frontend_configuration_utils.py b/arches/app/utils/frontend_configuration_utils.py index 2c13b2bed8c..54fe719971b 100644 --- a/arches/app/utils/frontend_configuration_utils.py +++ b/arches/app/utils/frontend_configuration_utils.py @@ -34,7 +34,21 @@ def _generate_frontend_configuration_directory(): def _generate_urls_json(): def generate_human_readable_urls(patterns, prefix="", namespace="", result={}): def join_paths(*args): - return "/".join(filter(None, (arg.strip("/") for arg in args))) + components = [] + + for index, segment in enumerate(args): + if index == 0: # only strip trailing slash for the first segment + segment = segment.rstrip("/") + elif ( + index == len(args) - 1 + ): # only strip leading slash for the last segment + segment = segment.lstrip("/") + else: # strip both slashes for middle segments + segment = segment.strip("/") + + components.append(segment) + + return "/".join(filter(None, components)) def interpolate_route(pattern): if isinstance(pattern, RoutePattern): @@ -57,7 +71,7 @@ def interpolate_route(pattern): # Remove regex-specific special characters (^, $, +, *, ?, (), etc.) regex = re.sub(r"[\^\$\+\*\?\(\)]", "", regex) - return regex.strip("/") + return regex for pattern in patterns: if isinstance(pattern, URLPattern): @@ -85,7 +99,7 @@ def interpolate_route(pattern): resolver = get_resolver() human_readable_urls = generate_human_readable_urls(resolver.url_patterns) - # manual additions + # Manual additions human_readable_urls["static_url"] = settings.STATIC_URL human_readable_urls["media_url"] = settings.MEDIA_URL From 50f71a0e02a5669464098aba8c4862fee35b3414 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Tue, 5 Nov 2024 13:44:14 -0800 Subject: [PATCH 18/18] nit #11567 --- .../app/utils/frontend_configuration_utils.py | 36 ++++++---- releases/8.0.0.md | 70 ++++++++++--------- 2 files changed, 57 insertions(+), 49 deletions(-) diff --git a/arches/app/utils/frontend_configuration_utils.py b/arches/app/utils/frontend_configuration_utils.py index 54fe719971b..cc9969307b7 100644 --- a/arches/app/utils/frontend_configuration_utils.py +++ b/arches/app/utils/frontend_configuration_utils.py @@ -32,18 +32,18 @@ def _generate_frontend_configuration_directory(): def _generate_urls_json(): - def generate_human_readable_urls(patterns, prefix="", namespace="", result={}): + def generate_human_readable_urls(patterns, prefix="", namespace=""): def join_paths(*args): components = [] for index, segment in enumerate(args): - if index == 0: # only strip trailing slash for the first segment + if index == 0: # Only strip trailing slash for the first segment segment = segment.rstrip("/") elif ( index == len(args) - 1 - ): # only strip leading slash for the last segment + ): # Only strip leading slash for the last segment segment = segment.lstrip("/") - else: # strip both slashes for middle segments + else: # Strip both slashes for middle segments segment = segment.strip("/") components.append(segment) @@ -63,37 +63,43 @@ def interpolate_route(pattern): regex = re.sub(r"\(\?:[^\)]+\)", "", regex) # Remove character sets (e.g., [0-9]) - regex = re.sub(r"\[[^\]]+\]", "", regex) + regex = re.sub(r"\[[^\]]]+\]", "", regex) # Remove backslashes (used to escape special characters in regex) regex = regex.replace("\\", "") - # Remove regex-specific special characters (^, $, +, *, ?, (), etc.) + # Remove regex-specific special characters regex = re.sub(r"[\^\$\+\*\?\(\)]", "", regex) return regex + result = {} + for pattern in patterns: if isinstance(pattern, URLPattern): - if pattern.name: - result[f"{namespace}{pattern.name}"] = "/" + join_paths( - prefix, interpolate_route(pattern.pattern) - ) + url_name = f"{namespace}{pattern.name}" + url_path = "/" + join_paths(prefix, interpolate_route(pattern.pattern)) + result[url_name] = url_path + elif isinstance(pattern, URLResolver): - current_namespace = namespace + ( - f":{pattern.namespace}:" if pattern.namespace else "" + current_namespace = ( + f"{namespace}{pattern.namespace}:" + if pattern.namespace + else namespace ) if isinstance( pattern.pattern, LocalePrefixPattern - ): # handles i18n_patterns + ): # Handles i18n_patterns new_prefix = join_paths(prefix, "{language_code}") else: new_prefix = join_paths(prefix, interpolate_route(pattern.pattern)) - generate_human_readable_urls( - pattern.url_patterns, new_prefix, current_namespace, result + sub_result = generate_human_readable_urls( + pattern.url_patterns, new_prefix, current_namespace ) + result.update(sub_result) + return result resolver = get_resolver() diff --git a/releases/8.0.0.md b/releases/8.0.0.md index 09a6fb6b6b7..9aad932bbdc 100644 --- a/releases/8.0.0.md +++ b/releases/8.0.0.md @@ -62,7 +62,7 @@ JavaScript: - `ensure_userprofile_exists()` was removed from the `Tile` model. -- The `arches` object is no longer available in frontend components that exist outside of defined Arches patterns. If your project contains Vue components that are mounted on templates that inherit directly from `base-root.htm`, they will need to be updated to use `generateArchesURL` and the settings API instead. +- The `arches` object is now only available in frontend components that mounted in templates that inherit `base.htm`. If your project contains Vue components that are mounted on templates that inherit directly from `base-root.htm`, they will need to be updated to use `generateArchesURL` and the settings API instead. ### Upgrading Arches @@ -76,18 +76,15 @@ JavaScript: 1. In settings.py, add the following key to `DATABASES` to [improve indexing performance](https://github.com/archesproject/arches/issues/11382): ``` - "OPTIONS": { - "options": "-c cursor_tuple_fraction=1", - }, + DATABASES = { + "default": { + ... # other entries + "OPTIONS": { + "options": "-c cursor_tuple_fraction=1", + }, + } + } ``` - -1. Update your frontend dependencies: - ``` - rm -rf node_modules package-lock.json - npm install - ``` - -<<<<<<< HEAD 1. Update `.gitignore`: 1. Remove `.tsconfig-paths.json` and `.frontend-configuration-settings.json` 2. Add `frontend_configuration` @@ -104,30 +101,35 @@ JavaScript: ``` 1. Within your project, with your Python 3 virtual environment activated: - ``` - python manage.py migrate - ``` + 1. Migrate your database: + ``` + python manage.py migrate + ``` + + 1. Then update your project: + ``` + python manage.py updateproject + ``` + + 1. Create editable_future_graphs for your Resource Models. This will publish new versions of each Graph. + ``` + python manage.py graph create_editable_future_graphs + ``` + + 1. Update your Graph publications and Resource instances to point to the newly published Graphs: + ``` + python manage.py graph publish --update -ui + ``` + + 1. Then reindex your database + ``` + python manage.py es reindex_database + ``` -1. Create editable_future_graphs for your Resource Models using the command `python manage.py graph create_editable_future_graphs`. This will publish new versions of each Graph. -======= -1. Within your project, with your Python 3 virtual environment activated run: - ``` - python manage.py migrate - ``` - -1. Then run: - ``` - python manage.py updateproject - ``` - -3. Create editable_future_graphs for your Resource Models using the command `python manage.py graph create_editable_future_graphs`. This will publish new versions of each Graph. ->>>>>>> ce9ca42f6d1a1582c472706ed052b3bb34b8dfa9 - -1. Update your Graph publications and Resource instances to point to the newly published Graphs by running `python manage.py graph publish --update -ui` - -1. Within your project with your Python 3 virtual environment activated: +1. Update your frontend dependencies: ``` - python manage.py es reindex_database + rm -rf node_modules package-lock.json + npm install ``` 1. Run `npm start` or `npm run build_development` to rebuild your static asset bundle: