django-spire 0.23.8__py3-none-any.whl → 0.23.10__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/consts.py +1 -1
- django_spire/contrib/progress/__init__.py +7 -13
- django_spire/contrib/progress/enums.py +2 -1
- django_spire/contrib/progress/session.py +283 -0
- django_spire/contrib/progress/static/django_spire/js/contrib/progress/progress.js +35 -57
- django_spire/contrib/progress/tasks.py +67 -0
- django_spire/contrib/progress/templates/django_spire/contrib/progress/card/card.html +25 -24
- django_spire/contrib/progress/templates/django_spire/contrib/progress/modal/content.html +58 -67
- django_spire/core/management/commands/spire_startapp_pkg/template/app/apps.py.template +2 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/__init__.py.template +2 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/form_urls.py.template +2 -0
- django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/page_urls.py.template +2 -0
- django_spire/core/templates/django_spire/card/card.html +1 -1
- django_spire/core/templates/django_spire/card/title_card.html +7 -4
- django_spire/core/templates/django_spire/table/base.html +4 -4
- {django_spire-0.23.8.dist-info → django_spire-0.23.10.dist-info}/METADATA +2 -2
- {django_spire-0.23.8.dist-info → django_spire-0.23.10.dist-info}/RECORD +20 -23
- {django_spire-0.23.8.dist-info → django_spire-0.23.10.dist-info}/licenses/LICENSE.md +1 -1
- django_spire/contrib/progress/mixins.py +0 -36
- django_spire/contrib/progress/runner.py +0 -140
- django_spire/contrib/progress/states.py +0 -64
- django_spire/contrib/progress/task.py +0 -40
- django_spire/contrib/progress/tracker.py +0 -245
- {django_spire-0.23.8.dist-info → django_spire-0.23.10.dist-info}/WHEEL +0 -0
- {django_spire-0.23.8.dist-info → django_spire-0.23.10.dist-info}/top_level.txt +0 -0
|
@@ -10,115 +10,106 @@
|
|
|
10
10
|
|
|
11
11
|
{% block modal_content_content %}
|
|
12
12
|
<div
|
|
13
|
-
data-stream-url="{% block progress_stream_url %}{% endblock %}"
|
|
14
|
-
data-redirect-url="{% block progress_redirect_url %}{% endblock %}"
|
|
15
13
|
data-redirect-delay="{% block progress_redirect_delay %}1000{% endblock %}"
|
|
14
|
+
data-redirect-url="{% block progress_redirect_url %}{% endblock %}"
|
|
15
|
+
data-stream-url="{% block progress_stream_url %}{% endblock %}"
|
|
16
16
|
x-data="{
|
|
17
|
-
tasks: {},
|
|
18
|
-
task_order: [],
|
|
19
|
-
overall_progress: 0,
|
|
20
|
-
message: 'Initializing...',
|
|
21
17
|
has_error: false,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
let stream_url = this.$el.dataset.streamUrl;
|
|
26
|
-
let redirect_url = this.$el.dataset.redirectUrl;
|
|
27
|
-
let redirect_delay = parseInt(this.$el.dataset.redirectDelay);
|
|
18
|
+
message: 'Initializing...',
|
|
19
|
+
overall_percent: 0,
|
|
20
|
+
tasks: {},
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (data.task_order) {
|
|
34
|
-
this.task_order = data.task_order;
|
|
35
|
-
}
|
|
36
|
-
if (data.tasks) {
|
|
37
|
-
this.tasks = data.tasks;
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
on_complete: (data) => {
|
|
41
|
-
setTimeout(() => {
|
|
42
|
-
close_modal();
|
|
43
|
-
}, 500);
|
|
22
|
+
async init() {
|
|
23
|
+
let stream = new ProgressStream(this.$el.dataset.streamUrl, {
|
|
24
|
+
on_complete: () => {
|
|
25
|
+
setTimeout(() => close_modal(), 500);
|
|
44
26
|
},
|
|
45
27
|
on_error: (data) => {
|
|
46
28
|
this.has_error = true;
|
|
47
|
-
this.message = data.message;
|
|
29
|
+
this.message = data.message || 'An error occurred';
|
|
30
|
+
},
|
|
31
|
+
on_update: (data) => {
|
|
32
|
+
this.overall_percent = data.overall_percent;
|
|
33
|
+
this.tasks = data.tasks;
|
|
48
34
|
},
|
|
49
|
-
|
|
50
|
-
|
|
35
|
+
redirect_delay: parseInt(this.$el.dataset.redirectDelay),
|
|
36
|
+
redirect_url: this.$el.dataset.redirectUrl,
|
|
51
37
|
});
|
|
52
|
-
this.stream.start();
|
|
53
|
-
},
|
|
54
38
|
|
|
55
|
-
|
|
56
|
-
return name.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
|
|
39
|
+
await stream.start();
|
|
57
40
|
},
|
|
58
41
|
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
if (
|
|
62
|
-
if (
|
|
63
|
-
return '
|
|
42
|
+
get_status_icon(status) {
|
|
43
|
+
if (status === 'complete') return 'bi-check-circle-fill text-success';
|
|
44
|
+
if (status === 'error') return 'bi-x-circle-fill text-danger';
|
|
45
|
+
if (status === 'running') return 'bi-arrow-repeat text-primary spin';
|
|
46
|
+
return 'bi-circle text-secondary';
|
|
64
47
|
}
|
|
65
48
|
}"
|
|
66
49
|
>
|
|
67
50
|
<div class="row g-3">
|
|
68
51
|
<div class="col-12" x-show="!has_error">
|
|
69
|
-
<template x-for="
|
|
70
|
-
<div class="mb-3"
|
|
71
|
-
<div class="d-flex
|
|
72
|
-
<
|
|
73
|
-
<span class="
|
|
52
|
+
<template x-for="(task, task_id) in tasks" :key="task_id">
|
|
53
|
+
<div class="mb-3">
|
|
54
|
+
<div class="d-flex align-items-center mb-1">
|
|
55
|
+
<i class="bi me-2" :class="get_status_icon(task.status)"></i>
|
|
56
|
+
<span class="fw-medium" x-text="task.name"></span>
|
|
57
|
+
<span class="ms-auto fs-7" x-text="task.percent + '%'"></span>
|
|
74
58
|
</div>
|
|
75
|
-
<div class="progress" style="height:
|
|
59
|
+
<div class="progress" style="height: 4px;">
|
|
76
60
|
<div
|
|
77
61
|
class="progress-bar"
|
|
78
|
-
:class="
|
|
62
|
+
:class="task.status === 'error' ? 'bg-danger' : 'bg-success'"
|
|
79
63
|
role="progressbar"
|
|
80
|
-
:style="'width: ' +
|
|
64
|
+
:style="'width: ' + task.percent + '%'"
|
|
81
65
|
></div>
|
|
82
66
|
</div>
|
|
67
|
+
<small class="text-muted" x-text="task.message"></small>
|
|
83
68
|
</div>
|
|
84
69
|
</template>
|
|
85
70
|
|
|
86
71
|
<div class="mt-4 pt-3 border-top">
|
|
87
72
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
|
88
|
-
<span class="
|
|
89
|
-
<span
|
|
73
|
+
<span class="fw-semibold">Overall Progress</span>
|
|
74
|
+
<span x-text="overall_percent + '%'"></span>
|
|
90
75
|
</div>
|
|
91
76
|
<div class="progress" style="height: 8px;">
|
|
92
77
|
<div
|
|
93
|
-
class="progress-bar bg-
|
|
78
|
+
class="progress-bar bg-primary"
|
|
94
79
|
role="progressbar"
|
|
95
|
-
:style="'width: ' +
|
|
80
|
+
:style="'width: ' + overall_percent + '%'"
|
|
96
81
|
></div>
|
|
97
82
|
</div>
|
|
98
83
|
</div>
|
|
99
|
-
</div>
|
|
100
84
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
{% block progress_wait_message %}Processing your request. This may take a moment.{% endblock %}
|
|
85
|
+
<p class="text-app-secondary mb-0 fs-7 text-center mt-3">
|
|
86
|
+
{% block progress_wait_message %}This may take a moment. Please do not close this window.{% endblock %}
|
|
104
87
|
</p>
|
|
105
88
|
</div>
|
|
106
89
|
|
|
107
90
|
<div class="col-12" x-show="has_error" x-cloak>
|
|
108
|
-
<div class="
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
<
|
|
114
|
-
|
|
115
|
-
{%
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
</span>
|
|
119
|
-
</div>
|
|
91
|
+
<div class="d-flex align-items-center justify-content-center py-4">
|
|
92
|
+
<i class="bi bi-x-circle-fill text-danger me-3 fs-4"></i>
|
|
93
|
+
<span class="fs-5" x-text="message"></span>
|
|
94
|
+
</div>
|
|
95
|
+
<div class="text-center">
|
|
96
|
+
<span @click="close_modal()">
|
|
97
|
+
{% block progress_error_button %}
|
|
98
|
+
{% include 'django_spire/button/primary_button.html' with button_text='Close' %}
|
|
99
|
+
{% endblock %}
|
|
100
|
+
</span>
|
|
120
101
|
</div>
|
|
121
102
|
</div>
|
|
122
103
|
</div>
|
|
123
104
|
</div>
|
|
105
|
+
|
|
106
|
+
<style>
|
|
107
|
+
.spin {
|
|
108
|
+
animation: spin 1s linear infinite;
|
|
109
|
+
}
|
|
110
|
+
@keyframes spin {
|
|
111
|
+
from { transform: rotate(0deg); }
|
|
112
|
+
to { transform: rotate(360deg); }
|
|
113
|
+
}
|
|
114
|
+
</style>
|
|
124
115
|
{% endblock %}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
class="card ms-0 shadow-sm rounded-3 bg-app-layer-two {% block card_class %}{% endblock %}"
|
|
3
3
|
style="{% block card_style %}{% endblock %}"
|
|
4
4
|
>
|
|
5
|
-
<div class="{% block card_padding %}p-3{% endblock %}" style="{% block card_body_style %}{% endblock %}">
|
|
5
|
+
<div class="h-100 {% block card_padding %}p-3{% endblock %}" style="min-height: 0; {% block card_body_style %}{% endblock %}">
|
|
6
6
|
{% block card_content %}{% endblock %}
|
|
7
7
|
</div>
|
|
8
8
|
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{% extends 'django_spire/card/card.html' %}
|
|
2
2
|
|
|
3
|
-
{% block
|
|
3
|
+
{% block card_class %}d-flex flex-column{% endblock %}
|
|
4
4
|
|
|
5
|
-
{% block
|
|
5
|
+
{% block card_padding %}p-3 flex-grow-1{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block card_body_style %}display: flex; flex-direction: column; min-height: 0;{% endblock %}
|
|
6
8
|
|
|
7
9
|
{% block card_content %}
|
|
8
10
|
<div
|
|
9
|
-
class="d-flex flex-column flex-grow-1
|
|
11
|
+
class="d-flex flex-column flex-grow-1"
|
|
12
|
+
style="min-height: 0;"
|
|
10
13
|
x-data="{
|
|
11
14
|
card_title_dropdown: false,
|
|
12
15
|
toggle_card_title_dropdown() {
|
|
@@ -29,7 +32,7 @@
|
|
|
29
32
|
{% block card_dropdown_content %}
|
|
30
33
|
{% endblock %}
|
|
31
34
|
</div>
|
|
32
|
-
<div class="flex-grow-1
|
|
35
|
+
<div class="flex-grow-1 d-flex flex-column" style="min-height: 0;">
|
|
33
36
|
{% block card_title_content %}
|
|
34
37
|
{% endblock %}
|
|
35
38
|
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{% extends 'django_spire/infinite_scroll/base.html' %}
|
|
2
2
|
|
|
3
|
-
{% block scroll_wrapper_class %}d-flex flex-column
|
|
3
|
+
{% block scroll_wrapper_class %}d-flex flex-column h-100{% endblock %}
|
|
4
4
|
|
|
5
5
|
{% block scroll_xdata %}
|
|
6
6
|
responsive_mode: '{{ responsive_mode|default:"collapse" }}',
|
|
@@ -140,8 +140,8 @@
|
|
|
140
140
|
|
|
141
141
|
{% block scroll_container %}
|
|
142
142
|
<div
|
|
143
|
-
class="position-relative table-container
|
|
144
|
-
style="height:
|
|
143
|
+
class="position-relative table-container flex-grow-1"
|
|
144
|
+
style="min-height: 200px; overflow-x: auto; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;"
|
|
145
145
|
x-ref="scroll_container"
|
|
146
146
|
:data-table-id="table_id"
|
|
147
147
|
>
|
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
{% endblock %}
|
|
206
206
|
|
|
207
207
|
{% block scroll_footer %}
|
|
208
|
-
<div class="row mt-3">
|
|
208
|
+
<div class="row mt-3 flex-shrink-0">
|
|
209
209
|
<div class="col text-start">
|
|
210
210
|
<span class="fs-7 text-app-secondary">
|
|
211
211
|
Showing <span x-text="loaded_count"></span> of <span x-text="total_count"></span> rows
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-spire
|
|
3
|
-
Version: 0.23.
|
|
3
|
+
Version: 0.23.10
|
|
4
4
|
Summary: A project for Django Spire
|
|
5
5
|
Author-email: Brayden Carlson <braydenc@stratusadv.com>, Nathan Johnson <nathanj@stratusadv.com>
|
|
6
|
-
License: Copyright (c)
|
|
6
|
+
License: Copyright (c) 2025 Stratus Advanced Technologies and Contributors.
|
|
7
7
|
|
|
8
8
|
Permission is hereby granted, free of charge, to any person
|
|
9
9
|
obtaining a copy of this software and associated documentation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
django_spire/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
django_spire/conf.py,sha256=3oUB1mtgHRjvbJsxfQWG5uL1KUP9uGig3zdP2dZphe8,942
|
|
3
|
-
django_spire/consts.py,sha256=
|
|
3
|
+
django_spire/consts.py,sha256=d5_qKitqKzGvVZucpkte-GZyZj9s2j8C0KuzkalsyVQ,172
|
|
4
4
|
django_spire/exceptions.py,sha256=M7buFvm-K4lK09pH5fVcZ-MxsDIzdpEJBF33Xss5bSw,289
|
|
5
5
|
django_spire/settings.py,sha256=0xImrKpF7VW4wc9jLGO07e2ev6D4-i_TREgpTepLp3I,1042
|
|
6
6
|
django_spire/urls.py,sha256=wQx6R-nXx69MeOF-WmDxcEUM5WmUHGplbY5uZ_HnDp8,703
|
|
@@ -397,17 +397,14 @@ django_spire/contrib/performance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
|
|
|
397
397
|
django_spire/contrib/performance/decorators.py,sha256=vCENOqcmXoEvi1Y3Uw55J21zB-ZvpWk7rRo2jqyg8pc,731
|
|
398
398
|
django_spire/contrib/performance/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
399
399
|
django_spire/contrib/performance/tests/test_performance.py,sha256=wVNzrUEG0bTMcvJrqkSWkAE27LSyJMxrRZRd04ZKDQM,3029
|
|
400
|
-
django_spire/contrib/progress/__init__.py,sha256=
|
|
401
|
-
django_spire/contrib/progress/enums.py,sha256=
|
|
402
|
-
django_spire/contrib/progress/
|
|
403
|
-
django_spire/contrib/progress/
|
|
404
|
-
django_spire/contrib/progress/states.py,sha256=V7JU_nzpZN77TQFW0S51Gjil8xn8CKLKkAWDOpqzA8k,1908
|
|
405
|
-
django_spire/contrib/progress/task.py,sha256=4pMbzOsjRRNqPKNohh08D39DRFpC3QomTCH5IdqQS0A,780
|
|
406
|
-
django_spire/contrib/progress/tracker.py,sha256=xjGlEyKe5aiKW_KC8NKZ8F0BjQdFpLUqHz5Gr_C7jws,6490
|
|
400
|
+
django_spire/contrib/progress/__init__.py,sha256=5a7LTmUyw_cfO-3_QuN5M6zAhrCNs7MjEypL13qhoQA,345
|
|
401
|
+
django_spire/contrib/progress/enums.py,sha256=Rexk804FhmVQou7UOKSOCnjaZrSDZdniV_MWLh-kGxI,218
|
|
402
|
+
django_spire/contrib/progress/session.py,sha256=Oo1QS8f7aTN7K_Y9bwXZHo6otZQkRSp6V_6c0stvYcI,8825
|
|
403
|
+
django_spire/contrib/progress/tasks.py,sha256=afC4vhWzvuRq6-P80LdB-BmDGD5kADtgYGM2SaKz8Ao,1625
|
|
407
404
|
django_spire/contrib/progress/static/django_spire/css/contrib/progress/progress.css,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
408
|
-
django_spire/contrib/progress/static/django_spire/js/contrib/progress/progress.js,sha256=
|
|
409
|
-
django_spire/contrib/progress/templates/django_spire/contrib/progress/card/card.html,sha256=
|
|
410
|
-
django_spire/contrib/progress/templates/django_spire/contrib/progress/modal/content.html,sha256=
|
|
405
|
+
django_spire/contrib/progress/static/django_spire/js/contrib/progress/progress.js,sha256=vhjwLWTqkjcuK7j_z9ndCGdWfBFmRAM4MvF8zpEKJL0,1730
|
|
406
|
+
django_spire/contrib/progress/templates/django_spire/contrib/progress/card/card.html,sha256=UB5PpaZzaSihiE6BnThYrM21qVrf1iT1fF-TbtkoZrc,3389
|
|
407
|
+
django_spire/contrib/progress/templates/django_spire/contrib/progress/modal/content.html,sha256=613hvePQFurk4Q0Id8NuQz9Umbh35eJSOR-IQipo_o4,4857
|
|
411
408
|
django_spire/contrib/queryset/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
412
409
|
django_spire/contrib/queryset/enums.py,sha256=dkzI464Q53huqtNGfnM-biuKpHUQU78WwuWvt3Pm8mI,145
|
|
413
410
|
django_spire/contrib/queryset/filter_tools.py,sha256=V_s6pG2uyqvoTNtBXXXNKXE69ipwexxWAR-X30H1-XI,1129
|
|
@@ -517,7 +514,7 @@ django_spire/core/management/commands/spire_startapp_pkg/user_input.py,sha256=kj
|
|
|
517
514
|
django_spire/core/management/commands/spire_startapp_pkg/validator.py,sha256=q6fsyRmR1kcN2eAFu-5pDaadJ05FDog7N23eR215Yx0,3322
|
|
518
515
|
django_spire/core/management/commands/spire_startapp_pkg/template/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
519
516
|
django_spire/core/management/commands/spire_startapp_pkg/template/app/__init__.py.template,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
520
|
-
django_spire/core/management/commands/spire_startapp_pkg/template/app/apps.py.template,sha256=
|
|
517
|
+
django_spire/core/management/commands/spire_startapp_pkg/template/app/apps.py.template,sha256=KG--onS7UQG7a1KUe142OzejZb3sBGOXSedSY-lU9Yw,429
|
|
521
518
|
django_spire/core/management/commands/spire_startapp_pkg/template/app/forms.py.template,sha256=zdHsuTjk_fM2s7o0_JgcHioIZKxBcmo4vziHXYEYHmA,361
|
|
522
519
|
django_spire/core/management/commands/spire_startapp_pkg/template/app/models.py.template,sha256=U5-5feDcgy63uPiuxm5mwrtsoC61ExAIyhK1c-pK3iY,1406
|
|
523
520
|
django_spire/core/management/commands/spire_startapp_pkg/template/app/querysets.py.template,sha256=my06IPSuiyKw1Goj7-cAMWRIRWDSY0RFpkrmFYLwuiE,539
|
|
@@ -551,9 +548,9 @@ django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test
|
|
|
551
548
|
django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_views/__init__.py.template,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
552
549
|
django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_views/test_form_views.py.template,sha256=ZXbAwKt9jl9Wv_ho-DoBQGdhRpPXld7PFbIFWfPLCMo,196
|
|
553
550
|
django_spire/core/management/commands/spire_startapp_pkg/template/app/tests/test_views/test_page_views.py.template,sha256=ZXbAwKt9jl9Wv_ho-DoBQGdhRpPXld7PFbIFWfPLCMo,196
|
|
554
|
-
django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/__init__.py.template,sha256=
|
|
555
|
-
django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/form_urls.py.template,sha256=
|
|
556
|
-
django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/page_urls.py.template,sha256=
|
|
551
|
+
django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/__init__.py.template,sha256=fPEmfEX9UIIFXQ5Xh570s8Np3NGJgJSUtVBT6OHQndA,288
|
|
552
|
+
django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/form_urls.py.template,sha256=a0v-kIjlbcpMKeSQmfRUs00DeYAAyCfmVLDSZyJMmfs,677
|
|
553
|
+
django_spire/core/management/commands/spire_startapp_pkg/template/app/urls/page_urls.py.template,sha256=PR3pHMcuHyxVd6fd_q5TQIs1n9lowhfRSJIBie_9yr8,298
|
|
557
554
|
django_spire/core/management/commands/spire_startapp_pkg/template/app/views/__init__.py.template,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
558
555
|
django_spire/core/management/commands/spire_startapp_pkg/template/app/views/form_views.py.template,sha256=np31b1k9htY_alOGc9VqDasomtiQRUfNtRKVObAP3H4,4548
|
|
559
556
|
django_spire/core/management/commands/spire_startapp_pkg/template/app/views/page_views.py.template,sha256=QMozesEIYhDMhsvVJH_MxgobE-SVnczP5dRmTdxyMFM,1409
|
|
@@ -702,12 +699,12 @@ django_spire/core/templates/django_spire/button/success_outlined_button.html,sha
|
|
|
702
699
|
django_spire/core/templates/django_spire/button/warning_button.html,sha256=KUlpESYRvZ4GklLhn5YBKnvjDJOaTARrLxv8Fpd-hNU,108
|
|
703
700
|
django_spire/core/templates/django_spire/button/warning_dark_button.html,sha256=5bqj3HO1Qwye0qgRsQ4jpPje-w62JQz3yyAAUthUGzc,113
|
|
704
701
|
django_spire/core/templates/django_spire/button/warning_outlined_button.html,sha256=_PLvsB6wCRoDcAien0f57urCSY_FcCkL8zWDDsNUbE0,117
|
|
705
|
-
django_spire/core/templates/django_spire/card/card.html,sha256=
|
|
702
|
+
django_spire/core/templates/django_spire/card/card.html,sha256=Nryuc1qgmSncY8t4ZZ2Bofs2Kr9D1VX1L5H6O-lhqSw,391
|
|
706
703
|
django_spire/core/templates/django_spire/card/delete_confirmation_form_card.html,sha256=A-IrDQHKgQ1iveGJJ9EKsvs-TUW0eVY8uTcWM4dmQ_4,1097
|
|
707
704
|
django_spire/core/templates/django_spire/card/delete_form_card.html,sha256=7nAZ0LuIq9l2BwNiBny_C__Q9EUXYQ_CM1aFXrafd6c,212
|
|
708
705
|
django_spire/core/templates/django_spire/card/form_card.html,sha256=bctVy9CeHuf05xsuE-zEsQVOaq24Igjq6xTKgv2AO4Y,391
|
|
709
706
|
django_spire/core/templates/django_spire/card/infinite_scroll_card.html,sha256=EM57LOCjuKqJZfsTwNmzRB3I8lzvRLcXdmpq8h7c-q0,261
|
|
710
|
-
django_spire/core/templates/django_spire/card/title_card.html,sha256=
|
|
707
|
+
django_spire/core/templates/django_spire/card/title_card.html,sha256=5ahO5PoB3ZPiluEZI7FqwB8E9t-BqVmj-uLSVh2RYPQ,1424
|
|
711
708
|
django_spire/core/templates/django_spire/container/container.html,sha256=Dfr7K8xgEbg3CZYxMleLjjiQGyRS-GNJdPySA4OYY8U,867
|
|
712
709
|
django_spire/core/templates/django_spire/container/form_container.html,sha256=FZwZs4gnIYkurV5u8v6fj2rbrm4WDX16jyUSTMniEtw,313
|
|
713
710
|
django_spire/core/templates/django_spire/container/infinite_scroll_container.html,sha256=L3sPkIQG99SFJpkuYOg_RnlYFFobxE0B-weuDqUwiv0,2494
|
|
@@ -776,7 +773,7 @@ django_spire/core/templates/django_spire/speech/speech_synthesis.html,sha256=25H
|
|
|
776
773
|
django_spire/core/templates/django_spire/tab/tab.html,sha256=1zSIX0Xk337VV9Qa4tvoSJlhoT2LDTfEfCwJvESNG-Q,1964
|
|
777
774
|
django_spire/core/templates/django_spire/tab/element/tab_section_element.html,sha256=tEo0ENKhss74ll8HcFE9_kml35vusAfiMQHpudh3aEc,181
|
|
778
775
|
django_spire/core/templates/django_spire/tab/element/tab_trigger_element.html,sha256=9VmMhfEGa3ARHerwyXojtQWyIkUj9sOPGhckcQR3h6k,442
|
|
779
|
-
django_spire/core/templates/django_spire/table/base.html,sha256=
|
|
776
|
+
django_spire/core/templates/django_spire/table/base.html,sha256=Bu0ijKNIaPJ8cTgp3HW1xwAX_uUwXayORmjTwKEVWYg,7270
|
|
780
777
|
django_spire/core/templates/django_spire/table/element/child_row.html,sha256=B0fIXw3-p7YREdNtpIBwijCom6RS64Lrzj-teRuvvKI,1916
|
|
781
778
|
django_spire/core/templates/django_spire/table/element/expandable_row.html,sha256=sAzzUeGishdYRUqs9t4lduxuxZaOzUYNhMfMytRLq90,1516
|
|
782
779
|
django_spire/core/templates/django_spire/table/element/footer.html,sha256=fVxbDrVj4C9jIswkri7B2Dr4nEr2Lf_EPPULMU3mRs0,312
|
|
@@ -1372,8 +1369,8 @@ django_spire/theme/urls/page_urls.py,sha256=Oak3x_xwQEb01NKdrsB1nk6yPaOEnheuSG1m
|
|
|
1372
1369
|
django_spire/theme/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1373
1370
|
django_spire/theme/views/json_views.py,sha256=PWwVTaty0BVGbj65L5cxex6JNhc-xVAI_rEYjbJWqEM,1893
|
|
1374
1371
|
django_spire/theme/views/page_views.py,sha256=WenjOa6Welpu3IMolY56ZwBjy4aK9hpbiMNuygjAl1A,3922
|
|
1375
|
-
django_spire-0.23.
|
|
1376
|
-
django_spire-0.23.
|
|
1377
|
-
django_spire-0.23.
|
|
1378
|
-
django_spire-0.23.
|
|
1379
|
-
django_spire-0.23.
|
|
1372
|
+
django_spire-0.23.10.dist-info/licenses/LICENSE.md,sha256=ZAeCT76WvaoEZE9xPhihyWjTwH0wQZXQmyRsnV2VPFs,1091
|
|
1373
|
+
django_spire-0.23.10.dist-info/METADATA,sha256=tdZ2P4q_PlnHfvRd4XibSjAzFHyxjzKG9PDX3EjAVU4,5128
|
|
1374
|
+
django_spire-0.23.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
1375
|
+
django_spire-0.23.10.dist-info/top_level.txt,sha256=xf3QV1e--ONkVpgMDQE9iqjQ1Vg4--_6C8wmO-KxPHQ,13
|
|
1376
|
+
django_spire-0.23.10.dist-info/RECORD,,
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
4
|
-
|
|
5
|
-
from django_spire.contrib.progress.tracker import ProgressTracker
|
|
6
|
-
|
|
7
|
-
if TYPE_CHECKING:
|
|
8
|
-
from typing import Any
|
|
9
|
-
|
|
10
|
-
from django_spire.contrib.progress.enums import ProgressStatus
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class ProgressTrackingMixin:
|
|
14
|
-
_tracker: ProgressTracker | None = None
|
|
15
|
-
|
|
16
|
-
def get_tracker_key(self) -> str:
|
|
17
|
-
raise NotImplementedError
|
|
18
|
-
|
|
19
|
-
@property
|
|
20
|
-
def tracker(self) -> ProgressTracker:
|
|
21
|
-
if self._tracker is None:
|
|
22
|
-
self._tracker = ProgressTracker(self.get_tracker_key())
|
|
23
|
-
|
|
24
|
-
return self._tracker
|
|
25
|
-
|
|
26
|
-
def progress_error(self, message: str) -> None:
|
|
27
|
-
self.tracker.error(message)
|
|
28
|
-
|
|
29
|
-
def update_progress(
|
|
30
|
-
self,
|
|
31
|
-
status: ProgressStatus,
|
|
32
|
-
message: str,
|
|
33
|
-
progress: int,
|
|
34
|
-
**kwargs: Any
|
|
35
|
-
) -> None:
|
|
36
|
-
self.tracker.update(status, message, progress, **kwargs)
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import math
|
|
4
|
-
import random
|
|
5
|
-
import threading
|
|
6
|
-
import time
|
|
7
|
-
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
9
|
-
|
|
10
|
-
from django_spire.contrib.progress.enums import ProgressStatus
|
|
11
|
-
from django_spire.contrib.progress.task import ProgressMessages, Task, TaskResult
|
|
12
|
-
|
|
13
|
-
if TYPE_CHECKING:
|
|
14
|
-
from typing import Any, Callable
|
|
15
|
-
|
|
16
|
-
from django_spire.contrib.progress.tracker import ProgressTracker
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class TaskProgressUpdater:
|
|
20
|
-
def __init__(self, tracker: ProgressTracker, task: Task) -> None:
|
|
21
|
-
self._messages = ProgressMessages()
|
|
22
|
-
self._task = task
|
|
23
|
-
self._tracker = tracker
|
|
24
|
-
|
|
25
|
-
def complete(self, message: str | None = None) -> None:
|
|
26
|
-
self._tracker._update_task(
|
|
27
|
-
self._task.name,
|
|
28
|
-
ProgressStatus.COMPLETE,
|
|
29
|
-
self._format(message or self._messages.complete),
|
|
30
|
-
100
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
def error(self, message: str) -> None:
|
|
34
|
-
self._tracker._update_task(
|
|
35
|
-
self._task.name,
|
|
36
|
-
ProgressStatus.ERROR,
|
|
37
|
-
self._format(message),
|
|
38
|
-
0
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
def start(self) -> None:
|
|
42
|
-
self._tracker._update_task(
|
|
43
|
-
self._task.name,
|
|
44
|
-
ProgressStatus.PROCESSING,
|
|
45
|
-
self._format(self._messages.starting),
|
|
46
|
-
2
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
def update(self, message: str, progress: int) -> None:
|
|
50
|
-
self._tracker._update_task(
|
|
51
|
-
self._task.name,
|
|
52
|
-
ProgressStatus.PROCESSING,
|
|
53
|
-
self._format(message),
|
|
54
|
-
progress
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
def _format(self, message: str) -> str:
|
|
58
|
-
return f'{self._task.label}: {message}'
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
class ProgressSimulator:
|
|
62
|
-
def __init__(
|
|
63
|
-
self,
|
|
64
|
-
updater: TaskProgressUpdater,
|
|
65
|
-
max_progress: int = 90,
|
|
66
|
-
update_interval: float = 0.15
|
|
67
|
-
) -> None:
|
|
68
|
-
self._max_progress = max_progress
|
|
69
|
-
self._messages = ProgressMessages()
|
|
70
|
-
self._update_interval = update_interval
|
|
71
|
-
self._updater = updater
|
|
72
|
-
|
|
73
|
-
def run(self, stop_event: threading.Event) -> None:
|
|
74
|
-
start_time = time.time()
|
|
75
|
-
duration = random.uniform(8.0, 15.0)
|
|
76
|
-
|
|
77
|
-
while not stop_event.is_set():
|
|
78
|
-
elapsed = time.time() - start_time
|
|
79
|
-
t = min(elapsed / duration, 1.0)
|
|
80
|
-
|
|
81
|
-
progress = self._ease_out_expo(t) * self._max_progress
|
|
82
|
-
progress = min(int(progress), self._max_progress)
|
|
83
|
-
|
|
84
|
-
jitter = random.uniform(-1.5, 1.5) if progress < self._max_progress - 5 else 0
|
|
85
|
-
progress = max(2, min(int(progress + jitter), self._max_progress))
|
|
86
|
-
|
|
87
|
-
message = self._get_message_for_progress(progress)
|
|
88
|
-
self._updater.update(message, progress)
|
|
89
|
-
|
|
90
|
-
if progress >= self._max_progress:
|
|
91
|
-
break
|
|
92
|
-
|
|
93
|
-
time.sleep(self._update_interval + random.uniform(0, 0.1))
|
|
94
|
-
|
|
95
|
-
def _ease_out_expo(self, t: float) -> float:
|
|
96
|
-
if t >= 1.0:
|
|
97
|
-
return 1.0
|
|
98
|
-
|
|
99
|
-
return 1.0 - math.pow(2, -10 * t)
|
|
100
|
-
|
|
101
|
-
def _get_message_for_progress(self, progress: int) -> str:
|
|
102
|
-
steps = self._messages.steps
|
|
103
|
-
index = min(int(progress / (self._max_progress / len(steps))), len(steps) - 1)
|
|
104
|
-
|
|
105
|
-
return steps[index]
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
class TaskRunner:
|
|
109
|
-
def __init__(self, tracker: ProgressTracker, task: Task) -> None:
|
|
110
|
-
self._stop_event = threading.Event()
|
|
111
|
-
self._task = task
|
|
112
|
-
self._tracker = tracker
|
|
113
|
-
self._updater = TaskProgressUpdater(tracker, task)
|
|
114
|
-
|
|
115
|
-
def run_parallel(self, results: dict[str, TaskResult]) -> None:
|
|
116
|
-
self._execute(results, lambda: self._task.func())
|
|
117
|
-
|
|
118
|
-
def run_sequential(self, results: dict[str, TaskResult]) -> None:
|
|
119
|
-
unwrapped = {name: result.value for name, result in results.items()}
|
|
120
|
-
self._execute(results, lambda: self._task.func(unwrapped))
|
|
121
|
-
|
|
122
|
-
def stop(self) -> None:
|
|
123
|
-
self._stop_event.set()
|
|
124
|
-
|
|
125
|
-
def _execute(self, results: dict[str, TaskResult], executor: Callable[[], Any]) -> None:
|
|
126
|
-
simulator = ProgressSimulator(self._updater)
|
|
127
|
-
progress_thread = threading.Thread(target=simulator.run, args=(self._stop_event,))
|
|
128
|
-
progress_thread.start()
|
|
129
|
-
|
|
130
|
-
try:
|
|
131
|
-
self._updater.start()
|
|
132
|
-
value = executor()
|
|
133
|
-
results[self._task.name] = TaskResult(value=value)
|
|
134
|
-
self._updater.complete()
|
|
135
|
-
except BaseException as e:
|
|
136
|
-
results[self._task.name] = TaskResult(error=e)
|
|
137
|
-
self._updater.error(str(e))
|
|
138
|
-
finally:
|
|
139
|
-
self._stop_event.set()
|
|
140
|
-
progress_thread.join(timeout=1)
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from dataclasses import dataclass, field
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
5
|
-
|
|
6
|
-
from django_spire.contrib.progress.enums import ProgressStatus
|
|
7
|
-
|
|
8
|
-
if TYPE_CHECKING:
|
|
9
|
-
from typing import Any
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@dataclass
|
|
13
|
-
class TaskState:
|
|
14
|
-
message: str = 'Waiting...'
|
|
15
|
-
progress: int = 0
|
|
16
|
-
status: ProgressStatus = ProgressStatus.PENDING
|
|
17
|
-
|
|
18
|
-
@classmethod
|
|
19
|
-
def from_dict(cls, data: dict[str, Any]) -> TaskState:
|
|
20
|
-
return cls(
|
|
21
|
-
message=data.get('message', 'Waiting...'),
|
|
22
|
-
progress=data.get('progress', 0),
|
|
23
|
-
status=ProgressStatus(data.get('step', ProgressStatus.PENDING)),
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
def to_dict(self) -> dict[str, Any]:
|
|
27
|
-
return {
|
|
28
|
-
'message': self.message,
|
|
29
|
-
'progress': self.progress,
|
|
30
|
-
'step': self.status.value,
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@dataclass
|
|
35
|
-
class TrackerState:
|
|
36
|
-
message: str = 'Initializing...'
|
|
37
|
-
progress: int = 0
|
|
38
|
-
status: ProgressStatus = ProgressStatus.PENDING
|
|
39
|
-
task_order: list[str] = field(default_factory=list)
|
|
40
|
-
tasks: dict[str, TaskState] = field(default_factory=dict)
|
|
41
|
-
|
|
42
|
-
@classmethod
|
|
43
|
-
def from_dict(cls, data: dict[str, Any]) -> TrackerState:
|
|
44
|
-
tasks = {
|
|
45
|
-
name: TaskState.from_dict(task_data)
|
|
46
|
-
for name, task_data in data.get('tasks', {}).items()
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return cls(
|
|
50
|
-
message=data.get('message', 'Initializing...'),
|
|
51
|
-
progress=data.get('progress', 0),
|
|
52
|
-
status=ProgressStatus(data.get('step', ProgressStatus.PENDING)),
|
|
53
|
-
task_order=data.get('task_order', []),
|
|
54
|
-
tasks=tasks,
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
def to_dict(self) -> dict[str, Any]:
|
|
58
|
-
return {
|
|
59
|
-
'message': self.message,
|
|
60
|
-
'progress': self.progress,
|
|
61
|
-
'step': self.status.value,
|
|
62
|
-
'task_order': self.task_order,
|
|
63
|
-
'tasks': {name: task.to_dict() for name, task in self.tasks.items()},
|
|
64
|
-
}
|