mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 15:17:01 +01:00
Requested Interview Features Update (Rave Radbury Edition) (#59621)
Added a few things that were requested by RaveRadbury to be added to the interview system: * Where appropriate clickable links are now added to open a interview in similar fashion to tickets * Changed fields to be read-only for admins looking at interviews while they're being written * Added the ability to include markdown-style links to interview welcome messages and interview questions * Updated the default questions to add a question about if the user has read the rules to demonstrate the ability to include links
This commit is contained in:
@@ -60,7 +60,7 @@
|
||||
GLOB.interviews.approved_ckeys |= owner_ckey
|
||||
GLOB.interviews.close_interview(src)
|
||||
log_admin_private("[key_name(approved_by)] has approved interview #[id] for [owner_ckey][!owner ? "(DC)": ""].")
|
||||
message_admins("<span class='adminnotice'>[key_name(approved_by)] has approved interview #[id] for [owner_ckey][!owner ? "(DC)": ""].</span>")
|
||||
message_admins("<span class='adminnotice'>[key_name(approved_by)] has approved [link_self()] for [owner_ckey][!owner ? "(DC)": ""].</span>")
|
||||
if (owner)
|
||||
SEND_SOUND(owner, sound('sound/effects/adminhelp.ogg'))
|
||||
to_chat(owner, "<font color='red' size='4'><b>-- Interview Update --</b></font>" \
|
||||
@@ -79,7 +79,7 @@
|
||||
GLOB.interviews.close_interview(src)
|
||||
GLOB.interviews.cooldown_ckeys |= owner_ckey
|
||||
log_admin_private("[key_name(denied_by)] has denied interview #[id] for [owner_ckey][!owner ? "(DC)": ""].")
|
||||
message_admins("<span class='adminnotice'>[key_name(denied_by)] has denied interview #[id] for [owner_ckey][!owner ? "(DC)": ""].</span>")
|
||||
message_admins("<span class='adminnotice'>[key_name(denied_by)] has denied [link_self()] for [owner_ckey][!owner ? "(DC)": ""].</span>")
|
||||
addtimer(CALLBACK(GLOB.interviews, /datum/interview_manager.proc/release_from_cooldown, owner_ckey), 180)
|
||||
if (owner)
|
||||
SEND_SOUND(owner, sound('sound/effects/adminhelp.ogg'))
|
||||
@@ -160,3 +160,9 @@
|
||||
"response" = responses.len < i ? null : responses[i]
|
||||
)
|
||||
.["questions"] += list(data)
|
||||
|
||||
/**
|
||||
* Generates a clickable link to open this interview
|
||||
*/
|
||||
/datum/interview/proc/link_self()
|
||||
return "<a href='?_src_=holder;[HrefToken(TRUE)];interview=[REF(src)]'>Interview #[id]</a>"
|
||||
|
||||
@@ -109,7 +109,7 @@ GLOBAL_DATUM_INIT(interviews, /datum/interview_manager, new)
|
||||
if(X.prefs.toggles & SOUND_ADMINHELP)
|
||||
SEND_SOUND(X, sound('sound/effects/adminhelp.ogg'))
|
||||
window_flash(X, ignorepref = TRUE)
|
||||
to_chat(X, "<span class='adminhelp'>Interview for [ckey] enqueued for review. Current position in queue: [to_queue.pos_in_queue]</span>", confidential = TRUE)
|
||||
to_chat(X, "<span class='adminhelp'>[to_queue.link_self()] for [ckey] enqueued for review. Current position in queue: [to_queue.pos_in_queue]</span>", confidential = TRUE)
|
||||
|
||||
/**
|
||||
* Removes a ckey from the cooldown list, used for enforcing cooldown after an interview is denied.
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
# Interview welcome message displayed at the top of all interview questionnaires
|
||||
# Should help to describe why the questionnaire is being given to the interviewee
|
||||
# You can include links using markdown-style link notation, like [our rules](https://tgstation13.org/wiki/Rules)
|
||||
INTERVIEW_WELCOME_MSG Welcome to our server. As you have not played here before, or played very little, we'll need you to answer a few questions below. After you submit your answers they will be reviewed and you may be asked further questions before being allowed to play. Please be patient as there may be others ahead of you.
|
||||
|
||||
# Interview questions are listed here, in the order that they will be displayed in-game.
|
||||
# You can include links using markdown-style link notation, like [our rules](https://tgstation13.org/wiki/Rules)
|
||||
INTERVIEW_QUESTIONS Why have you joined the server today?
|
||||
INTERVIEW_QUESTIONS Have you played space-station 13 before? If so, on what servers?
|
||||
INTERVIEW_QUESTIONS Do you know anybody on the server today? If so, who?
|
||||
INTERVIEW_QUESTIONS Do you have any additional comments?
|
||||
INTERVIEW_QUESTIONS Have you read and understood our [rules](https://tgstation13.org/wiki/Rules)?
|
||||
INTERVIEW_QUESTIONS Do you have any additional comments or questions?
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { Button, TextArea, Section, BlockQuote, NoticeBox } from '../components';
|
||||
import {
|
||||
Button,
|
||||
TextArea,
|
||||
Section,
|
||||
BlockQuote,
|
||||
NoticeBox,
|
||||
} from '../components';
|
||||
import { Window } from '../layouts';
|
||||
import { useBackend } from '../backend';
|
||||
|
||||
@@ -14,76 +20,111 @@ export const Interview = (props, context) => {
|
||||
connected,
|
||||
} = data;
|
||||
|
||||
const rendered_status = status => {
|
||||
const rendered_status = (status) => {
|
||||
switch (status) {
|
||||
case "interview_approved":
|
||||
return (<NoticeBox success>This interview was approved.</NoticeBox>);
|
||||
case "interview_denied":
|
||||
return (<NoticeBox danger>This interview was denied.</NoticeBox>);
|
||||
case 'interview_approved':
|
||||
return <NoticeBox success>This interview was approved.</NoticeBox>;
|
||||
case 'interview_denied':
|
||||
return <NoticeBox danger>This interview was denied.</NoticeBox>;
|
||||
default:
|
||||
return (<NoticeBox info>
|
||||
Your answers have been submitted. You are position {queue_pos} in
|
||||
queue.</NoticeBox>);
|
||||
return (
|
||||
<NoticeBox info>
|
||||
Your answers have been submitted. You are position {queue_pos} in
|
||||
queue.
|
||||
</NoticeBox>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Matches a complete markdown-style link, capturing the whole [...](...)
|
||||
const link_regex = /(\[[^[]+\]\([^)]+\))/;
|
||||
// Decomposes a markdown-style link into the link and display text
|
||||
const link_decompose_regex = /\[([^[]+)\]\(([^)]+)\)/;
|
||||
|
||||
// Renders any markdown-style links within a provided body of text
|
||||
const linkify_text = (text) => {
|
||||
let parts = text.split(link_regex);
|
||||
for (let i = 1; i < parts.length; i += 2) {
|
||||
const match = link_decompose_regex.exec(parts[i]);
|
||||
parts[i] = (
|
||||
<a key={'link' + i} href={match[2]}>
|
||||
{match[1]}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
return parts;
|
||||
};
|
||||
|
||||
return (
|
||||
<Window
|
||||
width={500}
|
||||
height={600}
|
||||
canClose={is_admin}>
|
||||
<Window width={500} height={600} canClose={is_admin}>
|
||||
<Window.Content scrollable>
|
||||
{(!read_only && (
|
||||
<Section title="Welcome!">
|
||||
<p>
|
||||
{welcome_message}
|
||||
</p>
|
||||
</Section>)) || rendered_status(status)}
|
||||
<p>{linkify_text(welcome_message)}</p>
|
||||
</Section>
|
||||
))
|
||||
|| rendered_status(status)}
|
||||
<Section
|
||||
title="Questionnaire"
|
||||
buttons={(
|
||||
buttons={
|
||||
<span>
|
||||
<Button
|
||||
content={read_only ? "Submitted" : "Submit"}
|
||||
content={read_only ? 'Submitted' : 'Submit'}
|
||||
onClick={() => act('submit')}
|
||||
disabled={read_only} />
|
||||
{!!is_admin && status === "interview_pending" && (
|
||||
disabled={read_only}
|
||||
/>
|
||||
{!!is_admin && status === 'interview_pending' && (
|
||||
<span>
|
||||
<Button content="Admin PM"
|
||||
enabled={connected} onClick={() => act('adminpm')} />
|
||||
<Button content="Approve"
|
||||
color="good" onClick={() => act('approve')} />
|
||||
<Button content="Deny"
|
||||
color="bad" onClick={() => act('deny')} />
|
||||
<Button
|
||||
content="Admin PM"
|
||||
enabled={connected}
|
||||
onClick={() => act('adminpm')}
|
||||
/>
|
||||
<Button
|
||||
content="Approve"
|
||||
color="good"
|
||||
onClick={() => act('approve')}
|
||||
/>
|
||||
<Button
|
||||
content="Deny"
|
||||
color="bad"
|
||||
onClick={() => act('deny')}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
)}>
|
||||
}>
|
||||
{!read_only && (
|
||||
<p>
|
||||
Please answer the following questions,
|
||||
and press submit when you are satisfied with your answers.
|
||||
<br /><br />
|
||||
Please answer the following questions, and press submit when you
|
||||
are satisfied with your answers.
|
||||
<br />
|
||||
<br />
|
||||
<b>You will not be able to edit your answers after submitting.</b>
|
||||
</p>)}
|
||||
</p>
|
||||
)}
|
||||
{questions.map(({ qidx, question, response }) => (
|
||||
<Section key={qidx} title={`Question ${qidx}`}>
|
||||
<p>{question}</p>
|
||||
{(read_only && (
|
||||
<BlockQuote>{response || "No response."}</BlockQuote>)) || (
|
||||
<p>{linkify_text(question)}</p>
|
||||
{((read_only || is_admin) && (
|
||||
<BlockQuote>{response || 'No response.'}</BlockQuote>
|
||||
)) || (
|
||||
<TextArea
|
||||
value={response}
|
||||
fluid
|
||||
height={10}
|
||||
maxLength={500}
|
||||
placeholder="Write your response here, max of 500 characters."
|
||||
onChange={(e, input) => input !== response
|
||||
onChange={(e, input) =>
|
||||
input !== response
|
||||
&& act('update_answer', {
|
||||
qidx: qidx,
|
||||
answer: input,
|
||||
})} />)}
|
||||
</Section>)
|
||||
)}
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</Section>
|
||||
))}
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
|
||||
Reference in New Issue
Block a user