From f2a36f517e7fb1bf878769cc7fe955720cc8590a Mon Sep 17 00:00:00 2001 From: twq110 Date: Mon, 10 Aug 2026 13:45:02 +0900 Subject: [PATCH] =?UTF-8?q?[FE]=20[FIX]:=20RichTextEditor=20=EB=B9=8C?= =?UTF-8?q?=EB=93=9C=20=EB=B0=8F=20=EB=B0=B0=ED=8F=AC=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20(#380)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 24 ++++++++---- .github/workflows/frontend-ci.yml | 37 +++++++++++++++++++ .../src/components/Board/RichTextEditor.jsx | 26 ++----------- 3 files changed, 58 insertions(+), 29 deletions(-) create mode 100644 .github/workflows/frontend-ci.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e508acd0..ecfef248 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -26,6 +26,7 @@ jobs: outputs: back: ${{ steps.filter.outputs.back }} front: ${{ steps.filter.outputs.front }} + compose: ${{ steps.filter.outputs.compose }} steps: - name: Checkout (full history) uses: actions/checkout@v4 @@ -39,16 +40,14 @@ jobs: filters: | back: - 'backend/**' - - 'docker-compose.yml' # ⬅ 추가 - - '.github/workflows/deploy.yml' # ⬅ 추가 front: - 'frontend/**' - - 'docker-compose.yml' # ⬅ 추가 - - '.github/workflows/deploy.yml' # ⬅ 추가 + compose: + - 'docker-compose.yml' # 2. 백엔드 빌드 build-back: needs: [changes] # deploy는 job 들이 병렬 처리가 되므로, 리스트 항목이 모두 끝나야 시작된다는 조건 추가 - #if: ${{ needs.changes.outputs.back == 'true' || github.event_name == 'workflow_dispatch' }} + if: ${{ needs.changes.outputs.back == 'true' || github.event_name == 'workflow_dispatch' }} environment: development runs-on: ubuntu-latest permissions: { contents: read, packages: write } @@ -87,7 +86,7 @@ jobs: build-front: needs: [changes] # deploy는 job 들이 병렬 처리가 되므로, 리스트 항목이 모두 끝나야 시작된다는 조건 추가 - #if: ${{ needs.changes.outputs.front == 'true' || github.event_name == 'workflow_dispatch' }} + if: ${{ needs.changes.outputs.front == 'true' || github.event_name == 'workflow_dispatch' }} runs-on: ubuntu-latest environment: development # development 이라는 environment에 있는 secrets 들을 쓰기 위함 permissions: { contents: read, packages: write } @@ -127,7 +126,18 @@ jobs: #cache-to: type=gha,mode=max deploy: - #if: ${{ always() && (needs.build-back.result == 'success' || needs.build-front.result == 'success') }} + if: >- + ${{ + always() && + !cancelled() && + needs.build-back.result != 'failure' && + needs.build-front.result != 'failure' && + ( + needs.build-back.result == 'success' || + needs.build-front.result == 'success' || + needs.changes.outputs.compose == 'true' + ) + }} needs: [changes, build-back, build-front] # deploy는 job 들이 병렬 처리가 되므로, 리스트 항목이 모두 끝나야 시작된다는 조건 추가 # - manual 실행(workflow_dispatch)이면 무조건 실행 # - push일 때는 둘 중 하나라도 성공한 경우에만 실행 (둘 다 failure가 아닌 이상 OK) diff --git a/.github/workflows/frontend-ci.yml b/.github/workflows/frontend-ci.yml new file mode 100644 index 00000000..1508fcdb --- /dev/null +++ b/.github/workflows/frontend-ci.yml @@ -0,0 +1,37 @@ +name: Frontend-CI + +on: + pull_request: + branches: [main] + paths: + - "frontend/**" + - ".github/workflows/frontend-ci.yml" + workflow_dispatch: {} + +permissions: + contents: read + +jobs: + build: + name: Frontend Build + runs-on: ubuntu-latest + defaults: + run: + working-directory: frontend + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: npm + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build diff --git a/frontend/src/components/Board/RichTextEditor.jsx b/frontend/src/components/Board/RichTextEditor.jsx index 052ece5b..5527dbec 100644 --- a/frontend/src/components/Board/RichTextEditor.jsx +++ b/frontend/src/components/Board/RichTextEditor.jsx @@ -18,6 +18,7 @@ import toolboxMidIcon from '../../assets/toolbox-mid-icon.svg'; import toolboxRightIcon from '../../assets/toolbox-right-icon.svg'; import toolboxLineIcon from '../../assets/toolbox-line-icon.svg'; import toolboxColonIcon from '../../assets/toolbox-colon-icon.svg'; +import toolboxVideoIcon from '../../assets/toolbox-video-icon.svg'; import toolboxTextColorIcon from '../../assets/toolbox-textcolor-icon.svg'; import toolboxTextBgIcon from '../../assets/toolbox-textBackgroundColor-icon.svg'; @@ -53,6 +54,7 @@ const FONT_FAMILY_OPTIONS = [ ]; const FONT_SIZE_OPTIONS = [12, 14, 16, 18, 20, 24, 28, 32, 40]; +const DEFAULT_FONT_SIZE = 16; const IMAGE_UPLOAD_ACCEPT = '.jpg,.jpeg,.png,.webp,.gif'; const FILE_UPLOAD_ACCEPT = '.pdf,.docx,.xlsx,.pptx,.csv,.txt,.mp4,.webm,.mov'; @@ -347,11 +349,13 @@ const RichTextEditor = ({ onUploadImage, onImageInserted, onUploadFile, + onUploadVideo, onAttachFiles, }) => { const onChangeRef = useRef(onChange); const imageInputRef = useRef(null); const fileInputRef = useRef(null); + const videoInputRef = useRef(null); const [isUploadingImage, setIsUploadingImage] = useState(false); const [, setSelectionTick] = useState(0); @@ -732,28 +736,6 @@ const RichTextEditor = ({ } finally { event.target.value = ''; } - const promptLink = () => { - if (!editor || !editable) return; - - const previousUrl = editor.getAttributes('link').href || ''; - const nextUrl = window.prompt('링크 주소를 입력하세요.', previousUrl); - - if (nextUrl === null) return; - - const trimmedUrl = nextUrl.trim(); - - if (!trimmedUrl) { - editor.chain().focus().extendMarkRange('link').unsetLink().run(); - return; - } - - editor.chain().focus().extendMarkRange('link').setLink({ href: trimmedUrl }).run(); - }; - - const clearFormatting = () => { - if (!editor || !editable) return; - - editor.chain().focus().unsetAllMarks().clearNodes().setParagraph().run(); }; const applyTextColor = (color) => {