mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-14 21:10:34 +01:00
Refactor of team websites.
This commit is contained in:
parent
2552e1d495
commit
dc3818baaa
@ -63,7 +63,7 @@ export function Dashboard() {
|
|||||||
{editing && <DashboardEdit />}
|
{editing && <DashboardEdit />}
|
||||||
{!editing && (
|
{!editing && (
|
||||||
<>
|
<>
|
||||||
<WebsiteChartList websites={data} showCharts={showCharts} limit={pageSize} />
|
<WebsiteChartList websites={data as any} showCharts={showCharts} limit={pageSize} />
|
||||||
<Pager
|
<Pager
|
||||||
page={page}
|
page={page}
|
||||||
pageSize={pageSize}
|
pageSize={pageSize}
|
||||||
|
@ -19,7 +19,7 @@ export function DashboardEdit() {
|
|||||||
const { get, useQuery } = useApi();
|
const { get, useQuery } = useApi();
|
||||||
const { data: result } = useQuery({
|
const { data: result } = useQuery({
|
||||||
queryKey: ['websites'],
|
queryKey: ['websites'],
|
||||||
queryFn: () => get('/websites', { includeTeams: 1 }),
|
queryFn: () => get('/websites'),
|
||||||
});
|
});
|
||||||
const { data: websites } = result || {};
|
const { data: websites } = result || {};
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ export default function FieldFilterForm({
|
|||||||
format(values[0]);
|
format(values[0]);
|
||||||
}
|
}
|
||||||
return formatted;
|
return formatted;
|
||||||
}, [values]);
|
}, [formatValue, locale, name, values]);
|
||||||
|
|
||||||
const renderFilterValue = value => {
|
const renderFilterValue = value => {
|
||||||
return filters.find(f => f.value === value)?.label;
|
return filters.find(f => f.value === value)?.label;
|
||||||
@ -65,7 +65,7 @@ export default function FieldFilterForm({
|
|||||||
items={filters}
|
items={filters}
|
||||||
value={filter}
|
value={filter}
|
||||||
renderValue={renderFilterValue}
|
renderValue={renderFilterValue}
|
||||||
onSelect={(key: any) => setFilter(key)}
|
onChange={(key: any) => setFilter(key)}
|
||||||
>
|
>
|
||||||
{({ value, label }) => {
|
{({ value, label }) => {
|
||||||
return <Item key={value}>{label}</Item>;
|
return <Item key={value}>{label}</Item>;
|
||||||
@ -78,7 +78,7 @@ export default function FieldFilterForm({
|
|||||||
items={values}
|
items={values}
|
||||||
value={value}
|
value={value}
|
||||||
renderValue={renderValue}
|
renderValue={renderValue}
|
||||||
onSelect={(key: any) => setValue(key)}
|
onChange={(key: any) => setValue(key)}
|
||||||
style={{
|
style={{
|
||||||
minWidth: '250px',
|
minWidth: '250px',
|
||||||
}}
|
}}
|
||||||
|
@ -29,7 +29,7 @@ export function LanguageSetting() {
|
|||||||
items={options}
|
items={options}
|
||||||
value={locale}
|
value={locale}
|
||||||
renderValue={renderValue}
|
renderValue={renderValue}
|
||||||
onSelect={saveLocale}
|
onChange={saveLocale}
|
||||||
allowSearch={true}
|
allowSearch={true}
|
||||||
onSearch={setSearch}
|
onSearch={setSearch}
|
||||||
menuProps={{ className: styles.menu }}
|
menuProps={{ className: styles.menu }}
|
||||||
|
@ -21,7 +21,7 @@ export function TimezoneSetting() {
|
|||||||
<Dropdown
|
<Dropdown
|
||||||
items={options}
|
items={options}
|
||||||
value={timezone}
|
value={timezone}
|
||||||
onSelect={saveTimezone}
|
onChange={saveTimezone}
|
||||||
menuProps={{ className: styles.menu }}
|
menuProps={{ className: styles.menu }}
|
||||||
allowSearch={true}
|
allowSearch={true}
|
||||||
onSearch={setSearch}
|
onSearch={setSearch}
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
|
|
||||||
import useMessages from 'components/hooks/useMessages';
|
|
||||||
import TeamDeleteForm from './TeamDeleteForm';
|
|
||||||
|
|
||||||
export function TeamDeleteButton({
|
|
||||||
teamId,
|
|
||||||
teamName,
|
|
||||||
onDelete,
|
|
||||||
}: {
|
|
||||||
teamId: string;
|
|
||||||
teamName: string;
|
|
||||||
onDelete?: () => void;
|
|
||||||
}) {
|
|
||||||
const { formatMessage, labels } = useMessages();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ModalTrigger>
|
|
||||||
<Button>
|
|
||||||
<Icon>
|
|
||||||
<Icons.Trash />
|
|
||||||
</Icon>
|
|
||||||
<Text>{formatMessage(labels.delete)}</Text>
|
|
||||||
</Button>
|
|
||||||
<Modal title={formatMessage(labels.deleteTeam)}>
|
|
||||||
{(close: any) => (
|
|
||||||
<TeamDeleteForm teamId={teamId} teamName={teamName} onSave={onDelete} onClose={close} />
|
|
||||||
)}
|
|
||||||
</Modal>
|
|
||||||
</ModalTrigger>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TeamDeleteButton;
|
|
@ -4,7 +4,6 @@ import useUser from 'components/hooks/useUser';
|
|||||||
import { ROLES } from 'lib/constants';
|
import { ROLES } from 'lib/constants';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { Button, GridColumn, GridTable, Icon, Icons, Text, useBreakpoint } from 'react-basics';
|
import { Button, GridColumn, GridTable, Icon, Icons, Text, useBreakpoint } from 'react-basics';
|
||||||
import TeamDeleteButton from './TeamDeleteButton';
|
|
||||||
import TeamLeaveButton from './TeamLeaveButton';
|
import TeamLeaveButton from './TeamLeaveButton';
|
||||||
|
|
||||||
export function TeamsTable({ data = [] }: { data: any[] }) {
|
export function TeamsTable({ data = [] }: { data: any[] }) {
|
||||||
@ -26,13 +25,10 @@ export function TeamsTable({ data = [] }: { data: any[] }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isOwner && <TeamDeleteButton teamId={id} teamName={name} />}
|
|
||||||
{!isOwner && <TeamLeaveButton teamId={id} teamName={name} />}
|
{!isOwner && <TeamLeaveButton teamId={id} teamName={name} />}
|
||||||
<Link href={`/settings/teams/${id}`}>
|
<Link href={`/settings/teams/${id}`}>
|
||||||
<Button>
|
<Button>
|
||||||
<Icon>
|
<Icon>{isOwner ? <Icons.Edit /> : <Icons.ArrowRight />}</Icon>
|
||||||
<Icons.Edit />
|
|
||||||
</Icon>
|
|
||||||
<Text>{formatMessage(isOwner ? labels.edit : labels.view)}</Text>
|
<Text>{formatMessage(isOwner ? labels.edit : labels.view)}</Text>
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
27
src/app/(main)/settings/teams/[id]/TeamData.tsx
Normal file
27
src/app/(main)/settings/teams/[id]/TeamData.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { ActionForm, Button, Modal, ModalTrigger } from 'react-basics';
|
||||||
|
import useMessages from 'components/hooks/useMessages';
|
||||||
|
import TeamDeleteForm from '../TeamDeleteForm';
|
||||||
|
|
||||||
|
export function TeamData({ teamId }: { teamId: string; onSave?: (value: string) => void }) {
|
||||||
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
|
|
||||||
|
const handleSave = () => {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ActionForm
|
||||||
|
label={formatMessage(labels.deleteTeam)}
|
||||||
|
description={formatMessage(messages.deleteTeamWarning)}
|
||||||
|
>
|
||||||
|
<ModalTrigger>
|
||||||
|
<Button variant="danger">{formatMessage(labels.delete)}</Button>
|
||||||
|
<Modal title={formatMessage(labels.deleteTeam)}>
|
||||||
|
{(close: () => void) => (
|
||||||
|
<TeamDeleteForm teamId={teamId} teamName={''} onSave={handleSave} onClose={close} />
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
</ModalTrigger>
|
||||||
|
</ActionForm>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TeamData;
|
@ -9,6 +9,7 @@ import useMessages from 'components/hooks/useMessages';
|
|||||||
import TeamEditForm from './TeamEditForm';
|
import TeamEditForm from './TeamEditForm';
|
||||||
import TeamMembers from './TeamMembers';
|
import TeamMembers from './TeamMembers';
|
||||||
import TeamWebsites from './TeamWebsites';
|
import TeamWebsites from './TeamWebsites';
|
||||||
|
import TeamData from './TeamData';
|
||||||
|
|
||||||
export function TeamSettings({ teamId }: { teamId: string }) {
|
export function TeamSettings({ teamId }: { teamId: string }) {
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
@ -52,12 +53,14 @@ export function TeamSettings({ teamId }: { teamId: string }) {
|
|||||||
<Item key="details">{formatMessage(labels.details)}</Item>
|
<Item key="details">{formatMessage(labels.details)}</Item>
|
||||||
<Item key="members">{formatMessage(labels.members)}</Item>
|
<Item key="members">{formatMessage(labels.members)}</Item>
|
||||||
<Item key="websites">{formatMessage(labels.websites)}</Item>
|
<Item key="websites">{formatMessage(labels.websites)}</Item>
|
||||||
|
<Item key="data">{formatMessage(labels.data)}</Item>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
{tab === 'details' && (
|
{tab === 'details' && (
|
||||||
<TeamEditForm teamId={teamId} data={values} onSave={handleSave} readOnly={!canEdit} />
|
<TeamEditForm teamId={teamId} data={values} onSave={handleSave} readOnly={!canEdit} />
|
||||||
)}
|
)}
|
||||||
{tab === 'members' && <TeamMembers teamId={teamId} readOnly={!canEdit} />}
|
{tab === 'members' && <TeamMembers teamId={teamId} readOnly={!canEdit} />}
|
||||||
{tab === 'websites' && <TeamWebsites teamId={teamId} readOnly={!canEdit} />}
|
{tab === 'websites' && <TeamWebsites teamId={teamId} readOnly={!canEdit} />}
|
||||||
|
{canEdit && tab === 'data' && <TeamData teamId={teamId} />}
|
||||||
</Flexbox>
|
</Flexbox>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
import { ActionForm, Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
|
|
||||||
import TeamWebsitesTable from './TeamWebsitesTable';
|
import TeamWebsitesTable from './TeamWebsitesTable';
|
||||||
import TeamWebsiteAddForm from './TeamWebsiteAddForm';
|
|
||||||
import useApi from 'components/hooks/useApi';
|
import useApi from 'components/hooks/useApi';
|
||||||
import useMessages from 'components/hooks/useMessages';
|
|
||||||
import useUser from 'components/hooks/useUser';
|
import useUser from 'components/hooks/useUser';
|
||||||
import useFilterQuery from 'components/hooks/useFilterQuery';
|
import useFilterQuery from 'components/hooks/useFilterQuery';
|
||||||
import DataTable from 'components/common/DataTable';
|
import DataTable from 'components/common/DataTable';
|
||||||
import useCache from 'store/cache';
|
import useCache from 'store/cache';
|
||||||
|
|
||||||
export function TeamWebsites({ teamId, readOnly }: { teamId: string; readOnly: boolean }) {
|
export function TeamWebsites({ teamId, readOnly }: { teamId: string; readOnly: boolean }) {
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
const { get } = useApi();
|
const { get } = useApi();
|
||||||
const modified = useCache(state => state?.['team:websites']);
|
const modified = useCache(state => state?.['team:websites']);
|
||||||
@ -28,26 +24,9 @@ export function TeamWebsites({ teamId, readOnly }: { teamId: string; readOnly: b
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<DataTable queryResult={queryResult}>
|
||||||
<ActionForm description={formatMessage(messages.teamWebsitesInfo)}>
|
{({ data }) => <TeamWebsitesTable data={data} onRemove={handleChange} readOnly={readOnly} />}
|
||||||
<ModalTrigger>
|
</DataTable>
|
||||||
<Button variant="primary">
|
|
||||||
<Icon>
|
|
||||||
<Icons.Plus />
|
|
||||||
</Icon>
|
|
||||||
<Text>{formatMessage(labels.addWebsite)}</Text>
|
|
||||||
</Button>
|
|
||||||
<Modal title={formatMessage(labels.addWebsite)}>
|
|
||||||
{close => <TeamWebsiteAddForm teamId={teamId} onSave={handleChange} onClose={close} />}
|
|
||||||
</Modal>
|
|
||||||
</ModalTrigger>
|
|
||||||
</ActionForm>
|
|
||||||
<DataTable queryResult={queryResult}>
|
|
||||||
{({ data }) => (
|
|
||||||
<TeamWebsitesTable data={data} onRemove={handleChange} readOnly={readOnly} />
|
|
||||||
)}
|
|
||||||
</DataTable>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,9 +12,6 @@ export interface WebsitesDataTableProps {
|
|||||||
allowEdit?: boolean;
|
allowEdit?: boolean;
|
||||||
allowView?: boolean;
|
allowView?: boolean;
|
||||||
showActions?: boolean;
|
showActions?: boolean;
|
||||||
showTeam?: boolean;
|
|
||||||
includeTeams?: boolean;
|
|
||||||
onlyTeams?: boolean;
|
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,9 +20,6 @@ export function WebsitesDataTable({
|
|||||||
allowEdit = true,
|
allowEdit = true,
|
||||||
allowView = true,
|
allowView = true,
|
||||||
showActions = true,
|
showActions = true,
|
||||||
showTeam,
|
|
||||||
includeTeams,
|
|
||||||
onlyTeams,
|
|
||||||
children,
|
children,
|
||||||
}: WebsitesDataTableProps) {
|
}: WebsitesDataTableProps) {
|
||||||
const { get } = useApi();
|
const { get } = useApi();
|
||||||
@ -33,11 +27,9 @@ export function WebsitesDataTable({
|
|||||||
const { websitesUrl } = useContext(SettingsContext);
|
const { websitesUrl } = useContext(SettingsContext);
|
||||||
|
|
||||||
const queryResult = useFilterQuery({
|
const queryResult = useFilterQuery({
|
||||||
queryKey: ['websites', { includeTeams, onlyTeams, modified }],
|
queryKey: ['websites', { modified }],
|
||||||
queryFn: (params: any) => {
|
queryFn: (params: any) => {
|
||||||
return get(websitesUrl, {
|
return get(websitesUrl, {
|
||||||
includeTeams,
|
|
||||||
onlyTeams,
|
|
||||||
...params,
|
...params,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -49,7 +41,6 @@ export function WebsitesDataTable({
|
|||||||
{({ data }) => (
|
{({ data }) => (
|
||||||
<WebsitesTable
|
<WebsitesTable
|
||||||
data={data}
|
data={data}
|
||||||
showTeam={showTeam}
|
|
||||||
showActions={showActions}
|
showActions={showActions}
|
||||||
allowEdit={allowEdit}
|
allowEdit={allowEdit}
|
||||||
allowView={allowView}
|
allowView={allowView}
|
||||||
|
@ -7,7 +7,6 @@ import SettingsContext from '../SettingsContext';
|
|||||||
|
|
||||||
export interface WebsitesTableProps {
|
export interface WebsitesTableProps {
|
||||||
data: any[];
|
data: any[];
|
||||||
showTeam?: boolean;
|
|
||||||
showActions?: boolean;
|
showActions?: boolean;
|
||||||
allowEdit?: boolean;
|
allowEdit?: boolean;
|
||||||
allowView?: boolean;
|
allowView?: boolean;
|
||||||
@ -16,7 +15,6 @@ export interface WebsitesTableProps {
|
|||||||
|
|
||||||
export function WebsitesTable({
|
export function WebsitesTable({
|
||||||
data = [],
|
data = [],
|
||||||
showTeam,
|
|
||||||
showActions,
|
showActions,
|
||||||
allowEdit,
|
allowEdit,
|
||||||
allowView,
|
allowView,
|
||||||
@ -31,16 +29,6 @@ export function WebsitesTable({
|
|||||||
<GridTable data={data} cardMode={['xs', 'sm', 'md'].includes(breakpoint)}>
|
<GridTable data={data} cardMode={['xs', 'sm', 'md'].includes(breakpoint)}>
|
||||||
<GridColumn name="name" label={formatMessage(labels.name)} />
|
<GridColumn name="name" label={formatMessage(labels.name)} />
|
||||||
<GridColumn name="domain" label={formatMessage(labels.domain)} />
|
<GridColumn name="domain" label={formatMessage(labels.domain)} />
|
||||||
{showTeam && (
|
|
||||||
<GridColumn name="teamName" label={formatMessage(labels.teamName)}>
|
|
||||||
{row => row.teamWebsite[0]?.team.name}
|
|
||||||
</GridColumn>
|
|
||||||
)}
|
|
||||||
{showTeam && (
|
|
||||||
<GridColumn name="owner" label={formatMessage(labels.owner)}>
|
|
||||||
{row => row.user.username}
|
|
||||||
</GridColumn>
|
|
||||||
)}
|
|
||||||
{showActions && (
|
{showActions && (
|
||||||
<GridColumn name="action" label=" " alignment="end">
|
<GridColumn name="action" label=" " alignment="end">
|
||||||
{row => {
|
{row => {
|
||||||
@ -51,7 +39,7 @@ export function WebsitesTable({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{allowEdit && (!showTeam || ownerId === user.id) && (
|
{allowEdit && ownerId === user.id && (
|
||||||
<Link href={`${settingsPath}/${id}`}>
|
<Link href={`${settingsPath}/${id}`}>
|
||||||
<Button>
|
<Button>
|
||||||
<Icon>
|
<Icon>
|
||||||
|
@ -43,7 +43,7 @@ export function WebsiteDeleteForm({
|
|||||||
<Form onSubmit={handleSubmit} error={error}>
|
<Form onSubmit={handleSubmit} error={error}>
|
||||||
<p>
|
<p>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
{...messages.deleteWebsite}
|
{...messages.actionConfirmation}
|
||||||
values={{ confirmation: <b>{CONFIRM_VALUE}</b> }}
|
values={{ confirmation: <b>{CONFIRM_VALUE}</b> }}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
|
@ -43,7 +43,7 @@ export function WebsiteResetForm({
|
|||||||
<Form onSubmit={handleSubmit} error={error}>
|
<Form onSubmit={handleSubmit} error={error}>
|
||||||
<p>
|
<p>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
{...messages.resetWebsite}
|
{...messages.actionConfirmation}
|
||||||
values={{ confirmation: <b>{CONFIRM_VALUE}</b> }}
|
values={{ confirmation: <b>{CONFIRM_VALUE}</b> }}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
|
@ -1,37 +1,12 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import WebsitesDataTable from '../settings/websites/WebsitesDataTable';
|
import WebsitesDataTable from '../settings/websites/WebsitesDataTable';
|
||||||
import { useMessages, useUser } from 'components/hooks';
|
import { useUser } from 'components/hooks';
|
||||||
import { useState } from 'react';
|
|
||||||
import { Item, Tabs } from 'react-basics';
|
|
||||||
|
|
||||||
const TABS = {
|
|
||||||
myWebsites: 'my-websites',
|
|
||||||
teamWebsites: 'team-websites',
|
|
||||||
};
|
|
||||||
|
|
||||||
export function WebsitesBrowse() {
|
export function WebsitesBrowse() {
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
const { formatMessage, labels } = useMessages();
|
|
||||||
const [tab, setTab] = useState(TABS.myWebsites);
|
|
||||||
const allowEdit = !process.env.cloudMode;
|
const allowEdit = !process.env.cloudMode;
|
||||||
|
|
||||||
return (
|
return <WebsitesDataTable userId={user.id} allowEdit={allowEdit} />;
|
||||||
<>
|
|
||||||
<Tabs selectedKey={tab} onSelect={(tab: any) => setTab(tab)} style={{ marginBottom: 30 }}>
|
|
||||||
<Item key={TABS.myWebsites}>{formatMessage(labels.myWebsites)}</Item>
|
|
||||||
<Item key={TABS.teamWebsites}>{formatMessage(labels.teamWebsites)}</Item>
|
|
||||||
</Tabs>
|
|
||||||
{tab === TABS.myWebsites && <WebsitesDataTable userId={user.id} allowEdit={allowEdit} />}
|
|
||||||
{tab === TABS.teamWebsites && (
|
|
||||||
<WebsitesDataTable
|
|
||||||
userId={user.id}
|
|
||||||
showTeam={true}
|
|
||||||
onlyTeams={true}
|
|
||||||
allowEdit={allowEdit}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default WebsitesBrowse;
|
export default WebsitesBrowse;
|
||||||
|
@ -134,7 +134,7 @@ export default function WebsiteExpandedView({
|
|||||||
items={items}
|
items={items}
|
||||||
value={view}
|
value={view}
|
||||||
renderValue={renderValue}
|
renderValue={renderValue}
|
||||||
onSelect={handleChange}
|
onChange={handleChange}
|
||||||
alignment="end"
|
alignment="end"
|
||||||
>
|
>
|
||||||
{({ key, label }) => <Item key={key}>{label}</Item>}
|
{({ key, label }) => <Item key={key}>{label}</Item>}
|
||||||
|
@ -113,7 +113,7 @@ export function DateFilter({
|
|||||||
value={value}
|
value={value}
|
||||||
alignment={alignment}
|
alignment={alignment}
|
||||||
placeholder={formatMessage(labels.selectDate)}
|
placeholder={formatMessage(labels.selectDate)}
|
||||||
onSelect={key => handleChange(key as any)}
|
onChange={key => handleChange(key as any)}
|
||||||
>
|
>
|
||||||
{({ label, value, divider }) => (
|
{({ label, value, divider }) => (
|
||||||
<Item key={value} divider={divider}>
|
<Item key={value} divider={divider}>
|
||||||
|
@ -50,7 +50,7 @@ export function WebsiteSelect({
|
|||||||
value={selectedId as string}
|
value={selectedId as string}
|
||||||
renderValue={renderValue}
|
renderValue={renderValue}
|
||||||
renderEmpty={renderEmpty}
|
renderEmpty={renderEmpty}
|
||||||
onSelect={handleSelect}
|
onChange={handleSelect}
|
||||||
alignment="end"
|
alignment="end"
|
||||||
placeholder={formatMessage(labels.selectWebsite)}
|
placeholder={formatMessage(labels.selectWebsite)}
|
||||||
allowSearch={true}
|
allowSearch={true}
|
||||||
|
@ -238,13 +238,9 @@ export const messages = defineMessages({
|
|||||||
id: 'message.team-already-member',
|
id: 'message.team-already-member',
|
||||||
defaultMessage: 'You are already a member of the team.',
|
defaultMessage: 'You are already a member of the team.',
|
||||||
},
|
},
|
||||||
deleteAccount: {
|
actionConfirmation: {
|
||||||
id: 'message.delete-account',
|
id: 'message.action-confirmation',
|
||||||
defaultMessage: 'To delete this account, type {confirmation} in the box below to confirm.',
|
defaultMessage: 'Type {confirmation} in the box below to confirm.',
|
||||||
},
|
|
||||||
deleteWebsite: {
|
|
||||||
id: 'message.delete-website',
|
|
||||||
defaultMessage: 'To delete this website, type {confirmation} in the box below to confirm.',
|
|
||||||
},
|
},
|
||||||
resetWebsite: {
|
resetWebsite: {
|
||||||
id: 'message.reset-website',
|
id: 'message.reset-website',
|
||||||
@ -263,6 +259,10 @@ export const messages = defineMessages({
|
|||||||
id: 'message.delete-website-warning',
|
id: 'message.delete-website-warning',
|
||||||
defaultMessage: 'All website data will be deleted.',
|
defaultMessage: 'All website data will be deleted.',
|
||||||
},
|
},
|
||||||
|
deleteTeamWarning: {
|
||||||
|
id: 'message.delete-team-warning',
|
||||||
|
defaultMessage: 'Deleting a team will also delete all team websites.',
|
||||||
|
},
|
||||||
noResultsFound: {
|
noResultsFound: {
|
||||||
id: 'message.no-results-found',
|
id: 'message.no-results-found',
|
||||||
defaultMessage: 'No results found.',
|
defaultMessage: 'No results found.',
|
||||||
|
@ -41,7 +41,6 @@ export interface TeamSearchFilter extends SearchFilter {
|
|||||||
export interface ReportSearchFilter extends SearchFilter {
|
export interface ReportSearchFilter extends SearchFilter {
|
||||||
userId?: string;
|
userId?: string;
|
||||||
websiteId?: string;
|
websiteId?: string;
|
||||||
includeTeams?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SearchFilter {
|
export interface SearchFilter {
|
||||||
|
@ -29,7 +29,7 @@ export async function getReports(
|
|||||||
params: ReportSearchFilter,
|
params: ReportSearchFilter,
|
||||||
options?: { include?: Prisma.ReportInclude },
|
options?: { include?: Prisma.ReportInclude },
|
||||||
): Promise<FilterResult<Report[]>> {
|
): Promise<FilterResult<Report[]>> {
|
||||||
const { query, userId, websiteId, includeTeams } = params;
|
const { query, userId, websiteId } = params;
|
||||||
|
|
||||||
const mode = prisma.getQueryMode();
|
const mode = prisma.getQueryMode();
|
||||||
|
|
||||||
@ -42,23 +42,6 @@ export async function getReports(
|
|||||||
{
|
{
|
||||||
userId,
|
userId,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
...(includeTeams && {
|
|
||||||
website: {
|
|
||||||
teamWebsite: {
|
|
||||||
some: {
|
|
||||||
team: {
|
|
||||||
teamUser: {
|
|
||||||
some: {
|
|
||||||
userId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Prisma, Website } from '@prisma/client';
|
import { Prisma, Website } from '@prisma/client';
|
||||||
import cache from 'lib/cache';
|
import cache from 'lib/cache';
|
||||||
import { ROLES } from 'lib/constants';
|
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import { FilterResult, WebsiteSearchFilter } from 'lib/types';
|
import { FilterResult, WebsiteSearchFilter } from 'lib/types';
|
||||||
|
|
||||||
@ -22,49 +21,16 @@ export async function getWebsites(
|
|||||||
filters: WebsiteSearchFilter,
|
filters: WebsiteSearchFilter,
|
||||||
options?: { include?: Prisma.WebsiteInclude },
|
options?: { include?: Prisma.WebsiteInclude },
|
||||||
): Promise<FilterResult<Website[]>> {
|
): Promise<FilterResult<Website[]>> {
|
||||||
const { userId, teamId, includeTeams, onlyTeams, query } = filters;
|
const { userId, teamId, query } = filters;
|
||||||
const mode = prisma.getQueryMode();
|
const mode = prisma.getQueryMode();
|
||||||
|
|
||||||
const where: Prisma.WebsiteWhereInput = {
|
const where: Prisma.WebsiteWhereInput = {
|
||||||
...(teamId && {
|
|
||||||
teamWebsite: {
|
|
||||||
some: {
|
|
||||||
teamId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
AND: [
|
AND: [
|
||||||
{
|
{
|
||||||
OR: [
|
OR: [
|
||||||
{
|
{
|
||||||
...(userId &&
|
...(userId && { userId }),
|
||||||
!onlyTeams && {
|
...(teamId && { teamId }),
|
||||||
userId,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...((includeTeams || onlyTeams) && {
|
|
||||||
AND: [
|
|
||||||
{
|
|
||||||
teamWebsite: {
|
|
||||||
some: {
|
|
||||||
team: {
|
|
||||||
teamUser: {
|
|
||||||
some: {
|
|
||||||
userId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
userId: {
|
|
||||||
not: userId,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -110,15 +76,6 @@ export async function getWebsitesByUserId(
|
|||||||
{ userId, ...filters },
|
{ userId, ...filters },
|
||||||
{
|
{
|
||||||
include: {
|
include: {
|
||||||
teamWebsite: {
|
|
||||||
include: {
|
|
||||||
team: {
|
|
||||||
select: {
|
|
||||||
name: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
user: {
|
user: {
|
||||||
select: {
|
select: {
|
||||||
username: true,
|
username: true,
|
||||||
@ -138,21 +95,9 @@ export async function getWebsitesByTeamId(
|
|||||||
{
|
{
|
||||||
teamId,
|
teamId,
|
||||||
...filters,
|
...filters,
|
||||||
includeTeams: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
include: {
|
include: {
|
||||||
teamWebsite: {
|
|
||||||
include: {
|
|
||||||
team: {
|
|
||||||
include: {
|
|
||||||
teamUser: {
|
|
||||||
where: { role: ROLES.teamOwner },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
user: {
|
user: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user