import CoreForm from "../Form/Form.js"; import FormInput from "../Form/Input.js"; import BsModal from "../Bootstrap/Modal.js"; import AbstractWidget from './Abstract.js'; import { useUrlStore } from '../../composables/Pseudostore/DashboardWidget/UrlStore.js'; export default { name: "WidgetsUrl", components:{ CoreForm, FormInput, BsModal, PvChips: primevue.chips, PvMultiSelect: primevue.multiselect, PvAutoComplete: primevue.autocomplete, }, mixins: [AbstractWidget], inject: { adminMode: { from: 'adminMode', default: false } }, data: () => ({ ready: false, bookmark_id: null, title_input: "", url_input: "", validation: { invalidURL: false, invalidTitel: false, }, selectedTags: [], selectedFilters: [], filteredArray: [] }), computed: { availableTags() { return (this.bookmarks || []) .map(bookmark => JSON.parse(bookmark.tag)) .flat() .filter((v, i, a) => v && a.indexOf(v) === i); }, filteredBookmarks() { if (!this.bookmarks) return []; if (!this.config.tags || !this.config.tags.length) return this.bookmarks; return this.bookmarks.filter(bookmark => { const tags = JSON.parse(bookmark.tag || "[]"); return tags.some(tag => this.config.tags.includes(tag)); }); }, newSort() { if (this.bookmarks.length == 0) return 1; else return Math.max(...this.bookmarks.map(b => b.sort)) + 1; }, maxSort() { if (this.bookmarks.length == 0) return 0; else return Math.max(...this.filteredBookmarks.map(b => b.sort)); }, minSort() { if (this.bookmarks.length == 0) return 0; else return Math.min(...this.filteredBookmarks.map(b => b.sort)); } }, methods: { clearInputs() { this.title_input = ""; this.url_input = ""; this.selectedTags = []; }, openCreateModal() { this.$refs.createModal.show() }, openEditModal(bookmark) { this.title_input = bookmark.title; this.url_input = bookmark.url; this.bookmark_id = bookmark.bookmark_id; this.selectedTags = JSON.parse(bookmark.tag); this.$refs.editModal.show(); }, editBookmark() { if (!this.bookmark_id || !this.url_input || !this.title_input) return; this.actions .update( this.bookmark_id, this.title_input, this.url_input, this.selectedTags ) .then(() => { this.$fhcAlert.alertInfo(this.$p.t("bookmark", "bookmarkUpdated")); // reset the values for the title and url inputs this.clearInputs(); this.$refs.editModal.hide(); this.bookmark_id = null; }) .catch(this.$fhcAlert.handleSystemError); }, insertBookmark() { // reset is-invalid css on url input field for (let key of Object.keys(this.validation)) { this.validation[key] = false; } // early return if validation failed if (!this.isValidationSuccessfull()) return; // get highest Sort const sort = this.newSort; this.actions .insert( this.title_input, this.url_input, this.selectedTags, sort ) .then(() => { this.$fhcAlert.alertInfo(this.$p.t("bookmark", "bookmarkAdded")); this.$refs.createModal.hide(); // reset the values for the title and url inputs this.clearInputs(); }) .catch(this.$fhcAlert.handleSystemError); }, isValidationSuccessfull() { // validate the input fields if (this.title_input.length === 0) { this.$fhcAlert.alertError(this.$p.t("bookmark", "invalidTitel")); this.validation.invalidTitel = true; } if (!URL.canParse(this.url_input)) { this.$fhcAlert.alertError(this.$p.t("bookmark", "invalidUrl")); this.validation.invalidURL = true; } return !Object.values(this.validation).some(value => value === true); }, async removeLink(bookmark_id) { let isConfirmed = await this.$fhcAlert.confirmDelete(); // early return if the confirm dialog was not confirmed if (!isConfirmed) return; const errors = await this.actions.remove(bookmark_id); if (!errors) { this.$fhcAlert.alertInfo(this.$p.t("bookmark", "bookmarkDeleted")); } }, sortDown(bookmark_id) { const current = this.filteredBookmarks.find(b => b.bookmark_id === bookmark_id); const next = this.filteredBookmarks .filter(b => b.sort > current.sort) .sort((a, b) => a.sort - b.sort)[0]; if (!next) { console.log("lowest sort item, no change"); return; } this.actions.swap(current.bookmark_id, next.bookmark_id); }, sortUp(bookmark_id) { const current = this.filteredBookmarks.find(b => b.bookmark_id === bookmark_id); const next = this.filteredBookmarks .filter(b => b.sort < current.sort) .sort((a, b) => a.sort + b.sort)[0]; if (!next) { console.log("highest sort item, no change"); return; } this.actions.swap(current.bookmark_id, next.bookmark_id); }, hasTags(link) { if (!link || !link.tag) return false; let tags = link.tag; if (typeof tags === 'string') { try { tags = JSON.parse(tags) } catch { return false; } } if (Array.isArray(tags) && tags.length > 0) { return tags.join(' '); } }, openFilterModal() { if (this.config.tags && this.config.tags.length) this.selectedFilters = [ ...this.config.tags ]; else this.selectedFilters = []; this.$refs.filterModal.show(); }, async handleAddingTagFilter() { this.config.tags = this.selectedFilters; this.$emit('change'); this.$fhcAlert.alertInfo(this.$p.t("bookmark", "filterUpdated")); this.$refs.filterModal.hide(); }, search(event) { const query = event.query ?? ""; // Filter for text this.filteredArray = this.availableTags.filter(item => item.toLowerCase().includes(query.toLowerCase()) ); // input if search not successful if (this.filteredArray.length === 0 && query) { this.filteredArray = [query]; } } }, setup() { const { bookmarks, getters: { tags }, actions } = useUrlStore(); return { bookmarks, tags, actions } }, async mounted() { if (!this.adminMode) { await this.actions.fetch(); this.ready = true; } }, template: /*html*/ `
{{ $p.t('bookmark/adminMode') }}
`, }; /* Link JSON structure: { "bookmark_id": number, "uid": string, "url": string, "title": string, "tag": string, "insertamum": "2024-07-30 14:33:03.699318", "insertvon": null, "updateamum": null, "updatevon": null } */