Skip to content

Commit

Permalink
data-menu: UI tweaks (#3310)
Browse files Browse the repository at this point in the history
* data-menu UI improvements
* API hints improved formatting
* fix plt. api hint typos
* custom API icons
* improve dark-theme support

---------

Co-authored-by: Jennifer Kotler <jkotler@stsci.edu>
  • Loading branch information
kecnry and Jennifer Kotler authored Dec 2, 2024
1 parent a8ec86c commit 81e940d
Show file tree
Hide file tree
Showing 34 changed files with 797 additions and 421 deletions.
2 changes: 1 addition & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
New Features
------------

* New design for viewer legend and data-menu. [#3220, #3254, #3263, #3264, #3271, #3272, #3274, #3289]
* New design for viewer legend and data-menu. [#3220, #3254, #3263, #3264, #3271, #3272, #3274, #3289, #3310]

Cubeviz
^^^^^^^
Expand Down
6 changes: 5 additions & 1 deletion jdaviz/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def to_unit(self, data, cid, values, original_units, target_units):
'j-child-layer-icon': 'components/child_layer_icon.vue',
'plugin-previews-temp-disabled': 'components/plugin_previews_temp_disabled.vue', # noqa
'plugin-table': 'components/plugin_table.vue',
'plugin-select': 'components/plugin_select.vue',
'plugin-dataset-select': 'components/plugin_dataset_select.vue',
'plugin-subset-select': 'components/plugin_subset_select.vue',
'plugin-viewer-select': 'components/plugin_viewer_select.vue',
Expand All @@ -156,6 +157,7 @@ def to_unit(self, data, cid, values, original_units, target_units):
'plugin-color-picker': 'components/plugin_color_picker.vue',
'plugin-input-header': 'components/plugin_input_header.vue',
'glue-state-sync-wrapper': 'components/glue_state_sync_wrapper.vue',
'glue-state-select': 'components/glue_state_select.vue',
'data-menu-add': 'components/data_menu_add.vue',
'data-menu-remove': 'components/data_menu_remove.vue',
'data-menu-subset-edit': 'components/data_menu_subset_edit.vue',
Expand Down Expand Up @@ -232,7 +234,9 @@ class ApplicationState(State):
'radialtocheck': read_icon(os.path.join(ICON_DIR, 'radialtocheck.svg'), 'svg+xml'),
'checktoradial': read_icon(os.path.join(ICON_DIR, 'checktoradial.svg'), 'svg+xml'),
'nuer': read_icon(os.path.join(ICON_DIR, 'right-east.svg'), 'svg+xml'),
'nuel': read_icon(os.path.join(ICON_DIR, 'left-east.svg'), 'svg+xml')
'nuel': read_icon(os.path.join(ICON_DIR, 'left-east.svg'), 'svg+xml'),
'api': read_icon(os.path.join(ICON_DIR, 'api.svg'), 'svg+xml'),
'api-lock': read_icon(os.path.join(ICON_DIR, 'api_lock.svg'), 'svg+xml'),
}, docstring="Custom application icons")

viewer_icons = DictCallbackProperty({}, docstring="Indexed icons (numbers) for viewers across the app") # noqa
Expand Down
5 changes: 4 additions & 1 deletion jdaviz/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
</j-tooltip>
<j-tooltip v-if="state.show_toolbar_buttons && checkNotebookContext()" tipid="app-api-hints">
<v-btn icon @click="state.show_api_hints = !state.show_api_hints" :class="{active : state.show_api_hints}">
<v-icon medium style="padding-top: 2px">mdi-code-tags</v-icon>
<img :src="state.icons['api']" width="24" class="invert-if-dark" style="opacity: 1.0"/>
</v-btn>
</j-tooltip>
<j-tooltip v-if="state.show_toolbar_buttons" tipid="app-snackbar-history">
Expand Down Expand Up @@ -125,6 +125,9 @@
{{ trayItem.label }}
</j-tooltip>
</v-list-item-title>
<v-list-item-subtitle v-if="state.show_api_hints" style="white-space: normal; font-size: 8pt; padding-top: 4px; padding-bottom: 4px" class="api-hint">
<span class="api-hint" :style="state.tray_items_open.includes(index) ? 'font-weight: bold' : null">plg = {{ config }}.plugins['{{ trayItem.label }}']</span>
</v-list-item-subtitle>
<v-list-item-subtitle style="white-space: normal; font-size: 8pt">
{{ trayItem.tray_item_description }}
</v-list-item-subtitle>
Expand Down
3 changes: 2 additions & 1 deletion jdaviz/components/data_menu_add.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
v-if="api_hints_enabled"
:hover_api_hint.sync="hover_api_hint"
:lock_hover_api_hint.sync="lock_hover_api_hint"
:icons="icons"
/>
</v-list>
</v-menu>
Expand All @@ -80,6 +81,6 @@ module.exports = {
lock_hover_api_hint: false,
}
},
props: ['dataset_items', 'subset_tools', 'loaded_n_data', 'api_hints_enabled'],
props: ['dataset_items', 'subset_tools', 'loaded_n_data', 'api_hints_enabled', 'icons'],
};
</script>
36 changes: 36 additions & 0 deletions jdaviz/components/glue_state_select.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<template>
<v-select
attach
:menu-props="{ left: true }"
:items="items"
v-model="selected"
@change="$emit('update:selected', $event)"
:label="api_hints_enabled && api_hint ? api_hint : label"
:class="api_hints_enabled && api_hint ? 'api-hint no-hint' : 'no-hint'"
dense
>
<template v-slot:selection="{ item, index }">
<span :class="api_hints_enabled ? 'api-hint' : null">
{{ api_hints_enabled ?
'\'' + item.text + '\''
:
item.text
}}
</span>
</template>
</v-select>
</template>

