Skip to content
This repository was archived by the owner on Feb 6, 2026. It is now read-only.

Commit 256791e

Browse files
si-bors-ng[bot]wendybujalskivbustamante
authored
merge: #3454
3454: feat(dal,web) show if value is set by dynamic function on prop editor backend r=vbustamante a=vbustamante <img src="https://media1.giphy.com/media/I0qyuvxbdzzYc8INP7/giphy.gif"/> This PR also adds commit_and_update_snapshot and connect_components_with_socket_names to the test harness, to diminish verbosity on our tests Co-authored-by: wendybujalski <wendydbujalski@gmail.com> Co-authored-by: Victor Bustamante <victor@systeminit.com>
2 parents 5bfdf7f + 2a80d2f commit 256791e

18 files changed

Lines changed: 1007 additions & 233 deletions

File tree

app/web/src/api/sdf/dal/property_editor.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,11 @@ export interface PropertyEditorValue {
110110
propId: string;
111111
key?: string;
112112
value: unknown;
113-
isFromExternalSource: boolean;
114113
canBeSetBySocket: boolean;
115-
isControlledByIntrinsicFunc: boolean;
114+
isFromExternalSource: boolean;
115+
isControlledByDynamicFunc: boolean;
116+
isControlledByAncestor: boolean;
116117
overridden: boolean;
117-
controllingFuncId: string;
118-
controllingAttributeValueId: string;
119118
ancestorManual: boolean;
120119
// TODO(Wendy) - we also need the default funcId and funcName for this prop to tell the user the default func that was overriden
121120
}

app/web/src/components/AttributesPanel/AttributesPanelItem.vue

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<template>
22
<div
3-
class="attributes-panel-item"
43
:class="{
54
'--section': canHaveChildren,
65
'--input': !canHaveChildren,
@@ -10,20 +9,21 @@
109
'--open': canHaveChildren && isOpen,
1110
'--collapsed': canHaveChildren && !isOpen,
1211
}"
12+
class="attributes-panel-item"
1313
>
1414
<!-- SECTION -->
1515
<div
1616
v-if="canHaveChildren"
17-
@mouseover.stop="onSectionHoverStart"
1817
@mouseleave="onSectionHoverEnd"
18+
@mouseover.stop="onSectionHoverStart"
1919
>
2020
<!-- HEADER -->
2121
<div
22-
class="attributes-panel-item__section-header-wrap"
2322
:style="{
2423
top: topPx,
2524
zIndex: headerZIndex,
2625
}"
26+
class="attributes-panel-item__section-header-wrap"
2727
>
2828
<div
2929
:class="
@@ -47,8 +47,8 @@
4747
</div>
4848

4949
<div
50-
class="attributes-panel-item__section-header"
5150
:style="{ marginLeft: indentPx }"
51+
class="attributes-panel-item__section-header"
5252
@click="toggleOpen(true)"
5353
>
5454
<Icon
@@ -58,8 +58,8 @@
5858
size="none"
5959
/>
6060
<Icon
61-
class="attributes-panel-item__type-icon"
6261
:name="icon"
62+
class="attributes-panel-item__type-icon"
6363
size="none"
6464
/>
6565
<div class="attributes-panel-item__section-header-label">
@@ -130,8 +130,8 @@
130130
<template v-for="source in sourceKinds" :key="source">
131131
<DropdownMenuItem
132132
v-if="source === 'manually' || propSource === source"
133-
:label="source"
134133
:checked="propSource === source"
134+
:label="source"
135135
@click="setSource(source)"
136136
/>
137137
</template>
@@ -143,8 +143,8 @@
143143
<!-- LEFT BORDER LINE -->
144144
<div
145145
v-show="isOpen && headerHasContent"
146-
class="attributes-panel-item__left-border"
147146
:style="{ marginLeft: indentPx, zIndex: headerZIndex }"
147+
class="attributes-panel-item__left-border"
148148
/>
149149

