Skip to content

Commit bca451f

Browse files
authored
Merge pull request #54474 from nextcloud/leftybournes/feat/contactsmenu_register_actions
feat: provide api to register actions in contacts menu
2 parents c026c7c + 9f3da00 commit bca451f

File tree

6 files changed

+77
-15
lines changed

6 files changed

+77
-15
lines changed

core/src/components/ContactsMenu.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
import Vue from 'vue'
77

88
import ContactsMenu from '../views/ContactsMenu.vue'
9+
import ContactsMenuService from '../services/ContactsMenuService.ts'
910

1011
/**
1112
* @todo move to contacts menu code https://github.com/orgs/nextcloud/projects/31#card-21213129
1213
*/
1314
export const setUp = () => {
1415
const mountPoint = document.getElementById('contactsmenu')
16+
1517
if (mountPoint) {
18+
window.OC.ContactsMenu = new ContactsMenuService()
1619
// eslint-disable-next-line no-new
1720
new Vue({
1821
name: 'ContactsMenuRoot',
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import type { IContactsMenuAction } from '../types/contactsMenuAction.ts'
7+
8+
export default class ContactsMenuService {
9+
10+
private _actions: IContactsMenuAction[]
11+
12+
constructor() {
13+
this._actions = []
14+
}
15+
16+
get actions(): IContactsMenuAction[] {
17+
return this._actions
18+
}
19+
20+
/*
21+
* Register an action for the contacts menu
22+
* Actions use NcButton
23+
*/
24+
addAction(action: IContactsMenuAction): void {
25+
this._actions.push(action)
26+
}
27+
28+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*!
2+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
export interface IContactsMenuAction {
7+
id: string
8+
icon: string
9+
label: string
10+
onClick: () => void | Promise<void>
11+
}

core/src/views/ContactsMenu.vue

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,31 @@
1212
<NcIconSvgWrapper class="contactsmenu__trigger-icon" :path="mdiContacts" />
1313
</template>
1414
<div class="contactsmenu__menu">
15-
<div class="contactsmenu__menu__input-wrapper">
16-
<NcTextField id="contactsmenu__menu__search"
17-
ref="contactsMenuInput"
18-
:value.sync="searchTerm"
19-
trailing-button-icon="close"
20-
:label="t('core', 'Search contacts')"
21-
:trailing-button-label="t('core','Reset search')"
22-
:show-trailing-button="searchTerm !== ''"
23-
:placeholder="t('core', 'Search contacts …')"
24-
class="contactsmenu__menu__search"
25-
@input="onInputDebounced"
26-
@trailing-button-click="onReset" />
15+
<div class="contactsmenu__menu__search-container">
16+
<div class="contactsmenu__menu__input-wrapper">
17+
<NcTextField id="contactsmenu__menu__search"
18+
ref="contactsMenuInput"
19+
v-model="searchTerm"
20+
trailing-button-icon="close"
21+
:label="t('core', 'Search contacts')"
22+
:trailing-button-label="t('core','Reset search')"
23+
:show-trailing-button="searchTerm !== ''"
24+
:placeholder="t('core', 'Search contacts …')"
25+
class="contactsmenu__menu__search"
26+
@input="onInputDebounced"
27+
@trailing-button-click="onReset" />
28+
</div>
29+
<NcButton v-for="action in actions"
30+
:key="action.id"
31+
:aria-label="action.label"
32+
:title="action.label"
33+
class="contactsmenu__menu__action"
34+
variant="tertiary-no-background"
35+
@click="action.onClick">
36+
<template #icon>
37+
<NcIconSvgWrapper :svg="action.icon" />
38+
</template>
39+
</NcButton>
2740
</div>
2841
<NcEmptyContent v-if="error" :name="t('core', 'Could not load your contacts')">
2942
<template #icon>
@@ -105,6 +118,7 @@ export default {
105118
data() {
106119
const user = getCurrentUser()
107120
return {
121+
actions: window.OC?.ContactsMenu?.actions || [],
108122
contactsAppEnabled: false,
109123
contactsAppURL: generateUrl('/apps/contacts'),
110124
contactsAppMgmtURL: generateUrl('/settings/apps/social/contacts'),
@@ -195,10 +209,16 @@ export default {
195209
margin-inline-start: 13px;
196210
}
197211
212+
&__search-container {
213+
display: flex;
214+
flex: row nowrap;
215+
}
216+
198217
&__input-wrapper {
199218
padding: 10px;
200219
z-index: 2;
201220
top: 0;
221+
flex-grow: 1;
202222
}
203223
204224
&__search {

dist/core-main.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/core-main.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)