@@ -19,8 +19,12 @@
:values="item"
/>
@@ -56,12 +60,12 @@ export default {
Loading,
Toolbar,
DocumentsForm,
- Panel
+ Panel,
},
mixins: [CreateMixin],
data() {
- const filetype = this.$route.query.filetype === 'certificate' ? 'certificate' : 'file';
- const finalTags = this.getCertificateTags();
+ const filetype = this.$route.query.filetype === "certificate" ? "certificate" : "file"
+ const finalTags = this.getCertificateTags()
return {
item: {
newDocument: true, // Used in FormNewDocument.vue to show the editor
@@ -72,7 +76,7 @@ export default {
},
templates: [],
finalTags,
- };
+ }
},
computed: {
...mapFields(["error", "isLoading", "created", "violations"]),
@@ -90,59 +94,60 @@ export default {
},
methods: {
- handleBack() {
- this.$router.back();
- },
- addTemplateToEditor(templateContent) {
- this.item.contentFile = templateContent;
- },
- fetchTemplates() {
- const courseId = this.$route.query.cid;
- axios.get(`/template/all-templates/${courseId}`)
- .then(response => {
- this.templates = response.data;
- console.log('Templates fetched successfully:', this.templates);
- })
- .catch(error => {
- console.error('Error fetching templates:', error);
- });
- },
- getCertificateTags(){
- let finalTags = "";
- let tags = [
- '((user_firstname))',
- '((user_lastname))',
- '((user_username))',
- '((gradebook_institution))',
- '((gradebook_sitename))',
- '((teacher_firstname))',
- '((teacher_lastname))',
- '((official_code))',
- '((date_certificate))',
- '((date_certificate_no_time))',
- '((course_code))',
- '((course_title))',
- '((gradebook_grade))',
- '((certificate_link))',
- '((certificate_link_html))',
- '((certificate_barcode))',
- '((external_style))',
- '((time_in_course))',
- '((time_in_course_in_all_sessions))',
- '((start_date_and_end_date))',
- '((course_objectives))',
- ];
+ handleBack() {
+ this.$router.back()
+ },
+ addTemplateToEditor(templateContent) {
+ this.item.contentFile = templateContent
+ },
+ fetchTemplates() {
+ const courseId = this.$route.query.cid
+ axios
+ .get(`/template/all-templates/${courseId}`)
+ .then((response) => {
+ this.templates = response.data
+ console.log("Templates fetched successfully:", this.templates)
+ })
+ .catch((error) => {
+ console.error("Error fetching templates:", error)
+ })
+ },
+ getCertificateTags() {
+ let finalTags = ""
+ let tags = [
+ "((user_firstname))",
+ "((user_lastname))",
+ "((user_username))",
+ "((gradebook_institution))",
+ "((gradebook_sitename))",
+ "((teacher_firstname))",
+ "((teacher_lastname))",
+ "((official_code))",
+ "((date_certificate))",
+ "((date_certificate_no_time))",
+ "((course_code))",
+ "((course_title))",
+ "((gradebook_grade))",
+ "((certificate_link))",
+ "((certificate_link_html))",
+ "((certificate_barcode))",
+ "((external_style))",
+ "((time_in_course))",
+ "((time_in_course_in_all_sessions))",
+ "((start_date_and_end_date))",
+ "((course_objectives))",
+ ]
- for (const tag of tags){
- finalTags += "
"+tag+"
"
- }
+ for (const tag of tags) {
+ finalTags += '
' + tag + "
"
+ }
- return finalTags;
- },
- ...mapActions('documents', ['createWithFormData', 'reset'])
+ return finalTags
+ },
+ ...mapActions("documents", ["createWithFormData", "reset"]),
},
mounted() {
- this.fetchTemplates();
+ this.fetchTemplates()
},
-};
+}
diff --git a/assets/vue/views/documents/DocumentsList.vue b/assets/vue/views/documents/DocumentsList.vue
index 7cd51a9fc4..7d80edbf19 100644
--- a/assets/vue/views/documents/DocumentsList.vue
+++ b/assets/vue/views/documents/DocumentsList.vue
@@ -41,16 +41,16 @@
@click="openNew"
/>
@@ -371,7 +371,6 @@ import DocumentAudioRecorder from "../../components/documents/DocumentAudioRecor
import { useNotification } from "../../composables/notification"
import { useSecurityStore } from "../../store/securityStore"
import prettyBytes from "pretty-bytes"
-import { ENTRYPOINT } from "../../config/entrypoint"
import BaseFileUpload from "../../components/basecomponents/BaseFileUpload.vue"
const store = useStore()
@@ -383,7 +382,7 @@ const { t } = useI18n()
const { filters, options, onUpdateOptions, deleteItem } = useDatatableList("Documents")
const notification = useNotification()
const { cid, sid, gid } = useCidReq()
-const { isImage, isHtml } = useFileUtils();
+const { isImage, isHtml } = useFileUtils()
const { relativeDatetime } = useFormatDate()
@@ -416,13 +415,13 @@ const hasImageInDocumentEntries = computed(() => {
})
const isCertificateMode = computed(() => {
- return route.query.filetype === 'certificate';
+ return route.query.filetype === "certificate"
})
-const defaultCertificateId = ref(null);
+const defaultCertificateId = ref(null)
const isHtmlFile = (fileData) => {
- return isHtml(fileData);
+ return isHtml(fileData)
}
onMounted(() => {
@@ -685,111 +684,111 @@ function recordedAudioNotSaved(error) {
async function selectAsDefaultCertificate(certificate) {
try {
- const response = await axios.patch(`/gradebook/set_default_certificate/${cid}/${certificate.iid}`);
+ const response = await axios.patch(`/gradebook/set_default_certificate/${cid}/${certificate.iid}`)
if (response.status === 200) {
loadDefaultCertificate()
onUpdateOptions(options.value)
- notification.showSuccessNotification(t('Certificate set as default successfully'));
+ notification.showSuccessNotification(t("Certificate set as default successfully"))
}
} catch (error) {
- notification.showErrorNotification(t('Error setting certificate as default'));
+ notification.showErrorNotification(t("Error setting certificate as default"))
}
}
async function loadDefaultCertificate() {
try {
- const response = await axios.get(`/gradebook/default_certificate/${cid}`);
- defaultCertificateId.value = response.data.certificateId;
+ const response = await axios.get(`/gradebook/default_certificate/${cid}`)
+ defaultCertificateId.value = response.data.certificateId
} catch (error) {
if (error.response && error.response.status === 404) {
- console.error('Default certificate not found.');
- defaultCertificateId.value = null;
+ console.error("Default certificate not found.")
+ defaultCertificateId.value = null
} else {
- console.error('Error loading the certificate', error);
+ console.error("Error loading the certificate", error)
}
}
}
-const showTemplateFormModal = ref(false);
-const selectedFile = ref(null);
+const showTemplateFormModal = ref(false)
+const selectedFile = ref(null)
const templateFormData = ref({
- title: '',
+ title: "",
thumbnail: null,
})
-const currentDocumentId = ref(null);
+const currentDocumentId = ref(null)
const isDocumentTemplate = async (documentId) => {
try {
- const response = await axios.get(`/template/document-templates/${documentId}/is-template`);
- return response.data.isTemplate;
+ const response = await axios.get(`/template/document-templates/${documentId}/is-template`)
+ return response.data.isTemplate
} catch (error) {
- console.error('Error verifying the template status:', error);
+ console.error("Error verifying the template status:", error)
return false
}
}
const deleteDocumentTemplate = async (documentId) => {
try {
- await axios.post(`/template/document-templates/${documentId}/delete`);
- onUpdateOptions(options.value);
- notification.showSuccessNotification(t('Template successfully deteled.'));
+ await axios.post(`/template/document-templates/${documentId}/delete`)
+ onUpdateOptions(options.value)
+ notification.showSuccessNotification(t("Template successfully deteled."))
} catch (error) {
- console.error('Error deleting the template:', error);
- notification.showErrorNotification(t('Error deleting the template.'));
+ console.error("Error deleting the template:", error)
+ notification.showErrorNotification(t("Error deleting the template."))
}
}
const getTemplateIcon = (documentId) => {
- const document = items.value.find((doc) => doc.iid === documentId);
- return document && document.template ? 'template-selected' : 'template-not-selected';
+ const document = items.value.find((doc) => doc.iid === documentId)
+ return document && document.template ? "template-selected" : "template-not-selected"
}
const openTemplateForm = async (documentId) => {
- const isTemplate = await isDocumentTemplate(documentId);
+ const isTemplate = await isDocumentTemplate(documentId)
if (isTemplate) {
await deleteDocumentTemplate(documentId)
- onUpdateOptions(listaoptions.value);
+ onUpdateOptions(options.value)
} else {
- currentDocumentId.value = documentId;
- showTemplateFormModal.value = true;
+ currentDocumentId.value = documentId
+ showTemplateFormModal.value = true
}
}
const submitTemplateForm = async () => {
- submitted.value = true;
+ submitted.value = true
if (!templateFormData.value.title || !selectedFile.value) {
- notification.showErrorNotification(t('The title and thumbnail are required.'));
- return;
+ notification.showErrorNotification(t("The title and thumbnail are required."))
+ return
}
try {
const formData = new FormData()
- formData.append('title', templateFormData.value.title);
- formData.append('thumbnail', selectedFile.value);
- formData.append('refDoc', currentDocumentId.value);
- formData.append('cid', cid);
+ formData.append("title", templateFormData.value.title)
+ formData.append("thumbnail", selectedFile.value)
+ formData.append("refDoc", currentDocumentId.value)
+ formData.append("cid", cid)
- const response = await axios.post('/template/document-templates/create', formData, {
+ const response = await axios.post("/template/document-templates/create", formData, {
headers: {
- 'Content-Type': 'multipart/form-data',
+ "Content-Type": "multipart/form-data",
},
- });
+ })
if (response.status === 200 || response.status === 201) {
- notification.showSuccessNotification(t('Template created successfully.'));
- templateFormData.value.title = '';
- selectedFile.value = null;
- showTemplateFormModal.value = false;
- onUpdateOptions(options.value);
+ notification.showSuccessNotification(t("Template created successfully."))
+ templateFormData.value.title = ""
+ selectedFile.value = null
+ showTemplateFormModal.value = false
+ onUpdateOptions(options.value)
} else {
- notification.showErrorNotification(t('Error creating the template.'));
+ notification.showErrorNotification(t("Error creating the template."))
}
} catch (error) {
- console.error('Error submitting the form:', error)
- notification.showErrorNotification(t('Error submitting the form.'));
+ console.error("Error submitting the form:", error)
+ notification.showErrorNotification(t("Error submitting the form."))
}
-};
+}
diff --git a/assets/vue/views/message/MessageCreate.vue b/assets/vue/views/message/MessageCreate.vue
index 847b4ce82a..51eb393b11 100644
--- a/assets/vue/views/message/MessageCreate.vue
+++ b/assets/vue/views/message/MessageCreate.vue
@@ -33,7 +33,11 @@
/>
-
+
{
- return axios
- .get(ENTRYPOINT + "users", {
- params: {
- username: query,
- },
- })
- .then((response) => {
- let data = response.data
-
- return (
- data["hydra:member"]?.map((member) => ({
- name: member.fullName,
- value: member["@id"],
- })) ?? []
- )
- })
- .catch(function (error) {
- console.log(error)
- })
+const asyncFind = async (query) => {
+ const { items } = await userService.findByUsername(query)
+
+ return items.map((member) => ({
+ name: member.fullName,
+ value: member["@id"],
+ }))
}
const currentUser = computed(() => store.getters["security/getUser"])
@@ -201,7 +190,6 @@ if (route.query.send_to_user) {
userService
.find("/api/users/" + parseInt(route.query.send_to_user))
- .then((response) => response.json())
.then((user) => {
sendToUser.value = user
@@ -214,7 +202,11 @@ if (route.query.send_to_user) {
const prefill = capitalize(route.query.prefill)
item.value.title = t(prefill + "Title")
- item.value.content = t(prefill + "Content", [user.firstname, currentUser.value.firstname, currentUser.value.firstname])
+ item.value.content = t(prefill + "Content", [
+ user.firstname,
+ currentUser.value.firstname,
+ currentUser.value.firstname,
+ ])
}
})
.catch((e) => notification.showErrorNotification(e))
diff --git a/assets/vue/views/message/MessageShow.vue b/assets/vue/views/message/MessageShow.vue
index 32658f94ba..b1c35cad24 100644
--- a/assets/vue/views/message/MessageShow.vue
+++ b/assets/vue/views/message/MessageShow.vue
@@ -144,8 +144,6 @@ import { useStore } from "vuex"
import Loading from "../../components/Loading.vue"
import { computed, ref } from "vue"
import isEmpty from "lodash/isEmpty"
-import axios from "axios"
-import { ENTRYPOINT } from "../../config/entrypoint"
import { useRoute, useRouter } from "vue-router"
import BaseButton from "../../components/basecomponents/BaseButton.vue"
import { useConfirm } from "primevue/useconfirm"
@@ -154,6 +152,7 @@ import BaseChip from "../../components/basecomponents/BaseChip.vue"
import BaseAutocomplete from "../../components/basecomponents/BaseAutocomplete.vue"
import { useFormatDate } from "../../composables/formatDate"
import { useMessageRelUserStore } from "../../store/messageRelUserStore"
+import messageTagService from "../../services/messageTagService"
const confirm = useConfirm()
const { t } = useI18n()
@@ -250,25 +249,14 @@ function createEvent() {
const foundTag = ref("")
-function onSearchTags(query) {
+async function onSearchTags(query) {
isLoadingSelect.value = true
- return axios
- .get(ENTRYPOINT + "message_tags", {
- params: {
- user: user["@id"],
- tag: query,
- },
- })
- .then((response) => {
- isLoadingSelect.value = false
+ const { items } = await messageTagService.searchUserTags(user["@id"], query)
- return response.data["hydra:member"]
- })
- .catch(function (error) {
- isLoadingSelect.value = false
- console.log(error)
- })
+ isLoadingSelect.value = false
+
+ return items
}
async function onItemSelect({ value }) {
diff --git a/assets/vue/views/user/courses/List.vue b/assets/vue/views/user/courses/List.vue
index 3b74750f4f..d43dae5e8d 100644
--- a/assets/vue/views/user/courses/List.vue
+++ b/assets/vue/views/user/courses/List.vue
@@ -1,13 +1,25 @@
-
+
-
+
-
-
-
+
+
+
diff --git a/assets/vue/views/usergroup/Invite.vue b/assets/vue/views/usergroup/Invite.vue
index fa96370296..8fa0cc51c2 100644
--- a/assets/vue/views/usergroup/Invite.vue
+++ b/assets/vue/views/usergroup/Invite.vue
@@ -1,59 +1,98 @@
-
+
-
![avatar]()
+
{{ friend.name }}
-
+
-
+
-
![avatar]()
+
{{ friend.name }}
-
+
-
-
-
![avatar]()
-
{{ user.name }}
-
+
+
+
![avatar]()
+
{{ user.name }}
+
diff --git a/assets/vue/views/usergroup/List.vue b/assets/vue/views/usergroup/List.vue
index 85893651a6..2a75cceedb 100644
--- a/assets/vue/views/usergroup/List.vue
+++ b/assets/vue/views/usergroup/List.vue
@@ -3,47 +3,113 @@
Social groups
-
+
-
+
-
-
![Group Image]()
-
+
+
![Group Image]()
+
-
+
-
-
![Group Image]()
-
+
+
![Group Image]()
+
-
-
+
+
+
-
-
![Group Image]()
-
+
+
![Group Image]()
+
@@ -54,27 +120,32 @@
-