mirror of https://github.com/Budibase/budibase.git
9 changed files with 189 additions and 279 deletions
@ -1,59 +0,0 @@ |
|||
<script> |
|||
import analytics from "analytics" |
|||
import { createEventDispatcher } from "svelte" |
|||
import { store } from "builderStore" |
|||
|
|||
const dispatch = createEventDispatcher() |
|||
const feedbackUrl = "https://feedback.budibase.com" |
|||
|
|||
let iframe |
|||
|
|||
// the app @ feedback.budibase.com expects to be loaded |
|||
// in an iframe, and posts messages back. |
|||
// this means that we can submit using the Builder's posthog setup |
|||
window.addEventListener( |
|||
"message", |
|||
function (ev) { |
|||
if (ev.origin !== feedbackUrl) return |
|||
|
|||
if (ev.data.type === "loaded") { |
|||
iframe.setAttribute( |
|||
"style", |
|||
`height:${ev.data.height}px; width:${ev.data.width}px` |
|||
) |
|||
} else if (ev.data.type === "submitted") { |
|||
analytics.submitFeedback(ev.data.data) |
|||
$store.highlightFeedbackIcon = false |
|||
dispatch("finished") |
|||
} |
|||
}, |
|||
false |
|||
) |
|||
</script> |
|||
|
|||
<iframe src={feedbackUrl} title="feedback" bind:this={iframe}> |
|||
<html lang="html"> |
|||
<style> |
|||
body { |
|||
display: flex; |
|||
height: 100%; |
|||
width: 100%; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
</style> |
|||
<body> |
|||
<div>Loading...</div> |
|||
</body> |
|||
</html> |
|||
</iframe> |
|||
|
|||
<style> |
|||
iframe { |
|||
border-style: none; |
|||
height: auto; |
|||
overflow-y: hidden; |
|||
overflow-x: hidden; |
|||
min-width: 500px; |
|||
} |
|||
</style> |
|||
@ -1,52 +0,0 @@ |
|||
<script> |
|||
import { Icon, Popover } from "@budibase/bbui" |
|||
import { store } from "builderStore" |
|||
import { onMount } from "svelte" |
|||
|
|||
import FeedbackIframe from "./FeedbackIframe.svelte" |
|||
import analytics from "analytics" |
|||
|
|||
const FIVE_MINUTES = 300000 |
|||
|
|||
let iconContainer |
|||
let popover |
|||
|
|||
onMount(() => { |
|||
const interval = setInterval(() => { |
|||
store.update(state => { |
|||
state.highlightFeedbackIcon = analytics.highlightFeedbackIcon() |
|||
return state |
|||
}) |
|||
}, FIVE_MINUTES) |
|||
return () => clearInterval(interval) |
|||
}) |
|||
</script> |
|||
|
|||
<div class="container" bind:this={iconContainer} on:click={popover.show}> |
|||
<Icon hoverable name="Feedback" /> |
|||
</div> |
|||
<div class="iframe"> |
|||
<Popover bind:this={popover} anchor={iconContainer} align="right"> |
|||
<FeedbackIframe on:finished={popover.hide} /> |
|||
</Popover> |
|||
</div> |
|||
|
|||
<style> |
|||
.container { |
|||
cursor: pointer; |
|||
color: var(--grey-7); |
|||
margin: 0 12px 0 0; |
|||
font-weight: 600; |
|||
font-size: 1rem; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
align-items: center; |
|||
height: 24px; |
|||
width: 24px; |
|||
} |
|||
|
|||
.iframe :global(.menu-container) { |
|||
background-color: white; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,168 @@ |
|||
<script> |
|||
import analytics from "analytics" |
|||
import { createEventDispatcher } from "svelte" |
|||
import { fade, fly } from "svelte/transition" |
|||
import { |
|||
ActionButton, |
|||
ClearButton, |
|||
RadioGroup, |
|||
TextArea, |
|||
ButtonGroup, |
|||
Button, |
|||
Heading, |
|||
Detail, |
|||
Divider, |
|||
Layout, |
|||
} from "@budibase/bbui" |
|||
import { auth } from "stores/portal" |
|||
|
|||
let step = 0 |
|||
let ratings = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] |
|||
let options = [ |
|||
"Importing / managing data", |
|||
"Designing", |
|||
"Automations", |
|||
"Managing users / groups", |
|||
"Deployment / hosting", |
|||
"Documentation", |
|||
] |
|||
|
|||
const dispatch = createEventDispatcher() |
|||
|
|||
// Data to send off |
|||
let rating |
|||
let improvements |
|||
let comment |
|||
|
|||
function selectNumber(n) { |
|||
rating = n |
|||
step = 1 |
|||
} |
|||
|
|||
function submitFeedback() { |
|||
analytics.submitFeedback({ |
|||
rating, |
|||
improvements, |
|||
comment, |
|||
}) |
|||
auth.updateSelf({ |
|||
flags: { |
|||
feedbackSubmitted: true, |
|||
}, |
|||
}) |
|||
dispatch("complete") |
|||
} |
|||
|
|||
function cancelFeedback() { |
|||
auth.updateSelf({ |
|||
flags: { |
|||
feedbackSubmitted: true, |
|||
}, |
|||
}) |
|||
dispatch("complete") |
|||
} |
|||
</script> |
|||
|
|||
<div |
|||
class="position" |
|||
in:fade={{ duration: 200 }} |
|||
out:fade|local={{ duration: 200 }} |
|||
> |
|||
<div |
|||
class="feedback-frame" |
|||
in:fly={{ y: 30, duration: 200 }} |
|||
out:fly|local={{ y: 30, duration: 200 }} |
|||
> |
|||
<div class="close"> |
|||
<ClearButton on:click={cancelFeedback} /> |
|||
</div> |
|||
<Layout gap="XS"> |
|||
{#if step === 0} |
|||
<Heading size="XS" |
|||
>How likely are you to recommend Budibase to a colleague?</Heading |
|||
> |
|||
<Divider /> |
|||
<div class="ratings"> |
|||
{#each ratings as number} |
|||
<ActionButton |
|||
size="L" |
|||
emphasized |
|||
selected={number === rating} |
|||
on:click={() => selectNumber(number)} |
|||
> |
|||
{number} |
|||
</ActionButton> |
|||
{/each} |
|||
</div> |
|||
<div class="footer"> |
|||
<Detail size="S">NOT LIKELY</Detail> |
|||
<Detail size="S">EXTREMELY LIKELY</Detail> |
|||
</div> |
|||
{:else if step === 1} |
|||
<Heading size="XS">What could be improved most in Budibase?</Heading> |
|||
<Divider /> |
|||
<RadioGroup bind:value={improvements} {options} /> |
|||
<div class="footer"> |
|||
<Detail size="S">STEP 2 OF 3</Detail> |
|||
<ButtonGroup> |
|||
<Button secondary on:click={() => (step -= 1)}>Previous</Button> |
|||
<Button |
|||
disabled={!improvements} |
|||
primary |
|||
on:click={() => (step += 1)}>Next</Button |
|||
> |
|||
</ButtonGroup> |
|||
</div> |
|||
{:else} |
|||
<Heading size="XS">How can we improve your experience?</Heading> |
|||
<Divider /> |
|||
<TextArea bind:value={comment} placeholder="Add comments" /> |
|||
<div class="footer"> |
|||
<Detail size="S">STEP 3 OF 3</Detail> |
|||
<ButtonGroup> |
|||
<Button secondary on:click={() => (step -= 1)}>Previous</Button> |
|||
<Button disabled={!comment} cta on:click={submitFeedback} |
|||
>Complete</Button |
|||
> |
|||
</ButtonGroup> |
|||
</div> |
|||
{/if} |
|||
</Layout> |
|||
</div> |
|||
</div> |
|||
|
|||
<style> |
|||
.feedback-frame :global(textarea) { |
|||
min-height: 180px !important; |
|||
} |
|||
|
|||
.position { |
|||
position: absolute; |
|||
right: var(--spacing-l); |
|||
bottom: calc(5 * var(--spacing-xl)); |
|||
} |
|||
.feedback-frame { |
|||
position: absolute; |
|||
bottom: 0; |
|||
right: 0; |
|||
min-width: 510px; |
|||
background: var(--background); |
|||
border-radius: var(--spectrum-global-dimension-size-50); |
|||
border: 2px solid var(--spectrum-global-color-blue-400); |
|||
padding: var(--spacing-xl); |
|||
} |
|||
.ratings { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
} |
|||
.close { |
|||
position: absolute; |
|||
top: 0; |
|||
right: 0; |
|||
} |
|||
.footer { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue