From c56aacdd13502751337aebb27bc4b0aca9b1a6b8 Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Mon, 2 Oct 2023 13:28:43 +0530 Subject: [PATCH 01/30] dev: create action to sync PR changes to the repo (#2333) --- .github/workflows/create-sync-pr.yml | 54 ++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/workflows/create-sync-pr.yml diff --git a/.github/workflows/create-sync-pr.yml b/.github/workflows/create-sync-pr.yml new file mode 100644 index 000000000..45cae3aef --- /dev/null +++ b/.github/workflows/create-sync-pr.yml @@ -0,0 +1,54 @@ +name: Create PR in Plane EE Repository to sync the changes + +on: + pull_request: + types: + - closed + +jobs: + create_pr: + # Only run the job when a PR is merged + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v2 + with: + persist-credentials: false + fetch-depth: 0 + + - name: Set up Branch Name + run: | + echo "BRANCH_NAME=${{ github.head_ref }}" >> $GITHUB_ENV + + - name: Setup GH CLI + run: | + type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y) + curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg + sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null + sudo apt update + sudo apt install gh -y + + - name: Create Pull Request + env: + GH_TOKEN: ${{ secrets.TOKEN }} + run: | + TARGET_REPO="makeplane/${{ secrets.REPO_NAME }}" + TARGET_BRANCH="${{ secrets.REPO_TARGET_BRANCH }}" + SOURCE_BRANCH="${{ env.BRANCH_NAME }}" + + git checkout $SOURCE_BRANCH + git remote add target "https://$GH_TOKEN@github.com/$TARGET_REPO.git" + git push target $SOURCE_BRANCH:$SOURCE_BRANCH + + PR_TITLE="${{ github.event.pull_request.title }}" + PR_BODY="${{ github.event.pull_request.body }}" + + gh pr create \ + --base $TARGET_BRANCH \ + --head $SOURCE_BRANCH \ + --title "$PR_TITLE" \ + --body "$PR_BODY" \ + --repo $TARGET_REPO + From 7eba4a503259cbe2c60ada6a94f22ddf093839d7 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Mon, 2 Oct 2023 13:40:28 +0530 Subject: [PATCH 02/30] fix: ui package readme added (#2334) --- packages/ui/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/ui/README.md diff --git a/packages/ui/README.md b/packages/ui/README.md new file mode 100644 index 000000000..ce447bf1c --- /dev/null +++ b/packages/ui/README.md @@ -0,0 +1 @@ +# UI Package From c96960955ba7e3b31734a85b288613207e3d89a1 Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:31:25 +0530 Subject: [PATCH 03/30] fix: variable name for token (#2336) --- .github/workflows/create-sync-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create-sync-pr.yml b/.github/workflows/create-sync-pr.yml index 45cae3aef..987984d00 100644 --- a/.github/workflows/create-sync-pr.yml +++ b/.github/workflows/create-sync-pr.yml @@ -32,7 +32,7 @@ jobs: - name: Create Pull Request env: - GH_TOKEN: ${{ secrets.TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | TARGET_REPO="makeplane/${{ secrets.REPO_NAME }}" TARGET_BRANCH="${{ secrets.REPO_TARGET_BRANCH }}" From de33e6775f8fac8c14251ef9f7ca2f46cf8ff43c Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:40:31 +0530 Subject: [PATCH 04/30] dev: update add permissions to the action (#2337) --- .github/workflows/create-sync-pr.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/create-sync-pr.yml b/.github/workflows/create-sync-pr.yml index 987984d00..caa872d2f 100644 --- a/.github/workflows/create-sync-pr.yml +++ b/.github/workflows/create-sync-pr.yml @@ -10,6 +10,9 @@ jobs: # Only run the job when a PR is merged if: github.event.pull_request.merged == true runs-on: ubuntu-latest + permissions: + pull-requests: write + contents: read steps: - name: Checkout Code uses: actions/checkout@v2 From 6d463ded1c874cc4a2117191bf58717278183715 Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:50:30 +0530 Subject: [PATCH 05/30] dev: rename token variables (#2338) --- .github/workflows/create-sync-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create-sync-pr.yml b/.github/workflows/create-sync-pr.yml index caa872d2f..995996263 100644 --- a/.github/workflows/create-sync-pr.yml +++ b/.github/workflows/create-sync-pr.yml @@ -35,7 +35,7 @@ jobs: - name: Create Pull Request env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.TOKEN }} run: | TARGET_REPO="makeplane/${{ secrets.REPO_NAME }}" TARGET_BRANCH="${{ secrets.REPO_TARGET_BRANCH }}" From 0d0cf3052a4c2ed9fb63b7d53b864b9440acf763 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Mon, 2 Oct 2023 16:13:27 +0530 Subject: [PATCH 06/30] fix: updated readme fixes (#2339) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3cbeed8c4..f9d969d72 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ chmod +x setup.sh - Run setup.sh ```bash -./setup.sh http://localhost +./setup.sh ``` > If running in a cloud env replace localhost with public facing IP address of the VM From d9bd07886fc87aaff4f55278680ca5bcd9150af1 Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Tue, 3 Oct 2023 18:41:26 +0530 Subject: [PATCH 07/30] dev: update sync workflow to run only when the source repo is configured (#2346) * dev: update sync workflow to run only when the source repo is configured * fix: naming convention changes --------- Co-authored-by: sriramveeraghanta --- ...equest.yml => build-test-pull-request.yml} | 0 .github/workflows/create-sync-pr.yml | 56 +++++++++++-------- ...er_Images.yml => update-docker-images.yml} | 0 3 files changed, 33 insertions(+), 23 deletions(-) rename .github/workflows/{Build_Test_Pull_Request.yml => build-test-pull-request.yml} (100%) rename .github/workflows/{Update_Docker_Images.yml => update-docker-images.yml} (100%) diff --git a/.github/workflows/Build_Test_Pull_Request.yml b/.github/workflows/build-test-pull-request.yml similarity index 100% rename from .github/workflows/Build_Test_Pull_Request.yml rename to .github/workflows/build-test-pull-request.yml diff --git a/.github/workflows/create-sync-pr.yml b/.github/workflows/create-sync-pr.yml index 995996263..6ca840197 100644 --- a/.github/workflows/create-sync-pr.yml +++ b/.github/workflows/create-sync-pr.yml @@ -11,20 +11,30 @@ jobs: if: github.event.pull_request.merged == true runs-on: ubuntu-latest permissions: - pull-requests: write - contents: read + pull-requests: write + contents: read steps: + - name: Check SOURCE_REPO + id: check_repo + env: + SOURCE_REPO: ${{ secrets.SOURCE_REPO_NAME }} + run: | + echo "::set-output name=is_correct_repo::$(if [[ "$SOURCE_REPO" == "makeplane/plane" ]]; then echo 'true'; else echo 'false'; fi)" + - name: Checkout Code + if: steps.check_repo.outputs.is_correct_repo == 'true' uses: actions/checkout@v2 with: persist-credentials: false fetch-depth: 0 - + - name: Set up Branch Name + if: steps.check_repo.outputs.is_correct_repo == 'true' run: | - echo "BRANCH_NAME=${{ github.head_ref }}" >> $GITHUB_ENV - + echo "SOURCE_BRANCH_NAME=${{ github.head_ref }}" >> $GITHUB_ENV + - name: Setup GH CLI + if: steps.check_repo.outputs.is_correct_repo == 'true' run: | type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y) curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg @@ -34,24 +44,24 @@ jobs: sudo apt install gh -y - name: Create Pull Request + if: steps.check_repo.outputs.is_correct_repo == 'true' env: - GH_TOKEN: ${{ secrets.TOKEN }} + GH_TOKEN: ${{ secrets.ACCESS_TOKEN }} run: | - TARGET_REPO="makeplane/${{ secrets.REPO_NAME }}" - TARGET_BRANCH="${{ secrets.REPO_TARGET_BRANCH }}" - SOURCE_BRANCH="${{ env.BRANCH_NAME }}" - - git checkout $SOURCE_BRANCH - git remote add target "https://$GH_TOKEN@github.com/$TARGET_REPO.git" - git push target $SOURCE_BRANCH:$SOURCE_BRANCH + TARGET_REPO="${{ secrets.TARGET_REPO_NAME }}" + TARGET_BRANCH="${{ secrets.TARGET_REPO_BRANCH }}" + SOURCE_BRANCH="${{ env.SOURCE_BRANCH_NAME }}" - PR_TITLE="${{ github.event.pull_request.title }}" - PR_BODY="${{ github.event.pull_request.body }}" - - gh pr create \ - --base $TARGET_BRANCH \ - --head $SOURCE_BRANCH \ - --title "$PR_TITLE" \ - --body "$PR_BODY" \ - --repo $TARGET_REPO - + git checkout $SOURCE_BRANCH + git remote add target "https://$GH_TOKEN@github.com/$TARGET_REPO.git" + git push target $SOURCE_BRANCH:$SOURCE_BRANCH + + PR_TITLE="${{ github.event.pull_request.title }}" + PR_BODY="${{ github.event.pull_request.body }}" + + gh pr create \ + --base $TARGET_BRANCH \ + --head $SOURCE_BRANCH \ + --title "$PR_TITLE" \ + --body "$PR_BODY" \ + --repo $TARGET_REPO diff --git a/.github/workflows/Update_Docker_Images.yml b/.github/workflows/update-docker-images.yml similarity index 100% rename from .github/workflows/Update_Docker_Images.yml rename to .github/workflows/update-docker-images.yml From cecdf890de06ec04b23c0aaff1e3b18df59a729a Mon Sep 17 00:00:00 2001 From: Dakshesh Jain <65905942+dakshesh14@users.noreply.github.com> Date: Wed, 4 Oct 2023 14:55:41 +0530 Subject: [PATCH 08/30] fix: issue relation mutation and draft issue (#2340) * fix: issue relation mutation and draft issue * fix: 'New Issue' in gantt view fix: emoji select going under * fix: profile page typo --- .../core/views/board-view/single-board.tsx | 40 ++- .../core/views/list-view/single-list.tsx | 297 +++++++++--------- web/components/emoji-icon-picker/index.tsx | 16 +- web/components/gantt-chart/chart/index.tsx | 5 +- web/components/issues/draft-issue-form.tsx | 34 +- web/components/issues/draft-issue-modal.tsx | 1 + web/components/issues/form.tsx | 25 +- .../issues/sidebar-select/blocked.tsx | 12 +- .../issues/sidebar-select/blocker.tsx | 2 +- .../issues/sidebar-select/duplicate.tsx | 6 +- .../issues/sidebar-select/relates-to.tsx | 6 +- web/components/issues/sidebar.tsx | 6 +- .../[workspaceSlug]/me/profile/index.tsx | 2 +- 13 files changed, 268 insertions(+), 184 deletions(-) diff --git a/web/components/core/views/board-view/single-board.tsx b/web/components/core/views/board-view/single-board.tsx index bdbfc27c2..6d583e772 100644 --- a/web/components/core/views/board-view/single-board.tsx +++ b/web/components/core/views/board-view/single-board.tsx @@ -6,6 +6,7 @@ import { useRouter } from "next/router"; import StrictModeDroppable from "components/dnd/StrictModeDroppable"; import { Draggable } from "react-beautiful-dnd"; // components +import { CreateUpdateDraftIssueModal } from "components/issues"; import { BoardHeader, SingleBoardIssue, BoardInlineCreateIssueForm } from "components/core"; // ui import { CustomMenu } from "components/ui"; @@ -57,6 +58,7 @@ export const SingleBoard: React.FC = (props) => { const [isCollapsed, setIsCollapsed] = useState(true); const [isInlineCreateIssueFormOpen, setIsInlineCreateIssueFormOpen] = useState(false); + const [isCreateDraftIssueModalOpen, setIsCreateDraftIssueModalOpen] = useState(false); const { displayFilters, groupedIssues } = viewProps; @@ -96,10 +98,27 @@ export const SingleBoard: React.FC = (props) => { scrollToBottom(); }; + const handleAddIssueToGroup = () => { + if (isDraftIssuesPage) setIsCreateDraftIssueModalOpen(true); + else if (isMyIssuesPage || isProfileIssuesPage) addIssueToGroup(); + else onCreateClick(); + }; + return (
+ setIsCreateDraftIssueModalOpen(false)} + prePopulateData={{ + ...(cycleId && { cycle: cycleId.toString() }), + ...(moduleId && { module: moduleId.toString() }), + [displayFilters?.group_by! === "labels" ? "labels_list" : displayFilters?.group_by!]: + displayFilters?.group_by === "labels" ? [groupTitle] : groupTitle, + }} + /> + = (props) => { {displayFilters?.group_by !== "created_by" && (
{type === "issue" - ? !disableAddIssueOption && ( + ? !disableAddIssueOption && + !isDraftIssuesPage && ( ) - : !disableUserActions && ( + : !disableUserActions && + !isDraftIssuesPage && ( = (props) => { position="left" noBorder > - onCreateClick()}> + { + if (isDraftIssuesPage) setIsCreateDraftIssueModalOpen(true); + else if (isMyIssuesPage || isProfileIssuesPage) addIssueToGroup(); + else onCreateClick(); + }} + > Create new {openIssuesListModal && ( diff --git a/web/components/core/views/list-view/single-list.tsx b/web/components/core/views/list-view/single-list.tsx index 9d3e9cb96..8cba67112 100644 --- a/web/components/core/views/list-view/single-list.tsx +++ b/web/components/core/views/list-view/single-list.tsx @@ -13,6 +13,7 @@ import projectService from "services/project.service"; // hooks import useProjects from "hooks/use-projects"; // components +import { CreateUpdateDraftIssueModal } from "components/issues"; import { SingleListIssue, ListInlineCreateIssueForm } from "components/core"; // ui import { Avatar, CustomMenu } from "components/ui"; @@ -75,6 +76,7 @@ export const SingleList: React.FC = (props) => { const { workspaceSlug, projectId, cycleId, moduleId } = router.query; const [isCreateIssueFormOpen, setIsCreateIssueFormOpen] = useState(false); + const [isDraftIssuesModalOpen, setIsDraftIssuesModalOpen] = useState(false); const isMyIssuesPage = router.pathname.split("/")[3] === "my-issues"; const isProfileIssuesPage = router.pathname.split("/")[2] === "profile"; @@ -208,154 +210,169 @@ export const SingleList: React.FC = (props) => { if (!groupedIssues) return null; return ( - - {({ open }) => ( -
-
- -
- {displayFilters?.group_by !== null && ( -
{getGroupIcon()}
- )} - {displayFilters?.group_by !== null ? ( -

- {getGroupTitle()} -

- ) : ( -

All Issues

- )} - - {groupedIssues[groupTitle as keyof IIssue].length} - -
-
- {isArchivedIssues ? ( - "" - ) : type === "issue" ? ( - !disableAddIssueOption && ( - - ) - ) : disableUserActions ? ( - "" - ) : ( - - -
- } - position="right" - noBorder - > - setIsCreateIssueFormOpen(true)}> - Create new - - {openIssuesListModal && ( - - Add an existing issue - - )} - - )} -
- - - {groupedIssues[groupTitle] ? ( - groupedIssues[groupTitle].length > 0 ? ( - groupedIssues[groupTitle].map((issue, index) => ( - handleIssueAction(issue, "edit")} - makeIssueCopy={() => handleIssueAction(issue, "copy")} - handleDeleteIssue={() => handleIssueAction(issue, "delete")} - handleDraftIssueSelect={ - handleDraftIssueAction - ? () => handleDraftIssueAction(issue, "edit") - : undefined - } - handleDraftIssueDelete={ - handleDraftIssueAction - ? () => handleDraftIssueAction(issue, "delete") - : undefined - } - handleMyIssueOpen={handleMyIssueOpen} - removeIssue={() => { - if (removeIssue !== null && issue.bridge_id) - removeIssue(issue.bridge_id, issue.id); - }} - disableUserActions={disableUserActions} - user={user} - userAuth={userAuth} - viewProps={viewProps} - /> - )) - ) : ( -

- No issues. -

- ) - ) : ( -
Loading...
- )} + <> + setIsDraftIssuesModalOpen(false)} + prePopulateData={{ + ...(cycleId && { cycle: cycleId.toString() }), + ...(moduleId && { module: moduleId.toString() }), + [displayFilters?.group_by! === "labels" ? "labels_list" : displayFilters?.group_by!]: + displayFilters?.group_by === "labels" ? [groupTitle] : groupTitle, + }} + /> - setIsCreateIssueFormOpen(false)} - prePopulatedData={{ - ...(cycleId && { cycle: cycleId.toString() }), - ...(moduleId && { module: moduleId.toString() }), - [displayFilters?.group_by!]: groupTitle, - }} - /> - - {!disableAddIssueOption && !isCreateIssueFormOpen && ( - // TODO: add border here -
+ + {({ open }) => ( +
+
+ +
+ {displayFilters?.group_by !== null && ( +
{getGroupIcon()}
+ )} + {displayFilters?.group_by !== null ? ( +

+ {getGroupTitle()} +

+ ) : ( +

All Issues

+ )} + + {groupedIssues[groupTitle as keyof IIssue].length} + +
+
+ {isArchivedIssues ? ( + "" + ) : type === "issue" ? ( + !disableAddIssueOption && ( -
+ ) + ) : disableUserActions ? ( + "" + ) : ( + + +
+ } + position="right" + noBorder + > + setIsCreateIssueFormOpen(true)}> + Create new + + {openIssuesListModal && ( + + Add an existing issue + + )} + )} - - -
- )} -
+
+ + + {groupedIssues[groupTitle] ? ( + groupedIssues[groupTitle].length > 0 ? ( + groupedIssues[groupTitle].map((issue, index) => ( + handleIssueAction(issue, "edit")} + makeIssueCopy={() => handleIssueAction(issue, "copy")} + handleDeleteIssue={() => handleIssueAction(issue, "delete")} + handleDraftIssueSelect={ + handleDraftIssueAction + ? () => handleDraftIssueAction(issue, "edit") + : undefined + } + handleDraftIssueDelete={ + handleDraftIssueAction + ? () => handleDraftIssueAction(issue, "delete") + : undefined + } + handleMyIssueOpen={handleMyIssueOpen} + removeIssue={() => { + if (removeIssue !== null && issue.bridge_id) + removeIssue(issue.bridge_id, issue.id); + }} + disableUserActions={disableUserActions} + user={user} + userAuth={userAuth} + viewProps={viewProps} + /> + )) + ) : ( +

+ No issues. +

+ ) + ) : ( +
Loading...
+ )} + + setIsCreateIssueFormOpen(false)} + prePopulatedData={{ + ...(cycleId && { cycle: cycleId.toString() }), + ...(moduleId && { module: moduleId.toString() }), + [displayFilters?.group_by! === "labels" + ? "labels_list" + : displayFilters?.group_by!]: + displayFilters?.group_by === "labels" ? [groupTitle] : groupTitle, + }} + /> + + {!disableAddIssueOption && !isCreateIssueFormOpen && !isDraftIssuesPage && ( +
+ +
+ )} +
+
+
+ )} + + ); }; diff --git a/web/components/emoji-icon-picker/index.tsx b/web/components/emoji-icon-picker/index.tsx index ab4eb022e..cc42dbec8 100644 --- a/web/components/emoji-icon-picker/index.tsx +++ b/web/components/emoji-icon-picker/index.tsx @@ -4,6 +4,7 @@ import { Tab, Transition, Popover } from "@headlessui/react"; // react colors import { TwitterPicker } from "react-color"; // hooks +import useDynamicDropdownPosition from "hooks/use-dynamic-dropdown"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; // types import { Props } from "./types"; @@ -38,6 +39,7 @@ const EmojiIconPicker: React.FC = ({ const [recentEmojis, setRecentEmojis] = useState([]); + const buttonRef = useRef(null); const emojiPickerRef = useRef(null); useEffect(() => { @@ -49,10 +51,12 @@ const EmojiIconPicker: React.FC = ({ }, [value, onChange]); useOutsideClickDetector(emojiPickerRef, () => setIsOpen(false)); + useDynamicDropdownPosition(isOpen, () => setIsOpen(false), buttonRef, emojiPickerRef); return ( setIsOpen((prev) => !prev)} className="outline-none" disabled={disabled} @@ -61,6 +65,8 @@ const EmojiIconPicker: React.FC = ({ = ({ leaveFrom="transform opacity-100 scale-100" leaveTo="transform opacity-0 scale-95" > - -
+ +
{tabOptions.map((tab) => ( diff --git a/web/components/gantt-chart/chart/index.tsx b/web/components/gantt-chart/chart/index.tsx index 61e3078d6..e21e803de 100644 --- a/web/components/gantt-chart/chart/index.tsx +++ b/web/components/gantt-chart/chart/index.tsx @@ -80,6 +80,9 @@ export const ChartViewRoot: FC = ({ const router = useRouter(); const { cycleId, moduleId } = router.query; + const isCyclePage = router.pathname.split("/")[4] === "cycles" && !cycleId; + const isModulePage = router.pathname.split("/")[4] === "modules" && !moduleId; + const renderBlockStructure = (view: any, blocks: IGanttBlock[] | null) => blocks && blocks.length > 0 ? blocks.map((block: any) => ({ @@ -317,7 +320,7 @@ export const ChartViewRoot: FC = ({ SidebarBlockRender={SidebarBlockRender} enableReorder={enableReorder} /> - {chartBlocks && ( + {chartBlocks && !(isCyclePage || isModulePage) && (
Promise; data?: Partial | null; + isOpen: boolean; prePopulatedData?: Partial | null; projectId: string; setActiveProject: React.Dispatch>; @@ -89,6 +91,7 @@ export const DraftIssueForm: FC = (props) => { const { handleFormSubmit, data, + isOpen, prePopulatedData, projectId, setActiveProject, @@ -109,6 +112,8 @@ export const DraftIssueForm: FC = (props) => { const [gptAssistantModal, setGptAssistantModal] = useState(false); const [iAmFeelingLucky, setIAmFeelingLucky] = useState(false); + const { setValue: setLocalStorageValue } = useLocalStorage("draftedIssue", {}); + const editorRef = useRef(null); const router = useRouter(); @@ -133,6 +138,33 @@ export const DraftIssueForm: FC = (props) => { const issueName = watch("name"); + const payload: Partial = { + name: watch("name"), + description: watch("description"), + description_html: watch("description_html"), + state: watch("state"), + priority: watch("priority"), + assignees: watch("assignees"), + labels: watch("labels"), + start_date: watch("start_date"), + target_date: watch("target_date"), + project: watch("project"), + parent: watch("parent"), + cycle: watch("cycle"), + module: watch("module"), + }; + + useEffect(() => { + if (!isOpen || data) return; + + setLocalStorageValue( + JSON.stringify({ + ...payload, + }) + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [JSON.stringify(payload), isOpen, data]); + const onClose = () => { handleClose(); }; @@ -273,7 +305,7 @@ export const DraftIssueForm: FC = (props) => { )}
- handleCreateUpdateIssue(formData, "convertToNewIssue") + handleCreateUpdateIssue(formData, data ? "convertToNewIssue" : "createDraft") )} >
diff --git a/web/components/issues/draft-issue-modal.tsx b/web/components/issues/draft-issue-modal.tsx index b6479d067..ca37ae03f 100644 --- a/web/components/issues/draft-issue-modal.tsx +++ b/web/components/issues/draft-issue-modal.tsx @@ -385,6 +385,7 @@ export const CreateUpdateDraftIssueModal: React.FC = (props) = > = (props) => { const issueName = watch("name"); const payload: Partial = { - name: getValues("name"), - description: getValues("description"), - state: getValues("state"), - priority: getValues("priority"), - assignees: getValues("assignees"), - labels: getValues("labels"), - start_date: getValues("start_date"), - target_date: getValues("target_date"), - project: getValues("project"), - parent: getValues("parent"), - cycle: getValues("cycle"), - module: getValues("module"), + name: watch("name"), + description: watch("description"), + description_html: watch("description_html"), + state: watch("state"), + priority: watch("priority"), + assignees: watch("assignees"), + labels: watch("labels"), + start_date: watch("start_date"), + target_date: watch("target_date"), + project: watch("project"), + parent: watch("parent"), + cycle: watch("cycle"), + module: watch("module"), }; useEffect(() => { diff --git a/web/components/issues/sidebar-select/blocked.tsx b/web/components/issues/sidebar-select/blocked.tsx index d7e448377..a4ebe0108 100644 --- a/web/components/issues/sidebar-select/blocked.tsx +++ b/web/components/issues/sidebar-select/blocked.tsx @@ -14,7 +14,7 @@ import { ExistingIssuesListModal } from "components/core"; import { XMarkIcon } from "@heroicons/react/24/outline"; import { BlockedIcon } from "components/icons"; // types -import { BlockeIssueDetail, IIssue, ISearchIssueResponse, UserAuth } from "types"; +import { BlockeIssueDetail, IIssue, ISearchIssueResponse } from "types"; type Props = { issueId?: string; @@ -41,6 +41,9 @@ export const SidebarBlockedSelect: React.FC = ({ setIsBlockedModalOpen(false); }; + const blockedByIssue = + watch("related_issues")?.filter((i) => i.relation_type === "blocked_by") || []; + const onSubmit = async (data: ISearchIssueResponse[]) => { if (data.length === 0) { setToastAlert({ @@ -80,18 +83,13 @@ export const SidebarBlockedSelect: React.FC = ({ }) .then((response) => { submitChanges({ - related_issues: [ - ...watch("related_issues")?.filter((i) => i.relation_type !== "blocked_by"), - ...response, - ], + related_issues: [...watch("related_issues"), ...response], }); }); handleClose(); }; - const blockedByIssue = watch("related_issues")?.filter((i) => i.relation_type === "blocked_by"); - return ( <> = (props) => { })), ], }) - .then((response) => { - submitChanges({ - related_issues: [...watch("related_issues"), ...(response ?? [])], - }); + .then(() => { + submitChanges(); }); handleClose(); diff --git a/web/components/issues/sidebar-select/relates-to.tsx b/web/components/issues/sidebar-select/relates-to.tsx index deadf4d20..b9e56dbeb 100644 --- a/web/components/issues/sidebar-select/relates-to.tsx +++ b/web/components/issues/sidebar-select/relates-to.tsx @@ -75,10 +75,8 @@ export const SidebarRelatesSelect: React.FC = (props) => { })), ], }) - .then((response) => { - submitChanges({ - related_issues: [...watch("related_issues"), ...(response ?? [])], - }); + .then(() => { + submitChanges(); }); handleClose(); diff --git a/web/components/issues/sidebar.tsx b/web/components/issues/sidebar.tsx index 5455192fb..e0c370eaf 100644 --- a/web/components/issues/sidebar.tsx +++ b/web/components/issues/sidebar.tsx @@ -53,7 +53,7 @@ import { copyTextToClipboard } from "helpers/string.helper"; // types import type { ICycle, IIssue, IIssueLink, linkDetails, IModule } from "types"; // fetch-keys -import { ISSUE_DETAILS } from "constants/fetch-keys"; +import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys"; import { ContrastIcon } from "components/icons"; type Props = { @@ -480,6 +480,7 @@ export const IssueDetailsSidebar: React.FC = ({ }, false ); + mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); }} watch={watchIssue} disabled={memberRole.isGuest || memberRole.isViewer || uneditable} @@ -500,6 +501,7 @@ export const IssueDetailsSidebar: React.FC = ({ }, false ); + mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); }} watch={watchIssue} disabled={memberRole.isGuest || memberRole.isViewer || uneditable} @@ -517,6 +519,7 @@ export const IssueDetailsSidebar: React.FC = ({ ...data, }; }); + mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); }} watch={watchIssue} disabled={memberRole.isGuest || memberRole.isViewer || uneditable} @@ -534,6 +537,7 @@ export const IssueDetailsSidebar: React.FC = ({ ...data, }; }); + mutate(PROJECT_ISSUES_ACTIVITY(issueId as string)); }} watch={watchIssue} disabled={memberRole.isGuest || memberRole.isViewer || uneditable} diff --git a/web/pages/[workspaceSlug]/me/profile/index.tsx b/web/pages/[workspaceSlug]/me/profile/index.tsx index 40ba8ecf3..8738ff46f 100644 --- a/web/pages/[workspaceSlug]/me/profile/index.tsx +++ b/web/pages/[workspaceSlug]/me/profile/index.tsx @@ -375,7 +375,7 @@ const Profile: NextPage = () => {
- {isSubmitting ? "Updating Project..." : "Update Project"} + {isSubmitting ? "Updating Profile..." : "Update Profile"}
From db1bcdb54fe13908640954b303893b5bc2db3dd8 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Wed, 4 Oct 2023 15:07:01 +0530 Subject: [PATCH 09/30] fix: sync workflow fixes (#2365) --- .github/workflows/create-sync-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/create-sync-pr.yml b/.github/workflows/create-sync-pr.yml index 6ca840197..ee1ac7c70 100644 --- a/.github/workflows/create-sync-pr.yml +++ b/.github/workflows/create-sync-pr.yml @@ -62,6 +62,6 @@ jobs: gh pr create \ --base $TARGET_BRANCH \ --head $SOURCE_BRANCH \ - --title "$PR_TITLE" \ - --body "$PR_BODY" \ + --title $PR_TITLE \ + --body $PR_BODY \ --repo $TARGET_REPO From 4017f6bc557fd743debd4e700e03d9462cd135c4 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Wed, 4 Oct 2023 15:29:45 +0530 Subject: [PATCH 10/30] fix: sync job pr description escaped values fix (#2366) --- .github/workflows/create-sync-pr.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/create-sync-pr.yml b/.github/workflows/create-sync-pr.yml index ee1ac7c70..98605af74 100644 --- a/.github/workflows/create-sync-pr.yml +++ b/.github/workflows/create-sync-pr.yml @@ -59,9 +59,19 @@ jobs: PR_TITLE="${{ github.event.pull_request.title }}" PR_BODY="${{ github.event.pull_request.body }}" + # Remove double quotes + PR_TITLE_CLEANED="${PR_TITLE//\"/}" + PR_BODY_CLEANED="${PR_BODY//\"/}" + + # Construct PR_BODY_CONTENT using a here-document + PR_BODY_CONTENT=$(cat < Date: Wed, 4 Oct 2023 06:07:01 -0600 Subject: [PATCH 11/30] Update index.tsx (#2343) Fixes #2342 From eacf543439e082dcd3854807914c93dbeeebc4b1 Mon Sep 17 00:00:00 2001 From: Nikhil <118773738+pablohashescobar@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:39:12 +0530 Subject: [PATCH 12/30] dev: update apiserver configuration files (#2348) * dev: update apiserver configuration files * dev: add email and minio redirection urls --- apiserver/.env.example | 5 +- apiserver/plane/settings/production.py | 187 +++++++++++++++---------- 2 files changed, 116 insertions(+), 76 deletions(-) diff --git a/apiserver/.env.example b/apiserver/.env.example index 4969f1766..8772dfd53 100644 --- a/apiserver/.env.example +++ b/apiserver/.env.example @@ -1,7 +1,7 @@ # Backend # Debug value for api server use it as 0 for production use DEBUG=0 -DJANGO_SETTINGS_MODULE="plane.settings.selfhosted" +DJANGO_SETTINGS_MODULE="plane.settings.production" # Error logs SENTRY_DSN="" @@ -59,3 +59,6 @@ DEFAULT_PASSWORD="password123" # SignUps ENABLE_SIGNUP="1" + +# Email redirections and minio domain settings +WEB_URL="http://localhost" diff --git a/apiserver/plane/settings/production.py b/apiserver/plane/settings/production.py index e434f9742..170a2067c 100644 --- a/apiserver/plane/settings/production.py +++ b/apiserver/plane/settings/production.py @@ -7,6 +7,7 @@ import dj_database_url import sentry_sdk from sentry_sdk.integrations.django import DjangoIntegration from sentry_sdk.integrations.redis import RedisIntegration +from urllib.parse import urlparse from .common import * # noqa @@ -89,90 +90,112 @@ if bool(os.environ.get("SENTRY_DSN", False)): profiles_sample_rate=1.0, ) -# The AWS region to connect to. -AWS_REGION = os.environ.get("AWS_REGION", "") +if DOCKERIZED and USE_MINIO: + INSTALLED_APPS += ("storages",) + STORAGES["default"] = {"BACKEND": "storages.backends.s3boto3.S3Boto3Storage"} + # The AWS access key to use. + AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID", "access-key") + # The AWS secret access key to use. + AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY", "secret-key") + # The name of the bucket to store files in. + AWS_STORAGE_BUCKET_NAME = os.environ.get("AWS_S3_BUCKET_NAME", "uploads") + # The full URL to the S3 endpoint. Leave blank to use the default region URL. + AWS_S3_ENDPOINT_URL = os.environ.get( + "AWS_S3_ENDPOINT_URL", "http://plane-minio:9000" + ) + # Default permissions + AWS_DEFAULT_ACL = "public-read" + AWS_QUERYSTRING_AUTH = False + AWS_S3_FILE_OVERWRITE = False -# The AWS access key to use. -AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID", "") + # Custom Domain settings + parsed_url = urlparse(os.environ.get("WEB_URL", "http://localhost")) + AWS_S3_CUSTOM_DOMAIN = f"{parsed_url.netloc}/{AWS_STORAGE_BUCKET_NAME}" + AWS_S3_URL_PROTOCOL = f"{parsed_url.scheme}:" +else: + # The AWS region to connect to. + AWS_REGION = os.environ.get("AWS_REGION", "") -# The AWS secret access key to use. -AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY", "") + # The AWS access key to use. + AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID", "") -# The optional AWS session token to use. -# AWS_SESSION_TOKEN = "" + # The AWS secret access key to use. + AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY", "") -# The name of the bucket to store files in. -AWS_S3_BUCKET_NAME = os.environ.get("AWS_S3_BUCKET_NAME") + # The optional AWS session token to use. + # AWS_SESSION_TOKEN = "" -# How to construct S3 URLs ("auto", "path", "virtual"). -AWS_S3_ADDRESSING_STYLE = "auto" + # The name of the bucket to store files in. + AWS_S3_BUCKET_NAME = os.environ.get("AWS_S3_BUCKET_NAME") -# The full URL to the S3 endpoint. Leave blank to use the default region URL. -AWS_S3_ENDPOINT_URL = os.environ.get("AWS_S3_ENDPOINT_URL", "") + # How to construct S3 URLs ("auto", "path", "virtual"). + AWS_S3_ADDRESSING_STYLE = "auto" -# A prefix to be applied to every stored file. This will be joined to every filename using the "/" separator. -AWS_S3_KEY_PREFIX = "" + # The full URL to the S3 endpoint. Leave blank to use the default region URL. + AWS_S3_ENDPOINT_URL = os.environ.get("AWS_S3_ENDPOINT_URL", "") -# Whether to enable authentication for stored files. If True, then generated URLs will include an authentication -# token valid for `AWS_S3_MAX_AGE_SECONDS`. If False, then generated URLs will not include an authentication token, -# and their permissions will be set to "public-read". -AWS_S3_BUCKET_AUTH = False + # A prefix to be applied to every stored file. This will be joined to every filename using the "/" separator. + AWS_S3_KEY_PREFIX = "" -# How long generated URLs are valid for. This affects the expiry of authentication tokens if `AWS_S3_BUCKET_AUTH` -# is True. It also affects the "Cache-Control" header of the files. -# Important: Changing this setting will not affect existing files. -AWS_S3_MAX_AGE_SECONDS = 60 * 60 # 1 hours. + # Whether to enable authentication for stored files. If True, then generated URLs will include an authentication + # token valid for `AWS_S3_MAX_AGE_SECONDS`. If False, then generated URLs will not include an authentication token, + # and their permissions will be set to "public-read". + AWS_S3_BUCKET_AUTH = False -# A URL prefix to be used for generated URLs. This is useful if your bucket is served through a CDN. This setting -# cannot be used with `AWS_S3_BUCKET_AUTH`. -AWS_S3_PUBLIC_URL = "" + # How long generated URLs are valid for. This affects the expiry of authentication tokens if `AWS_S3_BUCKET_AUTH` + # is True. It also affects the "Cache-Control" header of the files. + # Important: Changing this setting will not affect existing files. + AWS_S3_MAX_AGE_SECONDS = 60 * 60 # 1 hours. -# If True, then files will be stored with reduced redundancy. Check the S3 documentation and make sure you -# understand the consequences before enabling. -# Important: Changing this setting will not affect existing files. -AWS_S3_REDUCED_REDUNDANCY = False + # A URL prefix to be used for generated URLs. This is useful if your bucket is served through a CDN. This setting + # cannot be used with `AWS_S3_BUCKET_AUTH`. + AWS_S3_PUBLIC_URL = "" -# The Content-Disposition header used when the file is downloaded. This can be a string, or a function taking a -# single `name` argument. -# Important: Changing this setting will not affect existing files. -AWS_S3_CONTENT_DISPOSITION = "" + # If True, then files will be stored with reduced redundancy. Check the S3 documentation and make sure you + # understand the consequences before enabling. + # Important: Changing this setting will not affect existing files. + AWS_S3_REDUCED_REDUNDANCY = False -# The Content-Language header used when the file is downloaded. This can be a string, or a function taking a -# single `name` argument. -# Important: Changing this setting will not affect existing files. -AWS_S3_CONTENT_LANGUAGE = "" + # The Content-Disposition header used when the file is downloaded. This can be a string, or a function taking a + # single `name` argument. + # Important: Changing this setting will not affect existing files. + AWS_S3_CONTENT_DISPOSITION = "" -# A mapping of custom metadata for each file. Each value can be a string, or a function taking a -# single `name` argument. -# Important: Changing this setting will not affect existing files. -AWS_S3_METADATA = {} + # The Content-Language header used when the file is downloaded. This can be a string, or a function taking a + # single `name` argument. + # Important: Changing this setting will not affect existing files. + AWS_S3_CONTENT_LANGUAGE = "" -# If True, then files will be stored using AES256 server-side encryption. -# If this is a string value (e.g., "aws:kms"), that encryption type will be used. -# Otherwise, server-side encryption is not be enabled. -# Important: Changing this setting will not affect existing files. -AWS_S3_ENCRYPT_KEY = False + # A mapping of custom metadata for each file. Each value can be a string, or a function taking a + # single `name` argument. + # Important: Changing this setting will not affect existing files. + AWS_S3_METADATA = {} -# The AWS S3 KMS encryption key ID (the `SSEKMSKeyId` parameter) is set from this string if present. -# This is only relevant if AWS S3 KMS server-side encryption is enabled (above). -# AWS_S3_KMS_ENCRYPTION_KEY_ID = "" + # If True, then files will be stored using AES256 server-side encryption. + # If this is a string value (e.g., "aws:kms"), that encryption type will be used. + # Otherwise, server-side encryption is not be enabled. + # Important: Changing this setting will not affect existing files. + AWS_S3_ENCRYPT_KEY = False -# If True, then text files will be stored using gzip content encoding. Files will only be gzipped if their -# compressed size is smaller than their uncompressed size. -# Important: Changing this setting will not affect existing files. -AWS_S3_GZIP = True + # The AWS S3 KMS encryption key ID (the `SSEKMSKeyId` parameter) is set from this string if present. + # This is only relevant if AWS S3 KMS server-side encryption is enabled (above). + # AWS_S3_KMS_ENCRYPTION_KEY_ID = "" -# The signature version to use for S3 requests. -AWS_S3_SIGNATURE_VERSION = None + # If True, then text files will be stored using gzip content encoding. Files will only be gzipped if their + # compressed size is smaller than their uncompressed size. + # Important: Changing this setting will not affect existing files. + AWS_S3_GZIP = True -# If True, then files with the same name will overwrite each other. By default it's set to False to have -# extra characters appended. -AWS_S3_FILE_OVERWRITE = False + # The signature version to use for S3 requests. + AWS_S3_SIGNATURE_VERSION = None -STORAGES["default"] = { - "BACKEND": "django_s3_storage.storage.S3Storage", -} + # If True, then files with the same name will overwrite each other. By default it's set to False to have + # extra characters appended. + AWS_S3_FILE_OVERWRITE = False + STORAGES["default"] = { + "BACKEND": "django_s3_storage.storage.S3Storage", + } # AWS Settings End # Enable Connection Pooling (if desired) @@ -193,16 +216,27 @@ CSRF_COOKIE_SECURE = True REDIS_URL = os.environ.get("REDIS_URL") -CACHES = { - "default": { - "BACKEND": "django_redis.cache.RedisCache", - "LOCATION": REDIS_URL, - "OPTIONS": { - "CLIENT_CLASS": "django_redis.client.DefaultClient", - "CONNECTION_POOL_KWARGS": {"ssl_cert_reqs": False}, - }, +if DOCKERIZED: + CACHES = { + "default": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": REDIS_URL, + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + }, + } + } +else: + CACHES = { + "default": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": REDIS_URL, + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient", + "CONNECTION_POOL_KWARGS": {"ssl_cert_reqs": False}, + }, + } } -} WEB_URL = os.environ.get("WEB_URL", "https://app.plane.so") @@ -225,8 +259,12 @@ broker_url = ( f"{redis_url}?ssl_cert_reqs={ssl.CERT_NONE.name}&ssl_ca_certs={certifi.where()}" ) -CELERY_RESULT_BACKEND = broker_url -CELERY_BROKER_URL = broker_url +if DOCKERIZED: + CELERY_BROKER_URL = REDIS_URL + CELERY_RESULT_BACKEND = REDIS_URL +else: + CELERY_BROKER_URL = broker_url + CELERY_RESULT_BACKEND = broker_url GITHUB_ACCESS_TOKEN = os.environ.get("GITHUB_ACCESS_TOKEN", False) @@ -237,4 +275,3 @@ ENABLE_SIGNUP = os.environ.get("ENABLE_SIGNUP", "1") == "1" SCOUT_MONITOR = os.environ.get("SCOUT_MONITOR", False) SCOUT_KEY = os.environ.get("SCOUT_KEY", "") SCOUT_NAME = "Plane" - From 1e9149d8720a4bf59e8aeaddd4cb0329f377ba8a Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Wed, 4 Oct 2023 17:44:54 +0530 Subject: [PATCH 13/30] fix: themening validation in store init. (#2350) --- web/lib/mobx/store-init.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/web/lib/mobx/store-init.tsx b/web/lib/mobx/store-init.tsx index 5c2ee0558..771d8eaba 100644 --- a/web/lib/mobx/store-init.tsx +++ b/web/lib/mobx/store-init.tsx @@ -24,9 +24,12 @@ const MobxStoreInit = () => { ); // theme - if (store.theme.theme === null && store?.user?.currentUserSettings) { + if ( + (store.theme.theme === null || store.theme.theme === "undefined") && + store?.user?.currentUserSettings + ) { let currentTheme = localStorage.getItem("theme"); - currentTheme = currentTheme ? currentTheme : "system"; + currentTheme = currentTheme && currentTheme != "undefined" ? currentTheme : "system"; // validating the theme and applying for initial state if (currentTheme) { From fb6f6454df1d2a32a1555f75177fed28317e4ac4 Mon Sep 17 00:00:00 2001 From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:47:01 +0530 Subject: [PATCH 14/30] chore: member can change role (#2371) --- apiserver/plane/api/views/project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apiserver/plane/api/views/project.py b/apiserver/plane/api/views/project.py index c72b8d423..7847e3a80 100644 --- a/apiserver/plane/api/views/project.py +++ b/apiserver/plane/api/views/project.py @@ -495,7 +495,7 @@ class ProjectMemberViewSet(BaseViewSet): serializer_class = ProjectMemberAdminSerializer model = ProjectMember permission_classes = [ - ProjectBasePermission, + ProjectMemberPermission, ] search_fields = [ From c2f0ae1ec5921c7a2b404c5bfccf6dfacade94e9 Mon Sep 17 00:00:00 2001 From: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:47:46 +0530 Subject: [PATCH 15/30] chore: removed the issue draft log from my profile (#2368) --- apiserver/plane/api/views/workspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apiserver/plane/api/views/workspace.py b/apiserver/plane/api/views/workspace.py index 753fd861b..8d518b160 100644 --- a/apiserver/plane/api/views/workspace.py +++ b/apiserver/plane/api/views/workspace.py @@ -1197,7 +1197,7 @@ class WorkspaceUserActivityEndpoint(BaseAPIView): projects = request.query_params.getlist("project", []) queryset = IssueActivity.objects.filter( - ~Q(field__in=["comment", "vote", "reaction"]), + ~Q(field__in=["comment", "vote", "reaction", "draft"]), workspace__slug=slug, project__project_projectmember__member=request.user, actor=user_id, From 7a3b556ae0c08b2bde0c5247654ecdf60cf6bc62 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Wed, 4 Oct 2023 18:03:22 +0530 Subject: [PATCH 16/30] adding sync info in pr title (#2373) --- .github/workflows/create-sync-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/create-sync-pr.yml b/.github/workflows/create-sync-pr.yml index 98605af74..28e47a0d6 100644 --- a/.github/workflows/create-sync-pr.yml +++ b/.github/workflows/create-sync-pr.yml @@ -72,6 +72,6 @@ jobs: gh pr create \ --base $TARGET_BRANCH \ --head $SOURCE_BRANCH \ - --title "$PR_TITLE_CLEANED" \ + --title "[SYNC] $PR_TITLE_CLEANED" \ --body "$PR_BODY_CONTENT" \ --repo $TARGET_REPO From 05920a72a59ad58f7e67883ea5b5abf106ca2c84 Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Wed, 4 Oct 2023 18:17:34 +0530 Subject: [PATCH 17/30] chore: layout access validation and switch in plane deploy issues route (#2351) * chore: handled route validation and layout access validation in plane deploy issues * chore: impoved validation condition --- space/components/issues/navbar/index.tsx | 46 ++++++++++++++++++------ 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/space/components/issues/navbar/index.tsx b/space/components/issues/navbar/index.tsx index 509d676b7..35ffbe289 100644 --- a/space/components/issues/navbar/index.tsx +++ b/space/components/issues/navbar/index.tsx @@ -44,19 +44,43 @@ const IssueNavbar = observer(() => { }, [projectStore, workspace_slug, project_slug]); useEffect(() => { - if (workspace_slug && project_slug) { - if (!board) { - router.push({ - pathname: `/${workspace_slug}/${project_slug}`, - query: { - board: "list", - }, - }); - return projectStore.setActiveBoard("list"); + if (workspace_slug && project_slug && projectStore?.deploySettings) { + const viewsAcceptable: string[] = []; + let currentBoard: string | null = null; + + if (projectStore?.deploySettings?.views?.list) viewsAcceptable.push("list"); + if (projectStore?.deploySettings?.views?.kanban) viewsAcceptable.push("kanban"); + if (projectStore?.deploySettings?.views?.calendar) viewsAcceptable.push("calendar"); + if (projectStore?.deploySettings?.views?.gantt) viewsAcceptable.push("gantt"); + if (projectStore?.deploySettings?.views?.spreadsheet) viewsAcceptable.push("spreadsheet"); + + if (board) { + if (viewsAcceptable.includes(board.toString())) { + currentBoard = board.toString(); + } else { + if (viewsAcceptable && viewsAcceptable.length > 0) { + currentBoard = viewsAcceptable[0]; + } + } + } else { + if (viewsAcceptable && viewsAcceptable.length > 0) { + currentBoard = viewsAcceptable[0]; + } + } + + if (currentBoard) { + if (projectStore?.activeBoard === null || projectStore?.activeBoard !== currentBoard) { + projectStore.setActiveBoard(currentBoard); + router.push({ + pathname: `/${workspace_slug}/${project_slug}`, + query: { + board: currentBoard, + }, + }); + } } - projectStore.setActiveBoard(board.toString()); } - }, [board, workspace_slug, project_slug]); + }, [board, workspace_slug, project_slug, router, projectStore, projectStore?.deploySettings]); return (
From 7bdca9c73afea5c0621c394ac25d20946901cf50 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Wed, 4 Oct 2023 18:31:28 +0530 Subject: [PATCH 18/30] show current version in the help section dropdown (#2353) --- package.json | 1 + packages/eslint-config-custom/package.json | 2 +- packages/tailwind-config-custom/package.json | 2 +- packages/tsconfig/package.json | 2 +- packages/ui/package.json | 2 +- space/package.json | 2 +- web/components/workspace/help-section.tsx | 84 +++++++++++--------- web/package.json | 2 +- 8 files changed, 52 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index de09c6ee9..1f2f96414 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "repository": "https://github.com/makeplane/plane.git", + "version": "0.13.2", "license": "AGPL-3.0", "private": true, "workspaces": [ diff --git a/packages/eslint-config-custom/package.json b/packages/eslint-config-custom/package.json index 16fed7a78..12a7ab8c8 100644 --- a/packages/eslint-config-custom/package.json +++ b/packages/eslint-config-custom/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-custom", - "version": "0.0.0", + "version": "0.13.2", "main": "index.js", "license": "MIT", "dependencies": { diff --git a/packages/tailwind-config-custom/package.json b/packages/tailwind-config-custom/package.json index 1bd5a0e1c..6edaa0ec4 100644 --- a/packages/tailwind-config-custom/package.json +++ b/packages/tailwind-config-custom/package.json @@ -1,6 +1,6 @@ { "name": "tailwind-config-custom", - "version": "0.0.1", + "version": "0.13.2", "description": "common tailwind configuration across monorepo", "main": "index.js", "devDependencies": { diff --git a/packages/tsconfig/package.json b/packages/tsconfig/package.json index f4810fc3f..58bfb8451 100644 --- a/packages/tsconfig/package.json +++ b/packages/tsconfig/package.json @@ -1,6 +1,6 @@ { "name": "tsconfig", - "version": "0.0.0", + "version": "0.13.2", "private": true, "files": [ "base.json", diff --git a/packages/ui/package.json b/packages/ui/package.json index 6a9132fca..d107e711c 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "ui", - "version": "0.0.0", + "version": "0.13.2", "main": "./index.tsx", "types": "./index.tsx", "license": "MIT", diff --git a/space/package.json b/space/package.json index 6ce9ecefe..b539fbb65 100644 --- a/space/package.json +++ b/space/package.json @@ -1,6 +1,6 @@ { "name": "space", - "version": "0.0.1", + "version": "0.13.2", "private": true, "scripts": { "dev": "next dev -p 4000", diff --git a/web/components/workspace/help-section.tsx b/web/components/workspace/help-section.tsx index 965a9e8a3..9f35f337c 100644 --- a/web/components/workspace/help-section.tsx +++ b/web/components/workspace/help-section.tsx @@ -1,24 +1,23 @@ import React, { useRef, useState } from "react"; - import Link from "next/link"; - -// headless ui import { Transition } from "@headlessui/react"; + +// mobx store +import { useMobxStore } from "lib/mobx/store-provider"; // hooks -import useTheme from "hooks/use-theme"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; // icons import { Bolt, HelpOutlineOutlined, WestOutlined } from "@mui/icons-material"; -import { ChatBubbleOvalLeftEllipsisIcon } from "@heroicons/react/24/outline"; -import { DocumentIcon, DiscordIcon, GithubIcon } from "components/icons"; -// mobx store -import { useMobxStore } from "lib/mobx/store-provider"; +import { DiscordIcon } from "components/icons"; +import { FileText, Github, MessagesSquare } from "lucide-react"; +// assets +import packageJson from "package.json"; const helpOptions = [ { name: "Documentation", href: "https://docs.plane.so/", - Icon: DocumentIcon, + Icon: FileText, }, { name: "Join our Discord", @@ -28,13 +27,13 @@ const helpOptions = [ { name: "Report a bug", href: "https://github.com/makeplane/plane/issues/new/choose", - Icon: GithubIcon, + Icon: Github, }, { name: "Chat with us", href: null, onClick: () => (window as any).$crisp.push(["do", "chat:show"]), - Icon: ChatBubbleOvalLeftEllipsisIcon, + Icon: MessagesSquare, }, ]; @@ -123,37 +122,44 @@ export const WorkspaceHelpSection: React.FC = ({ setS leaveTo="transform opacity-0 scale-95" >
- {helpOptions.map(({ name, Icon, href, onClick }) => { - if (href) - return ( - - + {helpOptions.map(({ name, Icon, href, onClick }) => { + if (href) + return ( + + +
+ +
+ {name} +
+ + ); + else + return ( + - ); - })} +
+ +
+ {name} + + ); + })} +
+
Version: v{packageJson.version}
diff --git a/web/package.json b/web/package.json index 93fc9366e..e0cf4efed 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "web", - "version": "0.1.0", + "version": "0.13.2", "private": true, "scripts": { "dev": "next dev --port 3000", From d0a51d75f6f9ce1d42f35f82075621fc629b2a49 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Wed, 4 Oct 2023 18:36:14 +0530 Subject: [PATCH 19/30] fix: table menu positioning (#2354) --- web/components/tiptap/index.tsx | 2 +- web/components/tiptap/table-menu/index.tsx | 20 +------------------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/web/components/tiptap/index.tsx b/web/components/tiptap/index.tsx index 84f691c35..44076234e 100644 --- a/web/components/tiptap/index.tsx +++ b/web/components/tiptap/index.tsx @@ -89,7 +89,7 @@ const Tiptap = (props: ITipTapRichTextEditor) => { onClick={() => { editor?.chain().focus().run(); }} - className={`tiptap-editor-container cursor-text ${editorClassNames}`} + className={`tiptap-editor-container relative cursor-text ${editorClassNames}`} > {editor && }
diff --git a/web/components/tiptap/table-menu/index.tsx b/web/components/tiptap/table-menu/index.tsx index 94f9c0f8d..daa8f6953 100644 --- a/web/components/tiptap/table-menu/index.tsx +++ b/web/components/tiptap/table-menu/index.tsx @@ -80,8 +80,6 @@ export const TableMenu = ({ editor }: { editor: any }) => { const range = selection.getRangeAt(0); const tableNode = findTableAncestor(range.startContainer); - let parent = tableNode?.parentElement; - if (tableNode) { const tableRect = tableNode.getBoundingClientRect(); const tableCenter = tableRect.left + tableRect.width / 2; @@ -90,18 +88,6 @@ export const TableMenu = ({ editor }: { editor: any }) => { const tableBottom = tableRect.bottom; setTableLocation({ bottom: tableBottom, left: menuLeft }); - - while (parent) { - if (!parent.classList.contains("disable-scroll")) - parent.classList.add("disable-scroll"); - parent = parent.parentElement; - } - } else { - const scrollDisabledContainers = document.querySelectorAll(".disable-scroll"); - - scrollDisabledContainers.forEach((container) => { - container.classList.remove("disable-scroll"); - }); } } }; @@ -115,13 +101,9 @@ export const TableMenu = ({ editor }: { editor: any }) => { return (
{items.map((item, index) => ( From 48c65c9c95385ec14121fca08da1467b241aebe9 Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Wed, 4 Oct 2023 18:44:36 +0530 Subject: [PATCH 20/30] fix: handle cross project issues in the sub-issues. (#2357) --- web/components/issues/sub-issues/issue.tsx | 25 +++++++++++++------ .../issues/sub-issues/issues-list.tsx | 3 --- web/components/issues/sub-issues/root.tsx | 11 -------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/web/components/issues/sub-issues/issue.tsx b/web/components/issues/sub-issues/issue.tsx index d9c6fd303..a53d18bb9 100644 --- a/web/components/issues/sub-issues/issue.tsx +++ b/web/components/issues/sub-issues/issue.tsx @@ -1,7 +1,8 @@ import React from "react"; // next imports -import Link from "next/link"; import { useRouter } from "next/router"; +// swr +import { mutate } from "swr"; // lucide icons import { ChevronDown, @@ -13,6 +14,7 @@ import { Loader, } from "lucide-react"; // components +import { IssuePeekOverview } from "components/issues/peek-overview"; import { SubIssuesRootList } from "./issues-list"; import { IssueProperty } from "./properties"; // ui @@ -20,6 +22,8 @@ import { Tooltip, CustomMenu } from "components/ui"; // types import { ICurrentUserResponse, IIssue } from "types"; import { ISubIssuesRootLoaders, ISubIssuesRootLoadersHandler } from "./root"; +// fetch keys +import { SUB_ISSUES } from "constants/fetch-keys"; export interface ISubIssues { workspaceSlug: string; @@ -38,7 +42,6 @@ export interface ISubIssues { issueId: string, issue?: IIssue | null ) => void; - setPeekParentId: (id: string) => void; } export const SubIssues: React.FC = ({ @@ -54,14 +57,12 @@ export const SubIssues: React.FC = ({ handleIssuesLoader, copyText, handleIssueCrudOperation, - setPeekParentId, }) => { const router = useRouter(); + const { query } = router; + const { peekIssue } = query as { peekIssue: string }; const openPeekOverview = (issue_id: string) => { - const { query } = router; - - setPeekParentId(parentIssue?.id); router.push({ pathname: router.pathname, query: { ...query, peekIssue: issue_id }, @@ -199,7 +200,17 @@ export const SubIssues: React.FC = ({ handleIssuesLoader={handleIssuesLoader} copyText={copyText} handleIssueCrudOperation={handleIssueCrudOperation} - setPeekParentId={setPeekParentId} + /> + )} + + {peekIssue && peekIssue === issue?.id && ( + + parentIssue && parentIssue?.id && mutate(SUB_ISSUES(parentIssue?.id)) + } + projectId={issue?.project ?? ""} + workspaceSlug={workspaceSlug ?? ""} + readOnly={!editable} /> )}
diff --git a/web/components/issues/sub-issues/issues-list.tsx b/web/components/issues/sub-issues/issues-list.tsx index a713d6fb8..9fc77992e 100644 --- a/web/components/issues/sub-issues/issues-list.tsx +++ b/web/components/issues/sub-issues/issues-list.tsx @@ -27,7 +27,6 @@ export interface ISubIssuesRootList { issueId: string, issue?: IIssue | null ) => void; - setPeekParentId: (id: string) => void; } export const SubIssuesRootList: React.FC = ({ @@ -42,7 +41,6 @@ export const SubIssuesRootList: React.FC = ({ handleIssuesLoader, copyText, handleIssueCrudOperation, - setPeekParentId, }) => { const { data: issues, isLoading } = useSWR( workspaceSlug && projectId && parentIssue && parentIssue?.id @@ -83,7 +81,6 @@ export const SubIssuesRootList: React.FC = ({ handleIssuesLoader={handleIssuesLoader} copyText={copyText} handleIssueCrudOperation={handleIssueCrudOperation} - setPeekParentId={setPeekParentId} /> ))} diff --git a/web/components/issues/sub-issues/root.tsx b/web/components/issues/sub-issues/root.tsx index 352546eab..4b29b97c9 100644 --- a/web/components/issues/sub-issues/root.tsx +++ b/web/components/issues/sub-issues/root.tsx @@ -10,7 +10,6 @@ import { ExistingIssuesListModal } from "components/core"; import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues"; import { SubIssuesRootList } from "./issues-list"; import { ProgressBar } from "./progressbar"; -import { IssuePeekOverview } from "components/issues/peek-overview"; // ui import { CustomMenu } from "components/ui"; // hooks @@ -60,8 +59,6 @@ export const SubIssuesRoot: React.FC = ({ parentIssue, user }) = : null ); - const [peekParentId, setPeekParentId] = React.useState(""); - const [issuesLoader, setIssuesLoader] = React.useState({ visibility: [parentIssue?.id], delete: [], @@ -237,7 +234,6 @@ export const SubIssuesRoot: React.FC = ({ parentIssue, user }) = handleIssuesLoader={handleIssuesLoader} copyText={copyText} handleIssueCrudOperation={handleIssueCrudOperation} - setPeekParentId={setPeekParentId} />
)} @@ -363,13 +359,6 @@ export const SubIssuesRoot: React.FC = ({ parentIssue, user }) = )} )} - - peekParentId && peekIssue && mutateSubIssues(peekParentId)} - projectId={projectId ?? ""} - workspaceSlug={workspaceSlug ?? ""} - readOnly={!isEditable} - />
); }; From ea2c1e2d060c597ceb0dcbcd4d2201a2a3c4c510 Mon Sep 17 00:00:00 2001 From: sriram veeraghanta Date: Wed, 4 Oct 2023 18:55:29 +0530 Subject: [PATCH 21/30] fix: login process validation based on api config (#2361) --- .../account/email-password-form.tsx | 163 +++++++----------- web/components/account/email-signup-form.tsx | 114 ++++++++++++ .../account/github-login-button.tsx | 16 +- web/components/account/google-login.tsx | 15 +- web/components/account/index.ts | 1 + web/pages/index.tsx | 94 ++++++---- web/pages/sign-up.tsx | 25 +-- web/services/app-config.service.ts | 30 ++++ 8 files changed, 283 insertions(+), 175 deletions(-) create mode 100644 web/components/account/email-signup-form.tsx create mode 100644 web/services/app-config.service.ts diff --git a/web/components/account/email-password-form.tsx b/web/components/account/email-password-form.tsx index bb341b371..7a95095ee 100644 --- a/web/components/account/email-password-form.tsx +++ b/web/components/account/email-password-form.tsx @@ -1,12 +1,5 @@ -import React, { useState } from "react"; - -import { useRouter } from "next/router"; -import Link from "next/link"; - -// react hook form +import React from "react"; import { useForm } from "react-hook-form"; -// components -import { EmailResetPasswordForm } from "components/account"; // ui import { Input, PrimaryButton } from "components/ui"; // types @@ -18,14 +11,12 @@ type EmailPasswordFormValues = { type Props = { onSubmit: (formData: EmailPasswordFormValues) => Promise; + setIsResettingPassword: (value: boolean) => void; }; -export const EmailPasswordForm: React.FC = ({ onSubmit }) => { - const [isResettingPassword, setIsResettingPassword] = useState(false); - - const router = useRouter(); - const isSignUpPage = router.pathname === "/sign-up"; - +export const EmailPasswordForm: React.FC = (props) => { + const { onSubmit, setIsResettingPassword } = props; + // form info const { register, handleSubmit, @@ -42,94 +33,62 @@ export const EmailPasswordForm: React.FC = ({ onSubmit }) => { return ( <> -

- {isResettingPassword - ? "Reset your password" - : isSignUpPage - ? "Sign up on Plane" - : "Sign in to Plane"} -

- {isResettingPassword ? ( - - ) : ( - -
- - /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test( - value - ) || "Email address is not valid", - }} - error={errors.email} - placeholder="Enter your email address..." - className="border-custom-border-300 h-[46px]" - /> -
-
- -
-
- {isSignUpPage ? ( - - - Already have an account? Sign in. - - - ) : ( - - )} -
-
- - {isSignUpPage - ? isSubmitting - ? "Signing up..." - : "Sign up" - : isSubmitting - ? "Signing in..." - : "Sign in"} - - {!isSignUpPage && ( - - - Don{"'"}t have an account? Sign up. - - - )} -
- - )} +
+
+ + /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test( + value + ) || "Email address is not valid", + }} + error={errors.email} + placeholder="Enter your email address..." + className="border-custom-border-300 h-[46px]" + /> +
+
+ +
+
+ +
+
+ + {isSubmitting ? "Signing in..." : "Sign in"} + +
+
); }; diff --git a/web/components/account/email-signup-form.tsx b/web/components/account/email-signup-form.tsx new file mode 100644 index 000000000..0a219741f --- /dev/null +++ b/web/components/account/email-signup-form.tsx @@ -0,0 +1,114 @@ +import React from "react"; +import Link from "next/link"; +import { useForm } from "react-hook-form"; +// ui +import { Input, PrimaryButton } from "components/ui"; +// types +type EmailPasswordFormValues = { + email: string; + password?: string; + confirm_password: string; + medium?: string; +}; + +type Props = { + onSubmit: (formData: EmailPasswordFormValues) => Promise; +}; + +export const EmailSignUpForm: React.FC = (props) => { + const { onSubmit } = props; + + const { + register, + handleSubmit, + watch, + formState: { errors, isSubmitting, isValid, isDirty }, + } = useForm({ + defaultValues: { + email: "", + password: "", + confirm_password: "", + medium: "email", + }, + mode: "onChange", + reValidateMode: "onChange", + }); + + return ( + <> +
+
+ + /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test( + value + ) || "Email address is not valid", + }} + error={errors.email} + placeholder="Enter your email address..." + className="border-custom-border-300 h-[46px]" + /> +
+
+ +
+
+ { + if (watch("password") != val) { + return "Your passwords do no match"; + } + }, + }} + error={errors.confirm_password} + placeholder="Confirm your password..." + className="border-custom-border-300 h-[46px]" + /> +
+ +
+ + {isSubmitting ? "Signing up..." : "Sign up"} + +
+
+ + ); +}; diff --git a/web/components/account/github-login-button.tsx b/web/components/account/github-login-button.tsx index 2f4fcbc4d..9ea5b7df2 100644 --- a/web/components/account/github-login-button.tsx +++ b/web/components/account/github-login-button.tsx @@ -1,29 +1,27 @@ import { useEffect, useState, FC } from "react"; - import Link from "next/link"; import Image from "next/image"; import { useRouter } from "next/router"; - -// next-themes import { useTheme } from "next-themes"; // images import githubBlackImage from "/public/logos/github-black.png"; import githubWhiteImage from "/public/logos/github-white.png"; -const { NEXT_PUBLIC_GITHUB_ID } = process.env; - export interface GithubLoginButtonProps { handleSignIn: React.Dispatch; + clientId: string; } -export const GithubLoginButton: FC = ({ handleSignIn }) => { +export const GithubLoginButton: FC = (props) => { + const { handleSignIn, clientId } = props; + // states const [loginCallBackURL, setLoginCallBackURL] = useState(undefined); const [gitCode, setGitCode] = useState(null); - + // router const { query: { code }, } = useRouter(); - + // theme const { theme } = useTheme(); useEffect(() => { @@ -42,7 +40,7 @@ export const GithubLoginButton: FC = ({ handleSignIn }) return (
diff --git a/space/services/app-config.service.ts b/space/services/app-config.service.ts new file mode 100644 index 000000000..713cda3da --- /dev/null +++ b/space/services/app-config.service.ts @@ -0,0 +1,30 @@ +// services +import APIService from "services/api.service"; +// helper +import { API_BASE_URL } from "helpers/common.helper"; + +export interface IEnvConfig { + github: string; + google: string; + github_app_name: string | null; + email_password_login: boolean; + magic_login: boolean; +} + +export class AppConfigService extends APIService { + constructor() { + super(API_BASE_URL); + } + + async envConfig(): Promise { + return this.get("/api/configs/", { + headers: { + "Content-Type": "application/json", + }, + }) + .then((response) => response?.data) + .catch((error) => { + throw error?.response?.data; + }); + } +} diff --git a/turbo.json b/turbo.json index b3c5e4d9f..e40a56ab7 100644 --- a/turbo.json +++ b/turbo.json @@ -1,8 +1,6 @@ { "$schema": "https://turbo.build/schema.json", "globalEnv": [ - "NEXT_PUBLIC_GITHUB_ID", - "NEXT_PUBLIC_GOOGLE_CLIENTID", "NEXT_PUBLIC_API_BASE_URL", "NEXT_PUBLIC_DEPLOY_URL", "API_BASE_URL", diff --git a/web/pages/index.tsx b/web/pages/index.tsx index ed98d29f6..1696f2fbc 100644 --- a/web/pages/index.tsx +++ b/web/pages/index.tsx @@ -85,11 +85,11 @@ const HomePage: NextPage = observer(() => { const handleGitHubSignIn = async (credential: string) => { try { - if (process.env.NEXT_PUBLIC_GITHUB_ID && credential) { + if (data && data.github && credential) { const socialAuthPayload = { medium: "github", credential, - clientId: process.env.NEXT_PUBLIC_GITHUB_ID, + clientId: data.github, }; const response = await authenticationService.socialAuth(socialAuthPayload); if (response && response?.user) { From 62035f3bad19209f52cf1df1552e636d268502db Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Thu, 5 Oct 2023 12:04:09 +0530 Subject: [PATCH 28/30] fix: added user store variables in mobx store observable (#2380) --- space/store/user.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/space/store/user.ts b/space/store/user.ts index cc7334e87..cec2d340f 100644 --- a/space/store/user.ts +++ b/space/store/user.ts @@ -27,6 +27,9 @@ class UserStore implements IUserStore { constructor(_rootStore: any) { makeObservable(this, { // observable + loader: observable.ref, + error: observable.ref, + currentUser: observable.ref, // actions setCurrentUser: action, From 85147db85faba7bd9bc812d2fb7fe6d577ca3bb2 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Thu, 5 Oct 2023 13:08:27 +0530 Subject: [PATCH 29/30] fix: state group icons (#2381) --- web/components/icons/state/backlog.tsx | 24 +++++++++++++++++--- web/components/icons/state/started.tsx | 31 +++++++++++++++++++++----- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/web/components/icons/state/backlog.tsx b/web/components/icons/state/backlog.tsx index b6378b82d..369692c20 100644 --- a/web/components/icons/state/backlog.tsx +++ b/web/components/icons/state/backlog.tsx @@ -15,10 +15,28 @@ export const StateGroupBacklogIcon: React.FC = ({ height={height} width={width} className={className} - viewBox="0 0 12 12" - fill="none" xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 323.15 323.03" > - + + + + + + + + ); diff --git a/web/components/icons/state/started.tsx b/web/components/icons/state/started.tsx index 7bc39f9f7..f4796548b 100644 --- a/web/components/icons/state/started.tsx +++ b/web/components/icons/state/started.tsx @@ -9,17 +9,38 @@ export const StateGroupStartedIcon: React.FC = ({ width = "20", height = "20", className, - color = "#f59e0b", + color = "#f39e1f", }) => ( - - + + + + + + + + + ); From 67922f9c5d82b325771dbd3ba1005413d0e657f2 Mon Sep 17 00:00:00 2001 From: guru_sainath Date: Thu, 5 Oct 2023 13:47:51 +0530 Subject: [PATCH 30/30] fix: removed default theme setting in the index page (#2382) * fix: removed default theme setting in the index page * fix: empty space --- web/pages/index.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/web/pages/index.tsx b/web/pages/index.tsx index 1696f2fbc..cccd32407 100644 --- a/web/pages/index.tsx +++ b/web/pages/index.tsx @@ -155,10 +155,6 @@ const HomePage: NextPage = observer(() => { } }; - useEffect(() => { - setTheme("system"); - }, [setTheme]); - return ( {isLoading ? (