Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filterable create #7978

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/api/forms/components/FormProperties.vue
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ export default {
}
},
mounted() {
document.addEventListener('keydown', this.handleKeyDown);
this.formSections = this.model.sections.map((section) => {
section.id = uuid();

Expand All @@ -141,6 +142,9 @@ export default {
return section;
});
},
unmounted() {
document.removeEventListener('keydown', this.handleKeyDown);
},
methods: {
onChange(data) {
this.invalidProperties[data.model.key] = data.invalid;
Expand All @@ -152,6 +156,13 @@ export default {
},
onSave() {
this.$emit('on-save');
},
handleKeyDown({ key }) {
if (key === 'Enter' && !this.isInvalid) {
this.onSave();
} else if (key === 'Escape') {
this.onCancel();
}
}
}
};
Expand Down
154 changes: 107 additions & 47 deletions src/api/menu/components/SuperMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,53 +26,66 @@
:class="[options.menuClass, 'c-super-menu']"
:style="styleObject"
>
<ul
v-if="options.actions.length && options.actions[0].length"
role="menu"
class="c-super-menu__menu"
>
<template v-for="(actionGroups, index) in options.actions" :key="index">
<div role="group">
<li
v-for="action in actionGroups"
:key="action.name"
role="menuitem"
:aria-disabled="action.isDisabled"
aria-describedby="item-description"
:class="action.cssClass"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()"
>
{{ action.name }}
</li>
<div
v-if="index !== options.actions.length - 1"
:key="index"
role="separator"
class="c-menu__section-separator"
></div>
<li v-if="actionGroups.length === 0" :key="index">No actions defined.</li>
</div></template
<div class="c-super-menu__left-col">
<div v-if="options.filterable" class="c-super-menu__filter l-input-lg">
<input
ref="filterInput"
v-model="searchTerm"
type="text"
placeholder="Filter..."
@input="filterItems"
@keydown.stop="handleKeyDown"
@click.stop
/>
</div>
<ul
v-if="filteredActions.length && filteredActions[0].length"
role="menu"
class="c-super-menu__menu"
>
</ul>
<template v-for="(actionGroups, index) in filteredActions" :key="index">
<div role="group">
<li
v-for="action in actionGroups"
:key="action.name"
role="menuitem"
:aria-disabled="action.isDisabled"
aria-describedby="item-description"
:class="action.cssClass"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()"
>
{{ action.name }}
</li>
<div
v-if="index !== filteredActions.length - 1"
:key="index"
role="separator"
class="c-menu__section-separator"
></div>
<li v-if="actionGroups.length === 0" :key="index">No actions defined.</li>
</div></template
>
</ul>

<ul v-else class="c-super-menu__menu" role="menu">
<li
v-for="action in options.actions"
:key="action.name"
role="menuitem"
:class="action.cssClass"
:aria-label="action.name"
aria-describedby="item-description"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()"
>
{{ action.name }}
</li>
<li v-if="options.actions.length === 0">No actions defined.</li>
</ul>
<ul v-else class="c-super-menu__menu" role="menu">
<li
v-for="action in filteredActions"
:key="action.name"
role="menuitem"
:class="action.cssClass"
:aria-label="action.name"
aria-describedby="item-description"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()"
>
{{ action.name }}
</li>
<li v-if="filteredActions.length === 0">No actions defined.</li>
</ul>
</div>

<div aria-live="polite" class="c-super-menu__item-description">
<div :class="itemDescriptionIconClass"></div>
Expand All @@ -89,10 +102,12 @@
import popupMenuMixin from '../mixins/popupMenuMixin.js';
export default {
mixins: [popupMenuMixin],
inject: ['options'],
inject: ['options', 'dismiss'],
data() {
return {
hoveredItem: null
hoveredItem: null,
filteredActions: [],
searchTerm: ''
};
},
computed: {
Expand All @@ -114,6 +129,15 @@ export default {
return this.hoveredItem?.description ?? '';
}
},
mounted() {
this.filteredActions = this.options.actions;

if (this.options.filterable) {
this.$nextTick(() => {
this.$refs.filterInput.focus();
});
}
},
methods: {
toggleItemDescription(action = null) {
const hoveredItem = {
Expand All @@ -123,6 +147,42 @@ export default {
};

this.hoveredItem = hoveredItem;
},
filterItems() {
const term = this.searchTerm.toLowerCase();

if (!term) {
this.filteredActions = this.options.actions;

return;
}

if (Array.isArray(this.options.actions[0])) {
// Handle grouped actions
this.filteredActions = this.options.actions
.map((group) => group.filter((action) => action.name.toLowerCase().includes(term)))
.filter((group) => group.length > 0);
} else {
// Handle flat actions list
this.filteredActions = this.options.actions.filter((action) =>
action.name.toLowerCase().includes(term)
);
}
},
handleKeyDown({ key }) {
if (key === 'Enter') {
// if there is only one action, select it immediately on enter
const flattenedActions = Array.isArray(this.filteredActions[0])
? this.filteredActions.flat()
: this.filteredActions;

if (flattenedActions.length === 1) {
flattenedActions[0].onItemClicked();
this.dismiss();
}
} else if (key === 'Escape') {
this.dismiss();
}
}
}
};
Expand Down
3 changes: 2 additions & 1 deletion src/api/menu/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ class Menu extends EventEmitter {
return h(SuperMenuComponent);
},
provide: {
options: this.options
options: this.options,
dismiss: this.dismiss
}
});

