Browse Source

Merge branch 'main' into feature/simplify-user-table-of-admin-control-panel

pull/5263/head
Thomas Kaul 3 weeks ago
committed by GitHub
parent
commit
e454d68aea
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 14
      CHANGELOG.md
  2. 6
      apps/api/src/app/portfolio/portfolio.controller.ts
  3. 9
      apps/api/src/app/portfolio/portfolio.service.ts
  4. 415
      apps/api/src/assets/cryptocurrencies/cryptocurrencies.json
  5. 35
      apps/client/src/app/components/accounts-table/accounts-table.component.html
  6. 5
      apps/client/src/app/components/accounts-table/accounts-table.component.ts
  7. 1
      apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html
  8. 6
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts
  9. 57
      apps/client/src/assets/oss-friends.json
  10. 3266
      apps/client/src/locales/messages.ca.xlf
  11. 3314
      apps/client/src/locales/messages.de.xlf
  12. 3332
      apps/client/src/locales/messages.es.xlf
  13. 3076
      apps/client/src/locales/messages.fr.xlf
  14. 3318
      apps/client/src/locales/messages.it.xlf
  15. 3278
      apps/client/src/locales/messages.nl.xlf
  16. 3352
      apps/client/src/locales/messages.pl.xlf
  17. 3062
      apps/client/src/locales/messages.pt.xlf
  18. 3380
      apps/client/src/locales/messages.tr.xlf
  19. 3222
      apps/client/src/locales/messages.uk.xlf
  20. 3163
      apps/client/src/locales/messages.xlf
  21. 3306
      apps/client/src/locales/messages.zh.xlf
  22. 2
      apps/client/src/styles.scss
  23. 80
      apps/client/src/styles/bootstrap.scss
  24. 2
      libs/common/src/lib/interfaces/responses/portfolio-report.interface.ts
  25. 1
      libs/common/src/lib/types/account-with-value.type.ts
  26. 3
      libs/ui/src/lib/toggle/toggle.component.scss
  27. 1893
      package-lock.json
  28. 2
      package.json

14
CHANGELOG.md

@ -7,10 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Added the allocation column to the accounts table component of the holding detail dialog
### Changed
- Restructured the response of the portfolio report endpoint (_X-ray_)
- Improved the usability of the toggle component
- Simplified the users table of the admin control panel
- Restructured the response of the portfolio report endpoint (_X-ray_)
- Refreshed the cryptocurrencies list
- Improved the language localization for Catalan (`ca`)
- Improved the language localization for Chinese (`zh`)
- Improved the language localization for Dutch (`nl`)
- Improved the language localization for German (`de`)
- Improved the language localization for Spanish (`es`)
- Upgraded `ng-extract-i18n-merge` from version `2.15.1` to `3.0.0`
### Fixed

6
apps/api/src/app/portfolio/portfolio.controller.ts

