brilliance-admin 0.41.0__py3-none-any.whl → 0.41.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {admin_panel → brilliance_admin}/__init__.py +2 -2
- brilliance_admin/api/routers.py +18 -0
- {admin_panel → brilliance_admin}/api/utils.py +1 -1
- {admin_panel → brilliance_admin}/api/views/auth.py +6 -6
- {admin_panel → brilliance_admin}/api/views/autocomplete.py +9 -9
- {admin_panel → brilliance_admin}/api/views/graphs.py +8 -8
- {admin_panel → brilliance_admin}/api/views/index.py +11 -4
- {admin_panel → brilliance_admin}/api/views/schema.py +3 -3
- {admin_panel → brilliance_admin}/api/views/settings.py +5 -5
- {admin_panel → brilliance_admin}/api/views/table.py +23 -23
- {admin_panel → brilliance_admin}/auth.py +1 -1
- {admin_panel → brilliance_admin}/exceptions.py +3 -4
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/auth.py +4 -4
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/autocomplete.py +4 -4
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/fields.py +10 -10
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/fields_schema.py +6 -6
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/table/base.py +4 -4
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/table/create.py +7 -7
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/table/delete.py +3 -3
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/table/list.py +7 -7
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/table/retrieve.py +6 -6
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/table/update.py +6 -6
- brilliance_admin/locales/en.yml +22 -0
- brilliance_admin/locales/ru.yml +22 -0
- {admin_panel → brilliance_admin}/schema/admin_schema.py +38 -30
- {admin_panel → brilliance_admin}/schema/category.py +8 -8
- {admin_panel → brilliance_admin}/schema/graphs/category_graphs.py +10 -9
- {admin_panel → brilliance_admin}/schema/group.py +10 -10
- {admin_panel → brilliance_admin}/schema/table/admin_action.py +8 -7
- {admin_panel → brilliance_admin}/schema/table/category_table.py +21 -21
- {admin_panel → brilliance_admin}/schema/table/fields/base.py +21 -21
- {admin_panel → brilliance_admin}/schema/table/fields/function_field.py +3 -3
- {admin_panel → brilliance_admin}/schema/table/fields_schema.py +9 -9
- {admin_panel → brilliance_admin}/schema/table/table_models.py +1 -1
- admin_panel/static/index-BeniOHDv.js → brilliance_admin/static/index-D9axz5zK.js +24 -24
- {admin_panel → brilliance_admin}/templates/index.html +1 -1
- brilliance_admin/translations.py +115 -0
- brilliance_admin/utils.py +153 -0
- brilliance_admin-0.41.2.dist-info/METADATA +214 -0
- brilliance_admin-0.41.2.dist-info/RECORD +74 -0
- brilliance_admin-0.41.2.dist-info/top_level.txt +1 -0
- admin_panel/api/routers.py +0 -18
- admin_panel/static/favicon.jpg +0 -0
- admin_panel/translations.py +0 -145
- admin_panel/utils.py +0 -50
- brilliance_admin-0.41.0.dist-info/METADATA +0 -155
- brilliance_admin-0.41.0.dist-info/RECORD +0 -73
- brilliance_admin-0.41.0.dist-info/top_level.txt +0 -1
- {admin_panel → brilliance_admin}/api/__init__.py +0 -0
- {admin_panel → brilliance_admin}/api/views/__init__.py +0 -0
- {admin_panel → brilliance_admin}/docs.py +0 -0
- {admin_panel → brilliance_admin}/integrations/__init__.py +0 -0
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/__init__.py +0 -0
- {admin_panel → brilliance_admin}/integrations/sqlalchemy/table/__init__.py +0 -0
- {admin_panel → brilliance_admin}/schema/__init__.py +0 -0
- {admin_panel → brilliance_admin}/schema/graphs/__init__.py +0 -0
- {admin_panel → brilliance_admin}/schema/table/__init__.py +0 -0
- {admin_panel → brilliance_admin}/schema/table/fields/__init__.py +0 -0
- {admin_panel → brilliance_admin}/static/index-vlBToOhT.css +0 -0
- {admin_panel → brilliance_admin}/static/materialdesignicons-webfont-CYDMK1kx.woff2 +0 -0
- {admin_panel → brilliance_admin}/static/materialdesignicons-webfont-CgCzGbLl.woff +0 -0
- {admin_panel → brilliance_admin}/static/materialdesignicons-webfont-D3kAzl71.ttf +0 -0
- {admin_panel → brilliance_admin}/static/materialdesignicons-webfont-DttUABo4.eot +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/dark-first/content.min.css +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/dark-first/skin.min.css +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/dark-slim/content.min.css +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/dark-slim/skin.min.css +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/img/example.png +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/img/tinymce.woff2 +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/lightgray/content.min.css +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/lightgray/fonts/tinymce.woff +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/lightgray/skin.min.css +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/plugins/accordion/css/accordion.css +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/plugins/accordion/plugin.js +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/plugins/codesample/css/prism.css +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/plugins/customLink/css/link.css +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/plugins/customLink/plugin.js +0 -0
- {admin_panel → brilliance_admin}/static/tinymce/tinymce.min.js +0 -0
- {admin_panel → brilliance_admin}/static/vanilla-picker-B6E6ObS_.js +0 -0
- {brilliance_admin-0.41.0.dist-info → brilliance_admin-0.41.2.dist-info}/WHEEL +0 -0
- {brilliance_admin-0.41.0.dist-info → brilliance_admin-0.41.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import importlib.metadata
|
|
2
2
|
import json
|
|
3
3
|
from importlib import resources
|
|
4
|
-
from typing import Any, Dict, List, Optional
|
|
4
|
+
from typing import Any, Dict, List, Optional
|
|
5
5
|
from urllib.parse import urljoin
|
|
6
6
|
|
|
7
7
|
from fastapi import FastAPI, Request
|
|
@@ -9,11 +9,16 @@ from fastapi.middleware.cors import CORSMiddleware
|
|
|
9
9
|
from fastapi.staticfiles import StaticFiles
|
|
10
10
|
from pydantic.dataclasses import dataclass
|
|
11
11
|
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
from
|
|
15
|
-
from
|
|
16
|
-
from
|
|
12
|
+
from brilliance_admin.auth import UserABC
|
|
13
|
+
from brilliance_admin.docs import build_redoc_docs, build_scalar_docs
|
|
14
|
+
from brilliance_admin.schema.group import Group, GroupSchemaData
|
|
15
|
+
from brilliance_admin.translations import LanguageContext, LanguageManager
|
|
16
|
+
from brilliance_admin.utils import DataclassBase, SupportsStr
|
|
17
|
+
|
|
18
|
+
DEFAULT_LANGUAGES = {
|
|
19
|
+
'ru': 'Russian',
|
|
20
|
+
'en': 'English',
|
|
21
|
+
}
|
|
17
22
|
|
|
18
23
|
|
|
19
24
|
@dataclass
|
|
@@ -29,9 +34,9 @@ class AdminSchemaData(DataclassBase):
|
|
|
29
34
|
# pylint: disable=too-many-instance-attributes
|
|
30
35
|
@dataclass
|
|
31
36
|
class AdminSettingsData(DataclassBase):
|
|
32
|
-
title:
|
|
33
|
-
description:
|
|
34
|
-
login_greetings_message:
|
|
37
|
+
title: SupportsStr
|
|
38
|
+
description: SupportsStr | None
|
|
39
|
+
login_greetings_message: SupportsStr | None
|
|
35
40
|
navbar_density: str
|
|
36
41
|
languages: Dict[str, str] | None
|
|
37
42
|
|
|
@@ -48,30 +53,33 @@ class AdminSchema:
|
|
|
48
53
|
groups: List[Group]
|
|
49
54
|
auth: Any
|
|
50
55
|
|
|
51
|
-
title:
|
|
52
|
-
description:
|
|
53
|
-
login_greetings_message:
|
|
56
|
+
title: SupportsStr | None = 'Admin'
|
|
57
|
+
description: SupportsStr | None = None
|
|
58
|
+
login_greetings_message: SupportsStr | None = None
|
|
54
59
|
|
|
55
60
|
logo_image: str | None = None
|
|
56
|
-
favicon_image: str =
|
|
61
|
+
favicon_image: str | None = None
|
|
57
62
|
|
|
58
63
|
navbar_density: str = 'default'
|
|
59
64
|
|
|
60
65
|
backend_prefix = None
|
|
61
66
|
static_prefix = None
|
|
62
67
|
|
|
63
|
-
|
|
68
|
+
language_manager: LanguageManager | None = None
|
|
64
69
|
|
|
65
70
|
def __post_init__(self):
|
|
66
71
|
for group in self.groups:
|
|
67
72
|
if not issubclass(group.__class__, Group):
|
|
68
73
|
raise TypeError(f'Group "{group}" is not instance of Group subclass')
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
|
|
75
|
+
if not self.language_manager:
|
|
76
|
+
self.language_manager = LanguageManager(DEFAULT_LANGUAGES)
|
|
77
|
+
|
|
78
|
+
def get_language_context(self, language_slug: str | None) -> LanguageContext:
|
|
79
|
+
return LanguageContext(language_slug, language_manager=self.language_manager)
|
|
72
80
|
|
|
73
81
|
def generate_schema(self, user: UserABC, language_slug: str | None) -> AdminSchemaData:
|
|
74
|
-
|
|
82
|
+
language_context: LanguageContext = self.get_language_context(language_slug)
|
|
75
83
|
|
|
76
84
|
groups = {}
|
|
77
85
|
|
|
@@ -80,7 +88,7 @@ class AdminSchema:
|
|
|
80
88
|
msg = f'Category group {type(group).__name__}.slug is empty'
|
|
81
89
|
raise AttributeError(msg)
|
|
82
90
|
|
|
83
|
-
groups[group.slug] = group.generate_schema(user,
|
|
91
|
+
groups[group.slug] = group.generate_schema(user, language_context)
|
|
84
92
|
|
|
85
93
|
return AdminSchemaData(
|
|
86
94
|
groups=groups,
|
|
@@ -96,13 +104,13 @@ class AdminSchema:
|
|
|
96
104
|
|
|
97
105
|
async def get_settings(self, request: Request) -> AdminSettingsData:
|
|
98
106
|
language_slug = request.headers.get('Accept-Language')
|
|
99
|
-
|
|
107
|
+
language_context: LanguageContext = self.get_language_context(language_slug)
|
|
100
108
|
|
|
101
109
|
languages = None
|
|
102
|
-
if language_manager.languages:
|
|
110
|
+
if self.language_manager.languages:
|
|
103
111
|
languages = {}
|
|
104
|
-
for k, v in language_manager.languages.items():
|
|
105
|
-
languages[k] =
|
|
112
|
+
for k, v in self.language_manager.languages.items():
|
|
113
|
+
languages[k] = v
|
|
106
114
|
|
|
107
115
|
return AdminSettingsData(
|
|
108
116
|
title=self.title,
|
|
@@ -124,11 +132,11 @@ class AdminSchema:
|
|
|
124
132
|
include_redoc=False,
|
|
125
133
|
) -> FastAPI:
|
|
126
134
|
# pylint: disable=unused-variable
|
|
127
|
-
|
|
135
|
+
language_context = self.get_language_context(language_slug=None)
|
|
128
136
|
|
|
129
137
|
app = FastAPI(
|
|
130
|
-
title=
|
|
131
|
-
description=
|
|
138
|
+
title=language_context.get_text(self.title),
|
|
139
|
+
description=language_context.get_text(self.description),
|
|
132
140
|
debug=debug,
|
|
133
141
|
docs_url='/docs' if include_docs else None,
|
|
134
142
|
redoc_url=None,
|
|
@@ -143,7 +151,7 @@ class AdminSchema:
|
|
|
143
151
|
allow_headers=["*"]
|
|
144
152
|
)
|
|
145
153
|
|
|
146
|
-
static_dir = resources.files("
|
|
154
|
+
static_dir = resources.files("brilliance_admin").joinpath("static")
|
|
147
155
|
app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
|
|
148
156
|
|
|
149
157
|
app.state.schema = self
|
|
@@ -155,14 +163,14 @@ class AdminSchema:
|
|
|
155
163
|
app.include_router(build_redoc_docs(app, redoc_url='/redoc'))
|
|
156
164
|
|
|
157
165
|
# pylint: disable=import-outside-toplevel
|
|
158
|
-
from
|
|
159
|
-
app.include_router(
|
|
166
|
+
from brilliance_admin.api.routers import brilliance_admin_router
|
|
167
|
+
app.include_router(brilliance_admin_router)
|
|
160
168
|
|
|
161
169
|
return app
|
|
162
170
|
|
|
163
171
|
async def get_index_context_data(self, request: Request) -> dict:
|
|
164
|
-
|
|
165
|
-
context = {'
|
|
172
|
+
language_context = self.get_language_context(language_slug=None)
|
|
173
|
+
context = {'language_context': language_context}
|
|
166
174
|
|
|
167
175
|
backend_prefix = self.backend_prefix
|
|
168
176
|
if not backend_prefix:
|
|
@@ -5,9 +5,9 @@ from pydantic import Field
|
|
|
5
5
|
from pydantic.dataclasses import dataclass
|
|
6
6
|
from pydantic_core import core_schema
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
from brilliance_admin.auth import UserABC
|
|
9
|
+
from brilliance_admin.translations import LanguageContext
|
|
10
|
+
from brilliance_admin.utils import DataclassBase, SupportsStr
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
# pylint: disable=too-many-instance-attributes
|
|
@@ -116,18 +116,18 @@ class CategorySchemaData(DataclassBase):
|
|
|
116
116
|
|
|
117
117
|
class Category(abc.ABC):
|
|
118
118
|
slug: ClassVar[str]
|
|
119
|
-
title: ClassVar[
|
|
120
|
-
description: ClassVar[
|
|
119
|
+
title: ClassVar[SupportsStr | None] = None
|
|
120
|
+
description: ClassVar[SupportsStr | None] = None
|
|
121
121
|
|
|
122
122
|
# https://pictogrammers.com/library/mdi/
|
|
123
123
|
icon: ClassVar[str | None] = None
|
|
124
124
|
|
|
125
125
|
_type_slug: ClassVar[str]
|
|
126
126
|
|
|
127
|
-
def generate_schema(self, user: UserABC,
|
|
127
|
+
def generate_schema(self, user: UserABC, language_context: LanguageContext) -> CategorySchemaData:
|
|
128
128
|
return CategorySchemaData(
|
|
129
|
-
title=
|
|
130
|
-
description=
|
|
129
|
+
title=language_context.get_text(self.title) or self.slug,
|
|
130
|
+
description=language_context.get_text(self.description),
|
|
131
131
|
icon=self.icon,
|
|
132
132
|
type=self._type_slug,
|
|
133
133
|
)
|
|
@@ -2,10 +2,11 @@ from typing import Any, Dict, List
|
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel, Field
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
5
|
+
from brilliance_admin.schema import Category
|
|
6
|
+
from brilliance_admin.schema.category import GraphInfoSchemaData
|
|
7
|
+
from brilliance_admin.schema.table.fields_schema import FieldsSchema
|
|
8
|
+
from brilliance_admin.translations import LanguageContext
|
|
9
|
+
from brilliance_admin.utils import SupportsStr
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class GraphData(BaseModel):
|
|
@@ -29,19 +30,19 @@ class CategoryGraphs(Category):
|
|
|
29
30
|
_type_slug: str = 'graphs'
|
|
30
31
|
|
|
31
32
|
search_enabled: bool = False
|
|
32
|
-
search_help:
|
|
33
|
+
search_help: SupportsStr | None = None
|
|
33
34
|
|
|
34
35
|
table_filters: FieldsSchema | None = None
|
|
35
36
|
|
|
36
|
-
def generate_schema(self, user,
|
|
37
|
-
schema = super().generate_schema(user,
|
|
37
|
+
def generate_schema(self, user, language_context: LanguageContext) -> GraphInfoSchemaData:
|
|
38
|
+
schema = super().generate_schema(user, language_context)
|
|
38
39
|
graph = GraphInfoSchemaData(
|
|
39
40
|
search_enabled=self.search_enabled,
|
|
40
|
-
search_help=
|
|
41
|
+
search_help=language_context.get_text(self.search_help),
|
|
41
42
|
)
|
|
42
43
|
|
|
43
44
|
if self.table_filters:
|
|
44
|
-
graph.table_filters = self.table_filters.generate_schema(user,
|
|
45
|
+
graph.table_filters = self.table_filters.generate_schema(user, language_context)
|
|
45
46
|
|
|
46
47
|
schema.graph_info = graph
|
|
47
48
|
return schema
|
|
@@ -3,10 +3,10 @@ from typing import Dict, List
|
|
|
3
3
|
|
|
4
4
|
from pydantic.dataclasses import dataclass
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
from
|
|
6
|
+
from brilliance_admin.auth import UserABC
|
|
7
|
+
from brilliance_admin.schema.category import Category, CategorySchemaData
|
|
8
|
+
from brilliance_admin.translations import LanguageContext
|
|
9
|
+
from brilliance_admin.utils import DataclassBase, SupportsStr, get_logger
|
|
10
10
|
|
|
11
11
|
logger = get_logger()
|
|
12
12
|
|
|
@@ -23,8 +23,8 @@ class GroupSchemaData(DataclassBase):
|
|
|
23
23
|
class Group(abc.ABC):
|
|
24
24
|
categories: List[Category]
|
|
25
25
|
slug: str
|
|
26
|
-
title:
|
|
27
|
-
description:
|
|
26
|
+
title: SupportsStr | None = None
|
|
27
|
+
description: SupportsStr | None = None
|
|
28
28
|
|
|
29
29
|
# https://pictogrammers.com/library/mdi/
|
|
30
30
|
icon: str | None = None
|
|
@@ -34,10 +34,10 @@ class Group(abc.ABC):
|
|
|
34
34
|
if not issubclass(category.__class__, Category):
|
|
35
35
|
raise TypeError(f'Category "{category}" is not instance of Category subclass')
|
|
36
36
|
|
|
37
|
-
def generate_schema(self, user: UserABC,
|
|
37
|
+
def generate_schema(self, user: UserABC, language_context: LanguageContext) -> GroupSchemaData:
|
|
38
38
|
result = GroupSchemaData(
|
|
39
|
-
title=
|
|
40
|
-
description=
|
|
39
|
+
title=language_context.get_text(self.title) or self.slug,
|
|
40
|
+
description=language_context.get_text(self.description),
|
|
41
41
|
icon=self.icon,
|
|
42
42
|
categories={},
|
|
43
43
|
)
|
|
@@ -55,7 +55,7 @@ class Group(abc.ABC):
|
|
|
55
55
|
msg = f'Category {type(category).__name__}.slug "{self.slug}" already registered by "{exists.title}"'
|
|
56
56
|
raise KeyError(msg)
|
|
57
57
|
|
|
58
|
-
result.categories[category.slug] = category.generate_schema(user,
|
|
58
|
+
result.categories[category.slug] = category.generate_schema(user, language_context)
|
|
59
59
|
|
|
60
60
|
return result
|
|
61
61
|
|
|
@@ -4,8 +4,9 @@ from typing import Any, Dict, List, Optional
|
|
|
4
4
|
from pydantic import BaseModel, Field, validate_call
|
|
5
5
|
from pydantic.dataclasses import dataclass
|
|
6
6
|
|
|
7
|
-
from
|
|
8
|
-
from
|
|
7
|
+
from brilliance_admin.schema.table.fields_schema import FieldsSchema
|
|
8
|
+
from brilliance_admin.translations import DataclassBase
|
|
9
|
+
from brilliance_admin.utils import SupportsStr
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class ActionData(BaseModel):
|
|
@@ -20,7 +21,7 @@ class ActionData(BaseModel):
|
|
|
20
21
|
|
|
21
22
|
@dataclass
|
|
22
23
|
class ActionMessage(DataclassBase):
|
|
23
|
-
text:
|
|
24
|
+
text: SupportsStr
|
|
24
25
|
type: str = 'success'
|
|
25
26
|
position: str = 'top-center'
|
|
26
27
|
|
|
@@ -28,16 +29,16 @@ class ActionMessage(DataclassBase):
|
|
|
28
29
|
@dataclass
|
|
29
30
|
class ActionResult(DataclassBase):
|
|
30
31
|
message: ActionMessage | None = None
|
|
31
|
-
persistent_message:
|
|
32
|
+
persistent_message: SupportsStr | None = None
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
# pylint: disable=too-many-arguments
|
|
35
36
|
# pylint: disable=too-many-positional-arguments
|
|
36
37
|
@validate_call
|
|
37
38
|
def admin_action(
|
|
38
|
-
title:
|
|
39
|
-
description: Optional[
|
|
40
|
-
confirmation_text: Optional[
|
|
39
|
+
title: SupportsStr,
|
|
40
|
+
description: Optional[SupportsStr] = None,
|
|
41
|
+
confirmation_text: Optional[SupportsStr] = None,
|
|
41
42
|
|
|
42
43
|
# https://vuetifyjs.com/en/styles/colors/#material-colors
|
|
43
44
|
base_color: Optional[str] = None,
|
|
@@ -6,22 +6,22 @@ from typing import Awaitable, List
|
|
|
6
6
|
from fastapi import HTTPException, Request
|
|
7
7
|
from pydantic import Field
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
from
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
from
|
|
15
|
-
from
|
|
16
|
-
from
|
|
17
|
-
from
|
|
9
|
+
from brilliance_admin.auth import UserABC
|
|
10
|
+
from brilliance_admin.exceptions import AdminAPIException, APIError
|
|
11
|
+
from brilliance_admin.schema import Category
|
|
12
|
+
from brilliance_admin.schema.category import TableInfoSchemaData
|
|
13
|
+
from brilliance_admin.schema.table.admin_action import ActionData, ActionResult
|
|
14
|
+
from brilliance_admin.schema.table.fields_schema import FieldsSchema
|
|
15
|
+
from brilliance_admin.schema.table.table_models import AutocompleteData, AutocompleteResult, ListData, TableListResult
|
|
16
|
+
from brilliance_admin.translations import LanguageContext
|
|
17
|
+
from brilliance_admin.utils import DeserializeAction, SupportsStr
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class CategoryTable(Category):
|
|
21
21
|
_type_slug: str = 'table'
|
|
22
22
|
|
|
23
23
|
search_enabled: bool = False
|
|
24
|
-
search_help:
|
|
24
|
+
search_help: SupportsStr | None = None
|
|
25
25
|
|
|
26
26
|
table_schema: FieldsSchema = None
|
|
27
27
|
table_filters: FieldsSchema | None = None
|
|
@@ -60,20 +60,20 @@ class CategoryTable(Category):
|
|
|
60
60
|
fn = getattr(self, 'update', None)
|
|
61
61
|
return asyncio.iscoroutinefunction(fn)
|
|
62
62
|
|
|
63
|
-
def generate_schema(self, user,
|
|
64
|
-
schema = super().generate_schema(user,
|
|
63
|
+
def generate_schema(self, user, language_context: LanguageContext) -> dict:
|
|
64
|
+
schema = super().generate_schema(user, language_context)
|
|
65
65
|
|
|
66
66
|
table_schema = getattr(self, 'table_schema', None)
|
|
67
67
|
if not table_schema or not issubclass(table_schema.__class__, FieldsSchema):
|
|
68
68
|
raise AttributeError(f'Admin category {self.__class__} must have table_schema instance of FieldsSchema')
|
|
69
69
|
|
|
70
70
|
table = TableInfoSchemaData(
|
|
71
|
-
table_schema=self.table_schema.generate_schema(user,
|
|
71
|
+
table_schema=self.table_schema.generate_schema(user, language_context),
|
|
72
72
|
ordering_fields=self.ordering_fields,
|
|
73
73
|
default_ordering=self.default_ordering,
|
|
74
74
|
|
|
75
75
|
search_enabled=self.search_enabled,
|
|
76
|
-
search_help=
|
|
76
|
+
search_help=language_context.get_text(self.search_help),
|
|
77
77
|
|
|
78
78
|
pk_name=self.pk_name,
|
|
79
79
|
can_retrieve=self.has_retrieve,
|
|
@@ -83,7 +83,7 @@ class CategoryTable(Category):
|
|
|
83
83
|
)
|
|
84
84
|
|
|
85
85
|
if self.table_filters:
|
|
86
|
-
table.table_filters = self.table_filters.generate_schema(user,
|
|
86
|
+
table.table_filters = self.table_filters.generate_schema(user, language_context)
|
|
87
87
|
|
|
88
88
|
actions = {}
|
|
89
89
|
for attribute_name in dir(self):
|
|
@@ -94,14 +94,14 @@ class CategoryTable(Category):
|
|
|
94
94
|
if asyncio.iscoroutinefunction(attribute) and getattr(attribute, '__action__', False):
|
|
95
95
|
action = copy.copy(attribute.action_info)
|
|
96
96
|
|
|
97
|
-
action['title'] =
|
|
98
|
-
action['description'] =
|
|
99
|
-
action['confirmation_text'] =
|
|
97
|
+
action['title'] = language_context.get_text(action.get('title'))
|
|
98
|
+
action['description'] = language_context.get_text(action.get('description'))
|
|
99
|
+
action['confirmation_text'] = language_context.get_text(action.get('confirmation_text'))
|
|
100
100
|
|
|
101
101
|
form_schema = action['form_schema']
|
|
102
102
|
if form_schema:
|
|
103
103
|
try:
|
|
104
|
-
action['form_schema'] = form_schema.generate_schema(user,
|
|
104
|
+
action['form_schema'] = form_schema.generate_schema(user, language_context)
|
|
105
105
|
except Exception as e:
|
|
106
106
|
msg = f'Action {attribute} form schema {form_schema} error: {e}'
|
|
107
107
|
raise Exception(msg) from e
|
|
@@ -126,7 +126,7 @@ class CategoryTable(Category):
|
|
|
126
126
|
request: Request,
|
|
127
127
|
action: str,
|
|
128
128
|
action_data: ActionData,
|
|
129
|
-
|
|
129
|
+
language_context: LanguageContext,
|
|
130
130
|
user: UserABC,
|
|
131
131
|
) -> ActionResult:
|
|
132
132
|
action_fn = self._get_action_fn(action)
|
|
@@ -162,7 +162,7 @@ class CategoryTable(Category):
|
|
|
162
162
|
|
|
163
163
|
# pylint: disable=too-many-arguments
|
|
164
164
|
@abc.abstractmethod
|
|
165
|
-
async def get_list(self, list_data: ListData, user: UserABC,
|
|
165
|
+
async def get_list(self, list_data: ListData, user: UserABC, language_context: LanguageContext) -> TableListResult:
|
|
166
166
|
raise NotImplementedError()
|
|
167
167
|
|
|
168
168
|
# async def retrieve(self, pk: Any, user: UserABC) -> RetrieveResult:
|
|
@@ -4,24 +4,24 @@ from typing import Any, ClassVar, List, Tuple
|
|
|
4
4
|
|
|
5
5
|
from pydantic.dataclasses import dataclass
|
|
6
6
|
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
7
|
+
from brilliance_admin.exceptions import FieldError
|
|
8
|
+
from brilliance_admin.schema.category import FieldSchemaData
|
|
9
|
+
from brilliance_admin.translations import LanguageContext
|
|
10
|
+
from brilliance_admin.utils import DeserializeAction, SupportsStr, humanize_field_name
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
@dataclass
|
|
14
14
|
class TableField(abc.ABC, FieldSchemaData):
|
|
15
15
|
_type: ClassVar[str]
|
|
16
16
|
|
|
17
|
-
label:
|
|
18
|
-
help_text:
|
|
17
|
+
label: SupportsStr | None = None
|
|
18
|
+
help_text: SupportsStr | None = None
|
|
19
19
|
|
|
20
|
-
def generate_schema(self, user, field_slug,
|
|
20
|
+
def generate_schema(self, user, field_slug, language_context: LanguageContext) -> FieldSchemaData:
|
|
21
21
|
schema = FieldSchemaData(
|
|
22
22
|
type=self._type,
|
|
23
|
-
label=
|
|
24
|
-
help_text=
|
|
23
|
+
label=language_context.get_text(self.label) or humanize_field_name(field_slug),
|
|
24
|
+
help_text=language_context.get_text(self.help_text),
|
|
25
25
|
header=self.header,
|
|
26
26
|
read_only=self.read_only,
|
|
27
27
|
default=self.default,
|
|
@@ -59,8 +59,8 @@ class IntegerField(TableField):
|
|
|
59
59
|
precision: int | None = None
|
|
60
60
|
scale: int | None = None
|
|
61
61
|
|
|
62
|
-
def generate_schema(self, user, field_slug,
|
|
63
|
-
schema = super().generate_schema(user, field_slug,
|
|
62
|
+
def generate_schema(self, user, field_slug, language_context: LanguageContext) -> FieldSchemaData:
|
|
63
|
+
schema = super().generate_schema(user, field_slug, language_context)
|
|
64
64
|
|
|
65
65
|
schema.choices = self.choices
|
|
66
66
|
|
|
@@ -97,8 +97,8 @@ class StringField(TableField):
|
|
|
97
97
|
|
|
98
98
|
choices: List[Tuple[str, str]] | None = None
|
|
99
99
|
|
|
100
|
-
def generate_schema(self, user, field_slug,
|
|
101
|
-
schema = super().generate_schema(user, field_slug,
|
|
100
|
+
def generate_schema(self, user, field_slug, language_context: LanguageContext) -> FieldSchemaData:
|
|
101
|
+
schema = super().generate_schema(user, field_slug, language_context)
|
|
102
102
|
|
|
103
103
|
schema.multilined = self.multilined
|
|
104
104
|
schema.choices = self.choices
|
|
@@ -135,8 +135,8 @@ class DateTimeField(TableField):
|
|
|
135
135
|
include_date: bool | None = True
|
|
136
136
|
include_time: bool | None = True
|
|
137
137
|
|
|
138
|
-
def generate_schema(self, user, field_slug,
|
|
139
|
-
schema = super().generate_schema(user, field_slug,
|
|
138
|
+
def generate_schema(self, user, field_slug, language_context: LanguageContext) -> FieldSchemaData:
|
|
139
|
+
schema = super().generate_schema(user, field_slug, language_context)
|
|
140
140
|
|
|
141
141
|
schema.range = self.range
|
|
142
142
|
schema.include_date = self.include_date
|
|
@@ -180,8 +180,8 @@ class ArrayField(TableField):
|
|
|
180
180
|
|
|
181
181
|
array_type: str | None
|
|
182
182
|
|
|
183
|
-
def generate_schema(self, user, field_slug,
|
|
184
|
-
schema = super().generate_schema(user, field_slug,
|
|
183
|
+
def generate_schema(self, user, field_slug, language_context: LanguageContext) -> FieldSchemaData:
|
|
184
|
+
schema = super().generate_schema(user, field_slug, language_context)
|
|
185
185
|
|
|
186
186
|
schema.array_type = self.array_type
|
|
187
187
|
|
|
@@ -208,8 +208,8 @@ class ImageField(TableField):
|
|
|
208
208
|
preview_max_height: int = 100
|
|
209
209
|
preview_max_width: int = 100
|
|
210
210
|
|
|
211
|
-
def generate_schema(self, user, field_slug,
|
|
212
|
-
schema = super().generate_schema(user, field_slug,
|
|
211
|
+
def generate_schema(self, user, field_slug, language_context: LanguageContext) -> FieldSchemaData:
|
|
212
|
+
schema = super().generate_schema(user, field_slug, language_context)
|
|
213
213
|
|
|
214
214
|
if self.preview_max_height is not None:
|
|
215
215
|
schema.preview_max_height = self.preview_max_height
|
|
@@ -234,8 +234,8 @@ class ChoiceField(TableField):
|
|
|
234
234
|
variant: str = 'elevated'
|
|
235
235
|
size: str = 'default'
|
|
236
236
|
|
|
237
|
-
def generate_schema(self, user, field_slug,
|
|
238
|
-
schema = super().generate_schema(user, field_slug,
|
|
237
|
+
def generate_schema(self, user, field_slug, language_context: LanguageContext) -> FieldSchemaData:
|
|
238
|
+
schema = super().generate_schema(user, field_slug, language_context)
|
|
239
239
|
|
|
240
240
|
schema.choices = self.choices
|
|
241
241
|
|
|
@@ -4,9 +4,9 @@ from typing import Any
|
|
|
4
4
|
|
|
5
5
|
from pydantic.dataclasses import dataclass
|
|
6
6
|
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
from
|
|
7
|
+
from brilliance_admin.exceptions import AdminAPIException, APIError
|
|
8
|
+
from brilliance_admin.schema.table.fields.base import TableField
|
|
9
|
+
from brilliance_admin.utils import get_logger
|
|
10
10
|
|
|
11
11
|
logger = get_logger()
|
|
12
12
|
|
|
@@ -3,13 +3,13 @@ from typing import Any, ClassVar, Dict, List
|
|
|
3
3
|
|
|
4
4
|
from pydantic_core import core_schema
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
from
|
|
12
|
-
from
|
|
6
|
+
from brilliance_admin.auth import UserABC
|
|
7
|
+
from brilliance_admin.exceptions import AdminAPIException, APIError, FieldError
|
|
8
|
+
from brilliance_admin.schema.category import FieldSchemaData, FieldsSchemaData
|
|
9
|
+
from brilliance_admin.schema.table.fields.base import TableField
|
|
10
|
+
from brilliance_admin.schema.table.fields.function_field import FunctionField
|
|
11
|
+
from brilliance_admin.translations import LanguageContext
|
|
12
|
+
from brilliance_admin.utils import DeserializeAction
|
|
13
13
|
|
|
14
14
|
NOT_FUND_EXCEPTION = '''Field slug "{field_slug}" not found inside generated fields inside {class_name}
|
|
15
15
|
Available options: {available_fields}
|
|
@@ -143,13 +143,13 @@ class FieldsSchema:
|
|
|
143
143
|
def get_fields(self) -> Dict[str, TableField]:
|
|
144
144
|
return self._generated_fields
|
|
145
145
|
|
|
146
|
-
def generate_schema(self, user: UserABC,
|
|
146
|
+
def generate_schema(self, user: UserABC, language_context: LanguageContext) -> FieldsSchemaData:
|
|
147
147
|
fields_schema = FieldsSchemaData(
|
|
148
148
|
list_display=self.list_display,
|
|
149
149
|
)
|
|
150
150
|
|
|
151
151
|
for field_slug, field in self.get_fields().items():
|
|
152
|
-
field_schema: FieldSchemaData = field.generate_schema(user, field_slug,
|
|
152
|
+
field_schema: FieldSchemaData = field.generate_schema(user, field_slug, language_context)
|
|
153
153
|
fields_schema.fields[field_slug] = field_schema.to_dict(keep_none=False)
|
|
154
154
|
|
|
155
155
|
return fields_schema
|