fix: model user assignment by service instead of port
This commit is contained in:
56
src/App.tsx
56
src/App.tsx
@@ -18,6 +18,14 @@ const tabs: Array<{ id: TabId; label: string }> = [
|
||||
{ id: 'system', label: 'System' },
|
||||
];
|
||||
|
||||
const assignableServices = dashboardSnapshot.system.services.filter(
|
||||
(service) => service.enabled && service.assignable,
|
||||
);
|
||||
|
||||
const servicesById = new Map(
|
||||
dashboardSnapshot.system.services.map((service) => [service.id, service] as const),
|
||||
);
|
||||
|
||||
function LoginGate({ onUnlock }: { onUnlock: () => void }) {
|
||||
const [login, setLogin] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
@@ -71,6 +79,8 @@ function LoginGate({ onUnlock }: { onUnlock: () => void }) {
|
||||
}
|
||||
|
||||
function AddUserModal({ onClose }: { onClose: () => void }) {
|
||||
const [serviceId, setServiceId] = useState(assignableServices[0]?.id ?? '');
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (event: globalThis.KeyboardEvent) => {
|
||||
if (event.key === 'Escape') {
|
||||
@@ -87,6 +97,8 @@ function AddUserModal({ onClose }: { onClose: () => void }) {
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
const selectedService = servicesById.get(serviceId);
|
||||
|
||||
return (
|
||||
<div className="modal-backdrop" role="presentation" onClick={onClose}>
|
||||
<section
|
||||
@@ -112,13 +124,31 @@ function AddUserModal({ onClose }: { onClose: () => void }) {
|
||||
<input placeholder="generated secret" />
|
||||
</label>
|
||||
<label>
|
||||
Port
|
||||
<input placeholder="1080" />
|
||||
Service
|
||||
<select value={serviceId} onChange={(event) => setServiceId(event.target.value)}>
|
||||
{assignableServices.map((service) => (
|
||||
<option key={service.id} value={service.id}>
|
||||
{service.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Quota (MB)
|
||||
<input placeholder="Optional" />
|
||||
</label>
|
||||
<div className="modal-preview">
|
||||
<span>Endpoint</span>
|
||||
<strong>
|
||||
{selectedService
|
||||
? `${dashboardSnapshot.system.publicHost}:${selectedService.port}`
|
||||
: 'Unavailable'}
|
||||
</strong>
|
||||
</div>
|
||||
<div className="modal-preview">
|
||||
<span>Protocol</span>
|
||||
<strong>{selectedService ? selectedService.protocol : 'Unavailable'}</strong>
|
||||
</div>
|
||||
<div className="modal-actions">
|
||||
<button type="button" className="button-secondary" onClick={onClose}>
|
||||
Cancel
|
||||
@@ -269,7 +299,19 @@ function UsersTab() {
|
||||
</thead>
|
||||
<tbody>
|
||||
{dashboardSnapshot.userRecords.map((user) => {
|
||||
const proxyLink = buildProxyLink(user.username, user.password, user.host, user.port);
|
||||
const service = servicesById.get(user.serviceId);
|
||||
const endpoint = service
|
||||
? `${dashboardSnapshot.system.publicHost}:${service.port}`
|
||||
: 'service missing';
|
||||
const proxyLink = service
|
||||
? buildProxyLink(
|
||||
user.username,
|
||||
user.password,
|
||||
dashboardSnapshot.system.publicHost,
|
||||
service.port,
|
||||
service.protocol,
|
||||
)
|
||||
: '';
|
||||
const exhausted = isQuotaExceeded(user.usedBytes, user.quotaBytes);
|
||||
|
||||
return (
|
||||
@@ -279,7 +321,12 @@ function UsersTab() {
|
||||
<strong>{user.username}</strong>
|
||||
</div>
|
||||
</td>
|
||||
<td>{`${user.host}:${user.port}`}</td>
|
||||
<td>
|
||||
<div className="endpoint-cell">
|
||||
<strong>{service?.name ?? 'Unknown service'}</strong>
|
||||
<span>{endpoint}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span className={`status-pill ${getServiceTone(user.status)}`}>{user.status}</span>
|
||||
</td>
|
||||
@@ -291,6 +338,7 @@ function UsersTab() {
|
||||
type="button"
|
||||
className={exhausted ? 'copy-button danger' : 'copy-button'}
|
||||
onClick={() => handleCopy(user.id, proxyLink)}
|
||||
disabled={!service}
|
||||
>
|
||||
{copiedId === user.id ? 'Copied' : 'Copy'}
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user