django-spire 0.17.11__py3-none-any.whl → 0.18.0__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.
Files changed (72) hide show
  1. django_spire/consts.py +1 -1
  2. django_spire/contrib/seeding/model/base.py +1 -1
  3. django_spire/knowledge/entry/services/automation_service.py +7 -4
  4. django_spire/knowledge/entry/services/transformation_services.py +2 -2
  5. django_spire/knowledge/entry/version/block/choices.py +1 -2
  6. django_spire/knowledge/entry/version/block/data/data.py +33 -0
  7. django_spire/knowledge/entry/version/block/data/heading_data.py +15 -0
  8. django_spire/knowledge/entry/version/block/data/list/choices.py +17 -0
  9. django_spire/knowledge/entry/version/block/data/list/data.py +102 -0
  10. django_spire/knowledge/entry/version/block/data/list/maps.py +14 -0
  11. django_spire/knowledge/entry/version/block/data/list/meta.py +15 -0
  12. django_spire/knowledge/entry/version/block/data/maps.py +23 -0
  13. django_spire/knowledge/entry/version/block/data/text_data.py +13 -0
  14. django_spire/knowledge/entry/version/block/models.py +22 -14
  15. django_spire/knowledge/entry/version/block/querysets.py +17 -7
  16. django_spire/knowledge/entry/version/block/seeding/constants.py +271 -188
  17. django_spire/knowledge/entry/version/block/services/factory_service.py +14 -47
  18. django_spire/knowledge/entry/version/block/services/service.py +2 -12
  19. django_spire/knowledge/entry/version/block/tests/factories.py +18 -2
  20. django_spire/knowledge/entry/version/converters/markdown_converter.py +180 -105
  21. django_spire/knowledge/entry/version/maps.py +1 -1
  22. django_spire/knowledge/entry/version/models.py +1 -0
  23. django_spire/knowledge/entry/version/querysets.py +11 -1
  24. django_spire/knowledge/entry/version/seeding/seeder.py +4 -2
  25. django_spire/knowledge/entry/version/services/processor_service.py +18 -0
  26. django_spire/knowledge/entry/version/services/tests/test_processor_service.py +0 -0
  27. django_spire/knowledge/entry/version/tests/test_urls/test_json_urls.py +7 -24
  28. django_spire/knowledge/entry/version/urls/__init__.py +0 -3
  29. django_spire/knowledge/entry/version/urls/json_urls.py +5 -13
  30. django_spire/knowledge/entry/version/views/json_views.py +8 -76
  31. django_spire/knowledge/entry/version/views/page_views.py +10 -5
  32. django_spire/knowledge/migrations/0005_entryversionblock__tunes_data_and_more.py +23 -0
  33. django_spire/knowledge/static/django_spire/knowledge/css/navigation_items.css +1 -1
  34. django_spire/knowledge/static/django_spire/knowledge/entry/version/js/editor.js +87 -0
  35. django_spire/knowledge/static/django_spire/knowledge/entry/version/js/null_paragraph.js +15 -0
  36. django_spire/knowledge/templates/django_spire/knowledge/entry/file/page/list_page.html +1 -1
  37. django_spire/knowledge/templates/django_spire/knowledge/entry/version/container/detail_container.html +43 -12
  38. django_spire/knowledge/templates/django_spire/knowledge/entry/version/page/detail_page.html +17 -1
  39. django_spire/knowledge/templates/django_spire/knowledge/navigation/page/full_page.html +1 -1
  40. {django_spire-0.17.11.dist-info → django_spire-0.18.0.dist-info}/METADATA +2 -1
  41. {django_spire-0.17.11.dist-info → django_spire-0.18.0.dist-info}/RECORD +47 -60
  42. django_spire/knowledge/entry/version/block/blocks/block.py +0 -51
  43. django_spire/knowledge/entry/version/block/blocks/heading_block.py +0 -14
  44. django_spire/knowledge/entry/version/block/blocks/list_block.py +0 -31
  45. django_spire/knowledge/entry/version/block/blocks/sub_heading_block.py +0 -14
  46. django_spire/knowledge/entry/version/block/blocks/text_block.py +0 -14
  47. django_spire/knowledge/entry/version/block/maps.py +0 -16
  48. django_spire/knowledge/entry/version/block/services/processor_service.py +0 -33
  49. django_spire/knowledge/entry/version/block/services/transformation_service.py +0 -35
  50. django_spire/knowledge/entry/version/block/tests/test_urls/test_json_urls.py +0 -28
  51. django_spire/knowledge/entry/version/block/urls/__init__.py +0 -13
  52. django_spire/knowledge/entry/version/block/urls/json_urls.py +0 -9
  53. django_spire/knowledge/entry/version/block/views/json_views.py +0 -30
  54. django_spire/knowledge/entry/version/tests/test_urls/test_form_urls.py +0 -28
  55. django_spire/knowledge/entry/version/urls/form_urls.py +0 -10
  56. django_spire/knowledge/entry/version/views/form_views.py +0 -63
  57. django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/detail/component/heading_component.html +0 -3
  58. django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/detail/component/list_item_component.html +0 -38
  59. django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/detail/component/sub_heading_component.html +0 -3
  60. django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/detail/component/text_component.html +0 -3
  61. django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/dropdown/add_dropdown.html +0 -25
  62. django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/update/component/heading_component.html +0 -3
  63. django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/update/component/list_item_component.html +0 -13
  64. django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/update/component/sub_heading_component.html +0 -3
  65. django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/update/component/text_component.html +0 -50
  66. django_spire/knowledge/templates/django_spire/knowledge/entry/version/container/form_container.html +0 -129
  67. /django_spire/knowledge/entry/version/block/{blocks → data}/__init__.py +0 -0
  68. /django_spire/knowledge/entry/version/block/{tests/test_urls → data/list}/__init__.py +0 -0
  69. /django_spire/knowledge/entry/version/{block/views → services/tests}/__init__.py +0 -0
  70. {django_spire-0.17.11.dist-info → django_spire-0.18.0.dist-info}/WHEEL +0 -0
  71. {django_spire-0.17.11.dist-info → django_spire-0.18.0.dist-info}/licenses/LICENSE.md +0 -0
  72. {django_spire-0.17.11.dist-info → django_spire-0.18.0.dist-info}/top_level.txt +0 -0
@@ -1,20 +1,25 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import json
4
+
3
5
  from django.core.handlers.wsgi import WSGIRequest
6
+ from django.db.models import F, Prefetch
4
7
  from django.shortcuts import get_object_or_404
5
8
  from django.template.response import TemplateResponse
6
9
  from django.urls import reverse
7
10
 
8
11
  from django_spire.auth.controller.controller import AppAuthController
9
12
  from django_spire.contrib.generic_views import portal_views
13
+ from django_spire.knowledge.entry.version.block.models import EntryVersionBlock
10
14
  from django_spire.knowledge.entry.version.models import EntryVersion
