Skip to content

Commit

Permalink
merge: #4030
Browse files Browse the repository at this point in the history
4030: feat(dal,sdf,web): Endpoint to create unlocked sv copy r=vbustamante a=vbustamante

also:
- Add is_locked, make display_name required, rename name to version on schema variant
- Add upgrade code on schema variant content
- Unlock variant button on UI, behind feature flag

Co-authored-by: Victor Bustamante <victor@systeminit.com>
  • Loading branch information
si-bors-ng[bot] and vbustamante authored Jun 26, 2024
2 parents 0f785ed + 640383a commit 558273d
Show file tree
Hide file tree
Showing 23 changed files with 589 additions and 129 deletions.
68 changes: 43 additions & 25 deletions app/web/src/components/AssetDetailsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,56 @@
<div
class="flex flex-row items-center gap-xs p-xs border-b dark:border-neutral-600"
>
<VButton
v-if="useFeatureFlagsStore().IMMUTABLE_SCHEMA_VARIANTS"
icon="clipboard-copy"
label="Unlock"
size="md"
tone="neutral"
@click="unlock"
/>

<VButton
:loading="execAssetReqStatus.isPending"
loadingText="Regenerating Asset..."
label="Regenerate Asset"
successText="Successful"
:requestStatus="execAssetReqStatus"
tone="action"
icon="bolt"
label="Regenerate Asset"
loadingText="Regenerating Asset..."
size="md"
successText="Successful"
tone="action"
@click="executeAsset"
/>
<VButton
label="Clone"
tone="neutral"
icon="clipboard-copy"
label="Clone"
size="md"
tone="neutral"
@click="() => cloneAssetModalRef?.modal?.open()"
/>
</div>
<AssetNameModal
ref="cloneAssetModalRef"
title="Asset Name"
buttonLabel="Clone Asset"
title="Asset Name"
@submit="cloneAsset"
/>

<ErrorMessage
v-for="(warning, index) in assetStore.detachmentWarnings"
:key="warning.message"
class="mx-1"
:class="{ 'cursor-pointer': !!warning.kind }"
class="mx-1"
icon="alert-triangle"
tone="warning"
@click="openAttachModal(warning)"
>
{{ warning.message }}
<VButton
tone="destructive"
buttonRank="tertiary"
icon="trash"
size="xs"
tone="destructive"
@click.stop="assetStore.detachmentWarnings.splice(index, 1)"
/>
</ErrorMessage>
Expand All @@ -64,59 +73,59 @@
<VormInput
id="schemaName"
v-model="editingAsset.schemaName"
type="text"
label="Asset Name"
compact
label="Asset Name"
placeholder="(mandatory) Provide the asset a name"
type="text"
@blur="updateAsset"
/>
<VormInput
id="name"
v-model="editingAsset.name"
type="text"
label="Asset Version Name"
compact
disabled
label="Asset Version Name"
placeholder="(mandatory) Provide the asset version a name"
@blur="updateAsset"
type="text"
/>

<VormInput
id="displayName"
v-model="editingAsset.displayName"
type="text"
label="Display name"
compact
label="Display name"
placeholder="(optional) Provide the asset version a display name"
type="text"
@blur="updateAsset"
/>
<VormInput
id="category"
v-model="editingAsset.category"
type="text"
label="Category"
compact
label="Category"
placeholder="(mandatory) Provide a category for the asset"
type="text"
@blur="updateAsset"
/>
<VormInput
id="componentType"
v-model="editingAsset.componentType"
type="dropdown"
:options="componentTypeOptions"
compact
label="Component Type"
type="dropdown"
@change="updateAsset"
/>
<VormInput
id="description"
v-model="editingAsset.description"
type="textarea"
label="Description"
compact
label="Description"
placeholder="(optional) Provide a brief description of the asset"
type="textarea"
@blur="updateAsset"
/>
<VormInput type="container" compact label="color">
<VormInput compact label="color" type="container">
<ColorPicker
id="color"
v-model="editingAsset.color"
Expand All @@ -127,10 +136,10 @@
<VormInput
id="link"
v-model="editingAsset.link"
type="url"
label="Documentation Link"
compact
label="Documentation Link"
placeholder="(optional) Provide a documentation link for the asset"
type="url"
@blur="updateAsset"
/>
</Stack>
Expand All @@ -146,10 +155,10 @@
</div>
<Modal
ref="executeAssetModalRef"
size="sm"
:title="
editingAsset && editingAsset.id ? 'Asset Updated' : 'New Asset Created'
"
size="sm"
@closeComplete="closeHandler"
>
{{
Expand Down Expand Up @@ -177,6 +186,7 @@ import { FuncKind } from "@/api/sdf/dal/func";
import { useAssetStore } from "@/store/asset.store";
import { FuncId } from "@/store/func/funcs.store";
import { ComponentType } from "@/api/sdf/dal/diagram";
import { useFeatureFlagsStore } from "@/store/feature_flags.store";
import ColorPicker from "./ColorPicker.vue";
import AssetFuncAttachModal from "./AssetFuncAttachModal.vue";
import AssetNameModal from "./AssetNameModal.vue";
Expand Down Expand Up @@ -244,6 +254,14 @@ const executeAsset = async () => {
}
};
const unlock = async () => {
if (assetStore.selectedAsset?.defaultSchemaVariantId) {
await assetStore.CREATE_UNLOCKED_COPY(
assetStore.selectedAsset?.defaultSchemaVariantId,
);
}
};
const closeHandler = () => {
assetStore.executeAssetTaskId = undefined;
};
Expand Down
20 changes: 20 additions & 0 deletions app/web/src/store/asset.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import router from "@/router";
import { PropKind } from "@/api/sdf/dal/prop";
import { ComponentType } from "@/api/sdf/dal/diagram";
import { nonNullable } from "@/utils/typescriptLinter";
import { SchemaVariantId } from "@/api/sdf/dal/schema";
import { useChangeSetsStore } from "./change_sets.store";
import { useRealtimeStore } from "./realtime/realtime.store";
import {
Expand Down Expand Up @@ -464,6 +465,25 @@ export const useAssetStore = () => {
},
});
},

