wip5 - Users room re-arrangement + config fix
[+] Added the Drag'n'Drop mechanism in the wizard page, allowing to move orders between rooms, plus a 'placeholder' space to temporarily keep orders to move others [minor fix] Item category maps might be filled twice with the same IDs
This commit is contained in:
parent
13e5217601
commit
41373dfcfa
11
admin.py
11
admin.py
|
@ -108,8 +108,8 @@ async def room_wizard(request, order:Order):
|
|||
await clear_cache(request, order)
|
||||
|
||||
#Separate orders which have incomplete rooms and which have no rooms
|
||||
orders = request.app.ctx.om.cache.items()
|
||||
orders = {key:value for key,value in sorted(orders, key=lambda x: x[1].ans('fursona_name')) if value.status not in ['c', 'e'] and not value.room_confirmed}
|
||||
all_orders = {key:value for key,value in sorted(request.app.ctx.om.cache.items(), key=lambda x: len(x[1].room_members), reverse=True) if value.status not in ['c', 'e']}
|
||||
orders = {key:value for key,value in sorted(all_orders.items(), key=lambda x: x[1].ans('fursona_name')) if not value.room_confirmed}
|
||||
# Orders with incomplete rooms
|
||||
incomplete_orders = {key:value for key,value in orders.items() if value.code == value.room_id and (value.room_person_no - len(value.room_members)) > 0}
|
||||
# Roomless furs
|
||||
|
@ -124,6 +124,7 @@ async def room_wizard(request, order:Order):
|
|||
'B':{
|
||||
'type': 'new',
|
||||
'room_type': 5,
|
||||
'room_name': 'generated 1',
|
||||
'to_add': ['B', 'a', 'c']
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +155,8 @@ async def room_wizard(request, order:Order):
|
|||
'type': 'add_existing',
|
||||
'to_add': to_add
|
||||
}
|
||||
|
||||
generated_counter = 0
|
||||
# Create additional rooms
|
||||
while len(roomless_orders.items()) > 0:
|
||||
room = list(roomless_orders.items())[0][1]
|
||||
|
@ -174,14 +177,16 @@ async def room_wizard(request, order:Order):
|
|||
code_to_add = list(compatible_roomates.keys())[0]
|
||||
to_add.append(code_to_add)
|
||||
del roomless_orders[code_to_add]
|
||||
generated_counter += 1
|
||||
result_map[room.code] = {
|
||||
'type': 'new',
|
||||
'room_name': f'Generated Room {generated_counter}',
|
||||
'room_type': room.bed_in_room,
|
||||
'to_add': to_add
|
||||
}
|
||||
|
||||
tpl = request.app.ctx.tpl.get_template('wizard.html')
|
||||
return html(tpl.render(order=order, orders=orders, data=result_map))
|
||||
return html(tpl.render(order=order, all_orders=all_orders, unconfirmed_orders=orders, data=result_map))
|
||||
|
||||
@bp.get('/propic/remind')
|
||||
async def propic_remind_missing(request, order:Order):
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
function initObjects (){
|
||||
draggables = document.querySelectorAll("div.grid.people div.edit-drag");
|
||||
rooms = document.querySelectorAll("main.container>div.room");
|
||||
Array.from(draggables).forEach(element => {
|
||||
element.addEventListener('dragstart', dragStart);
|
||||
element.addEventListener('dragend', dragEnd);
|
||||
});
|
||||
Array.from(rooms).forEach(room => {
|
||||
room.addEventListener('dragenter', dragEnter)
|
||||
room.addEventListener('dragover', dragOver);
|
||||
room.addEventListener('dragleave', dragLeave);
|
||||
room.addEventListener('drop', drop);
|
||||
});
|
||||
}
|
||||
|
||||
function dragStart(e) {
|
||||
element = e.target;
|
||||
room = element.closest('div.room')
|
||||
dataToSave = {
|
||||
id: element.id,
|
||||
type: element.getAttribute('room-type'),
|
||||
parentId: room.id
|
||||
}
|
||||
e.dataTransfer.setData('application/json', JSON.stringify(dataToSave));
|
||||
toggleRoomSelection(true);
|
||||
}
|
||||
|
||||
function dragEnd(e) {
|
||||
toggleRoomSelection(false);
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
function dragEnter(e) {
|
||||
e.preventDefault();
|
||||
e.target.classList.add('drag-over');
|
||||
checkDragLocation (decodeData(e), e.target);
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
function dragOver(e) {
|
||||
e.preventDefault();
|
||||
e.target.classList.add('drag-over');
|
||||
checkDragLocation (decodeData(e), e.target);
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DragEvent} e
|
||||
* @returns
|
||||
*/
|
||||
function decodeData (e) {
|
||||
const raw = e.dataTransfer.getData('application/json');
|
||||
console.log(raw);
|
||||
return JSON.parse(raw);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Element} target
|
||||
*/
|
||||
function checkDragLocation (data, target) {
|
||||
let toReturn = true;
|
||||
const isInfinite = target.getAttribute("infinite");
|
||||
const maxSizeReached = target.getAttribute("current-size") >= target.getAttribute("room-size");
|
||||
const roomTypeMismatch = data.type !== target.getAttribute("room-type");
|
||||
if (!isInfinite && (maxSizeReached || roomTypeMismatch)) {
|
||||
target.classList.add('drag-forbidden');
|
||||
toReturn = false;
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
function dragLeave(e) {
|
||||
e.target.classList.remove('drag-over');
|
||||
e.target.classList.remove('drag-forbidden');
|
||||
}
|
||||
|
||||
function drop(e) {
|
||||
e.target.classList.remove('drag-over');
|
||||
toggleRoomSelection(false);
|
||||
if (checkDragLocation(decodeData(e), e.target) === true) {
|
||||
console.log ()
|
||||
const data = decodeData (e);
|
||||
let item = document.getElementById (data.id)
|
||||
let oldParent = document.getElementById (data.parentId)
|
||||
let newParent = e.target;
|
||||
let newParentContainer = newParent.querySelector('div.grid.people')
|
||||
newParentContainer.appendChild (item);
|
||||
oldParent.setAttribute("current-size", parseInt(oldParent.getAttribute("current-size") - 1))
|
||||
newParent.setAttribute("current-size", parseInt(newParent.getAttribute("current-size") + 1))
|
||||
}
|
||||
}
|
||||
|
||||
function toggleRoomSelection(newStatus) {
|
||||
rooms = document.querySelectorAll("main.container>div.room");
|
||||
Array.from(rooms).forEach(room=>{
|
||||
room.classList.toggle('interactless', newStatus);
|
||||
room.classList.remove('drag-over');
|
||||
room.classList.remove('drag-forbidden');
|
||||
})
|
||||
}
|
||||
|
||||
initObjects ();
|
|
@ -0,0 +1,23 @@
|
|||
div.grid.people div.edit-disabled {
|
||||
pointer-events: none;
|
||||
filter: grayscale(1);
|
||||
user-select: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
div.grid.people div.edit-drag>div.propic-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
div.drag-over {
|
||||
border-radius: 1rem;
|
||||
border: 0.2rem dashed white;
|
||||
}
|
||||
|
||||
div.drag-forbidden {
|
||||
border-color: #c92121aa;
|
||||
}
|
||||
|
||||
div.interactless>*{
|
||||
pointer-events: none;
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Admin panel{% endblock %}
|
||||
{% block title %}Room Wizard{% endblock %}
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/res/styles/wizard.css">
|
||||
{% endblock %}
|
||||
{% block main %}
|
||||
<main class="container">
|
||||
<script src="/res/scripts/wizardManager.js"></script>
|
||||
<script src="/res/scripts/wizardManager.js" type="text/javascript" defer="defer"></script>
|
||||
<header>
|
||||
<picture>
|
||||
<source srcset="/res/furizon.png" media="(prefers-color-scheme:dark)">
|
||||
|
@ -10,15 +13,50 @@
|
|||
</picture>
|
||||
</header>
|
||||
<!--order = current order login
|
||||
orders = all non confirmed rooms orders
|
||||
unconfirmed_orders = all non confirmed rooms orders
|
||||
all_orders = all orders
|
||||
data = assigned rooms -->
|
||||
<h2>Review rooms</h2>
|
||||
<hr>
|
||||
{% for room in data.items() %}
|
||||
{%with room_order = orders[room[0]] %}
|
||||
|
||||
{%with room_order = unconfirmed_orders[room[0]] %}
|
||||
<div class="room" id="room-{{room_order.code}}" room-type="{{room_order.bed_in_room}}" room-size="{{len(room[1]['to_add'])}}" current-size="{{len(room[1]['to_add'])}}">
|
||||
<h4 style="margin-top:1em;">
|
||||
<span>{{room_order.room_name if room_order.room_name else room[1]['room_name'] if room[1] and room[1]['room_name'] else ''}}</span>
|
||||
</h4>
|
||||
<div class="grid people" style="padding-bottom:1em;">
|
||||
{% for m in room_order.room_members %}
|
||||
{% if m in all_orders %}
|
||||
{% with person = all_orders[m] %}
|
||||
<div class="edit-disabled" style="margin-bottom: 1em;">
|
||||
{% with current=None, order=person, imgSrc='/res/propic/' + (person.ans('propic') or 'default.png'), effects = false, flag = true %}
|
||||
{% include 'blocks/propic.html' %}
|
||||
{% endwith %}
|
||||
<h5>{{person.ans('fursona_name')}}</h5>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for m in room[1]['to_add'] %}
|
||||
{% if m in unconfirmed_orders %}
|
||||
{% with person = unconfirmed_orders[m] %}
|
||||
<div class="edit-drag" id="{{person.code}}" room-type="{{person.bed_in_room}}" style="margin-bottom: 1em;" draggable="true">
|
||||
{% with current=None, order=person, imgSrc='/res/propic/' + (person.ans('propic') or 'default.png'), effects = false, flag = true %}
|
||||
{% include 'blocks/propic.html' %}
|
||||
{% endwith %}
|
||||
<h5>{{person.ans('fursona_name')}}</h5>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
<div class="room" infinite="true" id="room-infinite" room-size="999999999" current-size="0">
|
||||
<h2>Empty room</h2>
|
||||
<div class="grid people" style="padding-bottom:1em;"></div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{% endblock %}
|
||||
|
|
2
utils.py
2
utils.py
|
@ -84,7 +84,7 @@ async def load_items() -> bool:
|
|||
ROOM_TYPE_NAMES[v['id']] = roomName
|
||||
# Adds itself to the category list
|
||||
categoryName = check_and_get_category ('item', q)
|
||||
if not categoryName: continue
|
||||
if not categoryName or q['id'] in CATEGORIES_LIST_MAP[categoryName]: continue
|
||||
CATEGORIES_LIST_MAP[categoryName].append(q['id'])
|
||||
if (EXTRA_PRINTS):
|
||||
logger.debug(f'Mapped Items: %s', ITEMS_ID_MAP)
|
||||
|
|
Loading…
Reference in New Issue