mirror of
https://github.com/ever-co/ever-gauzy.git
synced 2026-10-02 01:54:50 +08:00
develop
100
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6783fa9c21 |
[Feat] Plugins/Integrations routing (#9623)
* feat: redesign and simplify plugin layout and add built-in tab control * refactor(plugins): improve marketplace layout and scrolling Restructure plugin marketplace and plugin detail UI to enhance responsiveness, layout consistency, and scrolling behavior. Key changes include: - Centralize height management across components, shifting from fixed viewport calculations to flexible 100% and flexbox distribution for better adaptability. - Delegate scrolling responsibility to appropriate parent containers (e.g., filter panel, plugin list, plugin detail body) to prevent nested scrollbars and ensure a smoother user experience. - Enhance responsive design for the plugin marketplace grid and plugin detail pages, adapting layouts and element ordering for various screen sizes. - Standardize arrow function syntax in plugin routing modules. * feat(plugins): export new modules and improve no-data-message layout Export `plugin-show-builtin.token`, `plugin-installed-routing.module`, and plugin resolvers from the desktop-ui-lib entry point. This makes them available for use in other parts of the application, supporting upcoming plugin management features. Apply flexbox styling to the time-tracker `no-data-message` component. This ensures the component correctly fills the available vertical space and behaves as expected within its flex container, improving UI consistency. * feat(integrations): implement built-in plugins view Introduce `PluginBuiltinComponent` for built-in integrations. This change unifies the integrations marketplace, providing distinct views for built-in and external integrations under the `/plugins` route. The previous '/integrations/new' route now redirects to this updated plugins section. Simplified IntegrationsComponent by delegating internal tab management to the new web-specific plugin routing module. * feat(i18n): add translations for built-in integrations and paid label Introduce new internationalization strings for the 'Built-in Integrations' section, including title, subtitle, and a desktop notice. Also adds a generic 'Paid' label. These translations support upcoming UI features related to integration management and pricing displays. * refactor(integrations): abstract common filtering logic Extract integration filter state and methods into a new `IntegrationFiltersBase` abstract class. This refactors `PluginBuiltinComponent` and `IntegrationsComponent` to extend the base class, reducing code duplication and improving maintainability. Further improvements include: - Implement `ChangeDetectionStrategy.OnPush` and use `inject()` for modernized component setup. - Adopt `NgOptimizedImage` for optimized image loading in `plugin-builtin.component.html`. - Enhance accessibility by adding `aria-label` to the search input and `type="button"` to the clear filter button. - Improve type safety and data modeling for `IIntegrationGroup` and `IIntegrationGroupTypeOption` in contract and service layers. - Standardize UI theming by migrating various SCSS properties to use CSS variables across integration-related components. - Centralize plugin route selectors into a new `PLUGIN_ROUTE_SELECTORS` constant. |
||
|
|
bde9eda379 |
[Fix] Implement web to desktop installation trigger (#9617)
* feat: add support for Gauzy Protocol in desktop timer packaging * feat: implement protocol handling for deep-link URLs with ProtocolRouter * feat: implement abstract protocol handler and install plugin handler for deep-link actions * feat: implement deep-link protocol handling and instance management * feat: add installation prompts for desktop application in i18n * refactor(plugin-marketplace): extract plugin selection to dedicated effect Moved the logic responsible for selecting a plugin, its version, and source from the getOne$ effect's map operator into a new getOneSuccess$ effect. This change improves the separation of concerns, making effects more granular and easier to test by dispatching a specific success action for further processing. * feat(plugin-deep-link): implement deep link installation for plugins Introduce actions and effects to handle plugin installations triggered by deep links. This enables direct installation via external links. The new `PluginDeepLinkEffects` listens for `deep-link-install-plugin` IPC events from the main process. It supports two main installation flows: - Force install: Directly dispatches `PluginMarketplaceActions.install` after navigating to the marketplace. - Review before install: Navigates the user to the plugin detail page and shows an informational toast, requiring manual confirmation. Includes error handling and fetches plugin details if not present in the store. * feat(plugins-deep-link): add deep link plugin installation Introduces a new service that listens for 'deep-link-install-plugin' Electron events. Upon receiving an event, it dispatches an NgRx action to trigger the installation of a plugin based on the provided payload. This enables external triggers, such as browser deep links, to initiate plugin installations within the desktop application. The service is eagerly initialized via an environment initializer. * feat(desktop-timer): provide plugin initializers Registers the necessary provider to ensure all plugin initialization logic is correctly executed during application bootstrap. This enables plugins to perform essential setup and configuration tasks upon application startup. * refactor(electron): provide ElectronService in root Configure ElectronService to be a singleton provided at the application root. This ensures a single instance across the application and enables tree-shaking for better optimization. * feat(plugin-marketplace): add web-to-desktop plugin installation button Introduces a button on the plugin marketplace detail page for web users. This allows initiating plugin installation in the desktop application via a `gauzy://` deep link. The button appears when not in the desktop app and the plugin is not yet installed, providing a seamless install experience from web to desktop. * feat(plugin-marketplace): add web-to-desktop plugin installation via deep link Introduces a new mechanism for installing desktop plugins directly from the web application using a custom deep link protocol. A `gauzy://install-plugin` deep link is constructed with relevant plugin details and dispatched via a new action. An effect then handles the deep link activation by creating and clicking a hidden `<a>` element. This approach ensures compatibility across browsers which might block direct assignment of non-http(s) schemes to `window.location.href`. The `plugin-marketplace-detail` component now dispatches this new action, delegating the deep link handling logic to the effects layer. * feat(desktop): make deep linking protocol configurable Introduce `PROTOCOL` environment variables for Agent, Desktop, Desktop Timer, Server, and Server API applications. This allows each application to define its custom URI scheme for deep linking through environment configuration. Integrate `ProtocolRouter` to centralize the handling of deep link URLs and ensure correct routing, including proper handling for multiple application instances (single instance lock logic). Update the plugin marketplace to use the dynamically configured protocol when generating plugin installation deep links. Additionally, expose the application protocol and application type flags via `PluginEnvironmentService` for use in UI logic. Desktop application entry points (`index.ts` files) are updated to register the custom protocol and process incoming deep links, including new `InstallPluginHandler` for the desktop app. * feat(plugin-marketplace): implement web-to-desktop installation flow with app selector dialog * feat(env): make app protocols configurable via environment variables Make several application protocols configurable via environment variables rather than being hardcoded. This allows for greater flexibility in deploying and configuring various desktop applications. Specifically, this commit introduces environment variables for the protocols of the Desktop, Desktop Server, Desktop API Server, and Agent applications. The `.scripts/configure.ts` and `packages/ui-config/src/lib/environments/model.ts` files have been updated to define these new protocol variables. The `packages/desktop-ui-lib/src/lib/settings/plugins/component/plugin-marketplace/plugin-marketplace-item/dialog-app-selector/dialog-app-selector.component.ts` component now consumes these environment variables. The `packages/desktop-ui-lib/src/lib/settings/plugins/services/plugin-environment.service.ts` was refactored to remove direct environment variable access, streamlining the environment management. * feat(plugin-installation): plugin installation logic for desktop and marketplace compatibility * feat(plugin-marketplace): installation logic for desktop environment compatibility * feat(plugin-installation): allow reinstallation of previously uninstalled plugins Re-installation of a plugin now reuses an existing PluginInstallation record if one is found, even if it was previously uninstalled. This prevents unique constraint violations and ensures a consistent lifecycle for plugin installations. The `InstallPluginCommandHandler` now: - Finds existing installations without filtering by `status: INSTALLED`. - Reuses and updates the found record by calling `markAsInstalled()`. - Explicitly clears the `uninstalledAt` timestamp in `markAsInstalled()`. Additionally, the uninstallation process has been improved for precision: - The `UninstallPluginCommand` and its handler now accept and use a specific `installationId`. - The `PluginInstallationController`'s DELETE endpoint now requires both `pluginId` and `installationId` in the URL. BREAKING CHANGE: The DELETE /plugins/registry/installation/:installationId endpoint path has changed to /plugins/registry/installation/:pluginId/:installationId. Consumers must update their calls to include the `pluginId` in the URL. * fix(plugin-installation): ensure correct plugin installation status updates The `installed$` observable was sometimes emitting redundant values or reflecting an incorrect installation status due to reliance on only the list of all plugins. This change: - Uses `combineLatest` with `plugin$` to ensure the currently viewed plugin's installation status is also considered for immediate accuracy. - Adds `distinctUntilChanged` to prevent unnecessary emissions when the plugin installation status hasn't actually changed, improving performance and reducing potential side effects. * fix(protocol-router): correct typos in comments and documentation fix(plugin-deep-link): fix typo in plugin marketplace query variable name fix(plugin-deep-link): correct typo in navigation path for plugins * refactor(plugin-marketplace): correct 'Markeplace' typo Correct the spelling of the `pluginMarkeplaceQuery` property to `pluginMarketplaceQuery`. This change updates the property name in the `PluginInstallationQuery` class constructor and all its usages within the class to ensure consistency and correctness. * feat: add new environment variables for desktop and agent application protocols. * feat(build): configure custom protocol handlers across platforms Registers the desktop application's custom protocol (e.g., `desktop-timer://`) with the operating system, allowing the application to be invoked via URLs. This enables deep linking and inter-process communication using custom URL schemes. - macOS: Adds `CFBundleURLTypes` to `Info.plist`. - Linux: Registers `x-scheme-handler` MIME types. - Windows: Configures NSIS installer with `perMachine: true` for handler registration. * feat(protocol): implement protocol registration for various packagers * feat(configure): expose DESKTOP_APP_PROTOCOL env var This change makes the DESKTOP_APP_PROTOCOL environment variable available for the desktop application at runtime. This protocol is used for handling custom URI schemes, enabling features like deep linking or inter-application communication. * feat(configure): add DESKTOP_SERVER_APP_PROTOCOL to environment variables * feat(protocol): register InstallPluginHandler for deep-link actions * feat(agent): enable plugin effects and initializers Integrates the plugin system's effect and initialization mechanisms into the agent application. This ensures that plugins can register side effects and execute necessary setup logic when the agent app starts. * feat(effects): add effects manager provider to bootstrap application * feat(plugin-installation): deep link handling and add user notifications * feat(protocol-router): implement FIFO queue for pending URLs and enhance error handling * fix(protocol-router): improve deep link error handling and reentrancy Enhance the ProtocolRouter to prevent it from stalling due to malformed deep links or concurrent processing. - Discard malformed URLs and URLs without registered handlers immediately in the `route` method. Previously, these could be queued as pending, leading to infinite retries for non-retriable errors. - Implement a reentrancy guard in `processPending` to ensure only a single loop processes the pending queue at a time, preventing race conditions. - When retrying pending URLs, validate them and their handlers, discarding any invalid or unhandled URLs from the queue to prevent it from stalling. - Mark the `_pendingUrls` array as readonly for minor hardening. * feat(plugin-deep-link): add version support for plugin deep links Enable deep links to specify a plugin version using the 'versionId' query parameter, allowing direct linking to a specific plugin release. Improved error handling now displays a toast message if the deep-linked plugin or version cannot be found. The default behavior for deep-link initiated installs is changed to navigate to the review page, preventing silent, forced installations. * feat(cspell): add new words "Dispatchable", "retriable", and "Reentrancy" to spell checker |
||
|
|
69087ed893 |
[Fix] Direct local installation (#9614)
* feat: local plugin installation with Zip Slip prevention and size limits
* feat: allow nullable marketplaceId in completeInstallation for local plugin installations
* feat: update IActivatePluginCommandParams to allow nullable marketplaceId and enhance local activation logic
* feat: local plugin installation handling and state management
* fix: local plugin installation handling with unique identifiers and improved error checks (AI fixes)
* docs: remove obsolete issue references from comments
These references were tied to internal tracking issues that are now resolved
or no longer relevant within the codebase. Removing them cleans up the
comments, making them more concise and up-to-date.
* chore(cspell): add 'Dispatchable' to dictionary
Prevent false positives for a valid term used within the project.
* fix: arbitrary file access during archive extraction ("Zip Slip")
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix: arbitrary file access during archive extraction ("Zip Slip")
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix: stuck loading state when a local install fails validation here (e.g., missing plugin.name), downloadFailed is dispatched without pluginId, and localInstallId is never cleared from the installation store
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* fix: enforce plugin name requirement for local installations in activation command
* fix: update completeInstallation to accept plugin name for local installations
* fix(settings-plugin): ensure local plugin detection is accurate
Previously, a plugin was considered local if it only lacked a marketplace ID. This was
insufficient as plugins with an installation ID (even without a marketplace ID)
may still require server interaction for activation and deactivation.
This update modifies the logic to check for the absence of both marketplaceId
and installationId to correctly identify truly local plugins that can bypass
server calls.
* fix(plugin-installation): clear local install id only on success
The `_localInstallId` tracks the loading state for locally installed
plugins. Previously, it was also cleared within the `catchError`
block. This could lead to incorrect state cleanup if a download
failed or was cancelled by `switchMap` before reaching the success tap.
By only clearing the id within the `tap` operator after successful
completion, the installation state is correctly managed.
---------
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
|
||
|
|
774d74cd1d |
[Feat] Plugin subscription management (#9580)
* fix(ui): update plugin category effects to use forkJoin for bulk updates and deletions
* fix: Use Number.isNaN for robust date validation
This commit addresses a minor bug by using the more reliable `Number.isNaN()` method, which is the recommended global function for checking `NaN`. It's a small, self-contained change that can be safely committed and reverted independently.
* refactor: Migrate plugin user management UI to Smart Tables
Replaces the custom list rendering and infinite scroll logic with `angular2-smart-table` and `ga-pagination` components for both available and assigned users.
This refactoring includes:
- Removing manual list iteration, user display, and pagination/scroll logic from the template.
- Introducing `angular2-smart-table` components and their data sources (`LocalDataSource`).
- Defining the smart table settings and custom render components for displaying user and assignment details.
- Updating the component's lifecycle hooks and data binding to work with the new table structure.
- Removing associated styling for the old list components and adding styles for the new table containers.
This is a major UI overhaul, replacing a significant portion of the component's template, styling, and TypeScript logic. Grouping these changes into a single commit ensures the entire UI migration is self-contained. The smart table settings, including columns like `_access` (for the upcoming feature), are fully defined here to provide a complete and functional (though not yet fully interactive for the new feature) table UI.
* feat: Integrate Plugin Tenant User Access Management UI
Wires up the user interface for managing plugin tenant user access.
This includes:
- Adding bulk access control buttons ('Enable All', 'Disable All') to the 'Current Assignments' tab in the HTML.
- Implementing `onToggleUserAccess`, `onEnableAllUsers`, and `onDisableAllUsers` methods in the component to dispatch actions to the facade.
- Adding the `NbToggleModule` and `AccessToggleCellComponent` imports, as well as necessary logic to `bindSourcesToStreams` for handling the access toggle within the Smart Table.
This commit completes the implementation of the new user access management feature by integrating the UI components with the facade methods introduced in the previous commit.
* feat: Integrate effects manager and update dependencies across multiple modules
* feat: user management tab with bulk actions and smart table integration
* feat(desktop): add plugin access verification
◦ add user assignment flows and services
◦ sync plugin access on assignment changes
◦ update plugin system interfaces, events, and channels
◦ include migration for plugin user scope table
* feat(plugin-tenant): add unassign operation for users
Introduce a new 'unassign' operation to manage plugin tenant users.
This operation removes a user from both the allowed and denied lists
for a specific plugin tenant. It updates the command handler, command DTO,
and the enum for available operations.
Fix a bug in the 'get-plugin-tenant-users' query handler where denied users
were incorrectly fetched from the allowed users table. The query now
correctly retrieves denied users from the dedicated denied users table.
* feat(plugin-user-management): add unassign user functionality
Introduce a new 'unassign' operation to completely remove users from plugin tenants, rather than just changing their active/inactive status.
Refactor user assignment loading to fetch all users (allowed and denied) by default, providing a comprehensive view of plugin assignments.
Implement optimistic UI updates for allow, deny, and unassign actions, reducing server reloads and improving responsiveness.
Enhance the user management UI with:
* A dedicated 'Disabled Users' count.
* Improved empty states for both overall plugin assignments and specific tabs.
* Confirmation dialogs for bulk enable/disable and individual unassign actions.
* Clearer status badges and tooltips.
* Add translation keys for various user management components.
* feat(plugin-user-assignment): enhance operation state management and UI feedback
* feat(plugin-user-assignment): add translations
* feat(plugin-subscription): improve error handling and response structure in subscription management
* fix: false promise validate
* feat(cspell): add new words to the spell checker dictionary
* fix(plugin-electron): correct channel name for updateTenantEnabled method
* feat: add ai fixes for user management in plugin marketplace
- Updated user management tab styles to use CSS variables for colors and shadows.
- Refactored user management component to utilize Angular's dependency injection for services.
- Improved loading states in user management component templates with skeleton loaders.
- Introduced new interfaces for user row data to enhance type safety.
- Replaced direct property access with computed properties in user cell components for better reactivity.
- Enhanced the plugin access sync service to handle timeout errors gracefully.
- Updated internationalization strings for clarity and consistency.
- Removed unused effects from the plugin routing module to streamline the codebase.
* fix(plugin-subscription): improve error handling when fetching updated subscriptions
* fix: bulk enable/disable actions are not permission-gated, so users without assign rights can trigger access changes.
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* fix: the new table styles are scoped to .available-users, but the assign tab uses .assign-users-section, so Assign Users table styling is not applied.
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* fix: replace skeleton loaders with spinner for loading states in user management tab
* refactor(integrations): move plugin effects provider to module level
Previously, `providePluginsEffects()` was declared directly within the route configuration for the 'plugins' path.
This change moves the provider to the `IntegrationsModule`'s main `providers` array.
Elevating the provider's scope ensures that plugin-related effects are available consistently across the entire integrations feature area, not just limited to the lazy-loaded 'plugins' route.
---------
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
|
||
|
|
2d4ca75cd7 |
Merge pull request #9574 from ever-co/bug/restart-app
[Bug] Restart app |
||
|
|
c87354be22 |
[Fix] Electron plugin window management (#9571)
* feat(desktop-window): improve plugin marketplace window lifecycle management - Format constructor parameters across multiple lines for better readability - Add close event listener to properly destroy window on close - Implement show() override to restore minimized windows and focus on display - Implement close() override with destruction state checks - Add isDestroyed() helper method to safely check window destruction state - Prevent operations on destroyed windows to avoid runtime errors * feat(desktop-window): enhance splash screen lifecycle management - Add close event handler to properly cleanup splash screen on window close - Add isDestroyed() method to safely check window destruction state - Unregister splash screen from WindowManager when window closes - Sort import statements alphabetically for consistency - Reformat code indentation from spaces to tabs for consistency with codebase - Improve JSDoc comments for better documentation clarity - Ensure proper resource cleanup and prevent memory leaks during splash screen lifecycle * feat(desktop-window): enhance always-on window lifecycle and formatting - Reorganize imports alphabetically for better maintainability - Add readonly modifier to manager property for immutability - Improve ternary operator formatting for better readability - Add close event listener to properly destroy window on close - Add isDestroyed() helper method to check window destruction state - Add override keyword to show() and hide() methods for clarity - Add new close() method override with destruction checks - Add destruction checks in show() method to prevent operations on destroyed windows - Improve code consistency and prevent potential memory leaks from unclosed windows * feat(desktop-lib): enhance window lifecycle management and code organization - Remove empty constructor from AppWindowManager class - Add null checks in pluginsWindow and alwaysOnWindow getters to handle destroyed windows - Update window initialization methods to check if window exists and is not destroyed before reusing - Simplify window close event handlers by using 'closed' event instead of 'close' with manual cleanup - Improve initSettingWindow formatting for better readability - Refactor initPluginsWindow to consolidate window creation and event handling logic - Refactor initAlwaysOnWindow to improve code clarity and reduce redundant checks - Update return type annotations for pluginsWindow and alwaysOnWindow getters to include null - Consolidate settingShow method signature formatting * feat(desktop-lib): enhance menu visibility and tray icon initialization - Add plugin menu visibility control based on authentication state in desktop-menu - Import AppWindowManager at top of desktop-menu for consistent ordering - Make TrayIcon class properties readonly for immutability - Add PluginEventManager initialization in TrayIcon constructor - Notify plugin event manager on authentication state changes - Use consistent property references (this.config, this.dependencies) throughout TrayIcon - Improve code organization and dependency injection patterns * feat(desktop-lib): enhance settings command window lifecycle and type safety - Add IPathWindow interface import for improved type safety - Replace any type with readonly IPathWindow in constructor parameter - Extract timeTrackerUi from windowPath for cleaner variable access - Refactor window initialization logic to check if window exists and is not destroyed - Consolidate window show operation to execute after initialization or reuse - Improve error handling by using consistent error variable naming - Simplify loadSetting call by using extracted timeTrackerUi variable - Enhance window lifecycle management to prevent duplicate initialization attempts * feat(desktop-lib): refine unauthenticated menu strategy and remove plugins - Remove OpenPluginsCommand import and plugins menu item from unauthenticated menu - Update timer menu item label from 'TIMER_TRACKER.MENU.OPEN_TIMER' to 'LOGIN_PAGE.TITLE' - Change timer menu accelerator from 'CmdOrCtrl+O' to 'CmdOrCtrl+L' - Simplify unauthenticated user menu by removing plugin access option * feat(desktop-timer): refactor window lifecycle - Simplify function parameter type definitions by collapsing multi-line signatures - Refactor always-on window initialization to use direct variable assignment instead of property access - Improve splash screen lifecycle management with closed event handler - Refactor language change callback to use arrow function syntax - Simplify plugins window closing logic with null check instead of optional chaining * feat(desktop-window): improve isDestroyed() null safety checks - Refactor AlwaysOn.isDestroyed() to explicitly check for null browserWindow - Refactor PluginMarketplaceWindow.isDestroyed() to explicitly check for null browserWindow - Replace ternary operator with early return pattern for improved readability - Ensure consistent null handling across window lifecycle implementations * feat(desktop-menu): improve null safety for auth store retrieval - Add null coalescing operator to handle undefined LocalStore.getStore() response - Prevent potential runtime errors when auth store is not initialized - Ensure pluginMenu visibility logic operates on valid object reference * feat(desktop-splash-screen): improve isDestroyed() null safety checks - Change isDestroyed() method from private to public for external access - Add explicit null check for browserWindow before calling isDestroyed() - Return true immediately if browserWindow is not initialized - Improve type safety and prevent potential null reference errors * feat(desktop-lib): improve settings window initialization order - Move initSettingWindow call after onReady listener registration - Ensure IPC listener is attached before window initialization begins - Improve reliability of settings window ready event handling - Maintain proper error handling with listener cleanup on failure * fix: plashScreen correctly calls this.manager.unregister(RegisteredWindow.SPLASH) inside its close event handler to remove the stale reference from the WindowManager. Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: calls unregister(RegisteredWindow.PLUGINS) on close Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: unregister window references on close for AlwaysOn, SplashScreen, and PluginMarketplaceWindow --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> |
||
|
|
9aaf4bb65c |
[chore] Desktop UI/ plugins module and routing (#9560)
* refactor(plugins): move effects providers to routing module - Move effects manager and all plugin effects providers from plugins.module.ts to plugin-routing.module.ts - Remove 16 effects imports from plugins.module.ts (PluginEffects, PluginInstallationEffects, PluginMarketplaceEffects, PluginVersionEffects, PluginSourceEffects, PluginUserAssignmentEffects, PluginSettingsEffects, PluginSubscriptionEffects, PluginPlanEffects, PluginPlanComparisonEffects, PluginSubscriptionAccessEffects, AvailableUsersEffects, PluginToggleEffects, PluginCategoryEffects, PluginUploadIntentEffects, PendingInstallationEffects) - Add provideEffectsManager and provideEffects to route configuration in plugin-routing.module.ts - Reorganize imports in plugins.module.ts for better code organization - Consolidate effects provider configuration at the routing level for improved modularity * refactor(plugin-subscription-access): update toastr service import and usage - Replace ToastrService import from @gauzy/ui-core with ToastrNotificationService from local services - Update toastrService type annotation to use ToastrNotificationService - Add nullish coalescing operator (??) to success notifications for assignUsersSuccess and revokeUsersSuccess effects - Add nullish coalescing operator (??) to error notification for bulkCheckAccessFailure effect - Ensures consistent fallback messages when notification content is null or undefined * refactor(plugin-settings): add root provider to plugin settings store - Add providedIn: 'root' to @Injectable decorator for PluginSettingsStore - Enable tree-shaking and singleton pattern for the store service - Improve dependency injection configuration consistency across the codebase |
||
|
|
8d50d68317 |
Merge pull request #9550 from ever-co/fix/build-docker
[Build] Add scheduler package to dockerfiles |
||
|
|
437ab6d5eb |
Merge pull request #9526 from ever-co/feat/create-scheduler-for-token
[Feat] Scheduler for token and deployment |
||
|
|
f2c6de62b0 |
[Feat] Background scheduling system with BullMQ (#9504)
* feat: add worker application and scheduler package Initialize a new NestJS-based worker application and a scheduler library within the workspace. This includes setting up the basic application structure, Nx project configurations, and updating the root TypeScript path mappings for the scheduler package. * feat(core): add redis module exports Export the redis module from the core package to make it available for use across the application. This includes adding the barrel export in the main entry point and creating the redis module index. * build: add bullmq dependency Add bullmq to the project dependencies to support background job processing and message queuing. * feat: add bullmq dependency and update related packages in yarn.lock * chore(deps): add @nestjs/bullmq Add @nestjs/bullmq version 11.0.4 to the project dependencies. * feat(scheduler): implement queue-aware background job system Introduce a robust scheduling and queueing system powered by BullMQ and NestJS. This update adds decorators for defining scheduled jobs and queue processors, along with a discovery mechanism to automatically register them across the application. - Add `@ScheduledJob`, `@QueueWorker`, and `@QueueJobHandler` decorators. - Implement a discovery service to automatically register jobs and processors from providers and controllers. - Integrate BullMQ for distributed job processing and persistence. - Refactor the worker application from a web server to a headless application context with signal handling. - Add worker lifecycle management through startup and heartbeat jobs. - Include support for job retries, timeouts, and overlap prevention. * chore(worker): disable redis integration and update heartbeat frequency Comment out Redis-related modules and services in the worker application. Increase the heartbeat job frequency from every 10 minutes to every 30 seconds for more frequent status checks. Additionally, refactor core package exports and remove redundant tsconfig path mappings. * chore(worker): remove Redis integration and clean up app module * feat(scheduler): enhance README with detailed usage, job definitions, and options for background job scheduling * fix(scheduler): return execution result from discovery handler Update the task handler in SchedulerDiscoveryService to return the result of the executed method. This ensures that any return value from the scheduled task is correctly propagated and can be captured by the caller. * refactor(scheduler): use crypto.randomInt for random delay Replace Math.random() with crypto.randomInt() in the randomDelay helper to provide a more robust source of randomness. This change also includes minor formatting cleanup and improves the handling of error messages and stack traces during job execution. * feat(cspell): add "bullmq" to custom words list * refactor(core): remove unused RedisModule import Remove the unused RedisModule import from the core index file to clean up the public API surface. * refactor(worker): use node: prefix for built-in imports Update the imports for fs and path to use the explicit node: protocol and reorder imports for consistency. * fix(tsconfig): correct extends path and update compiler options |
||
|
|
f184fa636f |
[Feat] Enhance refresh token mechanism (#9474)
* build(core): add @nestjs/schedule dependency Add @nestjs/schedule to the core package to support automated token cleanup tasks. * feat(core): implement centralized token management system Introduce a comprehensive TokenModule using the CQRS pattern to handle token lifecycle management, including creation, rotation, validation, and revocation. This system replaces manual JWT handling with a structured service-oriented approach. Key changes include: - Addition of a base Token entity with support for both TypeORM and MikroORM. - Implementation of token rotation with pessimistic locking for concurrency. - Specialized AccessToken and RefreshToken services for the auth layer. - Automated cleanup of expired and inactive tokens via a background scheduler. - Integration of new token services into the AuthService and AuthController. - Detailed audit tracking for token rotation chains. * refactor(token): resolve jwt service from registry by token type Update command and query handlers to fetch the required IJwtService from the TokenConfigRegistry instead of using direct injection. This enables the system to handle different JWT configurations for distinct token types dynamically at runtime. - Add registerJwtService and getJwtService to TokenConfigRegistry - Update handlers to resolve jwtService using the provided tokenType - Configure TokenModule to register scoped JWT services into the registry during initialization * fix(token): move command and query handlers to scoped providers Move the registration of CommandHandlers and QueryHandlers to the providers array to ensure they are correctly included and handled for the scoped service. * feat(token): streamline token repository methods and enhance type definitions in token module * feat(auth): include request metadata in tokens and refactor rotation Move token rotation logic from AuthController to AuthService to improve separation of concerns. Update JWT access and refresh token payloads to include the client IP address, user agent, and optional client ID. Add helper methods to RequestContext to extract client request details directly from the request context. * feat(token): add ValidateTokenHandler for token validation logic * refactor(token): enhance token validation logic and improve readability * feat(token): add isActivated method to token entity Add an isActivated helper method to the Token entity and IToken interface to determine if a token is currently active. Update the ValidateTokenHandler to use this method instead of direct status comparison for better encapsulation. * feat(token): require explicit provider tokens for async registration to prevent collisions * feat(token): enhance date filtering logic in query methods using Between for improved range queries * feat(token): enhance refresh token rotation logic to prevent revocation on access token generation failure * fix(token): preserve token-type mismatch error in ScopedJwtService.verify Move token-type validation outside jwt.verify() try/catch so a thrown "Token type mismatch" is not replaced by the generic "Token verification failed". This ensures callers receive the specific application error. * fix(token): log error when failing to decode token in ScopedJwtService.decode * fix(token): ensure threshold check for inactive tokens is not empty * refactor(token): clarify metadata handling in token rotation process * refactor(refresh-token): expose revoke method and remove internal call Change the visibility of the revoke method from private to public and remove the automatic revocation of the old token during the rotation process. This allows external callers to manage token lifecycle and revocation more explicitly. * refactor(auth): rename 'ip' to 'ipAddress' for clarity in token metadata * refactor(refresh-token): update ApiProperty to ApiPropertyOptional for clientId * fix(token): correct typo in comment regarding metadata handling * fix(access-token): correct expiration comment for JWT token duration * refactor(request-context): update return type of currentIp and currentUserAgent methods to string * fix(access-token): correct typo in client identifier comment and remove unused email field * fix(auth): await the token rotation process in refreshToken method * fix(token): update getCurrentUserId return type to string | null and adjust token creation metadata handling * refactor(token): wrap token creation and update in a transaction for improved consistency * feat(token): implement canRevoke method and update revoke logic for token handling * fix(token): change onDelete behavior for rotated tokens to SET NULL * refactor(token): extract token hashing to dedicated service Move token hashing logic from IJwtService into a standalone ITokenHasher interface and TokenHasherService. This improves separation of concerns by decoupling JWT-related operations from one-way hashing used for database storage. - Create ITokenHasher and TokenHasherService - Update command and query handlers to inject TokenHasher - Update TokenModule to provide the new service and injection token - Clean up JwtService and ScopedJwtService implementations * refactor(token): remove deprecated tokenHash fields from DTOs * refactor(token): remove resolveRawToken function and update token handlers to use rawToken directly * fix(token): change onDelete behavior for revoked tokens to SET NULL * fix(auth): re-throw UnauthorizedException for proper 401 response handling * refactor(token): enhance cycle detection in token audit trail retrieval * feat(core): implement pessimistic locking for MikroORM in token repository Add implementation for findByHashWithLock when using MikroORM by utilizing the PESSIMISTIC_WRITE lock mode. * fix(token): prevent metadata from overwriting core jwt claims Ensure that mandatory JWT claims such as userId, tokenType, and tokenId take precedence by spreading metadata at the beginning of the payload object. This prevents potential claim spoofing via metadata collisions. Additionally, remove redundant optional chaining when accessing metadata from the DTO. * refactor(token): update metadata structure in token entity * feat(cspell): add new words "Hasher" and "VARCHAR" to the spellcheck dictionary * refactor(token): streamline CleanupExpiredTokensCommand and update crypto import in TokenHasherService * refactor(core): remove raw-token export from shared index Remove the export of raw-token from the shared token module index to clean up the public API surface area. * feat(token): make provider tokens optional in forFeatureAsync Update TokenModule to automatically generate provider tokens based on the factory name when they are not explicitly provided. This simplifies the asynchronous registration of feature modules by removing the requirement for manual token configuration. Additionally, update RevokeTokenHandler to use the TokenHasher class constant for dependency injection instead of a string literal. * feat(token): log error when failing to update last used timestamp in token validation * refactor(token): remove unused jwt service from revoke handler Remove the IJwtService dependency and its associated token from the RevokeTokenHandler as they are no longer being used. * feat(token): enhance session control and implement usage limits Improve token lifecycle management by moving single-session revocation logic into transactions for atomicity. Implement max usage count validation during token verification and ensure rotation respects session constraints. Clean up unused repository dependencies and improve error handling during rotation. * refactor(token): migrate to @nestjs/jwt for token handling Replace the custom JWT service implementation with the @nestjs/jwt package. Update the IJwtService interface and ScopedJwtService to support asynchronous signing and verification operations. Ensure all callers in command handlers are updated to await the new asynchronous sign method. Standardize error handling by using NestJS built-in exceptions during token verification. * refactor(token): mark jwtService as readonly in ScopedJwtService Update the ScopedJwtService constructor to mark the jwtService property as readonly, ensuring it cannot be reassigned after initialization, and format the parameters for improved readability. * feat(token): enhance metadata column type for cross-database compatibility * feat(token): enhance token entity with unique index and refine column types * feat(database): add tokens table migration Implement a new migration to create the tokens table for managing authentication or access tokens. The schema supports token rotation, revocation reasons, metadata storage, and usage tracking across Postgres, SQLite, and MySQL. * feat(token): change user relationship onDelete behavior to CASCADE * fix(token): handle metadata serialization for sqlite Update token creation and rotation handlers to manually stringify and parse metadata when using SQLite. Since SQLite stores JSON as text, this ensures consistent behavior across different database providers and prevents type errors during JWT generation. * fix(token): bypass row lock for sqlite in token rotation Check the database type and avoid using findByHashWithLock when using better-sqlite3. This prevents errors as SQLite does not support row-level locking in the same way as other relational databases. * feat(core): add unified json column decorators Introduce JsonColumn, JsonbColumn, and JsonArrayColumn decorators to provide a consistent API for handling JSON data across TypeORM and MikroORM. These decorators automatically resolve the underlying storage type (e.g., jsonb for Postgres, json for MySQL) based on the database driver and handle serialization logic. The implementation allows native ORM column options to be passed directly, maintaining full type safety and autocomplete without resorting to generic record types. * refactor(token): simplify metadata handling with JsonColumn decorator Remove database-specific conditional logic for JSON serialization and parsing in token handlers and entities. Use the @JsonColumn decorator to abstract JSON storage logic across different database providers, and update types to consistently use objects for metadata. * fix(migration): generate new migration * refactor(token): remove deprecated token DTO definition * feat(token): implement token cleanup scheduler for automatic token management * fix(token): replace generic error with UnauthorizedException for token type mismatch * refactor(token): optimize findByHashWithLock method for TypeORM locking * fix(core): assign temporary uuid to token hash during rotation Assign a temporary random UUID to the tokenHash field during the initial token creation phase of the rotation process. This avoids potential database issues with empty strings before the actual JWT hash is generated and updated. * refactor(token): extract orm adapters to simplify repository Extract TypeORM and MikroORM repository logic into a dedicated adapter factory. This removes massive code duplication within the transaction method and ensures a consistent interface across different ORM implementations. * refactor(token): use UnauthorizedException for rotation errors Update RotateTokenHandler to consistently throw UnauthorizedException instead of ConflictException or NotFoundException for all validation failures. This ensures a uniform error response and prevents information leakage regarding the existence or specific state of tokens. Additionally, update the crypto import to use the node: prefix. * fix(token): use randomUUID for temporary tokenHash during creation * feat(core): enhance token entity with lifecycle and diagnostic methods Expand the Token entity and IToken interface with a comprehensive set of utility methods for state validation, lineage tracking, and observability. These changes facilitate more robust token management and debugging. Key additions: - Status predicates: isTerminal, isRotated, isUsable, isAtUsageLimit. - Lineage helpers: hasParent, hasSuccessor, isRootToken. - Temporal/Metadata helpers: getRemainingTime, getAgeTime, hasMetadata. - Diagnostic tools: toDebugInfo and getHealthReport for structured validity analysis. - Interface updates: New DTOs (BulkRevoke, Extend, Transfer) and expanded ITokenFilters for advanced querying. * refactor(token): improve robustness of create and validate handlers Refactor token command and query handlers to enhance error handling, logging, and logic flow. The create handler now fails fast on configuration errors and explicitly handles JWT signing or database persistence failures. The validation handler is restructured to delegate business rules to the domain entity and uses a centralized helper method to identify and persist specific failure reasons such as expiration, inactivity, or usage limits. Both handlers now utilize a structured logger instead of console logs. * feat(core): add verify method to AccessTokenService Implement a centralized token verification method in AccessTokenService that handles validation and inactivity checks. Refactor AuthService to use this new method, simplifying the isAuthenticated logic and ensuring consistent token validation and error handling across the application. * feat(auth): implement logout with token revocation Update the logout process to revoke both refresh and access tokens. The logout endpoint is changed from GET to POST and now requires a refresh_token in the body. Added a revoke method to AccessTokenService and unified the logout logic in AuthService to ensure secure session termination. * feat(auth): enhance logout process and improve token revocation handling * feat(auth): enhance logout process by conditionally revoking tokens * fix(auth): send refresh token during logout Update the logout process to use a POST request and include the refresh token in the request body. This ensures the backend can correctly identify and invalidate the specific session being terminated. The changes affect both the desktop-ui-lib and ui-core packages. * fix(token): improve logging for JWT verification failure to ensure sensitive info is redacted * fix(auth): require authentication for logout endpoint Remove the @Public() decorator from the logout route to ensure it is protected by the default authentication guard. This prevents unauthenticated requests from accessing the logout functionality. * chore(core): disable token module scheduler Disable the scheduler in TokenModule by setting enableScheduler to false. Additionally, reorganize and sort all imports in the AppModule for better maintainability and consistency. * chore(token): update comment to clarify default state of token cleanup scheduler * fix(auth): handle errors during logout by returning an empty observable * fix(core): enhance auth security and token validation logic Ensure the logout process awaits all token revocations using Promise.allSettled and add defense-in-depth verification by comparing token payloads against database records. Implement proper pessimistic locking and column escaping in token repositories for both TypeORM and MikroORM to prevent race conditions during usage count increments. Update token validation to strictly enforce usage limits by awaiting database updates for capped tokens. Additionally, improve JSON column serialization for text-based storage. * fix(auth): handle logout request errors Add error handling to the doLogout call within the auth strategy. This ensures that the client-side logout flow is not interrupted if the server-side token revocation request fails. |
||
|
|
5b8ef5ab85 |
[Bug] Login flow routing and change detection (#9475)
* feat(desktop-timer): add dark theme styles and fix css formatting Add overrides for the nb-theme-gauzy-dark class to support dark mode. Update body background, text colors, and spinner shadows. Improve CSS formatting by splitting selectors and normalizing hex color codes. * perf(desktop-ui): implement OnPush change detection for shared login components Apply ChangeDetectionStrategy.OnPush to LogoComponent, SocialLinksComponent, and WorkspaceSelectionComponent to improve rendering performance. Additionally, add a loading input to the WorkspaceSelectionComponent to support reactive state updates. * refactor(ui): improve login flow loading states and change detection Ensure proper UI updates by explicitly calling `markForCheck()` during asynchronous login operations. Use the `finalize` operator to manage loading states consistently across different login features and pass the loading state to the workspace selection component. Additionally, refine the navigation sequence after successful authentication using `concatMap`. * refactor(desktop): use reactive streams and ui routing for logout Refactor the logout process to use RxJS observable streams instead of imperative async/await logic. This migration shifts navigation responsibility from the Electron main process to the Angular router, ensuring a smoother UI transition. Key changes: - Implement `exhaustMap` and `concatMap` to handle logout events sequentially and prevent redundant triggers. - Use `Router.navigate` for UI-side routing to the login page. - Remove manual window URL loading from the Electron IPC main process. - Improve state handling and cleanup during the logout flow. * fix(time-tracker): prevent memory leaks and cleanup logout calls Add untilDestroyed to the logout subscription to ensure proper cleanup when the component is destroyed. Remove redundant await keywords from logout calls since the method returns a subscription instead of a promise. * feat(ui): add retry functionality to magic login workspace Add a retry button to the magic login workspace selection screen to allow users to recover from sign-in failures. Improve state management by resetting error and success flags during the selection process. Refactor ChangeDetectorRef and Router property names to use the underscore prefix convention for consistency across the login components. * refactor: move dark theme overrides to shared styles Relocate the nb-theme-gauzy-dark styles from the desktop-timer app index.html to the ui-core package's shared overrides. This change centralizes theme management and promotes style reusability. * fix(desktop-ui-lib): improve login retry flow and localize logout message Update the magic login workspace component to properly reset its state when a user attempts to retry after a failed sign-in. Additionally, replace the hardcoded logout message in the time tracker with a localized translation key and use asObservable on the logout stream. * refactor(ui-core): use css variables for dark theme overrides Replace hardcoded hex colors with CSS variables in the gauzy-dark theme overrides for body and spinner elements. This change improves theme consistency and maintainability by utilizing the existing theme tokens. * fix(login): navigate to magic login on retry Update the retry method in MagicSignInWorkspaceComponent to redirect users back to the magic login page. This ensures a consistent user flow by allowing users to restart the authentication process after an error. - Convert retry to an asynchronous method - Add router navigation to the magic login route - Remove manual change detection call - Clean up module imports * fix(login): improve formatting and structure of magic login workspace template |
||
|
|
9e835725dc |
[Feat] Windows data sync (#9454)
* Expose internal storage engines and logger utilities │ Files: packages/desktop-core/src/index.ts │ Rationale: Reorganizes and expands the public API of the core package to provide necessary Akita storage engines and helper types to dependent packages. * Enhance ElectronService with Observable-based IPC and export storage services │ Files: packages/desktop-ui-lib/src/lib/electron/services/electron/electron.service.ts, packages/desktop-ui-lib/src/lib/services/index.ts │ Rationale: Adds robust IPC invocation and event listening capabilities using Observables and NgZone, providing the necessary frontend infrastructure for synchronized storage. * feat: Implement Akita storage IPC handler and perform code cleanup │ Files: packages/desktop-lib/src/lib/desktop-ipc.ts │ Rationale: Adds the AkitaStorageHandler to manage IPC communication for state persistence. Includes formatting improvements and improved cleanup logic for power management handlers. * feat: Initialize Akita storage handler in the desktop main process │ Files: apps/desktop-timer/src/index.ts │ Rationale: Wires up the main process storage handler during the app is ready state and performs minor cleanup of imports and formatting. * feat: Configure Akita state persistence using GauzyStorageService in the renderer │ Files: apps/desktop-timer/src/main.ts │ Rationale: Migrates the application bootstrap process to use the custom GauzyStorageService within a provideAppInitializer, ensuring state is persisted via the new IPC-based mechanism. * feat(desktop): implement akita storage engine and ipc handlers Introduce a persistent storage solution for Akita in the desktop application. This implementation includes: - A core AkitaStorageEngine leveraging electron-store for data persistence. - IPC handlers in the main process to bridge storage operations between processes. - An Angular GauzyStorageService to provide a clean interface for the UI to interact with the storage engine via Electron IPC. * refactor: migrate akita state persistence to gauzystorageservice Move Akita's `persistState` and `akitaConfig` from top-level execution to `provideAppInitializer` during the application bootstrap process. This allows the use of `GauzyStorageService` through Angular's dependency injection and enables `enableInNonBrowser: true` to ensure state persistence works correctly across different environments. * feat(desktop): initialize akita storage handler Initialize the setupAkitaStorageHandler in the agent, desktop, server, and server-api applications. This ensures that Akita state management is correctly synchronized and handled via IPC communication across all electron-based components. * refactor(desktop-ui-lib): add missing await and types to storage service Update GauzyStorageService methods to properly await electron service invocations and include explicit Promise return types for improved type safety. * refactor(desktop-ui-lib): make electronService private in GauzyStorageService Change the visibility of the injected ElectronService from public to private to improve encapsulation within the GauzyStorageService. * fix(akita-storage): update default store name to 'window-state' * fix(electron-service): enhance API availability checks for Electron and ContextBridge * refactor(store.service): update state interfaces to use nullable types and improve initial state creation * refactor(language): ensure preferredLanguage is typed correctly * refactor(auth): enhance token validation and expand auth endpoints Implement robust JWT validation within the authentication strategy to ensure tokens received from refresh operations are well-formed and contain valid claims. This includes checks for expiration, issued-at, and not-before times using a 60-second clock skew buffer. Expand the list of authentication endpoints to include various sign-in and logout paths, ensuring they are excluded from automatic refresh logic to prevent potential infinite loops. Refine token expiry logic in the store to better handle missing or invalid expiry data by providing sane defaults and improved logging. * feat(auth): implement circuit breaker and improve token refresh synchronization Introduce a circuit breaker in the proactive refresh service to prevent infinite retry loops after multiple consecutive failures. The breaker automatically attempts recovery after a cooldown period. Improve synchronization across the authentication stack: - Replace ReplaySubject with a tracked Subject in RefreshStateManager using unique refresh IDs to ensure requests only resolve with the result of the specific refresh cycle they joined. - Add an atomic execution lock in SessionExpiredHandler to prevent race conditions when multiple concurrent requests return 401 status codes. - Ensure RefreshStateManager state is explicitly reset during logout flows to clear pending operations. - Standardize error handling and state notification in the refresh executor to prevent stalled request queues. * refactor(auth): simplify guards and improve offline mode support Simplify AuthGuard and NoAuthGuard by removing the AuthService dependency and relying on stored state (token and userId). This makes guards more lightweight and delegates token validation and refresh responsibilities to HTTP interceptors. Improve offline support by allowing authenticated users to access routes when the server is unreachable. Clean up redirection logic and remove redundant logout calls from within the guard components. * refactor(routing): reorganize application routes and update guard logic Reorganize routes into logical sections (Public, Auth, Protected, and Utility) to improve maintainability and clarity. Update route guards to consistently enforce authentication across internal pages and utility components. Key changes include: - Replace deprecated AppModuleGuard with specific Auth/NoAuth guards - Add AuthGuard to utility routes (updater, viewer, etc.) - Clarify guard execution order via documentation - Group public routes like splash-screen and server-down together * refactor(auth): centralize authentication data storage and enhance security - Extract authentication data storage logic into reusable `storeAuthenticationData()` method - Make `setTokenExpiry()` public to allow reuse across login components - Add `validateEmployeeUser()` public method to ensure user has employee record - Implement employee validation in offline login flow with proper error handling - Schedule electron authentication callback with 3-second delay using asyncScheduler - Pass full auth response to electron authentication instead of individual parameters - Update magic login component to use router state instead of query params for sensitive code - Improve code formatting and documentation in login components - Enhance security by preventing authentication codes from appearing in browser history * refactor(desktop-timer): remove unused AppModuleGuard import - Remove unused AppModuleGuard import from app-routing.module.ts - Simplify routing module dependencies and reduce unnecessary imports - Clean up module structure for better maintainability * refactor(server-down): enhance navigation and capture redirect URL - Add ActivatedRoute import to access query parameters - Capture original URL from query parameters on component initialization - Update navigation logic to redirect to original URL when server connection restored - Replace router.navigate with router.navigateByUrl for proper URL handling - Fix component decorator indentation to use tabs consistently - Add redirectUrl property to store the original navigation target - Improve logging to track server connection restoration and navigation flow * refactor(auth): enhance token management and improve offline access handling * refactor(auth.guard): update stored auth check logic to allow access with userId * refactor(auth): convert class-based guards to functional guards Migrate AuthGuard, NoAuthGuard, and AuthConnectionGuard from class-based implementations to functional guards using the Angular inject function. This aligns with modern Angular best practices and simplifies the routing configuration. Additional changes: - Update app routing to use the new functional guards. - Refactor tray icon initialization to use TrayIconFactory. - Clean up redundant guard providers and initializers in main.ts. - Update recap routing to utilize lazy-loaded child routes. * refactor(screen-capture): clean up imports and streamline code formatting * fix(auth): improve electron authentication flow and user validation Refactor the authentication process to use RxJS observables instead of manual delays when communicating with the Electron main process. This ensures more reliable state synchronization between the UI and the backend. Additional changes: - Add stricter validation for user records, including remote ID and employee status checks. - Update the IPC event listener from 'auth_success_tray_init' to 'timer_tracker_show'. - Implement defensive null checks in the user service retrieval logic. * refactor(desktop-lib): modularize tray icon using design patterns The monolithic TrayIcon class in desktop-tray.ts has been refactored into a more maintainable structure using several design patterns: - Strategy Pattern: for switching between authenticated and unauthenticated menu states. - Command Pattern: to encapsulate tray menu actions. - Observer Pattern: to handle language changes without recreating the tray. - Adapter Pattern: to decouple the tray logic from core services. - Builder Pattern: for fluent menu item construction. This restructuring improves testability and separates IPC handling, menu management, and authentication logic into dedicated classes. * feat(auth): enhance connection guard and refactor login flow Update `authConnectionGuard` to verify server connectivity via `ServerConnectionService` before allowing access. Refactor `AuthStrategy` and workspace login to utilize RxJS `switchMap` for better handling of asynchronous authentication processes, removing manual delays and improving code consistency. * refactor(auth): improve reactive state management and auth flow Convert authentication guards, interceptors, and services to use RxJS observable streams instead of synchronous property checks. This ensures that auth state is correctly evaluated after Akita state persistence has initialized. Changes include: - Update auth and no-auth guards to return Observables. - Integrate Akita persistence initialization checks in guards. - Refactor server ping logic using RxJS operators for better reliability. - Clean up logout and IPC handling logic in the desktop library. - Introduce a shared `isAuthenticated$` stream in the store service. - Update token refresh logic to be fully reactive. * refactor(desktop): migrate to functional guards and TrayIconFactory Update routing configuration to use the functional authConnectionGuard and ensure the time-tracker route is protected. Refactor the desktop tray icon creation to use TrayIconFactory for better abstraction and remove unused guard providers from the application bootstrap. * refactor(routing): replace AppModuleGuard with noAuthGuard and update route guards * refactor(tray): update tray icon creation to use variable assignment * refactor(magic-login): remove unused Store import and clean up constructor * refactor(auth-connection.guard): update access condition to use logical OR for connection state * refactor(auth-ipc-handler): improve type annotations and clean up logging * refactor(app.component): ensure proper cleanup of subscriptions with untilDestroyed * refactor: improve setting window initialization and event handling * refactor(start-timer-command): enhance execute method for better window handling * refactor(auth): streamline authentication success logging and improve error handling in command execution * fix(auth.guard): correct typo in isAuthenticated variable name * refactor(login): enhance change detection strategy and streamline imports across components * refactor(desktop-ui-lib): update screen capture component to use observables Switch the component to OnPush change detection and replace manual IPC listeners with observable streams. Implement proper subscription cleanup using untilDestroyed and remove the unused NgZone dependency. * refactor(tray): improve handling of time tracker window in logout and tray interactions * fix(tray): improve menu command execution and auth flow - Properly await command execution in the tray menu item builder. - Ensure the timer window is visible when attempting to start the timer via the tray while unauthenticated. - Delay auth IPC handler setup until tray icon initialization. - Add safety checks to the login response and remove the strict refresh token requirement during token refresh. - Remove an unused auth variable in the desktop-timer entry point. * refactor: update TablerIconsModule import path across multiple files * Update unauthenticated-menu-strategy.ts * Update packages/desktop-lib/src/lib/tray/strategies/authenticated-menu-strategy.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update packages/desktop-lib/src/lib/tray/observer/language-subject.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: Ruslan Konviser <evereq@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> |
||
|
|
390b8b4f06 |
[Refactor] Auto logout logic in angular interceptors (#9440)
* feat(auth): support refresh token rotation Update AuthStrategy and AuthService to handle new refresh tokens returned during the token refresh process. This ensures the stored refresh token is updated whenever a new one is provided by the backend, enabling support for refresh token rotation. * refactor(auth): consolidate auth error handling and interceptors Consolidate 401 Unauthorized error handling by removing the UnauthorizedInterceptor and refactoring the RefreshTokenInterceptor. The logic for token refreshing and session expiration is now delegated to specialized handlers (TokenRefreshHandler and SessionExpiredHandler). This cleanup simplifies the HTTP provider configuration in the agent and desktop-timer applications and migrates the RefreshTokenInterceptor to use Angular's inject() function. * feat(auth): add session expiry and token refresh handlers Introduce SessionExpiredHandler and TokenRefreshHandler to manage the authentication lifecycle. SessionExpiredHandler centralizes logout logic, cross-window synchronization via IPC for Electron, and login redirection. TokenRefreshHandler manages the 401 retry flow, ensuring only one refresh request is active at a time and queuing concurrent requests. * fix: start token refresh only if tokens are present Add a conditional check in AppComponent to ensure the token refresh service only starts when both the access token and refresh token are available in the store. This prevents potential errors during app initialization for unauthenticated users. * fix(auth): improve token refresh lifecycle and error handling Stop the token refresh service during logout and session expiration to prevent background activity. Ensure the refresh interval continues running if a proactive refresh attempt fails. Allow the service to be restarted by recreating internal subjects. Update the refresh interceptor to correctly handle 401 errors by removing a redundant expiry check. * fix(auth): improve token refresh error handling and subject lifecycle - Change refreshTokenSubject from readonly to mutable to allow recreation - Signal refresh failures to queued requests by calling error() on subject - Recreate refreshTokenSubject after each refresh cycle completes - Add error propagation in waitForRefresh to handle failed refresh attempts - Ensure all concurrent 401 requests receive failure notification when refresh fails - Improve error handling consistency across refresh and catchError paths * refactor(auth): rename refreshTokenSubject to refreshToken$ for clarity - Rename `refreshTokenSubject` to `refreshToken$` throughout token refresh handler - Improve naming convention by using `$` suffix to indicate Observable streams - Update all references in refresh flow, error handling, and finalization logic - Enhance code readability and consistency with RxJS naming conventions * feat(auth): export authentication utility services Export RefreshStateManagerService, TokenRefreshExecutorService, and TokenRequestClonerService from the auth services entry point. These services provide additional utilities for managing authentication state and token refresh logic. * feat(auth): improve session expired handler idempotency and navigation Ensure the session expiration flow is idempotent by adding an execution flag. Improve the navigation logic to prevent redirect loops by filtering out authentication and root URLs. Enhance error handling to guarantee login redirection even if the logout process fails. * refactor(auth): modularize token refresh orchestration Extract state management, refresh execution, and request cloning logic from TokenRefreshHandler into dedicated services. This improves maintainability by adhering to the Single Responsibility Principle and reducing the complexity of the main handler class. - Delegate state tracking to RefreshStateManager - Move refresh execution logic to TokenRefreshExecutor - Move request cloning to TokenRequestCloner * perf(auth): optimize proactive token refresh and state synchronization Refactor TokenRefreshService to coordinate with RefreshStateManager, preventing redundant refresh calls when a refresh is already in progress. Improve lifecycle management by switching from a Subject-based cleanup pattern to direct Subscription handling for the interval timer. Key improvements: - Integrate RefreshStateManager to prevent duplicate refresh attempts - Modularize refresh logic into private helper methods for readability - Simplify timer management in start and stop methods - Update to modern Angular dependency injection using the inject function * feat(auth): handle auth endpoint failures in refresh interceptor Modify the RefreshTokenInterceptor to detect 401 Unauthorized responses from authentication endpoints. Instead of skipping error handling, the interceptor now triggers the SessionExpiredHandler to log the user out, ensuring that local authentication state is properly cleared. This change prevents potential infinite loops and ensures a consistent user state when token refresh or login attempts fail. * feat(auth): add token refresh management and execution services Implement new services to handle authentication token refresh logic robustly: - RefreshStateManager: tracks refresh state and coordinates concurrent requests using ReplaySubject to prevent redundant calls. - TokenRefreshExecutor: orchestrates the refresh flow, including success and error handling with session expiry. - TokenRequestCloner: centralizes logic for cloning HTTP requests with updated Bearer tokens. Refactor TokenInterceptor to utilize the new TokenRequestCloner service. * refactor(auth): remove unused takeUntil operator from token refresh service - Remove unused `takeUntil` import from rxjs/operators - Simplify operator chain in token refresh subscription management - Reduce unnecessary dependencies in token refresh service * fix(auth): rename session expiry handler to refresh error handler - Rename handleSessionExpiry method call to handleRefreshError for better semantic clarity - Improve method naming to accurately reflect its purpose of handling token refresh errors - Align with existing error handling patterns in the token refresh executor service * fix(auth): replace error handler with direct throwError in token refresh - Replace handleRefreshError method call with direct throwError operator - Simplify error handling flow by throwing error immediately instead of delegating to separate method - Maintain same error propagation behavior while reducing unnecessary abstraction - Improves code clarity and reduces method call overhead in error path |
||
|
|
fb004513c7 |
[chore] Migrate desktop apps standalone (#9417)
* refactor(desktop-ui): convert components and directives to standalone Migrate numerous components, directives, and pipes within the desktop UI library to Angular's standalone architecture. This update involves: - Removing 'standalone: false' from component and directive decorators. - Adding necessary dependencies to the 'imports' array of individual standalone components. - Moving declarations from NgModule metadata to the 'imports' array. - Updating test suites to use 'imports' instead of 'declarations' for standalone components. * refactor: remove redundant modules in favor of standalone components Clean up the codebase by removing several intermediate Angular modules, including DesktopDirectiveModule, NoDataMessageModule, and PaginationModule. Components and directives are now imported directly into consuming modules, streamlining the dependency structure and supporting the transition to standalone components. * refactor(ui): migrate templates to angular control flow syntax Update various components to use the new @if and @for control flow syntax instead of *ngIf and *ngFor structural directives. This change also removes unnecessary NgIf and NgFor imports from the component metadata. * perf(desktop-ui): use loadComponent for lazy loading routes Replace static component imports with dynamic imports using the loadComponent property in routing configurations. This optimization enables lazy loading for these components, which helps reduce the initial bundle size and improves the application's startup time. * refactor: streamline component imports and remove unused modules * refactor(desktop-ui-lib): update component imports and clean up modules Add PipeModule to various recap components to provide necessary pipes. Remove several standalone components from NgModule declarations and exports as they are now managed via lazy loading or direct component imports. Clean up and reorder imports across affected files for consistency. * refactor(time-tracker): remove form value accessor and clean up imports Remove the NG_VALUE_ACCESSOR implementation and provider from the TimeTrackerComponent. Clean up redundant component references in TimeTrackerModule and reorganize imports for better maintainability. * refactor(desktop-timer): migrate to standalone application architecture Migrate the desktop-timer application from a module-based architecture to a standalone application architecture using Angular's bootstrapApplication API. - Delete AppModule and move its logic to main.ts. - Update AppRoutingModule to use loadComponent for route-level lazy loading of components from @gauzy/desktop-ui-lib. - Refactor RecapModule and SettingsModule to remove unnecessary component declarations and exports. - Consolidate application providers and third-party module initializations in the bootstrap process. * refactor(desktop-timer): convert AppComponent to standalone and simplify refresh Convert the root AppComponent to a standalone component and add the RouterOutlet to its imports. Simplify the initialization logic by removing manual token checks before starting the token refresh service. * refactor(desktop-ui-lib): replace LanguageModule with TranslateModule Replace the internal LanguageModule with TranslateModule from @ngx-translate/core in the recap and task-table modules. Additionally, import PipeModule in GauzyFiltersComponent to ensure required pipes are available. * refactor(desktop): migrate to standalone bootstrapping Remove AppModule and transition to the bootstrapApplication API in main.ts. This includes moving all providers and imported modules from the deleted app.module.ts into the bootstrap configuration, and replacing BrowserAnimationsModule with provideAnimations. * refactor(desktop): implement lazy loading and standalone component Update the routing configuration to use lazy loading for all component routes in app-routing.module.ts. Refactor AppComponent to support standalone imports and simplify the token refresh service initialization logic. * refactor(agent): migrate to standalone bootstrap api Remove the AppModule and use the bootstrapApplication function to initialize the app. Convert AppComponent to a standalone component and consolidate providers and module configurations in main.ts. * perf(agent): use lazy loading for routes and simplify token refresh Implement lazy loading for all routes in the agent application using the `loadComponent` syntax. This improves the initial bundle size and startup performance by loading component code only when needed. Additionally, simplify the initialization of the token refresh service in `AppComponent` by removing the manual check for existing tokens, allowing the service to handle its own internal state logic. * style(server): fix indentation in app component spec Correct the whitespace and indentation in the app component specification file to align with the project's formatting standards. * refactor: migrate server applications to standalone bootstrapping Remove AppModule from both server and server-api applications and transition to the Angular standalone bootstrap API. Provider configurations are moved to main.ts using bootstrapApplication and importProvidersFrom. * perf(routing): use lazy loading for desktop ui components Replace static component imports with dynamic imports using the loadComponent property in both server and server-api routing modules. This optimization reduces the initial bundle size and improves application startup performance by loading components from the @gauzy/desktop-ui-lib only when needed. * refactor(app): update component to use standalone imports for RouterOutlet * refactor(routing): update auth routes to use consistent lazy loading and guards * feat(build): add quick build script for mac agent * refactor(routing): add AuthGuard to server-dashboard route for enhanced security * feat(desktop): initialize TranslateModule in bootstrap process Configure the ngx-translate TranslateModule within the application bootstrap logic. This setup includes the HttpLoaderFactory and HttpClient dependencies to enable internationalization support. * build(gauzy): add nebular default theme styles Include the @nebular/theme prebuilt default CSS file in the project styles configuration to ensure UI components render correctly. * refactor(apps): simplify bootstrap process and update providers Streamline the bootstrap process for server and server-api applications by removing unused Nebular and feature modules. Configure the TranslateModule with HttpLoaderFactory and add Store to the application providers. Additionally, remove the AuthConnectionGuard from routing configurations and update global style paths in project.json. |
||
|
|
f7a3b61f2b |
fix(settings): Revert add plugin component UI (#9412)
* fix(settings): revert add plugin component UI Revert the add plugin component with a grid-based layout for installation options. Enhance accessibility by adding ARIA attributes and keyboard event handlers. Update the template to utilize Angular Signals and improve the overall form structure and error reporting. * fix(plugin): update auth token handling method and adjust imports * feat(ui): add visible label for cdn url input Add a visible label element linked to the CDN URL input field and remove the redundant aria-label attribute. This improves accessibility and ensures the input is properly identified by screen readers. * fix(add-plugin): prevent default space key behavior and add aria-disabled attribute during installation * fix(add-plugin): improve error handling display and add comments for clarity |
||
|
|
18a0b5feac |
Merge pull request #9406 from ever-co/GP-779-implement-load-more-functionality-lo
[Feat] Implement load more functionality |
||
|
|
919a4ae1d8 |
Merge pull request #9403 from ever-co/feat/plugins-migration-to-standalone
[Perf] Plugins migration to standalone |
||
|
|
5007c731f8 |
Merge pull request #9354 from ever-co/GP-760-employee-plugin-awareness
[Feat] Employee plugin awareness |
||
|
|
ac34064d05 |
[Feat] Plugin marketplace UI in Web App (#9319)
* feat(marketplace): introduce plugin marketplace UI and state Adds the foundational UI components and initial state management for the Plugin Marketplace feature. This includes: - A placeholder component (`PluginMarketplaceWrapperComponent`) for the marketplace view in the integrations section. - Basic styling for the placeholder component. - Initialization of necessary services and state within `desktop-ui-lib/src/lib/settings/plugins/plugins.module.ts`, including `ElectronService` and `ToastrNotificationService`. This commit lays the groundwork for the full plugin marketplace functionality, enabling future development of CRUD operations, subscriptions, and advanced filtering. * feat(integrations): add plugin marketplace placeholder UI Introduces a new UI component for the plugin marketplace, displaying a placeholder message while the full functionality is being integrated. This commit adds the HTML template, SCSS styling, and a basic TypeScript component structure for the `PluginMarketplaceWrapperComponent`. The placeholder informs users that the marketplace features, including CRUD operations and subscriptions, are under development. * refactor(integrations): remove plugin marketplace placeholder Remove the placeholder component for the plugin marketplace. This component was used to indicate that the feature was under development. The actual plugin marketplace functionality will be implemented separately. * refactor(plugins): restructure routing and module organization Move plugin routes into a dedicated `plugin.route.ts` file and refactor `PluginRoutingModule` to use `RouterModule.forChild` with lazy loading for a cleaner module structure. This change separates routing definitions from module configurations and improves modularity within the desktop UI library. * refactor(routing): update plugin route configuration to use PluginsModule This commit refactors the plugin routing configuration across multiple applications. Instead of loading a component and then separately loading plugin routes, it now directly uses `PluginsModule` for loading children. This simplifies the route definitions and ensures consistent plugin integration. * refactor(integrations): simplify UI and remove tabbed navigation Refactor the integrations component UI to remove the tabbed navigation for plugins. The integrations list is now displayed directly, with a clear link to the 'Plugins' section. This change simplifies the user interface and removes unnecessary complexity. SCSS styles related to the removed tabbed navigation have also been updated. * refactor(plugins): streamline routing and layout components Refactor plugin routing and layout components to improve efficiency and maintainability. This change updates the plugin installed routes to use direct component imports instead of lazy loading. The 'installed' tab in the plugin layout is now conditionally added based on whether the application is running in a desktop environment. The main plugin routing module also adopts direct component references for the plugin layout and its child routes. The default redirection for the plugin route has been changed from 'installed' to 'marketplace'. * refactor(plugin-marketplace): modularize tab modules and update routing Removes `RouterModule.forChild` from individual plugin marketplace tab modules. Updates the main `plugin-marketplace-routing.module.ts` to directly import tab components instead of lazy loading their modules. The `PluginsModule` is updated to import these tab modules directly. This change simplifies the routing configuration and improves the modularity of the plugin marketplace feature. * feat(plugins): update services with providedIn: 'root' and desktop checks Updates subscription-related services to use `providedIn: 'root'` for improved dependency injection. Adds checks for `isDesktop` within `PluginElectronService` to ensure that Electron-specific methods are only invoked in a desktop environment, preventing potential runtime errors in non-desktop builds. * refactor(plugins): use relative routing for marketplace navigation Refactors the plugin marketplace navigation to utilize relative routing. This change involves injecting `ActivatedRoute` and using it with `router.navigate` to construct paths relative to the current route. This approach provides more flexibility and robustness when navigating within the plugin marketplace, especially when routes are nested or change. It avoids hardcoding absolute paths, making the codebase easier to maintain and less prone to breaking if the application's routing structure evolves. The following navigations have been updated: - Navigating to plugin details. - Navigating back from an error state. - Navigating back from plugin item view. - Navigating to version history. - Navigating back from version history view. * refactor(integrations): use styled button for plugins navigation Refactor the integrations page header to replace the plain div link for "Plugins" with a styled `nb-button` component. This change improves the visual consistency and provides a more interactive user experience for navigating to the plugins section. The button now includes an icon and uses specific styling to align with the application's design language. * refactor(plugins): correct plugin category effects import and remove unused LanguageModule The import path for `PluginCategoryEffects` was incorrect and has been updated to point to the correct location within the `+state/effects` directory. Additionally, the `LanguageModule` was not being used and has been removed from the imports and the `imports` array to clean up the module. * feat: add PluginsModule to app modules Integrate the PluginsModule into the imports of the AppModule for desktop-timer, desktop, server-api, and server applications. This change ensures that plugin functionality is available across these application contexts. * feat(i18n): add plugins translation Adds the "PLUGINS" key to the English translation file. This allows for the display of plugins in the UI. * feat(plugins): add environment validation for plugin installation Introduce environment checks at the effect level to ensure plugins are compatible with the current environment (web, mobile, desktop) before proceeding with installation. This change enhances the robustness of plugin installation by: - Checking `pluginEnvironmentService.canInstallPlugin(plugin)` to determine compatibility. - Displaying a warning toast with a user-friendly message if the plugin is not compatible. - Disabling the plugin toggle if the environment check fails, preventing further installation attempts. - Optimistically enabling the plugin toggle only after the environment validation passes. * feat(i18n): add plugin environment validation error strings Adds new internationalization strings for various plugin environment validation errors. These strings will be used to provide clearer feedback to users when a plugin cannot be installed due to environment mismatches. * refactor(plugins): rename PluginEnvironmentService and move validation Rename `pluginEnvironmentService` to `environmentService` for brevity. Move plugin environment validation logic from the start of the `install` effect to after the optimistic toggle and before opening the installation dialog. This ensures the toggle is set immediately, and the validation occurs just before user interaction or deeper installation steps. The validation now directly calls `notifyEnvironmentMismatch` which encapsulates toastr and translation logic. * feat(plugins): introduce PluginEnvironmentService Introduce `PluginEnvironmentService` to manage plugin environment detection and validation. This service provides methods to determine if the current environment is desktop, mobile, or web, and to validate if a plugin is compatible with the current environment. It also handles notifying the user of environment mismatches. * feat(plugins): implement environment compatibility checks and warnings Implement checks to ensure plugins are compatible with the current environment before installation. This includes: - Disabling installation buttons and toggles if a plugin is not compatible. - Displaying tooltips that explain the environment mismatch. - Injecting `PluginEnvironmentService` into relevant components to utilize the new checks. - Refactoring `PluginEnvironmentService` to provide a `getEnvironmentMismatchWarning` method. * fix(plugins): update plugin environment mismatch translation keys Updates translation keys used for plugin environment mismatches. This change aims to provide more specific and accurate error messages to the user when a plugin's environment requirements are not met. The keys have been moved to the `PLUGIN.ERRORS` namespace to better categorize plugin-related errors. Specific keys have also been updated for clarity, including a new key for unsupported plugin types. * fix(plugin-marketplace): type getContextMenuItems return value The `getContextMenuItems` method in the `PluginMarketplaceDetailComponent` was missing a return type annotation. This commit adds `NbMenuItem[]` as the return type to improve code clarity and maintainability. * refactor(plugins): use relative paths for plugin navigation Replace hardcoded absolute paths in plugin layout and marketplace detail components with routes generated relative to the current path. This ensures navigation links remain functional regardless of the parent route configuration. * fix(plugins): disable install toggle only when explicitly disabled The install toggle and subscribe button in the plugin marketplace were being disabled not only when the `disabled` input was true, but also when the `canInstallInEnvironment()` method returned false. This commit removes the dependency on `canInstallInEnvironment()` for disabling these elements, ensuring they are only disabled when the `disabled` input is explicitly set. * fix(plugins): refine environment check for plan selection Update the plugin subscription plan selection logic to correctly handle environment compatibility. Ensure the ability to proceed without a subscription is gated by the environment check and refine the button disabled state for free plans when the environment is incompatible. * chore(deps): remove unused RouterModule imports The `RouterModule` and `Routes` imports were removed from several Angular modules as they were not being used. This is a cleanup task that does not affect the functionality of the application. Additionally, a typo in the `.cspell.json` file has been corrected by adding "Mobi" to the list of allowed words. * refactor(desktop-ui-lib): use inject and improve return type consistency Update PluginElectronService to use the Angular inject function for dependency injection. Ensure all methods return consistent types (resolved Promises or EMPTY Observables) instead of undefined when not in a desktop environment to improve type safety. * refactor(plugin-layout): improve tab list initialization Use an explicit conditional check to populate the tabs array, avoiding the inclusion of boolean values in the list. Additionally, mark the router property as readonly and reorder imports for better consistency. * refactor(plugins): use optional chaining for plugin type check Update the canInstallPlugin method to use the optional chaining operator instead of manual null and property checks to improve code readability. * refactor(integrations): remove unused OnDestroy and cleanup code Remove the empty ngOnDestroy lifecycle hook and its interface implementation. Additionally, add the readonly modifier to the searchElement ViewChild. * refactor(integrations): move search styles and remove ng-deep wrapper Relocate the #integrationSearch styling from the :host ::ng-deep block to the main component stylesheet block to simplify the SCSS structure. * refactor(plugins): use optional chaining for plugin type check Update the null check in getEnvironmentMismatchMessage to use the optional chaining operator for improved readability and conciseness. * fix(plugins): update fallback redirect path Change the wildcard route redirection from 'installed' to an empty string to ensure that unknown sub-paths correctly resolve to the base plugins route. |
||
|
|
2582fc981d |
[Fix] AI suggestions #9298 (#9311)
* fix: improve error logging format in plugin subscription plan service
* fix(plugin-system): enhance zip extraction security
This commit introduces several security enhancements to the zip extraction process within the CDN download strategy.
Previously, there was a potential for path traversal vulnerabilities if a malicious zip file contained entries with paths that attempted to escape the designated extraction directory.
The following changes were implemented:
- Added a check to ensure the resolved file path of an entry is strictly within the base extraction directory. If it escapes, the entry is logged and skipped.
- Explicitly ensured that the parent directory for each file being extracted exists before attempting to write the file. This prevents errors and potential issues with nested directories within zip archives.
- Refactored `isSafePath` to more robustly handle Windows path separators, disallow absolute paths and drive letters, and ensure the resolved target path starts with the resolved root directory, preventing traversal.
* fix(plugin-category): simplify slug generation logic
* fix(cspell): add new words to the spell checker dictionary
* fix(cdn-download): use replaceAll for entry path normalization
fix(plugin-category): refine slug generation regex for leading/trailing dashes
* fix(cspell): remove duplicated word "Zrdm" from the spell checker dictionary
* fix(cdn-download): improve file extraction handling and add error tracking
* fix(cdn-download): correct path normalization logic in isSafePath method
* fix: arbitrary file access during archive extraction ("Zip Slip")
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix(cdn-download): enhance security by rejecting Unix-style absolute paths and removing redundant path validation
* fix(cdn-download): update import for finished stream utility and remove redundant baseExtractPath variable
* fix(cdn-download): improve path normalization
The previous regex ` /\\/g ` for normalizing Windows path separators in `entryPath` was overly broad and could lead to incorrect path normalization in certain edge cases.
This change updates the `replaceAll` method to use a literal backslash character `'\'` instead of a regex, ensuring only backslashes are replaced with forward slashes. This provides more precise and reliable path normalization.
* refactor(cdn-download): simplify archive extraction logic
Refactors the `CdnDownloadStrategy` to use dedicated helper methods for directory creation and file extraction. This improves readability and maintainability of the archive processing logic.
The changes include:
- Extracting directory creation into `createDirectory`.
- Extracting file writing logic into `extractFile`.
- Renaming `filePath` to `entryPath` for clarity.
- Using `path.resolve` for safer path handling.
- Ensuring `entry.autodrain()` is called in error scenarios.
* fix(cdn-download): prevent path traversal in zip extraction
Add validation to the `extractEntry` function to prevent path traversal vulnerabilities during the extraction of zip archives. The target path is now resolved against the base directory of the extraction to ensure it remains within the intended scope.
This change enhances security by ensuring that malicious zip archives cannot write files outside of their designated extraction directory.
The `baseDir` option is now passed to `extractEntry` and used to construct a safe target path.
* fix(plugin-system): improve error handling and stream management in cdn download
This commit addresses several issues in the `CdnDownloadStrategy` related to error handling and stream management during plugin downloads.
Key changes:
- **Robust Error Logging:** Error messages for directory creation and file extraction now include the full error stack or message for better debugging. They also explicitly convert non-Error objects to strings.
- **Stream Pipeline for Extraction:** The `entry.pipe(writeStream)` and `finished(writeStream)` combination has been replaced with `pipeline(entry, writeStream)`. This provides more reliable error propagation and ensures streams are properly cleaned up.
- **Resource Cleanup on Error:** In the `extractFile` method, if an error occurs during file extraction, the `entry` and `writeStream` are explicitly destroyed to release resources.
- **Incomplete File Removal:** If an error occurs during file extraction, any partially created target file is now removed to prevent leaving incomplete artifacts. This handles potential `ENOENT` errors gracefully.
- **Throwing Errors:** Errors are now consistently re-thrown after cleanup, ensuring that the calling code is aware of and can handle extraction failures.
* fix(cdn-download): re-throw stream write errors
The previous implementation of `CdnDownloadStrategy` caught stream write errors and autodrained the entry. This masked the underlying error and prevented `Promise.all` from rejecting, leading to silent failures when downloading plugin files.
This change re-throws the caught error. This ensures that any failure during the file writing process is propagated up to `Promise.all`, allowing the overall download operation to fail gracefully and be reported to the user.
* fix: Rethrowing here propagates the error, but the unzipper entry stream is no longer drained/destroyed on failure. A write error can leave the entry unread and stall the unzip parse. Drain (or destroy) the entry before rethrowing.
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* fix(cdn-download): improve error handling and resource cleanup
Add robust error handling to the CDN download strategy. This includes:
- Logging detailed error messages, including stack traces when available.
- Destroying pipe streams to release resources on error.
- Attempting to remove incomplete files to prevent corrupted downloads.
- Handling potential errors during file removal (e.g., if the file doesn't exist).
- Ensuring the `entry` stream is also handled correctly on error.
* fix(cdn-download): ensure error is thrown in stream pipe
The previous implementation incorrectly called `entry.autodrain()` before re-throwing the error. This prevented the error from being propagated correctly, potentially leading to unhandled promise rejections.
This change ensures that the error is thrown immediately, allowing the calling code to catch and handle it as expected.
---------
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
|
||
|
|
43d68e4ef4 |
[Feat] Remove add plugin from installed plugins (#9314)
* feat(plugins): implement upload selection modal and intent handling Introduces a new upload selection modal that allows users to choose between installing a plugin locally or publishing it to the marketplace. This change includes: - A new `UploadSelectionComponent` with its associated HTML, SCSS, and TypeScript files. - New actions (`PluginUploadIntentActions`) and effects (`PluginUploadIntentEffects`) to manage the upload intent flow. - Updates to `PluginMarketplaceComponent` to trigger the upload selection. - New Akita store (`PluginUploadIntentStore`) and query (`PluginUploadIntentQuery`) to manage the upload intent state. - Internationalization updates for the new upload selection options. This refactors the previous direct "Upload" action in the plugin marketplace to provide a more guided user experience. The "Add Plugin" button's functionality is now integrated within the "Install Locally" flow of the new upload selection modal. * feat(plugins): redesign add plugin modal Refactors the add plugin modal to improve user experience and UI clarity. The changes include: - A new card-based design for installation options (local, CDN, NPM) with clear descriptions and icons. - Improved form structure for CDN and NPM installations, including better input fields and error handling. - Enhanced accessibility features such as ARIA labels and focus management. - A new signal-based approach for managing component state. - Refined styling for better responsiveness and visual appeal. - Added a subtitle to the plugin modal header. * feat(plugins): enhance plugin list and marketplace detail components with improved state handling and accessibility features * feat(plugins): adjust nb-toggle label margin for improved layout consistency * fix(i18n): remove unused upload translation The "UPLOAD" translation key was no longer being used in the UI. Removing it helps to keep the i18n files clean and maintainable. * fix(desktop-ui-lib): enable keyboard navigation for upload selection Add keyboard event listeners for 'enter' and 'space' keys to the upload selection cards. This allows users to select an installation option using their keyboard, improving accessibility and usability. * feat(plugins): translate add plugin options and aria-labels Translate the descriptive text and ARIA labels for the "Install from Computer", "Install from CDN", and "Install from NPM" options within the add plugin component. This change ensures that these options are properly localized and accessible to users who rely on translated interfaces. The `en.json` file has been updated with new translation keys for these strings. * fix(add-plugin): correct conditional rendering logic Update the template to use `@else if` for conditional rendering of plugin installation forms. This ensures that only one form is displayed at a time based on the context (CDN or NPM), preventing potential rendering issues and improving user experience. * fix(desktop-ui-lib): refactor plugin settings styles to use theme variables This commit refactors the SCSS styles for the plugin settings component in the desktop UI library. Instead of using hardcoded color and shadow values, it now utilizes theme variables. This change improves consistency across the application and makes it easier to manage the visual theme. The specific changes include: - Replacing hardcoded rgba shadows with `var(--gauzy-shadow)`. - Replacing hardcoded rgba borders with `var(--border-basic-color-3)`. - Replacing hardcoded rgba background colors with theme-specific variables like `var(--background-basic-color-2)`, `var(--color-primary-100)`, `var(--color-success-100)`, and `var(--color-danger-100)`. - Replacing hardcoded focus outlines with `var(--color-primary-focus)`. - Replacing hardcoded color values for icons and text with theme variables. - Replacing hardcoded input border colors on hover and focus with theme variables. - Replacing hardcoded background for the plugin details section with `var(--gauzy-card-2)`. * fix(add-plugin): initialize npmModel with default structure The `npmModel` was not being initialized with its default structure when the `reset` method was called. This commit ensures that `npmModel` is properly reset to its expected shape, preventing potential issues with form handling or state management. * refactor(plugin-list): improve readability of template variable declarations Break down the long `@let` declaration into multiple lines for better readability. Add comments to explain the purpose of each state variable. * fix(plugin-list): use theme variable for hover shadow Replaces the hardcoded box-shadow value with the `--gauzy-shadow` CSS variable for the plugin list item hover effect. This ensures consistency with the application's theme and allows for easier global shadow management. * fix(desktop-ui-lib): improve danger button styling and use inject This commit refactors the `.danger` CSS class to use CSS variables for more maintainable and themeable background colors. It also updates the `PluginUploadIntentEffects` to use the `inject` function for dependency injection, which is a more modern Angular practice. * chore: remove unused animation keyframes The `@keyframes pulse` was defined but not used anywhere in the component's stylesheet. This commit removes the unused animation definition to clean up the code and reduce file size. * fix(plugin-upload-intent): handle empty or null intents correctly The previous implementation incorrectly returned an empty array or a single action without proper handling of null or undefined upload intents. This change ensures that the observable correctly emits `EMPTY` when no valid intent is provided, and uses `of()` for dispatching single actions to avoid unexpected behavior. * fix(plugin-upload-intent): allow null for intent The `intent` property in `PluginUploadIntentQuery` and `IPluginUploadIntentState` was previously typed as `UploadIntent`, implying it must always have a value. However, the `setIntent` method in `PluginUploadIntentStore` was intended to allow clearing the intent by not explicitly setting it. This change updates the type definitions to `UploadIntent | null` to accurately reflect the possibility of the intent being null, allowing the clearing of the upload intent state. * fix(ui): add role button to upload selection cards Adds the `role="button"` attribute to the `nb-card` elements within the upload selection component. This improves accessibility by clearly indicating that these cards are interactive elements that can be activated using a mouse or keyboard. * fix(desktop-ui-lib): update aria-label for close button The aria-label for the close button in the upload selection component was previously hardcoded. This commit updates it to use the translated string 'BUTTONS.CLOSE' for better internationalization. * feat(plugins): internationalize plugin marketplace details This commit introduces internationalization for various text elements within the plugin marketplace detail view. Key changes include: - Translating labels such as "by", "downloads", "Free", "No description available", "Subscription Required", "Installing...", "Uninstalling...", "Trial", "Updated", "License", "Released", and "more tags". - Localizing the dynamic text for install/uninstall progress. - Translating the labels for the install toggle button based on plugin status and plan. - Internationalizing the action menu items for plugins, including "View Details", "Settings", "Manage Subscription", "Manage Users", "Homepage", "Repository", "Edit Plugin", and "Delete". This enhancement improves the accessibility and usability of the plugin marketplace for a global audience. * fix(plugins): update scss for gradient and button alignment Refactors the linear gradient calculation in `add-plugin.component.scss` to use `color-mix` for better theme integration. Adjusts `plugin-list.component.scss` to change `justify-content` from `stretch` to `flex-start` for improved button alignment. * refactor(plugin-list): extract smart table settings to a method Extract the `smartTableSettings` object into a dedicated `buildSmartTableSettings` method. This improves code organization and makes it easier to reinitialize settings, especially when the language changes. This change also moves the call to `loadPlugins()` to `ngAfterViewInit` to ensure that the table settings are fully initialized before attempting to load plugins. This addresses a potential race condition. * fix(ui): adjust button sizes and styling in plugin components Update the `size` attribute for close buttons in both the `add-plugin` and `upload-selection` components from `tiny` to `small`. This ensures a consistent and more appropriately sized close button across these plugin-related UI elements. Additionally, the SCSS for the `.close-button` in `add-plugin.component.scss` has been updated to use `var(--border-radius)` for its `border-radius` property, aligning with global theming. Padding has also been added to `.close-button` in both components for better visual spacing. * fix(desktop-ui-lib): use theme variable for card shadows Refactors the shadow styles in the upload selection component to use the `--gauzy-shadow` theme variable. This ensures consistency in the application's visual styling and makes it easier to manage shadows across different components. |
||
|
|
9ca1a6c2b9 |
[Refactor] Plugins menu and open plugins in a dedicated window (#9300)
* feat(window): add Plugin Marketplace window and wire it in desktop-window
* feat(ui/plugins): add Plugin Marketplace UI (list, detail, upload, filters, layout, styles)
* refactor(settings): wire plugin routes and access guard; update settings module
* refactor(desktop): menu/tray entries to open Plugin Marketplace window
* refactor(core): extend window manager interface to support plugin windows
* chore(timer): update routing/module and bootstrap for plugin window integration
* feat: export new components and modules
This commit adds exports for several new components and modules from the desktop-ui-lib. This includes components related to login, agent dashboard, integrations, language, recap, settings, and time tracker. These exports make these components and modules available for use in other parts of the application.
* feat(plugins): add plugin route and tray menu item
Adds a new route for plugins and integrates a new menu item into the tray icon's context menu. This enables users to access the plugin marketplace directly from the system tray.
The `app-routing.module.ts` now includes a 'plugins' path with a guard and lazy loading for plugin-related components and routes. The `app.module.ts` imports the `PluginsModule`.
The `tray.ts` file is updated to include a new "Plugins" menu item in the tray icon. Clicking this item will open the `PluginMarketplaceWindow` if it's not already open, or focus it if it is. This feature enhances the agent's extensibility and user experience by providing easy access to plugins.
* feat(plugins): implement plugin marketplace and routing
Integrates the plugin marketplace into the application and sets up the necessary routing for plugin management. This includes adding the `PluginsModule` to both desktop and server applications, and configuring the `plugins` route with `AuthConnectionGuard` to ensure authenticated access.
The plugin marketplace window is now created and loaded in both desktop and server entry points. This feature allows for dynamic loading and management of plugins within the application.
* fix(package): add missing newline at end of package.json
* fix(plugins): ensure plugin window is retrieved after creation
When creating a new plugin marketplace window, the code immediately tried to show it without re-retrieving the window instance from the `WindowManager`. This commit ensures that the `window` variable is updated after the new window is created, so that `window.show()` is called on the correct instance.
Additionally, removed an unnecessary `toggleDevTools()` call from the `PluginMarketplaceWindow` constructor.
Also updated the `desktop-ui-lib` to correctly bind the `routerLink` directive and added `ChangeDetectionStrategy.OnPush` to `PluginLayoutComponent` for performance.
* fix(tray): use correct ui path for plugin marketplace window
When opening the plugin marketplace window, the incorrect path was being used. This commit updates the path to `appWindow.getUiPath('plugins')` to ensure the window loads correctly.
* fix(plugin-layout): remove unnecessary change detection strategy
The `ChangeDetectionStrategy.OnPush` was implicitly handled by Angular's default behavior when not explicitly set. Removing it simplifies the component definition without altering its functionality or performance.
|
||
|
|
9d37532025 |
[Feat] Refresh token for desktops (#9202)
* feat(desktop-ui-lib): add token refresh service and interceptors; update auth services * chore(desktop): wire auth/interceptors in app module and component * feat(auth): add refresh token system Implement a comprehensive refresh token system for seamless authentication and extended user sessions. This change introduces: - `RefreshTokenInterceptor`: Automatically handles 401 responses by refreshing expired access tokens, queuing concurrent requests, and retrying original requests. - `TokenRefreshService`: Proactively refreshes tokens 5 minutes before expiration to prevent user-facing 401s. - Updates to `AuthStrategyService` and `StoreService`: Manage token rotation, securely store refresh tokens, and track JWT expiry timestamps. - Refined `UnauthorizedInterceptor`: Delegates 401 handling to the refresh interceptor, ensuring proper logout only when the refresh token is invalid or unavailable. - Integration into desktop and agent applications: The new interceptors and services are registered and initialized. This system provides a production-ready solution for managing token lifecycles, enhancing security, and improving user experience by minimizing login interruptions. Extensive documentation for the implementation is included in `REFRESH_TOKEN_QUICKSTART.md`, `REFRESH_TOKEN_SUMMARY.md`, and `packages/desktop-ui-lib/REFRESH_TOKEN_IMPLEMENTATION.md`. * refactor(token-refresh): simplify token refresh service API Rename `startTokenRefreshTimer` to `start` and `stopTokenRefreshTimer` to `stop` in the `TokenRefreshService`. This change improves method brevity and consistency. Update all call sites in `AppComponent` for both agent and desktop applications to reflect the new method names. Remove `REFRESH_TOKEN_QUICKSTART.md`, `REFRESH_TOKEN_SUMMARY.md`, and `packages/desktop-ui-lib/REFRESH_TOKEN_IMPLEMENTATION.md`. These documentation files are no longer current or have been consolidated into other documentation. * feat(auth): implement token refresh mechanism Integrates TokenRefreshService to automatically renew authentication tokens. Starts the refresh timer on application initialization for existing sessions and after successful social login. Registers RefreshTokenInterceptor to handle token refreshing for outgoing HTTP requests, ensuring continuous user session without manual re-authentication. * refactor(interceptors): centralize auth endpoint patterns Extract authentication endpoint paths into a dedicated `AUTH_ENDPOINTS` constant. This change reduces duplication and improves maintainability by providing a single source of truth for endpoints that should be excluded from automatic token refresh and unauthorized redirect logic. Updated `RefreshTokenInterceptor` and `UnauthorizedInterceptor` to utilize this new constant. Includes minor formatting improvements in `app.module.ts`. * refactor(interceptors): reorder RefreshTokenInterceptor Move RefreshTokenInterceptor after UnauthorizedInterceptor. This ensures that unauthorized responses are processed by the UnauthorizedInterceptor first, allowing for subsequent token refresh attempts in the correct order within the HTTP interceptor chain. |
||
|
|
1234e1ce54 |
feat(plugins): add comprehensive plugin management permissions (#9155)
* feat(plugins): add comprehensive plugin management permissions Introduces a new set of permissions for managing plugin lifecycle, configuration, and access control. This includes permissions for: - Viewing & Discovery (e.g., PLUGIN_VIEW, PLUGIN_DISCOVER) - Lifecycle Management (e.g., PLUGIN_INSTALL, PLUGIN_UNINSTALL, PLUGIN_UPDATE, PLUGIN_ENABLE, PLUGIN_DISABLE) - Configuration & Security (e.g., PLUGIN_CONFIGURE, PLUGIN_PUBLISH, PLUGIN_RESTRICT, PLUGIN_ASSIGN_ACCESS, PLUGIN_DELETE, PLUGIN_DELETE_FOREVER) These permissions are defined in `PermissionsEnum`, assigned to relevant default roles (e.g., SUPER_ADMIN, ADMIN, MANAGER), and a new database migration ensures they are applied to existing installations. * fix: spelling of 'permisions' to 'permissions'. Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: missing PLUGIN_DELETE_FOREVER permission for ADMIN role. Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * refactor(migrations): remove unused code from RolePermissionsReload migration Remove boilerplate database-specific `down` migration logic and empty helper methods (`*UpQueryRunner`, `*DownQueryRunner`) from the `RolePermissionsReload` migration. This simplifies the migration file by removing redundant code. * fix: correct missing closing bracket in default role permissions Adds the missing closing square bracket for a permissions array within 'default-role-permissions.ts'. This resolves a potential syntax issue or incomplete array definition. Also, updates 'package.json' by adding the 'packageManager' field. This ensures a consistent Yarn version (1.22.22) is used across all development environments, leveraging tools like corepack for enforcement. * feat(role-permission): grant default PLUGIN_DELETE permission Adds the PLUGIN_DELETE permission to the default set of permissions for roles with plugin management responsibilities. This ensures that these roles can fully manage plugin lifecycles, including removal. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> |
||
|
|
de31f06ad8 |
[Fix] Sentry integration in desktop timer (#9105)
* refactor(app): improve AppModule readability and Sentry import Reorder and group third-party library imports (Nebular, NgSelect, Translate) to improve consistency within the import section. Update the Sentry Angular SDK import path from `@sentry/angular-ivy` to `@sentry/angular`, aligning with the latest SDK conventions. Standardize indentation within the `@NgModule` decorator for enhanced code readability and adherence to style guidelines. * style(desktop-timer): reorder module imports Group related external and internal module imports for improved readability and consistency within the main application module. |
||
|
|
55ded12716 |
Merge pull request #9028 from ever-co/fix/memory-leaks-cleanup-events
[Fix] Memory leaks cleanup events |
||
|
|
246401d452 |
[Feat] Implement UI for soundshot/camshot (#9002)
* feat(videos-ui): add camshots state management and service
Add Akita store, effects, queries, and actions for managing camshot state.
Implement Angular service to fetch camshots from the API endpoint.
Define camshot model interface and class.
* refactor(videos-ui): simplify camshot query and model usage
Update CamshotQuery to directly use ICamshot interface instead of the Camshot class for camshots and camshot observables. This change enhances type safety and reduces unnecessary object instantiation, streamlining the state management for camshots.
* feat(videos-ui): add components for camshot list
Implement UI components for displaying a list of camshots.
Includes:
- camshot-list component (main container)
- camshot-item component (individual item)
- camshot-item-skeleton component (loading placeholder)
Uses Angular's @defer with 'on viewport' trigger for lazy loading individual camshot items and a minimum placeholder duration.
* refactor(videos-ui/camshots): refactor camshot list data flow
Refactor CamshotListComponent to consume camshots data from the
CamshotQuery observable instead of using an input property.
Refactor CamshotItemComponent to define its action buttons internally
based on the camshot's state (e.g., deleted status) and emit specific
events for each action (view, download, recover, delete, hard delete).
Remove the actions input from CamshotItemComponent.
Add CamshotItemComponent, CamshotItemSkeletonComponent, and
CamshotListComponent to the video-ui module declarations as they are
no longer standalone.
* feat(videos-ui): add camshots tab to video detail page
Display camshots associated with the video's time slot in a new tab on the video detail page.
Implement infinite scroll pagination for the camshot list to efficiently load camshots.
Refactor camshot list component to accept the time slot ID as input and manage its own data fetching and state based on the provided ID.
* feat(videos-ui): improve list display and loading
Introduce deferred loading for video and camshot lists on the detail page to
improve initial page load performance using Angular's @defer syntax.
Redesign the camshot item display by changing action buttons to a popover
menu accessed via an icon and updating the layout and styling of the
thumbnail, title, and meta information.
Adjust the initial and reset skip value in the camshot list component
to fix a potential pagination issue.
* refactor(camshot): restructure item skeleton html and style appearance
Restructure the HTML elements of the camshot item skeleton (e.g.,
using divs instead of semantic tags) to provide better hooks for
styling. Update the SCSS to apply new styles and refine the pulsing
animation colors and layout. Add overflow styling to the camshot
list container.
* refactor(video-detail): improve list loading and infinite scroll
Update camshot and similar video lists on the video detail page to:
- Display more informative 'Loading...' messages using ngx-no-data-message.
- Rename 'Videos' tab to 'Similars'.
- Prevent fetching camshots when timeSlotId is not available.
- Enable infinite scroll pagination for camshots only after the
initial data has loaded and timeSlotId is present.
- Remove unused console.log.
- Add minor styling to tab links.
* feat(camshot-item): emit full camshot object from item actions
Change camshot item action outputs to emit the full ICamshot object
instead of just the ID. Update output event emitter types and
button action callbacks to reflect this change.
* refactor(camshot-item): replace static button labels with i18n keys
Prepare the component for internationalization by using localization keys
instead of hardcoded strings for button labels.
* feat(videos-ui/camshot): add view, delete and restore functionality
Implement actions, effects, store updates, and service methods
for managing individual camshots.
Adds the ability to view, soft delete, hard delete, and restore
camshots from the UI.
Updates the camshot item component to emit events for these actions
and adds a delete confirmation dialog in the list component.
* feat(camshot): add loading state to actions and list deleted
Implement loading state feedback for action buttons in the UI.
Introduce an `ActionButton` class to standardize button properties and include a `loading` observable. Update camshot item component to use this class and bind the loading state of delete and recover actions to the respective query states (`deleting$`, `restoring$`). Update the action button component template to display a spinner based on the loading state.
Modify the `ListCamshotQueryHandler` to include deleted camshots (`withDeleted: true`) in the results, enabling recovery and hard delete actions from the list view. Refine the logic for filtering camshots by the current employee's uploads.
Includes minor UI updates: change recover icon to `refresh-outline` and soft delete button status to `danger`.
* feat(camshot): add downloading state for camshot item
Expose a downloading state observable via the query and add it to the camshot item component to show a loading indicator during download.
* feat(camshot): implement soft-deleted camshot recovery
Add backend endpoint, CQRS command, and handler to recover soft-deleted
camshot entities.
A new PATCH /plugins/camshots/:id endpoint is added to the CamshotController
to trigger the recovery command. The RecoverCamshotCommand and its handler
utilize the softRecover method in the CamshotService to restore the entity.
The DeleteCamshotCommandHandler is updated to correctly query for soft-deleted
entities using `withDeleted: true` when handling deletion commands,
particularly for forceDelete operations.
UI changes in the videos-ui plugin add event handlers and actions
(`onRecover`, `onHardDelete`) for the camshot list component to interact
with the new recovery and updated hard delete logic.
* feat(videos-ui/camshots): add camshot download feature
Implement the download camshot feature.
Adds a new action and effect to handle adding camshots to the download queue service.
Connects the download functionality to the camshot list component.
Updates modal titles for clarity and adds styling for no data message.
* feat(videos-ui/camshot): add dialog to view camshots
Implement a modal dialog component for viewing camshot images.
Replaces the console log action when clicking "view" on a camshot with opening
this new viewer dialog.
The viewer includes basic controls like zooming, loading state, and error
handling.
Updated the camshot query to include the 'uploadedBy' relation for displaying
the uploader's name in the viewer metadata.
Updated the camshot model to include the 'uploadedBy' property.
Includes necessary Angular NgOptimizedImage import for performance.
* feat(camshot-viewer): enhance image viewer with pan, drag, and ui updates
Implement image pan and drag functionality when the image is zoomed.
Redesign the user interface with floating header, updated loading/error states, floating zoom controls, and hoverable metadata.
Improve overall layout, styling, and responsiveness of the viewer dialog.
* fix(soundshot): remove IsUrl validator from file url
* feat(videos-ui/soundshot): add soundshot state management
Add Akita state management slice for soundshots, including:
- Actions for fetch, delete, restore, download
- Effects to handle actions and update store
- Query to select state data
- Store to hold soundshot state
- Service to interact with soundshot API
- Model definition
* feat(videos-ui): add sounshots list and player
Implement feature to display and play sounshots.
- Add `SounshotListComponent` with infinite scroll.
- Create `SounshotPlayerComponent` for audio playback.
- Introduce `SounshotPlayerSkeletonComponent` for loading states.
- Integrate list into video detail page with a new tab.
Includes updates to Codacy configuration, Codacy CLI script,
.gitignore, and .vscode/settings.json.
* feat(videos-ui/soundshot-player): add interactive player controls
Implement play/pause, seeking, and volume control for soundshots.
Display track duration and file size.
Refactor component logic using Angular signals and update template/styles.
Remove outdated spec file and Codacy configuration.
* style(soundshot-player): remove max width from player
Allow the player component to take up the full width of its container.
* refactor(soundshot-skeleton): restructure player skeleton
Rewrite the HTML and SCSS for the soundshot player skeleton
component.
Simplifies the layout structure and updates the animation
style. Also changes the background color variable.
* feat(soundshot-player): add cover image and update layout
Add a cover image element to the soundshot player component.
Adjust the layout to display the cover image alongside the soundshot
title and metadata on wider screens. Maintain a stacked layout on
smaller screens.
* style(soundshot-skeleton): improve skeleton layout and animation
Add a placeholder for the cover image to the soundshot player skeleton.
Refactor the layout of the title and meta information to accommodate
the new cover.
Apply the skeleton loading animation consistently to all significant
elements within the skeleton (cover, title, meta items, controls,
progress, time, volume).
* feat(soundshot-player): add actions popover
Add a popover with action buttons to the soundshot player component.
Include download, delete, and conditionally recover/hard delete actions based on the soundshot status.
Allows users to perform actions directly from the player UI.
* style(soundshot-player): update styling and layout
Adopt CSS variable for border radius for consistency.
Change align-items to flex-start in soundshot info.
Add transition for smoother visual updates.
Add specific styles for the actions element.
* feat(soundshot-player): emit player button action events and add loading state
Replace placeholder console.log actions for player buttons with EventEmitter
outputs. This allows parent components to handle the corresponding actions
such as download, recover, soft delete, and hard delete.
Add loading state indication to buttons based on query status for improved
user experience.
* feat(videos-ui): implement soundshot actions
Implement download, recover, soft delete, and hard delete actions for soundshots.
Add event handlers in the soundshot list component to dispatch corresponding
actions. Use confirmation modals for delete and hard delete operations.
Add visual styling to indicate deleted soundshots in the player component.
* fix(soundshot): include soft-deleted entities in delete lookup
When handling the delete command, the service needs to locate the
soundshot entity even if it has been previously soft-deleted.
Using `findOneByOptions` with `{ withDeleted: true }` ensures the
lookup finds the entity regardless of its soft-delete status.
* feat(soundshot/query): include deleted soundshots
Modify the query handler to pass `withDeleted: true` to the
pagination service, ensuring soft-deleted soundshots are
included in the results.
* feat(videos-ui): add toast notifications for restore and delete
Add toast notifications for camshot and soundshot restore and delete
operations.
These toasts inform the user about the status of the operation,
including when it starts, succeeds, or fails. This provides clearer
feedback than just updating the UI state.
* style(soundshot-player): reduce deleted background opacity
* feat(soundshot): add soundshot recovery endpoint and command
Implement command, handler, and controller endpoint to allow soft-recovering
a previously deleted soundshot record.
* feat(soundshot): allow filtering soundshots
Update GetSoundshotsQueryDTO to accept a generic FindOptionsWhere for the
where clause. This removes the previous limitation requiring
TenantOrganizationBaseDTO and a custom transformation.
Utilize the where clause in the soundshot list component to filter by
timeSlotId.
* refactor(soundshot): remove ValidateNested import
* fix(camshot): correctly apply filters to camshot query
When listing camshots, ensure that users without the
CHANGE_SELECTED_EMPLOYEE permission are correctly filtered by
their uploadedById. If a user lacks this permission and does
not have a current employee ID, return an empty result set
immediately to prevent unauthorized data exposure or query errors.
Also, ensure that the dynamically built 'where' clause (from
permissions or date filters) is correctly merged with any base
'where' conditions provided in the query parameters.
Update internal comments for accuracy.
* fix(videos): refine list query filtering and permissions
Add stricter checks in the list videos query handler:
- Ensure `employeeIds` filter is only applied for users
with the `CHANGE_SELECTED_EMPLOYEE` permission.
- Return empty result if user lacks permission and
current employee ID is missing.
- Include soft-deleted records in the query results.
Also update a comment in the list camshot query handler.
* refactor(videos): refactor video count query handler with validation
Add explicit validation for required query options (organizationId,
tenantId) to ensure the handler receives necessary parameters.
Refactor the handler by extracting validation and where condition
building logic into separate private methods. This improves code
structure, readability, and testability.
Enhance JSDoc comments to better explain the handler's purpose,
parameters, and behavior.
* chore(videos-ui): correct sounshot typo in soundshot components
Update component names, selectors, and file paths from "sounshot" to "soundshot" to fix consistent misspelling. This affects the soundshot list, player, and skeleton components and their imports.
* chore(cspell): ignore rules directory
* chore: ignore .codacy directory in spell check
* fix(video-detail-page): update similar tab title
* fix(camshot): correct recover camshot handler filename and import
Correct a typo in the filename for the recover camshot command handler and update the corresponding import path.
* fix(camshot): improve message for camshot recovery not found
Provide more detailed reasons when camshot recovery fails due
to not found or other issues.
* fix(video-detail-page): fix soundshot loading message status
Change the status of the placeholder message displayed while
soundshots are loading from danger to info. Danger status is misleading
for a simple loading state; info status better reflects the ongoing
process.
* fix(video-detail-page): correct loading message and status
Update the loading message from 'Loading camshots...' to
'Loading similar videos...' to accurately reflect the content.
Change the status from 'danger' to 'info' as the loading state
is not a critical error.
* style(camshot-list): clean up formatting
* fix: incorrect grammar in description
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix(soundshot-player): improve seek function robustness
Add checks to ensure the audio player and progress bar elements
are available before attempting to calculate the seek position.
Also add a check for zero width on the progress bar.
Wrap the seek operation in a try/catch block to gracefully handle
potential errors during playback updates.
Include console warnings/errors for debugging missing elements
or failed seek operations.
* fix: Duplicate 'nbButton' attribute on lines 2 and 5. Remove one instance.
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix: property 'border-radius-top-left' is invalid
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix: no feedback shown when isAdded is false. User should be notified if download queue addition fails
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix: command should implement ICommand interface from @nestjs/cqrs to follow CQRS pattern
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* feat(soundshot): return recovered soundshot from patch
Return the updated soundshot object after recovery.
This allows the client to immediately use the refreshed state of the
soundshot without needing a subsequent GET request.
BREAKING CHANGE: The PATCH /soundshots/:id endpoint now returns the
recovered soundshot object instead of nothing.
* fix: API description has a typo 'UUID, version UUID the plugin ID'
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* chore: remove sensitive nx cloud access token
Remove the hardcoded token from nx.json.
Environment variables or secrets management
should be used instead.
* style(camshot): fix formatting and API description typo
Correct constructor formatting in CamshotController and RecoverCamshotCommand. Update API description to remove redundancy in the recover camshot operation.
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
|
||
|
|
d1c5150e30 |
[Feat] Implement sound shot plugin (#8998)
* feat(plugin-soundshot): add plugin package Includes basic Nx configuration, package.json, tsconfig files, and a placeholder NestJS module for the new plugin. * feat(soundshot): add soundshot plugin Implement the soundshot feature including entity, services, and API endpoints for managing short audio recordings. This change introduces: - Soundshot entity definition with relations and file storage details. - DTOs for creating, deleting, and counting soundshots. - CQRS commands and queries for soundshot operations (create, delete, list, get, count). - Service layer with file upload preparation, validation, and interaction with storage providers. - Controller with REST endpoints for soundshot CRUD and listing. - TypeORM subscriber to manage file lifecycle (generate URL on insert, delete file on remove). - Updated plugin structure with dedicated module and entry point. * feat(soundshot): increase soundshot size limit Update the maximum allowed size for a soundshot file from 5MB to 100MB to accommodate larger or higher quality audio recordings. * docs(soundshot): update file examples and patterns to webm Update the FileDTO within the soundshot plugin to use .webm file examples and patterns instead of .png. This change aligns the DTO descriptions and expected file formats with the typical use case for soundshots, which are expected to handle audio or video content rather than static images. * feat(soundshot): add plugin Integrate Soundshot plugin into the API application by adding it to the list of available plugins. Refactor query handlers within the soundshot plugin package. Rename camshot-related handlers to soundshot handlers and update the exported list of handlers. * feat(soundshot): add media detail fields and rename title Rename the main identifying field from `title` to `name` across contracts, entity, and DTOs for improved clarity. Introduce `channels` and `rate` fields to the soundshot entity and contract to store audio media specific details. Update the creation process to allow setting the `name` explicitly via the `CreateSoundshotDTO` instead of deriving it from the uploaded file name. Removed explicit `size` mapping in the creation handler. Relaxed MIME type validation in the file DTO to permit any `/webm` subtype. * chore(soundshot): adjust delete soundshot command type format Update the static type string to follow the [Plugin] Action pattern. * refactor(soundshot): make soundshot delete error messages more specific Include tenant and soundshot IDs in error messages thrown during soundshot deletion. This provides more context for debugging when the requested resource is missing or the required IDs are not provided. * feat(soundshot): add dedicated soundshot query dto with filters Introduce GetSoundshotsQueryDTO to handle specific query parameters for listing soundshots, including date range, time zone, and employee IDs. This replaces the generic BaseQueryDTO in the soundshot list endpoint for improved type safety and clarity of available filters. Update findById endpoint to use FindOptionsQueryDTO. * feat(soundshot): add soundshot plugin package Add package metadata, dependencies, build scripts, and initial README documentation for the soundshot plugin. This plugin provides functionality to upload and manage sound shots. * build: include soundshot plugin Update package dependencies, build scripts, and Dockerfiles to integrate the soundshot plugin. Also add relevant terms to the spellcheck dictionary. * feat(database): add soundshots table * refactor(soundshot): make repository injectable Add Injectable decorator to allow the repository to be injected by the NestJS framework. * fix: doc comment mentions 'image file' but this is for audio files Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * feat(soundshot): add uploader fields to soundshot model Add `uploadedById` and `uploadedBy` properties to the `ISoundshot` interface to track which employee uploaded a soundshot. * docs(soundshot): update comments for entity properties Correct comments for `channels` and `rate` properties by removing inaccurate reference to bytes. Remove outdated note about maximum duration limit from `duration` property comment. * chore: configure codacy and update gitignore Add .codacy/codacy.yaml to specify analysis runtimes and tools. Update .gitignore to exclude .cursor directory and specific AI rule files. Improve JSDoc for the rate property in the Soundshot entity. * refactor(soundshot): use injected file storage provider Replace direct instantiation of `FileStorage` with the injected `this.fileStorage` instance within the prepare method. This aligns the service with dependency injection patterns and improves testability. * style(soundshot): apply formatting and fix comment Apply minor formatting to constructor and correct comment to reference the correct property `recordedAt` instead of `valueDate`. * build(server-api): remove duplicate posthog plugin reference from package files * docs(soundshot): clarify channels validation message Update the validation message for the 'channels' field in the Soundshot entity to provide clearer context regarding audio channels (mono/stereo). Also applies minor code formatting. * refactor(soundshot): use spread syntax for merging query params * fix(soundshot): re-throw error in subscriber beforeInsert Ensure that errors occurring during URL generation in the `beforeInsert` hook are propagated correctly. * refactor(soundshot): use service to get file storage provider for cleanup Obtain the file storage provider instance from the injected SoundshotService during error cleanup instead of creating a new FileStorage instance. This ensures consistency and avoids unnecessary object creation. Also update getFileStorageProviderInstance in service to allow retrieving the current provider without explicitly setting the enum. * feat(soundshot): add url validation to file dto * docs(soundshot): clarify soundshot channels property description Update JSDoc comment and validation message for the channels property to explicitly state it represents the number of audio channels. * fix(soundshot): fix soundshot query where property documentation The 'where' property in the GetSoundshotsQueryDTO was documented with @ApiProperty, incorrectly implying it was required. This change uses @ApiPropertyOptional to correctly reflect its optional status. * chore(cspell): add runtimes to dictionary * docs(soundshot): mark startDate and endDate as optional in count dto Update @ApiProperty to @ApiPropertyOptional and make type definition explicit using '?'. This aligns documentation and type hints with the @IsOptional validation already in place. * refactor(soundshot): clarify date types in count soundshot dto The startDate and endDate fields are already validated as ISO 8601 strings using the @IsISO8601 decorator. Update the type annotation to reflect this expected format and remove the redundant 'Date' type from the union. --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> |
||
|
|
62be88a755 |
[Fix] AI suggestion stage (#8996)
* chore(cspell): remove typo from cspell dictionary * chore(camshot): update delete command type * refactor(camshot): include id in camshot not found error message * docs(config): add jsdoc to activepieces property * refactor(camshot): standardize find options type for findById Replace TypeORM's FindOneOptions with the application's standardized FindOptionsQueryDTO for consistency in query parameter handling. * feat(integration-activepieces): use dto for activepieces query params Create ActivepiecesQueryDto to define the structure, typing, and validation for query parameters handled by the ActivepiecesAuthorizationController. Replace the 'any' type annotation with ActivepiecesQueryDto in the authorize and callback methods. This improves type safety and enables automatic validation and Swagger documentation generation for the API endpoints. * chore(integration-activepieces): remove empty entities array from plugin config The `entities` array in the Activepieces VendurePlugin configuration was declared but empty and served no purpose. Remove the array and the associated comment to clean up the configuration. * fix(activepieces): improve error handling for connection Update error handling in `createActivePiecesConnection` to provide more specific exception types. Catch and re-throw `UnauthorizedException` explicitly, and wrap other errors in `InternalServerErrorException` for clearer reporting downstream. * docs(common): fix typo in callback url documentation * refactor(activepieces): remove unused ID import * style(camshot): improve not found error message Add 'id' before the variable for clarity. Adjust formatting in the constructor. * docs(camshot): add api docs for get camshot by id add @ApiResponse decorators for status codes 200, 404, and 500 add @ApiQuery decorator for the optional options parameter * refactor(activepieces): rename query dto and add validation Rename ActivepiecesQueryDto to ActivepiecesQueryDTO for naming consistency. Add ValidationPipe to the authorize endpoint to ensure incoming query parameters are validated against the DTO schema. This improves input handling robustness. * fix(activepieces): correctly handle boolean setting values The previous implementation of `isIntegrationEnabled` only handled boolean values stored as JSON strings. This update adds support for boolean values stored as native booleans or other types, ensuring the check works correctly regardless of how the setting value is stored. * fix(activepieces): fix error handling and reporting Extract detailed error messages from the ActivePieces API response body when handling errors during connection creation. This provides users with more specific information about why a connection failed. Also, ensure that specific HTTP exceptions caught within the HTTP request observable's catchError are not subsequently wrapped in a BadRequestException by the outer try-catch block. This preserves the original HTTP status code and error type. |
||
|
|
33810da039 |
[Fix] API Missing dependency (#8995)
* docs(plugin-camshot): update readme Update README title to use the full package name `@gauzy/plugin-camshot`. Add overview of plugin functionality. Include instructions for building, testing, publishing, and installing the plugin. * build(plugin-camshot): setup package json Add standard package metadata fields (description, author, repo). Define build scripts for the plugin. Include core, contracts, and plugin dependencies. Update package version to 0.1.0. * feat(api): add camshot plugin Add dependency for the @gauzy/plugin-camshot. * chore(camshot): clean up readme and package description Fix typo in package.json description field. Adjust punctuation and formatting in README.md for improved readability. |
||
|
|
96173bd303 |
Merge pull request #8991 from ever-co/feat/implement-camshot-plugin
[Feat] Implement camshot plugin |
||
|
|
ab332a3791 |
chore(deps): update dependencies in yarn.lock
- Bump @cypress/request from 3.0.6 to 3.0.8 - Update qs from 6.13.0 to 6.14.0 - Upgrade @verdaccio/auth, @verdaccio/config, @verdaccio/core, and other Verdaccio packages to 8.0.0-next-8.15 - Update compression to 1.8.0 - Upgrade pino to 9.6.0 and other related packages - Remove deprecated versions and clean up unused dependencies |
||
|
|
382d169b4b |
feat(desktop-ipc): persist time slot id on return (#8986)
Store the time slot ID in local storage when returning to a time slot. Also destructure event arguments for clarity. |
||
|
|
0278f4e968 |
[Feat] Enhance plugin registry (#8976)
* feat(contracts): add plugin os type and arch enums
Add enums to define the operating system type and architecture a plugin is compatible with.
* feat(plugins): add OS type and architecture support to plugin entities
- Add PluginOSType and PluginOSArch enums to plugin source entity
- Update plugin version entity with extended metadata support
- Modify plugin installation entity for enhanced compatibility tracking
* feat(plugins): implement file processing strategy pattern
- Add file processing strategy factory for handling different file types
- Create file processor context for strategy orchestration
- Implement multiple and single file processing strategies
- Add file processing interface for standardization
- Update uploaded plugin storage to use new processing system
* feat(plugins): update controllers and handlers for enhanced plugin processing
- Refactor plugin management controller with new OS type support
- Update plugin version controller for improved file handling
- Modify command handlers to integrate with new file processing system
- Enhance plugin version handling with extended metadata support
- Update uninstall and update handlers for better compatibility
* feat(plugins): update supporting services and DTOs for plugin enhancements
- Update DTOs to support new plugin metadata fields
- Enhance plugin source and version models
- Modify security service for new plugin validation
- Update plugin source service with extended functionality
- Refine subscriber for enhanced plugin lifecycle management
- Update plugin factory utilities for new features
* refactor(plugin): restructure source and version models
Allow multiple sources per plugin version. Associate sources and installations
directly with the version instead of the plugin. Add operating system and
architecture fields to sources. Replace authToken with a private field
for NPM sources.
* feat(plugins): implement plugin sources listing
- Add ListPluginSources query and handler
- Create dedicated PluginSource controller
- Update version history component in desktop UI
- Add proper exports in index files
* feat(desktop-plugins): implement plugin source state management
- Add plugin source actions for state mutations
- Create plugin source effects for handling side effects
- Implement plugin source query for state selection
- Add plugin source store for state management
* refactor(desktop-plugins): implement service layer architecture
- Add builders for structured form data creation
- Create source factory for plugin source instantiation
- Implement source strategies for CDN, NPM, and Gauzy sources
- Add shared plugin models
- Update plugin service to use new architecture
* feat(plugin-marketplace): add source selector component
Introduce a dedicated component for selecting plugin sources within the
marketplace. This component integrates with the plugin source state
management to load and display available sources with pagination.
Renames the `selectVersion` action to `selectSource` for clarity and
adjusts data handling in the upload component accordingly.
* feat(plugin-marketplace): enhance UI components for plugin installation and version management
- Add installation validation dialog component
- Update version creation and selection components
- Improve marketplace item display and interaction
- Enhance plugin upload and source selection UI
- Update marketplace component structure
* feat(plugin-services): enhance plugin service layer and form handling
- Update plugin service with new marketplace capabilities
- Improve form data builder for plugin submissions
- Update plugin module configuration
* feat(plugin-registry): enhance plugin registry infrastructure
- Update plugin subscriber for improved event handling
- Enhance create plugin DTO with additional validation
- Improve plugin version DTO structure
* chore(desktop): update supporting components and dependencies
- Update desktop timer package dependencies
- Enhance spinner button directive functionality
- Improve marketplace detail component
* chore(spinner-button): initialize isSpinning as null
* feat(plugin-marketplace): add base plugin form infrastructure
* feat(plugin-marketplace): enhance plugin source management with creator and forms
* feat(plugin-marketplace): enhance upload workflow components for metadata, versioning, and basic information
* feat(plugin-marketplace): update module configuration for new components
* fix(plugin-upload): correct plugin upload source form array handling
Refactors the plugin source section in the upload form to correctly use a FormArray for handling multiple sources.
Updates the template binding to use `[formGroupName]` and pass the individual source form group to the `lib-plugin-source` component. Fixes the submission logic to correctly close the dialog with the full form value, including all sources in the array.
Includes minor UI improvements such as an empty state message for the sources list and disabling the "Add Source" button when no type is selected. Also cleans up redundant form control checks in templates and adds a null check for the form in the base component.
* refactor(plugin-marketplace-upload): replace formbuilder with direct instantiation
Replace FormBuilder usage with direct FormGroup, FormArray, and FormControl instantiation for creating reactive forms in the plugin marketplace upload components.
* refactor(plugin-marketplace-upload): remove default cdn source from form
Initialize the plugin source form without a default CDN source.
Adjust patch logic to ensure a source is added when creating a new plugin, as the form no longer starts with an initial source.
Also remove unused console.log.
* feat(plugin-marketplace): add support for multiple plugin sources
Allow defining multiple sources for a single plugin version.
The version form now uses a `sources` FormArray instead of a single `source` control. Updated the UI and logic for creating and uploading plugin versions to manage the list of sources, allowing users to add or remove source entries.
This enables specifying different sources (e.g., per operating system or architecture) for a single version release.
* feat(plugins/upload): implement source drag-and-drop and redesign add source ui
Refactor the plugin source management section in the marketplace upload component to enhance usability and visual design.
Key changes include:
- Introduce drag-and-drop functionality for reordering sources using Angular CDK.
- Redesign the "Add Source" experience to use a clickable card revealing an inline source type selector.
- Update styling for source cards with hover effects and add an empty state message.
This provides a more intuitive and polished user interface for configuring plugin sources.
* refactor(plugin-marketplace-upload): refactor UI layout and styles
Update layout of source options from grid to flex.
Adjust styling for headers (h4 to h5) and icon spacing.
Prevent click propagation issues in the source type selector.
Refactor source type icon mapping using a Map and update some icons.
* perf(plugin-marketplace): optimize form rendering and layout
Apply OnPush change detection strategy to plugin source forms (CDN,
Gauzy, NPM) to reduce unnecessary change detection cycles and
improve rendering performance.
Add a minimum width to the plugin container to prevent layout
instability or collapse issues.
* fix(plugin-marketplace): guard plugin form templates
Add `*ngIf="form"` and `*ngIf="form.get(...)"` checks to form elements
in plugin source components (cdn-form, gauzy-form, npm-form,
plugin-source).
This prevents potential template errors or rendering issues when the
form or its controls are not yet available.
Also remove `[formGroupName]` from the plugin marketplace upload
source card component.
* feat(plugin-marketplace): refactor plugin version create dialog with stepper and drag-drop
Restructure the dialog into a two-step process: configure sources, then
version details.
Add drag-and-drop functionality to reorder plugin sources.
Implement a new interactive UI for adding and selecting source types.
Change default operating system for new sources to Universal.
Remove redundant source type selection from individual source component.
* chore(plugins): cleanup marketplace templates
Remove unused hover actions in the plugin upload form.
Modify the source type header text in the create version dialog template.
* feat(plugins): enhance plugin and source models with additional properties
* feat(plugin-marketplace): enhance installation validation and source selection UI
* feat(plugin-marketplace): improve plugin source state management and services
* feat(plugin-registry): enhance plugin source entity and subscriber handling
* fix(plugins): refresh source selector on plugin or version change
Add OnChanges hook to the source selector component to reload the list
of sources whenever the input pluginId or versionId changes. This
ensures the source list correctly reflects the selected plugin/version
if inputs are updated after initial component load.
Remove redundant initial load from ngOnInit as ngOnChanges handles
the initial binding.
Also includes minor styling adjustments to the plugin installation
dialog and a cleanup in the form data builder by removing an unused
argument from appendSource.
* fix(plugins): reset plugin installation state on dialog close
Previously, closing the plugin installation validation dialog without
selecting a version or source would not reset the UI state, such as an
installation indicator.
Add a check after the dialog closes to dispatch an action that resets
the installation state if no data is provided.
* refactor(plugins): refactor plugin installation logic
Break down the installPlugin method into smaller private methods for
improved readability and maintainability.
Extract the creation of the installation observable, handling of the
dialog response, and error handling into dedicated methods. Explicitly
set the return type for handleDialogCloseWithoutData.
* feat(plugin-marketplace): add source selector to details view
Add a dropdown to the plugin marketplace item details view to allow selecting
the source associated with a plugin version. The source code display now
reflects the content of the selected source.
Includes CSS updates to add overflow scrolling to plugin-related dialogs to
prevent content overflow.
* fix(plugins/registry/application): validate query and refine source list filtering
Add validation for required pluginId.
Conditionally include 'version' and 'version.plugin' relations
when 'versionId' is provided to ensure correct joining.
Refine the filter logic to explicitly target the correct plugin
and version, while also ensuring the associated plugin is active
and not deleted.
Wrap logic in a try/catch block to provide better error feedback.
* feat(plugin-marketplace-state): add effects to manage plugin source selection and reset
These effects update the plugin source state in the store when the
`selectSource` or `reset` actions are dispatched. The `selectSource`
effect sets the currently selected source, and the `reset` effect
clears the list of available sources.
* chore(plugins): remove OnDestroy hook from plugin selectors
Remove the OnDestroy lifecycle hook and associated cleanup logic
from the source and version selectors.
In the version selector, the reset logic previously in
ngOnDestroy is moved to a public method and called from
ngOnChanges to reset and reload data when the pluginId input
changes, providing better state management tied to component
inputs.
The source selector's ngOnDestroy method was also removed.
* refactor(plugin-source): update full name generation logic
Update the algorithm used to generate the full name for plugin sources.
- Use underscore (_) as a separator instead of double colon (::).
- Include the source version number if available.
- Attempt to extract and include the hostname for CDN and NPM URLs.
- Include the file name for uploaded GAUZY/FILE sources.
- Convert the final name to lowercase.
This provides a more consistent and informative name structure.
* feat(plugins-ui): add icon to installation dialog header
Add a cube icon to the header of the plugin installation validation
dialog. This provides a visual cue and enhances the dialog's title
presentation.
* feat(plugin-marketplace): conditionally show auth token input in validation dialog
Hide the auth token input in the installation validation dialog unless the selected source is marked as private.
This improves the UI by not showing irrelevant fields.
Also add an icon to the continue button and adjust the dialog height.
* fix(plugins-registry): fix typo in plugin private property
Correct the misspelled 'privtae' property name to 'private' when creating the plugin source object in the update plugin command handler.
* fix(plugin-marketplace): always show delete source button in create version dialog
Remove condition that hid the delete button when only one source was present.
This allows deleting the last remaining source. Also remove unused `source` component property.
* fix(marketplace): fix width of file drop areas
Apply a fixed width to the drag-and-drop file upload areas in the plugin marketplace components (create version dialog and upload component) to ensure consistent sizing.
* refactor(plugins): update plugin version to support multiple sources
Change the relationship between PluginVersion and PluginSource
from one-to-one (or one-to-nullable-one) to one-to-many.
- Rename `source` property to `sources` (array) on PluginVersion
entity, DTOs, and handlers.
- Update entity relations (`@OneToMany`, `@ManyToOne`,
`@JoinColumn`) and query relations accordingly.
- Adjust DTO validation (`@ValidateNested({ each: true })`) and
add `@IsOptional()` for the sources array.
- Add `architecture` and `operatingSystem` fields to plugin source
update DTOs and handlers.
- Update UI to display version number from `plugin.version.number`.
* fix(plugin-source): update source handler and private field validation
Change update service call to use only DTO data.
This ensures only fields present in the DTO are updated, avoiding unintended
side effects from merging the entire existing record.
Add boolean validation and transformation for the private field to correctly
handle incoming boolean values.
Exclude fullName from the update DTO and interface as it should not be updated
directly.
* refactor(plugins): adjust form data builder for file indexing
Update the plugin form data builder to change the key used for Gauzy
source file uploads from 'file' to 'files[{index}]'.
Pass the source index to the appendToFormData strategy method, which is
used by the Gauzy strategy to create indexed file entries.
Also, centralize the addition of the source 'type' property in the
common data section of the builder, removing it from individual
strategy implementations.
* refactor(plugins): simplify file upload handling
Replace LazyFileInterceptor with LazyAnyFileInterceptor to accept files from any field name using `multer.any()` on the backend.
Update frontend FormDataBuilder to append files using the 'file' key instead of indexed keys (`files[index]`).
Modify ISourceStrategy interface and implementations to align with the simplified file handling.
Update controller logic to match uploaded files using the stored file name.
BREAKING CHANGE: ISourceStrategy.appendToFormData signature changed, removing the index parameter.
* feat(plugins-registry): add create plugin source command and api
Implement a new command, handler, and API endpoint for creating a single plugin source under a specific version.
Refactor plugin source and version creation/update logic into dedicated service methods. Update existing command handlers (create-plugin, create-plugin-version, update-plugin) to utilize these centralized service methods. This prepares the services to be consumed by the new create source command handler.
* feat(plugins-registry): enhance plugin source management API and commands
- Add create plugin source DTO and command
- Implement plugin source command handler
- Update plugin source service with enhanced functionality
- Extend plugin source controller with new endpoints
* feat(plugin-marketplace): enhance state management for plugin sources
- Add new plugin source actions for source management
- Implement effects for plugin source operations
- Update plugin version effects
- Enhance plugin source query and store functionality
* feat(plugin-marketplace): enhance plugin marketplace components and services
- Update plugin marketplace item component with new functionality
- Extend plugin service with additional features
- Add shared UI components
- Update plugins module configuration
* feat(plugin-marketplace): improve plugin upload and version creation dialogs
- Refactor dialog-create-version component template
- Enhance plugin marketplace upload component
- Simplify upload form interface
- Improve user experience for version creation workflow
* feat(plugin-marketplace): add dialog for creating plugin sources
- Add new dialog component for plugin source creation
- Implement source creation form interface
- Support plugin source management workflow
* refactor(plugin-source): improve create endpoint definition
Rename the createVersion method to create for clarity.
Update the @ApiBody and @ApiResponse decorators to use the correct
DTO types (CreatePluginSourceDTO for input, [PluginSourceDTO] for output)
for better API documentation accuracy. Also update the method parameter
type accordingly.
* feat(plugins-registry): add endpoint and command to delete plugin source
Add CQRS command `DeletePluginSourceCommand`.
Implement `DeletePluginSourceCommandHandler` to soft delete a plugin
source by its ID, associated version ID, and plugin ID.
Add a new `DELETE /plugin-sources/:sourceId` endpoint in the
`PluginSourceController` to handle the deletion request.
Include input validation (UUIDs) and ensure user permissions using
`PluginOwnerGuard`.
Add logic to prevent deleting the last source associated with a plugin
version, ensuring at least one source file remains per version.
* fix(plugins): correct error message for deleting last source
The previous message incorrectly stated 'last version' when
the check prevents deleting the last 'source'. Update the
message for clarity.
* feat(plugins-registry): add ownership validation for listing sources
Before listing plugin sources, validate if the requesting employee is
the owner of the plugin. This ensures only authorized users can access
the sources and allows the owner to view sources of deleted plugins.
* feat(plugin-source): add plugin source recovery
Implement the ability to soft-recover previously deleted plugin sources.
This includes:
- Adding the `RecoverPluginSourceCommand` for the recovery operation.
- Creating the `RecoverPluginSourceCommandHandler` to perform the recovery using the service layer.
- Exposing the recovery functionality via a new PATCH endpoint in the `PluginSourceController`.
This feature allows users to restore plugin sources that have been soft-deleted, typically linked to a specific version and plugin.
* feat(plugin-source): implement delete and restore
Add functionality to soft-delete and restore plugin sources.
This commit implements the necessary actions, effects, and service
methods to perform soft-deletion and restoration via the API.
The UI components (SourceContainerComponent and its usages in
dialogs/upload forms) are updated to provide controls for these
actions, including confirmation dialogs.
Also rename addSource and removeSource outputs to add and remove on
SourceContainerComponent.
* feat(plugin-marketplace): add version selector to plugin forms
Integrate `gauzy-version-selector` into the create/edit dialogs for plugin sources and versions, and the main plugin upload/edit form.
This enables users to select a specific version when managing plugin details, sources, or versions in an edit context. Components are updated to use `PluginVersionQuery` to react to the selected version. Also includes minor fixes like null checks and event propagation stops.
* refactor(source-container): emit source index on restore event
The restore event now emits the index of the source being restored.
* feat(plugin-system): add OS and architecture retrieval via IPC
Implement a new IPC handler to retrieve the operating system type and architecture. This includes mapping platform and architecture values to the corresponding enumerations. Update the PluginHandlerChannel to include the new GET_OS channel for this functionality.
* fix(plugin-marketplace): simplify loading state in source and version selectors
Remove unnecessary condition from the loading state binding in both source and version selector components, ensuring a more straightforward loading indication.
* feat(plugin-source): enhance plugin source sorting by OS platform
Add functionality to sort plugin sources based on the operating system platform. This includes integrating the PluginElectronService to retrieve the OS information and updating the source list accordingly during creation and retrieval processes.
* refactor(database): alter plugin registry tables schema
Remove authToken column from plugin_source and sourceId from plugin_version.
Add operatingSystem, architecture, private, and versionId columns to plugin_source.
Change the foreign key relationship between plugin_source and plugin_version so that plugin_source references a specific plugin_version.
BREAKING CHANGE: Changes schema of plugin_source and plugin_version tables.
* refactor(plugin-marketplace): clean up event handling and improve form validation
Removed unnecessary click event propagation in the plugin marketplace item and upload components. Updated the version listener method name for consistency and improved the form validation logic to ensure accurate handling of sources and dates. Enhanced the sources getter to handle potential null values gracefully.
* chore(cspell): update spell check configuration and add new term
Added "Archs" to the cspell configuration for improved spell checking. Updated the formatting in the dialog-create-source component for consistency by correcting the version listener method name.
* fix(plugin-marketplace): fix typo in setup version listener method name
* fix(plugin-system): cleanup plugin event listener syntax
Reorder imports for consistency, remove unused import, and unquote object keys
in map literals.
* fix: code scanning alert no. 265: Inefficient regular expression
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix: code scanning alert no. 263: Inefficient regular expression
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix: code scanning alert no. 264: Inefficient regular expression
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix: code scanning alert no. 267: Inefficient regular expression
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix: code scanning alert no. 269: Inefficient regular expression
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix: code scanning alert no. 270: Inefficient regular expression
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* refactor(plugin-marketplace-upload): use shared pattern for website url validation
Replace repeated inline regex with a shared pattern constant for website URL validation.
* refactor(plugin-marketplace): use website url pattern constant
Replace inline regex for URL validation with imported constant pattern
* fix: code scanning alert no. 271: Inefficient regular expression
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* feat(i18n): internationalize plugin source and installation messages
Move hardcoded strings and generic translation keys to new, specific i18n
keys for plugin source effects, dialog titles, and installation validation
messages.
Add corresponding translation strings for multiple languages for plugin
source creation, deletion, restoration, and installation toasts and dialogs.
* feat(plugins-ui): add i18n to marketplace and source templates
Apply translation pipes (`| translate`) to various text elements in the plugin
marketplace item and source container components. Add corresponding translation
keys and values to the internationalization files across supported languages.
Remove the empty state message from the source container template. Improve
HTML template formatting for better readability.
* fix: code scanning alert no. 272: Inefficient regular expression
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix: code scanning alert no. 273: Inefficient regular expression
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix(npm-source): update npm registry url validation pattern
Refine the regex used to validate the NPM registry URL format.
* refactor: rename delete plugin source command handler
Remove redundant 'command' from file name
* style(spinner-button): add explicit type annotation to _isSpinning
Add boolean | null type for clarity and stricter type checking
* fix(plugin-marketplace-detail): handle missing plugin version
Safely access the plugin version number in the template
using optional chaining (`?.`) to prevent errors if the
`plugin.version` object is null or undefined.
* refactor(plugins): make source strategy generic
Improve type safety for plugin source strategy implementations.
Use a generic type parameter on the ISourceStrategy interface
and its concrete classes to specify the expected type of the
source object passed to the strategy methods.
* feat(contracts): add os and architecture to plugin source model
Add operatingSystem and architecture properties to the IPluginSource
interface to support platform-specific plugin targets. Remove the
fullName property.
Update the INPMSource interface to replace the optional authToken
with an optional boolean `private` property for simpler indication
of private packages.
BREAKING CHANGE: IPluginSource requires operatingSystem and architecture.
BREAKING CHANGE: IPluginSource no longer has fullName.
BREAKING CHANGE: INPMSource replaces authToken with private boolean.
* feat(contracts): add fullName to IPluginSource
Add an optional field to store the full name or identifier of the plugin source.
* refactor(contracts): refactor plugin source interface
Consolidate common and specific properties into the main
IPluginSource interface and simplify derived interfaces.
Move IPluginSource definition below specific source interfaces
(ICDNSource, INPMSource, IGauzySource). Aggregate all possible
source properties into IPluginSource. Remove duplicate property
definitions from specific source interfaces.
Remove the storageProvider property from IPluginSource as it
is no longer needed in this context.
BREAKING CHANGE: IPluginSource interface structure changed,
consolidating properties from derived interfaces.
storageProvider property was removed from IPluginSource.
Derived interfaces (ICDNSource, INPMSource, IGauzySource)
were simplified.
* fix(registry): use plural in plugin source not found error
* fix(storage): improve error handling for multiple file processing
Add try-catch block to catch errors during file mapping in the multiple file
processing strategy. Rethrow the error as a BadRequestException to provide
better feedback to the caller.
Formalize the file mapping logic by adding the `mapUploadedFile` method to
the `IStorageProvider` interface. This ensures that storage providers explicitly
handle the transformation from FileDTO to UploadedFile.
* refactor(plugin-upload): allow null file selection
update onFileSelected parameter type to explicitly allow null values.
This accommodates scenarios where a file selection might be cleared or the
input state changes.
* feat(plugin-registry): add source array size constraints
Ensure the sources array contains between 1 and 4 elements
(inclusive) during plugin source creation.
* refactor(plugin-version): remove form input
Remove the '@Input() form' property from the plugin version component as it is no longer used.
* feat: add plugin sources array validation
Add ArrayMinSize and ArrayMaxSize to the sources property in
PluginVersionDTO to enforce a minimum of 1 and maximum of 4 sources.
Change the type of the file parameter in SingleFileProcessingStrategy.process
from File to any for increased flexibility.
Remove unused FormGroup import in plugin-version.component.
* refactor(plugins/gauzy-source): require file for strategy
Add validation to ensure `source.file` exists and is an instance
of `File` before appending to `FormData`.
Throw an error if the file is missing or invalid to prevent unexpected
behavior when the strategy relies on a valid file being present.
* fix(registry): correct validation for plugin version sources
Correct the validation logic for plugin creation input.
Modify the condition that checks for invalid version data when sources are present.
The validation now accounts for the case where `input.version.sources`
is an empty array.
Also remove a debug console log from the file upload interceptor.
* fix(plugin-system): default plugin arch to x64 on unknown value
When the detected process architecture does not match a known value in the architecture map, default the plugin architecture to PluginOSArch.X64 instead of using the raw architecture string. This prevents potential issues with unknown architecture values and provides a sensible default.
* refactor(registry): clarify plugin source messages
Update doc comments and error messages in plugin source handlers
to correctly use the term "plugin source" instead of "plugin
version".
Also add source ID to the not found error message in the recover
handler.
* docs(plugins/registry): update jsdoc return type for source handler
Correct the @returns tag for the `execute` method to match the
actual return type of `Promise<IPluginSource[]>`. The previous
documentation incorrectly listed `Promise<IPluginSource>`.
* fix(dialog-create-source): handle potential undefined plugin and version
Remove non-null assertion (!) from plugin and version properties, as they
are not guaranteed to be initialized immediately.
Add checks and optional chaining (?, || null) when accessing these
properties and patching the form to prevent errors.
Replace deprecated text-wrap with white-space in SCSS.
* style(plugin-marketplace): use optional chaining for plugin ID
Replaces the chained `&&` check for plugin existence and id
with the `?.` optional chaining operator.
* refactor(plugin-marketplace): specify type for restore action sourceId
Specify ID type for sourceId parameter in restore action for clarity and type safety.
* docs(registry): clarify PluginSource entity documentation
Correct the @ApiProperty type for the version field in the PluginSource entity.
It is a single PluginVersion object, not an array.
Update the comment for the fullName property to clarify it is computed by a
subscriber and explain its varying format.
* docs(plugins/registry): correct api param name for plugin source recovery
* refactor(plugin-source-service): correct createSources signature and validation
The createSources function was already designed to accept and process an array of plugin sources. This commit updates the JSDoc comments and input validation to correctly reflect this behavior, ensuring sources is a non-empty array.
* fix(plugin-marketplace): fix variable name when restoring plugin source state
Corrects variable name used to check currently selected source id when
restoring a plugin source in the state. Previously used `versionId`
instead of `sourceId`.
* docs(plugin-source-controller): correct grammar in recover operation description
* chore(registry): update error message for delete plugin source
Update the error message thrown when a plugin source is not found during the deletion process to be more accurate. The original message incorrectly referenced a plugin version.
* docs(plugins/registry): clarify sources parameter type in create method
The previous JSDoc incorrectly listed 'sources' as a single IPluginSource instead
of an array.
* fix(plugin-marketplace): correct plugin version count on delete
Decrement the plugin version count in the state when a version is successfully deleted.
Previously, the count was not updated, leading to an incorrect total number of versions.
* refactor(registry/storage): remove mapUploadedFile from IStorageProvider
The responsibility for mapping FileDTO to UploadedFile has been moved
elsewhere in the system.
BREAKING CHANGE: Implementations of IStorageProvider no longer need to
define mapUploadedFile. Remove the method from provider classes.
* chore(plugins): refine validation messages
Make validation error messages more concise for operating system and architecture types in plugin sources.
* style(registry/storage): reorder imports
* chore(registry): remove unused UploadedFile import
* refactor(plugin-marketplace): externalize strings for plugin source form
Move hardcoded strings for operating system, architecture, and unknown source message in the plugin source component to translation keys.
Add new translation keys for these strings to i18n files.
---------
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
|
||
|
|
b88e81e1d5 |
[Fix] Handle stringified activity data (#8978)
* fix(activity): handle stringified activity data Update data models and parsing logic to correctly handle activity fields (kbSequence, mouseEvents, screenshots) that may be stored or received as JSON strings. * Update apps/agent/src/main/workers/push-activities.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update packages/desktop-lib/src/lib/offline/models/kb-mouse-activity.model.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update apps/agent/src/main/workers/push-activities.ts Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update push-activities.ts --------- Co-authored-by: Ruslan Konviser <evereq@gmail.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> |
||
|
|
4e0328105e |
Merge pull request #8955 from ever-co/fix/desktop-app-missing-plugins
[Fix] Desktop apps missing plugins |
||
|
|
352c7d4064 |
[Feat] Add camera entitlement (#8938)
* feat(macos): add entitlements for media and accessibility access Adds necessary entitlements to `entitlements.mas.plist` allowing the desktop timer to request permissions for camera, microphone, audio input, screen capture, and accessibility features on macOS. Updates corresponding usage descriptions (`NSMicrophoneUsageDescription`, `NSCameraUsageDescription`, `NSAppleEventsUsageDescription`) in `package.json` to provide clear user explanations when requesting these permissions. * fix: swaped text Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * chore(cspell): add 'dyld' to dictionary The term 'dyld' is a valid technical term, often referring to the macOS dynamic linker. This addition prevents it from being incorrectly flagged as a misspelling by cspell. * feat(macos): update entitlements for media access in package.json Added entitlements for microphone and camera access in the `extendInfo` section of `package.json` for desktop, server, and server-api applications. This enhances the app's ability to request necessary permissions for audio and video functionalities. --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: Ruslan Konviser <evereq@gmail.com> |
||
|
|
c5d46a199b |
Merge pull request #8907 from ever-co/fix/internationalization
[Feat] Internationalization plugin marketplace |
||
|
|
421dd74c00 |
[Fix] Missing dependency (#8903)
* feat(api): add registry plugin dependency * chore(plugin-registry): bump version to 0.1.0 |
||
|
|
792690b6ab |
[Fix]: API Build plugin-registry (#8902)
* build(plugin-registry): integrate plugin into build process Add build scripts for the plugin-registry package. Updates the main build scripts (`build:package:plugins:post*`) in the root package.json to include the new plugin-registry. Also adds build scripts (`lib:build*`) to the plugin-registry package.json itself. * fix(build): add missing yarn run for registry plugin build scripts The `build:package:plugin:registry:prod` and `build:package:plugin:registry:docker` commands within the `build:package:plugins:post:prod` and `build:package:plugins:post:docker` scripts were missing the required `yarn run` prefix. This prevented the registry plugin build step from being executed correctly in the production and docker build workflows. |
||
|
|
8fcbe38811 |
[Feat] Implement plugin registry module (#8893)
* feat(plugin-registry): add plugin registry module This commit introduces the plugin registry module, which includes: - Entities for plugins, plugin versions, and plugin sources. - Repositories for managing these entities. - A basic module structure for future development. This module will allow users to manage plugins, their versions, and sources from different locations like CDN, NPM, and file uploads. It lays the groundwork for plugin management within the application. * feat(plugin-registry): add path alias Adds a path alias for `@gauzy/plugin-registry` to simplify imports. This change allows developers to import modules from the plugin registry using the shorter alias `@gauzy/plugin-registry` instead of relative paths, improving code readability and maintainability. * feat: adds relation IDs for `uploadedBy` and `source` Adds `uploadedById` and `sourceId` relation IDs to the `Plugin` entity. This improves performance by allowing direct access to the IDs of the related entities without needing to load the entire objects. It also adds corresponding column indexes for these new fields. * refactors: Plugin repositories Migrates `PluginInstallation` and `Plugin` repositories to TypeORM. Removes the MikroORM implementation for these repositories. Renames some repository files to adhere to naming conventions. * fix: plugin relationships Adds `pluginId` to `PluginSource` and `PluginVersion` entities and configures bi-directional relationships between `Plugin`, `PluginSource`, and `PluginVersion`. This ensures correct database relationships and improves data consistency. * feat: adds plugin management services Introduces services for managing plugins, plugin installations, plugin sources, and plugin versions. These services provide CRUD operations and utilize both TypeORM and MikroORM repositories for data access. * feat(plugins): add plugin management commands This commit introduces several new commands for managing plugins: - CreatePluginCommand - InstallPluginCommand - UninstallPluginCommand - ActivatePluginCommand - DeactivatePluginCommand - UpdatePluginCommand - DeletePluginCommand These commands provide a foundation for implementing plugin management functionality within the application. * feat(plugin-registry): Add plugin management models Introduces new data models for managing plugins, versions, sources, and installations. These models provide the necessary structure for tracking plugin metadata, installation status, and source information. This lays the foundation for the plugin registry feature. * feat(plugin-registry): Add DTOs for plugin creation Introduces `CreatePluginDTO` and `PluginVersionDTO` for creating new plugins. These DTOs utilize `class-transformer` and `class-validator` for data validation and transformation, ensuring data integrity. They omit unnecessary fields like IDs and timestamps, which are handled automatically by the system. The `CreatePluginDTO` nests `PluginVersionDTO` to manage plugin version information during creation. * refactor: Implement interfaces for plugin entities Implements interfaces for `Plugin`, `PluginVersion`, `PluginSource`, and `PluginInstallation` entities to improve type safety and code maintainability. This change ensures consistent data structures across the application. * feat(plugin-registry): adds input to CreatePluginCommand Adds `CreatePluginDTO` as input to the `CreatePluginCommand`. * feat(plugins): adds create plugin functionality This commit introduces the ability to create plugins, including their source and version information. It uses a database transaction to ensure data consistency during the creation process. Error handling is implemented to rollback the transaction in case of failure. * refactor: renames CreatePluginHandler Renames `CreatePluginHandler` to `CreatePluginCommandHandler` for consistency with the naming convention of other command handlers. * feat: adds DTO for updating plugins Introduces `UpdatePluginDTO` which extends `CreatePluginDTO` using `PartialType`. This allows for partial updates of plugin information. * feat: adds `UpdatePluginCommand` This change introduces the `UpdatePluginCommand` along with its required DTO and dependencies. It allows updating plugin information. * feat: Implements plugin update functionality Adds a new command handler to update plugin information, including its source and version. Uses a database transaction to ensure data consistency during the update process. Handles potential errors and includes robust error handling for missing plugins, sources, or versions. * fix: removes unnecessary @Injectable() decorator Removes the `@Injectable()` decorator from the `UpdatePluginCommandHandler` as it's not required for command handlers. * feat: adds pluginId to DeletePluginCommand Adds `pluginId` to the `DeletePluginCommand` constructor to specify which plugin should be deleted. * feat: implements delete plugin command Adds a command handler to delete a plugin by ID. Includes transaction management to ensure data consistency. Handles potential errors like invalid plugin IDs and non-existent plugins. * fix: removes unused `@Injectable` decorator The `@Injectable` decorator is unnecessary in a CQRS handler class as NestJS already handles dependency injection for these types of classes. This change removes the redundant decorator. * feat: adds plugin activation command handler Implements the `ActivatePluginCommandHandler` to handle plugin activation requests. Includes permission checks to ensure only authorized users can activate plugins. A plugin can only be activated if it's not already active. * feat(plugins): add command handler to deactivate plugin Adds a command handler to deactivate a plugin. The handler checks if the current user has permission to deactivate the plugin and throws a `ForbiddenException` if they do not. It also ensures the plugin exists and throws a `NotFoundException` if it does not. * fix: typo in filename Corrects the filename of the `uninstall-plugin` command. * feat: adds DTO for plugin installation Introduces a data transfer object (DTO) for handling plugin installation requests, specifying the plugin and version IDs. * refactor: InstallPluginCommand input Changes the `InstallPluginCommand` to accept an `InstallPluginDTO` object instead of just the plugin ID. This allows for more flexibility and potential future expansion of the install plugin functionality. * feat(plugins): add plugin installation command handler Adds a command handler for installing plugins. This handler allows installing a specific version of a plugin and saves the installation record with the installer's ID, plugin ID, version ID, and installation timestamp. * feat(plugins): add plugin uninstallation functionality Implements the ability to uninstall plugins. This includes updating the plugin installation status and recording the uninstallation date. * feat: adds `GetPluginQuery` This query retrieves a plugin by ID, allowing for flexible retrieval options. * feat: add handler for retrieving a plugin This commit introduces a new query handler, `GetPluginQueryHandler`, responsible for retrieving a plugin by its ID. The handler fetches the plugin from the database and returns it. If the plugin is not found, a `NotFoundException` is thrown. * feat: adds plugin listing functionality Implements a query handler and query for retrieving a paginated list of plugins. This allows clients to request and display available plugins with pagination support. * fix: plugin reinstallation issue Updates plugin installation logic to handle reinstallations. Prevents creating duplicate installation records when a user reinstalls a plugin. If an installation record already exists for the given plugin ID, user ID, and version ID, the existing record is updated instead of creating a new one. The `uninstalledAt` field is also set to null during reinstallation. * fix: plugin activation/deactivation permissions Uses `uploadedById` instead of `updatedByUserId` to determine plugin ownership for activation and deactivation. This ensures that only the user who uploaded the plugin can activate or deactivate it. * feat: enhances plugin deletion with deactivation and permission checks Deactivates a plugin before deletion to ensure a clean removal process. Implements permission checks to restrict plugin deletion to the uploader, preventing unauthorized removals. This addresses potential security vulnerabilities and ensures data integrity. * feat: adds file storage metadata to PluginSource Adds `fileKey` and `storageProvider` fields to the `PluginSource` model. This allows storing metadata about the storage location of the plugin source file, enabling support for different storage providers. * feat: adds file storage support to plugin sources Adds `fileKey` and `storageProvider` fields to the `PluginSource` entity. This allows storing plugin files and specifying the storage provider used. The `fileKey` field stores the unique identifier of the plugin file, validated for ZIP format and allowed characters. The `storageProvider` field indicates where the file is stored. * feat(plugin-registry): Add FileDTO for plugin uploads Introduces a new Data Transfer Object (DTO) for handling file uploads related to plugins. This DTO enforces data integrity and validation for uploaded plugin files, including type, size, and naming conventions. It also provides a structured format for managing file metadata. * feat(plugins): Adds plugin creation endpoint Implements a new endpoint for creating plugins, allowing users to upload plugin files along with metadata. Handles file uploads using a lazy file interceptor and supports different plugin source types. Includes validation and cleanup for uploaded files. * feat: adds registry plugin Adds the registry plugin to the application. Includes the necessary module, controller, services, handlers, and entities for the plugin to function. Updates the plugin list to include the new registry plugin. * refactor: removes plugin owner restriction Removes the owner restriction on plugin activation, deactivation, and deletion. This allows any user to manage plugins, simplifying the plugin management process. * feat: adds plugin ownership guard This change introduces a guard to protect plugin routes based on ownership. It verifies that the currently authenticated employee is the owner of the plugin before allowing access to plugin-related operations. This prevents unauthorized users from modifying or activating plugins they do not own. * feat(plugins): Implement plugin management API Implements API endpoints for managing plugins, including: - Creating new plugins with file upload. - Updating existing plugin metadata. - Activating and deactivating plugins. - Retrieving plugins by ID with optional relations. - Deleting plugins. Adds authorization and validation to ensure secure plugin management. * feat: registers subscribers in PluginRegistryModule Includes subscribers in the providers array of the PluginRegistryModule. This allows them to be properly registered and utilized within the application. * feat: adds basic properties to Plugin model Adds `name`, `description`, `type`, and `status` properties to the `IPlugin` model. These fields provide essential information for managing and identifying plugins. * feat: adds checksum and signature to PluginVersion Adds `checksum` and `signature` fields to the `PluginVersion` entity and model. These fields will be used for verifying the integrity and authenticity of plugin versions. * feat: adds plugin security service Introduces a new service to manage plugin security. This service provides functionalities for generating and verifying checksums and digital signatures for plugin versions, ensuring the integrity and authenticity of installed plugins. It uses SHA-256 hashing and RSA-SHA256 signing/verification. * feat: adds plugin version subscriber This adds a new subscriber for `PluginVersion` entities to automatically generate security credentials (checksum and signature) upon creation. It also prevents subsequent modification of these credentials to ensure integrity. * refactor: plugin download count Removes explicit database column and associated decorators for the `downloadCount` property of the `Plugin` entity. This field will now be calculated rather than stored directly. * feat: adds plugin download tracking Tracks plugin and plugin version download counts. Updates plugin's `lastDownloadedAt` timestamp on installation. Calculates total downloads for a plugin across all versions. * refactor: imports in Plugin entity Reorders imports in `Plugin` entity for better readability and consistency. * feat: optimizes plugin download count calculation Uses a direct database query to sum download counts for a plugin, replacing the previous less efficient method. This improves performance by reducing database operations. * feat: adds plugin verification endpoint Adds a new endpoint to verify a plugin using its ID and verification input. This allows users to verify the authenticity and integrity of plugins before installation or usage. * feat: adds type property to command classes Adds a static `type` property to all command classes in the plugin registry module. This type property will be used for identifying commands within the application. * refactor: plugin management and introduces versioning Introduces a new `PluginVersion` entity to manage plugin versions separately. Adds versioning support to plugins, allowing multiple versions per plugin. Refactors plugin source management for greater flexibility. Includes fields for tracking plugin uploads, downloads, and installation status. This change improves plugin management by providing a more structured and organized approach to handling different plugin versions and their associated metadata. * refactor: plugin management for versioning Handles plugin versions more robustly by using an object instead of a simple string. This allows storing additional information like changelog and release date for each version. Updates plugin installation status check to rely on the presence of a version object, indicating an installed plugin. Modifies plugin upload and display components to accommodate version objects and display version numbers correctly. Adds necessary form validation for new version fields during plugin upload. * fix: plugin creation with source Associates plugin source with plugin during creation to ensure correct linking. Updates plugin creation logic to save the plugin before creating the source and version. This ensures the plugin ID is available for association. Modifies plugin source entity to include a direct relation to the plugin entity. Adjusts DTOs and controllers to support this change. Removes unnecessary file storage provider from plugin source. * refactor: plugin version source referencing Moves the `source` and `sourceId` properties from the `IPlugin` interface to the `IPluginVersion` interface. This change clarifies the relationship between plugin versions and their sources. Removes the redundant `sourceId` and `pluginId` from the `IPlugin` interface. * fix: plugin form pre-population and form data handling Sets default release date to today if no previous date exists to avoid validation errors. Improves form error handling by creating a generic helper function to reduce code duplication. Fixes an issue where plugin source details were not included in the form data when updating a plugin, resulting in incomplete updates. Ensures all necessary data is correctly included when submitting the plugin form. * refactor: plugin management Moves plugin source to version level, simplifying the plugin model and improving data organization. Updates related services, commands, handlers, DTOs, entities, and subscribers to reflect this change. Improves plugin installation and uninstallation logic by directly managing installation status and dates. Includes plugin validation improvements and computed fields for download counts and latest version. * feat: adds release date and changelog translations Adds translations for "Release Date" and "Changelog" fields and placeholders across multiple languages (ar, bg, de, en, es, fr, he, it, nl, pl, pt, ru, zh). * feat: adds endpoint to list plugin versions This change introduces a new endpoint to retrieve a paginated list of plugin versions for a given plugin ID. It includes filtering and pagination capabilities to manage large result sets. This allows clients to easily access and manage different versions of installed plugins. * feat: adds endpoint to create plugin versions Adds a new endpoint and command handler to create new versions for existing plugins. This allows users to manage different versions of their plugins within the registry. * refactor: PluginController and module Removes unused imports and logic related to plugin creation, updating, activation, deactivation, installation, uninstallation, verification, and version management from `PluginController`. Updates `PluginRegistryModule` imports and adds `RolePermissionModule`. This change simplifies the controller and module by removing obsolete code. * feat: refactors plugin ID handling in controllers Standardizes plugin ID parameter name to `pluginId` across controllers and updates related logic. Improves consistency and clarifies the purpose of the ID parameter. Refactors the `PluginOwnerGuard` to handle various request parameter names for plugin ID, improving flexibility and reducing code duplication. Updates error messages for clarity and consistency. * refactor: plugin upload form to use a stepper Breaks down the plugin upload form into a multi-step stepper component for improved user experience. This enhances clarity and simplifies the upload process by grouping related fields into logical steps. The stepper includes sections for basic information, version details, source configuration, and metadata. This change also extracts reusable components for each step to improve code organization and maintainability. * feat: adds form validation to plugin upload stepper Adds stepControl to the first step of the plugin upload stepper. This connects the stepper navigation to the form validation of the basic information step, preventing advancement to the next step until the required fields are valid. * fix: plugin version and author display Handles plugin versioning to correctly display version numbers. Displays the uploader's name accurately in the plugin details. Updates plugin loading logic to include necessary relations for proper data fetching. * feat: Implement plugin version management Allows users to add new versions to existing plugins. Updates the plugin details view to display source information for each version. Adds a button to add new versions, edit existing versions, and delete plugins. Removes the version field from the NPM source interface. Adds an "installed" flag to the plugin interface. Updates the plugin installation and uninstallation logic to use the selected version. * fix: plugin update functionality Updates the plugin update method to require a plugin ID. This change ensures that the correct plugin is updated and prevents unintended modifications to other plugins. * refactor: plugin details view Improves the plugin details view with a tabbed interface for better organization and readability. Introduces separate tabs for "Overview" and "Source Code", categorizing information effectively. The Overview tab now includes plugin description, basic info, what's new, metadata, and usage statistics. The Source Code tab displays source details and security information. Updates styling for improved visual appeal and consistency. * refactor: plugin form handling Moves plugin source control inside the version group to reflect the backend data structure. This adjusts how the form is patched and updated, simplifying the data mapping and ensuring consistency. The source type listener is also updated to reflect this change. * feat(plugins): Add DTOs for updating plugin entities Introduces new Data Transfer Objects (DTOs) for updating plugin sources, versions, and plugins themselves. These DTOs allow for partial updates of plugin-related information, enhancing flexibility and control over plugin management. They include validation and type enforcement for data integrity. * fix: plugin activation/deactivation status update Updates plugin status to INACTIVE when activating and ACTIVE when deactivating. Includes plugin id in update payload and uses service update method instead of save. This ensures correct status updates during plugin activation and deactivation. * feat: plugin update endpoint to handle file uploads Handles file uploads for Gauzy plugin updates. Includes validation, metadata extraction, and cleanup on error. Updates the plugin record with the extracted metadata. * feat: adds plugin version history navigation Adds a button to navigate to the version history page from the plugin details page. Includes API changes to retrieve plugin versions and UI changes to display the navigation button and the version history page. Orders versions by creation date descending. * refactor: plugin update logic Updates plugin, version, and source update logic to use partial updates instead of full object assignment. This prevents unintended overwrites of existing data and improves the overall update process. Adds unique indexes to plugin name and version number to prevent duplicates. Refactors DTOs to implement interfaces for better type safety and consistency. * feat: adds "Installed" and "Hidden for security" translations Adds translations for "Installed" and "Hidden for security reasons" across multiple languages (ar, bg, de, en, es, fr, he, it, nl, pl, pt, ru, zh). * fix: duplicate plugin entries in marketplace Prioritizes marketplace plugins over locally installed plugins when duplicates are found. This ensures the latest version from the marketplace is displayed. * refactor: plugin marketplace item UI Updates the plugin marketplace item UI to improve user experience. - Styles action buttons with consistent classes and colors. - Improves uninstall flow with a confirmation dialog. - Updates button styles for better visual consistency. - Refactors plugin installation and uninstallation logic for improved UI updates. - Adds tooltip for delete button in version history. - Minor styling and text updates for consistency. * fix: plugin installation check Removes unnecessary versionId check when retrieving a plugin installation. This check prevented proper retrieval of the installation record. * feat: adds marketplaceId to plugin metadata This change introduces a new `marketplaceId` field to the plugin metadata. This allows associating plugins with their corresponding marketplace entries, enabling features like installation checks and updates based on marketplace IDs. A new database migration is included to add the `marketplaceId` column to the plugins table. The plugin manager, metadata service, and related components are updated to handle this new field. An IPC handler is also added to allow checking plugin installation status by marketplace ID. * fix: plugin version management and installation Updates plugin installation to include marketplace ID for tracking. Adds plugin version editing and deletion functionality. Improves plugin version history display and actions. Fixes plugin installation check to use marketplace ID. Updates plugin marketplace loading logic to prioritize marketplace plugins and display installed status. * feat: adds loading indicator to plugin marketplace Displays a loading message while the plugin marketplace retrieves plugins. This improves the user experience by providing feedback during the loading process. * feat: adds `withDeleted` option for soft delete queries. Improves type handling and consistency within the CRUD service. Fixes some minor formatting inconsistencies. * fix: plugin version restore/delete actions Swaps the logic for the restore and delete actions in the plugin version history. The previous implementation incorrectly called the delete endpoint when restoring a version and the restore endpoint when deleting. This commit corrects this behavior. It also removes the `withDeleted` flag from the version query as it is no longer needed. * refactor: plugin ownership validation Moves plugin ownership validation logic from the `PluginOwnerGuard` to the `PluginService`. This improves code organization and allows for reuse of the validation logic. The guard now simply calls the service's validation method and handles the result. * feat(plugins): add delete plugin version functionality Adds a new command and handler to delete a specific plugin version. Includes API endpoint, service logic, and necessary guards to ensure only authorized users can delete plugin versions. Updates plugin version listing to include deleted versions when appropriate. * feat: adds plugin version recovery Implements the ability to recover a soft-deleted plugin version. Adds a new command and handler for recovering plugin versions. Exposes a new API endpoint to trigger the recovery process. * feat: improves plugin version management Adds loading and action indicators for version history actions (remove/restore). Refreshes the version list after updating, removing, or restoring a version. Changes "Restore" button text to "Recover". * fix: spinner display in plugin version actions Shows the spinner only for the selected version's action button when recovering or removing a plugin version. Previously, the spinner was displayed for all version actions, even if the action was not being performed on that specific version. This change improves the user experience by providing more accurate visual feedback during these operations. * feat: allows editing existing plugin versions Adds the ability to edit existing plugin versions, including their source and version number. Improves the version history view by adding an edit button and disabling actions while other operations are in progress. * feat: adds update plugin version endpoint This change introduces a new endpoint and command handler for updating existing plugin versions. It allows updating plugin metadata and supports file uploads for Gauzy source plugins. The update process includes validation and cleanup for uploaded files. * feat: orders plugin versions by release date Changes the ordering of plugin versions from `createdAt` to `releaseDate` for a more accurate representation of version history. This affects the plugin details view and the version history modal. * refactor: plugin marketplace item component Improves the plugin marketplace item component by consolidating the disable logic for plugin actions. This simplifies the template and ensures consistent behavior across different actions. Adds loading spinners to action buttons to provide visual feedback during asynchronous operations. This enhances the user experience by clearly indicating when an action is in progress. Styles action buttons to improve layout and visual appeal. * fix: plugin installation status handling Ensures correct installation status updates by using `finalize` to always reset the installing/uninstalling flags after the operation completes. Improves error handling when checking local plugin installations by logging a warning instead of an error and correctly setting the installed state. * feat: adds read-more directive for long text Implements a new directive to truncate long text blocks and provide a "read more" button to expand the content. This improves the user experience by preventing long text descriptions from overflowing their containers and cluttering the UI. The directive is applied to plugin descriptions and changelogs in the plugin marketplace. * fix: plugin installation and editing process Handles plugin installation and uninstallation status updates from Electron. Displays a loading indicator during plugin installation, uninstallation, and editing. Updates plugin details to display the latest version number during upload. Fixes a gap issue in plugin actions. * fix: plugin installation rollback on failure Rolls back plugin installation if it fails. This ensures a clean state after a failed installation by uninstalling the partially installed plugin. Adds error handling to both the plugin detail and plugin item components. * fix: plugin installation check Adds `status` check to plugin installation queries to ensure only installed plugins are considered. This prevents scenarios where uninstalled plugins are incorrectly treated as installed. * fix: plugin installation check Ensures the plugin installation check accurately reflects the locally installed plugins. Handles cases where the plugin information might be outdated or incorrect, preventing potential issues during installation or uninstallation. * feat: silently handles missing plugin installations No longer throws an exception when attempting to uninstall a plugin that isn't installed. Instead, the handler now simply returns without taking any action. * fix: plugin installation check error handling Handles potential errors during plugin installation check by setting the checked state to false and preventing further emissions. This ensures the UI reflects the correct installation status even if the check fails. * refactor: imports in plugin marketplace item component Moves the import of `IPlugin as IPluginInstalled` from the bottom of the import list to be closer to other related imports. This improves code readability and organization. * feat: adds CUSTOM_ELEMENTS_SCHEMA to PluginsModule This allows the use of custom elements within the plugin system without Angular throwing errors. * fix: refreshes plugin list after upload Reloads the plugin list after a successful plugin upload to immediately reflect the change in the UI. * fix: unique constraint on plugin versions Changes the unique constraint on `PluginVersion` from `plugin.name` to `number`, `pluginId`, `tenantId`, and `organizationId`. This ensures that plugin versions are unique within a plugin, tenant, and organization, based on their version number. The previous implementation incorrectly used the plugin name, which could lead to conflicts when different plugins shared the same name across tenants or organizations. Also adds a unique constraint to the `Plugin` entity on `name`, `tenantId`, and `organizationId` to ensure plugin names are unique within a tenant and organization. * refactor: plugin marketplace forms Removes unnecessary ChangeDetectorRef usages and improves form handling logic. Improves form patching by creating a copy of the version object to avoid modifying the original object. Adds conditional rendering to form fields based on source type to prevent errors. Removes debounceTime operator to improve responsiveness. * refactor: plugin management logic Removes unnecessary try-catch blocks from plugin activation and deactivation handlers. Simplifies the logic by directly checking plugin status before updating. Removes an unused import from the plugin owner guard and fixes optional chaining in the plugin manager. * fix: regex for URL validation Corrects the regular expression used for validating URLs to allow paths with hyphens. * chore: docker build * feat: adds "uninstallation" to cspell dictionary Adds "uninstallation" to the list of recognized words in the cspell configuration file to prevent it from being flagged as a spelling error. * fix: incorrect FormData initialization Initializes FormData within the functions instead of outside, preventing potential data corruption when handling multiple requests concurrently. * fix: plugin registry path in tsconfig.json Adds missing `./` to the path for `@gauzy/plugin-registry` to ensure consistency with other plugin paths. * fix: validation messages for plugin ZIP files Clarifies the validation error messages for plugin ZIP files to accurately reflect the required format and allowed characters. Removes erroneous references to video formats. * fix: plugin marketplace and versioning issues Corrects typographical errors in variable names related to marketplace IDs. Improves plugin version handling and validation, including source type handling and form validation. Updates plugin version number type and adds a check for plugin ownership before editing or removing versions. Refines plugin source entity by removing unnecessary size validation and improves latest version computation. Fixes plugin deletion logic and updates command type for clarity. Adjusts plugin creation validation to handle missing version data. Handles potential not found exceptions during plugin version deletion. Ensures plugin ownership validation is asynchronous. * fix: plugin version release date validation Removes the validation rule that restricted the release date to be in the past. This allows for future release dates to be set. * fix: plugin toggle during installation Disables the plugin toggle while installation or uninstallation is in progress. This prevents users from interacting with the toggle while the operation is ongoing, avoiding unexpected behavior and improving the user experience. Also fixes an issue where the toggle state was incorrectly reverted after a failed installation or uninstallation. * fix: plugin install/uninstall toast notifications Moves toast notifications for successful plugin installation and uninstallation to the `finalize` block. This ensures the notification is displayed after the operation completes, even if an error occurs during the process. Prevents duplicate toast notifications when installing or uninstalling plugins. Adds toast notifications for errors during plugin installation or uninstallation. Adds a check to prevent multiple clicks on the install/uninstall buttons while the operation is in progress. * fix: clarifies `installed` property description Updates the description of the `installed` property in the `IPlugin` interface to clearly indicate that it represents whether the plugin is currently installed. * feat(plugins): Adds plugin management functionality This commit introduces actions, effects, a store, and a query for managing plugins. It provides functionality to get, select, activate, deactivate, install, and uninstall plugins. Loading and error handling are also implemented. * feat: adds plugin progress reporting Introduces a new method to report plugin installation progress to the UI. This allows users to track the installation process and receive updates on its status. * chore: adds @ngneat/effects-ng dependency Adds the `@ngneat/effects-ng` package to the `desktop-ui-lib` project. * feat: adds Akita state management for plugins Introduces Akita for managing plugin state, including effects, queries, and a store. This provides a more robust and scalable solution for handling plugin data. * refactor: plugin installation process Moves plugin installation logic to ng-effects. This simplifies the component logic and improves state management. * refactor: plugin management using Akita state management Moves plugin management logic to Akita, simplifying component logic and improving state handling. Adds loading indicator for plugins. Disables actions while plugin operations are in progress to prevent conflicts. * feat: refines plugin progress event handling Simplifies the data structure for plugin progress updates. Progress events now pass the message directly as a string instead of within an object, streamlining communication between the electron service and the UI effect. * feat: return plugin metadata after download Modifies the plugin download process to return the metadata of the newly downloaded plugin. This allows the caller to immediately access plugin details (like name, version, etc.) upon successful download without needing a separate query. Updates the corresponding event handler to forward this metadata in the success response. * feat: removes plugin install/uninstall actions and effects Removes the `install` and `uninstall` NgRx actions and their corresponding effects. Updates the `handleProgress` method signature to accept an object parameter for the message. * feat: adds state management for plugin marketplace Implements Akita stores, queries, and NgNeat effects for managing plugin state within the desktop UI. Handles asynchronous operations for: - Plugin installation and uninstallation via Electron service. - Plugin marketplace CRUD operations (upload, fetch, update, delete). - Plugin version management (CRUD, restore, selection). Provides state tracking for loading, progress, and errors, integrating with notification services for user feedback. * feat: updates plugin components to use installation actions Replaces the use of generic `PluginActions` with the more specific `PluginInstallationActions` for install and uninstall operations within the `AddPluginComponent` and `PluginListComponent`. This change isolates plugin installation and uninstallation logic into dedicated state management actions, improving code organization. * refactor: plugin marketplace to use state management Replaces direct service calls and local state (`BehaviorSubject`) in plugin marketplace components (list, item, detail, version history) with dedicated NgRx-style actions and queries. Centralizes logic for plugin operations like installation, uninstallation, updates, deletion, and version management within the state layer. This simplifies component responsibilities and improves overall state handling consistency. * feat: adds plugin marketplace effects and upload progress Integrates NgRx effects for plugin marketplace, installation, and version management. Updates plugin service methods (`getAll`, `getVersions`) to return full pagination objects instead of just item arrays. Implements upload progress reporting in the plugin upload service method. Enhances Electron IPC progress communication to potentially include data payloads alongside messages. * feat: adds versionId field for plugin management Introduces a `versionId` field to the plugin database schema and metadata interface. Updates the plugin download, installation, and update processes to handle and persist the `versionId`. This allows tracking specific plugin versions, potentially linked to marketplace releases. * feat: refines plugin marketplace state management and UX Centralizes plugin install/uninstall toggle state using Akita store and effects for improved consistency and reactivity across components. Refines loading indicators (spinners) on buttons to activate only for the specific plugin being installed, uninstalled, or modified, preventing simultaneous activation across all items. Ensures state immutability by consistently using the spread operator when updating plugin and version arrays within Akita stores. Corrects state property updates during plugin uninstallation (`uninstalling` flag) and fixes payload data (`versionId`) used during installation. Adds a reset action to clear the plugin version history state when the relevant component is destroyed, preventing stale data display. Passes the specific version ID during plugin installation actions and updates version history display to use `releaseDate` instead of `createdAt`. Refactors plugin effects slightly by using `from()` to handle async operations and scoping `finalize`/`catchError` more closely. * fix: plugin version management and UI stability Corrects state updates in effects when deleting or restoring plugin versions, ensuring the correct version ID is used. Switches from `switchMap` to `mergeMap` in version effects to allow concurrent operations without cancellation. Improves error handling and user feedback messages for plugin version restoration failures. Adds null checks in plugin marketplace templates to prevent potential errors when accessing plugin properties. Refines spinner display logic in the plugin detail view during editing. * feat: improves plugin marketplace state management and UX Resets selected plugin state in the plugin list component on initialization and destruction. Navigates back to the marketplace list and clears the selected plugin state after successful deletion in the marketplace effects. Merges updated plugin data with existing state instead of overwriting during marketplace updates. Dispatches an installation toggle action immediately when initiating plugin install, uninstall, update, or delete operations in the marketplace item component for better UI feedback. * feat: uses state management for plugin version selection Refactors plugin version selection within the marketplace item to utilize the central state store instead of local component state. Dispatches an action upon initial load and when the user selects a different version via the dropdown. The selected version is now read reactively from the state store for display and logic. Updates the state store effect to include the plugin ID when selecting a version. Removes local component state management for the selected version. * refactor: plugin install/uninstall state Move the 'installing' and 'uninstalling' state management from the main PluginQuery and PluginStore to the dedicated PluginInstallationQuery. This change isolates installation-specific state, improving modularity and clarifying the responsibilities of each state management slice. Components involved in installation now correctly source this state from PluginInstallationQuery. * feat(utils): add coalesceValue utility function Introduce a `coalesceValue` utility function. This function allows handling potentially null or undefined values by returning a default value or executing custom handler functions for null/undefined if provided. * feat(plugin-marketplace): show progress for plugin upload and version add Modify plugin upload and version addition services to report upload progress events. Update plugin marketplace and version effects/stores to handle progress information. Display the upload progress percentage in the UI during plugin uploads and new version additions to improve user feedback. * style(plugin-marketplace): remove left margin from upload progress indicator Removes the unnecessary left margin (ml-2) from the upload progress percentage display in the plugin marketplace header and item views for better visual consistency. Additionally, updates the conditional display logic in the item view to use the 'uploading' state variable for consistency. * feat(plugin-registry): prevent deleting last plugin version Introduce a check in the DeletePluginVersion command handler. Before attempting to delete a specific plugin version, the handler now verifies the total number of versions associated with the parent plugin. If deleting the target version would leave the plugin with no versions remaining (i.e., count <= 1), the deletion is prohibited, and a ForbiddenException is thrown. This ensures that a plugin entity always retains at least one version. BREAKING CHANGE: Deleting the last remaining version of a plugin is no longer permitted and will result in a 403 Forbidden error. * fix(plugin-registry): throw error for missing Gauzy plugin file key Previously, creating a plugin with source type 'GAUZY' without providing a file resulted in a console warning and an undefined return value. This change replaces the warning with a `BadRequestException` to ensure the client receives an appropriate HTTP 400 error response when the file key is missing. BREAKING CHANGE: Creating a plugin with source type 'GAUZY' without a file now returns a 400 Bad Request instead of potentially succeeding with a warning. * fix(plugin): fix issues in plugin creation and upload - Corrects the handling of `releaseDate` by using ISO string format before sending to the backend and standardizes max date selection in UI using NbDateService. - Fixes the incorrect step order (Source/Version) in the plugin upload stepper component. - Resolves an error where the uploaded file was not correctly extracted from the form data structure. - Adds error handling to plugin upload and version creation requests. * refactor(plugin-marketplace): reuse deletion timestamp when updating plugin version state Generate the deletion timestamp once before updating the plugin version store state. This ensures the exact same timestamp is used for both the single version view and the list view update, promoting consistency and slightly improving code clarity by avoiding redundant `new Date()` calls. * feat(plugin-marketplace): add infinite scrolling Implement infinite scrolling for the plugin marketplace list. This improves performance and user experience by loading plugins in batches as the user scrolls down, instead of loading all plugins at once. - Add `NbInfiniteListDirective` to the marketplace template. - Implement `loadMore` logic in the component to fetch subsequent pages. - Introduce a `reset` action and effect to clear the plugin list from the store when the component is destroyed, ensuring a fresh load on revisit. * feat(plugin-marketplace): add infinite scroll to plugin version history Implements infinite scrolling for the plugin version history list within the marketplace item view. This improves performance and user experience when viewing plugins with numerous versions. Also refactors plugin ID management in the parent component to utilize the state store consistently. * fix(plugin-marketplace): remove reset action dispatch on destroy Removes the dispatch of the `PluginMarketplaceActions.reset()` action within the `ngOnDestroy` lifecycle hook. This prevents the plugin marketplace state from being automatically cleared when the component instance is destroyed. * refactor(plugins/routing): organize plugin routes into child modules Extract routes for installed plugins and the marketplace into separate lazy-loaded routing modules (`plugin-installed-routing.module.ts` and `plugin-marketplace-routing.module.ts`). This improves code organization and separation of concerns within the plugin settings feature. Also includes fixes for pagination logic (`skip` initialization corrected to 1) and ensures state reset actions (`PluginVersionActions.reset`, `PluginMarketplaceActions.reset`) are dispatched on component destroy for related components. * refactor(plugins-state): make plugin action identifiers more specific Update the descriptive type strings for NgRx/Effects actions related to plugins. Replace the generic `[Plugin]` prefix with more specific domains: - `[Plugin Installed]` - `[Plugin Installation]` - `[Plugin Marketplace]` - `[Plugin Version]` This improves clarity and aids debugging by providing better context for actions, especially in state management developer tools. * fix(plugin-marketplace): load plugins on component initialization Call the load method during ngOnInit to ensure the plugin list is fetched when the component is displayed. Additionally, remove the 'versions' relation and its specific ordering from the data retrieval action as it is not required for the initial marketplace view. This simplifies the query. * fix(plugin-marketplace): correct plugin state update after install/uninstall Ensure the plugin's installed status is correctly reflected in both the main plugin list and the individual plugin state within the PluginMarketplaceStore after installation or uninstallation. Previously, the state update logic did not handle cases where the plugin being acted upon might only exist in the installation state (e.g., viewed directly) and not in the main marketplace list. This change uses the `PluginInstallationQuery` as a fallback to retrieve plugin details if necessary and updates both `plugins` array and the singular `plugin` state property consistently. * feat(plugin-marketplace): include relations in plugin fetch Fetch plugin versions, source, and uploader information alongside the main plugin data when listing plugins in the marketplace. This optimizes data loading and enables richer display of plugin details. * fix(plugins): improve loading state and infinite scroll logic - Reorder loading indicator display in plugin marketplace and version history templates to potentially show content sooner if available. - Refactor `hasNext` calculation for infinite scroll in both marketplace and version history components for clarity and efficiency. - Prevent `loadMore` in version history from triggering prematurely before initial data is loaded. - Add missing `NbListModule` import. * fix(plugins): fix plugin upload form state and backend error handling Mark the plugin upload form in the desktop UI as touched and dirty when a file is selected. This ensures the form state correctly reflects user interaction, enabling proper validation and UI updates. Additionally, improve backend error handling in the plugin version controller. Throw a BadRequestException instead of logging a warning when the file key is missing for a GAUZY source type plugin upload. This provides clearer and more appropriate error feedback. * refactor(plugin-system): improve structure of plugin download strategies Break down the monolithic `execute` methods in both CDN and Local download strategies into smaller, more focused private methods. This improves code clarity, maintainability, and testability. Key changes include: - Introduce separate methods for validation, directory preparation, download/file handling, unzipping, manifest processing, and cleanup. - Enhance error handling with more specific messages and dedicated cleanup logic on failure. - Add explicit validation for URLs (CDN) and selected files (Local). - Implement streaming download for the CDN strategy to reduce memory usage. - Improve logic for locating the plugin directory within the unzipped archive, including searching for `manifest.json`. - Introduce constants for retry logic and file extensions. * feat(desktop): enhance server connection detection and feedback Introduce a dedicated `serverConnection` state (0 for down, 200 for up) in the store, updated consistently by the app component and the server error interceptor upon successful pings or HTTP errors. Redesign the 'Server Down' page with improved visuals, animations, and a connecting status indicator. Refactor its connection checking logic using RxJS interval and switchMap for better reliability and resource management. Update the Plugin Marketplace to display an explicit offline message when the application detects a lost connection. * feat(i18n): add server down translations Add translations for messages displayed when the backend server is unavailable (HTTP 503). This includes keys for title, description, connecting status, and a hint with the error code across all supported languages. * refactor(plugin-marketplace): inject Store service Inject the global Store service into the PluginMarketplaceComponent. This makes the application's central store accessible within the component for potential future use, such as selecting state or dispatching actions. * feat(auth): add connection guard to block routes when offline Introduces the `AuthConnectionGuard` to prevent navigation to main application routes when the server connection is unavailable (status 0), unless the user already has an active session (userId exists in store). - Created `AuthConnectionGuard` checking `serverConnection` and `userId`. - Added the guard to `/auth`, `/time-tracker`, and the default route. - Provided default configuration for the guard's redirect behavior. - Refactored `ServerConnectionService` for improved reliability, error handling, and async/await usage. - Updated `AuthGuard` and `NoAuthGuard` to set connection status to 0 if authentication checks fail due to connection issues. - Refined server check logic on `ServerDownPage` to navigate away once connection or session is restored. - Standardized initial `serverConnection` state to 0. - Refactored common SCSS styles into `_reusable.scss`. * fix(plugins): refine error message display and IPC property access Simplify fallback error message construction for plugin uploads. Remove unnecessary optional chaining for Electron IPC message properties (`message`, `data`). Includes minor import order adjustment. * style(desktop-ui-lib): organize imports and remove unused code Remove unused imports (HttpErrorResponse, Http2ServerResponse, throwError) from the plugin service. Alphabetize RxJS imports in the server-down page for consistency and remove an unused RxJS operator import (take). * refactor(auth): use format specifiers for console logs Update console.warn and console.error calls in AuthConnectionGuard to utilize format specifiers (%s) rather than string concatenation. This improves the readability and consistency of log output, potentially aiding debugging and integration with logging tools that parse format strings. * fix(plugin-installation): reset toggle state on installation error When a plugin installation fails, the associated UI toggle element was not being reset to its previous state. This could leave the toggle in an active state despite the failed operation. This commit modifies the installation error handler to explicitly read the current toggle state via a new query getter and then updates the store with the inverted state, effectively resetting the toggle visually upon failure. * fix(plugins): fix version selection in plugin marketplace item Add a compareWith function to the version select dropdown in the plugin marketplace item component. This ensures that the correct version is highlighted in the dropdown, as Angular needs guidance on how to compare the IPluginVersion objects (by ID) rather than by object reference. * fix(plugin-marketplace): ensure correct plugin version selection and state update Update the plugin marketplace store immediately after a new version is created to include the new version in the plugin details. Prevent the marketplace item component from automatically selecting the latest version if a version is already selected, preserving the current selection state. * refactor(plugin-marketplace): extract version selector component Extract the plugin version selection logic from PluginMarketplaceItemComponent into a new dedicated VersionSelectorComponent. This new component utilizes the `gauzy-select` component instead of `nb-select` and introduces infinite scrolling for loading plugin versions. Adjusted the PluginVersionEffects to correctly update the version list in the store when creating or updating versions. The state update now modifies the existing version in the list if found, or prepends it otherwise, improving consistency. Additionally, the VersionHistoryComponent now fetches deleted versions. * feat(plugin-marketplace): add skeleton loaders and defer loading for plugins Implement skeleton placeholders for the plugin list and version history using Angular's `@defer` block with `@placeholder`. This improves the user experience by showing a structured loading state instead of a blank area or simple text message while data is being fetched. The `isLoading` condition is refined to only show the main loading indicator before the initial data arrives. Deferred loading (`@defer on viewport`) is used for the lists to potentially improve initial render performance. The plugin upload button is also deferred (`@defer on idle`) and disabled when the application is offline. * chore(plugin-marketplace): remove console warning for missing local installation Remove the console warning that appears when a plugin is not found locally during the marketplace check. This warning is redundant as it represents an expected state (plugin not installed) rather than an actual problem. * style(plugin-list): update uninstall icon Replace 'trash-2-outline' icon with 'slash-outline' for the plugin uninstall button. * fix(plugin-registry): update enum types and version index for db compatibility Update ORM entity definitions to use 'simple-enum' instead of 'enum' for better cross-database compatibility and simpler management. Add default values to several enum columns for consistency. Adjust the unique index definition on the PluginVersion entity to correctly handle differences between MySQL and other database systems regarding unique constraints involving tenant/organization IDs. * feat(plugin-registry): add plugin registry database tables Introduce a new TypeORM migration to establish the database schema for the plugin registry feature. This migration creates the following tables: - plugin: Stores core plugin metadata. - plugin_source: Details the source location (CDN, NPM, Gauzy) and storage details for plugin assets. - plugin_version: Manages different versions of each plugin, including changelogs and checksums. - plugin_installation: Tracks the installation status of plugins within tenants/organizations. The migration includes specific implementations for PostgreSQL, SQLite, and MySQL databases. * perf(plugin-registry): eagerly load version source Join the 'source' relation when querying for all plugin versions within the PluginSubscriber. This avoids potential N+1 query issues when accessing the source information for each version later in the process, improving database query performance. * feat(plugin-marketplace): select version on detail open and fix count Dispatch the PluginVersionActions.selectVersion action when navigating to the plugin detail page. This ensures the correct version context is set for subsequent operations. Fixes an issue where the total plugin count in the marketplace state was not incremented after a successful plugin upload. Also refactors the `plugin` getter in PluginMarketplaceItemComponent to be private. * feat(plugins): add plugin-registry dependency Add the @gauzy/plugin-registry package as a dependency to the desktop, server-api, and server applications. This prepares the applications for dynamic plugin loading and management capabilities. Add the @gauzy/plugin-videos dependency to the server-api and server applications to incorporate video-related features. Update productName and description in apps/server/package.json for consistency. * fix(plugins): remove success toast from upload/version dialogs The plugin upload and create version dialogs were showing a success message immediately upon form submission, before the parent component confirmed the success of the actual operation. This removes the premature success toasts. The responsibility for notifying the user of success now lies with the component that handles the dialog result. --------- Co-authored-by: Rahul R. <rahulrathore576@gmail.com> |
||
|
|
c05b6512ef |
[Fix] Skip notarize without env (#8861)
* fix: Allows notarization to continue without env vars Changes notarization process to warn instead of throwing an error when `APPLE_ID` or `APPLE_ID_APP_PASSWORD` environment variables are missing. This allows the process to continue. * feat: adds notarization step to build process Configures electron-builder to notarize the desktop, server, and server-api applications after signing. |
||
|
|
ce83ff3e4d |
[Refactor] Removes unused dependencies (#8862)
* refactor: removes unused dependencies Removes several unused dependencies from server and server-api package.json files to reduce bundle size and improve maintainability. * fix: revert "Gauzy Server" to "Ever Gauzy Server" |
||
|
|
3df287898a |
[Chore] Notarize macos app (#8849)
* chore: move to @electron/notarize, last package's deprecated * chore: use notarytool instead legacy altool * feat: centralizes notarization dependency Moves the `@electron/notarize` dependency from individual app packages to the root package.json. This centralizes the dependency and corrects a conditional check in the notarization script that prevented notarization from occurring. * fix: updates desktop timer app ID Updates the app ID to `com.ever.gauzydesktoptimer` and removes the unnecessary `@electron/notarize` dependency. This resolves notarization issues and streamlines the build process. * feat: adds Apple credentials to CI workflows Adds `APPLE_ID`, `APPLE_ID_APP_PASSWORD`, and `APPLE_TEAM_ID` secrets to the following CI workflows: - `desktop-app-prod.yml` - `desktop-app-stage.yml` - `desktop-timer-app-prod.yml` - `desktop-timer-app-stage.yml` - `server-api-prod.yml` - `server-api-stage.yml` - `server-prod.yml` - `server-stage.yml` This allows workflows to access Apple services for functionalities such as code signing and distribution. * fix: cspell spelling |
||
|
|
5ed535d4e1 |
[Feat] Create plugin marketplace for desktop app (#8843)
* feat(plugin): enhance plugin management - Adds plugin description and logo to plugin metadata. - Improves plugin activation and deactivation logic. - Implements lazy loading of plugin modules for better performance. - Updates plugin installation and uninstallation process. - Introduces a plugin marketplace for discovering and installing new plugins. - Adds UI enhancements for managing plugins, including a new settings page. - Adds confirmation dialogs for uninstalling and deactivating plugins. * feat: adds tooltip to plugin upload button Adds a tooltip to the plugin upload button to improve user experience. Also adds a cursor pointer to the upload button's styling. Includes the necessary NbTooltipModule import to the plugins module. * feat: adds Gauzy-hosted plugin support Adds support for Gauzy-hosted plugins alongside CDN and NPM. This includes a new `PluginSourceType.GAUZY` enum value and `IGauzySource` interface for handling Gauzy-hosted plugin details. The plugin upload UI now supports selecting a zip file for Gauzy hosting. The plugin model has been updated to accommodate multiple versions and a version channel. * feat: add translations to page * Reduces plugin icon size in upload section Reduces the size of plugin icons in the plugin marketplace upload section from 3rem to 2rem. * fix: simplifies plugin version management Changes plugin versioning to use a simple string array instead of a complex object. This simplifies version management and reduces code complexity. The previous `IVersion` interface, including `name`, `channel`, and `compatibility` fields, is replaced with a string array of versions. Corresponding updates are made to the `ICreatePlugin` and `IUpdatePlugin` interfaces. * fix: removes `tags` from plugin model Removes the `tags` property from the `IPlugin` interface. * feat: adds plugin upload functionality to marketplace Introduces a new upload button in the plugin marketplace, allowing users with appropriate permissions to upload new plugins. This functionality is controlled by a resolver that determines upload availability based on user roles. The plugin model is also updated to remove an unused tag import, streamlining the model definition. * feat: adds edit icon to plugin details Adds an edit icon next to the toggle in the plugin details view. Styles the plugin details section to include spacing between elements and updated color scheme. * refactors plugin details and adds plugin page Implements a dedicated page for viewing and managing individual plugins. Refactors plugin details view to be more informative and user-friendly, including: - Clearer display of plugin information, source details, and metadata. - Enhanced UI with badges and tags for better visualization of plugin status and type. - Usage statistics for tracking downloads and uploads. - Security information display. Updates plugin marketplace detail view with clickable plugin name and edit icon, allowing navigation to the plugin page and editing. Modifies plugin settings navigation to support the new plugin details page. * feat: adds marketplace button to plugin settings Adds a button to the "Add Plugin" page that redirects the user to the plugin marketplace. Updates the plugin marketplace item component styles for better readability and visual appeal. Includes minor updates to the mock data used for display. * feat: adds details view translations Adds translations for the new details view section, including usage statistics, download information, upload details, and security information. Translations added for all supported languages. * feat: restricts plugin edit access to owners Only allows plugin owners to edit plugin details and change the plugin status. Adds a check to conditionally render the edit controls based on ownership. * feat: implements plugin version selection and management Allows users to select a specific plugin version for installation. Adds UI elements for installing, updating, and uninstalling plugins. Modifies plugin details view to display version selection dropdown. * refactor: plugin marketplace item component Improves code structure, type safety, and error handling. Removes hardcoded plugin data and prepares for API integration. Adds clearer error handling and user feedback. Updates styling for consistency and uses stronger typing for improved maintainability. * feat: improves plugin management UI and functionality Adds loading indicators to plugin action buttons. Removes unnecessary margins and improves button layout using flexbox. Implements plugin installation, update, and uninstallation logic. Updates plugin status handling and notification messages. * fix: potential UI update issues in plugin marketplace Ensures UI updates correctly after plugin installation status changes by explicitly triggering change detection. * feat: localizes plugin settings tabs Translates "Discover" and "Installed" plugin tabs using the translate service. This allows the tab titles to be displayed in the user's selected language. Adds `PLUGIN.LAYOUT.DISCOVER` and `PLUGIN.LAYOUT.INSTALLED` keys to the translation files. * feat: disables buttons during plugin install/uninstall Disables the Edit, Update, Install, and Uninstall buttons while a plugin installation or uninstallation is in progress. This prevents multiple concurrent operations and improves the user experience by providing clear feedback during these processes. Adds a `uninstalling` variable to track uninstall operations and uses it to conditionally disable buttons. * feat: displays message for unavailable plugins Handles the case where a plugin is not available in the marketplace by displaying a "This plugin is unavailable on marketplace" message. This improves the user experience by providing feedback when a plugin cannot be found. Also replaces *ngIf directives with @if/@else blocks for conditional rendering of plugin information and loading state. * feat: adds translation for plugin marketplace unavailability Adds a new translation key "PLUGIN_MARKETPLACE" for the message displayed when a plugin is unavailable in the marketplace. This covers various languages including Arabic, Bulgarian, German, English, Spanish, French, Hebrew, Italian, Dutch, Polish, Portuguese, Russian, and Chinese. * refactor: plugin marketplace item component Removes hardcoded plugin data and related logic. This prepares the component for fetching real plugin data from an API. * feat: updates plugin management in marketplace Implements API calls for fetching, updating, and uploading plugins. Removes mock plugin data and replaces it with actual API integration. Adds success/error toast notifications for plugin updates and uploads. * fix: deepscan * fix: cspell spelling * fix: add code rabbit suggestions * fix: add code rabbit suggestions * feat: implements plugin installation logic Handles plugin installation based on source type (Gauzy, CDN, NPM). Downloads and installs the plugin using the appropriate method for each source. * fix: style sheet references Corrects incorrect style sheet references in two components and reorders imports in the module. `plugin-marketplace.component` was incorrectly referencing the style sheet for `plugin-marketplace-upload.component`. This has been corrected. `plugin-marketplace-upload.component` was using the deprecated `styleUrl` property. This has been updated to `styleUrls`. Import order for `PluginMarketplaceUploadComponent` and `PluginMarketplaceItemComponent` has been corrected in `plugins.module`. * fix: removes debug logging Removes console log statements related to plugin loading and fallback component usage. |
||
|
|
c5582a0d24 |
[Feat] Localizes video plugin UI elements and messages (#8786)
* feat: localizes video plugin UI elements and messages This commit introduces localization support for the video plugin, translating UI elements and messages into multiple languages. It replaces hardcoded strings with translation keys and updates the translation files accordingly. This improvement enhances the user experience by providing a localized interface for managing and interacting with videos. * fix: Incorrect toastr message key Updates the toastr message key from `PLUGIN.VIDEO.ADD_TO_QUEUE` to `PLUGIN.VIDEO.ADDED_TO_QUEUE` for a more grammatically correct message when a video is added to the download queue. |
||
|
|
619b6645fa |
[Fix] Video filtering (#8765)
* feat: adds API for video count and updates video service Adds a new API endpoint to retrieve the count of videos. Updates the video service to use the new API endpoint for checking video availability. This improves performance by only retrieving the count instead of the entire list of videos. Adds update video API endpoint to update video metadata. * refactor: video service imports Moves RxJS operators import to be with other RxJS imports. This improves code readability and consistency. * refactor: permission Check Enhancements - Updated `VideoService` in `video.service.ts` to refine selection logic, prioritizing `selectedOrganization` over `organizationId`. - Enhanced `GetVideoCountQueryHandler` in `get-video-count.handler.ts` by introducing permission checks for `CHANGE_SELECTED_EMPLOYEE`, ensuring queries respect user permissions. * feat: enhance video retrieval with timezone-based date filtering - Introduced `moment-timezone` for converting start and end dates to UTC. - Updated query to dynamically filter videos based on provided `startDate`, `endDate`, and `timeZone`. - Implemented dynamic WHERE clause with optional employee filtering using `TypeORM`'s `In` and `Between` utilities. * feat: conditional date filtering in video query Modify the query to conditionally include the recordedAt filter only when both startDate and endDate are provided. This change enhances the query flexibility by avoiding unnecessary date filtering. * fix: hide date selector on detailled page * refactor: deleteVideo method in VideosController - Updated import statements for DTOs and models in videos.controller.ts - Changed the Delete method to accept an optional IDeleteVideo parameter * refactor: enhance UpdateVideo command structure - Updated the VideoEffects update logic for better state management - Refactored UpdateVideoHandler to include description in video updates - Modified UpdateVideoCommand and UpdateVideoDTO for simplified DTO structure - Revised VideosController to adapt to new UpdateVideoCommand constructor * fix: reset video store on filter change - Ensures that the video store is cleared before fetching new video data when the filter changes. * feat(video-page): modify filter component inputs - Disable log type, source, and activity level filters in the video page filter component. - This change simplifies the available filters for a streamlined user experience. |
||
|
|
c6530008b1 |
[Refactor] Desktop core features (#8709)
* refactor: window management and electron store Moves window management related code into a dedicated directory. Removes electron-log and type definitions for electron store. Electron store is now handled globally in a dedicated module. Console logging will be handled by the renderer process. * refactor: store and adds logger utility Moves store related services into a dedicated store directory. Introduces a new logger utility for better logging and debugging. The logger is initialized and setup for Electron. * refactor: desktop store to use core services Replaces direct `electron-store` usage with core services for managing application settings, configurations, authentication, and project information. This change improves code organization, reduces redundancy, and promotes consistency with the core application logic. It centralizes data management and simplifies updates to the stored data. * refactor: config management and logging Centralizes environment variable assignment to `environment.ts`. Improves theme preference handling by simplifying the logic and setting a default theme if no setting exists. Updates server start logic to directly update config store instead of using a temporary object. Moves logging setup and node modules path output to after environment setup. Removes redundant `electron-log` imports and uses `@gauzy/desktop-core` logger. Refactors and simplifies setting default config by using `LocalStore.setAllDefaultConfig`. Simplifies timer duration update logging. * feat(desktop-core): add optional db field to IConfig interface - Introduced an optional `db` property to the `IConfig` interface to allow for database configuration specifications. - This change enables more flexible configurations within the desktop core setup. |
||
|
|
e9b60254eb |
fix: Prevent errors by checking if the browser window is destroyed before hiding or closing.
This update adds checks to ensure that `hide()` and `close()` do not attempt actions on an already destroyed window, improving stability in window management. |
||
|
|
63f7ae38fc | Fix indexing issue | ||
|
|
722649bb3a |
[Fix] Window manager multiple instance (#8638)
* feat: create desktop core library * fix: desktop-core commands & packages * feat: moves window management logic to desktop-core This change extracts window management logic from `desktop-window` and places it into a new package, `desktop-core`. This improves code organization and allows other desktop packages to reuse this functionality. The `desktop-timer` and `desktop-lib` packages are updated to use the new `desktop-core` package. * feat: adds desktop-core package dependency Adds the `@gauzy/desktop-core` package to the dependencies of the `desktop`, `server`, and `server-api` applications. * chore(deps): bump @gauzy/desktop-core from 0.0.1 to 0.1.0 Bumps [@gauzy/desktop-core](https://github.com/ever-co/gauzy/tree/master/packages/desktop-core) from 0.0.1 to 0.1.0. Updates `@gauzy/desktop-core` from `0.0.1` to `0.1.0` in: - `apps/desktop-timer/src/package.json` - `apps/desktop/src/package.json` - `apps/server-api/src/package.json` - `apps/server/src/package.json` - `packages/desktop-lib/package.json` - `packages/desktop-window/package.json` * fix: cspell spelling * fix: desktop-core package postion in packages array --------- Co-authored-by: Rahul R. <rahulrathore576@gmail.com> |
||
|
|
cfc501514b |
[Feat] Create video plugin module (#8613)
* feat: adds video model and refactors imports Introduces a new video model to support video functionalities. This includes properties for video metadata, storage information, and relationships with other models like time slots and employees. Additionally, several imports are reorganized for better code structure. * feat: adds Video entity This introduces the `Video` entity to store video-related information, including title, file path, recording date, duration, size, URL, storage provider, description, resolution, codec, frame rate, and uploader details. It includes validation and relationships with `TimeSlot` and `Employee` entities. * feat: introduces file storage path generation This change introduces a new mechanism for generating file storage paths. It uses a combination of date, tenant ID, and employee ID to create unique and organized storage locations. A factory class simplifies the creation of storage engines with this path generation logic. * feat(videos): adds DTOs for video management Introduces Data Transfer Objects (DTOs) for creating, updating, and deleting videos. Includes a FileDTO for handling video uploads and a BaseVideoDTO for common video properties. These DTOs provide type safety and validation for video-related operations. * feat: adds video repositories for MikroORM and TypeORM Introduces `MikroOrmVideoRepository` and `TypeOrmVideoRepository` to support different ORM integrations. * feat: adds video service Introduces a new service to manage video entities. It utilizes both TypeORM and MikroORM repositories for data access. * feat: add video entity and migration This commit introduces the `Video` entity and its corresponding database migration. The migration creates the `videos` table with fields for video metadata like title, file path, duration, size, storage provider, and relations to other entities such as tenant, organization, time slot, and uploading employee. It also includes indexes for efficient querying. The migration handles different database types (PostgreSQL, SQLite, Better SQLite3, MySQL) and includes specific up and down migration logic for each. * feat: adds commands and handlers for video management This commit introduces new commands and handlers for managing videos: - Creates `CreateVideoCommand` and `CreateVideoHandler` to add new videos. - Implements `UpdateVideoCommand` and `UpdateVideoHandler` to modify existing videos. - Adds `DeleteVideoCommand` and `DeleteVideoHandler` to remove videos. This change enables basic CRUD operations for videos within the application. * feat: adds queries and handlers for fetching videos This introduces new queries and handlers for retrieving video data: - `GetVideoQuery` and `GetVideoQueryHandler`: Fetch a single video by ID. - `GetVideosQuery` and `GetVideosQueryHandler`: Fetch a list of videos with pagination support. * feat: adds video subscriber for lifecycle management Implements a TypeORM subscriber for the `Video` entity to manage file storage during entity lifecycle events. - Sets the `fullUrl` property after loading a video entity by retrieving the URL from the configured storage provider. - Deletes the associated video file from storage after a video entity is deleted. This ensures consistent data and efficient storage management by automatically handling file operations related to videos. * feat(videos): implements video controller This commit introduces a new video controller feature, including: - Creating new video records with associated metadata and file uploads. - Retrieving video records by ID. - Listing all video records with pagination support. - Deleting video records. The implementation uses CQRS and leverages a file storage service for managing video files. It also includes validation and error handling for file uploads and data integrity. * feat: Implements video plugin module This commit introduces a new video plugin. It includes: - A new module for videos with controllers, services, and repositories. - Integration with TypeORM and MikroORM for database operations. - CQRS implementation for handling commands and queries. - Role-based permission management. - Routing configuration for the plugin. * feat: adds video entity and subscriber Introduces the `Video` entity and its corresponding subscriber to the core module. This lays the foundation for managing video data within the application. * feat: adds PluginModule to AppModule Registers the PluginModule in the application's root module to enable plugin functionality. * fix: cspell spelling * feat(plugin-video-capture): create library for video capture plugin * refactor: plugin video capture module & entity * fix(migration): video table for plugin video capture * fix(videos): Implement query handlers for video CRUD operations * fix(migration): refactor `video` [table] for MySQL * refactor: suggestion by coderabbit AI * fix(migration): refactor `video` [table] for DBs * fix(subscriber): video subscriber initialization and event handling * fix(cspell): typo spelling :-) --------- Co-authored-by: Rahul R. <rahulrathore576@gmail.com> |
||
|
|
ab9e03f3c6 | chore: target node v20 | ||
|
|
ed51e258fd |
[Feat] Prevent Double Click on Start/Stop Button (#8516)
* feat: add BLOCK_DELAY constant `10 sec` * feat: add pulse animation to start/stop buttons, modified button styles, and refactore timer logic * fix: cspell |
||
|
|
d86d8233fa | feat: only reset icon when remote timer is not running, and added ngIf condition to only render gauzy-time-tracker-status when isRemoteTimer is true. | ||
|
|
7023d16d06 | feat: add margin-top to .top-bottom-space and adjusted height of .gallery-inner in image-viewer.component.scss | ||
|
|
a0c6c71658 | refactor: getLastTimeSlotImage and localImage methods with additional checks and logic | ||
|
|
90d15d08e9 | feat: apply code rabbit suggestions | ||
|
|
3d556b2a91 | feat: apply code rabbit suggestions | ||
|
|
f33e8f6984 |
[Feat] use async processing status, added translations for loading messages in various languages (#8445)
* feat: use async processing status, added translations for loading messages in various languages. * fix: translation when quitApp is true * fix: using code rabbit suggestion |
||
|
|
8a3cf1451c | refactor: getLastTimeSlotImage call, and added null checks and warnings for empty image gallery | ||
|
|
9adecad7f2 | feat: add conditional icon display | ||
|
|
5b8a90fb24 | fiix: add return type to getTimeSlot method, checked for empty timeSlotId, and modified API request parameters | ||
|
|
84cca538fe | fix: update TimeSlotCacheService to extend AbstractCacheService<ITimeSlot> instead of AbstractCacheService<ITimeSlot[]> and adjust type parameters in constructor. | ||
|
|
9384fc31ea | feat: translated workspace selection component and added i18n support for multiple languages | ||
|
|
0002dd73fc |
[Fix] Selector error validators (#8433)
* feat: create validation interface * feat: implement validators * feat: add error method to note service * fix: text area error view * feat: implement error message component * fix: selectors validation * feat: add error messages for form fields, disabled apply button when form is invalid, and updated component styles and logic * fix: cspell spelling * fix: code rabbit |
||
|
|
97ea1a4e3f |
[Feat] Selector update persistence electron side (#8421)
* feat: create electron selector service * feat: electronService with selectorElectronService in client-selector, note, project-selector, task-selector, and team-selector components * fix: rename 'refresh' method to 'clear' in client-selector, project-selector, task-selector, and team-selector components * feat: add conditional check for `this.useStore` in `clear()` method of ClientSelector, ProjectSelector, TaskSelector, and TeamSelector components. |
||
|
|
4cae2ae0ca |
feat: add missing version property to timer objects in SequenceQueue and TimeTrackerComponent.
|
||
|
|
e0675a9de8 | feat: add two function calls to updateTaskStatus and updateOrganizationTeamEmployee on silent restart | ||
|
|
1446e8e0c2 | refactor: time tracker component to combine conditions for retrieving remote log and handle API request | ||
|
|
4f6475a7c4 | fix: login components to handle workspace navigation and state | ||
|
|
753327f718 | resolves #8379 by fixing late desktop theme listener setup | ||
|
|
d7f2eaa574 |
fix: rename _errorHandlingService to errorHandlingService and update type annotations in NgxLoginComponent constructor and tap callback.
|
||
|
|
be6b74d734 | feat: login components to handle workspace login and navigation | ||
|
|
37ef1bddad | feat: added "packages/ui-core/static/styles" to stylePreprocessorOptions includePaths in three Angular configurations. | ||
|
|
378bce530b |
[Fix] Remote timer logic stop calls (#8394)
* fix: remote timer logic and stopTimer calls * refactor: remote timer logic |
||
|
|
2ef1e4d1db |
[Fix] Task deselect on refresh (#8392)
* fix: task deselect on refresh * fix: add `organizationTeamId` missing property to time tracker API request and spread `arg.timer` into the request object. * fix: apply code rabbit suggestion |
||
|
|
f8080cfce5 |
[Feat] Implement magic login (#8387)
* feat: create reusable workspace selection component * feat: create debounce click directive * feat: create reusable avatar component * feat: implement login magic component * feat: implement login magic workspace component * feat: implement login workspace component * feat: reuse shared core styles * feat: add new component to login * feat: create authentication routes * feat: use lazy loading for authentications routes * fix: add code rabbit suggestions * fix: apply code rabbit suggestions * fix: apply code rabbit suggestions |
||
|
|
afb5d20f8c |
[Feat] Create Reusable Component and Add Workspace Links (#8383)
* feat: export social links * feat: create a shared logo component * feat: create a shared social links component * feat: add reusable patterns to constants * feat: add link to magic workspace signin and use reusable logo, links and switch * feat: SwitchThemeModule, LogoComponent, and SocialLinksComponent to NgxLoginModule |
||
|
|
4cb550b4ae |
[Feat] Add new workspace's methods to desktop authentication service (#8375)
* feat: add new methods to service * feat: remove unecessary try-catch blocks and type annotations for return values in AuthService methods. |
||
|
|
e691c0fb92 | feat: activate plugin after installation | ||
|
|
19b8708343 | fix: handle native modules | ||
|
|
0b8a5d7c57 | feat: reload setting on authentication | ||
|
|
5156db42a3 |
fix: remove unnecessary createSettingsWindow calls.
|
||
|
|
ec7fd910f2 | fix: build issue | ||
|
|
c377842396 | fix: timeslot startedAt variable | ||
|
|
3968519ea5 |
[Fix] Issue with Changing Task on Running Timer (#8281)
* feat: add ITimeTrackerFormState to time-tracker.store * feat: pass data to ignition restart and store last selector state * feat: add `data` parameter to concatMap operator and called update selector states with it |
||
|
|
383ecef3ef | fix: remove unsused line | ||
|
|
e4ae9e1c08 | feat: use windows manager and add new submenu to the unauth menu | ||
|
|
2ad75b65d2 | fix: desktop theme listener implementation | ||
|
|
ccd993ac57 |
[Perf] Introduce server side pagination for selectors (#8274)
* feat: create routing for tabs * feat: improve lanaguage service * feat: create cached server data server * feat: caching task for 24 hours * feat: add new observable to `selectorService` * feat: change modidier private to public * feat: improve create task dialog * feat: create task table features * feat: replace table with router tabset * fix: deepscan * feat: add pagination type to task cache * feat: improve selector with pagination params * feat: add new input to generic ng selector * feat: update ISelector interface * feat: introduce server side pagination for task selectors * feat: infinite scroll on client selector * feat: removed 'tags' from relations in client selector request and updated method call to getClientWithPagination * refactor: code in various components and services to improve pagination and caching functionality * feat: add reset page functionality to client, project, and team selectors; updated task table component to use selected project and team IDs; refactored time tracker service to use toParams function * fix: remove "prefix" property from search term object in task table component. * feat: updated TimeTrackerService to use TaskStatisticsCacheService * fix: 'tags' from relations and modified join and where clauses in TimeTrackerService * feat: add search component with debounce and loading indicator, updated task table component to display loading spinner, and refactored cached server data source to handle loading state * fix: removed spinner from search component, updated search component to use distinctUntilChange and filter, and removed loading state handling from task table component * feat: update SelectComponent to use Subject<string> for typeahead instead of any" * fix: add search functionality to TaskSelectorService and TaskSelectorComponent, updated TimeTrackerService to include search term in API request * fix: add search functionality to client selector, project selector, and team selector components and services * feat: add typeToSearchText input property to SelectComponent and updated template to use it * refactor: moved nbSpinner to separate div, added absolute positioning and dimensions to .smart-table class * fix: relations and join from TimeTrackerService query parameters, update employeeId condition * refactored: tasks component, replaced ng-select with gauzy-select, updated imports and modules, and made minor template changes. * fix: Task Table component HTML and SCSS: wrapped spinner in ng-container, changed smart-table styles to use absolute positioning and added padding. * fix: remove resetPage calls from client-selector, project-selector, and team-selector components. * refactor: selector components to extend AbstractSelectorComponent, update search logic, and add NG_VALUE_ACCESSOR provider * feat: use selectors as `formControl` for reactive forms * refactor: selectors and make it reusable for reactive form and template binding form * refactor: selector store and components, update time tracker component and dialog * fix: max-width property * fix: cspell * Update project-cache.service.ts * Update client-cache.service.ts * Update teams-cache.service.ts --------- Co-authored-by: Ruslan Konviser <evereq@gmail.com> |
||
|
|
417bb09507 |
[Refactor] Timer Stop flow and updated activity building (#8269)
* refactor: add remote timer check, updated activity building, and split screenshot taking and uploading into separate steps * refactor: modify createTimeSlot method to return timeSlotId and error, and adjust calling code accordingly * fix: deepscan * fix: comment in TimeTrackerComponent to change 'Check if is a remote timer.' to 'Make sure it's not a remote timer' * refactor: time tracker component to reorganize stop timer logic and add network processing * fix: typo in comment: "networtk" -> "network" |
||
|
|
dccb73d66c | fix: styles for switch theme component, including toggle button layout, icon display, and animation. | ||
|
|
d6930df88a | feat: add name filtering to project | ||
|
|
cef2854913 |
fix: moment.js comparisons and calculations in ScheduleTimeLogEntriesHandler
|
||
|
|
9326961153 | fix: update moment.js comparisons in TimerService: changed sort order and diff calculation | ||
|
|
2a89855f83 |
[Perf] Introduce server side pagination for tasks table and Lazy loading (#8243)
* feat: create routing for tabs * feat: improve lanaguage service * feat: create cached server data server * feat: caching task for 24 hours * feat: add new observable to `selectorService` * feat: change modidier private to public * feat: improve create task dialog * feat: create task table features * feat: replace table with router tabset * fix: deepscan |
||
|
|
ceb93a388a | feat: add today's start and end date to timer status request | ||
|
|
88de863ae1 |
[Feat] Implement NPM download strategy (#8237)
* feat: implement npm download strategy * feat: add support of private registry * refactor: NpmDownloadStrategy - add logging, decompress tarball, read and parse metadata, rename plugin directory, and remove downloaded .tgz file * feat: add Plugin component with new UI, added NPM installation option, and refactored code * feat: add tar and extract from .tgz * feat: add logging statements to NpmDownloadStrategy class to track package info, tarball URL, and download progress. * fix: remove unnecessary comments in NpmDownloadStrategy class. * refactor: NpmDownloadStrategy, update AddPluginComponent and plugins.module.ts * refactor: NpmDownloadStrategy to read and parse metadata, install dependencies, and add recursive dependency installation * feat: install dependencies in parallel * feat: added TextMaskDirective to DesktopDirectiveModule and implemented it in add-plugin component for authToken input field * Fix: typo in npm-download.strategy.ts and remove comment in tarball.util.t |