Skip to content

detail-button

목록의 한 행에 대해 상세 화면을 다양한 형태(모달, 탭, 새창)로 열 수 있는 공통 버튼 컴포넌트입니다. grid 내부나 외부 어디에서든 재사용이 가능합니다.

파일 위치는 src/components/plugins/grid/detail-button.vue 입니다(검색과 무관하므로 grid 플러그인 소속). 전역 자동 등록(unplugin-vue-components)이라 import 없이 <detail-button> 으로 바로 씁니다.

props

이름타입기본값설명
rowObject해당 row 의 데이터 객체. 그리드 안에서는 params.data
labelstring엔티티명. 버튼 문구("{label} 상세")와 모달 제목에 함께 쓰입니다
textstring버튼 문구만 직접 지정. 생략하면 "{label} 상세"
compComponent실제로 렌더링될 상세 컴포넌트 객체 (markRaw 권장)
component-namestring상세 컴포넌트 이름. 모달 id 로 .modal 이 붙어 쓰입니다
route-namestringtab / window 로 열 때 쓸 라우트 이름 (routes.ts 와 일치해야 함). popup 전용이면 생략 가능
back-tostring상세에서 목록으로 돌아갈 경로
typesArray['popup', 'tab']여는 방식. 'popup', 'tab', 'window'. 첫 항목이 주 버튼이 됩니다
popup-onlyBooleanfalsetruetypes 를 무시하고 모달로만 엽니다
id-keyString'id'row 에서 식별자를 꺼낼 키
callbackFunctionnull모달이 저장/삭제/닫힘으로 끝난 뒤 실행
paramsObject상세로 전달할 추가 파라미터. 라우트 파라미터로도 합쳐집니다
popup-content-styleObject{width: '800px'}모달 컨테이너 스타일

동작상 알아둘 것

  • callback 은 모달로 열었을 때만 호출됩니다. tab / window 로 열어 수정하면 목록이 자동 갱신되지 않습니다.
  • params 는 라우트 파라미터로도 합쳐집니다. user-detail 처럼 path: ':type/:id' 인 라우트는 :params="{type: TYPE}" 가 없으면 tab·window 열기가 실패합니다.
  • 앱 설정에서 탭 뷰(appTagsView)가 꺼져 있으면 'tab' 은 목록에서 자동으로 빠집니다. 남는 방식이 없으면 'popup' 으로 대체됩니다.
  • route-name 라우트가 없으면 'tab'·'window' 가 선택지에서 자동으로 빠지고 모달로만 엽니다. 개발자 콘솔에 어떤 이름을 못 찾았는지 경고가 한 번 출력됩니다.
  • row 가 비어 있거나 id-key 값이 없으면 버튼이 비활성 상태로 그려집니다.

라벨이 길면 text 로 버튼 문구만 따로 준다

label모달 제목(800px)과 버튼 문구를 겸합니다. Action 컬럼은 보통 150px 라, 설명적인 긴 이름을 label 에 넣으면 버튼이 깨집니다.

html
<!-- ❌ 30자짜리 라벨 → 150px 버튼에 "…캐시 목록 상세" 가 들어가지 않는다 -->
<detail-button label="메시지 타겟 아이템에 대한 직접 선택된 타겟 캐시 목록" />

<!-- ✅ 제목은 설명적으로, 버튼은 짧게 -->
<detail-button label="메시지 타겟 아이템에 대한 직접 선택된 타겟 캐시 목록" text="캐시 상세" />

NeoSQL 로 화면을 생성하면 labelDB 테이블 comment 가 들어가는 경우가 있습니다. comment 는 설명문이라 제목에는 맞아도 버튼에는 안 맞으니, 생성 후 짧은 이름으로 다듬거나 text 를 함께 지정하세요.

예시. grid 내부에서 사용법

vue
<nv-grid-col headerName="Action" :width="150" pinned="right" :cellStyle="grid.style.center" :cellClass="'actions-button-cell'">
  <template v-slot:render="{params}">
    <detail-button :row="params.data"
                   label="정보"
                   route-name="user-detail"
                   component-name="user-detail"
                   :comp="detailComponent"
                   back-to="/home"
                   id-key="id"
                   :callback="retrieve"
    />
  </template>
</nv-grid-col>

행 클릭과 같이 써도 안전하다

pinned="right" 컬럼은 nv-grid 가 행 클릭 대상에서 자동 제외하고, 셀 안의 버튼 클릭도 행 클릭으로 새지 않습니다. @nv-row-clicked="openDetail" 과 이 버튼을 함께 둬도 상세가 두 번 열리지 않습니다. 자세한 규칙은 nv-grid 의 Row Click 참고.

모바일에서는 이 Action 컬럼이 기본으로 숨겨집니다 (좁은 화면에서의 Action 컬럼).

상세 페이지 열기 타입별 사용법

  • Popup 타입 (모달)

    vue
    <detail-button
      :row="params.data"
      :types="['popup']"
      component-name="banner-detail"  // 실제 상세 컴포넌트 경로
      :comp="detailComponent"        // 상세 컴포넌트 객체
      :callback="retrieve"           // 모달 닫힐 실행할 함수
    />
  • Window 타입 (새 창)

    vue
    <detail-button
      :row="params.data"
      :types="['window']"
      route-name="banner-detail"     // routes.ts에 정의된 라우트명
      back-to="/content/banner"      // 닫기 버튼 클릭 돌아갈 경로
    />
  • Tab 타입 (새 탭)

    vue
    <detail-button
      :row="params.data"
      :types="['tab']"
      route-name="banner-detail"     // routes.ts에 정의된 라우트명
      back-to="/content/banner"      // 닫기 버튼 클릭 돌아갈 경로
    />

Window/Tab 타입은 라우터 설정이 필요합니다:

typescript
{
  path: 'banner/:id',
  name: 'banner-detail',
  // ⚠️ props.componentName 이 빠지면 탭/새창에서 빈 화면이 뜬다
  props: route => ({id: route.params.id, componentName: 'banner/banner-detail'}),
  component: () => import('src/views/common-detail.panel.vue'),
  meta: {
    hidden: true,
    title: '배너 상세',
    componentName: 'common-detail.panel'   // ← 위와 이름만 같고 뜻이 다르다
  }
}

componentName 이 두 군데 나오는데 뜻이 다릅니다

위치
props.componentName'banner/banner-detail'상세 컴포넌트 경로. src/views/ 를 뗀 경로이며 디렉터리를 포함합니다
meta.componentName'common-detail.panel'호스트 화면 식별자. 항상 이 값 고정

props.componentNamesrc/views/**/*-detail.vue 를 모아 만든 레지스트리에서 정확히 일치해야 합니다. 경로가 틀리면 상세 화면이 열리지 않고, 개발자 콘솔에 등록된 경로 목록이 함께 출력됩니다.

예: src/views/message/target/msg-target-group-detail.vue'message/target/msg-target-group-detail' (views/ 접두어 ❌, 중간 디렉터리 생략 ❌)

💡 여러 타입을 동시에 지원할 수 있습니다:

vue
<detail-button
  :types="['popup', 'window', 'tab']"  // 사용자가 선택 가능
/>

:::