micro-sidebar 1.2.2__py3-none-any.whl → 2.1.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.
@@ -0,0 +1,51 @@
1
+ /* --- Gold Theme (Luxury) --- */
2
+ :root.theme-gold {
3
+ --title: #78350f;
4
+ --body: #fffbeb8b;
5
+ --htitle: #92400e;
6
+ --hbody: #fef3c7db;
7
+ --table-row: #fef9e7;
8
+ --table-row-hover: #fdf1c0;
9
+ --primal: #d97706;
10
+ --primal_dark: #b45309;
11
+ --primal-rgb: 217, 119, 6;
12
+ --btn-primary-shadow: rgba(217, 119, 6, 0.4);
13
+
14
+ /* Login Theme Variables */
15
+ --bg-gradient: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
16
+ --right-bg: var(--title);
17
+ --primary-color: var(--primal);
18
+
19
+ /* Bootstrap Overrides */
20
+ --bs-primary: var(--primal);
21
+ --bs-primary-rgb: var(--primal-rgb);
22
+ --bs-btn-bg: var(--primal);
23
+ --bs-btn-border-color: var(--primal);
24
+ --bs-btn-hover-bg: var(--primal_dark);
25
+ --bs-btn-hover-border-color: var(--primal_dark);
26
+ --bs-link-color: var(--primal);
27
+ --bs-link-hover-color: var(--primal_dark);
28
+ }
29
+ :root.theme-gold .titlebar {
30
+ background: linear-gradient(90deg, #ffffff 10%, #fef9e7 90%) !important;
31
+ }
32
+ :root.theme-gold #sidebar {
33
+ background: linear-gradient(180deg, #ffffff 10%, #fef9e7 100%) !important;
34
+ border-left: 1px solid #fdf1c0 !important;
35
+ }
36
+
37
+ :root.theme-gold .page .right {
38
+ background: var(--primal_dark) !important; /* Darker logo container */
39
+ box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3) !important;
40
+ color: #e2e8f0 !important;
41
+ }
42
+
43
+ /* Gold Overrides */
44
+ :root.theme-gold .dropdown-item:hover {
45
+ background-color: rgba(217, 119, 6, 0.08) !important;
46
+ color: #b45309 !important;
47
+ }
48
+ :root.theme-gold .titlebar .btn-light:hover {
49
+ background-color: rgba(217, 119, 6, 0.08) !important;
50
+ color: #b45309 !important;
51
+ }
@@ -0,0 +1,63 @@
1
+ /* --- Green Theme (Emerald) --- */
2
+ :root.theme-green {
3
+ --title: #166534;
4
+ --body: #f0fdf48b;
5
+ --htitle: #15803d;
6
+ --hbody: #dcfce7db;
7
+ --table-row: #e9fdf0;
8
+ --table-row-hover: #d2f9df;
9
+ --primal: #10b981;
10
+ --primal_dark: #059669;
11
+ --primal-rgb: 16, 185, 129;
12
+ --btn-primary-shadow: rgba(16, 185, 129, 0.4);
13
+
14
+ /* Login Theme Variables */
15
+ --bg-gradient: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
16
+ --right-bg: var(--title);
17
+ --primary-color: var(--primal);
18
+
19
+ /* Bootstrap Overrides */
20
+ --bs-primary: var(--primal);
21
+ --bs-primary-rgb: var(--primal-rgb);
22
+ --bs-btn-bg: var(--primal);
23
+ --bs-btn-border-color: var(--primal);
24
+ --bs-btn-hover-bg: var(--primal_dark);
25
+ --bs-btn-hover-border-color: var(--primal_dark);
26
+ --bs-link-color: var(--primal);
27
+ --bs-link-hover-color: var(--primal_dark);
28
+ }
29
+ :root.theme-green .titlebar {
30
+ background: linear-gradient(90deg, #ffffff 10%, #e9fdf0 90%) !important;
31
+ }
32
+ :root.theme-green #sidebar {
33
+ background: linear-gradient(180deg, #ffffff 10%, #e9fdf0 100%) !important;
34
+ border-left: 1px solid #d2f9df !important;
35
+ }
36
+
37
+ :root.theme-green .page .right {
38
+ background: var(--primal_dark) !important; /* Darker logo container */
39
+ box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3) !important;
40
+ color: #e2e8f0 !important;
41
+ }
42
+
43
+ /* Green Overrides */
44
+ :root.theme-green .dropdown-item:hover {
45
+ background-color: rgba(16, 185, 129, 0.08) !important;
46
+ color: #059669 !important;
47
+ }
48
+ :root.theme-green .titlebar .btn-light:hover {
49
+ background-color: rgba(16, 185, 129, 0.08) !important;
50
+ color: #059669 !important;
51
+ }
52
+
53
+ /* Success Button Override in Green Theme */
54
+ :root.theme-green .btn-outline-success {
55
+ color: #475569 !important;
56
+ border-color: #475569 !important;
57
+ }
58
+
59
+ :root.theme-green .btn-outline-success:hover {
60
+ background-color: #475569 !important;
61
+ border-color: #475569 !important;
62
+ color: #ffffff !important;
63
+ }
@@ -0,0 +1,51 @@
1
+ /* --- Light Theme (Neutral / Silver) --- */
2
+ :root.theme-light {
3
+ --title: #334155; /* Slate 700 */
4
+ --body: #f8fafc; /* Slate 50 */
5
+ --htitle: #64748b; /* Slate 500 */
6
+ --hbody: #f1f5f9; /* Slate 100 */
7
+ --table-row: #f7f8fa;
8
+ --table-row-hover: #f1f5f9;
9
+ --primal: #475569; /* Slate 600 - Neutral Accent */
10
+ --primal_dark: #334155; /* Slate 700 */
11
+ --primal-rgb: 71, 85, 105;
12
+ --btn-primary-shadow: rgba(71, 85, 105, 0.4);
13
+
14
+ /* Login Theme Variables */
15
+ --bg-gradient: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
16
+ --right-bg: var(--title);
17
+ --primary-color: var(--primal);
18
+
19
+ /* Bootstrap Overrides */
20
+ --bs-primary: var(--primal);
21
+ --bs-primary-rgb: var(--primal-rgb);
22
+ --bs-btn-bg: var(--primal);
23
+ --bs-btn-border-color: var(--primal);
24
+ --bs-btn-hover-bg: var(--primal_dark);
25
+ --bs-btn-hover-border-color: var(--primal_dark);
26
+ --bs-link-color: var(--primal);
27
+ --bs-link-hover-color: var(--primal_dark);
28
+ }
29
+ :root.theme-light .titlebar {
30
+ background: linear-gradient(90deg, #ffffff 10%, #f8fafc 90%) !important;
31
+ }
32
+ :root.theme-light #sidebar {
33
+ background: linear-gradient(180deg, #ffffff 10%, #f8fafc 100%) !important;
34
+ border-left: 1px solid #e2e8f0 !important;
35
+ }
36
+
37
+ :root.theme-light .page .right {
38
+ background: var(--htitle) !important;
39
+ box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3) !important;
40
+ color: #f8fafc !important;
41
+ }
42
+
43
+ /* Neutral Overrides */
44
+ :root.theme-light .dropdown-item:hover {
45
+ background-color: rgba(71, 85, 105, 0.08) !important;
46
+ color: #334155 !important;
47
+ }
48
+ :root.theme-light .titlebar .btn-light:hover {
49
+ background-color: rgba(71, 85, 105, 0.08) !important;
50
+ color: #334155 !important;
51
+ }
@@ -0,0 +1,6 @@
1
+ @import 'light.css';
2
+ @import 'blue.css';
3
+ @import 'green.css';
4
+ @import 'red.css';
5
+ @import 'gold.css';
6
+ @import 'dark.css';
@@ -0,0 +1,41 @@
1
+ document.addEventListener('DOMContentLoaded', function() {
2
+ const root = document.documentElement;
3
+ const themes = ['light', 'blue', 'gold', 'green', 'red', 'dark'];
4
+
5
+ // Load saved theme
6
+ const savedTheme = localStorage.getItem('appTheme');
7
+ if (savedTheme && themes.includes(savedTheme)) {
8
+ root.classList.add(`theme-${savedTheme}`);
9
+ }
10
+
11
+ // Global function to set theme
12
+ window.setTheme = function(theme) {
13
+ // Remove all current theme classes
14
+ themes.forEach(t => root.classList.remove(`theme-${t}`));
15
+
16
+ if (theme && themes.includes(theme)) {
17
+ root.classList.add(`theme-${theme}`);
18
+ localStorage.setItem('appTheme', theme);
19
+ } else {
20
+ localStorage.removeItem('appTheme');
21
+ }
22
+
23
+ // Visual Update: Highlight active theme circle
24
+ updateActiveThemeUI(theme || 'light');
25
+
26
+ // Dispatch event for components that might need resizing (like Plotly)
27
+ window.dispatchEvent(new Event('resize'));
28
+ };
29
+
30
+ function updateActiveThemeUI(activeTheme) {
31
+ document.querySelectorAll('.theme-preview').forEach(el => {
32
+ el.classList.remove('active');
33
+ if (el.getAttribute('data-theme') === activeTheme) {
34
+ el.classList.add('active');
35
+ }
36
+ });
37
+ }
38
+
39
+ // Initialize UI on load
40
+ updateActiveThemeUI(savedTheme || 'light');
41
+ });
@@ -0,0 +1,51 @@
1
+ /* --- Red Theme (Bordeaux) --- */
2
+ :root.theme-red {
3
+ --title: #7f1d1d;
4
+ --body: #fef2f28b;
5
+ --htitle: #991b1b;
6
+ --hbody: #fee2e2db;
7
+ --table-row: #fdeded;
8
+ --table-row-hover: #fcdbdb;
9
+ --primal: #ef4444;
10
+ --primal_dark: #dc2626;
11
+ --primal-rgb: 239, 68, 68;
12
+ --btn-primary-shadow: rgba(239, 68, 68, 0.4);
13
+
14
+ /* Login Theme Variables */
15
+ --bg-gradient: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);
16
+ --right-bg: var(--title);
17
+ --primary-color: var(--primal);
18
+
19
+ /* Bootstrap Overrides */
20
+ --bs-primary: var(--primal);
21
+ --bs-primary-rgb: var(--primal-rgb);
22
+ --bs-btn-bg: var(--primal);
23
+ --bs-btn-border-color: var(--primal);
24
+ --bs-btn-hover-bg: var(--primal_dark);
25
+ --bs-btn-hover-border-color: var(--primal_dark);
26
+ --bs-link-color: var(--primal);
27
+ --bs-link-hover-color: var(--primal_dark);
28
+ }
29
+ :root.theme-red .titlebar {
30
+ background: linear-gradient(90deg, #ffffff 10%, #fdeded 90%) !important;
31
+ }
32
+ :root.theme-red #sidebar {
33
+ background: linear-gradient(180deg, #ffffff 10%, #fdeded 100%) !important;
34
+ border-left: 1px solid #fcdbdb !important;
35
+ }
36
+
37
+ :root.theme-red .page .right {
38
+ background: var(--primal_dark) !important; /* Darker logo container */
39
+ box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3) !important;
40
+ color: #e2e8f0 !important;
41
+ }
42
+
43
+ /* Red Overrides */
44
+ :root.theme-red .dropdown-item:hover {
45
+ background-color: rgba(239, 68, 68, 0.08) !important;
46
+ color: #dc2626 !important;
47
+ }
48
+ :root.theme-red .titlebar .btn-light:hover {
49
+ background-color: rgba(239, 68, 68, 0.08) !important;
50
+ color: #dc2626 !important;
51
+ }
@@ -0,0 +1,13 @@
1
+ {% for item in items %}
2
+ <a href="{{ item.url }}"
3
+ class="list-group-item list-group-item-action{% if item.active %} active{% endif %}"
4
+ data-url-name="{{ item.url_name }}">
5
+ <i class="bi {{ item.icon }} me-2" style="font-size: 24px;"></i>
6
+ <span>{{ item.label }}</span>
7
+ </a>
8
+ {% empty %}
9
+ <div class="p-3 text-center text-muted small">
10
+ <i class="bi bi-inbox mb-2" style="font-size: 24px;"></i>
11
+ <p class="mb-0">لا توجد عناصر</p>
12
+ </div>
13
+ {% endfor %}
@@ -0,0 +1,34 @@
1
+ {% if groups %}
2
+ <div class="accordion accordion-flush" id="sidebarExtraAccordion">
3
+ {% for group_name, group in groups.items %}
4
+ <div class="accordion-item">
5
+ <h2 class="accordion-header">
6
+ <button class="accordion-button{% if not group.has_active %} collapsed{% endif %}"
7
+ type="button"
8
+ data-bs-toggle="collapse"
9
+ data-bs-target="#extraGroup{{ forloop.counter }}"
10
+ aria-expanded="{% if group.has_active %}true{% else %}false{% endif %}"
11
+ aria-controls="extraGroup{{ forloop.counter }}">
12
+ <i class="bi {{ group.icon }} me-2" style="font-size: 24px;"></i>
13
+ <span>{{ group_name }}</span>
14
+ </button>
15
+ </h2>
16
+ <div id="extraGroup{{ forloop.counter }}"
17
+ class="accordion-collapse collapse{% if group.has_active %} show{% endif %}"
18
+ data-bs-parent="#sidebarExtraAccordion">
19
+ <div class="accordion-body p-0">
20
+ {% for item in group.items %}
21
+ <a href="{{ item.url }}"
22
+ class="list-group-item list-group-item-action{% if item.active %} active{% endif %}"
23
+ data-url-name="{{ item.url_name }}">
24
+ <i class="bi {{ item.icon }} me-2" style="font-size: 24px;"></i>
25
+ <span>{{ item.label }}</span>
26
+ </a>
27
+ {% endfor %}
28
+ </div>
29
+ </div>
30
+ </div>
31
+ {% endfor %}
32
+ </div>
33
+ {% endif %}
34
+
@@ -1,8 +1,13 @@
1
1
  {% load static %}
