Skip to content

Commit

Permalink
Merge pull request #2006 from Heigvd/PMG-10
Browse files Browse the repository at this point in the history
PMG-10 question display improvement
  • Loading branch information
SandraMonnier authored Jan 10, 2025
2 parents 7905b59 + e1dbd4b commit 024999f
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 140 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';

import { languagesCTX } from '../../Components/Contexts/LanguagesProvider';
import { languagesCTX } from '../Contexts/LanguagesProvider';
import { translate } from '../../data/i18n';

export function useTranslate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const cbxContainerStyle = css({
borderLeft: '1px solid ' + themeVar.colors.ActiveColor,
},
});

const cbxStyle = css({
'&.wegas.wegas-btn': {
color: themeVar.colors.LightTextColor,
Expand All @@ -49,6 +50,7 @@ const cbxStyle = css({
},
},
});

interface CbxChoiceDisplayProps {
choiceD: IChoiceDescriptor;
choiceI: IChoiceInstance;
Expand Down Expand Up @@ -79,36 +81,39 @@ function CbxChoiceDisplay({
}

return (
<ChoiceContainer
active={active}
descriptor={choiceD}
canReply={!disabled}
hasBeenSelected={questionChoosed}
className={cbxChoiceContainerStyle}
inputClassName={cbxContainerStyle}
onClick={async () => {
if (enableValidate) {
return onValidate(choiceD);
<>
<ChoiceContainer
active={active}
descriptor={choiceD}
canReply={!disabled}
hasBeenSelected={questionChoosed}
className={cbxChoiceContainerStyle}
inputClassName={cbxContainerStyle}
onClick={async () => {
if (enableValidate) {
return onValidate(choiceD);
}
}}
editMode={editMode}
validateButton={false}
>
{
<CheckBox
className={autoMargin}
value={questionChoosed}
onChange={() => {
if (enableValidate) {
onValidate(choiceD);
}
}}
disabled={disabled}
radio={radioButton}
checkBoxClassName={cbxStyle}
/>
}
}}
editMode={editMode}
validateButton={false}
>
{
<CheckBox
className={autoMargin}
value={questionChoosed}
onChange={() => {
if (enableValidate) {
onValidate(choiceD);
}
}}
disabled={disabled}
radio={radioButton}
checkBoxClassName={cbxStyle}
/>
}
</ChoiceContainer>
</ChoiceContainer>
<RepliesDisplay replies={replies} />
</>
);
}

Expand All @@ -123,16 +128,18 @@ export function CbxQuestionDisplay({
questionI,
choicesD,
choicesI,
replies,
editMode,
...options
}: CbxQuestionDisplayProps) {
const { maxReplies, minReplies } = questionD || {};

const replyCount = choicesI.reduce((acc, c) => {
return acc + (c?.replies ? c?.replies.length : 0);
}, 0);
const canReply =
questionI != null && !questionI.validated && isActionAllowed(options);
const maxReplyReached = maxReplies != null && replies.length >= maxReplies;
const remainingChoices = minReplies == null ? 0 : minReplies - replies.length;
const maxReplyReached = maxReplies != null && replyCount >= maxReplies;
const remainingChoices = minReplies == null ? 0 : minReplies - replyCount;
const radio = maxReplies === 1 && minReplies === 1;

const onChoiceValidate = React.useCallback(
Expand Down Expand Up @@ -177,7 +184,7 @@ export function CbxQuestionDisplay({
})}
{editMode && <AddChoiceMenu questionD={questionD} />}
{!questionI.validated && (
<div className={cx(choiceInputStyle)}>
<div className={cx(choiceInputStyle, 'wegas-question__choice-warning')}>
{remainingChoices > 0 && (
<MessageString
type="warning"
Expand All @@ -195,7 +202,6 @@ export function CbxQuestionDisplay({
/>
</div>
)}
<RepliesDisplay replies={replies} />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { IWhChoiceDescriptor } from '../../../data/scriptable/impl/QuestionDescr
import { editingStore } from '../../../data/Stores/editingStore';
import { classNameOrEmpty } from '../../../Helper/className';
import { componentsTranslations } from '../../../i18n/components/components';
import { useInternalTranslate } from '../../../i18n/internalTranslator';
import { useInternalPlayerLangTranslate } from '../../../i18n/internalTranslator';
import { languagesCTX } from '../../Contexts/LanguagesProvider';
import { useTranslate } from '../../Hooks/useTranslate';
import HTMLEditor from '../../HTML/HTMLEditor';
Expand Down Expand Up @@ -48,7 +48,7 @@ export const choiceContainerStyle = css({
color: themeVar.colors.DarkTextColor,
},
},
'&.disabled': {
'&.disabled, &.loading': {
backgroundColor: themeVar.colors.BackgroundColor,
opacity: '0.7',
cursor: 'cursor',
Expand All @@ -66,7 +66,7 @@ export const choiceContainerStyle = css({
},
},
});
export const choiceLabelStyle = css({
export const choiceHeaderStyle = css({
fontWeight: 'bold',
padding: '15px',
backgroundColor: themeVar.colors.HoverColor,
Expand All @@ -82,8 +82,11 @@ export const choiceDescriptionStyle = css({
padding: '10px 15px 10px 15px',
});
export const choiceButtonStyle = css({
padding: '0px 15px 15px 15px',
padding: '15px',
float: 'right',
flexDirection: 'row',
display: 'flex',
justifyContent: 'end',
});
export const choiceInputStyle = css({
display: 'flex',
Expand Down Expand Up @@ -116,6 +119,7 @@ interface ChoiceContainerProps {
onClick?: () => Promise<unknown>;
hasBeenSelected: boolean;
editMode?: boolean;
replyCount?: number;
validateButton?: boolean;
}

Expand All @@ -129,9 +133,10 @@ export function ChoiceContainer({
onClick,
hasBeenSelected,
editMode,
replyCount = undefined,
validateButton = true,
}: React.PropsWithChildren<ChoiceContainerProps>) {
const i18nValues = useInternalTranslate(componentsTranslations);
const i18nValues = useInternalPlayerLangTranslate(componentsTranslations);
const { label } = descriptor;

const description = entityIs(descriptor, 'ChoiceDescriptor', true)
Expand Down Expand Up @@ -232,7 +237,8 @@ export function ChoiceContainer({
className={
cx(choiceContainerStyle, classNameOrEmpty(className)) +
(hasBeenSelected && !canReply ? ' selected' : '') +
(canReply && !clicked ? '' : ' disabled') +
(canReply ? '' : ' disabled') +
(clicked ? ' loading' : '') +
(isEditing ? ' editing' : '') +
(label && labelText !== '' ? '' : ' no-label') +
(description && descriptionText !== '' ? '' : ' no-desc')
Expand All @@ -248,7 +254,7 @@ export function ChoiceContainer({
{isEditing ? (
<div className={cx(flex, flexColumn, css({ padding: '15px' }))}>
<div className={cx(flex, flexColumn, defaultMarginBottom)}>
<div className={choiceLabelStyle}>Label</div>
<div className={cx(choiceHeaderStyle, 'wegas-question__choice-header')}>Label</div>
<SimpleInput
value={values.label}
onChange={value =>
Expand All @@ -259,18 +265,17 @@ export function ChoiceContainer({
{entityIs(descriptor, 'ChoiceDescriptor', true) && (
<>
<div className={cx(flex, flexColumn, defaultMarginBottom)}>
<div className={choiceLabelStyle}>Description</div>
<div className={cx(choiceHeaderStyle, 'wegas-question__choice-header')}>Description</div>
<HTMLEditor
value={values.description}
onChange={value =>
setValues(o => ({ ...o, description: value }))
}
toolbarLayout="player"
// customToolbar="bold italic underline bullist"
/>
</div>
<div className={cx(flex, flexColumn, defaultMarginBottom)}>
<div className={choiceLabelStyle}>Feedback</div>
<div className={cx(choiceHeaderStyle, 'wegas-question__choice-header')}>Feedback</div>
<HTMLEditor
value={values.feedback}
onChange={value =>
Expand Down Expand Up @@ -308,21 +313,28 @@ export function ChoiceContainer({
{label && labelText !== '' && (
<HTMLText
className={cx(
choiceLabelStyle,
choiceHeaderStyle,
stretch,
hasBeenSelected && !canReply ? ' selected' : '',
'wegas-question__choice-label'
)}
text={labelText}
/>
)}
{description && descriptionText !== '' && (
<HTMLText
className={choiceDescriptionStyle}
className={cx(choiceDescriptionStyle, 'wegas-question__choice-description')}
text={descriptionText}
/>
)}
{canReply && validateButton && (
<div className={choiceButtonStyle}>

<div className={cx(choiceButtonStyle, 'wegas-question__choice-button')}>
{replyCount !== undefined && (
<p className={css({ opacity: 0.5, marginRight: 8 })}>
{replyCount}x
</p>
)}
{canReply && validateButton && (
<Button
style={{ float: 'right' }}
onClick={async () => {
Expand All @@ -335,8 +347,8 @@ export function ChoiceContainer({
>
{i18nValues.question.validate}
</Button>
</div>
)}
)}
</div>
</div>
{children && (
<div
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import {css, cx} from '@emotion/css';
import { css, cx } from '@emotion/css';
import * as React from 'react';
import {
IChoiceDescriptor,
IChoiceInstance,
IQuestionDescriptor,
IQuestionInstance,
IReply,
IWhQuestionDescriptor,
} from 'wegas-ts-api';
import { entityIs } from '../../../data/entities';
Expand All @@ -18,20 +17,22 @@ import { deepDifferent } from '../../Hooks/storeHookFactory';
import { CbxQuestionDisplay } from './CbxQuestion';
import { SimpleQuestionDisplay } from './SimpleQuestionDisplay';
import { WhQuestionDisplay, whQuestionInfo } from './WhQuestionDisplay';
import {defaultEntityDisplay} from "../../EntityChooser";
import { defaultEntityDisplay } from '../../EntityChooser';

export interface QuestionInfo {
questionD?: Readonly<IQuestionDescriptor>;
questionI?: Readonly<IQuestionInstance> | undefined;
choicesD: Readonly<IChoiceDescriptor>[];
choicesI: (Readonly<IChoiceInstance> | undefined)[];
replies: Readonly<IReply[]>;
}

export const questionStyle = css({
marginRight: 'auto',
marginLeft: 'auto',
});
export const questionStyle = cx(
css({
marginRight: 'auto',
marginLeft: 'auto',
}),
'wegas-question',
);

/**
* Query subtree / instance about a QuestionDescriptor
Expand All @@ -54,14 +55,6 @@ export function questionInfo(question: IQuestionDescriptor) {
questionI: getInstance(question),
choicesD: choicesD || [],
choicesI,
replies: (choicesI || [])
.reduce<IReply[]>((c, i) => {
if (i == null) {
return c;
}
return c.concat(i.replies);
}, [])
.sort((a, b) => a.createdTime - b.createdTime),
};
};
}
Expand Down Expand Up @@ -129,22 +122,22 @@ export function ConnectedQuestionDisplay({
editMode,
}: ConnectedQuestionDisplayProps) {
return (
<div className={cx(defaultEntityDisplay)}>
{entityIs(entity, 'QuestionDescriptor') ? (
<ConnectedSimpleQuestionDisplay
entity={entity}
disabled={disabled}
readOnly={readOnly}
editMode={editMode}
/>
) : (
<ConnectedWhQuestionDisplay
entity={entity}
disabled={disabled}
readOnly={readOnly}
editMode={editMode}
/>
)}
</div>
)
<div className={cx(defaultEntityDisplay)}>
{entityIs(entity, 'QuestionDescriptor') ? (
<ConnectedSimpleQuestionDisplay
entity={entity}
disabled={disabled}
readOnly={readOnly}
editMode={editMode}
/>
) : (
<ConnectedWhQuestionDisplay
entity={entity}
disabled={disabled}
readOnly={readOnly}
editMode={editMode}
/>
)}
</div>
);
}
Loading

0 comments on commit 024999f

Please sign in to comment.