[]
        
(Showing Draft Content)

셀 스레드 메모

스레드 메모는 사용자가 특정 셀에 컨텍스트 기반 토론을 추가하고 스레드 내에서 댓글에 답글을 달 수 있도록 합니다. 각 스레드는 답글로 구성된 대화 컨테이너 역할을 하여 팀이 문제를 효율적으로 논의, 검토 및 해결할 수 있도록 도와줍니다.

아래 예시는 팀원이 분기별 예산을 검토할 때 스레드 메모를 사용하는 방법을 보여줍니다.

image

주요 장점

  • 협업과 컨텍스트 기반 피드백을 가능하게 합니다.

  • 답글에서 사용자 멘션과 하이퍼링크를 지원합니다.

  • 이벤트 기반 통합 및 실행 취소/다시 실행(Undo/Redo)을 제공합니다.

  • SpreadJS API 및 Excel 내보내기와 호환성을 유지합니다.

의존성

스레드 메모를 포함하려면 올인원 번들을 참조하거나, 필요한 서브 모듈을 개별적으로 로드할 수 있습니다.

옵션 1 – 전체 패키지 사용

전체 라이브러리 파일을 참조하는 경우:

<script src="gc.spread.sheets.all.<version>.min.js"></script>

옵션 2 – 모듈 패키지 사용

개별 모듈을 포함할 경우, 스레드 메모 기능을 활성화하려면 다음 패키지를 로드해야 합니다:

<script src="gc.spread.sheets.comments.<version>.min.js"></script>
<script src="gc.spread.sheets.components.<version>.min.js"></script>
<script src="gc.spread.sheets.threadedcomments.<version>.min.js"></script>

참고:

이 기능은 SpreadJS v19.0 이상에서 사용할 수 있습니다.

스레드 메모는 댓글을 작성하거나 답글을 작성하는 현재 사용자를 식별하기 위해 GC.Spread.Common.UserManager 구성요소에 의존합니다.

명시적으로 사용자를 구성하지 않으면 기본 Guest 사용자가 자동으로 생성됩니다.

전역적으로 사용자를 구성하고 관리하는 방법은 사용자 관리 기능을 참조하세요.

일반 메모 vs 스레드 메모

구조와 API를 살펴보기 전에, 스레드 메모가 SpreadJS의 기존 셀 메모와 어떻게 다른지 명확히 하겠습니다.

유형

설명

주요 사용

아이콘

예시

메모

셀에 첨부된 단일 텍스트 노트. 답글이나 멘션을 지원하지 않음. Excel의 “노트”와 유사.

빠른 주석 또는 개발자 힌트

image

(API로 아이콘 색상/크기 변경 가능)

image

스레드 메모

셀에 첨부된 토론 스레드로, 여러 답글, 멘션(@user), 상태 추적(해결/열림)을 지원. Excel의 “Comment”와 동일.

협업, 검토 또는 다중 사용자 토론

  • 미해결:image

  • 해결:image

(고정 스타일, 자동 상태 색상)

image

참고:

  • Comment와 Threaded Comment는 동일한 워크북 내에서 공존할 수 있지만, 서로 다른 API와 모듈로 관리됩니다.

  • 셀에는 한 종류의 댓글만 포함될 수 있으며, 하나를 추가하면 다른 유형이 자동으로 대체됩니다.

아키텍처 개요

다음 표는 스레드 메모 아키텍처의 핵심 구성요소를 요약합니다.

구성요소

설명

그림

Comment Manager

시트의 모든 Threaded Comments를 관리. 스레드 생성 및 조회의 진입점 역할.

image

Thread

특정 셀에 바인딩된 댓글 스레드. 여러 댓글을 보유하며 해결 상태를 추적.

image

Comment

스레드 내 단일 메시지로, 메시지, 작성일, 작성자를 포함.작성자는 id, 이름, 성, 이메일, 아바타를 지원.

image

Content Blocks

메시지 콘텐츠의 내부 구조 정의: 텍스트, 멘션(@), 링크 블록.