@ -655,11 +655,11 @@ export class PortfolioController {
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
this.request.user.subscription.type === 'Basic'
) {
for (const rule in report['x-ray'].rules) {
report['x-ray'].rules[rule] = null;
for (const rule in report.xRay.rules) {
report.xRay.rules[rule] = null;
}
report['x-ray'].statistics = {
report.xRay.statistics = {
rulesActiveCount: 0,
rulesFulfilledCount: 0
};

9
apps/api/src/app/portfolio/portfolio.service.ts

@ -191,6 +191,7 @@ export class PortfolioService {
...account,
transactionCount,
valueInBaseCurrency,
allocationInPercentage: null, // TODO
balanceInBaseCurrency: this.exchangeRateDataService.toCurrency(
account.balance,
account.currency,
@ -1156,7 +1157,7 @@ export class PortfolioService {
})
).toNumber();
const rules: PortfolioReportResponse['x-ray']['rules'] = {
const rules: PortfolioReportResponse['xRay']['rules'] = {
accountClusterRisk:
summary.activityCount > 0
? await this.rulesService.evaluate(
@ -1312,7 +1313,7 @@ export class PortfolioService {
};
return {
'x-ray': {
xRay: {
rules,
statistics: this.getReportStatistics(rules)
}
@ -1736,8 +1737,8 @@ export class PortfolioService {
}
private getReportStatistics(
evaluatedRules: PortfolioReportResponse['x-ray']['rules']
): PortfolioReportResponse['x-ray']['statistics'] {
evaluatedRules: PortfolioReportResponse['xRay']['rules']
): PortfolioReportResponse['xRay']['statistics'] {
const rulesActiveCount = Object.values(evaluatedRules)
.flat()
.filter((rule) => {

415
apps/api/src/assets/cryptocurrencies/cryptocurrencies.json

File diff suppressed because it is too large

35
apps/client/src/app/components/accounts-table/accounts-table.component.html

@ -231,6 +231,35 @@
</td>
</ng-container>
<ng-container matColumnDef="allocation">
<th
*matHeaderCellDef
class="d-none d-lg-table-cell justify-content-end px-1"
mat-header-cell
mat-sort-header
>
<ng-container i18n>Allocation</ng-container>
</th>
<td
*matCellDef="let element"
class="d-none d-lg-table-cell px-1 text-right"
mat-cell
>
<gf-value
class="d-inline-block justify-content-end"
[isPercent]="true"
[locale]="locale"
[precision]="2"
[value]="element.allocationInPercentage"
/>
</td>
<td
*matFooterCellDef
class="d-none d-lg-table-cell px-1"
mat-footer-cell
></td>
</ng-container>
<ng-container matColumnDef="comment">
<th
*matHeaderCellDef
@ -291,7 +320,11 @@
</button>
</mat-menu>
</td>
<td *matFooterCellDef class="px-1" mat-footer-cell></td>
<td
*matFooterCellDef
class="d-none d-lg-table-cell px-1"
mat-footer-cell
></td>
</ng-container>
<tr *matHeaderRowDef="displayedColumns" mat-header-row></tr>

5
apps/client/src/app/components/accounts-table/accounts-table.component.ts

@ -60,6 +60,7 @@ export class GfAccountsTableComponent implements OnChanges, OnDestroy {
@Input() hasPermissionToOpenDetails = true;
@Input() locale = getLocale();
@Input() showActions: boolean;
@Input() showAllocationInPercentage: boolean;
@Input() showBalance = true;
@Input() showFooter = true;
@Input() showTransactions = true;
@ -117,6 +118,10 @@ export class GfAccountsTableComponent implements OnChanges, OnDestroy {
this.displayedColumns.push('valueInBaseCurrency');
}
if (this.showAllocationInPercentage) {
this.displayedColumns.push('allocation');
}
this.displayedColumns.push('comment');
if (this.showActions) {

1
apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html

@ -375,6 +375,7 @@
[deviceType]="data.deviceType"
[hasPermissionToOpenDetails]="false"
[locale]="user?.settings?.locale"
[showAllocationInPercentage]="user?.settings?.isExperimentalFeatures"
[showBalance]="false"
[showFooter]="false"
[showTransactions]="false"

6
apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts

@ -47,7 +47,7 @@ export class GfXRayPageComponent {
public inactiveRules: PortfolioReportRule[];
public isLoading = false;
public regionalMarketClusterRiskRules: PortfolioReportRule[];
public statistics: PortfolioReportResponse['x-ray']['statistics'];
public statistics: PortfolioReportResponse['xRay']['statistics'];
public user: User;
private unsubscribeSubject = new Subject<void>();
@ -115,7 +115,7 @@ export class GfXRayPageComponent {
this.dataService
.fetchPortfolioReport()
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe(({ 'x-ray': { rules, statistics } }) => {
.subscribe(({ xRay: { rules, statistics } }) => {
this.inactiveRules = this.mergeInactiveRules(rules);
this.statistics = statistics;
@ -161,7 +161,7 @@ export class GfXRayPageComponent {
}
private mergeInactiveRules(
rules: PortfolioReportResponse['x-ray']['rules']
rules: PortfolioReportResponse['xRay']['rules']
): PortfolioReportRule[] {
let inactiveRules: PortfolioReportRule[] = [];

57
apps/client/src/assets/oss-friends.json

@ -1,5 +1,5 @@
{
"createdAt": "2024-12-30T00:00:00.000Z",
"createdAt": "2025-07-28T00:00:00.000Z",
"data": [
{
"name": "Activepieces",
@ -16,11 +16,6 @@
"description": "Argos provides the developer tools to debug tests and detect visual regressions.",
"href": "https://argos-ci.com"
},
{
"name": "BoxyHQ",
"description": "BoxyHQ’s suite of APIs for security and privacy helps engineering teams build and ship compliant cloud applications faster.",
"href": "https://boxyhq.com"
},
{
"name": "Cal.com",
"description": "Cal.com is a scheduling tool that helps you schedule meetings without the back-and-forth emails.",
@ -31,41 +26,16 @@
"description": "ClassroomIO is a no-code tool that allows you build and scale your own teaching platform with ease.",
"href": "https://www.classroomio.com"
},
{
"name": "Crowd.dev",
"description": "Centralize community, product, and customer data to understand which companies are engaging with your open source project.",
"href": "https://www.crowd.dev"
},
{
"name": "DevHunt",
"description": "Find the best Dev Tools upvoted by the community every week.",
"href": "https://devhunt.org"
},
{
"name": "Documenso",
"description": "The Open-Source DocuSign Alternative. We aim to earn your trust by enabling you to self-host the platform and examine its inner workings.",
"href": "https://documenso.com"
},
{
"name": "dyrector.io",
"description": "dyrector.io is an open-source continuous delivery & deployment platform with version management.",
"href": "https://dyrector.io"
},
{
"name": "Firecamp",
"description": "vscode for apis, open-source postman/insomnia alternative",
"href": "https://firecamp.io"
},
{
"name": "Formbricks",
"description": "Open source survey software and Experience Management Platform. Understand your customers, keep full control over your data.",
"href": "https://formbricks.com"
},
{
"name": "GitWonk",
"description": "GitWonk is an open-source technical documentation tool, designed and built focusing on the developer experience.",
"href": "https://gitwonk.com"
},
{
"name": "Hanko",
"description": "Open-source authentication and user management for the passkey era. Integrated in minutes, for web and mobile apps.",
@ -96,11 +66,6 @@
"description": "Open source LLM engineering platform. Debug, analyze and iterate together.",
"href": "https://langfuse.com"
},
{
"name": "Lost Pixel",
"description": "Open source visual regression testing alternative to Percy & Chromatic",
"href": "https://lost-pixel.com"
},
{
"name": "Mockoon",
"description": "Mockoon is the easiest and quickest way to design and run mock REST APIs.",
@ -116,6 +81,11 @@
"description": "Open-source monitoring platform with beautiful status pages",
"href": "https://www.openstatus.dev"
},
{
"name": "Papermark",
"description": "Open-Source Docsend Alternative to securely share documents with real-time analytics.",
"href": "https://www.papermark.com"
},
{
"name": "Portkey AI",
"description": "AI Gateway with integrated Guardrails. Route to 250+ LLMs and 50+ Guardrails with 1-fast API. Supports caching, retries, and edge deployment for low latency.",
@ -146,11 +116,6 @@
"description": "Sniffnet is a network monitoring tool to help you easily keep track of your Internet traffic.",
"href": "https://www.sniffnet.net"
},
{
"name": "Spark.NET",
"description": "The .NET Web Framework for Makers. Build production ready, full-stack web applications fast without sweating the small stuff.",
"href": "https://spark-framework.net"
},
{
"name": "Tiledesk",
"description": "The innovative open-source framework for developing LLM-enabled chatbots, Tiledesk empowers developers to create advanced, conversational AI agents.",
@ -176,16 +141,16 @@
"description": "Typebot gives you powerful blocks to create unique chat experiences. Embed them anywhere on your apps and start collecting results like magic.",
"href": "https://typebot.io"
},
{
"name": "UnInbox",
"description": "Modern email for teams and professionals. Bringing the best of email and messaging into a single, modern, and secure platform.",
"href": "https://uninbox.com"
},
{
"name": "Unkey",
"description": "An API authentication and authorization platform for scaling user facing APIs. Create, verify, and manage low latency API keys in seconds.",
"href": "https://unkey.dev"
},
{
"name": "Voltagent",
"description": "Open Source TypeScript framework for building AI agents with enterprise-grade capabilities and seamless integrations.",
"href": "https://voltagent.dev"
},
{
"name": "Webiny",
"description": "Open-source enterprise-grade serverless CMS. Own your data. Scale effortlessly. Customize everything.",

3266
apps/client/src/locales/messages.ca.xlf

File diff suppressed because it is too large

3314
apps/client/src/locales/messages.de.xlf

File diff suppressed because it is too large

3332
apps/client/src/locales/messages.es.xlf

File diff suppressed because it is too large

3076
apps/client/src/locales/messages.fr.xlf

File diff suppressed because it is too large

3318
apps/client/src/locales/messages.it.xlf

File diff suppressed because it is too large

3278
apps/client/src/locales/messages.nl.xlf

File diff suppressed because it is too large

3352
apps/client/src/locales/messages.pl.xlf

File diff suppressed because it is too large

3062
apps/client/src/locales/messages.pt.xlf

File diff suppressed because it is too large

3380
apps/client/src/locales/messages.tr.xlf

File diff suppressed because it is too large

3222
apps/client/src/locales/messages.uk.xlf

File diff suppressed because it is too large

3163
apps/client/src/locales/messages.xlf

File diff suppressed because it is too large

3306
apps/client/src/locales/messages.zh.xlf

File diff suppressed because it is too large

2
apps/client/src/styles.scss

@ -1,7 +1,7 @@
@import './styles/bootstrap';
@import './styles/table';
@import 'node_modules/svgmap/dist/svgMap';
@import 'svgmap/dist/svgMap';
:root {
--dark-background: rgb(25, 25, 25);

80
apps/client/src/styles/bootstrap.scss

@ -1,44 +1,44 @@
/*!
* Bootstrap v4.5.2 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Bootstrap v4.6.2 (https://getbootstrap.com/)
* Copyright 2011-2022 The Bootstrap Authors
* Copyright 2011-2022 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@import 'node_modules/bootstrap/scss/functions';
@import 'node_modules/bootstrap/scss/variables';
@import 'node_modules/bootstrap/scss/mixins';
@import 'node_modules/bootstrap/scss/root';
@import 'node_modules/bootstrap/scss/reboot';
@import 'node_modules/bootstrap/scss/type';
@import 'node_modules/bootstrap/scss/images';
// @import 'node_modules/bootstrap/scss/code';
@import 'node_modules/bootstrap/scss/grid';
// @import 'node_modules/bootstrap/scss/tables';
// @import 'node_modules/bootstrap/scss/forms';
// @import 'node_modules/bootstrap/scss/buttons';
// @import 'node_modules/bootstrap/scss/transitions';
// @import 'node_modules/bootstrap/scss/dropdown';
// @import 'node_modules/bootstrap/scss/button-group';
// @import 'node_modules/bootstrap/scss/input-group';
// @import 'node_modules/bootstrap/scss/custom-forms';
// @import 'node_modules/bootstrap/scss/nav';
// @import 'node_modules/bootstrap/scss/navbar';
// @import 'node_modules/bootstrap/scss/card';
@import 'node_modules/bootstrap/scss/breadcrumb';
// @import 'node_modules/bootstrap/scss/pagination';
@import 'node_modules/bootstrap/scss/badge';
// @import 'node_modules/bootstrap/scss/jumbotron';
// @import 'node_modules/bootstrap/scss/alert';
// @import 'node_modules/bootstrap/scss/progress';
// @import 'node_modules/bootstrap/scss/media';
// @import 'node_modules/bootstrap/scss/list-group';
// @import 'node_modules/bootstrap/scss/close';
// @import 'node_modules/bootstrap/scss/toasts';
// @import 'node_modules/bootstrap/scss/modal';
// @import 'node_modules/bootstrap/scss/tooltip';
// @import 'node_modules/bootstrap/scss/popover';
// @import 'node_modules/bootstrap/scss/carousel';
// @import 'node_modules/bootstrap/scss/spinners';
@import 'node_modules/bootstrap/scss/utilities';
// @import 'node_modules/bootstrap/scss/print';
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins';
@import 'bootstrap/scss/root';
@import 'bootstrap/scss/reboot';
@import 'bootstrap/scss/type';
@import 'bootstrap/scss/images';
// @import 'bootstrap/scss/code';
@import 'bootstrap/scss/grid';
// @import 'bootstrap/scss/tables';
// @import 'bootstrap/scss/forms';
// @import 'bootstrap/scss/buttons';
// @import 'bootstrap/scss/transitions';
// @import 'bootstrap/scss/dropdown';
// @import 'bootstrap/scss/button-group';
// @import 'bootstrap/scss/input-group';
// @import 'bootstrap/scss/custom-forms';
// @import 'bootstrap/scss/nav';
// @import 'bootstrap/scss/navbar';
// @import 'bootstrap/scss/card';
@import 'bootstrap/scss/breadcrumb';
// @import 'bootstrap/scss/pagination';
@import 'bootstrap/scss/badge';
// @import 'bootstrap/scss/jumbotron';
// @import 'bootstrap/scss/alert';
// @import 'bootstrap/scss/progress';
// @import 'bootstrap/scss/media';
// @import 'bootstrap/scss/list-group';
// @import 'bootstrap/scss/close';
// @import 'bootstrap/scss/toasts';
// @import 'bootstrap/scss/modal';
// @import 'bootstrap/scss/tooltip';
// @import 'bootstrap/scss/popover';
// @import 'bootstrap/scss/carousel';
// @import 'bootstrap/scss/spinners';
@import 'bootstrap/scss/utilities';
// @import 'bootstrap/scss/print';

2
libs/common/src/lib/interfaces/responses/portfolio-report.interface.ts

@ -1,7 +1,7 @@
import { PortfolioReportRule } from '../portfolio-report-rule.interface';
export interface PortfolioReportResponse {
'x-ray': {
xRay: {
rules: { [group: string]: PortfolioReportRule[] };
statistics: {
rulesActiveCount: number;

1
libs/common/src/lib/types/account-with-value.type.ts

@ -1,6 +1,7 @@
import { Account as AccountModel, Platform } from '@prisma/client';
export type AccountWithValue = AccountModel & {
allocationInPercentage: number;
balanceInBaseCurrency: number;
platform?: Platform;
transactionCount: number;

3
libs/ui/src/lib/toggle/toggle.component.scss

@ -4,7 +4,6 @@
.mat-mdc-radio-button {
border-radius: 1rem;
margin: 0 0.25rem;
padding: 0.15rem 0.75rem;
&.mat-mdc-radio-checked {
background-color: rgba(var(--dark-dividers));
@ -19,7 +18,7 @@
color: rgba(var(--dark-primary-text), 1);
cursor: inherit;
margin: 0;
padding: 0;
padding: 0.15rem 0.75rem;
}
}
}

1893
package-lock.json

File diff suppressed because it is too large

2
package.json

@ -122,7 +122,7 @@
"lodash": "4.17.21",
"marked": "15.0.4",
"ms": "3.0.0-canary.1",
"ng-extract-i18n-merge": "2.15.1",
"ng-extract-i18n-merge": "3.0.0",
"ngx-device-detector": "10.0.2",
"ngx-markdown": "20.0.0",
"ngx-skeleton-loader": "11.2.1",

Loading…
Cancel
Save