Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trigger to open the support widget #1331

Merged
merged 51 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8021012
Bootstrap support widget
dallasread Dec 19, 2024
b1fcd20
Build and dev setup
dallasread Dec 19, 2024
fdecf35
Fix css variables
dallasread Dec 19, 2024
d89a08c
stub process.env
dallasread Dec 19, 2024
1d633f9
Show a fake site on the widget dev page for context
dallasread Dec 19, 2024
f36c3a9
Support widget at full width
dallasread Dec 19, 2024
f5123a0
Show the prompt only if there are no openers
dallasread Dec 19, 2024
a3d1983
Open with an opener
dallasread Dec 19, 2024
e748150
Include the support widget in the layout
dallasread Dec 19, 2024
dd69d28
Move z-index
dallasread Dec 19, 2024
5a751b5
Try to focus
dallasread Dec 19, 2024
bc29496
Add a z-index to the overlay
dallasread Dec 19, 2024
4e71ce4
A little bigger size
dallasread Dec 19, 2024
dc575cb
Merge remote-tracking branch 'origin/main' into spike/support-widget
dallasread Feb 6, 2025
fd5aa7d
Setup test env
kojdm Feb 7, 2025
9a374b3
Add test for main App component
kojdm Feb 7, 2025
a6d047e
Add tests for Article and Articles components
kojdm Feb 7, 2025
ced48d2
Remove unused file
dallasread Feb 7, 2025
c549220
Change the target of the build & build with webpack
dallasread Feb 7, 2025
40e250c
Include widget in linting
dallasread Feb 7, 2025
97cb37d
Linted
dallasread Feb 7, 2025
009c68b
Publish to `dist`
dallasread Feb 7, 2025
830bba7
Revert to `output` dir
dallasread Feb 7, 2025
4e2dea7
Allow for placement from dnsimple.com
dallasread Feb 7, 2025
682327f
Merge remote-tracking branch 'origin/spike/support-widget' into spike…
dallasread Feb 7, 2025
ce6b85c
Remove widget title
dallasread Feb 7, 2025
7d595bf
Trusty size
dallasread Feb 7, 2025
e2a2d50
Ensure DOM is loaded before finding listener elements
dallasread Feb 7, 2025
dd2737b
Ensure DOM is loaded before finding listener elements (2)
dallasread Feb 7, 2025
29b197a
Less jarring overlay
dallasread Feb 7, 2025
06d9101
Fix focus
dallasread Feb 7, 2025
8f6c52b
:robot:
dallasread Feb 7, 2025
a51a4f2
Only fetch the first time
dallasread Feb 7, 2025
beca9b2
Remove unused attr
dallasread Feb 7, 2025
99d96b7
Cleanup
dallasread Feb 7, 2025
6da19c6
Fix enclosing div reset
dallasread Feb 7, 2025
226a96c
:robot:
dallasread Feb 7, 2025
dd8710d
_
dallasread Feb 7, 2025
1adbdca
Remove results.js
dallasread Feb 7, 2025
48b6dbe
Set an article's source to determine if it should be opened in the sa…
dallasread Feb 7, 2025
906a50d
Remove unused var
dallasread Feb 7, 2025
32f1efe
Lint
dallasread Feb 7, 2025
c5dc0cf
Set the current site url
dallasread Feb 7, 2025
674fb7c
Remove the DOM content loaded func
dallasread Feb 7, 2025
cbc0e00
Avoid conflict
dallasread Feb 7, 2025
6ebfc29
Add a slight shadow
dallasread Feb 7, 2025
1be3ab6
Show on mobile
dallasread Feb 7, 2025
eeccbfb
Merge remote-tracking branch 'origin/main' into spike/support-widget-…
dallasread Feb 10, 2025
7eaaf56
Style the top input like the existing site
dallasread Feb 11, 2025
05d85fd
Search icon color
dallasread Feb 11, 2025
5930f14
Header color
dallasread Feb 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions _widget/index.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion _widget/src/assets/svgs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 33 additions & 10 deletions _widget/src/components/app/component.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
<template>
<div id="dnsimple-support">
<div v-if="isOpen" class="relative animated fadeInUp faster">
<Header :app="app" ref="header"/>
<Component :is="currentRoute[0]" :app="app" :article="currentRoute[1]"></Component>
<div v-if="isOpen">
<div class="overlay" @click="close"></div>
<div class="dnsimple-modal animated fadeInUp faster">
<Header :app="app" ref="header"/>
<Component :is="currentRoute[0]" :app="app" :article="currentRoute[1]"></Component>
</div>
</div>
<Prompt v-else :app="app"/>
<Prompt v-else-if="showPrompt" :app="app"/>
</div>
</template>

