IO-3223 Add Canny for feature request and change log.

This commit is contained in:
Patrick Fic
2025-04-25 14:02:40 -07:00
parent e015d3574a
commit b5973085e7
16 changed files with 5256 additions and 2409 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -74,50 +74,8 @@
})();
</script>
<% } %>
<script>
!(function () {
"use strict";
var e = [
"debug",
"destroy",
"do",
"help",
"identify",
"is",
"off",
"on",
"ready",
"render",
"reset",
"safe",
"set"
];
if (window.noticeable) console.warn("Noticeable SDK code snippet loaded more than once");
else {
var n = (window.noticeable = window.noticeable || []);
<script>!function(w,d,i,s){function l(){if(!d.getElementById(i)){var f=d.getElementsByTagName(s)[0],e=d.createElement(s);e.type="text/javascript",e.async=!0,e.src="https://canny.io/sdk.js",f.parentNode.insertBefore(e,f)}}if("function"!=typeof w.Canny){var c=function(){c.q.push(arguments)};c.q=[],w.Canny=c,"complete"===d.readyState?l():w.attachEvent?w.attachEvent("onload",l):w.addEventListener("load",l,!1)}}(window,document,"canny-jssdk","script");</script>
function t(e) {
return function () {
var t = Array.prototype.slice.call(arguments);
return t.unshift(e), n.push(t), n;
};
}
!(function () {
for (var o = 0; o < e.length; o++) {
var r = e[o];
n[r] = t(r);
}
})(),
(function () {
var e = document.createElement("script");
(e.async = !0), (e.src = "https://sdk.noticeable.io/l.js");
var n = document.head;
n.insertBefore(e, n.firstChild);
})();
}
})();
</script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

