diff --git a/assets/src/components/admin/admin_form.tsx b/assets/src/components/admin/admin_form.tsx index 7171a0842..c01aa84df 100644 --- a/assets/src/components/admin/admin_form.tsx +++ b/assets/src/components/admin/admin_form.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useRef } from "react"; -import { doSubmit } from "Util/admin"; +import { fetch } from "Util/admin"; const validateJson = (json) => { try { @@ -30,7 +30,7 @@ const AdminValidateControls = ({ const config = configRef.current.value; if (validateJson(config)) { const dataToSubmit = { config }; - doSubmit(validatePath, dataToSubmit).then(validateCallback); + fetch.post(validatePath, dataToSubmit).then(validateCallback); } else { alert("JSON is invalid!"); } @@ -65,7 +65,7 @@ const AdminConfirmControls = ({ const confirmFn = () => { const config = configRef.current.value; const dataToSubmit = { config }; - doSubmit(confirmPath, dataToSubmit).then(confirmCallback); + fetch.post(confirmPath, dataToSubmit).then(confirmCallback); }; return ( diff --git a/assets/src/components/admin/admin_image_manager.tsx b/assets/src/components/admin/admin_image_manager.tsx index a65f2c762..26a04f9dd 100644 --- a/assets/src/components/admin/admin_image_manager.tsx +++ b/assets/src/components/admin/admin_image_manager.tsx @@ -1,23 +1,17 @@ import React, { useCallback, useEffect, useState } from "react"; import { useDropzone } from "react-dropzone"; import _ from "lodash"; -import getCsrfToken from "Util/csrf"; + +import { fetch } from "Util/admin"; interface FileWithPreview extends File { preview: string; } -const fetchWithCsrf = (resource: RequestInfo, init: RequestInit = {}) => { - return fetch(resource, { - ...init, - headers: { ...(init?.headers || {}), "x-csrf-token": getCsrfToken() }, - credentials: "include", - }); -}; - const fetchImageFilenames = async () => { - const response = await fetchWithCsrf("/api/admin/image_filenames"); - const { image_filenames: imageFilenames } = await response.json(); + const { image_filenames: imageFilenames } = await fetch.get( + "/api/admin/image_filenames", + ); return _.sortBy(imageFilenames); }; @@ -88,12 +82,8 @@ const ImageUpload = (): JSX.Element => { formData.append("image", stagedImageUpload, stagedImageUpload.name); try { - const response = await fetchWithCsrf("/api/admin/image", { - method: "POST", - body: formData, - }); + const result = await fetch.post("/api/admin/image", formData); - const result = await response.json(); if (result.success) { alert(`Success. Image has been uploaded as "${result.uploaded_name}".`); location.reload(); @@ -166,12 +156,10 @@ const ImageManager = ({ imageFilenames }): JSX.Element => { setIsDeleting(true); try { - const response = await fetchWithCsrf( + const result = await fetch.delete( `/api/admin/image/${selectedFilename}`, - { method: "DELETE" }, ); - const result = await response.json(); if (result.success) { alert(`Success. "${selectedFilename}" has been deleted.`); location.reload(); diff --git a/assets/src/components/admin/admin_screen_config_form.tsx b/assets/src/components/admin/admin_screen_config_form.tsx index 3a6a0e569..9808e542e 100644 --- a/assets/src/components/admin/admin_screen_config_form.tsx +++ b/assets/src/components/admin/admin_screen_config_form.tsx @@ -2,13 +2,13 @@ import React from "react"; import _ from "lodash"; import AdminForm from "Components/admin/admin_form"; +import { fetch } from "Util/admin"; const fetchConfig = async () => { - const result = await fetch("/api/admin/"); - const resultJson = await result.json(); + const { config } = await fetch.get("/api/admin"); // This sorts the entries alphanumerically by screen ID, and otherwise leaves the config alone. - const screens = _.chain(JSON.parse(resultJson.config).screens) + const screens = _.chain(JSON.parse(config).screens) .toPairs() .sortBy(([screenId, _screenData]) => screenId) .fromPairs() diff --git a/assets/src/components/admin/admin_table.tsx b/assets/src/components/admin/admin_table.tsx index c0d47cc94..0b56179e0 100644 --- a/assets/src/components/admin/admin_table.tsx +++ b/assets/src/components/admin/admin_table.tsx @@ -3,7 +3,7 @@ import { useTable, useFilters, useRowSelect } from "react-table"; import _ from "lodash"; import weakKey from "weak-key"; -import { doSubmit } from "Util/admin"; +import { fetch } from "Util/admin"; import { IndeterminateCheckbox } from "Components/admin/admin_cells"; import AddModal from "Components/admin/admin_add_modal"; import EditModal from "Components/admin/admin_edit_modal"; @@ -157,7 +157,7 @@ const dataToConfig = (data) => { const doValidate = async (data, onValidate) => { const config = dataToConfig(data); const dataToSubmit = { config: JSON.stringify(config, null, 2) }; - const result = await doSubmit(VALIDATE_PATH, dataToSubmit); + const result = await fetch.post(VALIDATE_PATH, dataToSubmit); const validatedConfig = await configToData(result.config); onValidate(validatedConfig); }; @@ -165,7 +165,7 @@ const doValidate = async (data, onValidate) => { const doConfirm = async (data, setEditable) => { const config = dataToConfig(data); const dataToSubmit = { config: JSON.stringify(config, null, 2) }; - const result = await doSubmit(CONFIRM_PATH, dataToSubmit); + const result = await fetch.post(CONFIRM_PATH, dataToSubmit); if (result.success === true) { alert("Config updated successfully"); window.location.reload(); @@ -182,7 +182,7 @@ const doRefresh = async (data, selectedRowIds) => { const selectedRows = _.filter(data, (_row, i) => selectedRowIds[i]); const selectedScreenIds = _.map(selectedRows, ({ id }) => id); const dataToSubmit = { screen_ids: selectedScreenIds }; - const result = await doSubmit(REFRESH_PATH, dataToSubmit); + const result = await fetch.post(REFRESH_PATH, dataToSubmit); if (result.success === true) { alert("Refresh scheduled successfully"); window.location.reload(); @@ -269,10 +269,8 @@ const AdminTable = ({ columns, dataFilter }): JSX.Element => { // Fetch config on page load const fetchConfig = async () => { - const result = await fetch("/api/admin/"); - const json = await result.json(); - const config = JSON.parse(json.config); - setData(configToData(config)); + const { config } = await fetch.get("/api/admin"); + setData(configToData(JSON.parse(config))); }; useEffect(() => { diff --git a/assets/src/components/admin/devops.tsx b/assets/src/components/admin/devops.tsx index 25ac175af..a0a1b58b1 100644 --- a/assets/src/components/admin/devops.tsx +++ b/assets/src/components/admin/devops.tsx @@ -1,11 +1,13 @@ import React, { useState, useEffect } from "react"; -import { doSubmit } from "Util/admin"; +import { fetch } from "Util/admin"; const DEVOPS_PATH = "/api/admin/devops"; const updateDisabledModes = async (disabledModes) => { - const result = await doSubmit(DEVOPS_PATH, { disabled_modes: disabledModes }); + const result = await fetch.post(DEVOPS_PATH, { + disabled_modes: disabledModes, + }); if (result.success !== true) { alert("Config update failed"); } @@ -27,9 +29,9 @@ const Devops = () => { const [loaded, setLoaded] = useState(false); useEffect(() => { - fetch("/api/admin/") - .then((result) => result.json()) - .then((json) => JSON.parse(json.config)) + fetch + .get("/api/admin") + .then((response) => JSON.parse(response.config)) .then((config) => config.devops.disabled_modes) .then(setDisabledModes) .then((_) => setLoaded(true)) diff --git a/assets/src/components/admin/inspector.tsx b/assets/src/components/admin/inspector.tsx index f2f2c93fc..d156620b7 100644 --- a/assets/src/components/admin/inspector.tsx +++ b/assets/src/components/admin/inspector.tsx @@ -12,7 +12,7 @@ import AdminForm from "./admin_form"; import { type AudioConfig } from "Components/v2/screen_container"; -import { doSubmit, type Config, type Screen } from "Util/admin"; +import { fetch, type Config, type Screen } from "Util/admin"; import { type Message, INSPECTOR_FRAME_NAME, @@ -46,11 +46,10 @@ const Inspector: ComponentType = () => { const [config, setConfig] = useState(null); useEffect(() => { - fetch("/api/admin") - .then((result) => result.json()) - .then((json) => JSON.parse(json.config)) - .then((config) => setConfig(config)) - .catch(() => alert("Failed to load config!")); + fetch + .get("/api/admin") + .then((response) => JSON.parse(response.config)) + .then((config) => setConfig(config)); }, []); const { search } = useLocation(); @@ -238,7 +237,8 @@ const ConfigControls: ComponentType<{ screen: ScreenWithId }> = ({ disabled={isRequestingReload} onClick={() => { setIsRequestingReload(true); - doSubmit("/api/admin/refresh", { screen_ids: [screen.id] }) + fetch + .post("/api/admin/refresh", { screen_ids: [screen.id] }) .then(() => alert("Scheduled a reload for this screen.")) .finally(() => setIsRequestingReload(false)); }} @@ -415,10 +415,7 @@ const AudioControls: ComponentType<{ screen: ScreenWithId }> = ({ screen }) => {