Compare commits

..
Author SHA1 Message Date
VipinDevelops 9af759b333 feat: add scroll to issue 2025-03-13 16:15:43 +05:30
6 changed files with 157 additions and 24 deletions
+50
View File
@@ -47,6 +47,12 @@ jobs:
gh_buildx_version: ${{ steps.set_env_variables.outputs.BUILDX_VERSION }}
gh_buildx_platforms: ${{ steps.set_env_variables.outputs.BUILDX_PLATFORMS }}
gh_buildx_endpoint: ${{ steps.set_env_variables.outputs.BUILDX_ENDPOINT }}
build_proxy: ${{ steps.changed_files.outputs.proxy_any_changed }}
build_apiserver: ${{ steps.changed_files.outputs.apiserver_any_changed }}
build_admin: ${{ steps.changed_files.outputs.admin_any_changed }}
build_space: ${{ steps.changed_files.outputs.space_any_changed }}
build_web: ${{ steps.changed_files.outputs.web_any_changed }}
build_live: ${{ steps.changed_files.outputs.live_any_changed }}
dh_img_web: ${{ steps.set_env_variables.outputs.DH_IMG_WEB }}
dh_img_space: ${{ steps.set_env_variables.outputs.DH_IMG_SPACE }}
@@ -117,7 +123,46 @@ jobs:
name: Checkout Files
uses: actions/checkout@v4
- name: Get changed files
id: changed_files
uses: tj-actions/changed-files@v42
with:
files_yaml: |
apiserver:
- apiserver/**
proxy:
- nginx/**
admin:
- admin/**
- packages/**
- "package.json"
- "yarn.lock"
- "tsconfig.json"
- "turbo.json"
space:
- space/**
- packages/**
- "package.json"
- "yarn.lock"
- "tsconfig.json"
- "turbo.json"
web:
- web/**
- packages/**
- "package.json"
- "yarn.lock"
- "tsconfig.json"
- "turbo.json"
live:
- live/**
- packages/**
- 'package.json'
- 'yarn.lock'
- 'tsconfig.json'
- 'turbo.json'
branch_build_push_admin:
if: ${{ needs.branch_build_setup.outputs.build_admin == 'true' || github.event_name == 'workflow_dispatch' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
name: Build-Push Admin Docker Image
runs-on: ubuntu-22.04
needs: [branch_build_setup]
@@ -140,6 +185,7 @@ jobs:
buildx-endpoint: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
branch_build_push_web:
if: ${{ needs.branch_build_setup.outputs.build_web == 'true' || github.event_name == 'workflow_dispatch' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
name: Build-Push Web Docker Image
runs-on: ubuntu-22.04
needs: [branch_build_setup]
@@ -162,6 +208,7 @@ jobs:
buildx-endpoint: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
branch_build_push_space:
if: ${{ needs.branch_build_setup.outputs.build_space == 'true' || github.event_name == 'workflow_dispatch' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
name: Build-Push Space Docker Image
runs-on: ubuntu-22.04
needs: [branch_build_setup]
@@ -184,6 +231,7 @@ jobs:
buildx-endpoint: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
branch_build_push_live:
if: ${{ needs.branch_build_setup.outputs.build_live == 'true' || github.event_name == 'workflow_dispatch' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
name: Build-Push Live Collaboration Docker Image
runs-on: ubuntu-22.04
needs: [branch_build_setup]
@@ -206,6 +254,7 @@ jobs:
buildx-endpoint: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
branch_build_push_apiserver:
if: ${{ needs.branch_build_setup.outputs.build_apiserver == 'true' || github.event_name == 'workflow_dispatch' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
name: Build-Push API Server Docker Image
runs-on: ubuntu-22.04
needs: [branch_build_setup]
@@ -228,6 +277,7 @@ jobs:
buildx-endpoint: ${{ needs.branch_build_setup.outputs.gh_buildx_endpoint }}
branch_build_push_proxy:
if: ${{ needs.branch_build_setup.outputs.build_proxy == 'true' || github.event_name == 'workflow_dispatch' || needs.branch_build_setup.outputs.gh_branch_name == 'master' }}
name: Build-Push Proxy Docker Image
runs-on: ubuntu-22.04
needs: [branch_build_setup]
+47 -4
View File
@@ -6,9 +6,49 @@ on:
types: ["opened", "synchronize", "ready_for_review"]
jobs:
lint-apiserver:
get-changed-files:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
outputs:
apiserver_changed: ${{ steps.changed-files.outputs.apiserver_any_changed }}
admin_changed: ${{ steps.changed-files.outputs.admin_any_changed }}
space_changed: ${{ steps.changed-files.outputs.space_any_changed }}
web_changed: ${{ steps.changed-files.outputs.web_any_changed }}
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v44
with:
files_yaml: |
apiserver:
- apiserver/**
admin:
- admin/**
- packages/**
- 'package.json'
- 'yarn.lock'
- 'tsconfig.json'
- 'turbo.json'
space:
- space/**
- packages/**
- 'package.json'
- 'yarn.lock'
- 'tsconfig.json'
- 'turbo.json'
web:
- web/**
- packages/**
- 'package.json'
- 'yarn.lock'
- 'tsconfig.json'
- 'turbo.json'
lint-apiserver:
needs: get-changed-files
runs-on: ubuntu-latest
if: needs.get-changed-files.outputs.apiserver_changed == 'true'
steps:
- uses: actions/checkout@v4
- name: Set up Python
@@ -23,7 +63,8 @@ jobs:
run: ruff check --fix apiserver
lint-admin:
if: github.event.pull_request.draft == false
needs: get-changed-files
if: needs.get-changed-files.outputs.admin_changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -35,7 +76,8 @@ jobs:
- run: yarn lint --filter=admin
lint-space:
if: github.event.pull_request.draft == false
needs: get-changed-files
if: needs.get-changed-files.outputs.space_changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -47,7 +89,8 @@ jobs:
- run: yarn lint --filter=space
lint-web:
if: github.event.pull_request.draft == false
needs: get-changed-files
if: needs.get-changed-files.outputs.web_changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
+1 -1
View File
@@ -7,7 +7,7 @@
"private": true,
"type": "module",
"scripts": {
"dev": "PORT=3100 concurrently \"babel src --out-dir dist --extensions '.ts,.js' --watch\" \"nodemon dist/server.js\"",
"dev": "concurrently \"babel src --out-dir dist --extensions '.ts,.js' --watch\" \"nodemon dist/server.js\"",
"build": "babel src --out-dir dist --extensions \".ts,.js\"",
"start": "node dist/server.js",
"lint": "eslint src --ext .ts,.tsx",
@@ -25,7 +25,10 @@ export const IssueCommentBlock: FC<TIssueCommentBlock> = observer((props) => {
if (!comment) return <></>;
return (
<div className={`relative flex gap-3 ${ends === "top" ? `pb-2` : ends === "bottom" ? `pt-2` : `py-2`}`}>
<div
id={`comment-${commentId}`}
className={`relative flex gap-3 ${ends === "top" ? `pb-2` : ends === "bottom" ? `pt-2` : `py-2`}`}
>
<div className="absolute left-[13px] top-0 bottom-0 w-0.5 bg-custom-background-80" aria-hidden />
<div className="flex-shrink-0 relative w-7 h-7 rounded-full flex justify-center items-center z-[3] bg-gray-500 text-white border border-white uppercase font-medium">
{comment.actor_detail?.avatar_url && comment.actor_detail?.avatar_url !== "" ? (
@@ -2,8 +2,9 @@
import { FC, useEffect, useRef, useState } from "react";
import { observer } from "mobx-react";
import { useRouter, usePathname } from "next/navigation";
import { useForm } from "react-hook-form";
import { Check, Globe2, Lock, Pencil, Trash2, X } from "lucide-react";
import { Check, Globe2, Lock, Pencil, Trash2, X, Link } from "lucide-react";
// plane constants
import { EIssueCommentAccessSpecifier } from "@plane/constants";
// plane editor
@@ -13,13 +14,14 @@ import { useTranslation } from "@plane/i18n";
// plane types
import { TIssueComment } from "@plane/types";
// plane ui
import { CustomMenu } from "@plane/ui";
import { CustomMenu, TOAST_TYPE, setToast } from "@plane/ui";
// plane utils
import { cn } from "@plane/utils";
// components
import { LiteTextEditor, LiteTextReadOnlyEditor } from "@/components/editor";
// helpers
import { isCommentEmpty } from "@/helpers/string.helper";
import { HIGHLIGHT_CLASS } from "@/components/issues/issue-layouts/utils";
import { copyUrlToClipboard, isCommentEmpty } from "@/helpers/string.helper";
// hooks
import { useIssueDetail, useUser, useWorkspace } from "@/hooks/store";
// components
@@ -96,8 +98,42 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
}
}, [isEditing, setFocus]);
useEffect(() => {
const hash = window.location.hash;
if (hash === `#comment-${commentId}`) {
setTimeout(() => {
const element = document.getElementById(`comment-${commentId}`);
if (element) {
element.scrollIntoView({ behavior: "smooth", block: "center" });
element.classList.add(HIGHLIGHT_CLASS);
setTimeout(() => {
element.classList.remove(HIGHLIGHT_CLASS);
}, 2000);
}
}, 100);
}
}, [commentId]);
if (!comment || !currentUser) return <></>;
const pathName = usePathname();
const handleCommentLink = (id: string) => {
let path = pathName;
if (path.startsWith("/")) {
path = path.slice(1);
}
if (path.endsWith("/")) {
path = path.slice(0, -1);
}
const commentUrl = path + `#comment-${id}`;
copyUrlToClipboard(commentUrl).then(() =>
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Link copied",
message: "Comment link copied to clipboard",
})
);
};
return (
<IssueCommentBlock
commentId={commentId}
@@ -105,6 +141,10 @@ export const IssueCommentCard: FC<TIssueCommentCard> = observer((props) => {
<>
{!disabled && currentUser?.id === comment.actor && (
<CustomMenu ellipsis closeOnSelect>
<CustomMenu.MenuItem onClick={() => handleCommentLink(commentId)} className="flex items-center gap-1">
<Link className="flex-shrink-0 size-3" />
{t("common.actions.copy_link")}
</CustomMenu.MenuItem>
<CustomMenu.MenuItem onClick={() => setIsEditing(true)} className="flex items-center gap-1">
<Pencil className="flex-shrink-0 size-3" />
{t("common.actions.edit")}
@@ -90,17 +90,20 @@ export const ModulesListView: React.FC = observer(() => {
return (
<ContentWrapper variant={ERowVariant.HUGGING}>
<div className="size-full flex justify-between">
{displayFilters?.layout === "list" && (
{displayFilters?.layout === "list" && (
<div className="flex h-full w-full justify-between">
<ListLayout>
{filteredModuleIds.map((moduleId) => (
<ModuleListItem key={moduleId} moduleId={moduleId} />
))}
</ListLayout>
)}
{displayFilters?.layout === "board" && (
<Row
className={`size-full py-page-y grid grid-cols-1 gap-6 overflow-y-auto ${
<ModulePeekOverview projectId={projectId?.toString() ?? ""} workspaceSlug={workspaceSlug?.toString() ?? ""} />
</div>
)}
{displayFilters?.layout === "board" && (
<Row className="flex h-full w-full justify-between py-page-y">
<div
className={`grid h-full w-full grid-cols-1 gap-6 overflow-y-auto ${
peekModule
? "lg:grid-cols-1 xl:grid-cols-2 3xl:grid-cols-3"
: "lg:grid-cols-2 xl:grid-cols-3 3xl:grid-cols-4"
@@ -109,17 +112,11 @@ export const ModulesListView: React.FC = observer(() => {
{filteredModuleIds.map((moduleId) => (
<ModuleCardItem key={moduleId} moduleId={moduleId} />
))}
</Row>
)}
{displayFilters?.layout === "gantt" && (
<div className="size-full overflow-hidden">
<ModulesListGanttChartView />
</div>
)}
<div className="flex-shrink-0">
<ModulePeekOverview projectId={projectId?.toString() ?? ""} workspaceSlug={workspaceSlug?.toString() ?? ""} />
</div>
</div>
</Row>
)}
{displayFilters?.layout === "gantt" && <ModulesListGanttChartView />}
</ContentWrapper>
);
});