flagging unflagging cards

This commit is contained in:
Bachir Soussi Chiadmi 2020-11-24 14:07:10 +01:00
parent ffc4a88094
commit a38653f7ce
14 changed files with 476 additions and 81 deletions

View File

@ -3,9 +3,10 @@ langcode: en
status: true
dependencies:
module:
- flag_lists
- node
id: dossier
label: Dossier
label: Folder
bundles:
- article
- materiau
@ -21,11 +22,20 @@ unflag_long: ''
unflag_message: ''
unflag_denied_text: ''
flag_type: 'entity:node'
link_type: reload
link_type: ajax_link
flagTypeConfig:
show_in_links: { }
show_in_links:
card_big: card_big
card_full: card_full
card_medium: card_medium
card_small: card_small
full: full
search_index: search_index
search_result: search_result
teaser: teaser
token: token
show_as_field: true
show_on_form: false
show_on_form: true
show_contextual_link: true
extra_permissions:
owner: owner

View File

@ -3,7 +3,7 @@ langcode: en
status: true
dependencies: { }
id: dossier
label: Dossier
label: Folder
base_flag: dossier
owner: root
weight: null

View File

@ -21,3 +21,27 @@ materio_flag.delete_user_flagging_collection:
_title: 'Delete User Flagging Collection'
requirements:
_permission: 'edit own flag lists'
materio_flag.flag:
path: 'materio_flag/flag'
defaults:
_controller: '\Drupal\materio_flag\Controller\MaterioFlagActionsController::flaglistentity'
_title: 'Add entity to Flagging Collection'
requirements:
_permission: 'edit own flag lists'
materio_flag.unFlag:
path: 'materio_flag/unflag'
defaults:
_controller: '\Drupal\materio_flag\Controller\MaterioFlagActionsController::unFlaglistentity'
_title: 'Remove entity from Flagging Collection'
requirements:
_permission: 'edit own flag lists'
# materio_flag.unflag
# path: 'materio_flag/unflag'
# defaults:
# _controller: '\Drupal\materio_flag\Controller\MaterioFlagController::unFlag'
# _title: 'Remove entity from Flagging Collection'
# requirements:
# _permission: 'edit own flag lists'

View File

@ -0,0 +1,118 @@
<?php
// https://developpeur-drupal.com/article/injection-dependances-lors-heritage-classe-qui-implemente-controllerbase
namespace Drupal\materio_flag\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Session\AccountProxy;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\flag\FlagInterface;
use Drupal\flag\FlagServiceInterface;
use Drupal\flag_lists\FlagListsService;
use Drupal\flag_lists\FlagListsServiceInterface;
use Drupal\flag_lists\Entity\FlaggingCollection;
use Drupal\flag_lists\Controller\ActionLinkController;
use Drupal\flag_lists\Controller\ActionLinkHelper;
use Drupal\flag_lists\Entity\FlagListItem;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* Class AjaxHomeController.
*/
class MaterioFlagActionsController extends ActionLinkController {
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('flag'),
$container->get('flaglists'),
$container->get('renderer')
);
}
/**
* Constructs a new MaterioFlagController object.
*/
public function __construct(
FlagServiceInterface $flag,
FlagListsServiceInterface $flag_lists,
RendererInterface $renderer
) {
parent::__construct($flag, $flag_lists, $renderer);
}
public function flaglistentity(Request $request) {
$post_data = json_decode( $request->getContent(),TRUE);
$flagid = $post_data['flagid'];
$uuid = $post_data['uuid'];
$flagcollid = $post_data['flagcollid'];
// $flagcoll = $this->flagListsService->getFlaggingCollectionById($flagcollid);
// $flag = $flagcoll->getRelatedFlag();
$flag = $this->flagService->getFlagById($flagid);
$node = \Drupal::service('entity.repository')->loadEntityByUuid('node', $uuid);
$nid = $node->id();
// call the parent flag function
$this->flag($flag, $nid, $flagcollid);
// // OR rewrite it entirely
// $entity = $this->flagService->getFlaggableById($flag, $nid);
// // flag
// $this->flagService->flag($flag, $entity);
// // Create the flag list item.
// // $actionLinkHelper = new ActionLinkHelper($this->flagListsService);
// // $actionLinkHelper->flagHelper($flag, $nid, $flagcoll);
// $flag_list_item = FlagListItem::create([
// 'entity_id' => $nid,
// 'type' => $flag->getFlaggableEntityTypeId(),
// 'baseflag' => $flagid,
// 'flag_list' => $flagcollid,
// 'name' => $flagcoll->getName() . ' ' . $nid,
// ]);
// $flag_list_item->save();
$data = [
'flag' => $flag->toArray(),
'flagid' => $flagid,
'entity_id' => $nid,
'entity_uuid' => $uuid,
'flagcollid' => $flagcollid,
// 'post_data' => $post_data,
// 'flaggableEntityTypeId' => $flag->getFlaggableEntityTypeId(),
// 'entity_title' => $entity->get('title')->value,
// 'flag_list_item' => $flag_list_item->getName(),
];
return new JsonResponse($data);
}
public function unFlaglistentity(Request $request) {
$post_data = json_decode( $request->getContent(),TRUE);
$flagid = $post_data['flagid'];
$uuid = $post_data['uuid'];
$flagcollid = $post_data['flagcollid'];
// get flag
$flag = $this->flagService->getFlagById($flagid);
// get the nid from uuid
$node = \Drupal::service('entity.repository')->loadEntityByUuid('node', $uuid);
$nid = $node->id();
// call the parent flag function
$this->unflag($flag, $nid, $flagcollid);
// response
$data = [
'flag' => $flag->toArray(),
'flagid' => $flagid,
'entity_id' => $nid,
'entity_uuid' => $uuid,
'flagcollid' => $flagcollid,
];
return new JsonResponse($data);
}
}

