Bugzilla – Attachment 146642 Details for
Bug 32939
Have generic fetch functions in vue modules
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 32939: Have a generic fetch function for POST and PUT requests in vue modules
Bug-32939-Have-a-generic-fetch-function-for-POST-a.patch (text/plain), 18.65 KB, created by
Pedro Amorim
on 2023-02-14 16:17:00 UTC
(
hide
)
Description:
Bug 32939: Have a generic fetch function for POST and PUT requests in vue modules
Filename:
MIME Type:
Creator:
Pedro Amorim
Created:
2023-02-14 16:17:00 UTC
Size:
18.65 KB
patch
obsolete
>From 9c5e1462739a8d30c56ed63b6192923ba5c804b5 Mon Sep 17 00:00:00 2001 >From: Pedro Amorim <pedro.amorim@ptfs-europe.com> >Date: Tue, 14 Feb 2023 16:15:53 +0000 >Subject: [PATCH] Bug 32939: Have a generic fetch function for POST and PUT > requests in vue modules > >- Cleaned up the code and further extended the implementation concept on agreements only. >- Jonathan I followed your suggestions but had to keep async/await or the catch will not work if an error is thrown from the http-client >- I'm keeping this as a separate patch for diff check (intention is to squash all of it once we're happy) >- I plan on continuing with this in coming days but more feedback is always welcome, also plan on rebasing this to 32925 > >Later: >- api-client.js should be renamed to erm-api-client.js (or something of the sort) but I kept the same name for now for diff check >- erm.js will ultimately disappear once this is all done (or api-client.js will become erm.js) >--- > .../components/ERM/AgreementRelationships.vue | 5 +- > .../vue/components/ERM/AgreementsFormAdd.vue | 54 ++++----------- > .../ERM/AgreementsFormConfirmDelete.vue | 44 +++++-------- > .../js/vue/components/ERM/AgreementsList.vue | 5 +- > .../js/vue/components/ERM/AgreementsShow.vue | 12 ++-- > .../prog/js/vue/fetch/api-client.js | 43 +++++++++--- > .../intranet-tmpl/prog/js/vue/fetch/erm.js | 22 +------ > .../intranet-tmpl/prog/js/vue/fetch/fetch.js | 26 -------- > .../prog/js/vue/fetch/http-client.js | 65 +++++++------------ > 9 files changed, 103 insertions(+), 173 deletions(-) > delete mode 100644 koha-tmpl/intranet-tmpl/prog/js/vue/fetch/fetch.js > >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementRelationships.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementRelationships.vue >index 17bd31b784..241f065818 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementRelationships.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementRelationships.vue >@@ -85,7 +85,7 @@ > </template> > > <script> >-import { fetchAgreements } from "../../fetch/erm.js" >+import { ERMAPIClient } from "../../fetch/api-client.js"; > > export default { > data() { >@@ -94,7 +94,8 @@ export default { > } > }, > beforeCreate() { >- fetchAgreements().then(agreements => { >+ const client = new ERMAPIClient() >+ const agreements = client.agreements.getAll("_per_page=-1").then(agreements => { > this.agreements = agreements.filter( > agreement => agreement.agreement_id !== this.agreement_id > ) >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsFormAdd.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsFormAdd.vue >index 2e684dc681..9b85149ced 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsFormAdd.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsFormAdd.vue >@@ -194,12 +194,8 @@ import { > setMessage, > setError, > setWarning, >- isSubmitting, >- submitted, > } from "../../messages" >-import { fetchAgreement } from "../../fetch/erm.js" >-import { submitToAPI } from "../../fetch/fetch.js" >-import { ApiClient } from "../../fetch/api-client.js"; >+import { ERMAPIClient } from "../../fetch/api-client.js"; > import { storeToRefs } from "pinia" > > export default { >@@ -254,7 +250,7 @@ export default { > beforeRouteEnter(to, from, next) { > next(vm => { > if (to.params.agreement_id) { >- vm.agreement = vm.getAgreement(to.params.agreement_id) >+ vm.getAgreement(to.params.agreement_id) > } else { > vm.initialized = true > } >@@ -262,9 +258,12 @@ export default { > }, > methods: { > async getAgreement(agreement_id) { >- const agreement = await fetchAgreement(agreement_id) >- this.agreement = agreement >- this.initialized = true >+ const client = new ERMAPIClient(); >+ try { >+ client.agreements.get(agreement_id).then(data => { this.agreement = data; this.initialized = true; } ); >+ } catch (err) { >+ setError(err.message || err.statusText) >+ } > }, > checkForm(agreement) { > let errors = [] >@@ -335,21 +334,12 @@ export default { > > //let agreement= Object.assign( {} ,this.agreement); // copy > let agreement = JSON.parse(JSON.stringify(this.agreement)) // copy >+ let agreement_id = agreement.agreement_id; > > if (!this.checkForm(agreement)) { > return false > } > >- let apiUrl = "/api/v1/erm/agreements" >- >- //This is just temporary for new api calls implementation >- let a_id = agreement.agreement_id; >- >- let method = "POST" >- if (agreement.agreement_id) { >- method = "PUT" >- apiUrl += "/" + agreement.agreement_id >- } > delete agreement.agreement_id > delete agreement.vendor > agreement.is_perpetual = agreement.is_perpetual ? true : false >@@ -387,36 +377,20 @@ export default { > > delete agreement.agreement_packages > >- const options = { >- method: method, >- body: JSON.stringify(agreement), >- headers: { >- "Content-Type": "application/json;charset=utf-8", >- }, >- } >- >- const client = new ApiClient( >- "/api/v1/erm/", >- { >- "Content-Type": "application/json;charset=utf-8", >- } >- ); >- >+ const client = new ERMAPIClient(); > (async () => { > try { >- if ( this.$route.path.includes("edit") ) { >- await client.agreements.update(agreement, a_id); >- setMessage(this.$__("Agreement updated")); >+ if ( agreement_id ) { >+ await client.agreements.update(agreement, agreement_id).then(setMessage(this.$__("Agreement updated"))); > }else{ >- await client.agreements.create(agreement); >- setMessage(this.$__("Agreement created")); >+ await client.agreements.create(agreement).then(setMessage(this.$__("Agreement created"))); > } > this.$router.push("/cgi-bin/koha/erm/agreements") > } catch (err) { > setError(err.message || err.statusText) > } >- > })(); >+ > }, > onStatusChanged(e) { > if (e.authorised_value != "closed") { >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsFormConfirmDelete.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsFormConfirmDelete.vue >index 766233c92a..0fc1fd5669 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsFormConfirmDelete.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsFormConfirmDelete.vue >@@ -32,8 +32,8 @@ > </template> > > <script> >-import { fetchAgreement } from "../../fetch/erm.js" >-import { setMessage, setError, isSubmitting, submitted } from "../../messages" >+import { ERMAPIClient } from "../../fetch/api-client.js"; >+import { setMessage, setError } from "../../messages" > import ButtonSubmit from "../ButtonSubmit.vue" > > export default { >@@ -50,36 +50,26 @@ export default { > }, > methods: { > async getAgreement(agreement_id) { >- const agreement = await fetchAgreement(agreement_id) >- this.agreement = agreement >- this.initialized = true >+ const client = new ERMAPIClient(); >+ try { >+ client.agreements.get(agreement_id).then(data => { this.agreement = data; this.initialized = true; } ); >+ } catch (err) { >+ setError(err.message || err.statusText) >+ } > }, > onSubmit(e) { > e.preventDefault() > >- let apiUrl = "/api/v1/erm/agreements/" + this.agreement.agreement_id >- >- const options = { >- method: "DELETE", >- headers: { >- "Content-Type": "application/json;charset=utf-8", >- }, >- } >+ const client = new ERMAPIClient(); >+ (async () => { >+ try { >+ await client.agreements.delete(this.agreement.agreement_id).then(setMessage(this.$__("Agreement deleted"))); >+ this.$router.push("/cgi-bin/koha/erm/agreements") >+ } catch (err) { >+ setError(err) >+ } >+ })(); > >- isSubmitting() >- fetch(apiUrl, options) >- .then(response => { >- if (response.status == 204) { >- setMessage(this.$__("Agreement deleted")) >- this.$router.push("/cgi-bin/koha/erm/agreements") >- } else { >- setError(response.message || response.statusText) >- } >- }) >- .then(() => submitted()) >- .catch(error => { >- setError(error) >- }) > }, > }, > components: { >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsList.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsList.vue >index 2e8460aff2..b3b89999ce 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsList.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsList.vue >@@ -37,8 +37,8 @@ > import flatPickr from "vue-flatpickr-component" > import Toolbar from "./AgreementsToolbar.vue" > import { inject, createVNode, render } from "vue" >+import { ERMAPIClient } from "../../fetch/api-client.js"; > import { storeToRefs } from "pinia" >-import { fetchAgreements } from "../../fetch/erm.js" > import { useDataTable, build_url } from "../../composables/datatables" > > export default { >@@ -93,7 +93,8 @@ export default { > }, > methods: { > async getAgreements() { >- const agreements = await fetchAgreements() >+ const client = new ERMAPIClient() >+ const agreements = await client.agreements.getAll("_per_page=-1") > this.agreements = agreements > this.initialized = true > }, >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue >index c5b38ca84a..6dcac5130e 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/ERM/AgreementsShow.vue >@@ -300,7 +300,8 @@ > > <script> > import { inject } from "vue" >-import { fetchAgreement } from "../../fetch/erm.js" >+import { ERMAPIClient } from "../../fetch/api-client.js"; >+import { setError } from "../../messages" > > export default { > setup() { >@@ -346,9 +347,12 @@ export default { > }, > methods: { > async getAgreement(agreement_id) { >- const agreement = await fetchAgreement(agreement_id) >- this.agreement = agreement >- this.initialized = true >+ const client = new ERMAPIClient(); >+ try { >+ await client.agreements.get(agreement_id).then(data => { this.agreement = data; this.initialized = true; } ); >+ } catch (err) { >+ setError(err.message || err.statusText) >+ } > }, > }, > name: "AgreementsShow", >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/api-client.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/api-client.js >index 983a8bdeaa..158e329054 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/api-client.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/api-client.js >@@ -1,21 +1,46 @@ > import HttpClient from "./http-client"; > >-export class ApiClient extends HttpClient { >- constructor(baseURL, headers) { >+export class ERMAPIClient extends HttpClient { >+ constructor(options = {}) >+ { > super({ >- baseURL, >- headers: headers >+ baseURL: "/api/v1/erm/", >+ headers: options.headers > }); > } > > get agreements() { > return { >- get: () => this.get("/agreements"), >- delete: (id) => this.delete(`/agreements/${id}`), >- create: (agreement) => this.post("/agreements", agreement), >- update: (agreement, id) => this.put("/agreements/"+id, agreement) >+ get: (id) => this.get( >+ "agreements/"+id, >+ { >+ "x-koha-embed": >+ "periods,user_roles,user_roles.patron,agreement_licenses,agreement_licenses.license,agreement_relationships,agreement_relationships.related_agreement,documents,agreement_packages,agreement_packages.package,vendor", >+ } >+ ), >+ getAll: (query) => this.get("agreements"+(query?"?"+query:"")), >+ count: () => this.count("agreements"), >+ delete: (id) => this.delete( >+ "agreements/"+id, >+ { >+ "Content-Type": "application/json;charset=utf-8", >+ } >+ ), >+ create: (agreement) => this.post( >+ "agreements", >+ agreement, >+ { >+ "Content-Type": "application/json;charset=utf-8" >+ } >+ ), >+ update: (agreement, id) => this.put( >+ "agreements/"+id, agreement, >+ { >+ "Content-Type": "application/json;charset=utf-8" >+ } >+ ) > }; > } > } > >-export default ApiClient; >+export default ERMAPIClient; >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm.js >index e40a85a522..eaedb45229 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/erm.js >@@ -1,26 +1,6 @@ > import { setError } from "../messages"; > >-export const fetchAgreement = async function (agreement_id) { >- if (!agreement_id) return; >- const apiUrl = "/api/v1/erm/agreements/" + agreement_id; >- let agreement; >- await fetch(apiUrl, { >- headers: { >- "x-koha-embed": >- "periods,user_roles,user_roles.patron,agreement_licenses,agreement_licenses.license,agreement_relationships,agreement_relationships.related_agreement,documents,agreement_packages,agreement_packages.package,vendor", >- }, >- }) >- .then(checkError) >- .then( >- (result) => { >- agreement = result; >- }, >- (error) => { >- setError(error); >- } >- ); >- return agreement; >-}; >+//TODO: all of these functions should be deleted and reimplemented in the components using ERMAPIClient > > export const fetchAgreements = async function () { > const apiUrl = "/api/v1/erm/agreements?_per_page=-1"; >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/fetch.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/fetch.js >deleted file mode 100644 >index ba6aabdbe7..0000000000 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/fetch.js >+++ /dev/null >@@ -1,26 +0,0 @@ >-import { >- setMessage, >- setError, >- isSubmitting, >- submitted, >-} from "../messages" >- >-export const submitToAPI = async function (args) { >- isSubmitting() >- await fetch(args.apiUrl, args.options) >- .then(response => { >- if (response.status == 200) { >- args.router.push(args.success_redirect) >- setMessage(args.updated_message) >- } else if (response.status == 201) { >- args.router.push(args.success_redirect) >- setMessage(args.created_message) >- } else { >- setError(response.message || response.statusText) >- } >- }) >- .catch(error => { >- setError(error) >- }) >- .then(() => submitted()) >-}; >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/http-client.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/http-client.js >index 06e15e3d61..8078797caf 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/http-client.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/http-client.js >@@ -1,77 +1,58 @@ >+import { >+ isSubmitting, >+ submitted, >+} from "../messages" >+ > class HttpClient { > constructor(options = {}) { > this._baseURL = options.baseURL || ""; > this._headers = options.headers || {}; > } > >- async _fetchJSON(endpoint, options = {}) { >+ async _fetchJSON(endpoint, headers = {}, options = {}) { >+ // isSubmitting() //FIXME: need to fix below submitted() call > const res = await fetch(this._baseURL + endpoint, { > ...options, >- headers: this._headers >- }); >- >+ headers: headers >+ }) >+ // .then(() => submitted()); //FIXME: seemingly working but throws error on console? >+ > if (!res.ok) throw new Error(res.statusText); > > if (options.parseResponse !== false && res.status !== 204) > return res.json(); >- >+ > return undefined; > } > >- setHeader(key, value) { >- this._headers[key] = value; >- return this; >- } >- >- getHeader(key) { >- return this._headers[key]; >- } >- >- setBasicAuth(username, password) { >- this._headers.Authorization = `Basic ${btoa(`${username}:${password}`)}`; >- return this; >- } >- >- setBearerAuth(token) { >- this._headers.Authorization = `Bearer ${token}`; >- return this; >- } >- >- get(endpoint, options = {}) { >- return this._fetchJSON(endpoint, { >+ get(endpoint, headers = {}, options = {}) { >+ return this._fetchJSON(endpoint, headers, >+ { > ...options, > method: "GET" > }); > } >+ >+ //TODO: Implement count method > >- post(endpoint, body, options = {}) { >- return this._fetchJSON(endpoint, { >+ post(endpoint, body, headers = {}, options = {}) { >+ return this._fetchJSON(endpoint, headers, { > ...options, > body: body ? JSON.stringify(body) : undefined, > method: "POST" > }); > } > >- put(endpoint, body, options = {}) { >- console.log('puting'); >- return this._fetchJSON(endpoint, { >+ put(endpoint, body, headers = {}, options = {}) { >+ return this._fetchJSON(endpoint, headers, { > ...options, > body: body ? JSON.stringify(body) : undefined, > method: "PUT" > }); > } > >- patch(endpoint, operations, options = {}) { >- return this._fetchJSON(endpoint, { >- parseResponse: false, >- ...options, >- body: JSON.stringify(operations), >- method: "PATCH" >- }); >- } >- >- delete(endpoint, options = {}) { >- return this._fetchJSON(endpoint, { >+ delete(endpoint, headers = {}, options = {}) { >+ return this._fetchJSON(endpoint, headers, { > parseResponse: false, > ...options, > method: "DELETE" >-- >2.30.2
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 32939
:
146470
|
146509
|
146642
|
146644
|
146645
|
146668
|
146669
|
146670
|
146671
|
146672
|
146674
|
146675
|
146676
|
146677
|
146678
|
146679
|
146680
|
146681
|
146682
|
147029
|
147030
|
147031
|
147032
|
147033
|
147034
|
147035
|
147036
|
147037
|
147038
|
147039
|
147040
|
147041
|
147042
|
147043
|
147044
|
147056
|
147057
|
147059
|
147060
|
147061
|
147062
|
147063
|
147064
|
147065
|
147066
|
147067
|
147068
|
147069
|
147070
|
147071
|
147072
|
147073
|
147306
|
147307
|
147308
|
147309
|
147310
|
147311
|
147312
|
147313
|
147314
|
147315
|
147316
|
147317
|
147318
|
147319
|
147320
|
147321
|
147322
|
147332
|
149441