Skip to content

Commit

Permalink
Retain validations from asset func on regeneration
Browse files Browse the repository at this point in the history
This commit retains validations from asset funcs upon regeneration.
Currently, we successfully execute the asset func when regenerating
an asset. We see the validations in the resulting definition. However,
when exporting using the definition and converting it into a spec, the
validations are dropped. This commit ensures that are no longer dropped.

This commit also contains minor changes to how validations appear in the
attribute panel. The existing classes relied on colors outside of our
asset panel and neither matcher our light nor our dark theme. While the
current colors are not likely the final ones, they are closer to our
design language (even if only a little).

Disclaimer: this will require all affected assets to be regenerated and
re-exported, as applicable.

Signed-off-by: Nick Gerace <[email protected]>
  • Loading branch information
nickgerace committed Jun 25, 2024
1 parent a71ac66 commit 8f32217
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@

<div
:class="{
'force-border-red-400': validation && validation.status !== 'Success',
'force-border-destructive-500': validation && validation.status !== 'Success',
'my-1': validation && validation.status !== 'Success',
}"
class="attributes-panel-item__input-wrap"
Expand Down Expand Up @@ -474,7 +474,7 @@
<div
v-if="showValidationDetails && validation"
:style="{ marginLeft: indentPx }"
class="text-red-400 flex flex-col bg-black pl-3 border-y border-red-400 pb-1 my-1"
class="flex flex-col pl-3 border pb-1 m-2 text-destructive-500 border-destructive-500 bg-destructive-100 dark:text-destructive-900 dark:border-destructive-900 dark:bg-destructive-500"
>
<p class="my-3">{{ validation.message }}</p>

Expand Down Expand Up @@ -1269,8 +1269,8 @@ const sourceSelectMenuRef = ref<InstanceType<typeof DropdownMenu>>();
}
}
.force-border-red-400 {
border-color: rgb(251 113 133 / var(--tw-border-opacity)) !important;
.force-border-destructive-500 {
border-color: @colors-destructive-500 !important;
}
.attributes-panel-item__input-wrap {
position: relative;
Expand Down
17 changes: 17 additions & 0 deletions lib/dal-test/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,20 @@ pub async fn fetch_resource_last_synced_value(
.await?;
Ok(last_synced_value)
}

/// Extracts the value and validation from a raw property edtior value.
pub fn extract_value_and_validation(
prop_editor_value: serde_json::Value,
) -> Result<serde_json::Value> {
let value = prop_editor_value
.get("value")
.ok_or(eyre!("get value from property editor value"))?;
let validation = prop_editor_value
.get("validation")
.ok_or(eyre!("get validation from property editor value"))?;

Ok(serde_json::json!({
"value": value,
"validation": validation,
}))
}
3 changes: 3 additions & 0 deletions lib/dal/src/schema/variant/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ impl PropDefinition {
builder.map_key_func(map_key_func.to_spec(identity_func_unique_id)?);
}
}
if let Some(validation_format) = &self.validation_format {
builder.validation_format(validation_format);
}

Ok(builder.build()?)
}
Expand Down
15 changes: 8 additions & 7 deletions lib/dal/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::sync::Arc;
use telemetry::prelude::*;
use thiserror::Error;

use crate::attribute::value::AttributeValueError;
use crate::func::backend::validation::ValidationRunResult;
use crate::func::runner::{FuncRunner, FuncRunnerError};
use crate::layer_db_types::{ValidationContent, ValidationContentV1};
Expand All @@ -22,18 +23,18 @@ use crate::{
pk, schema::variant::SchemaVariantError, AttributeValue, AttributeValueId, ChangeSetError,
Component, ComponentId, FuncError, HistoryEventError, Prop, Timestamp,
};
use crate::{DalContext, TransactionsError};
use crate::{ComponentError, DalContext, TransactionsError};

