TT#39948 Reminder: Refactor api methods, component, mutations and actions

Change-Id: Ic9308c71bfc45bc34d8e4d910fc655453a664a04
changes/21/22421/4
Hans-Peter Herzog 7 years ago
parent 84d019734b
commit d99f6fa493

@ -1,68 +1,134 @@
import Vue from 'vue';
export function createReminder(id) {
import _ from 'lodash'
import Vue from 'vue'
import {
getList,
patchReplace
} from './common'
export function createReminder(subscriberId) {
return new Promise((resolve, reject) => {
var data = {
subscriber_id: id,
Vue.http.post('api/reminders/', {
subscriber_id: subscriberId,
time: '00:00',
recur: 'never',
active: false
};
Vue.http.post('api/reminders/', data).then((result) => {
var reminderID = result.headers.get('Location').split('/')[3];
resolve(reminderID);
}).then((result) => {
let parts = result.headers.get('Location').split('/');
resolve(_.last(parts));
}).catch((err) => {
reject(err);
});
});
}
export function getReminder(id) {
export function getFirstReminder(subscriberId) {
return new Promise((resolve, reject) => {
Vue.http.get('api/reminders/', {
getList({
path: 'api/reminders/',
root: '_embedded.ngcp:reminders',
params: {
supplier_id: id
page: 1,
rows: 1,
subscriber_id: subscriberId
}
}).then((result) => {
resolve(JSON.parse(result.body));
}).catch((err) => {
}).then((reminders)=>{
resolve(_.get(reminders, 'items.0', null));
}).catch((err)=>{
reject(err);
});
});
}
export function enableReminder(id) {
return patchReminder(id, '/active', true);
export function getReminder(subscriberId) {
return new Promise((resolve, reject)=>{
Promise.resolve().then(()=>{
return getFirstReminder(subscriberId);
}).then((reminder)=>{
if(reminder === null) {
return createAndGetReminder(subscriberId);
}
else {
return Promise.resolve(reminder);
}
}).then((reminder)=>{
resolve(reminder);
}).catch((err)=>{
reject(err);
});
});
}
export function disableReminder(id) {
return patchReminder(id, '/active', false);
export function createAndGetReminder(subscriberId) {
return new Promise((resolve, reject)=>{
Promise.resolve().then(()=>{
return createReminder(subscriberId);
}).then(()=>{
return getFirstReminder(subscriberId);
}).then((reminder)=>{
resolve(reminder);
}).catch((err)=>{
reject(err);
});
});
}
export function setTime(id, time) {
return patchReminder(id, '/time', time);
export function setReminderActive(reminderId, active) {
return patchReplace({
path: 'api/reminders/' + reminderId,
fieldPath: 'active',
value: active
});
}
export function setRecurrence(id, recurrence) {
return patchReminder(id, '/recur', recurrence);
export function setReminderTime(reminderId, time) {
return patchReplace({
path: 'api/reminders/' + reminderId,
fieldPath: 'time',
value: time
});
}
function patchReminder(id, field, value) {
return new Promise((resolve, reject) => {
var data = [{
"op": "replace",
"path": field,
"value": value
}];
var patchHeaders = {
headers: {
'Content-Type': 'application/json-patch+json'
}
};
Vue.http.patch('api/reminders/' + id, data, patchHeaders).then(() => {
resolve();
}).catch((err) => {
reject(err);
});
export function setReminderRecurrence(reminderId, reccurence) {
return patchReplace({
path: 'api/reminders/' + reminderId,
fieldPath: 'recur',
value: reccurence
});
}
// export function enableReminder(id) {
// return patchReminder(id, '/active', true);
// }
//
// export function disableReminder(id) {
// return patchReminder(id, '/active', false);
// }
//
// export function setTime(id, time) {
// return patchReminder(id, '/time', time);
// }
//
// export function setRecurrence(id, recurrence) {
// return patchReminder(id, '/recur', recurrence);
// }
//
// function patchReminder(id, field, value) {
// return new Promise((resolve, reject) => {
// var data = [{
// "op": "replace",
// "path": field,
// "value": value
// }];
// var patchHeaders = {
// headers: {
// 'Content-Type': 'application/json-patch+json'
// }
// };
// Vue.http.patch('api/reminders/' + id, data, patchHeaders).then(() => {
// resolve();
// }).catch((err) => {
// reject(err);
// });
// });
// }

@ -1,117 +1,166 @@
<template>
<csc-page :title="$t('pages.reminder.title')" class="csc-simple-page">
<q-field class="reminder-field">
<q-toggle :label="$t('pages.reminder.title') + (active ? ' enabled':' disabled')" @input="toggleReminder()" v-model="active" />
<csc-page
class="csc-simple-page"
>
<q-field
class="reminder-field"
>
<q-toggle
:disable="isReminderLoading"
:label="toggleLabel"
:value="isReminderActive"
@input="toggleReminder()"
checked-icon="notifications_active"
unchecked-icon="notifications_off"
/>
</q-field>
<q-field class="reminder-field">
<q-datetime type="time" :disable="!active" no-clear=true v-model="timeConverted" :placeholder="$t('reminder.timeLabel')" @change="changeTime()" />
<q-field
class="reminder-field"
>
<q-datetime
format24h
type="time"
:no-clear="true"
:disable="isReminderLoading"
:float-label="$t('pages.reminder.timeLabel')"
:value="normalizedTime"
@input="updateTime"
/>
</q-field>
<q-field class="reminder-field">
<q-option-group :disable="!active" color="positive" type="radio" v-model="recurrence" @change="changeRecurrence()" :options="[
{ label: $t('pages.reminder.recurrence.once'), value: 'never' },
{ label: $t('pages.reminder.recurrence.weekdays'), value: 'weekdays' },
{ label: $t('pages.reminder.recurrence.always'), value: 'always' }
]" />
<q-field
class="reminder-field"
>
<q-option-group
color="positive"
type="radio"
:disable="isReminderLoading"
:options="recurrenceOptions"
:value="reminderRecurrence"
@input="updateRecurrence"
/>
</q-field>
</csc-page>
</template>
<script>
import CscPage from '../CscPage'
import {
QField,
QToggle,
QDatetime,
QOptionGroup,
date,
Toast
} from 'quasar-framework'
export default {
data() {
return {
active: false,
time: undefined,
recurrence: 'never'
}
},
mounted() {
this.$store.dispatch('reminder/loadReminder').then(() => {
this.active = this.$store.state.reminder.active;
this.time = this.$store.state.reminder.time;
this.recurrence = this.$store.state.reminder.recurrence;
}).catch((err) => {
console.log(err);
});
},
components: {
CscPage,
import _ from 'lodash'
import {
mapGetters
} from 'vuex'
import CscPage from '../CscPage'
import {
QField,
QToggle,
Toast,
QDatetime,
QOptionGroup,
QField
},
computed: {
timeConverted: {
get: function() {
var computedTime;
if (this.time) {
computedTime = date.buildDate({
hours: this.time.split(':')[0],
minutes: this.time.split(':')[1],
seconds: '00'
});
Toast
} from 'quasar-framework'
import {
showToast
} from '../../helpers/ui'
export default {
data() {
return {}
},
mounted() {
this.$store.dispatch('reminder/loadReminder');
},
components: {
CscPage,
QToggle,
Toast,
QDatetime,
QOptionGroup,
QField
},
computed: {
...mapGetters('reminder', [
'isReminderActive',
'reminderTime',
'reminderRecurrence',
'reminderLoadingState',
'reminderUpdating',
'reminderError',
'isReminderLoading',
'reminderUpdated'
]),
recurrenceOptions() {
return [
{
label: this.$t('pages.reminder.recurrence.once'),
value: 'never'
},
{
label: this.$t('pages.reminder.recurrence.weekdays'),
value: 'weekdays'
},
{
label: this.$t('pages.reminder.recurrence.always'),
value: 'always'
}
]
},
toggleLabel() {
if(this.isReminderActive) {
return this.$t('pages.reminder.toggleEnabled');
}
else {
computedTime = date.buildDate({
hours: '00',
minutes: '00',
seconds: '00'
});
return this.$t('pages.reminder.toggleDisabled');
}
return computedTime;
},
set: function(newValue) {
this.time = date.formatDate(newValue, 'HH:mm:ss');
normalizedTime() {
let timeParts = this.reminderTime.split(':');
let newDate = new Date();
newDate.setHours(parseInt(_.get(timeParts, '0', 0)));
newDate.setMinutes(parseInt(_.get(timeParts, '1', 0)));
newDate.setSeconds(parseInt(_.get(timeParts, '2', 0)));
return newDate;
}
}
},
methods: {
toggleReminder() {
this.$store.dispatch('reminder/toggleReminder', this.active).then(() => {
Toast.create({
html: this.$t('pages.reminder.title') + (this.active ? ' enabled' : ' disabled'),
color: 'white',
bgColor: '#68A44E'
});
}).catch((err) => {
console.log(err);
});
},
changeTime() {
this.$store.dispatch('reminder/changeTime', this.time).then(() => {
Toast.create({
html: this.$t('pages.reminder.timeUpdatedMsg') ,
color: 'white',
bgColor: '#68A44E'
});
}).catch((err) => {
console.log(err);
});
methods: {
mapRecurrence(recurrence) {
switch(recurrence) {
case 'never':
return this.$t('pages.reminder.recurrence.once');
case 'weekdays':
return this.$t('pages.reminder.recurrence.weekdays');
case 'always':
return this.$t('pages.reminder.recurrence.always');
}
},
toggleReminder() {
this.$store.dispatch('reminder/toggleReminder');
},
updateTime(time) {
this.$store.dispatch('reminder/updateTime', time);
},
updateRecurrence(recurrence) {
this.$store.dispatch('reminder/updateRecurrence', recurrence);
}
},
changeRecurrence() {
this.$store.dispatch('reminder/changeRecurrence', this.recurrence).then(() => {
Toast.create({
html: this.$t('pages.reminder.recurrenceUpdatedMsg'),
color: 'white',
bgColor: '#68A44E'
});
}).catch((err) => {
console.log(err);
});
watch: {
reminderUpdated(updated) {
if(updated && this.reminderUpdating === 'active' && this.isReminderActive) {
showToast(this.$t('pages.reminder.enabledToast'));
}
else if(updated && this.reminderUpdating === 'active') {
showToast(this.$t('pages.reminder.disabledToast'));
}
else if(updated && this.reminderUpdating === 'time') {
showToast(this.$t('pages.reminder.timeChangedToast', {
time: this.reminderTime
}));
}
else if(updated && this.reminderUpdating === 'recurrence') {
showToast(this.$t('pages.reminder.recurrenceChangedToast', {
recurrence: this.mapRecurrence(this.reminderRecurrence)
}));
}
}
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">

@ -123,15 +123,18 @@
"reloadItemsErrorMessage": "Reloading conversation items failed"
},
"reminder": {
"title": "Reminder",
"toggleEnabled": "Reminder is enabled",
"toggleDisabled": "Reminder is disabled",
"timeLabel": "Time of the day",
"recurrence": {
"once": "Only once",
"weekdays": "On weekdays",
"always": "Always"
},
"timeUpdatedMsg": "Time updated!",
"recurrenceUpdatedMsg": "Recurrence updated!"
"enabledToast": "Reminder: Enabled successfully",
"disabledToast": "Reminder: Disabled successfully",
"timeChangedToast": "Reminder: Time changed to {time}",
"recurrenceChangedToast": "Reminder: Recurrence changed to \"{recurrence}\""
},
"callForward": {
"titles": {

@ -1,101 +1,129 @@
'use strict';
import moment from 'moment'
import _ from 'lodash'
import { RequestState } from './common'
import {
getReminder,
createReminder,
enableReminder,
disableReminder,
setTime,
setRecurrence
setReminderActive,
setReminderTime,
setReminderRecurrence
} from '../api/reminder';
export default {
namespaced: true,
state: {
reminder: null,
reminderLoadingState: RequestState.initiated,
reminderUpdating: null,
reminderUpdated: false,
reminderError: null
},
getters: {
isReminderActive(state) {
return state.reminder !== null && state.reminder.active === true;
},
reminderTime(state) {
return _.get(state.reminder, 'time', '00:00:00');
},
reminderRecurrence(state) {
return _.get(state.reminder, 'recur', null);
},
reminderLoadingState(state) {
return state.reminderLoadingState;
},
reminderUpdating(state) {
return state.reminderUpdating;
},
reminderError(state) {
return state.reminderError
},
reminderId(state) {
return _.get(state.reminder, 'id', null);
},
isReminderLoading(state) {
return state.reminderLoadingState === RequestState.requesting;
},
reminderUpdated(state) {
return state.reminderUpdated;
}
},
mutations: {
reminderLoaded(state, options) {
state.reminderID = options.id;
state.active = options.active;
state.time = options.time;
state.recurrence = options.recur;
reminderLoading(state) {
state.reminderLoadingState = RequestState.requesting;
state.reminderError = null;
},
enableReminder(state) {
state.active = true;
reminderLoaded(state, reminder) {
state.reminderLoadingState = RequestState.succeeded;
state.reminder = reminder;
},
disableReminder(state) {
state.active = false;
reminderLoadingFailed(state, error) {
state.reminderLoadingState = RequestState.failed;
state.reminderError = error;
},
setTime(state, newTime) {
state.time = newTime;
reminderUpdating(state, field) {
state.reminderLoadingState = RequestState.requesting;
state.reminderUpdating = field;
state.reminderUpdated = false;
},
setRecurrence(state, recurrence) {
state.recurrence = recurrence;
reminderUpdated(state) {
state.reminderError = null;
state.reminderUpdated = true;
},
reminderCreated(state, reminderID) {
state.reminderID = reminderID;
reminderUpdatingFailed(state, error) {
state.reminderLoadingState = RequestState.failed;
state.reminderError = error;
}
},
actions: {
loadReminder(context) {
return new Promise((resolve, reject) => {
getReminder(localStorage.getItem('subscriberId')).then((result) => {
if (result.total_count > 0) {
context.commit('reminderLoaded', result._embedded['ngcp:reminders'][0]); // open to suggestions on how to extract data here
}
else {
// If no default reminder is set, then we need to create it.
createReminder(localStorage.getItem('subscriberId')).then((result) => {
context.commit('reminderCreated', result);
resolve();
}).catch((err) => {
reject(err);
});
}
return new Promise((resolve, reject)=>{
context.commit('reminderLoading');
getReminder(localStorage.getItem('subscriberId')).then((reminder)=>{
context.commit('reminderLoaded', reminder);
resolve();
}).catch((err) => {
}).catch((err)=>{
reject(err);
context.commit('reminderLoadingFailed', err.message);
});
});
},
toggleReminder(context, enabled) {
return new Promise((resolve, reject) => {
if (enabled === true) {
enableReminder(context.state.reminderID).then(() => {
context.commit('enableReminder');
resolve();
}).catch((err) => {
reject(err);
});
}
else {
disableReminder(context.state.reminderID).then(() => {
context.commit('disableReminder');
resolve();
}).catch((err) => {
reject(err);
});
}
});
toggleReminder(context) {
context.commit('reminderUpdating', 'active');
if(context.getters.reminderId !== null) {
setReminderActive(context.getters.reminderId, !context.getters.isReminderActive).then(()=>{
return context.dispatch('loadReminder');
}).then(()=>{
context.commit('reminderUpdated');
}).catch((err)=>{
context.commit('reminderUpdatingFailed', err.message);
});
}
},
changeTime(context, time) {
return new Promise((resolve, reject) => {
setTime(context.state.reminderID, time).then(() => {
context.commit('setTime', time);
resolve();
}).catch((err) => {
reject(err);
updateTime(context, time) {
context.commit('reminderUpdating', 'time');
if(context.getters.reminderId !== null) {
setReminderTime(context.getters.reminderId, moment(time).format('HH:mm:ss')).then(()=>{
return context.dispatch('loadReminder');
}).then(()=>{
context.commit('reminderUpdated');
}).catch((err)=>{
context.commit('reminderUpdatingFailed', err.message);
});
});
}
},
changeRecurrence(context, recurrence) {
return new Promise((resolve, reject) => {
setRecurrence(context.state.reminderID, recurrence).then(() => {
context.commit('setRecurrence', recurrence);
resolve();
}).catch((err) => {
reject(err);
updateRecurrence(context, recurrence) {
context.commit('reminderUpdating', 'recurrence');
if(context.getters.reminderId !== null) {
setReminderRecurrence(context.getters.reminderId, recurrence).then(()=>{
return context.dispatch('loadReminder');
}).then(()=>{
context.commit('reminderUpdated');
}).catch((err)=>{
context.commit('reminderUpdatingFailed', err.message);
});
});
}
}
}
};

@ -1,157 +0,0 @@
'use strict';
import Vue from 'vue';
import VueResource from 'vue-resource';
import {
createReminder,
getReminder,
enableReminder,
disableReminder,
setTime,
setRecurrence
} from '../../src/api/reminder';
import {
assert
} from 'chai';
Vue.use(VueResource);
describe('Reminder', function() {
var subscriberId = 123;
var reminderID = 1;
beforeEach(function() {
Vue.http.interceptors = [];
});
it('should return 201 when creating a new reminder', function(done) {
Vue.http.interceptors.unshift((request, next) => {
assert.equal(request.url, 'api/reminders/');
assert.equal(request.body.subscriber_id, subscriberId);
assert.equal(request.body.time, '00:00');
assert.equal(request.body.recur, 'never');
assert.equal(request.body.active, false);
next(
request.respondWith('', {
status: 201,
headers: {
location: 'api/reminders/' + reminderID
}
})
)
});
createReminder(subscriberId).then((result) => {
done();
}).catch((err) => {
done(err);
});
});
it('should get the existing reminder', function(done) {
Vue.http.interceptors.unshift((request, next) => {
assert.equal(request.url, 'api/reminders/');
assert.equal(request.params.supplier_id, subscriberId);
next(request.respondWith(JSON.stringify({
"_embedded": {
"ngcp:reminders": [{
"active": true,
"id": reminderID,
"recur": "always",
"subscriber_id": 239,
"time": "18:47:00"
}]
},
"total_count": 1
}), {
status: 200
}));
});
getReminder(subscriberId).then((result) => {
var reminderData = result._embedded['ngcp:reminders'][0];
assert.property(reminderData, 'id');
assert.property(reminderData, 'active');
assert.property(reminderData, 'recur');
assert.property(reminderData, 'subscriber_id');
assert.property(reminderData, 'time');
assert.isNumber(reminderData.id);
assert.isTrue(reminderData.active);
assert.include(['always', 'once', 'weekdays'], reminderData.recur);
assert.isNumber(reminderData.subscriber_id);
assert.isString(reminderData.time)
done();
}).catch((err) => {
done(err);
});
});
it('should activate a reminder', function(done) {
Vue.http.interceptors.unshift((request, next) => {
assert.equal(request.url, 'api/reminders/' + reminderID);
assert.equal(request.body[0].op, 'replace');
assert.equal(request.body[0].path, '/active');
assert.equal(request.body[0].value, true);
next(request.respondWith('', {
status: 204
}));
});
enableReminder(reminderID).then(() => {
done();
}).catch((err) => {
done(err);
});
});
it('should deactivate a reminder', function(done) {
Vue.http.interceptors.unshift((request, next) => {
assert.equal(request.url, 'api/reminders/' + reminderID);
assert.equal(request.body[0].op, 'replace');
assert.equal(request.body[0].path, '/active');
assert.equal(request.body[0].value, false);
next(request.respondWith('', {
status: 204
}));
});
disableReminder(reminderID).then(() => {
done();
}).catch((err) => {
done(err);
});
});
it('should set reminder time', function(done) {
Vue.http.interceptors.unshift((request, next) => {
assert.equal(request.url, 'api/reminders/' + reminderID);
assert.equal(request.body[0].op, 'replace');
assert.equal(request.body[0].path, '/time');
assert.equal(request.body[0].value, '22:22:00');
next(request.respondWith('', {
status: 204
}));
});
setTime(reminderID, '22:22:00').then(() => {
done();
}).catch((err) => {
done(err);
});
});
it('should set reminder recurrence', function(done) {
Vue.http.interceptors.unshift((request, next) => {
assert.equal(request.url, 'api/reminders/' + reminderID);
assert.equal(request.body[0].op, 'replace');
assert.equal(request.body[0].path, '/recur');
assert.equal(request.body[0].value, 'always');
next(request.respondWith('', {
status: 204
}));
});
setRecurrence(reminderID, 'always').then(() => {
done();
}).catch((err) => {
done(err);
});
});
});

@ -1,54 +0,0 @@
'use strict';
import Reminder from '../../src/store/reminder';
import {
assert
} from 'chai';
describe('Reminder', () => {
it('should load reminder data', () => {
var state = {};
var data = {
id: '1',
active: true,
time: '23:23:00',
recur: 'always'
};
Reminder.mutations.reminderLoaded(state, data);
assert.equal(state.reminderID, data.id);
assert.equal(state.active, data.active);
assert.equal(state.time, data.time);
assert.equal(state.recurrence, data.recur);
});
it('should enable/disable the reminder', () => {
var state = {};
Reminder.mutations.enableReminder(state);
assert.equal(state.active, true);
Reminder.mutations.disableReminder(state);
assert.equal(state.active, false);
});
it('should set reminder time', () => {
var state = {};
var time = '23:23:00'
Reminder.mutations.setTime(state, time);
assert.equal(state.time, time);
});
it('should set reminder recurrence', () => {
var state = {};
var recurrence = 'always'
Reminder.mutations.setRecurrence(state, recurrence);
assert.equal(state.recurrence, recurrence);
});
it('should set reminder id', () => {
var state = {};
var reminderID = '1'
Reminder.mutations.reminderCreated(state, reminderID);
assert.equal(state.reminderID, reminderID);
});
});
Loading…
Cancel
Save