api: optimise pagination in API schema (#6478)
This commit is contained in:
parent
efc660938c
commit
00fae2353c
|
@ -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