Skip to content

Commit da37bee

Browse files
committed
feat: add undo/redo in metadata key-pair inspector
1 parent 35c1349 commit da37bee

File tree

2 files changed

+33
-49
lines changed

2 files changed

+33
-49
lines changed

editor/src/editor/layout/inspector/camera/editor.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import { IEditorInspectorImplementationProps } from "../inspector";
99
import { EditorInspectorNumberField } from "../fields/number";
1010
import { EditorInspectorSectionField } from "../fields/section";
1111

12-
import { CustomMetadataInspector } from "../metadata/custom-metadata";
13-
1412
import { FocalLengthInspector } from "./utils/focal";
1513

1614
export class EditorCameraInspector extends Component<IEditorInspectorImplementationProps<EditorCamera>> {
@@ -56,8 +54,6 @@ export class EditorCameraInspector extends Component<IEditorInspectorImplementat
5654
Configure in preferences...
5755
</Button>
5856
</EditorInspectorSectionField>
59-
60-
<CustomMetadataInspector object={this.props.object} />
6157
</>
6258
);
6359
}

editor/src/editor/layout/inspector/metadata/custom-metadata.tsx

Lines changed: 33 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import { IoAddSharp, IoCloseOutline } from "react-icons/io5";
44

55
import { Node } from "babylonjs";
66

7-
import { showAlert, showPrompt } from "../../../../ui/dialog";
87
import { Button } from "../../../../ui/shadcn/ui/button";
8+
import { showAlert, showPrompt } from "../../../../ui/dialog";
9+
10+
import { registerUndoRedo } from "../../../../tools/undoredo";
911

1012
import { EditorInspectorStringField } from "../fields/string";
1113
import { EditorInspectorSectionField } from "../fields/section";
@@ -20,50 +22,32 @@ export interface ICustomMetadataInspectorProps {
2022
*/
2123
export class CustomMetadataInspector extends Component<ICustomMetadataInspectorProps> {
2224
public render(): ReactNode {
23-
2425
const keys = Object.keys(this.props.object.metadata?.customMetadata ?? {});
2526

2627
return (
2728
<EditorInspectorSectionField title="Metadata">
28-
{keys.length === 0 && (
29-
<div className="text-center text-white/50 py-2">
30-
No metadata found. Click "Add" to create a new key-value pair.
31-
</div>
32-
)}
29+
{!keys.length && <div className="text-center text-white/50 py-2">No metadata found. Click "Add" to create a new key-value pair.</div>}
3330

3431
{keys.map((key, index) => (
35-
<div key={index} className="flex items-center gap-2">
32+
<div key={index} className="flex items-center">
3633
<div className="w-full">
37-
<EditorInspectorStringField
38-
label={key}
39-
object={this.props.object.metadata?.customMetadata ?? {}}
40-
property={key}
41-
onChange={() => this.forceUpdate()}
42-
/>
34+
<EditorInspectorStringField label={key} object={this.props.object.metadata?.customMetadata ?? {}} property={key} onChange={() => this.forceUpdate()} />
4335
</div>
4436

45-
<Button
46-
variant="secondary"
47-
className="p-2"
48-
onClick={() => this._handleRemoveKey(key)}
49-
>
37+
<Button variant="ghost" className="p-2" onClick={() => this._handleRemoveKey(key)}>
5038
<IoCloseOutline className="w-4 h-4" />
5139
</Button>
5240
</div>
5341
))}
5442

55-
<Button
56-
variant="secondary"
57-
className="flex items-center gap-2 w-full"
58-
onClick={() => this._handleAddKey()}
59-
>
43+
<Button variant="secondary" className="flex items-center gap-2 w-full" onClick={() => this._handleAddKey()}>
6044
<IoAddSharp className="w-6 h-6" /> Add
6145
</Button>
6246
</EditorInspectorSectionField>
6347
);
6448
}
6549

66-
private async _handleAddKey(): Promise<void> {
50+
private async _handleAddKey(): Promise<unknown> {
6751
const key = await showPrompt("Add Custom Metadata", "Enter the key name for the new metadata:");
6852

6953
if (!key) {
@@ -72,28 +56,23 @@ export class CustomMetadataInspector extends Component<ICustomMetadataInspectorP
7256

7357
// Validate key name
7458
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
75-
showAlert("Invalid Key Name", "Key must start with a letter or underscore and contain only letters, numbers, and underscores.");
76-
return;
59+
return showAlert("Invalid Key Name", "Key must start with a letter or underscore and contain only letters, numbers, and underscores.");
7760
}
7861

7962
// Ensure metadata exists
80-
if (!this.props.object.metadata) {
81-
this.props.object.metadata = {};
82-
}
83-
84-
// Ensure customMetadata exists
85-
if (!this.props.object.metadata.customMetadata) {
86-
this.props.object.metadata.customMetadata = {};
87-
}
63+
this.props.object.metadata ??= {};
64+
this.props.object.metadata.customMetadata ??= {};
8865

8966
// Check if key already exists
9067
if (key in this.props.object.metadata.customMetadata) {
91-
showAlert("Duplicate Key", `Key "${key}" already exists.`);
92-
return;
68+
return showAlert("Duplicate Key", `Key "${key}" already exists.`);
9369
}
9470

95-
// Add new key with empty string value
96-
this.props.object.metadata.customMetadata[key] = "";
71+
registerUndoRedo({
72+
executeRedo: true,
73+
undo: () => delete this.props.object.metadata.customMetadata[key],
74+
redo: () => (this.props.object.metadata.customMetadata[key] = ""),
75+
});
9776

9877
this.forceUpdate();
9978
}
@@ -103,12 +82,21 @@ export class CustomMetadataInspector extends Component<ICustomMetadataInspectorP
10382
return;
10483
}
10584

106-
delete this.props.object.metadata.customMetadata[key];
107-
108-
// Clean up empty customMetadata object
109-
if (Object.keys(this.props.object.metadata.customMetadata).length === 0) {
110-
delete this.props.object.metadata.customMetadata;
111-
}
85+
const oldValue = this.props.object.metadata.customMetadata[key];
86+
87+
registerUndoRedo({
88+
executeRedo: true,
89+
undo: () => {
90+
this.props.object.metadata.customMetadata ??= {};
91+
this.props.object.metadata.customMetadata[key] = oldValue;
92+
},
93+
redo: () => {
94+
delete this.props.object.metadata.customMetadata[key];
95+
if (Object.keys(this.props.object.metadata.customMetadata).length === 0) {
96+
delete this.props.object.metadata.customMetadata;
97+
}
98+
},
99+
});
112100

113101
this.forceUpdate();
114102
}

0 commit comments

Comments
 (0)