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

View file

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

View file

@ -54,11 +54,7 @@ export function NewIssue() {
/> />
</div> </div>
<div className="row"> <div className="row">
<input <input className="form" type="submit" value="Save" />
className="form"
type="submit"
value="Save"
/>
</div> </div>
</form> </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 { useState, useEffect } from "react";
import { Issue } from "/types/schema"; import { Issue } from "/types/schema";
export function useIssues() { type Result = {
const [issues, setIssues] = useState<Issue[]>([]); 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(() => { useEffect(() => {
fetch("/servlet/issues") refetch();
.then(res => res.json())
.then(res => setIssues(res.issues));
}, []); }, []);
return [issues]; return { issues, refetch };
} }