meshai/work/dashboard-frontend/node_modules/react-transition-group/esm/ReplaceTransition.js
malice 2c46c9104d
feat(region-routing): unified per-family routing cards + region-scoped family→channel routing (#87)
* feat(region-routing): P1 tagging + region_routes primitive + read/write API + preview launcher

- config.py: add Coverage.region_tagging (bool=False); add RegionRouteMatrix
  dataclass (enabled, cells) above NotificationsConfig; add region_routes field
  to NotificationsConfig; add explicit hydration branch for region_routes in
  _dict_to_dataclass mirroring destinations pattern.

- coverage_area.py: add MonitoringArea.name (str|None=None, frozen); update
  areas_from_config to preserve name; refactor inline geom extraction from
  classify_event_areas into shared _event_geom_json helper; add
  matching_area_names(geom_json, areas)->list[str] (additive, all named
  matches, config-order, deduped; gate unchanged); add event_region_names
  convenience wrapper.

- coverage_filter.py: add region_tagging ctor kwarg; stamp event.region/
  regions before the gate when region_tagging=True and areas non-empty and
  not event.regions (never clobbers satpass preset).

- pipeline/__init__.py: wire region_tagging into CoverageFilter construction.

- notification_routes.py: add GET /notifications/regions (named coverage area
  names, config-order, deduped); GET /notifications/region-routing (matrix as
  JSON); POST /notifications/region-routing (explicit RMW — only region_routes
  changes, toggles/rules/destinations survive).

- scripts/preview_dashboard.py: mesh-free launcher — dashboard API only, no
  mesh connector, no broadcast loop; vite runs separately.

All 87 coverage tests pass; 300 total pass; 6 pre-existing failures unchanged
(adapter config count mismatch + MeshCore EventType.NEW_CONTACT).

* feat(region-routing): manual region x family matrix editor page

Adds RegionRoutingMatrix.tsx — a plain editor over the region_routes
config primitive. Rows = families (via useFamilies()), cols = regions
(from GET /api/notifications/regions). Each cell exposes MT channel
(ChannelPicker single + includeDisabled), MC channel name (text input),
min_severity select (routine/priority/critical/immediate), and an enabled
checkbox. Only cells where MT or MC is set are included in the sparse
POST payload. Master enable toggle maps to top-level enabled. MT budget
guard warns when more than 7 distinct MT indices are in use. Sticky
family column; horizontal scroll for wide region sets.

Registers route /region-routing in App.tsx and adds "Region Routing"
nav entry (Map icon) under the Meshtastic section in Layout.tsx,
immediately after Routing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(region-routing): regions endpoint reads saved (disk) coverage so routing columns are dynamic without a bot restart; preview reloads config after writes

* feat(routing): unify MT/MC routing into per-family cards; region routing as an in-card expand; remove rules/destinations UI + standalone page

* refactor(routing): move Meshtastic Routing from /notifications to /meshtastic/routing (mirror /meshcore/routing); redirect legacy path

* feat(region-routing): dispatcher honors region_routes matrix (authoritative-on-match, per-region cooldown, per-channel dedup); non-matrix path unchanged

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(region-routing): matrix dedup key must match boot-restore 2-tuple form (prevents restart re-broadcast flood); regression test

---------

Co-authored-by: Matt Johnson <mj@k7zvx.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 16:52:03 -06:00

136 lines
No EOL
4.3 KiB
JavaScript

import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
import PropTypes from 'prop-types';
import React from 'react';
import ReactDOM from 'react-dom';
import TransitionGroup from './TransitionGroup';
/**
* The `<ReplaceTransition>` component is a specialized `Transition` component
* that animates between two children.
*
* ```jsx
* <ReplaceTransition in>
* <Fade><div>I appear first</div></Fade>
* <Fade><div>I replace the above</div></Fade>
* </ReplaceTransition>
* ```
*/
var ReplaceTransition = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(ReplaceTransition, _React$Component);
function ReplaceTransition() {
var _this;
for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {
_args[_key] = arguments[_key];
}
_this = _React$Component.call.apply(_React$Component, [this].concat(_args)) || this;
_this.handleEnter = function () {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return _this.handleLifecycle('onEnter', 0, args);
};
_this.handleEntering = function () {
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return _this.handleLifecycle('onEntering', 0, args);
};
_this.handleEntered = function () {
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
args[_key4] = arguments[_key4];
}
return _this.handleLifecycle('onEntered', 0, args);
};
_this.handleExit = function () {
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
args[_key5] = arguments[_key5];
}
return _this.handleLifecycle('onExit', 1, args);
};
_this.handleExiting = function () {
for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
args[_key6] = arguments[_key6];
}
return _this.handleLifecycle('onExiting', 1, args);
};
_this.handleExited = function () {
for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
args[_key7] = arguments[_key7];
}
return _this.handleLifecycle('onExited', 1, args);
};
return _this;
}
var _proto = ReplaceTransition.prototype;
_proto.handleLifecycle = function handleLifecycle(handler, idx, originalArgs) {
var _child$props;
var children = this.props.children;
var child = React.Children.toArray(children)[idx];
if (child.props[handler]) (_child$props = child.props)[handler].apply(_child$props, originalArgs);
if (this.props[handler]) {
var maybeNode = child.props.nodeRef ? undefined : ReactDOM.findDOMNode(this);
this.props[handler](maybeNode);
}
};
_proto.render = function render() {
var _this$props = this.props,
children = _this$props.children,
inProp = _this$props.in,
props = _objectWithoutPropertiesLoose(_this$props, ["children", "in"]);
var _React$Children$toArr = React.Children.toArray(children),
first = _React$Children$toArr[0],
second = _React$Children$toArr[1];
delete props.onEnter;
delete props.onEntering;
delete props.onEntered;
delete props.onExit;
delete props.onExiting;
delete props.onExited;
return /*#__PURE__*/React.createElement(TransitionGroup, props, inProp ? React.cloneElement(first, {
key: 'first',
onEnter: this.handleEnter,
onEntering: this.handleEntering,
onEntered: this.handleEntered
}) : React.cloneElement(second, {
key: 'second',
onEnter: this.handleExit,
onEntering: this.handleExiting,
onEntered: this.handleExited
}));
};
return ReplaceTransition;
}(React.Component);
ReplaceTransition.propTypes = process.env.NODE_ENV !== "production" ? {
in: PropTypes.bool.isRequired,
children: function children(props, propName) {
if (React.Children.count(props[propName]) !== 2) return new Error("\"" + propName + "\" must be exactly two transition components.");
return null;
}
} : {};
export default ReplaceTransition;