Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
4f40524
feat(ui): implement personalization for authenticated users
pntech-dev Mar 6, 2026
e9e9251
fix(test): resolve errors in API and UI test suites
pntech-dev Mar 6, 2026
01cbc86
Merge pull request #19 from pntech-dev/feat/user-preferences
pntech-dev Mar 6, 2026
cca0692
feat(ui): add profile window with user information editing capabilities
pntech-dev Mar 13, 2026
f5db9df
feat(ui): implement automatic user department selection
pntech-dev Mar 13, 2026
8541f55
fix(api): resolve issue with 'No department selected' state not saving
pntech-dev Mar 13, 2026
12ac89c
Merge pull request #20 from pntech-dev/feat/user-profile
pntech-dev Mar 13, 2026
6f639cf
docs: update README files to reflect changes in new version
pntech-dev Mar 13, 2026
fc450f5
fix API client handling of empty responses
pntech-dev Mar 14, 2026
f3a3f70
move main window startup loading off UI thread
pntech-dev Mar 14, 2026
60d1d9c
fail auth flows when session storage is unavailable
pntech-dev Mar 14, 2026
b351bf6
disable auto login state on logout
pntech-dev Mar 14, 2026
0224561
preserve visible documents when reload or search fails
pntech-dev Mar 14, 2026
8932a3c
update documentation for recent stability fixes
pntech-dev Mar 14, 2026
c1b37c0
Merge pull request #21 from pntech-dev/bugfix/stability-fixes
pntech-dev Mar 14, 2026
663b44b
Add changelog window for displaying version updates
pntech-dev Mar 14, 2026
d3de673
update changelog notes for what's new window
pntech-dev Mar 14, 2026
2d4ce0f
Merge pull request #22 from pntech-dev/feature/whats-new
pntech-dev Mar 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,36 +28,37 @@ Displays the hierarchy of Departments and Categories. Features a document table

### Document Editor:

Allows authorized users to create, edit, and manage document pages. Supports drag-and-drop reordering.
Allows authorized users to create, edit, and manage document pages. Support for adding and working with electronic document files. Supports drag-and-drop reordering.

![editor_window](screenshots/document_editor.png)
![editor_window_files](screenshots/document_editor_files.png)

---

## 💡 What's New (v1.1.0) - Tags & Filters
## 💡 What's New (v0.2.0) - Profile & Settings

This update brings powerful new ways to organize and find your documents.
This update focuses on personalization and user experience.

### 🏷️ Tags System
### 👤 Profile Editing

- **Document Tags:** You can now assign tags to documents for better categorization.
- **Auto-generation:** Automatically generate relevant tags based on document content.
- **Search by Tags:** Quickly find documents by clicking on tags or typing `@tagname` in the search bar.
- **Personal Info:** You can now edit your user information (First Name, Last Name, Department) directly within the application.
- **Access:** The profile dialog is accessible from the main application menu.

### 🔍 Search Filters
### ⚙️ Settings Persistence

A new search filter menu has been added to refine your search results:

- **Search Targets:** Option to include or exclude document pages from search results.
- **Search Fields:** Filter by Name or Code.
- **Match Mode:** Toggle exact match for precise queries.
- **Personalization:** The application now remembers your preferences on a per-user basis.
- **Theme:** Your selected theme (Light/Dark) is saved between sessions.
- **Filters:** Your most recently used search filters are also saved, speeding up repeated searches.

### ⚡ Also in this update

- **"All Documents" Category:** Option to create a virtual category that aggregates all documents within a department.
- **Guest Visibility:** Granular control over the visibility of departments and categories for guest users.
- **Password Hints:** New interactive password strength hint widget during registration and password change.
- **UI Improvements:** Minor visual enhancements and bug fixes.
- Added a dedicated "What's New" changelog window that opens after updates and shows version changes.
- Minor UI improvements and bug fixes for a more stable experience.
- Improved session stability after idle time: document lists and search results no longer disappear if a reload or search request fails.
- Main window startup loading was moved off the UI thread to reduce freezes during the initial data fetch.
- Authentication flows now fail safely if the system keyring or session storage is unavailable.
- API client now correctly handles empty successful responses such as `204 No Content`.
- Logging out now explicitly disables auto-login for the current profile.

---

Expand Down
35 changes: 18 additions & 17 deletions README_RU.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,36 +28,37 @@

### Редактор документов

Позволяет авторизованным пользователям создавать, редактировать и управлять страницами документа. Поддержка Drag-and-Drop.
Позволяет авторизованным пользователям создавать, редактировать и управлять страницами документа. Поддержка добавления и работы с электронными файлами документа. Поддержка Drag-and-Drop.

