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