Skip to content

Commit 4566d6e

Browse files
Merge pull request #3697 from makeplane/preview
release: 0.15.4-dev
2 parents e8d359e + bbbd704 commit 4566d6e

File tree

42 files changed

+704
-328
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+704
-328
lines changed

.github/workflows/build-branch.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
- id: set_env_variables
2929
name: Set Environment Variables
3030
run: |
31-
if [ "${{ env.TARGET_BRANCH }}" == "master" ]; then
31+
if [ "${{ env.TARGET_BRANCH }}" == "master" ] || [ "${{ github.event_name }}" == "release" ]; then
3232
echo "BUILDX_DRIVER=cloud" >> $GITHUB_OUTPUT
3333
echo "BUILDX_VERSION=lab:latest" >> $GITHUB_OUTPUT
3434
echo "BUILDX_PLATFORMS=linux/amd64,linux/arm64" >> $GITHUB_OUTPUT

apiserver/plane/app/views/inbox.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
InboxSerializer,
2828
InboxIssueSerializer,
2929
IssueCreateSerializer,
30-
IssueStateInboxSerializer,
30+
IssueDetailSerializer,
3131
)
3232
from plane.utils.issue_filters import issue_filters
3333
from plane.bgtasks.issue_activites_task import issue_activity
@@ -333,7 +333,7 @@ def partial_update(self, request, slug, project_id, inbox_id, issue_id):
333333

334334
def retrieve(self, request, slug, project_id, inbox_id, issue_id):
335335
issue = self.get_queryset().filter(pk=issue_id).first()
336-
serializer = IssueSerializer(issue, expand=self.expand,)
336+
serializer = IssueDetailSerializer(issue, expand=self.expand,)
337337
return Response(serializer.data, status=status.HTTP_200_OK)
338338

339339
def destroy(self, request, slug, project_id, inbox_id, issue_id):

apiserver/plane/app/views/issue.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,13 +1209,13 @@ def list(self, request, slug, project_id):
12091209
return Response(issues, status=status.HTTP_200_OK)
12101210

