drf-to-mkdoc 0.1.4__tar.gz → 0.1.5__tar.gz

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.

Potentially problematic release.


This version of drf-to-mkdoc might be problematic. Click here for more details.

Files changed (56) hide show
  1. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/MANIFEST.in +1 -0
  2. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/PKG-INFO +1 -1
  3. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc.egg-info/PKG-INFO +1 -1
  4. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc.egg-info/SOURCES.txt +19 -1
  5. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/pyproject.toml +1 -0
  6. drf_to_mkdoc-0.1.5/static/javascripts/endpoints-filter.js +189 -0
  7. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/accessibility.css +21 -0
  8. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/animations.css +11 -0
  9. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/badges.css +54 -0
  10. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/base.css +15 -0
  11. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/endpoint-content.css +48 -0
  12. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/endpoints-grid.css +75 -0
  13. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/filter-section.css +209 -0
  14. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/fixes.css +44 -0
  15. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/layout.css +31 -0
  16. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/loading.css +35 -0
  17. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/responsive.css +89 -0
  18. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/sections.css +35 -0
  19. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/stats.css +34 -0
  20. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/tags.css +92 -0
  21. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/theme-toggle.css +30 -0
  22. drf_to_mkdoc-0.1.5/static/stylesheets/endpoints/variables.css +30 -0
  23. drf_to_mkdoc-0.1.5/static/stylesheets/extra.css +358 -0
  24. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/.github/workflows/publish.yaml +0 -0
  25. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/CONTRIBUTING.md +0 -0
  26. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/LICENSE +0 -0
  27. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/README.md +0 -0
  28. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/conf/__init__.py +0 -0
  29. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/conf/defaults.py +0 -0
  30. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/conf/settings.py +0 -0
  31. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/docs/customizing_endpoints.md +0 -0
  32. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/docs/serving_mkdocs_with_django.md +0 -0
  33. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/__init__.py +0 -0
  34. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/apps.py +0 -0
  35. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/conf/__init__.py +0 -0
  36. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/conf/defaults.py +0 -0
  37. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/conf/settings.py +0 -0
  38. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/management/__init__.py +0 -0
  39. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/management/commands/__init__.py +0 -0
  40. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/management/commands/build_docs.py +0 -0
  41. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/management/commands/generate_doc_json.py +0 -0
  42. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/management/commands/generate_docs.py +0 -0
  43. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/management/commands/generate_model_docs.py +0 -0
  44. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/management/commands/update_doc_schema.py +0 -0
  45. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/utils/__init__.py +0 -0
  46. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/utils/common.py +0 -0
  47. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/utils/endpoint_generator.py +0 -0
  48. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/utils/extractors/__init__.py +0 -0
  49. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/utils/extractors/query_parameter_extractors.py +0 -0
  50. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/utils/md_generators/__init__.py +0 -0
  51. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/utils/md_generators/query_parameters_generators.py +0 -0
  52. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc/utils/model_generator.py +0 -0
  53. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc.egg-info/dependency_links.txt +0 -0
  54. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc.egg-info/requires.txt +0 -0
  55. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/drf_to_mkdoc.egg-info/top_level.txt +0 -0
  56. {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.5}/setup.cfg +0 -0
@@ -6,6 +6,7 @@ include pyproject.toml
6
6
  recursive-include drf_to_mkdoc/conf *.py
7
7
  recursive-include drf_to_mkdoc/utils *.py
8
8
  recursive-include drf_to_mkdoc/management *.py
9
+ recursive-include static *
9
10
 
10
11
  global-exclude *.pyc
11
12
  global-exclude *.pyo
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drf-to-mkdoc
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: Generate Markdown API docs from Django/DRF OpenAPI schema for MkDocs
5
5
  Author-email: Hossein Shayesteh <shayestehhs1@gmail.com>
6
6
  Maintainer-email: Hossein Shayesteh <shayestehhs1@gmail.com>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: drf-to-mkdoc
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: Generate Markdown API docs from Django/DRF OpenAPI schema for MkDocs
5
5
  Author-email: Hossein Shayesteh <shayestehhs1@gmail.com>
6
6
  Maintainer-email: Hossein Shayesteh <shayestehhs1@gmail.com>
@@ -33,4 +33,22 @@ drf_to_mkdoc/utils/model_generator.py
33
33
  drf_to_mkdoc/utils/extractors/__init__.py
34
34
  drf_to_mkdoc/utils/extractors/query_parameter_extractors.py
35
35
  drf_to_mkdoc/utils/md_generators/__init__.py
