Skip to content

[Refactor/#79] 워크스페이스 목록 로딩/에러 UI 랜더링 구조 개선 - #89

Merged
jjjsun merged 3 commits into
developfrom
refactor/#79
Mar 11, 2026
Merged

[Refactor/#79] 워크스페이스 목록 로딩/에러 UI 랜더링 구조 개선#89
jjjsun merged 3 commits into
developfrom
refactor/#79

Conversation

@jjjsun

@jjjsun jjjsun commented Mar 10, 2026

Copy link
Copy Markdown
Collaborator

🚨 관련 이슈

Closed #79

✨ 변경사항

  • 🐞 BugFix Something isn't working
  • 💻 CrossBrowsing Browser compatibility
  • 🌏 Deploy Deploy
  • 🎨 Design Markup & styling
  • 📃 Docs Documentation writing and editing (README.md, etc.)
  • ✨ Feature Feature
  • 🔨 Refactor Code refactoring
  • ⚙️ Setting Development environment setup
  • ✅ Test Test related (storybook, jest, etc.)

✏️ 작업 내용

  • 워크스페이스 목록 조회시 로딩/에러 UI를 별도 컴포넌트로 분리작업 진행

  • 워크스페이스 빈 상태 UI를 별도 컴포넌트로 분리작업 진행

  • 상태 관련 변수명 변경(listLoading -> isListLoading, creating -> isCreating)

  • 작업 내용

😅 미완성 작업

N/A

📢 논의 사항 및 참고 사항

N/A

💬 리뷰어 가이드 (P-Rules)
P1: 필수 반영 (Critical) - 버그 가능성, 컨벤션 위반. 해결 전 머지 불가.
P2: 적극 권장 (Recommended) - 더 나은 대안 제시. 가급적 반영 권장.
P3: 제안 (Suggestion) - 아이디어 공유. 반영 여부는 드라이버 자율.
P4: 단순 확인/칭찬 (Nit) - 사소한 오타, 칭찬 등 피드백.

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 워크스페이스 목록 로딩 중 시각적 피드백 추가
    • 워크스페이스 로드 실패 시 재시도 버튼이 있는 오류 UI 추가
    • 워크스페이스가 없을 때 표시되는 빈 상태 메시지 UI 추가
  • 개선 사항

    • 워크스페이스 리스트 렌더링 로직 통합으로 상태 처리 간소화
    • 워크스페이스 생성 중 입력 및 버튼 비활성화로 진행 상태 표기 개선

@jjjsun
jjjsun requested review from Seojegyeong and YermIm March 10, 2026 15:51
@jjjsun jjjsun self-assigned this Mar 10, 2026
@jjjsun jjjsun added the 🔨 Refactor 코드 리팩토링 label Mar 10, 2026
@coderabbitai

coderabbitai Bot commented Mar 10, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 861848b0-4657-4e9b-8911-82d8b27e8e4e

📥 Commits

Reviewing files that changed from the base of the PR and between 1a412e8 and 258a6fe.

📒 Files selected for processing (4)
  • src/components/workspace/WorkspaceEmptyState.tsx
  • src/components/workspace/WorkspaceListError.tsx
  • src/components/workspace/WorkspaceListLoading.tsx
  • src/pages/workspace/Workspace.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/components/workspace/WorkspaceListError.tsx
  • src/pages/workspace/Workspace.tsx

📝 Walkthrough

Walkthrough

워크스페이스 목록의 UI 상태 관리를 위해 로딩/에러/빈 상태를 담당하는 세 개의 프레젠테이션 컴포넌트를 추가하고, Workspace 페이지의 목록 렌더링 로직을 하나의 함수로 통합하며 상태 변수명을 더 명확하게 바꿨습니다.

Changes

Cohort / File(s) Summary
새로운 상태별 UI 컴포넌트
src/components/workspace/WorkspaceEmptyState.tsx, src/components/workspace/WorkspaceListError.tsx, src/components/workspace/WorkspaceListLoading.tsx
워크스페이스 목록의 Empty / Error / Loading UI를 각각 분리한 신규 컴포넌트 추가. Error 컴포넌트는 onRetry 버튼을 노출. 모두 프레젠테이션용이며 사이드 이펙트 없음.
Workspace 페이지 렌더링 로직
src/pages/workspace/Workspace.tsx
목록 렌더링 관련 로직을 renderWorkspaceContent()로 통합하고 상태 변수명 listLoadingisListLoading, creatingisCreating으로 변경. 생성 폼은 isCreating으로 disabled 제어 및 버튼 라벨 업데이트. 기존 인라인 조건 렌더링을 함수 호출로 대체.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • YermIm
  • Seojegyeong
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 PR의 주요 변경사항을 명확하게 반영하고 있습니다. 워크스페이스 목록의 로딩/에러 UI 구조 개선이라는 핵심 내용을 잘 전달합니다.
Description check ✅ Passed PR 설명이 템플릿에 따라 작성되었으며, 관련 이슈(#79), 변경사항 체크(Refactor), 작업 내용, 미완성 작업 상태를 모두 명시하고 있습니다.
Linked Issues check ✅ Passed 워크스페이스 목록의 로딩 UI와 에러 UI를 별도 컴포넌트로 분리하고, 상태 변수명을 개선한 변경사항이 이슈 #79의 요구사항과 정확히 일치합니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #79의 워크스페이스 목록 UI 구조 개선 범위 내에 있으며, 불필요한 변경이나 범위 외 수정은 없습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/#79

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown

📚 Storybook 배포 완료

항목 링크
📖 Storybook https://69a147b60a56365d9e2185ef-jfiqstmtng.chromatic.com/
🔍 Chromatic https://www.chromatic.com/build?appId=69a147b60a56365d9e2185ef&number=52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
src/components/workspace/WorkspaceListLoading.tsx (1)

1-9: 접근성: 로딩 상태에 대한 스크린 리더 지원 고려

현재 로딩 메시지가 정적 텍스트로만 표시되어 있어서, 스크린 리더 사용자에게 로딩 상태가 명확히 전달되지 않을 수 있습니다. role="status"aria-live="polite" 속성을 추가하면 접근성이 개선됩니다.

또한, 시각적 로딩 인디케이터(스피너 등)를 추가하면 사용자 경험이 향상될 수 있습니다.

♿ 접근성 개선 제안
 export default function WorkspaceListLoading() {
   return (
-    <div className="bg-white p-10 text-center border border-gray-100 rounded-component-lg">
+    <div
+      role="status"
+      aria-live="polite"
+      className="bg-white p-10 text-center border border-gray-100 rounded-component-lg"
+    >
       <p className="font-body2 text-text-sub">
         워크스페이스 목록을 불러오는 중입니다.
       </p>
     </div>
   );
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/workspace/WorkspaceListLoading.tsx` around lines 1 - 9, The
WorkspaceListLoading component currently renders static text that isn't
announced by screen readers; update the WorkspaceListLoading function to add
accessibility attributes (e.g., set role="status" and aria-live="polite" on the
outer div) so assistive tech notifies users of the loading state, and add a
visible loading indicator (spinner or animated element) alongside the paragraph
text to improve UX; keep these changes within the WorkspaceListLoading component
and ensure the spinner has appropriate aria-hidden or descriptive text as
needed.
src/components/workspace/WorkspaceListError.tsx (1)

12-19: 접근성: 에러 상태 알림을 위한 ARIA 속성 추가 권장

에러 메시지가 표시될 때 스크린 리더가 사용자에게 즉시 알릴 수 있도록 role="alert" 속성을 추가하면 좋습니다. 이렇게 하면 에러 발생 시 보조 기술이 자동으로 메시지를 읽어줍니다.

♿ 접근성 개선 제안
   return (
-    <div className="bg-white p-10 text-center border border-gray-100 rounded-component-lg space-y-4">
+    <div
+      role="alert"
+      className="bg-white p-10 text-center border border-gray-100 rounded-component-lg space-y-4"
+    >
       <p className="font-body2 text-status-red">{message}</p>
       <Button type="button" variant="primary" onClick={onRetry}>
         다시 시도
       </Button>
     </div>
   );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/workspace/WorkspaceListError.tsx` around lines 12 - 19, The
error container in the WorkspaceListError component should notify assistive tech
immediately; add an ARIA alert to the root element (the div that currently wraps
message and Button) by adding role="alert" (and optionally
aria-live="assertive") so the screen reader announces the {message} when the
error renders; update the JSX in WorkspaceListError (the div around message and
the Button with onClick={onRetry}) to include this attribute.
src/pages/workspace/Workspace.tsx (1)

47-47: UX 고려: isFetching 포함 시 백그라운드 갱신 중에도 로딩 UI 표시

isListLoadingisFetching을 포함하고 있어서, 백그라운드에서 데이터를 다시 가져올 때(예: 창 포커스 복귀, 수동 refetch)에도 로딩 UI가 표시됩니다. 이로 인해 이미 데이터가 있는 상태에서 잠깐 로딩 화면으로 깜빡이는 현상이 발생할 수 있습니다.

초기 로딩 시에만 로딩 UI를 보여주고 싶다면 isLoading만 사용하거나, React Query v5의 경우 isPending && !data 패턴을 고려해 보세요.

💡 개선 옵션
- const isListLoading = workspacesQuery.isLoading || workspacesQuery.isFetching;
+ // 초기 로딩 시에만 로딩 UI 표시 (백그라운드 refetch 시에는 기존 데이터 유지)
+ const isListLoading = workspacesQuery.isLoading;

또는 데이터가 없을 때만 로딩 표시:

- const isListLoading = workspacesQuery.isLoading || workspacesQuery.isFetching;
+ const isListLoading = workspacesQuery.isPending && !workspacesQuery.data;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/workspace/Workspace.tsx` at line 47, The current isListLoading
combines workspacesQuery.isLoading and workspacesQuery.isFetching which shows
the loading UI during background refetches; change the isListLoading computation
in Workspace.tsx (the const isListLoading = ...) to only use
workspacesQuery.isLoading (or, if using React Query v5, use
workspacesQuery.isPending && !workspacesQuery.data) or alternatively include a
data check (e.g., workspacesQuery.isFetching && !workspacesQuery.data) so the
loading UI appears only when there is no existing data.
src/components/workspace/WorkspaceEmptyState.tsx (1)

8-11: 구조 일관성: 다른 상태 컴포넌트들과의 렌더링 구조 차이

WorkspaceEmptyState<li> 요소로 렌더링되고, WorkspaceListLoadingWorkspaceListError<div>로 렌더링됩니다. Workspace.tsxrenderWorkspaceContent에서 빈 상태일 때만 <ul>로 감싸고 있어서 구조가 일관되지 않습니다.

현재 동작에는 문제가 없지만, 향후 유지보수나 스타일 일관성을 위해 모든 상태 컴포넌트의 루트 요소 타입을 통일하는 것을 고려해 보세요.

♻️ 구조 통일 제안 (선택적)

Option 1: EmptyState를 div로 변경

 export default function WorkspaceEmptyState({
   message,
 }: IWorkspaceEmptyStateProps) {
   return (
-    <li className="rounded-component-lg bg-white p-10 text-center border border-gray-100">
+    <div className="rounded-component-lg bg-white p-10 text-center border border-gray-100">
       <p className="font-body2 text-text-sub">{message}</p>
-    </li>
+    </div>
   );
 }

그리고 Workspace.tsx에서 <ul> 래퍼 제거

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/workspace/WorkspaceEmptyState.tsx` around lines 8 - 11,
WorkspaceEmptyState currently renders a <li> while WorkspaceListLoading and
WorkspaceListError render <div>, causing inconsistent DOM structure in
renderWorkspaceContent; change WorkspaceEmptyState's root element from <li> to
<div> (in the WorkspaceEmptyState component) and remove the special-case <ul>
wrapper in Workspace.tsx so all status components render the same root type,
keeping existing classes/ styling on the new <div> and updating any tests or
ARIA/semantic wrappers that expected an <li>.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/components/workspace/WorkspaceEmptyState.tsx`:
- Around line 8-11: WorkspaceEmptyState currently renders a <li> while
WorkspaceListLoading and WorkspaceListError render <div>, causing inconsistent
DOM structure in renderWorkspaceContent; change WorkspaceEmptyState's root
element from <li> to <div> (in the WorkspaceEmptyState component) and remove the
special-case <ul> wrapper in Workspace.tsx so all status components render the
same root type, keeping existing classes/ styling on the new <div> and updating
any tests or ARIA/semantic wrappers that expected an <li>.

In `@src/components/workspace/WorkspaceListError.tsx`:
- Around line 12-19: The error container in the WorkspaceListError component
should notify assistive tech immediately; add an ARIA alert to the root element
(the div that currently wraps message and Button) by adding role="alert" (and
optionally aria-live="assertive") so the screen reader announces the {message}
when the error renders; update the JSX in WorkspaceListError (the div around
message and the Button with onClick={onRetry}) to include this attribute.

In `@src/components/workspace/WorkspaceListLoading.tsx`:
- Around line 1-9: The WorkspaceListLoading component currently renders static
text that isn't announced by screen readers; update the WorkspaceListLoading
function to add accessibility attributes (e.g., set role="status" and
aria-live="polite" on the outer div) so assistive tech notifies users of the
loading state, and add a visible loading indicator (spinner or animated element)
alongside the paragraph text to improve UX; keep these changes within the
WorkspaceListLoading component and ensure the spinner has appropriate
aria-hidden or descriptive text as needed.

In `@src/pages/workspace/Workspace.tsx`:
- Line 47: The current isListLoading combines workspacesQuery.isLoading and
workspacesQuery.isFetching which shows the loading UI during background
refetches; change the isListLoading computation in Workspace.tsx (the const
isListLoading = ...) to only use workspacesQuery.isLoading (or, if using React
Query v5, use workspacesQuery.isPending && !workspacesQuery.data) or
alternatively include a data check (e.g., workspacesQuery.isFetching &&
!workspacesQuery.data) so the loading UI appears only when there is no existing
data.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 42d5b586-8f65-4320-a0e5-7f308385209e

📥 Commits

Reviewing files that changed from the base of the PR and between 9da070b and 1a412e8.

📒 Files selected for processing (4)
  • src/components/workspace/WorkspaceEmptyState.tsx
  • src/components/workspace/WorkspaceListError.tsx
  • src/components/workspace/WorkspaceListLoading.tsx
  • src/pages/workspace/Workspace.tsx

@github-actions

Copy link
Copy Markdown

📚 Storybook 배포 완료

항목 링크
📖 Storybook https://69a147b60a56365d9e2185ef-irssyzyjcr.chromatic.com/
🔍 Chromatic https://www.chromatic.com/build?appId=69a147b60a56365d9e2185ef&number=54

@YermIm

YermIm commented Mar 11, 2026

Copy link
Copy Markdown
Collaborator

P4: 확인했습니다! 수고하셨습니다!!

@Seojegyeong Seojegyeong left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P4: 확인했습니다. 수고하셨습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 Refactor 코드 리팩토링

Projects

None yet

Development

Successfully merging this pull request may close these issues.

♻️ [Refactor] 워크스페이스 목록 조회 로딩/에러 UI 구조 개선

3 participants