150150
<!-- CHILDREN -->
@@ -172,8 +172,8 @@
172172

173173
<template v-if="(isArray || isMap) && propManual">
174174
<div
175-
class="attributes-panel-item__add-child-row"
176175
:style="{ marginLeft: indentPx }"
176+
class="attributes-panel-item__add-child-row"
177177
>
178178
<Icon
179179
class="attributes-panel-item__nested-arrow-icon"
@@ -184,15 +184,15 @@
184184
<input
185185
v-if="isMap"
186186
v-model="newMapChildKey"
187-
type="text"
188-
placeholder="key"
189187
:class="
190188
clsx(
191189
'attributes-panel-item__new-child-key-input',
192190
isMapKeyError &&
193191
'attributes-panel-item__new-child-key-input__error',
194192
)
195193
"
194+
placeholder="key"
195+
type="text"
196196
@blur="clearKeyError"
197197
@keyup.enter="addChildHandler"
198198
/>
@@ -220,16 +220,16 @@
220220
<!-- INDIVIDUAL PROP INSIDE A SECTION -->
221221
<div
222222
v-else
223-
class="attributes-panel-item__item-inner"
224223
:style="{ paddingLeft: indentPx }"
224+
class="attributes-panel-item__item-inner"
225225
>
226226
<div class="attributes-panel-item__item-label">
227227
<Icon
228228
v-if="validation && validation.status !== 'Success'"
229229
:name="showValidationDetails ? 'chevron--down' : 'chevron--right'"
230+
class="cursor-pointer"
230231
size="sm"
231232
tone="error"
232-
class="cursor-pointer"
233233
@click="showValidationDetails = !showValidationDetails"
234234
/>
235235

@@ -240,8 +240,8 @@
240240
size="none"
241241
/>
242242
<div
243-
class="attributes-panel-item__item-label-text"
244243
:title="`${propLabelParts[0]}${propLabelParts[1]}`"
244+
class="attributes-panel-item__item-label-text"
245245
>
246246
<template v-if="isChildOfMap">{{ propLabelParts[1] }}</template>
247247
<template v-else-if="isChildOfArray">
@@ -279,8 +279,8 @@
279279

280280
<a
281281
v-if="fullPropDef.docLink"
282-
class="attributes-panel-item__docs-icon hover:scale-125"
283282
:href="fullPropDef.docLink"
283+
class="attributes-panel-item__docs-icon hover:scale-125"
284284
target="_blank"
285285
title="show docs"
286286
>
@@ -290,49 +290,49 @@
290290
</div>
291291