2893
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -113,7 +113,7 @@ export function UpdateAlert({ updateAvailable }) {
</Col>
<Col sm={24} md={8} lg={6}>
<Space wrap>
<Button onClick={() => window.open("https://imex-online.noticeable.news/", "_blank")}>
<Button onClick={() => window.open("https://shopmanagement.canny.io/changelog", "_blank")}>
{i18n.t("general.actions.viewreleasenotes")}
</Button>
<Button loading={loading} type="primary" onClick={() => ReloadNewVersion()}>

View File

@@ -0,0 +1,42 @@
import axios from "axios";
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { setBreadcrumbs, setSelectedHeader } from "../../redux/application/application.actions";
import InstanceRenderManager from "../../utils/instanceRenderMgr";
const mapDispatchToProps = (dispatch) => ({
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
setSelectedHeader: (key) => dispatch(setSelectedHeader(key))
});
export function FeedbackPage({ setBreadcrumbs, setSelectedHeader }) {
const { t } = useTranslation();
useEffect(() => {
document.title = t("titles.feature-request", {
app: InstanceRenderManager({
imex: "$t(titles.imexonline)",
rome: "$t(titles.romeonline)"
})
});
setBreadcrumbs([{ link: "/manage/feature-request", label: t("titles.bc.feature-request") }]);
}, [t, setBreadcrumbs, setSelectedHeader]);
useEffect(() => {
async function RenderCanny() {
const ssoToken = await axios.post("/sso/canny");
window.Canny("render", {
boardToken: "bba97b06-70db-0334-dee7-8108d73ef614",
basePath: `/manage/feature-request`, // See step 2
ssoToken: ssoToken.data, // See step 3,
theme: "light" // options: light [default], dark, auto
});
}
RenderCanny();
}, []);
return <div data-canny />;
}
export default connect(null, mapDispatchToProps)(FeedbackPage);

View File

@@ -1,4 +1,5 @@
import { FloatButton, Layout, Spin } from "antd";
import { Button, FloatButton, Layout, Space, Spin } from "antd";
import { AlertOutlined, BulbOutlined } from "@ant-design/icons";
// import preval from "preval.macro";
import React, { lazy, Suspense, useEffect, useState } from "react";
@@ -19,7 +20,6 @@ import LoadingSpinner from "../../components/loading-spinner/loading-spinner.com
import PartnerPingComponent from "../../components/partner-ping/partner-ping.component";
import PrintCenterModalContainer from "../../components/print-center-modal/print-center-modal.container";
import ShopSubStatusComponent from "../../components/shop-sub-status/shop-sub-status.component";
import { requestForToken } from "../../firebase/firebase.utils";
import { selectBodyshop, selectInstanceConflict } from "../../redux/user/user.selectors";
import UpdateAlert from "../../components/update-alert/update-alert.component";
import InstanceRenderManager from "../../utils/instanceRenderMgr.js";
@@ -56,6 +56,7 @@ const ContractCreatePage = lazy(() => import("../contract-create/contract-create
const ContractDetailPage = lazy(() => import("../contract-detail/contract-detail.page.container"));
const ContractsList = lazy(() => import("../contracts/contracts.page.container"));
const BillsListPage = lazy(() => import("../bills/bills.page.container"));
const FeatureRequestPage = lazy(() => import("../feature-request/feature-request.page.jsx"));
const JobCostingModal = lazy(() => import("../../components/job-costing-modal/job-costing-modal.container"));
const ReportCenterModal = lazy(() => import("../../components/report-center-modal/report-center-modal.container"));
@@ -180,15 +181,12 @@ export function Manage({ conflict, bodyshop, alerts, setAlerts }) {
});
}
}, [alerts, displayedAlertIds, notification]);
useEffect(() => {
const widgetId = InstanceRenderManager({
imex: "IABVNO4scRKY11XBQkNr",
rome: "mQdqARMzkZRUVugJ6TdS"
});
window.noticeable.render("widget", widgetId);
requestForToken().catch((error) => {
console.error(`Unable to request for token.`, error);
window.Canny("initChangelog", {
appID: "680bd2c7ee501290377f6686",
position: "top",
align: "left",
theme: "light" // options: light [default], dark, auto
});
}, []);
@@ -480,6 +478,8 @@ export function Manage({ conflict, bodyshop, alerts, setAlerts }) {
// element={<ShopTemplates />}
// />
}
<Route path="/feature-request/*" index element={<FeatureRequestPage />} />
<Route
path="/shop/vendors"
element={
@@ -669,7 +669,12 @@ export function Manage({ conflict, bodyshop, alerts, setAlerts }) {
margin: "1rem 0rem"
}}
>
<div style={{ display: "flex" }}>
<Link to="/manage/feature-request">
<Button icon={<BulbOutlined />} type="text">
{t("general.labels.feature-request")}
</Button>
</Link>
<Space>
<WssStatusDisplayComponent />
<div onClick={broadcastMessage}>
{`${InstanceRenderManager({
@@ -677,8 +682,10 @@ export function Manage({ conflict, bodyshop, alerts, setAlerts }) {
rome: t("titles.romeonline")
})} - ${import.meta.env.VITE_APP_GIT_SHA_DATE}`}
</div>
<div id="noticeable-widget" style={{ marginLeft: "1rem" }} />
</div>
<Button icon={<AlertOutlined />} data-canny-changelog type="text">
{t("general.labels.changelog")}
</Button>
</Space>
<Link to="/disclaimer" target="_blank" style={{ color: "#ccc" }}>
Disclaimer & Notices
</Link>

View File

@@ -335,7 +335,6 @@
"intellipay_config": {
"cash_discount_percentage": "Cash Discount %",
"enable_cash_discount": "Enable Cash Discounting",
"payment_type": "Payment Type Map",
"payment_map": {
"amex": "American Express",
"disc": "Discover",
@@ -344,7 +343,8 @@
"jcb": "JCB",
"mast": "MasterCard",
"visa": "Visa"
}
},
"payment_type": "Payment Type Map"
},
"invoice_federal_tax_rate": "Invoices - Federal Tax Rate",
"invoice_local_tax_rate": "Invoices - Local Tax Rate",
@@ -1235,6 +1235,7 @@
"areyousure": "Are you sure?",
"barcode": "Barcode",
"cancel": "Are you sure you want to cancel? Your changes will not be saved.",
"changelog": "Change Log",
"clear": "Clear",
"confirmpassword": "Confirm Password",
"created_at": "Created At",
@@ -1244,6 +1245,7 @@
"errors": "Errors",
"excel": "Excel",
"exceptiontitle": "An error has occurred.",
"feature-request": "Have a feature request?",
"friday": "Friday",
"globalsearch": "Global Search",
"help": "Help",
@@ -1322,9 +1324,9 @@
"notfoundtitle": "We couldn't find what you're looking for...",
"partnernotrunning": "{{app}} has detected that the partner is not running. Please ensure it is running to enable full functionality.",
"rbacunauth": "You are not authorized to view this content. Please reach out to your shop manager to change your access level.",
"submit-for-testing": "Submitted Job for testing successfully.",
"unsavedchanges": "You have unsaved changes.",
"unsavedchangespopup": "You have unsaved changes. Are you sure you want to leave?",
"submit-for-testing": "Submitted Job for testing successfully."
"unsavedchangespopup": "You have unsaved changes. Are you sure you want to leave?"
},
"validation": {
"dateRangeExceeded": "The date range has been exceeded.",
@@ -1760,9 +1762,9 @@
"est_ct_ln": "Estimator Last Name",
"est_ea": "Estimator Email",
"est_ph1": "Estimator Phone #",
"flat_rate_ats": "Flat Rate ATS?",
"federal_tax_payable": "Federal Tax Payable",
"federal_tax_rate": "Federal Tax Rate",
"flat_rate_ats": "Flat Rate ATS?",
"ins_addr1": "Insurance Co. Address",
"ins_city": "Insurance Co. City",
"ins_co_id": "Insurance Co. ID",
@@ -2316,8 +2318,8 @@
"duplicate": "Duplicate this Job",
"duplicatenolines": "Duplicate this Job without Repair Data",
"newcccontract": "Create Courtesy Car Contract",
"void": "Void Job",
"submit-for-testing": "Submit for Testing"
"submit-for-testing": "Submit for Testing",
"void": "Void Job"
},
"jobsdetail": {
"claimdetail": "Claim Details",
@@ -2423,6 +2425,60 @@
"updated": "Note updated successfully."
}
},
"notifications": {
"actions": {
"remove": "Remove"
},
"aria": {
"toggle": "Toggle Watching Job"
},
"channels": {
"app": "App",
"email": "Email",
"fcm": "Push"
},
"labels": {
"add-watchers": "Add Watchers",
"add-watchers-team": "Add Team Members",
"employee-search": "Search for an Employee",
"mark-all-read": "Mark All Read",
"new-notification-title": "New Notification:",
"no-watchers": "No Watchers",
"notification-center": "Notification Center",
"notification-popup-title": "Changes for Job #{{ro_number}}",
"notification-settings-failure": "Error saving Notification Settings. {{error}}",
"notification-settings-success": "Notification Settings saved successfully.",
"notificationscenarios": "Job Notification Scenarios",
"ro-number": "RO #{{ro_number}}",
"save": "Save Scenarios",
"scenario": "Scenario",
"show-unread-only": "Show Unread Only",
"teams-search": "Search for a Team",
"unwatch": "Unwatch",
"watch": "Watch",
"watching-issue": "Watching"
},
"scenarios": {
"alternate-transport-changed": "Alternate Transport Changed",
"bill-posted": "Bill Posted",
"critical-parts-status-changed": "Critical Parts Status Changed",
"intake-delivery-checklist-completed": "Intake or Delivery Checklist Completed",
"job-added-to-production": "Job Added to Production",
"job-assigned-to-me": "Job Assigned to Me",
"job-status-change": "Job Status Changed",
"new-media-added-reassigned": "New Media Added or Reassigned",
"new-note-added": "New Note Added",
"new-time-ticket-posted": "New Time Ticket Posted",
"part-marked-back-ordered": "Part Marked Back Ordered",
"payment-collected-completed": "Payment Collected / Completed",
"schedule-dates-changed": "Schedule Dates Changed",
"supplement-imported": "Supplement Imported",
"tasks-updated-created": "Tasks Updated / Created"
},
"tooltips": {
"job-watchers": "Job Watchers"
}
},
"owner": {
"labels": {
"noownerinfo": "No owner information."
@@ -3419,6 +3475,7 @@
"dashboard": "Dashboard",
"dms": "DMS Export",
"export-logs": "Export Logs",
"feature-request": "Feature Requet",
"inventory": "Inventory",
"jobs": "Jobs",
"jobs-active": "Active Jobs",
@@ -3463,6 +3520,7 @@
"dashboard": "Dashboard | {{app}}",
"dms": "DMS Export | {{app}}",
"export-logs": "Export Logs | {{app}}",
"feature-request": "Feature Request | {{app}}",
"imexonline": "ImEX Online",
"inventory": "Inventory | {{app}}",
"jobs": "Active Jobs | {{app}}",
@@ -3680,10 +3738,10 @@
"users": {
"errors": {
"signinerror": {
"auth/invalid-email": "A user with this email does not exist.",
"auth/user-disabled": "User account disabled. ",
"auth/user-not-found": "A user with this email does not exist.",
"auth/wrong-password": "The email and password combination you provided is incorrect.",
"auth/invalid-email": "A user with this email does not exist."
"auth/wrong-password": "The email and password combination you provided is incorrect."
}
}
},
@@ -3783,60 +3841,6 @@
"validation": {
"unique_vendor_name": "You must enter a unique vendor name."
}
},
"notifications": {
"labels": {
"notification-center": "Notification Center",
"scenario": "Scenario",
"notificationscenarios": "Job Notification Scenarios",
"save": "Save Scenarios",
"watching-issue": "Watching",
"add-watchers": "Add Watchers",
"employee-search": "Search for an Employee",
"teams-search": "Search for a Team",
"add-watchers-team": "Add Team Members",
"new-notification-title": "New Notification:",
"show-unread-only": "Show Unread Only",
"mark-all-read": "Mark All Read",
"notification-popup-title": "Changes for Job #{{ro_number}}",
"ro-number": "RO #{{ro_number}}",
"no-watchers": "No Watchers",
"notification-settings-success": "Notification Settings saved successfully.",
"notification-settings-failure": "Error saving Notification Settings. {{error}}",
"watch": "Watch",
"unwatch": "Unwatch"
},
"actions": {
"remove": "Remove"
},
"aria": {
"toggle": "Toggle Watching Job"
},
"tooltips": {
"job-watchers": "Job Watchers"
},
"scenarios": {
"job-assigned-to-me": "Job Assigned to Me",
"bill-posted": "Bill Posted",
"critical-parts-status-changed": "Critical Parts Status Changed",
"part-marked-back-ordered": "Part Marked Back Ordered",
"new-note-added": "New Note Added",
"supplement-imported": "Supplement Imported",
"schedule-dates-changed": "Schedule Dates Changed",
"tasks-updated-created": "Tasks Updated / Created",
"new-media-added-reassigned": "New Media Added or Reassigned",
"new-time-ticket-posted": "New Time Ticket Posted",
"intake-delivery-checklist-completed": "Intake or Delivery Checklist Completed",
"job-added-to-production": "Job Added to Production",
"job-status-change": "Job Status Changed",
"payment-collected-completed": "Payment Collected / Completed",
"alternate-transport-changed": "Alternate Transport Changed"
},
"channels": {
"app": "App",
"email": "Email",
"fcm": "Push"
}
}
}
}

