Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added hints to get complete guides by url #431

Merged
merged 9 commits into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions backend/src/controllers/guide.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ const bannerService = require("../service/banner.service");
const guidelogService = require("../service/guidelog.service");
const helperLinkService = require("../service/helperLink.service");
const popupService = require("../service/popup.service");
const hintService = require("../service/hint.service");
const { internalServerError } = require("../utils/errors.helper");

class GuideController {
async getGuidesByUrl(req, res) {
try {
Expand All @@ -11,12 +13,13 @@ class GuideController {
if (!url || typeof url !== 'string') {
return res.status(400).json({ errors: [{ msg: "URL is missing or invalid" }] });
}
const [banner, popup, helperLink] = await Promise.all([
const [banner, popup, hint, helperLink] = await Promise.all([
bannerService.getBannerByUrl(url),
popupService.getPopupByUrl(url),
hintService.getHintByUrl(url),
helperLinkService.getAllHelpersWithLinks(),
]);
res.status(200).json({ banner, popup, helperLink });
res.status(200).json({ banner, popup, hint, helperLink });
} catch (error) {
internalServerError(
"GET_GUIDES_BY_URL_ERROR",
Expand All @@ -36,22 +39,25 @@ class GuideController {
return res.status(400).json({ errors: [{ msg: "userId is missing or invalid" }] });
}

const [completePopupLogs, completeBannerLogs, completeHelperLogs] = await Promise.all([
const [completePopupLogs, completeBannerLogs, completeHintLogs, completeHelperLogs] = await Promise.all([
guidelogService.getCompletePopupLogs(userId),
guidelogService.getCompleteBannerLogs(userId),
guidelogService.getCompleteHintLogs(userId),
guidelogService.getCompleteHelperLogs(userId),
]);

const popupIds = completePopupLogs.map(log => log.guideId);
const bannerIds = completeBannerLogs.map(log => log.guideId);
const hintIds = completeHintLogs.map(log => log.guideId);
const helperLinkIds = completeHelperLogs.map(log => log.guideId);

const [banner, popup, helperLink] = await Promise.all([
bannerService.getIncompleteBannersByUrl(url, bannerIds),
const [popup, banner, hint, helperLink] = await Promise.all([
popupService.getIncompletePopupsByUrl(url, popupIds),
bannerService.getIncompleteBannersByUrl(url, bannerIds),
hintService.getIncompleteHintsByUrl(url, hintIds),
helperLinkService.getIncompleteHelpers(helperLinkIds),
]);
res.status(200).json({ banner, popup, helperLink });
res.status(200).json({popup, banner, hint, helperLink });

} catch (error) {
internalServerError(
Expand Down
5 changes: 5 additions & 0 deletions backend/src/models/Hint.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ module.exports = (sequelize, DataTypes) => {
isIn: [["no action", "open url", "open url in a new tab"]],
},
},
url: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: "",
},
actionButtonUrl: {
type: DataTypes.STRING,
allowNull: true,
Expand Down
2 changes: 1 addition & 1 deletion backend/src/routes/hint.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ router.put("/edit_hint/:hintId", authenticateJWT, accessGuard(teamPermissions.hi
router.get("/all_hints", authenticateJWT, hintController.getAllHints);
router.get("/hints", authenticateJWT, hintController.getHints);
router.get("/get_hint/:hintId", authenticateJWT, hintController.getHintById);
// router.get("/get_hint_by_url", hintController.getHintByUrl);
router.get("/get_hint_by_url", hintController.getHintByUrl);

module.exports = router;
2 changes: 1 addition & 1 deletion backend/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ sequelize
.catch((err) => console.log("Error: " + err));

sequelize
.sync({ force: false })
.sync({ alter: true })
.then(() => console.log("Models synced with the database..."))
.catch((err) => console.log("Error syncing models: " + err));

Expand Down
13 changes: 13 additions & 0 deletions backend/src/service/guidelog.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ class GuideLogService {
throw new Error(`Failed to retrieve popup log for user ${userId}: ${err.message}`);
}
}
async getCompleteHintLogs(userId) {
try {
return await GuideLog.findAll({
where: {
userId: userId,
completed: true,
guideType: GuideType.HINT
},
});
} catch (err) {
throw new Error(`Failed to retrieve hint log for user ${userId}: ${err.message}`);
}
}

async getCompleteHelperLogs(userId) {
try {
Expand Down
14 changes: 14 additions & 0 deletions backend/src/service/hint.service.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const db = require("../models");
const Hint = db.Hint;
const { Op } = require("sequelize");

class HintService {
async getAllHints() {
Expand Down Expand Up @@ -77,6 +78,19 @@ class HintService {
throw new Error("Error retrieving Hint by URL");
}
};

async getIncompleteHintsByUrl(url, ids) {
try {
return await Hint.findAll({
where: {
url,
id: { [Op.notIn]: ids }
}
});
} catch (error) {
throw new Error("Error retrieving hint by URL");
}
};
erenfn marked this conversation as resolved.
Show resolved Hide resolved
}

module.exports = new HintService();
1 change: 1 addition & 0 deletions backend/src/test/e2e/hint.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ describe("E2e tests hint", () => {
"createdBy",
"creator",
"header",
"url",
"targetElement",
"tooltipPlacement",
]);
Expand Down
1 change: 1 addition & 0 deletions backend/src/test/mocks/hint.mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class HintBuilder {
tooltipPlacement: "top",
hintContent: "content",
header: "header",
url: "",
headerBackgroundColor: "#FFFFFF",
headerColor: "#000000",
textColor: "#000000",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import DropdownList from "../../DropdownList/DropdownList";
import CustomTextField from "../../TextFieldComponents/CustomTextField/CustomTextField";
import "./HintLeftContent.css";

const HintLeftContent = ({ actionButtonText, setActionButtonText, actionButtonUrl, setActionButtonUrl, action, setAction, targetElement, setTargetElement, tooltipPlacement, setTooltipPlacement }) => {
const HintLeftContent = ({ actionButtonText, setActionButtonText, actionButtonUrl, setActionButtonUrl, action, setAction, targetElement, setTargetElement, tooltipPlacement, setTooltipPlacement, setUrl, url }) => {
const handleActionButtonText = (event) => {
setActionButtonText(event.target.value);
};
const handleActionButtonUrl = (event) => {
setActionButtonUrl(event.target.value);
};
const handleUrl = (event) => {
setUrl(event.target.value);
};
const handleActionChange = (newAction) => {
setAction(newAction);
};
Expand All @@ -24,6 +27,14 @@ const HintLeftContent = ({ actionButtonText, setActionButtonText, actionButtonUr

return (
<div className="left-content-container">
<h2 className="hint-label" style={{ marginBottom: 0, marginTop: "16px" }}>
Url (can be relative)
</h2>
<CustomTextField
TextFieldWidth="241px"
value={url}
onChange={handleUrl}
/>
<h2 className="hint-label" style={{ marginTop: "16px" }}>
Action
</h2>
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/scenes/hints/CreateHintPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ const HintPage = ({ autoOpen = false, isEdit, itemId, setItemsUpdated }) => {
const [header, setHeader] = useState("");
const [content, setContent] = useState("");
const markdownContent = new Turndown().turndown(content);


const [url, setUrl] = useState("https://");
const [actionButtonUrl, setActionButtonUrl] = useState("https://");
const [actionButtonText, setActionButtonText] = useState("Take me to subscription page");
const [action, setAction] = useState("No action");
Expand Down Expand Up @@ -76,6 +77,7 @@ const HintPage = ({ autoOpen = false, isEdit, itemId, setItemsUpdated }) => {
setHeader(hintData.header || "");
setContent(hintData.hintContent || "");
setActionButtonUrl(hintData.actionButtonUrl || "https://");
setUrl(hintData.url || "https://");
setActionButtonText(hintData.actionButtonText || "");
setAction(hintData.action || "No action");
} catch (error) {
Expand All @@ -89,6 +91,7 @@ const HintPage = ({ autoOpen = false, isEdit, itemId, setItemsUpdated }) => {
const onSave = async () => {
const hintData = {
tooltipPlacement: tooltipPlacement.toLowerCase(),
url,
actionButtonUrl,
actionButtonText,
action: action.toLowerCase(),
Expand Down Expand Up @@ -157,6 +160,8 @@ const HintPage = ({ autoOpen = false, isEdit, itemId, setItemsUpdated }) => {
setActionButtonText={setActionButtonText}
actionButtonUrl={actionButtonUrl}
setActionButtonUrl={setActionButtonUrl}
setUrl={setUrl}
url={url}
action={action}
setAction={setAction}
targetElement={targetElement}
Expand Down
Loading