fixes
This commit is contained in:
parent
21a0856587
commit
e8dc967e6a
26 changed files with 1373 additions and 481 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-CwTwvGWj.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-TfcI68oK.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-0MvM-hpw.css">
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export function App() {
|
|||
|
||||
return (
|
||||
<PermissionsProvider permissions={session.permissions ?? []} hideThirdPartyVerification={session.hide_third_party_verification ?? true}>
|
||||
<Shell actor={session.actor} build={session.build} route={route} navigate={navigate} onLogout={() => setSession(null)}>
|
||||
<Shell actor={session.actor} apiLayer={session.api_layer} build={session.build} route={route} navigate={navigate} onLogout={() => setSession(null)}>
|
||||
<Routes route={route} navigate={navigate} />
|
||||
</Shell>
|
||||
</PermissionsProvider>
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ import { MultiUserPicker } from "./EntityPicker";
|
|||
type TargetMode = "all" | "selected";
|
||||
|
||||
// CreateBroadcastModal composes the message and target list, then hands off to
|
||||
// ActionButton for the usual dry-run/confirm flow. "All users" is resolved to an
|
||||
// explicit id list server-side (cmd/telesrv-admin/server.go), not here -- the
|
||||
// picker only ever deals with an actual, visible list of accounts.
|
||||
// ActionButton for the usual dry-run/confirm flow. "All users" is never
|
||||
// resolved into an id list at all -- the admin service snapshots the
|
||||
// current eligible user set itself and a background worker enumerates it
|
||||
// incrementally, so this only ever sends user_ids for "selected" mode,
|
||||
// where the picker deals with an actual, visible list of accounts.
|
||||
export function CreateBroadcastModal({ onClose, onCreated }: { onClose: () => void; onCreated: () => void }) {
|
||||
const [message, setMessage] = useState("");
|
||||
const [targetMode, setTargetMode] = useState<TargetMode>("all");
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export function BootScreen() {
|
|||
|
||||
export function Shell({
|
||||
actor,
|
||||
apiLayer,
|
||||
build,
|
||||
route,
|
||||
navigate,
|
||||
|
|
@ -48,6 +49,7 @@ export function Shell({
|
|||
children
|
||||
}: {
|
||||
actor: string;
|
||||
apiLayer?: number;
|
||||
build?: { commit: string; short_commit: string; dirty: boolean; build_time: string };
|
||||
route: RouteState;
|
||||
navigate: Navigate;
|
||||
|
|
@ -178,6 +180,9 @@ export function Shell({
|
|||
</nav>
|
||||
<div className="sidebar-status">
|
||||
<span className="sidebar-label">{"Version: O7"}</span>
|
||||
{typeof apiLayer === "number" && (
|
||||
<span className="sidebar-label sidebar-api-layer">{`API layer: ${apiLayer}`}</span>
|
||||
)}
|
||||
{build?.short_commit && (
|
||||
<span className="sidebar-label sidebar-build" title={build.commit + (build.dirty ? " (uncommitted changes)" : "")}>
|
||||
{`Build: ${build.short_commit}${build.dirty ? "+" : ""}`}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ export function BroadcastsPage() {
|
|||
}, []);
|
||||
|
||||
const rows = data?.rows ?? [];
|
||||
const inFlight = rows.filter((row) => row.SentCount + row.FailedCount < row.TotalCount).length;
|
||||
const inFlight = rows.filter((row) => !row.EnumerationDone || row.SentCount + row.FailedCount < row.TargetCount).length;
|
||||
const canGoPrev = history.length > 0 && !busy;
|
||||
const canGoNext = Boolean(data?.has_more) && !busy;
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ export function BroadcastsPage() {
|
|||
<tbody>
|
||||
{rows.map((row) => {
|
||||
const delivered = row.SentCount + row.FailedCount;
|
||||
const done = row.TotalCount > 0 && delivered >= row.TotalCount;
|
||||
const done = row.EnumerationDone && row.TargetCount > 0 && delivered >= row.TargetCount;
|
||||
return (
|
||||
<tr key={row.ID}>
|
||||
<td className="mono">{row.ID}</td>
|
||||
|
|
@ -118,7 +118,7 @@ export function BroadcastsPage() {
|
|||
<td>{row.TargetMode === "all" ? <Badge tone="warn">{"All users"}</Badge> : <Badge>{"Selected"}</Badge>}</td>
|
||||
<td>{row.SentCount}</td>
|
||||
<td>{row.FailedCount > 0 ? <Badge tone="danger">{row.FailedCount}</Badge> : row.FailedCount}</td>
|
||||
<td>{row.TotalCount}</td>
|
||||
<td>{row.TargetCount}</td>
|
||||
<td>{row.CreatedBy || "-"}</td>
|
||||
<td>
|
||||
{formatDate(row.CreatedAt)}
|
||||
|
|
|
|||
|
|
@ -584,6 +584,9 @@ export type AdminSession = {
|
|||
// comment. Used by Server Settings' Restart/Update flow to detect a
|
||||
// genuinely new admin process after asking it to bounce.
|
||||
boot_id?: string;
|
||||
// The MTProto TL schema layer this server binary speaks -- shown in the
|
||||
// sidebar footer above the build/commit line.
|
||||
api_layer?: number;
|
||||
// This admin binary's own build -- shown under "Version" in the sidebar
|
||||
// footer so an operator can tell which build is actually running.
|
||||
build?: {
|
||||
|
|
@ -794,9 +797,11 @@ export type BroadcastRow = {
|
|||
ID: number;
|
||||
Message: string;
|
||||
TargetMode: string;
|
||||
TotalCount: number;
|
||||
TargetCount: number;
|
||||
MaterializedCount: number;
|
||||
SentCount: number;
|
||||
FailedCount: number;
|
||||
EnumerationDone: boolean;
|
||||
CreatedBy: string;
|
||||
CreatedAt: string;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue