|
1 | 1 | <template> |
2 | 2 | <div |
3 | | - class="attributes-panel-item" |
4 | 3 | :class="{ |
5 | 4 | '--section': canHaveChildren, |
6 | 5 | '--input': !canHaveChildren, |
|
10 | 9 | '--open': canHaveChildren && isOpen, |
11 | 10 | '--collapsed': canHaveChildren && !isOpen, |
12 | 11 | }" |
| 12 | + class="attributes-panel-item" |
13 | 13 | > |
14 | 14 | <!-- SECTION --> |
15 | 15 | <div |
16 | 16 | v-if="canHaveChildren" |
17 | | - @mouseover.stop="onSectionHoverStart" |
18 | 17 | @mouseleave="onSectionHoverEnd" |
| 18 | + @mouseover.stop="onSectionHoverStart" |
19 | 19 | > |
20 | 20 | <!-- HEADER --> |
21 | 21 | <div |
22 | | - class="attributes-panel-item__section-header-wrap" |
23 | 22 | :style="{ |
24 | 23 | top: topPx, |
25 | 24 | zIndex: headerZIndex, |
26 | 25 | }" |
| 26 | + class="attributes-panel-item__section-header-wrap" |
27 | 27 | > |
28 | 28 | <div |
29 | 29 | :class=" |
|
47 | 47 | </div> |
48 | 48 |
|
49 | 49 | <div |
50 | | - class="attributes-panel-item__section-header" |
51 | 50 | :style="{ marginLeft: indentPx }" |
| 51 | + class="attributes-panel-item__section-header" |
52 | 52 | @click="toggleOpen(true)" |
53 | 53 | > |
54 | 54 | <Icon |
|
58 | 58 | size="none" |
59 | 59 | /> |
60 | 60 | <Icon |
61 | | - class="attributes-panel-item__type-icon" |
62 | 61 | :name="icon" |
| 62 | + class="attributes-panel-item__type-icon" |
63 | 63 | size="none" |
64 | 64 | /> |
65 | 65 | <div class="attributes-panel-item__section-header-label"> |
|
130 | 130 | <template v-for="source in sourceKinds" :key="source"> |
131 | 131 | <DropdownMenuItem |
132 | 132 | v-if="source === 'manually' || propSource === source" |
133 | | - :label="source" |
134 | 133 | :checked="propSource === source" |
| 134 | + :label="source" |
135 | 135 | @click="setSource(source)" |
136 | 136 | /> |
137 | 137 | </template> |
|
143 | 143 | <!-- LEFT BORDER LINE --> |
144 | 144 | <div |
145 | 145 | v-show="isOpen && headerHasContent" |
146 | | - class="attributes-panel-item__left-border" |
147 | 146 | :style="{ marginLeft: indentPx, zIndex: headerZIndex }" |
| 147 | + class="attributes-panel-item__left-border" |
148 | 148 | /> |
149 | 149 |
|
150 | 150 | <!-- CHILDREN --> |
|
172 | 172 |
|
173 | 173 | <template v-if="(isArray || isMap) && propManual"> |
174 | 174 | <div |
175 | | - class="attributes-panel-item__add-child-row" |
176 | 175 | :style="{ marginLeft: indentPx }" |
| 176 | + class="attributes-panel-item__add-child-row" |
177 | 177 | > |
178 | 178 | <Icon |
179 | 179 | class="attributes-panel-item__nested-arrow-icon" |
|
184 | 184 | <input |
185 | 185 | v-if="isMap" |
186 | 186 | v-model="newMapChildKey" |
187 | | - type="text" |
188 | | - placeholder="key" |
189 | 187 | :class=" |
190 | 188 | clsx( |
191 | 189 | 'attributes-panel-item__new-child-key-input', |
192 | 190 | isMapKeyError && |
193 | 191 | 'attributes-panel-item__new-child-key-input__error', |
194 | 192 | ) |
195 | 193 | " |
| 194 | + placeholder="key" |
| 195 | + type="text" |
196 | 196 | @blur="clearKeyError" |
197 | 197 | @keyup.enter="addChildHandler" |
198 | 198 | /> |
|
220 | 220 | <!-- INDIVIDUAL PROP INSIDE A SECTION --> |
221 | 221 | <div |
222 | 222 | v-else |
223 | | - class="attributes-panel-item__item-inner" |
224 | 223 | :style="{ paddingLeft: indentPx }" |
| 224 | + class="attributes-panel-item__item-inner" |
225 | 225 | > |
226 | 226 | <div class="attributes-panel-item__item-label"> |
227 | 227 | <Icon |
228 | 228 | v-if="validation && validation.status !== 'Success'" |
229 | 229 | :name="showValidationDetails ? 'chevron--down' : 'chevron--right'" |
| 230 | + class="cursor-pointer" |
230 | 231 | size="sm" |
231 | 232 | tone="error" |
232 | | - class="cursor-pointer" |
233 | 233 | @click="showValidationDetails = !showValidationDetails" |
234 | 234 | /> |
235 | 235 |
|
|
240 | 240 | size="none" |
241 | 241 | /> |
242 | 242 | <div |
243 | | - class="attributes-panel-item__item-label-text" |
244 | 243 | :title="`${propLabelParts[0]}${propLabelParts[1]}`" |
| 244 | + class="attributes-panel-item__item-label-text" |
245 | 245 | > |
246 | 246 | <template v-if="isChildOfMap">{{ propLabelParts[1] }}</template> |
247 | 247 | <template v-else-if="isChildOfArray"> |
|
279 | 279 |
|
280 | 280 | <a |
281 | 281 | v-if="fullPropDef.docLink" |
282 | | - class="attributes-panel-item__docs-icon hover:scale-125" |
283 | 282 | :href="fullPropDef.docLink" |
| 283 | + class="attributes-panel-item__docs-icon hover:scale-125" |
284 | 284 | target="_blank" |
285 | 285 | title="show docs" |
286 | 286 | > |
|
290 | 290 | </div> |
291 | 291 |
|
292 | 292 | <div |
293 | | - class="attributes-panel-item__input-wrap" |
294 | 293 | :class="{ |
295 | 294 | 'force-border-red-400': validation && validation.status !== 'Success', |
296 | 295 | 'my-1': validation && validation.status !== 'Success', |
297 | 296 | }" |
298 | | - @mouseover="onHoverStart" |
| 297 | + class="attributes-panel-item__input-wrap" |
299 | 298 | @mouseleave="onHoverEnd" |
| 299 | + @mouseover="onHoverStart" |
300 | 300 | > |
301 | 301 | <Icon |
302 | 302 | v-if=" |
303 | 303 | noValue && !iconShouldBeHidden && !isFocus && !propPopulatedBySocket |
304 | 304 | " |
305 | 305 | :name="icon" |
306 | | - size="sm" |
307 | 306 | class="attributes-panel-item__type-icon" |
| 307 | + size="sm" |
308 | 308 | /> |
309 | 309 | <Icon |
310 | 310 | v-if=" |
311 | 311 | currentValue !== null && |
312 | 312 | !propPopulatedBySocket && |
313 | 313 | !propControlledByParent |
314 | 314 | " |
315 | | - name="x-circle" |
316 | 315 | class="attributes-panel-item__unset-button" |
| 316 | + name="x-circle" |
317 | 317 | @click="unsetHandler" |
318 | 318 | /> |
319 | 319 | <template v-if="propKind === 'integer'"> |
320 | 320 | <input |
321 | 321 | v-model="newValueNumber" |
322 | | - type="number" |
323 | 322 | spellcheck="false" |
324 | | - @focus="onFocus" |
| 323 | + type="number" |
325 | 324 | @blur="onBlur" |
| 325 | + @focus="onFocus" |
326 | 326 | @keyup.enter="updateValue" |
327 | 327 | /> |
328 | 328 | </template> |
329 | 329 | <template v-else-if="widgetKind === 'text'"> |
330 | 330 | <input |
331 | 331 | v-model="newValueString" |
332 | | - type="text" |
333 | 332 | spellcheck="false" |
334 | | - @focus="onFocus" |
| 333 | + type="text" |
335 | 334 | @blur="onBlur" |
| 335 | + @focus="onFocus" |
336 | 336 | @keyup.enter="updateValue" |
337 | 337 | /> |
338 | 338 | </template> |
|
341 | 341 | <input |
342 | 342 | v-model="newValueString" |
343 | 343 | type="password" |
344 | | - @focus="onFocus" |
345 | 344 | @blur="onBlur" |
| 345 | + @focus="onFocus" |
346 | 346 | @keyup.enter="updateValue" |
347 | 347 | /> |
348 | 348 | </template> |
|
352 | 352 | <textarea |
353 | 353 | v-model="newValueString" |
354 | 354 | spellcheck="false" |
355 | | - @focus="onFocus" |
356 | 355 | @blur="onBlur" |
| 356 | + @focus="onFocus" |
357 | 357 | @keydown.enter="(e) => e.metaKey && updateValue()" |
358 | 358 | /> |
359 | 359 | <Icon |
360 | 360 | v-if="propControlledByParent" |
361 | | - name="external-link" |
362 | 361 | class="attributes-panel-item__popout-view-button" |
| 362 | + name="external-link" |
363 | 363 | title="View in popup" |
364 | 364 | @click="viewModalRef?.open()" |
365 | 365 | /> |
366 | 366 | <Icon |
367 | 367 | v-else |
368 | | - name="external-link" |
369 | 368 | class="attributes-panel-item__popout-edit-button" |
| 369 | + name="external-link" |
370 | 370 | title="Edit in popup" |
371 | 371 | @click="editModalRef?.open()" |
372 | 372 | /> |
|
379 | 379 | <template v-else-if="widgetKind === 'checkbox'"> |
380 | 380 | <input |
381 | 381 | :checked="newValueBoolean" |
382 | | - type="checkbox" |
383 | 382 | class="attributes-panel-item__hidden-input" |
384 | | - @input="(e) => newValueBoolean = (e.target as HTMLInputElement)?.checked" |
385 | | - @focus="onFocus" |
| 383 | + type="checkbox" |
386 | 384 | @blur="onBlur" |
387 | 385 | @change="updateValue" |
| 386 | + @focus="onFocus" |
| 387 | + @input="(e) => newValueBoolean = (e.target as HTMLInputElement)?.checked" |
388 | 388 | /> |
389 | 389 | <div class="attributes-panel-item__input-value"> |
390 | 390 | <Icon |
391 | | - class="attributes-panel-item__checkbox-icon" |
392 | 391 | :name="newValueBoolean === true ? 'check-square' : 'empty-square'" |
| 392 | + class="attributes-panel-item__checkbox-icon" |
393 | 393 | /> |
394 | 394 | {{ newValueBoolean ? "TRUE" : "FALSE" }} |
395 | 395 | </div> |
|
400 | 400 | <select |
401 | 401 | v-model="newValueString" |
402 | 402 | class="attributes-panel-item__hidden-input" |
403 | | - @focus="onFocus" |
404 | 403 | @blur="onBlur" |
405 | 404 | @change="updateValue" |
| 405 | + @focus="onFocus" |
406 | 406 | > |
407 | 407 | <option v-for="o in widgetOptions" :key="o.value" :value="o.value"> |
408 | 408 | {{ o.label }} |
|
412 | 412 | {{ currentValue }} |
413 | 413 | </div> |
414 | 414 | <Icon |
415 | | - name="input-type-select" |
416 | 415 | class="absolute right-1 top-1 text-neutral-400 dark:text-neutral-600" |
| 416 | + name="input-type-select" |
417 | 417 | size="sm" |
418 | 418 | /> |
419 | 419 | </template> |
|
466 | 466 |
|
467 | 467 | <Icon |
468 | 468 | v-if="validation?.status === 'Success'" |
| 469 | + class="mr-2" |
469 | 470 | name="check" |
470 | 471 | tone="success" |
471 | | - class="mr-2" |
472 | 472 | /> |
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" /> |
474 | 474 | </div> |
475 | 475 |
|
476 | 476 | <!-- VALIDATION DETAILS --> |
|
494 | 494 | <Modal |
495 | 495 | v-if="widgetKind === 'textArea' || widgetKind === 'codeEditor'" |
496 | 496 | ref="editModalRef" |
497 | | - size="4xl" |
498 | 497 | :title="`Edit value - ${propLabel}`" |
499 | 498 | class="attributes-panel-item__edit-value-modal" |
| 499 | + size="4xl" |
500 | 500 | @close="updateValue" |
501 | 501 | > |
502 | 502 | <div class="attributes-panel-item__edit-value-modal-code-wrap"> |
|
517 | 517 | <Modal |
518 | 518 | v-if="widgetKind === 'textArea' || widgetKind === 'codeEditor'" |
519 | 519 | ref="viewModalRef" |
520 | | - size="4xl" |
521 | 520 | :title="`View value - ${propLabel}`" |
522 | 521 | class="attributes-panel-item__view-value-modal" |
| 522 | + size="4xl" |
523 | 523 | > |
524 | 524 | <div class="pb-xs text-destructive-500 font-bold"> |
525 | 525 | This value cannot currently be edited because |
|
562 | 562 | </div> |
563 | 563 | <div class="flex gap-sm"> |
564 | 564 | <VButton |
| 565 | + :class="propControlledByParent ? 'flex-grow' : ''" |
565 | 566 | icon="x" |
566 | 567 | tone="shade" |
567 | 568 | variant="ghost" |
568 | | - :class="propControlledByParent ? 'flex-grow' : ''" |
569 | 569 | @click="closeConfirmEditModal" |
570 | 570 | > |
571 | 571 | Cancel |
572 | 572 | </VButton> |
573 | 573 | <VButton |
574 | 574 | v-if="!propControlledByParent" |
| 575 | + class="flex-grow" |
575 | 576 | icon="edit" |
576 | 577 | tone="action" |
577 | | - class="flex-grow" |
578 | 578 | @click="confirmEdit" |
579 | 579 | > |
580 | 580 | Confirm |
|
584 | 584 | </div> |
585 | 585 | </template> |
586 | 586 |
|
587 | | -<script setup lang="ts"> |
| 587 | +<script lang="ts" setup> |
588 | 588 | import * as _ from "lodash-es"; |
589 | 589 | import { computed, PropType, ref, watch } from "vue"; |
590 | 590 | import clsx from "clsx"; |
@@ -753,7 +753,7 @@ const propHasSocket = computed( |
753 | 753 | ); |
754 | 754 | const propSetByFunc = computed( |
755 | 755 | () => |
756 | | - !props.attributeDef.value?.isControlledByIntrinsicFunc && |
| 756 | + props.attributeDef.value?.isControlledByDynamicFunc && |
757 | 757 | !propHasSocket.value && |
758 | 758 | !propPopulatedBySocket.value, |
759 | 759 | ); |
@@ -803,9 +803,7 @@ const sourceTooltip = computed(() => { |
803 | 803 | }); |
804 | 804 |
|
805 | 805 | const propControlledByParent = computed( |
806 | | - () => |
807 | | - props.attributeDef.value?.id !== |
808 | | - props.attributeDef.value?.controllingAttributeValueId, |
| 806 | + () => props.attributeDef.value?.isControlledByAncestor, |
809 | 807 | ); |
810 | 808 |
|
811 | 809 | function resetNewValueToCurrentValue() { |
|
0 commit comments