Skip to content

Commit

Permalink
Dropdown widget improvements. (#9186)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelMauderer authored Mar 4, 2024
1 parent 5676618 commit 94666e6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 63 deletions.
28 changes: 14 additions & 14 deletions app/gui2/e2e/widgets.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ test('Selection widgets in Data.read node', async ({ page }) => {
// Set value on `on_problems` (static drop-down)
const onProblemsArg = argumentNames.filter({ has: page.getByText('on_problems') })
await onProblemsArg.click()
await dropDown.expectVisibleWithOptions(page, ['Ignore', 'Report Warning', 'Report Error'])
await dropDown.clickOption(page, 'Report Error')
await dropDown.expectVisibleWithOptions(page, ['Ignore', 'Report_Warning', 'Report_Error'])
await dropDown.clickOption(page, 'Report_Error')
await expect(onProblemsArg.locator('.WidgetToken')).toHaveText([
'Problem_Behavior',
'.',
Expand All @@ -83,8 +83,8 @@ test('Selection widgets in Data.read node', async ({ page }) => {
notAppliedArguments: [0, 1],
})
await page.getByText('Report_Error').click()
await dropDown.expectVisibleWithOptions(page, ['Ignore', 'Report Warning', 'Report Error'])
await dropDown.clickOption(page, 'Report Warning')
await dropDown.expectVisibleWithOptions(page, ['Ignore', 'Report_Warning', 'Report_Error'])
await dropDown.clickOption(page, 'Report_Warning')
await expect(onProblemsArg.locator('.WidgetToken')).toHaveText([
'Problem_Behavior',
'.',
Expand All @@ -95,8 +95,8 @@ test('Selection widgets in Data.read node', async ({ page }) => {
const pathArg = argumentNames.filter({ has: page.getByText('path') })
await pathArg.click()
await expect(page.locator('.dropdownContainer')).toBeVisible()
await dropDown.expectVisibleWithOptions(page, ['File 1', 'File 2'])
await dropDown.clickOption(page, 'File 2')
await dropDown.expectVisibleWithOptions(page, ['"File 1"', '"File 2"'])
await dropDown.clickOption(page, '"File 2"')
await expect(pathArg.locator('.EnsoTextInputWidget > input')).toHaveValue('"File 2"')

// Change value on `path` (dynamic config)
Expand All @@ -109,8 +109,8 @@ test('Selection widgets in Data.read node', async ({ page }) => {
notAppliedArguments: [1],
})
await page.getByText('path').click()
await dropDown.expectVisibleWithOptions(page, ['File 1', 'File 2'])
await dropDown.clickOption(page, 'File 1')
await dropDown.expectVisibleWithOptions(page, ['"File 1"', '"File 2"'])
await dropDown.clickOption(page, '"File 1"')
await expect(pathArg.locator('.EnsoTextInputWidget > input')).toHaveValue('"File 1"')
})

Expand Down Expand Up @@ -154,8 +154,8 @@ test('Managing aggregates in `aggregate` node', async ({ page }) => {
// Change aggregation type
const firstItem = columnsArg.locator('.item > .WidgetPort > .WidgetSelection')
await firstItem.click()
await dropDown.expectVisibleWithOptions(page, ['Group By', 'Count', 'Count Distinct'])
await dropDown.clickOption(page, 'Count Distinct')
await dropDown.expectVisibleWithOptions(page, ['Group_By', 'Count', 'Count_Distinct'])
await dropDown.clickOption(page, 'Count_Distinct')
await expect(columnsArg.locator('.WidgetToken')).toHaveText([
'Aggregate_Column',
'.',
Expand All @@ -180,8 +180,8 @@ test('Managing aggregates in `aggregate` node', async ({ page }) => {
// Set column
const columnArg = firstItem.locator('.WidgetSelection').first()
await columnArg.click()
await dropDown.expectVisibleWithOptions(page, ['column 1', 'column 2'])
await dropDown.clickOption(page, 'column 1')
await dropDown.expectVisibleWithOptions(page, ['"column 1"', '"column 2"'])
await dropDown.clickOption(page, '"column 1"')
await expect(columnsArg.locator('.WidgetToken')).toHaveText([
'Aggregate_Column',
'.',
Expand Down Expand Up @@ -219,8 +219,8 @@ test('Managing aggregates in `aggregate` node', async ({ page }) => {
const secondItem = columnsArg.locator('.item > .WidgetPort > .WidgetSelection').nth(1)
const secondColumnArg = secondItem.locator('.WidgetSelection').first()
await secondColumnArg.click()
await dropDown.expectVisibleWithOptions(page, ['column 1', 'column 2'])
await dropDown.clickOption(page, 'column 2')
await dropDown.expectVisibleWithOptions(page, ['"column 1"', '"column 2"'])
await dropDown.clickOption(page, '"column 2"')
await expect(secondItem.locator('.WidgetToken')).toHaveText(['Aggregate_Column', '.', 'Group_By'])
await expect(secondItem.locator('.EnsoTextInputWidget > input').first()).toHaveValue('"column 2"')

Expand Down
26 changes: 11 additions & 15 deletions app/gui2/src/components/GraphEditor/widgets/WidgetSelection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ import { targetIsOutside } from '@/util/autoBlur'
import { ArgumentInfoKey } from '@/util/callTree'
import { arrayEquals } from '@/util/data/array'
import { asNot } from '@/util/data/types.ts'
import {
qnLastSegment,
tryQualifiedName,
type IdentifierOrOperatorIdentifier,
} from '@/util/qualifiedName'
import { qnLastSegment, tryQualifiedName } from '@/util/qualifiedName'
import { computed, ref, watch } from 'vue'
const props = defineProps(widgetProps(widgetDefinition))
Expand All @@ -42,24 +38,20 @@ interface Tag {
parameters?: ArgumentWidgetConfiguration[]
}
function identToLabel(name: IdentifierOrOperatorIdentifier): string {
return name.replaceAll('_', ' ')
}
function tagFromExpression(expression: string): Tag {
const qn = tryQualifiedName(expression)
if (!qn.ok) return { expression }
const entry = suggestions.entries.getEntryByQualifiedName(qn.value)
if (entry) return tagFromEntry(entry)
return {
label: identToLabel(qnLastSegment(qn.value)),
label: qnLastSegment(qn.value),
expression: qn.value,
}
}
function tagFromEntry(entry: SuggestionEntry): Tag {
return {
label: identToLabel(entry.name),
label: entry.name,
expression:
entry.selfType != null
? `_.${entry.name}`
Expand All @@ -81,7 +73,6 @@ const dynamicTags = computed<Tag[]>(() => {
if (config?.kind !== 'Single_Choice') return []
return config.values.map((value) => ({
...tagFromExpression(value.value),
...(value.label ? { label: value.label } : {}),
parameters: value.parameters,
}))
})
Expand Down Expand Up @@ -163,6 +154,8 @@ watch(selectedIndex, (_index) => {
},
})
})
const isHovered = ref(false)
</script>

<script lang="ts">
Expand Down Expand Up @@ -197,9 +190,11 @@ export const widgetDefinition = defineWidget(WidgetInput.isAstOrPlaceholder, {
@pointerdown.stop
@pointerup.stop
@click.stop="toggleDropdownWidget"
@pointerover="isHovered = true"
@pointerout="isHovered = false"
>
<NodeWidget ref="childWidgetRef" :input="innerWidgetInput" />
<SvgIcon name="arrow_right_head_only" class="arrow" />
<SvgIcon v-if="isHovered" name="arrow_right_head_only" class="arrow" />
<DropdownWidget
v-if="showDropdownWidget"
class="dropdownContainer"
Expand All @@ -219,8 +214,9 @@ export const widgetDefinition = defineWidget(WidgetInput.isAstOrPlaceholder, {
.arrow {
position: absolute;
bottom: -6px;
bottom: -7px;
left: 50%;
transform: translateX(-50%) rotate(90deg);
transform: translateX(-50%) rotate(90deg) scale(0.7);
opacity: 0.5;
}
</style>
48 changes: 14 additions & 34 deletions app/gui2/src/components/widgets/DropdownWidget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,14 @@ const NEXT_SORT_DIRECTION: Record<SortDirection, SortDirection> = {
[SortDirection.ascending]: SortDirection.descending,
[SortDirection.descending]: SortDirection.none,
}
// Currently unused.
const enableSortButton = ref(false)
</script>

<template>
<div class="Dropdown" @pointerdown.stop @pointerup.stop @click.stop>
<ul class="list" :style="{ background: color }" @wheel.stop>
<ul class="list scrollable" :style="{ background: color, borderColor: color }" @wheel.stop>
<template v-for="[value, index] in sortedValuesAndIndices" :key="value">
<li v-if="value === selectedValue">
<div class="selected-item button" @click.stop="emit('click', index, $event.altKey)">
Expand All @@ -60,7 +63,7 @@ const NEXT_SORT_DIRECTION: Record<SortDirection, SortDirection> = {
</li>
</template>
</ul>
<div class="sort button">
<div v-if="enableSortButton" class="sort button">
<div class="sort-background" :style="{ background: color }"></div>
<SvgIcon
:name="ICON_LOOKUP[sortDirection]"
Expand All @@ -75,21 +78,21 @@ const NEXT_SORT_DIRECTION: Record<SortDirection, SortDirection> = {
position: absolute;
top: 100%;
margin-top: 8px;
height: 136px;
overflow: visible;
}
.list {
position: relative;
user-select: none;
overflow: auto;
border-radius: 8px;
border-radius: 16px;
width: min-content;
height: 100%;
scrollbar-width: none;
scrollbar-gutter: stable both-edges;
max-height: 152px;
list-style-type: none;
color: var(--color-text-light);
scrollbar-width: thin;
padding: 4px 0;
border: 2px solid;
}
li {
Expand All @@ -101,33 +104,9 @@ li {
}
.list span {
vertical-align: text-bottom;
}
.list::-webkit-scrollbar {
-webkit-appearance: none;
width: 8px;
}
.list::-webkit-scrollbar-track {
-webkit-box-shadow: none;
}
.list::-webkit-scrollbar-thumb {
border: 2px solid #0000;
border-left-width: 1px;
border-right-width: 3px;
background-clip: padding-box;
border-radius: var(--radius-full);
background-color: rgba(0, 0, 0, 0.2);
}
.list::-webkit-scrollbar-corner {
background: rgba(0, 0, 0, 0);
}
.list::-webkit-scrollbar-button {
height: 4px;
display: inline-block;
vertical-align: middle;
margin: 3px 0;
}
.sort-background {
Expand Down Expand Up @@ -162,6 +141,7 @@ li {
padding-left: 8px;
padding-right: 8px;
width: min-content;
margin-left: 8px;
}
.selectable-item {
Expand Down

0 comments on commit 94666e6

Please sign in to comment.