@crazy-web/feedback
Version:
A feedback form handler package that shows a popup based on allowed URLs.
251 lines (246 loc) • 13.7 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.updatedSelectedCardComments = exports.commentSubmit = exports.onFeedbackCardClick = exports.renderComments = exports.renderFeedbackDetails = void 0;
const config_1 = require("../core/lib/config");
const fetchIdeasComments_1 = require("../core/usecases/fetchIdeasComments");
const submitIdeaComment_1 = require("../core/usecases/submitIdeaComment");
const checkIsDarkMode_1 = require("./reuseables/checkIsDarkMode");
const closeIcon_1 = require("./reuseables/closeIcon");
const comentBox_1 = require("./reuseables/comentBox");
const featureCard_1 = require("./reuseables/featureCard");
const renderFeedbackDetails = (selectedCard, data) => {
const { config, orgData } = data;
const { primaryColor = config_1.configData === null || config_1.configData === void 0 ? void 0 : config_1.configData.primaryColor, theme = config_1.configData === null || config_1.configData === void 0 ? void 0 : config_1.configData.theme } = config !== null && config !== void 0 ? config : {};
const isDarkMode = (0, checkIsDarkMode_1.checkIsDarkMode)({ theme });
const { userData } = orgData;
const sliderBackgroundColor = isDarkMode ? "#1B1D21" : "#F8F9FA";
const sliderBorderColor = isDarkMode ? "#313337" : "#E5E7EB";
const backgroundColor = "#fff";
const textColor = "#474747";
const commentHeadingColor = isDarkMode ? "#D2D3E0" : "#303540";
const fieldBg = isDarkMode ? "#222429" : "#FFFFFF";
const fieldTextColor = isDarkMode ? "#FAFAFA" : "#303540";
const fieldBorder = isDarkMode ? "1px solid #52526F40" : "1px solid #E5E7EB";
return `
<div
id="prodio-feedback-details-comment"
class="prodio-feedback-card-animate prodio-feedback-hidden-scrollbar"
style="position:fixed;top:0;right:0;height:100%;width:400px;z-index:13;background-color:${sliderBackgroundColor};overflow-y:auto;padding:15px;"
>
<span type="button" id="close-feedback-btn"
style="cursor: pointer; z-index: 25; width: max-content;position:absolute;right:25px;top:25px;">
${(0, closeIcon_1.renderCloseIcon)({ stroke: isDarkMode ? "#9FA1A7" : "#718096", size: "20" })}
</span>
${(0, featureCard_1.FeatureCards)(selectedCard, 2, "detail", primaryColor, 1, isDarkMode)}
<hr style="height:0.2px;border:none; background: ${sliderBorderColor};margin:15px -15px 0 -15px;"/>
<div style="display:flex;flex-direction:column;gap:10px;padding:10px 0px 20px 0px;">
<h3 id="prodio-ideas-comment-count-${selectedCard.id}" style="font-weight:700;font-size:18px;color:${commentHeadingColor};margin:0;padding:0;margin-bottom:5px;">Add a comment</h3>
<div style="display:flex;gap:8px; width:100%;">
<div style="display:flex;flex-direction:column;gap:20px; width:100%;">
<textarea type="text" id="prodio-ideas-comment" placeholder="Add a comment..." autocomplete="off"
style="padding: 6px 8px;font-size:14px; border-radius: 5px;border: ${fieldBorder}; outline: none; background: ${fieldBg}; color: ${fieldTextColor};"
rows="2"
></textarea>
<button id="prodio-ideas-comment-submit" style="padding: 5px 20px;border: none; width:max-content; background-color: ${primaryColor}; border-radius: 5px; color: #fff; font-size: 14px; cursor: pointer;">
Submit
</button>
</div>
</div>
</div>
<hr style="height:0.2px;border:none; background: ${sliderBorderColor};margin:0 0 15px 0"/>
<h3 id="prodio-ideas-comment-count-${selectedCard.id}" style="font-weight:700;font-size:18px;color:${commentHeadingColor};margin:0;padding:0;margin-bottom:20px;">Comments (${selectedCard.comments})</h3>
<div id="prodio-ideas-comment-list" style="display:flex;flex-direction:column;gap:15px;"></div>
</div>
`;
};
exports.renderFeedbackDetails = renderFeedbackDetails;
// export const renderComments = async (resetData: boolean = false, selectedCard: any) => {
// let currentPage = 1;
// let isFetching = false;
// let hasMoreData = true;
// const container = document.getElementById("prodio-feedback-details-comment");
// const commentsContainer = document.getElementById("prodio-ideas-comment-list")
// if (!container || !commentsContainer) return;
// if (resetData) {
// currentPage = 1;
// hasMoreData = true;
// commentsContainer.innerHTML = ""; // Clear previous feedbacks
// }
// const loadMoreComments = async () => {
// if (isFetching || !hasMoreData) return;
// isFetching = true;
// const res = await fetchIdeasComments({ feedbackId: selectedCard?.id, page: currentPage });
// const comments = res?.data || [];
// if (comments.length > 0) {
// const fragment = document.createDocumentFragment();
// comments.forEach((comment: any, index: number) => {
// const card = document.createElement("div");
// card.innerHTML = renderCommentBox(comment);
// card.setAttribute("data-comment", JSON.stringify(comment)); // Store ID for delegation
// fragment.appendChild(card);
// });
// commentsContainer.appendChild(fragment); // Append all at once
// currentPage++; // Move to next page
// } else {
// hasMoreData = false; // Stop fetching if no more data
// }
// isFetching = false;
// };
// await loadMoreComments(); // Load initial feedbacks
// const handleScroll = async () => {
// const nearBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - 20;
// if (nearBottom) {
// await loadMoreComments();
// }
// };
// setTimeout(() => {
// container.addEventListener("scroll", handleScroll);
// }, 100);
// }
// <span style="aspect-ratio:1;display:flex;justify-content:center;align-items:center;width:30px;height:30px;background-color:${generateRandomColors({ string: userData?.name })};color:white;font-size:14px;border-radius:50px;"> ${userData?.name ? userData?.name[0] : "A"}</span>
const renderComments = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (resetData = false, selectedCard, primaryColor, isDarkMode) {
let currentPage = 1;
let isFetching = false;
let hasMoreData = true;
const container = document.getElementById("prodio-feedback-details-comment");
const commentsContainer = document.getElementById("prodio-ideas-comment-list");
if (!container || !commentsContainer)
return;
// Remove existing comments if reset is requested
if (resetData) {
currentPage = 1;
hasMoreData = true;
commentsContainer.innerHTML = ""; // Clear previous feedbacks
}
// Add loading spinner only on first render
let loadingIndicator = commentsContainer.querySelector(".prodio-spinner-container");
if (!loadingIndicator) {
loadingIndicator = document.createElement("div");
loadingIndicator.classList.add("prodio-spinner-container");
loadingIndicator.innerHTML = `<div class="prodio-spinner"></div>`;
commentsContainer.appendChild(loadingIndicator);
}
const loadMoreComments = () => __awaiter(void 0, void 0, void 0, function* () {
if (isFetching || !hasMoreData)
return;
isFetching = true;
// Show loader only for the first render, hide it after data is fetched
if (currentPage === 1)
loadingIndicator.style.display = "flex";
try {
const res = yield (0, fetchIdeasComments_1.fetchIdeasComments)({ feedbackId: selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.id, page: currentPage });
const comments = (res === null || res === void 0 ? void 0 : res.data) || [];
if (comments.length > 0) {
const fragment = document.createDocumentFragment();
comments.forEach((comment) => {
const card = document.createElement("div");
card.innerHTML = (0, comentBox_1.renderCommentBox)(comment, primaryColor, isDarkMode);
card.setAttribute("data-comment", JSON.stringify(comment));
fragment.appendChild(card);
});
commentsContainer.appendChild(fragment);
currentPage++;
}
else {
hasMoreData = false;
// Show "No comments found" only if it's the first page
if (currentPage === 1) {
commentsContainer.innerHTML = "<div class='prodio-no-data'>No comments found.</div>";
}
}
}
catch (error) {
console.error("Error fetching comments:", error);
}
finally {
isFetching = false;
loadingIndicator.style.display = "none"; // Hide loader after fetching first batch
}
});
yield loadMoreComments(); // Load initial comments
const handleScroll = () => __awaiter(void 0, void 0, void 0, function* () {
const nearBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - 20;
if (nearBottom) {
yield loadMoreComments();
}
});
setTimeout(() => {
container.addEventListener("scroll", handleScroll);
}, 100);
});
exports.renderComments = renderComments;
const onFeedbackCardClick = (selectedCard, data, primaryColor, isDarkMode) => {
document.addEventListener("click", (event) => {
const target = event.target;
const feedbackDetails = document.getElementById("feedback-details");
const card = target.closest(".prodio-feedback-card");
const closeBtn = target.closest("#close-feedback-btn"); // Checks if span or any of its children is clicked
if (card && feedbackDetails && !selectedCard) {
const feedbackData = JSON.parse(card.getAttribute("data-feedback") || "{}");
selectedCard = feedbackData;
feedbackDetails.style.display = "block";
feedbackDetails.innerHTML = (0, exports.renderFeedbackDetails)(feedbackData, data);
(0, exports.renderComments)(false, selectedCard, primaryColor, isDarkMode);
(0, exports.commentSubmit)(selectedCard, data, primaryColor, isDarkMode);
(0, comentBox_1.handleDeleteIdeasComment)(selectedCard, primaryColor, isDarkMode);
}
if (closeBtn && feedbackDetails) {
feedbackDetails.style.display = "none";
selectedCard = null;
}
});
};
exports.onFeedbackCardClick = onFeedbackCardClick;
const commentSubmit = (selectedCard, data, primaryColor, isDarkMode) => {
var _a;
(_a = document.getElementById("prodio-ideas-comment-submit")) === null || _a === void 0 ? void 0 : _a.addEventListener("click", () => __awaiter(void 0, void 0, void 0, function* () {
const submitButton = document.getElementById("prodio-ideas-comment-submit");
const contentInput = document.getElementById("prodio-ideas-comment");
const content = contentInput.value;
if (content) {
const { orgData } = data;
const { userData } = orgData;
const { id, name } = userData;
submitButton.disabled = true;
submitButton.classList.add("prodio-disabled-btn");
const dataToSend = {
issue_id: selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.id,
content: content,
user_id: id,
user_name: name
};
(0, submitIdeaComment_1.submitIdeaComment)(dataToSend).then((res) => {
(0, exports.renderComments)(true, selectedCard, primaryColor, isDarkMode);
contentInput.value = "";
submitButton.disabled = false;
submitButton.classList.remove("prodio-disabled-btn");
(0, exports.updatedSelectedCardComments)(selectedCard, "increment", primaryColor, isDarkMode);
});
}
}));
};
exports.commentSubmit = commentSubmit;
const updatedSelectedCardComments = (selectedCard, type, primaryColor, isDarkMode) => {
const updatedValue = type === "increment" ? selectedCard.comments + 1 : selectedCard.comments - 1;
const count = document.getElementById(`prodio-ideas-comment-count-${selectedCard.id}`);
if (count) {
count.innerHTML = `Comments (${updatedValue})`;
}
selectedCard.comments = updatedValue;
const cardToUpdate = document.querySelector(`[data-feedback-id="${selectedCard.id}"]`);
const updatedFeedback = Object.assign(Object.assign({}, selectedCard), { comments: updatedValue });
if (cardToUpdate) {
cardToUpdate.innerHTML = (0, featureCard_1.FeatureCards)(updatedFeedback, 0, "card", primaryColor, 1, isDarkMode);
cardToUpdate.setAttribute("data-feedback", JSON.stringify(updatedFeedback));
}
};
exports.updatedSelectedCardComments = updatedSelectedCardComments;