Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"dependencies": {
"@axa-ch/react-polymorphic-types": "^1.4.1",
"@floating-ui/react": "^0.27.16",
"@inlang/paraglide-js": "^2.7.2",
"@inlang/paraglide-js": "^2.8.0",
"@react-hook/resize-observer": "^2.0.2",
"@shortercode/webzip": "1.1.1-0",
"@stablelib/base64": "^2.0.1",
Expand All @@ -24,8 +24,8 @@
"@tanstack/react-form": "^1.27.7",
"@tanstack/react-query": "^5.90.16",
"@tanstack/react-query-devtools": "^5.91.2",
"@tanstack/react-router": "^1.146.2",
"@tanstack/react-router-devtools": "^1.146.2",
"@tanstack/react-router": "^1.147.3",
"@tanstack/react-router-devtools": "^1.149.0",
"@tanstack/react-table": "^8.21.3",
"@tanstack/react-virtual": "^3.13.18",
"@uidotdev/usehooks": "^2.4.1",
Expand All @@ -50,19 +50,19 @@
"rxjs": "^7.8.2",
"text-case": "^1.2.9",
"zod": "^4.3.5",
"zustand": "^5.0.9"
"zustand": "^5.0.10"
},
"devDependencies": {
"@biomejs/biome": "2.3.11",
"@inlang/paraglide-js": "2.7.2",
"@tanstack/devtools-vite": "^0.4.1",
"@tanstack/router-plugin": "^1.146.3",
"@tanstack/router-plugin": "^1.149.0",
"@types/byte-size": "^8.1.2",
"@types/humanize-duration": "^3.27.4",
"@types/lodash-es": "^4.17.12",
"@types/node": "^25.0.3",
"@types/node": "^25.0.6",
"@types/qs": "^6.14.0",
"@types/react": "^19.2.7",
"@types/react": "^19.2.8",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react-swc": "^4.2.2",
"autoprefixer": "^10.4.23",
Expand Down
353 changes: 174 additions & 179 deletions web/pnpm-lock.yaml

Large diffs are not rendered by default.

20 changes: 19 additions & 1 deletion web/project.inlang/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,19 @@
cache
# IF GIT SHOWED THAT THIS FILE CHANGED
#
# 1. RUN THE FOLLOWING COMMAND
#
# ---
# git rm --cached '**/*.inlang/.gitignore'
# ---
#
# 2. COMMIT THE CHANGE
#
# ---
# git commit -m "fix: remove tracked .gitignore from inlang project"
# ---
#
# Inlang handles the gitignore itself starting with version ^2.5.
#
# everything is ignored except settings.json
*
!settings.json
27 changes: 15 additions & 12 deletions web/src/pages/ActivityLogPage/ActivityLogPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Page } from '../../shared/components/Page/Page';
import { SizedBox } from '../../shared/defguard-ui/components/SizedBox/SizedBox';
import { ThemeSpacing } from '../../shared/defguard-ui/types';
import { isPresent } from '../../shared/defguard-ui/utils/isPresent';
import { TablePageLayout } from '../../shared/layout/TablePageLayout/TablePageLayout';
import { ActivityLogTable } from './ActivityLogTable';