<script>
module.exports = {
props: ['items', 'selected', 'label', 'api_hint', 'api_hints_enabled']
};
</script>

<style scoped>
.v-select__selections {
flex-wrap: nowrap !important;
display: block !important;
margin-bottom: -32px;
}
</style>
32 changes: 13 additions & 19 deletions jdaviz/components/hover_api_hint.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,29 @@
{{ hover_api_hint }}
</span>
</v-list-item-content>
<v-list-item-action>
<v-list-item-action style="margin-right: -8px">
<j-tooltip
tooltipcontent="toggle whether API hints persist after hovering to allow for copying text"
>
<v-badge
overlap
bottom
color="#007BA1"
:icon="lock_hover_api_hint ? 'mdi-lock-outline' : 'mdi-lock-open-outline'"
<v-btn
small
text
width="24"
:style="lock_hover_api_hint ? 'background-color: #c7510996 !important' : null"
@click="(e) => {e.stopPropagation(); $emit('update:lock_hover_api_hint', !lock_hover_api_hint); $emit('update:hover_api_hint', '')}"
>
<v-btn
icon
small
@click="(e) => {e.stopPropagation(); $emit('update:lock_hover_api_hint', !lock_hover_api_hint); $emit('update:hover_api_hint', '')}"
>
<v-icon
:color="lock_hover_api_hint ? '#007BA1' : null"
>
mdi-code-tags
</v-icon>
</v-btn>
</v-badge>
<img
:src="icons['api-lock']"
width="20"
class="invert-if-dark"/>
</v-btn>
</j-tooltip>
</v-list-item-action>
</v-list-item>
</template>

