internal/dashboard/frontend/src/components/Filter/JsonFieldFilter.vue

<script setup lang="ts">
import { IconX } from "@tabler/icons-vue";
import FilterPill from "components/Filter/FilterPill.vue";
import { ref } from "vue";

const props = defineProps<{
  fieldKey?: string;
  modelValue?: string[];
  fixedKey?: boolean;
}>();

const emit = defineEmits<{
  (e: "update:modelValue", value: string[]): void;
  (e: "update:fieldKey", value: string): void;
  (e: "imgood"): void;
  (e: "remove"): void;
}>();

const currentKey = ref(props.fieldKey || "");
const currentValue = ref("");

function addValue() {
  if (!currentValue.value) return;
  const newValues = [...(props.modelValue || []), currentValue.value];
  emit("update:modelValue", newValues);
  currentValue.value = "";
}

function removeValue(val: string) {
  const newValues = (props.modelValue || []).filter((v) => v !== val);
  emit("update:modelValue", newValues);
}

function onKeyChange() {
  emit("update:fieldKey", currentKey.value);
}
</script>

<template>
  <div class="flex items-center gap-2">
    <!-- Label / Key Input -->
    <div v-if="fixedKey" class="filter-label cursor-pointer">
      {{ currentKey }}:
    </div>
    <div v-else class="flex items-center gap-1">
      <input
        v-model="currentKey"
        @change="onKeyChange"
        type="text"
        placeholder="key"
        class="w-24"
      />
      <span class="text-stone-500">:</span>
    </div>

    <!-- Value Input -->
    <div class="relative flex items-center gap-1">
      <input
        v-model="currentValue"
        @keydown.enter="addValue"
        type="text"
        :placeholder="modelValue?.length ? '' : 'value'"
        class="w-32"
      />
      <button
        v-if="currentValue.length > 0"
        @click="currentValue = ''"
        class="absolute top-1.5 right-1.5 text-stone-500 hover:text-stone-300"
      >
        <IconX size="14" />
      </button>
    </div>

    <!-- Values -->
    <div class="flex flex-wrap items-center" v-if="modelValue?.length">
      <FilterPill
        v-for="val in modelValue"
        :key="val"
        :label="val"
        @click="removeValue(val)"
      />
    </div>
  </div>
</template>