diff --git a/apps/web/src/app/dirt/reports/pages/breach-report.component.html b/apps/web/src/app/dirt/reports/pages/breach-report.component.html
index d645fa39d69..3a302b759b3 100644
--- a/apps/web/src/app/dirt/reports/pages/breach-report.component.html
+++ b/apps/web/src/app/dirt/reports/pages/breach-report.component.html
@@ -12,45 +12,58 @@
{{ "checkBreaches" | i18n }}
-
-
{{ "reportError" | i18n }}...
-
-
- {{ "breachUsernameNotFound" | i18n: checkedUsername }}
-
-
- {{ "breachUsernameFound" | i18n: checkedUsername : breachedAccounts.length }}
-
-
- -
-
-
![]()
-
-
-
{{ a.title }}
-
-
{{ "compromisedData" | i18n }}:
-
-
-
-
- - {{ "website" | i18n }}
- - {{ a.domain }}
- - {{ "affectedUsers" | i18n }}
- - {{ a.pwnCount | number }}
- - {{ "breachOccurred" | i18n }}
- - {{ a.breachDate | date: "mediumDate" }}
- - {{ "breachReported" | i18n }}
- - {{ a.addedDate | date: "mediumDate" }}
-
-
-
-
-
-
+ @if (!loading && checkedUsername) {
+
+ @if (error) {
+
{{ "reportError" | i18n }}...
+ }
+ @if (!error) {
+ @if (!breachedAccounts.length) {
+
+ {{ "breachUsernameNotFound" | i18n: checkedUsername }}
+
+ }
+ @if (breachedAccounts.length) {
+
+ {{ "breachUsernameFound" | i18n: checkedUsername : breachedAccounts.length }}
+
+ }
+ @if (breachedAccounts.length) {
+
+ @for (a of breachedAccounts; track a) {
+ -
+
+
![]()
+
+
+
{{ a.title }}
+
+
{{ "compromisedData" | i18n }}:
+
+ @for (d of a.dataClasses; track d) {
+ - {{ d }}
+ }
+
+
+
+
+ - {{ "website" | i18n }}
+ - {{ a.domain }}
+ - {{ "affectedUsers" | i18n }}
+ - {{ a.pwnCount | number }}
+ - {{ "breachOccurred" | i18n }}
+ - {{ a.breachDate | date: "mediumDate" }}
+ - {{ "breachReported" | i18n }}
+ - {{ a.addedDate | date: "mediumDate" }}
+
+
+
+ }
+
+ }
+ }
+
+ }
diff --git a/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.html b/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.html
index fcdb3f6ca64..b5b964a11b7 100644
--- a/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.html
+++ b/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.html
@@ -5,95 +5,110 @@
-
-
- {{ "noExposedPasswords" | i18n }}
-
-
-
- {{ "exposedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
-
-
-
-
- {{ getName(status) }}
- {{ getCount(status) }}
-
-
-
-
-
- |
- {{ "name" | i18n }} |
-
- {{ "owner" | i18n }}
- |
-
- {{ "timesExposed" | i18n }}
- |
-
-
-
-
- |
-
-
-
- {{ row.name }}
-
-
-
- {{ row.name }}
-
-
-
- {{ "shared" | i18n }}
-
-
-
- {{ "attachments" | i18n }}
-
-
- {{ row.subTitle }}
- |
-
-
-
- |
-
-
- {{ "exposedXTimes" | i18n: (row.exposedXTimes | number) }}
-
- |
-
-
-
-
+ @if (hasLoaded) {
+
+ @if (!ciphers.length) {
+
+ {{ "noExposedPasswords" | i18n }}
+
+ }
+ @if (ciphers.length) {
+
+ {{ "exposedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
+
+ @if (showFilterToggle && !isAdminConsoleActive) {
+
+ @for (status of filterStatus; track status) {
+
+ {{ getName(status) }}
+ {{ getCount(status) }}
+
+ }
+
+ }
+
+
+ |
+ {{ "name" | i18n }} |
+ @if (!isAdminConsoleActive) {
+
+ {{ "owner" | i18n }}
+ |
+ }
+
+ {{ "timesExposed" | i18n }}
+ |
+
+
+
+
+ |
+
+ @if (!organization || canManageCipher(row)) {
+
+ {{ row.name }}
+
+ } @else {
+ {{ row.name }}
+ }
+ @if (!organization && row.organizationId) {
+
+ {{ "shared" | i18n }}
+ }
+ @if (row.hasAttachments) {
+
+ {{ "attachments" | i18n }}
+ }
+
+ {{ row.subTitle }}
+ |
+ @if (!isAdminConsoleActive) {
+
+ @if (!organization) {
+
+
+ }
+ |
+ }
+
+
+ {{ "exposedXTimes" | i18n: (row.exposedXTimes | number) }}
+
+ |
+
+
+ }
+
+ }
diff --git a/apps/web/src/app/dirt/reports/pages/inactive-two-factor-report.component.html b/apps/web/src/app/dirt/reports/pages/inactive-two-factor-report.component.html
index 05758a854c2..592d6030f66 100644
--- a/apps/web/src/app/dirt/reports/pages/inactive-two-factor-report.component.html
+++ b/apps/web/src/app/dirt/reports/pages/inactive-two-factor-report.component.html
@@ -2,110 +2,125 @@
{{ "inactive2faReportDesc" | i18n }}
-
-
- {{ "loading" | i18n }}
-
-
-
- {{ "noInactive2fa" | i18n }}
-
-
-
- {{ "inactive2faFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
-
-
-
-
- {{ getName(status) }}
- {{ getCount(status) }}
-
-
-
-
-
-
- |
- {{ "name" | i18n }} |
- {{ "owner" | i18n }} |
- |
-
-
-
-
-
- |
-
- |
-
-
- {{ r.name }}
-
-
- {{ r.name }}
-
-
-
- {{ "shared" | i18n }}
-
-
-
- {{ "attachments" | i18n }}
-
-
- {{ r.subTitle }}
- |
-
-
-
- |
-
-
- {{ "instructions" | i18n }}
- |
-
-
-
-
-
+ @if (!hasLoaded && loading) {
+
+
+ {{ "loading" | i18n }}
+
+ }
+ @if (hasLoaded) {
+
+ @if (!ciphers.length) {
+
+ {{ "noInactive2fa" | i18n }}
+
+ }
+ @if (ciphers.length) {
+
+ {{ "inactive2faFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
+
+ @if (showFilterToggle && !isAdminConsoleActive) {
+
+ @for (status of filterStatus; track status) {
+
+ {{ getName(status) }}
+ {{ getCount(status) }}
+
+ }
+
+ }
+
+ @if (!isAdminConsoleActive) {
+
+
+ |
+ {{ "name" | i18n }} |
+ {{ "owner" | i18n }} |
+ |
+
+
+ }
+
+
+
+ @for (r of (rows$ | async); track r) {
+
+ |
+
+ |
+
+ @if (!organization || canManageCipher(r)) {
+ {{ r.name }}
+ } @else {
+ {{ r.name }}
+ }
+ @if (!organization && r.organizationId) {
+
+ {{ "shared" | i18n }}
+ }
+ @if (r.hasAttachments) {
+
+ {{ "attachments" | i18n }}
+ }
+
+ {{ r.subTitle }}
+ |
+
+ @if (!organization) {
+
+
+ }
+ |
+
+ @if (cipherDocs.has(r.id)) {
+
+ {{ "instructions" | i18n }}
+ }
+ |
+
+ }
+
+
+ }
+
+ }
diff --git a/apps/web/src/app/dirt/reports/pages/reused-passwords-report.component.html b/apps/web/src/app/dirt/reports/pages/reused-passwords-report.component.html
index d09dfa81fd4..af6b012d0c9 100644
--- a/apps/web/src/app/dirt/reports/pages/reused-passwords-report.component.html
+++ b/apps/web/src/app/dirt/reports/pages/reused-passwords-report.component.html
@@ -2,100 +2,107 @@
{{ "reusedPasswordsReportDesc" | i18n }}
-
-
- {{ "loading" | i18n }}
-
-
-
- {{ "noReusedPasswords" | i18n }}
-
-
-
- {{ "reusedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
-
-
-
-
-
- {{ getName(status) }}
- {{ getCount(status) }}
-
-
-
-
-
-
- |
- {{ "name" | i18n }} |
- {{ "owner" | i18n }} |
- {{ "timesReused" | i18n }} |
-
-
-
-
- |
-
-
- {{ row.name }}
+ @if (!hasLoaded && loading) {
+
+
+ {{ "loading" | i18n }}
+
+ }
+ @if (hasLoaded) {
+
+ @if (!ciphers.length) {
+
+ {{ "noReusedPasswords" | i18n }}
+
+ }
+ @if (ciphers.length) {
+
+ {{ "reusedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
+
+ @if (showFilterToggle && !isAdminConsoleActive) {
+
+ @for (status of filterStatus; track status) {
+
+ {{ getName(status) }}
+ {{ getCount(status) }}
+
+ }
+
+ }
+
+ @if (!isAdminConsoleActive) {
+
+ |
+ {{ "name" | i18n }} |
+ {{ "owner" | i18n }} |
+ {{ "timesReused" | i18n }} |
-
- {{ row.name }}
-
-
-
- {{ "shared" | i18n }}
-
-
-
- {{ "attachments" | i18n }}
-
-
- {{ row.subTitle }}
- |
-
-
-
- |
-
-
- {{ "reusedXTimes" | i18n: passwordUseMap.get(row.login.password) }}
-
- |
-
-
-
-
+ }
+
+
+
+ |
+
+ @if (!organization || canManageCipher(row)) {
+ {{ row.name }}
+ } @else {
+ {{ row.name }}
+ }
+ @if (!organization && row.organizationId) {
+
+ {{ "shared" | i18n }}
+ }
+ @if (row.hasAttachments) {
+
+ {{ "attachments" | i18n }}
+ }
+
+ {{ row.subTitle }}
+ |
+
+ @if (!organization) {
+
+
+ }
+ |
+
+
+ {{ "reusedXTimes" | i18n: passwordUseMap.get(row.login.password) }}
+
+ |
+
+
+ }
+
+ }
diff --git a/apps/web/src/app/dirt/reports/pages/unsecured-websites-report.component.html b/apps/web/src/app/dirt/reports/pages/unsecured-websites-report.component.html
index 5dd11b59999..1b2652d6258 100644
--- a/apps/web/src/app/dirt/reports/pages/unsecured-websites-report.component.html
+++ b/apps/web/src/app/dirt/reports/pages/unsecured-websites-report.component.html
@@ -2,98 +2,111 @@
{{ "unsecuredWebsitesReportDesc" | i18n }}
-
-
- {{ "loading" | i18n }}
-
-
-
- {{ "noUnsecuredWebsites" | i18n }}
-
-
-
- {{ "unsecuredWebsitesFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
-
-
-
-
-
- {{ getName(status) }}
- {{ getCount(status) }}
-
-
-
-
-
-
- |
- {{ "name" | i18n }} |
- {{ "owner" | i18n }} |
- |
-
-
-
-
- |
-
- |
-
-
- {{ r.name }}
-
-
- {{ r.name }}
-
-
-
- {{ "shared" | i18n }}
-
-
-
- {{ "attachments" | i18n }}
-
-
- {{ r.subTitle }}
- |
-
-
-
- |
-
-
-
-
-
+ @if (!hasLoaded && loading) {
+
+
+ {{ "loading" | i18n }}
+
+ }
+ @if (hasLoaded) {
+
+ @if (!ciphers.length) {
+
+ {{ "noUnsecuredWebsites" | i18n }}
+
+ }
+ @if (ciphers.length) {
+
+ {{ "unsecuredWebsitesFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
+
+ @if (showFilterToggle && !isAdminConsoleActive) {
+
+ @for (status of filterStatus; track status) {
+
+ {{ getName(status) }}
+ {{ getCount(status) }}
+
+ }
+
+ }
+
+ @if (!isAdminConsoleActive) {
+
+
+ |
+ {{ "name" | i18n }} |
+ {{ "owner" | i18n }} |
+ |
+
+
+ }
+
+
+ @for (r of (rows$ | async); track r) {
+
+ |
+
+ |
+
+ @if (!organization || canManageCipher(r)) {
+ {{ r.name }}
+ } @else {
+ {{ r.name }}
+ }
+ @if (!organization && r.organizationId) {
+
+ {{ "shared" | i18n }}
+ }
+ @if (r.hasAttachments) {
+
+ {{ "attachments" | i18n }}
+ }
+
+ {{ r.subTitle }}
+ |
+
+ @if (!organization) {
+
+
+ }
+ |
+
+ }
+
+
+ }
+
+ }
diff --git a/apps/web/src/app/dirt/reports/pages/weak-passwords-report.component.html b/apps/web/src/app/dirt/reports/pages/weak-passwords-report.component.html
index 92d56c1c7a3..b16a9bc2bdc 100644
--- a/apps/web/src/app/dirt/reports/pages/weak-passwords-report.component.html
+++ b/apps/web/src/app/dirt/reports/pages/weak-passwords-report.component.html
@@ -2,102 +2,115 @@
{{ "weakPasswordsReportDesc" | i18n }}
-
-
- {{ "loading" | i18n }}
-
-
-
- {{ "noWeakPasswords" | i18n }}
-
-
-
- {{ "weakPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
-
-
-
-
- {{ getName(status) }}
- {{ getCount(status) }}
-
-
-
-
-
- |
- {{ "name" | i18n }} |
-
- {{ "owner" | i18n }}
- |
-
- {{ "weakness" | i18n }}
- |
-
-
-
-
- |
-
-
- {{ row.name }}
-
-
- {{ row.name }}
-
-
-
- {{ "shared" | i18n }}
-
-
-
- {{ "attachments" | i18n }}
-
-
- {{ row.subTitle }}
- |
-
-
-
- |
-
-
- {{ row.reportValue.label | i18n }}
-
- |
-
-
-
-
+ @if (!hasLoaded && loading) {
+
+
+ {{ "loading" | i18n }}
+
+ }
+ @if (hasLoaded) {
+
+ @if (!ciphers.length) {
+
+ {{ "noWeakPasswords" | i18n }}
+
+ }
+ @if (ciphers.length) {
+
+ {{ "weakPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }}
+
+ @if (showFilterToggle && !isAdminConsoleActive) {
+
+ @for (status of filterStatus; track status) {
+
+ {{ getName(status) }}
+ {{ getCount(status) }}
+
+ }
+
+ }
+
+
+ |
+ {{ "name" | i18n }} |
+ @if (!isAdminConsoleActive) {
+
+ {{ "owner" | i18n }}
+ |
+ }
+
+ {{ "weakness" | i18n }}
+ |
+
+
+
+
+ |
+
+ @if (!organization || canManageCipher(row)) {
+ {{ row.name }}
+ } @else {
+ {{ row.name }}
+ }
+ @if (!organization && row.organizationId) {
+
+ {{ "shared" | i18n }}
+ }
+ @if (row.hasAttachments) {
+
+ {{ "attachments" | i18n }}
+ }
+
+ {{ row.subTitle }}
+ |
+ @if (!isAdminConsoleActive) {
+
+ @if (!organization) {
+
+
+ }
+ |
+ }
+
+
+ {{ row.reportValue.label | i18n }}
+
+ |
+
+
+ }
+
+ }
diff --git a/apps/web/src/app/dirt/reports/reports-layout.component.html b/apps/web/src/app/dirt/reports/reports-layout.component.html
index a27556a7aa9..0cb5d304a34 100644
--- a/apps/web/src/app/dirt/reports/reports-layout.component.html
+++ b/apps/web/src/app/dirt/reports/reports-layout.component.html
@@ -2,8 +2,10 @@
diff --git a/apps/web/src/app/dirt/reports/shared/report-list/report-list.component.html b/apps/web/src/app/dirt/reports/shared/report-list/report-list.component.html
index 2a03bf78dd4..bba57882027 100644
--- a/apps/web/src/app/dirt/reports/shared/report-list/report-list.component.html
+++ b/apps/web/src/app/dirt/reports/shared/report-list/report-list.component.html
@@ -1,13 +1,15 @@
-
+ @for (report of reports; track report) {
+
+ }