fix(admin): P0 user-reported bugs - raw keys, table overflow, builder escape route

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

- Transactions: 'adminTransactions.flag'/'clearFlag' raw keys rendered on the fraud toggle button (missed by earlier audit because the key sits inside a ternary); added en/ru/hy strings with merchant wording ('Flag as suspicious')
- Table overflow on Customers/Transactions root-caused: app-table host is a grid item with default min-width:auto, so wide tables stretched their parent card instead of scrolling inside the wrapper; shared TableComponent now declares display:block/min-width:0/max-width:100% on its element selector (encapsulation None - :host would not match), fixing every admin table at once; verified in browser: cards contained, wrapper scrolls internally
- Builder trap root-caused: section editor pages (/:lang/edit/<section>) had zero routes to the backoffice - only a link back to the builder overview - so admins inside a section could not return to the dashboard; sidebar now has a persistent 'Back to dashboard' link (new builder.backToDashboard key, en/ru/hy); verified navigation lands on /ru/backoffice/dashboard
This commit is contained in:
sdarbinyan
2026-07-19 08:25:29 +04:00
parent 16dec127c9
commit c452d28eca
8 changed files with 53 additions and 0 deletions

View File

@@ -8,6 +8,10 @@
<span class="pi pi-arrow-left" aria-hidden="true"></span> <span class="pi pi-arrow-left" aria-hidden="true"></span>
{{ 'builder.appName' | translate }} {{ 'builder.appName' | translate }}
</a> </a>
<a class="project-editor-layout__dashboard-link" [routerLink]="dashboardRoute()">
<span class="pi pi-home" aria-hidden="true"></span>
{{ 'builder.backToDashboard' | translate }}
</a>
<app-project-editor-nav (linkClicked)="closeMobileDrawer()" /> <app-project-editor-nav (linkClicked)="closeMobileDrawer()" />
</aside> </aside>

View File

