Restructure omni services and add Chatwoot research snapshot

This commit is contained in:
Ruslan Bakiev
2026-02-21 11:11:27 +07:00
parent edea7a0034
commit b73babbbf6
7732 changed files with 978203 additions and 32 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>