이번 포스팅에선 Retool을 이용해서 세모체 프로젝트의 어드민 페이지를 만들어보겠다.
이전에 그냥 Spring Thymeleaf를 이용해서 어드민 페이지를 구성했는데, 계속 시각적인 요소를 신경쓰게 되어서 시간이 많이 걸렸다.우선순위가 낮은 작업에 시간을 많이 쓰기 싫어서 Retool을 이용해보기로 했다.
먼저 Retool 관리자 페이지에 이용할 Resource를 생성해줘야 한다.
Retool 로그인하고 오른쪽 상단에 Resource 페이지로 이동한다.
그 다음에 화면에서 Create new 버튼을 클릭하고 Resource를 클릭한다.

Server랑 연결되는 REST API Resource 하나랑, DB랑 연결되는 MySQL Resource를 하나 생성한다.
MySQL Resource는 기본적으로 데이터 조회에 사용될 예정이고,
REST API Resource는 데이터 생성 및 수정에 사용될 예정이다.
이렇게 나눈 이유는, DB에 직접 접근해서 데이터를 수정하거나 삭제하는 것은 위험하다고 생각이 들어서 이렇게 했다. 또한 현재 참조되는 테이블이 여러개라서 DB에서 바로 수정하기 어려운 상태이다. (데이터 무결성 제약 문제)
그래서 이렇게 Resource를 나누고 조회는 DB를 통해서, 수정이나 삭제는 REST API를 통해서 진행할 계획이다.

이제 실제 어드민 페이지가 될 App을 생성한다.
나는 프로젝트 이름의 폴더를 따로 보고 해당 폴더 내에 App을 생성했다.
App을 생성하고 들어가면 다음과 같은 첫 페이지가 보인다.
왼쪽 사이드바에서 Header / Sidebar / Main 을 볼 수 있다.
나는 Header에는 Navigation과 Main에는 실제 어드민 페이지의 주요 기능을 넣을 것이다.
또한, 왼쪽 아래에 Code라는 부분에는 내가 사용할 query, api, javascript를 명시할 수 있다. 전에 만들었던 DataSource Resource를 연결해서 사용할 것이다.
오른쪽 사이드바를 보면 미리 정의된 여러 UI 컴포넌트를 확인할 수 있다.
해당 컴포넌트를 간단하게 drag-and-drop으로 사용하면 된다.

Header 부분에 서비스 이름과 밑에 다른 Page로 이동할 수 있는 Navigation bar를 둔다.
현재는 Checklist Page이므로, Member, Category, File만 두었다.
일단은 테스트용으로 몇개만 추가했고, 추후에는 서비스에서 이용하는 모든 Entity를 관리할 수 있도록 더 추가할 예정이다.

모든 체크리스트를 보여주는 테이블 UI를 구성할 것이다.
그러면 체크리스트 목록을 가져오는 query가 필요하다. 이는 조회에 해당하는 동작이므로 DB Resource를 통해 가져올 것이다.
Resource 부분에 전에 미리 정의했던 DB에 연결된 Resource를 연결한다.
그다음 보여줄 checklist 정보를 가져오는 sql문을 다음과 같이 작성한다.

이후 테이블 컴포넌트를 Main에 위치한다.
그 다음 오른쪽 사이드바에서 Data source를 방금 만든 get_all_checklists에 연결한다.
그러면 해당 정보를 테이블에 표현할 수 있다.
지금 상태는 너무 투박하므로, 약간의 javascript와 style만 입힌다.

테이블 위에 어떤 테이블인지 표시하는 Text를 위치한다.
그리고 중요하지 않은 정보는 뒤로 밀고, 중요한 정보를 앞에 위치시킨다.
그리고 Retool의 또 다른 장점인 바로 javascript를 통해 보여지는 방식을 바꿔준다.
Publish가 Boolean 타입인데 이를 그냥 두면 체크 표시로 보인다.
하지만 이는 직관적이지 않으므로, 좀 더 직관적으로 표현하기 위해 다음과 같이 공개, 비공개로 맵핑시킨다.
{{item ? '공개' : '비공개'}}
위와 같이 {{ }} 안에는 javascript 문법을 이용할 수 있다.
item은 해당 쿼리에서 가져온 데이터를 의미한다.
그래서 다음과 같이 삼항연산자를 이용하면 깔끔하게 Boolean Type을 String Type으로 맵핑시킬 수 있다.

