From 0633c1085f7a91a584abad080844a072997026ef Mon Sep 17 00:00:00 2001 From: Berry den Hartog <38954346+berrydenhartog@users.noreply.github.com> Date: Wed, 13 Nov 2024 08:20:15 +0000 Subject: [PATCH] Move project to algorithm --- amt/api/main.py | 6 +- amt/api/navigation.py | 23 +- amt/api/routes/{project.py => algorithm.py} | 342 +++++++++--------- amt/api/routes/{projects.py => algorithms.py} | 48 +-- amt/locale/base.pot | 170 ++++----- amt/locale/en_US/LC_MESSAGES/messages.po | 170 ++++----- amt/locale/nl_NL/LC_MESSAGES/messages.po | 170 ++++----- .../versions/1019b72fe63a_add_last_edited.py | 6 +- .../versions/14240ff670e2_add_lifecycle.py | 6 +- ...ad5b68_add_reference_to_project_in_task.py | 4 +- .../6581a03aabec_add_deleted_at_to_project.py | 6 +- .../7f20f8562007_add_system_card_column.py | 4 +- ...c85_make_model_card_nullable_in_project.py | 6 +- .../versions/c5254dc6083f_add_project.py | 6 +- amt/models/__init__.py | 3 +- amt/models/algorithm.py | 97 +++++ amt/models/project.py | 2 +- amt/models/task.py | 2 +- .../{projects.py => algorithms.py} | 66 ++-- amt/repositories/tasks.py | 10 +- amt/schema/{project.py => algorithm.py} | 4 +- amt/schema/model_card.py | 2 +- amt/services/{projects.py => algorithms.py} | 76 ++-- amt/services/tasks.py | 14 +- .../details_base.html.j2 | 12 +- .../details_data.html.j2 | 2 +- .../details_inference.html.j2 | 2 +- .../details_info.html.j2 | 10 +- .../details_instruments.html.j2 | 2 +- .../details_measure_modal.html.j2 | 2 +- .../details_requirements.html.j2 | 4 +- .../{projects => algorithms}/index.html.j2 | 2 +- .../{projects => algorithms}/new.html.j2 | 4 +- .../{projects => algorithms}/tasks.html.j2 | 6 +- .../macros/algorithm_systems_grid.html.j2 | 10 +- amt/site/templates/macros/table_row.html.j2 | 10 +- amt/site/templates/macros/tasks.html.j2 | 4 +- amt/site/templates/pages/model_card.html.j2 | 2 +- amt/site/templates/pages/system_card.html.j2 | 6 +- ...earch.html.j2 => algorithm_search.html.j2} | 14 +- amt/site/templates/parts/edit_cell.html.j2 | 2 +- amt/site/templates/parts/filter_list.html.j2 | 14 +- amt/site/templates/parts/view_cell.html.j2 | 2 +- .../{test_project.py => test_algorithm.py} | 224 ++++++------ .../{test_projects.py => test_algorithms.py} | 70 ++-- tests/api/test_navigation.py | 10 +- tests/constants.py | 20 +- tests/core/test_exception_handlers.py | 13 +- tests/database_e2e_setup.py | 16 +- ...te_project.py => test_create_algorithm.py} | 20 +- ...ll_project.py => test_scroll_algorithm.py} | 10 +- tests/e2e/test_search_algorithm.py | 80 ++++ tests/e2e/test_search_project.py | 80 ---- tests/middleware/test_authorization.py | 4 +- ...del_project.py => test_model_algorithm.py} | 64 ++-- tests/repositories/test_algorithms.py | 309 ++++++++++++++++ tests/repositories/test_projects.py | 309 ---------------- tests/repositories/test_tasks.py | 12 +- tests/schema/test_schema_ai_act_profile.py | 56 +-- tests/schema/test_schema_algorithm.py | 45 +++ tests/schema/test_schema_project.py | 45 --- tests/services/test_algorithms_service.py | 101 ++++++ tests/services/test_projects_service.py | 101 ------ tests/services/test_tasks_service.py | 32 +- ...ject.py => test_template_new_algorithm.py} | 6 +- 65 files changed, 1549 insertions(+), 1431 deletions(-) rename amt/api/routes/{project.py => algorithm.py} (58%) rename amt/api/routes/{projects.py => algorithms.py} (75%) create mode 100644 amt/models/algorithm.py rename amt/repositories/{projects.py => algorithms.py} (61%) rename amt/schema/{project.py => algorithm.py} (91%) rename amt/services/{projects.py => algorithms.py} (63%) rename amt/site/templates/{projects => algorithms}/details_base.html.j2 (96%) rename amt/site/templates/{projects => algorithms}/details_data.html.j2 (67%) rename amt/site/templates/{projects => algorithms}/details_inference.html.j2 (99%) rename amt/site/templates/{projects => algorithms}/details_info.html.j2 (84%) rename amt/site/templates/{projects => algorithms}/details_instruments.html.j2 (67%) rename amt/site/templates/{projects => algorithms}/details_measure_modal.html.j2 (98%) rename amt/site/templates/{projects => algorithms}/details_requirements.html.j2 (97%) rename amt/site/templates/{projects => algorithms}/index.html.j2 (61%) rename amt/site/templates/{projects => algorithms}/new.html.j2 (99%) rename amt/site/templates/{projects => algorithms}/tasks.html.j2 (78%) rename amt/site/templates/parts/{project_search.html.j2 => algorithm_search.html.j2} (93%) rename tests/api/routes/{test_project.py => test_algorithm.py} (69%) rename tests/api/routes/{test_projects.py => test_algorithms.py} (73%) rename tests/e2e/{test_create_project.py => test_create_algorithm.py} (76%) rename tests/e2e/{test_scroll_project.py => test_scroll_algorithm.py} (63%) create mode 100644 tests/e2e/test_search_algorithm.py delete mode 100644 tests/e2e/test_search_project.py rename tests/models/{test_model_project.py => test_model_algorithm.py} (54%) create mode 100644 tests/repositories/test_algorithms.py delete mode 100644 tests/repositories/test_projects.py create mode 100644 tests/schema/test_schema_algorithm.py delete mode 100644 tests/schema/test_schema_project.py create mode 100644 tests/services/test_algorithms_service.py delete mode 100644 tests/services/test_projects_service.py rename tests/site/static/templates/{test_template_new_project.py => test_template_new_algorithm.py} (57%) diff --git a/amt/api/main.py b/amt/api/main.py index 9b376926..ac72e101 100644 --- a/amt/api/main.py +++ b/amt/api/main.py @@ -1,11 +1,11 @@ from fastapi import APIRouter -from amt.api.routes import auth, health, pages, project, projects, root +from amt.api.routes import algorithm, algorithms, auth, health, pages, root api_router = APIRouter() api_router.include_router(root.router) api_router.include_router(health.router, prefix="/health", tags=["health"]) api_router.include_router(pages.router, prefix="/pages", tags=["pages"]) -api_router.include_router(projects.router, prefix="/algorithm-systems", tags=["algorithm-systems"]) -api_router.include_router(project.router, prefix="/algorithm-system", tags=["algorithm-system"]) +api_router.include_router(algorithms.router, prefix="/algorithm-systems", tags=["algorithm-systems"]) +algorithmapi_router.include_router(algorithm.router, prefix="/algorithm-system", tags=["algorithm-system"]) api_router.include_router(auth.router, prefix="/auth", tags=["auth"]) diff --git a/amt/api/navigation.py b/amt/api/navigation.py index c1df2acf..7256b769 100644 --- a/amt/api/navigation.py +++ b/amt/api/navigation.py @@ -95,39 +95,40 @@ class Navigation: ) PROJECTS_OVERVIEW = BaseNavigationItem(display_text=DisplayText.OVERVIEW, url="/algorithm-systems/") PROJECT_TASKS = BaseNavigationItem( - display_text=DisplayText.TASKS, url="/algorithm-system/{project_id}/details/tasks" + display_text=DisplayText.TASKS, url="/algorithm-system/{algorithm_id}/details/tasks" ) PROJECT_DETAILS = BaseNavigationItem( - display_text=DisplayText.DETAILS, url="/algorithm-system/{project_id}/details/system_card" + display_text=DisplayText.DETAILS, url="/algorithm-system/{algorithm_id}/details/system_card" ) PROJECT_MODEL = BaseNavigationItem( - display_text=DisplayText.MODEL, url="/algorithm-system/{project_id}/details/model/inference" + display_text=DisplayText.MODEL, url="/algorithm-system/{algorithm_id}/details/model/inference" ) PROJECT_NEW = BaseNavigationItem(display_text=DisplayText.NEW, url="/algorithm-systems/new") PROJECT_SYSTEM_INFO = BaseNavigationItem( - display_text=DisplayText.INFO, url="/algorithm-system/{project_id}/details" + display_text=DisplayText.INFO, url="/algorithm-system/{algorithm_id}/details" ) PROJECT_SYSTEM_ALGORITHM_DETAILS = BaseNavigationItem( - display_text=DisplayText.ALGORITHM_DETAILS, url="/algorithm-system/{project_id}/details/system_card" + display_text=DisplayText.ALGORITHM_DETAILS, url="/algorithm-system/{algorithm_id}/details/system_card" ) PROJECT_SYSTEM_CARD = BaseNavigationItem( - display_text=DisplayText.SYSTEMCARD, url="/algorithm-system/{project_id}/details/system_card" + display_text=DisplayText.SYSTEMCARD, url="/algorithm-system/{algorithm_id}/details/system_card" ) PROJECT_DATA_CARD = BaseNavigationItem( - display_text=DisplayText.DATA, url="/algorithm-system/{project_id}/details/system_card/data" + display_text=DisplayText.DATA, url="/algorithm-system/{algorithm_id}/details/system_card/data" ) PROJECT_MODEL_CARD = BaseNavigationItem( - display_text=DisplayText.MODELCARD, url="/algorithm-system/{project_id}/details/system_card/models/{model_card}" + display_text=DisplayText.MODELCARD, + url="/algorithm-system/{algorithm_id}/details/system_card/models/{model_card}", ) PROJECT_ASSESSMENT_CARD = BaseNavigationItem( display_text=DisplayText.ASSESSMENTCARD, - url="/algorithm-system/{project_id}/details/system_card/assessment/{assessment_card}", + url="/algorithm-system/{algorithm_id}/details/system_card/assessment/{assessment_card}", ) PROJECT_REQUIREMENTS = BaseNavigationItem( - display_text=DisplayText.REQUIREMENTS, url="/algorithm-system/{project_id}/details/system_card/requirements" + display_text=DisplayText.REQUIREMENTS, url="/algorithm-system/{algorithm_id}/details/system_card/requirements" ) PROJECT_SYSTEM_INSTRUMENTS = BaseNavigationItem( - display_text=DisplayText.INSTRUMENTS, url="/algorithm-system/{project_id}/details/system_card/instruments" + display_text=DisplayText.INSTRUMENTS, url="/algorithm-system/{algorithm_id}/details/system_card/instruments" ) diff --git a/amt/api/routes/project.py b/amt/api/routes/algorithm.py similarity index 58% rename from amt/api/routes/project.py rename to amt/api/routes/algorithm.py index 580677b2..ad0b5d62 100644 --- a/amt/api/routes/project.py +++ b/amt/api/routes/algorithm.py @@ -17,15 +17,15 @@ ) from amt.core.exceptions import AMTNotFound, AMTRepositoryError from amt.enums.status import Status -from amt.models import Project +from amt.models import Algorithm from amt.models.task import Task from amt.schema.measure import ExtendedMeasureTask, MeasureTask from amt.schema.requirement import RequirementTask from amt.schema.system_card import SystemCard from amt.schema.task import MovedTask from amt.services import task_registry +from amt.services.algorithms import AlgorithmsService from amt.services.instruments_and_requirements_state import InstrumentStateService, RequirementsStateService -from amt.services.projects import ProjectsService from amt.services.task_registry import fetch_measures, fetch_requirements from amt.services.tasks import TasksService @@ -55,17 +55,19 @@ def get_requirements_state(system_card: SystemCard) -> dict[str, Any]: } -async def get_project_or_error(project_id: int, projects_service: ProjectsService, request: Request) -> Project: +async def get_algorithm_or_error( + algorithm_id: int, algorithms_service: AlgorithmsService, request: Request +) -> Algorithm: try: - logger.debug(f"getting project with id {project_id}") - project = await projects_service.get(project_id) - request.state.path_variables = {"project_id": project_id} + logger.debug(f"getting algorithm with id {algorithm_id}") + algorithm = await algorithms_service.get(algorithm_id) + request.state.path_variables = {"algorithm_id": algorithm_id} except AMTRepositoryError as e: raise AMTNotFound from e - return project + return algorithm -def get_project_details_tabs(request: Request) -> list[NavigationItem]: +def get_algorithm_details_tabs(request: Request) -> list[NavigationItem]: return resolve_navigation_items( [ Navigation.PROJECT_SYSTEM_INFO, @@ -80,7 +82,7 @@ def get_project_details_tabs(request: Request) -> list[NavigationItem]: ) -def get_projects_submenu_items() -> list[BaseNavigationItem]: +def get_algorithms_submenu_items() -> list[BaseNavigationItem]: return [ Navigation.PROJECTS_OVERVIEW, Navigation.PROJECT_TASKS, @@ -88,32 +90,32 @@ def get_projects_submenu_items() -> list[BaseNavigationItem]: ] -async def gather_project_tasks(project_id: int, task_service: TasksService) -> dict[Status, Sequence[Task]]: - fetch_tasks = [task_service.get_tasks_for_project(project_id, status + 0) for status in Status] +async def gather_algorithm_tasks(algorithm_id: int, task_service: TasksService) -> dict[Status, Sequence[Task]]: + fetch_tasks = [task_service.get_tasks_for_algorithm(algorithm_id, status + 0) for status in Status] results = await asyncio.gather(*fetch_tasks) return dict(zip(Status, results, strict=True)) -@router.get("/{project_id}/details/tasks") +@router.get("/{algorithm_id}/details/tasks") async def get_tasks( request: Request, - project_id: int, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithm_id: int, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], tasks_service: Annotated[TasksService, Depends(TasksService)], ) -> HTMLResponse: - project = await get_project_or_error(project_id, projects_service, request) - instrument_state = get_instrument_state(project.system_card) - requirements_state = get_requirements_state(project.system_card) - tab_items = get_project_details_tabs(request) - tasks_by_status = await gather_project_tasks(project_id, task_service=tasks_service) + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) + instrument_state = get_instrument_state(algorithm.system_card) + requirements_state = get_requirements_state(algorithm.system_card) + tab_items = get_algorithm_details_tabs(request) + tasks_by_status = await gather_algorithm_tasks(algorithm_id, task_service=tasks_service) breadcrumbs = resolve_base_navigation_items( [ Navigation.PROJECTS_ROOT, BaseNavigationItem( - custom_display_text=project.name, url="/algorithm-system/{project_id}/details/system_card" + custom_display_text=algorithm.name, url="/algorithm-system/{algorithm_id}/details/system_card" ), Navigation.PROJECT_TASKS, ], @@ -125,13 +127,13 @@ async def get_tasks( "requirements_state": requirements_state, "tasks_by_status": tasks_by_status, "statuses": Status, - "project": project, - "project_id": project.id, + "algorithm": algorithm, + "algorithm_id": algorithm.id, "breadcrumbs": breadcrumbs, "tab_items": tab_items, } - return templates.TemplateResponse(request, "projects/tasks.html.j2", context) + return templates.TemplateResponse(request, "algorithms/tasks.html.j2", context) @router.patch("/move_task") @@ -164,35 +166,35 @@ async def move_task( return templates.TemplateResponse(request, "parts/task.html.j2", context=context) -async def get_project_context( - project_id: int, projects_service: ProjectsService, request: Request -) -> tuple[Project, dict[str, Any]]: - project = await get_project_or_error(project_id, projects_service, request) - instrument_state = get_instrument_state(project.system_card) - requirements_state = get_requirements_state(project.system_card) - tab_items = get_project_details_tabs(request) - return project, { - "last_edited": project.last_edited, - "system_card": project.system_card, +async def get_algorithm_context( + algorithm_id: int, algorithms_service: AlgorithmsService, request: Request +) -> tuple[Algorithm, dict[str, Any]]: + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) + instrument_state = get_instrument_state(algorithm.system_card) + requirements_state = get_requirements_state(algorithm.system_card) + tab_items = get_algorithm_details_tabs(request) + return algorithm, { + "last_edited": algorithm.last_edited, + "system_card": algorithm.system_card, "instrument_state": instrument_state, "requirements_state": requirements_state, - "project": project, - "project_id": project.id, + "algorithm": algorithm, + "algorithm_id": algorithm.id, "tab_items": tab_items, } -@router.get("/{project_id}/details") -async def get_project_details( - request: Request, project_id: int, projects_service: Annotated[ProjectsService, Depends(ProjectsService)] +@router.get("/{algorithm_id}/details") +async def get_algorithm_details( + request: Request, algorithm_id: int, algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)] ) -> HTMLResponse: - project, context = await get_project_context(project_id, projects_service, request) + algorithm, context = await get_algorithm_context(algorithm_id, algorithms_service, request) breadcrumbs = resolve_base_navigation_items( [ Navigation.PROJECTS_ROOT, BaseNavigationItem( - custom_display_text=project.name, url="/algorithm-system/{project_id}/details/system_card" + custom_display_text=algorithm.name, url="/algorithm-system/{algorithm_id}/details/system_card" ), Navigation.PROJECT_DETAILS, ], @@ -201,29 +203,29 @@ async def get_project_details( context["breadcrumbs"] = breadcrumbs - return templates.TemplateResponse(request, "projects/details_info.html.j2", context) + return templates.TemplateResponse(request, "algorithms/details_info.html.j2", context) -@router.get("/{project_id}/edit/{path:path}") -async def get_project_edit( +@router.get("/{algorithm_id}/edit/{path:path}") +async def get_algorithm_edit( request: Request, - project_id: int, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithm_id: int, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], path: str, ) -> HTMLResponse: - _, context = await get_project_context(project_id, projects_service, request) + _, context = await get_algorithm_context(algorithm_id, algorithms_service, request) context["path"] = path.replace("/", ".") return templates.TemplateResponse(request, "parts/edit_cell.html.j2", context) -@router.get("/{project_id}/cancel/{path:path}") -async def get_project_cancel( +@router.get("/{algorithm_id}/cancel/{path:path}") +async def get_algorithm_cancel( request: Request, - project_id: int, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithm_id: int, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], path: str, ) -> HTMLResponse: - _, context = await get_project_context(project_id, projects_service, request) + _, context = await get_algorithm_context(algorithm_id, algorithms_service, request) context["path"] = path.replace("/", ".") return templates.TemplateResponse(request, "parts/view_cell.html.j2", context) @@ -232,12 +234,12 @@ class UpdateFieldModel(BaseModel): value: str -def set_path(project: dict[str, Any] | object, path: str, value: str) -> None: +def set_path(algorithm: dict[str, Any] | object, path: str, value: str) -> None: if not path: raise ValueError("Path cannot be empty") attrs = path.lstrip("/").split("/") - obj: Any = project + obj: Any = algorithm for attr in attrs[:-1]: if isinstance(obj, dict): obj = cast(dict[str, Any], obj) @@ -255,38 +257,38 @@ def set_path(project: dict[str, Any] | object, path: str, value: str) -> None: setattr(obj, attrs[-1], value) -@router.put("/{project_id}/update/{path:path}") -async def get_project_update( +@router.put("/{algorithm_id}/update/{path:path}") +async def get_algorithm_update( request: Request, - project_id: int, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithm_id: int, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], update_data: UpdateFieldModel, path: str, ) -> HTMLResponse: - project, context = await get_project_context(project_id, projects_service, request) - set_path(project, path, update_data.value) - await projects_service.update(project) + algorithm, context = await get_algorithm_context(algorithm_id, algorithms_service, request) + set_path(algorithm, path, update_data.value) + await algorithms_service.update(algorithm) context["path"] = path.replace("/", ".") return templates.TemplateResponse(request, "parts/view_cell.html.j2", context) -@router.get("/{project_id}/details/system_card") +@router.get("/{algorithm_id}/details/system_card") async def get_system_card( request: Request, - project_id: int, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithm_id: int, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], ) -> HTMLResponse: - project = await get_project_or_error(project_id, projects_service, request) - instrument_state = get_instrument_state(project.system_card) - requirements_state = get_requirements_state(project.system_card) + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) + instrument_state = get_instrument_state(algorithm.system_card) + requirements_state = get_requirements_state(algorithm.system_card) - tab_items = get_project_details_tabs(request) + tab_items = get_algorithm_details_tabs(request) breadcrumbs = resolve_base_navigation_items( [ Navigation.PROJECTS_ROOT, BaseNavigationItem( - custom_display_text=project.name, url="/algorithm-system/{project_id}/details/system_card" + custom_display_text=algorithm.name, url="/algorithm-system/{algorithm_id}/details/system_card" ), Navigation.PROJECT_SYSTEM_CARD, ], @@ -294,12 +296,12 @@ async def get_system_card( ) context = { - "system_card": project.system_card, + "system_card": algorithm.system_card, "instrument_state": instrument_state, "requirements_state": requirements_state, - "last_edited": project.last_edited, - "project": project, - "project_id": project.id, + "last_edited": algorithm.last_edited, + "algorithm": algorithm, + "algorithm_id": algorithm.id, "tab_items": tab_items, "breadcrumbs": breadcrumbs, } @@ -307,65 +309,65 @@ async def get_system_card( return templates.TemplateResponse(request, "pages/system_card.html.j2", context) -@router.get("/{project_id}/details/model/inference") -async def get_project_inference( - request: Request, project_id: int, projects_service: Annotated[ProjectsService, Depends(ProjectsService)] +@router.get("/{algorithm_id}/details/model/inference") +async def get_algorithm_inference( + request: Request, algorithm_id: int, algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)] ) -> HTMLResponse: - project = await get_project_or_error(project_id, projects_service, request) + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) breadcrumbs = resolve_base_navigation_items( [ Navigation.PROJECTS_ROOT, BaseNavigationItem( - custom_display_text=project.name, url="/algorithm-system/{project_id}/details/model/inference" + custom_display_text=algorithm.name, url="/algorithm-system/{algorithm_id}/details/model/inference" ), Navigation.PROJECT_MODEL, ], request, ) - instrument_state = get_instrument_state(project.system_card) - requirements_state = get_requirements_state(project.system_card) + instrument_state = get_instrument_state(algorithm.system_card) + requirements_state = get_requirements_state(algorithm.system_card) - tab_items = get_project_details_tabs(request) + tab_items = get_algorithm_details_tabs(request) context = { - "last_edited": project.last_edited, - "system_card": project.system_card, + "last_edited": algorithm.last_edited, + "system_card": algorithm.system_card, "instrument_state": instrument_state, "requirements_state": requirements_state, - "project": project, - "project_id": project.id, + "algorithm": algorithm, + "algorithm_id": algorithm.id, "breadcrumbs": breadcrumbs, "tab_items": tab_items, } - return templates.TemplateResponse(request, "projects/details_inference.html.j2", context) + return templates.TemplateResponse(request, "algorithms/details_inference.html.j2", context) -@router.get("/{project_id}/details/system_card/requirements") +@router.get("/{algorithm_id}/details/system_card/requirements") async def get_system_card_requirements( request: Request, - project_id: int, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithm_id: int, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], ) -> HTMLResponse: - project = await get_project_or_error(project_id, projects_service, request) - instrument_state = get_instrument_state(project.system_card) - requirements_state = get_requirements_state(project.system_card) - tab_items = get_project_details_tabs(request) + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) + instrument_state = get_instrument_state(algorithm.system_card) + requirements_state = get_requirements_state(algorithm.system_card) + tab_items = get_algorithm_details_tabs(request) breadcrumbs = resolve_base_navigation_items( [ Navigation.PROJECTS_ROOT, BaseNavigationItem( - custom_display_text=project.name, url="/algorithm-system/{project_id}/details/system_card" + custom_display_text=algorithm.name, url="/algorithm-system/{algorithm_id}/details/system_card" ), Navigation.PROJECT_SYSTEM_CARD, ], request, ) - requirements = fetch_requirements([requirement.urn for requirement in project.system_card.requirements]) + requirements = fetch_requirements([requirement.urn for requirement in algorithm.system_card.requirements]) # Get measures that correspond to the requirements and merge them with the measuretasks requirements_and_measures = [] @@ -374,7 +376,7 @@ async def get_system_card_requirements( linked_measures = fetch_measures(requirement.links) extended_linked_measures: list[ExtendedMeasureTask] = [] for measure in linked_measures: - measure_task = find_measure_task(project.system_card, measure.urn) + measure_task = find_measure_task(algorithm.system_card, measure.urn) if measure_task: ext_measure_task = ExtendedMeasureTask( name=measure.name, @@ -392,14 +394,14 @@ async def get_system_card_requirements( context = { "instrument_state": instrument_state, "requirements_state": requirements_state, - "project": project, - "project_id": project.id, + "algorithm": algorithm, + "algorithm_id": algorithm.id, "tab_items": tab_items, "breadcrumbs": breadcrumbs, "requirements_and_measures": requirements_and_measures, } - return templates.TemplateResponse(request, "projects/details_requirements.html.j2", context) + return templates.TemplateResponse(request, "algorithms/details_requirements.html.j2", context) def find_measure_task(system_card: SystemCard, urn: str) -> MeasureTask | None: @@ -431,35 +433,35 @@ def find_requirement_tasks_by_measure_urn(system_card: SystemCard, measure_urn: return requirement_tasks -@router.delete("/{project_id}") -async def delete_project( +@router.delete("/{algorithm_id}") +async def delete_algorithm( request: Request, - project_id: int, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithm_id: int, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], ) -> HTMLResponse: - await projects_service.delete(project_id) + await algorithms_service.delete(algorithm_id) return templates.Redirect(request, "/algorithm-systems/") -@router.get("/{project_id}/measure/{measure_urn}") +@router.get("/{algorithm_id}/measure/{measure_urn}") async def get_measure( request: Request, - project_id: int, + algorithm_id: int, measure_urn: str, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], ) -> HTMLResponse: - project = await get_project_or_error(project_id, projects_service, request) + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) measure = task_registry.fetch_measures([measure_urn]) - measure_task = find_measure_task(project.system_card, measure_urn) + measure_task = find_measure_task(algorithm.system_card, measure_urn) context = { "measure": measure[0], "measure_state": measure_task.state, # pyright: ignore [reportOptionalMemberAccess] "measure_value": measure_task.value, # pyright: ignore [reportOptionalMemberAccess] - "project_id": project_id, + "algorithm_id": algorithm_id, } - return templates.TemplateResponse(request, "projects/details_measure_modal.html.j2", context) + return templates.TemplateResponse(request, "algorithms/details_measure_modal.html.j2", context) class MeasureUpdate(BaseModel): @@ -467,33 +469,33 @@ class MeasureUpdate(BaseModel): measure_value: str = Field(default=None) -@router.post("/{project_id}/measure/{measure_urn}") +@router.post("/{algorithm_id}/measure/{measure_urn}") async def update_measure_value( request: Request, - project_id: int, + algorithm_id: int, measure_urn: str, measure_update: MeasureUpdate, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], ) -> HTMLResponse: - project = await get_project_or_error(project_id, projects_service, request) + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) - measure_task = find_measure_task(project.system_card, measure_urn) + measure_task = find_measure_task(algorithm.system_card, measure_urn) measure_task.state = measure_update.measure_state # pyright: ignore [reportOptionalMemberAccess] measure_task.value = measure_update.measure_value # pyright: ignore [reportOptionalMemberAccess] # update for the linked requirements the state based on all it's measures - requirement_tasks = find_requirement_tasks_by_measure_urn(project.system_card, measure_urn) + requirement_tasks = find_requirement_tasks_by_measure_urn(algorithm.system_card, measure_urn) requirement_urns = [requirement_task.urn for requirement_task in requirement_tasks] requirements = fetch_requirements(requirement_urns) for requirement in requirements: count_completed = 0 for link_measure_urn in requirement.links: - link_measure_task = find_measure_task(project.system_card, link_measure_urn) + link_measure_task = find_measure_task(algorithm.system_card, link_measure_urn) if link_measure_task: # noqa: SIM102 if link_measure_task.state == "done": count_completed += 1 - requirement_task = find_requirement_task(project.system_card, requirement.urn) + requirement_task = find_requirement_task(algorithm.system_card, requirement.urn) if count_completed == len(requirement.links): requirement_task.state = "done" # pyright: ignore [reportOptionalMemberAccess] elif count_completed == 0 and len(requirement.links) > 0: @@ -501,33 +503,33 @@ async def update_measure_value( else: requirement_task.state = "in progress" # pyright: ignore [reportOptionalMemberAccess] - await projects_service.update(project) + await algorithms_service.update(algorithm) # TODO: FIX THIS!! The page now reloads at the top, which is annoying - return templates.Redirect(request, f"/algorithm-system/{project_id}/details/system_card/requirements") + return templates.Redirect(request, f"/algorithm-system/{algorithm_id}/details/system_card/requirements") # !!! -# Implementation of this endpoint is for now independent of the project ID, meaning -# that the same system card is rendered for all project ID's. This is due to the fact +# Implementation of this endpoint is for now independent of the algorithm ID, meaning +# that the same system card is rendered for all algorithm ID's. This is due to the fact # that the logical process flow of a system card is not complete. # !!! -@router.get("/{project_id}/details/system_card/data") +@router.get("/{algorithm_id}/details/system_card/data") async def get_system_card_data_page( request: Request, - project_id: int, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithm_id: int, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], ) -> HTMLResponse: - project = await get_project_or_error(project_id, projects_service, request) - instrument_state = get_instrument_state(project.system_card) - requirements_state = get_requirements_state(project.system_card) + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) + instrument_state = get_instrument_state(algorithm.system_card) + requirements_state = get_requirements_state(algorithm.system_card) - tab_items = get_project_details_tabs(request) + tab_items = get_algorithm_details_tabs(request) breadcrumbs = resolve_base_navigation_items( [ Navigation.PROJECTS_ROOT, BaseNavigationItem( - custom_display_text=project.name, url="/algorithm-system/{project_id}/details/system_card" + custom_display_text=algorithm.name, url="/algorithm-system/{algorithm_id}/details/system_card" ), Navigation.PROJECT_SYSTEM_CARD, ], @@ -537,37 +539,37 @@ async def get_system_card_data_page( context = { "instrument_state": instrument_state, "requirements_state": requirements_state, - "project": project, - "project_id": project.id, + "algorithm": algorithm, + "algorithm_id": algorithm.id, "tab_items": tab_items, "breadcrumbs": breadcrumbs, } - return templates.TemplateResponse(request, "projects/details_data.html.j2", context) + return templates.TemplateResponse(request, "algorithms/details_data.html.j2", context) # !!! -# Implementation of this endpoint is for now independent of the project ID, meaning -# that the same system card is rendered for all project ID's. This is due to the fact +# Implementation of this endpoint is for now independent of the algorithm ID, meaning +# that the same system card is rendered for all algorithm ID's. This is due to the fact # that the logical process flow of a system card is not complete. # !!! -@router.get("/{project_id}/details/system_card/instruments") +@router.get("/{algorithm_id}/details/system_card/instruments") async def get_system_card_instruments( request: Request, - project_id: int, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithm_id: int, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], ) -> HTMLResponse: - project = await get_project_or_error(project_id, projects_service, request) - instrument_state = get_instrument_state(project.system_card) - requirements_state = get_requirements_state(project.system_card) + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) + instrument_state = get_instrument_state(algorithm.system_card) + requirements_state = get_requirements_state(algorithm.system_card) - tab_items = get_project_details_tabs(request) + tab_items = get_algorithm_details_tabs(request) breadcrumbs = resolve_base_navigation_items( [ Navigation.PROJECTS_ROOT, BaseNavigationItem( - custom_display_text=project.name, url="/algorithm-system/{project_id}/details/system_card" + custom_display_text=algorithm.name, url="/algorithm-system/{algorithm_id}/details/system_card" ), Navigation.PROJECT_SYSTEM_CARD, ], @@ -577,35 +579,35 @@ async def get_system_card_instruments( context = { "instrument_state": instrument_state, "requirements_state": requirements_state, - "project": project, - "project_id": project.id, + "algorithm": algorithm, + "algorithm_id": algorithm.id, "tab_items": tab_items, "breadcrumbs": breadcrumbs, } - return templates.TemplateResponse(request, "projects/details_instruments.html.j2", context) + return templates.TemplateResponse(request, "algorithms/details_instruments.html.j2", context) -@router.get("/{project_id}/details/system_card/assessments/{assessment_card}") +@router.get("/{algorithm_id}/details/system_card/assessments/{assessment_card}") async def get_assessment_card( request: Request, - project_id: int, + algorithm_id: int, assessment_card: str, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], ) -> HTMLResponse: - project = await get_project_or_error(project_id, projects_service, request) - instrument_state = get_instrument_state(project.system_card) - requirements_state = get_requirements_state(project.system_card) + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) + instrument_state = get_instrument_state(algorithm.system_card) + requirements_state = get_requirements_state(algorithm.system_card) request.state.path_variables.update({"assessment_card": assessment_card}) - sub_menu_items = resolve_navigation_items(get_projects_submenu_items(), request, False) + sub_menu_items = resolve_navigation_items(get_algorithms_submenu_items(), request, False) breadcrumbs = resolve_base_navigation_items( [ Navigation.PROJECTS_ROOT, BaseNavigationItem( - custom_display_text=project.name, url="/algorithm-system/{project_id}/details/system_card" + custom_display_text=algorithm.name, url="/algorithm-system/{algorithm_id}/details/system_card" ), Navigation.PROJECT_ASSESSMENT_CARD, ], @@ -613,7 +615,7 @@ async def get_assessment_card( ) assessment_card_data = next( - (assessment for assessment in project.system_card.assessments if assessment.name.lower() == assessment_card), + (assessment for assessment in algorithm.system_card.assessments if assessment.name.lower() == assessment_card), None, ) @@ -625,7 +627,7 @@ async def get_assessment_card( "instrument_state": instrument_state, "requirements_state": requirements_state, "assessment_card": assessment_card_data, - "last_edited": project.last_edited, + "last_edited": algorithm.last_edited, "sub_menu_items": sub_menu_items, "breadcrumbs": breadcrumbs, } @@ -634,29 +636,29 @@ async def get_assessment_card( # !!! -# Implementation of this endpoint is for now independent of the project ID, meaning -# that the same system card is rendered for all project ID's. This is due to the fact +# Implementation of this endpoint is for now independent of the algorithm ID, meaning +# that the same system card is rendered for all algorithm ID's. This is due to the fact # that the logical process flow of a system card is not complete. # !!! -@router.get("/{project_id}/details/system_card/models/{model_card}") +@router.get("/{algorithm_id}/details/system_card/models/{model_card}") async def get_model_card( request: Request, - project_id: int, + algorithm_id: int, model_card: str, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], ) -> HTMLResponse: - project = await get_project_or_error(project_id, projects_service, request) + algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request) request.state.path_variables.update({"model_card": model_card}) - instrument_state = get_instrument_state(project.system_card) - requirements_state = get_requirements_state(project.system_card) + instrument_state = get_instrument_state(algorithm.system_card) + requirements_state = get_requirements_state(algorithm.system_card) - tab_items = get_project_details_tabs(request) + tab_items = get_algorithm_details_tabs(request) breadcrumbs = resolve_base_navigation_items( [ Navigation.PROJECTS_ROOT, BaseNavigationItem( - custom_display_text=project.name, url="/algorithm-system/{project_id}/details/system_card" + custom_display_text=algorithm.name, url="/algorithm-system/{algorithm_id}/details/system_card" ), Navigation.PROJECT_MODEL_CARD, ], @@ -666,7 +668,7 @@ async def get_model_card( model_card_data = next( ( model - for model in project.system_card.models + for model in algorithm.system_card.models if (model.name is not None and model.name.lower() == model_card) ), None, @@ -680,10 +682,10 @@ async def get_model_card( "instrument_state": instrument_state, "requirements_state": requirements_state, "model_card": model_card_data, - "last_edited": project.last_edited, + "last_edited": algorithm.last_edited, "breadcrumbs": breadcrumbs, - "project": project, - "project_id": project.id, + "algorithm": algorithm, + "algorithm_id": algorithm.id, "tab_items": tab_items, } diff --git a/amt/api/routes/projects.py b/amt/api/routes/algorithms.py similarity index 75% rename from amt/api/routes/projects.py rename to amt/api/routes/algorithms.py index cb9d45e9..77febf08 100644 --- a/amt/api/routes/projects.py +++ b/amt/api/routes/algorithms.py @@ -14,11 +14,11 @@ get_localized_publication_categories, get_localized_publication_category, ) -from amt.models import Project +from amt.models import Algorithm +from amt.schema.algorithm import AlgorithmNew from amt.schema.localized_value_item import LocalizedValueItem -from amt.schema.project import ProjectNew +from amt.services.algorithms import AlgorithmsService, get_template_files from amt.services.instruments import InstrumentsService -from amt.services.projects import ProjectsService, get_template_files router = APIRouter() logger = logging.getLogger(__name__) @@ -42,7 +42,7 @@ def get_localized_value(key: str, value: str, request: Request) -> LocalizedValu @router.get("/") async def get_root( request: Request, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], skip: int = Query(0, ge=0), limit: int = Query(5000, ge=1), # todo: fix infinite scroll search: str = Query(""), @@ -67,29 +67,31 @@ async def get_root( amount_algorithm_systems: int = 0 if display_type == "LIFECYCLE": - projects: dict[str, list[Project]] = {} + algorithms: dict[str, list[Algorithm]] = {} # When the lifecycle filter is active, only show these algorithm systems if "lifecycle" in filters: for lifecycle in Lifecycles: - projects[lifecycle.name] = [] - projects[filters["lifecycle"]] = await projects_service.paginate( + algorithms[lifecycle.name] = [] + algorithms[filters["lifecycle"]] = await algorithms_service.paginate( skip=skip, limit=limit, search=search, filters=filters, sort=sort_by ) - amount_algorithm_systems += len(projects[filters["lifecycle"]]) + amount_algorithm_systems += len(algorithms[filters["lifecycle"]]) else: for lifecycle in Lifecycles: filters["lifecycle"] = lifecycle.name - projects[lifecycle.name] = await projects_service.paginate( + algorithms[lifecycle.name] = await algorithms_service.paginate( skip=skip, limit=limit, search=search, filters=filters, sort=sort_by ) - amount_algorithm_systems += len(projects[lifecycle.name]) + amount_algorithm_systems += len(algorithms[lifecycle.name]) else: - projects = await projects_service.paginate(skip=skip, limit=limit, search=search, filters=filters, sort=sort_by) # pyright: ignore [reportAssignmentType] - # todo: the lifecycle has to be 'localized', maybe for display 'Project' should become a different object - for project in projects: - project.lifecycle = get_localized_lifecycle(project.lifecycle, request) # pyright: ignore [reportAttributeAccessIssue, reportUnknownMemberType, reportUnknownArgumentType] - amount_algorithm_systems += len(projects) + algorithms = await algorithms_service.paginate( + skip=skip, limit=limit, search=search, filters=filters, sort=sort_by + ) # pyright: ignore [reportAssignmentType] + # todo: the lifecycle has to be 'localized', maybe for display 'Algorithm' should become a different object + for algorithm in algorithms: + algorithm.lifecycle = get_localized_lifecycle(algorithm.lifecycle, request) # pyright: ignore [reportAttributeAccessIssue, reportUnknownMemberType, reportUnknownArgumentType] + amount_algorithm_systems += len(algorithms) next = skip + limit sub_menu_items = resolve_navigation_items([Navigation.PROJECTS_OVERVIEW], request) # pyright: ignore [reportUnusedVariable] # noqa @@ -98,7 +100,7 @@ async def get_root( context: dict[str, Any] = { "breadcrumbs": breadcrumbs, "sub_menu_items": {}, # sub_menu_items disabled for now - "projects": projects, + "algorithms": algorithms, "amount_algorithm_systems": amount_algorithm_systems, "next": next, "limit": limit, @@ -113,11 +115,11 @@ async def get_root( } if request.state.htmx and drop_filters: - return templates.TemplateResponse(request, "parts/project_search.html.j2", context) + return templates.TemplateResponse(request, "parts/algorithm_search.html.j2", context) elif request.state.htmx: return templates.TemplateResponse(request, "parts/filter_list.html.j2", context) else: - return templates.TemplateResponse(request, "projects/index.html.j2", context) + return templates.TemplateResponse(request, "algorithms/index.html.j2", context) @router.get("/new") @@ -141,16 +143,16 @@ async def get_new( "template_files": template_files, } - response = templates.TemplateResponse(request, "projects/new.html.j2", context) + response = templates.TemplateResponse(request, "algorithms/new.html.j2", context) return response @router.post("/new", response_class=HTMLResponse) async def post_new( request: Request, - project_new: ProjectNew, - projects_service: Annotated[ProjectsService, Depends(ProjectsService)], + algorithm_new: AlgorithmNew, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], ) -> HTMLResponse: - project = await projects_service.create(project_new) - response = templates.Redirect(request, f"/algorithm-system/{project.id}/details/tasks") + algorithm = await algorithms_service.create(algorithm_new) + response = templates.Redirect(request, f"/algorithm-system/{algorithm.id}/details/tasks") return response diff --git a/amt/locale/base.pot b/amt/locale/base.pot index 82c1a952..419f6518 100644 --- a/amt/locale/base.pot +++ b/amt/locale/base.pot @@ -1,12 +1,12 @@ # Translations template for PROJECT. # Copyright (C) 2024 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. +# This file is distributed under the same license as the PROJECT algorithm. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: PROJECT VERSION\n" +"Algorithm-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 0001-01-01 00:00+0000\n" "PO-Revision-Date: 0001-01-01 00:00+0000\n" @@ -43,9 +43,9 @@ msgstr "" #: amt/api/group_by_category.py:15 #: amt/site/templates/parts/filter_list.html.j2:94 -#: amt/site/templates/parts/project_search.html.j2:49 -#: amt/site/templates/projects/details_info.html.j2:24 -#: amt/site/templates/projects/new.html.j2:40 +#: amt/site/templates/parts/algorithm_search.html.j2:49 +#: amt/site/templates/algorithms/details_info.html.j2:24 +#: amt/site/templates/algorithms/new.html.j2:40 msgid "Lifecycle" msgstr "" @@ -141,7 +141,7 @@ msgstr "" msgid "Model" msgstr "" -#: amt/api/navigation.py:59 amt/site/templates/projects/new.html.j2:149 +#: amt/api/navigation.py:59 amt/site/templates/algorithms/new.html.j2:149 msgid "Instruments" msgstr "" @@ -238,7 +238,7 @@ msgid "Edit image" msgstr "" #: amt/site/templates/auth/profile.html.j2:34 -#: amt/site/templates/projects/details_info.html.j2:8 +#: amt/site/templates/algorithms/details_info.html.j2:8 msgid "Name" msgstr "" @@ -293,17 +293,17 @@ msgstr "" #: amt/site/templates/macros/editable.html.j2:24 #: amt/site/templates/macros/editable.html.j2:27 -#: amt/site/templates/projects/details_requirements.html.j2:55 +#: amt/site/templates/algorithms/details_requirements.html.j2:55 msgid "Edit" msgstr "" #: amt/site/templates/macros/editable.html.j2:63 -#: amt/site/templates/projects/details_measure_modal.html.j2:84 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:84 msgid "Save" msgstr "" #: amt/site/templates/macros/editable.html.j2:68 -#: amt/site/templates/projects/details_measure_modal.html.j2:88 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:88 msgid "Cancel" msgstr "" @@ -324,10 +324,10 @@ msgid "Reviewing" msgstr "" #: amt/site/templates/macros/tasks.html.j2:32 -#: amt/site/templates/projects/details_base.html.j2:74 -#: amt/site/templates/projects/details_base.html.j2:100 -#: amt/site/templates/projects/details_base.html.j2:129 -#: amt/site/templates/projects/details_base.html.j2:152 +#: amt/site/templates/algorithms/details_base.html.j2:74 +#: amt/site/templates/algorithms/details_base.html.j2:100 +#: amt/site/templates/algorithms/details_base.html.j2:129 +#: amt/site/templates/algorithms/details_base.html.j2:152 msgid "Done" msgstr "" @@ -340,7 +340,7 @@ msgstr "" #: amt/site/templates/pages/system_card.html.j2:4 #: amt/site/templates/parts/filter_list.html.j2:98 #: amt/site/templates/parts/filter_list.html.j2:120 -#: amt/site/templates/projects/details_info.html.j2:28 +#: amt/site/templates/algorithms/details_info.html.j2:28 msgid "Last updated" msgstr "" @@ -463,243 +463,243 @@ msgid "" " open manner." msgstr "" -#: amt/site/templates/parts/project_search.html.j2:9 +#: amt/site/templates/parts/algorithm_search.html.j2:9 msgid "Algorithm Systems" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:15 +#: amt/site/templates/parts/algorithm_search.html.j2:15 msgid "New algorithm system" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:25 +#: amt/site/templates/parts/algorithm_search.html.j2:25 msgid "Search" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:32 +#: amt/site/templates/parts/algorithm_search.html.j2:32 msgid "Find algorithm system..." msgstr "" -#: amt/site/templates/parts/project_search.html.j2:54 +#: amt/site/templates/parts/algorithm_search.html.j2:54 msgid "Select lifecycle" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:63 +#: amt/site/templates/parts/algorithm_search.html.j2:63 msgid "Category" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:68 +#: amt/site/templates/parts/algorithm_search.html.j2:68 msgid "Select publication category" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:86 +#: amt/site/templates/parts/algorithm_search.html.j2:86 msgid "Group by" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:96 +#: amt/site/templates/parts/algorithm_search.html.j2:96 msgid "Select group by" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:19 +#: amt/site/templates/algorithms/details_base.html.j2:19 msgid "Delete algoritmic system" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:26 +#: amt/site/templates/algorithms/details_base.html.j2:26 msgid "Are you sure you want to delete your algoritmic system " msgstr "" -#: amt/site/templates/projects/details_base.html.j2:30 +#: amt/site/templates/algorithms/details_base.html.j2:30 msgid "" "Data will be stored for at least 45 days before permanent\n" " deletion." msgstr "" -#: amt/site/templates/projects/details_base.html.j2:39 -#: amt/site/templates/projects/new.html.j2:132 +#: amt/site/templates/algorithms/details_base.html.j2:39 +#: amt/site/templates/algorithms/new.html.j2:132 msgid "Yes" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:44 -#: amt/site/templates/projects/new.html.j2:142 +#: amt/site/templates/algorithms/details_base.html.j2:44 +#: amt/site/templates/algorithms/new.html.j2:142 msgid "No" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:57 +#: amt/site/templates/algorithms/details_base.html.j2:57 msgid "Delete algorithm system" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:71 +#: amt/site/templates/algorithms/details_base.html.j2:71 msgid "Does the algorithm meet the requirements?" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:96 -#: amt/site/templates/projects/details_base.html.j2:150 +#: amt/site/templates/algorithms/details_base.html.j2:96 +#: amt/site/templates/algorithms/details_base.html.j2:150 msgid "To do" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:98 +#: amt/site/templates/algorithms/details_base.html.j2:98 msgid "In progress" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:115 +#: amt/site/templates/algorithms/details_base.html.j2:115 msgid "Go to all requirements" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:126 +#: amt/site/templates/algorithms/details_base.html.j2:126 msgid "Which instruments are executed?" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:167 +#: amt/site/templates/algorithms/details_base.html.j2:167 msgid "Go to all instruments" msgstr "" -#: amt/site/templates/projects/details_data.html.j2:3 -#: amt/site/templates/projects/details_instruments.html.j2:3 +#: amt/site/templates/algorithms/details_data.html.j2:3 +#: amt/site/templates/algorithms/details_instruments.html.j2:3 msgid "To be implemented" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:7 +#: amt/site/templates/algorithms/details_inference.html.j2:7 msgid "Floor area (m²):" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:16 +#: amt/site/templates/algorithms/details_inference.html.j2:16 msgid "Plot size (m²):" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:25 +#: amt/site/templates/algorithms/details_inference.html.j2:25 msgid "Building year:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:34 +#: amt/site/templates/algorithms/details_inference.html.j2:34 msgid "Object type:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:43 +#: amt/site/templates/algorithms/details_inference.html.j2:43 msgid "Number of annexes:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:52 +#: amt/site/templates/algorithms/details_inference.html.j2:52 msgid "Neighborhood code:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:61 +#: amt/site/templates/algorithms/details_inference.html.j2:61 msgid "Quality rating:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:73 +#: amt/site/templates/algorithms/details_inference.html.j2:73 msgid "Maintenance rating:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:85 +#: amt/site/templates/algorithms/details_inference.html.j2:85 msgid "Amenities rating:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:97 +#: amt/site/templates/algorithms/details_inference.html.j2:97 msgid "Location rating:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:113 +#: amt/site/templates/algorithms/details_inference.html.j2:113 msgid "Estimate WOZ Value" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:117 +#: amt/site/templates/algorithms/details_inference.html.j2:117 msgid "Estimated WOZ Value" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:119 +#: amt/site/templates/algorithms/details_inference.html.j2:119 msgid "Undefined" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:175 +#: amt/site/templates/algorithms/details_inference.html.j2:175 msgid "Failed to estimate WOZ value: " msgstr "" -#: amt/site/templates/projects/details_info.html.j2:12 -#: amt/site/templates/projects/details_measure_modal.html.j2:19 +#: amt/site/templates/algorithms/details_info.html.j2:12 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:19 msgid "Description" msgstr "" -#: amt/site/templates/projects/details_info.html.j2:16 +#: amt/site/templates/algorithms/details_info.html.j2:16 msgid "Repository" msgstr "" -#: amt/site/templates/projects/details_info.html.j2:20 +#: amt/site/templates/algorithms/details_info.html.j2:20 msgid "Algorithm system code" msgstr "" -#: amt/site/templates/projects/details_info.html.j2:32 +#: amt/site/templates/algorithms/details_info.html.j2:32 msgid "Labels" msgstr "" -#: amt/site/templates/projects/details_info.html.j2:40 +#: amt/site/templates/algorithms/details_info.html.j2:40 msgid "References" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:29 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:29 msgid "Read more on the algoritmekader" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:38 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:38 msgid "Status" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:45 -#: amt/site/templates/projects/details_measure_modal.html.j2:47 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:45 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:47 msgid "to do" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:50 -#: amt/site/templates/projects/details_measure_modal.html.j2:52 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:50 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:52 msgid "in progress" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:55 -#: amt/site/templates/projects/details_measure_modal.html.j2:57 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:55 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:57 msgid "done" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:68 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:68 msgid "Information on how this measure is implemented" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:74 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:74 msgid "" "Describe how the measure has been implemented, including challenges and " "solutions." msgstr "" -#: amt/site/templates/projects/details_requirements.html.j2:26 +#: amt/site/templates/algorithms/details_requirements.html.j2:26 msgid "measures executed" msgstr "" -#: amt/site/templates/projects/new.html.j2:7 +#: amt/site/templates/algorithms/new.html.j2:7 msgid "Create a Algorithm System" msgstr "" -#: amt/site/templates/projects/new.html.j2:25 +#: amt/site/templates/algorithms/new.html.j2:25 msgid "Algorithm System name" msgstr "" -#: amt/site/templates/projects/new.html.j2:29 +#: amt/site/templates/algorithms/new.html.j2:29 msgid "Name of the algorithm system" msgstr "" -#: amt/site/templates/projects/new.html.j2:43 +#: amt/site/templates/algorithms/new.html.j2:43 msgid "Select the lifecycle your algorithm system is currently in." msgstr "" -#: amt/site/templates/projects/new.html.j2:44 +#: amt/site/templates/algorithms/new.html.j2:44 msgid "For more information on lifecycle, read the" msgstr "" -#: amt/site/templates/projects/new.html.j2:47 +#: amt/site/templates/algorithms/new.html.j2:47 msgid "Algorithm Framework" msgstr "" -#: amt/site/templates/projects/new.html.j2:65 +#: amt/site/templates/algorithms/new.html.j2:65 msgid "AI Act Profile" msgstr "" -#: amt/site/templates/projects/new.html.j2:67 +#: amt/site/templates/algorithms/new.html.j2:67 msgid "" "The AI Act profile provides insight into, among other things, the type of" " AI system and the associated obligations from the European AI Act. If " @@ -708,25 +708,25 @@ msgid "" "tree." msgstr "" -#: amt/site/templates/projects/new.html.j2:74 +#: amt/site/templates/algorithms/new.html.j2:74 msgid "Find your AI Act profile" msgstr "" -#: amt/site/templates/projects/new.html.j2:151 +#: amt/site/templates/algorithms/new.html.j2:151 msgid "" "Overview of instruments for the responsible development, deployment, " "assessment and monitoring of algorithms and AI-systems." msgstr "" -#: amt/site/templates/projects/new.html.j2:159 +#: amt/site/templates/algorithms/new.html.j2:159 msgid "Choose one or more instruments" msgstr "" -#: amt/site/templates/projects/new.html.j2:183 +#: amt/site/templates/algorithms/new.html.j2:183 msgid "Create Algorithm System" msgstr "" -#: amt/site/templates/projects/new.html.j2:200 +#: amt/site/templates/algorithms/new.html.j2:200 msgid "Copy results and close" msgstr "" diff --git a/amt/locale/en_US/LC_MESSAGES/messages.po b/amt/locale/en_US/LC_MESSAGES/messages.po index 05324725..5e990248 100644 --- a/amt/locale/en_US/LC_MESSAGES/messages.po +++ b/amt/locale/en_US/LC_MESSAGES/messages.po @@ -1,11 +1,11 @@ # English (United States) translations for PROJECT. # Copyright (C) 2024 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. +# This file is distributed under the same license as the PROJECT algorithm. # FIRST AUTHOR , 2024. # msgid "" msgstr "" -"Project-Id-Version: PROJECT VERSION\n" +"Algorithm-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 0001-01-01 00:00+0000\n" "PO-Revision-Date: 0001-01-01 00:00+0000\n" @@ -44,9 +44,9 @@ msgstr "" #: amt/api/group_by_category.py:15 #: amt/site/templates/parts/filter_list.html.j2:94 -#: amt/site/templates/parts/project_search.html.j2:49 -#: amt/site/templates/projects/details_info.html.j2:24 -#: amt/site/templates/projects/new.html.j2:40 +#: amt/site/templates/parts/algorithm_search.html.j2:49 +#: amt/site/templates/algorithms/details_info.html.j2:24 +#: amt/site/templates/algorithms/new.html.j2:40 msgid "Lifecycle" msgstr "" @@ -142,7 +142,7 @@ msgstr "" msgid "Model" msgstr "" -#: amt/api/navigation.py:59 amt/site/templates/projects/new.html.j2:149 +#: amt/api/navigation.py:59 amt/site/templates/algorithms/new.html.j2:149 msgid "Instruments" msgstr "" @@ -239,7 +239,7 @@ msgid "Edit image" msgstr "" #: amt/site/templates/auth/profile.html.j2:34 -#: amt/site/templates/projects/details_info.html.j2:8 +#: amt/site/templates/algorithms/details_info.html.j2:8 msgid "Name" msgstr "" @@ -294,17 +294,17 @@ msgstr "" #: amt/site/templates/macros/editable.html.j2:24 #: amt/site/templates/macros/editable.html.j2:27 -#: amt/site/templates/projects/details_requirements.html.j2:55 +#: amt/site/templates/algorithms/details_requirements.html.j2:55 msgid "Edit" msgstr "" #: amt/site/templates/macros/editable.html.j2:63 -#: amt/site/templates/projects/details_measure_modal.html.j2:84 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:84 msgid "Save" msgstr "" #: amt/site/templates/macros/editable.html.j2:68 -#: amt/site/templates/projects/details_measure_modal.html.j2:88 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:88 msgid "Cancel" msgstr "" @@ -325,10 +325,10 @@ msgid "Reviewing" msgstr "" #: amt/site/templates/macros/tasks.html.j2:32 -#: amt/site/templates/projects/details_base.html.j2:74 -#: amt/site/templates/projects/details_base.html.j2:100 -#: amt/site/templates/projects/details_base.html.j2:129 -#: amt/site/templates/projects/details_base.html.j2:152 +#: amt/site/templates/algorithms/details_base.html.j2:74 +#: amt/site/templates/algorithms/details_base.html.j2:100 +#: amt/site/templates/algorithms/details_base.html.j2:129 +#: amt/site/templates/algorithms/details_base.html.j2:152 msgid "Done" msgstr "" @@ -341,7 +341,7 @@ msgstr "" #: amt/site/templates/pages/system_card.html.j2:4 #: amt/site/templates/parts/filter_list.html.j2:98 #: amt/site/templates/parts/filter_list.html.j2:120 -#: amt/site/templates/projects/details_info.html.j2:28 +#: amt/site/templates/algorithms/details_info.html.j2:28 msgid "Last updated" msgstr "" @@ -464,243 +464,243 @@ msgid "" " open manner." msgstr "" -#: amt/site/templates/parts/project_search.html.j2:9 +#: amt/site/templates/parts/algorithm_search.html.j2:9 msgid "Algorithm Systems" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:15 +#: amt/site/templates/parts/algorithm_search.html.j2:15 msgid "New algorithm system" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:25 +#: amt/site/templates/parts/algorithm_search.html.j2:25 msgid "Search" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:32 +#: amt/site/templates/parts/algorithm_search.html.j2:32 msgid "Find algorithm system..." msgstr "" -#: amt/site/templates/parts/project_search.html.j2:54 +#: amt/site/templates/parts/algorithm_search.html.j2:54 msgid "Select lifecycle" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:63 +#: amt/site/templates/parts/algorithm_search.html.j2:63 msgid "Category" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:68 +#: amt/site/templates/parts/algorithm_search.html.j2:68 msgid "Select publication category" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:86 +#: amt/site/templates/parts/algorithm_search.html.j2:86 msgid "Group by" msgstr "" -#: amt/site/templates/parts/project_search.html.j2:96 +#: amt/site/templates/parts/algorithm_search.html.j2:96 msgid "Select group by" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:19 +#: amt/site/templates/algorithms/details_base.html.j2:19 msgid "Delete algoritmic system" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:26 +#: amt/site/templates/algorithms/details_base.html.j2:26 msgid "Are you sure you want to delete your algoritmic system " msgstr "" -#: amt/site/templates/projects/details_base.html.j2:30 +#: amt/site/templates/algorithms/details_base.html.j2:30 msgid "" "Data will be stored for at least 45 days before permanent\n" " deletion." msgstr "" -#: amt/site/templates/projects/details_base.html.j2:39 -#: amt/site/templates/projects/new.html.j2:132 +#: amt/site/templates/algorithms/details_base.html.j2:39 +#: amt/site/templates/algorithms/new.html.j2:132 msgid "Yes" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:44 -#: amt/site/templates/projects/new.html.j2:142 +#: amt/site/templates/algorithms/details_base.html.j2:44 +#: amt/site/templates/algorithms/new.html.j2:142 msgid "No" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:57 +#: amt/site/templates/algorithms/details_base.html.j2:57 msgid "Delete algorithm system" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:71 +#: amt/site/templates/algorithms/details_base.html.j2:71 msgid "Does the algorithm meet the requirements?" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:96 -#: amt/site/templates/projects/details_base.html.j2:150 +#: amt/site/templates/algorithms/details_base.html.j2:96 +#: amt/site/templates/algorithms/details_base.html.j2:150 msgid "To do" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:98 +#: amt/site/templates/algorithms/details_base.html.j2:98 msgid "In progress" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:115 +#: amt/site/templates/algorithms/details_base.html.j2:115 msgid "Go to all requirements" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:126 +#: amt/site/templates/algorithms/details_base.html.j2:126 msgid "Which instruments are executed?" msgstr "" -#: amt/site/templates/projects/details_base.html.j2:167 +#: amt/site/templates/algorithms/details_base.html.j2:167 msgid "Go to all instruments" msgstr "" -#: amt/site/templates/projects/details_data.html.j2:3 -#: amt/site/templates/projects/details_instruments.html.j2:3 +#: amt/site/templates/algorithms/details_data.html.j2:3 +#: amt/site/templates/algorithms/details_instruments.html.j2:3 msgid "To be implemented" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:7 +#: amt/site/templates/algorithms/details_inference.html.j2:7 msgid "Floor area (m²):" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:16 +#: amt/site/templates/algorithms/details_inference.html.j2:16 msgid "Plot size (m²):" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:25 +#: amt/site/templates/algorithms/details_inference.html.j2:25 msgid "Building year:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:34 +#: amt/site/templates/algorithms/details_inference.html.j2:34 msgid "Object type:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:43 +#: amt/site/templates/algorithms/details_inference.html.j2:43 msgid "Number of annexes:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:52 +#: amt/site/templates/algorithms/details_inference.html.j2:52 msgid "Neighborhood code:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:61 +#: amt/site/templates/algorithms/details_inference.html.j2:61 msgid "Quality rating:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:73 +#: amt/site/templates/algorithms/details_inference.html.j2:73 msgid "Maintenance rating:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:85 +#: amt/site/templates/algorithms/details_inference.html.j2:85 msgid "Amenities rating:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:97 +#: amt/site/templates/algorithms/details_inference.html.j2:97 msgid "Location rating:" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:113 +#: amt/site/templates/algorithms/details_inference.html.j2:113 msgid "Estimate WOZ Value" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:117 +#: amt/site/templates/algorithms/details_inference.html.j2:117 msgid "Estimated WOZ Value" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:119 +#: amt/site/templates/algorithms/details_inference.html.j2:119 msgid "Undefined" msgstr "" -#: amt/site/templates/projects/details_inference.html.j2:175 +#: amt/site/templates/algorithms/details_inference.html.j2:175 msgid "Failed to estimate WOZ value: " msgstr "" -#: amt/site/templates/projects/details_info.html.j2:12 -#: amt/site/templates/projects/details_measure_modal.html.j2:19 +#: amt/site/templates/algorithms/details_info.html.j2:12 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:19 msgid "Description" msgstr "" -#: amt/site/templates/projects/details_info.html.j2:16 +#: amt/site/templates/algorithms/details_info.html.j2:16 msgid "Repository" msgstr "" -#: amt/site/templates/projects/details_info.html.j2:20 +#: amt/site/templates/algorithms/details_info.html.j2:20 msgid "Algorithm system code" msgstr "" -#: amt/site/templates/projects/details_info.html.j2:32 +#: amt/site/templates/algorithms/details_info.html.j2:32 msgid "Labels" msgstr "" -#: amt/site/templates/projects/details_info.html.j2:40 +#: amt/site/templates/algorithms/details_info.html.j2:40 msgid "References" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:29 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:29 msgid "Read more on the algoritmekader" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:38 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:38 msgid "Status" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:45 -#: amt/site/templates/projects/details_measure_modal.html.j2:47 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:45 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:47 msgid "to do" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:50 -#: amt/site/templates/projects/details_measure_modal.html.j2:52 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:50 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:52 msgid "in progress" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:55 -#: amt/site/templates/projects/details_measure_modal.html.j2:57 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:55 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:57 msgid "done" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:68 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:68 msgid "Information on how this measure is implemented" msgstr "" -#: amt/site/templates/projects/details_measure_modal.html.j2:74 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:74 msgid "" "Describe how the measure has been implemented, including challenges and " "solutions." msgstr "" -#: amt/site/templates/projects/details_requirements.html.j2:26 +#: amt/site/templates/algorithms/details_requirements.html.j2:26 msgid "measures executed" msgstr "" -#: amt/site/templates/projects/new.html.j2:7 +#: amt/site/templates/algorithms/new.html.j2:7 msgid "Create a Algorithm System" msgstr "" -#: amt/site/templates/projects/new.html.j2:25 +#: amt/site/templates/algorithms/new.html.j2:25 msgid "Algorithm System name" msgstr "" -#: amt/site/templates/projects/new.html.j2:29 +#: amt/site/templates/algorithms/new.html.j2:29 msgid "Name of the algorithm system" msgstr "" -#: amt/site/templates/projects/new.html.j2:43 +#: amt/site/templates/algorithms/new.html.j2:43 msgid "Select the lifecycle your algorithm system is currently in." msgstr "" -#: amt/site/templates/projects/new.html.j2:44 +#: amt/site/templates/algorithms/new.html.j2:44 msgid "For more information on lifecycle, read the" msgstr "" -#: amt/site/templates/projects/new.html.j2:47 +#: amt/site/templates/algorithms/new.html.j2:47 msgid "Algorithm Framework" msgstr "" -#: amt/site/templates/projects/new.html.j2:65 +#: amt/site/templates/algorithms/new.html.j2:65 msgid "AI Act Profile" msgstr "" -#: amt/site/templates/projects/new.html.j2:67 +#: amt/site/templates/algorithms/new.html.j2:67 msgid "" "The AI Act profile provides insight into, among other things, the type of" " AI system and the associated obligations from the European AI Act. If " @@ -709,25 +709,25 @@ msgid "" "tree." msgstr "" -#: amt/site/templates/projects/new.html.j2:74 +#: amt/site/templates/algorithms/new.html.j2:74 msgid "Find your AI Act profile" msgstr "" -#: amt/site/templates/projects/new.html.j2:151 +#: amt/site/templates/algorithms/new.html.j2:151 msgid "" "Overview of instruments for the responsible development, deployment, " "assessment and monitoring of algorithms and AI-systems." msgstr "" -#: amt/site/templates/projects/new.html.j2:159 +#: amt/site/templates/algorithms/new.html.j2:159 msgid "Choose one or more instruments" msgstr "" -#: amt/site/templates/projects/new.html.j2:183 +#: amt/site/templates/algorithms/new.html.j2:183 msgid "Create Algorithm System" msgstr "" -#: amt/site/templates/projects/new.html.j2:200 +#: amt/site/templates/algorithms/new.html.j2:200 msgid "Copy results and close" msgstr "" diff --git a/amt/locale/nl_NL/LC_MESSAGES/messages.po b/amt/locale/nl_NL/LC_MESSAGES/messages.po index faef836e..92eaa83f 100644 --- a/amt/locale/nl_NL/LC_MESSAGES/messages.po +++ b/amt/locale/nl_NL/LC_MESSAGES/messages.po @@ -1,11 +1,11 @@ # Dutch (Netherlands) translations for PROJECT. # Copyright (C) 2024 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. +# This file is distributed under the same license as the PROJECT algorithm. # FIRST AUTHOR , 2024. # msgid "" msgstr "" -"Project-Id-Version: PROJECT VERSION\n" +"Algorithm-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 0001-01-01 00:00+0000\n" "PO-Revision-Date: 0001-01-01 00:00+0000\n" @@ -44,9 +44,9 @@ msgstr "Rol" #: amt/api/group_by_category.py:15 #: amt/site/templates/parts/filter_list.html.j2:94 -#: amt/site/templates/parts/project_search.html.j2:49 -#: amt/site/templates/projects/details_info.html.j2:24 -#: amt/site/templates/projects/new.html.j2:40 +#: amt/site/templates/parts/algorithm_search.html.j2:49 +#: amt/site/templates/algorithms/details_info.html.j2:24 +#: amt/site/templates/algorithms/new.html.j2:40 msgid "Lifecycle" msgstr "Levenscyclus" @@ -142,7 +142,7 @@ msgstr "Data" msgid "Model" msgstr "Model" -#: amt/api/navigation.py:59 amt/site/templates/projects/new.html.j2:149 +#: amt/api/navigation.py:59 amt/site/templates/algorithms/new.html.j2:149 msgid "Instruments" msgstr "Instrumenten" @@ -247,7 +247,7 @@ msgid "Edit image" msgstr "Afbeelding aanpassen" #: amt/site/templates/auth/profile.html.j2:34 -#: amt/site/templates/projects/details_info.html.j2:8 +#: amt/site/templates/algorithms/details_info.html.j2:8 msgid "Name" msgstr "Naam" @@ -302,17 +302,17 @@ msgstr "Algoritme Management Toolkit (AMT)" #: amt/site/templates/macros/editable.html.j2:24 #: amt/site/templates/macros/editable.html.j2:27 -#: amt/site/templates/projects/details_requirements.html.j2:55 +#: amt/site/templates/algorithms/details_requirements.html.j2:55 msgid "Edit" msgstr "Bewerk" #: amt/site/templates/macros/editable.html.j2:63 -#: amt/site/templates/projects/details_measure_modal.html.j2:84 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:84 msgid "Save" msgstr "Opslaan" #: amt/site/templates/macros/editable.html.j2:68 -#: amt/site/templates/projects/details_measure_modal.html.j2:88 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:88 msgid "Cancel" msgstr "Annuleren" @@ -333,10 +333,10 @@ msgid "Reviewing" msgstr "Beoordelen" #: amt/site/templates/macros/tasks.html.j2:32 -#: amt/site/templates/projects/details_base.html.j2:74 -#: amt/site/templates/projects/details_base.html.j2:100 -#: amt/site/templates/projects/details_base.html.j2:129 -#: amt/site/templates/projects/details_base.html.j2:152 +#: amt/site/templates/algorithms/details_base.html.j2:74 +#: amt/site/templates/algorithms/details_base.html.j2:100 +#: amt/site/templates/algorithms/details_base.html.j2:129 +#: amt/site/templates/algorithms/details_base.html.j2:152 msgid "Done" msgstr "Afgerond" @@ -349,7 +349,7 @@ msgstr "Onbekend" #: amt/site/templates/pages/system_card.html.j2:4 #: amt/site/templates/parts/filter_list.html.j2:98 #: amt/site/templates/parts/filter_list.html.j2:120 -#: amt/site/templates/projects/details_info.html.j2:28 +#: amt/site/templates/algorithms/details_info.html.j2:28 msgid "Last updated" msgstr "Laatst bijgewerkt" @@ -488,51 +488,51 @@ msgid "" " open manner." msgstr "Deze website is in ontwikkeling. Alle versies ontstaan op een open manier." -#: amt/site/templates/parts/project_search.html.j2:9 +#: amt/site/templates/parts/algorithm_search.html.j2:9 msgid "Algorithm Systems" msgstr "Algoritmesystemen" -#: amt/site/templates/parts/project_search.html.j2:15 +#: amt/site/templates/parts/algorithm_search.html.j2:15 msgid "New algorithm system" msgstr "Nieuw algoritmesysteem" -#: amt/site/templates/parts/project_search.html.j2:25 +#: amt/site/templates/parts/algorithm_search.html.j2:25 msgid "Search" msgstr "Zoek" -#: amt/site/templates/parts/project_search.html.j2:32 +#: amt/site/templates/parts/algorithm_search.html.j2:32 msgid "Find algorithm system..." msgstr "Vind algoritmesysteem..." -#: amt/site/templates/parts/project_search.html.j2:54 +#: amt/site/templates/parts/algorithm_search.html.j2:54 msgid "Select lifecycle" msgstr "Selecteer levenscyclus" -#: amt/site/templates/parts/project_search.html.j2:63 +#: amt/site/templates/parts/algorithm_search.html.j2:63 msgid "Category" msgstr "Categorie" -#: amt/site/templates/parts/project_search.html.j2:68 +#: amt/site/templates/parts/algorithm_search.html.j2:68 msgid "Select publication category" msgstr "Selecteer publicatiecategorie" -#: amt/site/templates/parts/project_search.html.j2:86 +#: amt/site/templates/parts/algorithm_search.html.j2:86 msgid "Group by" msgstr "Groeperen op" -#: amt/site/templates/parts/project_search.html.j2:96 +#: amt/site/templates/parts/algorithm_search.html.j2:96 msgid "Select group by" msgstr "Selecteer groepering" -#: amt/site/templates/projects/details_base.html.j2:19 +#: amt/site/templates/algorithms/details_base.html.j2:19 msgid "Delete algoritmic system" msgstr "Verwijder Algoritmesysteem" -#: amt/site/templates/projects/details_base.html.j2:26 +#: amt/site/templates/algorithms/details_base.html.j2:26 msgid "Are you sure you want to delete your algoritmic system " msgstr "Weet u zeker dat u uw algoritmische systeem wilt verwijderen " -#: amt/site/templates/projects/details_base.html.j2:30 +#: amt/site/templates/algorithms/details_base.html.j2:30 msgid "" "Data will be stored for at least 45 days before permanent\n" " deletion." @@ -540,155 +540,155 @@ msgstr "" "gegevens worden minimaal 45 dagen bewaard voordat ze definitief worden\n" " verwijderd." -#: amt/site/templates/projects/details_base.html.j2:39 -#: amt/site/templates/projects/new.html.j2:132 +#: amt/site/templates/algorithms/details_base.html.j2:39 +#: amt/site/templates/algorithms/new.html.j2:132 msgid "Yes" msgstr "Ja" -#: amt/site/templates/projects/details_base.html.j2:44 -#: amt/site/templates/projects/new.html.j2:142 +#: amt/site/templates/algorithms/details_base.html.j2:44 +#: amt/site/templates/algorithms/new.html.j2:142 msgid "No" msgstr "Nee" -#: amt/site/templates/projects/details_base.html.j2:57 +#: amt/site/templates/algorithms/details_base.html.j2:57 msgid "Delete algorithm system" msgstr "Verwijder Algoritmesysteem" -#: amt/site/templates/projects/details_base.html.j2:71 +#: amt/site/templates/algorithms/details_base.html.j2:71 msgid "Does the algorithm meet the requirements?" msgstr "Voldoet het algoritme aan de vereisten?" -#: amt/site/templates/projects/details_base.html.j2:96 -#: amt/site/templates/projects/details_base.html.j2:150 +#: amt/site/templates/algorithms/details_base.html.j2:96 +#: amt/site/templates/algorithms/details_base.html.j2:150 msgid "To do" msgstr "Te doen" -#: amt/site/templates/projects/details_base.html.j2:98 +#: amt/site/templates/algorithms/details_base.html.j2:98 msgid "In progress" msgstr "Onderhanden" -#: amt/site/templates/projects/details_base.html.j2:115 +#: amt/site/templates/algorithms/details_base.html.j2:115 msgid "Go to all requirements" msgstr "Ga naar alle Vereisten" -#: amt/site/templates/projects/details_base.html.j2:126 +#: amt/site/templates/algorithms/details_base.html.j2:126 msgid "Which instruments are executed?" msgstr "Welke instrumenten zijn uitgevoerd?" -#: amt/site/templates/projects/details_base.html.j2:167 +#: amt/site/templates/algorithms/details_base.html.j2:167 msgid "Go to all instruments" msgstr "Ga naar all instrumenten" -#: amt/site/templates/projects/details_data.html.j2:3 -#: amt/site/templates/projects/details_instruments.html.j2:3 +#: amt/site/templates/algorithms/details_data.html.j2:3 +#: amt/site/templates/algorithms/details_instruments.html.j2:3 msgid "To be implemented" msgstr "Nog te implementeren" -#: amt/site/templates/projects/details_inference.html.j2:7 +#: amt/site/templates/algorithms/details_inference.html.j2:7 msgid "Floor area (m²):" msgstr "Vloeroppervlakte (m²):" -#: amt/site/templates/projects/details_inference.html.j2:16 +#: amt/site/templates/algorithms/details_inference.html.j2:16 msgid "Plot size (m²):" msgstr "Perceelgrootte (m²):" -#: amt/site/templates/projects/details_inference.html.j2:25 +#: amt/site/templates/algorithms/details_inference.html.j2:25 msgid "Building year:" msgstr "Bouwjaar:" -#: amt/site/templates/projects/details_inference.html.j2:34 +#: amt/site/templates/algorithms/details_inference.html.j2:34 msgid "Object type:" msgstr "Objecttype:" -#: amt/site/templates/projects/details_inference.html.j2:43 +#: amt/site/templates/algorithms/details_inference.html.j2:43 msgid "Number of annexes:" msgstr "Aantal bijgebouwen:" -#: amt/site/templates/projects/details_inference.html.j2:52 +#: amt/site/templates/algorithms/details_inference.html.j2:52 msgid "Neighborhood code:" msgstr "Buurtcode:" -#: amt/site/templates/projects/details_inference.html.j2:61 +#: amt/site/templates/algorithms/details_inference.html.j2:61 msgid "Quality rating:" msgstr "Kwaliteitsbeoordeling:" -#: amt/site/templates/projects/details_inference.html.j2:73 +#: amt/site/templates/algorithms/details_inference.html.j2:73 msgid "Maintenance rating:" msgstr "Onderhoudsbeoordeling:" -#: amt/site/templates/projects/details_inference.html.j2:85 +#: amt/site/templates/algorithms/details_inference.html.j2:85 msgid "Amenities rating:" msgstr "Voorzieningenbeoordeling:" -#: amt/site/templates/projects/details_inference.html.j2:97 +#: amt/site/templates/algorithms/details_inference.html.j2:97 msgid "Location rating:" msgstr "Locatiebeoordeling:" -#: amt/site/templates/projects/details_inference.html.j2:113 +#: amt/site/templates/algorithms/details_inference.html.j2:113 msgid "Estimate WOZ Value" msgstr "WOZ-waarde schatten" -#: amt/site/templates/projects/details_inference.html.j2:117 +#: amt/site/templates/algorithms/details_inference.html.j2:117 msgid "Estimated WOZ Value" msgstr "Geschatte WOZ-waarde" -#: amt/site/templates/projects/details_inference.html.j2:119 +#: amt/site/templates/algorithms/details_inference.html.j2:119 msgid "Undefined" msgstr "Ongedefinieerd" -#: amt/site/templates/projects/details_inference.html.j2:175 +#: amt/site/templates/algorithms/details_inference.html.j2:175 msgid "Failed to estimate WOZ value: " msgstr "Fout bij het schatten van de WOZ-waarde: " -#: amt/site/templates/projects/details_info.html.j2:12 -#: amt/site/templates/projects/details_measure_modal.html.j2:19 +#: amt/site/templates/algorithms/details_info.html.j2:12 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:19 msgid "Description" msgstr "Omschrijving" -#: amt/site/templates/projects/details_info.html.j2:16 +#: amt/site/templates/algorithms/details_info.html.j2:16 msgid "Repository" msgstr "Repository" -#: amt/site/templates/projects/details_info.html.j2:20 +#: amt/site/templates/algorithms/details_info.html.j2:20 msgid "Algorithm system code" msgstr "Algoritmesysteem code" -#: amt/site/templates/projects/details_info.html.j2:32 +#: amt/site/templates/algorithms/details_info.html.j2:32 msgid "Labels" msgstr "Labels" -#: amt/site/templates/projects/details_info.html.j2:40 +#: amt/site/templates/algorithms/details_info.html.j2:40 msgid "References" msgstr "Referenties" -#: amt/site/templates/projects/details_measure_modal.html.j2:29 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:29 msgid "Read more on the algoritmekader" msgstr "Lees meer op het algoritmekader" -#: amt/site/templates/projects/details_measure_modal.html.j2:38 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:38 msgid "Status" msgstr "Status" -#: amt/site/templates/projects/details_measure_modal.html.j2:45 -#: amt/site/templates/projects/details_measure_modal.html.j2:47 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:45 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:47 msgid "to do" msgstr "Te doen" -#: amt/site/templates/projects/details_measure_modal.html.j2:50 -#: amt/site/templates/projects/details_measure_modal.html.j2:52 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:50 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:52 msgid "in progress" msgstr "Onderhanden" -#: amt/site/templates/projects/details_measure_modal.html.j2:55 -#: amt/site/templates/projects/details_measure_modal.html.j2:57 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:55 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:57 msgid "done" msgstr "Afgerond" -#: amt/site/templates/projects/details_measure_modal.html.j2:68 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:68 msgid "Information on how this measure is implemented" msgstr "Informatie over hoe deze maatregel is geïmplementeerd" -#: amt/site/templates/projects/details_measure_modal.html.j2:74 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:74 msgid "" "Describe how the measure has been implemented, including challenges and " "solutions." @@ -696,41 +696,41 @@ msgstr "" "Beschrijf hoe de maatregel is geimplementeerd, inclusief uitdagingen " "enoplossingen." -#: amt/site/templates/projects/details_requirements.html.j2:26 +#: amt/site/templates/algorithms/details_requirements.html.j2:26 msgid "measures executed" msgstr "maatregelen uitgevoerd" -#: amt/site/templates/projects/new.html.j2:7 +#: amt/site/templates/algorithms/new.html.j2:7 msgid "Create a Algorithm System" msgstr "Creëer een Algoritmesysteem" -#: amt/site/templates/projects/new.html.j2:25 +#: amt/site/templates/algorithms/new.html.j2:25 msgid "Algorithm System name" msgstr "Algoritmesysteem naam" -#: amt/site/templates/projects/new.html.j2:29 +#: amt/site/templates/algorithms/new.html.j2:29 msgid "Name of the algorithm system" msgstr "Nieuw algoritmesysteem" -#: amt/site/templates/projects/new.html.j2:43 +#: amt/site/templates/algorithms/new.html.j2:43 msgid "Select the lifecycle your algorithm system is currently in." msgstr "" "Selecteer de levenscyclus waarin uw algoritmesysteem zich momenteel " "bevindt." -#: amt/site/templates/projects/new.html.j2:44 +#: amt/site/templates/algorithms/new.html.j2:44 msgid "For more information on lifecycle, read the" msgstr "Lees voor meer meer informatie over levenscyclus het" -#: amt/site/templates/projects/new.html.j2:47 +#: amt/site/templates/algorithms/new.html.j2:47 msgid "Algorithm Framework" msgstr "Algoritmekader" -#: amt/site/templates/projects/new.html.j2:65 +#: amt/site/templates/algorithms/new.html.j2:65 msgid "AI Act Profile" msgstr "AI Verordening Profiel" -#: amt/site/templates/projects/new.html.j2:67 +#: amt/site/templates/algorithms/new.html.j2:67 msgid "" "The AI Act profile provides insight into, among other things, the type of" " AI system and the associated obligations from the European AI Act. If " @@ -742,11 +742,11 @@ msgstr "" "onder andere het type AI systeem, de regelgeving die van toepassing is en" " de risicocategorie." -#: amt/site/templates/projects/new.html.j2:74 +#: amt/site/templates/algorithms/new.html.j2:74 msgid "Find your AI Act profile" msgstr "Vind uw AI Act profiel" -#: amt/site/templates/projects/new.html.j2:151 +#: amt/site/templates/algorithms/new.html.j2:151 msgid "" "Overview of instruments for the responsible development, deployment, " "assessment and monitoring of algorithms and AI-systems." @@ -754,15 +754,15 @@ msgstr "" "Overzicht van aanbevolen instrument voor het verantwoord ontwikkelen, " "gebruiken, beoordelen en monitoren van algoritmes en AI-systemen." -#: amt/site/templates/projects/new.html.j2:159 +#: amt/site/templates/algorithms/new.html.j2:159 msgid "Choose one or more instruments" msgstr "Kies één of meerdere instrumenten" -#: amt/site/templates/projects/new.html.j2:183 +#: amt/site/templates/algorithms/new.html.j2:183 msgid "Create Algorithm System" msgstr "Creëer Algoritmesysteem" -#: amt/site/templates/projects/new.html.j2:200 +#: amt/site/templates/algorithms/new.html.j2:200 msgid "Copy results and close" msgstr "Resultaten overnemen en sluiten" diff --git a/amt/migrations/versions/1019b72fe63a_add_last_edited.py b/amt/migrations/versions/1019b72fe63a_add_last_edited.py index aeff7f1b..d6900f80 100644 --- a/amt/migrations/versions/1019b72fe63a_add_last_edited.py +++ b/amt/migrations/versions/1019b72fe63a_add_last_edited.py @@ -1,4 +1,4 @@ -"""Add last_edited column to projects table +"""Add last_edited column to algorithms table Revision ID: 1019b72fe63a Revises: 14240ff670e2 @@ -20,10 +20,10 @@ def upgrade() -> None: # Add last_edited column with default value of current timestamp - op.add_column('project', + op.add_column('algorithm', sa.Column('last_edited', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False)) def downgrade() -> None: # Drop the last_edited column - op.drop_column('project', 'last_edited') + op.drop_column('algorithm', 'last_edited') diff --git a/amt/migrations/versions/14240ff670e2_add_lifecycle.py b/amt/migrations/versions/14240ff670e2_add_lifecycle.py index e3617241..5e25c2f4 100644 --- a/amt/migrations/versions/14240ff670e2_add_lifecycle.py +++ b/amt/migrations/versions/14240ff670e2_add_lifecycle.py @@ -1,4 +1,4 @@ -"""Add lifecycle field to project table +"""Add lifecycle field to algorithm table Revision ID: 14240ff670e2 Revises: 66cf279a7f62 @@ -38,12 +38,12 @@ def upgrade() -> None: lifecycle_enum.create(op.get_bind()) # Add the lifecycle column - op.add_column('project', sa.Column('lifecycle', lifecycle_enum, nullable=True)) + op.add_column('algorithm', sa.Column('lifecycle', lifecycle_enum, nullable=True)) def downgrade() -> None: # Remove the lifecycle column - op.drop_column('project', 'lifecycle') + op.drop_column('algorithm', 'lifecycle') # Drop the enum type lifecycle_enum = postgresql.ENUM(*lifecycle_values, name='lifecycle') diff --git a/amt/migrations/versions/2c84c4ad5b68_add_reference_to_project_in_task.py b/amt/migrations/versions/2c84c4ad5b68_add_reference_to_project_in_task.py index f895a97a..673ac89b 100644 --- a/amt/migrations/versions/2c84c4ad5b68_add_reference_to_project_in_task.py +++ b/amt/migrations/versions/2c84c4ad5b68_add_reference_to_project_in_task.py @@ -1,4 +1,4 @@ -"""add reference to project in task +"""add reference to algorithm in task Revision ID: 2c84c4ad5b68 Revises: c21dd0bc2c85 @@ -22,7 +22,7 @@ def upgrade() -> None: with op.batch_alter_table("task", schema=None) as batch_op: batch_op.add_column(sa.Column("project_id", sa.Integer(), nullable=True)) # Note that the value None below is due to the automatic naming generation from Base.metadata - batch_op.create_foreign_key(None, "project", ["project_id"], ["id"]) + batch_op.create_foreign_key(None, "algorithm", ["project_id"], ["id"]) def downgrade() -> None: diff --git a/amt/migrations/versions/6581a03aabec_add_deleted_at_to_project.py b/amt/migrations/versions/6581a03aabec_add_deleted_at_to_project.py index 03088d7c..07217f9e 100644 --- a/amt/migrations/versions/6581a03aabec_add_deleted_at_to_project.py +++ b/amt/migrations/versions/6581a03aabec_add_deleted_at_to_project.py @@ -1,4 +1,4 @@ -"""add deleted_at to project +"""add deleted_at to algorithm Revision ID: 6581a03aabec Revises: 7f20f8562007 @@ -20,8 +20,8 @@ def upgrade() -> None: - op.add_column("project", sa.Column("deleted_at", sa.DateTime(), nullable=True)) + op.add_column("algorithm", sa.Column("deleted_at", sa.DateTime(), nullable=True)) def downgrade() -> None: - op.drop_column("project", "deleted_at") + op.drop_column("algorithm", "deleted_at") diff --git a/amt/migrations/versions/7f20f8562007_add_system_card_column.py b/amt/migrations/versions/7f20f8562007_add_system_card_column.py index 4fcf31a4..b1cecf89 100644 --- a/amt/migrations/versions/7f20f8562007_add_system_card_column.py +++ b/amt/migrations/versions/7f20f8562007_add_system_card_column.py @@ -19,12 +19,12 @@ def upgrade() -> None: - with op.batch_alter_table("project", schema=None) as batch_op: + with op.batch_alter_table("algorithm", schema=None) as batch_op: batch_op.add_column(sa.Column("system_card_json", sa.JSON(), nullable=True)) batch_op.drop_column("model_card") def downgrade() -> None: - with op.batch_alter_table("project", schema=None) as batch_op: + with op.batch_alter_table("algorithm", schema=None) as batch_op: batch_op.add_column(sa.Column("model_card", sa.String(), nullable=True)) batch_op.drop_column("system_card_json") diff --git a/amt/migrations/versions/c21dd0bc2c85_make_model_card_nullable_in_project.py b/amt/migrations/versions/c21dd0bc2c85_make_model_card_nullable_in_project.py index 83afb16b..4db0421b 100644 --- a/amt/migrations/versions/c21dd0bc2c85_make_model_card_nullable_in_project.py +++ b/amt/migrations/versions/c21dd0bc2c85_make_model_card_nullable_in_project.py @@ -1,4 +1,4 @@ -"""make model_card nullable in project +"""make model_card nullable in algorithm Revision ID: c21dd0bc2c85 Revises: c5254dc6083f @@ -20,13 +20,13 @@ def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - with op.batch_alter_table("project", schema=None) as batch_op: + with op.batch_alter_table("algorithm", schema=None) as batch_op: batch_op.alter_column("model_card", existing_type=sa.VARCHAR(), nullable=True) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - with op.batch_alter_table("project", schema=None) as batch_op: + with op.batch_alter_table("algorithm", schema=None) as batch_op: batch_op.alter_column("model_card", existing_type=sa.VARCHAR(), nullable=False) # ### end Alembic commands ### diff --git a/amt/migrations/versions/c5254dc6083f_add_project.py b/amt/migrations/versions/c5254dc6083f_add_project.py index 0dc215dd..214f84d2 100644 --- a/amt/migrations/versions/c5254dc6083f_add_project.py +++ b/amt/migrations/versions/c5254dc6083f_add_project.py @@ -1,4 +1,4 @@ -"""add project +"""add algorithm Revision ID: c5254dc6083f Revises: bf86033947fc @@ -21,7 +21,7 @@ def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.create_table( - "project", + "algorithm", sa.Column("id", sa.Integer(), nullable=False), sa.Column("name",sa.String(255), nullable=False), sa.Column("model_card", sa.String(255), nullable=False), @@ -32,5 +32,5 @@ def upgrade() -> None: def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.drop_table("project") + op.drop_table("algorithm") # ### end Alembic commands ### diff --git a/amt/models/__init__.py b/amt/models/__init__.py index bf18df97..6491ac32 100644 --- a/amt/models/__init__.py +++ b/amt/models/__init__.py @@ -1,5 +1,6 @@ +from .algorithm import Algorithm from .project import Project from .task import Task from .user import User -__all__ = ["Task", "User", "Project"] +__all__ = ["Task", "User", "Algorithm", "Project"] diff --git a/amt/models/algorithm.py b/amt/models/algorithm.py new file mode 100644 index 00000000..8a0b16db --- /dev/null +++ b/amt/models/algorithm.py @@ -0,0 +1,97 @@ +import json +from datetime import datetime +from enum import Enum +from typing import Any, TypeVar + +from sqlalchemy import String, func +from sqlalchemy.dialects.postgresql import ENUM +from sqlalchemy.orm import Mapped, mapped_column +from sqlalchemy.types import JSON + +from amt.api.lifecycles import Lifecycles +from amt.models.base import Base +from amt.schema.system_card import SystemCard + +T = TypeVar("T", bound="Algorithm") + + +class CustomJSONEncoder(json.JSONEncoder): + def default(self, o: Any) -> Any: # noqa: ANN401 + if isinstance(o, datetime): + return o.isoformat() + if isinstance(o, Enum): + return o.name + return super().default(o) + + +class AlgorithmSystemCard(SystemCard): + def __init__(self, parent: "Algorithm", **data: Any) -> None: # noqa: ANN401 + super().__init__(**data) + self._parent = parent + + def __setattr__(self, name: str, value: Any) -> None: # noqa: ANN401 + super().__setattr__(name, value) + if name != "_parent" and hasattr(self, "_parent"): + self._parent.sync_system_card() + + def __eq__(self, other: Any) -> bool: # noqa: ANN401 + if isinstance(other, AlgorithmSystemCard | SystemCard): + return self.model_dump(exclude={"_parent"}) == other.model_dump() + return False + + def model_dump(self, *args: Any, **kwargs: Any) -> dict[str, Any]: # noqa: ANN401 + exclude_unset = kwargs.pop("exclude_unset", False) + by_alias = kwargs.pop("by_alias", False) + exclude_none = kwargs.pop("exclude_none", False) + + dumped = super().model_dump( + *args, exclude_unset=exclude_unset, by_alias=by_alias, exclude_none=exclude_none, **kwargs + ) + + return json.loads(json.dumps(dumped, cls=CustomJSONEncoder)) + + +class Algorithm(Base): + __tablename__ = "algorithm" + + id: Mapped[int] = mapped_column(primary_key=True) + name: Mapped[str] = mapped_column(String(255)) + lifecycle: Mapped[Lifecycles | None] = mapped_column(ENUM(Lifecycles, name="lifecycle"), nullable=True) + system_card_json: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict) + last_edited: Mapped[datetime] = mapped_column(server_default=func.now(), onupdate=func.now(), nullable=False) + deleted_at: Mapped[datetime | None] = mapped_column(server_default=None, nullable=True) + + def __init__(self, *args: Any, **kwargs: Any) -> None: # noqa: ANN401 + system_card: SystemCard | None = kwargs.pop("system_card", None) + super().__init__(*args, **kwargs) + self._system_card: AlgorithmSystemCard | None = None + if system_card is not None: + self.system_card = system_card + + @property + def system_card(self) -> AlgorithmSystemCard: + if not hasattr(self, "_system_card"): + self._system_card: AlgorithmSystemCard | None = None + + if self._system_card is None: + if self.system_card_json: + self._system_card = AlgorithmSystemCard(self, **self.system_card_json) + else: + self._system_card = AlgorithmSystemCard(self) + self.sync_system_card() + return self._system_card + + @system_card.setter + def system_card(self, value: SystemCard | None) -> None: + if value is None: + self._system_card = AlgorithmSystemCard(self) + else: + self._system_card = AlgorithmSystemCard(self, **value.model_dump(exclude_unset=True, by_alias=True)) + self.sync_system_card() + + def sync_system_card(self) -> None: + if self._system_card is not None: + self.system_card_json = self._system_card.model_dump(exclude_unset=True, by_alias=True) + + +Algorithm.__mapper_args__ = {"exclude_properties": ["_system_card"]} diff --git a/amt/models/project.py b/amt/models/project.py index fe5cf22b..6b107334 100644 --- a/amt/models/project.py +++ b/amt/models/project.py @@ -52,7 +52,7 @@ def model_dump(self, *args: Any, **kwargs: Any) -> dict[str, Any]: # noqa: ANN4 class Project(Base): - __tablename__ = "project" + __tablename__ = "algorithm" id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(255)) diff --git a/amt/models/task.py b/amt/models/task.py index 4fbd0f32..514a93f7 100644 --- a/amt/models/task.py +++ b/amt/models/task.py @@ -16,5 +16,5 @@ class Task(Base): # TODO: (Christopher) SQLModel does not allow to give the below restraint an name # which is needed for alembic. This results in changing the migration file # manually to give the restrain a name. - project_id: Mapped[int | None] = mapped_column(ForeignKey("project.id")) + algorithm_id: Mapped[int | None] = mapped_column(ForeignKey("algorithm.id")) # todo(robbert) Tasks probably are grouped (and sub-grouped), so we probably need a reference to a group_id diff --git a/amt/repositories/projects.py b/amt/repositories/algorithms.py similarity index 61% rename from amt/repositories/projects.py rename to amt/repositories/algorithms.py index 2ba07223..8f647348 100644 --- a/amt/repositories/projects.py +++ b/amt/repositories/algorithms.py @@ -10,100 +10,100 @@ from amt.api.publication_category import PublicationCategories from amt.core.exceptions import AMTRepositoryError -from amt.models import Project +from amt.models import Algorithm from amt.repositories.deps import get_session logger = logging.getLogger(__name__) -def sort_by_lifecycle(project: Project) -> int: - if project.lifecycle: - return project.lifecycle.index +def sort_by_lifecycle(algorithm: Algorithm) -> int: + if algorithm.lifecycle: + return algorithm.lifecycle.index else: return -1 -def sort_by_lifecycle_reversed(project: Project) -> int: - if project.lifecycle: - return -project.lifecycle.index +def sort_by_lifecycle_reversed(algorithm: Algorithm) -> int: + if algorithm.lifecycle: + return -algorithm.lifecycle.index else: return 1 -class ProjectsRepository: +class AlgorithmsRepository: def __init__(self, session: Annotated[AsyncSession, Depends(get_session)]) -> None: self.session = session - async def find_all(self) -> Sequence[Project]: - result = await self.session.execute(select(Project).where(Project.deleted_at.is_(None))) + async def find_all(self) -> Sequence[Algorithm]: + result = await self.session.execute(select(Algorithm).where(Algorithm.deleted_at.is_(None))) return result.scalars().all() - async def delete(self, project: Project) -> None: + async def delete(self, algorithm: Algorithm) -> None: """ Deletes the given status in the repository. :param status: the status to store :return: the updated status after storing """ try: - await self.session.delete(project) + await self.session.delete(algorithm) await self.session.commit() except Exception as e: - logger.exception("Error deleting project") + logger.exception("Error deleting algorithm") await self.session.rollback() raise AMTRepositoryError from e return None - async def save(self, project: Project) -> Project: + async def save(self, algorithm: Algorithm) -> Algorithm: try: - self.session.add(project) + self.session.add(algorithm) await self.session.commit() - await self.session.refresh(project) + await self.session.refresh(algorithm) except SQLAlchemyError as e: - logger.exception("Error saving project") + logger.exception("Error saving algorithm") await self.session.rollback() raise AMTRepositoryError from e - return project + return algorithm - async def find_by_id(self, project_id: int) -> Project: + async def find_by_id(self, algorithm_id: int) -> Algorithm: try: - statement = select(Project).where(Project.id == project_id).where(Project.deleted_at.is_(None)) + statement = select(Algorithm).where(Algorithm.id == algorithm_id).where(Algorithm.deleted_at.is_(None)) result = await self.session.execute(statement) return result.scalars().one() except NoResultFound as e: - logger.exception("Project not found") + logger.exception("Algorithm not found") raise AMTRepositoryError from e async def paginate( # noqa self, skip: int, limit: int, search: str, filters: dict[str, str], sort: dict[str, str] - ) -> list[Project]: + ) -> list[Algorithm]: try: - statement = select(Project) + statement = select(Algorithm) if search != "": - statement = statement.filter(Project.name.ilike(f"%{escape_like(search)}%")) + statement = statement.filter(Algorithm.name.ilike(f"%{escape_like(search)}%")) if filters: for key, value in filters.items(): match key: case "lifecycle": - statement = statement.filter(Project.lifecycle == value) + statement = statement.filter(Algorithm.lifecycle == value) case "publication-category": statement = statement.filter( - Project.system_card_json["ai_act_profile"]["publication_category"].as_string() + Algorithm.system_card_json["ai_act_profile"]["publication_category"].as_string() == PublicationCategories[value].value ) case _: raise TypeError(f"Unknown filter type with key: {key}") # noqa if sort: if "name" in sort and sort["name"] == "ascending": - statement = statement.order_by(func.lower(Project.name).asc()) + statement = statement.order_by(func.lower(Algorithm.name).asc()) elif "name" in sort and sort["name"] == "descending": - statement = statement.order_by(func.lower(Project.name).desc()) + statement = statement.order_by(func.lower(Algorithm.name).desc()) elif "last_update" in sort and sort["last_update"] == "ascending": - statement = statement.order_by(Project.last_edited.asc()) + statement = statement.order_by(Algorithm.last_edited.asc()) elif "last_update" in sort and sort["last_update"] == "descending": - statement = statement.order_by(Project.last_edited.desc()) + statement = statement.order_by(Algorithm.last_edited.desc()) else: - statement = statement.order_by(func.lower(Project.name)) - statement = statement.filter(Project.deleted_at.is_(None)) + statement = statement.order_by(func.lower(Algorithm.name)) + statement = statement.filter(Algorithm.deleted_at.is_(None)) statement = statement.offset(skip).limit(limit) db_result = await self.session.execute(statement) result = list(db_result.scalars()) @@ -116,5 +116,5 @@ async def paginate( # noqa result = sorted(result, key=sort_by_lifecycle_reversed) return result # noqa except Exception as e: - logger.exception("Error paginating projects") + logger.exception("Error paginating algorithms") raise AMTRepositoryError from e diff --git a/amt/repositories/tasks.py b/amt/repositories/tasks.py index 1e3a649b..22058e4f 100644 --- a/amt/repositories/tasks.py +++ b/amt/repositories/tasks.py @@ -38,15 +38,15 @@ async def find_by_status_id(self, status_id: int) -> Sequence[Task]: statement = select(Task).where(Task.status_id == status_id).order_by(Task.sort_order) return (await self.session.execute(statement)).scalars().all() - async def find_by_project_id_and_status_id(self, project_id: int, status_id: int) -> Sequence[Task]: + async def find_by_algorithm_id_and_status_id(self, algorithm_id: int, status_id: int) -> Sequence[Task]: """ - Returns all tasks in the repository for the given project_id. - :param project_id: the project_id to filter on - :return: a list of tasks in the repository for the given project_id + Returns all tasks in the repository for the given algorithm_id. + :param algorithm_id: the algorithm_id to filter on + :return: a list of tasks in the repository for the given algorithm_id """ statement = ( select(Task) - .where(and_(Task.status_id == status_id, Task.project_id == project_id)) + .where(and_(Task.status_id == status_id, Task.algorithm_id == algorithm_id)) .order_by(Task.sort_order) ) return (await self.session.execute(statement)).scalars().all() diff --git a/amt/schema/project.py b/amt/schema/algorithm.py similarity index 91% rename from amt/schema/project.py rename to amt/schema/algorithm.py index 5bfddfd3..09303124 100644 --- a/amt/schema/project.py +++ b/amt/schema/algorithm.py @@ -2,12 +2,12 @@ from pydantic.functional_validators import field_validator -class ProjectBase(BaseModel): +class AlgorithmBase(BaseModel): name: str = Field(min_length=3, max_length=255) lifecycle: str = Field() -class ProjectNew(ProjectBase): +class AlgorithmNew(AlgorithmBase): instruments: list[str] | str = [] type: str = Field(default=None) open_source: str = Field(default=None) diff --git a/amt/schema/model_card.py b/amt/schema/model_card.py index b9fabb75..bf7d097c 100644 --- a/amt/schema/model_card.py +++ b/amt/schema/model_card.py @@ -156,6 +156,6 @@ class ModelCardSchema(BaseModel): name: str | None = Field(None, description="Name of the model") language: list[str] | None = Field(None, description="The natural languages the model supports in ISO 639") license: License - tags: list[str] | None = Field(None, description="Tags with keywords to describe the project") + tags: list[str] | None = Field(None, description="Tags with keywords to describe the algorithm") owners: list[Owner] | None = None model_index: list[ModelIndexItem] = Field(alias="model-index") # pyright: ignore [reportGeneralTypeIssues] diff --git a/amt/services/projects.py b/amt/services/algorithms.py similarity index 63% rename from amt/services/projects.py rename to amt/services/algorithms.py index 454aa13b..3dfe3aa0 100644 --- a/amt/services/projects.py +++ b/amt/services/algorithms.py @@ -10,10 +10,10 @@ from fastapi import Depends from amt.core.exceptions import AMTNotFound -from amt.models import Project -from amt.repositories.projects import ProjectsRepository +from amt.models import Algorithm +from amt.repositories.algorithms import AlgorithmsRepository +from amt.schema.algorithm import AlgorithmNew from amt.schema.instrument import InstrumentBase -from amt.schema.project import ProjectNew from amt.schema.system_card import AiActProfile, SystemCard from amt.services.instruments import InstrumentsService from amt.services.task_registry import get_requirements_and_measures @@ -24,10 +24,10 @@ template_path = "resources/system_card_templates" -class ProjectsService: +class AlgorithmsService: def __init__( self, - repository: Annotated[ProjectsRepository, Depends(ProjectsRepository)], + repository: Annotated[AlgorithmsRepository, Depends(AlgorithmsRepository)], task_service: Annotated[TasksService, Depends(TasksService)], instrument_service: Annotated[InstrumentsService, Depends(InstrumentsService)], ) -> None: @@ -35,45 +35,45 @@ def __init__( self.instrument_service = instrument_service self.task_service = task_service - async def get(self, project_id: int) -> Project: - project = await self.repository.find_by_id(project_id) - if project.deleted_at: + async def get(self, algorithm_id: int) -> Algorithm: + algorithm = await self.repository.find_by_id(algorithm_id) + if algorithm.deleted_at: raise AMTNotFound() - return project + return algorithm - async def delete(self, project_id: int) -> Project: - project = await self.repository.find_by_id(project_id) - project.deleted_at = datetime.now(tz=None) # noqa: DTZ005 - project = await self.repository.save(project) - return project + async def delete(self, algorithm_id: int) -> Algorithm: + algorithm = await self.repository.find_by_id(algorithm_id) + algorithm.deleted_at = datetime.now(tz=None) # noqa: DTZ005 + algorithm = await self.repository.save(algorithm) + return algorithm - async def create(self, project_new: ProjectNew) -> Project: + async def create(self, algorithm_new: AlgorithmNew) -> Algorithm: system_card_from_template = None - if project_new.template_id: + if algorithm_new.template_id: template_files = get_template_files() - if project_new.template_id in template_files: - with open(Path(template_path) / Path(template_files[project_new.template_id]["value"])) as f: + if algorithm_new.template_id in template_files: + with open(Path(template_path) / Path(template_files[algorithm_new.template_id]["value"])) as f: system_card_from_template = json.load(f) else: raise AMTNotFound() instruments: list[InstrumentBase] = [ - InstrumentBase(urn=instrument_urn) for instrument_urn in project_new.instruments + InstrumentBase(urn=instrument_urn) for instrument_urn in algorithm_new.instruments ] ai_act_profile = AiActProfile( - type=project_new.type, - open_source=project_new.open_source, - publication_category=project_new.publication_category, - systemic_risk=project_new.systemic_risk, - transparency_obligations=project_new.transparency_obligations, - role=project_new.role, + type=algorithm_new.type, + open_source=algorithm_new.open_source, + publication_category=algorithm_new.publication_category, + systemic_risk=algorithm_new.systemic_risk, + transparency_obligations=algorithm_new.transparency_obligations, + role=algorithm_new.role, ) requirements, measures = get_requirements_and_measures(ai_act_profile) system_card = SystemCard( - name=project_new.name, + name=algorithm_new.name, ai_act_profile=ai_act_profile, instruments=instruments, requirements=requirements, @@ -100,28 +100,28 @@ async def create(self, project_new: ProjectNew) -> Project: } system_card = SystemCard.model_validate(system_card_merged) - project = Project(name=project_new.name, lifecycle=project_new.lifecycle, system_card=system_card) - project = await self.update(project) + algorithm = Algorithm(name=algorithm_new.name, lifecycle=algorithm_new.lifecycle, system_card=system_card) + algorithm = await self.update(algorithm) selected_instruments = self.instrument_service.fetch_instruments( - [instrument.urn for instrument in project.system_card.instruments] + [instrument.urn for instrument in algorithm.system_card.instruments] ) for instrument in selected_instruments: - await self.task_service.create_instrument_tasks(instrument.tasks, project) + await self.task_service.create_instrument_tasks(instrument.tasks, algorithm) - return project + return algorithm async def paginate( self, skip: int, limit: int, search: str, filters: dict[str, str], sort: dict[str, str] - ) -> list[Project]: - projects = await self.repository.paginate(skip=skip, limit=limit, search=search, filters=filters, sort=sort) - return projects + ) -> list[Algorithm]: + algorithms = await self.repository.paginate(skip=skip, limit=limit, search=search, filters=filters, sort=sort) + return algorithms - async def update(self, project: Project) -> Project: + async def update(self, algorithm: Algorithm) -> Algorithm: # TODO: Is this the right place to sync system cards: system_card and system_card_json? - project.sync_system_card() - project = await self.repository.save(project) - return project + algorithm.sync_system_card() + algorithm = await self.repository.save(algorithm) + return algorithm @lru_cache diff --git a/amt/services/tasks.py b/amt/services/tasks.py index 1b369026..42598ffc 100644 --- a/amt/services/tasks.py +++ b/amt/services/tasks.py @@ -5,7 +5,7 @@ from fastapi import Depends from amt.enums.status import Status -from amt.models.project import Project +from amt.models.algorithm import Algorithm from amt.models.task import Task from amt.models.user import User from amt.repositories.tasks import TasksRepository @@ -29,8 +29,8 @@ async def get_tasks(self, status_id: int) -> Sequence[Task]: task = await self.repository.find_by_status_id(status_id) return task - async def get_tasks_for_project(self, project_id: int, status_id: int) -> Sequence[Task]: - tasks = await self.repository.find_by_project_id_and_status_id(project_id, status_id) + async def get_tasks_for_algorithm(self, algorithm_id: int, status_id: int) -> Sequence[Task]: + tasks = await self.repository.find_by_algorithm_id_and_status_id(algorithm_id, status_id) return tasks async def assign_task(self, task: Task, user: User) -> Task: @@ -38,7 +38,7 @@ async def assign_task(self, task: Task, user: User) -> Task: task = await self.repository.save(task) return task - async def create_instrument_tasks(self, tasks: Sequence[InstrumentTask], project: Project) -> None: + async def create_instrument_tasks(self, tasks: Sequence[InstrumentTask], algorithm: Algorithm) -> None: # TODO: (Christopher) At this moment a status has to be retrieved from the DB. In the future # we will have static statuses, so this will need to change. status = Status.TODO @@ -47,7 +47,11 @@ async def create_instrument_tasks(self, tasks: Sequence[InstrumentTask], project # TODO: (Christopher) The ticket does not specify what to do when question type is not an # open questions, hence for now all titles will be set to task.question. Task( - title=task.question[:1024], description="", project_id=project.id, status_id=status, sort_order=idx + title=task.question[:1024], + description="", + algorithm_id=algorithm.id, + status_id=status, + sort_order=idx, ) for idx, task in enumerate(tasks) ] diff --git a/amt/site/templates/projects/details_base.html.j2 b/amt/site/templates/algorithms/details_base.html.j2 similarity index 96% rename from amt/site/templates/projects/details_base.html.j2 rename to amt/site/templates/algorithms/details_base.html.j2 index c58c4ed5..ded6d297 100644 --- a/amt/site/templates/projects/details_base.html.j2 +++ b/amt/site/templates/algorithms/details_base.html.j2 @@ -1,6 +1,6 @@ {% extends 'layouts/base.html.j2' %} {% from "macros/editable.html.j2" import editable with context %} -{% block title %}{{ project.name }} | AMT{% endblock %} +{% block title %}{{ algorithm.name }} | AMT{% endblock %} {% block content %}