2
2
  <link rel="stylesheet" href="{% static 'sidebar/sidebar.css' %}">
3
+ <link rel="stylesheet" href="{% static 'sidebar/css/theme_picker.css' %}">
4
+ <link rel="stylesheet" href="{% static 'themes/main.css' %}">
3
5
  <script src="{% static 'sidebar/sidebar.js' %}" nonce="{{ request.csp_nonce }}" defer></script>
6
+ <script src="{% static 'themes/main.js' %}" nonce="{{ request.csp_nonce }}" defer></script>
7
+ <script src="{% static 'sidebar/js/theme_picker.js' %}" nonce="{{ request.csp_nonce }}" defer></script>
4
8
  <!-- Ghost Sidebar for small screens layout stability -->
5
- <div class="sidebar-ghost"></div>
9
+ {% if request.user.is_authenticated %}
10
+ <!-- <div class="sidebar-ghost"></div> -->
6
11
 
7
12
  <!-- sidebar.html -->
8
13
  <div class="col-2 flex-column shadow-sm sidebar {% if request.session.sidebarCollapsed %}collapsed{% endif %} no-print"
@@ -43,4 +48,22 @@
43
48
 
44
49
  {% endblock %}
45
50
  </div>
51
+
52
+ <!-- Sidebar Toolbar (Theme Picker, etc.) -->
53
+ <div class="sidebar-toolbar no-print">
54
+ <i class="bi bi-chevron-up theme-arrow" id="sidebarThemeArrow"></i>
55
+ <div class="current-theme-indicator" id="sidebarThemeIndicator" title="تغيير المظهر"></div>
56
+ <div class="theme-popup" id="sidebarThemePopup">
57
+ <div class="small fw-bold mb-2 text-center border-bottom pb-1">اختر اللون</div>
58
+ <div class="theme-options-grid">
59
+ <div class="theme-option-circle theme-circle-light" data-theme="light" title="أبيض"></div>
60
+ <div class="theme-option-circle theme-circle-blue" data-theme="blue" title="ملكي"></div>
61
+ <div class="theme-option-circle theme-circle-gold" data-theme="gold" title="ذهبي"></div>
62
+ <div class="theme-option-circle theme-circle-green" data-theme="green" title="أخضر"></div>
63
+ <div class="theme-option-circle theme-circle-red" data-theme="red" title="أحمر"></div>
64
+ <div class="theme-option-circle theme-circle-dark" data-theme="dark" title="ليلي"></div>
65
+ </div>
66
+ </div>
67
+ </div>
46
68
  </div>