292292
<div
293-
class="attributes-panel-item__input-wrap"
294293
:class="{
295294
'force-border-red-400': validation && validation.status !== 'Success',
296295
'my-1': validation && validation.status !== 'Success',
297296
}"
298-
@mouseover="onHoverStart"
297+
class="attributes-panel-item__input-wrap"
299298
@mouseleave="onHoverEnd"
299+
@mouseover="onHoverStart"
300300
>
301301
<Icon
302302
v-if="
303303
noValue && !iconShouldBeHidden && !isFocus && !propPopulatedBySocket
304304
"
305305
:name="icon"
306-
size="sm"
307306
class="attributes-panel-item__type-icon"
307+
size="sm"
308308
/>
309309
<Icon
310310
v-if="
311311
currentValue !== null &&
312312
!propPopulatedBySocket &&
313313
!propControlledByParent
314314
"
315-
name="x-circle"
316315
class="attributes-panel-item__unset-button"
316+
name="x-circle"
317317
@click="unsetHandler"
318318
/>
319319
<template v-if="propKind === 'integer'">
320320
<input
321321
v-model="newValueNumber"
322-
type="number"
323322
spellcheck="false"
324-
@focus="onFocus"
323+
type="number"
325324
@blur="onBlur"
325+
@focus="onFocus"
326326
@keyup.enter="updateValue"
327327
/>
328328
</template>
329329
<template v-else-if="widgetKind === 'text'">
330330
<input
331331
v-model="newValueString"
332-
type="text"
333332
spellcheck="false"
334-
@focus="onFocus"
333+
type="text"
335334
@blur="onBlur"
335+
@focus="onFocus"
336336
@keyup.enter="updateValue"
337337
/>
338338
</template>
@@ -341,8 +341,8 @@
341341
<input
342342
v-model="newValueString"
343343
type="password"
344-
@focus="onFocus"
345344
@blur="onBlur"
345+
@focus="onFocus"
346346
@keyup.enter="updateValue"
347347
/>
348348
</template>
@@ -352,21 +352,21 @@
352352
<textarea
353353
v-model="newValueString"
354354
spellcheck="false"
355-
@focus="onFocus"
356355
@blur="onBlur"
356+
@focus="onFocus"
357357
@keydown.enter="(e) => e.metaKey && updateValue()"
358358
/>
359359
<Icon
360360
v-if="propControlledByParent"
361-
name="external-link"
362361
class="attributes-panel-item__popout-view-button"
362+
name="external-link"
363363
title="View in popup"
364364
@click="viewModalRef?.open()"
365365
/>
366366
<Icon
367367
v-else
368-
name="external-link"
369368
class="attributes-panel-item__popout-edit-button"
369+
name="external-link"
370370
title="Edit in popup"
371371
@click="editModalRef?.open()"
372372
/>
@@ -379,17 +379,17 @@
379379
<template v-else-if="widgetKind === 'checkbox'">
380380
<input
381381
:checked="newValueBoolean"
382-
type="checkbox"
383382
class="attributes-panel-item__hidden-input"
384-
@input="(e) => newValueBoolean = (e.target as HTMLInputElement)?.checked"
385-
@focus="onFocus"
383+
type="checkbox"
386384
@blur="onBlur"
387385
@change="updateValue"
386+
@focus="onFocus"
387+
@input="(e) => newValueBoolean = (e.target as HTMLInputElement)?.checked"
388388
/>
389389
<div class="attributes-panel-item__input-value">
390390
<Icon
391-
class="attributes-panel-item__checkbox-icon"
392391
:name="newValueBoolean === true ? 'check-square' : 'empty-square'"
392+
class="attributes-panel-item__checkbox-icon"
393393
/>
394394
{{ newValueBoolean ? "TRUE" : "FALSE" }}
395395
</div>
@@ -400,9 +400,9 @@
400400
<select
401401
v-model="newValueString"
402402
class="attributes-panel-item__hidden-input"
403-
@focus="onFocus"
404403
@blur="onBlur"
405404
@change="updateValue"
405+
@focus="onFocus"
406406
>
407407
<option v-for="o in widgetOptions" :key="o.value" :value="o.value">
408408
{{ o.label }}
@@ -412,8 +412,8 @@
412412
{{ currentValue }}
413413
</div>
414414
<Icon
415-
name="input-type-select"
416415
class="absolute right-1 top-1 text-neutral-400 dark:text-neutral-600"
416+
name="input-type-select"
417417
size="sm"
418418
/>
419419
</template>
@@ -466,11 +466,11 @@
466466

467467
<Icon
468468
v-if="validation?.status === 'Success'"
469+
class="mr-2"
469470
name="check"
470471
tone="success"
471-
class="mr-2"
472472
/>
473-
<Icon v-else-if="validation" name="x" tone="error" class="mr-2" />
473+
<Icon v-else-if="validation" class="mr-2" name="x" tone="error" />
474474
</div>
475475

