mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-10-29 08:07:48 +09:00
feat: inline variables outside current component/slot (#2778)
Ref https://github.com/webstudio-is/webstudio/issues/2532 Important constrain on the way to custom components to not use data sources defined in other components when copy paste. ## Steps for reproduction 1. Test covers it
This commit is contained in:
1 parent
8d073e598d
commit
a76c29fc05
4 files changed
+76
-2
No files matched your search
@@ -187,6 +187,7 @@ export const { emitCommand, subscribeCommands } = createCommandsEmitter({
|
||||
slice,
|
||||
availableDataSources: findAvailableDataSources(
|
||||
$dataSources.get(),
|
||||
$instances.get(),
|
||||
parentInstanceSelector
|
||||
),
|
||||
beforeTransactionEnd: (rootInstanceId, draft) => {
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
$registeredComponentMetas,
|
||||
$selectedPageId,
|
||||
} from "../nano-states";
|
||||
import { onCopy, onPaste } from "./plugin-instance";
|
||||
import { onCopy, onCut, onPaste } from "./plugin-instance";
|
||||
import { createDefaultPages } from "@webstudio-is/project-build";
|
||||
|
||||
const expectString = expect.any(String) as unknown as string;
|
||||
@@ -629,3 +629,66 @@ test("wrap siblings with span when instance is rich text container", () => {
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
test("inline data source not available in portal when copy paste inside the portal", () => {
|
||||
const instances = toMap([
|
||||
createInstance("body", "Body", [
|
||||
{ type: "id", value: "box" },
|
||||
{ type: "id", value: "portal" },
|
||||
]),
|
||||
createInstance("box", "Box", []),
|
||||
createInstance("portal", portalComponent, [
|
||||
{ type: "id", value: "fragment" },
|
||||
]),
|
||||
createInstance("fragment", "Fragment", []),
|
||||
]);
|
||||
$instances.set(instances);
|
||||
const dataSources = toMap<DataSource>([
|
||||
{
|
||||
id: "variableId",
|
||||
scopeInstanceId: "body",
|
||||
name: "variableName",
|
||||
type: "variable",
|
||||
value: { type: "string", value: "value" },
|
||||
},
|
||||
]);
|
||||
$dataSources.set(dataSources);
|
||||
const props = toMap<Prop>([
|
||||
{
|
||||
id: "propId",
|
||||
instanceId: "box",
|
||||
name: "data-value",
|
||||
type: "expression",
|
||||
value: "$ws$dataSource$variableId",
|
||||
},
|
||||
]);
|
||||
$props.set(props);
|
||||
$selectedInstanceSelector.set(["box", "body"]);
|
||||
const clipboardData = onCut() ?? "";
|
||||
$selectedInstanceSelector.set(["fragment", "portal", "body"]);
|
||||
onPaste(clipboardData);
|
||||
expect($instances.get()).toEqual(
|
||||
toMap([
|
||||
createInstance("body", "Body", [{ type: "id", value: "portal" }]),
|
||||
createInstance("portal", portalComponent, [
|
||||
{ type: "id", value: "fragment" },
|
||||
]),
|
||||
createInstance("fragment", "Fragment", [
|
||||
{ type: "id", value: expectString },
|
||||
]),
|
||||
createInstance(expectString, "Box", []),
|
||||
])
|
||||
);
|
||||
expect($dataSources.get()).toEqual(dataSources);
|
||||
expect($props.get()).toEqual(
|
||||
toMap<Prop>([
|
||||
{
|
||||
id: expectString,
|
||||
instanceId: expectString,
|
||||
name: "data-value",
|
||||
type: "expression",
|
||||
value: `"value"`,
|
||||
},
|
||||
])
|
||||
);
|
||||
});
|
||||
@@ -206,6 +206,7 @@ export const onPaste = (clipboardData: string): boolean => {
|
||||
slice: data,
|
||||
availableDataSources: findAvailableDataSources(
|
||||
$dataSources.get(),
|
||||
$instances.get(),
|
||||
instanceSelector
|
||||
),
|
||||
beforeTransactionEnd: (rootInstanceId, draft) => {
|
||||
|
||||
@@ -722,9 +722,18 @@ export const getInstancesSlice = (rootInstanceId: string) => {
|
||||
|
||||
export const findAvailableDataSources = (
|
||||
dataSources: DataSources,
|
||||
instances: Instances,
|
||||
instanceSelector: InstanceSelector
|
||||
) => {
|
||||
const instanceIds = new Set(instanceSelector);
|
||||
// inline data sources not scoped to current portal
|
||||
const instanceIds = new Set();
|
||||
for (const instanceId of instanceSelector) {
|
||||
const instance = instances.get(instanceId);
|
||||
if (instance?.component === portalComponent) {
|
||||
break;
|
||||
}
|
||||
instanceIds.add(instanceId);
|
||||
}
|
||||
const availableDataSources = new Set<DataSource["id"]>();
|
||||
for (const { id, scopeInstanceId } of dataSources.values()) {
|
||||
if (scopeInstanceId && instanceIds.has(scopeInstanceId)) {
|
||||
|
||||
Reference in new issue
Block a user