add pagination to agent table
This commit is contained in:
parent
9442acb028
commit
24cb0565b9
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.1.7 on 2021-02-28 06:38
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('accounts', '0011_user_default_agent_tbl_tab'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='agents_per_page',
|
||||
field=models.PositiveIntegerField(default=50),
|
||||
),
|
||||
]
|
|
@ -27,6 +27,7 @@ class User(AbstractUser, BaseAuditModel):
|
|||
default_agent_tbl_tab = models.CharField(
|
||||
max_length=50, choices=AGENT_TBL_TAB_CHOICES, default="server"
|
||||
)
|
||||
agents_per_page = models.PositiveIntegerField(default=50)
|
||||
|
||||
agent = models.OneToOneField(
|
||||
"agents.Agent",
|
||||
|
|
|
@ -283,6 +283,7 @@ class TestUserAction(TacticalTestCase):
|
|||
"userui": True,
|
||||
"agent_dblclick_action": "editagent",
|
||||
"default_agent_tbl_tab": "mixed",
|
||||
"agents_per_page": 1000,
|
||||
}
|
||||
r = self.client.patch(url, data, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
|
|
@ -199,4 +199,8 @@ class UserUI(APIView):
|
|||
user.default_agent_tbl_tab = request.data["default_agent_tbl_tab"]
|
||||
user.save(update_fields=["agent_dblclick_action", "default_agent_tbl_tab"])
|
||||
|
||||
if "agents_per_page" in request.data.keys():
|
||||
user.agents_per_page = request.data["agents_per_page"]
|
||||
user.save(update_fields=["agents_per_page"])
|
||||
|
||||
return Response("ok")
|
||||
|
|
|
@ -17,6 +17,107 @@ from .serializers import AgentSerializer
|
|||
from .tasks import auto_self_agent_update_task
|
||||
|
||||
|
||||
class TestAgentsList(TacticalTestCase):
|
||||
def setUp(self):
|
||||
self.authenticate()
|
||||
self.setup_coresettings()
|
||||
|
||||
def test_agents_list(self):
|
||||
url = "/agents/listagents/"
|
||||
|
||||
# 36 total agents
|
||||
company1 = baker.make("clients.Client")
|
||||
company2 = baker.make("clients.Client")
|
||||
site1 = baker.make("clients.Site", client=company1)
|
||||
site2 = baker.make("clients.Site", client=company1)
|
||||
site3 = baker.make("clients.Site", client=company2)
|
||||
|
||||
baker.make_recipe(
|
||||
"agents.online_agent", site=site1, monitoring_type="server", _quantity=15
|
||||
)
|
||||
baker.make_recipe(
|
||||
"agents.online_agent",
|
||||
site=site2,
|
||||
monitoring_type="workstation",
|
||||
_quantity=10,
|
||||
)
|
||||
baker.make_recipe(
|
||||
"agents.online_agent",
|
||||
site=site3,
|
||||
monitoring_type="server",
|
||||
_quantity=4,
|
||||
)
|
||||
baker.make_recipe(
|
||||
"agents.online_agent",
|
||||
site=site3,
|
||||
monitoring_type="workstation",
|
||||
_quantity=7,
|
||||
)
|
||||
|
||||
data = {
|
||||
"pagination": {
|
||||
"rowsPerPage": 50,
|
||||
"rowsNumber": None,
|
||||
"sortBy": "hostname",
|
||||
"descending": False,
|
||||
"page": 1,
|
||||
},
|
||||
"monType": "mixed",
|
||||
}
|
||||
|
||||
# test mixed
|
||||
r = self.client.patch(url, data, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertEqual(r.data["total"], 36) # type: ignore
|
||||
self.assertEqual(len(r.data["agents"]), 36) # type: ignore
|
||||
|
||||
# test servers
|
||||
data["monType"] = "server"
|
||||
data["pagination"]["rowsPerPage"] = 6
|
||||
r = self.client.patch(url, data, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertEqual(r.data["total"], 19) # type: ignore
|
||||
self.assertEqual(len(r.data["agents"]), 6) # type: ignore
|
||||
|
||||
# test workstations
|
||||
data["monType"] = "server"
|
||||
data["pagination"]["rowsPerPage"] = 6
|
||||
r = self.client.patch(url, data, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertEqual(r.data["total"], 19) # type: ignore
|
||||
self.assertEqual(len(r.data["agents"]), 6) # type: ignore
|
||||
|
||||
# test client1 mixed
|
||||
data = {
|
||||
"pagination": {
|
||||
"rowsPerPage": 3,
|
||||
"rowsNumber": None,
|
||||
"sortBy": "hostname",
|
||||
"descending": False,
|
||||
"page": 1,
|
||||
},
|
||||
"monType": "mixed",
|
||||
"clientPK": company1.pk, # type: ignore
|
||||
}
|
||||
|
||||
r = self.client.patch(url, data, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertEqual(r.data["total"], 25) # type: ignore
|
||||
self.assertEqual(len(r.data["agents"]), 3) # type: ignore
|
||||
|
||||
# test site3 workstations
|
||||
del data["clientPK"]
|
||||
data["monType"] = "workstation"
|
||||
data["sitePK"] = site3.pk # type: ignore
|
||||
|
||||
r = self.client.patch(url, data, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertEqual(r.data["total"], 7) # type: ignore
|
||||
self.assertEqual(len(r.data["agents"]), 3) # type: ignore
|
||||
|
||||
self.check_not_authenticated("patch", url)
|
||||
|
||||
|
||||
class TestAgentViews(TacticalTestCase):
|
||||
def setUp(self):
|
||||
self.authenticate()
|
||||
|
@ -256,7 +357,7 @@ class TestAgentViews(TacticalTestCase):
|
|||
mock_ret.return_value = "nt authority\system"
|
||||
r = self.client.post(url, data, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertIsInstance(r.data, str)
|
||||
self.assertIsInstance(r.data, str) # type: ignore
|
||||
|
||||
mock_ret.return_value = "timeout"
|
||||
r = self.client.post(url, data, format="json")
|
||||
|
@ -276,15 +377,15 @@ class TestAgentViews(TacticalTestCase):
|
|||
nats_cmd.return_value = "ok"
|
||||
r = self.client.patch(url, data, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertEqual(r.data["time"], "August 29, 2025 at 06:41 PM")
|
||||
self.assertEqual(r.data["agent"], self.agent.hostname)
|
||||
self.assertEqual(r.data["time"], "August 29, 2025 at 06:41 PM") # type: ignore
|
||||
self.assertEqual(r.data["agent"], self.agent.hostname) # type: ignore
|
||||
|
||||
nats_data = {
|
||||
"func": "schedtask",
|
||||
"schedtaskpayload": {
|
||||
"type": "schedreboot",
|
||||
"trigger": "once",
|
||||
"name": r.data["task_name"],
|
||||
"name": r.data["task_name"], # type: ignore
|
||||
"year": 2025,
|
||||
"month": "August",
|
||||
"day": 29,
|
||||
|
@ -305,7 +406,7 @@ class TestAgentViews(TacticalTestCase):
|
|||
r = self.client.patch(url, data_invalid, format="json")
|
||||
|
||||
self.assertEqual(r.status_code, 400)
|
||||
self.assertEqual(r.data, "Invalid date")
|
||||
self.assertEqual(r.data, "Invalid date") # type: ignore
|
||||
|
||||
self.check_not_authenticated("patch", url)
|
||||
|
||||
|
@ -316,8 +417,8 @@ class TestAgentViews(TacticalTestCase):
|
|||
|
||||
site = baker.make("clients.Site")
|
||||
data = {
|
||||
"client": site.client.id,
|
||||
"site": site.id,
|
||||
"client": site.client.id, # type: ignore
|
||||
"site": site.id, # type: ignore
|
||||
"arch": "64",
|
||||
"expires": 23,
|
||||
"installMethod": "exe",
|
||||
|
@ -401,14 +502,6 @@ class TestAgentViews(TacticalTestCase):
|
|||
|
||||
self.check_not_authenticated("post", url)
|
||||
|
||||
def test_agents_list(self):
|
||||
url = "/agents/listagents/"
|
||||
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
self.check_not_authenticated("get", url)
|
||||
|
||||
def test_agents_agent_detail(self):
|
||||
url = f"/agents/{self.agent.pk}/agentdetail/"
|
||||
|
||||
|
@ -425,7 +518,7 @@ class TestAgentViews(TacticalTestCase):
|
|||
|
||||
edit = {
|
||||
"id": self.agent.pk,
|
||||
"site": site.id,
|
||||
"site": site.id, # type: ignore
|
||||
"monitoring_type": "workstation",
|
||||
"description": "asjdk234andasd",
|
||||
"offline_time": 4,
|
||||
|
@ -456,7 +549,7 @@ class TestAgentViews(TacticalTestCase):
|
|||
|
||||
agent = Agent.objects.get(pk=self.agent.pk)
|
||||
data = AgentSerializer(agent).data
|
||||
self.assertEqual(data["site"], site.id)
|
||||
self.assertEqual(data["site"], site.id) # type: ignore
|
||||
|
||||
policy = WinUpdatePolicy.objects.get(agent=self.agent)
|
||||
data = WinUpdatePolicySerializer(policy).data
|
||||
|
@ -474,21 +567,21 @@ class TestAgentViews(TacticalTestCase):
|
|||
# TODO
|
||||
# decode the cookie
|
||||
|
||||
self.assertIn("&viewmode=13", r.data["file"])
|
||||
self.assertIn("&viewmode=12", r.data["terminal"])
|
||||
self.assertIn("&viewmode=11", r.data["control"])
|
||||
self.assertIn("&viewmode=13", r.data["file"]) # type: ignore
|
||||
self.assertIn("&viewmode=12", r.data["terminal"]) # type: ignore
|
||||
self.assertIn("&viewmode=11", r.data["control"]) # type: ignore
|
||||
|
||||
self.assertIn("&gotonode=", r.data["file"])
|
||||
self.assertIn("&gotonode=", r.data["terminal"])
|
||||
self.assertIn("&gotonode=", r.data["control"])
|
||||
self.assertIn("&gotonode=", r.data["file"]) # type: ignore
|
||||
self.assertIn("&gotonode=", r.data["terminal"]) # type: ignore
|
||||
self.assertIn("&gotonode=", r.data["control"]) # type: ignore
|
||||
|
||||
self.assertIn("?login=", r.data["file"])
|
||||
self.assertIn("?login=", r.data["terminal"])
|
||||
self.assertIn("?login=", r.data["control"])
|
||||
self.assertIn("?login=", r.data["file"]) # type: ignore
|
||||
self.assertIn("?login=", r.data["terminal"]) # type: ignore
|
||||
self.assertIn("?login=", r.data["control"]) # type: ignore
|
||||
|
||||
self.assertEqual(self.agent.hostname, r.data["hostname"])
|
||||
self.assertEqual(self.agent.client.name, r.data["client"])
|
||||
self.assertEqual(self.agent.site.name, r.data["site"])
|
||||
self.assertEqual(self.agent.hostname, r.data["hostname"]) # type: ignore
|
||||
self.assertEqual(self.agent.client.name, r.data["client"]) # type: ignore
|
||||
self.assertEqual(self.agent.site.name, r.data["site"]) # type: ignore
|
||||
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
|
@ -498,32 +591,6 @@ class TestAgentViews(TacticalTestCase):
|
|||
|
||||
self.check_not_authenticated("get", url)
|
||||
|
||||
def test_by_client(self):
|
||||
url = f"/agents/byclient/{self.agent.client.id}/"
|
||||
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(r.data)
|
||||
|
||||
url = f"/agents/byclient/500/"
|
||||
r = self.client.get(url)
|
||||
self.assertFalse(r.data) # returns empty list
|
||||
|
||||
self.check_not_authenticated("get", url)
|
||||
|
||||
def test_by_site(self):
|
||||
url = f"/agents/bysite/{self.agent.site.id}/"
|
||||
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(r.data)
|
||||
|
||||
url = f"/agents/bysite/500/"
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.data, [])
|
||||
|
||||
self.check_not_authenticated("get", url)
|
||||
|
||||
def test_overdue_action(self):
|
||||
url = "/agents/overdueaction/"
|
||||
|
||||
|
@ -532,14 +599,14 @@ class TestAgentViews(TacticalTestCase):
|
|||
self.assertEqual(r.status_code, 200)
|
||||
agent = Agent.objects.get(pk=self.agent.pk)
|
||||
self.assertTrue(agent.overdue_email_alert)
|
||||
self.assertEqual(self.agent.hostname, r.data)
|
||||
self.assertEqual(self.agent.hostname, r.data) # type: ignore
|
||||
|
||||
payload = {"pk": self.agent.pk, "overdue_text_alert": False}
|
||||
r = self.client.post(url, payload, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
agent = Agent.objects.get(pk=self.agent.pk)
|
||||
self.assertFalse(agent.overdue_text_alert)
|
||||
self.assertEqual(self.agent.hostname, r.data)
|
||||
self.assertEqual(self.agent.hostname, r.data) # type: ignore
|
||||
|
||||
self.check_not_authenticated("post", url)
|
||||
|
||||
|
@ -683,7 +750,7 @@ class TestAgentViews(TacticalTestCase):
|
|||
nats_cmd.return_value = "ok"
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertIn(self.agent.hostname, r.data)
|
||||
self.assertIn(self.agent.hostname, r.data) # type: ignore
|
||||
nats_cmd.assert_called_with(
|
||||
{"func": "recover", "payload": {"mode": "mesh"}}, timeout=45
|
||||
)
|
||||
|
@ -800,7 +867,7 @@ class TestAgentViewsNew(TacticalTestCase):
|
|||
|
||||
r = self.client.post(url, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertEqual(r.data, data)
|
||||
self.assertEqual(r.data, data) # type: ignore
|
||||
|
||||
self.check_not_authenticated("post", url)
|
||||
|
||||
|
@ -812,14 +879,14 @@ class TestAgentViewsNew(TacticalTestCase):
|
|||
agent = baker.make_recipe("agents.agent", site=site)
|
||||
|
||||
# Test client toggle maintenance mode
|
||||
data = {"type": "Client", "id": site.client.id, "action": True}
|
||||
data = {"type": "Client", "id": site.client.id, "action": True} # type: ignore
|
||||
|
||||
r = self.client.post(url, data, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(Agent.objects.get(pk=agent.pk).maintenance_mode)
|
||||
|
||||
# Test site toggle maintenance mode
|
||||
data = {"type": "Site", "id": site.id, "action": False}
|
||||
data = {"type": "Site", "id": site.id, "action": False} # type: ignore
|
||||
|
||||
r = self.client.post(url, data, format="json")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
|
|
@ -6,8 +6,6 @@ urlpatterns = [
|
|||
path("listagents/", views.AgentsTableList.as_view()),
|
||||
path("listagentsnodetail/", views.list_agents_no_detail),
|
||||
path("<int:pk>/agenteditdetails/", views.agent_edit_details),
|
||||
path("byclient/<int:clientpk>/", views.by_client),
|
||||
path("bysite/<int:sitepk>/", views.by_site),
|
||||
path("overdueaction/", views.overdue_action),
|
||||
path("sendrawcmd/", views.send_raw_cmd),
|
||||
path("<pk>/agentdetail/", views.agent_detail),
|
||||
|
|
|
@ -5,11 +5,13 @@ import random
|
|||
import string
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models import Q
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from loguru import logger
|
||||
from packaging import version as pyver
|
||||
from rest_framework import generics, status
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
@ -224,37 +226,61 @@ def send_raw_cmd(request):
|
|||
return Response(r)
|
||||
|
||||
|
||||
class AgentsTableList(generics.ListAPIView):
|
||||
queryset = (
|
||||
Agent.objects.select_related("site")
|
||||
.prefetch_related("agentchecks")
|
||||
.only(
|
||||
"pk",
|
||||
"hostname",
|
||||
"agent_id",
|
||||
"site",
|
||||
"monitoring_type",
|
||||
"description",
|
||||
"needs_reboot",
|
||||
"overdue_text_alert",
|
||||
"overdue_email_alert",
|
||||
"overdue_time",
|
||||
"offline_time",
|
||||
"last_seen",
|
||||
"boot_time",
|
||||
"logged_in_username",
|
||||
"last_logged_in_user",
|
||||
"time_zone",
|
||||
"maintenance_mode",
|
||||
)
|
||||
)
|
||||
serializer_class = AgentTableSerializer
|
||||
class AgentsTableList(APIView):
|
||||
def patch(self, request):
|
||||
pagination = request.data["pagination"]
|
||||
monType = request.data["monType"]
|
||||
client = Q()
|
||||
site = Q()
|
||||
mon_type = Q()
|
||||
|
||||
if monType == "server":
|
||||
mon_type = Q(monitoring_type="server")
|
||||
elif monType == "workstation":
|
||||
mon_type = Q(monitoring_type="workstation")
|
||||
|
||||
if "clientPK" in request.data:
|
||||
client = Q(site__client_id=request.data["clientPK"])
|
||||
|
||||
if "sitePK" in request.data:
|
||||
site = Q(site_id=request.data["sitePK"])
|
||||
|
||||
queryset = (
|
||||
Agent.objects.select_related("site")
|
||||
.prefetch_related("agentchecks")
|
||||
.filter(mon_type)
|
||||
.filter(client)
|
||||
.filter(site)
|
||||
.only(
|
||||
"pk",
|
||||
"hostname",
|
||||
"agent_id",
|
||||
"site",
|
||||
"monitoring_type",
|
||||
"description",
|
||||
"needs_reboot",
|
||||
"overdue_text_alert",
|
||||
"overdue_email_alert",
|
||||
"overdue_time",
|
||||
"offline_time",
|
||||
"last_seen",
|
||||
"boot_time",
|
||||
"logged_in_username",
|
||||
"last_logged_in_user",
|
||||
"time_zone",
|
||||
"maintenance_mode",
|
||||
)
|
||||
.order_by(pagination["sortBy"])
|
||||
)
|
||||
paginator = Paginator(queryset, pagination["rowsPerPage"])
|
||||
|
||||
def list(self, request):
|
||||
queryset = self.get_queryset()
|
||||
ctx = {"default_tz": get_default_timezone()}
|
||||
serializer = AgentTableSerializer(queryset, many=True, context=ctx)
|
||||
return Response(serializer.data)
|
||||
serializer = AgentTableSerializer(
|
||||
paginator.get_page(pagination["page"]), many=True, context=ctx
|
||||
)
|
||||
|
||||
ret = {"agents": serializer.data, "total": paginator.count}
|
||||
return Response(ret)
|
||||
|
||||
|
||||
@api_view()
|
||||
|
@ -269,66 +295,6 @@ def agent_edit_details(request, pk):
|
|||
return Response(AgentEditSerializer(agent).data)
|
||||
|
||||
|
||||
@api_view()
|
||||
def by_client(request, clientpk):
|
||||
agents = (
|
||||
Agent.objects.select_related("site")
|
||||
.filter(site__client_id=clientpk)
|
||||
.prefetch_related("agentchecks")
|
||||
.only(
|
||||
"pk",
|
||||
"hostname",
|
||||
"agent_id",
|
||||
"site",
|
||||
"monitoring_type",
|
||||
"description",
|
||||
"needs_reboot",
|
||||
"overdue_text_alert",
|
||||
"overdue_email_alert",
|
||||
"overdue_time",
|
||||
"offline_time",
|
||||
"last_seen",
|
||||
"boot_time",
|
||||
"logged_in_username",
|
||||
"last_logged_in_user",
|
||||
"time_zone",
|
||||
"maintenance_mode",
|
||||
)
|
||||
)
|
||||
ctx = {"default_tz": get_default_timezone()}
|
||||
return Response(AgentTableSerializer(agents, many=True, context=ctx).data)
|
||||
|
||||
|
||||
@api_view()
|
||||
def by_site(request, sitepk):
|
||||
agents = (
|
||||
Agent.objects.filter(site_id=sitepk)
|
||||
.select_related("site")
|
||||
.prefetch_related("agentchecks")
|
||||
.only(
|
||||
"pk",
|
||||
"hostname",
|
||||
"agent_id",
|
||||
"site",
|
||||
"monitoring_type",
|
||||
"description",
|
||||
"needs_reboot",
|
||||
"overdue_text_alert",
|
||||
"overdue_email_alert",
|
||||
"overdue_time",
|
||||
"offline_time",
|
||||
"last_seen",
|
||||
"boot_time",
|
||||
"logged_in_username",
|
||||
"last_logged_in_user",
|
||||
"time_zone",
|
||||
"maintenance_mode",
|
||||
)
|
||||
)
|
||||
ctx = {"default_tz": get_default_timezone()}
|
||||
return Response(AgentTableSerializer(agents, many=True, context=ctx).data)
|
||||
|
||||
|
||||
@api_view(["POST"])
|
||||
def overdue_action(request):
|
||||
agent = get_object_or_404(Agent, pk=request.data["pk"])
|
||||
|
|
|
@ -63,6 +63,7 @@ def dashboard_info(request):
|
|||
"show_community_scripts": request.user.show_community_scripts,
|
||||
"dbl_click_action": request.user.agent_dblclick_action,
|
||||
"default_agent_tbl_tab": request.user.default_agent_tbl_tab,
|
||||
"agents_per_page": request.user.agents_per_page,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ from rest_framework.decorators import (
|
|||
)
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from tacticalrmm.utils import notify_error
|
||||
|
||||
from agents.models import Agent
|
||||
from tacticalrmm.utils import notify_error
|
||||
|
||||
logger.configure(**settings.LOG_CONFIG)
|
||||
|
||||
|
|
|
@ -13,9 +13,11 @@
|
|||
row-key="id"
|
||||
binary-state-sort
|
||||
virtual-scroll
|
||||
:pagination.sync="pagination"
|
||||
:rows-per-page-options="[0]"
|
||||
:pagination.sync="agentPagination"
|
||||
:rows-per-page-options="[25, 50, 100, 200, 300, 500, 1000]"
|
||||
no-data-label="No Agents"
|
||||
rows-per-page-label="Agents per page:"
|
||||
@request="onRequest"
|
||||
>
|
||||
<!-- header slots -->
|
||||
<template v-slot:header-cell-smsalert="props">
|
||||
|
@ -413,7 +415,7 @@ import RunScript from "@/components/modals/agents/RunScript";
|
|||
|
||||
export default {
|
||||
name: "AgentTable",
|
||||
props: ["frame", "columns", "tab", "filter", "userName", "search", "visibleColumns"],
|
||||
props: ["frame", "columns", "tab", "filter", "userName", "search", "visibleColumns", "agentTblPagination"],
|
||||
components: {
|
||||
EditAgent,
|
||||
RebootLater,
|
||||
|
@ -425,11 +427,6 @@ export default {
|
|||
mixins: [mixins],
|
||||
data() {
|
||||
return {
|
||||
pagination: {
|
||||
rowsPerPage: 0,
|
||||
sortBy: "hostname",
|
||||
descending: false,
|
||||
},
|
||||
showSendCommand: false,
|
||||
showEditAgentModal: false,
|
||||
showRebootLaterModal: false,
|
||||
|
@ -441,6 +438,14 @@ export default {
|
|||
};
|
||||
},
|
||||
methods: {
|
||||
onRequest(props) {
|
||||
const { page, rowsPerPage, sortBy, descending } = props.pagination;
|
||||
this.agentTblPagination.page = page;
|
||||
this.agentTblPagination.rowsPerPage = rowsPerPage;
|
||||
this.agentTblPagination.sortBy = sortBy;
|
||||
this.agentTblPagination.descending = descending;
|
||||
this.$emit("refreshEdit");
|
||||
},
|
||||
filterTable(rows, terms, cols, cellValue) {
|
||||
const lowerTerms = terms ? terms.toLowerCase() : "";
|
||||
let advancedFilter = false;
|
||||
|
@ -759,6 +764,14 @@ export default {
|
|||
agentTableLoading() {
|
||||
return this.$store.state.agentTableLoading;
|
||||
},
|
||||
agentPagination: {
|
||||
get: function () {
|
||||
return this.agentTblPagination;
|
||||
},
|
||||
set: function (newVal) {
|
||||
this.$emit("agentPagChanged", newVal);
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -46,6 +46,11 @@
|
|||
class="col-4"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<div class="col-6">Agent table default records per page:</div>
|
||||
<div class="col-2"></div>
|
||||
<q-input v-model.number="agentsPerPage" type="number" filled style="max-width: 100px" />
|
||||
</q-card-section>
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
|
||||
|
@ -60,7 +65,6 @@
|
|||
|
||||
<script>
|
||||
import mixins from "@/mixins/mixins";
|
||||
import { mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
name: "UserPreferences",
|
||||
|
@ -69,6 +73,7 @@ export default {
|
|||
return {
|
||||
agentDblClickAction: "",
|
||||
defaultAgentTblTab: "",
|
||||
agentsPerPage: 50,
|
||||
tab: "ui",
|
||||
splitterModel: 20,
|
||||
agentDblClickOptions: [
|
||||
|
@ -106,6 +111,7 @@ export default {
|
|||
this.$axios.get("/core/dashinfo/").then(r => {
|
||||
this.agentDblClickAction = r.data.dbl_click_action;
|
||||
this.defaultAgentTblTab = r.data.default_agent_tbl_tab;
|
||||
this.agentsPerPage = r.data.agents_per_page;
|
||||
});
|
||||
},
|
||||
editUserPrefs() {
|
||||
|
@ -113,10 +119,12 @@ export default {
|
|||
userui: true,
|
||||
agent_dblclick_action: this.agentDblClickAction,
|
||||
default_agent_tbl_tab: this.defaultAgentTblTab,
|
||||
agents_per_page: this.agentsPerPage,
|
||||
};
|
||||
this.$axios.patch("/accounts/users/ui/", data).then(r => {
|
||||
this.notifySuccess("Preferences were saved!");
|
||||
this.$emit("edited");
|
||||
this.$emit("refresh");
|
||||
this.$emit("close");
|
||||
});
|
||||
},
|
||||
|
|
|
@ -215,9 +215,6 @@ export default function () {
|
|||
loadSites(context) {
|
||||
return axios.get("/clients/sites/");
|
||||
},
|
||||
loadAgents(context) {
|
||||
return axios.get("/agents/listagents/");
|
||||
},
|
||||
loadTree({ commit }) {
|
||||
axios.get("/clients/tree/").then(r => {
|
||||
|
||||
|
|
|
@ -195,6 +195,7 @@
|
|||
indicator-color="primary"
|
||||
align="left"
|
||||
narrow-indicator
|
||||
@input="tabChanged"
|
||||
>
|
||||
<q-tab name="server" icon="fas fa-server" label="Servers" />
|
||||
<q-tab name="workstation" icon="computer" label="Workstations" />
|
||||
|
@ -321,11 +322,13 @@
|
|||
:frame="frame"
|
||||
:columns="columns"
|
||||
:tab="tab"
|
||||
:filter="filteredAgents"
|
||||
:filter="frozenAgents"
|
||||
:userName="user"
|
||||
:search="search"
|
||||
:visibleColumns="visibleColumns"
|
||||
:agentTblPagination="agentTblPagination"
|
||||
@refreshEdit="refreshEntireSite"
|
||||
@agentPagChanged="setAgentTblPagination"
|
||||
/>
|
||||
</template>
|
||||
<template v-slot:separator>
|
||||
|
@ -363,13 +366,12 @@
|
|||
</q-dialog>
|
||||
<!-- user preferences modal -->
|
||||
<q-dialog v-model="showUserPreferencesModal">
|
||||
<UserPreferences @close="showUserPreferencesModal = false" @edited="getDashInfo" />
|
||||
<UserPreferences @close="showUserPreferencesModal = false" @edited="getDashInfo" @refresh="refreshEntireSite" />
|
||||
</q-dialog>
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
import { notifySuccessConfig, notifyErrorConfig } from "@/mixins/mixins";
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
|
@ -425,6 +427,13 @@ export default {
|
|||
filterRebootNeeded: false,
|
||||
currentTRMMVersion: null,
|
||||
showUserPreferencesModal: false,
|
||||
agentTblPagination: {
|
||||
rowsPerPage: 50,
|
||||
rowsNumber: null,
|
||||
sortBy: "hostname",
|
||||
descending: false,
|
||||
page: 1,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
name: "smsalert",
|
||||
|
@ -550,6 +559,16 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
tabChanged(val) {
|
||||
if (this.allClientsActive) {
|
||||
this.loadAllClients();
|
||||
} else {
|
||||
this.loadFrame(this.selectedTree, false);
|
||||
}
|
||||
},
|
||||
setAgentTblPagination(val) {
|
||||
this.agentTblPagination = val;
|
||||
},
|
||||
toggleDark(val) {
|
||||
this.$q.dark.set(val);
|
||||
this.$axios.patch("/accounts/users/ui/", { dark_mode: val });
|
||||
|
@ -578,23 +597,33 @@ export default {
|
|||
loadFrame(activenode, destroySub = true) {
|
||||
if (destroySub) this.$store.commit("destroySubTable");
|
||||
|
||||
let url, urlType, id;
|
||||
let execute = false;
|
||||
let urlType, id;
|
||||
let data = { pagination: this.agentTblPagination };
|
||||
|
||||
if (typeof activenode === "string") {
|
||||
urlType = activenode.split("|")[0];
|
||||
id = activenode.split("|")[1];
|
||||
|
||||
if (urlType === "Client") {
|
||||
url = `/agents/byclient/${id}/`;
|
||||
data.clientPK = id;
|
||||
execute = true;
|
||||
} else if (urlType === "Site") {
|
||||
url = `/agents/bysite/${id}/`;
|
||||
data.sitePK = id;
|
||||
execute = true;
|
||||
}
|
||||
|
||||
if (url) {
|
||||
if (execute) {
|
||||
this.$store.commit("AGENT_TABLE_LOADING", true);
|
||||
axios.get(url).then(r => {
|
||||
this.frame = r.data;
|
||||
this.$store.commit("AGENT_TABLE_LOADING", false);
|
||||
});
|
||||
// give time for vuex to set the tab, otherwise will always be 'server'
|
||||
setTimeout(() => {
|
||||
data.monType = this.tab;
|
||||
this.$axios.patch("/agents/listagents/", data).then(r => {
|
||||
this.frame = r.data.agents;
|
||||
this.agentTblPagination.rowsNumber = r.data.total;
|
||||
this.$store.commit("AGENT_TABLE_LOADING", false);
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -612,12 +641,18 @@ export default {
|
|||
},
|
||||
loadAllClients() {
|
||||
this.$store.commit("AGENT_TABLE_LOADING", true);
|
||||
axios.get("/agents/listagents/").then(r => {
|
||||
this.frame = r.data;
|
||||
//this.siteActive = "";
|
||||
//this.$store.commit("destroySubTable");
|
||||
this.$store.commit("AGENT_TABLE_LOADING", false);
|
||||
});
|
||||
// give time for vuex to set the tab, otherwise will always be 'server'
|
||||
setTimeout(() => {
|
||||
const data = {
|
||||
pagination: this.agentTblPagination,
|
||||
monType: this.tab,
|
||||
};
|
||||
this.$axios.patch("/agents/listagents/", data).then(r => {
|
||||
this.frame = r.data.agents;
|
||||
this.agentTblPagination.rowsNumber = r.data.total;
|
||||
this.$store.commit("AGENT_TABLE_LOADING", false);
|
||||
});
|
||||
}, 500);
|
||||
},
|
||||
showPolicyAdd(node) {
|
||||
if (node.children) {
|
||||
|
@ -709,13 +744,16 @@ export default {
|
|||
this.workstationOfflineCount = r.data.total_workstation_offline_count;
|
||||
});
|
||||
},
|
||||
getDashInfo(setDefaultTab = true) {
|
||||
getDashInfo(edited = true) {
|
||||
this.$store.dispatch("getDashInfo").then(r => {
|
||||
if (edited) {
|
||||
this.agentTblPagination.rowsPerPage = r.data.agents_per_page;
|
||||
this.$store.commit("SET_DEFAULT_AGENT_TBL_TAB", r.data.default_agent_tbl_tab);
|
||||
}
|
||||
this.darkMode = r.data.dark_mode;
|
||||
this.$q.dark.set(this.darkMode);
|
||||
this.currentTRMMVersion = r.data.trmm_version;
|
||||
this.$store.commit("SET_AGENT_DBLCLICK_ACTION", r.data.dbl_click_action);
|
||||
if (setDefaultTab) this.$store.commit("SET_DEFAULT_AGENT_TBL_TAB", r.data.default_agent_tbl_tab);
|
||||
this.$store.commit("setShowCommunityScripts", r.data.show_community_scripts);
|
||||
});
|
||||
},
|
||||
|
@ -809,13 +847,10 @@ export default {
|
|||
},
|
||||
},
|
||||
allClientsActive() {
|
||||
return this.selectedTree === "" ? true : false;
|
||||
return this.selectedTree === "";
|
||||
},
|
||||
filteredAgents() {
|
||||
if (this.tab === "mixed") {
|
||||
return Object.freeze(this.frame);
|
||||
}
|
||||
return Object.freeze(this.frame.filter(k => k.monitoring_type === this.tab));
|
||||
frozenAgents() {
|
||||
return Object.freeze(this.frame);
|
||||
},
|
||||
activeNode() {
|
||||
return {
|
||||
|
@ -841,13 +876,12 @@ export default {
|
|||
},
|
||||
created() {
|
||||
this.getDashInfo();
|
||||
this.getTree();
|
||||
this.$store.dispatch("getUpdatedSites");
|
||||
this.$store.dispatch("checkVer");
|
||||
this.getAgentCounts();
|
||||
this.getTree();
|
||||
},
|
||||
mounted() {
|
||||
this.loadFrame(this.activeNode);
|
||||
this.livePoll();
|
||||
},
|
||||
beforeDestroy() {
|
||||
|
|
Loading…
Reference in New Issue