이번에는 다음과 같이 선택된 checklist의 정보를 보여주는 detail UI를 설정하겠다.
만드는 방법은 정말 간단하다. 위의 그림처럼 tab을 이용해 상세정보, 체크리스트 나누어 보여주려고 한다.
그러면 미리 정의된 UI 컴포넌트 중 tabbedComponent를 가지고 다시 query를 정의하고 이를 연결하면 된다.

먼저 체크리스트 정보를 가져오는 get_steps_by_checklist_id query문을 정의한다.
그 다음 체크리스트 탭에 table UI를 위치하고 data source에 해당 query문을 연결하면 된다.
만약 보여지는 정보를 변환시키고 싶으면 이전과 같이 javascript 문법을 통해 바꾸면 된다.

체크리스트 상세정보는 먼저 상세정보를 받아오는 query문을 정의하고, 각 Text UI에 해당 내용을 넣어주면 된다.
나는 get_checklist_by_id를 라고 이름을 붙이고 다음과 같이 sql문을 작성했다.
select *
from checklist c
join checklist_stats cs on c.checklist_id = cs.checklist_id
join checklist_usage cu on c.checklist_id = cu.checklist_id
join file_detail fd on fd.file_id in (c.image_id, c.default_image_id)
where c.checklist_id = {{ checklistTable.selectedRow.checklist_id }}
[table name].selectRow은 해당 테이블의 선택된 row의 정보를 가져온다.
이때, 이미지는 image UI를 이용하면 된다.
그리고 image source URL에 해당 이미지의 URL을 입력해주면 다음과 같이 정보를 보여줄 수 있다.
나는 DB에 저장된 정보가 전체 URL path가 아닌 Amazon S3 앞부분 링크를 제외한 URL path이다. 따라서 그대로 가져다가 쓰면 이미지를 가져올 수 없고 위의 이미지처럼 앞에 Amazon S3 URL을 붙였다.
https://semocheck-s3.s3.ap-northeast-2.amazonaws.com/{{ get_checklist_by_id.data.path['0'] }}
체크리스트 정보를 확인할 수 있는 기본적인 UI 화면은 구성이 끝났다.
이번에는 새로운 체크리스트를 입력할 수 있는 생성 UI 화면 구성을 해보려고 한다.
생성은 조회와 달리 내부적으로 돌아가는 비즈니스 로직이 여러 있어서 SQL로만 처리하기 힘들다. 따라서 미리 생성해둔 API를 사용해서 체크리스트를 생성하려고 한다.

다음과 같이 create_checklist query를 정의한다.
이때 Resource는 이전과 달리 REST API Resource에 연결해줘야 한다.
그 다음 Body에 서버로 넘길 데이터를 담는다.
createForm은 아직 설명하지 않은 UI로 바로 뒤에 나온다.

위의 이미지가 createForm UI이다.
미리 정의된 form UI를 drag-and-drop으로 위치시키고 각 Input Component를 넣으면 된다.
이때 나는 마지막 스텝 입력 부분을 ListView로 설정했다.
그리고 안에 component 수를 동적으로 변화시켜야 했는데, 이는 다음과 같이 Number 입력 받는 부분을 만들어 이를 다음과 같이 연결시켰다.
{{createForm.data.numberInput1 }}
// 이렇게 동적으로 컴포넌트 생성도 가능한 것이 정말 Retool의 큰 장점인 것 같다.

마지막으로 Submit Button의 Event handler에 위에서 만든 create_checklist query를 연결시키면 모든 것이 끝난다.

생각한대로 제대로 동작하는 것을 확인할 수 있다!
기존에 Spring Thymeleaf로 작업하던 어드민 페이지를 Retool로 migration 해봤다.
Tutorial 부분이나 커뮤니티 부분이 잘 되어있어서 생각보다 쉽게 사용할 수 있었다.
Retool은 javascript로 데이터를 제어할 수 있는데 해당 부분이 정말 큰 강점인 것 같다. Spring Thymeleaf에서도 동적으로 데이터를 제어할 수 있는데 이 부분을 그대로 이용할 수 있었다.
그리고 무엇보다도 화면 구성하는데 걸리는 시간이 확 줄었다!
어드민 페이지는 사용자에게 보여지는 부분이 아니므로 디자인이 중요하지 않지만, 나도 모르게 개발하다보면 좀 더 이쁘고 깔끔한 것을 추구하다보니 디자인에 시간이 꽤나 소모되었다.
디자인에 쓰이는 시간이 정말 아까웠는데, Retool을 이용하니 빠르고 간편하게 깔끔한 UI를 구성할 수 있어서 최고였다...!
앞으로 어드민 페이지 개발에는 계속해서 Retool을 사용할 것 같다.