drf-to-mkdoc 0.1.4__tar.gz → 0.1.6__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.
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/MANIFEST.in +1 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/PKG-INFO +1 -1
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/conf/defaults.py +1 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/management/commands/generate_model_docs.py +36 -7
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/javascripts/endpoints-filter.js +189 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/accessibility.css +21 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/animations.css +11 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/badges.css +54 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/base.css +15 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/endpoint-content.css +48 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/endpoints-grid.css +75 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/filter-section.css +209 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/fixes.css +44 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/layout.css +31 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/loading.css +35 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/responsive.css +89 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/sections.css +35 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/stats.css +34 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/tags.css +92 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/theme-toggle.css +30 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/variables.css +30 -0
- drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/extra.css +358 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/utils/common.py +4 -4
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/utils/extractors/query_parameter_extractors.py +4 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc.egg-info/PKG-INFO +1 -1
- drf_to_mkdoc-0.1.6/drf_to_mkdoc.egg-info/SOURCES.txt +54 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/pyproject.toml +1 -0
- drf_to_mkdoc-0.1.4/drf_to_mkdoc.egg-info/SOURCES.txt +0 -36
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/.github/workflows/publish.yaml +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/CONTRIBUTING.md +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/LICENSE +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/README.md +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/conf/__init__.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/conf/settings.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/docs/customizing_endpoints.md +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/docs/serving_mkdocs_with_django.md +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/__init__.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/apps.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/conf/__init__.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/conf/defaults.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/conf/settings.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/management/__init__.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/management/commands/__init__.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/management/commands/build_docs.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/management/commands/generate_doc_json.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/management/commands/generate_docs.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/management/commands/update_doc_schema.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/utils/__init__.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/utils/endpoint_generator.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/utils/extractors/__init__.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/utils/md_generators/__init__.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/utils/md_generators/query_parameters_generators.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/utils/model_generator.py +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc.egg-info/dependency_links.txt +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc.egg-info/requires.txt +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc.egg-info/top_level.txt +0 -0
- {drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drf-to-mkdoc
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
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>
|
{drf_to_mkdoc-0.1.4 → drf_to_mkdoc-0.1.6}/drf_to_mkdoc/management/commands/generate_model_docs.py
RENAMED
|
@@ -139,21 +139,50 @@ class Command(BaseCommand):
|
|
|
139
139
|
|
|
140
140
|
def introspect_relationship(self, field):
|
|
141
141
|
"""Introspect relationship fields"""
|
|
142
|
-
|
|
142
|
+
# Safely resolve related model label; can be None for generic relations
|
|
143
|
+
related_model_label = None
|
|
144
|
+
try:
|
|
145
|
+
if getattr(field, "related_model", None) is not None:
|
|
146
|
+
related_model_label = (
|
|
147
|
+
f"{field.related_model._meta.app_label}.{field.related_model.__name__}"
|
|
148
|
+
)
|
|
149
|
+
except Exception:
|
|
150
|
+
related_model_label = None
|
|
151
|
+
|
|
152
|
+
relationship_data = {
|
|
143
153
|
"name": field.name,
|
|
144
154
|
"type": field.__class__.__name__,
|
|
145
|
-
"related_model":
|
|
146
|
-
f"{field.related_model.__name__}",
|
|
155
|
+
"related_model": related_model_label,
|
|
147
156
|
"related_name": getattr(field, "related_name", None),
|
|
148
157
|
"on_delete": self.get_on_delete_name(field),
|
|
149
158
|
"null": getattr(field, "null", False),
|
|
150
159
|
"blank": getattr(field, "blank", False),
|
|
151
|
-
"many_to_many": field
|
|
152
|
-
"one_to_many": field
|
|
153
|
-
"many_to_one": field
|
|
154
|
-
"one_to_one": field
|
|
160
|
+
"many_to_many": getattr(field, "many_to_many", False),
|
|
161
|
+
"one_to_many": getattr(field, "one_to_many", False),
|
|
162
|
+
"many_to_one": getattr(field, "many_to_one", False),
|
|
163
|
+
"one_to_one": getattr(field, "one_to_one", False),
|
|
155
164
|
}
|
|
156
165
|
|
|
166
|
+
# Handle Django generic relations where related_model can be None
|
|
167
|
+
field_class_name = field.__class__.__name__
|
|
168
|
+
if field_class_name in ("GenericForeignKey", "GenericRelation"):
|
|
169
|
+
relationship_data["is_generic"] = True
|
|
170
|
+
# Capture common generic relation details when available
|
|
171
|
+
for attr_name in (
|
|
172
|
+
"ct_field",
|
|
173
|
+
"fk_field",
|
|
174
|
+
"object_id_field",
|
|
175
|
+
"content_type_field",
|
|
176
|
+
"for_concrete_model",
|
|
177
|
+
"related_query_name",
|
|
178
|
+
):
|
|
179
|
+
if hasattr(field, attr_name):
|
|
180
|
+
relationship_data[attr_name] = getattr(field, attr_name)
|
|
181
|
+
else:
|
|
182
|
+
relationship_data["is_generic"] = False
|
|
183
|
+
|
|
184
|
+
return relationship_data
|
|
185
|
+
|
|
157
186
|
def get_on_delete_name(self, field):
|
|
158
187
|
"""Get readable name for on_delete option"""
|
|
159
188
|
if not hasattr(field, "on_delete") or field.on_delete is None:
|
|
@@ -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
|
+
}
|
drf_to_mkdoc-0.1.6/drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/endpoint-content.css
ADDED
|
@@ -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
|
+
}
|