#[allow(clippy::large_enum_variant)]
#[remain::sorted]
#[derive(Error, Debug)]
pub enum ValidationError {
#[error("attribute value error: {0}")]
AttributeValue(String),
AttributeValue(#[from] Box<AttributeValueError>),
#[error("change set error: {0}")]
ChangeSet(#[from] ChangeSetError),
#[error("component error: {0}")]
Component(String),
Component(#[from] Box<ComponentError>),
#[error("edge weight error: {0}")]
EdgeWeight(#[from] EdgeWeightError),
#[error("func error: {0}")]
Expand Down Expand Up @@ -265,7 +266,7 @@ impl ValidationOutput {
Ok(
if let Some(prop_id) = AttributeValue::prop_id_for_id(ctx, attribute_value_id)
.await
.map_err(|e| ValidationError::AttributeValue(e.to_string()))?
.map_err(Box::new)?
{
let prop = Prop::get_by_id_or_error(ctx, prop_id).await?;
prop.validation_format
Expand Down Expand Up @@ -348,11 +349,11 @@ impl ValidationOutput {
) -> ValidationResult<Vec<(AttributeValueId, ValidationOutput)>> {
let component = Component::get_by_id(ctx, component_id)
.await
.map_err(|e| ValidationError::Component(e.to_string()))?;
.map_err(Box::new)?;
let domain_av = component
.domain_prop_attribute_value(ctx)
.await
.map_err(|e| ValidationError::Component(e.to_string()))?;
.map_err(Box::new)?;

let mut outputs = vec![];
let mut queue = VecDeque::from(vec![domain_av]);
Expand All @@ -365,7 +366,7 @@ impl ValidationOutput {
let children_av_ids =
AttributeValue::get_child_av_ids_in_order(ctx, attribute_value_id)
.await
.map_err(|e| ValidationError::AttributeValue(e.to_string()))?;
.map_err(Box::new)?;

queue.extend(children_av_ids);

Expand Down
36 changes: 12 additions & 24 deletions lib/dal/tests/integration_test/validations.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use dal::workspace_snapshot::content_address::ContentAddressDiscriminants;
use dal::workspace_snapshot::edge_weight::EdgeWeightKindDiscriminants;
use dal::{AttributeValue, Component, DalContext};
use dal_test::helpers::ChangeSetTestHelpers;
use dal_test::helpers::{
connect_components_with_socket_names, create_component_for_schema_name, PropEditorTestView,
};
use dal_test::helpers::{extract_value_and_validation, ChangeSetTestHelpers};
use dal_test::test;
use serde_json::json;

Expand All @@ -31,7 +31,7 @@ async fn validation_format_errors(ctx: &mut DalContext) {
"message": "JoiValidationJsonParsingError: Unexpected token ' in JSON at position 0",
}
}),
extract_value_and_validation(prop_view)
extract_value_and_validation(prop_view).expect("could not extract")
);

let bad_format_path = &["root", "domain", "bad_validation_format"];
Expand All @@ -49,7 +49,7 @@ async fn validation_format_errors(ctx: &mut DalContext) {
"message": "JoiValidationFormatError: validationFormat must be of type object",
}
}),
extract_value_and_validation(prop_view)
extract_value_and_validation(prop_view).expect("could not extract")
);
}

Expand Down Expand Up @@ -84,7 +84,7 @@ async fn prop_editor_validation(ctx: &mut DalContext) {
"message": "\"value\" is required",
}
}),
extract_value_and_validation(prop_view)
extract_value_and_validation(prop_view).expect("could not extract")
);

AttributeValue::update(ctx, av_id, Some(json!(1)))
Expand All @@ -109,7 +109,7 @@ async fn prop_editor_validation(ctx: &mut DalContext) {
"message": null,
}
}),
extract_value_and_validation(prop_view)
extract_value_and_validation(prop_view).expect("could not extract")
);

AttributeValue::update(ctx, av_id, Some(json!(3)))
Expand All @@ -134,7 +134,7 @@ async fn prop_editor_validation(ctx: &mut DalContext) {
"message": "\"value\" must be less than or equal to 2",
}
}),
extract_value_and_validation(prop_view)
extract_value_and_validation(prop_view).expect("could not extract")
);
}

Expand Down Expand Up @@ -189,7 +189,7 @@ async fn validation_on_dependent_value(ctx: &mut DalContext) {
.expect("could not get value");

// Check validations and values
let source_result = extract_value_and_validation(source_prop_view);
let source_result = extract_value_and_validation(source_prop_view).expect("could not extract");
assert_eq!(
json!({
"value": 1,
Expand All @@ -202,7 +202,8 @@ async fn validation_on_dependent_value(ctx: &mut DalContext) {
source_result
);

let destination_result = extract_value_and_validation(destination_prop_view);
let destination_result =
extract_value_and_validation(destination_prop_view).expect("could not extract");
assert_eq!(source_result, destination_result,);

AttributeValue::update(ctx, av_id, Some(json!(3)))
Expand All @@ -224,7 +225,7 @@ async fn validation_on_dependent_value(ctx: &mut DalContext) {
.get_value(prop_path)
.expect("could not get value");

let source_result = extract_value_and_validation(source_prop_view);
let source_result = extract_value_and_validation(source_prop_view).expect("could not extract");
assert_eq!(
json!({
"value": 3,
Expand All @@ -237,7 +238,8 @@ async fn validation_on_dependent_value(ctx: &mut DalContext) {
source_result
);

let destination_result = extract_value_and_validation(destination_prop_view);
let destination_result =
extract_value_and_validation(destination_prop_view).expect("could not extract");
assert_eq!(source_result, destination_result,);
}

Expand Down Expand Up @@ -387,17 +389,3 @@ async fn validation_qualification(ctx: &mut DalContext) {
serde_json::to_value(validation_qualification).expect("serialise qualification")
);
}

fn extract_value_and_validation(prop_editor_value: serde_json::Value) -> serde_json::Value {
let value = prop_editor_value
.get("value")
.expect("get value from property editor value");
let validation = prop_editor_value
.get("validation")
.expect("get validation from property editor value");

json!({
"value": value,
"validation": validation,
})
}

0 comments on commit 8f32217

Please sign in to comment.