From 6607d5253928026854ac9ea735959dc4dc4983eb Mon Sep 17 00:00:00 2001 From: Charles Date: Tue, 28 Sep 2021 14:26:59 -0400 Subject: [PATCH 1/2] System page now displaying certs --- package-lock.json | 18 +- package.json | 4 +- public/locales/de/translation.json | 2 +- public/locales/en/translation.json | 2 +- public/locales/es/translation.json | 2 +- public/locales/fr/translation.json | 2 +- public/locales/pt/translation.json | 2 +- src/pages/SystemPage/index.js | 327 +++++++++++++++++++---------- 8 files changed, 231 insertions(+), 128 deletions(-) diff --git a/package-lock.json b/package-lock.json index b0e104a..24a170c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ucentral-client", - "version": "2.2.1", + "version": "2.2.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ucentral-client", - "version": "2.2.1", + "version": "2.2.2", "dependencies": { "@coreui/coreui": "^3.4.0", "@coreui/icons": "^2.0.1", @@ -32,7 +32,7 @@ "react-tooltip": "^4.2.21", "react-widgets": "^5.1.1", "sass": "^1.35.1", - "ucentral-libs": "^0.9.39", + "ucentral-libs": "^0.9.41", "uuid": "^8.3.2" }, "devDependencies": { @@ -14812,9 +14812,9 @@ } }, "node_modules/ucentral-libs": { - "version": "0.9.39", - "resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-0.9.39.tgz", - "integrity": "sha512-BGsT0tdOyJUNNIjD6y1gWATcyShhR/2Qik77FqF9m9efiLEbz7MiH+8IOxnup8X6gFt6nyTNqPZIzbXYuw48og==", + "version": "0.9.41", + "resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-0.9.41.tgz", + "integrity": "sha512-TXcxnZk9ornuaIN+vtRVJ/U3d5Dh76l6r3suEd/aLGlXvgW9iUwSqgBkA5kj/uV0wJXrZqxIr+hVsFndYvmtQQ==", "dependencies": { "@coreui/coreui": "^3.4.0", "@coreui/icons": "^2.0.1", @@ -27653,9 +27653,9 @@ } }, "ucentral-libs": { - "version": "0.9.39", - "resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-0.9.39.tgz", - "integrity": "sha512-BGsT0tdOyJUNNIjD6y1gWATcyShhR/2Qik77FqF9m9efiLEbz7MiH+8IOxnup8X6gFt6nyTNqPZIzbXYuw48og==", + "version": "0.9.41", + "resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-0.9.41.tgz", + "integrity": "sha512-TXcxnZk9ornuaIN+vtRVJ/U3d5Dh76l6r3suEd/aLGlXvgW9iUwSqgBkA5kj/uV0wJXrZqxIr+hVsFndYvmtQQ==", "requires": { "@coreui/coreui": "^3.4.0", "@coreui/icons": "^2.0.1", diff --git a/package.json b/package.json index 5e19459..fd6c566 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ucentral-client", - "version": "2.2.1", + "version": "2.2.2", "dependencies": { "@coreui/coreui": "^3.4.0", "@coreui/icons": "^2.0.1", @@ -26,7 +26,7 @@ "react-tooltip": "^4.2.21", "react-widgets": "^5.1.1", "sass": "^1.35.1", - "ucentral-libs": "^0.9.39", + "ucentral-libs": "^0.9.41", "uuid": "^8.3.2" }, "main": "index.js", diff --git a/public/locales/de/translation.json b/public/locales/de/translation.json index a3d45ab..035588c 100644 --- a/public/locales/de/translation.json +++ b/public/locales/de/translation.json @@ -468,7 +468,7 @@ "os": "Betriebssystem", "processors": "Prozessoren", "reload": "Neu laden", - "reload_subsystems": "Subsysteme neu laden", + "reload_subsystems": "Subsysteme", "subsystems": "Subsysteme", "success_reload": "Reload-Befehl erfolgreich gesendet!" }, diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 838fb20..345ea3f 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -468,7 +468,7 @@ "os": "Operation System", "processors": "Processors", "reload": "Reload", - "reload_subsystems": "Reload Subsystems", + "reload_subsystems": "Reload", "subsystems": "Subsystems", "success_reload": "Reload command successfully submitted!" }, diff --git a/public/locales/es/translation.json b/public/locales/es/translation.json index 89fc458..65c9bf6 100644 --- a/public/locales/es/translation.json +++ b/public/locales/es/translation.json @@ -468,7 +468,7 @@ "os": "sistema operativo", "processors": "Procesadores", "reload": "Recargar", - "reload_subsystems": "Recargar subsistemas", + "reload_subsystems": "Recargar", "subsystems": "Subsistemas", "success_reload": "¡El comando de recarga se envió correctamente!" }, diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json index f7af7dd..de8c617 100644 --- a/public/locales/fr/translation.json +++ b/public/locales/fr/translation.json @@ -468,7 +468,7 @@ "os": "le système d'exploitation", "processors": "Processeurs", "reload": "Recharger", - "reload_subsystems": "Recharger les sous-systèmes", + "reload_subsystems": "Recharger", "subsystems": "Sous-systèmes", "success_reload": "Recharger la commande soumise avec succès !" }, diff --git a/public/locales/pt/translation.json b/public/locales/pt/translation.json index 9cefbf8..a926e17 100644 --- a/public/locales/pt/translation.json +++ b/public/locales/pt/translation.json @@ -468,7 +468,7 @@ "os": "Sistema Operacional", "processors": "Processadores", "reload": "Recarregar", - "reload_subsystems": "Recarregar subsistemas", + "reload_subsystems": "Recarregar", "subsystems": "Subsistemas", "success_reload": "Comando de recarregamento enviado com sucesso!" }, diff --git a/src/pages/SystemPage/index.js b/src/pages/SystemPage/index.js index 5124164..d792054 100644 --- a/src/pages/SystemPage/index.js +++ b/src/pages/SystemPage/index.js @@ -1,30 +1,88 @@ import React, { useState, useEffect } from 'react'; -import { useTranslation } from 'react-i18next'; -import { ApiStatusCard, useAuth, useToast } from 'ucentral-libs'; -import { v4 as createUuid } from 'uuid'; +import PropTypes from 'prop-types'; +import { CModal, CModalHeader, CModalTitle, CModalBody, CButton, CPopover } from '@coreui/react'; +import CIcon from '@coreui/icons-react'; +import { cilX, cilSave } from '@coreui/icons'; +import { useFormFields, useAuth, useToast, useEntity, EditInventoryTagForm } from 'ucentral-libs'; import axiosInstance from 'utils/axiosInstance'; -import { CRow, CCol } from '@coreui/react'; -import { prettyDate, secondsToDetailed } from 'utils/helper'; +import { useTranslation } from 'react-i18next'; -const SystemPage = () => { +const initialForm = { + entity: { + value: '', + error: false, + hidden: false, + ignore: true, + }, + serialNumber: { + value: '', + error: false, + required: true, + regex: '^[a-fA-F0-9]+$', + length: 12, + ignore: true, + }, + name: { + value: '', + error: false, + required: true, + }, + description: { + value: '', + error: false, + }, + deviceType: { + value: '', + error: false, + required: true, + }, + rrm: { + value: 'inherit', + error: false, + required: true, + }, + deviceConfiguration: { + value: '', + uuid: '', + error: false, + ignore: true, + }, + venue: { + value: '', + error: false, + }, + notes: { + value: [], + error: false, + ignore: true, + }, +}; + +const EditTagModal = ({ show, toggle, tagSerialNumber, refreshTable }) => { const { t } = useTranslation(); const { currentToken, endpoints } = useAuth(); + const { deviceTypes } = useEntity(); const { addToast } = useToast(); - const [endpointsInfo, setEndpointsInfo] = useState([]); + const [fields, updateFieldWithId, updateField, setFormFields] = useFormFields(initialForm); + const [loading, setLoading] = useState(false); + const [tag, setTag] = useState({}); - const getSystemInfo = async (key, endpoint) => { - const systemInfo = { - title: key, - endpoint, - hostname: t('common.unknown'), - os: t('common.unknown'), - processors: t('common.unknown'), - uptime: t('common.unknown'), - version: t('common.unknown'), - start: t('common.unknown'), - subsystems: [], - }; + const validation = () => { + let success = true; + for (const [key, field] of Object.entries(fields)) { + if (field.required && field.value === '') { + updateField(key, { error: true }); + success = false; + break; + } + } + + return success; + }; + + const getTag = () => { + setLoading(true); const options = { headers: { Accept: 'application/json', @@ -32,42 +90,91 @@ const SystemPage = () => { }, }; - const getInfo = axiosInstance.get(`${endpoint}/api/v1/system?command=info`, options); - const getSubsystems = axiosInstance.post( - `${endpoint}/api/v1/system`, - { command: 'getsubsystemnames' }, - options, - ); + axiosInstance + .get(`${endpoints.owprov}/api/v1/inventory/${tagSerialNumber}`, options) + .then((response) => { + const newFields = fields; + for (const [key] of Object.entries(newFields)) { + if (response.data[key] !== undefined) { + if (key === 'deviceConfiguration') + newFields.deviceConfiguration = { value: '', uuid: response.data[key] }; + else if (key === 'rrm') + newFields[key].value = response.data[key] === '' ? 'inherit' : response.data[key]; + else newFields[key].value = response.data[key]; + } + } + setTag(response.data); + setFormFields({ ...newFields }); - return Promise.all([getInfo, getSubsystems]) - .then(([newInfo, newSubs]) => { - systemInfo.uptime = secondsToDetailed( - newInfo.data.uptime, - t('common.day'), - t('common.days'), - t('common.hour'), - t('common.hours'), - t('common.minute'), - t('common.minutes'), - t('common.second'), - t('common.seconds'), - ); - systemInfo.hostname = newInfo.data.hostname; - systemInfo.os = newInfo.data.os; - systemInfo.processors = newInfo.data.processors; - systemInfo.version = newInfo.data.version; - systemInfo.start = prettyDate(newInfo.data.start); - systemInfo.subsystems = newSubs.data.list.sort((a, b) => { - if (a < b) return -1; - if (a > b) return 1; - return 0; - }); - return systemInfo; + if (response.data.deviceConfiguration !== '') { + return axiosInstance.get( + `${endpoints.owprov}/api/v1/configurations/${response.data.deviceConfiguration}`, + options, + ); + } + return null; }) - .catch(() => systemInfo); + .then((response) => { + if (response) + updateField('deviceConfiguration', { value: response.data.name, uuid: response.data.id }); + }) + .catch(() => { + throw new Error('Error while fetching entity for edit'); + }) + .finally(() => { + setLoading(false); + }); }; - const reload = (subsystems, endpoint) => { + const editTag = () => { + if (validation()) { + setLoading(true); + const options = { + headers: { + Accept: 'application/json', + Authorization: `Bearer ${currentToken}`, + }, + }; + + const parameters = {}; + + for (const [key, field] of Object.entries(fields)) { + if (!field.ignore) { + if (tag[key] !== field.value) { + parameters[key] = field.value; + } + } + } + + axiosInstance + .put(`${endpoints.owprov}/api/v1/inventory/${tagSerialNumber}`, parameters, options) + .then(() => { + getTag(); + if (refreshTable !== null) refreshTable(); + addToast({ + title: t('common.success'), + body: t('inventory.successful_tag_update'), + color: 'success', + autohide: true, + }); + }) + .catch(() => { + addToast({ + title: t('common.error'), + body: t('inventory.tag_update_error'), + color: 'danger', + autohide: true, + }); + }) + .finally(() => { + setLoading(false); + }); + } + }; + + const addNote = (newNote) => { + setLoading(true); + const options = { headers: { Accept: 'application/json', @@ -76,83 +183,79 @@ const SystemPage = () => { }; const parameters = { - command: 'reload', - subsystems, + notes: [{ note: newNote }], }; axiosInstance - .post(`${endpoint}/api/v1/system?command=info`, parameters, options) + .put(`${endpoints.owprov}/api/v1/inventory/${tagSerialNumber}`, parameters, options) .then(() => { - addToast({ - title: t('common.success'), - body: t('system.success_reload'), - color: 'success', - autohide: true, - }); + getTag(); }) - .catch((e) => { + .catch(() => { addToast({ title: t('common.error'), - body: t('system.error_reloading', { error: e.response?.data?.ErrorDescription }), + body: t('inventory.tag_update_error'), color: 'danger', autohide: true, }); + }) + .finally(() => { + setLoading(false); }); - }; - - const getAllInfo = async () => { - const promises = []; - - for (const [key, value] of Object.entries(endpoints)) { - promises.push(getSystemInfo(key, value)); - } - - try { - const results = await Promise.all(promises); - setEndpointsInfo(results); - } catch { - addToast({ - title: t('common.error'), - body: t('system.error_fetching'), - color: 'danger', - autohide: true, - }); - } - }; - - const getColumn = (index) => { - const rows = []; - - for (let i = index; i < endpointsInfo.length; i += 3) { - rows.push(endpointsInfo[i]); - } - - return rows; + setLoading(false); }; useEffect(() => { - getAllInfo(); - }, []); + if (show) { + getTag(); + setFormFields(initialForm); + } + }, [show]); return ( - - - {getColumn(0).map((info) => ( - - ))} - - - {getColumn(1).map((info) => ( - - ))} - - - {getColumn(2).map((info) => ( - - ))} - - + + + + {t('common.edit')} {tag.name} + +
+ + + + + + + + + + +
+
+ + + +
); }; -export default SystemPage; +EditTagModal.propTypes = { + show: PropTypes.bool.isRequired, + toggle: PropTypes.func.isRequired, + refreshTable: PropTypes.func, + tagSerialNumber: PropTypes.string, +}; + +EditTagModal.defaultProps = { + tagSerialNumber: null, + refreshTable: null, +}; + +export default EditTagModal; From 967ef647284eb49c2dbc5ccf64140c0754475d3d Mon Sep 17 00:00:00 2001 From: Charles Date: Tue, 28 Sep 2021 14:35:52 -0400 Subject: [PATCH 2/2] Reverting problematic change --- src/pages/SystemPage/index.js | 331 ++++++++++++---------------------- 1 file changed, 114 insertions(+), 217 deletions(-) diff --git a/src/pages/SystemPage/index.js b/src/pages/SystemPage/index.js index d792054..54b7bf3 100644 --- a/src/pages/SystemPage/index.js +++ b/src/pages/SystemPage/index.js @@ -1,88 +1,31 @@ import React, { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; -import { CModal, CModalHeader, CModalTitle, CModalBody, CButton, CPopover } from '@coreui/react'; -import CIcon from '@coreui/icons-react'; -import { cilX, cilSave } from '@coreui/icons'; -import { useFormFields, useAuth, useToast, useEntity, EditInventoryTagForm } from 'ucentral-libs'; -import axiosInstance from 'utils/axiosInstance'; import { useTranslation } from 'react-i18next'; +import { ApiStatusCard, useAuth, useToast } from 'ucentral-libs'; +import { v4 as createUuid } from 'uuid'; +import axiosInstance from 'utils/axiosInstance'; +import { CRow, CCol } from '@coreui/react'; +import { prettyDate, secondsToDetailed } from 'utils/helper'; -const initialForm = { - entity: { - value: '', - error: false, - hidden: false, - ignore: true, - }, - serialNumber: { - value: '', - error: false, - required: true, - regex: '^[a-fA-F0-9]+$', - length: 12, - ignore: true, - }, - name: { - value: '', - error: false, - required: true, - }, - description: { - value: '', - error: false, - }, - deviceType: { - value: '', - error: false, - required: true, - }, - rrm: { - value: 'inherit', - error: false, - required: true, - }, - deviceConfiguration: { - value: '', - uuid: '', - error: false, - ignore: true, - }, - venue: { - value: '', - error: false, - }, - notes: { - value: [], - error: false, - ignore: true, - }, -}; - -const EditTagModal = ({ show, toggle, tagSerialNumber, refreshTable }) => { +const SystemPage = () => { const { t } = useTranslation(); const { currentToken, endpoints } = useAuth(); - const { deviceTypes } = useEntity(); const { addToast } = useToast(); - const [fields, updateFieldWithId, updateField, setFormFields] = useFormFields(initialForm); - const [loading, setLoading] = useState(false); - const [tag, setTag] = useState({}); + const [endpointsInfo, setEndpointsInfo] = useState([]); - const validation = () => { - let success = true; + const getSystemInfo = async (key, endpoint) => { + const systemInfo = { + title: key, + endpoint, + hostname: t('common.unknown'), + os: t('common.unknown'), + processors: t('common.unknown'), + uptime: t('common.unknown'), + version: t('common.unknown'), + start: t('common.unknown'), + certificates: [], + subsystems: [], + }; - for (const [key, field] of Object.entries(fields)) { - if (field.required && field.value === '') { - updateField(key, { error: true }); - success = false; - break; - } - } - - return success; - }; - - const getTag = () => { - setLoading(true); const options = { headers: { Accept: 'application/json', @@ -90,91 +33,41 @@ const EditTagModal = ({ show, toggle, tagSerialNumber, refreshTable }) => { }, }; - axiosInstance - .get(`${endpoints.owprov}/api/v1/inventory/${tagSerialNumber}`, options) - .then((response) => { - const newFields = fields; - for (const [key] of Object.entries(newFields)) { - if (response.data[key] !== undefined) { - if (key === 'deviceConfiguration') - newFields.deviceConfiguration = { value: '', uuid: response.data[key] }; - else if (key === 'rrm') - newFields[key].value = response.data[key] === '' ? 'inherit' : response.data[key]; - else newFields[key].value = response.data[key]; - } - } - setTag(response.data); - setFormFields({ ...newFields }); + const getInfo = axiosInstance.get(`${endpoint}/api/v1/system?command=info`, options); + const getSubsystems = axiosInstance.post( + `${endpoint}/api/v1/system`, + { command: 'getsubsystemnames' }, + options, + ); - if (response.data.deviceConfiguration !== '') { - return axiosInstance.get( - `${endpoints.owprov}/api/v1/configurations/${response.data.deviceConfiguration}`, - options, - ); - } - return null; - }) - .then((response) => { - if (response) - updateField('deviceConfiguration', { value: response.data.name, uuid: response.data.id }); - }) - .catch(() => { - throw new Error('Error while fetching entity for edit'); - }) - .finally(() => { - setLoading(false); - }); - }; - - const editTag = () => { - if (validation()) { - setLoading(true); - const options = { - headers: { - Accept: 'application/json', - Authorization: `Bearer ${currentToken}`, - }, - }; - - const parameters = {}; - - for (const [key, field] of Object.entries(fields)) { - if (!field.ignore) { - if (tag[key] !== field.value) { - parameters[key] = field.value; - } - } - } - - axiosInstance - .put(`${endpoints.owprov}/api/v1/inventory/${tagSerialNumber}`, parameters, options) - .then(() => { - getTag(); - if (refreshTable !== null) refreshTable(); - addToast({ - title: t('common.success'), - body: t('inventory.successful_tag_update'), - color: 'success', - autohide: true, - }); - }) - .catch(() => { - addToast({ - title: t('common.error'), - body: t('inventory.tag_update_error'), - color: 'danger', - autohide: true, - }); - }) - .finally(() => { - setLoading(false); + return Promise.all([getInfo, getSubsystems]) + .then(([newInfo, newSubs]) => { + let newSystem = { ...systemInfo }; + newSystem = { ...newSystem, ...newInfo.data, ...newSubs.data }; + newSystem.uptime = secondsToDetailed( + newInfo.data.uptime, + t('common.day'), + t('common.days'), + t('common.hour'), + t('common.hours'), + t('common.minute'), + t('common.minutes'), + t('common.second'), + t('common.seconds'), + ); + newSystem.start = prettyDate(newInfo.data.start); + newSystem.subsystems = newSubs.data.list.sort((a, b) => { + if (a < b) return -1; + if (a > b) return 1; + return 0; }); - } + + return newSystem; + }) + .catch(() => systemInfo); }; - const addNote = (newNote) => { - setLoading(true); - + const reload = (subsystems, endpoint) => { const options = { headers: { Accept: 'application/json', @@ -183,79 +76,83 @@ const EditTagModal = ({ show, toggle, tagSerialNumber, refreshTable }) => { }; const parameters = { - notes: [{ note: newNote }], + command: 'reload', + subsystems, }; axiosInstance - .put(`${endpoints.owprov}/api/v1/inventory/${tagSerialNumber}`, parameters, options) + .post(`${endpoint}/api/v1/system?command=info`, parameters, options) .then(() => { - getTag(); - }) - .catch(() => { addToast({ - title: t('common.error'), - body: t('inventory.tag_update_error'), - color: 'danger', + title: t('common.success'), + body: t('system.success_reload'), + color: 'success', autohide: true, }); }) - .finally(() => { - setLoading(false); + .catch((e) => { + addToast({ + title: t('common.error'), + body: t('system.error_reloading', { error: e.response?.data?.ErrorDescription }), + color: 'danger', + autohide: true, + }); }); - setLoading(false); + }; + + const getAllInfo = async () => { + const promises = []; + + for (const [key, value] of Object.entries(endpoints)) { + promises.push(getSystemInfo(key, value)); + } + + try { + const results = await Promise.all(promises); + setEndpointsInfo(results); + } catch { + addToast({ + title: t('common.error'), + body: t('system.error_fetching'), + color: 'danger', + autohide: true, + }); + } + }; + + const getColumn = (index) => { + const rows = []; + + for (let i = index; i < endpointsInfo.length; i += 3) { + rows.push(endpointsInfo[i]); + } + + return rows; }; useEffect(() => { - if (show) { - getTag(); - setFormFields(initialForm); - } - }, [show]); + getAllInfo(); + }, []); return ( - - - - {t('common.edit')} {tag.name} - -
- - - - - - - - - - -
-
- - - -
+ + + {getColumn(0).map((info) => ( + + ))} + + + {getColumn(1).map((info) => ( + + ))} + + + {getColumn(2).map((info) => ( + + ))} + + ); }; -EditTagModal.propTypes = { - show: PropTypes.bool.isRequired, - toggle: PropTypes.func.isRequired, - refreshTable: PropTypes.func, - tagSerialNumber: PropTypes.string, -}; - -EditTagModal.defaultProps = { - tagSerialNumber: null, - refreshTable: null, -}; - -export default EditTagModal; +export default SystemPage;