Page MenuHomePhorge

No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None
diff --git a/src/components/user_selector_input/user_selector_input.js b/src/components/user_selector_input/user_selector_input.js
index 4a171c2d67..67a50bb2c0 100644
--- a/src/components/user_selector_input/user_selector_input.js
+++ b/src/components/user_selector_input/user_selector_input.js
@@ -1,95 +1,98 @@
import { debounce } from 'lodash-es'
import { computed, ref, watch } from 'vue'
import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
import List from 'src/components/list/list.vue'
import { useSearchStore } from 'src/stores/search.js'
import { useUsersStore } from 'src/stores/users.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faCircleNotch,
faPencil,
faXmark,
} from '@fortawesome/free-solid-svg-icons'
library.add(faCircleNotch, faPencil, faXmark)
const UserSelectorInput = {
components: {
BasicUserCard,
List,
},
props: {
modelValue: String,
},
emits: ['update:modelValue'],
setup(props, { emit }) {
const usernameInput = ref('')
watch(props.modelValue, () => {
if (props.modelValue) {
useUsersStore().fetchUserIfMissing({ id: props.modelValue })
}
})
const editing = ref(!props.modelValue)
const user = computed(() => {
if (props.modelValue) {
return useUsersStore().findUser(props.modelValue)
}
return null
})
const searchResults = ref([])
const loading = ref(false)
+ const outdated = computed(() => searchResults.value.length && loading.value)
const debouncedLoad = debounce((newQuery) => {
let cancelled = false
if (newQuery) {
- loading.value = true
useSearchStore()
.searchUsers({ query: newQuery })
.then((users) => {
loading.value = false
if (!cancelled) {
searchResults.value = users
}
})
} else {
+ searchResults.value = []
loading.value = false
}
return () => {
cancelled = true
}
}, 1000)
watch(usernameInput, (newQuery, _, onCleanup) => {
+ loading.value = true
const cancel = debouncedLoad(newQuery)
onCleanup(() => {
if (cancel) {
cancel()
}
})
})
const selectUser = (user) => {
emit('update:modelValue', user.id)
editing.value = false
}
const clear = () => {
emit('update:modelValue', '')
editing.value = false
}
return {
user,
usernameInput,
searchResults,
loading,
+ outdated,
editing,
selectUser,
clear,
}
},
}
export default UserSelectorInput
diff --git a/src/components/user_selector_input/user_selector_input.vue b/src/components/user_selector_input/user_selector_input.vue
index c249afae69..6f8bd53a1d 100644
--- a/src/components/user_selector_input/user_selector_input.vue
+++ b/src/components/user_selector_input/user_selector_input.vue
@@ -1,106 +1,113 @@
<template>
<div class="user-selector">
<div class="input-row">
<component :is="editing ? 'label' : 'div'" class="input-label">
<slot>
</slot>
<input
v-show="editing"
v-model="usernameInput"
class="input"
:placeholder="$t('user_selector.username_input_placeholder')"
>
<span
v-show="!editing"
class="result-display"
>
<BasicUserCard
v-if="user"
:user="user"
/>
<span v-else>
{{ $t('user_selector.none') }}
</span>
</span>
</component>
<button
v-if="!editing"
class="btn button-default"
@click.prevent="editing = true"
:title="$t('user_selector.edit')"
>
<FAIcon
icon="pencil"
/>
</button>
<button
class="btn button-default"
:title="$t('user_selector.clear')"
@click.prevent="clear"
>
<FAIcon
icon="xmark"
/>
</button>
</div>
<List
v-if="editing && searchResults.length"
+ class="search-results"
+ :class="{ '-faded': outdated }"
:external-items="searchResults"
>
<template #item="{item}">
<BasicUserCard :user="item" />
<button
class="btn button-default"
@click.prevent="selectUser(item)"
>{{ $t('user_selector.select') }}</button>
</template>
</List>
<span
v-else-if="loading"
:aria-label="$t('general.loading')"
>
<FAIcon
class="fa-old-padding"
spin
icon="circle-notch"
/>
</span>
</div>
</template>
<script src="./user_selector_input.js"></script>
<style>
.user-selector {
display: flex;
flex-direction: column;
align-items: stretch;
.input-row {
display: flex;
flex-direction: row;
align-items: center;
}
.input-label {
flex: 1;
display: flex;
max-width: 100%;
flex-direction: row;
align-items: center;
overflow-x: hidden;
}
.input, .result-display {
flex: 1;
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.result-display {
display: flex;
flex-direction: row;
align-items: center;
}
+
+ .search-results.-faded {
+ --text: var(--textFaint);
+ --link: var(--linkFaint);
+ }
}
</style>

File Metadata

Mime Type
text/x-diff
Expires
Tue, Oct 13, 8:38 AM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1786672
Default Alt Text
(5 KB)

Event Timeline