View File

@@ -335,7 +335,6 @@
"intellipay_config": {
"cash_discount_percentage": "",
"enable_cash_discount": "",
"payment_type": "",
"payment_map": {
"amex": "American Express",
"disc": "Discover",
@@ -344,7 +343,8 @@
"jcb": "JCB",
"mast": "MasterCard",
"visa": "Visa"
}
},
"payment_type": ""
},
"invoice_federal_tax_rate": "",
"invoice_local_tax_rate": "",
@@ -1235,6 +1235,7 @@
"areyousure": "",
"barcode": "código de barras",
"cancel": "",
"changelog": "",
"clear": "",
"confirmpassword": "",
"created_at": "",
@@ -1244,6 +1245,7 @@
"errors": "",
"excel": "",
"exceptiontitle": "",
"feature-request": "",
"friday": "",
"globalsearch": "",
"help": "",
@@ -1322,9 +1324,9 @@
"notfoundtitle": "",
"partnernotrunning": "",
"rbacunauth": "",
"submit-for-testing": "",
"unsavedchanges": "Usted tiene cambios no guardados.",
"unsavedchangespopup": "",
"submit-for-testing": ""
"unsavedchangespopup": ""
},
"validation": {
"dateRangeExceeded": "",
@@ -1760,9 +1762,9 @@
"est_ct_ln": "Apellido del tasador",
"est_ea": "Correo electrónico del tasador",
"est_ph1": "Número de teléfono del tasador",
"flat_rate_ats": "",
"federal_tax_payable": "Impuesto federal por pagar",
"federal_tax_rate": "",
"flat_rate_ats": "",
"ins_addr1": "Dirección de Insurance Co.",
"ins_city": "Ciudad de seguros",
"ins_co_id": "ID de la compañía de seguros",
@@ -2316,8 +2318,8 @@
"duplicate": "",
"duplicatenolines": "",
"newcccontract": "",
"void": "",
"submit-for-testing": ""
"submit-for-testing": "",
"void": ""
},
"jobsdetail": {
"claimdetail": "Detalles de la reclamación",
@@ -2423,6 +2425,60 @@
"updated": "Nota actualizada con éxito."
}
},
"notifications": {
"actions": {
"remove": ""
},
"aria": {
"toggle": ""
},
"channels": {
"app": "",
"email": "",
"fcm": ""
},
"labels": {
"add-watchers": "",
"add-watchers-team": "",
"employee-search": "",
"mark-all-read": "",
"new-notification-title": "",
"no-watchers": "",
"notification-center": "",
"notification-popup-title": "",
"notification-settings-failure": "",
"notification-settings-success": "",
"notificationscenarios": "",
"ro-number": "",
"save": "",
"scenario": "",
"show-unread-only": "",
"teams-search": "",
"unwatch": "",
"watch": "",
"watching-issue": ""
},
"scenarios": {
"alternate-transport-changed": "",
"bill-posted": "",
"critical-parts-status-changed": "",
"intake-delivery-checklist-completed": "",
"job-added-to-production": "",
"job-assigned-to-me": "",
"job-status-change": "",
"new-media-added-reassigned": "",
"new-note-added": "",
"new-time-ticket-posted": "",
"part-marked-back-ordered": "",
"payment-collected-completed": "",
"schedule-dates-changed": "",
"supplement-imported": "",
"tasks-updated-created": ""
},
"tooltips": {
"job-watchers": ""
}
},
"owner": {
"labels": {
"noownerinfo": ""
@@ -3419,6 +3475,7 @@
"dashboard": "",
"dms": "",
"export-logs": "",
"feature-request": "",
"inventory": "",
"jobs": "",
"jobs-active": "",
@@ -3463,6 +3520,7 @@
"dashboard": "",
"dms": "",
"export-logs": "",
"feature-request": "",
"imexonline": "",
"inventory": "",
"jobs": "Todos los trabajos | {{app}}",
@@ -3680,10 +3738,10 @@
"users": {
"errors": {
"signinerror": {
"auth/invalid-email": "",
"auth/user-disabled": "",
"auth/user-not-found": "",
"auth/wrong-password": "",
"auth/invalid-email": ""
"auth/wrong-password": ""
}
}
},
@@ -3783,60 +3841,6 @@
"validation": {
"unique_vendor_name": ""
}
},
"notifications": {
"labels": {
"notification-center": "",
"scenario": "",
"notificationscenarios": "",
"save": "",
"watching-issue": "",
"add-watchers": "",
"employee-search": "",
"teams-search": "",
"add-watchers-team": "",
"new-notification-title": "",
"show-unread-only": "",
"mark-all-read": "",
"notification-popup-title": "",
"ro-number": "",
"no-watchers": "",
"notification-settings-success": "",
"notification-settings-failure": "",
"watch": "",
"unwatch": ""
},
"actions": {
"remove": ""
},
"aria": {
"toggle": ""
},
"tooltips": {
"job-watchers": ""
},
"scenarios": {
"job-assigned-to-me": "",
"bill-posted": "",
"critical-parts-status-changed": "",
"part-marked-back-ordered": "",
"new-note-added": "",
"supplement-imported": "",
"schedule-dates-changed": "",
"tasks-updated-created": "",
"new-media-added-reassigned": "",
"new-time-ticket-posted": "",
"intake-delivery-checklist-completed": "",
"job-added-to-production": "",
"job-status-change": "",
"payment-collected-completed": "",
"alternate-transport-changed": ""
},
"channels": {
"app": "",
"email": "",
"fcm": ""
}
}
}
}

