Skip to content

Commit

Permalink
configurable tours
Browse files Browse the repository at this point in the history
  • Loading branch information
elizavetaRa committed Jun 13, 2022
1 parent e791939 commit 689d1ea
Show file tree
Hide file tree
Showing 13 changed files with 471 additions and 5 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
"rollup-plugin-ts": "^1.4.0",
"rollup-plugin-visualizer": "^5.6.0",
"rollup-plugin-vue": "^5.1.4",
"shepherd.js": "^9.1.0",
"sync-fetch": "^0.3.1",
"ts-jest": "^27.1.3",
"ts-node": "^10.5.0",
Expand Down
13 changes: 11 additions & 2 deletions packages/web-runtime/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import LayoutLoading from './layouts/Loading.vue'
import LayoutPlain from './layouts/Plain.vue'
import { getBackendVersion, getWebVersion } from './container/versions'
import { defineComponent } from '@vue/composition-api'
import { autostartTours } from './helpers/tours'
export default defineComponent({
components: {
Expand All @@ -53,7 +54,12 @@ export default defineComponent({
},
computed: {
...mapState(['route', 'user', 'modal', 'sidebar']),
...mapGetters(['configuration', 'capabilities', 'getSettingsValue']),
...mapGetters([
'configuration',
'capabilities',
'getSettingsValue',
'currentTranslatedTourInfos'
]),
layout() {
if (this.user.isAuthenticated && !this.user.userReady) {
return LayoutLoading
Expand Down Expand Up @@ -93,6 +99,8 @@ export default defineComponent({
handler: function (to) {
this.announceRouteChange(to)
document.title = this.extractPageTitleFromRoute(to)
if (this.currentTranslatedTourInfos.length > 0)
autostartTours(this.currentTranslatedTourInfos, to.name)
}
},
capabilities: {
Expand Down Expand Up @@ -121,6 +129,7 @@ export default defineComponent({
if (languageCode) {
this.$language.current = languageCode
document.documentElement.lang = languageCode
this.setCurrentTranslatedTourInfos(languageCode)
}
}
}
Expand Down Expand Up @@ -148,7 +157,7 @@ export default defineComponent({
},
methods: {
...mapActions(['fetchNotifications']),
...mapActions(['fetchNotifications', 'setCurrentTranslatedTourInfos']),
focusModal(component, event) {
this.focus({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
:aria-label="buttonLabel"
appearance="raw"
variation="inverse"
style="white-space: nowrap"
@click="toggleTheme"
>
<span class="oc-visible@s" :aria-label="switchLabel" v-text="switchText" />
Expand Down
5 changes: 4 additions & 1 deletion packages/web-runtime/src/components/Topbar/TopBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<portal-target name="app.runtime.header" multiple></portal-target>
</div>
<div class="oc-topbar-right oc-flex oc-flex-middle oc-flex-between">
<tours />
<theme-switcher v-if="darkThemeAvailable" />
<feedback-link v-if="isFeedbackLinkEnabled" v-bind="feedbackLinkOptions" />
<notifications v-if="isNotificationBellEnabled" />
Expand All @@ -31,14 +32,16 @@ import UserMenu from './UserMenu.vue'
import Notifications from './Notifications.vue'
import FeedbackLink from './FeedbackLink.vue'
import ThemeSwitcher from './ThemeSwitcher.vue'
import Tours from './Tours/Tours.vue'
export default {
components: {
ApplicationsMenu,
FeedbackLink,
Notifications,
ThemeSwitcher,
UserMenu
UserMenu,
Tours
},
mixins: [NavigationMixin],
props: {
Expand Down
145 changes: 145 additions & 0 deletions packages/web-runtime/src/components/Topbar/Tours/Tours.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<template>
<div v-if="toursAllowed" id="tours">
<oc-button
v-if="tours.length === 1"
id="toursButton"
v-oc-tooltip="tours[0].tooltip"
size="small"
@click.stop="startTour(0)"
>
<oc-icon name="map" />
{{ tours[0].tourName }}
</oc-button>

<div v-else>
<oc-button id="toursButton" v-oc-tooltip="toursTooltip" size="small">
<oc-icon name="map" />
<translate>Tours</translate> </oc-button
><oc-drop
ref="menu"
drop-id="tours"
toggle="#toursButton"
mode="click"
close-on-click
padding-size="small"
>
<oc-list class="user-menu-list">
<li
v-for="(tour, id) in tours"
:id="tour.tourName"
:key="`tour-${tour.title}-list-${id}`"
class="user-menu-list"
@click.stop="startTour(id)"
>
<oc-button v-oc-tooltip="tour.tooltip" appearance="raw">
<span class="profile-info-wrapper" :class="'oc-py-xs'">
{{ tour.tourName }}
</span></oc-button
>
</li></oc-list
>
</oc-drop>
</div>
</div>
</template>

<script>
import { mapGetters } from 'vuex'
import { createTranslatedTour } from '../../../helpers/tours'
export default {
computed: {
...mapGetters(['currentTranslatedTourInfos']),
tours() {
return this.currentTranslatedTourInfos
},
language() {
return this.$language.current
},
toursAllowed() {
return this.tours.some((t) => this.tourAllowed(t))
},
toursTooltip() {
return this.$gettext('See tours through the interface')
}
},
methods: {
startTour(id) {
createTranslatedTour(this.tours[id]).start()
},
tourAllowed(tour) {
// if there are allowed locations, show based on them, otherwise check denied locations, otherwise show always
if (tour.allowedLocations?.length) return tour.allowedLocations.includes(this.$route.name)
else if (tour.deniedLocations?.length)
return !tour.deniedLocations?.includes(this.$route.name)
return true
}
}
}
</script>
<style src="shepherd.js/dist/css/shepherd.css"></style>
<style lang="scss">
.guide-highlight {
background-color: var(--oc-color-background-highlight);
}
#tour {
height: 100%;
width: 100%;
}
.guide-img {
width: 100%;
}
.shepherd-element {
max-width: 700px !important;
}
.shepherd-header {
align-items: center !important;
background-color: var(--oc-color-swatch-brand-default) !important;
border: 1px solid var(--oc-color-swatch-brand-default) !important;
border: 0 !important;
box-shadow: 5px 0 25px rgb(0 0 0 / 30%) !important;
display: flex !important;
flex-flow: row wrap !important;
padding: var(--oc-space-small) var(--oc-space-medium) !important;
h3 {
color: var(--oc-color-swatch-inverse-default) !important;
font-size: 1rem !important;
font-weight: 700 !important;
margin: 0 !important;
}
}
.shepherd-text {
border-top: 1px solid var(--oc-color-swatch-brand-default) !important;
}
.shepherd-element {
border-radius: 15px !important;
background-color: var(--oc-color-background-default) !important;
}
.shepherd-text,
.shepherd-footer {
background-color: var(--oc-color-background-default) !important;
border: 0 !important;
//box-shadow: 5px 0 25px rgb(0 0 0 / 30%) !important;
color: var(--oc-color-text-default) !important;
padding: var(--oc-space-medium) !important;
}
.shepherd-footer {
border: 0 !important;
}
.shepherd-button {
background-color: var(--oc-color-swatch-primary-default) !important;
border-color: var(--oc-color-swatch-primary-default) !important;
}
.shepherd-button-secondary {
background-color: initial !important;
color: var(--oc-color-swatch-passive-default) !important;
border: 1px solid transparent !important;
border-color: var(--oc-color-swatch-passive-default) !important;
}
</style>
17 changes: 17 additions & 0 deletions packages/web-runtime/src/container/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Store } from 'vuex'
import VueRouter from 'vue-router'
import { VueConstructor } from 'vue'
import { loadTheme } from '../helpers/theme'
import { loadTours } from '../helpers/tours'
import OwnCloud from 'owncloud-sdk'
import { sync as routerSync } from 'vuex-router-sync'
import getTextPlugin from 'vue-gettext'
Expand Down Expand Up @@ -209,6 +210,22 @@ export const announceTheme = async ({
})
}

/**
* announce runtime tours
*
* @param store
*/
export const announceTours = async ({
store,
runtimeConfiguration
}: {
store: Store<unknown>
runtimeConfiguration?: RuntimeConfiguration
}): Promise<void> => {
const { tours } = await loadTours(runtimeConfiguration?.tours)
await store.dispatch('setAllTranslatedTourInfos', tours)
}

/**
* announce runtime translations by injecting them into the getTextPlugin
*
Expand Down
Loading

0 comments on commit 689d1ea

Please sign in to comment.