36
- drf_to_mkdoc/utils/md_generators/query_parameters_generators.py
36
+ drf_to_mkdoc/utils/md_generators/query_parameters_generators.py
37
+ static/javascripts/endpoints-filter.js
38
+ static/stylesheets/extra.css
39
+ static/stylesheets/endpoints/accessibility.css
40
+ static/stylesheets/endpoints/animations.css
41
+ static/stylesheets/endpoints/badges.css
42
+ static/stylesheets/endpoints/base.css
43
+ static/stylesheets/endpoints/endpoint-content.css
44
+ static/stylesheets/endpoints/endpoints-grid.css
45
+ static/stylesheets/endpoints/filter-section.css
46
+ static/stylesheets/endpoints/fixes.css
47
+ static/stylesheets/endpoints/layout.css
48
+ static/stylesheets/endpoints/loading.css
49
+ static/stylesheets/endpoints/responsive.css
50
+ static/stylesheets/endpoints/sections.css
51
+ static/stylesheets/endpoints/stats.css
52
+ static/stylesheets/endpoints/tags.css
53
+ static/stylesheets/endpoints/theme-toggle.css
54
+ static/stylesheets/endpoints/variables.css
@@ -71,6 +71,7 @@ include = ["drf_to_mkdoc*"]
71
71
  "conf/*.py",
72
72
  "utils/**/*.py",
73
73
  "management/**/*.py",
74
+ "static/**/*",
74
75
  ]
75
76
 
76
77
  [tool.setuptools_scm]
