LINE Corporation이 2023년 10월 1일부로 LY Corporation이 되었습니다. LY Corporation의 새로운 기술 블로그를 소개합니다. LY Corporation Tech Blog

Blog


엑셀로 관리하던 자리 배치도, Leaflet을 통해 웹 시스템으로 탈바꿈하다

LINE 일본 오피스에서는 늘어나는 인원을 감당하기 위해 2017년 4월, 사무실을 JR 신주쿠 미라이나타워로 이전했습니다. 사무실 이전과 함께 IT 지원실은 몇 가지 새로운 사내 시스템을 도입했는데요, 오늘은 그 중 하나인 '자리 배치도'를 소개할까 합니다.

개발 동기

예전 사무실에서는 아래에 보시는 것처럼 엑셀을 이용하여 자리를 관리하였습니다(자리에 배치된 직원의 이름은 지워진 상태입니다).

가령 앨리스님의 자리가 어디인지 알아보고 싶으면 본 엑셀 파일이나 변환된 PDF 파일을 내려받은 뒤 뷰어의 검색창에 앨리스라는 이름을 입력해서 찾아봐야 했지요. 확실히 편한 방법은 아니었습니다. 따라서 사용자들은 많은 불만을 표현하였으나, 여러 이유로 불만을 감수하고 기존의 방식으로 버텨오던 상태였습니다. 그러나 자리 배치도를 관리하는 총무 담당자의 업무량은 인원 증가로 인한 관리 비용 상승으로 한계에 달해 있었습니다. 특히 문제가 된 것은 '각자 변경한 엑셀을 통합하기가 번거롭다'는 점, '자리 변경 여부를 총무 담당자에게 아예 처음부터 알리지 않다보니 자리 정보의 신뢰도가 떨어진다'는 점이었습니다. 이러한 문제들을 해결하기 위해서는 사용자가 직접 자리 정보를 변경할 수 있는 웹 시스템이 필요하다는 결론에 도달했습니다.

처음에는 외부 시스템을 도입하는 안을 검토하였습니다. 하지만 그런 시스템은 기능이 부족하거나, 가격이 너무 비싸거나, 플래시를 사용하고 있거나 해서 저희에게 알맞는 제품을 찾기는 쉽지 않았습니다. 그 결과, LINE 내부 실정을 반영한 자리 배치 시스템을 자체 개발하게 되었습니다.

어떤 자리 배치도를 만들 것인가?

새로운 시스템을 개발하면서 저희가 중요하게 생각한 요구사항은 다음과 같습니다.

  • 총무 담당자가 직접 자리 레이아웃을 관리할 수 있어야 한다 (사무실 이전이 아니더라도 LINE에서는 자리 구조가 자주 변경되기 때문)
    • 총무 담당자가 개발 지식이 없을 수 있으므로 구조 변경 시 HTML 파일을 직접 편집할 필요가 없는 시스템이어야 한다
  • 모든 자리 정보를 쉽고 자유롭게 변경할 수 있어야 한다
    • 누군가의 자리가 변경되었을 경우, 본인이 아니라도 그 사실을 인식한 다른 사람이 편집할 수 있어야 한다
  • 엑셀보다 편리한 검색 기능을 제공해야 한다

시스템의 요구사항을 수립하면서 가장 고민했던 점은 '자리 레이아웃 관리를 어떻게 할까'였습니다. 처음에는 엑셀에 정리해 둔 자리 배치도 레이아웃을 활용하고 싶었습니다. 하지만 도형이 많고 엑셀 파일에서 정확한 좌표 정보를 구하기가 어려워 이 생각은 접게 되었습니다. 한편, 총무 담당자는 엑셀을 이용한 자리 레이아웃 편집에 익숙해져 있는 상황. 결국 어떻게든 엑셀에 정리해둔 레이아웃을 활용해야 했습니다. 이에 엑셀 자리 배치도를 캡처한 이미지를 웹 페이지에 배경으로 넣고, 자리로 사용할 수 있는 곳의 좌표를 웹 화면에서 설정하는 방식을 택했습니다.

시스템 사용자 종류로는, 자리 정보 변경만 가능한 일반 사용자와 레이아웃 변경까지 가능한 관리자, 이렇게 두 종류만 설정하여 간단하게 구성했습니다. 또한 검색 기능으로는, 엑셀 상에서는 셀에 입력된 이름만 검색이 가능했지만 서로를 닉네임으로 부르는 부서도 있다는 점을 감안하여, 새 시스템에서는 닉네임으로도 검색할 수 있도록 했습니다.

어떻게 만들 것인가?

