Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure API requests with ForceChangeset always flip creatingChangeset back off on failure #4988

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ This template should help get you started developing with Vue 3 and Typescript i

## IDE Setup Instructions
### [VSCode](https://code.visualstudio.com/) (preferred)
- Install [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) plugin and [Typescript Volar](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) plugin
- Install [Volar](https://marketplace.visualstudio.com/items?itemName=vue.volar) plugin and [Typescript Volar](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) plugin
- and disable Vetur if installed
- Enable TS "takeover mode" (see [here](https://github.com/johnsoncodehk/volar/discussions/471))
- run "Extensions: Show built-in extensions" from command pallete
Expand Down
47 changes: 16 additions & 31 deletions app/web/src/store/asset.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ import { PropKind } from "@/api/sdf/dal/prop";
import { nonNullable } from "@/utils/typescriptLinter";
import { ChangeSetId } from "@/api/sdf/dal/change_set";
import { useFuncStore } from "./func/funcs.store";
import { useChangeSetsStore } from "./change_sets.store";
import {
useChangeSetsStore,
forceChangeSetApiRequest,
} from "./change_sets.store";
import { useModuleStore } from "./module.store";
import { useRealtimeStore } from "./realtime/realtime.store";
import handleStoreError from "./errors";
Expand Down Expand Up @@ -342,11 +345,10 @@ export const useAssetStore = (forceChangeSetId?: ChangeSetId) => {
},

async CREATE_VARIANT(name: string) {
if (changeSetStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetId === changeSetStore.headChangeSetId)
changeSetStore.creatingChangeSet = true;
return new ApiRequest<SchemaVariant, SchemaVariantCreateRequest>({
return forceChangeSetApiRequest<
SchemaVariant,
SchemaVariantCreateRequest
>({
method: "post",
url: "/variant/create_variant",
params: {
Expand All @@ -365,12 +367,10 @@ export const useAssetStore = (forceChangeSetId?: ChangeSetId) => {
},

async CLONE_VARIANT(schemaVariantId: SchemaVariantId, name: string) {
if (changeSetStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetStore.headSelected)
changeSetStore.creatingChangeSet = true;

return new ApiRequest<SchemaVariant, SchemaVariantCloneRequest>({
return forceChangeSetApiRequest<
SchemaVariant,
SchemaVariantCloneRequest
>({
method: "post",
keyRequestStatusBy: schemaVariantId,
url: "/variant/clone_variant",
Expand Down Expand Up @@ -439,7 +439,7 @@ export const useAssetStore = (forceChangeSetId?: ChangeSetId) => {
`cant save locked schema variant (${schemaVariant.displayName},${schemaVariant.schemaVariantId})`,
);

return new ApiRequest<
return forceChangeSetApiRequest<
{ success: boolean; assetFuncId: FuncId },
SchemaVariantSaveRequest
>({
Expand All @@ -460,17 +460,12 @@ export const useAssetStore = (forceChangeSetId?: ChangeSetId) => {
});
},
async REGENERATE_VARIANT(schemaVariantId: SchemaVariantId) {
if (changeSetStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetStore.headSelected)
changeSetStore.creatingChangeSet = true;

this.detachmentWarnings = [];
const variant = this.variantFromListById[schemaVariantId];
if (!variant)
throw new Error(`${schemaVariantId} Variant does not exist`);

return new ApiRequest<{
return forceChangeSetApiRequest<{
schemaVariantId: SchemaVariantId;
}>({
method: "post",
Expand Down Expand Up @@ -498,14 +493,9 @@ export const useAssetStore = (forceChangeSetId?: ChangeSetId) => {
},

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

this.detachmentWarnings = [];

return new ApiRequest<SchemaVariant>({
return forceChangeSetApiRequest<SchemaVariant>({
method: "post",
url: API_PREFIX.concat([id]),
keyRequestStatusBy: id,
Expand Down Expand Up @@ -543,12 +533,7 @@ export const useAssetStore = (forceChangeSetId?: ChangeSetId) => {
});
},
async DELETE_UNLOCKED_VARIANT(id: SchemaVariantId) {
if (changeSetStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetStore.headSelected)
changeSetStore.creatingChangeSet = true;

return new ApiRequest<SchemaVariant>({
return forceChangeSetApiRequest<SchemaVariant>({
method: "delete",
url: API_PREFIX.concat([id]),
keyRequestStatusBy: id,
Expand Down
34 changes: 33 additions & 1 deletion app/web/src/store/change_sets.store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { defineStore } from "pinia";
import * as _ from "lodash-es";
import { watch } from "vue";
import { ApiRequest, addStoreHooks, URLPattern } from "@si/vue-lib/pinia";
import {
ApiRequest,
addStoreHooks,
URLPattern,
ApiRequestDescription,
} from "@si/vue-lib/pinia";
import { useToast } from "vue-toastification";
import { ulid } from "ulid";
import {
Expand Down Expand Up @@ -696,3 +701,30 @@ export function useChangeSetsStore() {
}),
)();
}

/**
* Perform an API request that will automatically create a new changeset.
*
* This will set `creatingChangeSet` to true, and will set it back to false if the
* request fails.
*/
export function forceChangeSetApiRequest<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Response = any,
RequestParams = Record<string, unknown>,
>(requestSpec: ApiRequestDescription<Response, RequestParams>) {
const changeSetsStore = useChangeSetsStore();
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetsStore.headSelected) changeSetsStore.creatingChangeSet = true;

return new ApiRequest({
...requestSpec,
onFail: (response) => {
changeSetsStore.creatingChangeSet = false;
if (requestSpec.onFail) {
requestSpec.onFail(response);
}
},
});
},
40 changes: 16 additions & 24 deletions app/web/src/store/component_attributes.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import {
import { ComponentId } from "@/api/sdf/dal/component";
import { ComponentType } from "@/api/sdf/dal/schema";
import handleStoreError from "./errors";
import { useChangeSetsStore } from "./change_sets.store";
import {
useChangeSetsStore,
forceChangeSetApiRequest,
} from "./change_sets.store";
import { useRealtimeStore } from "./realtime/realtime.store";
import { useComponentsStore } from "./components.store";

Expand Down Expand Up @@ -249,12 +252,9 @@ export const useComponentAttributesStore = (componentId: ComponentId) => {
async REMOVE_PROPERTY_VALUE(
removePayload: DeletePropertyEditorValueArgs,
) {
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetId === changeSetsStore.headChangeSetId)
changeSetsStore.creatingChangeSet = true;

return new ApiRequest<{ success: true }>({
return forceChangeSetApiRequest<{
success: true;
}>({
method: "post",
url: "component/delete_property_editor_value",
params: {
Expand All @@ -270,11 +270,6 @@ export const useComponentAttributesStore = (componentId: ComponentId) => {
| { update: UpdatePropertyEditorValueArgs }
| { insert: InsertPropertyEditorValueArgs },
) {
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetId === changeSetsStore.headChangeSetId)
changeSetsStore.creatingChangeSet = true;

const isInsert = "insert" in updatePayload;

// If the valueid for this update does not exist in the values tree,
Expand All @@ -289,7 +284,9 @@ export const useComponentAttributesStore = (componentId: ComponentId) => {
return;
}

return new ApiRequest<{ success: true }>({
return forceChangeSetApiRequest<{
success: true;
}>({
method: "post",
url: isInsert
? "component/insert_property_editor_value"
Expand All @@ -301,11 +298,6 @@ export const useComponentAttributesStore = (componentId: ComponentId) => {
});
},
async SET_COMPONENT_TYPE(payload: SetTypeArgs) {
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetId === changeSetsStore.headChangeSetId)
changeSetsStore.creatingChangeSet = true;

// NOTE Since views came in overriding geometries on this operation
// became way more complex. Also frames start at the size of the
// original component so this is not going to be a problem for now.
Expand Down Expand Up @@ -390,7 +382,9 @@ export const useComponentAttributesStore = (componentId: ComponentId) => {
// };
// }

return new ApiRequest<{ success: true }>({
return forceChangeSetApiRequest<{
success: true;
}>({
method: "post",
url: "component/set_type",
params: {
Expand All @@ -402,11 +396,9 @@ export const useComponentAttributesStore = (componentId: ComponentId) => {
async RESET_PROPERTY_VALUE(
resetPayload: ResetPropertyEditorValueArgs,
) {
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetId === changeSetsStore.headChangeSetId)
changeSetsStore.creatingChangeSet = true;
return new ApiRequest<{ success: true }>({
return forceChangeSetApiRequest<{
success: true;
}>({
method: "post",
url: "component/restore_default_function",
params: {
Expand Down
35 changes: 10 additions & 25 deletions app/web/src/store/components.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ import { CodeView } from "@/api/sdf/dal/code_view";
import ComponentUpgrading from "@/components/toasts/ComponentUpgrading.vue";
import { nonNullable } from "@/utils/typescriptLinter";
import handleStoreError from "./errors";
import { useChangeSetsStore } from "./change_sets.store";
import {
useChangeSetsStore,
forceChangeSetApiRequest,
} from "./change_sets.store";
import { useAssetStore } from "./asset.store";
import { useRealtimeStore } from "./realtime/realtime.store";
import { useWorkspacesStore } from "./workspaces.store";
Expand Down Expand Up @@ -672,11 +675,6 @@ export const useComponentsStore = (forceChangeSetId?: ChangeSetId) => {
from: { componentId: ComponentNodeId; socketId: SocketId },
to: { componentId: ComponentNodeId; socketId: SocketId },
) {
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetId === changeSetsStore.headChangeSetId)
changeSetsStore.creatingChangeSet = true;

const timestamp = new Date().toISOString();

const newEdge = edgeFromRawEdge(false)({
Expand All @@ -692,7 +690,7 @@ export const useComponentsStore = (forceChangeSetId?: ChangeSetId) => {
},
});

return new ApiRequest({
return forceChangeSetApiRequest({
method: "post",
url: "diagram/create_connection",
params: {
Expand Down Expand Up @@ -823,12 +821,7 @@ export const useComponentsStore = (forceChangeSetId?: ChangeSetId) => {
toComponentId: ComponentId,
fromComponentId: ComponentId,
) {
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetId === changeSetsStore.headChangeSetId)
changeSetsStore.creatingChangeSet = true;

return new ApiRequest({
return forceChangeSetApiRequest({
method: "post",
url: "diagram/delete_connection",
keyRequestStatusBy: edgeId,
Expand Down Expand Up @@ -885,12 +878,9 @@ export const useComponentsStore = (forceChangeSetId?: ChangeSetId) => {
componentIds: ComponentId[],
forceErase = false,
) {
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetId === changeSetsStore.headChangeSetId)
changeSetsStore.creatingChangeSet = true;

return new ApiRequest<Record<ComponentId, boolean>>({
return forceChangeSetApiRequest<
Record<ComponentId, boolean>
>({
method: "post",
url: "diagram/delete_components",
keyRequestStatusBy: componentIds,
Expand Down Expand Up @@ -940,12 +930,7 @@ export const useComponentsStore = (forceChangeSetId?: ChangeSetId) => {
},

async RESTORE_COMPONENTS(...components: ComponentId[]) {
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetId === changeSetsStore.headChangeSetId)
changeSetsStore.creatingChangeSet = true;

return new ApiRequest({
return forceChangeSetApiRequest({
method: "post",
url: "diagram/remove_delete_intent",
keyRequestStatusBy: Object.keys(components),
Expand Down
Loading