Complete source 6 engineering workflows and preserve release validation evidence

This commit is contained in:
Codex
2026-09-06 21:49:04 -07:00
parent 2b2d2bc18b
commit 4b6b5fc197
290 changed files with 48271 additions and 1791 deletions
+168 -22
View File
@@ -1,5 +1,13 @@
mod checkpoints;
#[cfg(test)]
mod diagram_selection_tests;
mod hosted;
#[cfg(test)]
mod review_navigation_tests;
#[cfg(test)]
mod transition_context_tests;
#[cfg(test)]
mod view_copy_tests;
use crate::forms::Draft;
use crate::{
document::Document,
@@ -288,6 +296,7 @@ pub enum Pending {
HostedOpen,
New,
Demo,
Walkthrough,
Open,
Close(window::Id),
}
@@ -346,6 +355,7 @@ pub enum Message {
InspectorTab(crate::navigation::InspectorTab),
RevealInDiagram(Id, Id),
AddDiagram,
DuplicateDiagram(Id),
AddArtifact,
AddTrace,
Field(String, String),
@@ -354,6 +364,7 @@ pub enum Message {
FieldAppend(String, Value),
FieldValuePath(String, crate::data_values::FieldPathKey),
FieldValueBrowse(String, Option<crate::data_values::FieldPathKey>, usize),
FieldReferenceBrowse(String, String, usize),
FieldVariant(String, Value),
FieldArray(String, Option<usize>, i32),
Apply,
@@ -897,6 +908,44 @@ impl App {
fn diagram_for(&self, layer: Layer, element: Id) -> Option<Id> {
preferred_diagram(self.project(), self.active_diagram, layer, element)
}
/// Navigation after an accepted review is not another model operation.
/// Callers retain their workspace policy; keep an already visible target's
/// camera and never leave an old-layer diagram behind after counterpart focus.
fn focus_after_review(&mut self, target: Id, destination: Option<Id>) -> bool {
if !self.project().contains(target) {
return false;
}
let previous = (self.layer, self.active_diagram);
self.selected = target;
self.selected_node = None;
if let Some(layer) = self.project().layer_of(target) {
let retained = self.active_diagram.filter(|id| {
self.project().diagrams.get(id).is_some_and(|d| {
d.layer == layer
&& (d.nodes.values().any(|n| n.element == target)
|| self.project().elements.get(&target).is_some_and(|e| {
e.kind() == Kind::Port
&& project_view(self.project(), *id)
.ports
.iter()
.any(|port| port.element == target)
}))
})
});
self.layer = layer;
self.active_diagram = destination
.filter(|id| {
self.project()
.diagrams
.get(id)
.is_some_and(|d| d.layer == layer)
})
.or(retained)
.or_else(|| self.diagram_for(layer, target));
}
self.refresh_draft();
previous != (self.layer, self.active_diagram)
}
fn select(&mut self, id: Id) {
if self.selected == id {
return;
@@ -1530,7 +1579,14 @@ impl App {
self.canvas_epoch = self.canvas_epoch.wrapping_add(1);
self.selected_bend = None;
}
Message::Guide(event) => self.guide.update(event),
Message::Guide(event) => {
if self.guide.update(event) {
return iced::widget::operation::snap_to(
crate::guide::ARTICLE_SCROLL_ID,
iced::widget::scrollable::RelativeOffset::START,
);
}
}
Message::ExactStrings(enabled) => {
if let Some(d) = &mut self.draft {
match d.set_exact(enabled) {
@@ -1575,6 +1631,22 @@ impl App {
.insert(path, crate::forms::ValueBrowser { scope, page });
}
}
Message::FieldReferenceBrowse(path, query, page) => {
if let Some(draft) = &mut self.draft {
let page = if draft
.reference_browsers
.get(&path)
.is_some_and(|b| b.query == query)
{
page
} else {
0
};
draft
.reference_browsers
.insert(path, crate::forms::ReferenceBrowser { query, page });
}
}
Message::FieldValuePath(path, key) => {
if let Some(draft) = &mut self.draft
&& let Err(error) = draft.value_path(&path, key)
@@ -1799,13 +1871,11 @@ impl App {
match state.command(self.project()) {
Ok(command) => {
if self.execute(command) {
if let Some(target) = focus {
self.selected = target;
if let Some(layer) = self.project().layer_of(target)
{
self.layer = layer;
}
self.refresh_draft();
if let Some(target) = focus
&& self.focus_after_review(target, None)
&& self.page == Page::Diagram
{
self.fit();
}
self.status = "Semantic review applied · model, source and baseline form one undoable change".into();
return Task::none();
@@ -1827,11 +1897,19 @@ impl App {
&& matches!(&workflow, crate::workflow::Workflow::Ports(_));
let transition_focus = match &workflow {
crate::workflow::Workflow::Ports(state) => Some(state.focus()),
crate::workflow::Workflow::Transition(t) => {
t.plan.changes.first().map(|c| c.target)
}
crate::workflow::Workflow::Transition(t) => t
.request
.sources
.first()
.and_then(|source| t.plan.changes.iter().find(|c| c.source == *source))
.map(|c| c.target),
_ => None,
};
let behavior_transition = matches!(&workflow,
crate::workflow::Workflow::Transition(t)
if t.request.sources.first().is_some_and(|source|
crate::behavior::selected_behavior(self.project(), *source).is_some()));
let previous_behavior_context = self.state_view_identity();
match workflow.update(self.project(), event) {
Ok(Some(mut candidate)) => {
let focus = transition_focus
@@ -1849,25 +1927,33 @@ impl App {
.find(|id| !self.project().traces.contains_key(id))
.copied()
});
let behavior_owner = focus
.filter(|_| behavior_transition)
.and_then(|id| crate::behavior::selected_behavior(&candidate, id));
let destination = focus.and_then(|id| {
candidate.layer_of(id).and_then(|layer| {
preferred_diagram(&candidate, self.active_diagram, layer, id)
})
});
if let (Some(id), Some(diagram)) = (focus, destination) {
if let (None, Some(id), Some(diagram)) =
(behavior_owner, focus, destination)
{
reveal_port_owner(&mut candidate, diagram, id);
}
if self.execute(Command::Replace(candidate)) {
if let Some(id) = focus {
self.selected = id;
if let Some(layer) = self.project().layer_of(id) {
self.layer = layer;
self.active_diagram =
destination.or_else(|| self.diagram_for(layer, id));
}
self.refresh_draft();
self.focus_after_review(id, destination);
}
if !stay_in_catalog {
if let Some(owner) = behavior_owner {
self.selected_node = None;
self.behavior.active_owner = Some(owner);
self.page = Page::Behavior;
if self.reset_state_view_after_navigation(
previous_behavior_context,
) {
self.canvas_epoch = self.canvas_epoch.wrapping_add(1);
}
} else if !stay_in_catalog {
self.page = Page::Diagram;
self.fit();
}
@@ -2105,6 +2191,7 @@ impl App {
layer: self.layer,
projection: ProjectionKind::Allocation,
routes: Vec::new(),
view_options: Default::default(),
nodes: Default::default(),
};
if self.execute(Command::CreateDiagram(d)) {
@@ -2113,6 +2200,39 @@ impl App {
}
}
}
Message::DuplicateDiagram(source) => {
if !self.project().diagrams.contains_key(&source) {
self.status = "The saved view to duplicate no longer exists.".into();
return Task::none();
}
let original = self.selected;
if self.apply() {
let source = if source == original {
self.selected
} else {
source
};
match crate::view_copy::command(self.project(), source) {
Ok(command) => {
if self.execute(command) {
self.active_diagram = Some(self.selected);
self.layer = self.project().diagrams[&self.selected].layer;
self.selected_node = None;
self.selected_bend = None;
self.page = Page::Diagram;
self.canvas_epoch = self.canvas_epoch.wrapping_add(1);
self.route_state_diagram_workspace();
if self.page == Page::Diagram {
self.fit();
}
self.status =
"View copied; engineering elements are shared.".into();
}
}
Err(error) => self.status = error,
}
}
}
Message::AddArtifact => {
if self.apply() {
let id = Id::new_v4();
@@ -2206,11 +2326,28 @@ impl App {
});
}
Message::Diagram(choice) => {
// Reject a stale picker event before applying unrelated property input.
if !self.project().diagrams.contains_key(&choice.id) {
self.status = "Diagram no longer exists.".into();
return Task::none();
}
let previous_diagram = self.active_diagram;
let follow_view = previous_diagram == Some(self.selected);
if self.apply() {
self.active_diagram = Some(choice.id);
if let Some(d) = self.project().diagrams.get(&choice.id) {
// Apply may have changed the current diagram's UUID. A picker
// event for that same view must follow its new identity.
let diagram = if previous_diagram == Some(choice.id) {
self.active_diagram.unwrap_or(choice.id)
} else {
choice.id
};
self.active_diagram = Some(diagram);
if let Some(d) = self.project().diagrams.get(&diagram) {
self.layer = d.layer;
}
if follow_view {
self.selected = diagram;
}
self.selected_node = None;
self.refresh_draft();
self.fit();
@@ -2841,6 +2978,7 @@ impl App {
layer: self.layer,
projection: preferred,
routes: Vec::new(),
view_options: Default::default(),
nodes: Default::default(),
}));
diagram_target = Some(view);
@@ -3009,6 +3147,13 @@ impl App {
self.reset(Project::demo(), None);
Task::none()
}
Pending::Walkthrough => match crate::home::walkthrough_path() {
Ok(path) => self.load_from(path),
Err(error) => {
self.status = error;
Task::none()
}
},
Pending::Open => self.choose_file(FileOperation::Open),
Pending::Close(id) => {
self.retire_checkpoint();
@@ -4440,6 +4585,7 @@ mod port_view_tests {
layer: Layer::Sa,
projection: ProjectionKind::Capabilities,
routes: Vec::new(),
view_options: Default::default(),
nodes: Default::default(),
},
);