Skip to content

Commit 87407eb

Browse files
fixed front tests
1 parent 0810042 commit 87407eb

File tree

6 files changed

+42
-18
lines changed

6 files changed

+42
-18
lines changed

backend/domain/ports/user_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def add_project_user(self, project_name: str, email: str, role: ProjectRole) ->
1919
pass
2020

2121
@abstractmethod
22-
def get_all_users(self) -> list[str]:
22+
def get_all_users(self) -> list[dict]:
2323
pass
2424

2525
@abstractmethod

backend/infrastructure/user_psql_db_adapter.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,12 @@ def get_users_role_for_project(self, email, project_name):
229229
connection.close()
230230
return role
231231

232-
def get_all_users(self) -> list[str]:
232+
def get_all_users(self) -> list[dict]:
233233
connection = self._get_connection()
234234
try:
235235
cursor = connection.cursor()
236-
cursor.execute("SELECT email FROM users")
237-
users = cursor.fetchall()
238-
users = [user[0] for user in users]
236+
cursor.execute("SELECT email, role FROM users ORDER BY email")
237+
users = [{"email": row[0], "role": row[1]} for row in cursor.fetchall()]
239238
finally:
240239
connection.close()
241240
return users

frontend/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@
5151
<span class="nav-kbd">⌘K</span>
5252
</a>
5353
</div>
54+
<div class="nav-group" id="admin-nav-group" style="display:none">
55+
<span class="nav-group-label">ADMIN</span>
56+
<a class="nav-item" data-route="admin" href="#admin">
57+
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
58+
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
59+
<circle cx="9" cy="7" r="4"/>
60+
<path d="M23 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/>
61+
</svg>
62+
Users
63+
</a>
64+
</div>
5465
</nav>
5566

5667
<div class="sidebar-footer">
@@ -102,6 +113,7 @@
102113
<script src="js/pages/project-detail.js"></script>
103114
<script src="js/pages/governance.js"></script>
104115
<script src="js/pages/search.js"></script>
116+
<script src="js/pages/admin.js"></script>
105117
<script src="js/app.js"></script>
106118
</body>
107119
</html>

frontend/js/api.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ const API = (() => {
6666
// ── Users ─────────────────────────────────────────────────
6767
users: {
6868
getAll: () => get('/users/get_all').then(r => r.users ?? r),
69-
create: (email, password) =>
70-
post(`/users/add?email=${enc(email)}&password=${enc(password)}&role=SIMPLE_USER`),
69+
create: (email, password, role = 'SIMPLE_USER') =>
70+
post(`/users/add?email=${enc(email)}&password=${enc(password)}&role=${enc(role)}`),
7171
},
7272

7373
// ── Projects ──────────────────────────────────────────────

frontend/js/app.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ const App = (() => {
7474
SearchPage.render(container, currentParams);
7575
break;
7676

77+
case 'admin':
78+
showSidebar();
79+
updateNavActive('admin');
80+
AdminPage.render(container);
81+
break;
82+
7783
default:
7884
if (Auth.isLoggedIn()) {
7985
navigateTo('projects');
@@ -106,6 +112,10 @@ const App = (() => {
106112
const emailEl = document.getElementById('user-email');
107113
if (avatarEl) avatarEl.textContent = avatarChar;
108114
if (emailEl) emailEl.textContent = email;
115+
116+
// Show admin nav group only for ADMIN users
117+
const adminGroup = document.getElementById('admin-nav-group');
118+
if (adminGroup) adminGroup.style.display = user.role === 'ADMIN' ? '' : 'none';
109119
}
110120
}
111121

frontend/js/pages/project-detail.js

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -233,19 +233,21 @@ const ProjectDetailPage = (() => {
233233
}
234234
area.dataset.open = 'true';
235235

236+
// Try to load the user list for autocomplete (admin only).
237+
// Always fall back to a plain text input so non-admins can still add users.
236238
let allUsers = [];
237239
try { allUsers = await API.users.getAll(); } catch {}
238240

239-
const userOptions = allUsers.map(u => {
240-
const email = u.email || u.Email || u;
241-
return `<option value="${escHtml(email)}">${escHtml(email)}</option>`;
242-
}).join('');
241+
const hasUserList = allUsers.length > 0;
242+
const emailField = hasUserList
243+
? `<select class="form-select" id="add-user-email" style="flex:2">
244+
${allUsers.map(u => { const e = u.email || u; return `<option value="${escHtml(e)}">${escHtml(e)}</option>`; }).join('')}
245+
</select>`
246+
: `<input class="form-input" id="add-user-email" type="email" placeholder="user@example.com" style="flex:2" autocomplete="off">`;
243247

244248
area.innerHTML = `
245-
<div class="row-form">
246-
<select class="form-select" id="add-user-select" style="flex:2">
247-
${userOptions || '<option value="">No users available</option>'}
248-
</select>
249+
<div class="row-form" style="padding:10px 20px;border-bottom:1px solid var(--border-0)">
250+
${emailField}
249251
<select class="form-select" id="add-user-role" style="flex:1">
250252
${ROLES.map(r => `<option value="${r}">${r}</option>`).join('')}
251253
</select>
@@ -259,9 +261,10 @@ const ProjectDetailPage = (() => {
259261
});
260262

261263
document.getElementById('add-user-submit').addEventListener('click', async () => {
262-
const email = document.getElementById('add-user-select').value;
263-
const role = document.getElementById('add-user-role').value;
264-
if (!email) return;
264+
const emailEl = document.getElementById('add-user-email');
265+
const email = (emailEl.value || '').trim();
266+
const role = document.getElementById('add-user-role').value;
267+
if (!email) { Toast.error('Please enter a user email.'); return; }
265268
try {
266269
await API.projects.addUser(projectName, email, role);
267270
Toast.success(`${email} added as ${role}.`);

0 commit comments

Comments
 (0)