diff --git a/src/app/(main)/reports/retention/RetentionTable.js b/src/app/(main)/reports/retention/RetentionTable.js
index 4be7296f..a71fae6f 100644
--- a/src/app/(main)/reports/retention/RetentionTable.js
+++ b/src/app/(main)/reports/retention/RetentionTable.js
@@ -6,7 +6,9 @@ import { useMessages, useLocale } from 'components/hooks';
import { formatDate } from 'lib/date';
import styles from './RetentionTable.module.css';
-export function RetentionTable() {
+const DAYS = [1, 2, 3, 4, 5, 6, 7, 14, 21, 28];
+
+export function RetentionTable({ days = DAYS }) {
const { formatMessage, labels } = useMessages();
const { locale } = useLocale();
const { report } = useContext(ReportContext);
@@ -16,8 +18,6 @@ export function RetentionTable() {
return ;
}
- const days = [1, 2, 3, 4, 5, 6, 7, 14, 21, 28];
-
const rows = data.reduce((arr, row) => {
const { date, visitors, day } = row;
if (day === 0) {
diff --git a/src/app/(main)/settings/layout.tsx b/src/app/(main)/settings/layout.tsx
index e30b8108..42e9b62f 100644
--- a/src/app/(main)/settings/layout.tsx
+++ b/src/app/(main)/settings/layout.tsx
@@ -9,7 +9,7 @@ export default function SettingsLayout({ children }) {
const { user } = useUser();
const pathname = usePathname();
const { formatMessage, labels } = useMessages();
- const cloudMode = Boolean(process.env.cloudMode);
+ const cloudMode = !!process.env.cloudMode;
const items = [
{ key: 'websites', label: formatMessage(labels.websites), url: '/settings/websites' },
@@ -20,6 +20,10 @@ export default function SettingsLayout({ children }) {
const getKey = () => items.find(({ url }) => pathname === url)?.key;
+ if (cloudMode) {
+ return null;
+ }
+
return (
{!cloudMode && (
diff --git a/src/app/(main)/settings/profile/page.js b/src/app/(main)/settings/profile/page.tsx
similarity index 65%
rename from src/app/(main)/settings/profile/page.js
rename to src/app/(main)/settings/profile/page.tsx
index c1ea676b..d7a3ad92 100644
--- a/src/app/(main)/settings/profile/page.js
+++ b/src/app/(main)/settings/profile/page.tsx
@@ -1,5 +1,6 @@
import ProfileHeader from './ProfileHeader';
import ProfileSettings from './ProfileSettings';
+import { Metadata } from 'next';
export default function () {
return (
@@ -9,3 +10,7 @@ export default function () {
>
);
}
+
+export const metadata: Metadata = {
+ title: 'Profile Settings | umami',
+};
diff --git a/src/app/(main)/settings/teams/TeamJoinForm.js b/src/app/(main)/settings/teams/TeamJoinForm.js
index 23abcf00..498169d0 100644
--- a/src/app/(main)/settings/teams/TeamJoinForm.js
+++ b/src/app/(main)/settings/teams/TeamJoinForm.js
@@ -10,6 +10,7 @@ import {
} from 'react-basics';
import useApi from 'components/hooks/useApi';
import useMessages from 'components/hooks/useMessages';
+import { setValue } from 'store/cache';
export function TeamJoinForm({ onSave, onClose }) {
const { formatMessage, labels, getMessage } = useMessages();
@@ -20,8 +21,9 @@ export function TeamJoinForm({ onSave, onClose }) {
const handleSubmit = async data => {
mutate(data, {
onSuccess: async () => {
- onSave();
- onClose();
+ setValue('teams', Date.now());
+ onSave?.();
+ onClose?.();
},
});
};
diff --git a/src/app/(main)/settings/teams/TeamLeaveButton.js b/src/app/(main)/settings/teams/TeamLeaveButton.js
index 8cc85487..7b98f082 100644
--- a/src/app/(main)/settings/teams/TeamLeaveButton.js
+++ b/src/app/(main)/settings/teams/TeamLeaveButton.js
@@ -13,7 +13,7 @@ export function TeamLeaveButton({ teamId, teamName, onLeave }) {
diff --git a/src/app/(main)/settings/teams/TeamsDataTable.js b/src/app/(main)/settings/teams/TeamsDataTable.js
index 41287f48..49a2fb5b 100644
--- a/src/app/(main)/settings/teams/TeamsDataTable.js
+++ b/src/app/(main)/settings/teams/TeamsDataTable.js
@@ -3,10 +3,12 @@ import DataTable from 'components/common/DataTable';
import TeamsTable from 'app/(main)/settings/teams/TeamsTable';
import useApi from 'components/hooks/useApi';
import useFilterQuery from 'components/hooks/useFilterQuery';
+import useCache from 'store/cache';
export function TeamsDataTable() {
const { get } = useApi();
- const queryResult = useFilterQuery(['teams'], params => {
+ const modified = useCache(state => state?.websites);
+ const queryResult = useFilterQuery(['teams', { modified }], params => {
return get(`/teams`, {
...params,
});
diff --git a/src/app/(main)/settings/teams/TeamsTable.js b/src/app/(main)/settings/teams/TeamsTable.js
index 79ddf118..07199167 100644
--- a/src/app/(main)/settings/teams/TeamsTable.js
+++ b/src/app/(main)/settings/teams/TeamsTable.js
@@ -21,18 +21,18 @@ export function TeamsTable({ data = [] }) {
{row => {
const { id, name, teamUser } = row;
const owner = teamUser.find(({ role }) => role === ROLES.teamOwner);
- const showDelete = user.id === owner?.userId;
+ const isOwner = user.id === owner?.userId;
return (
<>
- {showDelete && }
- {!showDelete && }
+ {isOwner && }
+ {!isOwner && }
>
diff --git a/src/app/(main)/settings/teams/[id]/TeamWebsiteAddForm.js b/src/app/(main)/settings/teams/[id]/TeamWebsiteAddForm.js
index b2e22442..ba13fbd1 100644
--- a/src/app/(main)/settings/teams/[id]/TeamWebsiteAddForm.js
+++ b/src/app/(main)/settings/teams/[id]/TeamWebsiteAddForm.js
@@ -3,12 +3,13 @@ import { useState } from 'react';
import { Button, Form, FormButtons, GridColumn, Loading, SubmitButton, Toggle } from 'react-basics';
import useMessages from 'components/hooks/useMessages';
import WebsitesDataTable from '../../websites/WebsitesDataTable';
+import Empty from 'components/common/Empty';
export function TeamWebsiteAddForm({ teamId, onSave, onClose }) {
const { formatMessage, labels } = useMessages();
const { get, post, useQuery, useMutation } = useApi();
const { mutate, error } = useMutation(data => post(`/teams/${teamId}/websites`, data));
- const { data: websites } = useQuery(['websites'], () => get('/websites'));
+ const { data: websites, isLoading } = useQuery(['websites'], () => get('/websites'));
const [selected, setSelected] = useState([]);
const hasData = websites && websites.data.length > 0;
@@ -30,7 +31,8 @@ export function TeamWebsiteAddForm({ teamId, onSave, onClose }) {
return (
<>
- {!hasData && }
+ {isLoading && !hasData && }
+ {!isLoading && !hasData && }
{hasData && (