hide create bot functionality in modal window
This commit is contained in:
parent
0b3c861057
commit
bb1f680d3b
4 changed files with 93 additions and 57 deletions
File diff suppressed because one or more lines are too long
2
cmd/telesrv-admin/web/dist/index.html
vendored
2
cmd/telesrv-admin/web/dist/index.html
vendored
|
|
@ -23,7 +23,7 @@
|
|||
})();
|
||||
</script>
|
||||
|
||||
<script type="module" crossorigin src="/assets/index-DZsC6sWi.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-CUbSxjdM.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-BpSP1ojC.css">
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
68
cmd/telesrv-admin/web/src/components/CreateBotModal.tsx
Normal file
68
cmd/telesrv-admin/web/src/components/CreateBotModal.tsx
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import { Plus, X } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { toInt } from "../lib/format";
|
||||
import { ActionButton } from "./ActionButton";
|
||||
|
||||
// CreateBotModal collects the new bot's fields, then hands off to ActionButton
|
||||
// for the usual reason/dry-run/confirm flow -- the token is shown once in
|
||||
// ActionButton's own result panel after confirmation.
|
||||
export function CreateBotModal({ onClose, onCreated }: { onClose: () => void; onCreated: () => void }) {
|
||||
const [ownerID, setOwnerID] = useState("");
|
||||
const [botName, setBotName] = useState("");
|
||||
const [botUsername, setBotUsername] = useState("");
|
||||
|
||||
return createPortal(
|
||||
<div className="modal-backdrop" role="presentation">
|
||||
<section className="modal command-modal" role="dialog" aria-modal="true" aria-label={"Create a system bot"}>
|
||||
<div className="modal-head">
|
||||
<div>
|
||||
<div className="eyebrow">{"Bots"}</div>
|
||||
<h2>{"Create a system bot"}</h2>
|
||||
</div>
|
||||
<button className="icon-btn" type="button" onClick={onClose} aria-label={"Close"}><X size={15} /></button>
|
||||
</div>
|
||||
<div className="command-body">
|
||||
<p>{"Provision a bot account owned by the given user. The token is shown once after confirmation."}</p>
|
||||
<div className="bot-create-fields">
|
||||
<label className="duration-field">
|
||||
<span>{"Owner user ID"}</span>
|
||||
<input
|
||||
value={ownerID}
|
||||
onChange={(event) => setOwnerID(event.target.value)}
|
||||
type="number"
|
||||
min="1"
|
||||
placeholder="123456789"
|
||||
/>
|
||||
</label>
|
||||
<label className="duration-field">
|
||||
<span>{"Display name"}</span>
|
||||
<input value={botName} onChange={(event) => setBotName(event.target.value)} placeholder={"e.g. Service Bot"} maxLength={64} />
|
||||
</label>
|
||||
<label className="duration-field">
|
||||
<span>{"Username"}</span>
|
||||
<input value={botUsername} onChange={(event) => setBotUsername(event.target.value)} placeholder="my_service_bot" />
|
||||
</label>
|
||||
</div>
|
||||
<span className="bot-create-note">{"Username must be 5-32 characters and end with 'bot'."}</span>
|
||||
</div>
|
||||
<div className="modal-actions">
|
||||
<button className="btn" type="button" onClick={onClose}>{"Close"}</button>
|
||||
<ActionButton
|
||||
label={"Create bot"}
|
||||
icon={<Plus size={15} />}
|
||||
tone="neutral"
|
||||
path="/api/actions/create-bot"
|
||||
payload={() => ({
|
||||
owner_user_id: toInt(ownerID),
|
||||
name: botName.trim(),
|
||||
username: botUsername.trim().replace(/^@/, "")
|
||||
})}
|
||||
onDone={onCreated}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</div>,
|
||||
document.body
|
||||
);
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import { BadgeCheck, Bot, ChevronLeft, ChevronRight, Loader2, Plus, RefreshCw, Search } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { api, errorMessage } from "../api";
|
||||
import { ActionButton } from "../components/ActionButton";
|
||||
import { Avatar } from "../components/Avatar";
|
||||
import { CreateBotModal } from "../components/CreateBotModal";
|
||||
import { Alert, Badge, EmptyRow, Metric, PageFrame, QueryPanel } from "../components/ui";
|
||||
import { ScamFakeBadges } from "../components/flags";
|
||||
import { displayUsername, formatDate, toInt } from "../lib/format";
|
||||
import { displayUsername, formatDate } from "../lib/format";
|
||||
import type { Navigate } from "../routing";
|
||||
import type { BotListResponse } from "../types";
|
||||
|
||||
|
|
@ -25,10 +25,7 @@ export function BotsPage({ navigate }: { navigate: Navigate }) {
|
|||
const [cursor, setCursor] = useState<Cursor>(zeroCursor);
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
|
||||
const [ownerID, setOwnerID] = useState("");
|
||||
const [botName, setBotName] = useState("");
|
||||
const [botUsername, setBotUsername] = useState("");
|
||||
const [createModalOpen, setCreateModalOpen] = useState(false);
|
||||
|
||||
async function fetchPage(query: string, at: Cursor) {
|
||||
setBusy(true);
|
||||
|
|
@ -94,9 +91,14 @@ export function BotsPage({ navigate }: { navigate: Navigate }) {
|
|||
title={"Bots"}
|
||||
eyebrow={data?.listing === false ? "Search results" : "Recently created bots"}
|
||||
actions={
|
||||
<button className="btn" type="button" onClick={() => void loadFresh()} disabled={busy}>
|
||||
<RefreshCw size={15} /> {"Refresh"}
|
||||
</button>
|
||||
<>
|
||||
<button className="btn primary icon-text" type="button" onClick={() => setCreateModalOpen(true)}>
|
||||
<Plus size={15} /> {"Create bot"}
|
||||
</button>
|
||||
<button className="btn" type="button" onClick={() => void loadFresh()} disabled={busy}>
|
||||
<RefreshCw size={15} /> {"Refresh"}
|
||||
</button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{error && <Alert>{error}</Alert>}
|
||||
|
|
@ -106,50 +108,6 @@ export function BotsPage({ navigate }: { navigate: Navigate }) {
|
|||
<Metric label={"System"} value={String(systemCount)} />
|
||||
</div>
|
||||
|
||||
<section className="section-block">
|
||||
<div className="section-head">
|
||||
<div>
|
||||
<h2>{"Create a system bot"}</h2>
|
||||
<p>{"Provision a bot account owned by the given user. The token is shown once after confirmation."}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bot-create-fields">
|
||||
<label className="duration-field">
|
||||
<span>{"Owner user ID"}</span>
|
||||
<input
|
||||
value={ownerID}
|
||||
onChange={(event) => setOwnerID(event.target.value)}
|
||||
type="number"
|
||||
min="1"
|
||||
placeholder="123456789"
|
||||
/>
|
||||
</label>
|
||||
<label className="duration-field">
|
||||
<span>{"Display name"}</span>
|
||||
<input value={botName} onChange={(event) => setBotName(event.target.value)} placeholder={"e.g. Service Bot"} maxLength={64} />
|
||||
</label>
|
||||
<label className="duration-field">
|
||||
<span>{"Username"}</span>
|
||||
<input value={botUsername} onChange={(event) => setBotUsername(event.target.value)} placeholder="my_service_bot" />
|
||||
</label>
|
||||
</div>
|
||||
<div className="bot-create-actions">
|
||||
<span className="bot-create-note">{"Username must be 5-32 characters and end with 'bot'."}</span>
|
||||
<ActionButton
|
||||
label={"Create bot"}
|
||||
icon={<Plus size={15} />}
|
||||
tone="neutral"
|
||||
path="/api/actions/create-bot"
|
||||
payload={() => ({
|
||||
owner_user_id: toInt(ownerID),
|
||||
name: botName.trim(),
|
||||
username: botUsername.trim().replace(/^@/, "")
|
||||
})}
|
||||
onDone={() => void loadFresh()}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<QueryPanel>
|
||||
<form className="toolbar" onSubmit={(event) => { event.preventDefault(); void loadFresh(); }}>
|
||||
<label className="searchbox">
|
||||
|
|
@ -210,6 +168,16 @@ export function BotsPage({ navigate }: { navigate: Navigate }) {
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{createModalOpen && (
|
||||
<CreateBotModal
|
||||
onClose={() => setCreateModalOpen(false)}
|
||||
onCreated={() => {
|
||||
setCreateModalOpen(false);
|
||||
void loadFresh();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</PageFrame>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue