diff --git a/src/MyPrayerJournal.Api/Handlers.fs b/src/MyPrayerJournal.Api/Handlers.fs index 8041a7c..bdc6a0d 100644 --- a/src/MyPrayerJournal.Api/Handlers.fs +++ b/src/MyPrayerJournal.Api/Handlers.fs @@ -142,7 +142,6 @@ module Models = open FSharp.Control.Tasks.V2.ContextInsensitive - /// /api/journal URLs module Journal = @@ -333,3 +332,36 @@ module Request = return! setStatusCode 204 next ctx | None -> return! Error.notFound next ctx } + +open Giraffe.TokenRouter + +/// The routes for myPrayerJournal +let webApp : HttpHandler = + router Error.notFound [ + route "/" Vue.app + subRoute "/api/" [ + GET [ + route "journal" Journal.journal + subRoute "request" [ + route "s/answered" Request.answered + routef "/%s/full" Request.getFull + routef "/%s/notes" Request.getNotes + routef "/%s" Request.get + ] + ] + PATCH [ + subRoute "request" [ + routef "/%s/recurrence" Request.updateRecurrence + routef "/%s/show" Request.show + routef "/%s/snooze" Request.snooze + ] + ] + POST [ + subRoute "request" [ + route "" Request.add + routef "/%s/history" Request.addHistory + routef "/%s/note" Request.addNote + ] + ] + ] + ] diff --git a/src/MyPrayerJournal.Api/Program.fs b/src/MyPrayerJournal.Api/Program.fs index 7a6728c..e272c4b 100644 --- a/src/MyPrayerJournal.Api/Program.fs +++ b/src/MyPrayerJournal.Api/Program.fs @@ -37,7 +37,6 @@ module Configure = open Giraffe open Giraffe.Serialization - open Giraffe.TokenRouter open Microsoft.AspNetCore.Authentication.JwtBearer open Microsoft.Extensions.DependencyInjection open MyPrayerJournal.Indexes @@ -102,37 +101,6 @@ module Configure = |> ignore bldr.ConfigureLogging logz - /// Routes for the available URLs within myPrayerJournal - let webApp = - router Handlers.Error.notFound [ - route "/" Handlers.Vue.app - subRoute "/api/" [ - GET [ - route "journal" Handlers.Journal.journal - subRoute "request" [ - route "s/answered" Handlers.Request.answered - routef "/%s/full" Handlers.Request.getFull - routef "/%s/notes" Handlers.Request.getNotes - routef "/%s" Handlers.Request.get - ] - ] - PATCH [ - subRoute "request" [ - routef "/%s/recurrence" Handlers.Request.updateRecurrence - routef "/%s/show" Handlers.Request.show - routef "/%s/snooze" Handlers.Request.snooze - ] - ] - POST [ - subRoute "request" [ - route "" Handlers.Request.add - routef "/%s/history" Handlers.Request.addHistory - routef "/%s/note" Handlers.Request.addNote - ] - ] - ] - ] - open System /// Configure the web application @@ -148,7 +116,7 @@ module Configure = | a -> a.UseAuthentication() .UseStaticFiles() - .UseGiraffe webApp + .UseGiraffe Handlers.webApp |> ignore) bldr.Configure appConfig diff --git a/src/app/package.json b/src/app/package.json index a805f38..05020c1 100644 --- a/src/app/package.json +++ b/src/app/package.json @@ -18,7 +18,6 @@ "moment": "^2.18.1", "vue": "^2.5.15", "vue-material": "^1.0.0-beta-11", - "vue-progressbar": "^0.7.3", "vue-router": "^3.0.0", "vuex": "^3.0.1" }, diff --git a/src/app/src/App.vue b/src/app/src/App.vue index c9b9cae..0c46aad 100644 --- a/src/app/src/App.vue +++ b/src/app/src/App.vue @@ -10,8 +10,9 @@ span(style='font-weight:700;') Journal navigation md-app-content + md-progress-bar(v-if='progress.visible' + :md-mode='progress.mode') router-view - vue-progress-bar md-snackbar(:md-active.sync='snackbar.visible' md-position='center' :md-duration='snackbar.interval' @@ -43,8 +44,13 @@ export default { }, data () { return { - messageEvents: new Vue(), + progress: { + events: new Vue(), + visible: false, + mode: 'query' + }, snackbar: { + events: new Vue(), visible: false, message: '', interval: 4000 @@ -52,13 +58,12 @@ export default { } }, mounted () { - this.messageEvents.$on('info', this.showInfo) - this.messageEvents.$on('error', this.showError) + this.progress.events.$on('show', this.showProgress) + this.progress.events.$on('done', this.hideProgress) + this.snackbar.events.$on('info', this.showInfo) + this.snackbar.events.$on('error', this.showError) }, computed: { - messages () { - return this.messageEvents - }, version () { return version.endsWith('.0') ? version.endsWith('.0.0') @@ -79,11 +84,19 @@ export default { showError (message) { this.snackbar.interval = Infinity this.showSnackbar(message) + }, + showProgress (mode) { + this.progress.mode = mode + this.progress.visible = true + }, + hideProgress () { + this.progress.visible = false } }, provide () { return { - messages: this.messageEvents + messages: this.snackbar.events, + progress: this.progress.events } } } @@ -281,4 +294,7 @@ a:hover { .material-icons { vertical-align: middle; } +.md-progress-bar { + margin: 24px; +} diff --git a/src/app/src/components/Journal.vue b/src/app/src/components/Journal.vue index 62ebf73..f6d94aa 100644 --- a/src/app/src/components/Journal.vue +++ b/src/app/src/components/Journal.vue @@ -32,7 +32,10 @@ import actions from '@/store/action-types' export default { name: 'journal', - inject: ['messages'], + inject: [ + 'messages', + 'progress' + ], components: { NotesEdit, RequestCard, @@ -53,7 +56,7 @@ export default { ...mapState(['user', 'journal', 'isLoadingJournal']) }, async created () { - await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress) + await this.$store.dispatch(actions.LOAD_JOURNAL, this.progress) this.messages.$emit('info', `Loaded ${this.journal.length} prayer requests`) }, provide () { diff --git a/src/app/src/components/request/ActiveRequests.vue b/src/app/src/components/request/ActiveRequests.vue index b9bb7df..cc0e390 100644 --- a/src/app/src/components/request/ActiveRequests.vue +++ b/src/app/src/components/request/ActiveRequests.vue @@ -21,6 +21,7 @@ import actions from '@/store/action-types' export default { name: 'active-requests', + inject: ['progress'], components: { RequestListItem }, @@ -41,7 +42,7 @@ export default { async ensureJournal () { if (!Array.isArray(this.journal)) { this.loaded = false - await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress) + await this.$store.dispatch(actions.LOAD_JOURNAL, this.progress) } this.requests = this.journal .sort((a, b) => a.showAfter - b.showAfter) diff --git a/src/app/src/components/request/AnsweredRequests.vue b/src/app/src/components/request/AnsweredRequests.vue index 3b16f5e..9ad145e 100644 --- a/src/app/src/components/request/AnsweredRequests.vue +++ b/src/app/src/components/request/AnsweredRequests.vue @@ -19,7 +19,10 @@ import RequestListItem from '@/components/request/RequestListItem' export default { name: 'answered-requests', - inject: ['messages'], + inject: [ + 'messages', + 'progress' + ], components: { RequestListItem }, @@ -30,15 +33,15 @@ export default { } }, async mounted () { - this.$Progress.start() + this.progress.$emit('show', 'query') try { const reqs = await api.getAnsweredRequests() this.requests = reqs.data - this.$Progress.finish() + this.progress.$emit('done') } catch (err) { console.error(err) this.messages.$emit('error', 'Error loading requests; check console for details') - this.$Progress.fail() + this.progress.$emit('done') } finally { this.loaded = true } diff --git a/src/app/src/components/request/EditRequest.vue b/src/app/src/components/request/EditRequest.vue index 6d7ea36..7366d2f 100644 --- a/src/app/src/components/request/EditRequest.vue +++ b/src/app/src/components/request/EditRequest.vue @@ -77,7 +77,10 @@ import actions from '@/store/action-types' export default { name: 'edit-request', - inject: ['messages'], + inject: [ + 'messages', + 'progress' + ], props: { id: { type: String, @@ -162,7 +165,7 @@ export default { async saveRequest () { if (this.isNew) { await this.$store.dispatch(actions.ADD_REQUEST, { - progress: this.$Progress, + progress: this.progress, requestText: this.form.requestText, recurType: this.form.recur.typ === 'Immediate' ? 'Immediate' : this.form.recur.other, recurCount: this.form.recur.typ === 'Immediate' ? 0 : Number.parseInt(this.form.recur.count) @@ -170,7 +173,7 @@ export default { this.messages.$emit('info', 'New prayer request added') } else { await this.$store.dispatch(actions.UPDATE_REQUEST, { - progress: this.$Progress, + progress: this.progress, requestId: this.form.requestId, updateText: this.form.requestText, status: this.form.status, diff --git a/src/app/src/components/request/FullRequest.vue b/src/app/src/components/request/FullRequest.vue index 99bb6a7..dd4f960 100644 --- a/src/app/src/components/request/FullRequest.vue +++ b/src/app/src/components/request/FullRequest.vue @@ -31,6 +31,7 @@ const asOfDesc = (a, b) => b.asOf - a.asOf export default { name: 'full-request', + inject: ['progress'], props: { id: { type: String, @@ -72,14 +73,14 @@ export default { } }, async mounted () { - this.$Progress.start() + this.progress.$emit('show', 'indeterminate') try { const req = await api.getFullRequest(this.id) this.request = req.data - this.$Progress.finish() + this.progress.$emit('done') } catch (e) { console.log(e) - this.$Progress.fail() + this.progress.$emit('done') } }, methods: { diff --git a/src/app/src/components/request/NotesEdit.vue b/src/app/src/components/request/NotesEdit.vue index 51dee0c..ea36c38 100644 --- a/src/app/src/components/request/NotesEdit.vue +++ b/src/app/src/components/request/NotesEdit.vue @@ -38,8 +38,9 @@ import api from '@/api' export default { name: 'notes-edit', inject: [ + 'journalEvents', 'messages', - 'journalEvents' + 'progress' ], data () { return { @@ -72,14 +73,14 @@ export default { this.notesVisible = false }, async loadNotes () { - this.$Progress.start() + this.progress.$emit('show', 'indeterminate') try { const notes = await api.getNotes(this.form.requestId) this.priorNotes = notes.data - this.$Progress.finish() + this.progress.$emit('done') } catch (e) { console.error(e) - this.$Progress.fail() + this.progress.$emit('done') } finally { this.priorNotesLoaded = true } @@ -89,15 +90,15 @@ export default { this.notesVisible = true }, async saveNotes () { - this.$Progress.start() + this.progress.$emit('show', 'indeterminate') try { await api.addNote(this.form.requestId, this.form.notes) - this.$Progress.finish() + this.progress.$emit('done') this.messages.$emit('info', 'Added notes') this.closeDialog() } catch (e) { console.error(e) - this.$Progress.fail() + this.progress.$emit('done') } }, trimText () { diff --git a/src/app/src/components/request/RequestListItem.vue b/src/app/src/components/request/RequestListItem.vue index a8553e6..06b5709 100644 --- a/src/app/src/components/request/RequestListItem.vue +++ b/src/app/src/components/request/RequestListItem.vue @@ -35,7 +35,10 @@ import actions from '@/store/action-types' export default { name: 'request-list-item', - inject: ['messages'], + inject: [ + 'messages', + 'progress' + ], props: { request: { required: true } }, @@ -59,7 +62,7 @@ export default { methods: { async cancelSnooze () { await this.$store.dispatch(actions.SNOOZE_REQUEST, { - progress: this.$Progress, + progress: this.progress, requestId: this.request.requestId, until: 0 }) @@ -71,7 +74,7 @@ export default { }, async showNow () { await this.$store.dispatch(actions.SHOW_REQUEST_NOW, { - progress: this.$Progress, + progress: this.progress, requestId: this.request.requestId, showAfter: Date.now() }) diff --git a/src/app/src/components/request/SnoozeRequest.vue b/src/app/src/components/request/SnoozeRequest.vue index 007aa2d..ccfb800 100644 --- a/src/app/src/components/request/SnoozeRequest.vue +++ b/src/app/src/components/request/SnoozeRequest.vue @@ -26,7 +26,11 @@ import actions from '@/store/action-types' export default { name: 'snooze-request', - inject: ['messages'], + inject: [ + 'journalEvents', + 'messages', + 'progress' + ], props: { events: { required: true } }, @@ -40,7 +44,7 @@ export default { } }, created () { - this.events.$on('snooze', this.openDialog) + this.journalEvents.$on('snooze', this.openDialog) }, computed: { isValid () { @@ -59,7 +63,7 @@ export default { }, async snoozeRequest () { await this.$store.dispatch(actions.SNOOZE_REQUEST, { - progress: this.$Progress, + progress: this.progress, requestId: this.form.requestId, until: Date.parse(this.form.snoozedUntil) }) diff --git a/src/app/src/components/request/SnoozedRequests.vue b/src/app/src/components/request/SnoozedRequests.vue index 6e2b84a..9258093 100644 --- a/src/app/src/components/request/SnoozedRequests.vue +++ b/src/app/src/components/request/SnoozedRequests.vue @@ -21,6 +21,7 @@ import RequestListItem from '@/components/request/RequestListItem' export default { name: 'snoozed-requests', + inject: ['progress'], components: { RequestListItem }, @@ -40,7 +41,7 @@ export default { async ensureJournal () { if (!Array.isArray(this.journal)) { this.loaded = false - await this.$store.dispatch(actions.LOAD_JOURNAL, this.$Progress) + await this.$store.dispatch(actions.LOAD_JOURNAL, this.progress) } this.requests = this.journal .filter(req => req.snoozedUntil > Date.now()) diff --git a/src/app/src/components/user/LogOn.vue b/src/app/src/components/user/LogOn.vue index 35a96d9..a9a5afd 100644 --- a/src/app/src/components/user/LogOn.vue +++ b/src/app/src/components/user/LogOn.vue @@ -11,8 +11,9 @@ import AuthService from '@/auth/AuthService' export default { name: 'log-on', + inject: ['progress'], created () { - this.$Progress.start() + this.progress.$emit('show', 'indeterminate') new AuthService().handleAuthentication(this.$store, this.$router) // Auth service redirects to dashboard, which restarts the progress bar } diff --git a/src/app/src/main.js b/src/app/src/main.js index ceef0f5..1654f93 100644 --- a/src/app/src/main.js +++ b/src/app/src/main.js @@ -3,7 +3,6 @@ // Vue packages and components import Vue from 'vue' import VueMaterial from 'vue-material' -import VueProgressBar from 'vue-progressbar' // myPrayerJournal components import App from './App' @@ -20,17 +19,6 @@ import 'vue-material/dist/theme/default.css' Vue.config.productionTip = false -Vue.use(VueProgressBar, { - color: 'yellow', - failedColor: 'red', - height: '5px', - transition: { - speed: '0.2s', - opacity: '0.6s', - termination: 1000 - } -}) - Vue.use(VueMaterial) Vue.component('date-from-now', DateFromNow) Vue.component('page-title', PageTitle) diff --git a/src/app/src/store/index.js b/src/app/src/store/index.js index 830acd6..a805d41 100644 --- a/src/app/src/store/index.js +++ b/src/app/src/store/index.js @@ -76,34 +76,34 @@ export default new Vuex.Store({ }, actions: { async [actions.ADD_REQUEST] ({ commit }, { progress, requestText, recurType, recurCount }) { - progress.start() + progress.$emit('show', 'indeterminate') try { const newRequest = await api.addRequest(requestText, recurType, recurCount) commit(mutations.REQUEST_ADDED, newRequest.data) - progress.finish() + progress.$emit('done') } catch (err) { logError(err) - progress.fail() + progress.$emit('done') } }, async [actions.LOAD_JOURNAL] ({ commit }, progress) { commit(mutations.LOADED_JOURNAL, {}) - progress.start() + progress.$emit('show', 'query') commit(mutations.LOADING_JOURNAL, true) api.setBearer(localStorage.getItem('id_token')) try { const jrnl = await api.journal() commit(mutations.LOADED_JOURNAL, jrnl.data) - progress.finish() + progress.$emit('done') } catch (err) { logError(err) - progress.fail() + progress.$emit('done') } finally { commit(mutations.LOADING_JOURNAL, false) } }, async [actions.UPDATE_REQUEST] ({ commit, state }, { progress, requestId, status, updateText, recurType, recurCount }) { - progress.start() + progress.$emit('show', 'indeterminate') try { let oldReq = (state.journal.filter(req => req.requestId === requestId) || [])[0] || {} if (!(status === 'Prayed' && updateText === '')) { @@ -116,34 +116,34 @@ export default new Vuex.Store({ } const request = await api.getRequest(requestId) commit(mutations.REQUEST_UPDATED, request.data) - progress.finish() + progress.$emit('done') } catch (err) { logError(err) - progress.fail() + progress.$emit('done') } }, async [actions.SHOW_REQUEST_NOW] ({ commit }, { progress, requestId, showAfter }) { - progress.start() + progress.$emit('show', 'indeterminate') try { await api.showRequest(requestId, showAfter) const request = await api.getRequest(requestId) commit(mutations.REQUEST_UPDATED, request.data) - progress.finish() + progress.$emit('done') } catch (err) { logError(err) - progress.fail() + progress.$emit('done') } }, async [actions.SNOOZE_REQUEST] ({ commit }, { progress, requestId, until }) { - progress.start() + progress.$emit('show', 'indeterminate') try { await api.snoozeRequest(requestId, until) const request = await api.getRequest(requestId) commit(mutations.REQUEST_UPDATED, request.data) - progress.finish() + progress.$emit('done') } catch (err) { logError(err) - progress.fail() + progress.$emit('done') } } }, diff --git a/src/app/yarn.lock b/src/app/yarn.lock index c56589e..52dc2c9 100644 --- a/src/app/yarn.lock +++ b/src/app/yarn.lock @@ -8307,11 +8307,6 @@ vue-material@^1.0.0-beta-11: resolved "https://registry.yarnpkg.com/vue-material/-/vue-material-1.0.0-beta-11.tgz#11baf0cdb22a35d35859c619099d6c3cb3cc2cc3" integrity sha512-1+dIVkQafMIA/zNONb7OwGaTjAxaWk/JhUA2/FInQvbArxf1ToKB+yIdeSfzopQ1KICnBTAmk9E0Vdr5p4MWNA== -vue-progressbar@^0.7.3: - version "0.7.5" - resolved "https://registry.yarnpkg.com/vue-progressbar/-/vue-progressbar-0.7.5.tgz#414730892252b1e45582d4979dec93038e007f79" - integrity sha512-VeNG/inMsFbvdCTS7lJ1gjDAKSUZdqkhW9gS1tb0we1rqFKxR+BCEiVUgw5C84vODKb14M2GWHTw0WVdpoVg6g== - vue-router@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.1.2.tgz#2e0904703545dabdd42b2b7a2e617f02f99a1969"