[WEB-3567] chore: empty state refactoring and translation fix (#8014)
* chore: empty state component improvement and code refactor * chore: translation code refactor * chore: empty state code refactor
This commit is contained in:
parent
be0d1871f0
commit
3faf768112
14 changed files with 121 additions and 116 deletions
|
|
@ -8,9 +8,9 @@ import useSWR from "swr";
|
||||||
import { EUserPermissions, EUserPermissionsLevel, WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
|
import { EUserPermissions, EUserPermissionsLevel, WORKSPACE_SETTINGS_TRACKER_ELEMENTS } from "@plane/constants";
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
// components
|
// components
|
||||||
|
import { EmptyStateCompact } from "@plane/propel/empty-state";
|
||||||
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
|
import { NotAuthorizedView } from "@/components/auth-screens/not-authorized-view";
|
||||||
import { PageHead } from "@/components/core/page-title";
|
import { PageHead } from "@/components/core/page-title";
|
||||||
import { DetailedEmptyState } from "@/components/empty-state/detailed-empty-state-root";
|
|
||||||
import { SettingsContentWrapper } from "@/components/settings/content-wrapper";
|
import { SettingsContentWrapper } from "@/components/settings/content-wrapper";
|
||||||
import { SettingsHeading } from "@/components/settings/heading";
|
import { SettingsHeading } from "@/components/settings/heading";
|
||||||
import { WebhookSettingsLoader } from "@/components/ui/loader/settings/web-hook";
|
import { WebhookSettingsLoader } from "@/components/ui/loader/settings/web-hook";
|
||||||
|
|
@ -20,7 +20,6 @@ import { captureClick } from "@/helpers/event-tracker.helper";
|
||||||
import { useWebhook } from "@/hooks/store/use-webhook";
|
import { useWebhook } from "@/hooks/store/use-webhook";
|
||||||
import { useWorkspace } from "@/hooks/store/use-workspace";
|
import { useWorkspace } from "@/hooks/store/use-workspace";
|
||||||
import { useUserPermissions } from "@/hooks/store/user";
|
import { useUserPermissions } from "@/hooks/store/user";
|
||||||
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
|
|
||||||
|
|
||||||
const WebhooksListPage = observer(() => {
|
const WebhooksListPage = observer(() => {
|
||||||
// states
|
// states
|
||||||
|
|
@ -35,7 +34,6 @@ const WebhooksListPage = observer(() => {
|
||||||
const { currentWorkspace } = useWorkspace();
|
const { currentWorkspace } = useWorkspace();
|
||||||
// derived values
|
// derived values
|
||||||
const canPerformWorkspaceAdminActions = allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.WORKSPACE);
|
const canPerformWorkspaceAdminActions = allowPermissions([EUserPermissions.ADMIN], EUserPermissionsLevel.WORKSPACE);
|
||||||
const resolvedPath = useResolvedAssetPath({ basePath: "/empty-state/workspace-settings/webhooks" });
|
|
||||||
|
|
||||||
useSWR(
|
useSWR(
|
||||||
workspaceSlug && canPerformWorkspaceAdminActions ? `WEBHOOKS_LIST_${workspaceSlug}` : null,
|
workspaceSlug && canPerformWorkspaceAdminActions ? `WEBHOOKS_LIST_${workspaceSlug}` : null,
|
||||||
|
|
@ -90,21 +88,23 @@ const WebhooksListPage = observer(() => {
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-full w-full flex-col">
|
<div className="flex h-full w-full flex-col">
|
||||||
<div className="h-full w-full flex items-center justify-center">
|
<div className="h-full w-full flex items-center justify-center">
|
||||||
<DetailedEmptyState
|
<EmptyStateCompact
|
||||||
className="!p-0"
|
assetKey="webhook"
|
||||||
title=""
|
title={t("settings.webhooks.title")}
|
||||||
description=""
|
description={t("settings.webhooks.description")}
|
||||||
assetPath={resolvedPath}
|
actions={[
|
||||||
size="md"
|
{
|
||||||
primaryButton={{
|
label: t("settings.webhooks.cta_primary"),
|
||||||
text: t("workspace_settings.settings.webhooks.add_webhook"),
|
onClick: () => {
|
||||||
onClick: () => {
|
captureClick({
|
||||||
captureClick({
|
elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.EMPTY_STATE_ADD_WEBHOOK_BUTTON,
|
||||||
elementName: WORKSPACE_SETTINGS_TRACKER_ELEMENTS.EMPTY_STATE_ADD_WEBHOOK_BUTTON,
|
});
|
||||||
});
|
setShowCreateWebhookModal(true);
|
||||||
setShowCreateWebhookModal(true);
|
},
|
||||||
},
|
},
|
||||||
}}
|
]}
|
||||||
|
align="start"
|
||||||
|
rootClassName="py-20"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,14 @@ import { useParams } from "next/navigation";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
|
import { EmptyStateDetailed } from "@plane/propel/empty-state";
|
||||||
import type { TCycleFilters } from "@plane/types";
|
import type { TCycleFilters } from "@plane/types";
|
||||||
import { calculateTotalFilters } from "@plane/utils";
|
import { calculateTotalFilters } from "@plane/utils";
|
||||||
// components
|
// components
|
||||||
import { DetailedEmptyState } from "@/components/empty-state/detailed-empty-state-root";
|
|
||||||
import { CycleModuleListLayoutLoader } from "@/components/ui/loader/cycle-module-list-loader";
|
import { CycleModuleListLayoutLoader } from "@/components/ui/loader/cycle-module-list-loader";
|
||||||
// hooks
|
// hooks
|
||||||
import { useCycle } from "@/hooks/store/use-cycle";
|
import { useCycle } from "@/hooks/store/use-cycle";
|
||||||
import { useCycleFilter } from "@/hooks/store/use-cycle-filter";
|
import { useCycleFilter } from "@/hooks/store/use-cycle-filter";
|
||||||
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
|
|
||||||
// local imports
|
// local imports
|
||||||
import { CycleAppliedFiltersList } from "../applied-filters";
|
import { CycleAppliedFiltersList } from "../applied-filters";
|
||||||
import { ArchivedCyclesView } from "./view";
|
import { ArchivedCyclesView } from "./view";
|
||||||
|
|
@ -28,7 +27,6 @@ export const ArchivedCycleLayoutRoot: React.FC = observer(() => {
|
||||||
const { clearAllFilters, currentProjectArchivedFilters, updateFilters } = useCycleFilter();
|
const { clearAllFilters, currentProjectArchivedFilters, updateFilters } = useCycleFilter();
|
||||||
// derived values
|
// derived values
|
||||||
const totalArchivedCycles = currentProjectArchivedCycleIds?.length ?? 0;
|
const totalArchivedCycles = currentProjectArchivedCycleIds?.length ?? 0;
|
||||||
const resolvedPath = useResolvedAssetPath({ basePath: "/empty-state/archived/empty-cycles" });
|
|
||||||
|
|
||||||
useSWR(
|
useSWR(
|
||||||
workspaceSlug && projectId ? `ARCHIVED_CYCLES_${workspaceSlug.toString()}_${projectId.toString()}` : null,
|
workspaceSlug && projectId ? `ARCHIVED_CYCLES_${workspaceSlug.toString()}_${projectId.toString()}` : null,
|
||||||
|
|
@ -69,10 +67,10 @@ export const ArchivedCycleLayoutRoot: React.FC = observer(() => {
|
||||||
)}
|
)}
|
||||||
{totalArchivedCycles === 0 ? (
|
{totalArchivedCycles === 0 ? (
|
||||||
<div className="h-full place-items-center">
|
<div className="h-full place-items-center">
|
||||||
<DetailedEmptyState
|
<EmptyStateDetailed
|
||||||
title={t("project_cycles.empty_state.archived.title")}
|
assetKey="archived-cycle"
|
||||||
description={t("project_cycles.empty_state.archived.description")}
|
title={t("workspace.archive_cycles.title")}
|
||||||
assetPath={resolvedPath}
|
description={t("workspace.archive_cycles.description")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,13 @@ import useSWR, { mutate } from "swr";
|
||||||
import { MoveLeft, MoveRight, RefreshCw } from "lucide-react";
|
import { MoveLeft, MoveRight, RefreshCw } from "lucide-react";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
|
import { EmptyStateCompact } from "@plane/propel/empty-state";
|
||||||
import type { IExportData } from "@plane/types";
|
import type { IExportData } from "@plane/types";
|
||||||
import { Table } from "@plane/ui";
|
import { Table } from "@plane/ui";
|
||||||
// components
|
// components
|
||||||
import { DetailedEmptyState } from "@/components/empty-state/detailed-empty-state-root";
|
|
||||||
import { ImportExportSettingsLoader } from "@/components/ui/loader/settings/import-and-export";
|
import { ImportExportSettingsLoader } from "@/components/ui/loader/settings/import-and-export";
|
||||||
// constants
|
// constants
|
||||||
import { EXPORT_SERVICES_LIST } from "@/constants/fetch-keys";
|
import { EXPORT_SERVICES_LIST } from "@/constants/fetch-keys";
|
||||||
// hooks
|
|
||||||
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
|
|
||||||
// services
|
// services
|
||||||
import { IntegrationService } from "@/services/integrations";
|
import { IntegrationService } from "@/services/integrations";
|
||||||
// local imports
|
// local imports
|
||||||
|
|
@ -35,7 +33,6 @@ export const PrevExports = observer((props: Props) => {
|
||||||
// hooks
|
// hooks
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const columns = useExportColumns();
|
const columns = useExportColumns();
|
||||||
const resolvedPath = useResolvedAssetPath({ basePath: "/empty-state/workspace-settings/exports" });
|
|
||||||
|
|
||||||
const { data: exporterServices } = useSWR(
|
const { data: exporterServices } = useSWR(
|
||||||
workspaceSlug && cursor ? EXPORT_SERVICES_LIST(workspaceSlug as string, cursor, `${per_page}`) : null,
|
workspaceSlug && cursor ? EXPORT_SERVICES_LIST(workspaceSlug as string, cursor, `${per_page}`) : null,
|
||||||
|
|
@ -125,12 +122,12 @@ export const PrevExports = observer((props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-full w-full items-center justify-center">
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
<DetailedEmptyState
|
<EmptyStateCompact
|
||||||
title={t("workspace_settings.empty_state.exports.title")}
|
assetKey="export"
|
||||||
description={t("workspace_settings.empty_state.exports.description")}
|
title={t("settings.exports.title")}
|
||||||
assetPath={resolvedPath}
|
description={t("settings.exports.description")}
|
||||||
className="w-full !px-0"
|
align="start"
|
||||||
size="sm"
|
rootClassName="py-20"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,7 @@ export const InboxSidebar: FC<IInboxSidebarProps> = observer((props) => {
|
||||||
title="No request closed yet"
|
title="No request closed yet"
|
||||||
description="All the work items whether accepted or declined can be found here."
|
description="All the work items whether accepted or declined can be found here."
|
||||||
assetClassName="size-20"
|
assetClassName="size-20"
|
||||||
|
className="px-10"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,12 @@ import { useParams } from "next/navigation";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { EUserPermissionsLevel } from "@plane/constants";
|
import { EUserPermissionsLevel } from "@plane/constants";
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
|
import { EmptyStateDetailed } from "@plane/propel/empty-state";
|
||||||
import { EIssuesStoreType, EUserProjectRoles } from "@plane/types";
|
import { EIssuesStoreType, EUserProjectRoles } from "@plane/types";
|
||||||
// components
|
|
||||||
import { DetailedEmptyState } from "@/components/empty-state/detailed-empty-state-root";
|
|
||||||
// hooks
|
// hooks
|
||||||
import { useIssues } from "@/hooks/store/use-issues";
|
|
||||||
import { useUserPermissions } from "@/hooks/store/user";
|
import { useUserPermissions } from "@/hooks/store/user";
|
||||||
import { useWorkItemFilterInstance } from "@/hooks/store/work-item-filters/use-work-item-filter-instance";
|
import { useWorkItemFilterInstance } from "@/hooks/store/work-item-filters/use-work-item-filter-instance";
|
||||||
import { useAppRouter } from "@/hooks/use-app-router";
|
import { useAppRouter } from "@/hooks/use-app-router";
|
||||||
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
|
|
||||||
|
|
||||||
export const ProjectArchivedEmptyState: React.FC = observer(() => {
|
export const ProjectArchivedEmptyState: React.FC = observer(() => {
|
||||||
// router
|
// router
|
||||||
|
|
@ -22,48 +19,45 @@ export const ProjectArchivedEmptyState: React.FC = observer(() => {
|
||||||
// plane hooks
|
// plane hooks
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
// store hooks
|
// store hooks
|
||||||
const { issuesFilter } = useIssues(EIssuesStoreType.ARCHIVED);
|
|
||||||
const { allowPermissions } = useUserPermissions();
|
const { allowPermissions } = useUserPermissions();
|
||||||
// derived values
|
// derived values
|
||||||
const archivedWorkItemFilter = projectId
|
const archivedWorkItemFilter = projectId
|
||||||
? useWorkItemFilterInstance(EIssuesStoreType.ARCHIVED, projectId)
|
? useWorkItemFilterInstance(EIssuesStoreType.ARCHIVED, projectId)
|
||||||
: undefined;
|
: undefined;
|
||||||
const activeLayout = issuesFilter?.issueFilters?.displayFilters?.layout;
|
|
||||||
const additionalPath = archivedWorkItemFilter?.hasActiveFilters ? (activeLayout ?? "list") : undefined;
|
|
||||||
const canPerformEmptyStateActions = allowPermissions(
|
const canPerformEmptyStateActions = allowPermissions(
|
||||||
[EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER],
|
[EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER],
|
||||||
EUserPermissionsLevel.PROJECT
|
EUserPermissionsLevel.PROJECT
|
||||||
);
|
);
|
||||||
const emptyFilterResolvedPath = useResolvedAssetPath({
|
|
||||||
basePath: "/empty-state/empty-filters/",
|
|
||||||
additionalPath: additionalPath,
|
|
||||||
});
|
|
||||||
const archivedIssuesResolvedPath = useResolvedAssetPath({
|
|
||||||
basePath: "/empty-state/archived/empty-issues",
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative h-full w-full overflow-y-auto">
|
<div className="relative h-full w-full overflow-y-auto">
|
||||||
{archivedWorkItemFilter?.hasActiveFilters ? (
|
{archivedWorkItemFilter?.hasActiveFilters ? (
|
||||||
<DetailedEmptyState
|
<EmptyStateDetailed
|
||||||
title={t("project_issues.empty_state.issues_empty_filter.title")}
|
assetKey="search"
|
||||||
assetPath={emptyFilterResolvedPath}
|
title={t("common.search.title")}
|
||||||
secondaryButton={{
|
description={t("common.search.description")}
|
||||||
text: t("project_issues.empty_state.issues_empty_filter.secondary_button.text"),
|
actions={[
|
||||||
onClick: archivedWorkItemFilter?.clearFilters,
|
{
|
||||||
disabled: !canPerformEmptyStateActions || !archivedWorkItemFilter,
|
label: t("common.search.cta_secondary"),
|
||||||
}}
|
onClick: archivedWorkItemFilter?.clearFilters,
|
||||||
|
disabled: !canPerformEmptyStateActions || !archivedWorkItemFilter,
|
||||||
|
variant: "outline-primary",
|
||||||
|
},
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<DetailedEmptyState
|
<EmptyStateDetailed
|
||||||
title={t("project_issues.empty_state.no_archived_issues.title")}
|
assetKey="archived-work-item"
|
||||||
description={t("project_issues.empty_state.no_archived_issues.description")}
|
title={t("workspace.archive_work_items.title")}
|
||||||
assetPath={archivedIssuesResolvedPath}
|
description={t("workspace.archive_work_items.description")}
|
||||||
primaryButton={{
|
actions={[
|
||||||
text: t("project_issues.empty_state.no_archived_issues.primary_button.text"),
|
{
|
||||||
onClick: () => router.push(`/${workspaceSlug}/settings/projects/${projectId}/automations`),
|
label: t("workspace.archive_work_items.cta_primary"),
|
||||||
disabled: !canPerformEmptyStateActions,
|
onClick: () => router.push(`/${workspaceSlug}/settings/projects/${projectId}/automations`),
|
||||||
}}
|
disabled: !canPerformEmptyStateActions,
|
||||||
|
variant: "primary",
|
||||||
|
},
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,16 @@ import { useParams } from "next/navigation";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
// plane imports
|
// plane imports
|
||||||
import { useTranslation } from "@plane/i18n";
|
import { useTranslation } from "@plane/i18n";
|
||||||
|
import { EmptyStateDetailed } from "@plane/propel/empty-state";
|
||||||
import type { TModuleFilters } from "@plane/types";
|
import type { TModuleFilters } from "@plane/types";
|
||||||
// components
|
// components
|
||||||
import { calculateTotalFilters } from "@plane/utils";
|
import { calculateTotalFilters } from "@plane/utils";
|
||||||
import { DetailedEmptyState } from "@/components/empty-state/detailed-empty-state-root";
|
|
||||||
import { ArchivedModulesView, ModuleAppliedFiltersList } from "@/components/modules";
|
import { ArchivedModulesView, ModuleAppliedFiltersList } from "@/components/modules";
|
||||||
import { CycleModuleListLayoutLoader } from "@/components/ui/loader/cycle-module-list-loader";
|
import { CycleModuleListLayoutLoader } from "@/components/ui/loader/cycle-module-list-loader";
|
||||||
// helpers
|
// helpers
|
||||||
// hooks
|
// hooks
|
||||||
import { useModule } from "@/hooks/store/use-module";
|
import { useModule } from "@/hooks/store/use-module";
|
||||||
import { useModuleFilter } from "@/hooks/store/use-module-filter";
|
import { useModuleFilter } from "@/hooks/store/use-module-filter";
|
||||||
import { useResolvedAssetPath } from "@/hooks/use-resolved-asset-path";
|
|
||||||
|
|
||||||
export const ArchivedModuleLayoutRoot: React.FC = observer(() => {
|
export const ArchivedModuleLayoutRoot: React.FC = observer(() => {
|
||||||
// router
|
// router
|
||||||
|
|
@ -26,7 +25,6 @@ export const ArchivedModuleLayoutRoot: React.FC = observer(() => {
|
||||||
const { clearAllFilters, currentProjectArchivedFilters, updateFilters } = useModuleFilter();
|
const { clearAllFilters, currentProjectArchivedFilters, updateFilters } = useModuleFilter();
|
||||||
// derived values
|
// derived values
|
||||||
const totalArchivedModules = projectArchivedModuleIds?.length ?? 0;
|
const totalArchivedModules = projectArchivedModuleIds?.length ?? 0;
|
||||||
const resolvedPath = useResolvedAssetPath({ basePath: "/empty-state/archived/empty-modules" });
|
|
||||||
|
|
||||||
useSWR(
|
useSWR(
|
||||||
workspaceSlug && projectId ? `ARCHIVED_MODULES_${workspaceSlug.toString()}_${projectId.toString()}` : null,
|
workspaceSlug && projectId ? `ARCHIVED_MODULES_${workspaceSlug.toString()}_${projectId.toString()}` : null,
|
||||||
|
|
@ -72,10 +70,10 @@ export const ArchivedModuleLayoutRoot: React.FC = observer(() => {
|
||||||
)}
|
)}
|
||||||
{totalArchivedModules === 0 ? (
|
{totalArchivedModules === 0 ? (
|
||||||
<div className="h-full place-items-center">
|
<div className="h-full place-items-center">
|
||||||
<DetailedEmptyState
|
<EmptyStateDetailed
|
||||||
title={t("project_module.empty_state.archived.title")}
|
assetKey="archived-module"
|
||||||
description={t("project_module.empty_state.archived.description")}
|
title={t("workspace.archive_modules.title")}
|
||||||
assetPath={resolvedPath}
|
description={t("workspace.archive_modules.description")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export enum ETranslationFiles {
|
||||||
TRANSLATIONS = "translations",
|
TRANSLATIONS = "translations",
|
||||||
ACCESSIBILITY = "accessibility",
|
ACCESSIBILITY = "accessibility",
|
||||||
EDITOR = "editor",
|
EDITOR = "editor",
|
||||||
EMPTY_STATE = "emptyState",
|
EMPTY_STATE = "empty-state",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LANGUAGE_STORAGE_KEY = "userLanguage";
|
export const LANGUAGE_STORAGE_KEY = "userLanguage";
|
||||||
|
|
|
||||||
|
|
@ -12,114 +12,114 @@ export const locales = {
|
||||||
translations: () => import("./en/translations"),
|
translations: () => import("./en/translations"),
|
||||||
accessibility: () => import("./en/accessibility"),
|
accessibility: () => import("./en/accessibility"),
|
||||||
editor: () => import("./en/editor"),
|
editor: () => import("./en/editor"),
|
||||||
emptyState: () => import("./en/empty-state"),
|
"empty-state": () => import("./en/empty-state"),
|
||||||
},
|
},
|
||||||
fr: {
|
fr: {
|
||||||
translations: () => import("./fr/translations"),
|
translations: () => import("./fr/translations"),
|
||||||
accessibility: () => import("./fr/accessibility"),
|
accessibility: () => import("./fr/accessibility"),
|
||||||
editor: () => import("./fr/editor"),
|
editor: () => import("./fr/editor"),
|
||||||
emptyState: () => import("./fr/empty-state"),
|
"empty-state": () => import("./fr/empty-state"),
|
||||||
},
|
},
|
||||||
es: {
|
es: {
|
||||||
translations: () => import("./es/translations"),
|
translations: () => import("./es/translations"),
|
||||||
accessibility: () => import("./es/accessibility"),
|
accessibility: () => import("./es/accessibility"),
|
||||||
editor: () => import("./es/editor"),
|
editor: () => import("./es/editor"),
|
||||||
emptyState: () => import("./es/empty-state"),
|
"empty-state": () => import("./es/empty-state"),
|
||||||
},
|
},
|
||||||
ja: {
|
ja: {
|
||||||
translations: () => import("./ja/translations"),
|
translations: () => import("./ja/translations"),
|
||||||
accessibility: () => import("./ja/accessibility"),
|
accessibility: () => import("./ja/accessibility"),
|
||||||
editor: () => import("./ja/editor"),
|
editor: () => import("./ja/editor"),
|
||||||
emptyState: () => import("./ja/empty-state"),
|
"empty-state": () => import("./ja/empty-state"),
|
||||||
},
|
},
|
||||||
"zh-CN": {
|
"zh-CN": {
|
||||||
translations: () => import("./zh-CN/translations"),
|
translations: () => import("./zh-CN/translations"),
|
||||||
accessibility: () => import("./zh-CN/accessibility"),
|
accessibility: () => import("./zh-CN/accessibility"),
|
||||||
editor: () => import("./zh-CN/editor"),
|
editor: () => import("./zh-CN/editor"),
|
||||||
emptyState: () => import("./zh-CN/empty-state"),
|
"empty-state": () => import("./zh-CN/empty-state"),
|
||||||
},
|
},
|
||||||
"zh-TW": {
|
"zh-TW": {
|
||||||
translations: () => import("./zh-TW/translations"),
|
translations: () => import("./zh-TW/translations"),
|
||||||
accessibility: () => import("./zh-TW/accessibility"),
|
accessibility: () => import("./zh-TW/accessibility"),
|
||||||
editor: () => import("./zh-TW/editor"),
|
editor: () => import("./zh-TW/editor"),
|
||||||
emptyState: () => import("./zh-TW/empty-state"),
|
"empty-state": () => import("./zh-TW/empty-state"),
|
||||||
},
|
},
|
||||||
ru: {
|
ru: {
|
||||||
translations: () => import("./ru/translations"),
|
translations: () => import("./ru/translations"),
|
||||||
accessibility: () => import("./ru/accessibility"),
|
accessibility: () => import("./ru/accessibility"),
|
||||||
editor: () => import("./ru/editor"),
|
editor: () => import("./ru/editor"),
|
||||||
emptyState: () => import("./ru/empty-state"),
|
"empty-state": () => import("./ru/empty-state"),
|
||||||
},
|
},
|
||||||
it: {
|
it: {
|
||||||
translations: () => import("./it/translations"),
|
translations: () => import("./it/translations"),
|
||||||
accessibility: () => import("./it/accessibility"),
|
accessibility: () => import("./it/accessibility"),
|
||||||
editor: () => import("./it/editor"),
|
editor: () => import("./it/editor"),
|
||||||
emptyState: () => import("./it/empty-state"),
|
"empty-state": () => import("./it/empty-state"),
|
||||||
},
|
},
|
||||||
cs: {
|
cs: {
|
||||||
translations: () => import("./cs/translations"),
|
translations: () => import("./cs/translations"),
|
||||||
accessibility: () => import("./cs/accessibility"),
|
accessibility: () => import("./cs/accessibility"),
|
||||||
editor: () => import("./cs/editor"),
|
editor: () => import("./cs/editor"),
|
||||||
emptyState: () => import("./cs/empty-state"),
|
"empty-state": () => import("./cs/empty-state"),
|
||||||
},
|
},
|
||||||
sk: {
|
sk: {
|
||||||
translations: () => import("./sk/translations"),
|
translations: () => import("./sk/translations"),
|
||||||
accessibility: () => import("./sk/accessibility"),
|
accessibility: () => import("./sk/accessibility"),
|
||||||
editor: () => import("./sk/editor"),
|
editor: () => import("./sk/editor"),
|
||||||
emptyState: () => import("./sk/empty-state"),
|
"empty-state": () => import("./sk/empty-state"),
|
||||||
},
|
},
|
||||||
de: {
|
de: {
|
||||||
translations: () => import("./de/translations"),
|
translations: () => import("./de/translations"),
|
||||||
accessibility: () => import("./de/accessibility"),
|
accessibility: () => import("./de/accessibility"),
|
||||||
editor: () => import("./de/editor"),
|
editor: () => import("./de/editor"),
|
||||||
emptyState: () => import("./de/empty-state"),
|
"empty-state": () => import("./de/empty-state"),
|
||||||
},
|
},
|
||||||
ua: {
|
ua: {
|
||||||
translations: () => import("./ua/translations"),
|
translations: () => import("./ua/translations"),
|
||||||
accessibility: () => import("./ua/accessibility"),
|
accessibility: () => import("./ua/accessibility"),
|
||||||
editor: () => import("./ua/editor"),
|
editor: () => import("./ua/editor"),
|
||||||
emptyState: () => import("./ua/empty-state"),
|
"empty-state": () => import("./ua/empty-state"),
|
||||||
},
|
},
|
||||||
pl: {
|
pl: {
|
||||||
translations: () => import("./pl/translations"),
|
translations: () => import("./pl/translations"),
|
||||||
accessibility: () => import("./pl/accessibility"),
|
accessibility: () => import("./pl/accessibility"),
|
||||||
editor: () => import("./pl/editor"),
|
editor: () => import("./pl/editor"),
|
||||||
emptyState: () => import("./pl/empty-state"),
|
"empty-state": () => import("./pl/empty-state"),
|
||||||
},
|
},
|
||||||
ko: {
|
ko: {
|
||||||
translations: () => import("./ko/translations"),
|
translations: () => import("./ko/translations"),
|
||||||
accessibility: () => import("./ko/accessibility"),
|
accessibility: () => import("./ko/accessibility"),
|
||||||
editor: () => import("./ko/editor"),
|
editor: () => import("./ko/editor"),
|
||||||
emptyState: () => import("./ko/empty-state"),
|
"empty-state": () => import("./ko/empty-state"),
|
||||||
},
|
},
|
||||||
"pt-BR": {
|
"pt-BR": {
|
||||||
translations: () => import("./pt-BR/translations"),
|
translations: () => import("./pt-BR/translations"),
|
||||||
accessibility: () => import("./pt-BR/accessibility"),
|
accessibility: () => import("./pt-BR/accessibility"),
|
||||||
editor: () => import("./pt-BR/editor"),
|
editor: () => import("./pt-BR/editor"),
|
||||||
emptyState: () => import("./pt-BR/empty-state"),
|
"empty-state": () => import("./pt-BR/empty-state"),
|
||||||
},
|
},
|
||||||
id: {
|
id: {
|
||||||
translations: () => import("./id/translations"),
|
translations: () => import("./id/translations"),
|
||||||
accessibility: () => import("./id/accessibility"),
|
accessibility: () => import("./id/accessibility"),
|
||||||
editor: () => import("./id/editor"),
|
editor: () => import("./id/editor"),
|
||||||
emptyState: () => import("./id/empty-state"),
|
"empty-state": () => import("./id/empty-state"),
|
||||||
},
|
},
|
||||||
ro: {
|
ro: {
|
||||||
translations: () => import("./ro/translations"),
|
translations: () => import("./ro/translations"),
|
||||||
accessibility: () => import("./ro/accessibility"),
|
accessibility: () => import("./ro/accessibility"),
|
||||||
editor: () => import("./ro/editor"),
|
editor: () => import("./ro/editor"),
|
||||||
emptyState: () => import("./ro/empty-state"),
|
"empty-state": () => import("./ro/empty-state"),
|
||||||
},
|
},
|
||||||
"vi-VN": {
|
"vi-VN": {
|
||||||
translations: () => import("./vi-VN/translations"),
|
translations: () => import("./vi-VN/translations"),
|
||||||
accessibility: () => import("./vi-VN/accessibility"),
|
accessibility: () => import("./vi-VN/accessibility"),
|
||||||
editor: () => import("./vi-VN/editor"),
|
editor: () => import("./vi-VN/editor"),
|
||||||
emptyState: () => import("./vi-VN/empty-state"),
|
"empty-state": () => import("./vi-VN/empty-state"),
|
||||||
},
|
},
|
||||||
"tr-TR": {
|
"tr-TR": {
|
||||||
translations: () => import("./tr-TR/translations"),
|
translations: () => import("./tr-TR/translations"),
|
||||||
accessibility: () => import("./tr-TR/accessibility"),
|
accessibility: () => import("./tr-TR/accessibility"),
|
||||||
editor: () => import("./tr-TR/editor"),
|
editor: () => import("./tr-TR/editor"),
|
||||||
emptyState: () => import("./tr-TR/empty-state"),
|
"empty-state": () => import("./tr-TR/empty-state"),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import {
|
||||||
DraftVerticalStackIllustration,
|
DraftVerticalStackIllustration,
|
||||||
EpicVerticalStackIllustration,
|
EpicVerticalStackIllustration,
|
||||||
Error404VerticalStackIllustration,
|
Error404VerticalStackIllustration,
|
||||||
|
InitiativeVerticalStackIllustration,
|
||||||
InvalidLinkVerticalStackIllustration,
|
InvalidLinkVerticalStackIllustration,
|
||||||
ModuleVerticalStackIllustration,
|
ModuleVerticalStackIllustration,
|
||||||
NoAccessVerticalStackIllustration,
|
NoAccessVerticalStackIllustration,
|
||||||
|
|
@ -85,6 +86,7 @@ export const VERTICAL_STACK_ASSETS: Record<VerticalStackAssetType, React.Compone
|
||||||
draft: DraftVerticalStackIllustration,
|
draft: DraftVerticalStackIllustration,
|
||||||
epic: EpicVerticalStackIllustration,
|
epic: EpicVerticalStackIllustration,
|
||||||
"error-404": Error404VerticalStackIllustration,
|
"error-404": Error404VerticalStackIllustration,
|
||||||
|
initiative: InitiativeVerticalStackIllustration,
|
||||||
"invalid-link": InvalidLinkVerticalStackIllustration,
|
"invalid-link": InvalidLinkVerticalStackIllustration,
|
||||||
module: ModuleVerticalStackIllustration,
|
module: ModuleVerticalStackIllustration,
|
||||||
"no-access": NoAccessVerticalStackIllustration,
|
"no-access": NoAccessVerticalStackIllustration,
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ export type VerticalStackAssetType =
|
||||||
| "draft"
|
| "draft"
|
||||||
| "epic"
|
| "epic"
|
||||||
| "error-404"
|
| "error-404"
|
||||||
|
| "initiative"
|
||||||
| "invalid-link"
|
| "invalid-link"
|
||||||
| "module"
|
| "module"
|
||||||
| "no-access"
|
| "no-access"
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
DraftVerticalStackIllustration,
|
DraftVerticalStackIllustration,
|
||||||
EpicVerticalStackIllustration,
|
EpicVerticalStackIllustration,
|
||||||
Error404VerticalStackIllustration,
|
Error404VerticalStackIllustration,
|
||||||
|
InitiativeVerticalStackIllustration,
|
||||||
InvalidLinkVerticalStackIllustration,
|
InvalidLinkVerticalStackIllustration,
|
||||||
ModuleVerticalStackIllustration,
|
ModuleVerticalStackIllustration,
|
||||||
NoAccessVerticalStackIllustration,
|
NoAccessVerticalStackIllustration,
|
||||||
|
|
@ -56,6 +57,10 @@ export const VerticalStackAssetsMap = [
|
||||||
asset: <Error404VerticalStackIllustration />,
|
asset: <Error404VerticalStackIllustration />,
|
||||||
title: "Error404VerticalStackIllustration",
|
title: "Error404VerticalStackIllustration",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
asset: <InitiativeVerticalStackIllustration />,
|
||||||
|
title: "InitiativeVerticalStackIllustration",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
asset: <InvalidLinkVerticalStackIllustration />,
|
asset: <InvalidLinkVerticalStackIllustration />,
|
||||||
title: "InvalidLinkVerticalStackIllustration",
|
title: "InvalidLinkVerticalStackIllustration",
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ export const EmptyStateCompact: React.FC<BaseEmptyStateCommonProps> = ({
|
||||||
rootClassName,
|
rootClassName,
|
||||||
assetClassName,
|
assetClassName,
|
||||||
align = "center",
|
align = "center",
|
||||||
|
customButton,
|
||||||
}) => {
|
}) => {
|
||||||
// Determine which asset to use: assetKey takes precedence, fallback to custom asset
|
// Determine which asset to use: assetKey takes precedence, fallback to custom asset
|
||||||
const resolvedAsset = assetKey ? getCompactAsset(assetKey as CompactAssetType, assetClassName) : asset;
|
const resolvedAsset = assetKey ? getCompactAsset(assetKey as CompactAssetType, assetClassName) : asset;
|
||||||
|
|
@ -39,18 +40,21 @@ export const EmptyStateCompact: React.FC<BaseEmptyStateCommonProps> = ({
|
||||||
title && <p className="text-sm leading-5 text-custom-text-300">{title}</p>
|
title && <p className="text-sm leading-5 text-custom-text-300">{title}</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{actions && actions.length > 0 && (
|
{customButton
|
||||||
<div className="flex flex-col gap-4 sm:flex-row">
|
? customButton
|
||||||
{actions.map((action, index) => {
|
: actions &&
|
||||||
const { label, variant, ...rest } = action;
|
actions.length > 0 && (
|
||||||
return (
|
<div className="flex flex-col gap-4 sm:flex-row">
|
||||||
<Button key={index} variant={variant} {...rest}>
|
{actions.map((action, index) => {
|
||||||
{label}
|
const { label, variant, ...rest } = action;
|
||||||
</Button>
|
return (
|
||||||
);
|
<Button key={index} variant={variant} {...rest}>
|
||||||
})}
|
{label}
|
||||||
</div>
|
</Button>
|
||||||
)}
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ export const EmptyStateDetailed: React.FC<BaseEmptyStateCommonProps> = ({
|
||||||
className,
|
className,
|
||||||
rootClassName,
|
rootClassName,
|
||||||
assetClassName,
|
assetClassName,
|
||||||
|
customButton,
|
||||||
}) => {
|
}) => {
|
||||||
// Determine which asset to use: assetKey takes precedence, fallback to custom asset
|
// Determine which asset to use: assetKey takes precedence, fallback to custom asset
|
||||||
const resolvedAsset = assetKey ? getDetailedAsset(assetKey as DetailedAssetType, assetClassName) : asset;
|
const resolvedAsset = assetKey ? getDetailedAsset(assetKey as DetailedAssetType, assetClassName) : asset;
|
||||||
|
|
@ -31,18 +32,21 @@ export const EmptyStateDetailed: React.FC<BaseEmptyStateCommonProps> = ({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{actions && actions.length > 0 && (
|
{customButton
|
||||||
<div className="flex flex-col gap-4 sm:flex-row">
|
? customButton
|
||||||
{actions.map((action, index) => {
|
: actions &&
|
||||||
const { label, variant, ...rest } = action;
|
actions.length > 0 && (
|
||||||
return (
|
<div className="flex flex-col gap-4 sm:flex-row">
|
||||||
<Button key={index} variant={variant} {...rest}>
|
{actions.map((action, index) => {
|
||||||
{label}
|
const { label, variant, ...rest } = action;
|
||||||
</Button>
|
return (
|
||||||
);
|
<Button key={index} variant={variant} {...rest}>
|
||||||
})}
|
{label}
|
||||||
</div>
|
</Button>
|
||||||
)}
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,5 @@ export interface BaseEmptyStateCommonProps {
|
||||||
assetKey?: CompactAssetType | DetailedAssetType;
|
assetKey?: CompactAssetType | DetailedAssetType;
|
||||||
asset?: React.ReactNode;
|
asset?: React.ReactNode;
|
||||||
align?: TAlign;
|
align?: TAlign;
|
||||||
|
customButton?: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue