Browse Source

Merge branch 'main' into task/upgrade-countries-and-timezones-to-version-3.9.0

pull/6817/head
Thomas Kaul 6 days ago
committed by GitHub
parent
commit
eec7e96088
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      .gitignore
  2. 1
      .prettierignore
  3. 9
      CHANGELOG.md
  4. 132
      apps/api/src/assets/cryptocurrencies/cryptocurrencies.json
  5. 2
      apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts
  6. 2
      apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html
  7. 2
      apps/client/src/app/components/admin-jobs/admin-jobs.html
  8. 6
      apps/client/src/app/components/admin-market-data/admin-market-data.html
  9. 14
      apps/client/src/app/components/admin-users/admin-users.html
  10. 72
      apps/client/src/app/components/header/header.component.html
  11. 2
      apps/client/src/app/components/header/header.component.ts
  12. 2
      apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts
  13. 18
      apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html
  14. 2
      apps/client/src/app/components/home-holdings/home-holdings.component.ts
  15. 2
      apps/client/src/app/components/home-holdings/home-holdings.html
  16. 2
      apps/client/src/app/components/home-overview/home-overview.component.ts
  17. 7
      apps/client/src/app/components/home-overview/home-overview.html
  18. 4
      apps/client/src/app/components/portfolio-performance/portfolio-performance.component.html
  19. 3
      apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts
  20. 11
      apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html
  21. 3
      apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts
  22. 2
      apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts
  23. 10
      apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html
  24. 2
      apps/client/src/app/components/rule/rule.component.html
  25. 9
      apps/client/src/app/components/rule/rule.component.ts
  26. 3
      apps/client/src/app/pages/about/overview/about-overview-page.component.ts
  27. 2
      apps/client/src/app/pages/about/overview/about-overview-page.html
  28. 3
      apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts
  29. 2
      apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html
  30. 2
      apps/client/src/app/pages/landing/landing-page.component.ts
  31. 6
      apps/client/src/app/pages/landing/landing-page.html
  32. 2
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts
  33. 55
      apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html
  34. 4
      apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts
  35. 4
      apps/client/src/app/pages/portfolio/allocations/allocations-page.html
  36. 2
      apps/client/src/app/pages/portfolio/fire/fire-page.html
  37. 7
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html
  38. 2
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts
  39. 3
      apps/client/src/app/pages/pricing/pricing-page.component.ts
  40. 4
      apps/client/src/app/pages/pricing/pricing-page.html
  41. 2
      apps/client/src/app/pages/public/public-page.component.ts
  42. 2
      apps/client/src/app/pages/public/public-page.html
  43. 12
      apps/client/src/styles.scss
  44. 6
      libs/ui/src/lib/accounts-table/accounts-table.component.html
  45. 2
      libs/ui/src/lib/accounts-table/accounts-table.component.ts
  46. 8
      libs/ui/src/lib/activities-table/activities-table.component.html
  47. 2
      libs/ui/src/lib/activity-type/activity-type.component.html
  48. 3
      libs/ui/src/lib/activity-type/activity-type.component.ts
  49. 6
      libs/ui/src/lib/benchmark/benchmark.component.html
  50. 2
      libs/ui/src/lib/benchmark/benchmark.component.ts
  51. 2
      libs/ui/src/lib/dialog-header/dialog-header.component.html
  52. 3
      libs/ui/src/lib/dialog-header/dialog-header.component.ts
  53. 2
      libs/ui/src/lib/entity-logo/entity-logo.component.html
  54. 2
      libs/ui/src/lib/entity-logo/entity-logo.component.ts
  55. 2
      libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html
  56. 2
      libs/ui/src/lib/logo/logo.component.html
  57. 2
      libs/ui/src/lib/logo/logo.component.ts
  58. 4
      libs/ui/src/lib/membership-card/membership-card.component.html
  59. 9
      libs/ui/src/lib/membership-card/membership-card.component.ts
  60. 4
      libs/ui/src/lib/toggle/toggle.component.html
  61. 3
      libs/ui/src/lib/toggle/toggle.component.ts
  62. 6
      libs/ui/src/lib/top-holdings/top-holdings.component.html
  63. 2
      libs/ui/src/lib/top-holdings/top-holdings.component.ts
  64. 4
      libs/ui/src/lib/trend-indicator/trend-indicator.component.html
  65. 6
      libs/ui/src/lib/value/value.component.html
  66. 1327
      package-lock.json
  67. 26
      package.json

2
.gitignore

@ -32,6 +32,8 @@ npm-debug.log
.env.prod .env.prod
.github/instructions/nx.instructions.md .github/instructions/nx.instructions.md
.nx/cache .nx/cache
.nx/polygraph
.nx/self-healing
.nx/workspace-data .nx/workspace-data
/.sass-cache /.sass-cache
/connect.lock /connect.lock

1
.prettierignore

@ -1,5 +1,6 @@
/.agents/skills/angular-developer /.agents/skills/angular-developer
/.nx/cache /.nx/cache
/.nx/self-healing
/.nx/workspace-data /.nx/workspace-data
/apps/client/src/polyfills.ts /apps/client/src/polyfills.ts
/dist /dist

9
CHANGELOG.md

@ -9,7 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- Migrated various components from `NgClass` to class bindings
- Refreshed the cryptocurrencies list
- Upgraded `@ionic/angular` from version `8.8.1` to `8.8.5`
- Upgraded `countries-and-timezones` from version `3.8.0` to `3.9.0` - Upgraded `countries-and-timezones` from version `3.8.0` to `3.9.0`
- Upgraded `fuse.js` from version `7.1.0` to `7.3.0`
- Upgraded `Nx` from version `22.6.5` to `22.7.1`
### Fixed
- Fixed a visual regression in the bottom navigation bar on mobile
## 3.2.0 - 2026-05-03 ## 3.2.0 - 2026-05-03

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

