Skip to content
Snippets Groups Projects
OcResourceSearchSimple.vue 3.87 KiB
<template>
  <InputGroup class="w-full mt-8 mb-4">
    <InputGroupAddon 
      class="px-4 cursor-pointer hover:bg-gray-100 hover:text-primary"
      @click="emit('submit')"
    >
      <i class="fa-solid fa-magnifying-glass"/>
    </InputGroupAddon>
    <InputText
      id="search"
      v-model="model.q"
      fluid
      size="large"
      :placeholder="t('community.homepage.searchBarPlaceholder')"
      v-on:keyup.enter="emit('submit')"
      :disabled="props.loading"
    />
    <InputGroupAddon 
      class="px-4 cursor-pointer hover:text-black hover:bg-gray-100"
      @click="model = {params:{}}, emit('submit')"
    >
      <i class="fa-solid fa-xmark"/>
    </InputGroupAddon>
    <InputGroupAddon
      v-if="searchPop"
      class="inline-flex gap-2 text-gray-500 cursor-pointer hover:bg-gray-100 hover:text-black px-4"
      @click="searchPop.toggle"
    >
      <h3>{{ t('search.searchBarParamButtonLabel') }}</h3>
      <i :class="{
        'fa-chevron-down': !searchPop.visible,
        'fa-chevron-up': searchPop.visible
      }"
      class="fa-solid"
      />
    </InputGroupAddon>
  </InputGroup>
  <div id="popoverPlace" class="h-0 m-0 p-0" />
  <Popover id="popover" class="h-fit w-full" ref="searchPop" appendTo="#popoverPlace">
    <div v-for="key in Object.keys(SearchQueryParams)" v-bind:key="key">
      <label :for="key" class="font-medium">{{ translateValue(searchMetadata[key as keyof typeof SearchQueryParams].label) }}</label>
      <OcMultipleField
        class="mt-1 mb-2"
        :name="key"
        :id="key"
        :inputComponent="InputText"
        :inputProps="{ fluid: true }"
        :initialValue="model.params[key as keyof typeof SearchQueryParams]"
        v-on:updateValue="handleChange($event, key)"
        v-on:keyup.enter="emit('submit')"
      />
    </div>
    <div class="text-right">
      <Button class="mt-6" @click="searchPop.toggle($event), emit('submit')">
        {{ t('search.launchSearch') }}
      </Button>
    </div>
  </Popover>
  <div class="display flex flex-row flex-wrap gap-2 mb-4">
    <Chip
      v-if="model.q"
      class="bg-gray-200"
      :label="model.q"
      removable
      @remove="model.q='', emit('submit')"
    />
    <template v-for="key in Object.keys(SearchQueryParams)" v-bind:key="key">
      <Chip
        v-for="value in model.params[key as keyof typeof SearchQueryParams]" v-bind:key="value"
        class="bg-gray-200"
        :label="translateValue(searchMetadata[key as keyof typeof SearchQueryParams].label) + ': ' + value"
        removable
        @remove="model.params[key]=model.params[key as keyof typeof SearchQueryParams]?.filter((v) => v != value), emit('submit')"
      />
    </template>
  </div>
</template>

<script setup lang="ts">
import InputText from 'primevue/inputtext'
import InputGroup from 'primevue/inputgroup';
import InputGroupAddon from 'primevue/inputgroupaddon';
import Button from 'primevue/button'
import Popover from 'primevue/popover'
import Chip from 'primevue/chip';
import { SearchQueryParams, type OcSearchQuery } from '@/declarations'
import { useI18n } from 'vue-i18n'
import { ref } from 'vue'
import OcMultipleField from '@/components/FormInputs/OcMultipleField/OcMultipleField.vue'
import { searchMetadata } from '@/modelMetadata/search'
import { useTranslateValue } from '@/composables/useTranslateValue'

const { t } = useI18n()
const { translateValue } = useTranslateValue()

const model = defineModel<OcSearchQuery>({
  required: true,
  default: {
    params: {}
  }
})

const props = defineProps({
  loading: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits<{
  submit: []
}>()

const searchPop = ref()

function handleChange(newValue: any, key: string) {
  model.value.params[key as keyof typeof SearchQueryParams] = newValue
}
</script>
<style scoped>
:deep(#popover) {
  position: relative !important;
  left: 0 !important;
  top: 0 !important;
  z-index: 1 !important;
}
</style>