gather feedback after 24h, or first deploy
This commit is contained in:
parent
8cbfe250e4
commit
a9de659216
|
@ -6,6 +6,10 @@ let analyticsEnabled
|
||||||
const posthogConfigured = process.env.POSTHOG_TOKEN && process.env.POSTHOG_URL
|
const posthogConfigured = process.env.POSTHOG_TOKEN && process.env.POSTHOG_URL
|
||||||
const sentryConfigured = process.env.SENTRY_DSN
|
const sentryConfigured = process.env.SENTRY_DSN
|
||||||
|
|
||||||
|
const FEEDBACK_SUBMITTED_KEY = "budibase:feedback_submitted"
|
||||||
|
const APP_FIRST_STARTED_KEY = "budibase:first_run"
|
||||||
|
const feedbackHours = 12
|
||||||
|
|
||||||
async function activate() {
|
async function activate() {
|
||||||
if (analyticsEnabled === undefined) {
|
if (analyticsEnabled === undefined) {
|
||||||
// only the server knows the true NODE_ENV
|
// only the server knows the true NODE_ENV
|
||||||
|
@ -62,10 +66,50 @@ function captureEvent(eventName, props = {}) {
|
||||||
posthog.capture(eventName, props)
|
posthog.capture(eventName, props)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!localStorage.getItem(APP_FIRST_STARTED_KEY)) {
|
||||||
|
localStorage.setItem(APP_FIRST_STARTED_KEY, Date.now())
|
||||||
|
}
|
||||||
|
|
||||||
|
const isFeedbackTimeElapsed = sinceDateStr => {
|
||||||
|
const sinceDate = parseFloat(sinceDateStr)
|
||||||
|
const feedbackMilliseconds = feedbackHours * 60 * 60 * 1000
|
||||||
|
return Date.now() > sinceDate + feedbackMilliseconds
|
||||||
|
}
|
||||||
|
function submitFeedback(values) {
|
||||||
|
if (!analyticsEnabled || !process.env.POSTHOG_TOKEN) return
|
||||||
|
localStorage.setItem(FEEDBACK_SUBMITTED_KEY, Date.now())
|
||||||
|
|
||||||
|
const prefixedValues = Object.entries(values).reduce((obj, [key, value]) => {
|
||||||
|
obj[`feedback_${key}`] = value
|
||||||
|
return obj
|
||||||
|
}, {})
|
||||||
|
|
||||||
|
posthog.capture("Feedback Submitted", prefixedValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestFeedbackOnDeploy() {
|
||||||
|
if (!analyticsEnabled || !process.env.POSTHOG_TOKEN) return false
|
||||||
|
const lastSubmittedStr = localStorage.getItem(FEEDBACK_SUBMITTED_KEY)
|
||||||
|
if (!lastSubmittedStr) return true
|
||||||
|
return isFeedbackTimeElapsed(lastSubmittedStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlightFeedbackIcon() {
|
||||||
|
if (!analyticsEnabled || !process.env.POSTHOG_TOKEN) return false
|
||||||
|
const lastSubmittedStr = localStorage.getItem(FEEDBACK_SUBMITTED_KEY)
|
||||||
|
if (lastSubmittedStr) return isFeedbackTimeElapsed(lastSubmittedStr)
|
||||||
|
const firstRunStr = localStorage.getItem(APP_FIRST_STARTED_KEY)
|
||||||
|
if (!firstRunStr) return false
|
||||||
|
return isFeedbackTimeElapsed(firstRunStr)
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
activate,
|
activate,
|
||||||
identify,
|
identify,
|
||||||
identifyByApiKey,
|
identifyByApiKey,
|
||||||
captureException,
|
captureException,
|
||||||
captureEvent,
|
captureEvent,
|
||||||
|
requestFeedbackOnDeploy,
|
||||||
|
submitFeedback,
|
||||||
|
highlightFeedbackIcon,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import analytics from "analytics"
|
import analytics from "analytics"
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
|
import { store } from "builderStore"
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const feedbackUrl = "https://feedback.budibase.com"
|
const feedbackUrl = "https://feedback.budibase.com"
|
||||||
|
@ -21,7 +22,8 @@
|
||||||
`height:${ev.data.height}px; width:${ev.data.width}px`
|
`height:${ev.data.height}px; width:${ev.data.width}px`
|
||||||
)
|
)
|
||||||
} else if (ev.data.type === "submitted") {
|
} else if (ev.data.type === "submitted") {
|
||||||
analytics.captureEvent("Feedback Submitted", ev.data.data)
|
analytics.submitFeedback(ev.data.data)
|
||||||
|
$store.highlightFeedbackIcon = false
|
||||||
dispatch("finished")
|
dispatch("finished")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
<script>
|
<script>
|
||||||
import { FeedbackIcon } from "components/common/Icons/"
|
import { FeedbackIcon } from "components/common/Icons/"
|
||||||
import { Popover } from "@budibase/bbui"
|
import { Popover } from "@budibase/bbui"
|
||||||
|
import { store } from "builderStore"
|
||||||
|
|
||||||
import FeedbackIframe from "./FeedbackIframe.svelte"
|
import FeedbackIframe from "./FeedbackIframe.svelte"
|
||||||
|
import analytics from "analytics"
|
||||||
|
|
||||||
let iconContainer
|
let iconContainer
|
||||||
let popover
|
let popover
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
$store.highlightFeedbackIcon = analytics.highlightFeedbackIcon()
|
||||||
|
}, 300000 /*check every 5 minutes*/)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<span class="container" bind:this={iconContainer} on:click={popover.show}>
|
<span
|
||||||
|
class="container"
|
||||||
|
bind:this={iconContainer}
|
||||||
|
on:click={popover.show}
|
||||||
|
class:highlight={$store.highlightFeedbackIcon}>
|
||||||
<FeedbackIcon />
|
<FeedbackIcon />
|
||||||
</span>
|
</span>
|
||||||
<Popover bind:this={popover} anchor={iconContainer} align="right">
|
<Popover bind:this={popover} anchor={iconContainer} align="right">
|
||||||
|
@ -32,4 +43,12 @@
|
||||||
color: var(--ink);
|
color: var(--ink);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.highlight {
|
||||||
|
color: var(--blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight > :global(svg) {
|
||||||
|
filter: drop-shadow(0 0 20px var(--blue));
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -33,7 +33,10 @@
|
||||||
analytics.captureEvent("Deployed App", {
|
analytics.captureEvent("Deployed App", {
|
||||||
appId,
|
appId,
|
||||||
})
|
})
|
||||||
feedbackModal.show()
|
|
||||||
|
if (analytics.requestFeedbackOnDeploy()) {
|
||||||
|
feedbackModal.show()
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
analytics.captureEvent("Deploy App Failed", {
|
analytics.captureEvent("Deploy App Failed", {
|
||||||
appId,
|
appId,
|
||||||
|
@ -61,7 +64,7 @@
|
||||||
alt="Rocket flying through sky" />
|
alt="Rocket flying through sky" />
|
||||||
</section>
|
</section>
|
||||||
<Modal bind:this={feedbackModal}>
|
<Modal bind:this={feedbackModal}>
|
||||||
<FeedbackIframe on:finished={feedbackModal.hide} />
|
<FeedbackIframe on:finished={() => feedbackModal.hide()} />
|
||||||
</Modal>
|
</Modal>
|
||||||
<DeploymentHistory {appId} />
|
<DeploymentHistory {appId} />
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue