{"version":3,"file":"JSearchPanel.vue2.cjs","sources":["../../../../src/components/organisms/JSearchPanel.vue"],"sourcesContent":["<template>\n  <Card class=\"w-full\">\n    <!-- 헤더: 제목, Badge 목록, 초기화 버튼 -->\n    <CardHeader class=\"pt-2 pb-2 px-3\">\n      <div class=\"flex items-center justify-between\">\n        <div class=\"flex items-center gap-2 flex-1\">\n          <button\n            v-if=\"collapsible\"\n            type=\"button\"\n            class=\"flex items-center gap-2 font-semibold hover:text-primary transition-colors\"\n            @click=\"isExpanded = !isExpanded\"\n          >\n            <ChevronDown\n              :class=\"['h-4 w-4 transition-transform', isExpanded ? 'rotate-0' : '-rotate-90']\"\n            />\n            {{ title }}\n          </button>\n          <CardTitle v-else class=\"mb-0\">{{ title }}</CardTitle>\n          \n          <!-- 조건 Badge 목록 -->\n          <div v-if=\"conditionBadges.length > 0\" class=\"flex flex-wrap items-center gap-1 ml-1\">\n            <JBadge\n              v-for=\"badge in conditionBadges\"\n              :key=\"badge.fieldName\"\n              variant=\"secondary\"\n              size=\"sm\"\n              class=\"flex items-center gap-1.5 pr-1\"\n            >\n              <span>{{ badge.label }}: {{ badge.value }}</span>\n              <button\n                type=\"button\"\n                class=\"h-4 w-4 rounded-full hover:bg-destructive/20 hover:text-destructive transition-colors flex items-center justify-center\"\n                :aria-label=\"`${badge.label} 조건 제거`\"\n                @click.stop=\"handleFieldReset(badge.fieldName)\"\n              >\n                <X class=\"h-3 w-3\" />\n              </button>\n            </JBadge>\n          </div>\n        </div>\n        \n        <JButton\n          variant=\"outline\"\n          size=\"sm\"\n          @click.stop=\"handleReset\"\n        >\n          초기화\n        </JButton>\n      </div>\n    </CardHeader>\n    \n    <!-- 폼 내용 -->\n    <CardContent v-show=\"isExpanded || !collapsible\" class=\"px-3 pb-2 pt-0\">\n      <JDynamicForm\n        ref=\"dynamicFormRef\"\n        :schema=\"schema\"\n        :model-value=\"localModelValue\"\n        @update:model-value=\"handleFormValueUpdate\"\n        @submit=\"handleSubmit\"\n      />\n    </CardContent>\n  </Card>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, reactive, watch } from 'vue'\nimport { ChevronDown, X } from 'lucide-vue-next'\nimport { Card, CardHeader, CardTitle, CardContent } from '@/components/shadcn'\nimport { JButton, JBadge } from '@/components/atoms'\nimport JDynamicForm from './JDynamicForm.vue'\nimport type { FormSchema, DynamicFormField } from '@/types/dynamic-form'\nimport type { ComponentPublicInstance } from 'vue'\n\ninterface ConditionBadge {\n  fieldName: string\n  label: string\n  value: string\n}\n\nexport interface JSearchPanelProps {\n  /** 패널 제목 */\n  title?: string\n  /** JDynamicForm에 전달할 FormSchema */\n  schema: FormSchema\n  /** JDynamicForm의 v-model 값 */\n  modelValue?: Record<string, any>\n  /** 기본 접힘 상태 */\n  defaultCollapsed?: boolean\n  /** 접기/펼치기 가능 여부 */\n  collapsible?: boolean\n}\n\nconst props = withDefaults(defineProps<JSearchPanelProps>(), {\n  title: '조회조건',\n  defaultCollapsed: false,\n  collapsible: true,\n})\n\nconst emit = defineEmits<{\n  'update:modelValue': [value: Record<string, any>]\n  'submit': [values: Record<string, any>]\n  'reset': []\n}>()\n\nconst dynamicFormRef = ref<ComponentPublicInstance & { reset: () => void } | null>(null)\nconst isExpanded = ref(!props.defaultCollapsed)\n\n// 로컬 modelValue - reactive로 관리하여 양방향 바인딩\nconst localModelValue = reactive<Record<string, any>>(props.modelValue ? { ...props.modelValue } : {})\n\n// 내부 변경인지 외부 변경인지 구분하는 플래그\nlet isInternalUpdate = false\n\n// props.modelValue 변경 시 localModelValue 동기화 (외부 변경)\nwatch(\n  () => props.modelValue,\n  (newValue) => {\n    if (newValue && !isInternalUpdate) {\n      // 기존 키 중 새 값에 없는 것은 삭제\n      Object.keys(localModelValue).forEach(key => {\n        if (!(key in newValue)) {\n          delete localModelValue[key]\n        }\n      })\n      // 새 값으로 업데이트\n      Object.assign(localModelValue, newValue)\n    }\n    isInternalUpdate = false\n  },\n  { deep: true, immediate: true }\n)\n\n// JDynamicForm에서 값이 변경되었을 때 처리\nfunction handleFormValueUpdate(value: Record<string, any>) {\n  // JDynamicForm에서 emit된 값을 localModelValue에 반영\n  isInternalUpdate = true\n  Object.assign(localModelValue, value)\n  // 상위로 emit\n  emit('update:modelValue', { ...value })\n}\n\n// 모든 필드 가져오기\nconst allFields = computed((): DynamicFormField[] => {\n  if (!props.schema) return []\n  \n  const fields: DynamicFormField[] = []\n  if (props.schema.type === 'simple' && props.schema.fields) {\n    fields.push(...props.schema.fields)\n  } else if (props.schema.type === 'sectioned' && props.schema.sections) {\n    props.schema.sections.forEach(section => {\n      if (section.fields) fields.push(...section.fields)\n    })\n  } else if (props.schema.type === 'wizard' && props.schema.steps) {\n    props.schema.steps.forEach(step => {\n      if (step.fields) fields.push(...step.fields)\n    })\n  }\n  return fields\n})\n\n// 조건 Badge 목록 생성\nconst conditionBadges = computed((): ConditionBadge[] => {\n  if (!localModelValue || !props.schema) {\n    return []\n  }\n\n  const badges: ConditionBadge[] = []\n  const formState = localModelValue\n\n  allFields.value.forEach((field) => {\n    const value = formState[field.controlName]\n    \n    // 빈 값 체크 (빈 문자열, null, undefined, 'ALL', 'SELECT' 제외)\n    if (\n      value === undefined ||\n      value === null ||\n      value === '' ||\n      value === 'ALL' ||\n      value === 'SELECT' ||\n      (field.type === 'checkbox' && value === 'N') ||\n      (field.type === 'switch' && value === 'N')\n    ) {\n      return\n    }\n\n    // 필드 타입에 따라 값 표시\n    let displayValue = String(value)\n\n    // 콤보/검색콤보인 경우 옵션의 label 찾기\n    if ((field.type === 'combo' || field.type === 'searchcombo') && field.options) {\n      const option = field.options.find(opt => opt.value === value)\n      if (option) {\n        displayValue = option.label\n      }\n    }\n\n    // 체크박스/스위치는 'Y'일 때만 표시\n    if (field.type === 'checkbox' || field.type === 'switch') {\n      if (value === 'Y') {\n        badges.push({\n          fieldName: field.controlName,\n          label: field.label,\n          value: field.inlineLabel || field.label\n        })\n      }\n    } else {\n      badges.push({\n        fieldName: field.controlName,\n        label: field.label,\n        value: displayValue\n      })\n    }\n  })\n\n  return badges\n})\n\n// submit 핸들러\nfunction handleSubmit(values: Record<string, any>) {\n  emit('submit', values)\n}\n\n// 전체 초기화 핸들러\nfunction handleReset() {\n  if (dynamicFormRef.value) {\n    dynamicFormRef.value.reset()\n    emit('reset')\n  }\n}\n\n// 필드별 초기화 핸들러\nfunction handleFieldReset(fieldName: string) {\n  if (!localModelValue || !props.schema) return\n  \n  const field = allFields.value.find(f => f.controlName === fieldName)\n  \n  if (field) {\n    // 필드 타입에 따라 초기값 설정 - reactive 객체 직접 수정\n    if (field.type === 'checkbox' || field.type === 'switch') {\n      localModelValue[fieldName] = 'N'\n    } else {\n      localModelValue[fieldName] = ''\n    }\n    \n    // localModelValue 변경 후 상위로 emit하여 JDynamicForm에도 반영\n    isInternalUpdate = true\n    emit('update:modelValue', { ...localModelValue })\n  }\n}\n</script>\n\n<style scoped>\n/* 필요시 스타일 추가 */\n</style>\n"],"names":["props","__props","emit","__emit","dynamicFormRef","ref","isExpanded","localModelValue","reactive","isInternalUpdate","watch","newValue","key","handleFormValueUpdate","value","allFields","computed","fields","section","step","conditionBadges","badges","formState","field","displayValue","option","opt","handleSubmit","values","handleReset","handleFieldReset","fieldName","f","_createBlock","_unref","Card","_createVNode","CardHeader","_createElementVNode","_hoisted_1","_hoisted_2","_createElementBlock","_cache","$event","ChevronDown","_createTextVNode","CardTitle","_openBlock","_hoisted_3","_Fragment","_renderList","badge","JBadge","_toDisplayString","_withModifiers","X","JButton","CardContent","JDynamicForm","_vShow"],"mappings":"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"}