@@ -51,6 +51,28 @@
} }
} }
.project-editor-layout__dashboard-link {
display: flex;
align-items: center;
gap: var(--space-xs);
padding: var(--space-sm);
margin-bottom: var(--space-md);
border-radius: var(--radius-sm);
color: var(--text-secondary);
font-size: 0.85rem;
text-decoration: none;
&:hover {
background: var(--bg-tertiary);
color: var(--text-primary);
}
&:focus-visible {
outline: 2px solid var(--primary-color);
outline-offset: 2px;
}
}
.project-editor-layout__content { .project-editor-layout__content {
min-width: 0; min-width: 0;
padding: var(--space-lg); padding: var(--space-lg);

View File

@@ -95,6 +95,9 @@ export class ProjectEditorPageComponent {
readonly overviewRoute = computed(() => ['/', this.languageService.currentLanguage(), 'edit']); readonly overviewRoute = computed(() => ['/', this.languageService.currentLanguage(), 'edit']);
/** Persistent escape hatch back to the admin dashboard - section editors previously had no route to the backoffice at all. */
readonly dashboardRoute = computed(() => ['/', this.languageService.currentLanguage(), 'backoffice', 'dashboard']);
constructor() { constructor() {
this.facade.loadBootstrap(); this.facade.loadBootstrap();
effect(() => { effect(() => {

View File

@@ -686,6 +686,7 @@ export const en: Translations = {
linkUrlDesc: 'Path or URL this navigation link points to.', linkUrlDesc: 'Path or URL this navigation link points to.',
linkVisibleDesc: 'Whether this navigation link is shown to shoppers.', linkVisibleDesc: 'Whether this navigation link is shown to shoppers.',
appName: 'Marketplace Builder', appName: 'Marketplace Builder',
backToDashboard: 'Back to dashboard',
breadcrumbRoot: 'Marketplace Builder', breadcrumbRoot: 'Marketplace Builder',
statusComplete: 'Complete', statusComplete: 'Complete',
statusInProgress: 'In progress', statusInProgress: 'In progress',
@@ -1628,6 +1629,8 @@ export const en: Translations = {
method: 'Payment method', method: 'Payment method',
fraud: 'Fraud check', fraud: 'Fraud check',
flagged: 'Flagged', flagged: 'Flagged',
flag: 'Flag as suspicious',
clearFlag: 'Clear flag',
retry: 'Retry', retry: 'Retry',
audit: 'History', audit: 'History',
emptyTitle: 'No transactions found', emptyTitle: 'No transactions found',

View File

@@ -686,6 +686,7 @@ export const hy: Translations = {
linkUrlDesc: 'Ուղին կամ URL-ը, որին ուղղորդում է այս նավիգացիոն հղումը։', linkUrlDesc: 'Ուղին կամ URL-ը, որին ուղղորդում է այս նավիգացիոն հղումը։',
linkVisibleDesc: 'Արդյո՞ք այս նավիգացիոն հղումը ցուցադրվում է գնորդներին։', linkVisibleDesc: 'Արդյո՞ք այս նավիգացիոն հղումը ցուցադրվում է գնորդներին։',
appName: 'Մարկետփլեյսի կոնստրուկտոր', appName: 'Մարկետփլեյսի կոնստրուկտոր',
backToDashboard: 'Վերադառնալ կառավարման վահանակ',
breadcrumbRoot: 'Մարկետփլեյսի կոնստրուկտոր', breadcrumbRoot: 'Մարկետփլեյսի կոնստրուկտոր',
statusComplete: 'Ավարտված', statusComplete: 'Ավարտված',
statusInProgress: 'Ընթացքի մեջ', statusInProgress: 'Ընթացքի մեջ',
@@ -1623,6 +1624,8 @@ export const hy: Translations = {
method: 'Վճարման եղանակ', method: 'Վճարման եղանակ',
fraud: 'Խարդախության ստուգում', fraud: 'Խարդախության ստուգում',
flagged: 'Նշված', flagged: 'Նշված',
flag: 'Նշել որպես կասկածելի',
clearFlag: 'Հանել նշումը',
retry: 'Կրկնել', retry: 'Կրկնել',
audit: 'Պատմություն', audit: 'Պատմություն',
emptyTitle: 'Գործարքներ չեն գտնվել', emptyTitle: 'Գործարքներ չեն գտնվել',

View File

@@ -686,6 +686,7 @@ export const ru: Translations = {
linkUrlDesc: 'Путь или URL, на который ведёт эта ссылка навигации.', linkUrlDesc: 'Путь или URL, на который ведёт эта ссылка навигации.',
linkVisibleDesc: 'Показывать ли эту ссылку навигации покупателям.', linkVisibleDesc: 'Показывать ли эту ссылку навигации покупателям.',
appName: 'Конструктор маркетплейса', appName: 'Конструктор маркетплейса',
backToDashboard: 'Назад в панель управления',
breadcrumbRoot: 'Конструктор маркетплейса', breadcrumbRoot: 'Конструктор маркетплейса',
statusComplete: 'Готово', statusComplete: 'Готово',
statusInProgress: 'В процессе', statusInProgress: 'В процессе',
@@ -1623,6 +1624,8 @@ export const ru: Translations = {
method: 'Способ оплаты', method: 'Способ оплаты',
fraud: 'Проверка на мошенничество', fraud: 'Проверка на мошенничество',
flagged: 'Помечено', flagged: 'Помечено',
flag: 'Пометить как подозрительную',
clearFlag: 'Снять пометку',
retry: 'Повторить', retry: 'Повторить',
audit: 'История', audit: 'История',
emptyTitle: 'Транзакции не найдены', emptyTitle: 'Транзакции не найдены',

View File

@@ -684,6 +684,7 @@ export interface Translations {
linkUrlDesc: string; linkUrlDesc: string;
linkVisibleDesc: string; linkVisibleDesc: string;
appName: string; appName: string;
backToDashboard: string;
breadcrumbRoot: string; breadcrumbRoot: string;
statusComplete: string; statusComplete: string;
statusInProgress: string; statusInProgress: string;
@@ -1635,6 +1636,8 @@ export interface Translations {
method: string; method: string;
fraud: string; fraud: string;
flagged: string; flagged: string;
flag: string;
clearFlag: string;
retry: string; retry: string;
audit: string; audit: string;
emptyTitle: string; emptyTitle: string;

View File

@@ -1,3 +1,15 @@
/* Block-level host that is allowed to shrink inside grid/flex parents.
Without min-width: 0 a wide table forces its parent card to grow past
its container (grid items default to min-width: auto), which is exactly
the "table overflows the card" bug on Customers/Transactions. */
/* Encapsulation is None, so target the element selector directly
(:host would not match). */
app-table {
display: block;
min-width: 0;
max-width: 100%;
}
.app-table-wrapper { .app-table-wrapper {
width: 100%; width: 100%;
overflow-x: auto; overflow-x: auto;