@ -193,6 +193,7 @@
"AARK": "Aark", "AARK": "Aark",
"AART": "ALL.ART", "AART": "ALL.ART",
"AAST": "AASToken", "AAST": "AASToken",
"AASTEROID": "Alien Asteroid",
"AAT": "Agricultural Trade Chain", "AAT": "Agricultural Trade Chain",
"AAVAWBTC": "Aave aWBTC", "AAVAWBTC": "Aave aWBTC",
"AAVE": "Aave", "AAVE": "Aave",
@ -280,7 +281,7 @@
"ACTA": "Acta Finance", "ACTA": "Acta Finance",
"ACTIN": "Actinium", "ACTIN": "Actinium",
"ACTN": "Action Coin", "ACTN": "Action Coin",
"ACU": "ACU Platform", "ACU": "Acurast Token",
"ACX": "Across Protocol", "ACX": "Across Protocol",
"ACXT": "ACDX Exchange Token", "ACXT": "ACDX Exchange Token",
"ACYC": "All Coins Yield Capital", "ACYC": "All Coins Yield Capital",
@ -389,7 +390,7 @@
"AGATA": "Agatech", "AGATA": "Agatech",
"AGATOKEN": "AGA Token", "AGATOKEN": "AGA Token",
"AGB": "Apes Go Bananas", "AGB": "Apes Go Bananas",
"AGC": "Argocoin", "AGC": "Alien Green Cat",
"AGEN": "Agent Krasnov", "AGEN": "Agent Krasnov",
"AGENT": "AgentLayer", "AGENT": "AgentLayer",
"AGENTFUN": "AgentFun.AI", "AGENTFUN": "AgentFun.AI",
@ -417,6 +418,7 @@
"AGOV": "Answer Governance", "AGOV": "Answer Governance",
"AGPC": "AGPC", "AGPC": "AGPC",
"AGRI": "AgriDex Token", "AGRI": "AgriDex Token",
"AGRICULTURALUNIONS": "Agricultural Unions",
"AGRO": "Bit Agro", "AGRO": "Bit Agro",
"AGRS": "Agoras Token", "AGRS": "Agoras Token",
"AGS": "Aegis", "AGS": "Aegis",
@ -605,6 +607,7 @@
"ALBART": "Albärt", "ALBART": "Albärt",
"ALBE": "ALBETROS", "ALBE": "ALBETROS",
"ALBEDO": "ALBEDO", "ALBEDO": "ALBEDO",
"ALBON": "Albemarle (Ondo Tokenized)",
"ALBT": "AllianceBlock", "ALBT": "AllianceBlock",
"ALC": "Arab League Coin", "ALC": "Arab League Coin",
"ALCAZAR": "Alcazar", "ALCAZAR": "Alcazar",
@ -700,6 +703,7 @@
"ALTMAN": "SAM", "ALTMAN": "SAM",
"ALTOCAR": "AltoCar", "ALTOCAR": "AltoCar",
"ALTR": "Altranium", "ALTR": "Altranium",
"ALTSZN": "ALTSEASON",
"ALTT": "Altcoinist", "ALTT": "Altcoinist",
"ALU": "Altura", "ALU": "Altura",
"ALUSD": "Alchemix USD", "ALUSD": "Alchemix USD",
@ -994,6 +998,7 @@
"ARG": "Argentine Football Association Fan Token", "ARG": "Argentine Football Association Fan Token",
"ARGENTUM": "Argentum", "ARGENTUM": "Argentum",
"ARGO": "ArGoApp", "ARGO": "ArGoApp",
"ARGOCOIN": "Argocoin",
"ARGON": "Argon", "ARGON": "Argon",
"ARGUS": "ArgusCoin", "ARGUS": "ArgusCoin",
"ARI": "AriCoin", "ARI": "AriCoin",
@ -1123,10 +1128,11 @@
"ASTA": "ASTA", "ASTA": "ASTA",
"ASTER": "Aster", "ASTER": "Aster",
"ASTERINU": "Aster INU", "ASTERINU": "Aster INU",
"ASTEROID": "ASTEROID", "ASTEROID": "Asteroid Shiba",
"ASTEROIDBOT": "Asteroid Bot", "ASTEROIDBOT": "Asteroid Bot",
"ASTEROIDCOIN": "ASTEROID", "ASTEROIDCOIN": "ASTEROID",
"ASTEROIDETH": "Asteroid", "ASTEROIDETH": "Asteroid",
"ASTEROIDFIT": "ASTEROID",
"ASTHERUSUSDF": "Astherus USDF", "ASTHERUSUSDF": "Astherus USDF",
"ASTO": "Altered State Token", "ASTO": "Altered State Token",
"ASTON": "Aston", "ASTON": "Aston",
@ -1396,7 +1402,6 @@
"BABI": "Babylons", "BABI": "Babylons",
"BABL": "Babylon Finance", "BABL": "Babylon Finance",
"BABY": "Babylon", "BABY": "Babylon",
"BABY4": "Baby 4",
"BABYANDY": "Baby Andy", "BABYANDY": "Baby Andy",
"BABYASTER": "Baby Aster", "BABYASTER": "Baby Aster",
"BABYB": "Baby Bali", "BABYB": "Baby Bali",
@ -1778,7 +1783,7 @@
"BDID": "BDID", "BDID": "BDID",
"BDIN": "BendDAO BDIN", "BDIN": "BendDAO BDIN",
"BDL": "Bitdeal", "BDL": "Bitdeal",
"BDOG": "Bulldog Token", "BDOG": "BurnDog",
"BDOGITO": "BullDogito", "BDOGITO": "BullDogito",
"BDOT": "Binance Wrapped DOT", "BDOT": "Binance Wrapped DOT",
"BDP": "Big Data Protocol", "BDP": "Big Data Protocol",
@ -1846,6 +1851,7 @@
"BELA": "Bela", "BELA": "Bela",
"BELG": "Belgian Malinois", "BELG": "Belgian Malinois",
"BELIEVE": "Believe", "BELIEVE": "Believe",
"BELKA": "The Dancing Squirrel",
"BELL": "Bellscoin", "BELL": "Bellscoin",
"BELLE": "Isabelle", "BELLE": "Isabelle",
"BELLS": "Bellscoin", "BELLS": "Bellscoin",
@ -1882,8 +1888,9 @@
"BERN": "BERNcash", "BERN": "BERNcash",
"BERNIE": "BERNIE SENDERS", "BERNIE": "BERNIE SENDERS",
"BERRIE": "Berrie Token", "BERRIE": "Berrie Token",
"BERRY": "Berry", "BERRY": "Strawberry AI",
"BERRYS": "BerrySwap", "BERRYS": "BerrySwap",
"BERRYSTORE": "Berry",
"BERT": "Bertram The Pomeranian", "BERT": "Bertram The Pomeranian",
"BES": "battle esports coin", "BES": "battle esports coin",
"BESA": "Besa Gaming", "BESA": "Besa Gaming",
@ -1935,6 +1942,7 @@
"BGB": "Bitget token", "BGB": "Bitget token",
"BGBG": "BigMouthFrog", "BGBG": "BigMouthFrog",
"BGBP": "Binance GBP Stable Coin", "BGBP": "Binance GBP Stable Coin",
"BGBTC": "Bitget Wrapped BTC",
"BGBV1": "Bitget Token v1", "BGBV1": "Bitget Token v1",
"BGC": "Bee Token", "BGC": "Bee Token",
"BGCI": "Bloomberg Galaxy Crypto Index", "BGCI": "Bloomberg Galaxy Crypto Index",
@ -1989,6 +1997,7 @@
"BIDI": "Bidipass", "BIDI": "Bidipass",
"BIDP": "BID Protocol", "BIDP": "BID Protocol",
"BIDR": "Binance IDR Stable Coin", "BIDR": "Binance IDR Stable Coin",
"BIDUON": "Baidu (Ondo Tokenized)",
"BIDZ": "BIDZ Coin", "BIDZ": "BIDZ Coin",
"BIDZV1": "BIDZ Coin v1", "BIDZV1": "BIDZ Coin v1",
"BIFI": "Beefy.Finance", "BIFI": "Beefy.Finance",
@ -2133,6 +2142,7 @@
"BITTO": "BITTO", "BITTO": "BITTO",
"BITTON": "Bitton", "BITTON": "Bitton",
"BITTY": "The Bitcoin Mascot", "BITTY": "The Bitcoin Mascot",
"BITUBU": "UBU",
"BITUPTOKEN": "BitUP Token", "BITUPTOKEN": "BitUP Token",
"BITUSD": "bitUSD", "BITUSD": "bitUSD",
"BITV": "Bitvolt", "BITV": "Bitvolt",
@ -2196,6 +2206,7 @@
"BLC": "BlakeCoin", "BLC": "BlakeCoin",
"BLCT": "Bloomzed Loyalty Club Ticket", "BLCT": "Bloomzed Loyalty Club Ticket",
"BLD": "Agoric", "BLD": "Agoric",
"BLEND": "Fluent",
"BLENDR": "Blendr Network", "BLENDR": "Blendr Network",
"BLEPE": "Blepe", "BLEPE": "Blepe",
"BLERF": "BLERF", "BLERF": "BLERF",
@ -2218,7 +2229,7 @@
"BLKC": "BlackHat Coin", "BLKC": "BlackHat Coin",
"BLKD": "Blinked", "BLKD": "Blinked",
"BLKS": "Blockshipping", "BLKS": "Blockshipping",
"BLM": "Blombard", "BLM": "BLM coin",
"BLN": "Bulleon", "BLN": "Bulleon",
"BLNM": "Bolenum", "BLNM": "Bolenum",
"BLOB": "B.O.B the Blob", "BLOB": "B.O.B the Blob",
@ -2247,6 +2258,7 @@
"BLOCX": "BLOCX.", "BLOCX": "BLOCX.",
"BLOGGE": "Bloggercube", "BLOGGE": "Bloggercube",
"BLOK": "Bloktopia", "BLOK": "Bloktopia",
"BLOMBARD": "Blombard",
"BLOO": "bloo foster coin", "BLOO": "bloo foster coin",
"BLOOCYS": "BlooCYS", "BLOOCYS": "BlooCYS",
"BLOODY": "Bloody Token", "BLOODY": "Bloody Token",
@ -2880,6 +2892,7 @@
"BTFA": "Banana Task Force Ape", "BTFA": "Banana Task Force Ape",
"BTG": "Bitcoin Gold", "BTG": "Bitcoin Gold",
"BTGON": "B2Gold (Ondo Tokenized)", "BTGON": "B2Gold (Ondo Tokenized)",
"BTGOON": "BitGo Holdings (Ondo Tokenized)",
"BTH": "Bithereum", "BTH": "Bithereum",
"BTK": "Bostoken", "BTK": "Bostoken",
"BTL": "Bitlocus", "BTL": "Bitlocus",
@ -2973,11 +2986,12 @@
"BUL": "bul", "BUL": "bul",
"BULDAK": "Buldak", "BULDAK": "Buldak",
"BULEI": "Bulei", "BULEI": "Bulei",
"BULL": "Tron Bull", "BULL": "Bull",
"BULLA": "BULLA", "BULLA": "BULLA",
"BULLBEAR": "BullBear AI", "BULLBEAR": "BullBear AI",
"BULLC": "BuySell", "BULLC": "BuySell",
"BULLDOG": "BullDog Coin", "BULLDOG": "BullDog Coin",
"BULLDOGTOKEN": "Bulldog Token",
"BULLF": "BULL FINANCE", "BULLF": "BULL FINANCE",
"BULLGOD": "Bull God", "BULLGOD": "Bull God",
"BULLI": "Bullish On Ethereum", "BULLI": "Bullish On Ethereum",
@ -3392,7 +3406,6 @@
"CDOGE": "cyberdoge", "CDOGE": "cyberdoge",
"CDPT": "Creditor Data Platform", "CDPT": "Creditor Data Platform",
"CDRX": "CDRX", "CDRX": "CDRX",
"CDT": "CheckDot",
"CDX": "CDX Network", "CDX": "CDX Network",
"CDY": "Bitcoin Candy", "CDY": "Bitcoin Candy",
"CDragon": "Clumsy Dragon", "CDragon": "Clumsy Dragon",
@ -3513,6 +3526,7 @@
"CHC": "ChainCoin", "CHC": "ChainCoin",
"CHD": "CharityDAO", "CHD": "CharityDAO",
"CHECK": "Checkmate", "CHECK": "Checkmate",
"CHECKDOT": "CheckDot",
"CHECKR": "CheckerChain", "CHECKR": "CheckerChain",
"CHECOIN": "CheCoin", "CHECOIN": "CheCoin",
"CHED": "Giggleched", "CHED": "Giggleched",
@ -3573,6 +3587,7 @@
"CHINU": "Chubby Inu", "CHINU": "Chubby Inu",
"CHIP": "Chip", "CHIP": "Chip",
"CHIPI": "chipi", "CHIPI": "chipi",
"CHIPP": "Chip",
"CHIPPY": "Chippy", "CHIPPY": "Chippy",
"CHIPS": "CHIPS", "CHIPS": "CHIPS",
"CHIRP": "Chirp Token", "CHIRP": "Chirp Token",
@ -4350,6 +4365,7 @@
"CVX": "Convex Finance", "CVX": "Convex Finance",
"CVXCRV": "Convex CRV", "CVXCRV": "Convex CRV",
"CVXFXS": "Convex FXS", "CVXFXS": "Convex FXS",
"CVXON": "Chevron (Ondo Tokenized)",
"CVXX": "Chevron xStock", "CVXX": "Chevron xStock",
"CW": "CardWallet", "CW": "CardWallet",
"CWA": "Chris World Asset", "CWA": "Chris World Asset",
@ -4741,6 +4757,7 @@
"DEPAY": "DePay", "DEPAY": "DePay",
"DEPIN": "DEPIN", "DEPIN": "DEPIN",
"DEPINU": "Depression Inu", "DEPINU": "Depression Inu",
"DEPLOYR": "Deployr",
"DEPO": "Depo", "DEPO": "Depo",
"DEPTH": "Depth Token", "DEPTH": "Depth Token",
"DEQ": "Dequant", "DEQ": "Dequant",
@ -5363,6 +5380,7 @@
"DUA": "Brillion", "DUA": "Brillion",
"DUAL": "DUAL", "DUAL": "DUAL",
"DUALDAOTOKEN": "Dual Finance", "DUALDAOTOKEN": "Dual Finance",
"DUALV1": "BLOCKv",
"DUB": "DubCoin", "DUB": "DubCoin",
"DUBAICAT": "Dubai Cat", "DUBAICAT": "Dubai Cat",
"DUBBZ": "Dubbz", "DUBBZ": "Dubbz",
@ -5548,6 +5566,7 @@
"ECHO": "Echo", "ECHO": "Echo",
"ECHOBOT": "ECHO BOT", "ECHOBOT": "ECHO BOT",
"ECHOD": "EchoDEX", "ECHOD": "EchoDEX",
"ECHON": "iShares MSCI Chile ETF (Ondo Tokenized)",
"ECHT": "e-Chat", "ECHT": "e-Chat",
"ECI": "Euro Cup Inu", "ECI": "Euro Cup Inu",
"ECKODAO": "eckoDAO", "ECKODAO": "eckoDAO",
@ -6110,6 +6129,7 @@
"EVERGROW": "EverGrowCoin", "EVERGROW": "EverGrowCoin",
"EVERLIFE": "EverLife.AI", "EVERLIFE": "EverLife.AI",
"EVERMOON": "EverMoon", "EVERMOON": "EverMoon",
"EVERRISE": "EverRise",
"EVERV": "EverValue Coin", "EVERV": "EverValue Coin",
"EVERY": "Everyworld", "EVERY": "Everyworld",
"EVIL": "EvilCoin", "EVIL": "EvilCoin",
@ -6160,6 +6180,7 @@
"EXN": "Exeno", "EXN": "Exeno",
"EXNT": "EXNT", "EXNT": "EXNT",
"EXO": "Exosis", "EXO": "Exosis",
"EXODON": "Exodus Movement (Ondo Tokenized)",
"EXOS": "Exobots", "EXOS": "Exobots",
"EXP": "Expanse", "EXP": "Expanse",
"EXPAND": "Gems", "EXPAND": "Gems",
@ -6213,6 +6234,7 @@
"FACTR": "Defactor", "FACTR": "Defactor",
"FACTRPAY": "FactR", "FACTRPAY": "FactR",
"FACY": "ArAIstotle Fact Checker", "FACY": "ArAIstotle Fact Checker",
"FADEWALLET": "FadeWallet Token",
"FADO": "FADO Go", "FADO": "FADO Go",
"FAFO": "FAFO", "FAFO": "FAFO",
"FAFOSOL": "Fafo", "FAFOSOL": "Fafo",
@ -6312,6 +6334,7 @@
"FCT": "FirmaChain", "FCT": "FirmaChain",
"FCTC": "FaucetCoin", "FCTC": "FaucetCoin",
"FCTR": "FactorDAO", "FCTR": "FactorDAO",
"FCXON": "Freeport-McMoRan (Ondo Tokenized)",
"FDC": "FDrive Coin", "FDC": "FDrive Coin",
"FDGC": "FINTECH DIGITAL GOLD COIN", "FDGC": "FINTECH DIGITAL GOLD COIN",
"FDLS": "FIDELIS", "FDLS": "FIDELIS",
@ -6364,6 +6387,7 @@
"FFCT": "FortFC", "FFCT": "FortFC",
"FFM": "Files.fm Library", "FFM": "Files.fm Library",
"FFN": "Fairy Forest", "FFN": "Fairy Forest",
"FFOGON": "Franklin Focused Growth ETF (Ondo Tokenized)",
"FFTP": "FIGHT FOR THE PEOPLE", "FFTP": "FIGHT FOR THE PEOPLE",
"FFUEL": "getFIFO", "FFUEL": "getFIFO",
"FFYI": "Fiscus FYI", "FFYI": "Fiscus FYI",
@ -6535,6 +6559,7 @@
"FLOOR": "FloorDAO", "FLOOR": "FloorDAO",
"FLOP": "Big Floppa", "FLOP": "Big Floppa",
"FLOPPA": "Floppa Cat", "FLOPPA": "Floppa Cat",
"FLOR": "FLORK",
"FLORK": "FLORK BNB", "FLORK": "FLORK BNB",
"FLORKY": "Florky", "FLORKY": "Florky",
"FLOSHIDO": "FLOSHIDO INU", "FLOSHIDO": "FLOSHIDO INU",
@ -6549,6 +6574,7 @@
"FLOWP": "Flow Protocol", "FLOWP": "Flow Protocol",
"FLOYX": "Floyx", "FLOYX": "Floyx",
"FLP": "Gameflip", "FLP": "Gameflip",
"FLQLON": "Franklin US Large Cap Multifactor Index ETF (Ondo Tokenized)",
"FLR": "Flare", "FLR": "Flare",
"FLRBRG": "Floor Cheese Burger", "FLRBRG": "Floor Cheese Burger",
"FLRS": "Flourish Coin", "FLRS": "Flourish Coin",
@ -6802,6 +6828,7 @@
"FSN": "Fusion", "FSN": "Fusion",
"FSNV1": "Fusion v1", "FSNV1": "Fusion v1",
"FSO": "FSociety", "FSO": "FSociety",
"FSOLON": "Fidelity Solana Fund (Ondo Tokenized)",
"FST": "FreeStyle Token", "FST": "FreeStyle Token",
"FSTC": "FastCoin", "FSTC": "FastCoin",
"FSTR": "Fourth Star", "FSTR": "Fourth Star",
@ -7131,6 +7158,7 @@
"GENS": "Genshiro", "GENS": "Genshiro",
"GENSLR": "Good Gensler", "GENSLR": "Good Gensler",
"GENSTAKE": "Genstake", "GENSTAKE": "Genstake",
"GENSYN": "Gensyn",
"GENT": "Gentleman", "GENT": "Gentleman",
"GENX": "Genx Token", "GENX": "Genx Token",
"GENXNET": "Genesis Network", "GENXNET": "Genesis Network",
@ -7313,6 +7341,7 @@
"GLR": "Glory Finance", "GLR": "Glory Finance",
"GLS": "Glacier", "GLS": "Glacier",
"GLT": "GlobalToken", "GLT": "GlobalToken",
"GLTRON": "abrdn Physical Precious Metals Basket Shares ETF (Ondo Tokenized)",
"GLUE": "Glue", "GLUE": "Glue",
"GLX": "GalaxyCoin", "GLX": "GalaxyCoin",
"GLYPH": "GlyphCoin", "GLYPH": "GlyphCoin",
@ -7569,10 +7598,11 @@
"GRIDZ": "GridZone.io", "GRIDZ": "GridZone.io",
"GRIFFAIN": "GRIFFAIN", "GRIFFAIN": "GRIFFAIN",
"GRIFT": "ORBIT", "GRIFT": "ORBIT",
"GRIM": "GRIMREAPER", "GRIM": "GrimHustle",
"GRIMACE": "Grimace", "GRIMACE": "Grimace",
"GRIMEVO": "Grim EVO", "GRIMEVO": "Grim EVO",
"GRIMEX": "SpaceGrime", "GRIMEX": "SpaceGrime",
"GRIMREAPER": "GRIMREAPER",
"GRIN": "Grin", "GRIN": "Grin",
"GRIND": "Self Improving", "GRIND": "Self Improving",
"GRIPPY": "GRIPPY", "GRIPPY": "GRIPPY",
@ -7955,6 +7985,7 @@
"HEWE": "Health & Wealth", "HEWE": "Health & Wealth",
"HEX": "HEX", "HEX": "HEX",
"HEXC": "HexCoin", "HEXC": "HexCoin",
"HEYFLORK": "HeyFlork",
"HEZ": "Hermez Network Token", "HEZ": "Hermez Network Token",
"HF": "Have Fun", "HF": "Have Fun",
"HFI": "Holder Finance", "HFI": "Holder Finance",
@ -8348,11 +8379,12 @@
"IBG": "iBG Token", "IBG": "iBG Token",
"IBGT": "Infrared BGT", "IBGT": "Infrared BGT",
"IBIT": "InfinityBit Token", "IBIT": "InfinityBit Token",
"IBITON": "iShares Bitcoin Trust (Ondo Tokenized)",
"IBMX": "International Business Machines xStock", "IBMX": "International Business Machines xStock",
"IBNB": "iBNB", "IBNB": "iBNB",
"IBP": "Innovation Blockchain Payment", "IBP": "Innovation Blockchain Payment",
"IBS": "Irbis Network", "IBS": "Irbis Network",
"IC": "Ignition", "IC": "Icy",
"ICA": "Icarus Network", "ICA": "Icarus Network",
"ICAP": "ICAP Token", "ICAP": "ICAP Token",
"ICASH": "ICASH", "ICASH": "ICASH",
@ -8442,6 +8474,7 @@
"IGGT": "The Invincible Game Token", "IGGT": "The Invincible Game Token",
"IGI": "Igi", "IGI": "Igi",
"IGNIS": "Ignis", "IGNIS": "Ignis",
"IGNITION": "Ignition",
"IGT": "Infinitar", "IGT": "Infinitar",
"IGTT": "IGT", "IGTT": "IGT",
"IGU": "IguVerse", "IGU": "IguVerse",
@ -8496,7 +8529,6 @@
"IMS": "Independent Money System", "IMS": "Independent Money System",
"IMST": "Imsmart", "IMST": "Imsmart",
"IMT": "Immortal Token", "IMT": "Immortal Token",
"IMU": "Immunefi",
"IMUSIFY": "imusify", "IMUSIFY": "imusify",
"IMVR": "ImmVRse", "IMVR": "ImmVRse",
"IMX": "Immutable X", "IMX": "Immutable X",
@ -8509,11 +8541,13 @@
"INCEPT": "Incept", "INCEPT": "Incept",
"INCNT": "Incent", "INCNT": "Incent",
"INCO": "InfinitiCoin", "INCO": "InfinitiCoin",
"INCOME": "Universal High Income",
"INCORGNITO": "Incorgnito", "INCORGNITO": "Incorgnito",
"INCP": "InceptionCoin", "INCP": "InceptionCoin",
"INCREMENTUM": "Incrementum", "INCREMENTUM": "Incrementum",
"INCX": "INCX Coin", "INCX": "INCX Coin",
"IND": "Indorse", "IND": "Indorse",
"INDAON": "iShares MSCI India ETF (Ondo Tokenized)",
"INDAY": "Independence Day", "INDAY": "Independence Day",
"INDEPENDENCEDAY": "Independence Day", "INDEPENDENCEDAY": "Independence Day",
"INDEX": "Index Cooperative", "INDEX": "Index Cooperative",
@ -8621,6 +8655,7 @@
"IONC": "IONChain", "IONC": "IONChain",
"IONOMY": "Ionomy", "IONOMY": "Ionomy",
"IONP": "Ion Power Token", "IONP": "Ion Power Token",
"IONQON": "IonQ (Ondo Tokenized)",
"IONX": "Charged Particles", "IONX": "Charged Particles",
"IONZ": "IONZ", "IONZ": "IONZ",
"IOP": "Internet of People", "IOP": "Internet of People",
@ -8704,6 +8739,7 @@
"ITALOCOIN": "Italocoin", "ITALOCOIN": "Italocoin",
"ITAM": "ITAM Games", "ITAM": "ITAM Games",
"ITAMCUBE": "CUBE", "ITAMCUBE": "CUBE",
"ITAON": "iShares US Aerospace and Defense ETF (Ondo Tokenized)",
"ITC": "IoT Chain", "ITC": "IoT Chain",
"ITE": "Idle Tribe Era", "ITE": "Idle Tribe Era",
"ITEM": "ITEMVERSE", "ITEM": "ITEMVERSE",
@ -9377,6 +9413,7 @@
"KONET": "KONET", "KONET": "KONET",
"KONG": "KONG", "KONG": "KONG",
"KONO": "Konomi Network", "KONO": "Konomi Network",
"KOON": "Coca-Cola (Ondo Tokenized)",
"KORA": "Kortana", "KORA": "Kortana",
"KORC": "King of Referral Coin", "KORC": "King of Referral Coin",
"KORE": "KORE Vault", "KORE": "KORE Vault",
@ -9490,6 +9527,7 @@
"KWAI": "KWAI", "KWAI": "KWAI",
"KWATT": "4New", "KWATT": "4New",
"KWD": "KIWI DEFI", "KWD": "KIWI DEFI",
"KWEBON": "KraneShares CSI China Internet ETF (Ondo Tokenized)",
"KWEEN": "KWEEN", "KWEEN": "KWEEN",
"KWENTA": "Kwenta", "KWENTA": "Kwenta",
"KWH": "KWHCoin", "KWH": "KWHCoin",
@ -9877,6 +9915,7 @@
"LMR": "Lumerin", "LMR": "Lumerin",
"LMT": "LIMITUS", "LMT": "LIMITUS",
"LMTOKEN": "LM Token", "LMTOKEN": "LM Token",
"LMTON": "Lockheed (Ondo Tokenized)",
"LMTS": "Limitless Official Token", "LMTS": "Limitless Official Token",
"LMWR": "LimeWire Token", "LMWR": "LimeWire Token",
"LMXC": "LimonX", "LMXC": "LimonX",
@ -10118,6 +10157,7 @@
"LUNES": "Lunes", "LUNES": "Lunes",
"LUNG": "LunaGens", "LUNG": "LunaGens",
"LUNR": "Lunr Token", "LUNR": "Lunr Token",
"LUNRON": "Intuitive Machines (Ondo Tokenized)",
"LUPIN": "LUPIN", "LUPIN": "LUPIN",
"LUR": "Lumera", "LUR": "Lumera",
"LUS": "Luna Rush", "LUS": "Luna Rush",
@ -10295,7 +10335,8 @@
"MANUSAI": "Manus AI Agent", "MANUSAI": "Manus AI Agent",
"MANYU": "Manyu", "MANYU": "Manyu",
"MANYUDOG": "MANYU", "MANYUDOG": "MANYU",
"MAO": "Mao", "MAO": "MAO",
"MAOMEME": "Mao",
"MAOW": "MAOW", "MAOW": "MAOW",
"MAP": "MAP Protocol", "MAP": "MAP Protocol",
"MAPC": "MapCoin", "MAPC": "MapCoin",
@ -11573,6 +11614,7 @@
"NBAR": "NOBAR", "NBAR": "NOBAR",
"NBC": "Niobium", "NBC": "Niobium",
"NBD": "Never Back Down", "NBD": "Never Back Down",
"NBISON": "Nebius Group (Ondo Tokenized)",
"NBIT": "NetBit", "NBIT": "NetBit",
"NBL": "Nobility", "NBL": "Nobility",
"NBLU": "NuriTopia", "NBLU": "NuriTopia",
@ -11649,6 +11691,7 @@
"NEKOS": "Nekocoin", "NEKOS": "Nekocoin",
"NEKTAR": "Nektar Token", "NEKTAR": "Nektar Token",
"NEMO": "NEMO", "NEMO": "NEMO",
"NEMON": "Newmont (Ondo Tokenized)",
"NEMS": "The Nemesis", "NEMS": "The Nemesis",
"NEO": "NEO", "NEO": "NEO",
"NEOG": "NEO Gold", "NEOG": "NEO Gold",
@ -11938,6 +11981,7 @@
"NOVA": "Nova Finance", "NOVA": "Nova Finance",
"NOVAAI": "Nova AI", "NOVAAI": "Nova AI",
"NOW": "NOW Token", "NOW": "NOW Token",
"NOWON": "ServiceNow (Ondo Tokenized)",
"NOX": "NITRO", "NOX": "NITRO",
"NOXB": "Noxbox", "NOXB": "Noxbox",
"NPAS": "New Paradigm Assets Solution", "NPAS": "New Paradigm Assets Solution",
@ -12218,6 +12262,7 @@
"OHNOGG": "OHNHO (ohno.gg)", "OHNOGG": "OHNHO (ohno.gg)",
"OHO": "OHO", "OHO": "OHO",
"OICOIN": "Osmium Investment Coin", "OICOIN": "Osmium Investment Coin",
"OIHON": "VanEck Oil Services ETF (Ondo Tokenized)",
"OIIAOIIA": "spinning cat", "OIIAOIIA": "spinning cat",
"OIK": "Space Nation", "OIK": "Space Nation",
"OIL": "Oiler", "OIL": "Oiler",
@ -12314,8 +12359,9 @@
"ONION": "DeepOnion", "ONION": "DeepOnion",
"ONIT": "ONBUFF", "ONIT": "ONBUFF",
"ONIX": "Onix", "ONIX": "Onix",
"ONL": "On.Live", "ONL": "OneLink",
"ONLINE": "Onlinebase", "ONLINE": "Onlinebase",
"ONLIVE": "On.Live",
"ONLY": "OnlyCam", "ONLY": "OnlyCam",
"ONLYCUMIES": "OnlyCumies", "ONLYCUMIES": "OnlyCumies",
"ONLYFANSCOINS": "$OFC Coin", "ONLYFANSCOINS": "$OFC Coin",
@ -12375,6 +12421,7 @@
"OPES": "Opes", "OPES": "Opes",
"OPET": "ÕpetFoundation", "OPET": "ÕpetFoundation",
"OPEX": "Optherium Token", "OPEX": "Optherium Token",
"OPG": "OpenGradient",
"OPHX": "Operation Phoenix", "OPHX": "Operation Phoenix",
"OPINU": "Optimus Inu", "OPINU": "Optimus Inu",
"OPIUM": "Opium", "OPIUM": "Opium",
@ -12675,6 +12722,7 @@
"PATRIOT": "Patriot", "PATRIOT": "Patriot",
"PATTON": "Patton", "PATTON": "Patton",
"PAUL": "Elephant Penguin", "PAUL": "Elephant Penguin",
"PAVEON": "Global X US Infrastructure Development ETF (Ondo Tokenized)",
"PAVIA": "Pavia", "PAVIA": "Pavia",
"PAVO": "Pavocoin", "PAVO": "Pavocoin",
"PAW": "PAWSWAP", "PAW": "PAWSWAP",
@ -13397,6 +13445,7 @@
"PPI": "Primpy", "PPI": "Primpy",
"PPIZZA": "P Pizza", "PPIZZA": "P Pizza",
"PPL": "Pink Panther Lovers", "PPL": "Pink Panther Lovers",
"PPLTON": "abrdn Physical Platinum Shares ETF (Ondo Tokenized)",
"PPM": "Punk Panda Messenger", "PPM": "Punk Panda Messenger",
"PPN": "Puppies Network", "PPN": "Puppies Network",
"PPOVR": "POVR", "PPOVR": "POVR",
@ -13443,6 +13492,7 @@
"PRIMATE": "Primate", "PRIMATE": "Primate",
"PRIME": "Echelon Prime", "PRIME": "Echelon Prime",
"PRIMECHAIN": "PrimeChain", "PRIMECHAIN": "PrimeChain",
"PRIMECOIN": "PrimeCoin",
"PRIMEETH": "Prime Staked ETH", "PRIMEETH": "Prime Staked ETH",
"PRIMEX": "Primex Finance", "PRIMEX": "Primex Finance",
"PRIN": "Print The Pepe", "PRIN": "Print The Pepe",
@ -13792,6 +13842,7 @@
"QUBE": "Qube", "QUBE": "Qube",
"QUBIC": "Qubic", "QUBIC": "Qubic",
"QUBITICA": "Qubitica", "QUBITICA": "Qubitica",
"QUBTON": "Quantum Computing (Ondo Tokenized)",
"QUBY": "Quby", "QUBY": "Quby",
"QUDEFI": "Qudefi", "QUDEFI": "Qudefi",
"QUE": "Queen Of Memes", "QUE": "Queen Of Memes",
@ -13966,6 +14017,7 @@
"RDR": "Rise of Defenders", "RDR": "Rise of Defenders",
"RDS": "Reger Diamond", "RDS": "Reger Diamond",
"RDT": "Ridotto", "RDT": "Ridotto",
"RDWON": "Redwire (Ondo Tokenized)",
"RDX": "Redux Protocol", "RDX": "Redux Protocol",
"REA": "Realisto", "REA": "Realisto",
"REACH": "/Reach", "REACH": "/Reach",
@ -14028,6 +14080,7 @@
"REFI": "Realfinance Network", "REFI": "Realfinance Network",
"REFLECT": "REFLECT", "REFLECT": "REFLECT",
"REFLECTO": "Reflecto", "REFLECTO": "Reflecto",
"REFLECTOUSD": "Reflecto USD",
"REFTOKEN": "RefToken", "REFTOKEN": "RefToken",
"REFUND": "Refund", "REFUND": "Refund",
"REG": "RealToken Ecosystem Governance", "REG": "RealToken Ecosystem Governance",
@ -14037,6 +14090,7 @@
"REGEN": "Regen Network", "REGEN": "Regen Network",
"REGENT": "REGENT COIN", "REGENT": "REGENT COIN",
"REGI": "Resistance Girl", "REGI": "Resistance Girl",
"REGNON": "Regeneron Pharmaceuticals (Ondo Tokenized)",
"REGRET": "Regret", "REGRET": "Regret",
"REHA": "Resistance Hamster", "REHA": "Resistance Hamster",
"REHAB": "NFT Rehab", "REHAB": "NFT Rehab",
@ -14202,7 +14256,7 @@
"RIPT": "RiptideCoin", "RIPT": "RiptideCoin",
"RIPTO": "RiptoBuX", "RIPTO": "RiptoBuX",
"RIS": "Riser", "RIS": "Riser",
"RISE": "EverRise", "RISE": "Rise NASA",
"RISECOIN": "Rise coin", "RISECOIN": "Rise coin",
"RISEP": "Rise Protocol", "RISEP": "Rise Protocol",
"RISEVISION": "Rise", "RISEVISION": "Rise",
@ -14227,6 +14281,7 @@
"RKC": "Royal Kingdom Coin", "RKC": "Royal Kingdom Coin",
"RKEY": "RKEY", "RKEY": "RKEY",
"RKI": "RAKHI", "RKI": "RAKHI",
"RKLBON": "Rocket Lab (Ondo Tokenized)",
"RKN": "RAKON", "RKN": "RAKON",
"RKR": "REAKTOR", "RKR": "REAKTOR",
"RKT": "Rock Token", "RKT": "Rock Token",
@ -14426,6 +14481,7 @@
"RUGPROOF": "Launchpad", "RUGPROOF": "Launchpad",
"RUGPULL": "Captain Rug Pull", "RUGPULL": "Captain Rug Pull",
"RUGZ": "pulltherug.finance", "RUGZ": "pulltherug.finance",
"RUJI": "Rujira",
"RULER": "Ruler Protocol", "RULER": "Ruler Protocol",
"RUM": "RUM Pirates of The Arrland Token", "RUM": "RUM Pirates of The Arrland Token",
"RUN": "Speedrun", "RUN": "Speedrun",
@ -14440,7 +14496,7 @@
"RUP": "Rupee", "RUP": "Rupee",
"RUPX": "Rupaya", "RUPX": "Rupaya",
"RURI": "Ruri - Truth Terminal's Crush", "RURI": "Ruri - Truth Terminal's Crush",
"RUSD": "Reflecto USD", "RUSD": "Royal Dollar",
"RUSH": "RUSH COIN", "RUSH": "RUSH COIN",
"RUSHCMC": "RUSHCMC", "RUSHCMC": "RUSHCMC",
"RUSSELL": "Russell", "RUSSELL": "Russell",
@ -14659,6 +14715,7 @@
"SBSC": "Subscriptio", "SBSC": "Subscriptio",
"SBT": "SOLBIT", "SBT": "SOLBIT",
"SBTC": "Super Bitcoin", "SBTC": "Super Bitcoin",
"SBUXON": "Starbucks (Ondo Tokenized)",
"SC": "Siacoin", "SC": "Siacoin",
"SC20": "Shine Chain", "SC20": "Shine Chain",
"SCA": "Scallop", "SCA": "Scallop",
@ -14675,6 +14732,7 @@
"SCASH": "SpaceCash", "SCASH": "SpaceCash",
"SCAT": "Sad Cat Token", "SCAT": "Sad Cat Token",
"SCC": "StockChain Coin", "SCC": "StockChain Coin",
"SCCOON": "Southern Copper (Ondo Tokenized)",
"SCCP": "S.C. Corinthians Fan Token", "SCCP": "S.C. Corinthians Fan Token",
"SCDS": "Shrine Cloud Storage Network", "SCDS": "Shrine Cloud Storage Network",
"SCF": "Smoking Chicken Fish", "SCF": "Smoking Chicken Fish",
@ -15054,6 +15112,7 @@
"SHX": "Stronghold Token", "SHX": "Stronghold Token",
"SHXV1": "Stronghold Token v1", "SHXV1": "Stronghold Token v1",
"SHY": "Shytoshi Kusama", "SHY": "Shytoshi Kusama",
"SHYON": "iShares 1-3 Year Treasury Bond ETF (Ondo Tokenized)",
"SHYTCOIN": "ShytCoin", "SHYTCOIN": "ShytCoin",
"SI": "Siren", "SI": "Siren",
"SI14": "Si14", "SI14": "Si14",
@ -15248,6 +15307,7 @@
"SLUGDENG": "SLUG DENG", "SLUGDENG": "SLUG DENG",
"SLUMBO": "SLUMBO", "SLUMBO": "SLUMBO",
"SLVLUSD": "Staked Level USD", "SLVLUSD": "Staked Level USD",
"SLVN": "SLVNToken",
"SLVON": "iShares Silver Trust (Ondo Tokenized)", "SLVON": "iShares Silver Trust (Ondo Tokenized)",
"SLVX": "eToro Silver", "SLVX": "eToro Silver",
"SLX": "SLIMEX", "SLX": "SLIMEX",
@ -15339,6 +15399,7 @@
"SNC": "SunContract", "SNC": "SunContract",
"SNCT": "SnakeCity", "SNCT": "SnakeCity",
"SND": "Sandcoin", "SND": "Sandcoin",
"SNDKON": "SanDisk (Ondo Tokenized)",
"SNE": "StrongNode", "SNE": "StrongNode",
"SNEED": "Sneed", "SNEED": "Sneed",
"SNEK": "Snek", "SNEK": "Snek",
@ -15632,10 +15693,11 @@
"SPIDERMAN": "SPIDERMAN BITCOIN", "SPIDERMAN": "SPIDERMAN BITCOIN",
"SPIDEY": "Spidey", "SPIDEY": "Spidey",
"SPIK": "Spike", "SPIK": "Spike",
"SPIKE": "Spiking", "SPIKE": "SPIKE",
"SPIKE1984": "Spike 1984", "SPIKE1984": "Spike 1984",
"SPIKECOIN": "SPIKE", "SPIKECOIN": "SPIKE",
"SPIKEFURIE": "SPIKE", "SPIKEFURIE": "SPIKE",
"SPIKING": "Spiking",
"SPILLWAYS": "SpillWays", "SPILLWAYS": "SpillWays",
"SPIN": "SPIN Protocol", "SPIN": "SPIN Protocol",
"SPINT": "Spintria", "SPINT": "Spintria",
@ -15934,6 +15996,7 @@
"STRA": "STRAY", "STRA": "STRAY",
"STRAKS": "Straks", "STRAKS": "Straks",
"STRAT": "Strategic Hub for Innovation in Blockchain", "STRAT": "Strategic Hub for Innovation in Blockchain",
"STRAWBE": "Strawberry In Bloom",
"STRAX": "Stratis", "STRAX": "Stratis",
"STRAY": "Stray Dog", "STRAY": "Stray Dog",
"STRAYDOG": "Stray Dog", "STRAYDOG": "Stray Dog",
@ -15981,6 +16044,7 @@
"STV": "Sativa Coin", "STV": "Sativa Coin",
"STWEMIX": "Staked WEMIX", "STWEMIX": "Staked WEMIX",
"STX": "Stacks", "STX": "Stacks",
"STXON": "Seagate (Ondo Tokenized)",
"STYL": "Stylike Governance", "STYL": "Stylike Governance",
"STYLE": "Style", "STYLE": "Style",
"STZ": "99Starz", "STZ": "99Starz",
@ -16801,6 +16865,7 @@
"TRADECHAIN": "Trade Chain", "TRADECHAIN": "Trade Chain",
"TRADETIDE": "Trade Tide Token", "TRADETIDE": "Trade Tide Token",
"TRADEX": "TradeX AI", "TRADEX": "TradeX AI",
"TRADIX": "Tradix",
"TRADOOR": "Tradoor", "TRADOOR": "Tradoor",
"TRAI": "Trackgood AI", "TRAI": "Trackgood AI",
"TRAID": "Traid", "TRAID": "Traid",
@ -16881,6 +16946,7 @@
"TROLLRUN": "TROLL", "TROLLRUN": "TROLL",
"TROLLS": "trolls in a memes world", "TROLLS": "trolls in a memes world",
"TRONBETLIVE": "TRONbetLive", "TRONBETLIVE": "TRONbetLive",
"TRONBULL": "Tron Bull",
"TRONDOG": "TronDog", "TRONDOG": "TronDog",
"TRONI": "Tron Inu", "TRONI": "Tron Inu",
"TRONP": "Donald Tronp", "TRONP": "Donald Tronp",
@ -17015,6 +17081,7 @@
"TTM": "Tradetomato", "TTM": "Tradetomato",
"TTN": "TTN", "TTN": "TTN",
"TTNT": "TITA Project", "TTNT": "TITA Project",
"TTPA": "TRUMPTOPIA",
"TTT": "TRUMPETTOKEN", "TTT": "TRUMPETTOKEN",
"TTTU": "T-Project", "TTTU": "T-Project",
"TTU": "TaTaTu", "TTU": "TaTaTu",
@ -17077,7 +17144,7 @@
"TWP": "TrumpWifPanda", "TWP": "TrumpWifPanda",
"TWT": "Trust Wallet Token", "TWT": "Trust Wallet Token",
"TWURTLE": "twurtle the turtle", "TWURTLE": "twurtle the turtle",
"TX": "Tradix", "TX": "tx",
"TX20": "Trex20", "TX20": "Trex20",
"TXA": "TXA", "TXA": "TXA",
"TXAG": "tSILVER", "TXAG": "tSILVER",
@ -17160,6 +17227,7 @@
"UDT": "Unlock Protocol", "UDT": "Unlock Protocol",
"UE": "UE Coin", "UE": "UE Coin",
"UEC": "United Emirates Coin", "UEC": "United Emirates Coin",
"UECON": "Uranium Energy (Ondo Tokenized)",
"UEDC": "United Emirate Decentralized Coin", "UEDC": "United Emirate Decentralized Coin",
"UENC": "UniversalEnergyChain", "UENC": "UniversalEnergyChain",
"UET": "Useless Ethereum Token", "UET": "Useless Ethereum Token",
@ -17239,6 +17307,7 @@
"UNF": "Unfed Coin", "UNF": "Unfed Coin",
"UNFI": "Unifi Protocol DAO", "UNFI": "Unifi Protocol DAO",
"UNFK": "UNFK", "UNFK": "UNFK",
"UNGON": "US Natural Gas Fund (Ondo Tokenized)",
"UNHX": "UnitedHealth xStock", "UNHX": "UnitedHealth xStock",
"UNI": "Uniswap Protocol Token", "UNI": "Uniswap Protocol Token",
"UNIART": "UNIART", "UNIART": "UNIART",
@ -17276,6 +17345,7 @@
"UNITE": "Unite", "UNITE": "Unite",
"UNITED": "UnitedCoins", "UNITED": "UnitedCoins",
"UNITEDTRADERS": "United Traders Token", "UNITEDTRADERS": "United Traders Token",
"UNITOKEN": "Uni Token",
"UNITPROV2": "Unit Protocol New", "UNITPROV2": "Unit Protocol New",
"UNITRADE": "UniTrade", "UNITRADE": "UniTrade",
"UNITREEAI": "Unitree G1 AI", "UNITREEAI": "Unitree G1 AI",
@ -17292,17 +17362,18 @@
"UNO": "UnoRe", "UNO": "UnoRe",
"UNOB": "Unobtanium", "UNOB": "Unobtanium",
"UNP": "UNIPOLY", "UNP": "UNIPOLY",
"UNPON": "Union Pacific Corporation (Ondo Tokenized)",
"UNQ": "UNQ", "UNQ": "UNQ",
"UNQT": "Unique Utility Token", "UNQT": "Unique Utility Token",
"UNR": "Unirealchain", "UNR": "Unirealchain",
"UNRC": "UniversalRoyalCoin", "UNRC": "UniversalRoyalCoin",
"UNS": "UNS TOKEN", "UNS": "UNS TOKEN",
"UNSHETH": "unshETH Ether", "UNSHETH": "unshETH Ether",
"UNT": "Uni Token", "UNT": "UnityWallet Token",
"UNW": "UniWorld", "UNW": "UniWorld",
"UOP": "Utopia Genesis Foundation", "UOP": "Utopia Genesis Foundation",
"UOS": "UOS", "UOS": "UOS",
"UP": "UpToken", "UP": "Superform",
"UPC": "UPCX", "UPC": "UPCX",
"UPCG": "Upcomings", "UPCG": "Upcomings",
"UPCO2": "Universal Carbon", "UPCO2": "Universal Carbon",
@ -17317,6 +17388,7 @@
"UPRO": "ULTRAPRO", "UPRO": "ULTRAPRO",
"UPS": "UPFI Network", "UPS": "UPFI Network",
"UPT": "UPROCK", "UPT": "UPROCK",
"UPTOKEN": "UpToken",
"UPTOP": "UPTOP", "UPTOP": "UPTOP",
"UPTOS": "UPTOS", "UPTOS": "UPTOS",
"UPUNK": "Unicly CryptoPunks Collection", "UPUNK": "Unicly CryptoPunks Collection",
@ -17327,6 +17399,7 @@
"URAC": "Uranus", "URAC": "Uranus",
"URALS": "Urals Coin", "URALS": "Urals Coin",
"URANUS": "Uranus", "URANUS": "Uranus",
"URAON": "Global X Uranium ETF (Ondo Tokenized)",
"URFA": "Urfaspor Token", "URFA": "Urfaspor Token",
"URMOM": "urmom", "URMOM": "urmom",
"URO": "Urolithin A", "URO": "Urolithin A",
@ -17575,7 +17648,7 @@
"VEC2": "VectorCoin 2.0", "VEC2": "VectorCoin 2.0",
"VECT": "Vectorium", "VECT": "Vectorium",
"VECTOR": "VectorChat.ai", "VECTOR": "VectorChat.ai",
"VEE": "BLOCKv", "VEE": "Vee Token",
"VEED": "VEED", "VEED": "VEED",
"VEEN": "LIVEEN", "VEEN": "LIVEEN",
"VEETOKEN": "Vee Token", "VEETOKEN": "Vee Token",
@ -17638,6 +17711,7 @@
"VEXT": "Veloce", "VEXT": "Veloce",
"VFIL": "Venus Filecoin", "VFIL": "Venus Filecoin",
"VFOX": "VFOX", "VFOX": "VFOX",
"VFSON": "VinFast Auto (Ondo Tokenized)",
"VFT": "Value Finance", "VFT": "Value Finance",
"VFX": "ViFoxCoin", "VFX": "ViFoxCoin",
"VFY": "zkVerify", "VFY": "zkVerify",
@ -17758,6 +17832,7 @@
"VNM": "Venom", "VNM": "Venom",
"VNN": "VINU Network", "VNN": "VINU Network",
"VNO": "Veno Finance", "VNO": "Veno Finance",
"VNQON": "Vanguard Real Estate ETF (Ondo Tokenized)",
"VNST": "VNST Stablecoin", "VNST": "VNST Stablecoin",
"VNT": "VNT Chain", "VNT": "VNT Chain",
"VNTR": "Venture Mind AI", "VNTR": "Venture Mind AI",
@ -17831,6 +17906,7 @@
"VRSW": "VirtuSwap", "VRSW": "VirtuSwap",
"VRT": "Venus Reward Token", "VRT": "Venus Reward Token",
"VRTX": "Vertex Protocol", "VRTX": "Vertex Protocol",
"VRTXON": "Vertex Pharmaceuticals (Ondo Tokenized)",
"VRTY": "Verity", "VRTY": "Verity",
"VRX": "Verox", "VRX": "Verox",
"VS": "veSync", "VS": "veSync",
@ -17844,6 +17920,7 @@
"VSOL": "VSolidus", "VSOL": "VSolidus",
"VSP": "Vesper Finance", "VSP": "Vesper Finance",
"VSTA": "Vesta Finance", "VSTA": "Vesta Finance",
"VSTON": "Vistra (Ondo Tokenized)",
"VSTR": "Vestra DAO", "VSTR": "Vestra DAO",
"VSUI": "Volo Staked SUI", "VSUI": "Volo Staked SUI",
"VSX": "Versus-X", "VSX": "Versus-X",
@ -18038,6 +18115,7 @@
"WCUSD": "Wrapped Celo Dollar", "WCUSD": "Wrapped Celo Dollar",
"WDAI": "Dai (Wormhole)", "WDAI": "Dai (Wormhole)",
"WDC": "WorldCoin", "WDC": "WorldCoin",
"WDCON": "Western Digital (Ondo Tokenized)",
"WDOG": "Winterdog", "WDOG": "Winterdog",
"WDOGE": "Wrapped Dogecoin", "WDOGE": "Wrapped Dogecoin",
"WDOT": "WDOT", "WDOT": "WDOT",
@ -18273,6 +18351,7 @@
"WMM": "Weird Medieval Memes", "WMM": "Weird Medieval Memes",
"WMN": "WebMind Network", "WMN": "WebMind Network",
"WMNT": "Wrapped Mantle", "WMNT": "Wrapped Mantle",
"WMON": "Waste Management (Ondo Tokenized)",
"WMOXY": "Moxy", "WMOXY": "Moxy",
"WMT": "World Mobile Token v1", "WMT": "World Mobile Token v1",
"WMTON": "Walmart (Ondo Tokenized)", "WMTON": "Walmart (Ondo Tokenized)",
@ -18304,9 +18383,10 @@
"WOID": "WORLD ID", "WOID": "WORLD ID",
"WOJ": "Wojak Finance", "WOJ": "Wojak Finance",
"WOJA": "Wojak", "WOJA": "Wojak",
"WOJAK": "Wojak", "WOJAK": "wojak",
"WOJAK2": "Wojak 2.0 Coin", "WOJAK2": "Wojak 2.0 Coin",
"WOJAKC": "Wojak Coin", "WOJAKC": "Wojak Coin",
"WOJAKIO": "Wojak",
"WOKB": "Wrapped OKB", "WOKB": "Wrapped OKB",
"WOKIE": "Wokie Plumpkin by Virtuals", "WOKIE": "Wokie Plumpkin by Virtuals",
"WOKT": "Wrapped OKT", "WOKT": "Wrapped OKT",
@ -18462,6 +18542,7 @@
"WXRP": "Wrapped XRP", "WXRP": "Wrapped XRP",
"WXT": "WXT", "WXT": "WXT",
"WYAC": "Woman Yelling At Cat", "WYAC": "Woman Yelling At Cat",
"WYDE": "WYDE: End Hunger",
"WYN": "Wynn", "WYN": "Wynn",
"WYNN": "Anita Max Wynn", "WYNN": "Anita Max Wynn",
"WYS": "Wysker", "WYS": "Wysker",
@ -18683,6 +18764,7 @@
"XMN": "xMoney", "XMN": "xMoney",
"XMO": "Monero Original", "XMO": "Monero Original",
"XMON": "XMON", "XMON": "XMON",
"XMONEY": "X Money",
"XMOON": "r/CryptoCurrency Moons v1", "XMOON": "r/CryptoCurrency Moons v1",
"XMP": "Mapt.Coin", "XMP": "Mapt.Coin",
"XMR": "Monero", "XMR": "Monero",
@ -18741,7 +18823,7 @@
"XPL": "Plasma", "XPL": "Plasma",
"XPLA": "XPLA", "XPLA": "XPLA",
"XPLL": "ParallelChain", "XPLL": "ParallelChain",
"XPM": "PrimeCoin", "XPM": "XPMarket Token",
"XPN": "PANTHEON X", "XPN": "PANTHEON X",
"XPND": "Time Raiders", "XPND": "Time Raiders",
"XPNET": "XP Network", "XPNET": "XP Network",
@ -18860,6 +18942,7 @@
"XVS": "Venus", "XVS": "Venus",
"XWC": "WhiteCoin", "XWC": "WhiteCoin",
"XWG": "X World Games", "XWG": "X World Games",
"XWGT": "Wodo Gaming Token",
"XWIN": "xWIN Finance", "XWIN": "xWIN Finance",
"XWP": "Swap", "XWP": "Swap",
"XWT": "World Trade Funds", "XWT": "World Trade Funds",
@ -19102,7 +19185,8 @@
"ZEBU": "ZEBU", "ZEBU": "ZEBU",
"ZEC": "ZCash", "ZEC": "ZCash",
"ZECD": "ZCashDarkCoin", "ZECD": "ZCashDarkCoin",
"ZED": "ZedCoins", "ZED": "ZED Token",
"ZEDCOIN": "ZedCoin",
"ZEDD": "ZedDex", "ZEDD": "ZedDex",
"ZEDTOKEN": "Zed Token", "ZEDTOKEN": "Zed Token",
"ZEDX": "ZEDX Сoin", "ZEDX": "ZEDX Сoin",

