diff --git a/crates/weaver-app/assets/styling/record-view.css b/crates/weaver-app/assets/styling/record-view.css index f977b4d..2b01e21 100644 --- a/crates/weaver-app/assets/styling/record-view.css +++ b/crates/weaver-app/assets/styling/record-view.css @@ -73,7 +73,6 @@ display: flex; gap: 0; border-bottom: 1px solid var(--color-border); - margin-bottom: 1.5rem; margin-top: 1.5rem; align-items: center; } @@ -166,6 +165,7 @@ display: flex; flex-direction: column; align-items: flex-start; + border-left: 1px dashed var(--color-subtle); } .record-field { @@ -173,6 +173,7 @@ flex-direction: column; padding: 0rem 0 0rem 1rem; padding-right: 1rem; + margin-left: -1px; border-left: 2px solid var(--color-secondary); border-bottom: 1px dashed var(--color-subtle); z-index: 1; @@ -229,7 +230,17 @@ } .record-section { - padding-left: 1.5rem; + position: relative; + margin-left: 1.5rem; + border-left: 1px dashed var(--color-border); +} + +.section-content .record-section { + position: relative; + border-left: 1px dashed var(--color-border); +} + +.array-item .record-section { position: relative; border-left: 1px dashed var(--color-border); } @@ -242,9 +253,9 @@ padding-left: 1rem; padding-top: 0.5rem; padding-bottom: 0.25rem; + margin-left: -1px; border-left: 2px solid var(--color-primary); border-bottom: 1px dashed var(--color-muted); - margin-left: -1.55rem; } .section-content .section-label { @@ -254,7 +265,7 @@ font-weight: 600; padding-left: 1rem; padding-top: 0.5rem; - margin-left: -0.02rem; + margin-left: -1px; border-left: 2px solid var(--color-secondary); } @@ -263,7 +274,6 @@ flex-direction: column; align-items: flex-start; padding-right: 1rem; - margin-left: -0.02rem; } .section-content .record-field { @@ -425,7 +435,7 @@ font-family: var(--font-mono); font-size: 0.9rem; padding: 1rem; - background: var(--color-background-alt, rgba(0, 0, 0, 0.2)); + background: var(--color-surface, rgba(0, 0, 0, 0.2)); border: 1px solid var(--color-border); color: var(--color-text); resize: vertical; @@ -442,7 +452,7 @@ font-family: var(--font-mono); font-size: 0.85rem; padding: 1rem; - background: var(--color-background-alt, rgba(0, 0, 0, 0.2)); + background: var(--color-surface, rgba(0, 0, 0, 0.2)); border: 1px solid var(--color-border); overflow-y: auto; align-self: flex-start; @@ -450,13 +460,13 @@ .parse-error, .validation-errors { - color: var(--color-error, #ff6b6b); + color: var(--color-error); margin-top: 0.5rem; } .parse-success, .validation-success { - color: var(--color-success, #51cf66); + color: var(--color-success); } .validation-errors h4 { @@ -468,7 +478,7 @@ .validation-errors .error { padding: 0.25rem 0; - border-left: 2px solid var(--color-error, #ff6b6b); + border-left: 2px solid var(--color-error); padding-left: 0.5rem; margin: 0.25rem 0; } @@ -481,14 +491,11 @@ } .array-item .section-header { - margin-left: -1.53rem; } .array-item .section-content .record-field { - margin-left: 0rem; } .array-item .record-field { - margin-left: -1.5rem; } .array-length { @@ -502,7 +509,7 @@ width: 100%; display: flex; flex-direction: column; - margin-left: 1.49rem; + margin-left: 1.48rem; } /* Pretty Editor Input Fields */ @@ -601,6 +608,7 @@ align-items: center; padding: 0.75rem 0 0rem 0rem; margin-bottom: 1rem; + margin-left: 1.5rem; border-left: 1px solid var(--color-border); } diff --git a/crates/weaver-app/src/views/record.rs b/crates/weaver-app/src/views/record.rs index bc2c99d..9972c51 100644 --- a/crates/weaver-app/src/views/record.rs +++ b/crates/weaver-app/src/views/record.rs @@ -274,11 +274,14 @@ fn DataView(data: Data<'static>, path: String, did: String) -> Element { div { class: "section-content", for (idx, item) in arr.iter().enumerate() { { - let item_path = format!("{}[{}]", path, idx); + let item_path = format!("{}[{}]", label, idx); let is_object = matches!(item, Data::Object(_)); if is_object { rsx! { + + div { + class: "array-item", div { class: "record-section", div { class: "section-label", "{item_path}" } div { class: "section-content", @@ -289,14 +292,20 @@ fn DataView(data: Data<'static>, path: String, did: String) -> Element { } } } + } } } else { + rsx! { + + div { + class: "array-item", DataView { data: item.clone(), path: item_path, did: did.clone() } + } } } } @@ -307,21 +316,23 @@ fn DataView(data: Data<'static>, path: String, did: String) -> Element { } Data::Object(obj) => { let is_root = path.is_empty(); - let is_array_item = path.contains('['); + let is_array_item = path.split('.').last().unwrap_or(&path).contains('['); if is_root || is_array_item { // Root object or array item: just render children (array items already wrapped) rsx! { - for (key, value) in obj.iter() { - { - let new_path = if is_root { - key.to_string() - } else { - format!("{}.{}", path, key) - }; - let did_clone = did.clone(); - rsx! { - DataView { data: value.clone(), path: new_path, did: did_clone } + div { class: if !is_root { "record-section" } else {""}, + for (key, value) in obj.iter() { + { + let new_path = if is_root { + key.to_string() + } else { + format!("{}.{}", path, key) + }; + let did_clone = did.clone(); + rsx! { + DataView { data: value.clone(), path: new_path, did: did_clone } + } } } } @@ -330,8 +341,9 @@ fn DataView(data: Data<'static>, path: String, did: String) -> Element { // Nested object (not array item): wrap in section let label = path.split('.').last().unwrap_or(&path); rsx! { + + div { class: "section-label", "{label}" } div { class: "record-section", - div { class: "section-label", "{label}" } div { class: "section-content", for (key, value) in obj.iter() { {