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:
Bobbahbrown
2021-06-13 02:58:03 -03:00
committed by GitHub
parent a6e31b6c9d
commit 314777938f
4 changed files with 93 additions and 43 deletions
+8 -2
View File
@@ -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>"
+1 -1
View File
@@ -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.
+4 -1
View File
@@ -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?
+80 -39
View File
@@ -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>