Skip to content

Commit

Permalink
Merge branch 'openid_squashed' of https://github.com/lelemm/actual in…
Browse files Browse the repository at this point in the history
…to openid_squashed
  • Loading branch information
lelemm committed Dec 13, 2024
2 parents 2ed6f88 + 0ef78e9 commit e825acf
Show file tree
Hide file tree
Showing 23 changed files with 380 additions and 237 deletions.
6 changes: 3 additions & 3 deletions packages/desktop-client/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ function AppInner() {
addNotification({
type: 'error',
id: 'login-expired',
title: 'Login expired',
title: t('Login expired'),
sticky: true,
message: 'Login expired, please login again.',
message: t('Login expired, please login again.'),
button: {
title: 'Go to login',
title: t('Go to login'),
action: signOut,
},
});
Expand Down
4 changes: 3 additions & 1 deletion packages/desktop-client/src/components/LoggedInUser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,13 @@ export function LoggedInUser({

{!loading && multiuserEnabled && userData?.userName && (
<small>
(logged as:{' '}
<Trans>
(logged in as:{' '}
<span>
<PrivacyFilter>{userData?.displayName}</PrivacyFilter>
</span>
)
</Trans>
</small>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import React, {
useRef,
type CSSProperties,
} from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';

import { addNotification, pushModal } from 'loot-core/client/actions';
Expand Down Expand Up @@ -42,6 +43,8 @@ function UserAccessContent({
isModal,
setLoading,
}: ManageUserAccessContentProps) {
const { t } = useTranslation();

const [allAccess, setAllAccess] = useState([]);
const [page, setPage] = useState(0);
const [filter, setFilter] = useState('');
Expand Down Expand Up @@ -89,7 +92,7 @@ function UserAccessContent({
addNotification({
type: 'error',
id: 'error',
title: 'Error getting available users',
title: t('Error getting available users'),
sticky: true,
message: data.error,
});
Expand Down Expand Up @@ -168,19 +171,21 @@ function UserAccessContent({
}}
>
<Text>
Determine which users can view and manage your budgets..{' '}
<Link
variant="external"
to="https://actualbudget.org/docs/budgeting/users-access/"
linkColor="muted"
>
Learn more
</Link>
<Trans>
Determine which users can view and manage your budgets..{' '}
<Link
variant="external"
to="https://actualbudget.org/docs/budgeting/users-access/"
linkColor="muted"
>
Learn more
</Link>
</Trans>
</Text>
</View>
<View style={{ flex: 1 }} />
<Search
placeholder="Filter users..."
placeholder={t('Filter users...')}
value={filter}
onChange={onSearchChange}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from 'react';
import { useTranslation } from 'react-i18next';

import { Cell, TableHeader } from '../../table';

export function UserAccessHeader() {
const { t } = useTranslation();

return (
<TableHeader>
<Cell value="Access" width={100} style={{ paddingLeft: 15 }} />
<Cell value="User" width="flex" />
<Cell value="Owner" width={100} />
<Cell value={t('Access')} width={100} style={{ paddingLeft: 15 }} />
<Cell value={t('User')} width="flex" />
<Cell value={t('Owner')} width={100} />
</TableHeader>
);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from 'react';
import { useTranslation } from 'react-i18next';

import { Page } from '../../Page';

import { UserAccess } from './UserAccess';

export function UserAccessPage() {
const { t } = useTranslation();

return (
<Page
header="User Access"
header={t('User Access')}
style={{
borderRadius: '5px',
marginBottom: '25px',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @ts-strict-ignore
import React, { memo, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { send } from 'loot-core/platform/client/fetch';
import { getUserAccessErrors } from 'loot-core/shared/errors';
Expand All @@ -20,6 +21,8 @@ type UserAccessProps = {

export const UserAccessRow = memo(
({ access, hovered, onHover }: UserAccessProps) => {
const { t } = useTranslation();

const backgroundFocus = hovered;
const [marked, setMarked] = useState(
access.owner === 1 || access.haveAccess === 1,
Expand Down Expand Up @@ -47,8 +50,10 @@ export const UserAccessRow = memo(
if (someDeletionsFailed) {
actions.addNotification({
type: 'error',
title: 'Access Revocation Incomplete',
message: 'Some access permissions were not revoked successfully.',
title: t('Access Revocation Incomplete'),
message: t(
'Some access permissions were not revoked successfully.',
),
sticky: true,
});
}
Expand All @@ -61,11 +66,11 @@ export const UserAccessRow = memo(
actions.addNotification({
type: 'error',
id: 'login-expired',
title: 'Login expired',
title: t('Login expired'),
sticky: true,
message: getUserAccessErrors(error),
button: {
title: 'Go to login',
title: t('Go to login'),
action: () => {
actions.signOut();
},
Expand All @@ -74,7 +79,7 @@ export const UserAccessRow = memo(
} else {
actions.addNotification({
type: 'error',
title: 'Something happened while editing access',
title: t('Something happened while editing access'),
sticky: true,
message: getUserAccessErrors(error),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
type Dispatch,
type CSSProperties,
} from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';

import { pushModal } from 'loot-core/src/client/actions/modals';
Expand Down Expand Up @@ -37,37 +38,58 @@ type ManageUserDirectoryContentProps = {
setLoading?: Dispatch<SetStateAction<boolean>>;
};

function getUserDirectoryErrors(reason) {
switch (reason) {
case 'unauthorized':
return 'You are not logged in.';
case 'token-expired':
return 'Login expired, please login again.';
case 'user-cant-be-empty':
return 'Please enter a value for the username; the field cannot be empty.';
case 'role-cant-be-empty':
return 'Select a role; the field cannot be empty.';
case 'user-already-exists':
return 'The username you entered already exists. Please choose a different username.';
case 'not-all-deleted':
return 'Not all users were deleted. Check if one of the selected users is the server owner.';
case 'role-does-not-exists':
return 'Selected role does not exists, possibly a bug? Visit https://actualbudget.org/contact/ for support.';
default:
return `An internal error occurred, sorry! Visit https://actualbudget.org/contact/ for support. (ref: ${reason})`;
function useGetUserDirectoryErrors() {
const { t } = useTranslation();

function getUserDirectoryErrors(reason) {
switch (reason) {
case 'unauthorized':
return t('You are not logged in.');
case 'token-expired':
return t('Login expired, please login again.');
case 'user-cant-be-empty':
return t(
'Please enter a value for the username; the field cannot be empty.',
);
case 'role-cant-be-empty':
return t('Select a role; the field cannot be empty.');
case 'user-already-exists':
return t(
'The username you entered already exists. Please choose a different username.',
);
case 'not-all-deleted':
return t(
'Not all users were deleted. Check if one of the selected users is the server owner.',
);
case 'role-does-not-exists':
return t(
'Selected role does not exists, possibly a bug? Visit https://actualbudget.org/contact/ for support.',
);
default:
return t(
'An internal error occurred, sorry! Visit https://actualbudget.org/contact/ for support. (ref: {{reason}})',
{ reason },
);
}
}

return { getUserDirectoryErrors };
}

function UserDirectoryContent({
isModal,
setLoading,
}: ManageUserDirectoryContentProps) {
const { t } = useTranslation();

const [allUsers, setAllUsers] = useState([]);
const [page, setPage] = useState(0);
const [filter, setFilter] = useState('');
const dispatch = useDispatch();
const actions = useActions();

const { getUserDirectoryErrors } = useGetUserDirectoryErrors();

const filteredUsers = useMemo(() => {
return (
filter === ''
Expand Down Expand Up @@ -127,18 +149,18 @@ function UserDirectoryContent({
actions.addNotification({
type: 'error',
id: 'login-expired',
title: 'Login expired',
title: t('Login expired'),
sticky: true,
message: getUserDirectoryErrors(error),
button: {
title: 'Go to login',
title: t('Go to login'),
action: () => actions.signOut(),
},
});
} else {
actions.addNotification({
type: 'error',
title: 'Something happened while deleting users',
title: t('Something happened while deleting users'),
sticky: true,
message: getUserDirectoryErrors(error),
});
Expand Down Expand Up @@ -208,20 +230,22 @@ function UserDirectoryContent({
}}
>
<Text>
Manage and view users who can create new budgets or be invited to
access existing ones.{' '}
<Link
variant="external"
to="https://actualbudget.org/docs/budgeting/users/"
linkColor="muted"
>
Learn more
</Link>
<Trans>
Manage and view users who can create new budgets or be invited
to access existing ones.{' '}
<Link
variant="external"
to="https://actualbudget.org/docs/budgeting/users/"
linkColor="muted"
>
Learn more
</Link>
</Trans>
</Text>
</View>
<View style={{ flex: 1 }} />
<Search
placeholder="Filter users..."
placeholder={t('Filter users...')}
value={filter}
onChange={onSearchChange}
/>
Expand All @@ -235,7 +259,7 @@ function UserDirectoryContent({
style={{ marginBottom: -1 }}
>
{filteredUsers.length === 0 ? (
<EmptyMessage text="No users" style={{ marginTop: 15 }} />
<EmptyMessage text={t('No users')} style={{ marginTop: 15 }} />
) : (
<UsersList
users={filteredUsers}
Expand All @@ -258,11 +282,11 @@ function UserDirectoryContent({
<Stack direction="row" align="center" justify="flex-end" spacing={2}>
{selectedInst.items.size > 0 && (
<Button onPress={onDeleteSelected}>
Delete {selectedInst.items.size} users
<Trans> Delete {selectedInst.items.size} users </Trans>
</Button>
)}
<Button variant="primary" onPress={onAddUser}>
Add new user
<Trans>Add new user</Trans>
</Button>
</Stack>
</View>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import { useTranslation } from 'react-i18next';

import {
useSelectedItems,
Expand All @@ -7,6 +8,8 @@ import {
import { SelectCell, Cell, TableHeader } from '../../table';

export function UserDirectoryHeader() {
const { t } = useTranslation();

const selectedItems = useSelectedItems();
const dispatchSelected = useSelectedDispatch();

Expand All @@ -20,11 +23,11 @@ export function UserDirectoryHeader() {
dispatchSelected({ type: 'select-all', isRangeSelect: e.shiftKey })
}
/>
<Cell value="Username" width="flex" />
<Cell value="Display Name" width={250} />
<Cell value="Role" width={100} />
<Cell value="Enabled" width={100} />
<Cell value="Server Owner" width={100} />
<Cell value={t('Username')} width="flex" />
<Cell value={t('Display Name')} width={250} />
<Cell value={t('Role')} width={100} />
<Cell value={t('Enabled')} width={100} />
<Cell value={t('Server Owner')} width={100} />
<Cell value="" width={80} />
</TableHeader>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { type ReactNode } from 'react';
import { Trans, useTranslation } from 'react-i18next';

import { useNavigate } from '../../../hooks/useNavigate';
import { Button } from '../../common/Button2';
Expand All @@ -12,9 +13,11 @@ export function UserDirectoryPage({
}: {
bottomContent?: ReactNode;
}) {
const { t } = useTranslation();

return (
<Page
header="User Directory"
header={t('User Directory')}
style={{
borderRadius: '5px',
marginBottom: '25px',
Expand All @@ -40,7 +43,7 @@ export function BackToFileListButton() {

return (
<Button style={{ maxWidth: '200px' }} onPress={() => navigate('/')}>
Back to file list
<Trans>Back to file list</Trans>
</Button>
);
}
Loading

0 comments on commit e825acf

Please sign in to comment.