@@ -0,0 +1,189 @@
1
+ let currentFilters = {
2
+ method: '',
3
+ path: '',
4
+ models: '',
5
+ auth: '',
6
+ roles: '',
7
+ contentType: '',
8
+ params: '',
9
+ schema: '',
10
+ pagination: '',
11
+ tags: '',
12
+ app: '',
13
+ ordering: '',
14
+ search: ''
15
+ };
16
+
17
+ function applyFilters() {
18
+ // Read all filters
19
+ currentFilters = {
20
+ method: getValue('filter-method'),
21
+ path: getValue('filter-path'),
22
+ models: getValue('filter-models'),
23
+ auth: getValue('filter-auth'),
24
+ roles: getValue('filter-roles'),
25
+ contentType: getValue('filter-content-type'),
26
+ params: getValue('filter-params'),
27
+ schema: getValue('filter-schema'),
28
+ pagination: getValue('filter-pagination'),
29
+ tags: getValue('filter-tags'),
30
+ app: getValue('filter-app'),
31
+ ordering: getValue('filter-ordering'),
32
+ search: getValue('filter-search'),
33
+ };
34
+
35
+ updateURLParams(currentFilters);
36
+
37
+ const cards = document.querySelectorAll('.endpoint-card');
38
+ let visibleCount = 0;
39
+
40
+ cards.forEach(card => {
41
+ const visible = matchesFilters(card);
42
+ card.classList.toggle('hidden', !visible);
43
+ if (visible) visibleCount++;
44
+ });
45
+
46
+ // Collapse viewset sections with no visible cards
47
+ document.querySelectorAll('.viewset-section').forEach(section => {
48
+ const visibleCards = section.querySelectorAll('.endpoint-card:not(.hidden)');
49
+ section.style.display = visibleCards.length === 0 ? 'none' : '';
50
+ });
51
+
52
+ // Collapse app sections with no visible viewsets
53
+ document.querySelectorAll('.app-section').forEach(app => {
54
+ const visibleViewsets = app.querySelectorAll('.viewset-section:not([style*="display: none"])');
55
+ app.style.display = visibleViewsets.length === 0 ? 'none' : '';
56
+ });
57
+
58
+ // Update filter result stats
59
+ document.querySelector('.filter-results').textContent =
60
+ `Showing ${visibleCount} of ${cards.length} endpoints`;
61
+ }
62
+
63
+ function getValue(id) {
64
+ const el = document.getElementById(id);
65
+ return el ? el.value.trim().toLowerCase() : '';
66
+ }
67
+
68
+ function populateAppFilterOptions() {
69
+ const select = document.getElementById('filter-app');
70
+ const apps = new Set();
71
+
72
+ document.querySelectorAll('.endpoint-card').forEach(card => {
73
+ const app = card.dataset.app;
74
+ if (app) apps.add(app);
75
+ });
76
+
77
+ // Convert to sorted array and add as options
78
+ Array.from(apps).sort().forEach(app => {
79
+ const opt = document.createElement('option');
80
+ opt.value = app;
81
+ opt.textContent = app;
82
+ select.appendChild(opt);
83
+ });
84
+ }
85
+
86
+ function matchesFilters(card) {
87
+ const d = card.dataset;
88
+ const f = currentFilters;
89
+
90
+ if (f.method && d.method !== f.method) return false;
91
+ if (f.path && !d.path.includes(f.path)) return false;
92
+ if (f.app && d.app !== f.app) return false;
93
+ if (f.auth && d.auth !== f.auth) return false;
94
+ if (f.pagination && d.pagination !== f.pagination) return false;
95
+ if (f.search && d.search !== f.search) return false;
96
+ if (f.ordering && d.ordering !== f.ordering) return false;
97
+ if (f.models && !d.models.includes(f.models)) return false;
98
+ if (f.roles && !d.roles.includes(f.roles)) return false;
99
+ if (f.tags && !d.tags.includes(f.tags)) return false;
100
+ if (f.contentType && d.contentType !== f.contentType) return false;
101
+
102
+ if (f.params && !d.params.includes(f.params)) return false;
103
+
104
+ return true;
105
+ }
106
+
107
+ function clearFilters() {
108
+ document.querySelectorAll('.filter-input, .filter-select').forEach(el => el.value = '');
109
+ currentFilters = {
110
+ method: '', path: '', models: '', auth: '', roles: '', contentType: '',
111
+ params: '', schema: '', pagination: '', tags: '', app: '', ordering: '', search: ''
112
+ };
113
+ applyFilters();
114
+ updateURLParams(currentFilters);
115
+ }
116
+
117
+
118
+ function updateURLParams(filters) {
119
+ const params = new URLSearchParams();
120
+ Object.entries(filters).forEach(([k, v]) => {
121
+ if (v) params.set(k, v);
122
+ });
123
+ history.replaceState(null, '', '?' + params.toString());
124
+ }
125
+
126
+ function loadURLParams() {
127
+ const params = new URLSearchParams(location.search);
128
+ params.forEach((v, k) => {
129
+ const input = document.getElementById(`filter-${k}`);
130
+ if (input) input.value = v;
131
+ });
132
+ }
133
+
134
+ document.addEventListener('DOMContentLoaded', () => {
135
+ populateAppFilterOptions();
136
+ loadURLParams();
137
+ document.querySelectorAll('.filter-input, .filter-select').forEach(input => {
138
+ input.addEventListener('input', debounce(applyFilters, 250));
139
+ });
140
+ applyFilters();
141
+ });
142
+
143
+ function debounce(func, delay) {
144
+ let timeout;
145
+ return function () {
146
+ clearTimeout(timeout);
147
+ timeout = setTimeout(func, delay);
148
+ };
149
+ }
150
+
151
+
152
+
153
+ document.addEventListener('DOMContentLoaded', function() {
154
+ // Example filter implementation
155
+ const container = document.getElementById('fullscreen-container');
156
+
157
+ // Add filter controls
158
+ const filterControls = document.createElement('div');
159
+ filterControls.className = 'filter-controls';
160
+ filterControls.innerHTML = `
161
+ <select id="filter-select">
162
+ <option value="none">No Filter</option>
163
+ <option value="grayscale">Grayscale</option>
164
+ <option value="sepia">Sepia</option>
165
+ <option value="blur">Blur</option>
166
+ </select>
167
+ `;
168
+ container.prepend(filterControls);
169
+
170
+ // Apply filter based on selection
171
+ document.getElementById('filter-select').addEventListener('change', function(e) {
172
+ container.style.filter = e.target.value === 'none' ? '' : e.target.value + '(100%)';
173
+ });
174
+
175
+ // Your custom filter logic here
176
+ // Example: Apply initial filter if needed
177
+ // container.style.filter = 'grayscale(50%)';
178
+ });
179
+
180
+ document.addEventListener('DOMContentLoaded', () => {
181
+ const filterPanel = document.getElementById('filterSidebar');
182
+ const leftSidebar = document.querySelector('.md-sidebar--primary');
183
+
184
+ if (filterPanel && leftSidebar) {
185
+ leftSidebar.innerHTML = ''; // Remove nav if not needed
186
+ leftSidebar.appendChild(filterPanel);
187
+ filterPanel.classList.remove('collapsed'); // Make sure it's visible
188
+ }
189
+ });
@@ -0,0 +1,21 @@
1
+ /* ===== ACCESSIBILITY ===== */
2
+ @media (prefers-contrast: high) {
3
+ :root {
4
+ --border-color: #000000;
5
+ --text-secondary: #000000;
6
+ }
7
+
8
+ [data-theme="dark"],
9
+ [data-md-color-scheme="slate"] {
10
+ --border-color: #ffffff;
11
+ --text-secondary: #ffffff;
12
+ }
13
+ }
14
+
15
+ @media (prefers-reduced-motion: reduce) {
16
+ * {
17
+ animation-duration: 0.01ms !important;
18
+ animation-iteration-count: 1 !important;
19
+ transition-duration: 0.01ms !important;
20
+ }
21
+ }
@@ -0,0 +1,11 @@
1
+ /* ===== ANIMATIONS ===== */
2
+ .filter-highlight {
3
+ background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(147, 51, 234, 0.1));
4
+ border-color: var(--accent-primary) !important;
5
+ animation: highlight-pulse 2s ease-in-out;
6
+ }
7
+
8
+ @keyframes highlight-pulse {
9
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4); }
10
+ 50% { box-shadow: 0 0 0 10px rgba(59, 130, 246, 0); }
11
+ }
@@ -0,0 +1,54 @@
1
+ /* ===== METHOD BADGES ===== */
2
+ .method-badge {
3
+ position: relative;
4
+ padding: 6px 12px;
5
+ font-size: 12px;
6
+ font-weight: bold;
7
+ border-radius: 20px;
8
+ color: white;
9
+ text-transform: uppercase;
10
+ overflow: hidden;
11
+ min-width: 60px;
12
+ text-align: center;
13
+ flex-shrink: 0;
14
+ }
15
+
16
+ .method-badge::before {
17
+ content: '';
18
+ position: absolute;
19
+ top: 0;
20
+ left: -100%;
21
+ width: 100%;
22
+ height: 100%;
23
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
24
+ transition: left 0.5s ease;
25
+ }
26
+
27
+ .method-badge:hover::before {
28
+ left: 100%;
29
+ }
30
+
31
+ .method-get {
32
+ background: linear-gradient(135deg, #10b981, #059669);
33
+ box-shadow: 0 4px 15px rgba(16, 185, 129, 0.3);
34
+ }
35
+
36
+ .method-post {
37
+ background: linear-gradient(135deg, #f59e0b, #d97706);
38
+ box-shadow: 0 4px 15px rgba(245, 158, 11, 0.3);
39
+ }
40
+
41
+ .method-put {
42
+ background: linear-gradient(135deg, #8b5cf6, #7c3aed);
43
+ box-shadow: 0 4px 15px rgba(139, 92, 246, 0.3);
44
+ }
45
+
46
+ .method-patch {
47
+ background: linear-gradient(135deg, #06b6d4, #0891b2);
48
+ box-shadow: 0 4px 15px rgba(6, 182, 212, 0.3);
49
+ }
50
+
51
+ .method-delete {
52
+ background: linear-gradient(135deg, #ef4444, #dc2626);
53
+ box-shadow: 0 4px 15px rgba(239, 68, 68, 0.3);
54
+ }
@@ -0,0 +1,15 @@
1
+ /* ===== BASE STYLES ===== */
2
+ * {
3
+ box-sizing: border-box;
4
+ }
5
+
6
+ body {
7
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
8
+ background: var(--bg-primary);
9
+ color: var(--text-primary);
10
+ line-height: 1.6;
11
+ transition: background-color 0.3s ease, color 0.3s ease;
12
+ margin: 0;
13
+ padding: 0;
14
+ min-height: 100vh;
15
+ }
@@ -0,0 +1,48 @@
1
+ /* ===== ENDPOINT CONTENT ===== */
2
+ .endpoint-path {
3
+ font-family: 'Monaco', 'Menlo', 'SF Mono', monospace;
4
+ font-weight: 600;
5
+ color: var(--text-primary);
6
+ font-size: 15px;
7
+ margin-bottom: 8px;
8
+ word-break: break-all;
9
+ background: var(--bg-primary);
10
+ padding: 12px;
11
+ border-radius: 8px;
12
+ border: 1px solid var(--border-color);
13
+ flex: 1;
14
+ min-width: 0;
15
+ }
16
+
17
+ .endpoint-description {
18
+ color: var(--text-secondary);
19
+ font-size: 14px;
20
+ margin-bottom: 12px;
21
+ line-height: 1.5;
22
+ }
23
+
24
+ .related-models {
25
+ margin-bottom: 12px;
26
+ }
27
+
28
+ .related-models-label {
29
+ font-size: 12px;
30
+ color: var(--text-secondary);
31
+ margin-bottom: 4px;
32
+ }
33
+
34
+ .models-list {
35
+ display: flex;
36
+ flex-wrap: wrap;
37
+ gap: 4px;
38
+ }
39
+
40
+ .model-badge {
41
+ background: var(--bg-primary);
42
+ color: var(--text-primary);
43
+ padding: 2px 6px;
44
+ border-radius: 4px;
45
+ font-size: 11px;
46
+ font-family: monospace;
47
+ border: 1px solid var(--border-color);
48
+ }
@@ -0,0 +1,75 @@
1
+ /* ===== ENDPOINTS GRID ===== */
2
+ .endpoints-grid {
3
+ display: grid;
4
+ grid-template-columns: 1fr;
5
+ gap: 16px;
6
+ margin: 24px 0;
7
+ transition: all 0.3s ease;
8
+ width: 100%;
9
+ }
10
+
11
+ .endpoints-grid.filtering {
12
+ opacity: 0.7;
13
+ }
14
+
15
+ /* ===== ENDPOINT CARDS ===== */
16
+ .endpoint-card {
17
+ position: relative;
18
+ display: flex;
19
+ align-items: center;
20
+ gap: 16px;
21
+ padding: 20px;
22
+ background: var(--bg-secondary);
23
+ border: 1px solid var(--border-color);
24
+ border-radius: 12px;
25
+ transition: all 0.3s ease;
26
+ text-decoration: none;
27
+ color: var(--text-primary);
28
+ box-shadow: var(--shadow);
29
+ overflow: hidden;
30
+ width: 100%;
31
+ box-sizing: border-box;
32
+ }
33
+
34
+ .endpoint-card::before {
35
+ content: '';
36
+ position: absolute;
37
+ top: 0;
38
+ left: 0;
39
+ right: 0;
40
+ bottom: 0;
41
+ background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(147, 51, 234, 0.1));
42
+ opacity: 0;
43
+ transition: opacity 0.3s ease;
44
+ z-index: 1;
45
+ }
46
+
47
+ .endpoint-card:hover::before {
48
+ opacity: 1;
49
+ }
50
+
51
+ .endpoint-card:hover {
52
+ transform: translateY(-2px);
53
+ box-shadow: var(--shadow-hover);
54
+ }
55
+
56
+ .endpoint-card:focus {
57
+ outline: 2px solid var(--accent-primary);
58
+ outline-offset: 2px;
59
+ }
60
+
61
+ .endpoint-card.hidden {
62
+ opacity: 0;
63
+ transform: scale(0.95);
64
+ pointer-events: none;
65
+ position: absolute;
66
+ height: 0;
67
+ margin: 0;
68
+ padding: 0;
69
+ border: none;
70
+ }
71
+
72
+ .endpoint-card > * {
73
+ position: relative;
74
+ z-index: 2;
75
+ }
@@ -0,0 +1,209 @@
1
+ /* Filter Section - Fixed Layout */
2
+ .filter-section,
3
+ .filter-sidebar {
4
+ background: linear-gradient(135deg, #e0f2ff, #ffffff);
5
+ border: 1px solid var(--border-color);
6
+ border-radius: 16px;
7
+ padding: 24px;
8
+ margin-bottom: 32px;
9
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
10
+ transition: all 0.3s ease;
11
+ width: 100%;
12
+ max-width: 100%;
13
+ box-sizing: border-box; /* Prevents overflow */
14
+ position: relative; /* Ensures proper positioning */
15
+ z-index: 1; /* Prevents overlap with other elements */
16
+ }
17
+
18
+ .filter-sidebar.collapsed {
19
+ /* Add styles for collapsed state if needed */
20
+ overflow: hidden;
21
+ }
22
+
23
+ .filter-title {
24
+ font-size: 20px;
25
+ font-weight: 700;
26
+ color: var(--text-primary);
27
+ margin-bottom: 20px;
28
+ text-align: left;
29
+ display: flex;
30
+ align-items: center;
31
+ gap: 8px;
32
+ }
33
+
34
+ .filter-grid {
35
+ display: grid;
36
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
37
+ gap: 16px;
38
+ margin-bottom: 20px;
39
+ width: 100%;
40
+ }
41
+
42
+ .filter-group {
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: 6px;
46
+ min-width: 0; /* Prevents flex items from overflowing */
47
+ }
48
+
49
+ .filter-label {
50
+ font-size: 13px;
51
+ font-weight: 600;
52
+ color: var(--text-primary);
53
+ margin-bottom: 4px;
54
+ }
55
+
56
+ .filter-input,
57
+ .filter-select {
58
+ width: 100%;
59
+ max-width: 100%;
60
+ box-sizing: border-box;
61
+ padding: 10px 12px;
62
+ border: 1px solid var(--border-color);
63
+ border-radius: 8px;
64
+ font-size: 14px;
65
+ background: var(--bg-primary);
66
+ color: var(--text-primary);
67
+ transition: border 0.2s ease, box-shadow 0.2s ease;
68
+ appearance: none;
69
+ background-image: none;
70
+ min-height: 40px; /* Consistent height */
71
+ }
72
+
73
+ .filter-select {
74
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
75
+ background-position: right 10px center;
76
+ background-repeat: no-repeat;
77
+ background-size: 16px;
78
+ padding-right: 40px;
79
+ }
80
+
81
+ .filter-input:focus,
82
+ .filter-select:focus {
83
+ outline: none;
84
+ border-color: var(--accent-primary);
85
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
86
+ }
87
+
88
+ .filter-input:hover,
89
+ .filter-select:hover {
90
+ border-color: var(--accent-primary);
91
+ }
92
+
93
+ .filter-actions {
94
+ display: flex;
95
+ justify-content: center;
96
+ gap: 12px;
97
+ padding-top: 20px;
98
+ border-top: 1px solid var(--border-color);
99
+ margin-top: 20px;
100
+ }
101
+
102
+ .filter-apply,
103
+ .filter-clear {
104
+ padding: 10px 20px;
105
+ border-radius: 8px;
106
+ font-size: 14px;
107
+ font-weight: 600;
108
+ cursor: pointer;
109
+ transition: all 0.2s ease;
110
+ min-width: 100px;
111
+ border: none;
112
+ display: inline-flex;
113
+ align-items: center;
114
+ justify-content: center;
115
+ }
116
+
117
+ .filter-apply {
118
+ background: var(--accent-primary);
119
+ color: #fff;
120
+ }
121
+
122
+ .filter-clear {
123
+ background: transparent;
124
+ color: var(--text-secondary);
125
+ border: 1px solid var(--border-color);
126
+ }
127
+
128
+ .filter-apply:hover {
129
+ background: var(--accent-secondary);
130
+ transform: translateY(-1px);
131
+ }
132
+
133
+ .filter-clear:hover {
134
+ border-color: var(--accent-primary);
135
+ color: var(--text-primary);
136
+ background: rgba(59, 130, 246, 0.05);
137
+ }
138
+
139
+ .filter-apply:active,
140
+ .filter-clear:active {
141
+ transform: translateY(0);
142
+ }
143
+
144
+ .filter-results {
145
+ margin-top: 16px;
146
+ font-size: 13px;
147
+ text-align: center;
148
+ color: var(--text-secondary);
149
+ font-style: italic;
150
+ }
151
+
152
+ /* Main content layout to prevent overlap */
153
+ .main-content {
154
+ width: 100%;
155
+ max-width: 1200px;
156
+ margin: 0 auto;
157
+ padding: 0 16px;
158
+ }
159
+
160
+ /* Responsive adjustments */
161
+ @media (max-width: 768px) {
162
+ .filter-grid {
163
+ grid-template-columns: 1fr;
164
+ gap: 12px;
165
+ }
166
+
167
+ .filter-actions {
168
+ flex-direction: column;
169
+ gap: 8px;
170
+ }
171
+
172
+ .filter-apply,
173
+ .filter-clear {
174
+ width: 100%;
175
+ }
176
+
177
+ .filter-sidebar {
178
+ padding: 16px;
179
+ margin-bottom: 24px;
180
+ }
181
+ }
182
+
183
+ @media (max-width: 480px) {
184
+ .filter-title {
185
+ font-size: 18px;
186
+ }
187
+
188
+ .filter-input,
189
+ .filter-select {
190
+ font-size: 16px; /* Prevents zoom on iOS */
191
+ }
192
+ }
193
+
194
+ /* Ensure proper spacing with endpoint cards */
195
+ .endpoints-grid {
196
+ margin-top: 24px;
197
+ clear: both;
198
+ }
199
+
200
+ /* Fix any potential z-index issues */
201
+ .filter-sidebar {
202
+ position: relative;
203
+ z-index: 10;
204
+ }
205
+
206
+ .endpoint-card {
207
+ position: relative;
208
+ z-index: 1;
209
+ }