<script>
import { nextTick } from 'vue';
import { urlMatchingDictionary } from './url-dictionary.js';

import Footer from '../footer/component.vue';
Expand Down Expand Up @@ -38,6 +42,13 @@ export default {
props: {
query: {
default: ''
},
showPrompt: {
default: true
},
currentSiteUrl: {
type: String,
default: ''
}
},
data () {
Expand All @@ -51,7 +62,7 @@ export default {
q: query,
isOpen: false,
isLoading: true,
rootURL: 'https://support.dnsimple.com',
isFetched: false,
history: []
};
},
Expand All @@ -68,7 +79,9 @@ export default {

computed: {
filteredArticles () {
return window.DNSimpleSupport.search(this.q);
const articles = window.DNSimpleSupport.search(this.q);
articles.forEach((a) => { a.source = 'https://support.dnsimple.com'; });
return articles;
},

noResults () {
Expand Down Expand Up @@ -101,27 +114,33 @@ export default {
},

focus () {
const $header = this.$refs.header;
nextTick(() => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to wait a tick before the input is rendered.

const $header = this.$refs.header;

if ($header !== null && $header !== undefined)
$header.$refs.input.focus();
if ($header !== null && $header !== undefined)
$header.$refs.input.focus();
});
},

close () {
this.isOpen = false;
},

fetchArticles (done) {
if (this.isFetched) return done();

const script = document.createElement('script');

this.isLoading = true;

script.type = 'text/javascript';
script.src = `${this.rootURL}/search.js`;
script.src = `https://support.dnsimple.com/search.js`;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This'll be cleaned up when we add multiple sources (eg. dev site articles).


script.onload = () => {
setTimeout(() => {
this.isFetched = true;
this.isLoading = false;
done();
}, 500);
};

Expand All @@ -130,6 +149,10 @@ export default {

setQ (q) {
this.q = q;
},

getCurrentSiteUrl() {
return this.currentSiteUrl;
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion _widget/src/components/app/reset.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ v2.0 | 20110126
License: none (public domain)
*/

#dnsimple-support {
#dnsimple-support-widget {
box-sizing: border-box;

div, span, applet, object, iframe,
Expand Down
37 changes: 30 additions & 7 deletions _widget/src/components/app/style.scss
Original file line number Diff line number Diff line change
@@ -1,31 +1,54 @@
#dnsimple-support-widget {
position: fixed;
z-index: 999;
bottom: 0;
right: 0;
width: 480px;
font-size: var(--dnsimple-support-widget-rem);
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
line-height: 1.6;
color: #222;
z-index: 999;

@media (var(--dnsimple-support-widget-desktop-only)) {
display: none;
}
}

#dnsimple-support {
z-index: 999;

.dnsimple-modal {
position: fixed;
top: 0;
right: 0;
left: 0;
margin-top: 5vh;
z-index: 999;
max-width: 45rem;
margin-left: auto;
margin-right: auto;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.25);
}

.overlay {
position: fixed;
z-index: 998;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
}

.relative {
position: relative;
box-shadow: var(--dnsimple-support-widget-box-shadow);
}

.route {
height: 475px;
border-left: 1px solid var(--dnsimple-support-widget-line-color);
border: 1px solid var(--dnsimple-support-widget-line-color);
overflow-y: auto;
-webkit-overflow-scrolling: touch;
padding: var(--dnsimple-support-widget-padding);
background: var(--dnsimple-support-widget-white);
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
height: 75vh;
}
}
2 changes: 1 addition & 1 deletion _widget/src/components/article/component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export default {
return a.id === href;
});

a.href = `${this.app.rootURL}${href}`;
a.href = `${this.article.source}${href}`;
a.onclick = (event) => {
event.stopImmediatePropagation();
event.preventDefault();
Expand Down
12 changes: 9 additions & 3 deletions _widget/src/components/articles/component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@
<li v-for="article in app.filteredArticles" :key="article.id">
<h3>
<a
v-if="article.source === app.getCurrentSiteUrl()"
v-html="highlight(article.title, highlighter)"
:href="absoluteURL(article, article.id)"
></a>
<a
v-else
@click.prevent="app.go('Article', article)"
v-html="highlight(article.title, highlighter)"
:href="absoluteURL(article.id)"
:href="absoluteURL(article, article.id)"
></a>
</h3>

Expand Down Expand Up @@ -62,8 +68,8 @@ export default {
}
},
methods: {
absoluteURL (path) {
return `${this.app.rootURL}${path}`;
absoluteURL (article, path) {
return `${article.source}${path}`;
},

highlight (str, highlighter) {
Expand Down
2 changes: 1 addition & 1 deletion _widget/src/components/articles/style.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#dnsimple-support {
.articles {
margin-top: -var(--dnsimple-support-widget-padding);
margin-top: calc(var(--dnsimple-support-widget-padding) * -1);

h3 {
color: var(--dnsimple-support-widget-blue);
Expand Down
2 changes: 0 additions & 2 deletions _widget/src/components/header/component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
<a href="javascript:;" @click="app.close" class="minimize">
<div v-html="minimizeIcon"></div>
</a>
<h1>DNSimple Support</h1>
<input
type="text"
ref="input"
v-model="q"
placeholder='Try some keywords, like "alias" or "url redirect"'
data-cy='support-widget-input-search'
/>
</div>
</template>
Expand Down
14 changes: 5 additions & 9 deletions _widget/src/components/header/style.scss
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
#dnsimple-support {
.header {
background: var(--dnsimple-support-widget-blue);
background: var(--dnsimple-support-widget-dark-gray);
text-align: center;
padding: var(--dnsimple-support-widget-padding);
border-top-left-radius: 4px;

h1 {
color: var(--dnsimple-support-widget-white);
margin-bottom: var(--dnsimple-support-widget-padding);
}
border-top-right-radius: 4px;

.minimize {
color: var(--dnsimple-support-widget-white);
position: absolute;
top: 0;
right: 0;
line-height: 1;
padding: calc(var(--dnsimple-support-widget-padding) * 1.1) calc(var(--dnsimple-support-widget-padding) / 1.25);
padding: calc(var(--dnsimple-support-widget-padding) * 2) calc(var(--dnsimple-support-widget-padding) / 1.25);

svg {
width: calc(var(--dnsimple-support-widget-rem) * 1.25);
Expand All @@ -35,7 +31,7 @@
input {
outline: none;
padding: 10px;
width: 100%;
width: calc(100% - var(--dnsimple-support-widget-padding) * 4);
border: 0;
border-bottom: 1px solid #eee;
background: var(--dnsimple-support-widget-white);
Expand All @@ -48,7 +44,7 @@
position: absolute;
top: 0;
left: 0;
padding: calc(var(--dnsimple-support-widget-padding) / 1.25) calc(var(--dnsimple-support-widget-padding) / 2);
padding: calc(var(--dnsimple-support-widget-padding) * 1.6) calc(var(--dnsimple-support-widget-padding) / 2);
line-height: 1;

svg {
Expand Down
7 changes: 3 additions & 4 deletions _widget/src/components/welcome/style.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#dnsimple-support {
.welcome {
text-align: center;
padding-top: calc(var(--dnsimple-support-widget-padding) * 7);

h1 {
font-weight: bold;
Expand All @@ -10,15 +9,15 @@
}

p {
max-width: 70%;
max-width: 90%;
margin: 0 auto;
color: var(--dnsimple-support-widget-dark-gray);
}

.mascot {
bottom: 0;
max-width: 50%;
margin: 0 auto calc(var(--dnsimple-support-widget-padding) * 5);
max-width: 30vh;
margin: calc(var(--dnsimple-support-widget-padding) * 3) auto calc(var(--dnsimple-support-widget-padding) * 3);
}
}
}
16 changes: 14 additions & 2 deletions _widget/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,24 @@ import { createApp } from 'vue';
import App from './components/app/component.vue';

const elementId = 'dnsimple-support-widget';
const $openers = [...document.querySelectorAll('[data-dnsimple-open-support-widget]')];

let $target = document.querySelector(`#${elementId}`);

if (!$target) {
$target = document.createElement('div');
$target.id = elementId;
document.body.appendChild($target);
document.body.insertBefore($target, document.body.firstChild);
}

createApp(App).mount($target);
const app = createApp(App, {
showPrompt: $openers.length === 0,
currentSiteUrl: document.querySelector('[data-dnsimple-current-site-url]')?.getAttribute('data-dnsimple-current-site-url') || ''
}).mount($target);

$openers.forEach(($el) => {
$el.addEventListener('click', () => {
app.open();
app.focus();
});
});
4 changes: 4 additions & 0 deletions content/assets/css/_template.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
* { box-sizing: border-box; }

.input-search {
background: var(--elementInverse);
color: var(--gray);

&::-ms-clear { display: none; width : 0; height: 0; }
&::-ms-reveal { display: none; width : 0; height: 0; }
&::-webkit-search-decoration,
Expand All @@ -15,6 +18,7 @@
right: 10px;
border: none;
background: transparent;
color: var(--gray);
}

.bg-pipes {
Expand Down
Loading