diff --git a/app/web/src/components/AssetCard.vue b/app/web/src/components/AssetCard.vue
index 6e8ae230c7..f9380bbd9b 100644
--- a/app/web/src/components/AssetCard.vue
+++ b/app/web/src/components/AssetCard.vue
@@ -49,6 +49,16 @@
@click="updateAsset"
/>
+
+
+
(
undefined,
);
+const hasEditingVersion = computed(
+ () =>
+ assetStore.unlockedVariantIdForId[asset.value?.schemaVariantId ?? ""] !==
+ undefined,
+);
+
const asset = computed(
(): SchemaVariant | undefined =>
assetStore.variantFromListById[props.assetId],
@@ -174,4 +195,22 @@ const unlock = async () => {
}
}
};
+
+const deleteUnlockedVariantReqStatus = assetStore.getRequestStatus(
+ "DELETE_UNLOCKED_VARIANT",
+ asset.value?.schemaVariantId,
+);
+const deleteUnlockedVariant = async () => {
+ if (asset.value) {
+ const resp = await assetStore.DELETE_UNLOCKED_VARIANT(
+ asset.value.schemaVariantId,
+ );
+ if (resp.result.success) {
+ assetStore.setSchemaVariantSelection("");
+ router.replace({
+ name: "workspace-lab-assets",
+ });
+ }
+ }
+};
diff --git a/app/web/src/store/asset.store.ts b/app/web/src/store/asset.store.ts
index 7750be7a6b..44487f65cd 100644
--- a/app/web/src/store/asset.store.ts
+++ b/app/web/src/store/asset.store.ts
@@ -488,11 +488,34 @@ export const useAssetStore = () => {
const savedAssetIdx = this.variantList.findIndex(
(a) => a.schemaVariantId === variant.schemaVariantId,
);
+
if (savedAssetIdx === -1) this.variantList.push(variant);
else this.variantList.splice(savedAssetIdx, 1, variant);
},
});
},
+ async DELETE_UNLOCKED_VARIANT(id: SchemaVariantId) {
+ if (changeSetsStore.creatingChangeSet)
+ throw new Error("race, wait until the change set is created");
+ if (changeSetsStore.headSelected)
+ changeSetsStore.creatingChangeSet = true;
+
+ return new ApiRequest({
+ method: "post",
+ url: `v2/workspaces/${workspaceId}/change-sets/${changeSetId}/schema-variants/${id}/delete_unlocked_variant`,
+ keyRequestStatusBy: id,
+ params: {
+ // ...visibility,
+ },
+ onSuccess: (variant) => {
+ const deletedVariantIdx = this.variantList.findIndex(
+ (a) => a.schemaVariantId === variant.schemaVariantId,
+ );
+ if (deletedVariantIdx !== -1)
+ this.variantList.splice(deletedVariantIdx, 1, variant);
+ },
+ });
+ },
},
async onActivated() {
await Promise.all([
@@ -531,8 +554,8 @@ export const useAssetStore = () => {
},
{
eventType: "SchemaVariantDeleted",
- callback: (data, metadata) => {
- if (metadata.change_set_id !== changeSetId) return;
+ callback: (data) => {
+ if (data.changeSetId !== changeSetId) return;
const savedAssetIdx = this.variantList.findIndex(
(a) => a.schemaVariantId === data.schemaVariantId,
);
diff --git a/app/web/src/store/realtime/realtime_events.ts b/app/web/src/store/realtime/realtime_events.ts
index 5ff78ab019..24214dcc5e 100644
--- a/app/web/src/store/realtime/realtime_events.ts
+++ b/app/web/src/store/realtime/realtime_events.ts
@@ -261,6 +261,7 @@ export type WsEventPayloadMap = {
SchemaVariantDeleted: {
schemaVariantId: SchemaVariantId;
schemaId: SchemaId;
+ changeSetId: ChangeSetId;
};
SchemaVariantCreated: SchemaVariant;
SchemaVariantUpdated: SchemaVariant;
diff --git a/lib/dal/src/schema/variant.rs b/lib/dal/src/schema/variant.rs
index ca5b3602bd..58cbc73a6b 100644
--- a/lib/dal/src/schema/variant.rs
+++ b/lib/dal/src/schema/variant.rs
@@ -303,6 +303,7 @@ pub struct SchemaVariantSavedPayload {
pub struct SchemaVariantDeletedPayload {
schema_variant_id: SchemaVariantId,
schema_id: SchemaId,
+ change_set_id: ChangeSetId,
}
impl WsEvent {
@@ -333,6 +334,7 @@ impl WsEvent {
WsPayload::SchemaVariantDeleted(SchemaVariantDeletedPayload {
schema_variant_id,
schema_id,
+ change_set_id: ctx.change_set_id(),
}),
)
.await
@@ -553,12 +555,27 @@ impl SchemaVariant {
return Err(SchemaVariantError::SchemaVariantLocked(schema_variant_id));
}
+ let schema = variant.schema(ctx).await?;
+ dbg!(&schema);
+
// Firstly we want to delete the asset func
let asset_func = variant.get_asset_func(ctx).await?;
Func::delete_by_id(ctx, asset_func.id).await?;
- // now we want to delete the schema variant
let workspace_snapshot = ctx.workspace_snapshot()?;
+
+ if let Some(default_schema_variant_id) = schema.get_default_schema_variant_id(ctx).await? {
+ dbg!(&default_schema_variant_id);
+ if variant.id == default_schema_variant_id {
+ dbg!("Deletion of the schema");
+ dbg!(&schema);
+ workspace_snapshot
+ .remove_node_by_id(ctx.vector_clock_id()?, schema.id())
+ .await?;
+ }
+ }
+
+ // now we want to delete the schema variant
workspace_snapshot
.remove_node_by_id(ctx.vector_clock_id()?, variant.id)
.await?;
diff --git a/lib/sdf-server/src/server/service/v2/variant.rs b/lib/sdf-server/src/server/service/v2/variant.rs
index d6847416ba..115d549efa 100644
--- a/lib/sdf-server/src/server/service/v2/variant.rs
+++ b/lib/sdf-server/src/server/service/v2/variant.rs
@@ -4,7 +4,7 @@ use axum::{
routing::{get, post},
Router,
};
-use dal::{ChangeSetError, SchemaVariantId};
+use dal::{ChangeSetError, SchemaVariantId, WsEventError};
use telemetry::prelude::*;
use thiserror::Error;
@@ -19,6 +19,8 @@ mod list_variants;
pub enum SchemaVariantsAPIError {
#[error("cannot delete locked schema variant: {0}")]
CannotDeleteLockedSchemaVariant(SchemaVariantId),
+ #[error("cannot delete a schema variant that has attached components")]
+ CannotDeleteVariantWithComponents,
#[error("change set error: {0}")]
ChangeSet(#[from] ChangeSetError),
#[error("hyper error: {0}")]
@@ -29,6 +31,8 @@ pub enum SchemaVariantsAPIError {
Serde(#[from] serde_json::Error),
#[error("transactions error: {0}")]
Transactions(#[from] dal::TransactionsError),
+ #[error("ws event error: {0}")]
+ WsEvent(#[from] WsEventError),
}
pub type SchemaVariantsAPIResult = std::result::Result;
@@ -57,7 +61,7 @@ pub fn v2_routes() -> Router {
.route("/", get(list_variants::list_variants))
.route("/:schema_variant_id", get(get_variant::get_variant))
.route(
- "/:schema_variant_id/delete_unlocked_copy",
+ "/:schema_variant_id/delete_unlocked_variant",
post(delete_unlocked_variant::delete_unlocked_variant),
)
}
diff --git a/lib/sdf-server/src/server/service/v2/variant/delete_unlocked_variant.rs b/lib/sdf-server/src/server/service/v2/variant/delete_unlocked_variant.rs
index c4f2b498a1..a1c1e0e7e2 100644
--- a/lib/sdf-server/src/server/service/v2/variant/delete_unlocked_variant.rs
+++ b/lib/sdf-server/src/server/service/v2/variant/delete_unlocked_variant.rs
@@ -2,14 +2,14 @@ use axum::{
extract::{OriginalUri, Path},
response::IntoResponse,
};
-use dal::{ChangeSet, ChangeSetId, SchemaVariant, SchemaVariantId, WorkspacePk};
+use dal::{ChangeSet, ChangeSetId, SchemaVariant, SchemaVariantId, WorkspacePk, WsEvent};
use crate::server::{
extract::{AccessBuilder, HandlerContext, PosthogClient},
tracking::track,
};
-use super::SchemaVariantsAPIResult;
+use super::{SchemaVariantsAPIError, SchemaVariantsAPIResult};
pub async fn delete_unlocked_variant(
HandlerContext(builder): HandlerContext,
@@ -27,9 +27,20 @@ pub async fn delete_unlocked_variant(
.await?;
let force_change_set_id = ChangeSet::force_new(&mut ctx).await?;
let schema_variant = SchemaVariant::get_by_id_or_error(&ctx, schema_variant_id).await?;
+ let schema = schema_variant.schema(&ctx).await?;
+
+ let connected_components = SchemaVariant::list_component_ids(&ctx, schema_variant_id).await?;
+ if !connected_components.is_empty() {
+ return Err(SchemaVariantsAPIError::CannotDeleteVariantWithComponents);
+ }
SchemaVariant::cleanup_unlocked_variant(&ctx, schema_variant_id).await?;
+ WsEvent::schema_variant_deleted(&ctx, schema.id(), schema_variant_id)
+ .await?
+ .publish_on_commit(&ctx)
+ .await?;
+
track(
&posthog_client,
&ctx,