From 17adbe9e38bd5d02957ff92342028b530ef04c91 Mon Sep 17 00:00:00 2001 From: Nicholas Goodman Date: Tue, 19 Nov 2024 10:53:41 -0500 Subject: [PATCH 1/2] Basic broker and queue icons in the queue selector --- package-lock.json | 6 ++ package.json | 1 + src/App.jsx | 1 + src/components/BrokerConfigDialog/index.jsx | 8 +-- src/components/BrokerQueueTreeView/index.jsx | 56 +++++++++++++++---- .../BrokerQueueTreeView/styles.module.css | 2 + src/providers/SolaceConfigProvider.jsx | 24 ++++---- 7 files changed, 68 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 750490a..0455bf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@tabler/icons-react": "^3.11.0", "@tauri-apps/api": "^1", + "primeflex": "^3.3.1", "primeicons": "^7.0.0", "primereact": "^10.8.0", "react": "^18.2.0", @@ -2243,6 +2244,11 @@ "postcss": "^8.2.1" } }, + "node_modules/primeflex": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/primeflex/-/primeflex-3.3.1.tgz", + "integrity": "sha512-zaOq3YvcOYytbAmKv3zYc+0VNS9Wg5d37dfxZnveKBFPr7vEIwfV5ydrpiouTft8MVW6qNjfkaQphHSnvgQbpQ==" + }, "node_modules/primeicons": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/primeicons/-/primeicons-7.0.0.tgz", diff --git a/package.json b/package.json index 1966dba..0a804a0 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "@tabler/icons-react": "^3.11.0", "@tauri-apps/api": "^1", + "primeflex": "^3.3.1", "primeicons": "^7.0.0", "primereact": "^10.8.0", "react": "^18.2.0", diff --git a/src/App.jsx b/src/App.jsx index 3110bea..3bbd9de 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -8,6 +8,7 @@ import TreeView from './components/BrokerQueueTreeView'; import MessageList from './components/MessageList'; import MessageDetails from './components/MessageDetails'; +import 'primeflex/primeflex.css'; import 'primeicons/primeicons.css'; import './App.css'; diff --git a/src/components/BrokerConfigDialog/index.jsx b/src/components/BrokerConfigDialog/index.jsx index d83bd37..63d41f6 100644 --- a/src/components/BrokerConfigDialog/index.jsx +++ b/src/components/BrokerConfigDialog/index.jsx @@ -55,12 +55,8 @@ export default function BrokerConfigDialog( { config, brokerEditor, onHide }) { } const handleTestConnection = async () => { - const { severity, summary, detail } = await brokerEditor.test(values); - toast.current.show({ - severity, - summary, - detail - }); + const { message } = await brokerEditor.test(values); + toast.current.show(message); } const Header = () => ( diff --git a/src/components/BrokerQueueTreeView/index.jsx b/src/components/BrokerQueueTreeView/index.jsx index 055cc7d..2fbb25c 100644 --- a/src/components/BrokerQueueTreeView/index.jsx +++ b/src/components/BrokerQueueTreeView/index.jsx @@ -19,6 +19,27 @@ export default function TreeView({ brokers, brokerEditor, onQueueSelected }) { const queueApi = useSempApi(QueueApi); + const getBrokerIcon = (testResult) => ( + testResult ? ( + testResult.connected ? ( + testResult.replay ? + 'pi pi-circle-fill text-primary' : + 'pi pi-circle text-primary' + ) : + 'pi pi-times-circle text-red-500' + ) : 'pi pi-question-circle' + ); + + const getQueueIcon = (queue) => { + const isLvq = queue.maxMsgSpoolUsage === 0; + const isEmpty = queue.msgSpoolUsage === 0; + const isFull = (queue.msgSpoolUsage/queue.maxMsgSpoolUsage) > queue.eventMsgSpoolUsageThreshold.setPercent; + + const iconType = isLvq ? 'pi-caret-right' : 'pi-forward'; + const iconColor = isEmpty ? '' : (!isLvq && isFull) ? 'text-red-500' : 'text-primary'; + return `pi ${iconType} ${iconColor}`; + }; + const nodes2 = brokers.map(config => ({ id: config.id, key: config.id, @@ -27,6 +48,7 @@ export default function TreeView({ brokers, brokerEditor, onQueueSelected }) { type: 'broker', config }, + icon: getBrokerIcon(config.testResult), leaf: false, children: queuesListMap[config.id] || [] })); @@ -34,18 +56,28 @@ export default function TreeView({ brokers, brokerEditor, onQueueSelected }) { const handleExpand = async (event) => { setIsLoading(true); const { config } = event.node.data; - const queues = (await queueApi.with(config).getMsgVpnQueues(config.vpn, { count: 100 })).data; - const queueNodeList = queues - .filter((queue) => !queue.queueName.startsWith('#')) - .map((queue, n) => ({ - id: `${config.id}-${n}`, - key: n.toString(), - label: queue.queueName, - data: { - type: 'queue', - config: Object.assign({}, config, { queueName: queue.queueName }) - } - })); + + const { result } = await brokerEditor.test(config); + Object.assign(config, { testResult: result }); //HACK: this updates the during each expansion + + let queueNodeList = []; + if(result.connected) { + const queues = (await queueApi.with(config).getMsgVpnQueues(config.vpn, { count: 100 })).data; + console.dir(queues); + queueNodeList = queues + .filter((queue) => !queue.queueName.startsWith('#')) + .map((queue, n) => ({ + id: `${config.id}-${n}`, + key: n.toString(), + label: queue.queueName, + data: { + type: 'queue', + config: Object.assign({}, config, { queueName: queue.queueName }) + }, + icon: getQueueIcon(queue) + })); + } + setQueuesListMap(prev => ({...prev, [config.id]: queueNodeList})); setIsLoading(false); }; diff --git a/src/components/BrokerQueueTreeView/styles.module.css b/src/components/BrokerQueueTreeView/styles.module.css index 270876e..32069e6 100644 --- a/src/components/BrokerQueueTreeView/styles.module.css +++ b/src/components/BrokerQueueTreeView/styles.module.css @@ -1,5 +1,7 @@ .container { width: 100%; + display: flex; + flex-direction: column; } .toolbar { diff --git a/src/providers/SolaceConfigProvider.jsx b/src/providers/SolaceConfigProvider.jsx index 0ce4e59..21d0a5f 100644 --- a/src/providers/SolaceConfigProvider.jsx +++ b/src/providers/SolaceConfigProvider.jsx @@ -91,19 +91,19 @@ export function useSolaceConfigContext() { if(err.responseCode) switch(err.responseCode) { case 401: - return { result: false, severity: 'error', summary: 'SMF: Unauthorized', detail: 'Incorrect client username or password.' } + return { result: { connected: false, replay: false}, message: { severity:'error', summary: 'SMF: Unauthorized', detail: 'Incorrect client username or password.' }}; } const errMsg = err.message; if (errMsg.includes('invalid URL')) { - return { result: false, severity: 'error', summary: 'SMF: Failure', detail: 'Invalid broker URL.'} + return { result: { connected: false, replay: false}, message: { severity:'error', summary: 'SMF: Failure', detail: 'Invalid broker URL.'}}; } if (errMsg.includes('Connection error')) { - return { result: false, severity: 'error', summary: 'SMF: Failure', detail: 'General connection error.'} + return { result: { connected: false, replay: false}, message: { severity:'error', summary: 'SMF: Failure', detail: 'General connection error.'}}; } - return { result: false, severity: 'error', summary: 'SMF: Connection Error', detail: 'Unknown error!' }; + return { result: { connected: false, replay: false}, message: { severity:'error', summary: 'SMF: Connection Error', detail: 'Unknown error!' }}; } const replayLogApi = replayLogApiContext.with(config); @@ -121,16 +121,16 @@ export function useSolaceConfigContext() { switch (status) { case 200: if (body.data.length > 0) { - return { result: true, severity: 'info', summary: 'Success', detail: 'Broker connection succeeded.' }; + return { result: { connected: true, replay: true}, message: { severity:'info', summary: 'Success', detail: 'Broker connection succeeded.' }}; } else { - return { result: true, severity: 'warn', summary: 'Warning', detail: 'Replay Log not enabled on broker.' } + return { result: { connected: true, replay: false}, message: { severity:'warn', summary: 'Warning', detail: 'Replay Log not enabled on broker.' }}; } case 400: - return { result: false, severity: 'error', summary: 'SEMP: Bad Request', detail: errorDetail }; + return { result: { connected: false, replay: false}, message: { severity:'error', summary: 'SEMP: Bad Request', detail: errorDetail }}; case 401: - return { result: false, severity: 'error', summary: 'SEMP: Unauthorized', detail: errorDetail }; + return { result: { connected: false, replay: false}, message: { severity:'error', summary: 'SEMP: Unauthorized', detail: errorDetail }}; case 403: - return { result: false, severity: 'error', summary: 'SEMP: Forbidden', detail: errorDetail }; + return { result: { connected: false, replay: false}, message: { severity:'error', summary: 'SEMP: Forbidden', detail: errorDetail }}; } }; @@ -148,17 +148,17 @@ export function useSolaceConfigContext() { errMsg.includes('Invalid URL') || errMsg.includes('expected empty host') ) { - return { result: false, severity: 'error', summary: 'SEMP: Failure', detail: 'Invalid broker URL.' }; + return { result: { connected: false, replay: false}, message: { severity:'error', summary: 'SEMP: Failure', detail: 'Invalid broker URL.' }}; } if ( errMsg.includes('Network Error') || errMsg.includes('Request has been terminated') ) { - return { result: false, severity: 'error', summary: 'SEMP: Failure', detail: 'Broker service unreachable.' } + return { result: { connected: false, replay: false}, message: { severity:'error', summary: 'SEMP: Failure', detail: 'Broker service unreachable.' }} } } - return { result: false, severity: 'error', summary: 'SEMP: Failure', detail: 'Unknown error!' }; + return { result: { connected: false, replay: false}, message: { severity:'error', summary: 'SEMP: Failure', detail: 'Unknown error!' }}; } }; From 0b7e187a73868a22cf6fc19ac9d8d8d021413f7d Mon Sep 17 00:00:00 2001 From: Nicholas Goodman Date: Tue, 19 Nov 2024 11:34:14 -0500 Subject: [PATCH 2/2] Fix minor styling issues --- src/App.css | 5 +++++ src/components/BrokerQueueTreeView/index.jsx | 4 ++-- src/components/BrokerQueueTreeView/styles.module.css | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/App.css b/src/App.css index 995a220..c37c8c1 100644 --- a/src/App.css +++ b/src/App.css @@ -1,3 +1,8 @@ +:root { + font-family: "Open Sans", sans-serif; + --font-family: "Open Sans", sans-serif; +} + html { font-size: 14px; } diff --git a/src/components/BrokerQueueTreeView/index.jsx b/src/components/BrokerQueueTreeView/index.jsx index 2fbb25c..c75f1d2 100644 --- a/src/components/BrokerQueueTreeView/index.jsx +++ b/src/components/BrokerQueueTreeView/index.jsx @@ -40,7 +40,7 @@ export default function TreeView({ brokers, brokerEditor, onQueueSelected }) { return `pi ${iconType} ${iconColor}`; }; - const nodes2 = brokers.map(config => ({ + const nodes = brokers.map(config => ({ id: config.id, key: config.id, label: config.displayName, @@ -105,7 +105,7 @@ export default function TreeView({ brokers, brokerEditor, onQueueSelected }) { return (
); diff --git a/src/components/BrokerQueueTreeView/styles.module.css b/src/components/BrokerQueueTreeView/styles.module.css index 32069e6..9bb24ae 100644 --- a/src/components/BrokerQueueTreeView/styles.module.css +++ b/src/components/BrokerQueueTreeView/styles.module.css @@ -16,4 +16,8 @@ height: 100%; overflow: auto; user-select: none; +} + +.treeContainer { + overflow-x: hidden; } \ No newline at end of file