frontend/backend: add ability to destroy an issue

This commit is contained in:
0x1eef 2023-12-22 09:48:47 -03:00
parent 8b4387443c
commit dc4482035d
5 changed files with 74 additions and 16 deletions

View file

@ -1,14 +1,15 @@
class Twenty::Servlet::Issues < Twenty::Servlet
##
# GET /servlet/issues/
# GET /servlet/issues/<id>/
def do_GET(req, res)
case req.path_info
when ""
# GET /servlet/issues/
issues = Twenty::Issue.open.order(updated_at: :desc)
Response.new(res)
.set_status(200)
.set_body(issues:)
when %r|^/([\d]+)/?$|
# GET /servlet/issues/<issue-id>/
issue = Twenty::Issue.find_by(id: $1)
if issue
Response.new(res)
@ -22,10 +23,11 @@ class Twenty::Servlet::Issues < Twenty::Servlet
end
end
##
# POST /servlet/issues/
def do_POST(req, res)
case req.path_info
when ""
# POST /servlet/issues/
issue = Twenty::Issue.new(JSON.parse(req.body))
if issue.save
Response.new(res)
@ -41,4 +43,22 @@ class Twenty::Servlet::Issues < Twenty::Servlet
Response.new(res).not_found
end
end
##
# DELETE /servlet/issues/<id>/
def do_DELETE(req, res)
case req.path_info
when %r|^/([\d]+)/?$|
issue = Twenty::Issue.find_by(id: $1)
if issue.destroy
Response.new(res)
.set_status(200)
.set_body({ok: true})
else
Response.new(res).not_found
end
else
Response.new(res).not_found
end
end
end

View file

@ -1,9 +1,13 @@
import React from "react";
import { useIssues } from "/hooks/useIssues";
import { useDestroyIssue } from "/hooks/useDestroyIssue";
import { DateTime } from "luxon";
import { Issue } from "/types/schema";
export function Issues() {
const [issues] = useIssues();
const { issues, refetch } = useIssues();
const destroyIssue = useDestroyIssue();
return (
<div className="pure-u-1-1 issue-index">
<div className="pure-u-5-5 issue-row">
@ -18,7 +22,7 @@ export function Issues() {
</div>
<hr />
<ul className="pure-u-5-5 issue-items">
{issues.map((issue, key) => {
{issues.map((issue: Issue, key: number) => {
const { updated_at: updatedAt } = issue;
const datetime = DateTime.fromISO(updatedAt);
return (
@ -30,6 +34,17 @@ export function Issues() {
{datetime.toFormat("dd LLL, yyyy")} at{" "}
{datetime.toFormat("HH:mm")}
</div>
<div>
<button
onClick={() =>
destroyIssue({ id: issue.id }).then(() => {
refetch();
})
}
>
Destroy
</button>
</div>
</li>
);
})}

View file

@ -54,11 +54,7 @@ export function NewIssue() {
/>
</div>
<div className="row">
<input
className="form"
type="submit"
value="Save"
/>
<input className="form" type="submit" value="Save" />
</div>
</form>
);

View file

@ -0,0 +1,15 @@
type Params = {
id: number;
};
export function useDestroyIssue() {
return function ({ id }: Params) {
return new Promise((accept, reject) => {
const req = { method: "DELETE" };
return fetch(`/servlet/issues/${id}`, req)
.then(res => res.json())
.then(accept)
.catch(reject);
});
};
}

View file

@ -1,14 +1,26 @@
import { useState, useEffect } from "react";
import { Issue } from "/types/schema";
export function useIssues() {
const [issues, setIssues] = useState<Issue[]>([]);
type Result = {
issues: Issue[];
refetch: () => Promise<Issue[]>;
};
export function useIssues(): Result {
const [issues, setIssues] = useState<Issue[]>([]);
const set = (ary: Issue[]) => {
setIssues(ary);
return ary;
};
const refetch = async function (): Promise<Issue[]> {
return await fetch("/servlet/issues")
.then((res: Response) => res.json())
.then((res: { issues: Issue[] }) => set(res.issues))
.catch(() => null);
};
useEffect(() => {
fetch("/servlet/issues")
.then(res => res.json())
.then(res => setIssues(res.issues));
refetch();
}, []);
return [issues];
return { issues, refetch };
}