diff --git a/application/controllers/api/frontend/v1/Bookmark.php b/application/controllers/api/frontend/v1/Bookmark.php index 3e646bb51..4482159db 100644 --- a/application/controllers/api/frontend/v1/Bookmark.php +++ b/application/controllers/api/frontend/v1/Bookmark.php @@ -29,9 +29,15 @@ class Bookmark extends FHCAPI_Controller parent::__construct([ 'getBookmarks' => self::PERM_LOGGED, 'delete' => self::PERM_LOGGED, - 'insert' => self::PERM_LOGGED, + 'insert' => self::PERM_LOGGED, 'update' => self::PERM_LOGGED, - ]); + 'changeOrder' => self::PERM_LOGGED, + 'getAllBookmarkTags' => self::PERM_LOGGED, + 'getTagFilter' => self::PERM_LOGGED, + 'addAndUpdateTagFilter' => self::PERM_LOGGED, + 'isInOverride' => self::PERM_LOGGED, + 'addWidgetToOverride' => self::PERM_LOGGED, + ]); $this->load->model('dashboard/Bookmark_model', 'BookmarkModel'); @@ -51,7 +57,7 @@ class Bookmark extends FHCAPI_Controller */ public function getBookmarks() { - $this->BookmarkModel->addOrder("bookmark_id"); + $this->BookmarkModel->addOrder("sort"); $bookmarks = $this->BookmarkModel->loadWhere(["uid"=>$this->uid]); $bookmarks = $this->getDataOrTerminateWithError($bookmarks); @@ -99,8 +105,12 @@ class Bookmark extends FHCAPI_Controller $url = $this->input->post('url',true); $title = $this->input->post('title',true); $tag = $this->input->post('tag', true); + if (is_array($tag)) { + $tag = json_encode($tag); // convert PHP array to JSON string + } + $sort = $this->input->post('sort', true); - $insert_into_result = $this->BookmarkModel->insert(['uid'=>$this->uid, 'url'=>$url, 'title'=>$title,'tag'=>$tag, 'insertvon'=>$this->uid, 'updateamum'=>NULL, 'updatevon'=>NULL]); + $insert_into_result = $this->BookmarkModel->insert(['uid'=>$this->uid, 'url'=>$url, 'title'=>$title,'tag'=>$tag, 'insertvon'=>$this->uid, 'updateamum'=>NULL, 'updatevon'=>NULL, 'sort'=>$sort,]); $insert_into_result = $this->getDataOrTerminateWithError($insert_into_result); @@ -123,16 +133,195 @@ class Bookmark extends FHCAPI_Controller $url = $this->input->post('url',true); $title = $this->input->post('title',true); + $tag = $this->input->post('tag', true); + if (is_array($tag)) { + $tag = json_encode($tag); + } $now = new DateTime(); $now = $now->format('Y-m-d H:i:s'); - $update_result = $this->BookmarkModel->update($bookmark_id,['url'=>$url, 'title'=>$title,'updateamum'=>$now]); + $update_result = $this->BookmarkModel->update($bookmark_id,['url'=>$url, 'title'=>$title, 'tag'=>$tag, 'updateamum'=>$now]); $update_result = $this->getDataOrTerminateWithError($update_result); $this->terminateWithSuccess($update_result); } + + /** + * changes sort of two bookmarks in the bookmark table + * @access public + * @return void + */ + public function changeOrder($bookmark_id1, $bookmark_id2) + { + + $result1 = $this->BookmarkModel->load($bookmark_id1); + $data1 = $this->getDataOrTerminateWithError($result1); + $sort1 = current($data1)->sort; + + $result2 = $this->BookmarkModel->load(["bookmark_id"=>$bookmark_id2]); + $data2 = $this->getDataOrTerminateWithError($result2); + $sort2 = current($data2)->sort; + + $update_result1 = $this->BookmarkModel->update($bookmark_id1,['sort'=>$sort2,]); + $update_result[] = $this->getDataOrTerminateWithError($update_result1); + + $update_result2 = $this->BookmarkModel->update($bookmark_id2,['sort'=>$sort1,]); + $update_result[] = $this->getDataOrTerminateWithError($update_result2); + + $this->terminateWithSuccess($update_result); + } + + /** + * get all the bookmark tags associated to a user + * @access public + * @return void + */ + public function getAllBookmarkTags() + { + $this->BookmarkModel->addOrder("sort"); + $result = $this->BookmarkModel->getAllBookmarkTags($this->uid); + + $bookmarks = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($bookmarks)); + } + + /** + * get all tagFilter of a certain bookmark widget + * @access public + * @return void + */ + public function getTagFilter($widgetId, $sectionName) + { + $result = $this->BookmarkModel->getTagFilter($widgetId, $this->uid, $sectionName); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($data)); + } + /** + * get all tagFilter of a certain bookmark widget + * @access public + * @return void + */ + public function addAndUpdateTagFilter($widgetId, $sectionName) + { + $tags = $this->input->post('tags',true); + if (is_array($tags)) + { + $tags = json_encode($tags); + } + $result = $this->BookmarkModel->addAndUpdateTagFilter($widgetId, $this->uid, $sectionName, $tags); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + /** + * checks if a widget has already an entry in the benutzeroverride + * @access public + * @return void + */ + public function isInOverride($widgetId, $sectionName) + { + $result = $this->BookmarkModel->checkOrAddToOverride($widgetId, $this->uid, $sectionName); + + $data = getData($result); + if(!$data) + $this->terminateWithSuccess([false, 0]); + + $id = current($data)->widgetid; + $id = trim($id, '"'); + + if ($id != $widgetId) + $this->terminateWithSuccess([false, 1]); + else + $this->terminateWithSuccess([true, null]); + } + /** + * adds widget benutzeroverride + * @access public + * @return void + */ + public function addWidgetToOverride($widgetId, $sectionName, $mode, $x, $y, $h, $w) + { + $this->load->library('dashboard/DashboardLib', null, 'DashboardLib'); + $dashboard_kurzbz = "CIS"; + $structure = [ + "custom" => [ + "widgets" => [] + ], + "general" => [ + "widgets" => [ + $widgetId => [ + "widget" => 3, + "config" => new stdClass(), + "place" => [ + "3" => [ + "x" => $x, + "y" => $y, + "w" => $w, + "h" => $h + ] + ], + "widgetid" => $widgetId, + "custom" => 1, + "id" => "insertByBookmarkwidget" + ] + ] + ] + ]; + $jsonOverrideNew = json_encode($structure, JSON_UNESCAPED_UNICODE); + + //no existing benutzeroverride + if($mode == 0) + { + $override = $this->DashboardLib->getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $this->uid); + + $override->override = $jsonOverrideNew; + + $result = $this->DashboardLib->insertOrUpdateOverride($override); + + $this->terminateWithSuccess($result); + + } + //benutzeroverride existing, but widget not included + elseif($mode == 1) + { + $overrideExisting = $this->DashboardLib->getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $this->uid); + $override = json_decode($overrideExisting->override, true); // decode as Array + + $newWidget = [ + "widget" => 3, + "config" => new stdClass(), + "place" => [ + "3" => [ + "x" => $x, + "y" => $y, + "w" => $w, + "h" => $h + ] + ], + "widgetid" => $widgetId, + "custom" => 1, + "id" => "insertByBookmarkwidget" + ]; + + $override['general']['widgets'][$widgetId] = $newWidget; + + $jsonOverrideUpdated = json_encode($override, JSON_UNESCAPED_UNICODE); + $overrideExisting->override = $jsonOverrideUpdated; + + $result = $this->DashboardLib->insertOrUpdateOverride($overrideExisting); + + $this->terminateWithSuccess($result); + } + else + $this->terminateWithError("Error: no known mode"); + } + } diff --git a/application/models/dashboard/Bookmark_model.php b/application/models/dashboard/Bookmark_model.php index 5efacc26b..931fe7064 100644 --- a/application/models/dashboard/Bookmark_model.php +++ b/application/models/dashboard/Bookmark_model.php @@ -12,7 +12,83 @@ class Bookmark_model extends DB_Model $this->pk = 'bookmark_id'; } + /** + * returns all bookmark tags of a user + */ + public function getAllBookmarkTags($uid) + { + $qry = " + SELECT array_agg(DISTINCT tag) AS data + FROM ( + SELECT jsonb_array_elements_text(tag) AS tag + FROM dashboard.tbl_bookmark + WHERE uid = ? + ) t; + "; - + return $this->execQuery($qry, array('uid' => $uid)); + } + /** + * Get Overrides of given uid and funktion_kurzbz and widget_id + * @param integer $widget_id + * @param string $uid + * @param string $funktion_kurzbz + * @return array + */ + public function getTagFilter($widgetId, $uid, $funktion_kurzbz) + { + $qry = " SELECT override -> '" . $funktion_kurzbz . "'-> 'widgets'-> '" . $widgetId . "'-> 'config' -> 'tags' AS tags FROM dashboard.tbl_dashboard_benutzer_override WHERE uid = '" . $uid . "';"; + + return $this->execQuery($qry); + } + + /* + * updates Tagfilter + * checks and changes type of config + * if config == array -> change to object + */ + public function addAndUpdateTagFilter($widgetId, $uid, $funktion_kurzbz, $tags) + { + $params = [ + $funktion_kurzbz, $widgetId, + $funktion_kurzbz, $widgetId, + $funktion_kurzbz, $widgetId, + $funktion_kurzbz, $widgetId, + $tags, + $uid + ]; + + $qry = " + UPDATE dashboard.tbl_dashboard_benutzer_override + SET override = jsonb_set( + -- check if config is object + jsonb_set( + COALESCE(override, '{}'::jsonb), + format('{%s,widgets,%s,config}', ?, ?)::text[], + CASE + WHEN jsonb_typeof(override #> format('{%s,widgets,%s,config}', ?, ?)::text[]) = 'array' + THEN '{}'::jsonb + ELSE COALESCE((override #> format('{%s,widgets,%s,config}', ?, ?)::text[])::jsonb, '{}'::jsonb) + END, + true + ), + -- insert tags + format('{%s,widgets,%s,config,tags}', ?, ?)::text[], + ?::jsonb, + true + ) + WHERE uid = ? + "; + + return $this->execQuery($qry, $params); + } + + public function checkOrAddToOverride($widgetId, $uid, $funktion_kurzbz) + { + $params = [$funktion_kurzbz, $widgetId, $uid]; + $qry = " SELECT override -> '" . $funktion_kurzbz . "'-> 'widgets'-> '" . $widgetId . "'-> 'widgetid' as widgetid FROM dashboard.tbl_dashboard_benutzer_override WHERE uid = '" . $uid . "';"; + + return $this->execQuery($qry, $params); + } } diff --git a/application/views/CisRouterView/CisRouterView.php b/application/views/CisRouterView/CisRouterView.php index 6ff428362..37c18e39c 100644 --- a/application/views/CisRouterView/CisRouterView.php +++ b/application/views/CisRouterView/CisRouterView.php @@ -23,12 +23,14 @@ $includesArray = array( 'public/css/components/FormUnderline.css', 'public/css/components/abgabetool/abgabe.css', 'public/css/Cis4/Cms.css', - 'public/css/Cis4/Studium.css', + 'public/css/Cis4/Studium.css' ), 'customJSs' => array( 'vendor/npm-asset/primevue/accordion/accordion.min.js', 'vendor/npm-asset/primevue/accordiontab/accordiontab.min.js', 'vendor/npm-asset/primevue/checkbox/checkbox.min.js', + 'vendor/npm-asset/primevue/chips/chips.min.js', + 'vendor/npm-asset/primevue/multiselect/multiselect.min.js', 'vendor/npm-asset/primevue/inputnumber/inputnumber.min.js', 'vendor/npm-asset/primevue/speeddial/speeddial.min.js', 'vendor/npm-asset/primevue/textarea/textarea.min.js', diff --git a/public/js/api/factory/widget/bookmark.js b/public/js/api/factory/widget/bookmark.js index 9768e25ac..9379b42b2 100644 --- a/public/js/api/factory/widget/bookmark.js +++ b/public/js/api/factory/widget/bookmark.js @@ -17,6 +17,7 @@ export default { getBookmarks() { + return { method: 'get', url: '/api/frontend/v1/Bookmark/getBookmarks' @@ -28,18 +29,55 @@ export default { url: `/api/frontend/v1/Bookmark/delete/${bookmark_id}` }; }, - update({ bookmark_id, url, title, tag=null }) { + update({ bookmark_id, url, title, tag }) { return { method: 'post', url: `/api/frontend/v1/Bookmark/update/${bookmark_id}`, - params: { url, title } + params: { url, title, tag } }; }, - insert({ url, title, tag }) { + insert({ url, title, tag, sort }) { return { method: 'post', url: `/api/frontend/v1/Bookmark/insert`, - params: { url, title, tag } + params: { url, title, tag, sort } }; + }, + changeOrder(bookmark_id1, bookmark_id2) { + return { + method: 'post', + url: `/api/frontend/v1/Bookmark/changeOrder/${bookmark_id1}/${bookmark_id2}`, + }; + }, + getAllBookmarkTags() { + return { + method: 'get', + url: '/api/frontend/v1/Bookmark/getAllBookmarkTags' + }; + }, + getTagFilter(widgetId, sectionName){ + return { + method: 'get', + url: `/api/frontend/v1/Bookmark/getTagFilter/${widgetId}/${sectionName}` + }; + }, + addTagFilter(widgetId, sectionName, tags){ + return { + method: 'post', + url: `/api/frontend/v1/Bookmark/addAndUpdateTagFilter/${widgetId}/${sectionName}`, + params: { tags } + }; + }, + isInOverride(widgetId, sectionName){ + return { + method: 'post', + url: `/api/frontend/v1/Bookmark/isInOverride/${widgetId}/${sectionName}` + }; + }, + addWidgetToOverride(widgetId, sectionName, mode, x, y, h, w){ + return { + method: 'post', + url: `/api/frontend/v1/Bookmark/addWidgetToOverride/${widgetId}/${sectionName}/${mode}/${x}/${y}/${h}/${w}`, + }; } }; \ No newline at end of file diff --git a/public/js/components/Dashboard/Item.js b/public/js/components/Dashboard/Item.js index 79e61293d..626ae7024 100644 --- a/public/js/components/Dashboard/Item.js +++ b/public/js/components/Dashboard/Item.js @@ -203,8 +203,9 @@ export default { +
- +
diff --git a/public/js/components/DashboardWidget/Abstract.js b/public/js/components/DashboardWidget/Abstract.js index e9f87490d..0b6a1151f 100644 --- a/public/js/components/DashboardWidget/Abstract.js +++ b/public/js/components/DashboardWidget/Abstract.js @@ -5,7 +5,9 @@ export default { "height", "configMode", "sharedData", - "widgetInfo" + "widgetInfo", + "widgetId", + "item_data" ], emits: [ "setConfig", diff --git a/public/js/components/DashboardWidget/Url.js b/public/js/components/DashboardWidget/Url.js index 16eacab90..6e7ffeeb3 100644 --- a/public/js/components/DashboardWidget/Url.js +++ b/public/js/components/DashboardWidget/Url.js @@ -12,23 +12,38 @@ export default { editModeIsActive: { type: Boolean, default: false + }, + sectionName: { + type: String, + default: false } }, components:{ CoreForm, FormInput, - BsModal + BsModal, + PvChips: primevue.chips, + PvMultiSelect: primevue.multiselect, + PvAutoComplete: primevue.autocomplete, }, data: () => ({ bookmark_id: null, title_input: "", url_input: "", + sort: null, validation: { invalidURL: false, invalidTitel: false, }, + tagsArrayMS: [], + tagsArrayAC: [], + selectedTags: [], + newTag: null, + selectedFilters: [], + filter: [], + filteredArray: [], + sharedFiltered: {}, }), - computed: { tagName() { return this.config.tag !== undefined && this.config.tag.length > 0 @@ -42,6 +57,27 @@ export default { return false; }, + newSort(){ + if(this.shared.length == 0) + return 1; + else + return Math.max(...this.shared.map(b => b.sort)) + 1; + }, + maxSort(){ + if(this.shared.length == 0) + return 0; + else + return Math.max(...this.sharedFiltered.map(b => b.sort)); + }, + minSort(){ + if(this.shared.length == 0) + return 0; + else + return Math.min(...this.sharedFiltered.map(b => b.sort)); + }, + filterInput(){ + return this.selectedFilters.map(item => item.tag); + }, }, methods: { stopDrag(event){ @@ -49,7 +85,8 @@ export default { }, clearInputs(){ this.title_input = ""; - this.url_input = ""; + this.url_input = ""; + this.selectedTags = []; }, openCreateModal() { this.$refs.createModal.show() @@ -58,22 +95,26 @@ export default { this.title_input = bookmark.title; this.url_input = bookmark.url; this.bookmark_id = bookmark.bookmark_id; - this.$refs.editModal.show() + this.selectedTags = JSON.parse(bookmark.tag); + + this.$refs.editModal.show(); }, editBookmark(event){ event.preventDefault(); if(!this.bookmark_id || !this.url_input || !this.title_input) return; - + this.$api .call(ApiBookmark.update({ bookmark_id: this.bookmark_id, title: this.title_input, url: this.url_input, + tag: this.selectedTags, })) .then((res) => res.data) .then((result) => { this.$fhcAlert.alertInfo(this.$p.t("bookmark", "bookmarkUpdated")); // refetch the bookmarks to see the updates + this.getAllBookmarkTags(); this.fetchBookmarks(); // reset the values for the title and url inputs this.clearInputs(); @@ -94,16 +135,21 @@ export default { // early return if validation failed if (!this.isValidationSuccessfull()) return; + // get highest Sort + this.sort = this.newSort; + this.$api .call(ApiBookmark.insert({ - tag: this.config.tag, + tag: this.selectedTags, title: this.title_input, url: this.url_input, + sort: this.sort })) .then((res) => res.data) .then((result) => { this.$fhcAlert.alertInfo(this.$p.t("bookmark", "bookmarkAdded")); // refetch the bookmarks to see the updates + this.getAllBookmarkTags(); this.fetchBookmarks(); this.$refs.createModal.hide(); // reset the values for the title and url inputs @@ -111,7 +157,6 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); }, - isValidationSuccessfull() { // validate the input fields if (this.title_input.length === 0) { @@ -131,6 +176,10 @@ export default { .then((res) => res.data) .then((result) => { this.shared = result; + + this.$nextTick(() => { + this.sharedFiltered = this.filterBookmarksByTags(this.shared); + }); }) .catch(this.$fhcAlert.handleSystemError); }, @@ -147,39 +196,268 @@ export default { this.$fhcAlert.alertInfo(this.$p.t("bookmark", "bookmarkDeleted")); // refetch the bookmarks to see the updates this.fetchBookmarks(); + this.getAllBookmarkTags(); }) .catch(this.$fhcAlert.handleSystemError); }, + filterBookmarksByTags(bookmarks) { + const filter = this.filter; + if (!filter || filter.length === 0 || filter == "[]") return bookmarks; + + return bookmarks.filter(b => { + const tags = JSON.parse(b.tag || "[]"); + return tags.some(tag => filter.includes(tag)); + }); + }, + sortDown(bookmark_id){ + const current = this.sharedFiltered.find(b => b.bookmark_id === bookmark_id); + + const next = this.sharedFiltered + .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.changeOrder(current.bookmark_id, next.bookmark_id); + }, + sortUp(bookmark_id){ + const current = this.sharedFiltered.find(b => b.bookmark_id === bookmark_id); + + const next = this.sharedFiltered + .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.changeOrder(current.bookmark_id, next.bookmark_id); + }, + addNewTag(){ + if(this.newTag != null && this.newTag.length) { + this.tagsArrayMS.push({tag: this.newTag, code: this.newTag}); + this.selectedTags.push({tag: this.newTag, code: this.newTag}); + this.newTag = null; + } + else + this.$fhcAlert.alertError(this.$p.t("bookmark", "errorInputNecessary")); + }, + changeOrder(bookmark_id_1, bookmark_id_2){ + this.$api + .call(ApiBookmark.changeOrder(bookmark_id_1, bookmark_id_2)) + .then((res) => res.data) + .then((result) => { + // refetch the bookmarks to see the updates + this.fetchBookmarks(); + }) + .catch(this.$fhcAlert.handleSystemError); + }, + 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(' '); + } + }, + prepareTag(bookmarkArr){ + const parsedArr = Array.isArray(bookmarkArr) + ? bookmarkArr + : JSON.parse(bookmarkArr); + + const result = parsedArr.map(tag => ({ + tag, + code: tag + })); + + return result; + }, + getAllBookmarkTags(){ + this.$api + .call(ApiBookmark.getAllBookmarkTags()) + .then((res) => res.data) + .then((result) => { + //Version Chips + this.tagsArrayMS = this.prepareTag(result.data); + + //Version Autocomplete + this.tagsArrayAC = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + }, + openFilterModal(){ + this.$refs.filterModal.show(); + }, + async handleAddingTagFilter(widgetId){ + + const result = await this.isInOverride(widgetId); + + if (!result) { + return; + } + const [status, reason] = result; + + if (status) { + this.addTagFilter(widgetId); + } else { + this.addWidgetToOverride(widgetId, reason); + } + }, + addTagFilter(widgetId){ + this.$api + .call(ApiBookmark.addTagFilter(widgetId, this.sectionName, this.filterInput)) + .then((res) => res.data) + .then((result) => { + this.$fhcAlert.alertInfo(this.$p.t("bookmark", "filterUpdated")); + this.$refs.filterModal.hide(); + this.getTagFilter(this.widgetId); + + this.$nextTick(() => { + this.getAllBookmarkTags(); + }); + this.fetchBookmarks(); + }) + .catch(this.$fhcAlert.handleSystemError); + }, + async isInOverride(widgetId) { + try { + const res = await this.$api.call(ApiBookmark.isInOverride(widgetId, this.sectionName)); + const result = res.data; + return result; + } catch (err) { + this.$fhcAlert.handleSystemError(err); + return null; + } + }, + addWidgetToOverride(widgetId, reason){ + this.$api + .call(ApiBookmark.addWidgetToOverride( + widgetId, + this.sectionName, + reason, + this.item_data.x, + this.item_data.y, + this.item_data.h, + this.item_data.w + )) + .then((res) => res.data) + .then((result) => { + this.addTagFilter(widgetId); + }) + .catch(this.$fhcAlert.handleSystemError); + }, + getTagFilter(widget_id){ + this.$api + .call(ApiBookmark.getTagFilter(widget_id, this.sectionName)) + .then((res) => res.data) + .then((result) => { + const rawTags = result.tags; // string + this.filter = rawTags; + if(rawTags != null) { + this.rawTagsParsed = JSON.parse(rawTags); + this.selectedFilters = this.prepareTag(this.rawTagsParsed); + } + this.fetchBookmarks(); + }) + .catch(this.$fhcAlert.handleSystemError); + }, + search(event) { + const query = event.query ?? ""; + + // Filter for text + this.filteredArray = this.tagsArrayAC.filter(item => + item.toLowerCase().includes(query.toLowerCase()) + ); + + // input if search not successful + if (this.filteredArray.length === 0 && query) { + this.filteredArray = [query]; + } + }, }, async mounted() { + if(this.widgetId) { + this.getTagFilter(this.widgetId); + } await this.fetchBookmarks(); + this.getAllBookmarkTags(); }, created() { - // - // this.$emit('setConfig', true); -> use this to enable widget config mode if needed + // this.$emit('setConfig', true); // -> use this to enable widget config mode if needed }, + + template: /*html*/ `
-
- - +
@@ -204,8 +482,20 @@ export default {

{{$p.t('bookmark','editLink')}}

+ + + + + + + + `, }; + /* Link JSON structure: { diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index f75c150e9..2632548d6 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -95,6 +95,7 @@ require_once('dbupdate_3.4/71645_studvw_messagetab_ladezeit.php'); require_once('dbupdate_3.4/71566_studienordnungsdokument_neuer_organisationseinheitstyp_programm.php'); require_once('dbupdate_3.4/70376_lohnguide.php'); require_once('dbupdate_3.4/76150_perm_other_lv_plan.php'); +require_once('dbupdate_3.4/68957_dashboard_bookmark_neue_Spalte_sort.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; @@ -468,7 +469,7 @@ $tabellen=array( "wawi.tbl_rechnungsbetrag" => array("rechnungsbetrag_id","rechnung_id","mwst","betrag","bezeichnung","ext_id"), "wawi.tbl_aufteilung" => array("aufteilung_id","bestellung_id","oe_kurzbz","anteil","insertamum","insertvon","updateamum","updatevon"), "wawi.tbl_aufteilung_default" => array("aufteilung_id","kostenstelle_id","oe_kurzbz","anteil","insertamum","insertvon","updateamum","updatevon"), - "dashboard.tbl_bookmark" => array("bookmark_id","uid","url","title","tag","insertamum","insertvon","updateamum","updatevon"), + "dashboard.tbl_bookmark" => array("bookmark_id","uid","url","title","tag","insertamum","insertvon","updateamum","updatevon","sort"), ); diff --git a/system/dbupdate_3.4/68957_dashboard_bookmark_neue_Spalte_sort.php b/system/dbupdate_3.4/68957_dashboard_bookmark_neue_Spalte_sort.php new file mode 100644 index 000000000..ccef52686 --- /dev/null +++ b/system/dbupdate_3.4/68957_dashboard_bookmark_neue_Spalte_sort.php @@ -0,0 +1,57 @@ +db_query("SELECT sort FROM dashboard.tbl_bookmark LIMIT 1")) { + $qry = "ALTER TABLE dashboard.tbl_bookmark ADD COLUMN sort integer DEFAULT NULL; + COMMENT ON COLUMN dashboard.tbl_bookmark.sort IS 'Sort Index for Bookmark.'; + "; + + if (!$db->db_query($qry)) + echo 'dashboard.tbl_bookmark ' . $db->db_last_error() . '
'; + else + echo '
Spalte sort zu Tabelle dashboard.tbl_bookmark hinzugefügt'; + + //add preliminary Sort for all bookmarks if NULL + if(@$db->db_query("SELECT sort FROM dashboard.tbl_bookmark LIMIT 1")) { + $qry = "WITH ranked AS ( + SELECT + t1.bookmark_id, + ( + SELECT COUNT(*) + FROM dashboard.tbl_bookmark t2 + WHERE t2.uid = t1.uid + AND t2.bookmark_id <= t1.bookmark_id + ) AS rn + FROM dashboard.tbl_bookmark t1 + ) + UPDATE dashboard.tbl_bookmark t + SET sort = ranked.rn + FROM ranked + WHERE t.bookmark_id = ranked.bookmark_id + AND t.sort IS NULL;"; + + if (!$db->db_query($qry)) + echo 'dashboard.tbl_bookmark ' . $db->db_last_error() . '
'; + else + echo '
Tabelle dashboard.tbl_bookmark: Spalte sort mit vorläufiger Sortierung befüllt'; + } +} + +//set column tag to type JSONB +if($result = @$db->db_query("SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='dashboard' + AND TABLE_NAME='tbl_bookmark' AND COLUMN_NAME = 'tag' + AND DATA_TYPE='character varying' AND character_maximum_length='255';")) +{ + $qry = " + ALTER TABLE dashboard.tbl_bookmark + ALTER COLUMN tag TYPE jsonb + USING tag::jsonb; + "; + + if (!$db->db_query($qry)) + echo 'dashboard.tbl_bookmark ' . $db->db_last_error() . '
'; + else + echo '
Tabelle dashboard.tbl_bookmark: Spalte tag auf Typ JSONB geändert'; + +} \ No newline at end of file diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 4a240d47e..a4c55bde3 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -35742,6 +35742,207 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'bookmark', + 'phrase' => 'editFilter', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Filter bearbeiten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'edit Filter', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'bookmark', + 'phrase' => 'filterByTags', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nach Tags Filtern', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'filter by Tags', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'bookmark', + 'phrase' => 'sortDownwards', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nach unten verschieben', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'sort downwards', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'bookmark', + 'phrase' => 'sortToTop', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nach oben verschieben', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'sort to top', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'bookmark', + 'phrase' => 'deleteBookmark', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lesezeichen löschen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'delete Bookmark', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'bookmark', + 'phrase' => 'editBookmark', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lesezeichen bearbeiten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'edit Bookmark', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'bookmark', + 'phrase' => 'filterUpdated', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Filteraktion erfolgreich durchgeführt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'filter updated successfully', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'bookmark', + 'phrase' => 'errorInputNecessary', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Eingabe eines Zeichens erforderlich', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'One character must be entered', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'bookmark', + 'phrase' => 'noFilter', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Kein Filter für Lesezeichen ausgewählt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No bookmark filter entered', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'bookmark', + 'phrase' => 'headerFilterBookmark', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lesezeichen filtern', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Filter Bookmarks', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + // BOOKMARK PHRASEN END ---------------------------------------------------------------------- array( 'app' => 'core', 'category' => 'global',