Skip to content

Commit 5d918ea

Browse files
feature/CRUD for Rate Limiting
1 parent 2cec411 commit 5d918ea

6 files changed

Lines changed: 1007 additions & 230 deletions

File tree

apimanager/consumers/static/consumers/css/consumers.css

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,169 @@
182182
font-size: 12px;
183183
padding: 6px 12px;
184184
}
185+
186+
/* Rate Limiting CRUD Interface Styles */
187+
#rateLimitForm {
188+
margin-bottom: 30px;
189+
}
190+
191+
#rateLimitForm .panel-heading {
192+
background-color: #f8f9fa;
193+
border-bottom: 1px solid #dee2e6;
194+
}
195+
196+
#rateLimitForm .panel-title {
197+
color: #495057;
198+
font-weight: bold;
199+
font-size: 16px;
200+
}
201+
202+
#addRateLimitBtn {
203+
background-color: #28a745;
204+
border-color: #28a745;
205+
font-weight: bold;
206+
}
207+
208+
#addRateLimitBtn:hover {
209+
background-color: #218838;
210+
border-color: #1e7e34;
211+
}
212+
213+
/* Rate limits table styling */
214+
#rateLimitsList .table {
215+
margin-bottom: 0;
216+
}
217+
218+
#rateLimitsList .table th {
219+
background-color: #f8f9fa;
220+
color: #495057;
221+
font-weight: bold;
222+
font-size: 12px;
223+
text-transform: uppercase;
224+
border-top: none;
225+
}
226+
227+
#rateLimitsList .table td {
228+
font-size: 13px;
229+
vertical-align: middle;
230+
}
231+
232+
/* Action buttons styling */
233+
#rateLimitsList .btn-sm {
234+
font-size: 11px;
235+
padding: 4px 8px;
236+
margin-right: 5px;
237+
}
238+
239+
#rateLimitsList .btn-primary {
240+
background-color: #007bff;
241+
border-color: #007bff;
242+
}
243+
244+
#rateLimitsList .btn-primary:hover {
245+
background-color: #0056b3;
246+
border-color: #0056b3;
247+
}
248+
249+
#rateLimitsList .btn-danger {
250+
background-color: #dc3545;
251+
border-color: #dc3545;
252+
}
253+
254+
#rateLimitsList .btn-danger:hover {
255+
background-color: #c82333;
256+
border-color: #bd2130;
257+
}
258+
259+
/* Form styling */
260+
#rateLimitFormElement .form-group label {
261+
font-weight: bold;
262+
color: #495057;
263+
font-size: 13px;
264+
}
265+
266+
#rateLimitFormElement .form-control {
267+
font-size: 13px;
268+
border-radius: 3px;
269+
}
270+
271+
#rateLimitFormElement .btn {
272+
margin-right: 10px;
273+
}
274+
275+
/* Empty state styling */
276+
.alert-info {
277+
background-color: #d1ecf1;
278+
border-color: #bee5eb;
279+
color: #0c5460;
280+
}
281+
282+
.alert-info .glyphicon {
283+
margin-right: 8px;
284+
}
285+
286+
/* Responsive table */
287+
@media (max-width: 1200px) {
288+
#rateLimitsList .table-responsive {
289+
font-size: 12px;
290+
}
291+
292+
#rateLimitsList .table th,
293+
#rateLimitsList .table td {
294+
padding: 8px 4px;
295+
}
296+
297+
#rateLimitsList .btn-sm {
298+
font-size: 10px;
299+
padding: 3px 6px;
300+
margin: 1px;
301+
display: block;
302+
width: 100%;
303+
margin-bottom: 2px;
304+
}
305+
}
306+
307+
@media (max-width: 768px) {
308+
#rateLimitForm .col-xs-6 {
309+
margin-bottom: 10px;
310+
}
311+
312+
#rateLimitsList .table {
313+
font-size: 11px;
314+
}
315+
316+
#addRateLimitBtn {
317+
width: 100%;
318+
margin-bottom: 15px;
319+
}
320+
}
321+
322+
/* Animation for form show/hide */
323+
#rateLimitForm {
324+
transition: all 0.3s ease-in-out;
325+
}
326+
327+
/* Highlight new/updated rows */
328+
.table tr.highlight {
329+
background-color: #d4edda;
330+
transition: background-color 2s ease-out;
331+
}
332+
333+
/* Loading states */
334+
.btn[disabled] {
335+
opacity: 0.6;
336+
cursor: not-allowed;
337+
}
338+
339+
/* Panel improvements */
340+
.panel-default > .panel-heading {
341+
background-image: none;
342+
background-color: #f8f9fa;
343+
}
344+
345+
.panel-default {
346+
border-color: #dee2e6;
347+
box-shadow:
348+
0 1px 3px rgba(0, 0, 0, 0.12),
349+
0 1px 2px rgba(0, 0, 0, 0.24);
350+
}

