Add Page Titles Everywhere (#177)

Add page titles everywhere

Add global mixin to set page title

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/177
This commit is contained in:
konrad 2020-07-07 20:07:13 +00:00
parent d23f07d5ac
commit a0b9acee41
25 changed files with 80 additions and 7 deletions

View file

@ -419,6 +419,8 @@
} }
}, },
doStuffAfterRoute(e) { doStuffAfterRoute(e) {
// this.setTitle('') // Reset the title if the page component does not set one itself
if (this.$store.state[IS_FULLPAGE]) { if (this.$store.state[IS_FULLPAGE]) {
this.$store.commit(IS_FULLPAGE, false) this.$store.commit(IS_FULLPAGE, false)
} }

9
src/helpers/setTitle.js Normal file
View file

@ -0,0 +1,9 @@
export const setTitle = title => {
if (typeof title === 'undefined' || title === '') {
document.title = 'Vikunja'
return
}
document.title = `${title} | Vikunja`
}

View file

@ -143,6 +143,7 @@ Vue.directive('focus', {
import message from './message' import message from './message'
import {format, formatDistance} from 'date-fns' import {format, formatDistance} from 'date-fns'
import {colorIsDark} from './helpers/colorIsDark' import {colorIsDark} from './helpers/colorIsDark'
import {setTitle} from './helpers/setTitle'
Vue.mixin({ Vue.mixin({
methods: { methods: {
formatDateSince: date => { formatDateSince: date => {
@ -161,7 +162,8 @@ Vue.mixin({
formatDate: date => format(date, 'PPPPpppp'), formatDate: date => format(date, 'PPPPpppp'),
error: (e, context, actions = []) => message.error(e, context, actions), error: (e, context, actions = []) => message.error(e, context, actions),
success: (s, context, actions = []) => message.success(s, context, actions), success: (s, context, actions = []) => message.success(s, context, actions),
colorIsDark: colorIsDark colorIsDark: colorIsDark,
setTitle: setTitle,
} }
}) })

View file

@ -11,6 +11,7 @@ import kanban from './modules/kanban'
import tasks from './modules/tasks' import tasks from './modules/tasks'
import lists from './modules/lists' import lists from './modules/lists'
import ListService from '../services/list' import ListService from '../services/list'
import {setTitle} from '../helpers/setTitle'
export const store = new Vuex.Store({ export const store = new Vuex.Store({
modules: { modules: {
@ -45,6 +46,9 @@ export const store = new Vuex.Store({
state.isFullpage = fullpage state.isFullpage = fullpage
}, },
[CURRENT_LIST](state, currentList) { [CURRENT_LIST](state, currentList) {
setTitle(currentList.title)
// Not sure if this is the right way to do it but hey, it works // Not sure if this is the right way to do it but hey, it works
if ( if (
// List changed // List changed

View file

@ -7,6 +7,9 @@
<script> <script>
export default { export default {
name: '404' name: '404',
mounted() {
this.setTitle('404')
},
} }
</script> </script>

View file

@ -117,6 +117,9 @@
this.labelEditLabel = new LabelModel() this.labelEditLabel = new LabelModel()
this.loadLabels() this.loadLabels()
}, },
mounted() {
this.setTitle('Labels')
},
computed: mapState({ computed: mapState({
userInfo: state => state.auth.info userInfo: state => state.auth.info
}), }),

View file

@ -218,6 +218,7 @@
// This will trigger the dynamic loading of components once we actually have all the data to pass to them // This will trigger the dynamic loading of components once we actually have all the data to pass to them
this.manageTeamsComponent = 'manageSharing' this.manageTeamsComponent = 'manageSharing'
this.manageUsersComponent = 'manageSharing' this.manageUsersComponent = 'manageSharing'
this.setTitle(`Edit ${this.list.title}`)
}) })
.catch(e => { .catch(e => {
this.error(e, this) this.error(e, this)

View file

@ -51,6 +51,9 @@
this.listService = new ListService() this.listService = new ListService()
this.$store.commit(IS_FULLPAGE, true) this.$store.commit(IS_FULLPAGE, true)
}, },
mounted() {
this.setTitle('Create a new list')
},
methods: { methods: {
newList() { newList() {
if (this.list.title === '') { if (this.list.title === '') {

View file

@ -70,11 +70,12 @@
return this.$store.state.background return this.$store.state.background
}, },
currentList() { currentList() {
return typeof this.$store.state.currentList === 'undefined' ? {id: 0} : this.$store.state.currentList return typeof this.$store.state.currentList === 'undefined' ? {id: 0, title: ''} : this.$store.state.currentList
}, },
}, },
methods: { methods: {
loadList() { loadList() {
this.setTitle(this.currentList.title)
// This invalidates the loaded list at the kanban board which lets it reload its content when // This invalidates the loaded list at the kanban board which lets it reload its content when
// switched to it. This ensures updates done to tasks in the gantt or list views are consistently // switched to it. This ensures updates done to tasks in the gantt or list views are consistently

View file

@ -14,6 +14,9 @@
<script> <script>
export default { export default {
name: 'migrate.service', name: 'migrate.service',
mounted() {
this.setTitle('Import your data to Vikunja')
},
computed: { computed: {
availableMigrators() { availableMigrators() {
return this.$store.state.config.availableMigrators return this.$store.state.config.availableMigrators

View file

@ -20,6 +20,9 @@
identifier: '', identifier: '',
} }
}, },
mounted() {
this.setTitle(`Import your data from ${this.name} into Vikunja`)
},
created() { created() {
switch (this.$route.params.service) { switch (this.$route.params.service) {
case 'wunderlist': case 'wunderlist':

View file

@ -153,6 +153,7 @@
// This will trigger the dynamic loading of components once we actually have all the data to pass to them // This will trigger the dynamic loading of components once we actually have all the data to pass to them
this.manageTeamsComponent = 'manageSharing' this.manageTeamsComponent = 'manageSharing'
this.manageUsersComponent = 'manageSharing' this.manageUsersComponent = 'manageSharing'
this.setTitle(`Edit ${this.namespace.title}`)
}) })
.catch(e => { .catch(e => {
this.error(e, this) this.error(e, this)

View file

@ -65,14 +65,17 @@
backgrounds: {}, backgrounds: {},
} }
}, },
created() {
this.loadBackgroundsForLists()
},
mounted() {
this.setTitle('Namespaces & Lists')
},
computed: mapState({ computed: mapState({
namespaces(state) { namespaces(state) {
return state.namespaces.namespaces.filter(n => this.showArchived ? true : !n.isArchived) return state.namespaces.namespaces.filter(n => this.showArchived ? true : !n.isArchived)
}, },
}), }),
created() {
this.loadBackgroundsForLists()
},
methods: { methods: {
loadBackgroundsForLists() { loadBackgroundsForLists() {
const listService = new ListService() const listService = new ListService()

View file

@ -53,6 +53,9 @@
this.namespaceService = new NamespaceService() this.namespaceService = new NamespaceService()
this.$store.commit(IS_FULLPAGE, true) this.$store.commit(IS_FULLPAGE, true)
}, },
mounted() {
this.setTitle('Create a new namespace')
},
methods: { methods: {
newNamespace() { newNamespace() {
if (this.namespace.title === '') { if (this.namespace.title === '') {

View file

@ -22,6 +22,9 @@
created() { created() {
this.auth() this.auth()
}, },
mounted() {
this.setTitle('Authenticating...')
},
methods: { methods: {
auth() { auth() {
this.$store.dispatch('auth/linkShareAuth', this.$route.params.share) this.$store.dispatch('auth/linkShareAuth', this.$route.params.share)

View file

@ -56,6 +56,12 @@
return return
} }
if (this.showAll) {
this.setTitle('Current Tasks')
} else {
this.setTitle(`Tasks from ${this.startDate.toLocaleDateString()} until ${this.endDate.toLocaleDateString()}`)
}
const params = { const params = {
sort_by: ['due_date', 'id'], sort_by: ['due_date', 'id'],
order_by: ['desc', 'desc'], order_by: ['desc', 'desc'],

View file

@ -453,6 +453,7 @@
this.taskTitle = this.task.title this.taskTitle = this.task.title
this.taskColor = this.task.hexColor this.taskColor = this.task.hexColor
this.setActiveFields() this.setActiveFields()
this.setTitle(this.task.title)
}) })
.catch(e => { .catch(e => {
this.error(e, this) this.error(e, this)

View file

@ -227,6 +227,7 @@
this.teamService.get(this.team) this.teamService.get(this.team)
.then(response => { .then(response => {
this.$set(this, 'team', response) this.$set(this, 'team', response)
this.setTitle(`Edit Team ${this.team.name}`)
let members = response.members let members = response.members
for (const m in members) { for (const m in members) {
members[m].teamId = this.teamId members[m].teamId = this.teamId

View file

@ -21,7 +21,7 @@
import TeamService from '../../services/team' import TeamService from '../../services/team'
export default { export default {
name: "ListTeams", name: 'ListTeams',
data() { data() {
return { return {
teamService: TeamService, teamService: TeamService,
@ -32,6 +32,9 @@
this.teamService = new TeamService() this.teamService = new TeamService()
this.loadTeams() this.loadTeams()
}, },
mounted() {
this.setTitle('Teams')
},
methods: { methods: {
loadTeams() { loadTeams() {
this.teamService.getAll() this.teamService.getAll()

View file

@ -51,6 +51,9 @@
this.team = new TeamModel() this.team = new TeamModel()
this.$store.commit(IS_FULLPAGE, true) this.$store.commit(IS_FULLPAGE, true)
}, },
mounted() {
this.setTitle('Create a new Team')
},
methods: { methods: {
newTeam() { newTeam() {

View file

@ -107,6 +107,9 @@
router.push({name: 'home'}) router.push({name: 'home'})
} }
}, },
created() {
this.setTitle('Login')
},
computed: mapState({ computed: mapState({
registrationEnabled: state => state.config.registrationEnabled, registrationEnabled: state => state.config.registrationEnabled,
loading: LOADING, loading: LOADING,

View file

@ -57,6 +57,9 @@
created() { created() {
this.passwordResetService = new PasswordResetService() this.passwordResetService = new PasswordResetService()
}, },
mounted() {
this.setTitle('Reset your password')
},
methods: { methods: {
submit() { submit() {
this.errorMsg = '' this.errorMsg = ''

View file

@ -67,6 +67,9 @@
router.push({name: 'home'}) router.push({name: 'home'})
} }
}, },
mounted() {
this.setTitle('Register')
},
computed: mapState({ computed: mapState({
authenticated: state => state.auth.authenticated, authenticated: state => state.auth.authenticated,
loading: LOADING, loading: LOADING,

View file

@ -47,6 +47,9 @@
this.passwordResetService = new PasswordResetService() this.passwordResetService = new PasswordResetService()
this.passwordReset = new PasswordResetModel() this.passwordReset = new PasswordResetModel()
}, },
mounted() {
this.setTitle('Reset your password')
},
methods: { methods: {
submit() { submit() {
this.errorMsg = '' this.errorMsg = ''

View file

@ -232,6 +232,9 @@
this.totpStatus() this.totpStatus()
}, },
mounted() {
this.setTitle('Settings')
},
computed: mapState({ computed: mapState({
totpEnabled: state => state.config.totpEnabled, totpEnabled: state => state.config.totpEnabled,
migratorsEnabled: state => state.config.availableMigrators !== null && state.config.availableMigrators.length > 0, migratorsEnabled: state => state.config.availableMigrators !== null && state.config.availableMigrators.length > 0,