2
apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts

@ -20,7 +20,6 @@ import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table';
import { DataService } from '@ghostfolio/ui/services'; import { DataService } from '@ghostfolio/ui/services';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
@ -57,7 +56,6 @@ import { AccountDetailDialogParams } from './interfaces/interfaces';
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'd-flex flex-column h-100' }, host: { class: 'd-flex flex-column h-100' },
imports: [ imports: [
CommonModule,
GfAccountBalancesComponent, GfAccountBalancesComponent,
GfActivitiesTableComponent, GfActivitiesTableComponent,
GfDialogFooterComponent, GfDialogFooterComponent,

2
apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html

@ -91,8 +91,8 @@
<mat-tab-group <mat-tab-group
animationDuration="0ms" animationDuration="0ms"
[class.d-none]="isLoadingActivities"
[mat-stretch-tabs]="false" [mat-stretch-tabs]="false"
[ngClass]="{ 'd-none': isLoadingActivities }"
> >
<mat-tab> <mat-tab>
<ng-template mat-tab-label> <ng-template mat-tab-label>

2
apps/client/src/app/components/admin-jobs/admin-jobs.html

@ -172,7 +172,7 @@
<ion-icon <ion-icon
class="h6 mb-0" class="h6 mb-0"
name="time-outline" name="time-outline"
[ngClass]="{ 'text-danger': element.stacktrace?.length > 0 }" [class.text-danger]="element.stacktrace?.length > 0"
/> />
} @else if (element.state === 'failed') { } @else if (element.state === 'failed') {
<ion-icon <ion-icon

6
apps/client/src/app/components/admin-market-data/admin-market-data.html

@ -309,11 +309,11 @@
</div> </div>
<mat-paginator <mat-paginator
[class.d-none]="
(isLoading && totalItems === 0) || totalItems <= pageSize
"
[hidePageSize]="true" [hidePageSize]="true"
[length]="totalItems" [length]="totalItems"
[ngClass]="{
'd-none': (isLoading && totalItems === 0) || totalItems <= pageSize
}"
[pageSize]="pageSize" [pageSize]="pageSize"
[showFirstLastButtons]="true" [showFirstLastButtons]="true"
(page)="onChangePage($event)" (page)="onChangePage($event)"

14
apps/client/src/app/components/admin-users/admin-users.html

@ -19,16 +19,12 @@
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<span <span
class="d-none d-sm-inline-block text-monospace" class="d-none d-sm-inline-block text-monospace"
[ngClass]="{ [class.text-line-through]="element.role === 'INACTIVE'"
'text-line-through': element.role === 'INACTIVE'
}"
>{{ element.id }}</span >{{ element.id }}</span
> >
<span <span
class="d-inline-block d-sm-none text-monospace" class="d-inline-block d-sm-none text-monospace"
[ngClass]="{ [class.text-line-through]="element.role === 'INACTIVE'"
'text-line-through': element.role === 'INACTIVE'
}"
>{{ `${(element.id | slice: 0 : 5)}...` }}</span >{{ `${(element.id | slice: 0 : 5)}...` }}</span
> >
@if (element.subscription?.expiresAt) { @if (element.subscription?.expiresAt) {
@ -273,11 +269,11 @@
</div> </div>
<mat-paginator <mat-paginator
[class.d-none]="
(isLoading && totalItems === 0) || totalItems <= pageSize
"
[hidePageSize]="true" [hidePageSize]="true"
[length]="totalItems" [length]="totalItems"
[ngClass]="{
'd-none': (isLoading && totalItems === 0) || totalItems <= pageSize
}"
[pageSize]="pageSize" [pageSize]="pageSize"
[showFirstLastButtons]="true" [showFirstLastButtons]="true"
(page)="onChangePage($event)" (page)="onChangePage($event)"

72
apps/client/src/app/components/header/header.component.html

@ -1,10 +1,10 @@
<mat-toolbar class="px-0"> <mat-toolbar class="px-0">
@if (user) { @if (user) {
<div class="d-flex h-100 logo-container" [ngClass]="{ filled: hasTabs }"> <div class="d-flex h-100 logo-container" [class.filled]="hasTabs">
<a <a
class="align-items-center h-100 justify-content-start px-2 px-sm-3 rounded-0" class="align-items-center h-100 justify-content-start px-2 px-sm-3 rounded-0"
mat-button mat-button
[ngClass]="{ 'w-100': hasTabs }" [class.w-100]="hasTabs"
[routerLink]="['/']" [routerLink]="['/']"
(click)="onLogoClick()" (click)="onLogoClick()"
> >
@ -18,7 +18,7 @@
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
i18n i18n
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': 'font-weight-bold':
currentRoute === internalRoutes.home.path || currentRoute === internalRoutes.home.path ||
currentRoute === internalRoutes.zen.path, currentRoute === internalRoutes.zen.path,
@ -35,7 +35,7 @@
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
i18n i18n
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': currentRoute === internalRoutes.portfolio.path, 'font-weight-bold': currentRoute === internalRoutes.portfolio.path,
'text-decoration-underline': 'text-decoration-underline':
currentRoute === internalRoutes.portfolio.path currentRoute === internalRoutes.portfolio.path
@ -49,7 +49,7 @@
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
i18n i18n
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': currentRoute === internalRoutes.accounts.path, 'font-weight-bold': currentRoute === internalRoutes.accounts.path,
'text-decoration-underline': 'text-decoration-underline':
currentRoute === internalRoutes.accounts.path currentRoute === internalRoutes.accounts.path
@ -64,7 +64,7 @@
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
i18n i18n
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': 'font-weight-bold':
currentRoute === internalRoutes.adminControl.path, currentRoute === internalRoutes.adminControl.path,
'text-decoration-underline': 'text-decoration-underline':
@ -80,7 +80,7 @@
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
i18n i18n
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': currentRoute === routeResources, 'font-weight-bold': currentRoute === routeResources,
'text-decoration-underline': currentRoute === routeResources 'text-decoration-underline': currentRoute === routeResources
}" }"
@ -95,7 +95,7 @@
<a <a
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': currentRoute === routePricing, 'font-weight-bold': currentRoute === routePricing,
'text-decoration-underline': currentRoute === routePricing 'text-decoration-underline': currentRoute === routePricing
}" }"
@ -115,7 +115,7 @@
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
i18n i18n
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': currentRoute === routeAbout, 'font-weight-bold': currentRoute === routeAbout,
'text-decoration-underline': currentRoute === routeAbout 'text-decoration-underline': currentRoute === routeAbout
}" }"
@ -239,11 +239,10 @@
class="d-flex d-sm-none" class="d-flex d-sm-none"
i18n i18n
mat-menu-item mat-menu-item
[ngClass]="{ [class.font-weight-bold]="
'font-weight-bold': currentRoute === internalRoutes.home.path ||
currentRoute === internalRoutes.home.path || currentRoute === internalRoutes.zen.path
currentRoute === internalRoutes.zen.path "
}"
[routerLink]="['/']" [routerLink]="['/']"
>Overview</a >Overview</a
> >
@ -251,9 +250,9 @@
class="d-flex d-sm-none" class="d-flex d-sm-none"
i18n i18n
mat-menu-item mat-menu-item
[ngClass]="{ [class.font-weight-bold]="
'font-weight-bold': currentRoute === internalRoutes.portfolio.path currentRoute === internalRoutes.portfolio.path
}" "
[routerLink]="routerLinkPortfolio" [routerLink]="routerLinkPortfolio"
>Portfolio</a >Portfolio</a
> >
@ -261,18 +260,18 @@
class="d-flex d-sm-none" class="d-flex d-sm-none"
i18n i18n
mat-menu-item mat-menu-item
[ngClass]="{ [class.font-weight-bold]="
'font-weight-bold': currentRoute === internalRoutes.accounts.path currentRoute === internalRoutes.accounts.path
}" "
[routerLink]="routerLinkAccounts" [routerLink]="routerLinkAccounts"
>Accounts</a >Accounts</a
> >
<a <a
i18n i18n
mat-menu-item mat-menu-item
[ngClass]="{ [class.font-weight-bold]="
'font-weight-bold': currentRoute === internalRoutes.account.path currentRoute === internalRoutes.account.path
}" "
[routerLink]="routerLinkAccount" [routerLink]="routerLinkAccount"
>My Ghostfolio</a >My Ghostfolio</a
> >
@ -281,10 +280,9 @@
class="d-flex d-sm-none" class="d-flex d-sm-none"
i18n i18n
mat-menu-item mat-menu-item
[ngClass]="{ [class.font-weight-bold]="
'font-weight-bold': currentRoute === internalRoutes.adminControl.path
currentRoute === internalRoutes.adminControl.path "
}"
[routerLink]="routerLinkAdminControl" [routerLink]="routerLinkAdminControl"
>Admin Control</a >Admin Control</a
> >
@ -294,9 +292,7 @@
class="d-flex d-sm-none" class="d-flex d-sm-none"
i18n i18n
mat-menu-item mat-menu-item
[ngClass]="{ [class.font-weight-bold]="currentRoute === routeResources"
'font-weight-bold': currentRoute === routeResources
}"
[routerLink]="routerLinkResources" [routerLink]="routerLinkResources"
>Resources</a >Resources</a
> >
@ -306,7 +302,7 @@
<a <a
class="d-flex d-sm-none" class="d-flex d-sm-none"
mat-menu-item mat-menu-item
[ngClass]="{ 'font-weight-bold': currentRoute === routePricing }" [class.font-weight-bold]="currentRoute === routePricing"
[routerLink]="routerLinkPricing" [routerLink]="routerLinkPricing"
> >
<span class="align-items-center d-flex"> <span class="align-items-center d-flex">
@ -321,7 +317,7 @@
class="d-flex d-sm-none" class="d-flex d-sm-none"
i18n i18n
mat-menu-item mat-menu-item
[ngClass]="{ 'font-weight-bold': currentRoute === routeAbout }" [class.font-weight-bold]="currentRoute === routeAbout"
[routerLink]="routerLinkAbout" [routerLink]="routerLinkAbout"
>About Ghostfolio</a >About Ghostfolio</a
> >
@ -332,11 +328,11 @@
</ul> </ul>
} }
@if (user === null) { @if (user === null) {
<div class="d-flex h-100 logo-container" [ngClass]="{ filled: hasTabs }"> <div class="d-flex h-100 logo-container" [class.filled]="hasTabs">
<a <a
class="align-items-center h-100 justify-content-start px-2 px-sm-3 rounded-0" class="align-items-center h-100 justify-content-start px-2 px-sm-3 rounded-0"
mat-button mat-button
[ngClass]="{ 'w-100': hasTabs }" [class.w-100]="hasTabs"
[routerLink]="['/']" [routerLink]="['/']"
> >
<gf-logo <gf-logo
@ -352,7 +348,7 @@
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
i18n i18n
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': currentRoute === routeFeatures, 'font-weight-bold': currentRoute === routeFeatures,
'text-decoration-underline': currentRoute === routeFeatures 'text-decoration-underline': currentRoute === routeFeatures
}" }"
@ -365,7 +361,7 @@
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
i18n i18n
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': currentRoute === routeAbout, 'font-weight-bold': currentRoute === routeAbout,
'text-decoration-underline': currentRoute === routeAbout 'text-decoration-underline': currentRoute === routeAbout
}" }"
@ -378,7 +374,7 @@
<a <a
class="d-sm-block rounded" class="d-sm-block rounded"
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': currentRoute === routePricing, 'font-weight-bold': currentRoute === routePricing,
'text-decoration-underline': currentRoute === routePricing 'text-decoration-underline': currentRoute === routePricing
}" }"
@ -399,7 +395,7 @@
class="d-none d-sm-block rounded" class="d-none d-sm-block rounded"
i18n i18n
mat-button mat-button
[ngClass]="{ [class]="{
'font-weight-bold': currentRoute === routeMarkets, 'font-weight-bold': currentRoute === routeMarkets,
'text-decoration-underline': currentRoute === routeMarkets 'text-decoration-underline': currentRoute === routeMarkets
}" }"