11
15
 
12
16
 
13
17
  @AppAuthController('knowledge').permission_required('can_view')
14
18
  def detail_view(request: WSGIRequest, pk: int) -> TemplateResponse:
15
- current_version = get_object_or_404(EntryVersion, pk=pk)
16
- entry = current_version.entry
17
- version_blocks = current_version.blocks.active().order_by('order')
19
+ entry_version = get_object_or_404(EntryVersion.objects.prefetch_blocks(),pk=pk)
20
+
21
+ entry = entry_version.entry
22
+ version_blocks = entry_version.blocks.format_for_editor()
18
23
 
19
24
  def breadcrumbs_func(breadcrumbs):
20
25
  breadcrumbs.add_breadcrumb(
@@ -35,8 +40,8 @@ def detail_view(request: WSGIRequest, pk: int) -> TemplateResponse:
35
40
  breadcrumbs_func=breadcrumbs_func,
36
41
  context_data={
37
42
  'entry': entry,
38
- 'current_version': current_version,
39
- 'version_blocks': version_blocks,
43
+ 'version': entry_version,
44
+ 'version_blocks': json.dumps(list(version_blocks)),
40
45
  },
41
46
  template='django_spire/knowledge/entry/version/page/detail_page.html',
42
47
  )
@@ -0,0 +1,23 @@
1
+ # Generated by Django 5.2.7 on 2025-10-22 01:31
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('django_spire_knowledge', '0004_alter_collection_options_collectiongroup'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='entryversionblock',
15
+ name='_tunes_data',
16
+ field=models.JSONField(blank=True, null=True),
17
+ ),
18
+ migrations.AlterField(
19
+ model_name='entryversionblock',
20
+ name='type',
21
+ field=models.CharField(choices=[('text', 'Text'), ('heading', 'Heading'), ('sub_heading', 'Sub Heading'), ('list_item', 'List Item'), ('list', 'List'), ('code', 'Code')], default='text', max_length=32),
22
+ ),
23
+ ]
@@ -6,4 +6,4 @@
6
6
 
7
7
  .knowledge-nav-item:hover {
8
8
  background-color: var(--app-layer-three);
9
- }
9
+ }
@@ -0,0 +1,87 @@
1
+ function create_editorjs_instance({holder_id, update_url, initial_editor_blocks}) {
2
+ return new EditorJS({
3
+ holder: holder_id,
4
+ readOnly: !should_init_editor_in_edit_mode(),
5
+ tools: {
6
+ text: {
7
+ class: Paragraph,
8
+ inlineToolbar: true,
9
+ config: {
10
+ placeholder: 'Write something awesome!',
11
+ }
12
+ },
13
+ heading: {
14
+ class: Header,
15
+ inlineToolbar: true,
16
+ config: {
17
+ placeholder: 'Enter heading text...',
18
+ levels: [1, 2, 3, 4, 5, 6],
19
+ defaultLevel: 1
20
+ }
21
+ },
22
+ list: {
23
+ class: EditorjsList,
24
+ inlineToolbar: true,
25
+ config: {
26
+ defaultStyle: 'unordered'
27
+ },
28
+ },
29
+ paragraph: NullParagraph
30
+ },
31
+ defaultBlock: 'text',
32
+ onChange: async (api, _) => {
33
+ const raw_editor_blocks = await api.saver.save()
34
+
35
+ const parsed_editor_blocks = raw_editor_blocks.blocks.map((block, i) => ({
36
+ block_order: i,
37
+ block_data: block.data,
38
+ block_type: block.type,
39
+ block_tunes: block?.tunes ?? {},
40
+ }))
41
+
42
+ try {
43
+ await django_glue_fetch(
44
+ update_url,
45
+ {
46
+ payload: parsed_editor_blocks,
47
+ }
48
+ )
49
+ }
50
+ catch (e) {
51
+ console.error('Error saving editor blocks', e)
52
+ const event_detail = {
53
+ 'id': Date.now(),
54
+ 'type': 'error',
55
+ 'message': 'Something went wrong when saving your changes. Please reload the page and try again.'
56
+ }
57
+
58
+ const editor_error_event = new CustomEvent('notify', { detail: event_detail })
59
+ window.dispatchEvent(editor_error_event)
60
+ }
61
+ },
62
+ onReady: () => {
63
+ try {
64
+ if (initial_editor_blocks.length > 0) {
65
+ KNOWLEDGE_ENTRY_VERSION_EDITOR.blocks.render({
66
+ blocks: initial_editor_blocks,
67
+ })
68
+ if (should_init_editor_in_edit_mode()) {
69
+ focus_editor()
70
+ }
71
+ }
72
+ }
73
+ catch (e) {
74
+ console.error('Invalid JSON found in included initial block data', e)
75
+ }
76
+ }
77
+ })
78
+ }
79
+
80
+ function focus_editor() {
81
+ // editor seems to have trouble focusing without this slight setTimeout applied
82
+ setTimeout(() => KNOWLEDGE_ENTRY_VERSION_EDITOR.focus(), 10)
83
+ }
84
+
85
+ function should_init_editor_in_edit_mode() {
86
+ return new URLSearchParams(window.location.search).get('view_mode') === 'edit'
87
+ }
@@ -0,0 +1,15 @@
1
+ class NullParagraph {
2
+ static isReadOnlySupported = true;
3
+
4
+ constructor({data, api, config, readOnly, block}){}
5
+
6
+ render()
7
+ {
8
+ return null;
9
+ }
10
+
11
+ save()
12
+ {
13
+ return null;
14
+ }
15
+ }
@@ -1,4 +1,4 @@
1
- {% extends 'django_spire/page/full_page.html' %}
1
+ {% extends 'django_spire/knowledge/navigation/page/full_page.html' %}
2
2
 
3
3
  {% block full_page_content %}
4
4
  <div class="row">
@@ -8,9 +8,28 @@
8
8
  <div class="container">
9
9
  <div class="row align-items-center">
10
10
  {% if AuthController.knowledge.can_change %}
11
- <div class="col">
12
- {% url 'django_spire:knowledge:entry:version:form:update' pk=entry.current_version_id as entry_edit_url %}
13
- {% include 'django_spire/button/primary_button.html' with button_text='Edit' button_class='btn-md' button_href=entry_edit_url %}
11
+ <div
12
+ class="col"
13
+ x-data="{
14
+ editor_is_readonly: !should_init_editor_in_edit_mode(),
15
+ toggle_editor_readonly() {
16
+ KNOWLEDGE_ENTRY_VERSION_EDITOR?.readOnly?.toggle()
17
+ this.editor_is_readonly = KNOWLEDGE_ENTRY_VERSION_EDITOR?.readOnly?.isEnabled
18
+
19
+ const view_mode = this.editor_is_readonly ? 'readonly' : 'edit'
20
+
21
+ const url = new URL(window.location)
22
+ url.searchParams.set('view_mode', view_mode)
23
+ history.pushState(null, '', url);
24
+ }
25
+ }"
26
+ >
27
+ <div class="btn shadow-sm btn-md btn-app-primary"
28
+ @click="
29
+ toggle_editor_readonly();
30
+ ">
31
+ <span x-text="editor_is_readonly ? 'Edit' : 'Save'"></span>
32
+ </div>
14
33
  </div>