공수를 그다지 많이 들일 시스템이 아니라 개발은 기본적으로 저 혼자 진행하게 되었습니다. 다만 제가 JavaScript 기반의 개발 경력이 짧은 편이고 시간도 많지 않아, 손쉽게 지도 앱 형태로 표현해주는 JavaScript 라이브러리가 필요했습니다. 이에 도달한 결론이 Leaflet이었지요.

Leaflet이란?

Leaflet은 모바일 및 PC 브라우저용 웹 지도를 위한 JavaScript 라이브러리입니다. 2011년에 0.1 버전, 2016년 9월에는 1.0 버전이 출시되었고, 이 글을 작성하는 현재(2017년 12월)의 최신 버전은 1.2입니다. Leaflet은 LINE 자리 배치도에 필요한 기능들을 두루 갖추고 있을 뿐 아니라, 사용하기에도 꽤 간단한 편입니다. 관련 문서도 알아보기 쉽게 정리되어 있다는 느낌을 받았습니다. Google Maps API를 사용해 본 적 있는 분이라면 그와 비슷한 부분이 있으니, Leaflet을 이용해서도 비교적 쉽게 개발하실 수 있을 것입니다.

Leaflet을 이용한 자리 배치도의 예시

다음의 HTML 코드는 간단한 Leaflet 사용 예시입니다.

<!DOCTYPE html>
<html>
<head>
    <title>Floor Map Example - Leaflet</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" crossorigin=""/>
    <script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js" integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log==" crossorigin=""></script>
</head>
<body>
<div id="map" style="width: 600px; height: 400px;"></div>
<script>
    var map = L.map('map', {crs: L.CRS.Simple});

    var bounds = [[0,0], [480,640]]; // 이미지의 해상도를 bounds로 설정한다.
    L.imageOverlay('seat.png', bounds).addTo(map); // 배경 이미지를 설정한다.

    L.circle([170, 170], {color: 'green',radius: 35}).addTo(map)
    .bindTooltip("iwatsuki", {permanent: true, direction: 'center'}).openTooltip()
    .bindPopup("iwatsuki <br />IT Support Department");

    L.circle([170, 290], {color: 'green',radius: 35}).addTo(map)
    .bindTooltip("Name A", {permanent: true, direction: 'center'}).openTooltip();

    L.circle([170, 410], {color: 'green',radius: 35}).addTo(map)
    .bindTooltip("Name B", {permanent: true, direction: 'center'}).openTooltip();

    L.circle([60, 170], {color: 'green',radius: 35}).addTo(map)
    .bindTooltip("Name C", {permanent: true, direction: 'center'}).openTooltip();

    L.circle([60, 290], {color: 'green',radius: 35}).addTo(map)
    .bindTooltip("Name D", {permanent: true, direction: 'center'}).openTooltip();

    L.circle([60, 410], {color: 'gray',radius: 35}).addTo(map)
    .bindTooltip("Name E", {permanent: true, direction: 'center'}).openTooltip();

    map.fitBounds(bounds); // 표현 영역을 설정한다
</script>
</body>
</html>

위 HTML 파일을 웹 브라우저에서 열어보면 다음과 같은 화면이 나옵니다. 어떤가요? 이렇게만 해도 얼추 자리 배치도로 보이지 않나요?

각 자리의 이름은 Leaflet의 툴팁으로 표시하는데, 툴팁의 permanent 속성을 true로 설정하면, 유저의 액션 없이도 툴팁이 렌더링되어 엑셀이나 PDF 파일에서처럼 어느 자리에 누가 앉는지를 한번에 볼 수 있게 해줍니다. 또 마우스를 드래그하면 배치도를 스크롤할 수 있고, 화면 좌측 상단의 '+', '-' 버튼을 클릭하거나 마우스 휠을 앞뒤로 움직이면 별도로 구현하지 않아도 배치도를 축소하거나 확대할 수 있습니다. 다음은 배치도를 확대한 후 'iwatsuki'가 적힌 원을 클릭했을 때의 모습입니다. 자리 배치도니까 이름 말고도 부서명과 프로필 사진, 연락처도 있으면 좋겠지요. Leaflet의 팝업 기능을 이용하면 이러한 상세 정보도 아주 손쉽게 표시할 수 있습니다.

그럼 검색은 어떻게 구현했을까요? Leaflet의 map.fitBounds(bounds) 메서드를 이용하면 표현 영역을 설정할 수 있습니다. 입력된 키워드에 따라 좌표 정보를 반환하는 API를 백엔드에 구현하면 검색 기능을 제공할 수 있습니다. 한편, LINE 일본 오피스는 미라이나타워 15층부터 23층까지 입주해 있기 때문에 층별 표시 기능도 필요한데, 이는 Leaflet의 레이어 기능을 통해 구현할 수 있습니다. 다음의 코드는 화면 오른쪽 상단에 레이어 변경 버튼을 추가하고, 버튼에 마우스 커서를 올렸을 때, '21F', '22F', '23F'를 선택할 수 있게 합니다.

