Admin → Rust zone presets: named sets of ZoneManager flags and settings for one server, several, or every server (D195), ticked in groups read from each server's own ZoneManager list in its last hello (D211). A flag not on a covered server is refused on save with the server named; two presets of one name may not share a server. rust.zone.open gains options (one line, NoBuild, radiation=10), enterMessage, leaveMessage, delivery, dome and domeStack. The options field's dropdown is rust.options.zone_presets, whose row VALUE is the preset's line, so picking one copies it into the step (D210) and no published event changes when a preset does. The line and the dome are checked against the server's hello on save and in a dry run; bad-option and dome-unavailable are permanent. Schema: rust_zone_presets, rust_zone_preset_servers. Swagger fragment and routes.manifest regenerated against the pinned core f0e7d2a. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
127 lines
4.1 KiB
JavaScript
127 lines
4.1 KiB
JavaScript
// ── The nav glyph for this module's player-portal row ─────────────────────
|
|
//
|
|
// `icon` is part of the nav-item contract (MODULE_API.md §3.3, 1.3.0): core
|
|
// renders whatever component a row carries, exactly as it renders its own rows'
|
|
// icons — and core's player portal draws a glyph on every row, so a row without
|
|
// one reads as breakage rather than as a design. The client suite asserts it.
|
|
//
|
|
// The public header is text buttons and carries no icons, which is why this file
|
|
// arrives with the player row and not before it.
|
|
//
|
|
// **The frame is copied from core's `PlayerPortalLayout`, deliberately and by
|
|
// copy rather than by import** — 16px, `currentColor`, stroke 2. Four attributes
|
|
// of presentation are not a component: putting them in the shared kit would
|
|
// freeze core's icon sizing into the contract, where changing it later would be a
|
|
// major bump. A module that wants to look like the nav it is in matches that nav.
|
|
|
|
const Icon = ({ children }) => (
|
|
<svg
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
aria-hidden="true"
|
|
focusable="false"
|
|
>
|
|
{children}
|
|
</svg>
|
|
)
|
|
|
|
/**
|
|
* A chain link — what the row is for.
|
|
*
|
|
* Not a gem, a person or a server: the portal's rows say what a player does
|
|
* there, and what a player does at `/player/rust` is link an account. Core's own
|
|
* neighbours are a gear (account), a shield (appeals) and a bell (notifications),
|
|
* so the row has to read as a verb in that company.
|
|
*/
|
|
export const IconLink = () => (
|
|
<Icon>
|
|
<path d="M10 13a5 5 0 007.07 0l2.83-2.83a5 5 0 00-7.07-7.07L11.5 4.5" />
|
|
<path d="M14 11a5 5 0 00-7.07 0L4.1 13.83a5 5 0 007.07 7.07L12.5 19.5" />
|
|
</Icon>
|
|
)
|
|
|
|
/**
|
|
* A key — the admin sidebar's row for the permission mirror.
|
|
*
|
|
* Core's admin groups are labelled by subject and drawn with glyphs of the same
|
|
* weight, so this is the same 16px frame as the portal's. A key rather than a
|
|
* shield: a shield is protection from something, and this row is about handing
|
|
* somebody the right to do something.
|
|
*/
|
|
export const IconKey = () => (
|
|
<Icon>
|
|
<circle cx="7.5" cy="15.5" r="4.5" />
|
|
<path d="M10.7 12.3L20 3" />
|
|
<path d="M17 6l2.5 2.5" />
|
|
</Icon>
|
|
)
|
|
|
|
/**
|
|
* Sliders — the admin sidebar's row for the mod-configuration editor.
|
|
*
|
|
* Not a gear: core's account row is a gear, and two gears in one sidebar say
|
|
* "settings" twice without saying whose. Sliders read as values being tuned,
|
|
* which is exactly what that page does to somebody else's game host.
|
|
*/
|
|
export const IconSliders = () => (
|
|
<Icon>
|
|
<path d="M4 6h10" />
|
|
<path d="M18 6h2" />
|
|
<circle cx="16" cy="6" r="2" />
|
|
<path d="M4 12h4" />
|
|
<path d="M12 12h8" />
|
|
<circle cx="10" cy="12" r="2" />
|
|
<path d="M4 18h10" />
|
|
<path d="M18 18h2" />
|
|
<circle cx="16" cy="18" r="2" />
|
|
</Icon>
|
|
)
|
|
|
|
/**
|
|
* An eye — the admin sidebar's row for who may see who is online.
|
|
*
|
|
* The page decides what the public can SEE, so the glyph is the act of seeing.
|
|
*/
|
|
export const IconEye = () => (
|
|
<Icon>
|
|
<path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z" />
|
|
<circle cx="12" cy="12" r="3" />
|
|
</Icon>
|
|
)
|
|
|
|
/**
|
|
* Two stacked units — the admin sidebar's row for the servers themselves.
|
|
*
|
|
* The one row that is about the machines rather than what happens on them: the
|
|
* sidecar each one answers through, and when each one wipes.
|
|
*/
|
|
export const IconServer = () => (
|
|
<Icon>
|
|
<rect x="3" y="4" width="18" height="7" rx="1.5" />
|
|
<rect x="3" y="13" width="18" height="7" rx="1.5" />
|
|
<path d="M7 7.5h.01" />
|
|
<path d="M7 16.5h.01" />
|
|
</Icon>
|
|
)
|
|
|
|
export default { IconLink, IconKey, IconSliders, IconEye, IconServer }
|
|
|
|
/**
|
|
* A circle inside a dashed ring — the admin sidebar's row for zone presets.
|
|
*
|
|
* A zone is an area with rules at its edge, so the glyph is a place and its
|
|
* boundary rather than a map pin, which the live map already means.
|
|
*/
|
|
export const IconZone = () => (
|
|
<Icon>
|
|
<circle cx="12" cy="12" r="9" strokeDasharray="3 3" />
|
|
<circle cx="12" cy="12" r="3" />
|
|
</Icon>
|
|
)
|