인라인 수정 개선하기 - UI 이야기

안녕하세요. 셀렉트팀 이진혁입니다.

어드민 데이터 테이블에서 인라인 수정하는 UI를 개선하며 느낀점을 적었습니다.

배경

셀렉트 어드민에서는 updateOptions 라는 개념으로 모든 부분에 클릭하여 수정하는 기능을 제공하고 있습니다.

필드별 수정, 상태갑 변경, 플래그 켜고끄기 할때마다 API를 만들거나 프론트 단 처리를 개별로 해야하는 불편함을 해결하기 위해 몇가지 YAML로 이를 단축시켰습니다.

sql: >
  SELECT id, name, vintage 
  FROM wine_stock
  LIMIT 10
columns:
  vintage:
    # dropdown:
    #   - 2024
    #   - 2023
    updateOptions:
      type: query
      resource: mysql.qa
      sqlType: update
      sql: >
        UPDATE wine_stock 
        SET vintage = :value
        WHERE id = :id

위의 조회퀴리에서 vintage 부분을 클릭하면 바로 input이 표시되고 수정시 쿼리가 실행됩니다. (물론 confirm, confirmText, toast, log등을 지원합니다!)

일반적으로 여러가지 용어로 불리웁니다.

  • Inline Editing
  • Inline Table Edit
  • Inline Table Editing

Inline Editing(이하 인라인 수정) 경우의 큰 장점은 이와 같습니다.

  • 보고 있는 데이터에서 바로 수정하여 반영을 확인 (문맥 전환을 최소화)
  • 여러건의 수정을 안정적으로 빠르게 완료
  • 모두가 수정 상태인것(엑셀)보다 개별 선택건마다 수정하기에 안전함
  • 데이터 칸 수정시 그때그때 검증, 성공, 실패를 표시 가능 (사용자가 빠르게 오류를 파악)

문제

셀렉트는 테이블, 폼, 다단(col-1,2,3)등 여러가지 레이아웃에서 updateOptions 옵션으로 인라인 수정을 지원하고 있습니다. 그 중 테이블쪽 인라인 수정 기능이 최초로 제공하였고 많이 사용되고 있어서 높은 우선순위로 해결이 필요했습니다.

초기 기획의도는 테이블 목록 조회 역할을 최대한 살려서, UI를 최소한으로 표시하고, 클릭시 바로 수정되는 모습이었습니다.

평소에는 수정 표시하지 않음
마우스를 올렸을때 수정 표시
클릭시 바로 수정 상태로 전환 (저장 또는 취소-discard)

그러나 dropdown, checkbox, date등 다양한 데이터 입력 포맷이 생기면서 테이블 칸 크기의 제약이 생겼습니다.

"테이블 컬럼 크기를 고정형으로 하면 해결되지 않을까?"

화면에서 표시하는 칸 가로 크기 제한이 있고, 특히 textarea, JSON Editor 는 더 큰 가로 크기가 필요합니다.

"지금 수정하고 있는 row, column이 헷갈려요."

인라인 표시를 하기 때문에 혼선이 적을 것이라 생각했지만 여러칸, 여러줄을 수정하는경우 원래 보고있던 데이터건(내역)을 헷갈리게 됩니다.

"업데이트한 내용을 다시 확인하고싶어요."

표시 부분과 입력 부분이 한 곳에 있게되면서 입력했던 값이 표시 부분에 잘 들어갔는지 확인이 필요했습니다. 결국 조회 버튼을 한번더 눌러 반영을 체크하게 됩니다.

"그리고 불편해요."

구현상의 문제로 반드시 1개의 input field만 표시되어 다른 필드를 수정하려는 경우 반드시 X를 눌러야하는 불편함이 있었습니다.

1차 시도

2024년 초반에 흔히말하는 '노션 스타일'로 엑셀처럼 간편한 인라인 수정을 생각하여 cell: true 옵션을 추가했습니다.

그러나 어드민 데이터 테이블에서 원하는 느낌의 수정은 아니었습니다. 키보드 전환과 Enter, ESC가 있어도 안전한-일괄수정-개별수정-컨펌 과정을 대체할 수 없습니다.

마우스사용: 로우와 칸이 표시되고 클릭시 전환
입력의 부분을 덮어씌워서 맥락을 최소한으로 전환
키보드사용: 방향키로 칸을 들어가고 나오기

2차 시도

기존 사용자들은 위의 1차 셀 수정 방식을 원하지 않았고 이전하지 않았습니다. 결국 몇가지 문제 해결을 다시 시도했습니다.

  • 조회 영역 레이아웃을 수정하지 않을 것 (덜컹거림)
  • 선택한 Row, Column 맥락을 표시할 것
  • 여러칸을 계속 수정-취소-수정-취소 가능할 것 (편의성을 최대한제공하고, 안정성은 confirm등 옵션으로 제공)
  • 기존(이전) 내용을 보면서, 새로운(입력) 내용을 볼것
클릭시 input field를 하단(가능한 영역)에 표시 (popover, popper 활용)
마우스 사용자의 경우 수정표시를 유지할것, 클릭시 포커스를 이동할것
날짜나 체크박스의 경우 다른 맥락에서 점검이 필요
선택한 로우를 표시하는 예제
선택한 로우와 컬럼 표시하는 예제노란색은 변경내역 confirm before/after와 동일하게 유지)

결과

Floating Vue
Tooltips & dropdowns made easy

너무나 애용하고 있습니다.

조회 영역위에 수정 영역(popper) 표시하여 레이아웃 변동을 최소화

기존 내용을 보면서, 새로운 내용을 입력 가능해요.

선택한 Row, Column 맥락을 표시

마우스 hover에 대한 색상이 있어서 row context는 잃지 않았지만, editing 상태에서 다른 페이지를 왔다갔다하면 잃는 경우를 방지해요.

여러칸을 계속 수정-취소-수정-취소 가능할 것

popper의 autoHide 기능을 통해 cancel_inline_edit을 쉽게 구현했습니다.

간혹 개별 모달, popper가 존재해서 append-to-body 인 컴포넌트의 경우, popper에서 이탈한것으로 간주되어 popper가 꺼지는 문제가 있습니다.

이 경우 :appendToBody='false' 또는 inline 형태로 표시해야 popper 간섭을 최소화 가능합니다.

그래도 정말 editing state 자체가 불필요한 컴포넌트는 분리하기

기존에도 checkbox는 클릭 후 수정하도록 하였지만 간단한 toggle의 경우 위의 방식이 너무나 불편하게 됩니다.

columns:
  outflow:
    format: toggle
    trueValue: 1
    falseValue: 0
    trueLabel: 사용
    falseLabel: 사용안함
    updateOptions:
      confirm: true
      type: query
      resource: mysql.qa
      sqlType: update
      sql: >
        UPDATE wine_stock 
        SET outflow = :value
        WHERE id = :id

이 경우 toggle을 추가하여 즉시 수정하도록 추가

trueValue 만 입력하여도 사용에 지장이 없어야함

결론

아직 여러 레이아웃에 column 단위 updateOptions가 존재하지만, 테이블 인라인 수정에 대해서는 급한 부분을 보완했습니다.

여전히 인라인 테이블에서 [편집] 버튼을 통해 모든 컬럼을 input field로 표시하는등 기능은 지원하지 않지만 이미 모달내부에서 display: form 그리고 block단위 updateOptions로 지원을 하기에 범위를 제외했습니다.

간단한 수정이지만 여러가지 디자인 결정이 필요했습니다. 특히나 셀렉트 어드민은 전통적인 UI 위주로 지원하고 (notion과 같은) popper를 쓰지 않았기 때문에 기존의 inline placement, new window, modal등 통일성에 대해 고민이 필요했습니다.

앞으로도 사용하기 안전하고 편리한 페이지를 위해 셀렉트팀 내부에서 이야기를 이어가겠습니다.