mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 03:02:54 +00:00
@@ -90,6 +90,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
|||||||
//Tickets statpanel
|
//Tickets statpanel
|
||||||
/datum/admin_help_tickets/proc/stat_entry()
|
/datum/admin_help_tickets/proc/stat_entry()
|
||||||
var/num_disconnected = 0
|
var/num_disconnected = 0
|
||||||
|
stat("== Admin Tickets ==")
|
||||||
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
|
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
|
||||||
for(var/datum/admin_help/AH as anything in active_tickets)
|
for(var/datum/admin_help/AH as anything in active_tickets)
|
||||||
if(AH.initiator)
|
if(AH.initiator)
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ GLOBAL_DATUM_INIT(mhelp_tickets, /datum/mentor_help_tickets, new)
|
|||||||
//Tickets statpanel
|
//Tickets statpanel
|
||||||
/datum/mentor_help_tickets/proc/stat_entry()
|
/datum/mentor_help_tickets/proc/stat_entry()
|
||||||
var/num_disconnected = 0
|
var/num_disconnected = 0
|
||||||
|
stat("== Mentor Tickets ==")
|
||||||
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
|
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
|
||||||
for(var/datum/mentor_help/MH as anything in active_tickets)
|
for(var/datum/mentor_help/MH as anything in active_tickets)
|
||||||
if(MH.initiator)
|
if(MH.initiator)
|
||||||
@@ -259,6 +260,9 @@ GLOBAL_DATUM_INIT(mhelp_tickets, /datum/mentor_help_tickets, new)
|
|||||||
|
|
||||||
//Show the ticket panel
|
//Show the ticket panel
|
||||||
/datum/mentor_help/proc/TicketPanel()
|
/datum/mentor_help/proc/TicketPanel()
|
||||||
|
tgui_interact(usr.client.mob)
|
||||||
|
|
||||||
|
/datum/mentor_help/proc/TicketPanelLegacy()
|
||||||
var/list/dat = list("<html><head><title>Ticket #[id]</title></head>")
|
var/list/dat = list("<html><head><title>Ticket #[id]</title></head>")
|
||||||
var/ref_src = "\ref[src]"
|
var/ref_src = "\ref[src]"
|
||||||
dat += "<h4>Mentor Help Ticket #[id]: [LinkedReplyName(ref_src)]</h4>"
|
dat += "<h4>Mentor Help Ticket #[id]: [LinkedReplyName(ref_src)]</h4>"
|
||||||
@@ -287,6 +291,63 @@ GLOBAL_DATUM_INIT(mhelp_tickets, /datum/mentor_help_tickets, new)
|
|||||||
|
|
||||||
usr << browse(dat.Join(), "window=mhelp[id];size=620x480")
|
usr << browse(dat.Join(), "window=mhelp[id];size=620x480")
|
||||||
|
|
||||||
|
/datum/mentor_help/tgui_fallback(payload)
|
||||||
|
if(..())
|
||||||
|
return
|
||||||
|
|
||||||
|
TicketPanelLegacy()
|
||||||
|
|
||||||
|
/datum/mentor_help/tgui_interact(mob/user, datum/tgui/ui)
|
||||||
|
ui = SStgui.try_update_ui(user, src, ui)
|
||||||
|
if(!ui)
|
||||||
|
ui = new(user, src, "MentorTicketPanel", "Ticket #[id] - [LinkedReplyName("\ref[src]")]")
|
||||||
|
ui.open()
|
||||||
|
|
||||||
|
/datum/mentor_help/tgui_state(mob/user)
|
||||||
|
return GLOB.tgui_mentor_state
|
||||||
|
|
||||||
|
/datum/mentor_help/tgui_data(mob/user)
|
||||||
|
var/list/data = list()
|
||||||
|
|
||||||
|
data["id"] = id
|
||||||
|
|
||||||
|
var/ref_src = "\ref[src]"
|
||||||
|
data["title"] = name
|
||||||
|
data["name"] = LinkedReplyName(ref_src)
|
||||||
|
|
||||||
|
switch(state)
|
||||||
|
if(AHELP_ACTIVE)
|
||||||
|
data["state"] = "open"
|
||||||
|
if(AHELP_RESOLVED)
|
||||||
|
data["state"] = "resolved"
|
||||||
|
else
|
||||||
|
data["state"] = "unknown"
|
||||||
|
|
||||||
|
data["opened_at"] = (world.time - opened_at)
|
||||||
|
data["closed_at"] = (world.time - closed_at)
|
||||||
|
data["opened_at_date"] = gameTimestamp(wtime = opened_at)
|
||||||
|
data["closed_at_date"] = gameTimestamp(wtime = closed_at)
|
||||||
|
|
||||||
|
data["actions"] = Context(ref_src)
|
||||||
|
|
||||||
|
data["log"] = _interactions
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
/datum/mentor_help/tgui_act(action, params)
|
||||||
|
if(..())
|
||||||
|
return
|
||||||
|
switch(action)
|
||||||
|
if("escalate")
|
||||||
|
Escalate()
|
||||||
|
. = TRUE
|
||||||
|
if("reopen")
|
||||||
|
Reopen()
|
||||||
|
. = TRUE
|
||||||
|
if("legacy")
|
||||||
|
TicketPanelLegacy()
|
||||||
|
. = TRUE
|
||||||
|
|
||||||
//Kick ticket to admins
|
//Kick ticket to admins
|
||||||
/datum/mentor_help/proc/Escalate()
|
/datum/mentor_help/proc/Escalate()
|
||||||
if(tgui_alert(usr, "Really escalate this ticket to admins? No mentors will ever be able to interact with it again if you do.","Escalate",list("Yes","No")) != "Yes")
|
if(tgui_alert(usr, "Really escalate this ticket to admins? No mentors will ever be able to interact with it again if you do.","Escalate",list("Yes","No")) != "Yes")
|
||||||
|
|||||||
@@ -694,6 +694,11 @@
|
|||||||
for(var/datum/SDQL2_query/Q as anything in GLOB.sdql2_queries)
|
for(var/datum/SDQL2_query/Q as anything in GLOB.sdql2_queries)
|
||||||
Q.generate_stat()
|
Q.generate_stat()
|
||||||
|
|
||||||
|
|
||||||
|
if(has_mentor_powers(client))
|
||||||
|
if(statpanel("Tickets"))
|
||||||
|
GLOB.mhelp_tickets.stat_entry()
|
||||||
|
|
||||||
if(listed_turf && client)
|
if(listed_turf && client)
|
||||||
if(!TurfAdjacent(listed_turf))
|
if(!TurfAdjacent(listed_turf))
|
||||||
listed_turf = null
|
listed_turf = null
|
||||||
|
|||||||
12
code/modules/tgui/states/mentor.dm
Normal file
12
code/modules/tgui/states/mentor.dm
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* tgui state: mentor_state
|
||||||
|
*
|
||||||
|
* Checks that the user is an mentor.
|
||||||
|
**/
|
||||||
|
|
||||||
|
GLOBAL_DATUM_INIT(tgui_mentor_state, /datum/tgui_state/mentor_state, new)
|
||||||
|
|
||||||
|
/datum/tgui_state/mentor_state/can_use_topic(src_object, mob/user)
|
||||||
|
if(has_mentor_powers(user.client))
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
|
return STATUS_CLOSE
|
||||||
67
tgui/packages/tgui/interfaces/MentorTicketPanel.tsx
Normal file
67
tgui/packages/tgui/interfaces/MentorTicketPanel.tsx
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/* eslint react/no-danger: "off" */
|
||||||
|
import { useBackend } from '../backend';
|
||||||
|
import { Box, Button, LabeledList, Section } from '../components';
|
||||||
|
import { Window } from '../layouts';
|
||||||
|
|
||||||
|
const State = {
|
||||||
|
'open': 'Open',
|
||||||
|
'resolved': 'Resolved',
|
||||||
|
'unknown': 'Unknown',
|
||||||
|
};
|
||||||
|
|
||||||
|
type Data = {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
name: string;
|
||||||
|
state: string;
|
||||||
|
opened_at: number;
|
||||||
|
closed_at: number;
|
||||||
|
opened_at_date: string;
|
||||||
|
closed_at_date: string;
|
||||||
|
actions: string;
|
||||||
|
log: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MentorTicketPanel = (props, context) => {
|
||||||
|
const { act, data } = useBackend<Data>(context);
|
||||||
|
const { id, title, name, state, opened_at, closed_at, opened_at_date, closed_at_date, actions, log } = data;
|
||||||
|
return (
|
||||||
|
<Window width={900} height={600}>
|
||||||
|
<Window.Content scrollable>
|
||||||
|
<Section
|
||||||
|
title={'Ticket #' + id}
|
||||||
|
buttons={
|
||||||
|
<Box nowrap>
|
||||||
|
<Button icon="arrow-up" content="Escalate" onClick={() => act('escalate')} />{' '}
|
||||||
|
<Button content="Legacy UI" onClick={() => act('legacy')} />
|
||||||
|
</Box>
|
||||||
|
}>
|
||||||
|
<LabeledList>
|
||||||
|
<LabeledList.Item label="Mentor Help Ticket">
|
||||||
|
#{id}: <div dangerouslySetInnerHTML={{ __html: name }} />
|
||||||
|
</LabeledList.Item>
|
||||||
|
<LabeledList.Item label="State">{State[state]}</LabeledList.Item>
|
||||||
|
{State[state] === State.open ? (
|
||||||
|
<LabeledList.Item label="Opened At">
|
||||||
|
{opened_at_date} ({Math.round((opened_at / 600) * 10) / 10} minutes ago.)
|
||||||
|
</LabeledList.Item>
|
||||||
|
) : (
|
||||||
|
<LabeledList.Item label="Closed At">
|
||||||
|
{closed_at_date} ({Math.round((closed_at / 600) * 10) / 10} minutes ago.){' '}
|
||||||
|
<Button content="Reopen" onClick={() => act('reopen')} />
|
||||||
|
</LabeledList.Item>
|
||||||
|
)}
|
||||||
|
<LabeledList.Item label="Actions">
|
||||||
|
<div dangerouslySetInnerHTML={{ __html: actions }} />
|
||||||
|
</LabeledList.Item>
|
||||||
|
<LabeledList.Item label="Log">
|
||||||
|
{Object.keys(log).map((L) => (
|
||||||
|
<div dangerouslySetInnerHTML={{ __html: log[L] }} />
|
||||||
|
))}
|
||||||
|
</LabeledList.Item>
|
||||||
|
</LabeledList>
|
||||||
|
</Section>
|
||||||
|
</Window.Content>
|
||||||
|
</Window>
|
||||||
|
);
|
||||||
|
};
|
||||||
File diff suppressed because one or more lines are too long
@@ -4246,6 +4246,7 @@
|
|||||||
#include "code\modules\tgui\states\human_adjacent.dm"
|
#include "code\modules\tgui\states\human_adjacent.dm"
|
||||||
#include "code\modules\tgui\states\inventory.dm"
|
#include "code\modules\tgui\states\inventory.dm"
|
||||||
#include "code\modules\tgui\states\inventory_vr.dm"
|
#include "code\modules\tgui\states\inventory_vr.dm"
|
||||||
|
#include "code\modules\tgui\states\mentor.dm"
|
||||||
#include "code\modules\tgui\states\not_incapacitated.dm"
|
#include "code\modules\tgui\states\not_incapacitated.dm"
|
||||||
#include "code\modules\tgui\states\notcontained.dm"
|
#include "code\modules\tgui\states\notcontained.dm"
|
||||||
#include "code\modules\tgui\states\observer.dm"
|
#include "code\modules\tgui\states\observer.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user