![editor_window](screenshots/document_editor.png)
![editor_window_files](screenshots/document_editor_files.png)

---

## 💡 Что нового (v1.1.0) - Теги и Фильтры
## 💡 Что нового (v0.2.0) - Профиль и Настройки

Это обновление добавляет мощные инструменты для организации и поиска документов.
Это обновление добавляет персонализацию и удобство использования.

### 🏷️ Система тегов
### 👤 Редактирование профиля

- **Теги документов:** Теперь можно присваивать теги документам для лучшей категоризации.
- **Автогенерация:** Возможность автоматической генерации тегов на основе содержимого документа.
- **Поиск по тегам:** Быстрый поиск документов по клику на тег или при вводе `@тег` в строку поиска.
- **Персональные данные:** Теперь вы можете изменять свои данные (Имя, Фамилия, Отдел) прямо в приложении.
- **Доступ:** Диалог профиля доступен из главного меню приложения.

### 🔍 Фильтры поиска
### ⚙️ Сохранение настроек

Добавлено меню фильтров для уточнения результатов поиска:

- **Объекты поиска:** Возможность включить или исключить страницы документов из поиска.
- **Поля поиска:** Фильтрация по Наименованию или Коду.
- **Режим совпадения:** Опция точного совпадения для конкретных запросов.
- **Персонализация:** Приложение теперь запоминает ваши предпочтения для каждого пользователя.
- **Тема:** Выбранная тема (светлая/тёмная) сохраняется между сессиями.
- **Фильтры:** Последние использованные фильтры поиска также сохраняются, ускоряя повторный поиск.

### ⚡ Также в этом обновлении

- **Категория "Все документы":** Возможность создания виртуальной категории, объединяющей все документы отдела.
- **Видимость для гостей:** Настройка видимости отделов и категорий для пользователей в гостевом режиме.
- **Подсказки пароля:** Новый интерактивный виджет с требованиями к паролю при регистрации и смене пароля.
- **Улучшения UI:** Небольшие визуальные улучшения и исправления ошибок.
- Добавлено отдельное окно "Что нового", которое открывается после обновления и показывает список изменений версии.
- Улучшения интерфейса и исправления ошибок для более стабильной работы.
- Улучшена стабильность сессии после простоя: список документов и результаты поиска больше не исчезают, если запрос обновления или поиска завершился ошибкой.
- Начальная загрузка главного окна перенесена из UI-потока в фоновый, чтобы уменьшить подвисания при первом получении данных.
- Сценарии авторизации теперь корректно завершаются ошибкой, если системное хранилище ключей или сессии недоступно.
- API-клиент теперь корректно обрабатывает успешные пустые ответы, например `204 No Content`.
- При выходе из аккаунта теперь явно отключается auto-login для текущего профиля.

---

Expand Down
26 changes: 24 additions & 2 deletions api/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ def verify(self, token: str) -> dict:
dict: The JSON response from the API containing user data.
"""
headers = {"Authorization": f"Bearer {token}"}
return self._request("GET",
res = self._request("GET",
url=self.base_url + "/auth/user",
headers=headers
)
return res


def get_user_data(self, token: str) -> dict:
Expand All @@ -44,6 +45,25 @@ def get_user_data(self, token: str) -> dict:
dict: The JSON response containing user data.
"""
return self.verify(token)


def update_user_data(self, token: str, user_id: int, data: dict) -> dict:
"""Updates user data.

Args:
token (str): The access token.
user_id (int): The ID of the user to update.
data (dict): The user data to update.

Returns:
dict: The JSON response from the API containing user data.
"""
headers = {"Authorization": f"Bearer {token}"}
return self._request("PATCH",
url=self.base_url + f"/auth/user/{user_id}",
headers=headers,
json=data
)


# === Login ===
Expand Down Expand Up @@ -517,4 +537,6 @@ def _request(self, method: str, url: str, timeout: int = 10, **kwargs) -> dict:
"""Generic method for making API requests."""
request = self.session.request(method, url, timeout=timeout, **kwargs)
request.raise_for_status()
return request.json()
if request.status_code == 204 or not request.content:
return {}
return request.json()
63 changes: 56 additions & 7 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@
from utils.app_paths import get_local_data_dir
from core.updater import UpdateManager
from utils.file_utils import load_config
from utils.settings_manager import SettingsManager
from utils.whats_new_modal import WhatsNewDialog