15
34
  {% endif %}
16
35
  <div class="col">
@@ -27,15 +46,27 @@
27
46
  {% block container_content %}
28
47
  <div class="container">
29
48
  <div class="row px-3">
30
- {% for version_block in version_blocks %}
31
- <div class="col-12">
32
- {% include version_block.block.detail_template with value=version_block.block.value %}
33
- </div>
34
- {% empty %}
35
- <div class="col-12">
36
- No information...
37
- </div>
38
- {% endfor %}
49
+ <script>
50
+ // Define editor instance outside of alpine js scope to avoid potential issues caused by reactivity
51
+ // and to allow above button to access
52
+ let KNOWLEDGE_ENTRY_VERSION_EDITOR;
53
+ </script>
54
+
55
+ {# The EditorJS will be attached to this div #}
56
+ <div
57
+ x-data="{
58
+ editor_element_id: 'knowledge-entry-version-editor',
59
+ init() {
60
+ KNOWLEDGE_ENTRY_VERSION_EDITOR = create_editorjs_instance({
61
+ holder_id: this.editor_element_id,
62
+ update_url: '{% url "django_spire:knowledge:entry:version:json:update_blocks" pk=entry.id %}',
63
+ initial_editor_blocks: {{ version_blocks }}
64
+ })
65
+ }
66
+ }"
67
+ :id="editor_element_id"
68
+ >
69
+ </div>
39
70
  </div>
40
71
  </div>
41
72
  {% endblock %}
@@ -1,9 +1,25 @@
1
1
  {% extends 'django_spire/knowledge/navigation/page/full_page.html' %}
2
2
 
3
+ {% load static %}
4
+
5
+ {% block base_body_top_js %}
6
+ {{ block.super }}
7
+ <script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@2.31.0/dist/editorjs.umd.min.js"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/@editorjs/paragraph@2.11.7/dist/paragraph.umd.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/@editorjs/list@2.0.8/dist/editorjs-list.umd.min.js"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/@editorjs/header@2.8.8/dist/header.umd.min.js"></script>
11
+ {% endblock %}
12
+
3
13
  {% block knowledge_full_page_content %}
4
14
  <div class="row justify-content-center ps-3">
5
- <div class="col-12 col-xl-8'">
15
+ <div class="col-12 col-xl-8">
6
16
  {% include 'django_spire/knowledge/entry/version/container/detail_container.html' %}
7
17
  </div>
8
18
  </div>
9
19
  {% endblock %}
20
+
21
+ {% block base_body_additional_bottom_js %}
22
+ {{ block.super }}
23
+ <script type="application/javascript" src="{% static 'django_spire/knowledge/entry/version/js/null_paragraph.js' %}?v={{ DJANGO_SPIRE_VERSION }}"></script>
24
+ <script type="application/javascript" src="{% static 'django_spire/knowledge/entry/version/js/editor.js' %}?v={{ DJANGO_SPIRE_VERSION }}"></script>
25
+ {% endblock %}
@@ -66,7 +66,7 @@
66
66
  >
67
67
  <div
68
68
  class="position-relative h-100"
69
- :style="nav_toggle_type === 'collapse' && 'width: 35vw'"
69
+ :style="nav_toggle_type === 'collapse' && 'width: 400px'"
70
70
  >
