Skip to content

Commit

Permalink
wip: server status card completed
Browse files Browse the repository at this point in the history
  • Loading branch information
tabarra committed Nov 28, 2023
1 parent 9d2f38e commit 9a9d459
Show file tree
Hide file tree
Showing 19 changed files with 940 additions and 61 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ ConVar usage **example** for different port and profile:

## License, Credits and Thanks
- This project is licensed under the [MIT License](https://github.com/tabarra/txAdmin/blob/master/LICENSE);
- [Favicons](https://www.flaticon.com/free-icon/support_1545728?term=gear%20wrench&page=2&position=11) made by Freepik from [www.flaticon.com](https://www.flaticon.com) are licensed under [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/);
- Warning Sounds ([1](https://freesound.org/people/Ultranova105/sounds/136756/)/[2](https://freesound.org/people/Ultranova105/sounds/136754/)) made by Ultranova105 are licensed under [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/);
- [Announcement Sound](https://freesound.org/people/IENBA/sounds/545495/) made by IENBA is licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/);
- [Message Sound](https://freesound.org/people/Divinux/sounds/198414/) made by Divinux is licensed under [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/);
- ["Kick All" button icon](https://www.flaticon.com/free-icon/users-avatar_8188385) made by __SeyfDesigner__ from [www.flaticon.com](https://www.flaticon.com);
- Warning Sounds ([1](https://freesound.org/people/Ultranova105/sounds/136756/)/[2](https://freesound.org/people/Ultranova105/sounds/136754/)) made by __Ultranova105__ are licensed under [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/);
- [Announcement Sound](https://freesound.org/people/IENBA/sounds/545495/) made by __IENBA__ is licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/);
- [Message Sound](https://freesound.org/people/Divinux/sounds/198414/) made by __Divinux__ is licensed under [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/);
- Especial thanks to everyone that contributed to this project, especially the very fine Discord folks that provide support for others;
8 changes: 8 additions & 0 deletions core/components/Scheduler.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default class Scheduler {
//Cron Function
setInterval(() => {
this.checkSchedule();
globals.webServer?.webSocket.pushRefresh('status');
}, 60 * 1000);
}

Expand All @@ -53,6 +54,7 @@ export default class Scheduler {
this.nextSkip = false;
this.nextTempSchedule = false;
this.checkSchedule();
globals.webServer?.webSocket.pushRefresh('status');
}

/**
Expand Down Expand Up @@ -107,6 +109,9 @@ export default class Scheduler {

//This is needed to refresh this.calculatedNextRestartMinuteFloorTs
this.checkSchedule();

//Refresh UI
globals.webServer?.webSocket.pushRefresh('status');
}


Expand Down Expand Up @@ -148,6 +153,9 @@ export default class Scheduler {

//This is needed to refresh this.calculatedNextRestartMinuteFloorTs
this.checkSchedule();

//Refresh UI
globals.webServer?.webSocket.pushRefresh('status');
}


Expand Down
7 changes: 4 additions & 3 deletions core/components/WebServer/wsRooms/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ const getinitialData = (txAdmin: TxAdmin): GlobalStatusType => {
mutex: txAdmin.fxRunner?.currentMutex,
status: txAdmin.healthMonitor.currentStatus || '??',
process: txAdmin.fxRunner.getStatus(),
instantiated: !!txAdmin.fxRunner.fxChild, //used to disable the control buttons
name: txAdmin.globalConfig.serverName,
players: txAdmin.playerlistManager.onlineCount,
// @ts-ignore scheduler type narrowing id wrong because cant use "as const" in javascript
scheduler: txAdmin.scheduler.getStatus(), //no push events, only passively updated
whitelist: txAdmin.playerDatabase.config.whitelistMode,
},
// @ts-ignore scheduler type narrowing id wrong because cant use "as const" in javascript
scheduler: txAdmin.scheduler.getStatus(), //no push events, only passively updated
}
}

Expand Down
9 changes: 6 additions & 3 deletions docs/dev_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ Processo:
- [x][2h] warning for outdated tx, visible in all pages
- [x][1h] dynamic title
- [x][1h] dynamic favicon
- [ ][1d] server status
- [x][1d] server status
- [ ][4h] update notices via socket.io
- [ ][2h] tooltips on everything
- [x][2h] tooltips on everything
- [ ][1h] zap hosting advertisement
- [ ][1d] toasts API
- [ ] generic toasts
Expand All @@ -86,7 +86,7 @@ Processo:
- [x] cfx.re login
- [x] error page
- [x] master account pin add page
- [ ] master account bkp password page
- [x] master account bkp password page
- [ ] disable menu links based on permissions
- [ ] flow to refresh the permissions on the client side
- [ ] flow to refresh the page if invalidated auth
Expand Down Expand Up @@ -125,6 +125,9 @@ Quickies
- [ ] check if strick mode is indeed disabled in prod build
- [ ] easter egg with some old music? https://www.youtube.com/watch?v=nNoaXej0Jeg

Bugs
- [ ] when you open the server sheet, the control tooltip shows automatically


=======================================================================

Expand Down
35 changes: 35 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions panel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tooltip": "^1.0.7",
"@tailwindcss/typography": "^0.5.10",
"@tanstack/react-query": "^5.0.5",
"class-variance-authority": "^0.7.0",
Expand Down
3 changes: 3 additions & 0 deletions panel/src/components/KickAllIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function KickAllIcon({style}: {style?: React.CSSProperties}) {
return <svg style={style} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.97 18.35a3.076 3.076 0 0 1-3.42 3.4h-7.1a4.075 4.075 0 0 1-1.529-.25.75.75 0 1 1 .558-1.4 2.679 2.679 0 0 0 .971.146h7.1c1.363 0 1.92-.55 1.92-1.9a3.42 3.42 0 0 0-3.4-3.7.748.748 0 0 1-.714-.783.768.768 0 0 1 .783-.715 4.872 4.872 0 0 1 4.831 5.202zm-12.67.407L2.53 22.53a.75.75 0 0 1-1.06-1.06l3.579-3.579a4.81 4.81 0 0 1 4.721-4.722l1.486-1.485a3.755 3.755 0 1 1 4.428-4.428l2.95-2.95a1.407 1.407 0 0 0-1.124-.556 1.345 1.345 0 0 0-.947.367.75.75 0 1 1-1.046-1.074 2.832 2.832 0 0 1 1.993-.793 2.9 2.9 0 0 1 2.184 1l1.776-1.78a.75.75 0 0 1 1.06 1.06L6.3 18.756zm6.55-8.667 1.24-1.24a2.29 2.29 0 0 0 .17-.84 2.255 2.255 0 1 0-2.25 2.25 2.29 2.29 0 0 0 .84-.17zm5.94-1.41h-.22a.75.75 0 0 0 0 1.5h.22a2.261 2.261 0 0 1 2.46 2.47c0 .864-.309 1.17-1.18 1.17h-.36a.75.75 0 0 0 0 1.5h.36a2.435 2.435 0 0 0 2.68-2.67 3.76 3.76 0 0 0-3.96-3.97zM5.922 8.035a.75.75 0 1 0 .3-1.471A1.421 1.421 0 0 1 6.51 3.75a1.386 1.386 0 0 1 .956.375.749.749 0 0 0 1.029-1.09A2.875 2.875 0 0 0 6.51 2.25a2.922 2.922 0 0 0-.588 5.785zM3.93 15.32h.35a.75.75 0 1 0 0-1.5h-.35c-.871 0-1.18-.306-1.18-1.17a2.261 2.261 0 0 1 2.46-2.47h.99a.75.75 0 0 0 0-1.5h-.99a3.726 3.726 0 0 0-3.96 3.97 2.435 2.435 0 0 0 2.68 2.67z"/></svg>;
}
28 changes: 28 additions & 0 deletions panel/src/components/ui/tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as React from "react"
import * as TooltipPrimitive from "@radix-ui/react-tooltip"

import { cn } from "@/lib/utils"

const TooltipProvider = TooltipPrimitive.Provider

const Tooltip = TooltipPrimitive.Root

const TooltipTrigger = TooltipPrimitive.Trigger

const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
))
TooltipContent.displayName = TooltipPrimitive.Content.displayName

export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
4 changes: 3 additions & 1 deletion panel/src/hooks/socketio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export const getSocket = (rooms: string[] | string) => {
* Consts
*/
export const globalStatusAtom = atom<GlobalStatusType | null>(null);
export const serverNameAtom = atom((get) => get(globalStatusAtom)?.server.name ?? 'unconfigured')
export const serverNameAtom = atom((get) => get(globalStatusAtom)?.server.name ?? 'unconfigured');
export const processInstantiatedAtom = atom((get) => get(globalStatusAtom)?.server.instantiated ?? false);
export const serverMutexAtom = atom((get) => get(globalStatusAtom)?.server.mutex);


/**
Expand Down
2 changes: 1 addition & 1 deletion panel/src/layout/MainSheets.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ScrollArea } from "@/components/ui/scroll-area";
import { Sheet, SheetContent, SheetHeader, SheetTitle } from "@/components/ui/sheet";
import { ServerSidebar } from "./ServerSidebar";
import { ServerSidebar } from "./serverSidebar/ServerSidebar";
import { useGlobalMenuSheet, usePlayerlistSheet, useServerSheet } from "@/hooks/sheets";
import { MenuNavLink } from "@/components/MainPageLink";
import { ClipboardCheckIcon, ListIcon, PieChartIcon, ScrollIcon, SettingsIcon, UserSquare2Icon, UsersIcon, ZapIcon } from 'lucide-react';
Expand Down
2 changes: 1 addition & 1 deletion panel/src/layout/MainShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEventListener } from 'usehooks-ts';
import MainRouter from "./MainRouter";
import { useExpireAuthData } from '../hooks/auth';
import { Header } from './Header';
import { ServerSidebar } from './ServerSidebar';
import { ServerSidebar } from './serverSidebar/ServerSidebar';
import { PlayersSidebar } from './PlayersSidebar';
import MainSheets from './MainSheets';
import WarningBar from './WarningBar';
Expand Down
130 changes: 130 additions & 0 deletions panel/src/layout/serverSidebar/ServerControls.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import KickAllIcon from '@/components/KickAllIcon';
import { processInstantiatedAtom } from '@/hooks/socketio';
import { cn } from '@/lib/utils';
import { cva } from 'class-variance-authority';
import { useAtomValue } from 'jotai';
import { MegaphoneIcon, PowerIcon, PowerOffIcon, RotateCcwIcon } from 'lucide-react';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";


const tooltipDelay = 300;

const controlButtonsVariants = cva(
`h-10 sm:h-8 rounded-md transition-colors
flex flex-grow items-center justify-center flex-shrink-0
border bg-muted shadow-md
focus:outline-none disabled:pointer-events-none disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2`,
{
variants: {
type: {
default: "hover:bg-primary hover:text-primary-foreground hover:border-primary",
destructive: "hover:bg-destructive hover:text-destructive-foreground hover:border-destructive",
warning: "hover:bg-warning hover:text-warning-foreground hover:border-warning",
success: "hover:bg-success hover:text-success-foreground hover:border-success",
info: "hover:bg-info hover:text-info-foreground hover:border-info",
},
},
defaultVariants: {
type: "default",
},
}
);

export default function ServerControls({ isSheet }: { isSheet?: boolean }) {
const processInstantiated = useAtomValue(processInstantiatedAtom);

const handleStartStop = () => {
alert('FIXME: Start/stop');
}
const handleRestart = () => {
if (!processInstantiated) return;
alert('FIXME: Restart');
}
const handleAnnounce = () => {
if (!processInstantiated) return;
alert('FIXME: Announce');
}
const handleKickAll = () => {
if (!processInstantiated) return;
alert('FIXME: KickAll');
}

return (
<TooltipProvider delayDuration={tooltipDelay} disableHoverableContent={true} >
<div className="flex flex-row justify-between gap-2">
<Tooltip>
<TooltipTrigger asChild>
{processInstantiated
? <button
onClick={handleStartStop}
className={cn(controlButtonsVariants({ type: 'destructive' }))}
>
<PowerOffIcon className='h-5' />
</button>
: <div className="relative flex flex-grow h-8">
<div className='absolute inset-0 bg-success animate-pulse rounded blur-sm'></div>
<button
onClick={handleStartStop}
className={cn(controlButtonsVariants({ type: 'success' }), 'relative')}
>
<PowerIcon className='h-5' />
</button>
</div>
}
</TooltipTrigger>
<TooltipContent className='max-w-md flex-wrap'>
<p>{processInstantiated ? 'Stop the server' : 'Start the server! 🚀'}</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<button
onClick={handleRestart}
className={cn(controlButtonsVariants({ type: 'warning' }))}
disabled={!processInstantiated}
>
<RotateCcwIcon className='h-5' />
</button>
</TooltipTrigger>
<TooltipContent>
<p>Restart Server</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<button
onClick={handleAnnounce}
className={cn(controlButtonsVariants())}
disabled={!processInstantiated}
>
<MegaphoneIcon className='h-5' />
</button>
</TooltipTrigger>
<TooltipContent>
<p>Send Announcement</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<button
onClick={handleKickAll}
className={controlButtonsVariants()}
disabled={!processInstantiated}
>
<KickAllIcon style={{ height: '1.25rem', width: '1.5rem', fill: 'currentcolor' }} />
</button>
</TooltipTrigger>
<TooltipContent>
<p>Kick All Players</p>
</TooltipContent>
</Tooltip>
</div>
</TooltipProvider>
);
}

0 comments on commit 9a9d459

Please sign in to comment.