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')}}
-
+
+
+
+
+
@@ -219,17 +509,66 @@ export default {
{{$p.t('bookmark','newLink')}}
+
+
+
+
+
+
+
+
+
+ {{$p.t('bookmark','headerFilterBookmark')}}
+
+
+
+
+
+
+
+
+
+
+
`,
};
+
/*
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',