Some checks failed
Build and Publish / build-release (push) Failing after 1m31s
147 lines
3.4 KiB
Vue
147 lines
3.4 KiB
Vue
<script setup lang="ts">
|
|
|
|
const { organizations, selectedOrg, selectOrg } = useOrganizationSelection()
|
|
|
|
const dropdownOpen = ref(false)
|
|
const dropdownRoot = ref<HTMLElement | null>(null)
|
|
|
|
function toggleDropdown() {
|
|
dropdownOpen.value = !dropdownOpen.value
|
|
}
|
|
|
|
function closeDropdown() {
|
|
dropdownOpen.value = false
|
|
}
|
|
|
|
function onDocClick(e: MouseEvent) {
|
|
const el = dropdownRoot.value
|
|
if (el && dropdownOpen.value && !el.contains(e.target as Node)) {
|
|
dropdownOpen.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(() => document.addEventListener('click', onDocClick))
|
|
onUnmounted(() => document.removeEventListener('click', onDocClick))
|
|
</script>
|
|
|
|
<template>
|
|
<div v-if="organizations.length > 0" ref="dropdownRoot" class="org-selector-root">
|
|
<button
|
|
type="button"
|
|
class="org-selector-btn"
|
|
aria-label="Organization selector"
|
|
:aria-expanded="dropdownOpen"
|
|
@click.stop="toggleDropdown"
|
|
>
|
|
<UIcon name="i-heroicons-building-office" style="width: 13px; height: 13px; flex-shrink: 0;" />
|
|
<span class="org-selector-label">{{ selectedOrg?.orgSubDomain ?? 'Org' }}</span>
|
|
<UIcon name="i-heroicons-chevron-down" style="width: 8px; height: 8px; opacity: 0.4; flex-shrink: 0;" />
|
|
</button>
|
|
<div
|
|
v-show="dropdownOpen"
|
|
class="org-dropdown"
|
|
>
|
|
<button
|
|
v-for="org in organizations"
|
|
:key="org.orgId"
|
|
type="button"
|
|
class="org-option"
|
|
:class="{ 'org-option-active': org.orgId === selectedOrg?.orgId }"
|
|
@click="selectOrg(org.orgId); closeDropdown()"
|
|
>
|
|
<UIcon
|
|
name="i-heroicons-check"
|
|
class="shrink-0"
|
|
:class="org.orgId === selectedOrg?.orgId ? 'opacity-100' : 'opacity-0'"
|
|
style="width: 14px; height: 14px;"
|
|
/>
|
|
<span class="org-option-label">{{ org.orgSubDomain }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.org-selector-root {
|
|
position: relative;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.org-selector-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 2px 8px;
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
line-height: normal;
|
|
color: #8a8a86;
|
|
background: transparent;
|
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
transition: all 150ms ease;
|
|
white-space: nowrap;
|
|
box-sizing: content-box;
|
|
height: auto;
|
|
}
|
|
.org-selector-btn:hover {
|
|
color: var(--text-primary);
|
|
background: rgba(0, 0, 0, 0.03);
|
|
border-color: rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.org-selector-label {
|
|
max-width: 100px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.org-dropdown {
|
|
position: absolute;
|
|
right: 0;
|
|
top: calc(100% + 6px);
|
|
z-index: 50;
|
|
min-width: 180px;
|
|
max-width: 280px;
|
|
overflow: hidden;
|
|
border-radius: 12px;
|
|
border: 1px solid var(--sidebar-border);
|
|
background: var(--surface);
|
|
padding: 4px 0;
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.03);
|
|
}
|
|
|
|
.org-option {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
width: 100%;
|
|
padding: 6px 12px;
|
|
text-align: left;
|
|
font-size: 12px;
|
|
color: var(--text-secondary);
|
|
background: transparent;
|
|
border: none;
|
|
cursor: pointer;
|
|
border-radius: 4px;
|
|
transition: background 100ms ease;
|
|
}
|
|
.org-option:hover {
|
|
background: var(--brand-faint);
|
|
color: var(--text-primary);
|
|
}
|
|
.org-option-active {
|
|
color: var(--text-primary);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.org-option-label {
|
|
max-width: 200px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
</style>
|