django-spire 0.16.4__py3-none-any.whl → 0.16.6__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.
- django_spire/auth/group/templates/django_spire/auth/group/navigation/accordion/permission_nav_accordion.html +2 -2
- django_spire/auth/mfa/views/page_views.py +1 -2
- django_spire/auth/templates/django_spire/auth/page/password_change_done_page.html +2 -2
- django_spire/auth/templates/django_spire/auth/page/password_change_page.html +19 -3
- django_spire/auth/views/admin_views.py +16 -0
- django_spire/consts.py +1 -1
- django_spire/core/management/commands/spire_startapp.py +0 -4
- django_spire/core/management/commands/spire_startapp_pkg/processor.py +18 -3
- django_spire/core/management/commands/spire_startapp_pkg/reporter.py +32 -30
- django_spire/core/redirect/generic_redirect.py +1 -1
- django_spire/core/static/django_spire/js/theme.js +2 -2
- django_spire/core/templates/django_spire/element/pagination_element.html +2 -0
- django_spire/core/templates/django_spire/navigation/top_navigation.html +39 -35
- django_spire/core/templates/django_spire/page/full_page.html +2 -2
- django_spire/core/templatetags/json.py +7 -4
- django_spire/knowledge/auth/controller.py +10 -0
- django_spire/knowledge/collection/admin.py +10 -3
- django_spire/knowledge/collection/models.py +23 -1
- django_spire/knowledge/collection/querysets.py +19 -1
- django_spire/knowledge/collection/services/factory_service.py +42 -0
- django_spire/knowledge/collection/services/service.py +9 -1
- django_spire/knowledge/collection/services/transformation_service.py +29 -7
- django_spire/knowledge/collection/tests/test_services/test_transformation_service.py +4 -2
- django_spire/knowledge/collection/views/form_views.py +20 -4
- django_spire/knowledge/context_processors.py +1 -2
- django_spire/knowledge/migrations/0004_alter_collection_options_collectiongroup.py +27 -0
- django_spire/knowledge/static/django_spire/knowledge/collection/js/managers.js +17 -14
- django_spire/knowledge/templates/django_spire/knowledge/collection/card/context_menu_card.html +16 -10
- django_spire/knowledge/templates/django_spire/knowledge/collection/form/form.html +10 -1
- django_spire/knowledge/templates/django_spire/knowledge/collection/navigation/navigation.html +3 -0
- django_spire/knowledge/templates/django_spire/knowledge/entry/card/context_menu_card.html +1 -1
- django_spire/knowledge/templates/django_spire/knowledge/page/full_page.html +1 -1
- django_spire/theme/tests/test_filesystem.py +2 -2
- django_spire/theme/tests/{test_views.py → test_views/test_json_views.py} +14 -14
- django_spire/theme/urls/__init__.py +1 -1
- django_spire/theme/urls/json_urls.py +10 -0
- {django_spire-0.16.4.dist-info → django_spire-0.16.6.dist-info}/METADATA +1 -1
- {django_spire-0.16.4.dist-info → django_spire-0.16.6.dist-info}/RECORD +43 -81
- django_spire/core/management/commands/spire_startapp_pkg/template/app/apps.py +0 -7
- django_spire/core/management/commands/spire_startapp_pkg/template/app/forms.py +0 -15
- django_spire/core/management/commands/spire_startapp_pkg/template/app/intelligence/__init__.py +0 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/intelligence/bots.py +0 -19
- django_spire/core/management/commands/spire_startapp_pkg/template/app/intelligence/intel.py +0 -7
- django_spire/core/management/commands/spire_startapp_pkg/template/app/intelligence/prompts.py +0 -30
- django_spire/core/management/commands/spire_startapp_pkg/template/app/migrations/__init__.py +0 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/models.py +0 -52
- django_spire/core/management/commands/spire_startapp_pkg/template/app/querysets.py +0 -12
- django_spire/core/management/commands/spire_startapp_pkg/template/app/seeding/__init__.py +0 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/seeding/seed.py +0 -3
- django_spire/core/management/commands/spire_startapp_pkg/template/app/seeding/seeder.py +0 -13
- django_spire/core/management/commands/spire_startapp_pkg/template/app/services/__init__.py +0 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/services/factory_service.py +0 -11
- django_spire/core/management/commands/spire_startapp_pkg/template/app/services/intelligence_service.py +0 -11
- django_spire/core/management/commands/spire_startapp_pkg/template/app/services/processor_service.py +0 -11
- django_spire/core/management/commands/spire_startapp_pkg/template/app/services/service.py +0 -20
- django_spire/core/management/commands/spire_startapp_pkg/template/app/services/transformation_service.py +0 -11
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/__init__.py +0 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_intelligence/__init__.py +0 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_intelligence/test_bots.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_models.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_services/__init__.py +0 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_services/test_factory_service.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_services/test_intelligence_service.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_services/test_processor_service.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_services/test_service.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_services/test_transformation_service.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_urls/__init__.py +0 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_urls/test_form_urls.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_urls/test_page_urls.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_views/__init__.py +0 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_views/test_form_views.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_views/test_page_views.py +0 -6
- django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/__init__.py +0 -9
- django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/form_urls.py +0 -13
- django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/page_urls.py +0 -11
- django_spire/core/management/commands/spire_startapp_pkg/template/app/views/__init__.py +0 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/views/form_views.py +0 -120
- django_spire/core/management/commands/spire_startapp_pkg/template/app/views/page_views.py +0 -45
- django_spire/theme/urls/ajax_urls.py +0 -10
- /django_spire/{core/management/commands/spire_startapp_pkg/template/app → theme/tests/test_views}/__init__.py +0 -0
- /django_spire/theme/views/{ajax_views.py → json_views.py} +0 -0
- {django_spire-0.16.4.dist-info → django_spire-0.16.6.dist-info}/WHEEL +0 -0
- {django_spire-0.16.4.dist-info → django_spire-0.16.6.dist-info}/licenses/LICENSE.md +0 -0
- {django_spire-0.16.4.dist-info → django_spire-0.16.6.dist-info}/top_level.txt +0 -0
|
@@ -4,25 +4,39 @@ import json
|
|
|
4
4
|
|
|
5
5
|
from django.conf import settings
|
|
6
6
|
from django.contrib.sites.models import Site
|
|
7
|
-
from django.db.models import
|
|
7
|
+
from django.db.models import Prefetch
|
|
8
8
|
from django.urls import reverse
|
|
9
9
|
|
|
10
|
+
from django_spire.auth.controller.controller import AppAuthController
|
|
10
11
|
from django_spire.contrib.service import BaseDjangoModelService
|
|
11
12
|
|
|
12
13
|
from typing import TYPE_CHECKING
|
|
13
14
|
|
|
14
15
|
if TYPE_CHECKING:
|
|
15
|
-
from django.
|
|
16
|
+
from django.core.handlers.wsgi import WSGIRequest
|
|
16
17
|
from django_spire.knowledge.collection.models import Collection
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class CollectionTransformationService(BaseDjangoModelService['Collection']):
|
|
20
21
|
obj: Collection
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
def to_hierarchy_json(self, request: WSGIRequest) -> str:
|
|
24
|
+
user = request.user
|
|
25
|
+
|
|
26
|
+
collections = (
|
|
27
|
+
self.obj_class.objects
|
|
28
|
+
.active()
|
|
29
|
+
.select_related('parent')
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
if not (
|
|
33
|
+
user.is_superuser or
|
|
34
|
+
AppAuthController('knowledge', request).can_access_all_collections()
|
|
35
|
+
):
|
|
36
|
+
collections = collections.user_has_access(user=user)
|
|
37
|
+
|
|
24
38
|
entry_queryset = (
|
|
25
|
-
|
|
39
|
+
collections.model._meta.fields_map.get('entry')
|
|
26
40
|
.related_model
|
|
27
41
|
.objects
|
|
28
42
|
.active()
|
|
@@ -33,7 +47,7 @@ class CollectionTransformationService(BaseDjangoModelService['Collection']):
|
|
|
33
47
|
)
|
|
34
48
|
|
|
35
49
|
collections = list(
|
|
36
|
-
|
|
50
|
+
collections.prefetch_related(Prefetch('entries', queryset=entry_queryset))
|
|
37
51
|
.active()
|
|
38
52
|
.order_by('order')
|
|
39
53
|
)
|
|
@@ -44,7 +58,7 @@ class CollectionTransformationService(BaseDjangoModelService['Collection']):
|
|
|
44
58
|
|
|
45
59
|
tree = []
|
|
46
60
|
for collection in collections:
|
|
47
|
-
if collection.parent_id:
|
|
61
|
+
if collection.parent_id and collection.parent_id in collection_map:
|
|
48
62
|
collection_map[collection.parent_id]['children'].append(
|
|
49
63
|
collection_map[collection.pk]
|
|
50
64
|
)
|
|
@@ -74,6 +88,14 @@ class CollectionTransformationService(BaseDjangoModelService['Collection']):
|
|
|
74
88
|
)
|
|
75
89
|
}
|
|
76
90
|
''',
|
|
91
|
+
'edit_url': f'''
|
|
92
|
+
{site}{
|
|
93
|
+
reverse(
|
|
94
|
+
'django_spire:knowledge:collection:form:update',
|
|
95
|
+
kwargs={'pk': self.obj.pk},
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
''',
|
|
77
99
|
'create_entry_url': f'''
|
|
78
100
|
{site}{
|
|
79
101
|
reverse(
|
|
@@ -2,6 +2,7 @@ import json
|
|
|
2
2
|
|
|
3
3
|
from django.contrib.sites.models import Site
|
|
4
4
|
from django.conf import settings
|
|
5
|
+
from django.test import RequestFactory
|
|
5
6
|
|
|
6
7
|
from django_spire.core.tests.test_cases import BaseTestCase
|
|
7
8
|
from django_spire.knowledge.collection.models import Collection
|
|
@@ -29,9 +30,10 @@ class TestCollectionTransformationService(BaseTestCase):
|
|
|
29
30
|
self.test_collection_2 = Collection.objects.create(name='Parent A1', id=2, parent_id=1)
|
|
30
31
|
self.test_collection_3 = Collection.objects.create(name='Child A1a', id=3, parent_id=2)
|
|
31
32
|
|
|
33
|
+
request = RequestFactory().get('/')
|
|
34
|
+
request.user = self.super_user
|
|
32
35
|
family_tree = Collection.services.transformation.to_hierarchy_json(
|
|
33
|
-
|
|
34
|
-
user=self.super_user
|
|
36
|
+
request=request
|
|
35
37
|
)
|
|
36
38
|
|
|
37
39
|
for collection_json in json.loads(family_tree):
|
|
@@ -8,10 +8,11 @@ from django.http import HttpResponseRedirect
|
|
|
8
8
|
from django.urls import reverse
|
|
9
9
|
|
|
10
10
|
from django_spire.auth.controller.controller import AppAuthController
|
|
11
|
+
from django_spire.auth.group.models import AuthGroup
|
|
11
12
|
from django_spire.contrib.form.utils import show_form_errors
|
|
12
13
|
from django_spire.contrib.generic_views import portal_views
|
|
13
14
|
from django_spire.core.shortcuts import get_object_or_null_obj
|
|
14
|
-
from django_spire.knowledge.collection.models import Collection
|
|
15
|
+
from django_spire.knowledge.collection.models import Collection, CollectionGroup
|
|
15
16
|
from django_spire.knowledge.collection.forms import CollectionForm
|
|
16
17
|
|
|
17
18
|
if TYPE_CHECKING:
|
|
@@ -30,7 +31,13 @@ def form_view(
|
|
|
30
31
|
dg.glue_query_set(
|
|
31
32
|
request,
|
|
32
33
|
unique_name='collections',
|
|
33
|
-
target=Collection.objects.active(),
|
|
34
|
+
target=Collection.objects.active().user_has_access(request.user),
|
|
35
|
+
fields=['name']
|
|
36
|
+
)
|
|
37
|
+
dg.glue_query_set(
|
|
38
|
+
request,
|
|
39
|
+
unique_name='group_query_set',
|
|
40
|
+
target=AuthGroup.objects.all(),
|
|
34
41
|
fields=['name']
|
|
35
42
|
)
|
|
36
43
|
|
|
@@ -38,7 +45,13 @@ def form_view(
|
|
|
38
45
|
form = CollectionForm(request.POST, instance=collection)
|
|
39
46
|
|
|
40
47
|
if form.is_valid():
|
|
41
|
-
|
|
48
|
+
collection, _ = collection.services.save_model_obj(**form.cleaned_data)
|
|
49
|
+
|
|
50
|
+
_ = CollectionGroup.services.factory.replace_groups(
|
|
51
|
+
request=request,
|
|
52
|
+
group_pks=dict(request.POST).get('groups'),
|
|
53
|
+
collection=collection,
|
|
54
|
+
)
|
|
42
55
|
|
|
43
56
|
return HttpResponseRedirect(
|
|
44
57
|
reverse('django_spire:knowledge:collection:page:list')
|
|
@@ -53,7 +66,10 @@ def form_view(
|
|
|
53
66
|
form=form,
|
|
54
67
|
obj=collection,
|
|
55
68
|
context_data={
|
|
56
|
-
'collection': collection
|
|
69
|
+
'collection': collection,
|
|
70
|
+
'group_ids': list(
|
|
71
|
+
collection.groups.all().values_list('auth_group_id', flat=True)
|
|
72
|
+
) if collection.id else [],
|
|
57
73
|
},
|
|
58
74
|
template='django_spire/knowledge/collection/page/form_page.html'
|
|
59
75
|
)
|
|
@@ -11,7 +11,6 @@ def django_spire_knowledge(request: WSGIRequest) -> dict[str, Any]:
|
|
|
11
11
|
|
|
12
12
|
return {
|
|
13
13
|
'collection_tree_json': Collection.services.transformation.to_hierarchy_json(
|
|
14
|
-
|
|
15
|
-
user=request.user,
|
|
14
|
+
request=request,
|
|
16
15
|
)
|
|
17
16
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Generated by Django 5.2.6 on 2025-09-23 14:11
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('django_spire_auth_group', '0001_initial'),
|
|
11
|
+
('django_spire_knowledge', '0003_alter_collection_order_alter_entry_order_and_more'),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.AlterModelOptions(
|
|
16
|
+
name='collection',
|
|
17
|
+
options={'permissions': [('can_access_all_collections', 'Can Access All Collections'), ('can_change_collection_groups', 'Can Change Collection Groups')], 'verbose_name': 'Collection', 'verbose_name_plural': 'Collections'},
|
|
18
|
+
),
|
|
19
|
+
migrations.CreateModel(
|
|
20
|
+
name='CollectionGroup',
|
|
21
|
+
fields=[
|
|
22
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
23
|
+
('auth_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='collection_groups', related_query_name='collection_group', to='django_spire_auth_group.authgroup')),
|
|
24
|
+
('collection', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='groups', related_query_name='group', to='django_spire_knowledge.collection')),
|
|
25
|
+
],
|
|
26
|
+
),
|
|
27
|
+
]
|
|
@@ -28,27 +28,29 @@ class Entry {
|
|
|
28
28
|
|
|
29
29
|
class Collection {
|
|
30
30
|
constructor({
|
|
31
|
-
children = [],
|
|
32
|
-
create_entry_url = '',
|
|
33
|
-
delete_url = '',
|
|
34
|
-
description = '',
|
|
35
|
-
entries = [],
|
|
36
31
|
id = -1,
|
|
37
|
-
import_entry_url = '',
|
|
38
32
|
name = 'None',
|
|
33
|
+
description = '',
|
|
39
34
|
order = 0,
|
|
40
35
|
parent = null,
|
|
36
|
+
children = [],
|
|
37
|
+
entries = [],
|
|
38
|
+
delete_url = '',
|
|
39
|
+
edit_url = '',
|
|
40
|
+
create_entry_url = '',
|
|
41
|
+
import_entry_url = '',
|
|
41
42
|
}) {
|
|
42
|
-
this.children = children
|
|
43
|
-
this.create_entry_url = create_entry_url
|
|
44
|
-
this.delete_url = delete_url
|
|
45
|
-
this.description = description
|
|
46
|
-
this.entries = entries
|
|
47
43
|
this.id = id
|
|
48
|
-
this.import_entry_url = import_entry_url
|
|
49
44
|
this.name = name
|
|
45
|
+
this.description = description
|
|
50
46
|
this.order = order
|
|
51
47
|
this.parent = parent
|
|
48
|
+
this.children = children
|
|
49
|
+
this.entries = entries
|
|
50
|
+
this.delete_url = delete_url
|
|
51
|
+
this.edit_url = edit_url
|
|
52
|
+
this.create_entry_url = create_entry_url
|
|
53
|
+
this.import_entry_url = import_entry_url
|
|
52
54
|
this.show_details = false
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -107,9 +109,10 @@ class CollectionManager {
|
|
|
107
109
|
parent: new Collection({}),
|
|
108
110
|
children: this._create_tree_structure({collections: collection.children}),
|
|
109
111
|
entries: this._create_entries({entries_json: collection.entries}),
|
|
112
|
+
delete_url: collection.delete_url,
|
|
113
|
+
edit_url: collection.edit_url,
|
|
110
114
|
create_entry_url: collection.create_entry_url,
|
|
111
|
-
import_entry_url: collection.import_entry_url
|
|
112
|
-
delete_url: collection.delete_url
|
|
115
|
+
import_entry_url: collection.import_entry_url
|
|
113
116
|
})
|
|
114
117
|
|
|
115
118
|
this.collection_lookup_map.set(collection_object.id, collection_object)
|
django_spire/knowledge/templates/django_spire/knowledge/collection/card/context_menu_card.html
CHANGED
|
@@ -7,21 +7,27 @@
|
|
|
7
7
|
top: y + 'px',
|
|
8
8
|
left: x + 'px',
|
|
9
9
|
}"
|
|
10
|
-
class="position-fixed card shadow-lg z-3 vstack cursor-pointer"
|
|
10
|
+
class="position-fixed card shadow-lg z-3 vstack cursor-pointer bg-app-layer-one"
|
|
11
11
|
@click.away="hide_menu()"
|
|
12
12
|
>
|
|
13
13
|
<span class="px-2 py-1" x-text="title"></span>
|
|
14
14
|
|
|
15
|
+
{% if AuthController.knowledge.can_change %}
|
|
16
|
+
<span class="border-top bg-app-layer-one-hover px-3 text-app-default-link-color" @click="edit_collection()">
|
|
17
|
+
<i class="bi bi-pencil pe-1"></i>
|
|
18
|
+
Edit Collection
|
|
19
|
+
</span>
|
|
20
|
+
{% endif %}
|
|
15
21
|
{% if AuthController.knowledge.can_add %}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
<span class="border-top bg-app-layer-one-hover px-3 text-app-default-link-color" @click="add_entry()">
|
|
23
|
+
<i class="bi bi-plus pe-1"></i>
|
|
24
|
+
Add Entry
|
|
25
|
+
</span>
|
|
26
|
+
<span class="border-top bg-app-layer-one-hover px-3 text-app-default-link-color" @click="import_entry()">
|
|
27
|
+
<i class="bi bi-upload pe-1">
|
|
28
|
+
</i>
|
|
29
|
+
Import Entry
|
|
30
|
+
</span>
|
|
25
31
|
{% endif %}
|
|
26
32
|
|
|
27
33
|
{% if AuthController.knowledge.can_delete %}
|
|
@@ -5,11 +5,15 @@
|
|
|
5
5
|
x-data="{
|
|
6
6
|
collection: new ModelObjectGlue('collection'),
|
|
7
7
|
collection_query_set: new QuerySetGlue('collections'),
|
|
8
|
+
groups: new GlueCharField('groups'),
|
|
9
|
+
group_query_set: new QuerySetGlue('group_query_set'),
|
|
8
10
|
async init() {
|
|
9
11
|
await this.collection.get()
|
|
10
12
|
this.collection.glue_fields.parent.choices = await this.collection_query_set.to_choices()
|
|
11
|
-
|
|
12
13
|
this.collection.glue_fields.parent.label = 'Parent Collection'
|
|
14
|
+
|
|
15
|
+
this.groups.choices = await this.group_query_set.to_choices()
|
|
16
|
+
this.groups.value = JSON.parse('{{ group_ids }}')
|
|
13
17
|
}
|
|
14
18
|
}"
|
|
15
19
|
>
|
|
@@ -23,6 +27,11 @@
|
|
|
23
27
|
<div class="col-12 mt-2">
|
|
24
28
|
{% include 'django_glue/form/field/search_and_select_field.html' with glue_model_field='collection.parent' %}
|
|
25
29
|
</div>
|
|
30
|
+
{% if AuthController.knowledge.can_change_collection_groups %}
|
|
31
|
+
<div class="col-12 mt-2">
|
|
32
|
+
{% include 'django_glue/form/field/multi_select_field.html' with glue_field='groups' %}
|
|
33
|
+
</div>
|
|
34
|
+
{% endif %}
|
|
26
35
|
<div class="col-12 mt-2">
|
|
27
36
|
{% include 'django_spire/contrib/form/button/form_submit_button.html' %}
|
|
28
37
|
</div>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
top: y + 'px',
|
|
8
8
|
left: x + 'px',
|
|
9
9
|
}"
|
|
10
|
-
class="position-fixed card shadow-lg z-3 vstack cursor-pointer"
|
|
10
|
+
class="position-fixed card shadow-lg z-3 vstack cursor-pointer bg-app-layer-one"
|
|
11
11
|
@click.away="hide_menu()"
|
|
12
12
|
>
|
|
13
13
|
<span class="px-2 py-1" x-text="title"></span>
|
|
@@ -15,7 +15,7 @@ class ThemeFilesystemValidationTests(TestCase):
|
|
|
15
15
|
def _get_themes_base_path(self) -> Path:
|
|
16
16
|
file = Path(__file__)
|
|
17
17
|
root = file.parent.parent.parent.parent
|
|
18
|
-
return root / 'django_spire' / 'static' / 'django_spire' / 'css' / 'themes'
|
|
18
|
+
return root / 'django_spire' / 'core' / 'static' / 'django_spire' / 'css' / 'themes'
|
|
19
19
|
|
|
20
20
|
def test_themes_directory_exists(self) -> None:
|
|
21
21
|
if not self.base_path.exists():
|
|
@@ -98,7 +98,7 @@ class ThemeFilesystemValidationTests(TestCase):
|
|
|
98
98
|
|
|
99
99
|
file = Path(__file__)
|
|
100
100
|
root = file.parent.parent.parent.parent
|
|
101
|
-
path = root / 'django_spire' / 'static' / expected
|
|
101
|
+
path = root / 'django_spire' / 'core' / 'static' / expected
|
|
102
102
|
|
|
103
103
|
if not path.exists():
|
|
104
104
|
missing.append(f'{theme.value}: {expected}')
|
|
@@ -11,7 +11,7 @@ from django.http import JsonResponse
|
|
|
11
11
|
from django_spire.core.tests.test_cases import BaseTestCase
|
|
12
12
|
from django_spire.theme.enums import ThemeFamily
|
|
13
13
|
from django_spire.theme.utils import get_theme_cookie_name
|
|
14
|
-
from django_spire.theme.views import
|
|
14
|
+
from django_spire.theme.views import json_views
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class ThemeViewTests(TestCase):
|
|
@@ -19,8 +19,8 @@ class ThemeViewTests(TestCase):
|
|
|
19
19
|
self.factory = RequestFactory()
|
|
20
20
|
|
|
21
21
|
def test_get_config_success(self) -> None:
|
|
22
|
-
request = self.factory.get('/theme/
|
|
23
|
-
response =
|
|
22
|
+
request = self.factory.get('/django_spire/theme/json/get_config/')
|
|
23
|
+
response = json_views.get_config(request)
|
|
24
24
|
|
|
25
25
|
self.assertIsInstance(response, JsonResponse)
|
|
26
26
|
self.assertEqual(response.status_code, HTTPStatus.OK)
|
|
@@ -42,18 +42,18 @@ class ThemeViewTests(TestCase):
|
|
|
42
42
|
self.assertEqual(set(family_config['modes']), {'dark', 'light'})
|
|
43
43
|
|
|
44
44
|
def test_get_config_cache_header(self) -> None:
|
|
45
|
-
_ = self.factory.get('/theme/
|
|
45
|
+
_ = self.factory.get('/django_spire/theme/json/get_config/')
|
|
46
46
|
|
|
47
|
-
with patch('django_spire.theme.views.
|
|
48
|
-
self.assertTrue(hasattr(
|
|
47
|
+
with patch('django_spire.theme.views.json_views.cache_page') as _:
|
|
48
|
+
self.assertTrue(hasattr(json_views.get_config, '__wrapped__'))
|
|
49
49
|
|
|
50
50
|
def test_set_theme_success(self) -> None:
|
|
51
51
|
request = self.factory.post(
|
|
52
|
-
'/theme/
|
|
52
|
+
'/django_spire/theme/json/set_theme/',
|
|
53
53
|
data=json.dumps({'theme': 'dracula-dark'}),
|
|
54
54
|
content_type='application/json'
|
|
55
55
|
)
|
|
56
|
-
response =
|
|
56
|
+
response = json_views.set_theme(request)
|
|
57
57
|
|
|
58
58
|
self.assertIsInstance(response, JsonResponse)
|
|
59
59
|
self.assertEqual(response.status_code, HTTPStatus.OK)
|
|
@@ -72,11 +72,11 @@ class ThemeViewTests(TestCase):
|
|
|
72
72
|
|
|
73
73
|
def test_set_theme_missing_theme(self) -> None:
|
|
74
74
|
request = self.factory.post(
|
|
75
|
-
'/theme/
|
|
75
|
+
'/django_spire/theme/json/set_theme/',
|
|
76
76
|
data=json.dumps({}),
|
|
77
77
|
content_type='application/json'
|
|
78
78
|
)
|
|
79
|
-
response =
|
|
79
|
+
response = json_views.set_theme(request)
|
|
80
80
|
|
|
81
81
|
self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST)
|
|
82
82
|
data = json.loads(response.content)
|
|
@@ -86,11 +86,11 @@ class ThemeViewTests(TestCase):
|
|
|
86
86
|
|
|
87
87
|
def test_set_theme_invalid_theme(self) -> None:
|
|
88
88
|
request = self.factory.post(
|
|
89
|
-
'/theme/
|
|
89
|
+
'/django_spire/theme/json/set_theme/',
|
|
90
90
|
data=json.dumps({'theme': 'invalid-theme'}),
|
|
91
91
|
content_type='application/json'
|
|
92
92
|
)
|
|
93
|
-
response =
|
|
93
|
+
response = json_views.set_theme(request)
|
|
94
94
|
|
|
95
95
|
self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST)
|
|
96
96
|
data = json.loads(response.content)
|
|
@@ -102,7 +102,7 @@ class ThemeViewTests(TestCase):
|
|
|
102
102
|
class ThemeViewIntegrationTests(BaseTestCase):
|
|
103
103
|
def test_set_theme_with_authenticated_client(self) -> None:
|
|
104
104
|
response = self.client.post(
|
|
105
|
-
'/theme/
|
|
105
|
+
'/django_spire/theme/json/set_theme/',
|
|
106
106
|
data=json.dumps({'theme': 'dracula-dark'}),
|
|
107
107
|
content_type='application/json'
|
|
108
108
|
)
|
|
@@ -112,7 +112,7 @@ class ThemeViewIntegrationTests(BaseTestCase):
|
|
|
112
112
|
self.assertTrue(data['success'])
|
|
113
113
|
|
|
114
114
|
def test_get_config_with_authenticated_client(self) -> None:
|
|
115
|
-
response = self.client.get('/theme/
|
|
115
|
+
response = self.client.get('/django_spire/theme/json/get_config/')
|
|
116
116
|
self.assertEqual(response.status_code, HTTPStatus.OK)
|
|
117
117
|
|
|
118
118
|
data = json.loads(response.content)
|
|
@@ -4,6 +4,6 @@ from django.urls.conf import path, include
|
|
|
4
4
|
app_name = 'theme'
|
|
5
5
|
|
|
6
6
|
urlpatterns = [
|
|
7
|
-
path('
|
|
7
|
+
path('json/', include('django_spire.theme.urls.json_urls', namespace='json')),
|
|
8
8
|
path('page/', include('django_spire.theme.urls.page_urls', namespace='page')),
|
|
9
9
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-spire
|
|
3
|
-
Version: 0.16.
|
|
3
|
+
Version: 0.16.6
|
|
4
4
|
Summary: A project for Django Spire
|
|
5
5
|
Author-email: Brayden Carlson <braydenc@stratusadv.com>, Nathan Johnson <nathanj@stratusadv.com>
|
|
6
6
|
License: Copyright (c) 2024 Stratus Advanced Technologies and Contributors.
|