Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
24 changes: 22 additions & 2 deletions apps/builder/app/builder/features/pages/page-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ROOT_FOLDER_ID,
type Page,
SYSTEM_VARIABLE_ID,
Resource,
} from "@webstudio-is/sdk";
import {
cleanupChildRefsMutable,
Expand All @@ -23,11 +24,12 @@ import {
$dataSourceVariables,
$dataSources,
$pages,
$resourceValues,
$resources,
} from "~/shared/nano-states";
import { registerContainers } from "~/shared/sync";
import { $awareness } from "~/shared/awareness";
import { updateCurrentSystem } from "~/shared/system";
import { $resourcesCache, getResourceKey } from "~/shared/resources";

setEnv("*");
registerContainers();
Expand Down Expand Up @@ -521,7 +523,25 @@ test("page root scope should use variable and resource values", () => {
$dataSourceVariables.set(
new Map([["valueVariableId", "value variable value"]])
);
$resourceValues.set(new Map([["resourceId", "resource variable value"]]));
const resourceKey = getResourceKey({
name: "my-resource",
url: "",
searchParams: [],
method: "get",
headers: [],
});
$resources.set(
toMap<Resource>([
{
id: "resourceId",
name: "my-resource",
url: `""`,
method: "get",
headers: [],
},
])
);
$resourcesCache.set(new Map([[resourceKey, "resource variable value"]]));
expect($pageRootScope.get()).toEqual({
aliases: new Map([
["$ws$system", "system"],
Expand Down
68 changes: 40 additions & 28 deletions apps/builder/app/builder/features/settings-panel/resource-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export const parseResource = ({
formData,
}: {
id: string;
name: string;
name?: string;
formData: FormData;
}) => {
const searchParamNames = formData.getAll("search-param-name") as string[];
Expand All @@ -84,7 +84,7 @@ export const parseResource = ({
const headerValues = formData.getAll("header-value") as string[];
return Resource.parse({
id,
name,
name: name ?? formData.get("name"),
url: formData.get("url"),
searchParams: searchParamNames
.map((name, index) => ({ name, value: searchParamValues[index] }))
Expand Down Expand Up @@ -175,17 +175,21 @@ export const UrlField = ({
}
try {
const url = new URL(value);
const searchParams: Resource["searchParams"] = [];
for (const [name, value] of url.searchParams) {
searchParams.push({ name, value: JSON.stringify(value) });
if (url.searchParams.size > 0) {
const searchParams: Resource["searchParams"] = [];
for (const [name, value] of url.searchParams) {
searchParams.push({ name, value: JSON.stringify(value) });
}
// remove all search params from url
url.search = "";
// update text value as string literal
onChange(JSON.stringify(url.href), searchParams);
return;
}
// remove all search params from url
url.search = "";
// update text value as string literal
onChange(JSON.stringify(url.href), searchParams);
} catch {
onChange(JSON.stringify(value));
// serialize without changes when url is invalid
}
onChange(JSON.stringify(value));
}}
onBlur={(event) => event.currentTarget.checkValidity()}
onInvalid={(event) =>
Expand Down Expand Up @@ -515,9 +519,9 @@ export const getResourceScopeForInstance = ({
}
if (dataSource) {
const name = encodeDataVariableId(dataSourceId);
variableValues.set(dataSourceId, value);
scope[name] = value;
aliases.set(name, dataSource.name);
variableValues.set(dataSource.name, value);
}
}
}
Expand All @@ -544,7 +548,7 @@ const getVariableInstanceKey = ({
return getInstanceKey(instancePath[0].instanceSelector);
};

const useScope = ({ variable }: { variable?: DataSource }) => {
export const useResourceScope = ({ variable }: { variable?: DataSource }) => {
return useStore(
useMemo(
() =>
Expand All @@ -561,22 +565,32 @@ const useScope = ({ variable }: { variable?: DataSource }) => {
variableValuesByInstanceSelector,
dataSources
) => {
const { scope, aliases } = getResourceScopeForInstance({
page,
instanceKey: getVariableInstanceKey({
variable,
instancePath,
}),
dataSources,
variableValuesByInstanceSelector,
});
const { scope, aliases, variableValues } =
getResourceScopeForInstance({
page,
instanceKey: getVariableInstanceKey({
variable,
instancePath,
}),
dataSources,
variableValuesByInstanceSelector,
});
// prevent showing currently edited variable in suggestions
// to avoid cirular dependeny
const newScope = { ...scope };
const newAliases = new Map(aliases);
const newVariableValues = new Map(variableValues);
if (variable) {
delete newScope[encodeDataVariableId(variable.id)];
const key = encodeDataVariableId(variable.id);
delete newScope[key];
newAliases.delete(key);
newVariableValues.delete(variable.name);
}
return { scope: newScope, aliases };
return {
scope: newScope,
aliases: newAliases,
variableValues: newVariableValues,
};
}
),
[variable]
Expand Down Expand Up @@ -706,7 +720,7 @@ export const ResourceForm = forwardRef<
undefined | PanelApi,
{ variable?: DataSource }
>(({ variable }, ref) => {
const { scope, aliases } = useScope({ variable });
const { scope, aliases } = useResourceScope({ variable });

const resources = useStore($resources);
const resource =
Expand Down Expand Up @@ -739,16 +753,14 @@ export const ResourceForm = forwardRef<
if (scopeInstanceId === undefined) {
return;
}
const name = z.string().parse(formData.get("name"));
const newResource = parseResource({
id: resource?.id ?? nanoid(),
name,
formData,
});
const newVariable: DataSource = {
id: variable?.id ?? nanoid(),
scopeInstanceId,
name,
name: newResource.name,
type: "resource",
resourceId: newResource.id,
};
Expand Down Expand Up @@ -942,7 +954,7 @@ export const GraphqlResourceForm = forwardRef<
undefined | PanelApi,
{ variable?: DataSource }
>(({ variable }, ref) => {
const { scope, aliases } = useScope({ variable });
const { scope, aliases } = useResourceScope({ variable });

const resources = useStore($resources);
const resource =
Expand Down
Loading
Loading