diff --git a/config/index.js b/config/index.js index b094ac4..1ba8003 100644 --- a/config/index.js +++ b/config/index.js @@ -27,7 +27,8 @@ module.exports = { '/login': 'http://localhost:3000', '/logout': 'http://localhost:3000', '/user': 'http://localhost:3000', - '/groups': 'http://localhost:3000' + '/groups': 'http://localhost:3000', + '/settings': 'http://localhost:3000' }, // CSS Sourcemaps off by default because relative paths are "buggy" // with this option, according to the CSS-Loader README diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 2c25d8e..8e1b47b 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -13,6 +13,7 @@ These are the paths you see in the browser (VueJS does client-side routing: no r - /#/day/:day - show groups for the given date (in yyyy-mm-dd format) - /#/user/ - list of all users (only visible by admins) - /#/user/:id - show setting for the give user ID +- /#/settings - global setting (only visible by admins) Web server ---------- @@ -33,6 +34,8 @@ Web server - /users/:id GET - a single user - /users/:id PUT - update a user - /users/current GET - information about the currently logged in user +- /settings GET - get all global settings +- /settings POST and PUT - add one or more new settings, or update existing ones - /login POST - login of a user - /logout GET - log the current user out diff --git a/src/App.vue b/src/App.vue index 692d469..3ac2310 100644 --- a/src/App.vue +++ b/src/App.vue @@ -9,12 +9,12 @@
today {{ day.day }}
- + more_vert - + edit notes edit @@ -81,32 +81,45 @@ export default { return { dates: datesWithGroups }; + }, + + loggedInUser() { + return this.$store.state.loggedInUser; + }, + + settings() { + return this.$store.state.settings || {}; } }, beforeCreate: function() { this.daysUrl = this.$resource('days{/day}'); this.daysInfoUrl = this.$resource('days{/day}/info'); + this.settingsUrl = this.$resource('settings'); }, mounted: function() { - var [year, month, day] = (this.$route.params.day || '').split('-'); - year = parseInt(year); - month = parseInt(month) - 1; - day = parseInt(day); - if (!isNaN(year) && !isNaN(month) && !isNaN(day)) { - this.date = new Date(year, month, day); - } - if (!(this.date && !isNaN(this.date.getTime()))) { - this.date = new Date(); - } - $('div.calendar span.prev').on('click', this.changeMonth); - $('div.calendar span.next').on('click', this.changeMonth); - $('div.calendar span.month').on('click', this.changeMonth); - this.reload(); + this.fetchSettings(this.initialize); }, methods: { + initialize() { + var [year, month, day] = (this.$route.params.day || '').split('-'); + year = parseInt(year); + month = parseInt(month) - 1; + day = parseInt(day); + if (!isNaN(year) && !isNaN(month) && !isNaN(day)) { + this.date = new Date(year, month, day); + } + if (!(this.date && !isNaN(this.date.getTime()))) { + this.date = new Date(); + } + $('div.calendar span.prev').on('click', this.changeMonth); + $('div.calendar span.next').on('click', this.changeMonth); + $('div.calendar span.month').on('click', this.changeMonth); + this.reload(); + }, + reload() { var ym = this.dateToString(this.date, true); this.getSummary({start: ym, end: ym}); @@ -193,6 +206,21 @@ export default { this.day.notes = json.notes; this.reload(); }); + }, + + fetchSettings(cb) { + this.settingsUrl.get().then((response) => { + return response.json(); + }, (response) => { + this.$refs.dialogObj.show({text: 'unable to fetch settings'}); + }).then((json) => { + if (!json || json.error) { + this.$refs.dialogObj.show({text: 'unable to fetch settings: ' + (json && json.message) || ''}); + } else { + this.$store.commit('updateSettings', json); + } + cb(); + }); } }, diff --git a/src/Attendee.vue b/src/Attendee.vue index 1641389..eda4e78 100644 --- a/src/Attendee.vue +++ b/src/Attendee.vue @@ -52,6 +52,9 @@ export default { computed: { loggedInUser() { return this.$store.state.loggedInUser; + }, + settings() { + return this.$store.state.settings || {}; } }, @@ -61,7 +64,7 @@ export default { methods: { isAuthorized(ownerID) { - return !ownerID || this.$store.state.loggedInUser.isAdmin || (this.$store.state.loggedInUser._id && this.$store.state.loggedInUser._id == ownerID); + return (!ownerID && !this.$store.state.settings.protectUnregistered) || this.$store.state.loggedInUser.isAdmin || (this.$store.state.loggedInUser._id && this.$store.state.loggedInUser._id == ownerID); }, editAttendee() { diff --git a/src/Group.vue b/src/Group.vue index 21841ad..229647e 100644 --- a/src/Group.vue +++ b/src/Group.vue @@ -7,16 +7,16 @@
folder_open {{ group.group }} {{ counter }}
- + more_vert - + edit notes edit - + rename group label @@ -146,6 +146,9 @@ export default { }, loggedInUser() { return this.$store.state.loggedInUser; + }, + settings() { + return this.$store.state.settings || {}; } }, diff --git a/src/Toolbar.vue b/src/Toolbar.vue index d3d3660..5157e74 100644 --- a/src/Toolbar.vue +++ b/src/Toolbar.vue @@ -11,6 +11,10 @@ ibt2 + + global settings + settings + list of users people_outline @@ -108,6 +112,10 @@ export default { this.$router.push('/user/'); }, + toSettingsPage() { + this.$router.push('/settings/'); + }, + focusToLoginForm() { var that = this; setTimeout(function() { that.$refs.usernameInput.$el.focus(); }, 400); diff --git a/src/User.vue b/src/User.vue index fea5b97..0b0d96c 100644 --- a/src/User.vue +++ b/src/User.vue @@ -17,8 +17,8 @@ is admin -
+
Save @@ -32,7 +32,7 @@ import IbtDialog from './IbtDialog.vue'; import IbtSnackbar from './IbtSnackbar.vue'; export default { - data () { + data() { return { user: {_id: null, email: '', password: null, isAdmin: false}, password: null diff --git a/src/main.js b/src/main.js index 96ce00e..40aea11 100644 --- a/src/main.js +++ b/src/main.js @@ -26,6 +26,7 @@ import store_data from './store.js'; import App from './App'; import User from './User'; import Users from './Users'; +import GlobalSettings from './GlobalSettings'; import Toolbar from './Toolbar'; import IbtFooter from './IbtFooter'; @@ -41,7 +42,8 @@ var routes = [ {path: '/day/', name: 'days', component: App}, {path: '/day/:day', name: 'day', component: App}, {path: '/user/', name: 'users', component: Users}, - {path: '/user/:id', name: 'user', component: User} + {path: '/user/:id', name: 'user', component: User}, + {path: '/settings/', name: 'settings', component: GlobalSettings}, ]; const store = new Vuex.Store(store_data); @@ -52,5 +54,5 @@ var vue = new Vue({ store: store, template: '
', router: router, - components: { App, Toolbar, IbtFooter, Users, User } + components: { App, Toolbar, IbtFooter, Users, User, GlobalSettings } }); diff --git a/src/store.js b/src/store.js index c251afc..6195f59 100644 --- a/src/store.js +++ b/src/store.js @@ -4,14 +4,20 @@ export default { state: { - loggedInUser: {username: ''} + loggedInUser: {username: ''}, + settings: {} }, mutations: { clearLoggedInUser(state, user) { state.loggedInUser = {username: ''}; }, + setLoggedInUser(state, user) { state.loggedInUser = user; + }, + + updateSettings(state, settings) { + state.settings = settings; } } };