69
+ {% endif %}
@@ -0,0 +1 @@
1
+ # This file makes templatetags a Python package
@@ -0,0 +1,74 @@
1
+ """
2
+ Template tags for the sidebar app.
3
+
4
+ Provides the {% auto_sidebar %} tag for rendering auto-discovered
5
+ navigation items.
6
+ """
7
+ from django import template
8
+ from django.urls import reverse, NoReverseMatch
9
+
10
+ register = template.Library()
11
+
12
+
13
+ @register.inclusion_tag('sidebar/auto.html', takes_context=True)
14
+ def auto_sidebar(context):
15
+ """
16
+ Render auto-discovered sidebar items.
17
+
18
+ Uses items from sidebar_auto_items context variable (provided by
19
+ the context processor) and adds resolved URLs and active state.
20
+
21
+ Usage:
22
+ {% load sidebar_tags %}
23
+ {% auto_sidebar %}
24
+ """
25
+ request = context.get('request')
26
+ items = list(context.get('sidebar_auto_items', []))
27
+
28
+ # Add resolved URLs and active state
29
+ for item in items:
30
+ try:
31
+ item['url'] = reverse(item['url_name'])
32
+ # Check if current path matches or starts with this URL
33
+ item['active'] = request.path == item['url'] or request.path.startswith(item['url'].rstrip('/') + '/')
34
+ except NoReverseMatch:
35
+ item['url'] = '#'
36
+ item['active'] = False
37
+
38
+ return {'items': items, 'request': request}
39
+
40
+
41
+ @register.simple_tag(takes_context=True)
42
+ def sidebar_item_class(context, url_name):
43
+ """
44
+ Return 'active' class if current path matches the given URL name.
45
+
46
+ Usage:
47
+ <a href="{% url 'decree_list' %}" class="list-group-item {% sidebar_item_class 'decree_list' %}">
48
+ """
49
+ request = context.get('request')
50
+ try:
51
+ url = reverse(url_name)
52
+ if request.path == url or request.path.startswith(url.rstrip('/') + '/'):
53
+ return 'active'
54
+ except NoReverseMatch:
55
+ pass
56
+ return ''
57
+
58
+
59
+ @register.inclusion_tag('sidebar/extra_groups.html', takes_context=True)
60
+ def extra_sidebar(context):
61
+ """
62
+ Render extra sidebar items grouped in accordions.
63
+
64
+ Uses sidebar_extra_groups from context (provided by context processor).
65
+ Groups are rendered as Bootstrap accordions at the end of the sidebar.
66
+
67
+ Usage:
68
+ {% load sidebar_tags %}
69
+ {% extra_sidebar %}
70
+ """
71
+ groups = context.get('sidebar_extra_groups', {})
72
+ request = context.get('request')
73
+ return {'groups': groups, 'request': request}
74
+
@@ -1,13 +0,0 @@
1
- sidebar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- sidebar/apps.py,sha256=4UjKXHoBGKRLxpC9AY6eaq8YZx8unirUz_8u-IrlfVQ,145
3
- sidebar/urls.py,sha256=UL_9e1RLNMxZXkah65m7GRU1dbViZRGeNPBIiSZpOYg,142
4
- sidebar/views.py,sha256=MebyJ1ZiylSOPESXFkkQ8QTg-ClrkJn-oYLN6KrcgiM,418
5
- sidebar/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- sidebar/static/sidebar/sidebar.css,sha256=f6xLSC3JiZFABkxWlFesuzAZZtAT3WW1nZBFMDQNS6Y,5283
7
- sidebar/static/sidebar/sidebar.js,sha256=xDp038tlscz5KeTjBiEQTzZ2T7a8k4NY3rC6e9NvMsM,6314
8
- sidebar/templates/sidebar/main.html,sha256=zp_ENJberDGhPERxnzDMwLsjwr5_uTAKd3UpDFNUW-k,1944
9
- micro_sidebar-1.2.2.dist-info/LICENSE,sha256=Fco89ULLSSxKkC2KKnx57SaT0R7WOkZfuk8IYcGiN50,1063
10
- micro_sidebar-1.2.2.dist-info/METADATA,sha256=35UC3_f-k_PQ1mh1c3FIyUn5-ORTgJQKU72tJqKc320,4431
11
- micro_sidebar-1.2.2.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
12
- micro_sidebar-1.2.2.dist-info/top_level.txt,sha256=ih69sjMhU1wOB9HzUV90yEY98aiPuGhzPBBBE-YtJ3w,8
13
- micro_sidebar-1.2.2.dist-info/RECORD,,