fix dashboard source groups
All checks were successful
CI/CD Pipeline / Manual Action Help (push) Has been skipped
CI/CD Pipeline / Start Dev Containers in Dokploy (push) Has been skipped
CI/CD Pipeline / Cleanup Dev Database (push) Has been skipped
CI/CD Pipeline / Quality Gate (push) Successful in 1m49s
CI/CD Pipeline / Build and Push Images (push) Successful in 2m22s
CI/CD Pipeline / Internal Notify (push) Successful in 1s
All checks were successful
CI/CD Pipeline / Manual Action Help (push) Has been skipped
CI/CD Pipeline / Start Dev Containers in Dokploy (push) Has been skipped
CI/CD Pipeline / Cleanup Dev Database (push) Has been skipped
CI/CD Pipeline / Quality Gate (push) Successful in 1m49s
CI/CD Pipeline / Build and Push Images (push) Successful in 2m22s
CI/CD Pipeline / Internal Notify (push) Successful in 1s
This commit is contained in:
@@ -2064,6 +2064,10 @@ class ParserDashboardDataView(APIView):
|
||||
|
||||
def get(self, request: Request):
|
||||
sources = ParserSourceSerializer(PARSER_SOURCES.values(), many=True).data
|
||||
api_sources = [
|
||||
source for source in sources if not source["supports_file_upload"]
|
||||
]
|
||||
file_sources = [source for source in sources if source["supports_file_upload"]]
|
||||
jobs = BackgroundJobService.get_user_jobs(user_id=request.user.id, limit=30)
|
||||
source_counts = dict(
|
||||
GenericParserRecord.objects.values("source")
|
||||
@@ -2083,12 +2087,12 @@ class ParserDashboardDataView(APIView):
|
||||
return api_response(
|
||||
{
|
||||
"sources": sources,
|
||||
"api_sources": [
|
||||
source for source in sources if not source["supports_file_upload"]
|
||||
],
|
||||
"file_sources": [
|
||||
source for source in sources if source["supports_file_upload"]
|
||||
],
|
||||
"api_sources": api_sources,
|
||||
"file_sources": file_sources,
|
||||
"groups": {
|
||||
"api": api_sources,
|
||||
"uploads": file_sources,
|
||||
},
|
||||
"schedules": ParserScheduleSerializer(schedules, many=True).data,
|
||||
"jobs": BackgroundJobListSerializer(jobs, many=True).data,
|
||||
"source_counts": source_counts,
|
||||
|
||||
@@ -1378,6 +1378,14 @@
|
||||
return map;
|
||||
}
|
||||
|
||||
function sourceGroups() {
|
||||
const sources = dashboardData?.sources || [];
|
||||
return dashboardData?.groups || {
|
||||
api: dashboardData?.api_sources || sources.filter((source) => !source.supports_file_upload),
|
||||
uploads: dashboardData?.file_sources || sources.filter((source) => source.supports_file_upload),
|
||||
};
|
||||
}
|
||||
|
||||
function latestLoadForSource(source) {
|
||||
return latestLoadsBySource().get(source.source) || null;
|
||||
}
|
||||
@@ -1398,7 +1406,7 @@
|
||||
const other = Math.max(latestLoads.length - success - failed, 0);
|
||||
const activeSchedules = (dashboardData?.schedules || []).filter((schedule) => schedule.enabled).length;
|
||||
const runningJobs = (dashboardData?.jobs || []).filter((job) => ["pending", "started", "retry"].includes(job.status)).length;
|
||||
const uploadCount = (dashboardData?.groups?.uploads || []).length;
|
||||
const uploadCount = (sourceGroups().uploads || []).length;
|
||||
|
||||
$("analyticsKpis").innerHTML = [
|
||||
["Источников", sources.length],
|
||||
@@ -1708,14 +1716,15 @@
|
||||
function renderDashboard(data) {
|
||||
dashboardData = data.data;
|
||||
const sources = dashboardData.sources || [];
|
||||
const groups = sourceGroups();
|
||||
const options = sources.map((source) => `<option value="${source.key}">${source.title}</option>`).join("");
|
||||
$("runSource").innerHTML = options;
|
||||
$("scheduleSource").innerHTML = options;
|
||||
$("sourceCount").textContent = `${sources.length} источников`;
|
||||
$("uploadCount").textContent = `${(dashboardData.groups.uploads || []).length} источника`;
|
||||
$("uploadCount").textContent = `${(groups.uploads || []).length} источника`;
|
||||
renderAnalytics();
|
||||
renderSourceCards(sources);
|
||||
renderUploadSources(dashboardData.groups.uploads || [], "uploadSources");
|
||||
renderUploadSources(groups.uploads || [], "uploadSources");
|
||||
|
||||
$("jobsBody").innerHTML = (dashboardData.jobs || []).map((job) => {
|
||||
const canRevoke = ["pending", "started", "retry"].includes(job.status);
|
||||
|
||||
@@ -21,3 +21,11 @@ class ParserDashboardPageTest(TestCase):
|
||||
content = response.content.decode()
|
||||
self.assertIn("refreshRegisters().catch(renderRegistersUnavailable)", content)
|
||||
self.assertIn("isAuthError(error)", content)
|
||||
|
||||
def test_dashboard_has_group_fallback_for_current_api_shape(self):
|
||||
response = self.client.get("/dashboard")
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
content = response.content.decode()
|
||||
self.assertIn("function sourceGroups()", content)
|
||||
self.assertIn("dashboardData?.file_sources", content)
|
||||
|
||||
@@ -120,6 +120,19 @@ class ParsersViewSetTest(APITestCase):
|
||||
)
|
||||
self.assertEqual(detail.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test_dashboard_data_exposes_source_groups_for_page(self):
|
||||
self.client.force_authenticate(self.user)
|
||||
|
||||
response = self.client.get("/api/v1/parsers/dashboard/")
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
payload = response.data["data"]
|
||||
self.assertIn("groups", payload)
|
||||
self.assertIn("api", payload["groups"])
|
||||
self.assertIn("uploads", payload["groups"])
|
||||
self.assertEqual(payload["api_sources"], payload["groups"]["api"])
|
||||
self.assertEqual(payload["file_sources"], payload["groups"]["uploads"])
|
||||
|
||||
def test_financial_reports_list_and_retrieve(self):
|
||||
report = FinancialReport.objects.create(
|
||||
external_id=_digits(5),
|
||||
|
||||
Reference in New Issue
Block a user