Restructure omni services and add Chatwoot research snapshot
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<script setup>
|
||||
import Button from 'dashboard/components-next/button/Button.vue';
|
||||
|
||||
const emit = defineEmits(['add']);
|
||||
|
||||
const addLabel = () => {
|
||||
emit('add');
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Button
|
||||
faded
|
||||
xs
|
||||
icon="i-lucide-plus"
|
||||
class="mb-0.5 ltr:mr-0.5 rtl:ml-0.5 !rounded-[4px]"
|
||||
:label="$t('CONTACT_PANEL.LABELS.CONVERSATION.ADD_BUTTON')"
|
||||
@click="addLabel"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
class="list-none my-1 mx-0 border-b border-n-weak"
|
||||
:tabindex="null"
|
||||
:aria-disabled="true"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,22 @@
|
||||
<script>
|
||||
export default {
|
||||
componentName: 'WootDropdownMenu',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li class="inline-flex list-none" :tabindex="null" :aria-disabled="true">
|
||||
<span
|
||||
class="text-xs text-n-slate-12 mt-1 font-medium w-full block text-left rtl:text-right whitespace-nowrap p-2"
|
||||
>
|
||||
{{ title }}
|
||||
</span>
|
||||
<slot />
|
||||
</li>
|
||||
</template>
|
||||
@@ -0,0 +1,46 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'WootDropdownItem',
|
||||
componentName: 'WootDropdownMenu',
|
||||
props: {
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
class="mb-1 list-none dropdown-menu__item"
|
||||
:class="{
|
||||
'is-disabled': disabled,
|
||||
}"
|
||||
:tabindex="disabled ? null : -1"
|
||||
:aria-disabled="disabled"
|
||||
>
|
||||
<slot />
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dropdown-menu__item {
|
||||
::v-deep {
|
||||
a,
|
||||
.button {
|
||||
@apply inline-flex whitespace-nowrap w-full text-left rtl:text-right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A hacky fix to remove the background that came from the foundation styles node module file
|
||||
// Can be removed once we remove the foundation styles node module
|
||||
.dropdown.menu {
|
||||
// Top-level item
|
||||
> li > a {
|
||||
background: transparent;
|
||||
padding: 4px 10.8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,66 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
|
||||
|
||||
defineProps({
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'top',
|
||||
},
|
||||
});
|
||||
|
||||
const dropdownMenuRef = ref(null);
|
||||
|
||||
const dropdownMenuButtons = () => {
|
||||
return dropdownMenuRef.value.querySelectorAll(
|
||||
'ul.dropdown li.dropdown-menu__item .button'
|
||||
);
|
||||
};
|
||||
|
||||
const getActiveButtonIndex = menuButtons => {
|
||||
const focusedButton = dropdownMenuRef.value.querySelector(
|
||||
'ul.dropdown li.dropdown-menu__item .button:focus'
|
||||
);
|
||||
return Array.from(menuButtons).indexOf(focusedButton);
|
||||
};
|
||||
|
||||
const focusButton = (menuButtons, newIndex) => {
|
||||
if (menuButtons.length === 0) return;
|
||||
menuButtons[newIndex].focus();
|
||||
};
|
||||
|
||||
const focusPreviousButton = menuButtons => {
|
||||
const activeIndex = getActiveButtonIndex(menuButtons);
|
||||
const newIndex = activeIndex >= 1 ? activeIndex - 1 : menuButtons.length - 1;
|
||||
focusButton(menuButtons, newIndex);
|
||||
};
|
||||
|
||||
const focusNextButton = menuButtons => {
|
||||
const activeIndex = getActiveButtonIndex(menuButtons);
|
||||
const newIndex = activeIndex === menuButtons.length - 1 ? 0 : activeIndex + 1;
|
||||
focusButton(menuButtons, newIndex);
|
||||
};
|
||||
|
||||
const keyboardEvents = {
|
||||
ArrowUp: {
|
||||
action: () => focusPreviousButton(dropdownMenuButtons()),
|
||||
allowOnFocusedInput: true,
|
||||
},
|
||||
ArrowDown: {
|
||||
action: () => focusNextButton(dropdownMenuButtons()),
|
||||
allowOnFocusedInput: true,
|
||||
},
|
||||
};
|
||||
|
||||
useKeyboardEvents(keyboardEvents);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul
|
||||
ref="dropdownMenuRef"
|
||||
class="dropdown menu vertical"
|
||||
:class="[placement && `dropdown--${placement}`]"
|
||||
>
|
||||
<slot />
|
||||
</ul>
|
||||
</template>
|
||||
@@ -0,0 +1,27 @@
|
||||
<script>
|
||||
import WootDropdownHeader from 'shared/components/ui/dropdown/DropdownHeader.vue';
|
||||
|
||||
export default {
|
||||
name: 'WootDropdownMenu',
|
||||
componentName: 'WootDropdownMenu',
|
||||
|
||||
components: {
|
||||
WootDropdownHeader,
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li class="!mt-0.5">
|
||||
<ul class="!m-0">
|
||||
<WootDropdownHeader v-if="title" :title="title" />
|
||||
<slot />
|
||||
</ul>
|
||||
</li>
|
||||
</template>
|
||||
Reference in New Issue
Block a user