export const ActivityLogPage = () => {
Expand Down Expand Up @@ -36,18 +37,20 @@ export const ActivityLogPage = () => {
return (
<Page id="activity-log-page" title={`Activity log`}>
<SizedBox height={ThemeSpacing.Xl3} />
{isPresent(flatData) && isPresent(pagination) && (
<ActivityLogTable
data={flatData}
pagination={pagination}
filters={{}}
loadingNextPage={isFetchingNextPage}
onNextPage={() => {
fetchNextPage();
}}
hasNextPage={pagination.next_page !== null}
/>
)}
<TablePageLayout>
{isPresent(flatData) && isPresent(pagination) && (
<ActivityLogTable
data={flatData}
pagination={pagination}
filters={{}}
loadingNextPage={isFetchingNextPage}
onNextPage={() => {
fetchNextPage();
}}
hasNextPage={pagination.next_page !== null}
/>
)}
</TablePageLayout>
</Page>
);
};
5 changes: 4 additions & 1 deletion web/src/pages/GroupsPage/GroupsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useSuspenseQuery } from '@tanstack/react-query';
import { Page } from '../../shared/components/Page/Page';
import { SizedBox } from '../../shared/defguard-ui/components/SizedBox/SizedBox';
import { ThemeSpacing } from '../../shared/defguard-ui/types';
import { TablePageLayout } from '../../shared/layout/TablePageLayout/TablePageLayout';
import { getGroupsInfoQueryOptions, getUsersQueryOptions } from '../../shared/query';
import { GroupsTable } from './components/GroupsTable/GroupsTable';
import { CEGroupModal } from './modals/CEGroupModal/CEGroupModal';
Expand All @@ -13,7 +14,9 @@ export const GroupsPage = () => {
<>
<Page id="groups-page" title="Groups">
<SizedBox height={ThemeSpacing.Xl3} />
<GroupsTable groups={groups} users={users} />
<TablePageLayout>
<GroupsTable groups={groups} users={users} />
</TablePageLayout>
</Page>
<CEGroupModal />
</>
Expand Down
5 changes: 4 additions & 1 deletion web/src/pages/NetworkDevicesPage/NetworkDevicesPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useSuspenseQuery } from '@tanstack/react-query';
import { Page } from '../../shared/components/Page/Page';
import { TablePageLayout } from '../../shared/layout/TablePageLayout/TablePageLayout';
import { getNetworkDevicesQueryOptions } from '../../shared/query';
import { AddNetworkDeviceModal } from './modals/AddNetworkDeviceModal/AddNetworkDeviceModal';
import { EditNetworkDeviceModal } from './modals/EditNetworkDeviceModal/EditNetworkDeviceModal';
Expand All @@ -13,7 +14,9 @@ export const NetworkDevicesPage = () => {
return (
<>
<Page id="network-devices-page" title="Network Devices">
<NetworkDevicesTable networkDevices={networkDevices} />
<TablePageLayout>
<NetworkDevicesTable networkDevices={networkDevices} />
</TablePageLayout>
</Page>
<AddNetworkDeviceModal />
<NetworkDeviceConfigModal />
Expand Down
15 changes: 9 additions & 6 deletions web/src/pages/RulesPage/RulesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Tabs } from '../../shared/defguard-ui/components/Tabs/Tabs';
import type { TabsItem } from '../../shared/defguard-ui/components/Tabs/types';
import { ThemeSpacing } from '../../shared/defguard-ui/types';
import { isPresent } from '../../shared/defguard-ui/utils/isPresent';
import { TablePageLayout } from '../../shared/layout/TablePageLayout/TablePageLayout';
import { getRulesQueryOptions } from '../../shared/query';
import { RulesDeployedTab } from './tabs/RulesDeployedTab';
import { RulesPendingTab } from './tabs/RulesPendingTab';
Expand Down Expand Up @@ -53,12 +54,14 @@ export const RulesPage = () => {
<Page title="Rules" id="rules-page">
<SizedBox height={ThemeSpacing.Md} />
<Tabs items={tabs} />
{activeTab === RulesPageTab.Deployed && isPresent(deployed) && (
<RulesDeployedTab rules={deployed} />
)}
{activeTab === RulesPageTab.Pending && isPresent(pending) && (
<RulesPendingTab rules={pending} />
)}
<TablePageLayout>
{activeTab === RulesPageTab.Deployed && isPresent(deployed) && (
<RulesDeployedTab rules={deployed} />
)}
{activeTab === RulesPageTab.Pending && isPresent(pending) && (
<RulesPendingTab rules={pending} />
)}
</TablePageLayout>
</Page>
);
};
6 changes: 4 additions & 2 deletions web/src/pages/UsersOverviewPage/UsersOverviewPage.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useQuery } from '@tanstack/react-query';
import { LayoutGrid } from '../../shared/components/LayoutGrid/LayoutGrid';
import { Page } from '../../shared/components/Page/Page';
import './style.scss';
import { m } from '../../paraglide/messages';
import { AddAuthKeyModal } from '../../shared/components/modals/AddAuthKeyModal/AddAuthKeyModal';
import { ChangePasswordModal } from '../../shared/components/modals/ChangePasswordModal/ChangePasswordModal';
import { isPresent } from '../../shared/defguard-ui/utils/isPresent';
import { TablePageLayout } from '../../shared/layout/TablePageLayout/TablePageLayout';
import { getUsersQueryOptions } from '../../shared/query';
import { AddUserModal } from './modals/AddUserModal/AddUserModal';
import { AssignUsersToGroupsModal } from './modals/AssignUsersToGroupsModal/AssignUsersToGroupsModal';
Expand All @@ -17,7 +17,9 @@ export const UsersOverviewPage = () => {
return (
<>
<Page title={m.users_title()} id="users-overview-page">
<LayoutGrid>{isPresent(users) && <UsersTable users={users} />}</LayoutGrid>
<TablePageLayout>
{isPresent(users) && <UsersTable users={users} />}
</TablePageLayout>
</Page>
<AddUserModal />
<EditUserModal />
Expand Down
56 changes: 28 additions & 28 deletions web/src/pages/UsersOverviewPage/UsersTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import { TableValuesListCell } from '../../shared/components/TableValuesListCell
import { Avatar } from '../../shared/defguard-ui/components/Avatar/Avatar';
import { Badge } from '../../shared/defguard-ui/components/Badge/Badge';
import { Button } from '../../shared/defguard-ui/components/Button/Button';
import type { ButtonProps } from '../../shared/defguard-ui/components/Button/types';
import { EmptyState } from '../../shared/defguard-ui/components/EmptyState/EmptyState';
import { EmptyStateFlexible } from '../../shared/defguard-ui/components/EmptyStateFlexible/EmptyStateFlexible';
import { Icon } from '../../shared/defguard-ui/components/Icon';
import { IconButtonMenu } from '../../shared/defguard-ui/components/IconButtonMenu/IconButtonMenu';
import { Search } from '../../shared/defguard-ui/components/Search/Search';
Expand Down Expand Up @@ -52,6 +54,22 @@ export const UsersTable = ({ users }: Props) => {
const reservedEmails = useMemo(() => users.map((u) => u.email.toLowerCase()), [users]);
const reservedUsernames = useMemo(() => users.map((u) => u.username), [users]);

const addButtonProps = useMemo(
(): ButtonProps => ({
variant: 'primary',
text: 'Add new user',
iconLeft: 'add-user',
testId: 'add-user',
onClick: () => {
useAddUserModal.getState().open({
reservedEmails,
reservedUsernames,
});
},
}),
[reservedEmails, reservedUsernames],
);

const [search, setSearch] = useState('');
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);

Expand Down Expand Up @@ -429,6 +447,15 @@ export const UsersTable = ({ users }: Props) => {
getRowCanExpand: (row) => row.original.devices.length > 0,
});

if (users.length === 0)
return (
<EmptyStateFlexible
title={`No users here yet.`}
subtitle={`Add users by clicking the button below.`}
primaryAction={addButtonProps}
/>
);

return (
<>
<TableTop text={m.users_header_title()}>
Expand All @@ -455,17 +482,7 @@ export const UsersTable = ({ users }: Props) => {
initialValue={search}
onChange={setSearch}
/>
<Button
iconLeft="add-user"
text={m.users_add()}
testId="add-user"
onClick={() => {
useAddUserModal.getState().open({
reservedEmails,
reservedUsernames,
});
}}
/>
<Button {...addButtonProps} />
</TableTop>
{transformedData.length === 0 && search.length > 0 && (
<EmptyState
Expand All @@ -474,23 +491,6 @@ export const UsersTable = ({ users }: Props) => {
subtitle={m.search_empty_common_subtitle()}
/>
)}
{transformedData.length === 0 && search.length === 0 && (
<EmptyState
icon="search"
title={m.users_empty_title()}
subtitle={m.users_empty_subtitle()}
primaryAction={{
text: m.users_add(),
iconLeft: 'add-user',
onClick: () => {
useAddUserModal.getState().open({
reservedEmails,
reservedUsernames,
});
},
}}
/>
)}
{transformedData.length > 0 && (
<TableBody
table={table}
Expand Down
5 changes: 0 additions & 5 deletions web/src/pages/UsersOverviewPage/style.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
#users-overview-page {
.table,
.table-top {
grid-column: 1 / 13;
}

.page-content {
padding-top: var(--spacing-3xl);
box-sizing: border-box;
Expand Down
5 changes: 4 additions & 1 deletion web/src/pages/WebhooksPage/WebhooksPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useSuspenseQuery } from '@tanstack/react-query';
import { Page } from '../../shared/components/Page/Page';
import { SizedBox } from '../../shared/defguard-ui/components/SizedBox/SizedBox';
import { ThemeSpacing } from '../../shared/defguard-ui/types';
import { TablePageLayout } from '../../shared/layout/TablePageLayout/TablePageLayout';
import { getWebhooksQueryOptions } from '../../shared/query';
import { CeWebhookModal } from './modals/CEWebhookModal/CEWebhookModal';
import { WebhooksTable } from './WebhooksTable';
Expand All @@ -13,7 +14,9 @@ export const WebhooksPage = () => {
<>
<Page id="webhooks-page" title="Webhooks">
<SizedBox height={ThemeSpacing.Xl3} />
<WebhooksTable webhooks={webhooks} />
<TablePageLayout>
<WebhooksTable webhooks={webhooks} />
</TablePageLayout>
</Page>
<CeWebhookModal />
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ const ModalContent = () => {
<AppText font={TextStyle.TBodySm400} color={ThemeVariable.FgMuted}>
{`Check if your SMTP configuration works by sending a test email.`}
</AppText>
<SizedBox height={ThemeSpacing.Xl2} />
<form
onSubmit={(e) => {
e.stopPropagation();
Expand Down
5 changes: 5 additions & 0 deletions web/src/shared/hooks/modalControls/modalsSubjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type PayloadOf<N extends ModalNameValue> =
}
? D
: undefined;

export function openModal<N extends ModalNameValue>(
name: N,
...args: PayloadOf<N> extends undefined ? [] : [PayloadOf<N>]
Expand All @@ -44,5 +45,9 @@ export function openModal<N extends ModalNameValue>(
args.length === 0 ? { name } : { name, data: args[0] }
) as ModalOpenEvent;

// blur whatever right now has focus
const activeElement = document.activeElement as HTMLElement | null;
activeElement?.blur();

openModalSubject.next(event);
}
7 changes: 7 additions & 0 deletions web/src/shared/layout/TablePageLayout/TablePageLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import './style.scss';
import type { PropsWithChildren } from 'react';
import { LayoutGrid } from '../../components/LayoutGrid/LayoutGrid';

export const TablePageLayout = ({ children }: PropsWithChildren) => {
return <LayoutGrid className="table-page-layout">{children}</LayoutGrid>;
};
7 changes: 7 additions & 0 deletions web/src/shared/layout/TablePageLayout/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.table-page-layout {
.flexible-empty-state,
.table-top,
.table {
grid-column: 1 / 13;
}
}
Loading