71
71
  <template x-if="nav_toggle_type === 'offcanvas'"> {# Needs to be template, x-show doesn't work here #}
72
72
  <div class="w-100 d-flex justify-content-end pb-2">
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-spire
3
- Version: 0.17.11
3
+ Version: 0.18.0
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.
@@ -45,6 +45,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
45
45
  Requires-Python: >=3.11
46
46
  Description-Content-Type: text/markdown
47
47
  License-File: LICENSE.md
48
+ Requires-Dist: beautifulsoup4>=4.14.2
48
49
  Requires-Dist: boto3>=1.34.0
49
50
  Requires-Dist: botocore>=1.34.0
50
51
  Requires-Dist: crispy-bootstrap5==2024.10
@@ -1,6 +1,6 @@
1
1
  django_spire/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  django_spire/conf.py,sha256=EYC1hXqYqheYrb_b6Q93LrSgNl91JV633E4N5j-KGTo,1012
3
- django_spire/consts.py,sha256=Bie71C5pHWjbYwTai1019M83OJOCxc-dh12K5Wsbbcw,391
3
+ django_spire/consts.py,sha256=8dDmU1AN7lUqpAKJhC3ilR8UnTjUc4UZ2TQY684N6P8,390
4
4
  django_spire/exceptions.py,sha256=L5ndRO5ftMmh0pHkO2z_NG3LSGZviJ-dDHNT73SzTNw,48
5
5
  django_spire/settings.py,sha256=tGxgEri3TQRBaiwX7YRcWifMf_g1xv1RznplFR6zZnI,821
6
6
  django_spire/urls.py,sha256=mKeZszb5U4iIGqddMb5Tt5fRC72U2wABEOi6mvOfEBU,656
@@ -377,7 +377,7 @@ django_spire/contrib/seeding/management/example.py,sha256=gVRnd5prEbIFgehoUOL8TM
377
377
  django_spire/contrib/seeding/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
378
378
  django_spire/contrib/seeding/management/commands/seeding.py,sha256=MQKYtw2HmoKbBfQAy_ajmxXgRTmzurmF__b0DE3v_wk,1617
379
379
  django_spire/contrib/seeding/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
380
- django_spire/contrib/seeding/model/base.py,sha256=7eNHVLIBk8PUymIkfkAoBZt_ziIGLfXFL1QsWTbxuu4,3232
380
+ django_spire/contrib/seeding/model/base.py,sha256=eqFk-F02GxedsdVtGRF-z1X_9sN8CzfBbsKMcRRpnuY,3244
381
381
  django_spire/contrib/seeding/model/config.py,sha256=ithRH5Em1ixKCVRMGenQsdRaOGuS0BkNMIicsRWH1-c,2049
382
382
  django_spire/contrib/seeding/model/enums.py,sha256=jLh6araHD6LrhzCvex8-xNQQLru2Y6XxjPKkiC0ISCo,129
383
383
  django_spire/contrib/seeding/model/django/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -812,12 +812,12 @@ django_spire/knowledge/entry/seeding/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
812
812
  django_spire/knowledge/entry/seeding/seed.py,sha256=n7ereq118GuqV1luNih7nuVpkrZpkBgPWt0FuE4Bl88,105
813
813
  django_spire/knowledge/entry/seeding/seeder.py,sha256=m5X9iqa9UnbtvmjFdtPsx2dcFA1Q0se4ZF2nps6oaNE,1955
814
814
  django_spire/knowledge/entry/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
815
- django_spire/knowledge/entry/services/automation_service.py,sha256=-WnEuexvcugK_MUKehN_CpYPtQIiumr8YStj2aygDNw,1685
815
+ django_spire/knowledge/entry/services/automation_service.py,sha256=0_Ypk5cXhGvkQLkmKBArFTrE_sZhXCnBencmuJeLxMI,1826
816
816
  django_spire/knowledge/entry/services/factory_service.py,sha256=bgUEHjdc9u2mxUJFy26qYOxUiJRHmhtcoH6AG3xzU0I,1379
817
817
  django_spire/knowledge/entry/services/processor_service.py,sha256=sfAM5ku7Td4k0jCe2szyoR72Bt1_OS75UKh7YPL4l2s,494
818
818
  django_spire/knowledge/entry/services/service.py,sha256=n8N2pshbE977bNoN5zf0gO-Kyy9LQLcGOJ4MMNT8Uj8,1806
819
819
  django_spire/knowledge/entry/services/tool_service.py,sha256=QL6w8t284LfSOJrQaF46uWInd4t413WYxcXCWsat_jE,1083
820
- django_spire/knowledge/entry/services/transformation_services.py,sha256=0ZJHO_ynm9GyFPfNYA0N_KjloGTPouyu9kEv1TebcOE,2672
820
+ django_spire/knowledge/entry/services/transformation_services.py,sha256=iLIg58Udv61brf3EyxuGEkIn5SuSEiTzrxJW5guzE0U,2687
821
821
  django_spire/knowledge/entry/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
822
822
  django_spire/knowledge/entry/tests/factories.py,sha256=gV6CK11SmLw2aE-g6WQc4m7eDodzoH94iCmqHn5PTXI,448
823
823
  django_spire/knowledge/entry/tests/test_urls/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -833,66 +833,60 @@ django_spire/knowledge/entry/version/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
833
833
  django_spire/knowledge/entry/version/admin.py,sha256=-I7UDBdaFODaziJya5UWWKhzckVKrbVcvvkzOrqYpzQ,638
834
834
  django_spire/knowledge/entry/version/choices.py,sha256=HQLCzgTQpskkcJ7s1PbvYTmHd-E8aKJsuWKz5gowg7k,163
835
835
  django_spire/knowledge/entry/version/constants.py,sha256=BXLllSze2dOz2ye6kJPtl3nfrlNO1kDER1HLZHpGP9o,30
836
- django_spire/knowledge/entry/version/maps.py,sha256=QgV0RuKUhhMbrE54ZoNjTXwVBb7ZjVLTEq-wGf6r9cs,320
837
- django_spire/knowledge/entry/version/models.py,sha256=gUeTL6l8D03Vzs_gexDq3hfq33L_DoiTVNR1ZrYU2Rk,1463
838
- django_spire/knowledge/entry/version/querysets.py,sha256=YwSX1DG8cB1g7AevJxnTTISNgnXbb37mzQYGjjCpG68,151
836
+ django_spire/knowledge/entry/version/maps.py,sha256=UJ_3-dD8p3-boQ_dT0pclXogYavDaFlrb_BSg19TE0k,319
837
+ django_spire/knowledge/entry/version/models.py,sha256=4qG-dsXzlHSXClpUK8d_pnXvU0316RuqKVSVbuEeR2w,1464
838
+ django_spire/knowledge/entry/version/querysets.py,sha256=RMMAWMdcqJ8n_TK8l2LUINRfbsVYec2DRi8l8groCR4,479
839
839
  django_spire/knowledge/entry/version/block/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
840
840
  django_spire/knowledge/entry/version/block/admin.py,sha256=mFcVIU2P02MaBPkf_UADPnY24nMzuHcAQa95r0tP2N0,535
841
- django_spire/knowledge/entry/version/block/choices.py,sha256=kbfW2d03lC_4YOE0Xs2pkJdNS6NA9GbEGsCh_I12FAY,182
841
+ django_spire/knowledge/entry/version/block/choices.py,sha256=A_QbRGJJOIBtrevoJN6TBwNHvl3QT4n-DBJYHxTwRgM,140
842
842
  django_spire/knowledge/entry/version/block/constants.py,sha256=rClZzAMRu603_mAqOPn9OKw-8Eomck69Cg0ehwbh8X8,22
843
- django_spire/knowledge/entry/version/block/maps.py,sha256=kY1nwT5_JzAXr-vbPQeyqlljotrZnNb3NwIOD8HXXE0,681
844
- django_spire/knowledge/entry/version/block/models.py,sha256=jz_ilfBh9Rx2gP6x7FZ98G5N3eGxezOqj31KQZOilLw,1827
845
- django_spire/knowledge/entry/version/block/querysets.py,sha256=OGKYOg-SifZWQNJ_8r5NsC5_JeV2lVzuMZkWKHKVYs0,562
846
- django_spire/knowledge/entry/version/block/blocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
847
- django_spire/knowledge/entry/version/block/blocks/block.py,sha256=ZMZ6pLfS-Dnl67BCHPEPFxMb39NqxttddPZ9SYt-leQ,1522
848
- django_spire/knowledge/entry/version/block/blocks/heading_block.py,sha256=5dMe1wtBk5mAuA7_aMTuBrKnkquAbl1qBycBkSaH61g,591
849
- django_spire/knowledge/entry/version/block/blocks/list_block.py,sha256=o11x-DFdpZHGcDS7HeqFCGvoaUI-k_GcItaNBF-8lV8,1212
850
- django_spire/knowledge/entry/version/block/blocks/sub_heading_block.py,sha256=qtvIPLVr9vKyTs3zIsqAbKdyZ67wyev2pyp2NtwJshI,606
851
- django_spire/knowledge/entry/version/block/blocks/text_block.py,sha256=BBBW89xPjCZrV0UBaMcJMBgZhMWzyTbWJNIorbIBDLI,579
843
+ django_spire/knowledge/entry/version/block/models.py,sha256=aY1LLDtUx9AytdUBmp1SVWxw9mmF0zpCfr2AiF8WEps,2185
844
+ django_spire/knowledge/entry/version/block/querysets.py,sha256=WGJbcpG2RhL5IHHbBkyGoVWB0Bfl8TeA6lgEj2bkFek,806
845
+ django_spire/knowledge/entry/version/block/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
846
+ django_spire/knowledge/entry/version/block/data/data.py,sha256=MTPV2O7bm80ONzKLdOEDo_XNcMhu9JfAae3Tj1npggs,1098
847
+ django_spire/knowledge/entry/version/block/data/heading_data.py,sha256=kP0ctDQhSnXJfsXqs_TQ8GsMxi4CR5MmfacBNa7AyHU,468
848
+ django_spire/knowledge/entry/version/block/data/maps.py,sha256=RZvoTPcooS-zxiaELbZ5-k3-AyDdRY9YclU4lStaF0E,777
849
+ django_spire/knowledge/entry/version/block/data/text_data.py,sha256=JibuYNs4qFojASAuNhEw_xT7ycRlt2F2PMMxsLmKK5U,411
850
+ django_spire/knowledge/entry/version/block/data/list/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
851
+ django_spire/knowledge/entry/version/block/data/list/choices.py,sha256=-wmuZ7qPc-b-4Uk_uFwW3rFPjHiRrPC1GGTn4eXk3gw,401
852
+ django_spire/knowledge/entry/version/block/data/list/data.py,sha256=b06acpjSnak38o4gD6vT49Ia7ThHxtsD-QGwbvCHwO4,3415
853
+ django_spire/knowledge/entry/version/block/data/list/maps.py,sha256=aus83oh5h2SXdip2z9gpXbRwMKpq1HanywTw6h2z_Wg,582
854
+ django_spire/knowledge/entry/version/block/data/list/meta.py,sha256=o1ddEnVS4lSZWbuAwRgOVThtjEP_vEkmlOxwM9QtCRU,363
852
855
  django_spire/knowledge/entry/version/block/seeding/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
853
- django_spire/knowledge/entry/version/block/seeding/constants.py,sha256=YYEvL0N9P2xKs5e2gtlcZ7fz3AoHwXUPsxS3LLapOyw,15830
856
+ django_spire/knowledge/entry/version/block/seeding/constants.py,sha256=cFjWloJLkx1Ov1AAUHRDeghqqh4QtiY9ho-iAn2uIDw,18528
854
857
  django_spire/knowledge/entry/version/block/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
855
- django_spire/knowledge/entry/version/block/services/factory_service.py,sha256=H-mYjw2trGFWLpZk2Q9edVQ6acpcGphIj3lg3j8CxkE,2464
856
- django_spire/knowledge/entry/version/block/services/processor_service.py,sha256=2dyIoNQt_8PPG6xsd9eq6wAbQq0AoOX96_AY2PiUZhg,919
857
- django_spire/knowledge/entry/version/block/services/service.py,sha256=ltjGNCLQDWt5I2xwsmpQ0GtZA20HYrWhnAGDsXvxsxA,987
858
- django_spire/knowledge/entry/version/block/services/transformation_service.py,sha256=Tyax1paMc3xOo-v-U5SVjHxKZbio3XJjbOVwnImRv4s,1001
858
+ django_spire/knowledge/entry/version/block/services/factory_service.py,sha256=0emWKluuVuPd63G9uguhgCEwZ2GPyWklD_LU7S-V3HU,1668
859
+ django_spire/knowledge/entry/version/block/services/service.py,sha256=9wz_2Rn3iWienOUjjiE5ngaHcjyAywAVPhBP-DmyS7s,508
859
860
  django_spire/knowledge/entry/version/block/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
860
- django_spire/knowledge/entry/version/block/tests/factories.py,sha256=O_K4187OY6_hTWpjkJxZKm1vh2eOExfPVRVEWGSPw1U,853
861
- django_spire/knowledge/entry/version/block/tests/test_urls/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
862
- django_spire/knowledge/entry/version/block/tests/test_urls/test_json_urls.py,sha256=xqDpZ7lk6on119RKWfyaNUYd4oXa5o8wCRdO6AslGGo,838
863
- django_spire/knowledge/entry/version/block/urls/__init__.py,sha256=zngwT2tZGswWlhTLfuMlQV6fSCxttK8U78rbtE-PmgE,240
864
- django_spire/knowledge/entry/version/block/urls/json_urls.py,sha256=de6CfWEh8_SL7xBKKrjon-yny0Xk2OMAd1XefvzVM1w,215
865
- django_spire/knowledge/entry/version/block/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
866
- django_spire/knowledge/entry/version/block/views/json_views.py,sha256=f8fUNEljAO99_GAweNUExmhKEEqYsoeOrDf5yKRKe0Y,996
861
+ django_spire/knowledge/entry/version/block/tests/factories.py,sha256=rcBMAnuu1jNo8kcC4yQX5oGteP4jobJ6NagcISz5p8M,1130
867
862
  django_spire/knowledge/entry/version/converters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
868
863
  django_spire/knowledge/entry/version/converters/converter.py,sha256=0zbM7FTCpXe_O8gfsVc4V0Pg4cks7HMZi4SXJQ_HIEw,584
869
864
  django_spire/knowledge/entry/version/converters/docx_converter.py,sha256=zMPYoro4H3l993vSUoDSOjYubWlEfPJ0hwlM8Uw9W9k,2624
870
- django_spire/knowledge/entry/version/converters/markdown_converter.py,sha256=MsSqdwNBQkk3pV086pKrXJ7al7-FrQRQD75WXbVB2_0,4990
865
+ django_spire/knowledge/entry/version/converters/markdown_converter.py,sha256=uJisGt1nXg78XdA2jSCftN0fmFn9BLZuuLvBGi7c_Vg,8423
871
866
  django_spire/knowledge/entry/version/intelligence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
872
867
  django_spire/knowledge/entry/version/intelligence/bots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
873
868
  django_spire/knowledge/entry/version/intelligence/bots/markdown_format_llm_bot.py,sha256=3DPR-Er6S_2Z7FZC87SxocHk7Go7-LZPsh7IG4WI_OU,585
874
869
  django_spire/knowledge/entry/version/seeding/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
875
- django_spire/knowledge/entry/version/seeding/seeder.py,sha256=hsi8bm8kIDnWz9XJQUb_Ml9eFaDABs5odDKjq3DKfcY,2515
870
+ django_spire/knowledge/entry/version/seeding/seeder.py,sha256=QlakhnKr-v8sM7TW2yMMUl2EZuOJOcIGS3yA6MDCcXc,2660
876
871
  django_spire/knowledge/entry/version/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
877
- django_spire/knowledge/entry/version/services/processor_service.py,sha256=0K_GxJKyAho58bRG2YBLOe2dF33_jqSkF5CKrQt_PGw,614
872
+ django_spire/knowledge/entry/version/services/processor_service.py,sha256=b_f34r7d5FlPk-sEuXU-8ANFOTQ9JKxuN0nAtlfH_dA,1239
878
873
  django_spire/knowledge/entry/version/services/service.py,sha256=qQvy4k9Zwyi1p7d2eu97-OmKDZrI96PFNaHQ7E5RQuI,506
874
+ django_spire/knowledge/entry/version/services/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
875
+ django_spire/knowledge/entry/version/services/tests/test_processor_service.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
879
876
  django_spire/knowledge/entry/version/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
880
877
  django_spire/knowledge/entry/version/tests/factories.py,sha256=vQ-6O2mgsE70UWDaxCk7_60Rpg2roOpSvxoSb8pI5KQ,594
881
878
  django_spire/knowledge/entry/version/tests/test_converters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
882
879
  django_spire/knowledge/entry/version/tests/test_converters/test_docx_converter.py,sha256=KpDUr4kVGSBtDXV7UmOy9yv7cI8LNuguZr0PEtunxZw,1597
883
880
  django_spire/knowledge/entry/version/tests/test_urls/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
884
- django_spire/knowledge/entry/version/tests/test_urls/test_form_urls.py,sha256=S60v1xMCO6SoGBGyFKOp-Wdx8xauU_QuGwedm07aaC4,929
885
- django_spire/knowledge/entry/version/tests/test_urls/test_json_urls.py,sha256=7ENBpph8uZHCmF4Y60FkJNaSj_fznor80Ivk61NJt4w,1704
881
+ django_spire/knowledge/entry/version/tests/test_urls/test_json_urls.py,sha256=WFN-aR6NmZGNKv03Jlw10YR730JYpbydYHDQPPbbkJI,1161
886
882
  django_spire/knowledge/entry/version/tests/test_urls/test_page_urls.py,sha256=wd2COFdO4ijso4cNwHIMdY4dSkZksdFDZDkNaPMwDL4,946
887
- django_spire/knowledge/entry/version/urls/__init__.py,sha256=Ey2OtPpyHrH2xmXIF6fBlqI7A9XgZxpTQc1JIbXerSM,595
888
- django_spire/knowledge/entry/version/urls/form_urls.py,sha256=oLvVKjLqGsNaXzzTaXlW17s4MhmaQw0IJKWxuOjKs_Y,209
889
- django_spire/knowledge/entry/version/urls/json_urls.py,sha256=mqrmf_NIk-rBTyVbuBPmOhjNtmMz9kh6qac0A_K86RA,492
883
+ django_spire/knowledge/entry/version/urls/__init__.py,sha256=e0MeLIxK5W4H68nK3A5TKbD7ZJFwFFJ2bZNhh2T-4uk,394
884
+ django_spire/knowledge/entry/version/urls/json_urls.py,sha256=Mns6ZTB5-52iHbaFw5Cb5elw-PqhYa3mxBTeSNY2saw,258
890
885
  django_spire/knowledge/entry/version/urls/page_urls.py,sha256=5kcQ6LZZj0NN9t-eKe2Vo6TJx_aSjyweEtpcEtr2qhY,204
891
886
  django_spire/knowledge/entry/version/urls/redirect_urls.py,sha256=9X7UqKYIxwDRVPHTwT1zywpWybD1hJ923p3cX1itZ5Q,219
892
887
  django_spire/knowledge/entry/version/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
893
- django_spire/knowledge/entry/version/views/form_views.py,sha256=ePBhEes9t4WL9Lh8AmLJKo15Ce6ko0xRDPtKCKKsEqo,2314
894
- django_spire/knowledge/entry/version/views/json_views.py,sha256=N_QfKcb689zbHndfWh0y0kbz__JPuFGNtjhSAbSDDGI,2869
895
- django_spire/knowledge/entry/version/views/page_views.py,sha256=TQgv5gXkc5v0xVj5DgCoXyP9S9JA4BuM5_6XhZnpBFw,1456
888
+ django_spire/knowledge/entry/version/views/json_views.py,sha256=2CWaNseOsbUx6NFBlvI8dBG6s5_xn1HGRNJTHuXlsy8,819
889
+ django_spire/knowledge/entry/version/views/page_views.py,sha256=CEwmvihZPe0VilQtM3wvhHb38by79Kz86c-seAJmKFw,1611
896
890
  django_spire/knowledge/entry/version/views/redirect_views.py,sha256=4MT4nxSaQHkuD6pCj08iV8BmPufQ89kyuusiPGGkNWk,754
897
891
  django_spire/knowledge/entry/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
898
892
  django_spire/knowledge/entry/views/form_views.py,sha256=7iSuTLmYA9No_E62YrP3LRYsSB2fzCfR0ZjVxlw7lSQ,4256
@@ -915,13 +909,16 @@ django_spire/knowledge/migrations/0001_initial.py,sha256=0oAx4e0Tu1wbcMwQZ4I_B2X
915
909
  django_spire/knowledge/migrations/0002_alter_entryversionblock_type.py,sha256=Eg8tLjDO0nJ3go_jgVvoqwYKFOpYUUyNtZtLI2V3IQQ,527
916
910
  django_spire/knowledge/migrations/0003_alter_collection_order_alter_entry_order_and_more.py,sha256=nIIUg1lHQ1iLbPlOulwZgzHrP1erGMYVXDaEdDXv4ik,749
917
911
  django_spire/knowledge/migrations/0004_alter_collection_options_collectiongroup.py,sha256=Ds6axLJLsmbcJORQmmwHe0aTYhpDJEgGH-UkL0jIk2k,1309
912
+ django_spire/knowledge/migrations/0005_entryversionblock__tunes_data_and_more.py,sha256=sA_YCnFX6R2Wt9OecVpW4Sj27k2iRcw4KbyJVdcQYqY,771
918
913
  django_spire/knowledge/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
919
914
  django_spire/knowledge/seeding/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
920
915
  django_spire/knowledge/seeding/seed.py,sha256=LRhVfPHiFluSLLtjSY44YM9Oo1Hvfs_U-ksRvKk7pOg,97
921
916
  django_spire/knowledge/static/django_spire/knowledge/collection/js/managers.js,sha256=1b0pRPYJvYjKKZB2wshdoseAUR3_Al-2qxFUWE5q-oo,4319
922
917
  django_spire/knowledge/static/django_spire/knowledge/collection/js/x_component.js,sha256=avczuHac3i58k06wA-LPpgupedCYbuDVTjTYVjEho18,898
923
- django_spire/knowledge/static/django_spire/knowledge/css/navigation_items.css,sha256=LwWOW4lsgkeIz3JuP9DQ-x10_04TvQw8fM4Fi-QT9M8,179
918
+ django_spire/knowledge/static/django_spire/knowledge/css/navigation_items.css,sha256=jhjW4fiQI13PUAkSupLrLn-Fu9nzAVqMezK8EkJnGZ8,178
919
+ django_spire/knowledge/static/django_spire/knowledge/entry/version/js/editor.js,sha256=wkqXANqVNfDvYL0X_Xvt18F0JclbT2QumEAowV4QzG0,2939
924
920
  django_spire/knowledge/static/django_spire/knowledge/entry/version/js/managers.js,sha256=q-HiSnOnMMomxU0EAWSbQO55HMVvb8wPxA0KCP3VyP4,2772
921
+ django_spire/knowledge/static/django_spire/knowledge/entry/version/js/null_paragraph.js,sha256=Bc0oslLdlLcncbcUklhU1RF4PGiByC-mH-ENq1S1Niw,211
925
922
  django_spire/knowledge/templates/django_spire/knowledge/collection/card/form_card.html,sha256=Fm1PFgMJO0B1ji86pjeL_KbGkKq-ho7n6v9gtCODlzU,154
926
923
  django_spire/knowledge/templates/django_spire/knowledge/collection/component/x_collection_navigation.html,sha256=QlkduxfxCuQkObk0kNHJm2rL_EYPRZA24eVJhWxrXpY,2332
927
924
  django_spire/knowledge/templates/django_spire/knowledge/collection/container/detail_container.html,sha256=0T1L7mRyAH-I04_8rmyL6ZbsT1TWcIGzZ-NnGPllRco,321
@@ -933,25 +930,15 @@ django_spire/knowledge/templates/django_spire/knowledge/entry/card/list_card.htm
933
930
  django_spire/knowledge/templates/django_spire/knowledge/entry/container/import_form_container.html,sha256=Bs2mH4qjWsOUzX70cvwAo_0keIHTJI9h3MrNL1px-mY,225
934
931
  django_spire/knowledge/templates/django_spire/knowledge/entry/file/card/list_card.html,sha256=4Beh6y3ywi1Ihlihamb42f-6OK2-raNkdLk0GuuTIKs,1178
935
932
  django_spire/knowledge/templates/django_spire/knowledge/entry/file/item/list_item.html,sha256=JfmhTm4wKQmMh9dQ5qfQDa8d4B0uMFPASqWnV_psHSM,693
936
- django_spire/knowledge/templates/django_spire/knowledge/entry/file/page/list_page.html,sha256=J66ukMYF2TVUlHQxOgsME-CoYXEZO3Y8z7pD2K1jMqE,254
933
+ django_spire/knowledge/templates/django_spire/knowledge/entry/file/page/list_page.html,sha256=T-dT1HnjEJJiBC9BIbegd7jtws3nZSh2ZPNGC5EypC0,275
937
934
  django_spire/knowledge/templates/django_spire/knowledge/entry/form/form.html,sha256=hklsBNX-p1aGnxMMsi3W6W5Rsb58XGKTDtDB0MWEo5c,491
938
935
  django_spire/knowledge/templates/django_spire/knowledge/entry/form/import_form.html,sha256=VHmD01qOdHq4s8zOnEHyMeiJLLEfnQepj844sDi2_ug,1944
939
936
  django_spire/knowledge/templates/django_spire/knowledge/entry/item/list_item.html,sha256=s95BghTQVtPvXF8usDiOOZI1WI7J9E7qr5SovY1fXIY,2103
940
937
  django_spire/knowledge/templates/django_spire/knowledge/entry/modal/publish_confirm_modal.html,sha256=7SsTjvk_iOdBgnYy83pMBPIdbuvJadd4h5XI5mPos5o,724
941
938
  django_spire/knowledge/templates/django_spire/knowledge/entry/page/form_page.html,sha256=eynNheKGCBbGjjrMExUnNBMVGN_ObCWEKhKdoXRJUY4,280
942
939
  django_spire/knowledge/templates/django_spire/knowledge/entry/page/import_form_page.html,sha256=b91A9j2F5FhGPqpnxwcsCpGfxXfj4fQzfJHJK1OI_SI,297
943
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/detail/component/heading_component.html,sha256=9uRL0aC5yL8xYwCyBwBBIKIyF4B_lk07NCZFoMQ6U2s,97
944
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/detail/component/list_item_component.html,sha256=9Qaj8SQZjg3aRjXAPMOhBCAekke1wKfOSY7hPcvIAs8,1043
945
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/detail/component/sub_heading_component.html,sha256=xWZ_11C85XUoss4lm_IcdFyg9_UK9sdau-xJvHkFQhg,97
946
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/detail/component/text_component.html,sha256=oWAb3ZKQ512LzWUzWc_RghwAE0cNPqim5cUm6Fg25j4,94
947
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/dropdown/add_dropdown.html,sha256=AB_HvGzUuL4i77tCsRU7O1KcNX9tlbHHDMGs3lUjwXY,865
948
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/update/component/heading_component.html,sha256=RhT8tmzOBYNZlozaNnXxAyhLvrsqtpScaVEncjEbsgg,142
949
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/update/component/list_item_component.html,sha256=l8MUO4bGeOZXuFKQO-sWPn1hd5Bm6ro5JezZG2M0aZI,430
950
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/update/component/sub_heading_component.html,sha256=bN4m-uwDqgu1imj9qSFjCe_J0m_SVt66dKzmyVJWaIk,142
951
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/block/update/component/text_component.html,sha256=HEiMP2MEyCrBgpppL0OB5su_D4WTslx3Y2TwmupCHYM,2065
952
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/container/detail_container.html,sha256=fdVyqOnrf_cQOA7aXB2KgavlXsg5merlJotaiErBMWI,1618
953
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/container/form_container.html,sha256=PS6AXIVulrYKEOldVOf3YSB8vbdX-pqqf4eWIppOVgw,5812
954
- django_spire/knowledge/templates/django_spire/knowledge/entry/version/page/detail_page.html,sha256=tMHA_2jRzFqpP725fQaPJJEdlmuiDmaqSiynVin4Sl0,338
940
+ django_spire/knowledge/templates/django_spire/knowledge/entry/version/container/detail_container.html,sha256=UFZFe_b9Fm7pPxv-XQKj1IucvdOTVBf1MSgWOr7aEho,2950
941
+ django_spire/knowledge/templates/django_spire/knowledge/entry/version/page/detail_page.html,sha256=RsjExLrhEY1RmUytC1knYYRBcFebYsnXgRZrpNQXRFc,1244
955
942
  django_spire/knowledge/templates/django_spire/knowledge/entry/version/page/form_page.html,sha256=0g8jujdyS20THm9GZ-Oi6CdsZi8m9w6k-MhKYuXwouM,733
956
943
  django_spire/knowledge/templates/django_spire/knowledge/message/knowledge_message_intel.html,sha256=yIca58o4_UC-6WgeGT9WOrJ0cQrXfZo3B0QFd03nlXU,130
957
944
  django_spire/knowledge/templates/django_spire/knowledge/navigation/card/navigation_card.html,sha256=oOiPVPGpdzATH4jCsoSG5hHs25bDyjk10NELHg7ac4Y,223
@@ -960,7 +947,7 @@ django_spire/knowledge/templates/django_spire/knowledge/navigation/item/collecti
960
947
  django_spire/knowledge/templates/django_spire/knowledge/navigation/item/collection/dropdown/navigation_ellipsis_dropdown.html,sha256=DeM7yRcjRN25eRvdOK-3Ae0kbYaMWvk7Ufbc8AZphgk,1023
961
948
  django_spire/knowledge/templates/django_spire/knowledge/navigation/item/entry/entry_item.html,sha256=3sXmm1fMIxHMuSc0Hp0FLWujrHS6v_YrLsHWSFSaFjg,780
962
949
  django_spire/knowledge/templates/django_spire/knowledge/navigation/item/entry/dropdown/navigation_ellipsis_dropdown.html,sha256=SiwlFdvIbmcWyexxNMBO4b-mbOwqAAtPHLv8Fqr8UIs,757
963
- django_spire/knowledge/templates/django_spire/knowledge/navigation/page/full_page.html,sha256=kYebthTpZqUtW0QM_cDC-47_4Ocz_27YEJk8IjbOL7Q,3552
950
+ django_spire/knowledge/templates/django_spire/knowledge/navigation/page/full_page.html,sha256=60cOozhmpf7THR6T2k6Pzpn069nH7nnW-P54Spw6I9k,3553
964
951
  django_spire/knowledge/templates/django_spire/knowledge/page/home_page.html,sha256=hRWDcr1H86gg3pXGKnbcsYeyV0RrdBLpBaHXi-9wtko,300
965
952
  django_spire/knowledge/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
966
953
  django_spire/knowledge/templatetags/spire_knowledge_tags.py,sha256=n3eHc8QZplOi9ovD8qbfzp66F91tdm6q8z1YPcnmVOM,622
@@ -1105,8 +1092,8 @@ django_spire/theme/urls/page_urls.py,sha256=S8nkKkgbhG3XHI3uMUL-piOjXIrRkuY2UlM_
1105
1092
  django_spire/theme/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1106
1093
  django_spire/theme/views/json_views.py,sha256=W1khC2K_EMbEzAFmMxC_P76_MFnkRH4-eVdodrRfAhw,1904
1107
1094
  django_spire/theme/views/page_views.py,sha256=pHr8iekjtR99xs7w1taj35HEo133Svq1dvDD0y0VL1c,3933
1108
- django_spire-0.17.11.dist-info/licenses/LICENSE.md,sha256=tlTbOtgKoy-xAQpUk9gPeh9O4oRXCOzoWdW3jJz0wnA,1091
1109
- django_spire-0.17.11.dist-info/METADATA,sha256=9-OpANaoQUpUgf3TIP7ZjlIzPdhDYvj689KbwbZ1cuk,4937
1110
- django_spire-0.17.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1111
- django_spire-0.17.11.dist-info/top_level.txt,sha256=xf3QV1e--ONkVpgMDQE9iqjQ1Vg4--_6C8wmO-KxPHQ,13
1112
- django_spire-0.17.11.dist-info/RECORD,,
1095
+ django_spire-0.18.0.dist-info/licenses/LICENSE.md,sha256=tlTbOtgKoy-xAQpUk9gPeh9O4oRXCOzoWdW3jJz0wnA,1091
1096
+ django_spire-0.18.0.dist-info/METADATA,sha256=AZ9gn0TzJPSN7CG9k1yNFi5UrBIQe3Qb2q3b_VJXcuI,4974
1097
+ django_spire-0.18.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1098
+ django_spire-0.18.0.dist-info/top_level.txt,sha256=xf3QV1e--ONkVpgMDQE9iqjQ1Vg4--_6C8wmO-KxPHQ,13
1099
+ django_spire-0.18.0.dist-info/RECORD,,
@@ -1,51 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING
4
-
5
- from abc import ABC, abstractmethod
6
- from typing import Any
7
-
8
- from django.template.loader import render_to_string
9
- from pydantic import BaseModel
10
-
11
- from django_spire.knowledge.entry.version.block.choices import BlockTypeChoices
12
-
13
- if TYPE_CHECKING:
14
- from django_spire.knowledge.entry.version.block.models import EntryVersionBlock
15
-
16
-
17
- class BaseBlock(ABC, BaseModel):
18
- value: Any
19
- type: BlockTypeChoices
20
- detail_template: str
21
- update_template: str
22
-
23
- def __init_subclass__(cls, *args, **kwargs):
24
- super().__init_subclass__(*args, **kwargs)
25
-
26
- if cls.detail_template is None or cls.detail_template == '':
27
- raise ValueError(
28
- f'{cls.__module__}.{cls.__qualname__}.detail_template must be set'
29
- )
30
-
31
- if cls.update_template is None or cls.update_template == '':
32
- raise ValueError(
33
- f'{cls.__module__}.{cls.__qualname__}.update_template must be set'
34
- )
35
-
36
- @abstractmethod
37
- def render_to_text(self) -> str:
38
- raise NotImplementedError
39
-
40
- def to_dict(self, version_block: EntryVersionBlock):
41
- return {
42
- 'value': self.value,
43
- 'type': self.type,
44
- 'update_template_rendered': render_to_string(
45
- context={
46
- 'version_block': version_block,
47
- 'value': self.value,
48
- },
49
- template_name=self.update_template,
50
- )
51
- }
@@ -1,14 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from django_spire.knowledge.entry.version.block.choices import BlockTypeChoices
4
- from django_spire.knowledge.entry.version.block.blocks.block import BaseBlock
5
-
6
-
7
- class HeadingBlock(BaseBlock):
8
- value: str
9
- type: BlockTypeChoices = BlockTypeChoices.HEADING
10
- detail_template: str = 'django_spire/knowledge/entry/version/block/detail/component/heading_component.html'
11
- update_template: str = 'django_spire/knowledge/entry/version/block/update/component/heading_component.html'
12
-
13
- def render_to_text(self) -> str:
14
- return f'{self.value}\n'
@@ -1,31 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING
4
-
5
- from django_spire.knowledge.entry.version.block.blocks.block import BaseBlock
6
- from django_spire.knowledge.entry.version.block.choices import BlockTypeChoices
7
- from django_spire.knowledge.entry.version.block.constants import SPACES_PER_INDENT
8
-
9
- if TYPE_CHECKING:
10
- from django_spire.knowledge.entry.version.block.models import EntryVersionBlock
11
-
12
-
13
- class ListItemBlock(BaseBlock):
14
- value: str
15
- type: BlockTypeChoices = BlockTypeChoices.LIST_ITEM
16
- detail_template: str = 'django_spire/knowledge/entry/version/block/detail/component/list_item_component.html'
17
- update_template: str = 'django_spire/knowledge/entry/version/block/update/component/list_item_component.html'
18
- indent_level: int = 0
19
- bullet: str = '-'
20
- ordered: bool = False
21
-
22
- def render_to_text(self) -> str:
23
- indent = ' ' * self.indent_level * SPACES_PER_INDENT
24
- return f'{indent}{self.bullet} {self.value}\n'
25
-
26
- def to_dict(self, version_block: EntryVersionBlock):
27
- return super().to_dict(version_block) | {
28
- 'indent_level': self.indent_level,
29
- 'bullet': self.bullet,
30
- 'ordered': self.ordered,
31
- }