async CREATE_UNLOCKED_COPY(id: SchemaVariantId) {
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetsStore.headSelected)
changeSetsStore.creatingChangeSet = true;

this.detachmentWarnings = [];

return new ApiRequest<null>({
method: "post",
url: "/variant/create_unlocked_copy",
keyRequestStatusBy: id,
params: {
...visibility,
id,
},
});
},
},
async onActivated() {
await this.LOAD_ASSET_LIST();
Expand Down
1 change: 1 addition & 0 deletions app/web/src/store/feature_flags.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { posthog } from "@/utils/posthog";
const FLAG_MAPPING = {
// STORE_FLAG_NAME: "posthogFlagName",
MODULES_TAB: "modules_tab",
IMMUTABLE_SCHEMA_VARIANTS: "immutable_schema_variants",
};

type FeatureFlags = keyof typeof FLAG_MAPPING;
Expand Down
21 changes: 21 additions & 0 deletions lib/dal/src/attribute/prototype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,27 @@ impl AttributePrototype {
}
Ok(sources)
}

pub async fn list_arguments_for_id(
ctx: &DalContext,
ap_id: AttributePrototypeId,
) -> AttributePrototypeResult<Vec<AttributePrototypeArgumentId>> {
let mut apas = vec![];

let snap = ctx.workspace_snapshot()?;

for idx in snap
.outgoing_targets_for_edge_weight_kind(
ap_id,
EdgeWeightKindDiscriminants::PrototypeArgument,
)
.await?
{
apas.push(snap.get_node_weight(idx).await?.id().into())
}

Ok(apas)
}
}

#[remain::sorted]
Expand Down
23 changes: 23 additions & 0 deletions lib/dal/src/attribute/prototype/argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ pub enum AttributePrototypeArgumentError {
NodeWeight(#[from] NodeWeightError),
#[error("no targets for prototype argument: {0}")]
NoTargets(AttributePrototypeArgumentId),
#[error("prototype argument not found for attribute prototype {0} and func arg {1}")]
NotFoundForApAndFuncArg(AttributePrototypeId, FuncArgumentId),
#[error("serde json error: {0}")]
Serde(#[from] serde_json::Error),
#[error("transactions error: {0}")]
Expand Down Expand Up @@ -322,6 +324,27 @@ impl AttributePrototypeArgument {
Err(AttributePrototypeArgumentError::MissingFuncArgument(apa_id))
}

pub async fn find_by_func_argument_id_and_attribute_prototype_id(
ctx: &DalContext,
func_argument_id: FuncArgumentId,
ap_id: AttributePrototypeId,
) -> AttributePrototypeArgumentResult<AttributePrototypeArgumentId> {
// AP --> APA --> Func Arg

for apa_id in AttributePrototype::list_arguments_for_id(ctx, ap_id).await? {
let this_func_arg_id = Self::func_argument_id_by_id(ctx, apa_id).await?;

if this_func_arg_id == func_argument_id {
return Ok(apa_id);
}
}

Err(AttributePrototypeArgumentError::NotFoundForApAndFuncArg(
ap_id,
func_argument_id,
))
}

pub async fn value_source(
&self,
ctx: &DalContext,
Expand Down
2 changes: 1 addition & 1 deletion lib/dal/src/diagram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ impl SummaryDiagramComponent {
schema_name: schema.name().to_owned(),
schema_id: schema.id(),
schema_variant_id: schema_variant.id(),
schema_variant_name: schema_variant.name().to_owned(),
schema_variant_name: schema_variant.version().to_owned(),
schema_category: schema_variant.category().to_owned(),
display_name: component.name(ctx).await?,
position,
Expand Down
1 change: 1 addition & 0 deletions lib/dal/src/history_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl HistoryActor {
HistoryActor::SystemInit => "unknown-backend".to_string(),
}
}

pub async fn email(&self, ctx: &DalContext) -> HistoryEventResult<String> {
Ok(match self {
HistoryActor::SystemInit => "sally@systeminit.com".to_string(),
Expand Down
Loading

0 comments on commit 558273d

Please sign in to comment.