refactor(OspfToolsPage): rename and restructure optimal cost hints to probability map for improved clarity and functionality
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m59s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m59s
This commit is contained in:
@@ -76,7 +76,7 @@ function buildOspfTemplatesFromRouterResults(routerResults = [], servers = []) {
|
||||
return Array.from(byComposite.values());
|
||||
}
|
||||
|
||||
function buildOptimalCostHints(routeOptimizerData, servers = []) {
|
||||
function buildOptimizerProbabilityMap(routeOptimizerData, servers = []) {
|
||||
const homes = Array.isArray(routeOptimizerData?.homes) ? routeOptimizerData.homes : [];
|
||||
const byRef = new Map();
|
||||
(servers || []).forEach((server) => {
|
||||
@@ -85,7 +85,7 @@ function buildOptimalCostHints(routeOptimizerData, servers = []) {
|
||||
.forEach((ref) => byRef.set(String(ref), server));
|
||||
});
|
||||
|
||||
const hints = {};
|
||||
const probabilities = {};
|
||||
|
||||
homes.forEach((entry) => {
|
||||
const homeRefCandidates = [
|
||||
@@ -119,18 +119,15 @@ function buildOptimalCostHints(routeOptimizerData, servers = []) {
|
||||
uniqueIface.forEach((candidate, idx) => {
|
||||
const iface = String(candidate?.interfaceName || '').trim();
|
||||
const hintKey = `${identity.key}::${iface.toUpperCase()}`;
|
||||
const nextHint = {
|
||||
optimalCost: (idx + 1) * OSPF_COST_STEP,
|
||||
probabilityOptimal: Number(candidate?.probabilityOptimal || 0),
|
||||
};
|
||||
const prev = hints[hintKey];
|
||||
if (!prev || nextHint.probabilityOptimal > prev.probabilityOptimal) {
|
||||
hints[hintKey] = nextHint;
|
||||
const probabilityOptimal = Number(candidate?.probabilityOptimal || 0);
|
||||
const prev = probabilities[hintKey];
|
||||
if (prev == null || probabilityOptimal > prev) {
|
||||
probabilities[hintKey] = probabilityOptimal;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return hints;
|
||||
return probabilities;
|
||||
}
|
||||
|
||||
export default function OspfToolsPage() {
|
||||
@@ -141,7 +138,7 @@ export default function OspfToolsPage() {
|
||||
const [optimizerLoading, setOptimizerLoading] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [dragging, setDragging] = useState(null);
|
||||
const [optimalHints, setOptimalHints] = useState({});
|
||||
const [optimizerProbabilities, setOptimizerProbabilities] = useState({});
|
||||
|
||||
const groupedByRouter = useMemo(() => {
|
||||
const grouped = {};
|
||||
@@ -171,6 +168,34 @@ export default function OspfToolsPage() {
|
||||
.sort((a, b) => a.area.localeCompare(b.area)),
|
||||
}));
|
||||
}, [templates, servers]);
|
||||
const optimalHints = useMemo(() => {
|
||||
const hints = {};
|
||||
|
||||
groupedByRouter.forEach((routerGroup) => {
|
||||
(routerGroup.areas || []).forEach((areaGroup) => {
|
||||
const ranked = [...(areaGroup.items || [])]
|
||||
.map((item) => {
|
||||
const ifaceKey = `${routerGroup.routerKey}::${String(item.interfaceName || '').toUpperCase()}`;
|
||||
const probabilityOptimal = Number(optimizerProbabilities[ifaceKey] || 0);
|
||||
return { item, probabilityOptimal };
|
||||
})
|
||||
.sort((a, b) =>
|
||||
Number(b.probabilityOptimal || 0) - Number(a.probabilityOptimal || 0) ||
|
||||
String(a.item.interfaceName || '').localeCompare(String(b.item.interfaceName || ''))
|
||||
);
|
||||
|
||||
ranked.forEach(({ item, probabilityOptimal }, idx) => {
|
||||
const hintKey = `${routerGroup.routerKey}::${areaGroup.area}::${String(item.interfaceName || '').toUpperCase()}`;
|
||||
hints[hintKey] = {
|
||||
optimalCost: (idx + 1) * OSPF_COST_STEP,
|
||||
probabilityOptimal,
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return hints;
|
||||
}, [groupedByRouter, optimizerProbabilities]);
|
||||
const routerColumnClass = groupedByRouter.length > 1 ? 'col-12 col-xxl-6' : 'col-12';
|
||||
|
||||
const loadServers = async () => {
|
||||
@@ -208,11 +233,11 @@ export default function OspfToolsPage() {
|
||||
setOptimizerLoading(true);
|
||||
try {
|
||||
const response = await api.get('/route-optimizer', { timeout: 30000 });
|
||||
const hints = buildOptimalCostHints(response?.data, servers);
|
||||
setOptimalHints(hints);
|
||||
const probabilities = buildOptimizerProbabilityMap(response?.data, servers);
|
||||
setOptimizerProbabilities(probabilities);
|
||||
} catch (error) {
|
||||
console.error('Failed to load route optimizer hints:', error);
|
||||
setOptimalHints({});
|
||||
setOptimizerProbabilities({});
|
||||
if (!silent) notify.warning('Не удалось загрузить рекомендации из оптимизатора маршрутов');
|
||||
} finally {
|
||||
setOptimizerLoading(false);
|
||||
@@ -346,7 +371,7 @@ export default function OspfToolsPage() {
|
||||
<div className="list-group list-group-flush">
|
||||
{areaGroup.items.map((item) => (
|
||||
(() => {
|
||||
const hint = optimalHints[`${routerGroup.routerKey}::${String(item.interfaceName || '').toUpperCase()}`];
|
||||
const hint = optimalHints[`${routerGroup.routerKey}::${areaGroup.area}::${String(item.interfaceName || '').toUpperCase()}`];
|
||||
const hintMatches = hint && Number(hint.optimalCost) === Number(item.cost);
|
||||
return (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user