Expand Down
16 changes: 16 additions & 0 deletions src/api/overlays/components/OverlayComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export default {
};
},
mounted() {
document.addEventListener('keydown', this.handleKeyDown);
const element = this.$refs.element;
element.appendChild(this.element);
const elementForFocus = this.getElementForFocus() || element;
Expand All @@ -73,6 +74,7 @@ export default {
},
methods: {
destroy() {
document.removeEventListener('keydown', this.handleKeyDown);
if (this.dismissible) {
this.dismiss();
}
Expand Down Expand Up @@ -100,6 +102,20 @@ export default {
}

return focusButton[0];
},
handleKeyDown({ key }) {
if (key === 'Enter') {
if (this.focusIndex >= 0 && this.focusIndex < this.buttons.length) {
this.buttonClickHandler(this.buttons[this.focusIndex].callback);
} else {
const okButton = this.buttons?.find((button) => button.label.toLowerCase() === 'ok');
if (okButton) {
this.buttonClickHandler(okButton.callback);
}
}
} else if (key === 'Escape') {
this.destroy();
}
}
}
};
Expand Down
14 changes: 13 additions & 1 deletion src/plugins/timeConductor/TimePopupFixed.vue
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,22 @@ export default {
this.handleNewBounds = _.throttle(this.handleNewBounds, 300);
},
mounted() {
document.addEventListener('keydown', this.handleKeyDown);
this.setTimeSystem(JSON.parse(JSON.stringify(this.openmct.time.getTimeSystem())));
this.setViewFromBounds(this.bounds);
},
beforeUnmount() {
this.clearAllValidation();
document.removeEventListener('keydown', this.handleKeyDown);
},
methods: {
handleKeyDown({ key }) {
if (key === 'Enter' && !this.hasInputValidityError) {
this.handleFormSubmission(true);
} else if (key === 'Escape') {
this.dismiss();
}
},
handleNewBounds(bounds) {
this.setBounds(bounds);
this.setViewFromBounds(bounds);
Expand Down Expand Up @@ -322,8 +331,11 @@ export default {
},
hide($event) {
if ($event.target.className.indexOf('c-button icon-x') > -1) {
this.$emit('dismiss');
this.dismiss();
}
},
dismiss() {
this.$emit('dismiss');
}
}
};
Expand Down
16 changes: 14 additions & 2 deletions src/plugins/timeConductor/TimePopupRealtime.vue
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,20 @@ export default {
mounted() {
this.setOffsets();
document.addEventListener('click', this.hide);
document.addEventListener('keydown', this.handleKeyDown);
},
beforeUnmount() {
document.removeEventListener('click', this.hide);
document.removeEventListener('keydown', this.handleKeyDown);
},
methods: {
handleKeyDown({ key }) {
if (key === 'Enter' && !this.isDisabled) {
this.submit();
} else if (key === 'Escape') {
this.dismiss();
}
},
format(ref) {
const curVal = this[ref];
this[ref] = curVal.toString().padStart(2, '0');
Expand Down Expand Up @@ -218,13 +227,16 @@ export default {
seconds: this.endInputSecs
}
});
this.$emit('dismiss');
this.dismiss();
},
hide($event) {
if ($event.target.className.indexOf('c-button icon-x') > -1) {
this.$emit('dismiss');
this.dismiss();
}
},
dismiss() {
this.$emit('dismiss');
},
increment($ev, ref) {
$ev.preventDefault();
const step = ref === 'startInputHrs' || ref === 'endInputHrs' ? 1 : 5;
Expand Down
2 changes: 1 addition & 1 deletion src/styles/_constants-darkmatter.scss
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ $colorMenuElementHilite: pullForward($colorMenuBg, 10%);
$shdwMenu: rgba(black, 0.8) 0 2px 10px;
$shdwMenuInner: inset 0 0 0 1px rgba(white, 0.2);
$shdwMenuText: none;
$menuItemPad: $interiorMargin, floor($interiorMargin * 1.25);
$menuItemPad: 4px, 6px;

// Palettes and Swatches
$paletteItemBorderOuterColorSelected: black;
Expand Down
2 changes: 1 addition & 1 deletion src/styles/_constants-espresso.scss
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ $colorMenuElementHilite: pullForward($colorMenuBg, 10%);
$shdwMenu: rgba(black, 0.8) 0 2px 10px;
$shdwMenuInner: inset 0 0 0 1px rgba(white, 0.2);
$shdwMenuText: none;
$menuItemPad: $interiorMargin, floor($interiorMargin * 1.25);
$menuItemPad: 4px, 6px;

// Palettes and Swatches
$paletteItemBorderOuterColorSelected: black;
Expand Down
2 changes: 1 addition & 1 deletion src/styles/_constants-maelstrom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ $colorMenuElementHilite: pullForward($colorMenuBg, 10%);
$shdwMenu: rgba(black, 0.8) 0 2px 10px;
$shdwMenuInner: inset 0 0 0 1px rgba(white, 0.2);
$shdwMenuText: none;
$menuItemPad: $interiorMargin, floor($interiorMargin * 1.25);
$menuItemPad: 4px, 6px;

// Palettes and Swatches
$paletteItemBorderOuterColorSelected: black;
Expand Down
2 changes: 1 addition & 1 deletion src/styles/_constants-snow.scss
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ $colorMenuElementHilite: darken($colorMenuBg, 10%);
$shdwMenu: rgba(black, 0.8) 0 2px 10px;
$shdwMenuInner: none;
$shdwMenuText: none;
$menuItemPad: $interiorMargin, floor($interiorMargin * 1.25);
$menuItemPad: 4px, 6px;

// Palettes and Swatches
$paletteItemBorderOuterColorSelected: black;
Expand Down
Loading
Loading