[IMP] web: Command Palette Footer Clickable

With this commit, it will be possible to click on the different namespace
in the footer of the command palette to insert the namespace value
directly into the searchValue. The purpose of this feature is to make it
easier to discover how namespaces work.

closes odoo/odoo#82773

Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
FrancoisGe
2022-03-08 11:03:35 +00:00
parent b2058b9942
commit 4cfe0e4b2d
5 changed files with 92 additions and 3 deletions
@@ -82,7 +82,7 @@ export class CommandPalette extends Component {
this.DefaultCommandItem = DefaultCommandItem;
this.activeElement = useService("ui").activeElement;
this.defaultDebounceSearch = debounce.apply(this, [this.search, 0]);
useAutofocus();
this.inputRef = useAutofocus();
useHotkey("Enter", () => this.executeSelectedCommand(), { bypassEditableProtection: true });
useHotkey("ArrowUp", () => this.selectCommandAndScrollTo("PREV"), {
@@ -267,6 +267,9 @@ export class CommandPalette extends Component {
searchValue,
activeElement: this.activeElement,
});
if (this.inputRef.el) {
this.inputRef.el.focus();
}
}
debounceSearch(value) {
@@ -299,5 +302,11 @@ export class CommandPalette extends Component {
}
return { namespace, searchValue };
}
switchNamespace(namespace) {
const searchValue = `${namespace}${this.clearSearchValue}`;
this.state.searchValue = searchValue;
this.debounceSearch(searchValue);
}
}
CommandPalette.template = "web.CommandPalette";
@@ -122,6 +122,12 @@
padding: 0.6rem 1.3em;
border-top: 1px solid rgba(0, 0, 0, 0.1);
.o_namespace:hover {
color: $o-brand-primary;
cursor: pointer;
text-decoration: underline dotted;
}
.o_promote {
color: $o-brand-primary;
font-weight: 900;
@@ -37,7 +37,7 @@
</div>
<div t-if="state.FooterComponent" class="o_command_palette_footer">
<t t-component="state.FooterComponent"/>
<t t-component="state.FooterComponent" switchNamespace="(namespace) => this.switchNamespace(namespace)"/>
</div>
</div>
@@ -43,6 +43,10 @@ class DefaultFooter extends Component {
.map((el) => ({ namespace: el[0], name: el[1].name }))
.filter((el) => el.name);
}
onClick(namespace) {
this.props.switchNamespace(namespace);
}
}
DefaultFooter.template = xml`
<span>
@@ -50,7 +54,9 @@ DefaultFooter.template = xml`
<t t-foreach="elements" t-as="element" t-key="element.namespace">
<t t-if="!(element_first || element_last)">, </t>
<t t-if="element_last and !element_first"> and </t>
<span t-esc="element.namespace" class='o_promote'/><t t-esc="element.name"/>
<span class="o_namespace" t-on-click="() => this.onClick(element.namespace)">
<span t-esc="element.namespace" class='o_promote'/><t t-esc="element.name"/>
</span>
</t>
</span>
`;
@@ -490,6 +490,74 @@ QUnit.test("footer displays the right tips", async (assert) => {
);
});
QUnit.test("namespaces display in the footer are still clickable", async (assert) => {
const action = () => {};
clearRegistryWithCleanup(commandProviderRegistry);
commandProviderRegistry.add("@", {
namespace: "@",
provide: () => [
{
name: "Command@",
action,
},
],
});
commandProviderRegistry.add("#", {
namespace: "#",
provide: () => [
{
name: "Command#",
action,
},
],
});
const commandSetupRegistry = registry.category("command_setup");
clearRegistryWithCleanup(commandSetupRegistry);
commandSetupRegistry.add("default", {});
commandSetupRegistry.add("@", {
name: "users",
});
commandSetupRegistry.add("#", {
name: "channels",
});
await mount(TestComponent, target, { env });
// Open palette
triggerHotkey("control+k");
await nextTick();
assert.strictEqual(
target.querySelector(".o_command_palette_footer").textContent,
"TIP — search for @users and #channels"
);
assert.deepEqual(
[...target.querySelectorAll(".o_command")].map((el) => el.textContent),
[]
);
await click(target.querySelectorAll(".o_command_palette_footer .o_namespace")[0]);
assert.strictEqual(target.querySelector(".o_command_palette_search input").value, "@");
assert.deepEqual(
[...target.querySelectorAll(".o_command")].map((el) => el.textContent),
["Command@"]
);
await editSearchBar("Com");
await click(target.querySelectorAll(".o_command_palette_footer .o_namespace")[1]);
assert.strictEqual(target.querySelector(".o_command_palette_search input").value, "#Com");
assert.deepEqual(
[...target.querySelectorAll(".o_command")].map((el) => el.textContent),
["Command#"]
);
await click(target.querySelectorAll(".o_command_palette_footer .o_namespace")[0]);
assert.strictEqual(target.querySelector(".o_command_palette_search input").value, "@Com");
assert.deepEqual(
[...target.querySelectorAll(".o_command")].map((el) => el.textContent),
["Command@"]
);
});
QUnit.test("defined multiple providers with the same namespace", async (assert) => {
assert.expect(2);