api: optimise pagination in API schema (#6478)
This commit is contained in:
		@ -2,6 +2,43 @@
 | 
				
			|||||||
from rest_framework import pagination
 | 
					from rest_framework import pagination
 | 
				
			||||||
from rest_framework.response import Response
 | 
					from rest_framework.response import Response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PAGINATION_COMPONENT_NAME = "Pagination"
 | 
				
			||||||
 | 
					PAGINATION_SCHEMA = {
 | 
				
			||||||
 | 
					    "type": "object",
 | 
				
			||||||
 | 
					    "properties": {
 | 
				
			||||||
 | 
					        "next": {
 | 
				
			||||||
 | 
					            "type": "number",
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "previous": {
 | 
				
			||||||
 | 
					            "type": "number",
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "count": {
 | 
				
			||||||
 | 
					            "type": "number",
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "current": {
 | 
				
			||||||
 | 
					            "type": "number",
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "total_pages": {
 | 
				
			||||||
 | 
					            "type": "number",
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "start_index": {
 | 
				
			||||||
 | 
					            "type": "number",
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "end_index": {
 | 
				
			||||||
 | 
					            "type": "number",
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "required": [
 | 
				
			||||||
 | 
					        "next",
 | 
				
			||||||
 | 
					        "previous",
 | 
				
			||||||
 | 
					        "count",
 | 
				
			||||||
 | 
					        "current",
 | 
				
			||||||
 | 
					        "total_pages",
 | 
				
			||||||
 | 
					        "start_index",
 | 
				
			||||||
 | 
					        "end_index",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Pagination(pagination.PageNumberPagination):
 | 
					class Pagination(pagination.PageNumberPagination):
 | 
				
			||||||
    """Pagination which includes total pages and current page"""
 | 
					    """Pagination which includes total pages and current page"""
 | 
				
			||||||
@ -35,41 +72,7 @@ class Pagination(pagination.PageNumberPagination):
 | 
				
			|||||||
        return {
 | 
					        return {
 | 
				
			||||||
            "type": "object",
 | 
					            "type": "object",
 | 
				
			||||||
            "properties": {
 | 
					            "properties": {
 | 
				
			||||||
                "pagination": {
 | 
					                "pagination": {"$ref": f"#/components/schemas/{PAGINATION_COMPONENT_NAME}"},
 | 
				
			||||||
                    "type": "object",
 | 
					 | 
				
			||||||
                    "properties": {
 | 
					 | 
				
			||||||
                        "next": {
 | 
					 | 
				
			||||||
                            "type": "number",
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "previous": {
 | 
					 | 
				
			||||||
                            "type": "number",
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "count": {
 | 
					 | 
				
			||||||
                            "type": "number",
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "current": {
 | 
					 | 
				
			||||||
                            "type": "number",
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "total_pages": {
 | 
					 | 
				
			||||||
                            "type": "number",
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "start_index": {
 | 
					 | 
				
			||||||
                            "type": "number",
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "end_index": {
 | 
					 | 
				
			||||||
                            "type": "number",
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    "required": [
 | 
					 | 
				
			||||||
                        "next",
 | 
					 | 
				
			||||||
                        "previous",
 | 
					 | 
				
			||||||
                        "count",
 | 
					 | 
				
			||||||
                        "current",
 | 
					 | 
				
			||||||
                        "total_pages",
 | 
					 | 
				
			||||||
                        "start_index",
 | 
					 | 
				
			||||||
                        "end_index",
 | 
					 | 
				
			||||||
                    ],
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "results": schema,
 | 
					                "results": schema,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "required": ["pagination", "results"],
 | 
					            "required": ["pagination", "results"],
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
"""Error Response schema, from https://github.com/axnsan12/drf-yasg/issues/224"""
 | 
					"""Error Response schema, from https://github.com/axnsan12/drf-yasg/issues/224"""
 | 
				
			||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
 | 
					from drf_spectacular.generators import SchemaGenerator
 | 
				
			||||||
from drf_spectacular.plumbing import (
 | 
					from drf_spectacular.plumbing import (
 | 
				
			||||||
    ResolvedComponent,
 | 
					    ResolvedComponent,
 | 
				
			||||||
    build_array_type,
 | 
					    build_array_type,
 | 
				
			||||||
@ -9,6 +10,8 @@ from drf_spectacular.plumbing import (
 | 
				
			|||||||
from drf_spectacular.settings import spectacular_settings
 | 
					from drf_spectacular.settings import spectacular_settings
 | 
				
			||||||
from drf_spectacular.types import OpenApiTypes
 | 
					from drf_spectacular.types import OpenApiTypes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from authentik.api.pagination import PAGINATION_COMPONENT_NAME, PAGINATION_SCHEMA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def build_standard_type(obj, **kwargs):
 | 
					def build_standard_type(obj, **kwargs):
 | 
				
			||||||
    """Build a basic type with optional add owns."""
 | 
					    """Build a basic type with optional add owns."""
 | 
				
			||||||
@ -36,7 +39,19 @@ VALIDATION_ERROR = build_object_type(
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def postprocess_schema_responses(result, generator, **kwargs):  # noqa: W0613
 | 
					def create_component(generator: SchemaGenerator, name, schema, type_=ResolvedComponent.SCHEMA):
 | 
				
			||||||
 | 
					    """Register a component and return a reference to it."""
 | 
				
			||||||
 | 
					    component = ResolvedComponent(
 | 
				
			||||||
 | 
					        name=name,
 | 
				
			||||||
 | 
					        type=type_,
 | 
				
			||||||
 | 
					        schema=schema,
 | 
				
			||||||
 | 
					        object=name,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    generator.registry.register_on_missing(component)
 | 
				
			||||||
 | 
					    return component
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def postprocess_schema_responses(result, generator: SchemaGenerator, **kwargs):  # noqa: W0613
 | 
				
			||||||
    """Workaround to set a default response for endpoints.
 | 
					    """Workaround to set a default response for endpoints.
 | 
				
			||||||
    Workaround suggested at
 | 
					    Workaround suggested at
 | 
				
			||||||
    <https://github.com/tfranzel/drf-spectacular/issues/119#issuecomment-656970357>
 | 
					    <https://github.com/tfranzel/drf-spectacular/issues/119#issuecomment-656970357>
 | 
				
			||||||
@ -44,19 +59,10 @@ def postprocess_schema_responses(result, generator, **kwargs):  # noqa: W0613
 | 
				
			|||||||
    <https://github.com/tfranzel/drf-spectacular/issues/101>.
 | 
					    <https://github.com/tfranzel/drf-spectacular/issues/101>.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def create_component(name, schema, type_=ResolvedComponent.SCHEMA):
 | 
					    create_component(generator, PAGINATION_COMPONENT_NAME, PAGINATION_SCHEMA)
 | 
				
			||||||
        """Register a component and return a reference to it."""
 | 
					 | 
				
			||||||
        component = ResolvedComponent(
 | 
					 | 
				
			||||||
            name=name,
 | 
					 | 
				
			||||||
            type=type_,
 | 
					 | 
				
			||||||
            schema=schema,
 | 
					 | 
				
			||||||
            object=name,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        generator.registry.register_on_missing(component)
 | 
					 | 
				
			||||||
        return component
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    generic_error = create_component("GenericError", GENERIC_ERROR)
 | 
					    generic_error = create_component(generator, "GenericError", GENERIC_ERROR)
 | 
				
			||||||
    validation_error = create_component("ValidationError", VALIDATION_ERROR)
 | 
					    validation_error = create_component(generator, "ValidationError", VALIDATION_ERROR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for path in result["paths"].values():
 | 
					    for path in result["paths"].values():
 | 
				
			||||||
        for method in path.values():
 | 
					        for method in path.values():
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2101
									
								
								schema.yml
									
									
									
									
									
								
							
							
						
						
									
										2101
									
								
								schema.yml
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -49,6 +49,8 @@ export class SystemTaskListPage extends TablePage<Task> {
 | 
				
			|||||||
                    startIndex: 1,
 | 
					                    startIndex: 1,
 | 
				
			||||||
                    endIndex: tasks.length,
 | 
					                    endIndex: tasks.length,
 | 
				
			||||||
                    current: page,
 | 
					                    current: page,
 | 
				
			||||||
 | 
					                    next: 0,
 | 
				
			||||||
 | 
					                    previous: 0,
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                results: tasks,
 | 
					                results: tasks,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
				
			|||||||
@ -47,6 +47,8 @@ export class DeleteObjectsTable<T> extends Table<T> {
 | 
				
			|||||||
                totalPages: 1,
 | 
					                totalPages: 1,
 | 
				
			||||||
                startIndex: 1,
 | 
					                startIndex: 1,
 | 
				
			||||||
                endIndex: this.objects.length,
 | 
					                endIndex: this.objects.length,
 | 
				
			||||||
 | 
					                next: 0,
 | 
				
			||||||
 | 
					                previous: 0,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            results: this.objects,
 | 
					            results: this.objects,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,6 @@ import "@goauthentik/elements/chips/Chip";
 | 
				
			|||||||
import "@goauthentik/elements/chips/ChipGroup";
 | 
					import "@goauthentik/elements/chips/ChipGroup";
 | 
				
			||||||
import { getURLParam, updateURLParams } from "@goauthentik/elements/router/RouteMatch";
 | 
					import { getURLParam, updateURLParams } from "@goauthentik/elements/router/RouteMatch";
 | 
				
			||||||
import "@goauthentik/elements/table/TablePagination";
 | 
					import "@goauthentik/elements/table/TablePagination";
 | 
				
			||||||
import { Pagination } from "@goauthentik/elements/table/TablePagination";
 | 
					 | 
				
			||||||
import "@goauthentik/elements/table/TableSearch";
 | 
					import "@goauthentik/elements/table/TableSearch";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { msg } from "@lit/localize";
 | 
					import { msg } from "@lit/localize";
 | 
				
			||||||
@ -24,6 +23,8 @@ import PFToolbar from "@patternfly/patternfly/components/Toolbar/toolbar.css";
 | 
				
			|||||||
import PFBullseye from "@patternfly/patternfly/layouts/Bullseye/bullseye.css";
 | 
					import PFBullseye from "@patternfly/patternfly/layouts/Bullseye/bullseye.css";
 | 
				
			||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
 | 
					import PFBase from "@patternfly/patternfly/patternfly-base.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Pagination } from "@goauthentik/api";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class TableColumn {
 | 
					export class TableColumn {
 | 
				
			||||||
    title: string;
 | 
					    title: string;
 | 
				
			||||||
    orderBy?: string;
 | 
					    orderBy?: string;
 | 
				
			||||||
 | 
				
			|||||||
@ -8,17 +8,7 @@ import PFButton from "@patternfly/patternfly/components/Button/button.css";
 | 
				
			|||||||
import PFPagination from "@patternfly/patternfly/components/Pagination/pagination.css";
 | 
					import PFPagination from "@patternfly/patternfly/components/Pagination/pagination.css";
 | 
				
			||||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
 | 
					import PFBase from "@patternfly/patternfly/patternfly-base.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface Pagination {
 | 
					import { Pagination } from "@goauthentik/api";
 | 
				
			||||||
    next?: number;
 | 
					 | 
				
			||||||
    previous?: number;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    count: number;
 | 
					 | 
				
			||||||
    current: number;
 | 
					 | 
				
			||||||
    totalPages: number;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    startIndex: number;
 | 
					 | 
				
			||||||
    endIndex: number;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@customElement("ak-table-pagination")
 | 
					@customElement("ak-table-pagination")
 | 
				
			||||||
export class TablePagination extends AKElement {
 | 
					export class TablePagination extends AKElement {
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,8 @@ export class UserDeviceList extends MFADevicesPage {
 | 
				
			|||||||
                        totalPages: 1,
 | 
					                        totalPages: 1,
 | 
				
			||||||
                        startIndex: 1,
 | 
					                        startIndex: 1,
 | 
				
			||||||
                        endIndex: res.length,
 | 
					                        endIndex: res.length,
 | 
				
			||||||
 | 
					                        next: 0,
 | 
				
			||||||
 | 
					                        previous: 0,
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    results: res,
 | 
					                    results: res,
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
				
			|||||||
@ -49,6 +49,8 @@ export class MFADevicesPage extends Table<Device> {
 | 
				
			|||||||
                totalPages: 1,
 | 
					                totalPages: 1,
 | 
				
			||||||
                startIndex: 1,
 | 
					                startIndex: 1,
 | 
				
			||||||
                endIndex: devices.length,
 | 
					                endIndex: devices.length,
 | 
				
			||||||
 | 
					                next: 0,
 | 
				
			||||||
 | 
					                previous: 0,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            results: devices,
 | 
					            results: devices,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user