From e7497a7d7a9a6f50a866f6a7f1713fcdc82c8e22 Mon Sep 17 00:00:00 2001 From: Luke Berndt Date: Sun, 19 Mar 2023 10:29:02 -0400 Subject: [PATCH] Import / Export Talkgroups is working --- admin/server/controllers/talkgroups.js | 7 ++--- admin/server/index.js | 24 ++++++++++----- admin/src/System/System.js | 41 ++++---------------------- admin/src/features/api/apiSlice.js | 23 ++++++++++++++- 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/admin/server/controllers/talkgroups.js b/admin/server/controllers/talkgroups.js index 27fc974..4077116 100644 --- a/admin/server/controllers/talkgroups.js +++ b/admin/server/controllers/talkgroups.js @@ -1,9 +1,7 @@ const Talkgroup = require("../models/talkgroup"); const System = require("../models/system"); const fs = require('fs-extra'); - -const crypto = require("crypto"); -var parse = require('csv-parse'); +const {parse} = require('csv-parse'); exports.isLoggedIn = function (req, res, next) { if (req.isAuthenticated()) return next(); @@ -148,7 +146,7 @@ async function csv_import(shortName, filename, callback) { //router.post("/tg_import/:shortName", isLoggedIn, upload.single('file'), function(req, res, next) { exports.importTalkgroups = function (req, res, next) { process.nextTick(async function () { - const system = System.findOne({ shortName: req.params.shortName.toLowerCase() }).catch(err => { + const system = await System.findOne({ shortName: req.params.shortName.toLowerCase() }).catch(err => { res.status(500); console.error("Error - importTalkgroups: " + err); res.json({ success: false, message: err }); @@ -174,6 +172,7 @@ exports.importTalkgroups = function (req, res, next) { return; } if (!req.file || req.file.size === 0) { + console.error("Error - File is bad. Size"); res.status(500); res.json({ success: false, message: "Please select a file." }); return; diff --git a/admin/server/index.js b/admin/server/index.js index 2335f75..24be240 100644 --- a/admin/server/index.js +++ b/admin/server/index.js @@ -128,7 +128,6 @@ function isAdmin(req, res, next) { } function isLoggedIn(req, res, next) { - console.log(req.body); if (req.isAuthenticated()) return next(); res.status(401).send({ success: false, @@ -136,6 +135,22 @@ function isLoggedIn(req, res, next) { }); }; +function uploadFile(req, res, next) { + const upload = multer({dest: 'uploads/'}).single('file'); + + upload(req, res, function (err) { + if (err instanceof multer.MulterError) { + console.error("Multer Error: " + err) + } else if (err) { + console.error(err); + // An unknown error occurred when uploading. + } + console.log("Things look good for Multer") + // Everything went fine. + next() + }) +} + // ------------------------------------------- configurePassport(app, passport) @@ -145,13 +160,8 @@ configureExpress(app, passport) app.use(express.static(path.join(__dirname, "public"))); app.get("") -//app.get("/permissions/:shortname", isOwner, permissions.fetchPermissions) -/*app.get("/permissions/:shortName", permissions.fetchPermissions); -app.delete("/permissions/:shortName/:permissionId", isAdmin, permissions.deletePermission); -app.post("/permissions/:shortName/:permissionId", isAdmin, permissions.updatePermission); -app.post("/permissions/:shortName", isAdmin, permissions.addPermission);*/ app.get("/talkgroups/:shortName", isLoggedIn, talkgroups.fetchTalkgroups) -app.post("/talkgroups/:shortName/import", isLoggedIn, upload.single('file'), talkgroups.importTalkgroups) +app.post("/talkgroups/:shortName/import", isLoggedIn, uploadFile, talkgroups.importTalkgroups) app.get("/talkgroups/:shortName/export", isLoggedIn, talkgroups.exportTalkgroups) app.post("/groups/:shortName/reorder", isLoggedIn, groups.reorderGroups); app.post("/groups/:shortName/:groupId?", isLoggedIn, groups.upsertGroup); diff --git a/admin/src/System/System.js b/admin/src/System/System.js index 8992917..004a93d 100644 --- a/admin/src/System/System.js +++ b/admin/src/System/System.js @@ -8,7 +8,7 @@ import UpdatePermissionModal from "../Permission/UpdatePermissionModalContainer. import AddPermissionModal from "../Permission/AddPermissionModalContainer.js"; import ErrorChart from "./ResponsiveErrorChart" import CallChart from "./ResponsiveCallChart" -import { useGetSystemsQuery, useGetTalkgroupsQuery, useGetGroupsQuery, useGetErrorsQuery, useDeleteGroupMutation, useCreateGroupMutation, useSaveGroupOrderMutation } from '../features/api/apiSlice' +import { useGetSystemsQuery, useGetTalkgroupsQuery, useGetGroupsQuery, useGetErrorsQuery, useDeleteGroupMutation, useCreateGroupMutation, useImportTalkgroupsMutation, useSaveGroupOrderMutation } from '../features/api/apiSlice' import { Button, Confirm, @@ -33,6 +33,7 @@ const System = (props) => { const { data: errorsData, isSuccess: isErrorsSuccess } = useGetErrorsQuery(shortName); const [deleteGroupAPI, { isLoading: isDeleting }] = useDeleteGroupMutation(); const [reorderGroupsAPI, { isLoading: isReordering }] = useSaveGroupOrderMutation(); + const [importTalkgroupsAPI, { isLoading: isImporting}] = useImportTalkgroupsMutation(); const [openSystemDeleteConfirm, setOpenSystemDeleteConfirm] = useState(false); const [openPermissionDeleteConfirm, setOpenPermissionDeleteConfirm] = useState(false); const [openMessage, setOpenMessage] = useState(false); @@ -185,44 +186,14 @@ const System = (props) => { setGroupVisible((state) => !state) } - - - const handleExport = () => { - /* this.props.talkgroupActions - .exportTalkgroups(this.props.system.shortName) - .then(requestMessage => { - if (requestMessage) { - // report to the user is there was a problem during registration - this.setState({ requestMessage }); - } - });*/ - } - const saveGroupOrder = async () => { await reorderGroupsAPI({shortName: shortName, order: {groupOrder: JSON.stringify(groupOrder)}}); - - /*const order = this.props.groups.map(x => x._id); - const data = { - groupOrder: JSON.stringify(order) - }; - this.props.groupActions - .saveGroupOrder(this.props.system.shortName, data) - .then(requestMessage => { - if (requestMessage) { - } - });*/ } - - const handleUpload = (file) => { - /*this.props.talkgroupActions - .importTalkgroups(this.props.system.shortName, file) - .then(requestMessage => { - if (requestMessage) { - // report to the user is there was a problem during registration - this.setState({ requestMessage }); - } - });*/ + const handleUpload = async (file) => { + const formData = new FormData(); + formData.append('file',file) + await importTalkgroupsAPI({shortName:shortName, file:formData}); } diff --git a/admin/src/features/api/apiSlice.js b/admin/src/features/api/apiSlice.js index 5a4d0dc..289c928 100644 --- a/admin/src/features/api/apiSlice.js +++ b/admin/src/features/api/apiSlice.js @@ -85,6 +85,27 @@ export const apiSlice = createApi({ //invalidatesTags: (result, error, group) => ['Group'], }), + importTalkgroups: builder.mutation({ + query: ({shortName,file}) => ({ + url: `${process.env.REACT_APP_ADMIN_SERVER}/talkgroups/${shortName}/import`, + method: 'POST', + credentials: "include", + body: file, + }), + + async onQueryStarted({shortName,file}, { dispatch, queryFulfilled }) { + try { + const { data: newTalkgroups } = await queryFulfilled; + const patchResult = dispatch( + apiSlice.util.updateQueryData('getTalkgroups', shortName, (talkgroups) => { + talkgroups.length = 0; // Clear your array + talkgroups.push(...newTalkgroups); + }) + ) + } catch { } + }, + //invalidatesTags: (result, error, group) => ['Group'], + }), getSystems: builder.query({ // The URL for the request is '/fakeApi/posts' query: () => ({ url: `/systems`, credentials: "include" }) @@ -94,4 +115,4 @@ export const apiSlice = createApi({ }) // Export the auto-generated hook for the `getPosts` query endpoint -export const { useGetGroupsQuery, useGetSystemsQuery, useGetTalkgroupsQuery, useGetErrorsQuery, useDeleteGroupMutation, useCreateGroupMutation, useSaveGroupOrderMutation, useUpdateGroupMutation } = apiSlice +export const { useGetGroupsQuery, useGetSystemsQuery, useGetTalkgroupsQuery, useGetErrorsQuery, useDeleteGroupMutation, useCreateGroupMutation, useSaveGroupOrderMutation, useUpdateGroupMutation, useImportTalkgroupsMutation } = apiSlice