View File

@ -6,8 +6,10 @@ use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Session\AccountProxy;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\flag_lists\FlagListsService;
use Drupal\flag_lists\Entity\FlaggingCollection;
use Drupal\flag_lists\Controller\ActionLinkController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
@ -16,10 +18,15 @@ use Symfony\Component\HttpFoundation\JsonResponse;
class MaterioFlagController extends ControllerBase {
/*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var \Drupal\flag_lists\FlagListsService
*/
protected $flaglists;
protected $flagListsService;
/**
* @var \Drupal\user\User
@ -31,6 +38,7 @@ class MaterioFlagController extends ControllerBase {
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('flaglists'),
$container->get('current_user')
);
@ -39,8 +47,9 @@ class MaterioFlagController extends ControllerBase {
/**
* Constructs a new MaterioFlagController object.
*/
public function __construct(FlagListsService $flag_lists_service, AccountProxyInterface $account) {
$this->flaglists = $flag_lists_service;
public function __construct(EntityTypeManagerInterface $entity_type_manager, FlagListsService $flag_lists_service, AccountProxyInterface $account) {
$this->entityTypeManager = $entity_type_manager;
$this->flagListsService = $flag_lists_service;
$this->user = $account;
}
@ -52,13 +61,35 @@ class MaterioFlagController extends ControllerBase {
*/
public function getUsersFlaggingCollections() {
$colls = $this->flaglists->getUsersFlaggingCollections();
$colls = $this->flagListsService->getUsersFlaggingCollections();
$data = [];
foreach ($colls as $id => $collection) {
$data[] = array(
"id" => $id,
"name" => $collection->getName()
$flag_id = $collection->getRelatedFlag()->id();
// get the items
$itemsids = $this->flagListsService->getFlagListItemIds($flag_id,$id);
$items = [];
foreach ($this->flagListsService->getFlagListItems($itemsids) as $id => $item) {
// $items[] = array(
// 'id' => $id,
// 'name' => $item->getName(),
// 'connected_entity_id' => $item->getConnectedEntityId(),
// );
$items[] = $item->getConnectedEntityId();
}
$items_uuids = [];
foreach ($items as $nid) {
$node = $this->entityTypeManager->getStorage('node')->load($nid);
$items_uuids[] = $node->uuid();
}
$data[$collection->id()] = array(
"id" => $collection->id(),
"name" => $collection->getName(),
"flag_id" => $flag_id,
"items" => $items,
"items_uuids" => $items_uuids,
);
}
@ -91,9 +122,9 @@ class MaterioFlagController extends ControllerBase {
public function deleteUserFlaggingCollection(Request $request) {
// dpm($request);
$post_data = json_decode( $request->getContent(),TRUE);
$flagid = $post_data['flagid'];
$flagcollid = $post_data['flagcollid'];
$flagcoll = $this->flaglists->getFlaggingCollectionById($flagid);
$flagcoll = $this->flagListsService->getFlaggingCollectionById($flagcollid);
// dump($flagcoll);
$flagcoll->delete();
// TODO: warning, sometimes relatedFlag deos not exists
@ -101,9 +132,36 @@ class MaterioFlagController extends ControllerBase {
$data = [
// 'result' => $flag,
'id' => $flagid
'id' => $flagcollid
];
return new JsonResponse($data);
}
// public function flag(Request $request) {
// // dpm($request);
// $post_data = json_decode( $request->getContent(),TRUE);
// $flagid = $post_data['flagid'];
// $nid = $post_data['nid'];
// $flagcollid = $post_data['flagcollid'];
//
// $actionLinkController = new ActionLinkController();
// // FlagInterface $flag, $entity_id, $flag_list
// $status = $actionLinkController->flag($flagid, $nid, $flagcollid);
//
// // $flagcoll = $this->flagListsService->getFlaggingCollectionById($flagid);
// // // dump($flagcoll);
// // $flagcoll->delete();
// // // TODO: warning, sometimes relatedFlag deos not exists
// // // $flag = $flagcoll->getRelatedFlag();
//
// $data = [
// 'status' => $flag,
// 'flagid' => $flagid,
// 'nid' => $nid,
// 'flagcollid' => $flagcollid
// ];
// return new JsonResponse($data);
// }
}

View File

@ -101,6 +101,7 @@ class Base extends ControllerBase {
// $items = [];
$uuids = [];
$nids = [];
foreach ($this->results as $result) {
// $nid = $result->getField('nid')->getValues()[0];
// $uuid = $result->getField('uuid')->getValues()[0];
@ -111,9 +112,11 @@ class Base extends ControllerBase {
// 'title' => $title,
// ];
$uuids[] = $result->getField('uuid')->getValues()[0];
$nids[] = $result->getField('nid')->getValues()[0];
}
// $resp['items'] = $items;
$resp['uuids'] = $uuids;
$resp['nids'] = $nids;
}
return new JsonResponse($resp);

View File

@ -1631,6 +1631,37 @@ article.card {
font-size: 0.693em;
font-weight: 300;
line-height: 1; }
article.card nav.tools {
position: absolute;
top: 0;
right: 0;
z-index: 21;
width: 1em;
background-color: #fff;
box-sizing: content-box;
padding: 0.3em 0.1em; }
article.card nav.tools > * {
overflow: visible;
position: relative; }
article.card nav.tools > * span.btn {
overflow: hidden;
font-size: 0.882em; }
article.card nav.tools > * .tool-content {
position: absolute;
top: 0px;
right: 100%;
width: 5em;
box-sizing: content-box;
padding: 0.3em;
background-color: #fff;
box-shadow: -2px 3px 4px rgba(0, 0, 0, 0.2); }
article.card nav.tools .tool.flags span.flag {
cursor: pointer;
font-size: 0.756em;
color: #bbb;
transition: color 0.3s ease-in-out; }
article.card nav.tools .tool.flags span.flag:hover, article.card nav.tools .tool.flags span.flag.isActive {
color: #1a1a1a; }
article.card section.images {
position: relative; }
article.card section.images, article.card section.images * {

File diff suppressed because one or more lines are too long

View File

@ -694,6 +694,45 @@ article.card{
line-height: 1;
}
}
nav.tools{
position: absolute;
top: 0;
right: 0;
z-index: 21;
width: 1em;
background-color: #fff;
box-sizing: content-box;
padding: 0.3em 0.1em;
>*{
overflow: visible;
position: relative;
span.btn{
overflow: hidden;
font-size: 0.882em;
}
.tool-content{
position: absolute;
top: 0px;
right: 100%;
width: 5em;
box-sizing: content-box;
padding: 0.3em;
background-color: #fff;
box-shadow: -2px 3px 4px rgba(0, 0, 0, 0.2);
}
}
.tool.flags{
span.flag{
cursor: pointer;
font-size: 0.756em;
color: #bbb;
transition: color 0.3s ease-in-out;
&:hover, &.isActive{
color:#1a1a1a;
}
}
}
}
section.images{
position: relative;
&, *{width: 100%; height:100%;}

View File

@ -9,5 +9,6 @@ export const MA = axios.create({
withCredentials: true,
headers: {
"Content-Type": "application/json"
// "X-CSRF-Token": "csrf_token"
}
})

View File

@ -5,6 +5,27 @@
<h4>{{ item.field_short_description }}</h4>
<span class="ref">{{ item.field_reference }}</span>
</header>
<nav class="tools">
<section class="tool flags">
<span class="btn mdi mdi-folder-outline"/>
<div class="tool-content">
<ul>
<li v-if="flagcolls" v-for="coll in flagcolls" :key="coll.id">
<span
class="flag mdi"
:class="[
flagIsLoading(coll.id) ? 'mdi-loading mdi-spin' : flagIsActive(coll.id) ? 'mdi-close isActive' : 'mdi-plus'
]"
:collid="coll.id"
@click.prevent="onFlagActionCard"
>
{{ coll.name }}
</span>
</li>
</ul>
</div>
</section>
</nav>
<section class="images" v-switcher>
<figure
v-for="(img, index) in item.images"
@ -23,15 +44,22 @@
</template>
<script>
import { mapState, mapActions } from 'vuex'
export default {
name: "Card",
props: ['item'],
data() {
return {
blanksrc:`${drupalSettings.path.themePath}/assets/img/blank.gif`
blanksrc:`${drupalSettings.path.themePath}/assets/img/blank.gif`,
loadingFlag: false
}
},
computed: {
...mapState({
flagcolls: state => state.User.flagcolls
})
},
directives: {
lazy: {
bind(img,binding){
@ -79,6 +107,45 @@ export default {
img.classList.remove('lazy')
})
}, {once : true})
},
methods: {
...mapActions({
flag: 'User/flag',
unFlag: 'User/unFlag'
}),
flagIsActive(collid) {
// console.log(this.item.uuid);
// console.log(this.flagcolls[collid].items_uuids);
return this.flagcolls[collid].items_uuids.indexOf(this.item.uuid) !== -1;
},
flagIsLoading(collid) {
// console.log(this.item.uuid);
// console.log(this.flagcolls[collid].items_uuids);
return collid === this.loadingFlag;
},
onFlagActionCard (e) {
console.log("Card onFlagActionCard", isActive, e);
if (!this.loadingFlag) {
let collid = e.target.getAttribute('collid');
let isActive = this.flagIsActive(collid);
// console.log('collid', collid);
// console.log("this.item", this.item);
this.loadingFlag = collid;
if (isActive) {
this.unFlag({uuid: this.item.uuid, collid: collid})
.then(data => {
console.log("onFlagActionCard then", data);
this.loadingFlag = false;
})
}else{
this.flag({uuid: this.item.uuid, collid: collid})
.then(data => {
console.log("onFlagActionCard then", data);
this.loadingFlag = false;
})
}
}
}
}
}

View File

@ -4,14 +4,14 @@
class="mdi mdi-folder-outline"
>My folders</h2>
<ul>
<li v-if="flags" v-for="flag in flags" :key="flag.id">
<h5>{{ flag.name }}</h5>
<li v-if="flagcolls" v-for="coll in flagcolls" :key="coll.id">
<h5>{{ coll.name }} ({{ coll.items.length }})</h5>
<div class="actions">
<span
class="delete-btn mdi"
:class="flagDeletingClassObj"
:flagid="flag.id"
@click.prevent="onDeleteFlag"
:flagcollid="coll.id"
@click.prevent="onDeleteFlagColl"
/>
</div>
</li>
@ -23,7 +23,7 @@
<span
class="add-btn mdi"
:class="addFlagBtnClassObj"
@click.prevent="onCreateFlag"
@click.prevent="onCreateFlagColl"
/>
</li>
</ul>
@ -43,7 +43,7 @@ export default {
}),
computed: {
...mapState({
flags: state => state.User.flags
flagcolls: state => state.User.flagcolls
}),
addFlagBtnClassObj() {
return {
@ -63,26 +63,26 @@ export default {
},
methods: {
...mapActions({
createFlag: 'User/createFlag',
deleteFlag: 'User/deleteFlag'
createFlagColl: 'User/createFlagColl',
deleteFlagColl: 'User/deleteFlagColl'
}),
onCreateFlag () {
console.log("UserFlags onCreateFlag", this.new_folder_name)
onCreateFlagColl () {
console.log("UserFlags onCreateFlagColl", this.new_folder_name)
this.is_creating_folder = true;
this.createFlag(this.new_folder_name)
this.createFlagColl(this.new_folder_name)
.then(data => {
console.log("onCreateFlag then", data);
console.log("onCreateFlagColl then", data);
this.new_folder_name = "";
this.is_creating_folder = false;
})
},
onDeleteFlag (e) {
let flagid = e.target.getAttribute('flagid');
console.log("UserFlags onDeleteFlag", flagid);
this.is_deleting_folder = flagid;
this.deleteFlag(flagid)
onDeleteFlagColl (e) {
let flagcollid = e.target.getAttribute('flagcollid');
console.log("UserFlags onDeleteFlagColl", flagcollid);
this.is_deleting_folder = flagcollid;
this.deleteFlagColl(flagcollid)
.then(() => {
// console.log("onDeleteFlag then", data);
// console.log("onDeleteFlagColl then", data);
this.is_deleting_folder = false;
})
}

View File

@ -103,6 +103,7 @@ export default {
getItems({ dispatch, commit, state }, uuids) {
let params = {
// include: 'images', // no needs to include thanks to consumers_image_styles module
// include: 'drupal_internal__nid',
'filter[uuids-groupe][group][conjunction]': 'OR'
};
for (var i = 0; i < uuids.length; i++) {
@ -153,7 +154,7 @@ export default {
// get images included values
let img_src = relations.images.data
console.log('img_src', img_src);
// console.log('img_src', img_src);
// this is a temporary deactivation of images
// img_src = [];
item.images = []

View File

@ -11,15 +11,14 @@ export default {
uid: null,
// username: '',
mail: "",
token: null,
csrftoken: null,
csrf_token: null,
logout_token: null,
isloggedin: false,
isAdmin: false,
isAdherent: false,
canSearch: false,
roles: [],
flags: false
flagcolls: false
},
// getters
@ -28,13 +27,14 @@ export default {
// mutations
mutations: {
SetCsrftoken(state, token) {
state.csrftoken = token;
console.log('SetCsrftoken', token);
state.csrf_token = token;
},
setToken(state, data) {
state.uid = data.current_user.uid;
// state.username = data.username;
state.mail = data.current_user.mail;
state.token = data.csrf_token;
state.csrf_token = data.csrf_token;
state.isloggedin = true;
state.logout_token = data.logout_token;
},
@ -71,7 +71,7 @@ export default {
console.log("setLoggedOut state", state);
state.uid = null;
state.mail = "";
state.token = null;
state.csrf_token = null;
state.isloggedin = false;
state.logout_token = null;
if (state.isAdmin) {
@ -81,9 +81,9 @@ export default {
state.asAdmin = false;
state.canSearch = false;
},
setFlags(state, flags) {
console.log("User setFlags", flags);
state.flags = flags;
setFlagColls(state, flagcolls) {
console.log("User setFlagColls", flagcolls);
state.flagcolls = flagcolls;
}
},
@ -134,10 +134,15 @@ export default {
});
},
getUser({ dispatch, commit, state }) {
return new Promise((resolve, reject) => {
REST.get("/session/token").then(({ data }) => {
console.log('csrftoken', data);
commit("SetCsrftoken", data);
console.log('state.csrf_token', state.csrf_token);
const params = {
token: state.token
token: state.csrf_token
};
return REST.get(`/user/${state.uid}?_format=json`, params)
REST.get(`/user/${state.uid}?_format=json`, params)
.then(({ data }) => {
console.log("user REST getUser data", data);
console.log("roles", data.roles);
@ -145,14 +150,17 @@ export default {
if (data.roles) {
commit("setRoles", data.roles);
}
dispatch("getUserFlags");
dispatch("getUserFlagColls");
resolve();
})
.catch(error => {
console.warn("Issue with getUser", error);
Promise.reject(error);
});
});
});
},
getUserFlags({ dispatch, commit, state }) {
getUserFlagColls({ dispatch, commit, state }) {
// flags
// REST.get('/flagging_collection/1?_format=json')
// .then(( data ) => {
@ -162,10 +170,11 @@ export default {
// console.warn('Issue USER TEST FLAG REST', error)
// Promise.reject(error)
// })
return MA.get("materio_flag/user_flagging_collections")
.then(({ data }) => {
console.log("user MA getFlags data", data);
commit("setFlags", data);
commit("setFlagColls", data);
})
.catch(error => {
console.warn("Issue USER MA getFlags", error);
@ -173,17 +182,17 @@ export default {
});
},
// https://drupal.stackexchange.com/questions/248539/cant-get-flagging-api-to-accept-post-request
createFlag({ dispatch, commit, state }, new_flag_name) {
console.log("user createFlag", new_flag_name);
createFlagColl({ dispatch, commit, state }, new_collection_name) {
console.log("user createFlagColl", new_collection_name);
return new Promise((resolve, reject) => {
const params = {
name: new_flag_name
name: new_collection_name
};
MA.post("materio_flag/create_user_flagging_collection", params)
.then(({ data }) => {
console.log("user MA createFlag data", data);
console.log("user MA createFlagColl data", data);
if (data.status) {
dispatch('getUserFlags').then(() => {
dispatch('getUserFlagColls').then(() => {
resolve();
})
}
@ -194,16 +203,16 @@ export default {
});
});
},
deleteFlag({ dispatch, commit, state }, flagid) {
console.log("user deleteFlag", flagid);
deleteFlagColl({ dispatch, commit, state }, flagcollid) {
console.log("user deleteFlagColl", flagcollid);
return new Promise((resolve, reject) => {
const params = {
flagid: flagid
flagcollid: flagcollid
};
MA.post("materio_flag/delete_user_flagging_collection", params)
.then(({ data }) => {
console.log("user MA deleteFlag data", data);
dispatch('getUserFlags').then(() =>{
console.log("user MA deleteFlagColl data", data);
dispatch('getUserFlagColls').then(() =>{
resolve();
});
})
@ -213,9 +222,43 @@ export default {
});
});
},
flag({ dispatch, commit, state }, args) {
console.log("user flag", args.uuid, args.collid);
const params = {
flagid: state.flagcolls[args.collid].flag_id,
uuid: args.uuid,
flagcollid: args.collid
};
return MA.post(`materio_flag/flag`, params)
.then(({ data }) => {
console.log("user MA flag", data);
dispatch('getUserFlagColls')
})
.catch(error => {
console.warn("Issue USER MA flag", error);
});
},
unFlag({ dispatch, commit, state }, args) {
console.log("user unFlag", args.uuid, args.collid);
const params = {
flagid: state.flagcolls[args.collid].flag_id,
uuid: args.uuid,
flagcollid: args.collid
};
return MA.post(`materio_flag/unflag`, params)
.then(({ data }) => {
console.log("user MA unFlag", data);
dispatch('getUserFlagColls')
})
.catch(error => {
console.warn("Issue USER MA unFlag", error);
});
},
userLogout({ commit, state }) {
const credentials = qs.stringify({
token: state.token
token: state.csrf_token
});
REST.post("/user/logout", credentials)
.then(resp => {