image

사용자 인터페이스 작업

이러한 작업은 UI를 통해 가능하며, 관련 API를 통해서도 접근할 수 있습니다.

작업

설명

스레드 메모 추가

선택된 셀에 새 메모 스레드를 생성합니다.

스레드에는 작성자 정보와 타임스탬프를 포함합니다.

답글

기존 스레드에 답글을 추가합니다.

답글은 시간 순으로 추가됩니다.

편집/업데이트

기존 메모나 답글을 수정합니다.

편집된 메시지는 원래 타임스탬프를 유지합니다.

삭제

메모나 답글을 삭제합니다.

권한이 있는 사용자는 허용 시 다른 사용자의 항목도 삭제 가능합니다.

해결/재개

스레드를 해결로 표시(새 답글 비활성화)하거나 추가 논의를 위해 재개합니다.

복사/잘라내기/붙여넣기

셀을 복사, 잘라내기 또는 붙여넣을 때 스레드 메모를 유지합니다.

실행 취소/다시 실행

마지막 추가, 편집 또는 삭제 작업을 취소하거나 재적용합니다.

세부 기능

이벤트

이벤트

발생 시점

ThreadedCommentChanging

스레드 또는 답글 업데이트 전 발생.

ThreadedCommentChanged

스레드 또는 답글 업데이트 후 발생.

UserMentioned

답글에 사용자가 멘션될 때 발생.

협업 모델

  • 편집자(Editors): 스레드 메모 추가, 편집, 삭제, 해결 가능.

  • 뷰어(Viewers): 읽기 전용 접근 (조작 버튼이나 답글 편집기 없음).

멘션(@)

  • 답글에서 @username으로 협업자 멘션 가능.

  • 멘션이 추가되면 UserMentioned 이벤트 발생.

  • 멘션 목록은 최대 20명 지원.

해결 상태

스레드는 resolved 플래그를 포함.

  • 보라색 플래그: 미해결

  • 회색 플래그: 해결됨

메모 동작 및 제한 사항

편집 규칙

  • 여러 스레드 메모를 동시에 편집 가능.

  • 저장되지 않은 편집 내용은 메모 숨김 시 삭제됨.

  • 명시적 편집 상태 플래그는 유지되지 않음.

멘션 및 링크

  • 멘션 클릭(@user) 시 사용자 정보 카드가 열리지 않음.

  • 하이퍼링크 편집 동작은 브라우저별로 다름:

    • Safari: 게시 후 붙여넣거나 입력한 URL을 자동으로 하이퍼링크 변환.

    • 기타 브라우저: Space 또는 Enter 입력 시 텍스트를 하이퍼링크로 변환.

내보내기 및 호환성 제한

  • Excel로 내보낼 때 사용자 ID는 UUID 형식 준수 필요:

    {XXXXXXXX‑XXXX‑XXXX‑XXXX‑XXXXXXXXXXXX}

  • 형식에 맞지 않는 사용자 ID는 SpreadJS가 Excel 규격에 맞게 조정.

    재가져오기 후 편집 권한이 손실될 수 있음.

구조적 제한

스레드 메모는 현재 중첩 구조를 지원하지 않음. 모든 답글은 단일(평면) 레벨에 위치.

실시간 제한

스레드 메모는 실시간 접속 상태나 라이브 편집 표시를 지원하지 않음.

단축키

스레드 메모 작업 시 사용 가능한 키보드 단축키:

단축키

기능

Ctrl + Alt + M

선택된 셀에 새 스레드 메모 삽입.

Ctrl + Enter

편집 중인 답글 제출.

Enter

선택한 댓글 스레드 확장/축소.

Esc

답글 편집 취소, 변경 사항 저장하지 않음.

참고: macOS에서는 Ctrl 대신 Command (⌘) 사용.

관련 API

스레드 메모는 SpreadJS 내 여러 핵심 클래스 및 이벤트에 의존.

핵심 객체

클래스

용도

GC.Spread.Sheets.ThreadedComments