apimanager/consumers/static/consumers/js/consumers.js

Lines changed: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ $(document).ready(function ($) {
22
// Handle datetime-local inputs for rate limiting
33
function initializeDateTimeFields() {
44
// Set default values for datetime fields if they're empty
5-
var fromDateField = $("#id_from_date");
6-
var toDateField = $("#id_to_date");
5+
var fromDateField = $("#from_date");
6+
var toDateField = $("#to_date");
77

88
// If fields are empty, set default values
99
if (!fromDateField.val()) {
@@ -27,33 +27,35 @@ $(document).ready(function ($) {
2727
var toDate = $("[data-to-date]").data("to-date");
2828

2929
if (fromDate && fromDate !== "1099-12-31T23:00:00Z") {
30-
$("#id_from_date").val(convertISOToLocalDateTime(fromDate));
30+
$("#from_date").val(convertISOToLocalDateTime(fromDate));
3131
}
3232
if (toDate && toDate !== "1099-12-31T23:00:00Z") {
33-
$("#id_to_date").val(convertISOToLocalDateTime(toDate));
33+
$("#to_date").val(convertISOToLocalDateTime(toDate));
3434
}
3535
}
3636

3737
// Form validation
3838
function validateRateLimitingForm() {
39-
$("form").on("submit", function (e) {
39+
$("#rateLimitFormElement").on("submit", function (e) {
4040
var hasError = false;
4141
var errorMessage = "";
4242

4343
// Check if any limit values are negative (except -1 which means unlimited)
44-
$('input[type="number"]').each(function () {
45-
var value = parseInt($(this).val());
46-
if (value < -1) {
47-
hasError = true;
48-
errorMessage +=
49-
"Rate limit values must be -1 (unlimited) or positive numbers.\n";
50-
return false;
51-
}
52-
});
44+
$(this)
45+
.find('input[type="number"]')
46+
.each(function () {
47+
var value = parseInt($(this).val());
48+
if (isNaN(value) || value < -1) {
49+
hasError = true;
50+
errorMessage +=
51+
"Rate limit values must be -1 (unlimited) or positive numbers.\n";
52+
return false;
53+
}
54+
});
5355

5456
// Check date range
55-
var fromDate = new Date($("#id_from_date").val());
56-
var toDate = new Date($("#id_to_date").val());
57+
var fromDate = new Date($("#from_date").val());
58+
var toDate = new Date($("#to_date").val());
5759

5860
if (fromDate && toDate && fromDate > toDate) {
5961
hasError = true;
@@ -65,6 +67,52 @@ $(document).ready(function ($) {
6567
e.preventDefault();
6668
return false;
6769
}
70+
71+
// Handle form submission via AJAX
72+
e.preventDefault();
73+
submitRateLimitForm();
74+
});
75+
}
76+
77+
// Submit rate limit form via AJAX
78+
function submitRateLimitForm() {
79+
var form = $("#rateLimitFormElement");
80+
var formData = new FormData(form[0]);
81+
var submitBtn = $("#submitBtn");
82+
var originalText = submitBtn.text();
83+
84+
// Disable submit button and show loading
85+
submitBtn.prop("disabled", true).text("Saving...");
86+
87+
$.ajax({
88+
url: window.location.pathname,
89+
type: "POST",
90+
data: formData,
91+
processData: false,
92+
contentType: false,
93+
headers: {
94+
"X-CSRFToken": $("[name=csrfmiddlewaretoken]").val(),
95+
},
96+
success: function (response) {
97+
if (response.success) {
98+
// Hide form and reload page to show updated data
99+
hideRateLimitForm();
100+
window.location.reload();
101+
} else {
102+
alert("Error: " + (response.error || "Unknown error occurred"));
103+
}
104+
},
105+
error: function (xhr, status, error) {
106+
var errorMessage = "Error saving rate limit";
107+
if (xhr.responseJSON && xhr.responseJSON.error) {
108+
errorMessage = xhr.responseJSON.error;
109+
}
110+
alert(errorMessage);
111+
},
112+
complete: function () {
113+
// Re-enable submit button
114+
submitBtn.prop("disabled", false).text(originalText);
115+
},
68116
});
69117
}
70118

@@ -98,3 +146,11 @@ $(document).ready(function ($) {
98146
);
99147
});
100148
});
149+
150+
// Global functions are now defined inline in the template
151+
// This file now only contains form validation and initialization
152+
153+
// Refresh rate limits list
154+
function refreshRateLimits() {
155+
window.location.reload();
156+
}

0 commit comments

Comments
 (0)