Conversation
Ganapathy-dev
commented
Mar 13, 2026
- Moved Sentinel design separately from Testpress.
- Updated sidebar to highlight the current tab.
- Added a new audit list page.
- Moved Sentinel design separately from testpress - update side bar to show current tab - Add new audit list page
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the TPSentinel module by introducing a new, dedicated audit list page. This change involves restructuring the Sentinel design to operate independently, improving the overall modularity of the application. Additionally, the sidebar navigation has been refined to provide clearer visual feedback on the active section, contributing to a more intuitive user interface. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a new audit list page for TPSentinel, refactors the main index page, and updates the sidebar for better navigation. The changes are a good step forward, but I've identified several issues, including critical security vulnerabilities and bugs in the new audit page functionality. Specifically, there's a hardcoded CSRF token, broken selection logic in the table, and several instances of hardcoded links and non-functional UI elements. Addressing these issues is crucial for the security and functionality of the new page.
| <tr class="hover:bg-gray-50 dark:hover:bg-neutral-700/50"> | ||
| <td class="py-3 ps-4"> | ||
| <div class="flex items-center h-5"> | ||
| <input type="checkbox" class="border-gray-200 rounded-sm text-blue-600 focus:ring-blue-500 dark:bg-neutral-700 dark:border-neutral-500 dark:checked:bg-blue-500 dark:checked:border-blue-500" @change="selectedRows.includes('1') ? selectedRows.splice(selectedRows.indexOf('1'), 1) : selectedRows.push('1')" value="1"> |
There was a problem hiding this comment.
The checkbox for each row has a hardcoded value="1" and the @change handler is also hardcoded to use the value '1'. This will prevent correct selection of multiple items. The value and the handler should use a unique identifier for each audit record, such as audit.id.
<input type="checkbox" class="border-gray-200 rounded-sm text-blue-600 focus:ring-blue-500 dark:bg-neutral-700 dark:border-neutral-500 dark:checked:bg-blue-500 dark:checked:border-blue-500" @change="selectedRows.includes('{{ audit.id }}') ? selectedRows.splice(selectedRows.indexOf('{{ audit.id }}'), 1) : selectedRows.push('{{ audit.id }}')" value="{{ audit.id }}">
|
|
||
|
|
||
| <form method="post" action="#"> | ||
| <input type="hidden" name="csrfmiddlewaretoken" value="ocF0ev8IosDq7dvSCwaz8axDgGis3fdxuM7q74OWS7rtfk0Q0sjjne7Yjfx2MReV"> |
There was a problem hiding this comment.
A CSRF token is hardcoded in this form. This is a critical security vulnerability that could expose the application to Cross-Site Request Forgery (CSRF) attacks. CSRF tokens must be unique per user session and should be dynamically generated by the server.
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
| </span> | ||
| </td> | ||
| <td class="py-3 px-5 whitespace-nowrap"> | ||
| <a class="text-sm text-foreground decoration-2 truncate hover:text-primary hover:underline focus:outline-none focus:text-primary focus:underline dark:text-foreground dark:hover:text-primary dark:focus:text-primary" href="/workspaces/1/">{{ audit.workspace_name }}</a> |
There was a problem hiding this comment.
The link to the workspace is hardcoded to /workspaces/1/. It should be dynamic and use the workspace_id from the audit data to link to the correct workspace.
<a class="text-sm text-foreground decoration-2 truncate hover:text-primary hover:underline focus:outline-none focus:text-primary focus:underline dark:text-foreground dark:hover:text-primary dark:focus:text-primary" href="/workspaces/{{ audit.workspace_id }}/">{{ audit.workspace_name }}</a>
| function createApplyButton(instance, selectedDates) { | ||
| const btn = document.createElement("button"); | ||
| btn.textContent = "Apply"; | ||
| btn.className = | ||
| "py-2 px-3 text-xs rounded-lg border-transparent bg-blue-600 text-white"; | ||
| return btn; | ||
| } |
There was a problem hiding this comment.
The createApplyButton function is not fully implemented. It accepts a selectedDates parameter that is not used. More importantly, the 'Apply' button it creates has no onclick handler, making it non-functional. The button should trigger the filtering logic and close the date picker. You can access the selected dates via instance.selectedDates within the click handler. Remember to also update the call to this function in createFooter to pass only instance.
| function createApplyButton(instance, selectedDates) { | |
| const btn = document.createElement("button"); | |
| btn.textContent = "Apply"; | |
| btn.className = | |
| "py-2 px-3 text-xs rounded-lg border-transparent bg-blue-600 text-white"; | |
| return btn; | |
| } | |
| function createApplyButton(instance) { | |
| const btn = document.createElement("button"); | |
| btn.textContent = "Apply"; | |
| btn.className = | |
| "py-2 px-3 text-xs rounded-lg border-transparent bg-blue-600 text-white"; | |
| btn.onclick = () => { | |
| // TODO: Add logic to apply date range filter using instance.selectedDates | |
| instance.close(); | |
| }; | |
| return btn; | |
| } |
| <!-- End Header --> | ||
| <div> | ||
| <div class="py-4 px-5 flex flex-wrap justify-between items-center gap-y-2 gap-x-5"> | ||
| <div class="w-1/2"> |
There was a problem hiding this comment.
The container for the search input is missing position: relative. This is necessary because the search icon inside it is absolutely positioned. Without a relative parent, the icon will be positioned relative to the nearest positioned ancestor, which could lead to incorrect layout.
| <div class="w-1/2"> | |
| <div class="w-1/2 relative"> |
| <!-- End Search Input --> | ||
| </div> | ||
| <div class="flex justify-end items-center gap-x-2"> | ||
| <div class="p-2 inline-flex items-center text-xs font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-2xs hover:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none focus:outline-hidden focus:bg-gray-50 dark:bg-neutral-800 dark:border-neutral-700 dark:text-neutral-300 dark:hover:bg-neutral-800 dark:focus:bg-neutral-800"> |
There was a problem hiding this comment.
| </button> | ||
| <div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-in duration-75" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-95" class="absolute top-0 left-0 mt-10 w-40 z-10 bg-white rounded-xl shadow-xl dark:bg-neutral-900" role="menu" aria-orientation="vertical" style="display: none;"> | ||
| <div class="p-1"> | ||
| <a href="#"open = false" class="w-full flex items-center gap-x-3 py-1.5 px-2 rounded-lg text-[13px] font-normal text-gray-800 hover:bg-gray-100 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-300 focus:outline-hidden focus:bg-gray-100 dark:hover:bg-neutral-800 dark:focus:bg-neutral-800"> |
There was a problem hiding this comment.
There appears to be a syntax error in this anchor tag: href="#"open = false". It seems you intended to use an event handler like @click="open = false" to close the dropdown menu. This error is repeated for all sortable column headers in this file.
| <a href="#"open = false" class="w-full flex items-center gap-x-3 py-1.5 px-2 rounded-lg text-[13px] font-normal text-gray-800 hover:bg-gray-100 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-300 focus:outline-hidden focus:bg-gray-100 dark:hover:bg-neutral-800 dark:focus:bg-neutral-800"> | |
| <a href="#" @click="open = false" class="w-full flex items-center gap-x-3 py-1.5 px-2 rounded-lg text-[13px] font-normal text-gray-800 hover:bg-gray-100 disabled:opacity-50 disabled:pointer-events-none dark:text-neutral-300 focus:outline-hidden focus:bg-gray-100 dark:hover:bg-neutral-800 dark:focus:bg-neutral-800"> |
| <span class="truncate">English</span> | ||
| </button> | ||
| <div x-show="dropdownOpen === 'lang'" x-cloak x-transition x-on:click="$event.stopPropagation()" | ||
| <div x-cloak x-show="dropdownOpen === 'lang'" x-cloak x-transition x-on:click="$event.stopPropagation()" |
There was a problem hiding this comment.
| const enableTime = false | ||
|
|
||
| function formatDateParam(date) { | ||
| const pad = v => String(v).padStart(2, "0"); | ||
| return `${pad(date.getMonth() + 1)}/${pad(date.getDate())}/${date.getFullYear()} ` + | ||
| `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`; | ||
| } |
|