12111211
def retrieve(self, request, slug, project_id, pk=None):
1212-
issue = Issue.objects.get(
1213-
workspace__slug=slug,
1214-
project_id=project_id,
1215-
archived_at__isnull=False,
1216-
pk=pk,
1212+
issue = self.get_queryset().filter(pk=pk).first()
1213+
return Response(
1214+
IssueDetailSerializer(
1215+
issue, fields=self.fields, expand=self.expand
1216+
).data,
1217+
status=status.HTTP_200_OK,
12171218
)
1218-
return Response(IssueSerializer(issue).data, status=status.HTTP_200_OK)
12191219

12201220
def unarchive(self, request, slug, project_id, pk=None):
12211221
issue = Issue.objects.get(

packages/editor/rich-text-editor/src/ui/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { EditorBubbleMenu } from "src/ui/menus/bubble-menu";
1515

1616
export type IRichTextEditor = {
1717
value: string;
18+
initialValue?: string;
1819
dragDropEnabled?: boolean;
1920
uploadFile: UploadImage;
2021
restoreFile: RestoreImage;
@@ -54,6 +55,7 @@ const RichTextEditor = ({
5455
setShouldShowAlert,
5556
editorContentCustomClassNames,
5657
value,
58+
initialValue,
5759
uploadFile,
5860
deleteFile,
5961
noBorder,
@@ -97,6 +99,10 @@ const RichTextEditor = ({
9799
customClassName,
98100
});
99101

102+
React.useEffect(() => {
103+
if (editor && initialValue && editor.getHTML() != initialValue) editor.commands.setContent(initialValue);
104+
}, [editor, initialValue]);
105+
100106
if (!editor) return null;
101107

102108
return (

web/components/core/theme/custom-theme-selector.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ export const CustomThemeSelector: React.FC = observer(() => {
6666

6767
const handleValueChange = (val: string | undefined, onChange: any) => {
6868
let hex = val;
69-
7069
// prepend a hashtag if it doesn't exist
7170
if (val && val[0] !== "#") hex = `#${val}`;
7271

@@ -94,7 +93,7 @@ export const CustomThemeSelector: React.FC = observer(() => {
9493
placeholder="#0d101b"
9594
className="w-full"
9695
style={{
97-
backgroundColor: value,
96+
backgroundColor: watch("background"),
9897
color: watch("text"),
9998
}}
10099
hasError={Boolean(errors?.background)}
@@ -120,8 +119,8 @@ export const CustomThemeSelector: React.FC = observer(() => {
120119
placeholder="#c5c5c5"
121120
className="w-full"
122121
style={{
123-
backgroundColor: watch("background"),
124-
color: value,
122+
backgroundColor: watch("text"),
123+
color: watch("background"),
125124
}}
126125
hasError={Boolean(errors?.text)}
127126
/>
@@ -146,7 +145,7 @@ export const CustomThemeSelector: React.FC = observer(() => {
146145
placeholder="#3f76ff"
147146
className="w-full"
148147
style={{
149-
backgroundColor: value,
148+
backgroundColor: watch("primary"),
150149
color: watch("text"),
151150
}}
152151
hasError={Boolean(errors?.primary)}
@@ -172,7 +171,7 @@ export const CustomThemeSelector: React.FC = observer(() => {
172171
placeholder="#0d101b"
173172
className="w-full"
174173
style={{
175-
backgroundColor: value,
174+
backgroundColor: watch("sidebarBackground"),
176175
color: watch("sidebarText"),
177176
}}
178177
hasError={Boolean(errors?.sidebarBackground)}
@@ -200,8 +199,8 @@ export const CustomThemeSelector: React.FC = observer(() => {
200199
placeholder="#c5c5c5"
201200
className="w-full"
202201
style={{
203-
backgroundColor: watch("sidebarBackground"),
204-
color: value,
202+
backgroundColor: watch("sidebarText"),
203+
color: watch("sidebarBackground"),
205204
}}
206205
hasError={Boolean(errors?.sidebarText)}
207206
/>

web/components/dropdowns/cycle.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
6161
const [isOpen, setIsOpen] = useState(false);
6262
// refs
6363
const dropdownRef = useRef<HTMLDivElement | null>(null);
64+
const inputRef = useRef<HTMLInputElement | null>(null);
6465
// popper-js refs
6566
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
6667
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
@@ -111,23 +112,15 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
111112
const filteredOptions =
112113
query === "" ? options : options?.filter((o) => o.query.toLowerCase().includes(query.toLowerCase()));
113114

114-
// fetch cycles of the project if not already present in the store
115-
useEffect(() => {
116-
if (!workspaceSlug) return;
117-
118-
if (!cycleIds) fetchAllCycles(workspaceSlug, projectId);
119-
}, [cycleIds, fetchAllCycles, projectId, workspaceSlug]);
120-
121115
const selectedCycle = value ? getCycleById(value) : null;
122116

123117
const onOpen = () => {
124-
if (referenceElement) referenceElement.focus();
118+
if (workspaceSlug && !cycleIds) fetchAllCycles(workspaceSlug, projectId);
125119
};
126120

127121
const handleClose = () => {
128122
if (!isOpen) return;
129123
setIsOpen(false);
130-
if (referenceElement) referenceElement.blur();
131124
onClose && onClose();
132125
};
133126

@@ -151,6 +144,12 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
151144

152145
useOutsideClickDetector(dropdownRef, handleClose);
153146

147+
useEffect(() => {
148+
if (isOpen && inputRef.current) {
149+
inputRef.current.focus();
150+
}
151+
}, [isOpen]);
152+
154153
return (
155154
<Combobox
156155
as="div"
@@ -216,6 +215,8 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
216215
<div className="flex items-center gap-1.5 rounded border border-custom-border-100 bg-custom-background-90 px-2">
217216
<Search className="h-3.5 w-3.5 text-custom-text-400" strokeWidth={1.5} />
218217
<Combobox.Input
218+
as="input"
219+
ref={inputRef}
219220
className="w-full bg-transparent py-1 text-xs text-custom-text-200 placeholder:text-custom-text-400 focus:outline-none"
220221
value={query}
221222
onChange={(e) => setQuery(e.target.value)}

web/components/dropdowns/estimate.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Fragment, ReactNode, useRef, useState } from "react";
1+
import { Fragment, ReactNode, useEffect, useRef, useState } from "react";
22
import { observer } from "mobx-react-lite";
33
import { Combobox } from "@headlessui/react";
44
import { usePopper } from "react-popper";
@@ -60,6 +60,7 @@ export const EstimateDropdown: React.FC<Props> = observer((props) => {
6060
const [isOpen, setIsOpen] = useState(false);
6161
// refs
6262
const dropdownRef = useRef<HTMLDivElement | null>(null);
63+
const inputRef = useRef<HTMLInputElement | null>(null);
6364
// popper-js refs
6465
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
6566
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
@@ -110,13 +111,11 @@ export const EstimateDropdown: React.FC<Props> = observer((props) => {
110111

111112
const onOpen = () => {
112113
if (!activeEstimate && workspaceSlug) fetchProjectEstimates(workspaceSlug, projectId);
113-
if (referenceElement) referenceElement.focus();
114114
};
115115

116116
const handleClose = () => {
117117
if (!isOpen) return;
118118
setIsOpen(false);
119-
if (referenceElement) referenceElement.blur();
120119
onClose && onClose();
121120
};
122121

@@ -140,6 +139,12 @@ export const EstimateDropdown: React.FC<Props> = observer((props) => {
140139

141140
useOutsideClickDetector(dropdownRef, handleClose);
142141

142+
useEffect(() => {
143+
if (isOpen && inputRef.current) {
144+
inputRef.current.focus();
145+
}
146+
}, [isOpen]);
147+
143148
return (
144149
<Combobox
145150
as="div"
@@ -205,6 +210,8 @@ export const EstimateDropdown: React.FC<Props> = observer((props) => {
205210
<div className="flex items-center gap-1.5 rounded border border-custom-border-100 bg-custom-background-90 px-2">
206211
<Search className="h-3.5 w-3.5 text-custom-text-400" strokeWidth={1.5} />
207212
<Combobox.Input
213+
as="input"
214+
ref={inputRef}
208215
className="w-full bg-transparent py-1 text-xs text-custom-text-200 placeholder:text-custom-text-400 focus:outline-none"
209216
value={query}
210217
onChange={(e) => setQuery(e.target.value)}

web/components/dropdowns/member/project-member.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Fragment, useRef, useState } from "react";
1+
import { Fragment, useEffect, useRef, useState } from "react";
22
import { observer } from "mobx-react-lite";
33
import { Combobox } from "@headlessui/react";
44
import { usePopper } from "react-popper";
@@ -50,6 +50,7 @@ export const ProjectMemberDropdown: React.FC<Props> = observer((props) => {
5050
const [isOpen, setIsOpen] = useState(false);
5151
// refs
5252
const dropdownRef = useRef<HTMLDivElement | null>(null);
53+
const inputRef = useRef<HTMLInputElement | null>(null);
5354
// popper-js refs
5455
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
5556
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
@@ -103,13 +104,11 @@ export const ProjectMemberDropdown: React.FC<Props> = observer((props) => {
103104

104105
const onOpen = () => {
105106
if (!projectMemberIds && workspaceSlug) fetchProjectMembers(workspaceSlug, projectId);
106-
if (referenceElement) referenceElement.focus();
107107
};
108108

109109
const handleClose = () => {
110110
if (!isOpen) return;
111111
setIsOpen(false);
112-
if (referenceElement) referenceElement.blur();
113112
onClose && onClose();
114113
};
115114

@@ -133,6 +132,12 @@ export const ProjectMemberDropdown: React.FC<Props> = observer((props) => {
133132

134133
useOutsideClickDetector(dropdownRef, handleClose);
135134

135+
useEffect(() => {
136+
if (isOpen && inputRef.current) {
137+
inputRef.current.focus();
138+
}
139+
}, [isOpen]);
140+
136141
return (
137142
<Combobox
138143
as="div"
@@ -203,6 +208,8 @@ export const ProjectMemberDropdown: React.FC<Props> = observer((props) => {
203208
<div className="flex items-center gap-1.5 rounded border border-custom-border-100 bg-custom-background-90 px-2">
204209
<Search className="h-3.5 w-3.5 text-custom-text-400" strokeWidth={1.5} />
205210
<Combobox.Input
211+
as="input"
212+
ref={inputRef}
206213
className="w-full bg-transparent py-1 text-xs text-custom-text-200 placeholder:text-custom-text-400 focus:outline-none"
207214
value={query}
208215
onChange={(e) => setQuery(e.target.value)}

web/components/dropdowns/member/workspace-member.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Fragment, useRef, useState } from "react";
1+
import { Fragment, useEffect, useRef, useState } from "react";
22
import { observer } from "mobx-react-lite";
33
import { Combobox } from "@headlessui/react";
44
import { usePopper } from "react-popper";
@@ -44,6 +44,7 @@ export const WorkspaceMemberDropdown: React.FC<MemberDropdownProps> = observer((
4444
const [isOpen, setIsOpen] = useState<boolean>(false);
4545
// refs
4646
const dropdownRef = useRef<HTMLDivElement | null>(null);
47+
const inputRef = useRef<HTMLInputElement | null>(null);
4748
// popper-js refs
4849
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
4950
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
@@ -91,19 +92,13 @@ export const WorkspaceMemberDropdown: React.FC<MemberDropdownProps> = observer((
9192
};
9293
if (multiple) comboboxProps.multiple = true;
9394

94-
const onOpen = () => {
95-
if (referenceElement) referenceElement.focus();
96-
};
97-
9895
const handleClose = () => {
9996
if (!isOpen) return;
10097
setIsOpen(false);
101-
if (referenceElement) referenceElement.blur();
10298
onClose && onClose();
10399
};
104100

105101
const toggleDropdown = () => {
106-
if (!isOpen) onOpen();
107102
setIsOpen((prevIsOpen) => !prevIsOpen);
108103
};
109104

@@ -122,6 +117,12 @@ export const WorkspaceMemberDropdown: React.FC<MemberDropdownProps> = observer((
122117

123118
useOutsideClickDetector(dropdownRef, handleClose);
124119

120+
useEffect(() => {
121+
if (isOpen && inputRef.current) {
122+
inputRef.current.focus();
123+
}
124+
}, [isOpen]);
125+
125126
return (
126127
<Combobox
127128
as="div"
@@ -192,6 +193,8 @@ export const WorkspaceMemberDropdown: React.FC<MemberDropdownProps> = observer((
192193
<div className="flex items-center gap-1.5 rounded border border-custom-border-100 bg-custom-background-90 px-2">
193194
<Search className="h-3.5 w-3.5 text-custom-text-400" strokeWidth={1.5} />
194195
<Combobox.Input
196+
as="input"
197+
ref={inputRef}
195198
className="w-full bg-transparent py-1 text-xs text-custom-text-200 placeholder:text-custom-text-400 focus:outline-none"
196199
value={query}
197200
onChange={(e) => setQuery(e.target.value)}

web/components/dropdowns/module.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
166166
const [isOpen, setIsOpen] = useState(false);
167167
// refs
168168
const dropdownRef = useRef<HTMLDivElement | null>(null);
169+
const inputRef = useRef<HTMLInputElement | null>(null);
169170
// popper-js refs
170171
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
171172
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
@@ -216,21 +217,13 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
216217
const filteredOptions =
217218
query === "" ? options : options?.filter((o) => o.query.toLowerCase().includes(query.toLowerCase()));
218219

219-
// fetch modules of the project if not already present in the store
220-
useEffect(() => {
221-
if (!workspaceSlug) return;
222-
223-
if (!moduleIds) fetchModules(workspaceSlug, projectId);
224-
}, [moduleIds, fetchModules, projectId, workspaceSlug]);
225-
226220
const onOpen = () => {
227-
if (referenceElement) referenceElement.focus();
221+
if (!moduleIds && workspaceSlug) fetchModules(workspaceSlug, projectId);
228222
};
229223

230224
const handleClose = () => {
231225
if (!isOpen) return;
232226
setIsOpen(false);
233-
if (referenceElement) referenceElement.blur();
234227
onClose && onClose();
235228
};
236229

@@ -261,6 +254,12 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
261254
};
262255
if (multiple) comboboxProps.multiple = true;
263256

257+
useEffect(() => {
258+
if (isOpen && inputRef.current) {
259+
inputRef.current.focus();
260+
}
261+
}, [isOpen]);
262+
264263
return (
265264
<Combobox
266265
as="div"
@@ -331,6 +330,8 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
331330
<div className="flex items-center gap-1.5 rounded border border-custom-border-100 bg-custom-background-90 px-2">
332331
<Search className="h-3.5 w-3.5 text-custom-text-400" strokeWidth={1.5} />
333332
<Combobox.Input
333+
as="input"
334+
ref={inputRef}
334335
className="w-full bg-transparent py-1 text-xs text-custom-text-200 placeholder:text-custom-text-400 focus:outline-none"
335336
value={query}
336337
onChange={(e) => setQuery(e.target.value)}

0 commit comments

Comments
 (0)