476476
<!-- VALIDATION DETAILS -->
@@ -494,9 +494,9 @@
494494
<Modal
495495
v-if="widgetKind === 'textArea' || widgetKind === 'codeEditor'"
496496
ref="editModalRef"
497-
size="4xl"
498497
:title="`Edit value - ${propLabel}`"
499498
class="attributes-panel-item__edit-value-modal"
499+
size="4xl"
500500
@close="updateValue"
501501
>
502502
<div class="attributes-panel-item__edit-value-modal-code-wrap">
@@ -517,9 +517,9 @@
517517
<Modal
518518
v-if="widgetKind === 'textArea' || widgetKind === 'codeEditor'"
519519
ref="viewModalRef"
520-
size="4xl"
521520
:title="`View value - ${propLabel}`"
522521
class="attributes-panel-item__view-value-modal"
522+
size="4xl"
523523
>
524524
<div class="pb-xs text-destructive-500 font-bold">
525525
This value cannot currently be edited because
@@ -562,19 +562,19 @@
562562
</div>
563563
<div class="flex gap-sm">
564564
<VButton
565+
:class="propControlledByParent ? 'flex-grow' : ''"
565566
icon="x"
566567
tone="shade"
567568
variant="ghost"
568-
:class="propControlledByParent ? 'flex-grow' : ''"
569569
@click="closeConfirmEditModal"
570570
>
571571
Cancel
572572
</VButton>
573573
<VButton
574574
v-if="!propControlledByParent"
575+
class="flex-grow"
575576
icon="edit"
576577
tone="action"
577-
class="flex-grow"
578578
@click="confirmEdit"
579579
>
580580
Confirm
@@ -584,7 +584,7 @@
584584
</div>
585585
</template>
586586

587-
<script setup lang="ts">
587+
<script lang="ts" setup>
588588
import * as _ from "lodash-es";
589589
import { computed, PropType, ref, watch } from "vue";
590590
import clsx from "clsx";
@@ -753,7 +753,7 @@ const propHasSocket = computed(
753753
);
754754
const propSetByFunc = computed(
755755
() =>
756-
!props.attributeDef.value?.isControlledByIntrinsicFunc &&
756+
props.attributeDef.value?.isControlledByDynamicFunc &&
757757
!propHasSocket.value &&
758758
!propPopulatedBySocket.value,
759759
);
@@ -803,9 +803,7 @@ const sourceTooltip = computed(() => {
803803
});
804804
805805
const propControlledByParent = computed(
806-
() =>
807-
props.attributeDef.value?.id !==
808-
props.attributeDef.value?.controllingAttributeValueId,
806+
() => props.attributeDef.value?.isControlledByAncestor,
809807
);
810808
811809
function resetNewValueToCurrentValue() {

app/web/src/components/AttributesPanel/SourceIcon.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const classes = computed(() => {
2020
return clsx(
2121
"border dark:group-hover/header:hover:text-action-500 group-hover/header:hover:text-action-300 rounded p-[1px] m-[2px] w-5 h-5 cursor-pointer",
2222
props.overridden
23-
? " text-warning-500 dark:text-warning-300 border-warning-500 dark:border-warning-300 dark:group-hover/header:hover:border-action-500 group-hover/header:hover:border-action-300 dark:group-hover/header:text-shade-100 dark:group-hover/header:border-shade-100 group-hover/header:text-shade-0 group-hover/header:border-shade-0"
23+
? "text-warning-500 dark:text-warning-300 border-warning-500 dark:border-warning-300 dark:group-hover/header:hover:border-action-500 group-hover/header:hover:border-action-300 dark:group-hover/header:text-shade-100 dark:group-hover/header:border-shade-100 group-hover/header:text-shade-0 group-hover/header:border-shade-0"
2424
: "border-transparent",
2525
);
2626
} else {

app/web/src/store/component_attributes.store.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export const useComponentAttributesStore = (componentId: ComponentId) => {
135135
value.ancestorManual = ancestorManual;
136136
const isAncestorManual =
137137
ancestorManual &&
138-
value.isControlledByIntrinsicFunc &&
138+
!value.isControlledByDynamicFunc &&
139139
!(value.canBeSetBySocket || value.isFromExternalSource);
140140

141141
return {

0 commit comments

Comments
 (0)