feat(ui): refactor page layouts to use RdxPageContent for improved structure and consistency
This commit is contained in:
parent
939577dbec
commit
35dca3954d
@ -24,13 +24,13 @@ export const SettingsLayout = ({ sections }: SettingsLayoutProps) => {
|
||||
|
||||
return (
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer className="space-y-6" width="full">
|
||||
<RdxPageHeader
|
||||
description={t("web.settings.description")}
|
||||
title={t("web.settings.title")}
|
||||
/>
|
||||
|
||||
<RdxPageContainer width="full">
|
||||
<RdxPageContent spacing="default">
|
||||
<RdxPageHeader
|
||||
description={t("web.settings.description")}
|
||||
title={t("web.settings.title")}
|
||||
/>
|
||||
|
||||
<div className="grid gap-6 lg:grid-cols-[18rem_minmax(0,1fr)]">
|
||||
<aside className="min-w-0 lg:sticky lg:top-6 lg:self-start">
|
||||
<SettingsNavigation sections={sections} />
|
||||
|
||||
@ -82,7 +82,7 @@ RdxPageContent
|
||||
→ composición de los hijos principales
|
||||
```
|
||||
|
||||
Regla: Las Pages no deben reconstruir estas responsabilidades con wrappers HTML locales. En Create/Update y Detail/Show, la composición canónica es RdxPageFrame → RdxPageContainer → RdxPageContent: errores, alertas, secciones semánticas y contenido funcional son hijos directos de RdxPageContent; los dialogs son hermanos del frame; RdxPanel se reserva para secciones semánticas reales.
|
||||
Regla: Las Pages no deben reconstruir estas responsabilidades con wrappers HTML locales. En Create/Update, Detail/Show y LIST, la composición canónica es RdxPageFrame → RdxPageContainer → RdxPageContent: errores, alertas, secciones semánticas y contenido funcional son hijos directos de RdxPageContent; los dialogs son hermanos del frame; RdxPanel se reserva para secciones semánticas reales.
|
||||
|
||||
## 6. Identity y sesión
|
||||
|
||||
|
||||
@ -22,6 +22,18 @@ Los componentes aquí citados se definen en `ui-system.md`; este documento expli
|
||||
</RdxPageFrame>
|
||||
```
|
||||
|
||||
El error inicial bloqueante conserva el mismo shell:
|
||||
|
||||
```tsx
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<RdxPageContent>
|
||||
<PageErrorState />
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
```
|
||||
|
||||
- El CTA de creación permanece durante loading, empty y errores de refresh; puede desaparecer ante error inicial bloqueante.
|
||||
- Búsqueda, filtros y controles viven en `DataTable.topContent`.
|
||||
- TanStack Query conserva los datos remotos y la paginación server-side.
|
||||
@ -29,6 +41,7 @@ Los componentes aquí citados se definen en `ui-system.md`; este documento expli
|
||||
- No se calculan contadores globales a partir de una página parcial.
|
||||
- El click de fila recibe la fila; la página/controller usa explícitamente `row.id`.
|
||||
- Una vista de composición de dominio puede encapsular el shell si permanece pura.
|
||||
- Los listados no reconstruyen con HTML local las responsabilidades de Frame, Container o Content. Search, filtros, tabs, tabla y paginación son contenido funcional de `RdxPageContent`; el scroll interno de una tabla o grid es legítimo y no sustituye el scroll de página.
|
||||
|
||||
El controller de página concentra URL, filtros, consulta, estados y navegación. La Page define columnas y conecta callbacks; no reproduce reglas de dominio.
|
||||
|
||||
|
||||
@ -152,6 +152,8 @@ Excepción: un detalle documental puede configurar el contenido del frame con `o
|
||||
Los avisos, errores inline, secciones y contenido funcional deben ser hijos directos cuando pertenezcan al mismo nivel visual.
|
||||
`RdxPanel` no es un wrapper genérico. Se usa únicamente cuando existe una sección con identidad visual o semántica propia.
|
||||
|
||||
En LIST, toolbar, búsqueda, filtros, tabs, tabla/lista/grid y paginación son bloques funcionales de `RdxPageContent`. Una tabla no implica un `RdxPanel`, y su scroll horizontal, virtualizado o interno es legítimo: no sustituye el scroll estructural de `RdxPageFrame`. No se anidan containers ni contents para filtros, alertas o paginación.
|
||||
|
||||
```tsx
|
||||
<RdxPageContent>
|
||||
{error ? <ErrorAlert /> : null}
|
||||
|
||||
@ -36,16 +36,18 @@ export const AuditPage = () => {
|
||||
return (
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<PageErrorState
|
||||
description={t("audit.error.load")}
|
||||
primaryAction={{
|
||||
label: t("audit.retry"),
|
||||
onClick: retry,
|
||||
isLoading: controller.isFetching,
|
||||
}}
|
||||
title={t("audit.error.load")}
|
||||
variant="unknown"
|
||||
/>
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={t("audit.error.load")}
|
||||
primaryAction={{
|
||||
label: t("audit.retry"),
|
||||
onClick: retry,
|
||||
isLoading: controller.isFetching,
|
||||
}}
|
||||
title={t("audit.error.load")}
|
||||
variant="unknown"
|
||||
/>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
@ -96,9 +98,9 @@ export const AuditPage = () => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<AuditEntrySheet entryId={controller.entry} onClose={controller.closeEntry} />
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
<AuditEntrySheet entryId={controller.entry} onClose={controller.closeEntry} />
|
||||
</RdxPageFrame>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { PageErrorState } from "@erp/core/components";
|
||||
import { RdxBadge, RdxPageContainer } from "@repo/rdx-ui/components";
|
||||
import { RdxBadge } from "@repo/rdx-ui/components";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
@ -30,27 +30,23 @@ export const PaymentMethodsSettingsPage = () => {
|
||||
|
||||
if (ctrl.pageError) {
|
||||
return (
|
||||
<RdxPageContainer width="full">
|
||||
<div className="mx-auto w-full max-w-3xl">
|
||||
<PageErrorState
|
||||
description={ctrl.pageError.description}
|
||||
primaryAction={
|
||||
ctrl.pageError.canRetry
|
||||
? {
|
||||
label: ctrl.isRetrying
|
||||
? t("settings.paymentMethods.pageError.actions.retrying")
|
||||
: t("settings.paymentMethods.pageError.actions.retry"),
|
||||
onClick: ctrl.retry,
|
||||
isLoading: ctrl.isRetrying,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
reference={ctrl.pageError.reference}
|
||||
title={ctrl.pageError.title}
|
||||
variant={ctrl.pageError.variant}
|
||||
/>
|
||||
</div>
|
||||
</RdxPageContainer>
|
||||
<PageErrorState
|
||||
description={ctrl.pageError.description}
|
||||
primaryAction={
|
||||
ctrl.pageError.canRetry
|
||||
? {
|
||||
label: ctrl.isRetrying
|
||||
? t("settings.paymentMethods.pageError.actions.retrying")
|
||||
: t("settings.paymentMethods.pageError.actions.retry"),
|
||||
onClick: ctrl.retry,
|
||||
isLoading: ctrl.isRetrying,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
reference={ctrl.pageError.reference}
|
||||
title={ctrl.pageError.title}
|
||||
variant={ctrl.pageError.variant}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { PageErrorState } from "@erp/core/components";
|
||||
import { RdxPageContainer } from "@repo/rdx-ui/components";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
@ -38,27 +37,23 @@ export const PaymentTermsSettingsPage = () => {
|
||||
|
||||
if (ctrl.pageError) {
|
||||
return (
|
||||
<RdxPageContainer width="full">
|
||||
<div className="mx-auto w-full max-w-3xl">
|
||||
<PageErrorState
|
||||
description={ctrl.pageError.description}
|
||||
primaryAction={
|
||||
ctrl.pageError.canRetry
|
||||
? {
|
||||
label: ctrl.isRetrying
|
||||
? t("settings.paymentTerms.pageError.actions.retrying")
|
||||
: t("settings.paymentTerms.pageError.actions.retry"),
|
||||
onClick: ctrl.retry,
|
||||
isLoading: ctrl.isRetrying,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
reference={ctrl.pageError.reference}
|
||||
title={ctrl.pageError.title}
|
||||
variant={ctrl.pageError.variant}
|
||||
/>
|
||||
</div>
|
||||
</RdxPageContainer>
|
||||
<PageErrorState
|
||||
description={ctrl.pageError.description}
|
||||
primaryAction={
|
||||
ctrl.pageError.canRetry
|
||||
? {
|
||||
label: ctrl.isRetrying
|
||||
? t("settings.paymentTerms.pageError.actions.retrying")
|
||||
: t("settings.paymentTerms.pageError.actions.retry"),
|
||||
onClick: ctrl.retry,
|
||||
isLoading: ctrl.isRetrying,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
reference={ctrl.pageError.reference}
|
||||
title={ctrl.pageError.title}
|
||||
variant={ctrl.pageError.variant}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { PageErrorState } from "@erp/core/components";
|
||||
import { RdxBadge, RdxPageContainer } from "@repo/rdx-ui/components";
|
||||
import { RdxBadge } from "@repo/rdx-ui/components";
|
||||
import { Button, Card, CardContent, CardHeader } from "@repo/shadcn-ui/components";
|
||||
import { cn } from "@repo/shadcn-ui/lib/utils";
|
||||
import { CircleIcon, LandmarkIcon, PlusIcon } from "lucide-react";
|
||||
@ -23,27 +23,23 @@ export const TaxRegimesSettingsPage = () => {
|
||||
|
||||
if (ctrl.pageError) {
|
||||
return (
|
||||
<RdxPageContainer width="full">
|
||||
<div className="mx-auto w-full max-w-3xl">
|
||||
<PageErrorState
|
||||
description={ctrl.pageError.description}
|
||||
primaryAction={
|
||||
ctrl.pageError.canRetry
|
||||
? {
|
||||
label: ctrl.isRetrying
|
||||
? t("settings.taxRegimes.pageError.actions.retrying")
|
||||
: t("settings.taxRegimes.pageError.actions.retry"),
|
||||
onClick: ctrl.retry,
|
||||
isLoading: ctrl.isRetrying,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
reference={ctrl.pageError.reference}
|
||||
title={ctrl.pageError.title}
|
||||
variant={ctrl.pageError.variant}
|
||||
/>
|
||||
</div>
|
||||
</RdxPageContainer>
|
||||
<PageErrorState
|
||||
description={ctrl.pageError.description}
|
||||
primaryAction={
|
||||
ctrl.pageError.canRetry
|
||||
? {
|
||||
label: ctrl.isRetrying
|
||||
? t("settings.taxRegimes.pageError.actions.retrying")
|
||||
: t("settings.taxRegimes.pageError.actions.retry"),
|
||||
onClick: ctrl.retry,
|
||||
isLoading: ctrl.isRetrying,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
reference={ctrl.pageError.reference}
|
||||
title={ctrl.pageError.title}
|
||||
variant={ctrl.pageError.variant}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -127,7 +127,8 @@ export const IssuedInvoicesStatusSegmentedFilter = ({
|
||||
}: IssuedInvoicesStatusSegmentedFilterProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleValueChange = (nextValue: string) => {
|
||||
const handleValueChange = (nextValues: string[]) => {
|
||||
const nextValue = nextValues[0];
|
||||
if (!(nextValue && isIssuedInvoiceStatusFilter(nextValue)) || nextValue === value) {
|
||||
return;
|
||||
}
|
||||
@ -138,21 +139,22 @@ export const IssuedInvoicesStatusSegmentedFilter = ({
|
||||
return (
|
||||
<ToggleGroup
|
||||
aria-label={t("pages.issued_invoices.list.filters.status.label", "Filtrar por estado")}
|
||||
className="flex w-full flex-wrap justify-start gap-1"
|
||||
className="flex w-full flex-wrap justify-start gap-4"
|
||||
disabled={disabled}
|
||||
multiple={false}
|
||||
onValueChange={handleValueChange}
|
||||
size="sm"
|
||||
spacing={1}
|
||||
type="single"
|
||||
value={value}
|
||||
value={[value]}
|
||||
variant="outline"
|
||||
>
|
||||
{ISSUED_INVOICE_STATUS_FILTER_OPTIONS.map((option) => (
|
||||
<ToggleGroupItem
|
||||
className={cn(
|
||||
"group h-auto min-w-fit rounded-full border-transparent px-3 py-2 text-xs shadow-none transition-colors sm:text-sm",
|
||||
"group h-auto min-w-fit rounded-md border-transparent px-3 py-2 text-xs sm:text-sm shadow-none transition-colors",
|
||||
"text-muted-foreground hover:border-border hover:bg-muted/60 hover:text-foreground",
|
||||
"data-[state=on]:shadow-none",
|
||||
|
||||
option.activeClassName
|
||||
)}
|
||||
key={option.value}
|
||||
@ -164,7 +166,7 @@ export const IssuedInvoicesStatusSegmentedFilter = ({
|
||||
value={option.value}
|
||||
>
|
||||
<span className="flex items-center gap-2">
|
||||
{option.icon ? <option.icon className="size-3.5" /> : null}
|
||||
{option.icon ? <option.icon className="size-4" /> : null}
|
||||
<span>
|
||||
{t(
|
||||
`catalog.issued_invoices.status.${option.value.toLowerCase()}.label`,
|
||||
|
||||
@ -3,6 +3,7 @@ import { useReturnToNavigation } from "@erp/core/hooks";
|
||||
import {
|
||||
LogoVerifactu,
|
||||
RdxPageContainer,
|
||||
RdxPageContent,
|
||||
RdxPageFrame,
|
||||
RdxPageHeader,
|
||||
} from "@repo/rdx-ui/components";
|
||||
@ -65,34 +66,36 @@ export const ListIssuedInvoicesPage = () => {
|
||||
return (
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<PageErrorState
|
||||
description={pageError.description}
|
||||
primaryAction={
|
||||
pageError.canRetry
|
||||
? {
|
||||
label: isRetrying
|
||||
? t("pages.issued_invoices.list.actions.retrying")
|
||||
: t("pages.issued_invoices.list.actions.retry"),
|
||||
onClick: retryList,
|
||||
isLoading: isRetrying,
|
||||
}
|
||||
: {
|
||||
label: t("pages.issued_invoices.list.actions.go_home"),
|
||||
onClick: () => navigate("/"),
|
||||
}
|
||||
}
|
||||
reference={pageError.reference}
|
||||
secondaryAction={
|
||||
pageError.canRetry
|
||||
? {
|
||||
label: t("pages.issued_invoices.list.actions.go_home"),
|
||||
onClick: () => navigate("/"),
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
title={pageError.title}
|
||||
variant={pageError.variant}
|
||||
/>
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={pageError.description}
|
||||
primaryAction={
|
||||
pageError.canRetry
|
||||
? {
|
||||
label: isRetrying
|
||||
? t("pages.issued_invoices.list.actions.retrying")
|
||||
: t("pages.issued_invoices.list.actions.retry"),
|
||||
onClick: retryList,
|
||||
isLoading: isRetrying,
|
||||
}
|
||||
: {
|
||||
label: t("pages.issued_invoices.list.actions.go_home"),
|
||||
onClick: () => navigate("/"),
|
||||
}
|
||||
}
|
||||
reference={pageError.reference}
|
||||
secondaryAction={
|
||||
pageError.canRetry
|
||||
? {
|
||||
label: t("pages.issued_invoices.list.actions.go_home"),
|
||||
onClick: () => navigate("/"),
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
title={pageError.title}
|
||||
variant={pageError.variant}
|
||||
/>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
@ -100,78 +103,80 @@ export const ListIssuedInvoicesPage = () => {
|
||||
|
||||
return (
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer className="space-y-6" width="full">
|
||||
<RdxPageHeader
|
||||
actions={
|
||||
<Button
|
||||
aria-label={t("pages.issued_invoices.create.title")}
|
||||
className="hidden"
|
||||
onClick={() => navigate("/issued-invoices/create")}
|
||||
>
|
||||
<PlusIcon aria-hidden className="mr-2 size-4" />
|
||||
{t("pages.issued_invoices.create.title")}
|
||||
</Button>
|
||||
}
|
||||
description={t("pages.issued_invoices.list.description")}
|
||||
title={t("pages.issued_invoices.list.title")}
|
||||
/>
|
||||
|
||||
<div className="mx-auto w-full space-y-4">
|
||||
{hasRefreshError && refreshError ? (
|
||||
<ErrorAlert message={refreshError.message} title={refreshError.title} />
|
||||
) : null}
|
||||
|
||||
<Alert className="bg-green-50 text-green-800 flex items-center justify-between gap-6">
|
||||
<div>
|
||||
<AlertTitle className="font-semibold text-green-800">¡Atención!</AlertTitle>
|
||||
<AlertDescription className="text-green-800">
|
||||
Las facturas de esta pantalla son de solo lectura. Se generan automáticamente al
|
||||
emitir una proforma aprobada y no se pueden modificar ni eliminar. Solo puedes
|
||||
descargar el PDF de cada factura.
|
||||
</AlertDescription>
|
||||
</div>
|
||||
<LogoVerifactu className="text-green-800 w-50" color="" />
|
||||
</Alert>
|
||||
|
||||
<IssuedInvoicesGrid
|
||||
columns={columns}
|
||||
data={listCtrl.data}
|
||||
fetching={listCtrl.isFetching}
|
||||
loading={listCtrl.isLoading}
|
||||
onPageChange={listCtrl.setPageIndex}
|
||||
onPageSizeChange={listCtrl.setPageSize}
|
||||
onRowClick={handleOpenDetail}
|
||||
onSortChange={listCtrl.setSort}
|
||||
pageIndex={listCtrl.pageIndex}
|
||||
pageSize={listCtrl.pageSize}
|
||||
searching={isSearchPending}
|
||||
sort={listCtrl.sort}
|
||||
topContent={
|
||||
<div className="space-y-5">
|
||||
<div className="flex flex-col gap-4 xl:flex-row xl:items-center xl:justify-between">
|
||||
<div className="w-full">
|
||||
<SimpleSearchInput
|
||||
loading={listCtrl.isLoading}
|
||||
onPendingChange={setIsSearchPending}
|
||||
onSearchChange={listCtrl.setSearchValue}
|
||||
placeholder={t("pages.issued_invoices.list.search_placeholder")}
|
||||
value={listCtrl.search}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<IssuedInvoicesStatusSegmentedFilter
|
||||
counts={listCtrl.data.statusCounts}
|
||||
disabled={listCtrl.isLoading}
|
||||
onValueChange={listCtrl.setStatusFilter}
|
||||
value={listCtrl.statusFilter}
|
||||
/>
|
||||
</div>
|
||||
<RdxPageContainer width="full">
|
||||
<RdxPageContent>
|
||||
<RdxPageHeader
|
||||
actions={
|
||||
<Button
|
||||
aria-label={t("pages.issued_invoices.create.title")}
|
||||
className="hidden"
|
||||
onClick={() => navigate("/issued-invoices/create")}
|
||||
>
|
||||
<PlusIcon aria-hidden className="mr-2 size-4" />
|
||||
{t("pages.issued_invoices.create.title")}
|
||||
</Button>
|
||||
}
|
||||
description={t("pages.issued_invoices.list.description")}
|
||||
title={t("pages.issued_invoices.list.title")}
|
||||
/>
|
||||
|
||||
{listCtrl.data.totalItems === 0 ? <IssuedInvoicesEmptyGrid /> : null}
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{hasRefreshError && refreshError ? (
|
||||
<ErrorAlert message={refreshError.message} title={refreshError.title} />
|
||||
) : null}
|
||||
|
||||
<Alert className="bg-green-50 text-green-800 flex items-center justify-between gap-6">
|
||||
<div>
|
||||
<AlertTitle className="font-semibold text-green-800">¡Atención!</AlertTitle>
|
||||
<AlertDescription className="text-green-800">
|
||||
Las facturas de esta pantalla son de solo lectura. Se generan automáticamente al
|
||||
emitir una proforma aprobada y no se pueden modificar ni eliminar. Solo puedes
|
||||
descargar el PDF de cada factura.
|
||||
</AlertDescription>
|
||||
</div>
|
||||
<LogoVerifactu className="text-green-800 w-50" color="" />
|
||||
</Alert>
|
||||
|
||||
<IssuedInvoicesGrid
|
||||
columns={columns}
|
||||
data={listCtrl.data}
|
||||
fetching={listCtrl.isFetching}
|
||||
loading={listCtrl.isLoading}
|
||||
onPageChange={listCtrl.setPageIndex}
|
||||
onPageSizeChange={listCtrl.setPageSize}
|
||||
onRowClick={handleOpenDetail}
|
||||
onSortChange={listCtrl.setSort}
|
||||
pageIndex={listCtrl.pageIndex}
|
||||
pageSize={listCtrl.pageSize}
|
||||
searching={isSearchPending}
|
||||
sort={listCtrl.sort}
|
||||
topContent={
|
||||
<div className="space-y-5">
|
||||
<div className="flex flex-col gap-4 xl:flex-row xl:items-center xl:justify-between">
|
||||
<div className="w-full">
|
||||
<SimpleSearchInput
|
||||
loading={listCtrl.isLoading}
|
||||
onPendingChange={setIsSearchPending}
|
||||
onSearchChange={listCtrl.setSearchValue}
|
||||
placeholder={t("pages.issued_invoices.list.search_placeholder")}
|
||||
value={listCtrl.search}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<IssuedInvoicesStatusSegmentedFilter
|
||||
counts={listCtrl.data.statusCounts}
|
||||
disabled={listCtrl.isLoading}
|
||||
onValueChange={listCtrl.setStatusFilter}
|
||||
value={listCtrl.statusFilter}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
|
||||
{listCtrl.data.totalItems === 0 ? <IssuedInvoicesEmptyGrid /> : null}
|
||||
</div>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
import { PageErrorState, SimpleSearchInput } from "@erp/core/components";
|
||||
import { useDataSource, useReturnToNavigation } from "@erp/core/hooks";
|
||||
import { type DataTableMeta, RdxPageContainer } from "@repo/rdx-ui/components";
|
||||
import {
|
||||
type DataTableMeta,
|
||||
RdxPageContainer,
|
||||
RdxPageContent,
|
||||
RdxPageFrame,
|
||||
} from "@repo/rdx-ui/components";
|
||||
import { showErrorToast, showSuccessToast } from "@repo/rdx-ui/helpers";
|
||||
import {
|
||||
Button,
|
||||
@ -458,30 +463,32 @@ const ScopedListProformasPage = ({ scope }: ScopedListProformasPageProps) => {
|
||||
|
||||
if (pageError) {
|
||||
return (
|
||||
<RdxPageContainer width="full">
|
||||
<div className="mx-auto w-full max-w-3xl">
|
||||
<PageErrorState
|
||||
description={pageError.description}
|
||||
primaryAction={
|
||||
pageError.canRetry
|
||||
? {
|
||||
label: isRetrying
|
||||
? t("pages.proformas.list.actions.retrying")
|
||||
: t("pages.proformas.list.actions.retry"),
|
||||
onClick: retryList,
|
||||
isLoading: isRetrying,
|
||||
}
|
||||
: {
|
||||
label: t("pages.proformas.list.actions.go_home"),
|
||||
onClick: goHome,
|
||||
}
|
||||
}
|
||||
reference={pageError.reference}
|
||||
title={pageError.title}
|
||||
variant={pageError.variant}
|
||||
/>
|
||||
</div>
|
||||
</RdxPageContainer>
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={pageError.description}
|
||||
primaryAction={
|
||||
pageError.canRetry
|
||||
? {
|
||||
label: isRetrying
|
||||
? t("pages.proformas.list.actions.retrying")
|
||||
: t("pages.proformas.list.actions.retry"),
|
||||
onClick: retryList,
|
||||
isLoading: isRetrying,
|
||||
}
|
||||
: {
|
||||
label: t("pages.proformas.list.actions.go_home"),
|
||||
onClick: goHome,
|
||||
}
|
||||
}
|
||||
reference={pageError.reference}
|
||||
title={pageError.title}
|
||||
variant={pageError.variant}
|
||||
/>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -46,9 +46,9 @@ export const ScopedListProformasPageView = ({
|
||||
|
||||
{content}
|
||||
</RdxPageContent>
|
||||
|
||||
{dialogs}
|
||||
</RdxPageContainer>
|
||||
|
||||
{dialogs}
|
||||
</RdxPageFrame>
|
||||
);
|
||||
};
|
||||
|
||||
@ -4,6 +4,8 @@ import {
|
||||
DataTableColumnHeader,
|
||||
RdxBadge,
|
||||
RdxPageContainer,
|
||||
RdxPageContent,
|
||||
RdxPageFrame,
|
||||
type RdxRowAction,
|
||||
RdxRowActions,
|
||||
SkeletonDataTable,
|
||||
@ -267,20 +269,22 @@ export const ListRecurringProformasPage = () => {
|
||||
|
||||
if (hasBlockingError && pageError) {
|
||||
return (
|
||||
<RdxPageContainer width="full">
|
||||
<div className="mx-auto w-full max-w-3xl">
|
||||
<PageErrorState
|
||||
description={pageError.description}
|
||||
primaryAction={{
|
||||
label: t("recurring_proformas.list.error.retry"),
|
||||
onClick: retryList,
|
||||
isLoading: isRetrying,
|
||||
}}
|
||||
title={pageError.title}
|
||||
variant="unknown"
|
||||
/>
|
||||
</div>
|
||||
</RdxPageContainer>
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={pageError.description}
|
||||
primaryAction={{
|
||||
label: t("recurring_proformas.list.error.retry"),
|
||||
onClick: retryList,
|
||||
isLoading: isRetrying,
|
||||
}}
|
||||
title={pageError.title}
|
||||
variant="unknown"
|
||||
/>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -46,9 +46,9 @@ export const ListCustomersPageView = ({
|
||||
|
||||
{content}
|
||||
</RdxPageContent>
|
||||
|
||||
{dialogs}
|
||||
</RdxPageContainer>
|
||||
|
||||
{dialogs}
|
||||
</RdxPageFrame>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { PageErrorState, SimpleSearchInput } from "@erp/core/components";
|
||||
import { useReturnToNavigation } from "@erp/core/hooks";
|
||||
import { RdxPageContainer, RdxPageFrame } from "@repo/rdx-ui/components";
|
||||
import { RdxPageContainer, RdxPageContent, RdxPageFrame } from "@repo/rdx-ui/components";
|
||||
import {
|
||||
Button,
|
||||
ResizableHandle,
|
||||
@ -93,24 +93,26 @@ export const ListCustomersPage = () => {
|
||||
return (
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<PageErrorState
|
||||
description={pageError.description}
|
||||
primaryAction={
|
||||
pageError.canRetry
|
||||
? {
|
||||
label: isRetrying ? t("list.actions.retrying") : t("list.actions.retry"),
|
||||
onClick: retryList,
|
||||
isLoading: isRetrying,
|
||||
}
|
||||
: {
|
||||
label: t("list.actions.go_home"),
|
||||
onClick: goHome,
|
||||
}
|
||||
}
|
||||
reference={pageError.reference}
|
||||
title={pageError.title}
|
||||
variant={pageError.variant}
|
||||
/>
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={pageError.description}
|
||||
primaryAction={
|
||||
pageError.canRetry
|
||||
? {
|
||||
label: isRetrying ? t("list.actions.retrying") : t("list.actions.retry"),
|
||||
onClick: retryList,
|
||||
isLoading: isRetrying,
|
||||
}
|
||||
: {
|
||||
label: t("list.actions.go_home"),
|
||||
onClick: goHome,
|
||||
}
|
||||
}
|
||||
reference={pageError.reference}
|
||||
title={pageError.title}
|
||||
variant={pageError.variant}
|
||||
/>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
|
||||
@ -39,17 +39,19 @@ export const SuppliersListPage = () => {
|
||||
return (
|
||||
<RdxPageFrame>
|
||||
<RdxPageContainer width="content">
|
||||
<PageErrorState
|
||||
description={t("list.error.description")}
|
||||
primaryAction={{
|
||||
label: t("common.actions.retry"),
|
||||
onClick: async () => {
|
||||
await controller.refetch();
|
||||
},
|
||||
}}
|
||||
title={t("list.error.title")}
|
||||
variant="unknown"
|
||||
/>
|
||||
<RdxPageContent>
|
||||
<PageErrorState
|
||||
description={t("list.error.description")}
|
||||
primaryAction={{
|
||||
label: t("common.actions.retry"),
|
||||
onClick: async () => {
|
||||
await controller.refetch();
|
||||
},
|
||||
}}
|
||||
title={t("list.error.title")}
|
||||
variant="unknown"
|
||||
/>
|
||||
</RdxPageContent>
|
||||
</RdxPageContainer>
|
||||
</RdxPageFrame>
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user