diff --git a/amt/api/forms/algorithm.py b/amt/api/forms/algorithm.py index dc08d8b1..e4eb925f 100644 --- a/amt/api/forms/algorithm.py +++ b/amt/api/forms/algorithm.py @@ -6,7 +6,11 @@ async def get_algorithm_form( - id: str, translations: NullTranslations, organizations_service: OrganizationsService, user_id: str | UUID | None + id: str, + translations: NullTranslations, + organizations_service: OrganizationsService, + user_id: str | UUID | None, + organization_id: int | None, ) -> WebForm: _ = translations.gettext @@ -28,7 +32,7 @@ async def get_algorithm_form( WebFormOption(value=str(organization.id), display_value=organization.name) for organization in my_organizations ], - default_value="", + default_value=str(organization_id), group="1", ), ] diff --git a/amt/api/routes/algorithms.py b/amt/api/routes/algorithms.py index 3af0ee99..e2a59211 100644 --- a/amt/api/routes/algorithms.py +++ b/amt/api/routes/algorithms.py @@ -39,33 +39,9 @@ async def get_root( ) -> HTMLResponse: filters, drop_filters, localized_filters, sort_by = get_filters_and_sort_by(request) - amount_algorithm_systems: int = 0 - if display_type == "LIFECYCLE": - algorithms: dict[str, list[Algorithm]] = {} - - # When the lifecycle filter is active, only show these algorithms - if "lifecycle" in filters: - for lifecycle in Lifecycles: - 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(algorithms[filters["lifecycle"]]) - else: - for lifecycle in Lifecycles: - filters["lifecycle"] = lifecycle.name - algorithms[lifecycle.name] = await algorithms_service.paginate( - skip=skip, limit=limit, search=search, filters=filters, sort=sort_by - ) - amount_algorithm_systems += len(algorithms[lifecycle.name]) - else: - 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) + algorithms, amount_algorithm_systems = await get_algorithms( + algorithms_service, display_type, filters, limit, request, search, skip, sort_by + ) next = skip + limit sub_menu_items = resolve_navigation_items([Navigation.ALGORITHMS_OVERVIEW], request) # pyright: ignore [reportUnusedVariable] # noqa @@ -86,6 +62,7 @@ async def get_root( "filters": localized_filters, "sort_by": sort_by, "display_type": display_type, + "base_href": "/algorithms/", } if request.state.htmx and drop_filters: @@ -96,11 +73,52 @@ async def get_root( return templates.TemplateResponse(request, "algorithms/index.html.j2", context) +async def get_algorithms( + algorithms_service: AlgorithmsService, + display_type: str, + filters: dict[str, str], + limit: int, + request: Request, + search: str, + skip: int, + sort_by: dict[str, str], +) -> tuple[dict[str, list[Algorithm]], int | Any]: + amount_algorithm_systems: int = 0 + if display_type == "LIFECYCLE": + algorithms: dict[str, list[Algorithm]] = {} + + # When the lifecycle filter is active, only show these algorithms + if "lifecycle" in filters: + for lifecycle in Lifecycles: + 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(algorithms[filters["lifecycle"]]) + else: + for lifecycle in Lifecycles: + filters["lifecycle"] = lifecycle.name + algorithms[lifecycle.name] = await algorithms_service.paginate( + skip=skip, limit=limit, search=search, filters=filters, sort=sort_by + ) + amount_algorithm_systems += len(algorithms[lifecycle.name]) + else: + 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) + return algorithms, amount_algorithm_systems + + @router.get("/new") async def get_new( request: Request, instrument_service: Annotated[InstrumentsService, Depends(create_instrument_service)], organizations_service: Annotated[OrganizationsService, Depends(OrganizationsService)], + organization_id: int = Query(None), ) -> HTMLResponse: sub_menu_items = resolve_navigation_items([Navigation.ALGORITHMS_OVERVIEW], request) # pyright: ignore [reportUnusedVariable] # noqa breadcrumbs = resolve_base_navigation_items([Navigation.ALGORITHMS_ROOT, Navigation.ALGORITHM_NEW], request) @@ -116,6 +134,7 @@ async def get_new( translations=get_current_translation(request), organizations_service=organizations_service, user_id=user["sub"] if user else None, + organization_id=organization_id, ) template_files = get_template_files() diff --git a/amt/api/routes/organizations.py b/amt/api/routes/organizations.py index a474d59b..533a358b 100644 --- a/amt/api/routes/organizations.py +++ b/amt/api/routes/organizations.py @@ -9,6 +9,8 @@ from amt.api.deps import templates from amt.api.forms.organization import get_organization_form +from amt.api.group_by_category import get_localized_group_by_categories +from amt.api.lifecycles import get_localized_lifecycles from amt.api.navigation import ( BaseNavigationItem, Navigation, @@ -17,7 +19,9 @@ resolve_navigation_items, ) from amt.api.organization_filter_options import get_localized_organization_filters +from amt.api.risk_group import get_localized_risk_groups from amt.api.routes.algorithm import UpdateFieldModel, set_path +from amt.api.routes.algorithms import get_algorithms from amt.api.routes.shared import get_filters_and_sort_by from amt.core.authorization import get_user from amt.core.exceptions import AMTAuthorizationError, AMTNotFound, AMTRepositoryError @@ -26,6 +30,7 @@ from amt.repositories.organizations import OrganizationsRepository from amt.repositories.users import UsersRepository from amt.schema.organization import OrganizationBase, OrganizationNew, OrganizationSlug, OrganizationUsers +from amt.services.algorithms import AlgorithmsService from amt.services.organizations import OrganizationsService router = APIRouter() @@ -145,27 +150,34 @@ async def get_by_slug( slug: str, organizations_repository: Annotated[OrganizationsRepository, Depends(OrganizationsRepository)], ) -> HTMLResponse: + organization = await get_organization_or_error(organizations_repository, request, slug) + breadcrumbs = resolve_base_navigation_items( + [ + Navigation.ORGANIZATIONS_ROOT, + BaseNavigationItem(custom_display_text=organization.name, url="/organizations/{organization_slug}"), + ], + request, + ) + + tab_items = get_organization_tabs(request, organization_slug=slug) + context = { + "base_href": f"/organizations/{ slug }", + "organization": organization, + "tab_items": tab_items, + "breadcrumbs": breadcrumbs, + } + return templates.TemplateResponse(request, "organizations/home.html.j2", context) + + +async def get_organization_or_error( + organizations_repository: OrganizationsRepository, request: Request, slug: str +) -> Organization: try: organization = await organizations_repository.find_by_slug(slug) request.state.path_variables = {"organization_slug": organization.slug} - breadcrumbs = resolve_base_navigation_items( - [ - Navigation.ORGANIZATIONS_ROOT, - BaseNavigationItem(custom_display_text=organization.name, url="/organizations/{organization_slug}"), - ], - request, - ) - - tab_items = get_organization_tabs(request, organization_slug=slug) - context = { - "base_href": f"/organizations/{ slug }", - "organization": organization, - "tab_items": tab_items, - "breadcrumbs": breadcrumbs, - } - return templates.TemplateResponse(request, "organizations/home.html.j2", context) except AMTRepositoryError as e: raise AMTNotFound from e + return organization @router.get("/{slug}/edit/{path:path}") @@ -177,7 +189,7 @@ async def get_organization_edit( edit_type: str, ) -> HTMLResponse: context: dict[str, Any] = {"base_href": f"/organizations/{ slug }"} - organization = await organizations_repository.find_by_slug(slug) + organization = await get_organization_or_error(organizations_repository, request, slug) context.update({"path": path.replace("/", "."), "edit_type": edit_type, "object": organization}) return templates.TemplateResponse(request, "parts/edit_cell.html.j2", context) @@ -195,7 +207,7 @@ async def get_organization_cancel( "path": path.replace("/", "."), "edit_type": edit_type, } - organization = await organizations_repository.find_by_slug(slug) + organization = await get_organization_or_error(organizations_repository, request, slug) context.update({"object": organization}) return templates.TemplateResponse(request, "parts/view_cell.html.j2", context) @@ -214,7 +226,7 @@ async def get_organization_update( "path": path.replace("/", "."), "edit_type": edit_type, } - organization = await organizations_repository.find_by_slug(slug) + organization = await get_organization_or_error(organizations_repository, request, slug) context.update({"object": organization}) redirect_to: str | None = None @@ -244,10 +256,62 @@ async def get_organization_update( @router.get("/{slug}/algorithms") -async def get_algorithms( +async def show_algorithms( request: Request, + algorithms_service: Annotated[AlgorithmsService, Depends(AlgorithmsService)], + organizations_repository: Annotated[OrganizationsRepository, Depends(OrganizationsRepository)], + slug: str, + skip: int = Query(0, ge=0), + limit: int = Query(5000, ge=1), # todo: fix infinite scroll + search: str = Query(""), + display_type: str = Query(""), ) -> HTMLResponse: - return templates.TemplateResponse(request, "pages/under_construction.html.j2", {}) + organization = await get_organization_or_error(organizations_repository, request, slug) + filters, drop_filters, localized_filters, sort_by = get_filters_and_sort_by(request) + + filters["organization-id"] = str(organization.id) + algorithms, amount_algorithm_systems = await get_algorithms( + algorithms_service, display_type, filters, limit, request, search, skip, sort_by + ) + next = skip + limit + + tab_items = get_organization_tabs(request, organization_slug=slug) + + breadcrumbs = resolve_base_navigation_items( + [ + Navigation.ORGANIZATIONS_ROOT, + BaseNavigationItem(custom_display_text=organization.name, url="/organizations/{organization_slug}"), + Navigation.ORGANIZATIONS_ALGORITHMS, + ], + request, + ) + + context: dict[str, Any] = { + "breadcrumbs": breadcrumbs, + "tab_items": tab_items, + "sub_menu_items": {}, + "algorithms": algorithms, + "amount_algorithm_systems": amount_algorithm_systems, + "next": next, + "limit": limit, + "start": skip, + "search": search, + "lifecycles": get_localized_lifecycles(request), + "risk_groups": get_localized_risk_groups(request), + "group_by_categories": get_localized_group_by_categories(request), + "filters": localized_filters, + "sort_by": sort_by, + "display_type": display_type, + "base_href": f"/organizations/{slug}/algorithms", + "organization_id": organization.id, + } + + if request.state.htmx and drop_filters: + 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, "organizations/algorithms.html.j2", context) @router.delete("/{slug}/members/{user_id}") @@ -259,7 +323,7 @@ async def remove_member( users_repository: Annotated[UsersRepository, Depends(UsersRepository)], ) -> HTMLResponse: # TODO (Robbert): add authorization and check if user and organization exist? - organization = await organizations_repository.find_by_slug(slug) + organization = await get_organization_or_error(organizations_repository, request, slug) user: User | None = await users_repository.find_by_id(user_id) if user: await organizations_repository.remove_user(organization, user) @@ -281,10 +345,11 @@ async def get_members_form( async def add_new_members( request: Request, slug: str, + organizations_repository: Annotated[OrganizationsRepository, Depends(OrganizationsRepository)], organizations_service: Annotated[OrganizationsService, Depends(OrganizationsService)], organization_users: OrganizationUsers, ) -> HTMLResponse: - organization = await organizations_service.find_by_slug(slug) + organization = await get_organization_or_error(organizations_repository, request, slug) await organizations_service.add_users(organization, organization_users.user_ids) return templates.Redirect(request, f"/organizations/{slug}/members") @@ -299,10 +364,9 @@ async def get_members( limit: int = Query(5000, ge=1), # todo: fix infinite scroll search: str = Query(""), ) -> HTMLResponse: + organization = await get_organization_or_error(organizations_repository, request, slug) filters, drop_filters, localized_filters, sort_by = get_filters_and_sort_by(request) - organization = await organizations_repository.find_by_slug(slug) tab_items = get_organization_tabs(request, organization_slug=slug) - request.state.path_variables = {"organization_slug": organization.slug} breadcrumbs = resolve_base_navigation_items( [ Navigation.ORGANIZATIONS_ROOT, diff --git a/amt/core/exception_handlers.py b/amt/core/exception_handlers.py index 3a06f261..c7777f49 100644 --- a/amt/core/exception_handlers.py +++ b/amt/core/exception_handlers.py @@ -21,6 +21,7 @@ "missing": _("Field required"), "value_error": _("Field required"), "string_pattern_mismatch": _("String should match pattern '{pattern}'"), + "int_parsing": _("Input should be a valid integer."), } @@ -78,6 +79,7 @@ async def general_exception_handler(request: Request, exc: Exception) -> HTMLRes request, template_name, {"message": message}, status_code=status_code, headers=response_headers ) except Exception: + logger.exception("Can not display error template") response = templates.TemplateResponse( request, fallback_template_name, diff --git a/amt/locale/base.pot b/amt/locale/base.pot index 36de6717..8ba12e3d 100644 --- a/amt/locale/base.pot +++ b/amt/locale/base.pot @@ -48,7 +48,7 @@ msgstr "" #: amt/api/group_by_category.py:15 #: amt/site/templates/algorithms/details_info.html.j2:28 #: amt/site/templates/algorithms/new.html.j2:41 -#: amt/site/templates/parts/algorithm_search.html.j2:47 +#: amt/site/templates/parts/algorithm_search.html.j2:48 #: amt/site/templates/parts/filter_list.html.j2:71 msgid "Lifecycle" msgstr "" @@ -126,7 +126,7 @@ msgstr "" msgid "Details" msgstr "" -#: amt/api/navigation.py:56 +#: amt/api/navigation.py:56 amt/site/templates/organizations/home.html.j2:8 msgid "Info" msgstr "" @@ -155,7 +155,7 @@ msgstr "" msgid "Organizations" msgstr "" -#: amt/api/navigation.py:64 amt/site/templates/organizations/home.html.j2:32 +#: amt/api/navigation.py:64 amt/site/templates/organizations/home.html.j2:33 #: amt/site/templates/organizations/parts/members_results.html.j2:6 #: amt/site/templates/organizations/parts/overview_results.html.j2:132 msgid "Members" @@ -189,11 +189,11 @@ msgstr "" msgid "niet van toepassing" msgstr "" -#: amt/api/forms/algorithm.py:19 +#: amt/api/forms/algorithm.py:23 msgid "Select organization" msgstr "" -#: amt/api/forms/algorithm.py:25 +#: amt/api/forms/algorithm.py:29 #: amt/site/templates/algorithms/details_info.html.j2:12 msgid "Organization" msgstr "" @@ -243,7 +243,7 @@ msgstr "" #: amt/api/forms/organization.py:23 #: amt/site/templates/algorithms/details_info.html.j2:8 #: amt/site/templates/auth/profile.html.j2:34 -#: amt/site/templates/organizations/home.html.j2:12 +#: amt/site/templates/organizations/home.html.j2:13 #: amt/site/templates/organizations/parts/members_results.html.j2:118 msgid "Name" msgstr "" @@ -257,7 +257,7 @@ msgid "The slug is the web path, like /organizations/my-organization-name" msgstr "" #: amt/api/forms/organization.py:33 -#: amt/site/templates/organizations/home.html.j2:16 +#: amt/site/templates/organizations/home.html.j2:17 msgid "Slug" msgstr "" @@ -291,6 +291,10 @@ msgstr "" msgid "String should match pattern '{pattern}'" msgstr "" +#: amt/core/exception_handlers.py:24 +msgid "Input should be a valid integer." +msgstr "" + #: amt/core/exceptions.py:20 msgid "" "An error occurred while configuring the options for '{field}'. Please " @@ -504,12 +508,12 @@ msgstr "" msgid "Read more on the algoritmekader" msgstr "" -#: amt/site/templates/algorithms/details_measure_modal.html.j2:63 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:64 #: amt/site/templates/macros/editable.html.j2:82 msgid "Save" msgstr "" -#: amt/site/templates/algorithms/details_measure_modal.html.j2:67 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:68 #: amt/site/templates/macros/editable.html.j2:87 #: amt/site/templates/organizations/parts/add_members_modal.html.j2:26 msgid "Cancel" @@ -631,6 +635,7 @@ msgid "Login" msgstr "" #: amt/site/templates/errors/Exception.html.j2:5 +#: amt/site/templates/errors/RequestValidationError_400.html.j2:5 msgid "An error occurred" msgstr "" @@ -647,7 +652,7 @@ msgstr "" msgid "There is one error:" msgstr "" -#: amt/site/templates/layouts/base.html.j2:11 +#: amt/site/templates/layouts/base.html.j2:1 msgid "Algorithmic Management Toolkit (AMT)" msgstr "" @@ -695,15 +700,15 @@ msgstr "" msgid "Unknown" msgstr "" -#: amt/site/templates/organizations/home.html.j2:20 +#: amt/site/templates/organizations/home.html.j2:21 msgid "Created at" msgstr "" -#: amt/site/templates/organizations/home.html.j2:24 +#: amt/site/templates/organizations/home.html.j2:25 msgid "Created by" msgstr "" -#: amt/site/templates/organizations/home.html.j2:28 +#: amt/site/templates/organizations/home.html.j2:29 msgid "Modified at" msgstr "" @@ -722,7 +727,7 @@ msgstr "" #: amt/site/templates/organizations/parts/members_results.html.j2:29 #: amt/site/templates/organizations/parts/overview_results.html.j2:26 -#: amt/site/templates/parts/algorithm_search.html.j2:24 +#: amt/site/templates/parts/algorithm_search.html.j2:25 msgid "Search" msgstr "" @@ -866,31 +871,31 @@ msgstr "" msgid "This page is yet to be build." msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:14 +#: amt/site/templates/parts/algorithm_search.html.j2:15 msgid "New algorithm" msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:31 +#: amt/site/templates/parts/algorithm_search.html.j2:32 msgid "Find algorithm..." msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:52 +#: amt/site/templates/parts/algorithm_search.html.j2:53 msgid "Select lifecycle" msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:61 +#: amt/site/templates/parts/algorithm_search.html.j2:62 msgid "Category" msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:66 +#: amt/site/templates/parts/algorithm_search.html.j2:67 msgid "Select risk group" msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:82 +#: amt/site/templates/parts/algorithm_search.html.j2:83 msgid "Group by" msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:92 +#: amt/site/templates/parts/algorithm_search.html.j2:88 msgid "Select group by" msgstr "" @@ -915,6 +920,10 @@ msgid "" " algorithms." msgstr "" +#: amt/site/templates/parts/filter_list.html.j2:116 +msgid "Does not exist" +msgstr "" + #: amt/site/templates/parts/header.html.j2:7 msgid "Beta Version" msgstr "" diff --git a/amt/locale/en_US/LC_MESSAGES/messages.mo b/amt/locale/en_US/LC_MESSAGES/messages.mo index 738f59d7..9948b9f6 100644 Binary files a/amt/locale/en_US/LC_MESSAGES/messages.mo and b/amt/locale/en_US/LC_MESSAGES/messages.mo differ diff --git a/amt/locale/en_US/LC_MESSAGES/messages.po b/amt/locale/en_US/LC_MESSAGES/messages.po index 64b4dda5..bee1995d 100644 --- a/amt/locale/en_US/LC_MESSAGES/messages.po +++ b/amt/locale/en_US/LC_MESSAGES/messages.po @@ -49,7 +49,7 @@ msgstr "" #: amt/api/group_by_category.py:15 #: amt/site/templates/algorithms/details_info.html.j2:28 #: amt/site/templates/algorithms/new.html.j2:41 -#: amt/site/templates/parts/algorithm_search.html.j2:47 +#: amt/site/templates/parts/algorithm_search.html.j2:48 #: amt/site/templates/parts/filter_list.html.j2:71 msgid "Lifecycle" msgstr "" @@ -127,7 +127,7 @@ msgstr "" msgid "Details" msgstr "" -#: amt/api/navigation.py:56 +#: amt/api/navigation.py:56 amt/site/templates/organizations/home.html.j2:8 msgid "Info" msgstr "" @@ -156,7 +156,7 @@ msgstr "" msgid "Organizations" msgstr "" -#: amt/api/navigation.py:64 amt/site/templates/organizations/home.html.j2:32 +#: amt/api/navigation.py:64 amt/site/templates/organizations/home.html.j2:33 #: amt/site/templates/organizations/parts/members_results.html.j2:6 #: amt/site/templates/organizations/parts/overview_results.html.j2:132 msgid "Members" @@ -190,11 +190,11 @@ msgstr "Exception of application" msgid "niet van toepassing" msgstr "Not applicable" -#: amt/api/forms/algorithm.py:19 +#: amt/api/forms/algorithm.py:23 msgid "Select organization" msgstr "" -#: amt/api/forms/algorithm.py:25 +#: amt/api/forms/algorithm.py:29 #: amt/site/templates/algorithms/details_info.html.j2:12 msgid "Organization" msgstr "" @@ -244,7 +244,7 @@ msgstr "" #: amt/api/forms/organization.py:23 #: amt/site/templates/algorithms/details_info.html.j2:8 #: amt/site/templates/auth/profile.html.j2:34 -#: amt/site/templates/organizations/home.html.j2:12 +#: amt/site/templates/organizations/home.html.j2:13 #: amt/site/templates/organizations/parts/members_results.html.j2:118 msgid "Name" msgstr "" @@ -258,7 +258,7 @@ msgid "The slug is the web path, like /organizations/my-organization-name" msgstr "" #: amt/api/forms/organization.py:33 -#: amt/site/templates/organizations/home.html.j2:16 +#: amt/site/templates/organizations/home.html.j2:17 msgid "Slug" msgstr "" @@ -292,6 +292,10 @@ msgstr "" msgid "String should match pattern '{pattern}'" msgstr "" +#: amt/core/exception_handlers.py:24 +msgid "Input should be a valid integer." +msgstr "" + #: amt/core/exceptions.py:20 msgid "" "An error occurred while configuring the options for '{field}'. Please " @@ -505,12 +509,12 @@ msgstr "" msgid "Read more on the algoritmekader" msgstr "" -#: amt/site/templates/algorithms/details_measure_modal.html.j2:63 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:64 #: amt/site/templates/macros/editable.html.j2:82 msgid "Save" msgstr "" -#: amt/site/templates/algorithms/details_measure_modal.html.j2:67 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:68 #: amt/site/templates/macros/editable.html.j2:87 #: amt/site/templates/organizations/parts/add_members_modal.html.j2:26 msgid "Cancel" @@ -632,6 +636,7 @@ msgid "Login" msgstr "" #: amt/site/templates/errors/Exception.html.j2:5 +#: amt/site/templates/errors/RequestValidationError_400.html.j2:5 msgid "An error occurred" msgstr "" @@ -648,7 +653,7 @@ msgstr "" msgid "There is one error:" msgstr "" -#: amt/site/templates/layouts/base.html.j2:11 +#: amt/site/templates/layouts/base.html.j2:1 msgid "Algorithmic Management Toolkit (AMT)" msgstr "" @@ -696,15 +701,15 @@ msgstr "" msgid "Unknown" msgstr "" -#: amt/site/templates/organizations/home.html.j2:20 +#: amt/site/templates/organizations/home.html.j2:21 msgid "Created at" msgstr "" -#: amt/site/templates/organizations/home.html.j2:24 +#: amt/site/templates/organizations/home.html.j2:25 msgid "Created by" msgstr "" -#: amt/site/templates/organizations/home.html.j2:28 +#: amt/site/templates/organizations/home.html.j2:29 msgid "Modified at" msgstr "" @@ -723,7 +728,7 @@ msgstr "" #: amt/site/templates/organizations/parts/members_results.html.j2:29 #: amt/site/templates/organizations/parts/overview_results.html.j2:26 -#: amt/site/templates/parts/algorithm_search.html.j2:24 +#: amt/site/templates/parts/algorithm_search.html.j2:25 msgid "Search" msgstr "" @@ -867,31 +872,31 @@ msgstr "" msgid "This page is yet to be build." msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:14 +#: amt/site/templates/parts/algorithm_search.html.j2:15 msgid "New algorithm" msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:31 +#: amt/site/templates/parts/algorithm_search.html.j2:32 msgid "Find algorithm..." msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:52 +#: amt/site/templates/parts/algorithm_search.html.j2:53 msgid "Select lifecycle" msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:61 +#: amt/site/templates/parts/algorithm_search.html.j2:62 msgid "Category" msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:66 +#: amt/site/templates/parts/algorithm_search.html.j2:67 msgid "Select risk group" msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:82 +#: amt/site/templates/parts/algorithm_search.html.j2:83 msgid "Group by" msgstr "" -#: amt/site/templates/parts/algorithm_search.html.j2:92 +#: amt/site/templates/parts/algorithm_search.html.j2:88 msgid "Select group by" msgstr "" @@ -916,6 +921,10 @@ msgid "" " algorithms." msgstr "" +#: amt/site/templates/parts/filter_list.html.j2:116 +msgid "Does not exist" +msgstr "" + #: amt/site/templates/parts/header.html.j2:7 msgid "Beta Version" msgstr "" diff --git a/amt/locale/nl_NL/LC_MESSAGES/messages.mo b/amt/locale/nl_NL/LC_MESSAGES/messages.mo index 87b5523a..b7171443 100644 Binary files a/amt/locale/nl_NL/LC_MESSAGES/messages.mo and b/amt/locale/nl_NL/LC_MESSAGES/messages.mo differ diff --git a/amt/locale/nl_NL/LC_MESSAGES/messages.po b/amt/locale/nl_NL/LC_MESSAGES/messages.po index 9a794fa7..f4210748 100644 --- a/amt/locale/nl_NL/LC_MESSAGES/messages.po +++ b/amt/locale/nl_NL/LC_MESSAGES/messages.po @@ -51,7 +51,7 @@ msgstr "Rol" #: amt/api/group_by_category.py:15 #: amt/site/templates/algorithms/details_info.html.j2:28 #: amt/site/templates/algorithms/new.html.j2:41 -#: amt/site/templates/parts/algorithm_search.html.j2:47 +#: amt/site/templates/parts/algorithm_search.html.j2:48 #: amt/site/templates/parts/filter_list.html.j2:71 msgid "Lifecycle" msgstr "Levenscyclus" @@ -129,7 +129,7 @@ msgstr "Model kaart" msgid "Details" msgstr "Details" -#: amt/api/navigation.py:56 +#: amt/api/navigation.py:56 amt/site/templates/organizations/home.html.j2:8 msgid "Info" msgstr "Info" @@ -158,7 +158,7 @@ msgstr "Instrumenten" msgid "Organizations" msgstr "Organisaties" -#: amt/api/navigation.py:64 amt/site/templates/organizations/home.html.j2:32 +#: amt/api/navigation.py:64 amt/site/templates/organizations/home.html.j2:33 #: amt/site/templates/organizations/parts/members_results.html.j2:6 #: amt/site/templates/organizations/parts/overview_results.html.j2:132 msgid "Members" @@ -192,11 +192,11 @@ msgstr "Uitzondering van toepassing" msgid "niet van toepassing" msgstr "Niet van toepassing" -#: amt/api/forms/algorithm.py:19 +#: amt/api/forms/algorithm.py:23 msgid "Select organization" msgstr "Selecteer organisatie" -#: amt/api/forms/algorithm.py:25 +#: amt/api/forms/algorithm.py:29 #: amt/site/templates/algorithms/details_info.html.j2:12 msgid "Organization" msgstr "Organisatie" @@ -248,7 +248,7 @@ msgstr "Voeg link naar bestanden toe" #: amt/api/forms/organization.py:23 #: amt/site/templates/algorithms/details_info.html.j2:8 #: amt/site/templates/auth/profile.html.j2:34 -#: amt/site/templates/organizations/home.html.j2:12 +#: amt/site/templates/organizations/home.html.j2:13 #: amt/site/templates/organizations/parts/members_results.html.j2:118 msgid "Name" msgstr "Naam" @@ -264,7 +264,7 @@ msgstr "" "organisatie-naam" #: amt/api/forms/organization.py:33 -#: amt/site/templates/organizations/home.html.j2:16 +#: amt/site/templates/organizations/home.html.j2:17 msgid "Slug" msgstr "Slug" @@ -298,6 +298,10 @@ msgstr "Veld verplicht" msgid "String should match pattern '{pattern}'" msgstr "De waarde moet voldoen aan het patroon '{pattern}'" +#: amt/core/exception_handlers.py:24 +msgid "Input should be a valid integer." +msgstr "Invoer moet een valide getal zijn." + #: amt/core/exceptions.py:20 msgid "" "An error occurred while configuring the options for '{field}'. Please " @@ -523,12 +527,12 @@ msgstr "Referenties" msgid "Read more on the algoritmekader" msgstr "Lees meer op het algoritmekader" -#: amt/site/templates/algorithms/details_measure_modal.html.j2:63 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:64 #: amt/site/templates/macros/editable.html.j2:82 msgid "Save" msgstr "Opslaan" -#: amt/site/templates/algorithms/details_measure_modal.html.j2:67 +#: amt/site/templates/algorithms/details_measure_modal.html.j2:68 #: amt/site/templates/macros/editable.html.j2:87 #: amt/site/templates/organizations/parts/add_members_modal.html.j2:26 msgid "Cancel" @@ -655,6 +659,7 @@ msgid "Login" msgstr "Inloggen" #: amt/site/templates/errors/Exception.html.j2:5 +#: amt/site/templates/errors/RequestValidationError_400.html.j2:5 msgid "An error occurred" msgstr "Er is een fout opgetreden" @@ -671,7 +676,7 @@ msgstr "Er zijn enkele fouten" msgid "There is one error:" msgstr "Er is één fout:" -#: amt/site/templates/layouts/base.html.j2:11 +#: amt/site/templates/layouts/base.html.j2:1 msgid "Algorithmic Management Toolkit (AMT)" msgstr "Algoritme Management Toolkit" @@ -719,15 +724,15 @@ msgstr "Beoordelen" msgid "Unknown" msgstr "Onbekend" -#: amt/site/templates/organizations/home.html.j2:20 +#: amt/site/templates/organizations/home.html.j2:21 msgid "Created at" msgstr "Aangemaakt op" -#: amt/site/templates/organizations/home.html.j2:24 +#: amt/site/templates/organizations/home.html.j2:25 msgid "Created by" msgstr "Aangemaakt door" -#: amt/site/templates/organizations/home.html.j2:28 +#: amt/site/templates/organizations/home.html.j2:29 msgid "Modified at" msgstr "Bijgewerkt op" @@ -746,7 +751,7 @@ msgstr "Voeg personen toe" #: amt/site/templates/organizations/parts/members_results.html.j2:29 #: amt/site/templates/organizations/parts/overview_results.html.j2:26 -#: amt/site/templates/parts/algorithm_search.html.j2:24 +#: amt/site/templates/parts/algorithm_search.html.j2:25 msgid "Search" msgstr "Zoek" @@ -897,31 +902,31 @@ msgstr "In ontwikkeling" msgid "This page is yet to be build." msgstr "Deze pagina is nog niet klaar." -#: amt/site/templates/parts/algorithm_search.html.j2:14 +#: amt/site/templates/parts/algorithm_search.html.j2:15 msgid "New algorithm" msgstr "Nieuw algoritme" -#: amt/site/templates/parts/algorithm_search.html.j2:31 +#: amt/site/templates/parts/algorithm_search.html.j2:32 msgid "Find algorithm..." msgstr "Vind algoritme..." -#: amt/site/templates/parts/algorithm_search.html.j2:52 +#: amt/site/templates/parts/algorithm_search.html.j2:53 msgid "Select lifecycle" msgstr "Selecteer levenscyclus" -#: amt/site/templates/parts/algorithm_search.html.j2:61 +#: amt/site/templates/parts/algorithm_search.html.j2:62 msgid "Category" msgstr "Categorie" -#: amt/site/templates/parts/algorithm_search.html.j2:66 +#: amt/site/templates/parts/algorithm_search.html.j2:67 msgid "Select risk group" msgstr "Selecteer groepering" -#: amt/site/templates/parts/algorithm_search.html.j2:82 +#: amt/site/templates/parts/algorithm_search.html.j2:83 msgid "Group by" msgstr "Groeperen op" -#: amt/site/templates/parts/algorithm_search.html.j2:92 +#: amt/site/templates/parts/algorithm_search.html.j2:88 msgid "Select group by" msgstr "Selecteer groepering" @@ -954,6 +959,10 @@ msgstr "" "Er zijn geen Algoritmes die overeen komen met de geselecteerde filters. " "Pas de filters aan of verwijder ze om meer algoritmes te zien." +#: amt/site/templates/parts/filter_list.html.j2:116 +msgid "Does not exist" +msgstr "Bestaat niet" + #: amt/site/templates/parts/header.html.j2:7 msgid "Beta Version" msgstr "Bètaversie" diff --git a/amt/repositories/algorithms.py b/amt/repositories/algorithms.py index c7e3a48c..e4edc874 100644 --- a/amt/repositories/algorithms.py +++ b/amt/repositories/algorithms.py @@ -90,6 +90,8 @@ async def paginate( # noqa Algorithm.system_card_json["ai_act_profile"]["risk_group"].as_string() == RiskGroup[value].value ) + case "organization-id": + statement = statement.filter(Algorithm.organization_id == int(value)) case _: raise TypeError(f"Unknown filter type with key: {key}") # noqa if sort: diff --git a/amt/site/static/ts/amt.ts b/amt/site/static/ts/amt.ts index 429ed072..c6fa62be 100644 --- a/amt/site/static/ts/amt.ts +++ b/amt/site/static/ts/amt.ts @@ -426,3 +426,5 @@ export function getFiles(element: HTMLInputElement, target_id: string) { } } } + +// for debugging htmx use -> htmx.logAll(); diff --git a/amt/site/templates/errors/RequestValidationError_400.html.j2 b/amt/site/templates/errors/RequestValidationError_400.html.j2 new file mode 100644 index 00000000..d19aa57b --- /dev/null +++ b/amt/site/templates/errors/RequestValidationError_400.html.j2 @@ -0,0 +1,9 @@ +{% extends 'layouts/base.html.j2' %} +{% block content %} +