<script>
module.exports = {
props: ['hover_api_hint', 'lock_hover_api_hint'],
props: ['hover_api_hint', 'lock_hover_api_hint', 'icons'],
};
</script>
10 changes: 7 additions & 3 deletions jdaviz/components/plugin_dataset_select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@
{{ data.item.label }}
</span>
</v-chip>
<span v-else>
<j-layer-viewer-icon v-if="data.item.icon" span_style="margin-right: 4px" :icon="data.item.icon" :prevent_invert_if_dark="true"></j-layer-viewer-icon>
{{ data.item.label }}
<span v-else :class="api_hints_enabled ? 'api-hint' : null">
<j-layer-viewer-icon v-if="data.item.icon && !api_hints_enabled" span_style="margin-right: 4px" :icon="data.item.icon" :prevent_invert_if_dark="true"></j-layer-viewer-icon>
{{ api_hints_enabled ?
'\'' + data.item.label + '\''
:
data.item.label
}}
</span>
</div>
</template>
Expand Down
11 changes: 11 additions & 0 deletions jdaviz/components/plugin_editable_select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@
item-value="label"
persistent-hint
>
<template slot="selection" slot-scope="data">
<div class="single-line" style="width: 100%">
<span :class="api_hints_enabled ? 'api-hint' : null">
{{ api_hints_enabled ?
'\'' + data.item.label + '\''
:
data.item.label
}}
</span>
</div>
</template>
<template v-slot:append>
<v-icon style="cursor: pointer">mdi-menu-down</v-icon>
<j-tooltip tooltipcontent="rename">
Expand Down
12 changes: 11 additions & 1 deletion jdaviz/components/plugin_file_import_select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,17 @@
:class="api_hints_enabled && api_hint ? 'api-hint' : null"
:hint="hint"
persistent-hint
></v-select>
>
<template v-slot:selection="{ item }">
<span :class="api_hints_enabled ? 'api-hint' : null">
{{ api_hints_enabled ?
'\'' + item + '\''
:
item
}}
</span>
</template>
</v-select>
<v-chip v-if="selected === 'From File...'"
close
close-icon="mdi-close"
Expand Down
1 change: 1 addition & 0 deletions jdaviz/components/plugin_inline_select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
@update:selected="$emit('update:selected', $event)"
:multiselect="multiselect"
:single_select_allow_blank="single_select_allow_blank"
:api_hints_enabled="api_hints_enabled"
></plugin-inline-select-item>
</v-row>
</div>
Expand Down
14 changes: 9 additions & 5 deletions jdaviz/components/plugin_inline_select_item.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,23 @@
<v-icon v-if="multiselect">{{isSelected() ? "mdi-checkbox-marked" : "mdi-checkbox-blank-outline"}}</v-icon>
<v-icon v-else>{{isSelected() ? "mdi-radiobox-marked" : "mdi-radiobox-blank"}}</v-icon>
</v-btn>
<span>
<j-layer-viewer-icon v-if="item.icon" :icon="item.icon" :prevent_invert_if_dark="false"></j-layer-viewer-icon>
<v-icon v-else-if="item.color && item.type" left :color="item.color">
<span :class="api_hints_enabled ? 'api-hint' : null">
<j-layer-viewer-icon v-if="item.icon && !api_hints_enabled" :icon="item.icon" :prevent_invert_if_dark="false"></j-layer-viewer-icon>
<v-icon v-else-if="item.color && item.type && !api_hints_enabled" left :color="item.color">
{{ item.type=='spectral' ? 'mdi-chart-bell-curve' : 'mdi-chart-scatter-plot' }}
</v-icon>
{{ item.label }}
{{ api_hints_enabled ?
'\'' + item.label + '\''
:
item.label
}}
</span>
</div>
</template>

