Skip to content

Commit

Permalink
[MIRROR] Fixes interview panel [NO GBP] [MDB IGNORE] (#25689) (#1178)
Browse files Browse the repository at this point in the history
* Fixes interview panel [NO GBP] (#80395)

## About The Pull Request
This was a problematic UI based on how React handles onChange compared
to Inferno, our previous. It was extra laggy after the switch, sending
data on every key. When I had changed it to not send on keystroke, it
wasn't super obvious that you must press "enter". I've tried to make
this more obvious, and it now also safeguards against incomplete forms.
This should resolve the issue, but not a screen I can test locally 100%.

<details>
<summary>Pictures</summary>

![image](https://github.com/tgstation/tgstation/assets/42397676/3f06e0ab-3a58-4d03-b3c4-fdd809937bfc)

</details>

## Why It's Good For The Game
Bug fix
fixes #80378
## Changelog
:cl:
fix: Interview UI should now be more obvious how it works: You must
press "enter" or save the answer.
/:cl:

* Fixes interview panel [NO GBP]

---------

Co-authored-by: SkyratBot <[email protected]>
Co-authored-by: Jeremiah <[email protected]>
  • Loading branch information
3 people authored Dec 18, 2023
1 parent 12815ad commit ff167f4
Showing 1 changed file with 97 additions and 49 deletions.
146 changes: 97 additions & 49 deletions tgui/packages/tgui/interfaces/Interview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import {
Section,
BlockQuote,
NoticeBox,
Box,
} from '../components';
import { Window } from '../layouts';
import { useBackend } from '../backend';
import { ReactNode } from 'react';
import { ReactNode, useState } from 'react';

type Data = {
connected: boolean;
Expand All @@ -22,7 +23,7 @@ type Data = {
type Question = {
qidx: number;
question: string;
response: string;
response: string | null;
};

enum STATUS {
Expand Down Expand Up @@ -56,13 +57,16 @@ export const Interview = (props) => {
const {
connected,
is_admin,
questions = [], // TODO: Remove default
questions = [],
queue_pos,
read_only,
status,
welcome_message = '',
} = data;

const allAnswered = questions.every((q) => q.response);
const numAnswered = questions.filter((q) => q.response)?.length;

return (
<Window
width={500}
Expand All @@ -80,62 +84,55 @@ export const Interview = (props) => {
buttons={
<span>
<Button
content={read_only ? 'Submitted' : 'Submit'}
onClick={() => act('submit')}
disabled={read_only}
/>
disabled={read_only || !allAnswered || !questions.length}
icon="envelope"
tooltip={
!allAnswered &&
`Please answer all questions.
${numAnswered} / ${questions.length}`
}
>
{read_only ? 'Submitted' : 'Submit'}
</Button>
{!!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 disabled={!connected} onClick={() => act('adminpm')}>
Admin PM
</Button>
<Button color="good" onClick={() => act('approve')}>
Approve
</Button>
<Button color="bad" onClick={() => act('deny')}>
Deny
</Button>
</span>
)}
</span>
}
>
{!read_only && (
<p>
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>
<>
<Box as="p" color="label">
Please answer the following questions.
<ul>
<li>
You can press enter key or the save button to save an
answer.
</li>
<li>
You can edit your answers until you press the submit button.
</li>
<li>Press SUBMIT when you are done.</li>
</ul>
</Box>
<NoticeBox info align="center">
You will not be able to edit your answers after submitting.
</NoticeBox>
</>
)}
{questions.map(({ qidx, question, response }) => (
<Section key={qidx} title={`Question ${qidx}`}>
<p>{linkifyText(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. Press enter to submit."
onEnter={(e, input) =>
act('update_answer', {
qidx,
answer: input,
})
}
/>
)}
</Section>
{questions.map((question) => (
<QuestionArea key={question.qidx} {...question} />
))}
</Section>
</Window.Content>
Expand All @@ -160,3 +157,54 @@ const RenderedStatus = (props: { status: string; queue_pos: number }) => {
);
}
};

const QuestionArea = (props: Question) => {
const { qidx, question, response } = props;
const { act, data } = useBackend<Data>();
const { is_admin, read_only } = data;

const [userInput, setUserInput] = useState(response);

const saveResponse = () => {
act('update_answer', {
qidx,
answer: userInput,
});
};

const changedResponse = userInput !== response;

const saveAvailable = !read_only && !!userInput && changedResponse;

const isSaved = !!response && !changedResponse;

return (
<Section
title={`Question ${qidx}`}
buttons={
<Button
disabled={!saveAvailable}
onClick={saveResponse}
icon={isSaved ? 'check' : 'save'}
>
{isSaved ? 'Saved' : 'Save'}
</Button>
}
>
<p>{linkifyText(question)}</p>
{((read_only || is_admin) && (
<BlockQuote>{response || 'No response.'}</BlockQuote>
)) || (
<TextArea
fluid
height={10}
maxLength={500}
onChange={(e, input) => setUserInput(input)}
onEnter={saveResponse}
placeholder="Write your response here, max of 500 characters. Press enter to submit."
value={response}
/>
)}
</Section>
);
};

0 comments on commit ff167f4

Please sign in to comment.