frontend/backend: add ability to destroy an issue
This commit is contained in:
parent
8b4387443c
commit
dc4482035d
5 changed files with 74 additions and 16 deletions
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
15
twenty-frontend/src/js/hooks/useDestroyIssue.ts
Normal file
15
twenty-frontend/src/js/hooks/useDestroyIssue.ts
Normal 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);
|
||||
});
|
||||
};
|
||||
}
|
|
@ -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 };
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue