improve(messages): add group management panel (members, rename, add/remove)
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
When viewing a group conversation, a settings button appears in the chat header. Clicking it opens a panel to: rename the group (owner only), view members with roles, remove members (owner only), and add new members via search. Uses existing API endpoints. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ca75468367
commit
b626e4b76d
@ -1664,3 +1664,153 @@ mark.search-highlight {
|
|||||||
border-radius: var(--conv-radius);
|
border-radius: var(--conv-radius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
* GROUP SETTINGS BUTTON & MANAGEMENT PANEL
|
||||||
|
* ============================================================ */
|
||||||
|
|
||||||
|
.btn-group-settings {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--conv-radius);
|
||||||
|
background: transparent;
|
||||||
|
color: var(--conv-text-secondary);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.15s, color 0.15s;
|
||||||
|
}
|
||||||
|
.btn-group-settings:hover {
|
||||||
|
background: var(--conv-surface-secondary);
|
||||||
|
color: var(--conv-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-panel {
|
||||||
|
background: var(--conv-surface);
|
||||||
|
border-bottom: 1px solid var(--conv-border);
|
||||||
|
max-height: 50vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-panel-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-bottom: 1px solid var(--conv-border);
|
||||||
|
}
|
||||||
|
.group-panel-header h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-panel-body {
|
||||||
|
padding: 12px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-panel-section {
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
.group-panel-section:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.group-panel-section label {
|
||||||
|
display: block;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--conv-text-secondary);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-name-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.group-name-row input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 7px 10px;
|
||||||
|
border: 1px solid var(--conv-border);
|
||||||
|
border-radius: var(--conv-radius);
|
||||||
|
font-size: 13px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.group-name-row input:focus {
|
||||||
|
border-color: var(--conv-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm {
|
||||||
|
padding: 6px 14px !important;
|
||||||
|
font-size: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-members-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-member-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
border-radius: var(--conv-radius);
|
||||||
|
}
|
||||||
|
.group-member-item:hover {
|
||||||
|
background: var(--conv-surface-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-member-info {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
.group-member-name {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.group-member-role {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--conv-text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-member-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-member-action {
|
||||||
|
padding: 3px 8px;
|
||||||
|
font-size: 11px;
|
||||||
|
border: 1px solid var(--conv-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--conv-text-secondary);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.15s;
|
||||||
|
}
|
||||||
|
.btn-member-action:hover {
|
||||||
|
background: var(--conv-surface-secondary);
|
||||||
|
}
|
||||||
|
.btn-member-action.danger {
|
||||||
|
color: #d32f2f;
|
||||||
|
border-color: #d32f2f;
|
||||||
|
}
|
||||||
|
.btn-member-action.danger:hover {
|
||||||
|
background: #fce4ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#groupAddMemberSearch {
|
||||||
|
width: 100%;
|
||||||
|
padding: 7px 10px;
|
||||||
|
border: 1px solid var(--conv-border);
|
||||||
|
border-radius: var(--conv-radius);
|
||||||
|
font-size: 13px;
|
||||||
|
outline: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
#groupAddMemberSearch:focus {
|
||||||
|
border-color: var(--conv-primary);
|
||||||
|
}
|
||||||
|
|||||||
@ -289,6 +289,7 @@
|
|||||||
var headerName = document.getElementById('headerName');
|
var headerName = document.getElementById('headerName');
|
||||||
if (headerName) headerName.textContent = conv.display_name || conv.name || 'Bez nazwy';
|
if (headerName) headerName.textContent = conv.display_name || conv.name || 'Bez nazwy';
|
||||||
ChatView.updateHeaderAvatar(conv);
|
ChatView.updateHeaderAvatar(conv);
|
||||||
|
GroupManager.updateSettingsButton(conv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load conversation details + messages
|
// Load conversation details + messages
|
||||||
@ -2441,6 +2442,280 @@
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// 10c. GROUP MANAGEMENT PANEL
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
var GroupManager = {
|
||||||
|
_visible: false,
|
||||||
|
_debounceTimer: null,
|
||||||
|
|
||||||
|
init: function () {
|
||||||
|
var settingsBtn = document.getElementById('groupSettingsBtn');
|
||||||
|
var closeBtn = document.getElementById('closeGroupPanel');
|
||||||
|
var saveNameBtn = document.getElementById('saveGroupName');
|
||||||
|
var addSearch = document.getElementById('groupAddMemberSearch');
|
||||||
|
|
||||||
|
if (settingsBtn) {
|
||||||
|
settingsBtn.addEventListener('click', function () {
|
||||||
|
GroupManager.toggle();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (closeBtn) {
|
||||||
|
closeBtn.addEventListener('click', function () {
|
||||||
|
GroupManager.hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (saveNameBtn) {
|
||||||
|
saveNameBtn.addEventListener('click', function () {
|
||||||
|
GroupManager.saveName();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (addSearch) {
|
||||||
|
addSearch.addEventListener('input', function () {
|
||||||
|
clearTimeout(GroupManager._debounceTimer);
|
||||||
|
GroupManager._debounceTimer = setTimeout(function () {
|
||||||
|
GroupManager.searchNewMember(addSearch.value);
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function () {
|
||||||
|
var panel = document.getElementById('groupPanel');
|
||||||
|
if (!panel) return;
|
||||||
|
GroupManager._visible = true;
|
||||||
|
panel.style.display = 'block';
|
||||||
|
GroupManager.loadDetails();
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function () {
|
||||||
|
var panel = document.getElementById('groupPanel');
|
||||||
|
if (!panel) return;
|
||||||
|
GroupManager._visible = false;
|
||||||
|
panel.style.display = 'none';
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle: function () {
|
||||||
|
if (GroupManager._visible) {
|
||||||
|
GroupManager.hide();
|
||||||
|
} else {
|
||||||
|
GroupManager.show();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSettingsButton: function (conv) {
|
||||||
|
var btn = document.getElementById('groupSettingsBtn');
|
||||||
|
if (!btn) return;
|
||||||
|
btn.style.display = conv && conv.is_group ? '' : 'none';
|
||||||
|
// Hide panel when switching conversations
|
||||||
|
GroupManager.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
loadDetails: async function () {
|
||||||
|
var convId = state.currentConversation;
|
||||||
|
if (!convId) return;
|
||||||
|
|
||||||
|
var details = state.conversationDetails[convId];
|
||||||
|
if (!details) {
|
||||||
|
try {
|
||||||
|
details = await api('/api/conversations/' + convId);
|
||||||
|
state.conversationDetails[convId] = details;
|
||||||
|
} catch (e) { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name
|
||||||
|
var nameInput = document.getElementById('groupEditName');
|
||||||
|
if (nameInput) nameInput.value = details.name || '';
|
||||||
|
|
||||||
|
// Owner check
|
||||||
|
var isOwner = details.members.some(function (m) {
|
||||||
|
return m.user_id === window.__CURRENT_USER__.id && m.role === 'owner';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save name — show only for owner
|
||||||
|
var saveBtn = document.getElementById('saveGroupName');
|
||||||
|
if (saveBtn) saveBtn.style.display = isOwner ? '' : 'none';
|
||||||
|
if (nameInput) nameInput.readOnly = !isOwner;
|
||||||
|
|
||||||
|
// Add member section — owner only
|
||||||
|
var addSection = document.getElementById('groupAddMemberSection');
|
||||||
|
if (addSection) addSection.style.display = isOwner ? '' : 'none';
|
||||||
|
|
||||||
|
// Members list
|
||||||
|
var countEl = document.getElementById('groupMemberCount');
|
||||||
|
if (countEl) countEl.textContent = details.members.length;
|
||||||
|
|
||||||
|
var listEl = document.getElementById('groupMembersList');
|
||||||
|
if (!listEl) return;
|
||||||
|
listEl.innerHTML = '';
|
||||||
|
|
||||||
|
details.members.forEach(function (m) {
|
||||||
|
var item = el('div', 'group-member-item');
|
||||||
|
|
||||||
|
var avatar = el('div', 'conv-avatar ' + avatarColor(m.name));
|
||||||
|
avatar.style.width = '30px';
|
||||||
|
avatar.style.height = '30px';
|
||||||
|
avatar.style.minWidth = '30px';
|
||||||
|
avatar.style.fontSize = '11px';
|
||||||
|
avatar.textContent = initials(m.name);
|
||||||
|
|
||||||
|
var info = el('div', 'group-member-info');
|
||||||
|
var nameEl = el('div', 'group-member-name', m.name);
|
||||||
|
info.appendChild(nameEl);
|
||||||
|
if (m.role === 'owner') {
|
||||||
|
var roleEl = el('span', 'group-member-role', ' (właściciel)');
|
||||||
|
nameEl.appendChild(roleEl);
|
||||||
|
}
|
||||||
|
if (m.company_name) {
|
||||||
|
var companyEl = el('div', 'group-member-role', m.company_name);
|
||||||
|
info.appendChild(companyEl);
|
||||||
|
}
|
||||||
|
|
||||||
|
item.appendChild(avatar);
|
||||||
|
item.appendChild(info);
|
||||||
|
|
||||||
|
// Actions (owner can remove others, anyone can see)
|
||||||
|
if (isOwner && m.user_id !== window.__CURRENT_USER__.id) {
|
||||||
|
var actions = el('div', 'group-member-actions');
|
||||||
|
var removeBtn = el('button', 'btn-member-action danger', 'Usuń');
|
||||||
|
removeBtn.addEventListener('click', function () {
|
||||||
|
GroupManager.removeMember(convId, m.user_id, m.name);
|
||||||
|
});
|
||||||
|
actions.appendChild(removeBtn);
|
||||||
|
item.appendChild(actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
listEl.appendChild(item);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
saveName: async function () {
|
||||||
|
var convId = state.currentConversation;
|
||||||
|
var nameInput = document.getElementById('groupEditName');
|
||||||
|
if (!convId || !nameInput) return;
|
||||||
|
|
||||||
|
var newName = nameInput.value.trim();
|
||||||
|
if (!newName) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await api('/api/conversations/' + convId, 'PATCH', { name: newName });
|
||||||
|
// Update local state
|
||||||
|
var conv = state.conversations.find(function (c) { return c.id === convId; });
|
||||||
|
if (conv) {
|
||||||
|
conv.name = newName;
|
||||||
|
conv.display_name = newName;
|
||||||
|
}
|
||||||
|
if (state.conversationDetails[convId]) {
|
||||||
|
state.conversationDetails[convId].name = newName;
|
||||||
|
}
|
||||||
|
ConversationList.renderList();
|
||||||
|
var headerName = document.getElementById('headerName');
|
||||||
|
if (headerName) headerName.textContent = newName;
|
||||||
|
} catch (e) {
|
||||||
|
alert('Nie udało się zmienić nazwy: ' + e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
removeMember: async function (convId, userId, userName) {
|
||||||
|
if (!confirm('Czy na pewno chcesz usunąć ' + userName + ' z grupy?')) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await api('/api/conversations/' + convId + '/members/' + userId, 'DELETE');
|
||||||
|
// Refresh details
|
||||||
|
delete state.conversationDetails[convId];
|
||||||
|
GroupManager.loadDetails();
|
||||||
|
// Update subtitle
|
||||||
|
ChatView.loadConversationDetails(convId);
|
||||||
|
} catch (e) {
|
||||||
|
alert('Nie udało się usunąć członka: ' + e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
searchNewMember: async function (query) {
|
||||||
|
var suggestions = document.getElementById('groupAddMemberSuggestions');
|
||||||
|
if (!suggestions) return;
|
||||||
|
suggestions.innerHTML = '';
|
||||||
|
|
||||||
|
query = (query || '').trim();
|
||||||
|
if (query.length < 2) return;
|
||||||
|
|
||||||
|
var convId = state.currentConversation;
|
||||||
|
var details = state.conversationDetails[convId];
|
||||||
|
var existingIds = details ? details.members.map(function (m) { return m.user_id; }) : [];
|
||||||
|
|
||||||
|
suggestions.innerHTML = '<div style="padding:8px 12px;color:var(--conv-text-muted);font-size:13px">Szukam...</div>';
|
||||||
|
|
||||||
|
try {
|
||||||
|
var resp = await fetch('/api/users/search?q=' + encodeURIComponent(query), {
|
||||||
|
headers: { 'X-CSRFToken': window.__CSRF_TOKEN__ },
|
||||||
|
});
|
||||||
|
if (!resp.ok) throw new Error('search failed');
|
||||||
|
var users = await resp.json();
|
||||||
|
|
||||||
|
suggestions.innerHTML = '';
|
||||||
|
var matches = users.filter(function (u) {
|
||||||
|
return existingIds.indexOf(u.id) === -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!matches.length) {
|
||||||
|
suggestions.innerHTML = '<div style="padding:8px 12px;color:var(--conv-text-muted);font-size:13px">Brak wyników</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
matches.forEach(function (u) {
|
||||||
|
var item = el('div', 'suggestion-item');
|
||||||
|
item.style.padding = '8px 12px';
|
||||||
|
item.style.cursor = 'pointer';
|
||||||
|
item.style.display = 'flex';
|
||||||
|
item.style.alignItems = 'center';
|
||||||
|
item.style.gap = '8px';
|
||||||
|
item.style.borderBottom = '1px solid var(--conv-border)';
|
||||||
|
|
||||||
|
var avatar = el('div', 'conv-avatar ' + avatarColor(u.name));
|
||||||
|
avatar.style.width = '28px';
|
||||||
|
avatar.style.height = '28px';
|
||||||
|
avatar.style.minWidth = '28px';
|
||||||
|
avatar.style.fontSize = '10px';
|
||||||
|
avatar.textContent = initials(u.name);
|
||||||
|
|
||||||
|
var nameEl = el('div', '', u.name || u.email);
|
||||||
|
nameEl.style.fontSize = '13px';
|
||||||
|
|
||||||
|
item.appendChild(avatar);
|
||||||
|
item.appendChild(nameEl);
|
||||||
|
|
||||||
|
item.addEventListener('click', function () {
|
||||||
|
GroupManager.addMember(convId, u.id, u.name);
|
||||||
|
});
|
||||||
|
item.addEventListener('mouseenter', function () { item.style.background = 'var(--conv-surface-secondary)'; });
|
||||||
|
item.addEventListener('mouseleave', function () { item.style.background = ''; });
|
||||||
|
|
||||||
|
suggestions.appendChild(item);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
suggestions.innerHTML = '<div style="padding:8px 12px;color:var(--conv-text-muted);font-size:13px">Błąd wyszukiwania</div>';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addMember: async function (convId, userId, userName) {
|
||||||
|
try {
|
||||||
|
await api('/api/conversations/' + convId + '/members', 'POST', { user_id: userId });
|
||||||
|
// Clear search
|
||||||
|
var search = document.getElementById('groupAddMemberSearch');
|
||||||
|
if (search) search.value = '';
|
||||||
|
var suggestions = document.getElementById('groupAddMemberSuggestions');
|
||||||
|
if (suggestions) suggestions.innerHTML = '';
|
||||||
|
// Refresh
|
||||||
|
delete state.conversationDetails[convId];
|
||||||
|
GroupManager.loadDetails();
|
||||||
|
ChatView.loadConversationDetails(convId);
|
||||||
|
} catch (e) {
|
||||||
|
alert('Nie udało się dodać członka: ' + e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// 11. SEARCH
|
// 11. SEARCH
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@ -2812,6 +3087,7 @@
|
|||||||
Composer.init();
|
Composer.init();
|
||||||
NewMessageModal.init();
|
NewMessageModal.init();
|
||||||
NewGroupModal.init();
|
NewGroupModal.init();
|
||||||
|
GroupManager.init();
|
||||||
Search.init();
|
Search.init();
|
||||||
Pins.init();
|
Pins.init();
|
||||||
initContextMenu();
|
initContextMenu();
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
{% block head_extra %}
|
{% block head_extra %}
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/quill.snow.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/quill.snow.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/conversations.css') }}?v=12">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/conversations.css') }}?v=13">
|
||||||
<script src="{{ url_for('static', filename='js/vendor/quill.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/vendor/quill.js') }}"></script>
|
||||||
<style>
|
<style>
|
||||||
footer { display: none !important; }
|
footer { display: none !important; }
|
||||||
@ -110,6 +110,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="chat-header-actions">
|
<div class="chat-header-actions">
|
||||||
|
<button class="btn-group-settings" id="groupSettingsBtn" style="display:none" title="Zarządzaj grupą">
|
||||||
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
|
||||||
|
<circle cx="9" cy="7" r="4"></circle>
|
||||||
|
<path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
|
||||||
|
<path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -119,6 +127,32 @@
|
|||||||
<button id="togglePins">Pokaż</button>
|
<button id="togglePins">Pokaż</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Group management panel -->
|
||||||
|
<div class="group-panel" id="groupPanel" style="display:none">
|
||||||
|
<div class="group-panel-header">
|
||||||
|
<h3>Zarządzanie grupą</h3>
|
||||||
|
<button class="modal-close" id="closeGroupPanel">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="group-panel-body">
|
||||||
|
<div class="group-panel-section">
|
||||||
|
<label>Nazwa grupy:</label>
|
||||||
|
<div class="group-name-row">
|
||||||
|
<input type="text" id="groupEditName" placeholder="Nazwa grupy...">
|
||||||
|
<button class="btn-primary btn-sm" id="saveGroupName">Zapisz</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="group-panel-section">
|
||||||
|
<label>Członkowie (<span id="groupMemberCount">0</span>):</label>
|
||||||
|
<div id="groupMembersList" class="group-members-list"></div>
|
||||||
|
</div>
|
||||||
|
<div class="group-panel-section" id="groupAddMemberSection">
|
||||||
|
<label>Dodaj członka:</label>
|
||||||
|
<input type="text" id="groupAddMemberSearch" placeholder="Wpisz imię lub nazwisko...">
|
||||||
|
<div class="recipient-suggestions" id="groupAddMemberSuggestions"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Messages area -->
|
<!-- Messages area -->
|
||||||
<div class="chat-messages" id="chatMessages" style="display:none">
|
<div class="chat-messages" id="chatMessages" style="display:none">
|
||||||
<!-- Rendered by JS -->
|
<!-- Rendered by JS -->
|
||||||
@ -292,7 +326,7 @@ window.__CSRF_TOKEN__ = '{{ csrf_token() }}';
|
|||||||
// Load conversations.js after data is set
|
// Load conversations.js after data is set
|
||||||
(function() {
|
(function() {
|
||||||
var s = document.createElement('script');
|
var s = document.createElement('script');
|
||||||
s.src = '{{ url_for("static", filename="js/conversations.js") }}?v=19';
|
s.src = '{{ url_for("static", filename="js/conversations.js") }}?v=20';
|
||||||
document.body.appendChild(s);
|
document.body.appendChild(s);
|
||||||
})();
|
})();
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user