<script>
module.exports = {
props: ['item', 'selected', 'multiselect', 'single_select_allow_blank'],
props: ['item', 'selected', 'multiselect', 'single_select_allow_blank', 'api_hints_enabled'],
methods: {
isSelected() {
if (this.multiselect) {
Expand Down
23 changes: 15 additions & 8 deletions jdaviz/components/plugin_layer_select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,30 @@
:hint="hint ? hint : 'Select layer.'"
:rules="rules ? rules : []"
:multiple="multiselect"
:chips="multiselect"
:chips="multiselect && !api_hints_enabled"
item-text="label"
item-value="label"
:persistent-hint="!disable_persistent_hint"
:hide-details="disable_persistent_hint"
>
<template slot="selection" slot-scope="data">
<template v-slot:selection="{ item, index }">
<div class="single-line" style="width: 100%">
<v-chip v-if="multiselect" style="width: calc(100% - 10px)">
<span v-if="api_hints_enabled" class="api-hint" :style="index > 0 ? 'display: none' : null">
{{ multiselect ?
selected
:
'\'' + selected + '\''
}}
</span>
<v-chip v-else-if="multiselect" style="width: calc(100% - 10px)">
<span>
<j-layer-viewer-icon v-if="data.item.icon" :icon="data.item.icon" :icons="icons" :prevent_invert_if_dark="true"></j-layer-viewer-icon>
{{ data.item.label }}
<j-layer-viewer-icon v-if="data.item.icon" :icon="item.icon" :icons="icons" :prevent_invert_if_dark="true"></j-layer-viewer-icon>
{{ item.label }}
</span>
</v-chip>
<span v-else>
<j-layer-viewer-icon v-if="data.item.icon" span_style="margin-right: 4px" :icon="data.item.icon" :icons="icons" :prevent_invert_if_dark="true"></j-layer-viewer-icon>
{{ data.item.label }}
<span v-else >
<j-layer-viewer-icon v-if="item.icon" span_style="margin-right: 4px" :icon="item.icon" :icons="icons" :prevent_invert_if_dark="true"></j-layer-viewer-icon>
{{ item.label }}
</span>
</div>
</template>
Expand Down
87 changes: 87 additions & 0 deletions jdaviz/components/plugin_select.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<template>
<v-row v-if="items.length > 1 || selected.length===0 || show_if_single_entry || api_hints_enabled">
<v-select
:menu-props="{ left: true }"
attach
:items="items"
v-model="selected"
@change="$emit('update:selected', $event)"
:label="api_hints_enabled && api_hint ? api_hint : label"
:class="api_hints_enabled && api_hint ? 'api-hint' : null"
:hint="hint"
:rules="rules ? rules : []"
:multiple="multiselect"
:chips="multiselect && !api_hints_enabled"
:disabled="disabled"
:dense="dense"
item-text="label"
item-value="label"
persistent-hint
>
<template v-slot:selection="{ item, index }">
<div class="single-line" style="width: 100%">
<span v-if="api_hints_enabled" class="api-hint" :style="index > 0 ? 'display: none' : null">
{{ multiselect ?
selected
:
'\'' + selected + '\''
}}
</span>
<v-chip v-else-if="multiselect" style="width: calc(100% - 10px)">
<span>
{{ item }}
</span>
</v-chip>
<span v-else>
{{ item }}
</span>
</div>
</template>
<template v-slot:prepend-item v-if="multiselect">
<v-list-item
ripple
@mousedown.prevent
@click="() => {if (selected.length < items.length) { $emit('update:selected', items.map((item) => {item.label || item.text}))} else {$emit('update:selected', [])}}"
>
<v-list-item-action>
<v-icon>
{{ selected.length == items.length ? 'mdi-close-box' : selected.length ? 'mdi-minus-box' : 'mdi-checkbox-blank-outline' }}
</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>
{{ selected.length < items.length ? "Select All" : "Clear All" }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-divider class="mt-2"></v-divider>
</template>
<template v-slot:item="{ item }">
<span style="margin-top: 8px; margin-bottom: 0px">
{{ item }}
</span>
</template>
</v-select>
<slot> </slot>
</v-row>
</template>

<script>
module.exports = {
props: ['items', 'selected', 'label', 'hint', 'rules', 'show_if_single_entry', 'multiselect',
'api_hint', 'api_hints_enabled', 'dense', 'disabled']
};
</script>

<style scoped>
.v-select__selections {
flex-wrap: nowrap !important;
display: block !important;
margin-bottom: -32px;
}
.single-line {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
Loading

0 comments on commit 81e940d

Please sign in to comment.