워크시트 셀과 연결된 모든 메모 스레드 관리.

GC.Spread.Sheets.ThreadedComments.ThreadedComment

단일 스레드 메모 또는 답글 표현; 콘텐츠 편집 및 해결 상태 표시.

GC.Spread.Sheets.Events

ThreadedCommentChanging, ThreadedCommentChanged, UserMentioned 등 댓글 관련 이벤트 노출.

GC.Spread.Common.UserManager

댓글 작성자용 현재 사용자 구성 및 추적.

추가 지원

GC.Spread.Sheets.SearchGC.Spread.Sheets 클래스는 검색, 복사, 잘라내기, 지우기, 사용 범위 등 일반 작업에 스레드 메모 데이터를 포함하도록 확장.

코드 예제 사용

다음 섹션은 SpreadJS API를 사용한 스레드 메모 기본 작업 예제를 보여줍니다.

기본 예제 — 댓글 추가

현재 사용자가 E3 셀에 새 스레드 메모를 생성합니다.

댓글 표시기가 자동으로 셀에 나타납니다.

// Initialize workbook
const spread = new GC.Spread.Sheets.Workbook("ss");
const sheet = spread.getActiveSheet();

// Define user info
var users = [
        { id: "user1", name: "Alice Johnson", email: "alice.johnson@company.com",},
        { id: "user2", name: "Bob Smith", email: "bob.smith@company.com",}
    ];
GC.Spread.Common.UserManager.configure({
    get: async (userId) => {
        if (userId === undefined) {
            return;
        }
        return new Promise((resolve) => {
            const user = users.find(u => u.id === userId);
            resolve(user);
        });
    },
    search: async (query) => {
        return new Promise((resolve) => {
            resolve(users.filter(u => 
                        u.name.toLowerCase().includes(query.toLowerCase()) || 
                        u.email.toLowerCase().includes(query.toLowerCase())
                    ));
        });
    }
});

// Set current user
GC.Spread.Common.UserManager.current("user1");

// Create a comment
const comment_1 = {
    message: [
       { type: GC.Spread.Sheets.ThreadedComments.ContentType.text, value: "Hey " },
       { type: GC.Spread.Sheets.ThreadedComments.ContentType.mention, userId: "user2" },
       { type: GC.Spread.Sheets.ThreadedComments.ContentType.text, value: ", please review the budget variance in Development department: " },
       { type: GC.Spread.Sheets.ThreadedComments.ContentType.link, href: "https://example.com/budget-policy", text: "Budget Policy" }
    ],
    authorId: "user1",
    createdAt: new Date("2025-12-10T15:44:00")
};

// Add a threaded comment to cell B4
const threadedCommentManager = sheet.threadedComments;
const threadedComment = threadedCommentManager.add(2, 4);
threadedComment.add(comment_1);

image

예제 - 스레드 메모 업데이트, 답글, 상태 변경, 삭제

이 예제는 이전 예제를 기반으로 합니다.

// Get a specific thread
const thread = threadedCommentManager.get(2, 4);  
console.log(thread.row()); // Output: 2

// Create a reply
const reply_1 = {
    message: [
    {type: GC.Spread.Sheets.ThreadedComments.ContentType.text,
        value: "Confirmed. "
    }],
    authorId: "user2", 
    createdAt: new Date("2025-12-12T11:47:00")
};

// Add a reply
thread.add(reply_1);

// Edit an existing reply
thread.set(0,{ message: [{ type: GC.Spread.Sheets.ThreadedComments.ContentType.text, value: 'Please verify this value.' }] });

// Delete a reply
thread.remove(1);

// Resolve / reopen
thread.resolved(true)

예제 - 스레드 메모 이벤트 처리

이벤트를 구독하여 맞춤 로직을 트리거합니다.

sheet.bind(GC.Spread.Sheets.Events.ThreadedCommentChanging, function (e, info) {
    // Handle threaded comment property or reply changes
});

sheet.bind(GC.Spread.Sheets.Events.UserMentioned, function (e, info) {
    console.log(args);
});