minimal changes required to deploy the CAP samples in _shared db_ mode: - db: all bookshop, orders, reviews CDS models into one db instance (_shared-db_) - services: bookstore, orders, reviews - approuter with UI symlinks: - Vue: bookshop, reviews - Fiori: orders - authentification: xsuaa - messaging: Event Mesh - destinations: orders, reviews - cds: - projection OrdersNoDraft for backend direct access - event OrderChanged - deployment: mta.yml
94 lines
2.8 KiB
JavaScript
94 lines
2.8 KiB
JavaScript
/* global Vue axios */ //> from vue.html
|
|
const $ = sel => document.querySelector(sel)
|
|
const GET = (url) => axios.get('/reviews'+url)
|
|
const PUT = (cmd,data) => axios.patch('/reviews'+cmd,data)
|
|
const POST = (cmd,data) => axios.post('/reviews'+cmd,data)
|
|
|
|
const reviews = Vue.createApp ({
|
|
|
|
data() {
|
|
return {
|
|
list: [],
|
|
review: undefined,
|
|
message: {},
|
|
Ratings: Object.entries({
|
|
5 : '★★★★★',
|
|
4 : '★★★★',
|
|
3 : '★★★',
|
|
2 : '★★',
|
|
1 : '★',
|
|
}).reverse()
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
|
|
search: ({target:{value:v}}) => reviews.fetch(v && '&$search='+v),
|
|
|
|
async fetch (etc='') {
|
|
const {data} = await GET(`/Reviews?${etc}`)
|
|
reviews.list = data.value
|
|
},
|
|
|
|
async inspect (eve) {
|
|
const review = reviews.review = reviews.list [eve.currentTarget.rowIndex-1]
|
|
const res = await GET(`/Reviews/${review.ID}/text/$value`)
|
|
review.text = res.data
|
|
reviews.message = {}
|
|
},
|
|
|
|
newReview () {
|
|
reviews.review = {}
|
|
reviews.message = {}
|
|
setTimeout (()=> $('form > input').focus(), 111)
|
|
},
|
|
|
|
async submitReview () {
|
|
const review = reviews.review; review.rating = parseInt (review.rating) // REVISIT: Okra should be less strict
|
|
try {
|
|
if (!review.ID) {
|
|
const res = await POST(`/Reviews`,review)
|
|
reviews.ID = res.data.ID
|
|
} else {
|
|
await PUT(`/Reviews/${review.ID}`,review)
|
|
}
|
|
reviews.message = { succeeded: 'Your review was submitted successfully. Thanks.' }
|
|
} catch (e) {
|
|
reviews.message = { failed: e.response.data.error.message }
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
filters: {
|
|
stars: (r) => ('★'.repeat(Math.round(r))+'☆☆☆☆☆').slice(0,5),
|
|
datetime: (d) => d && new Date(d).toLocaleString(),
|
|
},
|
|
|
|
}).mount("#app")
|
|
|
|
// initially fill list of my reviews
|
|
reviews.fetch()
|
|
|
|
axios.interceptors.request.use(csrfToken)
|
|
function csrfToken (request) {
|
|
if (request.method === 'head' || request.method === 'get') return request
|
|
if ('csrfToken' in document) {
|
|
request.headers['x-csrf-token'] = document.csrfToken
|
|
return request
|
|
}
|
|
return fetchToken().then(token => {
|
|
document.csrfToken = token
|
|
request.headers['x-csrf-token'] = document.csrfToken
|
|
return request
|
|
}).catch(() => {
|
|
document.csrfToken = null // set mark to not try again
|
|
return request
|
|
})
|
|
|
|
function fetchToken() {
|
|
return axios.get('/', { headers: { 'x-csrf-token': 'fetch' } })
|
|
.then(res => res.headers['x-csrf-token'])
|
|
}
|
|
}
|