Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ JIRA_LABELS=sites_BAU
JIRA_COPY_UPDATES_EPIC=KAN-1
GOOGLE_CREDENTIALS=googlecreds
GOOGLE_DRIVE_FOLDER_ID=googlecreds
COPYD0C_TEMPLATE_ID=googlecreds
COPYDOC_TEMPLATE_ID=googlecreds
GOOGLE_PRIVATE_KEY=base64encodedprivatekey
GOOGLE_PRIVATE_KEY_ID=privatekeyid
3 changes: 2 additions & 1 deletion static/client/components/Navigation/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import NavigationItems from "./NavigationItems";

import NavigationCollapseToggle from "@/components/Navigation/NavigationCollapseToggle";
import SiteSelector from "@/components/SiteSelector";
import type { IUser } from "@/services/api/types/users";
import { useStore } from "@/store";

const Navigation = (): JSX.Element => {
Expand All @@ -17,7 +18,7 @@ const Navigation = (): JSX.Element => {
const [user, setUser] = useStore((state) => [state.user, state.setUser]);

const logout = useCallback(() => {
setUser(null);
setUser({} as IUser);
window.open("/logout", "_self");
}, [setUser]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ export interface IUseUsersRequest {
setOptions: Dispatch<SetStateAction<IUser[]>>;
handleChange: (event: ChangeEvent<HTMLInputElement>) => void;
}

export interface IReporterProps {
reporter: IUser | null;
setReporter: React.Dispatch<React.SetStateAction<IUser>>;
}
42 changes: 42 additions & 0 deletions static/client/components/OwnerAndReviewers/Reporter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useCallback } from "react";

import CustomSearchAndFilter from "./CustomSearchAndFilter";
import { useUsersRequest } from "./OwnerAndReviewers.hooks";
import type { IReporterProps } from "./OwnerAndReviewers.types";

import { type IUser } from "@/services/api/types/users";
import { useStore } from "@/store";

const Reporter = ({ reporter, setReporter }: IReporterProps): JSX.Element => {
const user = useStore((state) => state.user);
const { options, setOptions, handleChange } = useUsersRequest();

const handleRemoveReporter = useCallback(
() => () => {
setReporter(user);
},
[setReporter, user],
);

const handleSelectReporter = useCallback(
(option: IUser) => {
setOptions([]);
setReporter(option);
},
[setOptions, setReporter],
);

return (
<CustomSearchAndFilter
label="Reporter"
onChange={handleChange}
onRemove={handleRemoveReporter}
onSelect={handleSelectReporter}
options={options}
placeholder="Select a reporter"
selectedOptions={reporter ? [reporter] : []}
/>
);
};

export default Reporter;
13 changes: 10 additions & 3 deletions static/client/components/RequestTaskModal/RequestTaskModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import { Button, Input, Modal, RadioInput, Spinner, Textarea, Tooltip } from "@c

import type { IRequestTaskModalProps } from "./RequestTaskModal.types";

import Reporter from "@/components/OwnerAndReviewers/Reporter";
import config from "@/config";
import { PagesServices } from "@/services/api/services/pages";
import { ChangeRequestType, PageStatus } from "@/services/api/types/pages";
import { DatesServices } from "@/services/dates";
import { useStore } from "@/store";

const RequestTaskModal = ({
changeType,
Expand All @@ -21,6 +23,8 @@ const RequestTaskModal = ({
const [summary, setSummary] = useState<string>();
const [descr, setDescr] = useState("");
const [isLoading, setIsLoading] = useState(false);
const user = useStore((state) => state.user);
const [reporter, setReporter] = useState(user);

const handleChangeDueDate = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setDueDate(e.target.value);
Expand Down Expand Up @@ -52,7 +56,7 @@ const RequestTaskModal = ({
PagesServices.requestRemoval({
due_date: dueDate,
webpage_id: webpage.id,
reporter_id: webpage.owner.id,
reporter_struct: reporter,
description: descr,
}).then(() => {
setIsLoading(false);
Expand All @@ -67,7 +71,7 @@ const RequestTaskModal = ({
PagesServices.requestChanges({
due_date: dueDate,
webpage_id: webpage.id,
reporter_id: webpage.owner.id,
reporter_struct: reporter,
type: changeType,
summary,
description: `Copy doc link: ${webpage.copy_doc_link} \n${descr}`,
Expand All @@ -78,7 +82,7 @@ const RequestTaskModal = ({
});
}
}
}, [changeType, dueDate, summary, descr, webpage, onClose]);
}, [dueDate, webpage.id, webpage.status, webpage.copy_doc_link, changeType, reporter, descr, onClose, summary]);

const title = useMemo(() => {
switch (changeType) {
Expand Down Expand Up @@ -176,6 +180,9 @@ const RequestTaskModal = ({
</div>
</>
)}
<div className="u-sv3">
<Reporter reporter={reporter} setReporter={setReporter} />
</div>
<Input label="Due date" min={DatesServices.getNowStr()} onChange={handleChangeDueDate} required type="date" />
<Input label="Summary" onChange={handleSummaryChange} type="text" />
<Textarea label="Description" onChange={handleDescrChange} />
Expand Down
2 changes: 1 addition & 1 deletion static/client/pages/NewWebpage/NewWebpage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const NewWebpage = (): JSX.Element => {
if (isNewPageExist) {
// TODO: there is a max depth React error on this line, needs more investigation
setSelectedProject(project);
window.location.href = `/webpage/${project.name}${location}/${titleValue}`;
window.location.href = `/app/webpage/${project.name}${location}/${titleValue}`;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion static/client/services/api/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const ENDPOINTS = {
setReviewers: "/api/set-reviewers",
createNewPage: "/api/create-page",
requestChanges: "/api/request-changes",
requestRemoval: "/api/remove-webpage",
requestRemoval: "/api/request-removal",
currentUser: "/api/current-user",
};

Expand Down
4 changes: 2 additions & 2 deletions static/client/services/api/types/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const ChangeRequestType = {

export interface IRequestChanges {
due_date: string;
reporter_id: number;
reporter_struct: IUser;
webpage_id: number;
type: (typeof ChangeRequestType)[keyof typeof ChangeRequestType];
summary?: string;
Expand All @@ -66,7 +66,7 @@ export interface IRequestChanges {

export interface IRequestRemoval {
due_date: string;
reporter_id: number;
reporter_struct: IUser;
webpage_id: number;
description: string;
}
4 changes: 3 additions & 1 deletion static/client/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { devtools, persist } from "zustand/middleware";

import type { IStore } from "./types";

import type { IUser } from "@/services/api/types/users";

export const useStore = create<IStore>()(
devtools(
persist(
(set) => ({
selectedProject: null,
user: null,
user: {} as IUser,
setSelectedProject: (s) => set({ selectedProject: s }),
setUser: (u) => set({ user: u }),
}),
Expand Down
4 changes: 2 additions & 2 deletions static/client/store/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type IUser } from "@/services/api/types/users";

export interface IStore {
selectedProject: IPagesResponse["data"] | null;
user: IUser | null;
user: IUser;
setSelectedProject: (s: IPagesResponse["data"]) => void;
setUser: (u: IUser | null) => void;
setUser: (u: IUser) => void;
}
7 changes: 4 additions & 3 deletions webapp/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def create_jira_task(app, body):

# Get the webpage
webpage_id = body["webpage_id"]
reporter_id = get_or_create_user_id(body.get("reporter_struct"))
webpage = Webpage.query.filter_by(id=webpage_id).first()
if not webpage:
raise Exception(f"Webpage with ID {webpage_id} not found")
Expand All @@ -57,7 +58,7 @@ def create_jira_task(app, body):
jira = app.config["JIRA"]
issue = jira.create_issue(
due_date=body["due_date"],
reporter_id=body["reporter_id"],
reporter_id=reporter_id,
request_type=body["type"],
description=body["description"],
summary=summary,
Expand All @@ -69,7 +70,7 @@ def create_jira_task(app, body):
JiraTask,
jira_id=issue["key"],
webpage_id=body["webpage_id"],
user_id=body["reporter_id"],
user_id=reporter_id,
summary=summary,
)

Expand Down Expand Up @@ -162,7 +163,7 @@ def convert_webpage_to_dict(webpage, owner, project):
else:
jira_tasks_list = []

# Serialize product fields
# Serialize product fields
if webpage_products:
webpage_products_list = []
for product in webpage_products:
Expand Down
10 changes: 6 additions & 4 deletions webapp/routes/jira.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def get_jira_tasks(webpage_id: int):
return jsonify({"error": "Failed to fetch Jira tasks"}), 500


@jira_blueprint.route("/remove-webpage", methods=["POST"])
@jira_blueprint.route("/request-removal", methods=["POST"])
@validate()
@login_required
def remove_webpage(body: RemoveWebpageModel):
Expand Down Expand Up @@ -110,6 +110,9 @@ def remove_webpage(body: RemoveWebpageModel):
webpage = Webpage.query.filter(Webpage.id == webpage_id).one_or_none()
if webpage is None:
return jsonify({"error": "webpage not found"}), 404

reporter_id = get_or_create_user_id(body.reporter_struct)

if webpage.status == WebpageStatus.NEW:
try:
jira_tasks = JiraTask.query.filter_by(webpage_id=webpage_id).all()
Expand Down Expand Up @@ -151,8 +154,7 @@ def remove_webpage(body: RemoveWebpageModel):

if webpage.status == WebpageStatus.AVAILABLE:
if not (
body.reporter_id
and User.query.filter_by(id=body.reporter_id).one_or_none()
reporter_id and User.query.filter_by(id=reporter_id).one_or_none()
):
return (
jsonify({"error": "provided parameters are incorrect"}),
Expand All @@ -161,7 +163,7 @@ def remove_webpage(body: RemoveWebpageModel):
task_details = {
"webpage_id": webpage_id,
"due_date": body.due_date,
"reporter_id": body.reporter_id,
"reporter_struct": body.reporter_struct,
"description": body.description,
"type": None,
"summary": f"Remove {webpage.name} webpage from code repository",
Expand Down
4 changes: 2 additions & 2 deletions webapp/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def wrapper(*args, **kwargs):

class ChangesRequestModel(BaseModel):
due_date: str
reporter_id: int
reporter_struct: object
webpage_id: int
type: int
description: str
Expand All @@ -31,7 +31,7 @@ class ChangesRequestModel(BaseModel):
class RemoveWebpageModel(BaseModel):
webpage_id: int
due_date: str = ""
reporter_id: int = None
reporter_struct: object = {}
description: str = ""

@field_validator("due_date")
Expand Down
Loading