View File

@@ -335,7 +335,6 @@
"intellipay_config": {
"cash_discount_percentage": "",
"enable_cash_discount": "",
"payment_type": "",
"payment_map": {
"amex": "American Express",
"disc": "Discover",
@@ -344,7 +343,8 @@
"jcb": "JCB",
"mast": "MasterCard",
"visa": "Visa"
}
},
"payment_type": ""
},
"invoice_federal_tax_rate": "",
"invoice_local_tax_rate": "",
@@ -1235,6 +1235,7 @@
"areyousure": "",
"barcode": "code à barre",
"cancel": "",
"changelog": "",
"clear": "",
"confirmpassword": "",
"created_at": "",
@@ -1244,6 +1245,7 @@
"errors": "",
"excel": "",
"exceptiontitle": "",
"feature-request": "",
"friday": "",
"globalsearch": "",
"help": "",
@@ -1322,10 +1324,9 @@
"notfoundtitle": "",
"partnernotrunning": "",
"rbacunauth": "",
"submit-for-testing": "",
"unsavedchanges": "Vous avez des changements non enregistrés.",
"unsavedchangespopup": "",
"submit-for-testing": ""
"unsavedchangespopup": ""
},
"validation": {
"dateRangeExceeded": "",
@@ -1761,9 +1762,9 @@
"est_ct_ln": "Nom de l'évaluateur",
"est_ea": "Courriel de l'évaluateur",
"est_ph1": "Numéro de téléphone de l'évaluateur",
"flat_rate_ats": "",
"federal_tax_payable": "Impôt fédéral à payer",
"federal_tax_rate": "",
"flat_rate_ats": "",
"ins_addr1": "Adresse Insurance Co.",
"ins_city": "Insurance City",
"ins_co_id": "ID de la compagnie d'assurance",
@@ -2317,8 +2318,8 @@
"duplicate": "",
"duplicatenolines": "",
"newcccontract": "",
"void": "",
"submit-for-testing": ""
"submit-for-testing": "",
"void": ""
},
"jobsdetail": {
"claimdetail": "Détails de la réclamation",
@@ -2424,6 +2425,60 @@
"updated": "Remarque mise à jour avec succès."
}
},
"notifications": {
"actions": {
"remove": ""
},
"aria": {
"toggle": ""
},
"channels": {
"app": "",
"email": "",
"fcm": ""
},
"labels": {
"add-watchers": "",
"add-watchers-team": "",
"employee-search": "",
"mark-all-read": "",
"new-notification-title": "",
"no-watchers": "",
"notification-center": "",
"notification-popup-title": "",
"notification-settings-failure": "",
"notification-settings-success": "",
"notificationscenarios": "",
"ro-number": "",
"save": "",
"scenario": "",
"show-unread-only": "",
"teams-search": "",
"unwatch": "",
"watch": "",
"watching-issue": ""
},
"scenarios": {
"alternate-transport-changed": "",
"bill-posted": "",
"critical-parts-status-changed": "",
"intake-delivery-checklist-completed": "",
"job-added-to-production": "",
"job-assigned-to-me": "",
"job-status-change": "",
"new-media-added-reassigned": "",
"new-note-added": "",
"new-time-ticket-posted": "",
"part-marked-back-ordered": "",
"payment-collected-completed": "",
"schedule-dates-changed": "",
"supplement-imported": "",
"tasks-updated-created": ""
},
"tooltips": {
"job-watchers": ""
}
},
"owner": {
"labels": {
"noownerinfo": ""
@@ -3420,6 +3475,7 @@
"dashboard": "",
"dms": "",
"export-logs": "",
"feature-request": "",
"inventory": "",
"jobs": "",
"jobs-active": "",
@@ -3464,6 +3520,7 @@
"dashboard": "",
"dms": "",
"export-logs": "",
"feature-request": "",
"imexonline": "",
"inventory": "",
"jobs": "Tous les emplois | {{app}}",
@@ -3681,10 +3738,10 @@
"users": {
"errors": {
"signinerror": {
"auth/invalid-email": "",
"auth/user-disabled": "",
"auth/user-not-found": "",
"auth/wrong-password": "",
"auth/invalid-email": ""
"auth/wrong-password": ""
}
}
},
@@ -3784,60 +3841,6 @@
"validation": {
"unique_vendor_name": ""
}
},
"notifications": {
"labels": {
"notification-center": "",
"scenario": "",
"notificationscenarios": "",
"save": "",
"watching-issue": "",
"add-watchers": "",
"employee-search": "",
"teams-search": "",
"add-watchers-team": "",
"new-notification-title": "",
"show-unread-only": "",
"mark-all-read": "",
"notification-popup-title": "",
"ro-number": "",
"no-watchers": "",
"notification-settings-success": "",
"notification-settings-failure": "",
"watch": "",
"unwatch": ""
},
"actions": {
"remove": ""
},
"aria": {
"toggle": ""
},
"tooltips": {
"job-watchers": ""
},
"scenarios": {
"job-assigned-to-me": "",
"bill-posted": "",
"critical-parts-status-changed": "",
"part-marked-back-ordered": "",
"new-note-added": "",
"supplement-imported": "",
"schedule-dates-changed": "",
"tasks-updated-created": "",
"new-media-added-reassigned": "",
"new-time-ticket-posted": "",
"intake-delivery-checklist-completed": "",
"job-added-to-production": "",
"job-status-change": "",
"payment-collected-completed": "",
"alternate-transport-changed": ""
},
"channels": {
"app": "",
"email": "",
"fcm": ""
}
}
}
}

