Skip to content

Commit

Permalink
Merge pull request #516 from bluewave-labs/501-add-repetition-to-hints
Browse files Browse the repository at this point in the history
501 add repetition to hints
  • Loading branch information
erenfn authored Jan 23, 2025
2 parents 5d9cce0 + 7c03a9b commit ab3bb40
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 2 deletions.
1 change: 1 addition & 0 deletions backend/config/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module.exports = {
},
hint: {
action: ['no action', 'open url', 'open url in a new tab'],
repetition: ['show only once', 'show every visit'],
tooltipPlacement: ['top', 'right', 'bottom', 'left'],
},
popup: {
Expand Down
7 changes: 6 additions & 1 deletion backend/migrations/0006-1.0-hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ module.exports = {
primaryKey: true,
type: Sequelize.INTEGER,
},
action: {
repetitionType: {
type: Sequelize.STRING(255),
allowNull: false,
defaultValue: 'show only once'
},
action: {
type: Sequelize.STRING(255),
allowNull: false,
},
Expand Down
7 changes: 7 additions & 0 deletions backend/src/models/Hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ module.exports = (sequelize, DataTypes) => {
isIn: [settings.hint.action],
},
},
repetitionType: {
type: DataTypes.STRING,
allowNull: false,
validate: {
isIn: [['show only once', 'show every visit']]
},
},
url: {
type: DataTypes.STRING,
allowNull: true,
Expand Down
25 changes: 25 additions & 0 deletions backend/src/test/e2e/hint.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,30 @@ describe('E2e tests hint', () => {
errors: ['Invalid value for action'],
});
});
it('should return 400 if repetitionType is missing', async () => {
const res = await chai.request
.execute(app)
.post('/api/hint/add_hint')
.set('Authorization', `Bearer ${token}`)
.send(hint().missingRepetitionType().build());
expect(res).to.have.status(400);
expect(res.body).to.be.deep.equal({
errors: ['Invalid value', 'RepetitionType is required', 'Invalid value for repetitionType'],
});
});
it('should return 400 if repetitionType is invalid', async () => {
const res = await chai.request
.execute(app)
.post('/api/hint/add_hint')
.set('Authorization', `Bearer ${token}`)
.send({
...hint().invalidRepetitionType().build(),
});
expect(res).to.have.status(400);
expect(res.body).to.be.deep.equal({
errors: ['Invalid value for repetitionType']
});
});
it('should return 400 if headerBackgroundColor is invalid', async () => {
const res = await chai.request
.execute(app)
Expand Down Expand Up @@ -464,6 +488,7 @@ describe('E2e tests hint', () => {
expect(it).to.have.all.keys([
'id',
'action',
'repetitionType',
'hintContent',
'actionButtonText',
'actionButtonUrl',
Expand Down
11 changes: 11 additions & 0 deletions backend/src/test/mocks/hint.mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class HintBuilder {
this.hint = {
id,
action: "open url in a new tab",
repetitionType: "show only once",
actionButtonUrl: "/url",
actionButtonText: "text",
targetElement: ".element",
Expand Down Expand Up @@ -33,6 +34,16 @@ class HintBuilder {
return this;
}

missingRepetitionType() {
this.hint.repetitionType = undefined;
return this;
}

invalidRepetitionType() {
this.hint.repetitionType = "invalid repetition type";
return this;
}

invalidHeaderBackgroundColor() {
this.hint.headerBackgroundColor = "invalid";
return this;
Expand Down
8 changes: 8 additions & 0 deletions backend/src/utils/hint.helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ const hintValidator = [
createColorValidator('textColor'),
createColorValidator('buttonBackgroundColor'),
createColorValidator('buttonTextColor'),
body('repetitionType')
.isString()
.notEmpty()
.withMessage('RepetitionType is required')
.custom((value) => {
return settings.hint.repetition.includes(value);
})
.withMessage('Invalid value for repetitionType'),
body('url')
.optional()
.isString()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Form, Formik } from 'formik';
import React from 'react';
import PropTypes from 'prop-types';
import { newHintSchema } from '../../../utils/hintHelper';
import DropdownList from '../../DropdownList/DropdownList';
import CustomTextField from '../../TextFieldComponents/CustomTextField/CustomTextField';
import './HintLeftContent.css';

const HintLeftContent = ({
buttonRepetition,
setButtonRepetition,
actionButtonText,
setActionButtonText,
actionButtonUrl,
Expand All @@ -20,6 +23,11 @@ const HintLeftContent = ({
url,
onSave,
}) => {

const handleRepetitionChange = (newRepetitionType) => {
setButtonRepetition(newRepetitionType);
};

const handleActionButtonText = (event) => {
setActionButtonText(event.target.value);
};
Expand Down Expand Up @@ -75,7 +83,18 @@ const HintLeftContent = ({
<Form className="left-content-container">
<h2
className="hint-label"
style={{ marginBottom: 0, marginTop: '16px' }}
style={{ marginBottom: '0.2rem', marginTop: '1.2rem' }}
>
Repetition
</h2>
<DropdownList
actions={['Show only once', 'Show every visit']}
onActionChange={handleRepetitionChange}
selectedActionString={buttonRepetition}
/>
<h2
className="hint-label"
style={{ marginBottom: 0, marginTop: '1rem' }}
>
Url (can be relative)
</h2>
Expand Down Expand Up @@ -184,4 +203,22 @@ const HintLeftContent = ({
);
};

HintLeftContent.proptype = {
buttonRepetition: PropTypes.string,
setButtonRepetition: PropTypes.func,
actionButtonText: PropTypes.string,
setActionButtonText: PropTypes.func,
actionButtonUrl: PropTypes.string,
setActionButtonUrl: PropTypes.func,
action: PropTypes.string,
setAction: PropTypes.func,
targetElement: PropTypes.string,
setTargetElement: PropTypes.func,
tooltipPlacement: PropTypes.string,
setTooltipPlacement: PropTypes.func,
url: PropTypes.string,
setUrl: PropTypes.func,
onSave: PropTypes.func,
}

export default HintLeftContent;
8 changes: 8 additions & 0 deletions frontend/src/scenes/hints/CreateHintPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const HintPage = ({
const [content, setContent] = useState('');
const markdownContent = new Turndown().turndown(content);

const [buttonRepetition, setButtonRepetition] = useState('show only once');

const [url, setUrl] = useState('https://');
const [actionButtonUrl, setActionButtonUrl] = useState('https://');
const [actionButtonText, setActionButtonText] = useState(
Expand All @@ -62,13 +64,15 @@ const HintPage = ({
const fetchHintData = async () => {
try {
const hintData = await getHintById(itemId);

setAppearance({
headerBackgroundColor: hintData.headerBackgroundColor || '#F8F9F8',
headerColor: hintData.headerColor || '#101828',
textColor: hintData.textColor || '#344054',
buttonBackgroundColor: hintData.buttonBackgroundColor || '#7F56D9',
buttonTextColor: hintData.buttonTextColor || '#FFFFFF',
});
setButtonRepetition(hintData.repetitionType || 'Show only once')
setHeader(hintData.header || '');
setContent(hintData.hintContent || '');
setActionButtonUrl(hintData.actionButtonUrl || 'https://');
Expand All @@ -87,6 +91,7 @@ const HintPage = ({

const onSave = async () => {
const hintData = {
repetitionType: buttonRepetition.toLowerCase(),
tooltipPlacement: tooltipPlacement.toLowerCase(),
url,
actionButtonUrl,
Expand All @@ -101,6 +106,7 @@ const HintPage = ({
buttonBackgroundColor,
buttonTextColor,
};

try {
const response = isEdit
? await editHint(itemId, hintData)
Expand Down Expand Up @@ -160,6 +166,8 @@ const HintPage = ({
)}
leftContent={() => (
<HintLeftContent
buttonRepetition={buttonRepetition}
setButtonRepetition={setButtonRepetition}
actionButtonText={actionButtonText}
setActionButtonText={setActionButtonText}
actionButtonUrl={actionButtonUrl}
Expand Down

0 comments on commit ab3bb40

Please sign in to comment.