2
apps/client/src/app/components/header/header.component.ts

@ -19,7 +19,6 @@ import { NotificationService } from '@ghostfolio/ui/notifications';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { DataService } from '@ghostfolio/ui/services'; import { DataService } from '@ghostfolio/ui/services';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
@ -56,7 +55,6 @@ import { catchError } from 'rxjs/operators';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ imports: [
CommonModule,
GfAssistantComponent, GfAssistantComponent,
GfLogoComponent, GfLogoComponent,
GfPremiumIndicatorComponent, GfPremiumIndicatorComponent,

2
apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts

@ -29,7 +29,6 @@ import { DataService } from '@ghostfolio/ui/services';
import { GfTagsSelectorComponent } from '@ghostfolio/ui/tags-selector'; import { GfTagsSelectorComponent } from '@ghostfolio/ui/tags-selector';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -76,7 +75,6 @@ import { HoldingDetailDialogParams } from './interfaces/interfaces';
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'd-flex flex-column h-100' }, host: { class: 'd-flex flex-column h-100' },
imports: [ imports: [
CommonModule,
GfAccountsTableComponent, GfAccountsTableComponent,
GfActivitiesTableComponent, GfActivitiesTableComponent,
GfDataProviderCreditsComponent, GfDataProviderCreditsComponent,

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

@ -117,13 +117,12 @@
<gf-value <gf-value
i18n i18n
size="medium" size="medium"
[class.text-danger]="
marketPriceMin?.toFixed(2) === marketPrice?.toFixed(2) &&
marketPriceMax?.toFixed(2) !== marketPriceMin?.toFixed(2)
"
[isCurrency]="true" [isCurrency]="true"
[locale]="data.locale" [locale]="data.locale"
[ngClass]="{
'text-danger':
marketPriceMin?.toFixed(2) === marketPrice?.toFixed(2) &&
marketPriceMax?.toFixed(2) !== marketPriceMin?.toFixed(2)
}"
[precision]="marketPriceMinPrecision" [precision]="marketPriceMinPrecision"
[unit]="SymbolProfile?.currency" [unit]="SymbolProfile?.currency"
[value]="marketPriceMin" [value]="marketPriceMin"
@ -134,13 +133,12 @@
<gf-value <gf-value
i18n i18n
size="medium" size="medium"
[class.text-success]="
marketPriceMax?.toFixed(2) === marketPrice?.toFixed(2) &&
marketPriceMax?.toFixed(2) !== marketPriceMin?.toFixed(2)
"
[isCurrency]="true" [isCurrency]="true"
[locale]="data.locale" [locale]="data.locale"
[ngClass]="{
'text-success':
marketPriceMax?.toFixed(2) === marketPrice?.toFixed(2) &&
marketPriceMax?.toFixed(2) !== marketPriceMin?.toFixed(2)
}"
[precision]="marketPriceMaxPrecision" [precision]="marketPriceMaxPrecision"
[unit]="SymbolProfile?.currency" [unit]="SymbolProfile?.currency"
[value]="marketPriceMax" [value]="marketPriceMax"

