diff --git a/api/tacticalrmm/agents/urls.py b/api/tacticalrmm/agents/urls.py index 34451fc6..d4d488ff 100644 --- a/api/tacticalrmm/agents/urls.py +++ b/api/tacticalrmm/agents/urls.py @@ -30,5 +30,4 @@ urlpatterns = [ path("agent_counts/", views.agent_counts), path("maintenance/", views.agent_maintenance), path("/wmi/", views.WMI.as_view()), - path("customfields/", views.AgentCustomFields.as_view()), ] diff --git a/api/tacticalrmm/agents/views.py b/api/tacticalrmm/agents/views.py index f32ca6de..6bbe8f3a 100644 --- a/api/tacticalrmm/agents/views.py +++ b/api/tacticalrmm/agents/views.py @@ -14,7 +14,7 @@ from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework.views import APIView -from core.models import CoreSettings +from core.models import CoreSettings, CustomField from logs.models import AuditLog, PendingAction from scripts.models import Script from scripts.tasks import handle_bulk_command_task, handle_bulk_script_task @@ -104,6 +104,37 @@ def edit_agent(request): p_serializer.is_valid(raise_exception=True) p_serializer.save() + if "custom_fields" in request.data.keys(): + + for field in request.data["custom_fields"]: + + # get custom field for validation + obj = CustomField.objects.get(pk=field["field"]) + + if obj.default_value and field.value == obj.default_value: + continue + + custom_field = { + "value": field["value"], + "field": field["field"], + "agent": agent.id, + } + if AgentCustomField.objects.filter( + field=field["field"], agent=agent.id + ): + value = AgentCustomField.objects.get( + field=field["field"], agent=agent.id + ) + serializer = AgentCustomFieldSerializer( + instance=value, data=custom_field + ) + serializer.is_valid(raise_exception=True) + serializer.save() + else: + serializer = AgentCustomFieldSerializer(data=custom_field) + serializer.is_valid(raise_exception=True) + serializer.save() + return Response("ok") @@ -726,36 +757,3 @@ class WMI(APIView): if r != "ok": return notify_error("Unable to contact the agent") return Response("ok") - - -class AgentCustomFields(APIView): - def post(self, request): - - if "custom_fields" in request.data.keys(): - - for field in request.data["custom_fields"]: - - custom_field = { - "value": field["value"], - "field": field["field"], - "agent": field["model"], - } - if AgentCustomField.objects.filter( - field=field["field"], agent=field["model"] - ): - value = AgentCustomField.objects.get( - field=field["field"], agent=field["model"] - ) - serializer = AgentCustomFieldSerializer( - instance=value, data=custom_field, partial=True - ) - serializer.is_valid(raise_exception=True) - serializer.save() - else: - serializer = AgentCustomFieldSerializer(data=custom_field) - serializer.is_valid(raise_exception=True) - serializer.save() - else: - return notify_error("The request is invalid") - - return Response("ok") \ No newline at end of file diff --git a/api/tacticalrmm/clients/urls.py b/api/tacticalrmm/clients/urls.py index 8017e6ee..00b769f9 100644 --- a/api/tacticalrmm/clients/urls.py +++ b/api/tacticalrmm/clients/urls.py @@ -13,6 +13,4 @@ urlpatterns = [ path("deployments/", views.AgentDeployment.as_view()), path("/deployment/", views.AgentDeployment.as_view()), path("/deploy/", views.GenerateAgent.as_view()), - path("customfields/", views.ClientCustomFields.as_view()), - path("sites/customfields/", views.SiteCustomFields.as_view()), ] diff --git a/api/tacticalrmm/clients/views.py b/api/tacticalrmm/clients/views.py index 797493d1..b021f12e 100644 --- a/api/tacticalrmm/clients/views.py +++ b/api/tacticalrmm/clients/views.py @@ -11,7 +11,7 @@ from rest_framework.response import Response from rest_framework.views import APIView from agents.models import Agent -from core.models import CoreSettings +from core.models import CoreSettings, CustomField from tacticalrmm.utils import generate_installer_exe, notify_error from .models import Client, Deployment, Site, ClientCustomField, SiteCustomField @@ -55,6 +55,18 @@ class GetAddClients(APIView): core.default_time_zone = request.data["timezone"] core.save(update_fields=["default_time_zone"]) + # save custom fields + if "custom_fields" in request.data.keys(): + for field in request.data["custom_fields"]: + custom_field = { + "value": field["value"], + "field": field["field"], + "client": client.id, + } + serializer = ClientCustomFieldSerializer(data=custom_field) + serializer.is_valid(raise_exception=True) + serializer.save() + return Response(f"{client} was added!") @@ -70,6 +82,35 @@ class GetUpdateClient(APIView): serializer.is_valid(raise_exception=True) serializer.save() + # update custom fields + if "custom_fields" in request.data.keys(): + for field in request.data["custom_fields"]: + + # get custom field for validation + obj = CustomField.objects.get(pk=field["field"]) + + if obj.default_value and field.value == obj.default_value: + continue + + custom_field = { + "value": field["value"], + "field": field["field"], + "client": pk, + } + if ClientCustomField.objects.filter(field=field["field"], client=pk): + value = ClientCustomField.objects.get( + field=field["field"], client=pk + ) + serializer = ClientCustomFieldSerializer( + instance=value, data=custom_field + ) + serializer.is_valid(raise_exception=True) + serializer.save() + else: + serializer = ClientCustomFieldSerializer(data=custom_field) + serializer.is_valid(raise_exception=True) + serializer.save() + return Response("The Client was updated") @@ -107,9 +148,24 @@ class GetAddSites(APIView): return Response(SiteSerializer(sites, many=True).data) def post(self, request): - serializer = SiteSerializer(data=request.data) + serializer = SiteSerializer(data=request.data["site"]) serializer.is_valid(raise_exception=True) - serializer.save() + site = serializer.save() + + # save custom fields + if "custom_fields" in request.data.keys(): + + for field in request.data["custom_fields"]: + + custom_field = { + "value": field["value"], + "field": field["field"], + "site": site.id, + } + + serializer = SiteCustomFieldSerializer(data=custom_field) + serializer.is_valid(raise_exception=True) + serializer.save() return Response("ok") @@ -123,13 +179,44 @@ class GetUpdateSite(APIView): site = get_object_or_404(Site, pk=pk) - if site.client.id != request.data["client"] and site.client.sites.count() == 1: + if ( + site.client.id != request.data["site"]["client"] + and site.client.sites.count() == 1 + ): return notify_error("A client must have at least one site") - serializer = SiteSerializer(instance=site, data=request.data, partial=True) + serializer = SiteSerializer(instance=site, data=request.data["site"]) serializer.is_valid(raise_exception=True) serializer.save() + # update custom field + if "custom_fields" in request.data.keys(): + + for field in request.data["custom_fields"]: + + # get custom field for validation + obj = CustomField.objects.get(pk=field["field"]) + + if obj.default_value and field.value == obj.default_value: + continue + + custom_field = { + "value": field["value"], + "field": field["field"], + "site": pk, + } + if SiteCustomField.objects.filter(field=field["field"], site=pk): + value = SiteCustomField.objects.get(field=field["field"], site=pk) + serializer = SiteCustomFieldSerializer( + instance=value, data=custom_field, partial=True + ) + serializer.is_valid(raise_exception=True) + serializer.save() + else: + serializer = SiteCustomFieldSerializer(data=custom_field) + serializer.is_valid(raise_exception=True) + serializer.save() + return Response("ok") @@ -243,67 +330,3 @@ class GenerateAgent(APIView): download_url=settings.DL_64 if d.arch == "64" else settings.DL_32, token=d.token_key, ) - - -class ClientCustomFields(APIView): - def post(self, request): - - if "custom_fields" in request.data.keys(): - for field in request.data["custom_fields"]: - custom_field = { - "value": field["value"], - "field": field["field"], - "client": field["model"], - } - if ClientCustomField.objects.filter( - field=field["field"], client=field["model"] - ): - value = ClientCustomField.objects.get( - field=field["field"], client=field["model"] - ) - serializer = ClientCustomFieldSerializer( - instance=value, data=custom_field, partial=True - ) - serializer.is_valid(raise_exception=True) - serializer.save() - else: - serializer = ClientCustomFieldSerializer(data=custom_field) - serializer.is_valid(raise_exception=True) - serializer.save() - else: - return notify_error("The request is invalid") - - return Response("ok") - - -class SiteCustomFields(APIView): - def post(self, request): - - if "custom_fields" in request.data.keys(): - - for field in request.data["custom_fields"]: - - custom_field = { - "value": field["value"], - "field": field["field"], - "site": field["model"], - } - if SiteCustomField.objects.filter( - field=field["field"], site=field["model"] - ): - value = SiteCustomField.objects.get( - field=field["field"], site=field["model"] - ) - serializer = SiteCustomFieldSerializer( - instance=value, data=custom_field, partial=True - ) - serializer.is_valid(raise_exception=True) - serializer.save() - else: - serializer = SiteCustomFieldSerializer(data=custom_field) - serializer.is_valid(raise_exception=True) - serializer.save() - else: - return notify_error("The request is invalid") - - return Response("ok") diff --git a/web/src/components/modals/agents/EditAgent.vue b/web/src/components/modals/agents/EditAgent.vue index 8761ef28..6ecf1ff2 100644 --- a/web/src/components/modals/agents/EditAgent.vue +++ b/web/src/components/modals/agents/EditAgent.vue @@ -233,24 +233,17 @@ export default { } this.$axios - .patch("/agents/editagent/", this.agent) + .patch("/agents/editagent/", { + ...this.agent, + custom_fields: this.formatCustomFields(this.customFields, this.custom_fields), + }) .then(r => { - this.saveCustomFields(this.agent.id) this.$emit("close"); this.$emit("edited"); this.notifySuccess("Agent was edited!"); }) .catch(() => this.notifyError("Something went wrong")); }, - saveCustomFields(pk = None) { - this.$axios - .post(`/agents/customfields/`, { - custom_fields: this.formatCustomFields(this.customFields, this.custom_fields, pk), - }) - .catch(e => { - console.log({ e }); - }); - }, }, computed: { ...mapGetters(["selectedAgentPk"]), diff --git a/web/src/components/modals/clients/ClientsForm.vue b/web/src/components/modals/clients/ClientsForm.vue index dac02549..4165f443 100644 --- a/web/src/components/modals/clients/ClientsForm.vue +++ b/web/src/components/modals/clients/ClientsForm.vue @@ -81,13 +81,14 @@ export default { }, addClient() { this.$q.loading.show(); + const data = { + client: this.localClient, + site: this.site, + custom_fields: this.formatCustomFields(this.customFields, this.custom_fields), + }; this.$axios - .post("/clients/clients/", { - site: this.site, - client: this.localClient, - }) + .post("/clients/clients/", data) .then(r => { - this.saveCustomFields(); this.refreshDashboardTree(); this.$q.loading.hide(); this.onOk(); @@ -104,11 +105,14 @@ export default { }, editClient() { this.$q.loading.show(); + const data = { + client: this.localClient, + custom_fields: this.formatCustomFields(this.customFields, this.custom_fields), + }; this.$axios - .put(`/clients/${this.client.id}/client/`, this.localClient) + .put(`/clients/${this.client.id}/client/`, data) .then(r => { - this.saveCustomFields(this.client.id); this.refreshDashboardTree(); this.onOk(); this.$q.loading.hide(); @@ -116,7 +120,6 @@ export default { }) .catch(e => { this.$q.loading.hide(); - console.log({ e }); if (e.response.data.name) { this.notifyError(e.response.data.name); } else { @@ -144,15 +147,6 @@ export default { this.$q.loading.hide(); }); }, - saveCustomFields(pk = None) { - this.$axios - .post(`/clients/customfields/`, { - custom_fields: this.formatCustomFields(this.customFields, this.custom_fields, pk), - }) - .catch(e => { - console.log({ e }); - }); - }, refreshDashboardTree() { this.$store.dispatch("loadTree"); this.$store.dispatch("getUpdatedSites"); diff --git a/web/src/components/modals/clients/SitesForm.vue b/web/src/components/modals/clients/SitesForm.vue index 811651c2..41ef8ea2 100644 --- a/web/src/components/modals/clients/SitesForm.vue +++ b/web/src/components/modals/clients/SitesForm.vue @@ -86,10 +86,13 @@ export default { }, addSite() { this.$q.loading.show(); + const data = { + site: this.localSite, + custom_fields: this.formatCustomFields(this.customFields, this.custom_fields), + }; this.$axios - .post("/clients/sites/", this.localSite) + .post("/clients/sites/", data) .then(r => { - this.saveCustomFields(); this.refreshDashboardTree(); this.$q.loading.hide(); this.onOk(); @@ -106,10 +109,13 @@ export default { }, editSite() { this.$q.loading.show(); + const data = { + site: this.localSite, + custom_fields: this.formatCustomFields(this.customFields, this.custom_fields), + }; this.$axios - .put(`/clients/sites/${this.site.id}/`, this.localSite) + .put(`/clients/sites/${this.site.id}/`, data) .then(r => { - this.saveCustomFields(this.site.id); this.refreshDashboardTree(); this.onOk(); this.$q.loading.hide(); @@ -156,15 +162,6 @@ export default { }); }); }, - saveCustomFields(pk = None) { - this.$axios - .post(`/clients/sites/customfields/`, { - custom_fields: this.formatCustomFields(this.customFields, this.custom_fields, pk), - }) - .catch(e => { - console.log({ e }); - }); - }, show() { this.$refs.dialog.show(); }, diff --git a/web/src/mixins/mixins.js b/web/src/mixins/mixins.js index 4b90977a..25919edc 100644 --- a/web/src/mixins/mixins.js +++ b/web/src/mixins/mixins.js @@ -147,18 +147,14 @@ export default { this.notifyError("There was an issue getting Custom Fields") }) }, - formatCustomFields(fields, values, pk) { + formatCustomFields(fields, values) { let tempArray = [] for (let field of fields) { - const value = values[field.name] - if (value !== field.default_value) { - let obj = { value: value, field: field.id } - if (!!pk) obj.model = pk - tempArray.push(obj) - } + let obj = { value: values[field.name], field: field.id } + tempArray.push(obj) + } - console.log(tempArray) return tempArray },