var map = L.map('map', {crs: L.CRS.Simple});

var bounds = [[0,0], [428,608]];

var baseMaps = {
  "21F": L.imageOverlay('21F Image Link', bounds),
  "22F": L.imageOverlay('22F Image Link', bounds),
  "23F": L.imageOverlay('22F Image Link', bounds)
}
L.control.layers(baseMaps).addTo(map);

map.on("baselayerchange", (event) => {
  console.log(event.name); // 변경 후의 층수를 출력한다.
  // 층별 처리를 구현한다.
});

map.addLayer(baseMaps["15F"]);
map.fitBounds(bounds);

이 밖에도 클릭이나 마우스 오버 등 이벤트 발생 시 좌표를 쉽게 구할 수 있고, 객체를 그룹 단위로 처리할 수 있는 등 편리한 API가 많습니다. 자세한 내용은 Leaflet의 문서를 통해 확인하시기 바랍니다.

완성된 자리 배치도

이번에 자리 배치를 개발할 때, 프론트엔드에서는 Angular 4를, 백엔드에서는 Rails 5를 API 모드로 사용했습니다. 이 부분은 특별한 사항이 없으므로 자세한 설명을 생략하고자 합니다. 아래 스크린샷은 이렇게 완성된 LINE Floor Map 화면의 일부입니다.

위 그림에서 모자이크 처리된 곳에는 해당 자리에 배치된 직원의 이름과 부서명, 프로필 사진, 메일 주소가 표시되고 있습니다. 팝업창 왼쪽 상단의 빨강 지우개 마크를 클릭하면 해당 자리에 대한 정보를 삭제할 수 있으며, 바로 오른쪽의 링크 버튼을 클릭하면 자리의 퍼머링크(permalink)를 복사할 수 있습니다. 빈 자리가 있으면 누구든지 이름을 입력하여 자유롭게 자리를 설정할 수 있습니다. 단, 너무 자유롭게 변경이 가능해도 문제가 될 수 있기 때문에 누군가 내 자리에 대한 정보를 변경하면, 정보를 변경한 사람이 누구인지 당사자에게 메일로 알림이 오게 되어 있습니다.

또한, 직원 정보뿐 아니라 회의실 등 시설 정보도 검색할 수 있게 하여, 엑셀 파일에서 사용하던 기능을 모두 지원하도록 했습니다. 기능상으로는 만족스럽습니다만, 한 가지 아쉬운 점이 있습니다. 처음부터 알고 있던 점이긴 하나, 기존 자리 배치도를 배경으로 사용하다 보니 세련된 느낌은 다소 부족하다는 것입니다. 이 점에 대한 아쉬움 덕분인지, 조금 늦게 도입된 LINE Fukuoka의 자리 배치도를 보니 배경 디자인이 한결 세련된 느낌으로 바뀌어 있었습니다.

훨씬 낫지 않나요? (배치도를 확대하면 툴팁이 서로 겹치기 때문에, 일정 수준 이상으로 배치도를 확대하면 툴팁이 사라지게 했습니다). 아, 추가적인 기능으로, 자리 배치도에는 직원 정보뿐 아니라 '작업용', '입사자용' 등의 메모를 추가해서 회의실 정보와 마찬가지로 추가 정보를 검색할 수 있게 했습니다. 스마트폰에서도 조회가 되는 것은 물론입니다.

자리 배치도를 웹 시스템화하고 보니

이번 자리 배치도 개발은 총무팀의 업무를 줄여보고자 시작한 프로젝트였습니다. 그리고 도입 결과는 대단히 성공적이었다고 생각합니다. '이런 걸 기다렸다'며, 사용자들의 반응은 무척 긍정적인 편으로, 원활한 사내 커뮤니케이션에 일조하고 있는 것으로 보입니다. 누구 자리든 마음대로 변경할 수 있게 한 것도 현재로서는 별다른 문제없이 순조롭게 운영되고 있습니다.

다만 자리 배치 변경을 검토하는 작업은 엑셀로 관리할 때보다 불편해졌습니다. 엑셀을 사용할 때는 현재의 레이아웃이 담긴 엑셀 파일을 살짝 편집하기만 하면 자리 변경을 검토할 수 있었지만, 웹을 이용하면 바로바로 검토하기가 어려워진 것이지요. 지금은, 검토 작업을 하려면 빈 엑셀 자리 배치도에 기존 자리 배치를 하나씩 복사해서 붙여넣기 해야 하는 상황입니다. 이렇듯 약간의 과제가 남아 있는 시스템이지만, 엑셀을 통한 자리 관리나 조회가 번잡하고 불편하게 느껴지는 분께 이 글이 조금이라도 도움이 된다면 좋겠습니다.