View File

@@ -14,10 +14,7 @@ const onServiceWorkerUpdate = (registration) => {
<Button
onClick={async () => {
window.open(
InstanceRenderManager({
imex: "https://imex-online.noticeable.news/",
rome: "https://rome-online.noticeable.news/"
}),
`https://shopmanagement.canny.io/changelog`,
"_blank"
);
}}

View File

@@ -15,7 +15,7 @@ const currentDatePST = new Date()
.reverse()
.join("-");
const sentryRelease =
`${import.meta.env.VITE_APP_IS_TEST ? "test" : "production"}-${currentDatePST}-${process.env.VITE_GIT_COMMIT_HASH}`.trim();
`${import.meta.env.VITE_APP_IS_TEST ? "test" : "production"}-${currentDatePST}`.trim();
if (!import.meta.env.DEV) {
Sentry.init({

2929
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -52,6 +52,7 @@
"intuit-oauth": "^4.2.0",
"ioredis": "^5.6.0",
"json-2-csv": "^5.5.9",
"jsonwebtoken": "^9.0.2",
"juice": "^11.0.1",
"lodash": "^4.17.21",
"moment": "^2.30.1",

View File

@@ -117,6 +117,7 @@ const applyRoutes = ({ app }) => {
app.use("/cdk", require("./server/routes/cdkRoutes"));
app.use("/csi", require("./server/routes/csiRoutes"));
app.use("/payroll", require("./server/routes/payrollRoutes"));
app.use("/sso", require("./server/routes/ssoRoutes"));
// Default route for forbidden access
app.get("/", (req, res) => {

View File

@@ -0,0 +1,13 @@
const express = require("express");
const router = express.Router();
const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware");
const withUserGraphQLClientMiddleware = require("../middleware/withUserGraphQLClientMiddleware");
const { cannySsoHandler } = require("../sso/canny");
router.use(validateFirebaseIdTokenMiddleware);
router.post("/canny", withUserGraphQLClientMiddleware, cannySsoHandler);
module.exports = router;

28
server/sso/canny.js Normal file
View File

@@ -0,0 +1,28 @@
const path = require("path");
require("dotenv").config({
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
});
const logger = require("../utils/logger");
var jwt = require('jsonwebtoken');
const cannySsoHandler = async (req, res) => {
try {
var userData = {
//avatarURL: user.avatarURL, // optional, but preferred
email: req.user.email,
id: req.user.uid,
name: req.user.displayName || req.user.email,
};
res.status(200).send(jwt.sign(userData, process.env.CANNY_PRIVATE_KEY, { algorithm: 'HS256' }));
} catch (error) {
logger.log("sso-canny-error", "error", req?.user?.email, null, {
message: error.message,
stack: error.stack
});
res.status(500).json({ error: error.message });
}
};
module.exports = {
cannySsoHandler
};