2
apps/client/src/app/components/home-holdings/home-holdings.component.ts

@ -14,7 +14,6 @@ import { DataService } from '@ghostfolio/ui/services';
import { GfToggleComponent } from '@ghostfolio/ui/toggle'; import { GfToggleComponent } from '@ghostfolio/ui/toggle';
import { GfTreemapChartComponent } from '@ghostfolio/ui/treemap-chart'; import { GfTreemapChartComponent } from '@ghostfolio/ui/treemap-chart';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
@ -34,7 +33,6 @@ import { DeviceDetectorService } from 'ngx-device-detector';
@Component({ @Component({
imports: [ imports: [
CommonModule,
FormsModule, FormsModule,
GfHoldingsTableComponent, GfHoldingsTableComponent,
GfToggleComponent, GfToggleComponent,

2
apps/client/src/app/components/home-holdings/home-holdings.html

@ -44,7 +44,7 @@
(treemapChartClicked)="onHoldingClicked($event)" (treemapChartClicked)="onHoldingClicked($event)"
/> />
} }
<div [ngClass]="{ 'd-none': viewModeFormControl.value !== 'TABLE' }"> <div [class.d-none]="viewModeFormControl.value !== 'TABLE'">
<gf-holdings-table <gf-holdings-table
[holdings]="holdings" [holdings]="holdings"
[locale]="user?.settings?.locale" [locale]="user?.settings?.locale"

2
apps/client/src/app/components/home-overview/home-overview.component.ts

@ -14,7 +14,6 @@ import { internalRoutes } from '@ghostfolio/common/routes/routes';
import { GfLineChartComponent } from '@ghostfolio/ui/line-chart'; import { GfLineChartComponent } from '@ghostfolio/ui/line-chart';
import { DataService } from '@ghostfolio/ui/services'; import { DataService } from '@ghostfolio/ui/services';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
@ -29,7 +28,6 @@ import { DeviceDetectorService } from 'ngx-device-detector';
@Component({ @Component({
imports: [ imports: [
CommonModule,
GfLineChartComponent, GfLineChartComponent,
GfPortfolioPerformanceComponent, GfPortfolioPerformanceComponent,
MatButtonModule, MatButtonModule,

7
apps/client/src/app/components/home-overview/home-overview.html

@ -11,10 +11,7 @@
<h4 i18n>Welcome to Ghostfolio</h4> <h4 i18n>Welcome to Ghostfolio</h4>
<p i18n>Ready to take control of your personal finances?</p> <p i18n>Ready to take control of your personal finances?</p>
<ol class="font-weight-bold"> <ol class="font-weight-bold">
<li <li class="mb-2" [class.text-muted]="user?.accounts?.length > 1">
class="mb-2"
[ngClass]="{ 'text-muted': user?.accounts?.length > 1 }"
>
<a class="d-block" [routerLink]="routerLinkAccounts" <a class="d-block" [routerLink]="routerLinkAccounts"
><span i18n>Setup your accounts</span><br /> ><span i18n>Setup your accounts</span><br />
<span class="font-weight-normal" i18n <span class="font-weight-normal" i18n
@ -70,13 +67,13 @@
<gf-line-chart <gf-line-chart
class="position-absolute" class="position-absolute"
unit="%" unit="%"
[class.pr-3]="deviceType === 'mobile'"
[colorScheme]="user?.settings?.colorScheme" [colorScheme]="user?.settings?.colorScheme"
[hidden]="historicalDataItems?.length === 0" [hidden]="historicalDataItems?.length === 0"
[historicalDataItems]="historicalDataItems" [historicalDataItems]="historicalDataItems"
[isAnimated]="user?.settings?.dateRange === '1d' ? false : true" [isAnimated]="user?.settings?.dateRange === '1d' ? false : true"
[label]="performanceLabel" [label]="performanceLabel"
[locale]="user?.settings?.locale" [locale]="user?.settings?.locale"
[ngClass]="{ 'pr-3': deviceType === 'mobile' }"
[showGradient]="true" [showGradient]="true"
[showLoader]="false" [showLoader]="false"
[showXAxis]="false" [showXAxis]="false"

4
apps/client/src/app/components/portfolio-performance/portfolio-performance.component.html

@ -24,11 +24,11 @@
} }
<div <div
class="display-4 font-weight-bold m-0 text-center value-container" class="display-4 font-weight-bold m-0 text-center value-container"
[hidden]="isLoading" [class]="{
[ngClass]="{
'text-danger': isAllTimeLow, 'text-danger': isAllTimeLow,
'text-success': isAllTimeHigh 'text-success': isAllTimeHigh
}" }"
[hidden]="isLoading"
> >
<span #value id="value"></span> <span #value id="value"></span>
</div> </div>

3
apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts

@ -10,7 +10,6 @@ import {
import { NotificationService } from '@ghostfolio/ui/notifications'; import { NotificationService } from '@ghostfolio/ui/notifications';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
@ -28,7 +27,7 @@ import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, GfValueComponent, IonIcon, NgxSkeletonLoaderModule], imports: [GfValueComponent, IonIcon, NgxSkeletonLoaderModule],
selector: 'gf-portfolio-performance', selector: 'gf-portfolio-performance',
styleUrls: ['./portfolio-performance.component.scss'], styleUrls: ['./portfolio-performance.component.scss'],
templateUrl: './portfolio-performance.component.html' templateUrl: './portfolio-performance.component.html'

11
apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html

@ -181,12 +181,11 @@
</div> </div>
<div <div
class="align-items-center d-flex justify-content-end" class="align-items-center d-flex justify-content-end"
[ngClass]="{ [class.cursor-pointer]="
'cursor-pointer': hasPermissionToUpdateUserSettings &&
hasPermissionToUpdateUserSettings && !user?.settings?.isRestrictedView &&
!user?.settings?.isRestrictedView && user?.subscription?.type !== 'Basic'
user?.subscription?.type !== 'Basic' "
}"
(click)=" (click)="
hasPermissionToUpdateUserSettings && hasPermissionToUpdateUserSettings &&
!user?.settings?.isRestrictedView && !user?.settings?.isRestrictedView &&

3
apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts

@ -5,7 +5,6 @@ import { translate } from '@ghostfolio/ui/i18n';
import { NotificationService } from '@ghostfolio/ui/notifications'; import { NotificationService } from '@ghostfolio/ui/notifications';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
@ -25,7 +24,7 @@ import {
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, GfValueComponent, IonIcon, MatTooltipModule], imports: [GfValueComponent, IonIcon, MatTooltipModule],
selector: 'gf-portfolio-summary', selector: 'gf-portfolio-summary',
styleUrls: ['./portfolio-summary.component.scss'], styleUrls: ['./portfolio-summary.component.scss'],
templateUrl: './portfolio-summary.component.html' templateUrl: './portfolio-summary.component.html'

2
apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts

@ -1,7 +1,6 @@
import { XRayRulesSettings } from '@ghostfolio/common/interfaces'; import { XRayRulesSettings } from '@ghostfolio/common/interfaces';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { Component, Inject } from '@angular/core'; import { Component, Inject } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
@ -16,7 +15,6 @@ import { RuleSettingsDialogParams } from './interfaces/interfaces';
@Component({ @Component({
imports: [ imports: [
CommonModule,
FormsModule, FormsModule,
GfValueComponent, GfValueComponent,
MatButtonModule, MatButtonModule,

10
apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.html

@ -47,10 +47,7 @@
</div> </div>
</div> </div>
} @else { } @else {
<div <div class="w-100" [class.d-none]="!data.rule.configuration.thresholdMin">
class="w-100"
[ngClass]="{ 'd-none': !data.rule.configuration.thresholdMin }"
>
<h6 class="d-flex mb-0"> <h6 class="d-flex mb-0">
<ng-container i18n>Threshold Min</ng-container>: <ng-container i18n>Threshold Min</ng-container>:
<gf-value <gf-value
@ -85,10 +82,7 @@
/> />
</div> </div>
</div> </div>
<div <div class="w-100" [class.d-none]="!data.rule.configuration.thresholdMax">
class="w-100"
[ngClass]="{ 'd-none': !data.rule.configuration.thresholdMax }"
>
<h6 class="d-flex mb-0"> <h6 class="d-flex mb-0">
<ng-container i18n>Threshold Max</ng-container>: <ng-container i18n>Threshold Max</ng-container>:
<gf-value <gf-value

2
apps/client/src/app/components/rule/rule.component.html

@ -14,7 +14,7 @@
} @else { } @else {
<div <div
class="align-items-center d-flex icon-container mr-2 px-2" class="align-items-center d-flex icon-container mr-2 px-2"
[ngClass]="{ [class]="{
okay: rule?.value === true, okay: rule?.value === true,
warn: rule?.value === false warn: rule?.value === false
}" }"

9
apps/client/src/app/components/rule/rule.component.ts

@ -5,7 +5,6 @@ import {
XRayRulesSettings XRayRulesSettings
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
@ -37,13 +36,7 @@ import { GfRuleSettingsDialogComponent } from './rule-settings-dialog/rule-setti
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ imports: [IonIcon, MatButtonModule, MatMenuModule, NgxSkeletonLoaderModule],
CommonModule,
IonIcon,
MatButtonModule,
MatMenuModule,
NgxSkeletonLoaderModule
],
selector: 'gf-rule', selector: 'gf-rule',
styleUrls: ['./rule.component.scss'], styleUrls: ['./rule.component.scss'],
templateUrl: './rule.component.html' templateUrl: './rule.component.html'

3
apps/client/src/app/pages/about/overview/about-overview-page.component.ts

@ -4,7 +4,6 @@ import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { DataService } from '@ghostfolio/ui/services'; import { DataService } from '@ghostfolio/ui/services';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
@ -26,7 +25,7 @@ import {
} from 'ionicons/icons'; } from 'ionicons/icons';
@Component({ @Component({
imports: [CommonModule, IonIcon, MatButtonModule, RouterModule], imports: [IonIcon, MatButtonModule, RouterModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-about-overview-page', selector: 'gf-about-overview-page',
styleUrls: ['./about-overview-page.scss'], styleUrls: ['./about-overview-page.scss'],

2
apps/client/src/app/pages/about/overview/about-overview-page.html

@ -178,7 +178,7 @@
<div class="mb-5 row"> <div class="mb-5 row">
<div <div
class="col-md-6 col-xs-12 my-2" class="col-md-6 col-xs-12 my-2"
[ngClass]="{ 'offset-md-3': hasPermissionForSubscription === false }" [class.offset-md-3]="hasPermissionForSubscription === false"
> >
<a <a
class="py-4 w-100" class="py-4 w-100"

3
apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts

@ -4,7 +4,7 @@ import { GfCurrencySelectorComponent } from '@ghostfolio/ui/currency-selector';
import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo'; import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo';
import { DataService } from '@ghostfolio/ui/services'; import { DataService } from '@ghostfolio/ui/services';
import { CommonModule, NgClass } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
import { import {
AbstractControl, AbstractControl,
@ -43,7 +43,6 @@ import { CreateOrUpdateAccountDialogParams } from './interfaces/interfaces';
MatDialogModule, MatDialogModule,
MatFormFieldModule, MatFormFieldModule,
MatInputModule, MatInputModule,
NgClass,
ReactiveFormsModule ReactiveFormsModule
], ],
selector: 'gf-create-or-update-account-dialog', selector: 'gf-create-or-update-account-dialog',

2
apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html

@ -43,7 +43,7 @@
}}</span> }}</span>
</mat-form-field> </mat-form-field>
</div> </div>
<div [ngClass]="{ 'd-none': platforms?.length < 1 }"> <div [class.d-none]="platforms?.length < 1">
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Platform</mat-label> <mat-label i18n>Platform</mat-label>
<input <input

2
apps/client/src/app/pages/landing/landing-page.component.ts

@ -8,7 +8,6 @@ import { DataService } from '@ghostfolio/ui/services';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { GfWorldMapChartComponent } from '@ghostfolio/ui/world-map-chart'; import { GfWorldMapChartComponent } from '@ghostfolio/ui/world-map-chart';
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
@ -25,7 +24,6 @@ import { DeviceDetectorService } from 'ngx-device-detector';
@Component({ @Component({
host: { class: 'page' }, host: { class: 'page' },
imports: [ imports: [
CommonModule,
GfCarouselComponent, GfCarouselComponent,
GfLogoCarouselComponent, GfLogoCarouselComponent,
GfLogoComponent, GfLogoComponent,

6
apps/client/src/app/pages/landing/landing-page.html

@ -54,7 +54,7 @@
<div class="row mb-5"> <div class="row mb-5">
<div <div
class="col-md-4 d-flex my-1" class="col-md-4 d-flex my-1"
[ngClass]="{ 'justify-content-center': deviceType !== 'mobile' }" [class.justify-content-center]="deviceType !== 'mobile'"
> >
<a <a
class="d-block" class="d-block"
@ -72,7 +72,7 @@
</div> </div>
<div <div
class="col-md-4 d-flex my-1" class="col-md-4 d-flex my-1"
[ngClass]="{ 'justify-content-center': deviceType !== 'mobile' }" [class.justify-content-center]="deviceType !== 'mobile'"
> >
<a <a
class="d-block" class="d-block"
@ -90,7 +90,7 @@
</div> </div>
<div <div
class="col-md-4 d-flex my-1" class="col-md-4 d-flex my-1"
[ngClass]="{ 'justify-content-center': deviceType !== 'mobile' }" [class.justify-content-center]="deviceType !== 'mobile'"
> >
<a <a
class="d-block" class="d-block"

2
apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts

@ -16,7 +16,6 @@ import { GfSymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplet
import { GfTagsSelectorComponent } from '@ghostfolio/ui/tags-selector'; import { GfTagsSelectorComponent } from '@ghostfolio/ui/tags-selector';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { NgClass } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
@ -70,7 +69,6 @@ import { ActivityType } from './types/activity-type.type';
MatFormFieldModule, MatFormFieldModule,
MatInputModule, MatInputModule,
MatSelectModule, MatSelectModule,
NgClass,
ReactiveFormsModule ReactiveFormsModule
], ],
selector: 'gf-create-or-update-activity-dialog', selector: 'gf-create-or-update-activity-dialog',

55
apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html

@ -76,11 +76,12 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>
<div [ngClass]="{ 'mb-3': mode === 'update' }"> <div [class.mb-3]="mode === 'update'">
<mat-form-field <mat-form-field
appearance="outline" appearance="outline"
class="w-100" class="w-100"
[ngClass]="{ 'mb-1 without-hint': mode === 'create' }" [class.mb-1]="mode === 'create'"
[class.without-hint]="mode === 'create'"
> >
<mat-label i18n>Account</mat-label> <mat-label i18n>Account</mat-label>
<mat-select formControlName="accountId"> <mat-select formControlName="accountId">
@ -103,18 +104,16 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="mb-3" [ngClass]="{ 'd-none': mode === 'update' }"> <div class="mb-3" [class.d-none]="mode === 'update'">
<mat-checkbox color="primary" formControlName="updateAccountBalance" i18n <mat-checkbox color="primary" formControlName="updateAccountBalance" i18n
>Update Cash Balance</mat-checkbox >Update Cash Balance</mat-checkbox
> >
</div> </div>
<div <div
class="mb-3" class="mb-3"
[ngClass]="{ [class.d-none]="
'd-none': !activityForm !activityForm.get('searchSymbol')?.hasValidator(Validators.required)
.get('searchSymbol') "
?.hasValidator(Validators.required)
}"
> >
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Name, symbol or ISIN</mat-label> <mat-label i18n>Name, symbol or ISIN</mat-label>
@ -127,9 +126,9 @@
</div> </div>
<div <div
class="mb-3" class="mb-3"
[ngClass]="{ [class.d-none]="
'd-none': !activityForm.get('name')?.hasValidator(Validators.required) !activityForm.get('name')?.hasValidator(Validators.required)
}" "
> >
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Name</mat-label> <mat-label i18n>Name</mat-label>
@ -173,13 +172,12 @@
</div> </div>
<div <div
class="mb-3" class="mb-3"
[ngClass]="{ [class.d-none]="
'd-none': activityForm.get('type')?.value === 'FEE' ||
activityForm.get('type')?.value === 'FEE' || activityForm.get('type')?.value === 'INTEREST' ||
activityForm.get('type')?.value === 'INTEREST' || activityForm.get('type')?.value === 'ITEM' ||
activityForm.get('type')?.value === 'ITEM' || activityForm.get('type')?.value === 'LIABILITY'
activityForm.get('type')?.value === 'LIABILITY' "
}"
> >
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Quantity</mat-label> <mat-label i18n>Quantity</mat-label>
@ -188,7 +186,7 @@
</div> </div>
<div <div
class="mb-3" class="mb-3"
[ngClass]="{ 'd-none': activityForm.get('type')?.value === 'FEE' }" [class.d-none]="activityForm.get('type')?.value === 'FEE'"
> >
<div class="align-items-start d-flex"> <div class="align-items-start d-flex">
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
@ -215,7 +213,7 @@
<div <div
class="ml-2" class="ml-2"
matTextSuffix matTextSuffix
[ngClass]="{ 'd-none': !activityForm.get('currency')?.value }" [class.d-none]="!activityForm.get('currency')?.value"
> >
<mat-select formControlName="currencyOfUnitPrice"> <mat-select formControlName="currencyOfUnitPrice">
@for (currency of currencies; track currency) { @for (currency of currencies; track currency) {
@ -247,12 +245,11 @@
</div> </div>
<div <div
class="mb-3" class="mb-3"
[ngClass]="{ [class.d-none]="
'd-none': activityForm.get('type')?.value === 'INTEREST' ||
activityForm.get('type')?.value === 'INTEREST' || activityForm.get('type')?.value === 'ITEM' ||
activityForm.get('type')?.value === 'ITEM' || activityForm.get('type')?.value === 'LIABILITY'
activityForm.get('type')?.value === 'LIABILITY' "
}"
> >
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Fee</mat-label> <mat-label i18n>Fee</mat-label>
@ -260,7 +257,7 @@
<div <div
class="ml-2" class="ml-2"
matTextSuffix matTextSuffix
[ngClass]="{ 'd-none': !activityForm.get('currency')?.value }" [class.d-none]="!activityForm.get('currency')?.value"
> >
{{ activityForm.get('currencyOfUnitPrice')?.value }} {{ activityForm.get('currencyOfUnitPrice')?.value }}
</div> </div>
@ -280,7 +277,7 @@
</div> </div>
<div <div
class="mb-3" class="mb-3"
[ngClass]="{ 'd-none': activityForm.get('type')?.value !== 'ITEM' }" [class.d-none]="activityForm.get('type')?.value !== 'ITEM'"
> >
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Asset Class</mat-label> <mat-label i18n>Asset Class</mat-label>
@ -299,7 +296,7 @@
</div> </div>
<div <div
class="mb-3" class="mb-3"
[ngClass]="{ 'd-none': activityForm.get('type')?.value !== 'ITEM' }" [class.d-none]="activityForm.get('type')?.value !== 'ITEM'"
> >
<mat-form-field appearance="outline" class="w-100"> <mat-form-field appearance="outline" class="w-100">
<mat-label i18n>Asset Sub Class</mat-label> <mat-label i18n>Asset Sub Class</mat-label>

4
apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts

@ -21,7 +21,6 @@ import { GfTopHoldingsComponent } from '@ghostfolio/ui/top-holdings';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { GfWorldMapChartComponent } from '@ghostfolio/ui/world-map-chart'; import { GfWorldMapChartComponent } from '@ghostfolio/ui/world-map-chart';
import { NgClass } from '@angular/common';
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
@ -51,8 +50,7 @@ import { DeviceDetectorService } from 'ngx-device-detector';
GfValueComponent, GfValueComponent,
GfWorldMapChartComponent, GfWorldMapChartComponent,
MatCardModule, MatCardModule,
MatProgressBarModule, MatProgressBarModule
NgClass
], ],
selector: 'gf-allocations-page', selector: 'gf-allocations-page',
styleUrls: ['./allocations-page.scss'], styleUrls: ['./allocations-page.scss'],

4
apps/client/src/app/pages/portfolio/allocations/allocations-page.html

@ -319,9 +319,7 @@
</div> </div>
<div <div
class="col-md-12" class="col-md-12"
[ngClass]="{ [class.d-none]="!user?.settings?.isExperimentalFeatures"
'd-none': !user?.settings?.isExperimentalFeatures
}"
> >
<mat-card appearance="outlined" class="mb-3"> <mat-card appearance="outlined" class="mb-3">
<mat-card-header class="overflow-hidden w-100"> <mat-card-header class="overflow-hidden w-100">

2
apps/client/src/app/pages/portfolio/fire/fire-page.html

@ -62,7 +62,7 @@
/> />
</div> </div>
} @else { } @else {
<div [ngClass]="{ 'text-muted': user?.subscription?.type === 'Basic' }"> <div [class.text-muted]="user?.subscription?.type === 'Basic'">
<div class="mb-2"> <div class="mb-2">
<ng-container i18n <ng-container i18n
>If you retire today, you would be able to withdraw</ng-container >If you retire today, you would be able to withdraw</ng-container

7
apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.html

@ -30,7 +30,7 @@
} @else { } @else {
<div <div
class="align-items-center d-flex icon-container mr-2 px-2" class="align-items-center d-flex icon-container mr-2 px-2"
[ngClass]="{ [class]="{
okay: okay:
statistics?.rulesFulfilledCount === statistics?.rulesFulfilledCount ===
statistics?.rulesActiveCount, statistics?.rulesActiveCount,
@ -60,10 +60,7 @@
} }
</div> </div>
@for (category of categories; track category.key) { @for (category of categories; track category.key) {
<div <div class="mb-4" [class.d-none]="category.rules?.length === 0">
class="mb-4"
[ngClass]="{ 'd-none': category.rules?.length === 0 }"
>
<h4 class="align-items-center d-flex m-0"> <h4 class="align-items-center d-flex m-0">
<span>{{ category.name }}</span> <span>{{ category.name }}</span>
@if (user?.subscription?.type === 'Basic') { @if (user?.subscription?.type === 'Basic') {

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

@ -12,7 +12,6 @@ import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { DataService } from '@ghostfolio/ui/services'; import { DataService } from '@ghostfolio/ui/services';
import { NgClass } from '@angular/common';
import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core'; import { ChangeDetectorRef, Component, DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { IonIcon } from '@ionic/angular/standalone'; import { IonIcon } from '@ionic/angular/standalone';
@ -29,7 +28,6 @@ import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
GfPremiumIndicatorComponent, GfPremiumIndicatorComponent,
GfRulesComponent, GfRulesComponent,
IonIcon, IonIcon,
NgClass,
NgxSkeletonLoaderModule NgxSkeletonLoaderModule
], ],
selector: 'gf-x-ray-page', selector: 'gf-x-ray-page',

3
apps/client/src/app/pages/pricing/pricing-page.component.ts

@ -7,7 +7,6 @@ import { NotificationService } from '@ghostfolio/ui/notifications';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { DataService } from '@ghostfolio/ui/services'; import { DataService } from '@ghostfolio/ui/services';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
@ -35,7 +34,6 @@ import { catchError } from 'rxjs/operators';
@Component({ @Component({
host: { class: 'page' }, host: { class: 'page' },
imports: [ imports: [
CommonModule,
GfPremiumIndicatorComponent, GfPremiumIndicatorComponent,
IonIcon, IonIcon,
MatButtonModule, MatButtonModule,
@ -78,6 +76,7 @@ export class GfPricingPageComponent implements OnInit {
'Interactive Brokers', 'Interactive Brokers',
'Mintos', 'Mintos',
'Monefit SmartSaver', 'Monefit SmartSaver',
'Revolut',
'Swissquote', 'Swissquote',
'VIAC', 'VIAC',
'Zak' 'Zak'

4
apps/client/src/app/pages/pricing/pricing-page.html

@ -103,7 +103,7 @@
<mat-card <mat-card
appearance="outlined" appearance="outlined"
class="h-100" class="h-100"
[ngClass]="{ active: user?.subscription?.type === 'Basic' }" [class.active]="user?.subscription?.type === 'Basic'"
> >
<mat-card-content class="d-flex flex-column h-100"> <mat-card-content class="d-flex flex-column h-100">
<div class="flex-grow-1"> <div class="flex-grow-1">
@ -169,7 +169,7 @@
<mat-card <mat-card
appearance="outlined" appearance="outlined"
class="h-100" class="h-100"
[ngClass]="{ active: user?.subscription?.type === 'Premium' }" [class.active]="user?.subscription?.type === 'Premium'"
> >
<mat-card-content class="d-flex flex-column h-100"> <mat-card-content class="d-flex flex-column h-100">
@if (label) { @if (label) {

2
apps/client/src/app/pages/public/public-page.component.ts

@ -14,7 +14,6 @@ import { DataService } from '@ghostfolio/ui/services';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { GfWorldMapChartComponent } from '@ghostfolio/ui/world-map-chart'; import { GfWorldMapChartComponent } from '@ghostfolio/ui/world-map-chart';
import { CommonModule } from '@angular/common';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { import {
ChangeDetectorRef, ChangeDetectorRef,
@ -40,7 +39,6 @@ import { catchError } from 'rxjs/operators';
@Component({ @Component({
host: { class: 'page' }, host: { class: 'page' },
imports: [ imports: [
CommonModule,
GfActivitiesTableComponent, GfActivitiesTableComponent,
GfHoldingsTableComponent, GfHoldingsTableComponent,
GfPortfolioProportionChartComponent, GfPortfolioProportionChartComponent,

2
apps/client/src/app/pages/public/public-page.html

@ -202,7 +202,7 @@
</div> </div>
</div> </div>
} }
<div class="row" [ngClass]="{ 'd-none': hasPermissionForSubscription }"> <div class="row" [class.d-none]="hasPermissionForSubscription">
<div class="col-md-12"> <div class="col-md-12">
<mat-card appearance="outlined"> <mat-card appearance="outlined">
<mat-card-header class="overflow-hidden w-100"> <mat-card-header class="overflow-hidden w-100">

12
apps/client/src/styles.scss

@ -520,15 +520,15 @@ ngx-skeleton-loader {
padding: 2rem 0; padding: 2rem 0;
} }
@include mat.tabs-overrides(
(
divider-height: 0
)
);
@media (min-width: 576px) { @media (min-width: 576px) {
flex-direction: row-reverse; flex-direction: row-reverse;
@include mat.tabs-overrides(
(
divider-height: 0
)
);
.mat-mdc-tab-header { .mat-mdc-tab-header {
background-color: rgba(var(--palette-foreground-base), 0.02); background-color: rgba(var(--palette-foreground-base), 0.02);
padding: 2rem 0; padding: 2rem 0;

6
libs/ui/src/lib/accounts-table/accounts-table.component.html

@ -340,15 +340,13 @@
<tr <tr
*matRowDef="let row; columns: displayedColumns()" *matRowDef="let row; columns: displayedColumns()"
mat-row mat-row
[ngClass]="{ [class.cursor-pointer]="hasPermissionToOpenDetails()"
'cursor-pointer': hasPermissionToOpenDetails()
}"
(click)="onOpenAccountDetailDialog(row.id)" (click)="onOpenAccountDetailDialog(row.id)"
></tr> ></tr>
<tr <tr
*matFooterRowDef="displayedColumns()" *matFooterRowDef="displayedColumns()"
mat-footer-row mat-footer-row
[ngClass]="{ 'd-none': isLoading() || !showFooter() }" [class.d-none]="isLoading() || !showFooter()"
></tr> ></tr>
</table> </table>
</div> </div>

2
libs/ui/src/lib/accounts-table/accounts-table.component.ts

@ -4,7 +4,6 @@ import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo';
import { NotificationService } from '@ghostfolio/ui/notifications'; import { NotificationService } from '@ghostfolio/ui/notifications';
import { GfValueComponent } from '@ghostfolio/ui/value'; import { GfValueComponent } from '@ghostfolio/ui/value';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
@ -37,7 +36,6 @@ import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ imports: [
CommonModule,
GfEntityLogoComponent, GfEntityLogoComponent,
GfValueComponent, GfValueComponent,
IonIcon, IonIcon,

8
libs/ui/src/lib/activities-table/activities-table.component.html

@ -516,9 +516,7 @@
<tr <tr
*matRowDef="let row; columns: displayedColumns()" *matRowDef="let row; columns: displayedColumns()"
mat-row mat-row
[ngClass]="{ [class.cursor-pointer]="canClickActivity(row)"
'cursor-pointer': canClickActivity(row)
}"
(click)="onClickActivity(row)" (click)="onClickActivity(row)"
></tr> ></tr>
</table> </table>
@ -536,11 +534,9 @@
} }
<mat-paginator <mat-paginator
[class.d-none]="(isLoading() && !totalItems) || totalItems <= pageSize"
[hidePageSize]="true" [hidePageSize]="true"
[length]="totalItems" [length]="totalItems"
[ngClass]="{
'd-none': (isLoading() && !totalItems) || totalItems <= pageSize
}"
[pageIndex]="pageIndex" [pageIndex]="pageIndex"
[pageSize]="pageSize" [pageSize]="pageSize"
[showFirstLastButtons]="true" [showFirstLastButtons]="true"

2
libs/ui/src/lib/activity-type/activity-type.component.html

@ -1,6 +1,6 @@
<div <div
class="d-inline-flex p-1 activity-type-badge" class="d-inline-flex p-1 activity-type-badge"
[ngClass]="{ [class]="{
buy: activityType === 'BUY', buy: activityType === 'BUY',
dividend: activityType === 'DIVIDEND', dividend: activityType === 'DIVIDEND',
fee: activityType === 'FEE', fee: activityType === 'FEE',

3
libs/ui/src/lib/activity-type/activity-type.component.ts

@ -1,4 +1,3 @@
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -22,7 +21,7 @@ import { translate } from '../i18n';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, IonIcon], imports: [IonIcon],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-activity-type', selector: 'gf-activity-type',
styleUrls: ['./activity-type.component.scss'], styleUrls: ['./activity-type.component.scss'],

6
libs/ui/src/lib/benchmark/benchmark.component.html

@ -122,14 +122,14 @@
@if (isNumber(element?.performances?.allTimeHigh?.performancePercent)) { @if (isNumber(element?.performances?.allTimeHigh?.performancePercent)) {
<gf-value <gf-value
class="d-inline-block justify-content-end" class="d-inline-block justify-content-end"
[isPercent]="true" [class]="{
[locale]="locale()"
[ngClass]="{
'text-danger': 'text-danger':
element?.performances?.allTimeHigh?.performancePercent < 0, element?.performances?.allTimeHigh?.performancePercent < 0,
'text-success': 'text-success':
element?.performances?.allTimeHigh?.performancePercent === 0 element?.performances?.allTimeHigh?.performancePercent === 0
}" }"
[isPercent]="true"
[locale]="locale()"
[value]="element?.performances?.allTimeHigh?.performancePercent" [value]="element?.performances?.allTimeHigh?.performancePercent"
/> />
} }

2
libs/ui/src/lib/benchmark/benchmark.component.ts

@ -11,7 +11,6 @@ import {
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import { NotificationService } from '@ghostfolio/ui/notifications'; import { NotificationService } from '@ghostfolio/ui/notifications';
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -46,7 +45,6 @@ import { BenchmarkDetailDialogParams } from './benchmark-detail-dialog/interface
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ imports: [
CommonModule,
GfTrendIndicatorComponent, GfTrendIndicatorComponent,
GfValueComponent, GfValueComponent,
IonIcon, IonIcon,

2
libs/ui/src/lib/dialog-header/dialog-header.component.html

@ -1,7 +1,7 @@
<div class="d-flex" mat-dialog-title> <div class="d-flex" mat-dialog-title>
<span <span
class="flex-grow-1 text-truncate" class="flex-grow-1 text-truncate"
[ngClass]="{ 'text-center': position === 'center' }" [class.text-center]="position === 'center'"
>{{ title }}</span >{{ title }}</span
> >
@if (deviceType !== 'mobile') { @if (deviceType !== 'mobile') {

3
libs/ui/src/lib/dialog-header/dialog-header.component.ts

@ -1,4 +1,3 @@
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
@ -15,7 +14,7 @@ import { close } from 'ionicons/icons';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'justify-content-center' }, host: { class: 'justify-content-center' },
imports: [CommonModule, IonIcon, MatButtonModule, MatDialogModule], imports: [IonIcon, MatButtonModule, MatDialogModule],
selector: 'gf-dialog-header', selector: 'gf-dialog-header',
styleUrls: ['./dialog-header.component.scss'], styleUrls: ['./dialog-header.component.scss'],
templateUrl: './dialog-header.component.html' templateUrl: './dialog-header.component.html'

2
libs/ui/src/lib/entity-logo/entity-logo.component.html

@ -1,7 +1,7 @@
@if (src) { @if (src) {
<img <img
onerror="this.style.display = 'none'" onerror="this.style.display = 'none'"
[ngClass]="{ large: size === 'large' }" [class.large]="size === 'large'"
[src]="src" [src]="src"
[title]="tooltip ? tooltip : ''" [title]="tooltip ? tooltip : ''"
/> />

2
libs/ui/src/lib/entity-logo/entity-logo.component.ts

@ -1,6 +1,5 @@
import { EntityLogoImageSourceService } from '@ghostfolio/ui/entity-logo/entity-logo-image-source.service'; import { EntityLogoImageSourceService } from '@ghostfolio/ui/entity-logo/entity-logo-image-source.service';
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -12,7 +11,6 @@ import { DataSource } from '@prisma/client';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-entity-logo', selector: 'gf-entity-logo',
styleUrls: ['./entity-logo.component.scss'], styleUrls: ['./entity-logo.component.scss'],

2
libs/ui/src/lib/historical-market-data-editor/historical-market-data-editor.component.html

@ -6,7 +6,7 @@
@for (day of days; track day) { @for (day of days; track day) {
<div <div
class="day" class="day"
[ngClass]="{ [class]="{
'cursor-pointer valid': isDateOfInterest( 'cursor-pointer valid': isDateOfInterest(
`${itemByMonth.key}-${formatDay(day)}` `${itemByMonth.key}-${formatDay(day)}`
), ),

2
libs/ui/src/lib/logo/logo.component.html

@ -1,5 +1,5 @@
<span class="align-items-center d-flex" <span class="align-items-center d-flex"
><span class="d-inline-block logo" [ngClass]="{ 'mr-1': showLabel }"></span> ><span class="d-inline-block logo" [class.mr-1]="showLabel"></span>
@if (showLabel) { @if (showLabel) {
<span class="label">{{ label ?? 'Ghostfolio' }}</span> <span class="label">{{ label ?? 'Ghostfolio' }}</span>
} }

2
libs/ui/src/lib/logo/logo.component.ts

@ -1,4 +1,3 @@
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -9,7 +8,6 @@ import {
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-logo', selector: 'gf-logo',
styleUrls: ['./logo.component.scss'], styleUrls: ['./logo.component.scss'],

4
libs/ui/src/lib/membership-card/membership-card.component.html

@ -1,5 +1,5 @@
<div class="card-wrapper position-relative" [class.hover-3d]="hover3d"> <div class="card-wrapper position-relative" [class.hover-3d]="hover3d">
<div class="card-container" [ngClass]="{ premium: name === 'Premium' }"> <div class="card-container" [class.premium]="name === 'Premium'">
<a <a
class="card-item d-flex flex-column justify-content-between p-4" class="card-item d-flex flex-column justify-content-between p-4"
[routerLink]="routerLinkPricing" [routerLink]="routerLinkPricing"
@ -12,7 +12,7 @@
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
<gf-logo <gf-logo
size="large" size="large"
[ngClass]="{ 'text-muted': name === 'Basic' }" [class.text-muted]="name === 'Basic'"
[showLabel]="false" [showLabel]="false"
/> />
</div> </div>

9
libs/ui/src/lib/membership-card/membership-card.component.ts

@ -1,6 +1,5 @@
import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { publicRoutes } from '@ghostfolio/common/routes/routes';
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -19,13 +18,7 @@ import { GfLogoComponent } from '../logo';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ imports: [GfLogoComponent, IonIcon, MatButtonModule, RouterModule],
CommonModule,
GfLogoComponent,
IonIcon,
MatButtonModule,
RouterModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA], schemas: [CUSTOM_ELEMENTS_SCHEMA],
selector: 'gf-membership-card', selector: 'gf-membership-card',
styleUrls: ['./membership-card.component.scss'], styleUrls: ['./membership-card.component.scss'],

4
libs/ui/src/lib/toggle/toggle.component.html

@ -6,12 +6,12 @@
@for (option of options(); track option) { @for (option of options(); track option) {
<mat-radio-button <mat-radio-button
class="d-inline-flex" class="d-inline-flex"
[disabled]="isLoading()" [class]="{
[ngClass]="{
'cursor-default': option.value === optionFormControl.value, 'cursor-default': option.value === optionFormControl.value,
'cursor-pointer': 'cursor-pointer':
!isLoading() && option.value !== optionFormControl.value !isLoading() && option.value !== optionFormControl.value
}" }"
[disabled]="isLoading()"
[value]="option.value" [value]="option.value"
>{{ option.label }}</mat-radio-button >{{ option.label }}</mat-radio-button
> >

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

@ -1,6 +1,5 @@
import { ToggleOption } from '@ghostfolio/common/interfaces'; import { ToggleOption } from '@ghostfolio/common/interfaces';
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
@ -13,7 +12,7 @@ import { MatRadioModule } from '@angular/material/radio';
@Component({ @Component({
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [CommonModule, MatRadioModule, ReactiveFormsModule], imports: [MatRadioModule, ReactiveFormsModule],
selector: 'gf-toggle', selector: 'gf-toggle',
styleUrls: ['./toggle.component.scss'], styleUrls: ['./toggle.component.scss'],
templateUrl: './toggle.component.html' templateUrl: './toggle.component.html'

6
libs/ui/src/lib/top-holdings/top-holdings.component.html

@ -120,7 +120,7 @@
<tr <tr
*matRowDef="let row; columns: displayedColumns" *matRowDef="let row; columns: displayedColumns"
mat-row mat-row
[ngClass]="{ 'cursor-pointer': row.position }" [class.cursor-pointer]="row.position"
(click)="onClickHolding(row.position)" (click)="onClickHolding(row.position)"
></tr> ></tr>
<tr <tr
@ -138,7 +138,7 @@
<tr <tr
*matRowDef="let element; columns: displayedColumns" *matRowDef="let element; columns: displayedColumns"
mat-row mat-row
[ngClass]="{ [class]="{
'cursor-pointer': element.parents?.length > 0, 'cursor-pointer': element.parents?.length > 0,
expanded: element.expand ?? false expanded: element.expand ?? false
}" }"
@ -150,7 +150,7 @@
*matRowDef="let row; columns: ['expandedDetail']" *matRowDef="let row; columns: ['expandedDetail']"
class="holding-detail" class="holding-detail"
mat-row mat-row
[ngClass]="{ 'd-none': !row.parents?.length }" [class.d-none]="!row.parents?.length"
></tr> ></tr>
</table> </table>
</div> </div>

2
libs/ui/src/lib/top-holdings/top-holdings.component.ts

@ -12,7 +12,6 @@ import {
transition, transition,
trigger trigger
} from '@angular/animations'; } from '@angular/animations';
import { CommonModule } from '@angular/common';
import { import {
CUSTOM_ELEMENTS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA,
ChangeDetectionStrategy, ChangeDetectionStrategy,
@ -44,7 +43,6 @@ import { GfValueComponent } from '../value/value.component';
], ],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ imports: [
CommonModule,
GfSymbolPipe, GfSymbolPipe,
GfValueComponent, GfValueComponent,
MatButtonModule, MatButtonModule,

4
libs/ui/src/lib/trend-indicator/trend-indicator.component.html

@ -16,7 +16,7 @@
<ion-icon <ion-icon
class="text-danger" class="text-danger"
name="arrow-down-circle-outline" name="arrow-down-circle-outline"
[ngClass]="{ 'rotate-45-down': value > -0.01 }" [class.rotate-45-down]="value > -0.01"
[size]="size" [size]="size"
/> />
} @else if (value > -0.0005 && value < 0.0005) { } @else if (value > -0.0005 && value < 0.0005) {
@ -29,7 +29,7 @@
<ion-icon <ion-icon
class="text-success" class="text-success"
name="arrow-up-circle-outline" name="arrow-up-circle-outline"
[ngClass]="{ 'rotate-45-up': value < 0.01 }" [class.rotate-45-up]="value < 0.01"
[size]="size" [size]="size"
/> />
} }

6
libs/ui/src/lib/value/value.component.html

@ -27,7 +27,7 @@
@if (value || value === 0 || value === null) { @if (value || value === 0 || value === null) {
<div <div
class="align-items-center d-flex" class="align-items-center d-flex"
[ngClass]="position === 'end' ? 'justify-content-end' : ''" [class.justify-content-end]="position === 'end'"
> >
@if (isNumber || value === null) { @if (isNumber || value === null) {
@if (colorizeSign && !useAbsoluteValue) { @if (colorizeSign && !useAbsoluteValue) {
@ -40,7 +40,7 @@
} }
<div <div
class="mb-0 value" class="mb-0 value"
[ngClass]="{ [class]="{
'font-weight-bold h2': size === 'large', 'font-weight-bold h2': size === 'large',
h4: size === 'medium' h4: size === 'medium'
}" }"
@ -60,7 +60,7 @@
@if (isString) { @if (isString) {
<div <div
class="mb-0 text-truncate value" class="mb-0 text-truncate value"
[ngClass]="{ [class]="{
'font-weight-bold h2': size === 'large', 'font-weight-bold h2': size === 'large',
h4: size === 'medium' h4: size === 'medium'
}" }"

1327
package-lock.json

File diff suppressed because it is too large

26
package.json

@ -72,7 +72,7 @@
"@codewithdan/observable-store": "2.2.15", "@codewithdan/observable-store": "2.2.15",
"@date-fns/utc": "2.1.1", "@date-fns/utc": "2.1.1",
"@internationalized/number": "3.6.5", "@internationalized/number": "3.6.5",
"@ionic/angular": "8.8.1", "@ionic/angular": "8.8.5",
"@keyv/redis": "4.4.0", "@keyv/redis": "4.4.0",
"@nestjs/bull": "11.0.4", "@nestjs/bull": "11.0.4",
"@nestjs/cache-manager": "3.1.0", "@nestjs/cache-manager": "3.1.0",
@ -113,7 +113,7 @@
"dotenv-expand": "12.0.3", "dotenv-expand": "12.0.3",
"envalid": "8.1.1", "envalid": "8.1.1",
"fast-redact": "3.5.0", "fast-redact": "3.5.0",
"fuse.js": "7.1.0", "fuse.js": "7.3.0",
"google-spreadsheet": "3.2.0", "google-spreadsheet": "3.2.0",
"helmet": "7.0.0", "helmet": "7.0.0",
"http-status-codes": "2.3.0", "http-status-codes": "2.3.0",
@ -158,16 +158,16 @@
"@eslint/js": "9.35.0", "@eslint/js": "9.35.0",
"@nestjs/schematics": "11.1.0", "@nestjs/schematics": "11.1.0",
"@nestjs/testing": "11.1.19", "@nestjs/testing": "11.1.19",
"@nx/angular": "22.6.5", "@nx/angular": "22.7.1",
"@nx/eslint-plugin": "22.6.5", "@nx/eslint-plugin": "22.7.1",
"@nx/jest": "22.6.5", "@nx/jest": "22.7.1",
"@nx/js": "22.6.5", "@nx/js": "22.7.1",
"@nx/module-federation": "22.6.5", "@nx/module-federation": "22.7.1",
"@nx/nest": "22.6.5", "@nx/nest": "22.7.1",
"@nx/node": "22.6.5", "@nx/node": "22.7.1",
"@nx/storybook": "22.6.5", "@nx/storybook": "22.7.1",
"@nx/web": "22.6.5", "@nx/web": "22.7.1",
"@nx/workspace": "22.6.5", "@nx/workspace": "22.7.1",
"@schematics/angular": "21.2.6", "@schematics/angular": "21.2.6",
"@storybook/addon-docs": "10.1.10", "@storybook/addon-docs": "10.1.10",
"@storybook/addon-themes": "10.1.10", "@storybook/addon-themes": "10.1.10",
@ -194,7 +194,7 @@
"jest": "30.2.0", "jest": "30.2.0",
"jest-environment-jsdom": "30.2.0", "jest-environment-jsdom": "30.2.0",
"jest-preset-angular": "16.0.0", "jest-preset-angular": "16.0.0",
"nx": "22.6.5", "nx": "22.7.1",
"prettier": "3.8.3", "prettier": "3.8.3",
"prettier-plugin-organize-attributes": "1.0.0", "prettier-plugin-organize-attributes": "1.0.0",
"prisma": "7.7.0", "prisma": "7.7.0",

Loading…
Cancel
Save