Skip to content

Commit d0abebf

Browse files
committed
Replace direct axios calls with baseService
1 parent 437b2b7 commit d0abebf

93 files changed

Lines changed: 1700 additions & 1116 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

assets/vue/App.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ import {
8686
watchEffect,
8787
} from "vue"
8888
import { useRoute, useRouter } from "vue-router"
89-
import axios from "axios"
89+
import api from "./config/api"
9090
import { capitalize, isEmpty } from "lodash"
9191
import ConfirmDialog from "primevue/confirmdialog"
9292
import { useSecurityStore } from "./store/securityStore"
@@ -307,7 +307,7 @@ onUpdated(() => {
307307
app.dataset.flashes = ""
308308
})
309309
310-
axios.interceptors.response.use(
310+
api.interceptors.response.use(
311311
(r) => r,
312312
(error) => {
313313
const s = error?.response?.status

assets/vue/components/assignments/UppyModalUploader.vue

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { Dashboard } from "@uppy/vue"
2525
import Uppy from "@uppy/core"
2626
import Dialog from "primevue/dialog"
2727
import { useNotification } from "../../composables/notification"
28-
import axios from "axios"
28+
import cStudentPublicationService from "../../services/cstudentpublication"
2929
import "@uppy/core/dist/style.css"
3030
import "@uppy/dashboard/dist/style.css"
3131
@@ -81,17 +81,9 @@ function setupUppy() {
8181
const formData = new FormData()
8282
formData.append("uploadFile", file.data)
8383
84-
const uploadUrl =
85-
`/api/c_student_publication_corrections/upload` +
86-
`?parentResourceNodeId=${props.parentResourceNodeId}` +
87-
`&submissionId=${props.submissionId}` +
88-
`&filetype=file`
89-
90-
await axios.post(uploadUrl, formData, {
91-
headers: {
92-
"Content-Type": "multipart/form-data",
93-
Accept: "application/json",
94-
},
84+
await cStudentPublicationService.uploadCorrection(formData, {
85+
parentResourceNodeId: props.parentResourceNodeId,
86+
submissionId: props.submissionId,
9587
})
9688
9789
showSuccessNotification("Correction uploaded successfully!")

assets/vue/components/documents/DocumentAiMediaDialog.vue

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@
279279

280280
<script setup>
281281
import { computed, nextTick, onBeforeUnmount, ref, watch } from "vue"
282-
import axios from "axios"
283282
import Dialog from "primevue/dialog"
284283
import Dropdown from "primevue/dropdown"
285284
import InputText from "primevue/inputtext"
@@ -292,6 +291,8 @@ import { usePlatformConfig } from "../../store/platformConfig"
292291
import { useCourseSettings } from "../../store/courseSettingStore"
293292
import { useSecurityStore } from "../../store/securityStore"
294293
import { checkIsAllowedToEdit } from "../../composables/userPermissions"
294+
import documentsService from "../../services/documents"
295+
import aiService from "../../services/aiService"
295296
296297
const props = defineProps({
297298
visible: { type: Boolean, default: false },
@@ -706,11 +707,9 @@ async function createFolder(title, parentNodeId) {
706707
formData.append("parentResourceNodeId", String(parentNodeId))
707708
formData.append("resourceLinkList", buildResourceLinkList())
708709
709-
const response = await axios.post("/api/documents", formData, {
710-
headers: { "Content-Type": "multipart/form-data" },
711-
})
710+
const data = await documentsService.uploadDocumentFile(formData)
712711
713-
return response?.data || {}
712+
return data || {}
714713
}
715714
716715
async function fetchFolders(nodeId = null) {
@@ -736,20 +735,18 @@ async function fetchFolders(nodeId = null) {
736735
continue
737736
}
738737
739-
const response = await axios.get("/api/documents", {
740-
params: {
741-
loadNode: 1,
742-
filetype: ["folder"],
743-
"resourceNode.parent": currentNodeId,
744-
cid,
745-
sid,
746-
gid,
747-
page: 1,
748-
itemsPerPage: 200,
749-
},
738+
const { items } = await documentsService.listDocuments({
739+
loadNode: 1,
740+
filetype: ["folder"],
741+
"resourceNode.parent": currentNodeId,
742+
cid,
743+
sid,
744+
gid,
745+
page: 1,
746+
itemsPerPage: 200,
750747
})
751748
752-
const members = response.data?.["hydra:member"] || []
749+
const members = items || []
753750
for (const folder of members) {
754751
const folderNodeId =
755752
normalizeResourceNodeId(folder?.resourceNode?.id) ?? normalizeResourceNodeId(folder?.resourceNodeId)
@@ -832,11 +829,7 @@ async function saveToDocuments(file) {
832829
formData.append("fileExistsOption", "rename")
833830
formData.append("ai_assisted", "1")
834831
835-
const response = await axios.post("/api/documents", formData, {
836-
headers: { "Content-Type": "multipart/form-data" },
837-
})
838-
839-
const data = response?.data || {}
832+
const data = (await documentsService.uploadDocumentFile(formData)) || {}
840833
savedIri.value = String(data?.["@id"] || data?.id || "")
841834
return data
842835
}
@@ -856,8 +849,7 @@ async function resolveSavedDocument(savedDoc) {
856849
}
857850
858851
try {
859-
const response = await axios.get(iri)
860-
const fresh = response?.data || {}
852+
const fresh = (await documentsService.getDocumentByIri(iri)) || {}
861853
const freshUrl = String(fresh?.contentUrl || fresh?.downloadUrl || fresh?.url || "").trim()
862854
863855
return {
@@ -875,7 +867,7 @@ async function loadCapabilities() {
875867
isLoadingCaps.value = true
876868
877869
try {
878-
const { data } = await axios.get("/ai/capabilities")
870+
const data = await aiService.getCapabilities()
879871
880872
hasImage.value = !!data?.has?.image
881873
hasVideo.value = !!data?.has?.video
@@ -923,10 +915,7 @@ function stopVideoPolling(reason = "") {
923915
}
924916
925917
async function pollVideoJobOnce(jobId, providerCode) {
926-
const response = await axios.get(`/ai/video_job/${encodeURIComponent(jobId)}`, {
927-
params: { ai_provider: providerCode || null },
928-
})
929-
return response?.data
918+
return aiService.getVideoJob(jobId, providerCode)
930919
}
931920
932921
function isTerminalVideoStatus(status) {
@@ -1089,9 +1078,7 @@ async function generate() {
10891078
payload.height = parsedHeight.value
10901079
}
10911080
1092-
const { data } = await axios.post(endpoint, payload, {
1093-
headers: { "Content-Type": "application/json" },
1094-
})
1081+
const data = await aiService.generateMedia(endpoint, payload)
10951082
10961083
if (!data?.success) {
10971084
const msg = String(data?.text || "")

assets/vue/components/documents/FormNewDocument.vue

Lines changed: 7 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@
182182
import useVuelidate from "@vuelidate/core"
183183
import { required } from "@vuelidate/validators"
184184
import { ref } from "vue"
185-
import axios from "axios"
186185
import { useI18n } from "vue-i18n"
187186
import { usePlatformConfig } from "../../store/platformConfig"
188187
import { useCourseSettings } from "../../store/courseSettingStore"
@@ -195,6 +194,8 @@ import BaseInputTextWithVuelidate from "../basecomponents/BaseInputTextWithVueli
195194
import DocumentAiMediaDialog from "./DocumentAiMediaDialog.vue"
196195
import BaseTextArea from "../basecomponents/BaseTextArea.vue"
197196
import ResourceLanguageSelector from "../resources/ResourceLanguageSelector.vue"
197+
import courseService from "../../services/courseService"
198+
import searchEngineFieldService from "../../services/searchEngineFieldService"
198199
199200
export default {
200201
name: "DocumentsForm",
@@ -667,8 +668,7 @@ export default {
667668
}
668669
669670
try {
670-
const response = await axios.get(`/api/courses/${cid}`)
671-
const data = response?.data || {}
671+
const data = (await courseService.find(`/api/courses/${cid}`)) || {}
672672
673673
const apiTitle = String(data?.title || data?.name || "").trim()
674674
const apiLanguage = String(data?.language || "").trim()
@@ -782,19 +782,10 @@ export default {
782782
},
783783
async loadSearchEngineFields() {
784784
try {
785-
const response = await fetch("/api/search_engine_fields", {
786-
credentials: "same-origin",
787-
})
788-
789-
if (!response.ok) {
790-
console.error("[Search] Failed to load search engine fields:", response.status)
791-
return
792-
}
793-
794-
const json = await response.json()
795-
const rawFields = Array.isArray(json) ? json : json["hydra:member"] || []
785+
const { items } = await searchEngineFieldService.listFields()
786+
const rawFields = items || []
796787
if (!Array.isArray(rawFields)) {
797-
console.error("[Search] Unexpected search engine fields payload:", json)
788+
console.error("[Search] Unexpected search engine fields payload:", items)
798789
return
799790
}
800791
@@ -824,35 +815,7 @@ export default {
824815
}
825816
},
826817
async fetchFieldValues(resourceNodeId) {
827-
const iri = `/api/resource_nodes/${resourceNodeId}`
828-
829-
const tryUrls = [
830-
`/api/search_engine_field_values?resourceNode=${encodeURIComponent(iri)}&pagination=false`,
831-
`/api/search_engine_field_values?resourceNodeId=${encodeURIComponent(resourceNodeId)}&pagination=false`,
832-
]
833-
834-
for (const url of tryUrls) {
835-
try {
836-
const response = await fetch(url, { credentials: "same-origin" })
837-
if (!response.ok) {
838-
console.warn("[Search] Field values request failed:", response.status, url)
839-
continue
840-
}
841-
842-
const json = await response.json()
843-
const items = Array.isArray(json) ? json : json["hydra:member"] || []
844-
if (!Array.isArray(items)) {
845-
console.warn("[Search] Unexpected field values payload:", json)
846-
continue
847-
}
848-
849-
return items
850-
} catch (error) {
851-
console.warn("[Search] Field values request error:", error)
852-
}
853-
}
854-
855-
return []
818+
return searchEngineFieldService.listFieldValues(resourceNodeId)
856819
},
857820
async loadSearchEngineFieldValuesForEdit() {
858821
if (this.searchValuesLoaded) return
Lines changed: 33 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,63 @@
11
// From
22
// https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/upload-adapter.html
33

4+
import documentsService from "../../services/documents"
5+
46
export default class MyUploadAdapter {
57
constructor(loader) {
68
// The file loader instance to use during the upload.
79
this.loader = loader
10+
// Allows aborting the in-flight request from abort().
11+
this.controller = new AbortController()
812
}
913

1014
// Starts the upload process.
1115
upload() {
12-
return this.loader.file.then(
13-
(file) =>
14-
new Promise((resolve, reject) => {
15-
this._initRequest()
16-
this._initListeners(resolve, reject, file)
17-
this._sendRequest(file)
18-
}),
19-
)
16+
return this.loader.file.then((file) => this._sendRequest(file))
2017
}
2118

2219
// Aborts the upload process.
2320
abort() {
24-
if (this.xhr) {
25-
this.xhr.abort()
26-
}
27-
}
28-
29-
// Initializes the XMLHttpRequest object using the URL passed to the constructor.
30-
_initRequest() {
31-
const xhr = (this.xhr = new XMLHttpRequest())
32-
33-
// Note that your request may look different. It is up to you and your editor
34-
// integration to choose the right communication channel. This example uses
35-
// a POST request with JSON as a data structure but your configuration
36-
// could be different.
37-
xhr.open("POST", "/api/documents", true)
38-
xhr.responseType = "json"
21+
this.controller.abort()
3922
}
4023

41-
// Initializes XMLHttpRequest listeners.
42-
_initListeners(resolve, reject, file) {
43-
const xhr = this.xhr
44-
const loader = this.loader
24+
// Prepares the data and sends the request through the documents service.
25+
async _sendRequest(file) {
4526
const genericErrorText = `Couldn't upload file: ${file.name}.`
27+
const loader = this.loader
4628

47-
xhr.addEventListener("error", () => reject(genericErrorText))
48-
xhr.addEventListener("abort", () => reject())
49-
xhr.addEventListener("load", () => {
50-
const response = xhr.response
51-
52-
// This example assumes the XHR server's "response" object will come with
53-
// an "error" which has its own "message" that can be passed to reject()
54-
// in the upload promise.
55-
//
56-
// Your integration may handle upload errors in a different way so make sure
57-
// it is done properly. The reject() function must be called when the upload fails.
58-
if (!response || response.error) {
59-
return reject(response && response.error ? response.error.message : genericErrorText)
60-
}
61-
62-
// If the upload is successful, resolve the upload promise with an object containing
63-
// at least the "default" URL, pointing to the image on the server.
64-
// This URL will be used to display the image in the content. Learn more in the
65-
// UploadAdapter#upload documentation.
66-
resolve({
67-
//default: response.url
68-
default: response.contentUrl,
69-
})
70-
})
71-
72-
// Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded
73-
// properties which are used e.g. to display the upload progress bar in the editor
74-
// user interface.
75-
if (xhr.upload) {
76-
xhr.upload.addEventListener("progress", (evt) => {
77-
if (evt.lengthComputable) {
78-
loader.uploadTotal = evt.total
79-
loader.uploaded = evt.loaded
80-
}
81-
})
82-
}
83-
}
84-
85-
// Prepares the data and sends the request.
86-
_sendRequest(file) {
8729
// Prepare the form data.
8830
const data = new FormData()
8931

9032
// Chamilo
9133
data.append("filetype", "file")
9234
data.append("parentResourceNodeId", "4")
93-
//data.append('resourceLinkList', '{"cid": 1, "visibility":2}');
9435
data.append("uploadFile", file)
95-
//data.append( 'upload', file );
9636

97-
// Important note: This is the right place to implement security mechanisms
98-
// like authentication and CSRF protection. For instance, you can use
99-
// XMLHttpRequest.setRequestHeader() to set the request headers containing
100-
// the CSRF token generated earlier by your application.
37+
try {
38+
const response = await documentsService.uploadDocumentFile(data, {
39+
signal: this.controller.signal,
40+
// The file loader has the #uploadTotal and #uploaded properties which are
41+
// used e.g. to display the upload progress bar in the editor user interface.
42+
onUploadProgress: (evt) => {
43+
if (evt.lengthComputable) {
44+
loader.uploadTotal = evt.total
45+
loader.uploaded = evt.loaded
46+
}
47+
},
48+
})
10149

102-
// Send the request.
103-
this.xhr.send(data)
50+
if (!response || response.error) {
51+
throw new Error(response && response.error ? response.error.message : genericErrorText)
52+
}
53+
54+
// Resolve the upload promise with an object containing at least the "default"
55+
// URL, pointing to the image on the server. This URL is used to display the
56+
// image in the content.
57+
return { default: response.contentUrl }
58+
} catch (error) {
59+
const apiMessage = error?.response?.data?.error?.message
60+
throw new Error(apiMessage || error?.message || genericErrorText, { cause: error })
61+
}
10462
}
10563
}

0 commit comments

Comments
 (0)