os.environ.setdefault("QT_ENABLE_HIGHDPI_SCALING", "1")
os.environ.setdefault("QT_AUTO_SCREEN_SCALE_FACTOR", "1")
os.environ.setdefault("QT_SCALE_FACTOR_ROUNDING_POLICY", "PassThrough")


APP_VERSION = "0.1.1"
APP_VERSION = "0.2.0"

class Application:
"""
Expand All @@ -49,6 +51,8 @@ def __init__(self):

self.main_window = None
self.auth_window = None
self.settings_manager = None
self.current_user_id = None

# Setup logging
log_dir = get_local_data_dir()
Expand All @@ -70,7 +74,7 @@ def __init__(self):
self.logger = logging.getLogger("App")

# Set theme
self.theme_manager = ThemeManagerInstance()
self.theme_manager = ThemeManagerInstance
self.theme_manager.switch_theme(theme=1)

# Check for updates
Expand All @@ -84,6 +88,22 @@ def __init__(self):
# NotificationService is initialized in AuthWindow
self.show_auth_window()

def init_user_services(self, user_id: int):
"""Initializes user-specific services like SettingsManager."""
if not user_id or user_id == -1:
self.logger.warning("Cannot initialize user services: invalid user_id.")
# For guests or invalid IDs, we proceed without personalization.
self.theme_manager.switch_theme(theme=1) # Default to dark theme
return

self.current_user_id = user_id
self.settings_manager = SettingsManager(user_id=self.current_user_id)
self.theme_manager.set_settings_manager(self.settings_manager)

# Apply theme from settings
theme_id = self.settings_manager.get_setting("theme", 1) # Default to dark
self.theme_manager.switch_theme(theme=theme_id)

def check_for_updates(self):
"""Checks for updates using the GitHub repository specified in config."""
config = load_config()
Expand All @@ -94,6 +114,12 @@ def check_for_updates(self):

def attempt_auto_login(self):
"""Attempts to automatically log in the user using stored tokens."""
user_id = self.auth_model.get_last_logged_user_id()
if not user_id:
self.show_auth_window()
return

self.current_user_id = user_id
self.worker = APIWorker(self.auth_model.verify_token)
self.worker.finished.connect(self.on_token_verified)
self.worker.error.connect(self.on_token_verification_failed)
Expand All @@ -107,6 +133,8 @@ def on_token_verified(self, data):
Args:
data (dict): The data returned from the verification API.
"""
# Initialize user-specific services (settings, etc.)
self.init_user_services(self.current_user_id)
# Token is valid, show the main window
self.show_main_window(mode="auth")

Expand Down Expand Up @@ -167,14 +195,19 @@ def show_main_window(self, mode: str = "auth"):
mode (str): The mode to open the window in ('auth' or 'guest').
"""
try:
self.main_window = MainWindow(mode=mode)
self.main_window = MainWindow(
mode=mode,
settings_manager=self.settings_manager
)
self.main_window.logout_requested.connect(self.on_logout_requested)
self.main_window.showMaximized()

if self.auth_window:
self.auth_window.close()
self.auth_window = None

self.maybe_show_whats_new(mode=mode)

except Exception as e:
self.logger.critical(f"Error initializing MainWindow: {e}", exc_info=True)
if not self.auth_window:
Expand All @@ -187,16 +220,29 @@ def show_main_window(self, mode: str = "auth"):
message=msg
)

def maybe_show_whats_new(self, mode: str) -> None:
"""Shows the release notes once per app version for authorized users."""
if mode != "auth" or not self.settings_manager or not self.main_window:
return

last_seen_version = self.settings_manager.get_setting("last_seen_whats_new_version", "")
if last_seen_version == APP_VERSION:
return

def on_login_successful(self, mode: str):
dialog = WhatsNewDialog(parent=self.main_window, version=APP_VERSION)
dialog.exec_()
self.settings_manager.set_setting("last_seen_whats_new_version", APP_VERSION)


def on_login_successful(self, mode: str, user_id: int):
"""
Handles successful login event from AuthWindow.

Args:
mode (str): The mode of login ('auth' or 'guest').
user_id (int): The ID of the logged-in user (-1 for guest).
"""
# Guest mode doesn't need verification.
# Auth mode just came from a successful login, so it's already verified.
self.init_user_services(user_id=user_id)
self.show_main_window(mode=mode)


Expand All @@ -205,8 +251,11 @@ def on_logout_requested(self):
if self.main_window:
self.main_window.close()
self.main_window = None
# On logout, clear the stored user data

# On logout, clear the stored user data and settings
self.auth_model.logout()
self.current_user_id = None
self.settings_manager = None
self.show_auth_window()


Expand Down
Loading
Loading