Merge pull request #1387 from umami-software/dev

v1.37.0
This commit is contained in:
Mike Cao 2022-08-09 17:13:39 -05:00 committed by GitHub
commit 2f24a8775e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
163 changed files with 3619 additions and 2728 deletions

View File

@ -12,15 +12,11 @@ WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules COPY --from=deps /app/node_modules ./node_modules
COPY . . COPY . .
ARG DATABASE_URL
ARG DATABASE_TYPE ARG DATABASE_TYPE
ARG BASE_PATH ARG BASE_PATH
ARG DISABLE_LOGIN
ENV DATABASE_URL $DATABASE_URL
ENV DATABASE_TYPE $DATABASE_TYPE ENV DATABASE_TYPE $DATABASE_TYPE
ENV BASE_PATH $BASE_PATH ENV BASE_PATH $BASE_PATH
ENV DISABLE_LOGIN $DISABLE_LOGIN
ENV NEXT_TELEMETRY_DISABLED 1 ENV NEXT_TELEMETRY_DISABLED 1
@ -36,12 +32,11 @@ ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs RUN adduser --system --uid 1001 nextjs
RUN yarn global add prisma RUN yarn add npm-run-all dotenv prisma
RUN yarn add npm-run-all dotenv
# You only need to copy next.config.js if you are NOT using the default configuration # You only need to copy next.config.js if you are NOT using the default configuration
COPY --from=builder /app/next.config.js . COPY --from=builder /app/next.config.js .
COPY --from=builder /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder /app/package.json ./package.json COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/prisma ./prisma COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/scripts ./scripts COPY --from=builder /app/scripts ./scripts

View File

@ -1 +0,0 @@
web: npm run start-env

View File

@ -30,7 +30,7 @@ export default function UpdateNotice() {
if (!checked) { if (!checked) {
checkVersion(); checkVersion();
} }
}, []); }, [checked]);
if (!hasUpdate || dismissed) { if (!hasUpdate || dismissed) {
return null; return null;

View File

@ -4,10 +4,12 @@ import { useRouter } from 'next/router';
import Button from 'components/common/Button'; import Button from 'components/common/Button';
import FormLayout, { FormButtons, FormRow } from 'components/layout/FormLayout'; import FormLayout, { FormButtons, FormRow } from 'components/layout/FormLayout';
import CopyButton from 'components/common/CopyButton'; import CopyButton from 'components/common/CopyButton';
import useConfig from 'hooks/useConfig';
export default function TrackingCodeForm({ values, onClose }) { export default function TrackingCodeForm({ values, onClose }) {
const ref = useRef(); const ref = useRef();
const { basePath } = useRouter(); const { basePath } = useRouter();
const { trackerScriptName } = useConfig();
return ( return (
<FormLayout> <FormLayout>
@ -24,7 +26,9 @@ export default function TrackingCodeForm({ values, onClose }) {
rows={3} rows={3}
cols={60} cols={60}
spellCheck={false} spellCheck={false}
defaultValue={`<script async defer data-website-id="${values.website_uuid}" src="${document.location.origin}${basePath}/umami.js"></script>`} defaultValue={`<script async defer data-website-id="${values.website_uuid}" src="${
document.location.origin
}${basePath}/${trackerScriptName ? `${trackerScriptName}.js` : 'umami.js'}"></script>`}
readOnly readOnly
/> />
</FormRow> </FormRow>

View File

@ -1,13 +1,13 @@
import React from 'react'; import { useRouter } from 'next/router';
import Script from 'next/script';
import classNames from 'classnames'; import classNames from 'classnames';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import Link from 'components/common/Link'; import Link from 'components/common/Link';
import styles from './Footer.module.css'; import styles from './Footer.module.css';
import useStore from 'store/version'; import { CURRENT_VERSION, HOMEPAGE_URL, REPO_URL } from 'lib/constants';
import { HOMEPAGE_URL, REPO_URL } from 'lib/constants';
export default function Footer() { export default function Footer() {
const { current } = useStore(); const { pathname } = useRouter();
return ( return (
<footer className={classNames(styles.footer, 'row')}> <footer className={classNames(styles.footer, 'row')}>
@ -26,11 +26,9 @@ export default function Footer() {
/> />
</div> </div>
<div className={classNames(styles.version, 'col-12 col-md-4')}> <div className={classNames(styles.version, 'col-12 col-md-4')}>
<Link href={REPO_URL}>{`v${current}`}</Link> <Link href={REPO_URL}>{`v${CURRENT_VERSION}`}</Link>
</div> </div>
{!process.env.telemetryDisabled && ( {!pathname.includes('/share/') && <Script src={`/telemetry.js`} />}
<img src={`https://i.umami.is/a.png?v=${current}`} alt="" />
)}
</footer> </footer>
); );
} }

View File

@ -8,22 +8,26 @@ import ThemeButton from 'components/settings/ThemeButton';
import HamburgerButton from 'components/common/HamburgerButton'; import HamburgerButton from 'components/common/HamburgerButton';
import UpdateNotice from 'components/common/UpdateNotice'; import UpdateNotice from 'components/common/UpdateNotice';
import UserButton from 'components/settings/UserButton'; import UserButton from 'components/settings/UserButton';
import { HOMEPAGE_URL } from 'lib/constants';
import useConfig from '/hooks/useConfig';
import useUser from 'hooks/useUser';
import Logo from 'assets/logo.svg'; import Logo from 'assets/logo.svg';
import styles from './Header.module.css'; import styles from './Header.module.css';
import useUser from 'hooks/useUser';
import { HOMEPAGE_URL } from 'lib/constants';
export default function Header() { export default function Header() {
const { user } = useUser(); const { user } = useUser();
const { pathname } = useRouter(); const { pathname } = useRouter();
const { updatesDisabled } = useConfig();
const isSharePage = pathname.includes('/share/');
const allowUpdate = user?.is_admin && !updatesDisabled && !isSharePage;
return ( return (
<> <>
{user?.is_admin && !process.env.updatesDisabled && <UpdateNotice />} {allowUpdate && <UpdateNotice />}
<header className={classNames(styles.header, 'row')}> <header className={classNames(styles.header, 'row')}>
<div className={styles.title}> <div className={styles.title}>
<Icon icon={<Logo />} size="large" className={styles.logo} /> <Icon icon={<Logo />} size="large" className={styles.logo} />
<Link href={pathname.includes('/share') ? HOMEPAGE_URL : '/'}>umami</Link> <Link href={isSharePage ? HOMEPAGE_URL : '/'}>umami</Link>
</div> </div>
<HamburgerButton /> <HamburgerButton />
{user && ( {user && (

View File

@ -12,7 +12,7 @@ export default function EventsChart({ websiteId, className, token }) {
const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId); const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId);
const [timezone] = useTimezone(); const [timezone] = useTimezone();
const { const {
query: { url, eventType }, query: { url, eventName },
} = usePageQuery(); } = usePageQuery();
const { data, loading } = useFetch( const { data, loading } = useFetch(
@ -24,11 +24,11 @@ export default function EventsChart({ websiteId, className, token }) {
unit, unit,
tz: timezone, tz: timezone,
url, url,
event_type: eventType, event_name: eventName,
token, token,
}, },
}, },
[modified, eventType], [modified, eventName],
); );
const datasets = useMemo(() => { const datasets = useMemo(() => {

View File

@ -1,62 +1,26 @@
import React, { useState } from 'react'; import { defineMessages, useIntl } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import MetricsTable from './MetricsTable'; import MetricsTable from './MetricsTable';
import Tag from 'components/common/Tag';
import DropDown from 'components/common/DropDown';
import { eventTypeFilter } from 'lib/filters';
import usePageQuery from 'hooks/usePageQuery';
import styles from './EventsTable.module.css';
const EVENT_FILTER_DEFAULT = { const messages = defineMessages({
value: 'all', events: { id: 'metrics.events', defaultMessage: 'Events' },
label: <FormattedMessage id="label.all-events" defaultMessage="All events" />, actions: { id: 'metrics.actions', defaultMessage: 'Actions' },
}; });
export default function EventsTable({ websiteId, ...props }) { export default function EventsTable({ websiteId, ...props }) {
const [eventType, setEventType] = useState(EVENT_FILTER_DEFAULT.value); const { formatMessage } = useIntl();
const [eventTypes, setEventTypes] = useState([]);
const { resolve, router } = usePageQuery();
const dropDownOptions = [EVENT_FILTER_DEFAULT, ...eventTypes.map(t => ({ value: t, label: t }))];
function handleDataLoad(data) { function handleDataLoad(data) {
setEventTypes([...new Set(data.map(({ x }) => x.split('\t')[0]))]);
props.onDataLoad?.(data); props.onDataLoad?.(data);
} }
function handleChange(value) {
router.replace(resolve({ eventType: value === 'all' ? undefined : value }));
setEventType(value);
}
return ( return (
<> <MetricsTable
{eventTypes?.length > 1 && ( {...props}
<div className={styles.filter}> title={formatMessage(messages.events)}
<DropDown value={eventType} options={dropDownOptions} onChange={handleChange} /> type="event"
</div> metric={formatMessage(messages.actions)}
)} websiteId={websiteId}
<MetricsTable onDataLoad={handleDataLoad}
{...props} />
title={<FormattedMessage id="metrics.events" defaultMessage="Events" />}
type="event"
metric={<FormattedMessage id="metrics.actions" defaultMessage="Actions" />}
websiteId={websiteId}
dataFilter={eventTypeFilter}
filterOptions={eventType === EVENT_FILTER_DEFAULT.value ? [] : [eventType]}
renderLabel={({ x }) => <Label value={x} />}
onDataLoad={handleDataLoad}
/>
</>
); );
} }
const Label = ({ value }) => {
const [event, label] = value.split('\t');
return (
<>
<Tag>{event}</Tag>
{label}
</>
);
};

View File

@ -1,6 +0,0 @@
.filter {
display: flex;
justify-content: flex-start;
align-items: center;
margin-bottom: 15px;
}

View File

@ -54,9 +54,12 @@ export default function MetricsTable({
const filteredData = useMemo(() => { const filteredData = useMemo(() => {
if (data) { if (data) {
const items = percentFilter(dataFilter ? dataFilter(data, filterOptions) : data); let items = percentFilter(dataFilter ? dataFilter(data, filterOptions) : data);
if (limit) { if (limit) {
return items.filter((e, i) => i < limit).sort(firstBy('y', -1).thenBy('x')); items = items.filter((e, i) => i < limit);
}
if (filterOptions?.sort === false) {
return items;
} }
return items.sort(firstBy('y', -1).thenBy('x')); return items.sort(firstBy('y', -1).thenBy('x'));
} }

View File

@ -0,0 +1,56 @@
import { useState } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import MetricsTable from './MetricsTable';
import Tag from 'components/common/Tag';
import { paramFilter } from 'lib/filters';
import { safeDecodeURI } from 'lib/url';
import FilterButtons from '../common/FilterButtons';
const FILTER_COMBINED = 0;
const FILTER_RAW = 1;
const messages = defineMessages({
combined: { id: 'metrics.filter.combined', defaultMessage: 'Combined' },
raw: { id: 'metrics.filter.raw', defaultMessage: 'Raw' },
views: { id: 'metrics.views', defaultMessage: 'Views' },
none: { id: 'label.none', defaultMessage: 'None' },
query: { id: 'metrics.query-parameters', defaultMessage: 'Query parameters' },
});
export default function QueryParametersTable({ websiteId, showFilters, ...props }) {
const [filter, setFilter] = useState(FILTER_COMBINED);
const { formatMessage } = useIntl();
const buttons = [
{
label: formatMessage(messages.combined),
value: FILTER_COMBINED,
},
{ label: formatMessage(messages.raw), value: FILTER_RAW },
];
return (
<>
{showFilters && <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />}
<MetricsTable
{...props}
title={formatMessage(messages.query)}
type="query"
metric={formatMessage(messages.views)}
websiteId={websiteId}
dataFilter={filter !== FILTER_RAW ? paramFilter : null}
renderLabel={({ x, p, v }) =>
filter === FILTER_RAW ? (
x
) : (
<>
<Tag>{safeDecodeURI(p)}</Tag>
{safeDecodeURI(v)}
</>
)
}
delay={0}
/>
</>
);
}

View File

@ -3,7 +3,6 @@ import { FormattedMessage, useIntl } from 'react-intl';
import { FixedSizeList } from 'react-window'; import { FixedSizeList } from 'react-window';
import firstBy from 'thenby'; import firstBy from 'thenby';
import Icon from 'components/common/Icon'; import Icon from 'components/common/Icon';
import Tag from 'components/common/Tag';
import Dot from 'components/common/Dot'; import Dot from 'components/common/Dot';
import FilterButtons from 'components/common/FilterButtons'; import FilterButtons from 'components/common/FilterButtons';
import NoData from 'components/common/NoData'; import NoData from 'components/common/NoData';
@ -92,8 +91,7 @@ export default function RealtimeLog({ data, websites, websiteId }) {
} }
function getDetail({ function getDetail({
event_type, event_name,
event_value,
view_id, view_id,
session_id, session_id,
url, url,
@ -103,12 +101,8 @@ export default function RealtimeLog({ data, websites, websiteId }) {
device, device,
website_id, website_id,
}) { }) {
if (event_type) { if (event_name) {
return ( return <div>{event_name}</div>;
<div>
<Tag>{event_type}</Tag> {event_value}
</div>
);
} }
if (view_id) { if (view_id) {
const domain = getWebsite({ website_id })?.domain; const domain = getWebsite({ website_id })?.domain;

View File

@ -5,8 +5,8 @@ import FilterButtons from 'components/common/FilterButtons';
import FilterLink from 'components/common/FilterLink'; import FilterLink from 'components/common/FilterLink';
import { refFilter } from 'lib/filters'; import { refFilter } from 'lib/filters';
export const FILTER_COMBINED = 0; const FILTER_COMBINED = 0;
export const FILTER_RAW = 1; const FILTER_RAW = 1;
const messages = defineMessages({ const messages = defineMessages({
combined: { id: 'metrics.filter.combined', defaultMessage: 'Combined' }, combined: { id: 'metrics.filter.combined', defaultMessage: 'Combined' },

View File

@ -6,7 +6,7 @@ export default function ScreenTable({ websiteId, ...props }) {
return ( return (
<MetricsTable <MetricsTable
{...props} {...props}
title={<FormattedMessage id="metrics.screens" defaultMessage="Screen" />} title={<FormattedMessage id="metrics.screens" defaultMessage="Screens" />}
type="screen" type="screen"
metric={<FormattedMessage id="metrics.visitors" defaultMessage="Visitors" />} metric={<FormattedMessage id="metrics.visitors" defaultMessage="Visitors" />}
websiteId={websiteId} websiteId={websiteId}

View File

@ -1,47 +0,0 @@
import React, { useState } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import MetricsTable from './MetricsTable';
import FilterButtons from 'components/common/FilterButtons';
export const UTM_SOURCE = 'utm_source';
export const UTM_MEDIUM = 'utm_medium';
export const UTM_CAMPAIGN = 'utm_campaign';
export const UTM_CONTENT = 'utm_content';
export const UTM_TERM = 'utm_term';
const messages = defineMessages({
utm_source: { id: 'metrics.utm_source', defaultMessage: 'UTM Source' },
utm_medium: { id: 'metrics.utm_medium', defaultMessage: 'UTM Medium' },
utm_campaign: { id: 'metrics.utm_campaign', defaultMessage: 'UTM Campaign' },
utm_content: { id: 'metrics.utm_content', defaultMessage: 'UTM Content' },
utm_term: { id: 'metrics.utm_term', defaultMessage: 'UTM Term' },
views: { id: 'metrics.views', defaultMessage: 'Views' },
none: { id: 'label.none', defaultMessage: 'None' },
});
export default function UTMTable({ websiteId, showFilters, ...props }) {
const [type, setType] = useState(UTM_SOURCE);
const { formatMessage } = useIntl();
const buttons = [
{ label: formatMessage(messages.utm_source), value: UTM_SOURCE },
{ label: formatMessage(messages.utm_medium), value: UTM_MEDIUM },
{ label: formatMessage(messages.utm_campaign), value: UTM_CAMPAIGN },
{ label: formatMessage(messages.utm_content), value: UTM_CONTENT },
{ label: formatMessage(messages.utm_term), value: UTM_TERM },
];
return (
<>
{showFilters && <FilterButtons buttons={buttons} selected={type} onClick={setType} />}
<MetricsTable
{...props}
title={formatMessage(messages[type])}
type={type}
metric={formatMessage(messages.views)}
websiteId={websiteId}
delay={0}
/>
</>
);
}

View File

@ -1,5 +1,5 @@
import { useState } from 'react'; import { useState } from 'react';
import { FormattedMessage } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import Page from 'components/layout/Page'; import Page from 'components/layout/Page';
import PageHeader from 'components/layout/PageHeader'; import PageHeader from 'components/layout/PageHeader';
@ -7,19 +7,24 @@ import WebsiteList from 'components/pages/WebsiteList';
import Button from 'components/common/Button'; import Button from 'components/common/Button';
import DashboardSettingsButton from 'components/settings/DashboardSettingsButton'; import DashboardSettingsButton from 'components/settings/DashboardSettingsButton';
import useFetch from 'hooks/useFetch'; import useFetch from 'hooks/useFetch';
import useStore from 'store/app'; import useDashboard from 'store/dashboard';
import DashboardEdit from './DashboardEdit';
import styles from './WebsiteList.module.css'; import styles from './WebsiteList.module.css';
const selector = state => state.dashboard; const messages = defineMessages({
dashboard: { id: 'label.dashboard', defaultMessage: 'Dashboard' },
more: { id: 'label.more', defaultMessage: 'More' },
});
export default function Dashboard() { export default function Dashboard() {
const router = useRouter(); const router = useRouter();
const { id } = router.query; const { id } = router.query;
const userId = id?.[0]; const userId = id?.[0];
const store = useStore(selector); const dashboard = useDashboard();
const { showCharts, limit } = store; const { showCharts, limit, editing } = dashboard;
const [max, setMax] = useState(limit); const [max, setMax] = useState(limit);
const { data } = useFetch('/websites', { params: { user_id: userId } }); const { data } = useFetch('/websites', { params: { user_id: userId } });
const { formatMessage } = useIntl();
function handleMore() { function handleMore() {
setMax(max + limit); setMax(max + limit);
@ -32,15 +37,14 @@ export default function Dashboard() {
return ( return (
<Page> <Page>
<PageHeader> <PageHeader>
<div> <div>{formatMessage(messages.dashboard)}</div>
<FormattedMessage id="label.dashboard" defaultMessage="Dashboard" /> {!editing && <DashboardSettingsButton />}
</div>
<DashboardSettingsButton />
</PageHeader> </PageHeader>
<WebsiteList websites={data} showCharts={showCharts} limit={max} /> {editing && <DashboardEdit websites={data} />}
{!editing && <WebsiteList websites={data} showCharts={showCharts} limit={max} />}
{max < data.length && ( {max < data.length && (
<Button className={styles.button} onClick={handleMore}> <Button className={styles.button} onClick={handleMore}>
<FormattedMessage id="label.more" defaultMessage="More" /> {formatMessage(messages.more)}
</Button> </Button>
)} )}
</Page> </Page>

View File

@ -0,0 +1,102 @@
import { useState, useMemo } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
import classNames from 'classnames';
import Button from 'components/common/Button';
import { sortArrayByMap } from 'lib/array';
import useDashboard, { saveDashboard } from 'store/dashboard';
import styles from './DashboardEdit.module.css';
const messages = defineMessages({
save: { id: 'label.save', defaultMessage: 'Save' },
reset: { id: 'label.reset', defaultMessage: 'Reset' },
cancel: { id: 'label.cancel', defaultMessage: 'Cancel' },
});
const dragId = 'dashboard-website-ordering';
export default function DashboardEdit({ websites }) {
const settings = useDashboard();
const { websiteOrder } = settings;
const { formatMessage } = useIntl();
const [order, setOrder] = useState(websiteOrder || []);
const ordered = useMemo(() => sortArrayByMap(websites, order, 'website_id'), [websites, order]);
console.log({ order, ordered });
function handleWebsiteDrag({ destination, source }) {
if (!destination || destination.index === source.index) return;
const orderedWebsites = [...ordered];
const [removed] = orderedWebsites.splice(source.index, 1);
orderedWebsites.splice(destination.index, 0, removed);
setOrder(orderedWebsites.map(({ website_id }) => website_id));
}
function handleSave() {
saveDashboard({
editing: false,
websiteOrder: order,
});
}
function handleCancel() {
saveDashboard({ editing: false, websiteOrder });
}
function handleReset() {
setOrder([]);
}
return (
<>
<div className={styles.buttons}>
<Button onClick={handleSave} variant="action" size="small">
{formatMessage(messages.save)}
</Button>
<Button onClick={handleCancel} size="small">
{formatMessage(messages.cancel)}
</Button>
<Button onClick={handleReset} size="small">
{formatMessage(messages.reset)}
</Button>
</div>
<div className={styles.dragActive}>
<DragDropContext onDragEnd={handleWebsiteDrag}>
<Droppable droppableId={dragId}>
{(provided, snapshot) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
style={{ marginBottom: snapshot.isDraggingOver ? 260 : null }}
>
{ordered.map(({ website_id, name, domain }, index) => (
<Draggable key={website_id} draggableId={`${dragId}-${website_id}`} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
className={classNames(styles.item, {
[styles.active]: snapshot.isDragging,
})}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<div className={styles.text}>
<h1>{name}</h1>
<h2>{domain}</h2>
</div>
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</div>
</>
);
}

View File

@ -0,0 +1,40 @@
.buttons {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-bottom: 20px;
}
.item {
padding: 5px 0;
}
.item h1 {
font-weight: 600;
font-size: 16px;
}
.item h2 {
font-size: 14px;
color: var(--gray700);
}
.text {
padding: 20px;
border-radius: 5px;
border: 1px solid var(--gray400);
background: var(--gray50);
}
.active .text {
border-color: var(--gray600);
box-shadow: 4px 4px 4px var(--gray100);
}
.dragActive {
cursor: grab;
}
.dragActive:active {
cursor: grabbing;
}

View File

@ -1,4 +1,3 @@
import React, { useState } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import Head from 'next/head'; import Head from 'next/head';
import Link from 'next/link'; import Link from 'next/link';
@ -9,35 +8,37 @@ import DropDown from 'components/common/DropDown';
import WebsiteChart from 'components/metrics/WebsiteChart'; import WebsiteChart from 'components/metrics/WebsiteChart';
import EventsChart from 'components/metrics/EventsChart'; import EventsChart from 'components/metrics/EventsChart';
import Button from 'components/common/Button'; import Button from 'components/common/Button';
import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
import Icon from 'components/common/Icon';
import useFetch from 'hooks/useFetch'; import useFetch from 'hooks/useFetch';
import useUser from 'hooks/useUser';
import ChevronDown from 'assets/chevron-down.svg';
import styles from './TestConsole.module.css'; import styles from './TestConsole.module.css';
export default function TestConsole() { export default function TestConsole() {
const { user } = useUser();
const [website, setWebsite] = useState();
const [show, setShow] = useState(true);
const { basePath } = useRouter();
const { data } = useFetch('/websites'); const { data } = useFetch('/websites');
const router = useRouter();
const {
basePath,
query: { id },
} = router;
const websiteId = id?.[0];
if (!data || !user?.is_admin) { if (!data) {
return null; return null;
} }
const options = data.map(({ name, website_id }) => ({ label: name, value: website_id })); const options = data.map(({ name, website_id }) => ({ label: name, value: website_id }));
const website = data.find(({ website_id }) => website_id === +websiteId);
const selectedValue = options.find(({ value }) => value === website?.website_id)?.value; const selectedValue = options.find(({ value }) => value === website?.website_id)?.value;
console.log({ websiteId, data, options, website });
function handleSelect(value) { function handleSelect(value) {
setWebsite(data.find(({ website_id }) => website_id === value)); router.push(`/console/${value}`);
} }
function handleClick() { function handleClick() {
window.umami('event (default)'); window.umami('umami-default');
window.umami.trackView('/page-view', 'https://www.google.com'); window.umami.trackView('/page-view', 'https://www.google.com');
window.umami.trackEvent('event (custom)', 'custom-type'); window.umami.trackEvent('track-event-no-data');
window.umami.trackEvent('track-event-with-data', { test: 'test-data', time: Date.now() });
} }
return ( return (
@ -61,54 +62,47 @@ export default function TestConsole() {
onChange={handleSelect} onChange={handleSelect}
/> />
</PageHeader> </PageHeader>
{!selectedValue && <EmptyPlaceholder msg="I hope you know what you're doing here" />} {website && (
{selectedValue && (
<> <>
<div> <div className={classNames(styles.test, 'row')}>
<Icon <div className="col-4">
icon={<ChevronDown />} <PageHeader>Page links</PageHeader>
className={classNames({ [styles.hidden]: !show })} <div>
onClick={() => setShow(!show)} <Link href={`/console/${websiteId}?page=1`}>
/> <a>page one</a>
</div> </Link>
{show && (
<div className={classNames(styles.test, 'row')}>
<div className="col-4">
<PageHeader>Page links</PageHeader>
<div>
<Link href={`?page=1`}>
<a>page one</a>
</Link>
</div>
<div>
<Link href={`?page=2`}>
<a>page two</a>
</Link>
</div>
<div>
<Link href={`https://www.google.com`}>
<a className="umami--click--external-link">external link</a>
</Link>
</div>
</div> </div>
<div className="col-4"> <div>
<PageHeader>CSS events</PageHeader> <Link href={`/console/${websiteId}?page=2`}>
<Button <a>page two</a>
id="primary-button" </Link>
className="umami--click--primary-button"
variant="action"
>
Send event
</Button>
</div> </div>
<div className="col-4"> <div>
<PageHeader>Javascript events</PageHeader> <Link href={`https://www.google.com`}>
<Button id="manual-button" variant="action" onClick={handleClick}> <a className="umami--click--external-link-direct">external link (direct)</a>
Run script </Link>
</Button> </div>
<div>
<Link href={`https://www.google.com`}>
<a className="umami--click--external-link-tab" target="_blank">
external link (tab)
</a>
</Link>
</div> </div>
</div> </div>
)} <div className="col-4">
<PageHeader>CSS events</PageHeader>
<Button id="primary-button" className="umami--click--button-click" variant="action">
Send event
</Button>
</div>
<div className="col-4">
<PageHeader>Javascript events</PageHeader>
<Button id="manual-button" variant="action" onClick={handleClick}>
Run script
</Button>
</div>
</div>
<div className="row"> <div className="row">
<div className="col-12"> <div className="col-12">
<WebsiteChart <WebsiteChart

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { FormattedMessage } from 'react-intl'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import WebsiteChart from 'components/metrics/WebsiteChart'; import WebsiteChart from 'components/metrics/WebsiteChart';
import WorldMap from 'components/common/WorldMap'; import WorldMap from 'components/common/WorldMap';
@ -18,12 +18,25 @@ import CountriesTable from 'components/metrics/CountriesTable';
import LanguagesTable from 'components/metrics/LanguagesTable'; import LanguagesTable from 'components/metrics/LanguagesTable';
import EventsTable from 'components/metrics/EventsTable'; import EventsTable from 'components/metrics/EventsTable';
import EventsChart from 'components/metrics/EventsChart'; import EventsChart from 'components/metrics/EventsChart';
import ScreenTable from 'components/metrics/ScreenTable';
import QueryParametersTable from 'components/metrics/QueryParametersTable';
import useFetch from 'hooks/useFetch'; import useFetch from 'hooks/useFetch';
import usePageQuery from 'hooks/usePageQuery'; import usePageQuery from 'hooks/usePageQuery';
import { DEFAULT_ANIMATION_DURATION } from 'lib/constants'; import { DEFAULT_ANIMATION_DURATION } from 'lib/constants';
import styles from './WebsiteDetails.module.css'; import styles from './WebsiteDetails.module.css';
import ScreenTable from 'components/metrics/ScreenTable';
import UTMTable from 'components/metrics/UTMTable'; const messages = defineMessages({
pages: { id: 'metrics.pages', defaultMessage: 'Pages' },
referrers: { id: 'metrics.referrers', defaultMessage: 'Referrers' },
screens: { id: 'metrics.screens', defaultMessage: 'Screens' },
browsers: { id: 'metrics.browsers', defaultMessage: 'Browsers' },
os: { id: 'metrics.operating-systems', defaultMessage: 'Operating system' },
devices: { id: 'metrics.devices', defaultMessage: 'Devices' },
countries: { id: 'metrics.countries', defaultMessage: 'Countries' },
languages: { id: 'metrics.languages', defaultMessage: 'Languages' },
events: { id: 'metrics.events', defaultMessage: 'Events' },
query: { id: 'metrics.query-parameters', defaultMessage: 'Query parameters' },
});
const views = { const views = {
url: PagesTable, url: PagesTable,
@ -35,7 +48,7 @@ const views = {
country: CountriesTable, country: CountriesTable,
language: LanguagesTable, language: LanguagesTable,
event: EventsTable, event: EventsTable,
utm: UTMTable, query: QueryParametersTable,
}; };
export default function WebsiteDetails({ websiteId }) { export default function WebsiteDetails({ websiteId }) {
@ -47,6 +60,7 @@ export default function WebsiteDetails({ websiteId }) {
resolve, resolve,
query: { view }, query: { view },
} = usePageQuery(); } = usePageQuery();
const { formatMessage } = useIntl();
const BackButton = () => ( const BackButton = () => (
<div key="back-button" className={classNames(styles.backButton, 'col-12')}> <div key="back-button" className={classNames(styles.backButton, 'col-12')}>
@ -61,44 +75,44 @@ export default function WebsiteDetails({ websiteId }) {
render: BackButton, render: BackButton,
}, },
{ {
label: <FormattedMessage id="metrics.pages" defaultMessage="Pages" />, label: formatMessage(messages.pages),
value: resolve({ view: 'url' }), value: resolve({ view: 'url' }),
}, },
{ {
label: <FormattedMessage id="metrics.referrers" defaultMessage="Referrers" />, label: formatMessage(messages.referrers),
value: resolve({ view: 'referrer' }), value: resolve({ view: 'referrer' }),
}, },
{ {
label: <FormattedMessage id="metrics.screens" defaultMessage="Screens" />, label: formatMessage(messages.browsers),
value: resolve({ view: 'screen' }),
},
{
label: <FormattedMessage id="metrics.browsers" defaultMessage="Browsers" />,
value: resolve({ view: 'browser' }), value: resolve({ view: 'browser' }),
}, },
{ {
label: <FormattedMessage id="metrics.operating-systems" defaultMessage="Operating system" />, label: formatMessage(messages.os),
value: resolve({ view: 'os' }), value: resolve({ view: 'os' }),
}, },
{ {
label: <FormattedMessage id="metrics.devices" defaultMessage="Devices" />, label: formatMessage(messages.devices),
value: resolve({ view: 'device' }), value: resolve({ view: 'device' }),
}, },
{ {
label: <FormattedMessage id="metrics.countries" defaultMessage="Countries" />, label: formatMessage(messages.countries),
value: resolve({ view: 'country' }), value: resolve({ view: 'country' }),
}, },
{ {
label: <FormattedMessage id="metrics.languages" defaultMessage="Languages" />, label: formatMessage(messages.languages),
value: resolve({ view: 'language' }), value: resolve({ view: 'language' }),
}, },
{ {
label: <FormattedMessage id="metrics.events" defaultMessage="Events" />, label: formatMessage(messages.screens),
value: resolve({ view: 'screen' }),
},
{
label: formatMessage(messages.events),
value: resolve({ view: 'event' }), value: resolve({ view: 'event' }),
}, },
{ {
label: <FormattedMessage id="metrics.utm" defaultMessage="UTM" />, label: formatMessage(messages.query),
value: resolve({ view: 'utm' }), value: resolve({ view: 'query' }),
}, },
]; ];

View File

@ -1,25 +1,42 @@
import { FormattedMessage } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import Link from 'components/common/Link'; import Link from 'components/common/Link';
import WebsiteChart from 'components/metrics/WebsiteChart'; import WebsiteChart from 'components/metrics/WebsiteChart';
import Page from 'components/layout/Page'; import Page from 'components/layout/Page';
import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
import Arrow from 'assets/arrow-right.svg'; import Arrow from 'assets/arrow-right.svg';
import styles from './WebsiteList.module.css'; import styles from './WebsiteList.module.css';
import useDashboard from 'store/dashboard';
import { sortArrayByMap } from 'lib/array';
import { useMemo } from 'react';
const messages = defineMessages({
noWebsites: {
id: 'message.no-websites-configured',
defaultMessage: "You don't have any websites configured.",
},
goToSettngs: {
id: 'message.go-to-settings',
defaultMessage: 'Go to settings',
},
});
export default function WebsiteList({ websites, showCharts, limit }) { export default function WebsiteList({ websites, showCharts, limit }) {
const { websiteOrder } = useDashboard();
const { formatMessage } = useIntl();
console.log({ websiteOrder });
const ordered = useMemo(
() => sortArrayByMap(websites, websiteOrder, 'website_id'),
[websites, websiteOrder],
);
if (websites.length === 0) { if (websites.length === 0) {
return ( return (
<Page> <Page>
<EmptyPlaceholder <EmptyPlaceholder msg={formatMessage(messages.noWebsites)}>
msg={
<FormattedMessage
id="message.no-websites-configured"
defaultMessage="You don't have any websites configured."
/>
}
>
<Link href="/settings" icon={<Arrow />} iconRight> <Link href="/settings" icon={<Arrow />} iconRight>
<FormattedMessage id="message.go-to-settings" defaultMessage="Go to settings" /> {formatMessage(messages.goToSettngs)}
</Link> </Link>
</EmptyPlaceholder> </EmptyPlaceholder>
</Page> </Page>
@ -28,7 +45,7 @@ export default function WebsiteList({ websites, showCharts, limit }) {
return ( return (
<div> <div>
{websites.map(({ website_id, name, domain }, index) => {ordered.map(({ website_id, name, domain }, index) =>
index < limit ? ( index < limit ? (
<div key={website_id} className={styles.website}> <div key={website_id} className={styles.website}>
<WebsiteChart <WebsiteChart

View File

@ -1,26 +1,35 @@
import React from 'react'; import React from 'react';
import { FormattedMessage } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import MenuButton from 'components/common/MenuButton'; import MenuButton from 'components/common/MenuButton';
import Gear from 'assets/gear.svg'; import Gear from 'assets/gear.svg';
import useStore, { setDashboard, defaultDashboardConfig } from 'store/app'; import { saveDashboard } from 'store/dashboard';
const selector = state => state.dashboard; const messages = defineMessages({
toggleCharts: { id: 'message.toggle-charts', defaultMessage: 'Toggle charts' },
editDashboard: { id: 'message.edit-dashboard', defaultMessage: 'Edit dashboard' },
});
export default function DashboardSettingsButton() { export default function DashboardSettingsButton() {
const settings = useStore(selector); const { formatMessage } = useIntl();
const menuOptions = [ const menuOptions = [
{ {
label: <FormattedMessage id="message.toggle-charts" defaultMessage="Toggle charts" />, label: formatMessage(messages.toggleCharts),
value: 'charts', value: 'charts',
}, },
{
label: formatMessage(messages.editDashboard),
value: 'order',
},
]; ];
function handleSelect(value) { function handleSelect(value) {
if (value === 'charts') { if (value === 'charts') {
setDashboard({ ...defaultDashboardConfig, showCharts: !settings.showCharts }); saveDashboard(state => ({ showCharts: !state.showCharts }));
}
if (value === 'order') {
saveDashboard({ editing: true });
} }
//setDashboard(value);
} }
return <MenuButton icon={<Gear />} options={menuOptions} onSelect={handleSelect} hideLabel />; return <MenuButton icon={<Gear />} options={menuOptions} onSelect={handleSelect} hideLabel />;

View File

@ -0,0 +1,5 @@
.buttonGroup {
display: flex;
place-items: center;
gap: 10px;
}

View File

@ -36,6 +36,7 @@ export default function WebsiteSettings() {
const [showUrl, setShowUrl] = useState(); const [showUrl, setShowUrl] = useState();
const [saved, setSaved] = useState(0); const [saved, setSaved] = useState(0);
const [message, setMessage] = useState(); const [message, setMessage] = useState();
const { data } = useFetch('/websites', { params: { include_all: !!user?.is_admin } }, [saved]); const { data } = useFetch('/websites', { params: { include_all: !!user?.is_admin } }, [saved]);
const Buttons = row => ( const Buttons = row => (

View File

@ -0,0 +1,62 @@
-- DropForeignKey
ALTER TABLE `event` DROP FOREIGN KEY `event_ibfk_1`;
ALTER TABLE `event` DROP FOREIGN KEY `event_ibfk_2`;
DROP INDEX `event_created_at_idx` ON `event`;
DROP INDEX `event_session_id_idx` ON `event`;
DROP INDEX `event_website_id_idx` ON `event`;
CREATE INDEX `event_old_created_at_idx` ON `event` (created_at);
CREATE INDEX `event_old_session_id_idx` ON `event` (session_id);
CREATE INDEX `event_old_website_id_idx` ON `event` (website_id);
-- RenameTable
RENAME TABLE `event` TO `_event_old`;
-- CreateTable
CREATE TABLE `event`
(
`event_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`website_id` INTEGER UNSIGNED NOT NULL,
`session_id` INTEGER UNSIGNED NOT NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`url` VARCHAR(500) NOT NULL,
`event_name` VARCHAR(50) NOT NULL,
INDEX `event_created_at_idx`(`created_at`),
INDEX `event_session_id_idx`(`session_id`),
INDEX `event_website_id_idx`(`website_id`),
PRIMARY KEY (`event_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `event` ADD CONSTRAINT `event_ibfk_2` FOREIGN KEY (`session_id`) REFERENCES `session`(`session_id`) ON DELETE CASCADE ON UPDATE NO ACTION;
-- AddForeignKey
ALTER TABLE `event` ADD CONSTRAINT `event_ibfk_1` FOREIGN KEY (`website_id`) REFERENCES `website`(`website_id`) ON DELETE CASCADE ON UPDATE NO ACTION;
-- CreateTable
CREATE TABLE `event_data` (
`event_data_id` INTEGER NOT NULL AUTO_INCREMENT,
`event_id` INTEGER UNSIGNED NOT NULL,
`event_data` JSON NOT NULL,
UNIQUE INDEX `event_data_event_id_key`(`event_id`),
PRIMARY KEY (`event_data_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `event_data` ADD CONSTRAINT `event_data_event_id_fkey` FOREIGN KEY (`event_id`) REFERENCES `event`(`event_id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- RenameIndex
ALTER TABLE `account` RENAME INDEX `username` TO `account_username_key`;
-- RenameIndex
ALTER TABLE `session` RENAME INDEX `session_uuid` TO `session_session_uuid_key`;
-- RenameIndex
ALTER TABLE `website` RENAME INDEX `share_id` TO `website_share_id_key`;
-- RenameIndex
ALTER TABLE `website` RENAME INDEX `website_uuid` TO `website_website_uuid_key`;

View File

@ -9,7 +9,7 @@ datasource db {
model account { model account {
user_id Int @id @default(autoincrement()) @db.UnsignedInt user_id Int @id @default(autoincrement()) @db.UnsignedInt
username String @unique(map: "username") @db.VarChar(255) username String @unique() @db.VarChar(255)
password String @db.VarChar(60) password String @db.VarChar(60)
is_admin Boolean @default(false) is_admin Boolean @default(false)
created_at DateTime? @default(now()) @db.Timestamp(0) created_at DateTime? @default(now()) @db.Timestamp(0)
@ -18,21 +18,28 @@ model account {
} }
model event { model event {
event_id Int @id @default(autoincrement()) @db.UnsignedInt event_id Int @id @default(autoincrement()) @db.UnsignedInt
website_id Int @db.UnsignedInt website_id Int @db.UnsignedInt
session_id Int @db.UnsignedInt session_id Int @db.UnsignedInt
created_at DateTime? @default(now()) @db.Timestamp(0) created_at DateTime? @default(now()) @db.Timestamp(0)
url String @db.VarChar(500) url String @db.VarChar(500)
event_type String @db.VarChar(50) event_name String @db.VarChar(50)
event_value String @db.VarChar(50) session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_2")
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_2") website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_1")
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_1") event_data event_data?
@@index([created_at]) @@index([created_at])
@@index([session_id]) @@index([session_id])
@@index([website_id]) @@index([website_id])
} }
model event_data {
event_data_id Int @id @default(autoincrement())
event_id Int @unique @db.UnsignedInt
event_data Json
event event @relation(fields: [event_id], references: [event_id])
}
model pageview { model pageview {
view_id Int @id @default(autoincrement()) @db.UnsignedInt view_id Int @id @default(autoincrement()) @db.UnsignedInt
website_id Int @db.UnsignedInt website_id Int @db.UnsignedInt
@ -52,7 +59,7 @@ model pageview {
model session { model session {
session_id Int @id @default(autoincrement()) @db.UnsignedInt session_id Int @id @default(autoincrement()) @db.UnsignedInt
session_uuid String @unique(map: "session_uuid") @db.VarChar(36) session_uuid String @unique() @db.VarChar(36)
website_id Int @db.UnsignedInt website_id Int @db.UnsignedInt
created_at DateTime? @default(now()) @db.Timestamp(0) created_at DateTime? @default(now()) @db.Timestamp(0)
hostname String? @db.VarChar(100) hostname String? @db.VarChar(100)
@ -72,11 +79,11 @@ model session {
model website { model website {
website_id Int @id @default(autoincrement()) @db.UnsignedInt website_id Int @id @default(autoincrement()) @db.UnsignedInt
website_uuid String @unique(map: "website_uuid") @db.VarChar(36) website_uuid String @unique() @db.VarChar(36)
user_id Int @db.UnsignedInt user_id Int @db.UnsignedInt
name String @db.VarChar(100) name String @db.VarChar(100)
domain String? @db.VarChar(500) domain String? @db.VarChar(500)
share_id String? @unique(map: "share_id") @db.VarChar(64) share_id String? @unique() @db.VarChar(64)
created_at DateTime? @default(now()) @db.Timestamp(0) created_at DateTime? @default(now()) @db.Timestamp(0)
account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade, onUpdate: NoAction, map: "website_ibfk_1") account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade, onUpdate: NoAction, map: "website_ibfk_1")
event event[] event event[]

View File

@ -0,0 +1,66 @@
-- DropForeignKey
ALTER TABLE "event" DROP CONSTRAINT "event_session_id_fkey";
ALTER TABLE "event" DROP CONSTRAINT "event_website_id_fkey";
-- RenameIndex
ALTER INDEX "event_pkey" RENAME TO "event_old_pkey";
ALTER INDEX "event_created_at_idx" RENAME TO "event_old_created_at_idx";
ALTER INDEX "event_session_id_idx" RENAME TO "event_old_session_id_idx";
ALTER INDEX "event_website_id_idx" RENAME TO "event_old_website_id_idx";
-- RenameTable
ALTER TABLE "event" RENAME TO "_event_old";
-- CreateTable
CREATE TABLE "event" (
"event_id" SERIAL NOT NULL,
"website_id" INTEGER NOT NULL,
"session_id" INTEGER NOT NULL,
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
"url" VARCHAR(500) NOT NULL,
"event_name" VARCHAR(50) NOT NULL,
PRIMARY KEY ("event_id")
);
-- CreateIndex
CREATE INDEX "event_created_at_idx" ON "event"("created_at");
-- CreateIndex
CREATE INDEX "event_session_id_idx" ON "event"("session_id");
-- CreateIndex
CREATE INDEX "event_website_id_idx" ON "event"("website_id");
-- AddForeignKey
ALTER TABLE "event" ADD CONSTRAINT "event_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "session"("session_id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "event" ADD CONSTRAINT "event_website_id_fkey" FOREIGN KEY ("website_id") REFERENCES "website"("website_id") ON DELETE CASCADE ON UPDATE CASCADE;
-- CreateTable
CREATE TABLE "event_data" (
"event_data_id" SERIAL NOT NULL,
"event_id" INTEGER NOT NULL,
"event_data" JSONB NOT NULL,
CONSTRAINT "event_data_pkey" PRIMARY KEY ("event_data_id")
);
-- CreateIndex
CREATE UNIQUE INDEX "event_data_event_id_key" ON "event_data"("event_id");
-- AddForeignKey
ALTER TABLE "event_data" ADD CONSTRAINT "event_data_event_id_fkey" FOREIGN KEY ("event_id") REFERENCES "event"("event_id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- RenameIndex
ALTER INDEX "account.username_unique" RENAME TO "account_username_key";
-- RenameIndex
ALTER INDEX "session.session_uuid_unique" RENAME TO "session_session_uuid_key";
-- RenameIndex
ALTER INDEX "website.share_id_unique" RENAME TO "website_share_id_key";
-- RenameIndex
ALTER INDEX "website.website_uuid_unique" RENAME TO "website_website_uuid_key";

View File

@ -18,21 +18,28 @@ model account {
} }
model event { model event {
event_id Int @id @default(autoincrement()) event_id Int @id @default(autoincrement())
website_id Int website_id Int
session_id Int session_id Int
created_at DateTime? @default(now()) @db.Timestamptz(6) created_at DateTime? @default(now()) @db.Timestamptz(6)
url String @db.VarChar(500) url String @db.VarChar(500)
event_type String @db.VarChar(50) event_name String @db.VarChar(50)
event_value String @db.VarChar(50) session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade)
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction) website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade)
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction) event_data event_data?
@@index([created_at]) @@index([created_at])
@@index([session_id]) @@index([session_id])
@@index([website_id]) @@index([website_id])
} }
model event_data {
event_data_id Int @id @default(autoincrement())
event_id Int @unique
event_data Json
event event @relation(fields: [event_id], references: [event_id])
}
model pageview { model pageview {
view_id Int @id @default(autoincrement()) view_id Int @id @default(autoincrement())
website_id Int website_id Int
@ -40,8 +47,8 @@ model pageview {
created_at DateTime? @default(now()) @db.Timestamptz(6) created_at DateTime? @default(now()) @db.Timestamptz(6)
url String @db.VarChar(500) url String @db.VarChar(500)
referrer String? @db.VarChar(500) referrer String? @db.VarChar(500)
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction) session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade)
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction) website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade)
@@index([created_at]) @@index([created_at])
@@index([session_id]) @@index([session_id])
@ -58,13 +65,13 @@ model session {
hostname String? @db.VarChar(100) hostname String? @db.VarChar(100)
browser String? @db.VarChar(20) browser String? @db.VarChar(20)
os String? @db.VarChar(20) os String? @db.VarChar(20)
device String? @db.VarChar(20)
screen String? @db.VarChar(11) screen String? @db.VarChar(11)
language String? @db.VarChar(35) language String? @db.VarChar(35)
country String? @db.Char(2) country String? @db.Char(2)
device String? @db.VarChar(20) website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade)
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction)
event event[]
pageview pageview[] pageview pageview[]
event event[]
@@index([created_at]) @@index([created_at])
@@index([website_id]) @@index([website_id])
@ -73,15 +80,15 @@ model session {
model website { model website {
website_id Int @id @default(autoincrement()) website_id Int @id @default(autoincrement())
website_uuid String @unique @db.Uuid website_uuid String @unique @db.Uuid
name String @db.VarChar(100)
created_at DateTime? @default(now()) @db.Timestamptz(6)
user_id Int user_id Int
name String @db.VarChar(100)
domain String? @db.VarChar(500) domain String? @db.VarChar(500)
share_id String? @unique(map: "website_share_id_idx") @db.VarChar(64) share_id String? @unique @db.VarChar(64)
account account @relation(fields: [user_id], references: [user_id], onDelete: NoAction, onUpdate: NoAction) created_at DateTime? @default(now()) @db.Timestamptz(6)
event event[] account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade)
pageview pageview[] pageview pageview[]
session session[] session session[]
event event[]
@@index([user_id]) @@index([user_id])
} }

View File

@ -6,7 +6,7 @@ import useStore from 'store/app';
const selector = state => state.shareToken; const selector = state => state.shareToken;
function parseHeaders(headers = {}, { authToken, shareToken }) { function parseHeaders(headers, { authToken, shareToken }) {
if (authToken) { if (authToken) {
headers.authorization = `Bearer ${authToken}`; headers.authorization = `Bearer ${authToken}`;
} }
@ -25,7 +25,7 @@ export default function useApi() {
return { return {
get: useCallback( get: useCallback(
async (url, params, headers) => { async (url, params = {}, headers = {}) => {
return get( return get(
`${basePath}/api${url}`, `${basePath}/api${url}`,
params, params,
@ -36,7 +36,7 @@ export default function useApi() {
), ),
post: useCallback( post: useCallback(
async (url, params, headers) => { async (url, params = {}, headers = {}) => {
return post( return post(
`${basePath}/api${url}`, `${basePath}/api${url}`,
params, params,
@ -47,7 +47,7 @@ export default function useApi() {
), ),
put: useCallback( put: useCallback(
async (url, params, headers) => { async (url, params = {}, headers = {}) => {
return put( return put(
`${basePath}/api${url}`, `${basePath}/api${url}`,
params, params,
@ -58,7 +58,7 @@ export default function useApi() {
), ),
del: useCallback( del: useCallback(
async (url, params, headers) => { async (url, params = {}, headers = {}) => {
return del( return del(
`${basePath}/api${url}`, `${basePath}/api${url}`,
params, params,

24
hooks/useConfig.js Normal file
View File

@ -0,0 +1,24 @@
import { useEffect } from 'react';
import useStore, { setConfig } from 'store/app';
import useApi from 'hooks/useApi';
let fetched = false;
export default function useConfig() {
const { config } = useStore();
const { get } = useApi();
async function loadConfig() {
const { data } = await get('/config');
setConfig(data);
}
useEffect(() => {
if (!config && !fetched) {
fetched = true;
loadConfig();
}
}, []);
return config || {};
}

View File

@ -8,7 +8,9 @@
"metrics.device.desktop", "metrics.device.desktop",
"metrics.device.laptop", "metrics.device.laptop",
"metrics.device.tablet", "metrics.device.tablet",
"metrics.referrers" "metrics.referrers",
"metrics.utm",
"metrics.utm_medium"
], ],
"en-GB": "*", "en-GB": "*",
"fr-FR": ["metrics.actions", "metrics.pages"], "fr-FR": ["metrics.actions", "metrics.pages"],
@ -34,5 +36,10 @@
"metrics.device.desktop", "metrics.device.desktop",
"metrics.device.tablet", "metrics.device.tablet",
"metrics.filter.raw" "metrics.filter.raw"
],
"pt-PT": [
"label.websites",
"metrics.device.desktop",
"metrics.device.tablet"
] ]
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "إضافة موقع", "label.add-website": "إضافة موقع",
"label.administrator": "مدير عام؟", "label.administrator": "مدير عام؟",
"label.all": "الكل", "label.all": "الكل",
"label.all-events": "كافة الأحداث",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "كافة المواقع", "label.all-websites": "كافة المواقع",
"label.back": "للخلف", "label.back": "للخلف",
@ -68,6 +67,7 @@
"message.confirm-reset": "هل أنت متأكد من اعادة تعيين الإحصائيات لـ {target}؟", "message.confirm-reset": "هل أنت متأكد من اعادة تعيين الإحصائيات لـ {target}؟",
"message.copied": "تم النسخ!", "message.copied": "تم النسخ!",
"message.delete-warning": "كافة البيانات المرتبطة سيم حذفها ايضا.", "message.delete-warning": "كافة البيانات المرتبطة سيم حذفها ايضا.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "حدث خطأ ما.", "message.failure": "حدث خطأ ما.",
"message.get-share-url": "احصل على رابط المشاركة", "message.get-share-url": "احصل على رابط المشاركة",
"message.get-tracking-code": "احصل على كود التتبع", "message.get-tracking-code": "احصل على كود التتبع",
@ -103,15 +103,10 @@
"metrics.operating-systems": "نظام التشغيل", "metrics.operating-systems": "نظام التشغيل",
"metrics.page-views": "مشاهدات الصفحة", "metrics.page-views": "مشاهدات الصفحة",
"metrics.pages": "الصفحات", "metrics.pages": "الصفحات",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "التحويلات", "metrics.referrers": "التحويلات",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "زائرون فريدون", "metrics.unique-visitors": "زائرون فريدون",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "مشاهدات", "metrics.views": "مشاهدات",
"metrics.visitors": "زوار" "metrics.visitors": "زوار"
} }

112
lang/bn-BD.json Normal file
View File

@ -0,0 +1,112 @@
{
"label.accounts": "অ্যাকাউন্ট",
"label.add-account": "অ্যাকাউন্ট যুক্ত করুন",
"label.add-website": "ওয়েবসাইট যুক্ত করুন",
"label.administrator": "অ্যাডমিন",
"label.all": "সবগুলো",
"label.all-time": "সব সময়",
"label.all-websites": "সবগুলো ওয়েবসাইট",
"label.back": "পেছনে",
"label.cancel": "বাতিল",
"label.change-password": "পাসওয়ার্ড পরিবর্তন করুন",
"label.confirm-password": "পাসওয়ার্ড নিশ্চিত করুন",
"label.copy-to-clipboard": "কপি করুন",
"label.current-password": "বর্তমান পাসওয়ার্ড",
"label.custom-range": "কাস্টম রেঞ্জ",
"label.dashboard": "ড্যাশবোর্ড",
"label.date-range": "তারিখের পরিসীমা",
"label.default-date-range": "ডিফল্ট তারিখের পরিসীমা",
"label.delete": "মুছে ফেলুন",
"label.delete-account": "অ্যাকাউন্ট মুছুন",
"label.delete-website": "ওয়েবসাইট মুছুন",
"label.dismiss": "বাতিল",
"label.domain": "ডোমেইন",
"label.edit": "সম্পাদনা করুন",
"label.edit-account": "অ্যাকাউন্ট সম্পাদনা করুন",
"label.edit-website": "ওয়েবসাইট সম্পাদনা করুন",
"label.enable-share-url": "শেয়ার ইউআরএল শেয়ার করুন",
"label.invalid": "ভুল",
"label.invalid-domain": "ভুল ডোমেন",
"label.language": "ভাষা",
"label.last-days": "শেষ {x} দিন",
"label.last-hours": "শেষ {x} ঘন্টা",
"label.logged-in-as": "{username} অ্যাকাউন্টে লগ ইন",
"label.login": "লগিন",
"label.logout": "লগ আউট",
"label.more": "আরও",
"label.name": "নাম",
"label.new-password": "নতুন পাসওয়ার্ড",
"label.none": "কিছুই না",
"label.owner": "মালিক",
"label.password": "পাসওয়ার্ড",
"label.passwords-dont-match": "পাসওয়ার্ড মেলে না",
"label.profile": "প্রোফাইল",
"label.realtime": "সরাসরি",
"label.realtime-logs": "সরাসরি লগ",
"label.refresh": "রিফ্রেশ",
"label.required": "প্রয়োজনীয়",
"label.reset": "রিসেট",
"label.reset-website": "ওয়েবসাইট রিসেট করুন",
"label.save": "সংরক্ষণ",
"label.settings": "সেটিংস",
"label.share-url": "ইউআরএল শেয়ার করুন",
"label.single-day": "একদিন",
"label.theme": "থিম",
"label.this-month": "এই মাস",
"label.this-week": "এই সপ্তাহ",
"label.this-year": "এই বছর",
"label.timezone": "সময়স্থান",
"label.today": "আজ",
"label.tracking-code": "ট্র্যাকিং কোড",
"label.unknown": "অজানা",
"label.username": "ব্যবহারকারীর নাম",
"label.view-details": "বিস্তারিত দেখুন",
"label.websites": "সবগুলো ওয়েবসাইট",
"message.active-users": "{x} বর্তমান {x, plural, one {visitor} other {visitors}}",
"message.confirm-delete": "আপনি কি নিশ্চিত যে আপনি {target} মুছতে চান?",
"message.confirm-reset": "আপনি কি নিশ্চিত যে আপনি {target} এর পরিসংখ্যান পুনরায় সেট করতে চান?",
"message.copied": "কপি হয়েছে",
"message.delete-warning": "সমস্ত সম্পর্কিত ডেটা পাশাপাশি মুছে ফেলা হবে।",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "কিছু ভুল হয়েছে।",
"message.get-share-url": "শেয়ার ইউআরএল",
"message.get-tracking-code": "ট্র্যাকিং কোড পান",
"message.go-to-settings": "সেটিংস এ যান",
"message.incorrect-username-password": "ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড।",
"message.log.visitor": "{country} থেকে একজন ভিসিটর {ব্রাউজার}, ব্যবহার করছেন {os} {device} এর মধ্যে।",
"message.new-version-available": "নতুন সংস্করণ {version} পাওয়া গিয়েছে।",
"message.no-data-available": "কোন তথ্য নেই।",
"message.no-websites-configured": "কোনও ওয়েবসাইট কনফিগার করা নেই।",
"message.page-not-found": "পৃষ্ঠা খুঁজে পাওয়া যায়নি।",
"message.powered-by": "{name} দ্বারা চালিত",
"message.reset-warning": "এই ওয়েবসাইটের সমস্ত পরিসংখ্যান মুছে ফেলা হবে, তবে আপনার ট্র্যাকিং কোডটি অক্ষত থাকবে।",
"message.save-success": "সংরক্ষিত হয়েছে।",
"message.share-url": "এটি {target} এর জন্য প্রকাশ্যে শেয়ার করার ইউআরএল।",
"message.toggle-charts": "চার্ট পরিবর্তন করুন",
"message.track-stats": "{target} এর জন্য পরিসংখ্যানগুলি ট্র্যাক করতে, আপনার ওয়েবসাইটের {head} বিভাগে নিম্নলিখিত কোডটি রাখুন।",
"message.type-delete": "নিশ্চিত করতে নীচের বাক্সে {delete} টাইপ করুন।",
"message.type-reset": "নিশ্চিত করতে নীচের বাক্সে {reset} টাইপ করুন।",
"metrics.actions": "অ্যাকশনস",
"metrics.average-visit-time": "গড় পরিদর্শনের সময়",
"metrics.bounce-rate": "বহিষ্কারের হার",
"metrics.browsers": "ব্রাউজার",
"metrics.countries": "দেশ",
"metrics.device.desktop": "ডেস্কটপ",
"metrics.device.laptop": "ল্যাপটপ",
"metrics.device.mobile": "মুঠোফোন",
"metrics.device.tablet": "ট্যাবলেট",
"metrics.devices": "ডিভাইস গুলো",
"metrics.events": "ঘটনা",
"metrics.filter.combined": "সম্মিলিত",
"metrics.filter.raw": "অপরিশোধিত",
"metrics.languages": "ভাষা",
"metrics.operating-systems": "অপারেটিং সিস্টেম গুলো",
"metrics.page-views": "পৃষ্ঠা পরিদর্শন গুলো",
"metrics.pages": "পৃষ্ঠাগুলি",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "রেফারার্স",
"metrics.screens": "স্ক্রিনগুলি",
"metrics.unique-visitors": "অনন্য ভিজিটর",
"metrics.views": "ভিউস",
"metrics.visitors": "পরিদর্শনার্থী"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Afegeix lloc web", "label.add-website": "Afegeix lloc web",
"label.administrator": "Administrador", "label.administrator": "Administrador",
"label.all": "Tots", "label.all": "Tots",
"label.all-events": "Tots els esdeveniments",
"label.all-time": "Sempre", "label.all-time": "Sempre",
"label.all-websites": "Tots els llocs web", "label.all-websites": "Tots els llocs web",
"label.back": "Enrere", "label.back": "Enrere",
@ -68,6 +67,7 @@
"message.confirm-reset": "Segur que vols restablir les estadístiques de {target}?", "message.confirm-reset": "Segur que vols restablir les estadístiques de {target}?",
"message.copied": "S'ha copiat", "message.copied": "S'ha copiat",
"message.delete-warning": "També s'esborraran totes les dades relacionades.", "message.delete-warning": "També s'esborraran totes les dades relacionades.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "S'ha produït un error.", "message.failure": "S'ha produït un error.",
"message.get-share-url": "Obté l'enllaç per compartir", "message.get-share-url": "Obté l'enllaç per compartir",
"message.get-tracking-code": "Obté el codi de seguiment", "message.get-tracking-code": "Obté el codi de seguiment",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemes operatius", "metrics.operating-systems": "Sistemes operatius",
"metrics.page-views": "Pàgines vistes", "metrics.page-views": "Pàgines vistes",
"metrics.pages": "Pàgines", "metrics.pages": "Pàgines",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referents", "metrics.referrers": "Referents",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitants únics", "metrics.unique-visitors": "Visitants únics",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vistes", "metrics.views": "Vistes",
"metrics.visitors": "Visitants" "metrics.visitors": "Visitants"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Přidat web", "label.add-website": "Přidat web",
"label.administrator": "Administrátor", "label.administrator": "Administrátor",
"label.all": "Vše", "label.all": "Vše",
"label.all-events": "All events",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "Všechny weby", "label.all-websites": "Všechny weby",
"label.back": "Zpět", "label.back": "Zpět",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Zkopírováno!", "message.copied": "Zkopírováno!",
"message.delete-warning": "Všechna související data budou také smazána.", "message.delete-warning": "Všechna související data budou také smazána.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Něco se pokazilo.", "message.failure": "Něco se pokazilo.",
"message.get-share-url": "Získat sdílené URL", "message.get-share-url": "Získat sdílené URL",
"message.get-tracking-code": "Získat měřící kód", "message.get-tracking-code": "Získat měřící kód",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operační systém", "metrics.operating-systems": "Operační systém",
"metrics.page-views": "Zobrazení stránek", "metrics.page-views": "Zobrazení stránek",
"metrics.pages": "Stránky", "metrics.pages": "Stránky",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Odkazy", "metrics.referrers": "Odkazy",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Jedinečné návštěvy", "metrics.unique-visitors": "Jedinečné návštěvy",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Zobrazení", "metrics.views": "Zobrazení",
"metrics.visitors": "Návštěvy" "metrics.visitors": "Návštěvy"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Tilføj hjemmeside", "label.add-website": "Tilføj hjemmeside",
"label.administrator": "Administrator", "label.administrator": "Administrator",
"label.all": "Alle", "label.all": "Alle",
"label.all-events": "Alle hændelser",
"label.all-time": "Altid", "label.all-time": "Altid",
"label.all-websites": "Alle hjemmesider", "label.all-websites": "Alle hjemmesider",
"label.back": "Tilbage", "label.back": "Tilbage",
@ -68,6 +67,7 @@
"message.confirm-reset": "Er du sikker på at du ville nulstille {target}'s statistikker?", "message.confirm-reset": "Er du sikker på at du ville nulstille {target}'s statistikker?",
"message.copied": "Kopieret!", "message.copied": "Kopieret!",
"message.delete-warning": "Alle tilknyttede data slettes også.", "message.delete-warning": "Alle tilknyttede data slettes også.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Noget gik galt.", "message.failure": "Noget gik galt.",
"message.get-share-url": "Få delings-URL", "message.get-share-url": "Få delings-URL",
"message.get-tracking-code": "Få sporingskode", "message.get-tracking-code": "Få sporingskode",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operativsystemer", "metrics.operating-systems": "Operativsystemer",
"metrics.page-views": "Sidevisninger", "metrics.page-views": "Sidevisninger",
"metrics.pages": "Sider", "metrics.pages": "Sider",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Henvisninger", "metrics.referrers": "Henvisninger",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unikke besøgende", "metrics.unique-visitors": "Unikke besøgende",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visninger", "metrics.views": "Visninger",
"metrics.visitors": "Besøgende" "metrics.visitors": "Besøgende"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Webseite hinzufügen", "label.add-website": "Webseite hinzufügen",
"label.administrator": "Administrator", "label.administrator": "Administrator",
"label.all": "Alle", "label.all": "Alle",
"label.all-events": "Alle Ereignisse",
"label.all-time": "Gesamter Zeitraum", "label.all-time": "Gesamter Zeitraum",
"label.all-websites": "Alle Webseiten", "label.all-websites": "Alle Webseiten",
"label.back": "Zurück", "label.back": "Zurück",
@ -37,7 +36,7 @@
"label.more": "Mehr", "label.more": "Mehr",
"label.name": "Name", "label.name": "Name",
"label.new-password": "Neues Passwort", "label.new-password": "Neues Passwort",
"label.none": "None", "label.none": "Keine",
"label.owner": "Besitzer", "label.owner": "Besitzer",
"label.password": "Passwort", "label.password": "Passwort",
"label.passwords-dont-match": "Passwörter stimmen nicht überein", "label.passwords-dont-match": "Passwörter stimmen nicht überein",
@ -68,6 +67,7 @@
"message.confirm-reset": "Sind Sie sicher, dass Sie die Statistiken von {target} zurücksetzen wollen?", "message.confirm-reset": "Sind Sie sicher, dass Sie die Statistiken von {target} zurücksetzen wollen?",
"message.copied": "In Zwischenablage kopiert!", "message.copied": "In Zwischenablage kopiert!",
"message.delete-warning": "Alle zugehörigen Daten werden ebenfalls gelöscht.", "message.delete-warning": "Alle zugehörigen Daten werden ebenfalls gelöscht.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Es ist ein Fehler aufgetreten.", "message.failure": "Es ist ein Fehler aufgetreten.",
"message.get-share-url": "Freigabe-URL abrufen", "message.get-share-url": "Freigabe-URL abrufen",
"message.get-tracking-code": "Erstelle Tracking Kennung", "message.get-tracking-code": "Erstelle Tracking Kennung",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Betriebssysteme", "metrics.operating-systems": "Betriebssysteme",
"metrics.page-views": "Seitenaufrufe", "metrics.page-views": "Seitenaufrufe",
"metrics.pages": "Seiten", "metrics.pages": "Seiten",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referrer", "metrics.referrers": "Referrer",
"metrics.screens": "Bildschirmauflösungen", "metrics.screens": "Bildschirmauflösungen",
"metrics.unique-visitors": "Eindeutige Besucher", "metrics.unique-visitors": "Eindeutige Besucher",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Aufrufe", "metrics.views": "Aufrufe",
"metrics.visitors": "Besucher" "metrics.visitors": "Besucher"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Προσθήκη ιστότοπου", "label.add-website": "Προσθήκη ιστότοπου",
"label.administrator": "Διαχειριστής", "label.administrator": "Διαχειριστής",
"label.all": "All", "label.all": "All",
"label.all-events": "All events",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "All websites", "label.all-websites": "All websites",
"label.back": "Πίσω", "label.back": "Πίσω",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Αντιγράφηκε!", "message.copied": "Αντιγράφηκε!",
"message.delete-warning": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης.", "message.delete-warning": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Κάτι πήγε στραβά.", "message.failure": "Κάτι πήγε στραβά.",
"message.get-share-url": "Λήψη URL κοινής χρήσης", "message.get-share-url": "Λήψη URL κοινής χρήσης",
"message.get-tracking-code": "Λήψη κώδικα παρακολούθησης", "message.get-tracking-code": "Λήψη κώδικα παρακολούθησης",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Λειτουργικά συστήματα", "metrics.operating-systems": "Λειτουργικά συστήματα",
"metrics.page-views": "Προβολές σελίδας", "metrics.page-views": "Προβολές σελίδας",
"metrics.pages": "Σελίδες", "metrics.pages": "Σελίδες",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Παραπομπές", "metrics.referrers": "Παραπομπές",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Μοναδικοί επισκέπτες", "metrics.unique-visitors": "Μοναδικοί επισκέπτες",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Προβολές", "metrics.views": "Προβολές",
"metrics.visitors": "Επισκέπτες" "metrics.visitors": "Επισκέπτες"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Add website", "label.add-website": "Add website",
"label.administrator": "Administrator", "label.administrator": "Administrator",
"label.all": "All", "label.all": "All",
"label.all-events": "All events",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "All websites", "label.all-websites": "All websites",
"label.back": "Back", "label.back": "Back",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are you sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are you sure you want to reset {target}'s statistics?",
"message.copied": "Copied!", "message.copied": "Copied!",
"message.delete-warning": "All associated data will be deleted as well.", "message.delete-warning": "All associated data will be deleted as well.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Something went wrong.", "message.failure": "Something went wrong.",
"message.get-share-url": "Get share URL", "message.get-share-url": "Get share URL",
"message.get-tracking-code": "Get tracking code", "message.get-tracking-code": "Get tracking code",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operating systems", "metrics.operating-systems": "Operating systems",
"metrics.page-views": "Page views", "metrics.page-views": "Page views",
"metrics.pages": "Pages", "metrics.pages": "Pages",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referrers", "metrics.referrers": "Referrers",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unique visitors", "metrics.unique-visitors": "Unique visitors",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Views", "metrics.views": "Views",
"metrics.visitors": "Visitors" "metrics.visitors": "Visitors"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Add website", "label.add-website": "Add website",
"label.administrator": "Administrator", "label.administrator": "Administrator",
"label.all": "All", "label.all": "All",
"label.all-events": "All events",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "All websites", "label.all-websites": "All websites",
"label.back": "Back", "label.back": "Back",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are you sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are you sure you want to reset {target}'s statistics?",
"message.copied": "Copied!", "message.copied": "Copied!",
"message.delete-warning": "All associated data will be deleted as well.", "message.delete-warning": "All associated data will be deleted as well.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Something went wrong.", "message.failure": "Something went wrong.",
"message.get-share-url": "Get share URL", "message.get-share-url": "Get share URL",
"message.get-tracking-code": "Get tracking code", "message.get-tracking-code": "Get tracking code",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operating systems", "metrics.operating-systems": "Operating systems",
"metrics.page-views": "Page views", "metrics.page-views": "Page views",
"metrics.pages": "Pages", "metrics.pages": "Pages",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referrers", "metrics.referrers": "Referrers",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unique visitors", "metrics.unique-visitors": "Unique visitors",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Views", "metrics.views": "Views",
"metrics.visitors": "Visitors" "metrics.visitors": "Visitors"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Agregar sitio", "label.add-website": "Agregar sitio",
"label.administrator": "Administrador", "label.administrator": "Administrador",
"label.all": "Todos", "label.all": "Todos",
"label.all-events": "Todos los eventos",
"label.all-time": "Todos los tiempos", "label.all-time": "Todos los tiempos",
"label.all-websites": "Todos los sitios", "label.all-websites": "Todos los sitios",
"label.back": "Atrás", "label.back": "Atrás",
@ -68,6 +67,7 @@
"message.confirm-reset": "¿Seguro que deseas restablecer las estadísticas de {target}?", "message.confirm-reset": "¿Seguro que deseas restablecer las estadísticas de {target}?",
"message.copied": "¡Copiado!", "message.copied": "¡Copiado!",
"message.delete-warning": "Toda la información relacionada será eliminada.", "message.delete-warning": "Toda la información relacionada será eliminada.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Algo falló.", "message.failure": "Algo falló.",
"message.get-share-url": "Obtener URL para compartir", "message.get-share-url": "Obtener URL para compartir",
"message.get-tracking-code": "Obtener código de rastreo", "message.get-tracking-code": "Obtener código de rastreo",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemas operativos", "metrics.operating-systems": "Sistemas operativos",
"metrics.page-views": "Vistas", "metrics.page-views": "Vistas",
"metrics.pages": "Páginas", "metrics.pages": "Páginas",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referentes", "metrics.referrers": "Referentes",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitantes únicos", "metrics.unique-visitors": "Visitantes únicos",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vistas", "metrics.views": "Vistas",
"metrics.visitors": "Visitantes" "metrics.visitors": "Visitantes"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "افزودن وب‌سایت", "label.add-website": "افزودن وب‌سایت",
"label.administrator": "مدیر", "label.administrator": "مدیر",
"label.all": "همه", "label.all": "همه",
"label.all-events": "همه‌ی رویدادها",
"label.all-time": "همه زمان", "label.all-time": "همه زمان",
"label.all-websites": "همه‌ی وب‌سایت‌ها", "label.all-websites": "همه‌ی وب‌سایت‌ها",
"label.back": "برگشت", "label.back": "برگشت",
@ -68,6 +67,7 @@
"message.confirm-reset": "آیا از بازنشانی آمار {target} مطمئن هستید?", "message.confirm-reset": "آیا از بازنشانی آمار {target} مطمئن هستید?",
"message.copied": "کپی شد!", "message.copied": "کپی شد!",
"message.delete-warning": "همه‌ی داده‌های مرتبط هم حذف خواهد شد.", "message.delete-warning": "همه‌ی داده‌های مرتبط هم حذف خواهد شد.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "مشکلی پیش آمده است.", "message.failure": "مشکلی پیش آمده است.",
"message.get-share-url": "دریافت URL برای اشتراک گذاری", "message.get-share-url": "دریافت URL برای اشتراک گذاری",
"message.get-tracking-code": "گرفتن کد رهگیری", "message.get-tracking-code": "گرفتن کد رهگیری",
@ -103,15 +103,10 @@
"metrics.operating-systems": "سیستم‌عامل‌ها", "metrics.operating-systems": "سیستم‌عامل‌ها",
"metrics.page-views": "بازدید صفحه", "metrics.page-views": "بازدید صفحه",
"metrics.pages": "صفحه‌ها", "metrics.pages": "صفحه‌ها",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "ارجاع دهندگان", "metrics.referrers": "ارجاع دهندگان",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "بازدیدکننده‌های یکتا", "metrics.unique-visitors": "بازدیدکننده‌های یکتا",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "بازدید", "metrics.views": "بازدید",
"metrics.visitors": "بازدیدکننده" "metrics.visitors": "بازدیدکننده"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Lisää verkkosivu", "label.add-website": "Lisää verkkosivu",
"label.administrator": "Järjestelmänvalvoja", "label.administrator": "Järjestelmänvalvoja",
"label.all": "Kaikki", "label.all": "Kaikki",
"label.all-events": "Kaikki tapahtumat",
"label.all-time": "Alusta lähtien", "label.all-time": "Alusta lähtien",
"label.all-websites": "Kaikki verkkosivut", "label.all-websites": "Kaikki verkkosivut",
"label.back": "Takaisin", "label.back": "Takaisin",
@ -68,6 +67,7 @@
"message.confirm-reset": "Haluatko varmasti poistaa sivuston {target} tilastot?", "message.confirm-reset": "Haluatko varmasti poistaa sivuston {target} tilastot?",
"message.copied": "Kopioitu!", "message.copied": "Kopioitu!",
"message.delete-warning": "Kaikki siihen liittyvät tiedot poistetaan.", "message.delete-warning": "Kaikki siihen liittyvät tiedot poistetaan.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Jotain meni pieleen.", "message.failure": "Jotain meni pieleen.",
"message.get-share-url": "Hanki jakamisen URL-osoite", "message.get-share-url": "Hanki jakamisen URL-osoite",
"message.get-tracking-code": "Hanki seurantakoodi", "message.get-tracking-code": "Hanki seurantakoodi",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Käyttöjärjestelmät", "metrics.operating-systems": "Käyttöjärjestelmät",
"metrics.page-views": "Sivun näyttökerrat", "metrics.page-views": "Sivun näyttökerrat",
"metrics.pages": "Sivut", "metrics.pages": "Sivut",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Viittaajat", "metrics.referrers": "Viittaajat",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Yksittäiset kävijät", "metrics.unique-visitors": "Yksittäiset kävijät",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Näyttökerrat", "metrics.views": "Näyttökerrat",
"metrics.visitors": "Vierailijat" "metrics.visitors": "Vierailijat"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Legg heimasíðu afturat", "label.add-website": "Legg heimasíðu afturat",
"label.administrator": "Fyrisitari", "label.administrator": "Fyrisitari",
"label.all": "Alt", "label.all": "Alt",
"label.all-events": "All events",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "Allar heimasíður", "label.all-websites": "Allar heimasíður",
"label.back": "Aftur", "label.back": "Aftur",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Avrita!", "message.copied": "Avrita!",
"message.delete-warning": "Øll data ið er knýtt at verður eisini strika.", "message.delete-warning": "Øll data ið er knýtt at verður eisini strika.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Okkurt bleiv gali.", "message.failure": "Okkurt bleiv gali.",
"message.get-share-url": "Fá leinku sum tú kanst deila", "message.get-share-url": "Fá leinku sum tú kanst deila",
"message.get-tracking-code": "Fá sporings kotu", "message.get-tracking-code": "Fá sporings kotu",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Stýrikervir", "metrics.operating-systems": "Stýrikervir",
"metrics.page-views": "Opnaðar síðir", "metrics.page-views": "Opnaðar síðir",
"metrics.pages": "Síðir", "metrics.pages": "Síðir",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Framsendingar", "metrics.referrers": "Framsendingar",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Einsýna vitjanir", "metrics.unique-visitors": "Einsýna vitjanir",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Sýningar", "metrics.views": "Sýningar",
"metrics.visitors": "Vitjandi" "metrics.visitors": "Vitjandi"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Ajouter un site", "label.add-website": "Ajouter un site",
"label.administrator": "Administrateur", "label.administrator": "Administrateur",
"label.all": "Tout", "label.all": "Tout",
"label.all-events": "Tous les événements",
"label.all-time": "Toutes les données", "label.all-time": "Toutes les données",
"label.all-websites": "Tous les sites web", "label.all-websites": "Tous les sites web",
"label.back": "Retour", "label.back": "Retour",
@ -68,6 +67,7 @@
"message.confirm-reset": "Êtes-vous sûr de vouloir réinistialiser les statistiques de {target} ?", "message.confirm-reset": "Êtes-vous sûr de vouloir réinistialiser les statistiques de {target} ?",
"message.copied": "Copié !", "message.copied": "Copié !",
"message.delete-warning": "Toutes les données associées seront également supprimées.", "message.delete-warning": "Toutes les données associées seront également supprimées.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Un problème est survenu.", "message.failure": "Un problème est survenu.",
"message.get-share-url": "Obtenir l'URL de partage", "message.get-share-url": "Obtenir l'URL de partage",
"message.get-tracking-code": "Obtenir le code de suivi", "message.get-tracking-code": "Obtenir le code de suivi",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Systèmes d'exploitation", "metrics.operating-systems": "Systèmes d'exploitation",
"metrics.page-views": "Pages vues", "metrics.page-views": "Pages vues",
"metrics.pages": "Pages", "metrics.pages": "Pages",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Sources", "metrics.referrers": "Sources",
"metrics.screens": "Tailles d'écran", "metrics.screens": "Tailles d'écran",
"metrics.unique-visitors": "Visiteurs uniques", "metrics.unique-visitors": "Visiteurs uniques",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vues", "metrics.views": "Vues",
"metrics.visitors": "Visiteurs" "metrics.visitors": "Visiteurs"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Engadir sitio web", "label.add-website": "Engadir sitio web",
"label.administrator": "Administradora", "label.administrator": "Administradora",
"label.all": "Todo", "label.all": "Todo",
"label.all-events": "Tódolos eventos",
"label.all-time": "Sempre", "label.all-time": "Sempre",
"label.all-websites": "Tódolos sitios web", "label.all-websites": "Tódolos sitios web",
"label.back": "Atrás", "label.back": "Atrás",
@ -68,6 +67,7 @@
"message.confirm-reset": "Tes a certeza de querer restablecer as estatísticas de {target}?", "message.confirm-reset": "Tes a certeza de querer restablecer as estatísticas de {target}?",
"message.copied": "Copiado!", "message.copied": "Copiado!",
"message.delete-warning": "Tamén serán borrados tódolos datos asociados.", "message.delete-warning": "Tamén serán borrados tódolos datos asociados.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Houbo un fallo.", "message.failure": "Houbo un fallo.",
"message.get-share-url": "Obter URL de compartición", "message.get-share-url": "Obter URL de compartición",
"message.get-tracking-code": "Obter código de seguimento", "message.get-tracking-code": "Obter código de seguimento",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemas operativos", "metrics.operating-systems": "Sistemas operativos",
"metrics.page-views": "Vistas de páxinas", "metrics.page-views": "Vistas de páxinas",
"metrics.pages": "Páxinas", "metrics.pages": "Páxinas",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Orixes", "metrics.referrers": "Orixes",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitas únicas", "metrics.unique-visitors": "Visitas únicas",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizacións", "metrics.views": "Visualizacións",
"metrics.visitors": "Visitantes" "metrics.visitors": "Visitantes"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "הוספת אתר", "label.add-website": "הוספת אתר",
"label.administrator": "מנהל", "label.administrator": "מנהל",
"label.all": "הכל", "label.all": "הכל",
"label.all-events": "All events",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "כל האתרים", "label.all-websites": "כל האתרים",
"label.back": "חזרה", "label.back": "חזרה",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "הועתק!", "message.copied": "הועתק!",
"message.delete-warning": "כל המידע המקושר יימחק", "message.delete-warning": "כל המידע המקושר יימחק",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "משהו השתבש", "message.failure": "משהו השתבש",
"message.get-share-url": "קבלת URL שיתוף", "message.get-share-url": "קבלת URL שיתוף",
"message.get-tracking-code": "קבלת קוד מעקב", "message.get-tracking-code": "קבלת קוד מעקב",
@ -103,15 +103,10 @@
"metrics.operating-systems": "מערכות הפעלה", "metrics.operating-systems": "מערכות הפעלה",
"metrics.page-views": "צפיות בדפים", "metrics.page-views": "צפיות בדפים",
"metrics.pages": "דפים", "metrics.pages": "דפים",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "מפנים", "metrics.referrers": "מפנים",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "מבקרים ייחודיים", "metrics.unique-visitors": "מבקרים ייחודיים",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "צפיות", "metrics.views": "צפיות",
"metrics.visitors": "מבקרים" "metrics.visitors": "מבקרים"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "वेबसाइट", "label.add-website": "वेबसाइट",
"label.administrator": "प्रशासक", "label.administrator": "प्रशासक",
"label.all": "सब", "label.all": "सब",
"label.all-events": "All events",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "सभी वेबसाइटें", "label.all-websites": "सभी वेबसाइटें",
"label.back": "पीछे", "label.back": "पीछे",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "कॉपी हो गया!", "message.copied": "कॉपी हो गया!",
"message.delete-warning": "सभी संबद्ध डेटा को भी हटा दिया जाएगा।", "message.delete-warning": "सभी संबद्ध डेटा को भी हटा दिया जाएगा।",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "कुछ गलत हो गया।", "message.failure": "कुछ गलत हो गया।",
"message.get-share-url": "शेयर URL प्राप्त करें", "message.get-share-url": "शेयर URL प्राप्त करें",
"message.get-tracking-code": "ट्रैकिंग कोड प्राप्त करें", "message.get-tracking-code": "ट्रैकिंग कोड प्राप्त करें",
@ -103,15 +103,10 @@
"metrics.operating-systems": "ऑपरेटिंग सिस्टम", "metrics.operating-systems": "ऑपरेटिंग सिस्टम",
"metrics.page-views": "पृष्ठ दृश्य", "metrics.page-views": "पृष्ठ दृश्य",
"metrics.pages": "पृष्ठों", "metrics.pages": "पृष्ठों",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "सन्दर्भदाता", "metrics.referrers": "सन्दर्भदाता",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "अद्वितीय आगंतुकों", "metrics.unique-visitors": "अद्वितीय आगंतुकों",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "दृश्य", "metrics.views": "दृश्य",
"metrics.visitors": "आगंतुकों" "metrics.visitors": "आगंतुकों"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Weboldal hozzáadása", "label.add-website": "Weboldal hozzáadása",
"label.administrator": "Adminisztrátor", "label.administrator": "Adminisztrátor",
"label.all": "Összes", "label.all": "Összes",
"label.all-events": "Összes esemény",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "Összes weboldal", "label.all-websites": "Összes weboldal",
"label.back": "Vissza", "label.back": "Vissza",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Kimásolva!", "message.copied": "Kimásolva!",
"message.delete-warning": "Minden társított adat törlésre kerül.", "message.delete-warning": "Minden társított adat törlésre kerül.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Valami baj történt.", "message.failure": "Valami baj történt.",
"message.get-share-url": "Megosztási URL kimásolása", "message.get-share-url": "Megosztási URL kimásolása",
"message.get-tracking-code": "Követési kód kimásolása", "message.get-tracking-code": "Követési kód kimásolása",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operációs rendszerek", "metrics.operating-systems": "Operációs rendszerek",
"metrics.page-views": "Oldalmegtekintések", "metrics.page-views": "Oldalmegtekintések",
"metrics.pages": "Oldalak", "metrics.pages": "Oldalak",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Hivatkozók", "metrics.referrers": "Hivatkozók",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Egyedi látogatók", "metrics.unique-visitors": "Egyedi látogatók",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Megtekintések", "metrics.views": "Megtekintések",
"metrics.visitors": "Látogatók" "metrics.visitors": "Látogatók"
} }

View File

@ -4,8 +4,7 @@
"label.add-website": "Tambah situs web", "label.add-website": "Tambah situs web",
"label.administrator": "Pengelola", "label.administrator": "Pengelola",
"label.all": "Semua", "label.all": "Semua",
"label.all-events": "Semua peristiwa", "label.all-time": "Semua waktu",
"label.all-time": "All time",
"label.all-websites": "Semua website", "label.all-websites": "Semua website",
"label.back": "Kembali", "label.back": "Kembali",
"label.cancel": "Batal", "label.cancel": "Batal",
@ -28,7 +27,7 @@
"label.enable-share-url": "Aktifkan URL berbagi", "label.enable-share-url": "Aktifkan URL berbagi",
"label.invalid": "Tidak valid", "label.invalid": "Tidak valid",
"label.invalid-domain": "Domain tidak valid", "label.invalid-domain": "Domain tidak valid",
"label.language": "Language", "label.language": "Bahasa",
"label.last-days": "{x} hari terakhir", "label.last-days": "{x} hari terakhir",
"label.last-hours": "{x} jam terakhir", "label.last-hours": "{x} jam terakhir",
"label.logged-in-as": "Masuk sebagai {username}", "label.logged-in-as": "Masuk sebagai {username}",
@ -38,7 +37,7 @@
"label.name": "Nama", "label.name": "Nama",
"label.new-password": "Kata sandi baru", "label.new-password": "Kata sandi baru",
"label.none": "None", "label.none": "None",
"label.owner": "Owner", "label.owner": "Pemilik",
"label.password": "Kata sandi", "label.password": "Kata sandi",
"label.passwords-dont-match": "Kata sandi tidak cocok", "label.passwords-dont-match": "Kata sandi tidak cocok",
"label.profile": "Profil", "label.profile": "Profil",
@ -52,7 +51,7 @@
"label.settings": "Pengaturan", "label.settings": "Pengaturan",
"label.share-url": "Bagikan URL", "label.share-url": "Bagikan URL",
"label.single-day": "Sehari", "label.single-day": "Sehari",
"label.theme": "Theme", "label.theme": "Tema",
"label.this-month": "Bulan ini", "label.this-month": "Bulan ini",
"label.this-week": "Minggu ini", "label.this-week": "Minggu ini",
"label.this-year": "Tahun ini", "label.this-year": "Tahun ini",
@ -65,9 +64,10 @@
"label.websites": "Situs web", "label.websites": "Situs web",
"message.active-users": "{x} pengunjung saat ini", "message.active-users": "{x} pengunjung saat ini",
"message.confirm-delete": "Apakah kamu yakin ingin menghapus {target}?", "message.confirm-delete": "Apakah kamu yakin ingin menghapus {target}?",
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Anda yakin ingin mengatur ulang statistik {target}?",
"message.copied": "Tersalin!", "message.copied": "Tersalin!",
"message.delete-warning": "Semua data terkait juga akan dihapus.", "message.delete-warning": "Semua data terkait juga akan dihapus.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ada yang salah.", "message.failure": "Ada yang salah.",
"message.get-share-url": "Dapatkan URL berbagi", "message.get-share-url": "Dapatkan URL berbagi",
"message.get-tracking-code": "Dapatkan kode pelacakan", "message.get-tracking-code": "Dapatkan kode pelacakan",
@ -82,8 +82,8 @@
"message.reset-warning": "Semua statistik pada website ini akan dihapus, tetapi kode lacak akan tetap terpasang", "message.reset-warning": "Semua statistik pada website ini akan dihapus, tetapi kode lacak akan tetap terpasang",
"message.save-success": "Berhasil disimpan.", "message.save-success": "Berhasil disimpan.",
"message.share-url": "Ini adalah URL yang dibagikan secara publik untuk {target}.", "message.share-url": "Ini adalah URL yang dibagikan secara publik untuk {target}.",
"message.toggle-charts": "Toggle charts", "message.toggle-charts": "Buka grafik",
"message.track-stats": "Untuk melacak statistik {target}, tempatkan kode berikut di bagian {head} situs web anda.", "message.track-stats": "Untuk melacak statistik {target}, tempatkan kode berikut di bagian {head} situs web nda.",
"message.type-delete": "Ketikkan {delete} pada kotak di bawah untuk konfirmasi.", "message.type-delete": "Ketikkan {delete} pada kotak di bawah untuk konfirmasi.",
"message.type-reset": "Ketikkan {reset} pada kotak di bawah untuk konfirmasi.", "message.type-reset": "Ketikkan {reset} pada kotak di bawah untuk konfirmasi.",
"metrics.actions": "Aksi", "metrics.actions": "Aksi",
@ -99,19 +99,14 @@
"metrics.events": "Perihal", "metrics.events": "Perihal",
"metrics.filter.combined": "Gabungan", "metrics.filter.combined": "Gabungan",
"metrics.filter.raw": "Mentah", "metrics.filter.raw": "Mentah",
"metrics.languages": "Languages", "metrics.languages": "Bahasa",
"metrics.operating-systems": "Sistem Operasi", "metrics.operating-systems": "Sistem Operasi",
"metrics.page-views": "Tampilan halaman", "metrics.page-views": "Tampilan halaman",
"metrics.pages": "Halaman", "metrics.pages": "Halaman",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Perujuk", "metrics.referrers": "Perujuk",
"metrics.screens": "Screens", "metrics.screens": "Layar",
"metrics.unique-visitors": "Pengunjung unik", "metrics.unique-visitors": "Pengunjung unik",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Tampilan", "metrics.views": "Tampilan",
"metrics.visitors": "Pengunjung" "metrics.visitors": "Pengunjung"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Aggiungi sito", "label.add-website": "Aggiungi sito",
"label.administrator": "Amministratore", "label.administrator": "Amministratore",
"label.all": "Tutto", "label.all": "Tutto",
"label.all-events": "Tutti gli eventi",
"label.all-time": "Sempre", "label.all-time": "Sempre",
"label.all-websites": "Tutti i siti web", "label.all-websites": "Tutti i siti web",
"label.back": "Indietro", "label.back": "Indietro",
@ -68,6 +67,7 @@
"message.confirm-reset": "Sei sicuro di voler azzerare le statistiche di {target}?", "message.confirm-reset": "Sei sicuro di voler azzerare le statistiche di {target}?",
"message.copied": "Copiato!", "message.copied": "Copiato!",
"message.delete-warning": "Saranno eliminati anche tutti i dati associati.", "message.delete-warning": "Saranno eliminati anche tutti i dati associati.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Si è verificato un errore.", "message.failure": "Si è verificato un errore.",
"message.get-share-url": "Ottieni l'URL di condivisione", "message.get-share-url": "Ottieni l'URL di condivisione",
"message.get-tracking-code": "Ottieni il codice di tracking", "message.get-tracking-code": "Ottieni il codice di tracking",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemi operativi", "metrics.operating-systems": "Sistemi operativi",
"metrics.page-views": "Visualizzazioni di pagina", "metrics.page-views": "Visualizzazioni di pagina",
"metrics.pages": "Pagine", "metrics.pages": "Pagine",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referrers", "metrics.referrers": "Referrers",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitatori unici", "metrics.unique-visitors": "Visitatori unici",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizzazioni", "metrics.views": "Visualizzazioni",
"metrics.visitors": "Visitatori" "metrics.visitors": "Visitatori"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Webサイトの追加", "label.add-website": "Webサイトの追加",
"label.administrator": "管理者", "label.administrator": "管理者",
"label.all": "すべて表示", "label.all": "すべて表示",
"label.all-events": "All events",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "すべてのWebサイト", "label.all-websites": "すべてのWebサイト",
"label.back": "戻る", "label.back": "戻る",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "コピーしました!", "message.copied": "コピーしました!",
"message.delete-warning": "関連するすべてのデータも削除されます。", "message.delete-warning": "関連するすべてのデータも削除されます。",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "問題が発生しました。", "message.failure": "問題が発生しました。",
"message.get-share-url": "共有リンクを取得", "message.get-share-url": "共有リンクを取得",
"message.get-tracking-code": "トラッキングコードを取得", "message.get-tracking-code": "トラッキングコードを取得",
@ -103,15 +103,10 @@
"metrics.operating-systems": "OS", "metrics.operating-systems": "OS",
"metrics.page-views": "閲覧数", "metrics.page-views": "閲覧数",
"metrics.pages": "ページ", "metrics.pages": "ページ",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "リファラー", "metrics.referrers": "リファラー",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "ユニーク訪問者数", "metrics.unique-visitors": "ユニーク訪問者数",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "閲覧数", "metrics.views": "閲覧数",
"metrics.visitors": "訪問者数" "metrics.visitors": "訪問者数"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "웹사이트 추가", "label.add-website": "웹사이트 추가",
"label.administrator": "관리자", "label.administrator": "관리자",
"label.all": "전체", "label.all": "전체",
"label.all-events": "모든 이벤트",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "모든 웹사이트", "label.all-websites": "모든 웹사이트",
"label.back": "뒤로", "label.back": "뒤로",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "복사했습니다!", "message.copied": "복사했습니다!",
"message.delete-warning": "관련된 모든 데이터도 삭제됩니다.", "message.delete-warning": "관련된 모든 데이터도 삭제됩니다.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "오류가 발생하였습니다.", "message.failure": "오류가 발생하였습니다.",
"message.get-share-url": "공유 URL 가져오기", "message.get-share-url": "공유 URL 가져오기",
"message.get-tracking-code": "추적 코드 가져오기", "message.get-tracking-code": "추적 코드 가져오기",
@ -103,15 +103,10 @@
"metrics.operating-systems": "운영체제", "metrics.operating-systems": "운영체제",
"metrics.page-views": "페이지 뷰(PV)", "metrics.page-views": "페이지 뷰(PV)",
"metrics.pages": "페이지", "metrics.pages": "페이지",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "리퍼러", "metrics.referrers": "리퍼러",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "순방문자(UV)", "metrics.unique-visitors": "순방문자(UV)",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "조회수", "metrics.views": "조회수",
"metrics.visitors": "방문객" "metrics.visitors": "방문객"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Pridėti svetainę", "label.add-website": "Pridėti svetainę",
"label.administrator": "Administratorius", "label.administrator": "Administratorius",
"label.all": "Visi", "label.all": "Visi",
"label.all-events": "Visi įvykiai",
"label.all-time": "Visas laikotarpis", "label.all-time": "Visas laikotarpis",
"label.all-websites": "Visos svetainės", "label.all-websites": "Visos svetainės",
"label.back": "Atgal", "label.back": "Atgal",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are esate tikri, jog norite atstatyti svetainės {target} statistikos duomenis?", "message.confirm-reset": "Are esate tikri, jog norite atstatyti svetainės {target} statistikos duomenis?",
"message.copied": "Nukopijuota!", "message.copied": "Nukopijuota!",
"message.delete-warning": "Visi susiję duomenys taip pat bus ištrinti.", "message.delete-warning": "Visi susiję duomenys taip pat bus ištrinti.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Kažkas įvyko ne taip.", "message.failure": "Kažkas įvyko ne taip.",
"message.get-share-url": "Gauti bendrinimo nuorodą", "message.get-share-url": "Gauti bendrinimo nuorodą",
"message.get-tracking-code": "Gauti sekimo kodą", "message.get-tracking-code": "Gauti sekimo kodą",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operacinės sistemos", "metrics.operating-systems": "Operacinės sistemos",
"metrics.page-views": "Puslapių peržiūros", "metrics.page-views": "Puslapių peržiūros",
"metrics.pages": "Puslapiai", "metrics.pages": "Puslapiai",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referrers", "metrics.referrers": "Referrers",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unikalūs lankytojai", "metrics.unique-visitors": "Unikalūs lankytojai",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Peržiūros", "metrics.views": "Peržiūros",
"metrics.visitors": "Lankytojai" "metrics.visitors": "Lankytojai"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Веб нэмэх", "label.add-website": "Веб нэмэх",
"label.administrator": "Админ", "label.administrator": "Админ",
"label.all": "Бүх", "label.all": "Бүх",
"label.all-events": "Бүх үйл явдал",
"label.all-time": "Бүх цаг үеийн", "label.all-time": "Бүх цаг үеийн",
"label.all-websites": "Бүх вебүүд", "label.all-websites": "Бүх вебүүд",
"label.back": "Буцах", "label.back": "Буцах",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Хуулсан!", "message.copied": "Хуулсан!",
"message.delete-warning": "Үүнтэй холбоотой бүх өгөгдөл устах болно.", "message.delete-warning": "Үүнтэй холбоотой бүх өгөгдөл устах болно.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ямар нэг зүйл буруу боллоо.", "message.failure": "Ямар нэг зүйл буруу боллоо.",
"message.get-share-url": "Хуваалцах холбоос авах", "message.get-share-url": "Хуваалцах холбоос авах",
"message.get-tracking-code": "Мөрдөх код авах", "message.get-tracking-code": "Мөрдөх код авах",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Үйлдлийн систем", "metrics.operating-systems": "Үйлдлийн систем",
"metrics.page-views": "Хуудас үзсэн", "metrics.page-views": "Хуудас үзсэн",
"metrics.pages": "Хуудас", "metrics.pages": "Хуудас",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Чиглүүлэгч", "metrics.referrers": "Чиглүүлэгч",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Зочин", "metrics.unique-visitors": "Зочин",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Үзсэн", "metrics.views": "Үзсэн",
"metrics.visitors": "Зочин" "metrics.visitors": "Зочин"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Tambah laman web", "label.add-website": "Tambah laman web",
"label.administrator": "Pentadbir", "label.administrator": "Pentadbir",
"label.all": "Semua", "label.all": "Semua",
"label.all-events": "Semua peristiwa",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "Semua laman web", "label.all-websites": "Semua laman web",
"label.back": "Kembali", "label.back": "Kembali",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Disalin!", "message.copied": "Disalin!",
"message.delete-warning": "Semua data yang berkaitan juga akan dihapuskan.", "message.delete-warning": "Semua data yang berkaitan juga akan dihapuskan.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ada yang tidak kena.", "message.failure": "Ada yang tidak kena.",
"message.get-share-url": "Dapatkan URL berkongsi", "message.get-share-url": "Dapatkan URL berkongsi",
"message.get-tracking-code": "Dapatkan kod penjejakan", "message.get-tracking-code": "Dapatkan kod penjejakan",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistem operasi", "metrics.operating-systems": "Sistem operasi",
"metrics.page-views": "Paparan halaman", "metrics.page-views": "Paparan halaman",
"metrics.pages": "Halaman", "metrics.pages": "Halaman",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Perujuk", "metrics.referrers": "Perujuk",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Pelawat unik", "metrics.unique-visitors": "Pelawat unik",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Lawatan", "metrics.views": "Lawatan",
"metrics.visitors": "Pelawat" "metrics.visitors": "Pelawat"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Legg til nettsted", "label.add-website": "Legg til nettsted",
"label.administrator": "Administrator", "label.administrator": "Administrator",
"label.all": "Alle", "label.all": "Alle",
"label.all-events": "Alle hendelser",
"label.all-time": "Noensinne", "label.all-time": "Noensinne",
"label.all-websites": "Alle nettsteder", "label.all-websites": "Alle nettsteder",
"label.back": "Tilbake", "label.back": "Tilbake",
@ -68,6 +67,7 @@
"message.confirm-reset": "Er du sikker på at du vil nullstille {target}'s statistikk?", "message.confirm-reset": "Er du sikker på at du vil nullstille {target}'s statistikk?",
"message.copied": "Kopiert!", "message.copied": "Kopiert!",
"message.delete-warning": "Alle tilknyttede data slettes også.", "message.delete-warning": "Alle tilknyttede data slettes også.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Noe gikk galt.", "message.failure": "Noe gikk galt.",
"message.get-share-url": "Få delings-URL", "message.get-share-url": "Få delings-URL",
"message.get-tracking-code": "Få sporingskode", "message.get-tracking-code": "Få sporingskode",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operativsystemer", "metrics.operating-systems": "Operativsystemer",
"metrics.page-views": "Sidevisninger", "metrics.page-views": "Sidevisninger",
"metrics.pages": "Sider", "metrics.pages": "Sider",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referanser", "metrics.referrers": "Referanser",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unike besøkende", "metrics.unique-visitors": "Unike besøkende",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visninger", "metrics.views": "Visninger",
"metrics.visitors": "Besøkende" "metrics.visitors": "Besøkende"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Website toevoegen", "label.add-website": "Website toevoegen",
"label.administrator": "Administrator", "label.administrator": "Administrator",
"label.all": "Alles", "label.all": "Alles",
"label.all-events": "Alle gebeurtenissen",
"label.all-time": "Onbeperkt", "label.all-time": "Onbeperkt",
"label.all-websites": "Alle websites", "label.all-websites": "Alle websites",
"label.back": "Terug", "label.back": "Terug",
@ -68,6 +67,7 @@
"message.confirm-reset": "Weet je zeker dat je de statistieken van {target} opnieuw wilt instellen?", "message.confirm-reset": "Weet je zeker dat je de statistieken van {target} opnieuw wilt instellen?",
"message.copied": "Gekopiëerd!", "message.copied": "Gekopiëerd!",
"message.delete-warning": "Alle verwante gegezens zullen ook verwijderd worden.", "message.delete-warning": "Alle verwante gegezens zullen ook verwijderd worden.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Er is iets misgegaan.", "message.failure": "Er is iets misgegaan.",
"message.get-share-url": "Openbare URL", "message.get-share-url": "Openbare URL",
"message.get-tracking-code": "Tracking code", "message.get-tracking-code": "Tracking code",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Besturingssystemen", "metrics.operating-systems": "Besturingssystemen",
"metrics.page-views": "Paginaweergaven", "metrics.page-views": "Paginaweergaven",
"metrics.pages": "Pagina's", "metrics.pages": "Pagina's",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Verwijzers", "metrics.referrers": "Verwijzers",
"metrics.screens": "Schermen", "metrics.screens": "Schermen",
"metrics.unique-visitors": "Unieke bezoekers", "metrics.unique-visitors": "Unieke bezoekers",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Weergaven", "metrics.views": "Weergaven",
"metrics.visitors": "Bezoekers" "metrics.visitors": "Bezoekers"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Dodaj witrynę", "label.add-website": "Dodaj witrynę",
"label.administrator": "Administrator", "label.administrator": "Administrator",
"label.all": "Wszystkie", "label.all": "Wszystkie",
"label.all-events": "Wszystkie wydarzenia",
"label.all-time": "Cały czas", "label.all-time": "Cały czas",
"label.all-websites": "Wszystkie witryny", "label.all-websites": "Wszystkie witryny",
"label.back": "Powrót", "label.back": "Powrót",
@ -68,6 +67,7 @@
"message.confirm-reset": "Czy na pewno chcesz zresetować statystyki {target}?", "message.confirm-reset": "Czy na pewno chcesz zresetować statystyki {target}?",
"message.copied": "Skopiowano!", "message.copied": "Skopiowano!",
"message.delete-warning": "Wszystkie powiązane dane również zostaną usunięte.", "message.delete-warning": "Wszystkie powiązane dane również zostaną usunięte.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Coś poszło nie tak.", "message.failure": "Coś poszło nie tak.",
"message.get-share-url": "Uzyskaj adres URL udostępniania", "message.get-share-url": "Uzyskaj adres URL udostępniania",
"message.get-tracking-code": "Pobierz kod śledzenia", "message.get-tracking-code": "Pobierz kod śledzenia",
@ -103,15 +103,10 @@
"metrics.operating-systems": "System operacyjny", "metrics.operating-systems": "System operacyjny",
"metrics.page-views": "Wyświetlenia strony", "metrics.page-views": "Wyświetlenia strony",
"metrics.pages": "Strony", "metrics.pages": "Strony",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Źródła odsyłające", "metrics.referrers": "Źródła odsyłające",
"metrics.screens": "Ekrany", "metrics.screens": "Ekrany",
"metrics.unique-visitors": "Unikalni odwiedzający", "metrics.unique-visitors": "Unikalni odwiedzający",
"metrics.utm": "Kampanie UTM",
"metrics.utm_campaign": "Kampania",
"metrics.utm_content": "Treść",
"metrics.utm_medium": "Medium",
"metrics.utm_source": "Źródło",
"metrics.utm_term": "Słowa kluczowe",
"metrics.views": "Wyświetlenia", "metrics.views": "Wyświetlenia",
"metrics.visitors": "Odwiedzający" "metrics.visitors": "Odwiedzający"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Adicionar site", "label.add-website": "Adicionar site",
"label.administrator": "Administrador", "label.administrator": "Administrador",
"label.all": "Todos", "label.all": "Todos",
"label.all-events": "Todos os eventos",
"label.all-time": "Todo o período", "label.all-time": "Todo o período",
"label.all-websites": "Todos os sites", "label.all-websites": "Todos os sites",
"label.back": "Voltar", "label.back": "Voltar",
@ -68,6 +67,7 @@
"message.confirm-reset": "Você tem certeza que deseja redefinir as estatísticas de {target}?", "message.confirm-reset": "Você tem certeza que deseja redefinir as estatísticas de {target}?",
"message.copied": "Copiado!", "message.copied": "Copiado!",
"message.delete-warning": "Todos os dados associados também serão eliminados.", "message.delete-warning": "Todos os dados associados também serão eliminados.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ocorreu um erro.", "message.failure": "Ocorreu um erro.",
"message.get-share-url": "Obter link de compartilhamento", "message.get-share-url": "Obter link de compartilhamento",
"message.get-tracking-code": "Obter código de rastreamento", "message.get-tracking-code": "Obter código de rastreamento",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemas operacionais", "metrics.operating-systems": "Sistemas operacionais",
"metrics.page-views": "Visualizações de página", "metrics.page-views": "Visualizações de página",
"metrics.pages": "Páginas", "metrics.pages": "Páginas",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referências", "metrics.referrers": "Referências",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitantes únicos", "metrics.unique-visitors": "Visitantes únicos",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizações", "metrics.views": "Visualizações",
"metrics.visitors": "Visitantes" "metrics.visitors": "Visitantes"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Adicionar website", "label.add-website": "Adicionar website",
"label.administrator": "Administrador", "label.administrator": "Administrador",
"label.all": "Todos", "label.all": "Todos",
"label.all-events": "Todos os eventos",
"label.all-time": "Todo o tempo", "label.all-time": "Todo o tempo",
"label.all-websites": "Todos os websites", "label.all-websites": "Todos os websites",
"label.back": "Voltar", "label.back": "Voltar",
@ -28,7 +27,7 @@
"label.enable-share-url": "Ativar link de partilha", "label.enable-share-url": "Ativar link de partilha",
"label.invalid": "Inválido", "label.invalid": "Inválido",
"label.invalid-domain": "Domínio inválido", "label.invalid-domain": "Domínio inválido",
"label.language": "Language", "label.language": "Língua",
"label.last-days": "Últimos {x} dias", "label.last-days": "Últimos {x} dias",
"label.last-hours": "Últimas {x} horas", "label.last-hours": "Últimas {x} horas",
"label.logged-in-as": "Sessão iniciada como {username}", "label.logged-in-as": "Sessão iniciada como {username}",
@ -52,7 +51,7 @@
"label.settings": "Definições", "label.settings": "Definições",
"label.share-url": "Partilhar link", "label.share-url": "Partilhar link",
"label.single-day": "Dia único", "label.single-day": "Dia único",
"label.theme": "Theme", "label.theme": "Tema",
"label.this-month": "Este mês", "label.this-month": "Este mês",
"label.this-week": "Esta semana", "label.this-week": "Esta semana",
"label.this-year": "Este ano", "label.this-year": "Este ano",
@ -68,6 +67,7 @@
"message.confirm-reset": "Tem a certeza que pretende restaurar as estatísticas de {target}?", "message.confirm-reset": "Tem a certeza que pretende restaurar as estatísticas de {target}?",
"message.copied": "Copiado!", "message.copied": "Copiado!",
"message.delete-warning": "Todos os dados associados também serão eliminados.", "message.delete-warning": "Todos os dados associados também serão eliminados.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ocorreu um erro.", "message.failure": "Ocorreu um erro.",
"message.get-share-url": "Obter link de partilha", "message.get-share-url": "Obter link de partilha",
"message.get-tracking-code": "Obter código de rastreamento", "message.get-tracking-code": "Obter código de rastreamento",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemas operativos", "metrics.operating-systems": "Sistemas operativos",
"metrics.page-views": "Visualizações da página", "metrics.page-views": "Visualizações da página",
"metrics.pages": "Páginas", "metrics.pages": "Páginas",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referenciadores", "metrics.referrers": "Referenciadores",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitantes únicos", "metrics.unique-visitors": "Visitantes únicos",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizações", "metrics.views": "Visualizações",
"metrics.visitors": "Visitantes" "metrics.visitors": "Visitantes"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Adăugare site web", "label.add-website": "Adăugare site web",
"label.administrator": "Administrator", "label.administrator": "Administrator",
"label.all": "Toate", "label.all": "Toate",
"label.all-events": "Toate evenimentele",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "Toate site-urile web", "label.all-websites": "Toate site-urile web",
"label.back": "Înapoi", "label.back": "Înapoi",
@ -68,6 +67,7 @@
"message.confirm-reset": "Sunteți sigur că doriți să resetați statisticile pentru {target}?", "message.confirm-reset": "Sunteți sigur că doriți să resetați statisticile pentru {target}?",
"message.copied": "Copiat!", "message.copied": "Copiat!",
"message.delete-warning": "Toate datele asociate vor fi șterse, de asemenea.", "message.delete-warning": "Toate datele asociate vor fi șterse, de asemenea.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ceva n-a mers bine.", "message.failure": "Ceva n-a mers bine.",
"message.get-share-url": "Obține adresa URL de partajare", "message.get-share-url": "Obține adresa URL de partajare",
"message.get-tracking-code": "Obține codul de urmărire", "message.get-tracking-code": "Obține codul de urmărire",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sisteme de operare", "metrics.operating-systems": "Sisteme de operare",
"metrics.page-views": "Vizualizări de pagină", "metrics.page-views": "Vizualizări de pagină",
"metrics.pages": "Pagini", "metrics.pages": "Pagini",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Site-uri de proveniență", "metrics.referrers": "Site-uri de proveniență",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Vizitatori unici", "metrics.unique-visitors": "Vizitatori unici",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vizualizări", "metrics.views": "Vizualizări",
"metrics.visitors": "Vizitatori" "metrics.visitors": "Vizitatori"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Добавить сайт", "label.add-website": "Добавить сайт",
"label.administrator": "Администратор", "label.administrator": "Администратор",
"label.all": "Все", "label.all": "Все",
"label.all-events": "Все события",
"label.all-time": "Все время", "label.all-time": "Все время",
"label.all-websites": "Все сайты", "label.all-websites": "Все сайты",
"label.back": "Назад", "label.back": "Назад",
@ -68,6 +67,7 @@
"message.confirm-reset": "Вы уверены, что хотите сбросить статистику {target}?", "message.confirm-reset": "Вы уверены, что хотите сбросить статистику {target}?",
"message.copied": "Скопировано!", "message.copied": "Скопировано!",
"message.delete-warning": "Все связанные данные будут также удалены.", "message.delete-warning": "Все связанные данные будут также удалены.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Что-то пошло не так.", "message.failure": "Что-то пошло не так.",
"message.get-share-url": "Получить публичную ссылку", "message.get-share-url": "Получить публичную ссылку",
"message.get-tracking-code": "Получить код отслеживания", "message.get-tracking-code": "Получить код отслеживания",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Операционные системы", "metrics.operating-systems": "Операционные системы",
"metrics.page-views": "Просмотры страниц", "metrics.page-views": "Просмотры страниц",
"metrics.pages": "Страницы", "metrics.pages": "Страницы",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Источники", "metrics.referrers": "Источники",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Уникальные посетители", "metrics.unique-visitors": "Уникальные посетители",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Просмотры", "metrics.views": "Просмотры",
"metrics.visitors": "Посетители" "metrics.visitors": "Посетители"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Pridať web", "label.add-website": "Pridať web",
"label.administrator": "Administrátor", "label.administrator": "Administrátor",
"label.all": "Všetko", "label.all": "Všetko",
"label.all-events": "All events",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "Všetky weby", "label.all-websites": "Všetky weby",
"label.back": "Späť", "label.back": "Späť",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Skopírované!", "message.copied": "Skopírované!",
"message.delete-warning": "Všetky príbuzné data budu tiež zmazané.", "message.delete-warning": "Všetky príbuzné data budu tiež zmazané.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Niečo sa pokazilo.", "message.failure": "Niečo sa pokazilo.",
"message.get-share-url": "Získať zdielané URL", "message.get-share-url": "Získať zdielané URL",
"message.get-tracking-code": "Získať tracking kód", "message.get-tracking-code": "Získať tracking kód",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operačný systém", "metrics.operating-systems": "Operačný systém",
"metrics.page-views": "Zobrazenie stánok", "metrics.page-views": "Zobrazenie stánok",
"metrics.pages": "Stránky", "metrics.pages": "Stránky",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Odkazy", "metrics.referrers": "Odkazy",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Jedinečné návštevy", "metrics.unique-visitors": "Jedinečné návštevy",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Zobrazení", "metrics.views": "Zobrazení",
"metrics.visitors": "Návštevy" "metrics.visitors": "Návštevy"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Dodaj spletno mesto", "label.add-website": "Dodaj spletno mesto",
"label.administrator": "Administrator", "label.administrator": "Administrator",
"label.all": "Vse", "label.all": "Vse",
"label.all-events": "Vsi dogodki",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "Vsa spletna mesta", "label.all-websites": "Vsa spletna mesta",
"label.back": "Nazaj", "label.back": "Nazaj",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Kopirano!", "message.copied": "Kopirano!",
"message.delete-warning": "Izbrisani bodo tudi vsi povezani podatki.", "message.delete-warning": "Izbrisani bodo tudi vsi povezani podatki.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Prišlo je do napake.", "message.failure": "Prišlo je do napake.",
"message.get-share-url": "Pridobi URL za skupno rabo", "message.get-share-url": "Pridobi URL za skupno rabo",
"message.get-tracking-code": "Pridobi kodo za sledenje", "message.get-tracking-code": "Pridobi kodo za sledenje",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operacijski sistemi", "metrics.operating-systems": "Operacijski sistemi",
"metrics.page-views": "Ogledi strani", "metrics.page-views": "Ogledi strani",
"metrics.pages": "Strani", "metrics.pages": "Strani",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Viri", "metrics.referrers": "Viri",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unikatni obiskovalci", "metrics.unique-visitors": "Unikatni obiskovalci",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Ogledi", "metrics.views": "Ogledi",
"metrics.visitors": "Obiskovalci" "metrics.visitors": "Obiskovalci"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Lägg till webbsajt", "label.add-website": "Lägg till webbsajt",
"label.administrator": "Administratör", "label.administrator": "Administratör",
"label.all": "Alla", "label.all": "Alla",
"label.all-events": "Alla händelser",
"label.all-time": "Sedan början", "label.all-time": "Sedan början",
"label.all-websites": "Alla sajter", "label.all-websites": "Alla sajter",
"label.back": "Tillbaka", "label.back": "Tillbaka",
@ -68,6 +67,7 @@
"message.confirm-reset": "Är du säker på att du vill återställa statistiken för {target}?", "message.confirm-reset": "Är du säker på att du vill återställa statistiken för {target}?",
"message.copied": "Kopierad!", "message.copied": "Kopierad!",
"message.delete-warning": "All tillhörande data kommer också raderas.", "message.delete-warning": "All tillhörande data kommer också raderas.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Något gick fel.", "message.failure": "Något gick fel.",
"message.get-share-url": "Visa delnings-URL", "message.get-share-url": "Visa delnings-URL",
"message.get-tracking-code": "Visa spårningskod", "message.get-tracking-code": "Visa spårningskod",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operativsystem", "metrics.operating-systems": "Operativsystem",
"metrics.page-views": "Sidvisningar", "metrics.page-views": "Sidvisningar",
"metrics.pages": "Sidor", "metrics.pages": "Sidor",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Hänvisare", "metrics.referrers": "Hänvisare",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unika besökare", "metrics.unique-visitors": "Unika besökare",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visningar", "metrics.views": "Visningar",
"metrics.visitors": "Besökare" "metrics.visitors": "Besökare"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "வலைத்தளத்தைச் சேர்க்க", "label.add-website": "வலைத்தளத்தைச் சேர்க்க",
"label.administrator": "நிர்வாகியைச் சேர்க்க", "label.administrator": "நிர்வாகியைச் சேர்க்க",
"label.all": "எல்லாம்", "label.all": "எல்லாம்",
"label.all-events": "அனைத்து நிகழ்வுகளும்",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "அனைத்து வலைத்தளங்களும்", "label.all-websites": "அனைத்து வலைத்தளங்களும்",
"label.back": "பின்னால்", "label.back": "பின்னால்",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "நகலெடுக்கப்பட்டது!", "message.copied": "நகலெடுக்கப்பட்டது!",
"message.delete-warning": "தொடர்புடைய எல்லா தரவும் நீக்கப்படும்.", "message.delete-warning": "தொடர்புடைய எல்லா தரவும் நீக்கப்படும்.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "ஏதோ தவறு நடந்துவிட்டது.", "message.failure": "ஏதோ தவறு நடந்துவிட்டது.",
"message.get-share-url": "கள முகவரியை ஐப் பெறுக", "message.get-share-url": "கள முகவரியை ஐப் பெறுக",
"message.get-tracking-code": "கண்காணிப்பு குறியீட்டைப் பெறுக", "message.get-tracking-code": "கண்காணிப்பு குறியீட்டைப் பெறுக",
@ -103,15 +103,10 @@
"metrics.operating-systems": "இயக்க முறைமைகள்", "metrics.operating-systems": "இயக்க முறைமைகள்",
"metrics.page-views": "பக்க காட்சிகள்", "metrics.page-views": "பக்க காட்சிகள்",
"metrics.pages": "பக்கங்கள்", "metrics.pages": "பக்கங்கள்",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "குறிப்பிடுவோர்", "metrics.referrers": "குறிப்பிடுவோர்",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "தனிப்பட்ட பார்வையாளர்கள்", "metrics.unique-visitors": "தனிப்பட்ட பார்வையாளர்கள்",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "பார்வைகள்", "metrics.views": "பார்வைகள்",
"metrics.visitors": "பார்வையாளர்கள்" "metrics.visitors": "பார்வையாளர்கள்"
} }

112
lang/th-TH.json Normal file
View File

@ -0,0 +1,112 @@
{
"label.accounts": "บัญชี",
"label.add-account": "เพิ่มบัญชี",
"label.add-website": "เพิ่มเว็บไซต์",
"label.administrator": "ผู้ดูแลระบบ",
"label.all": "ทั้งหมด",
"label.all-time": "ทุกช่วงเวลา",
"label.all-websites": "เว็บไซต์ทั้งหมด",
"label.back": "ย้อนกลับ",
"label.cancel": "ยกเลิก",
"label.change-password": "เปลี่ยนรหัสผ่าน",
"label.confirm-password": "ยืนยันรหัสผ่าน",
"label.copy-to-clipboard": "คัดลอกไปยังคลิปบอร์ด",
"label.current-password": "รหัสผ่านปัจจุบัน",
"label.custom-range": "กำหนดช่วงเวลา",
"label.dashboard": "แดชบอร์ด",
"label.date-range": "ตั้งแต่วันที่",
"label.default-date-range": "ช่วงเวลา",
"label.delete": "ลบ",
"label.delete-account": "ลบบัญชี",
"label.delete-website": "ลบเว็บไซต์",
"label.dismiss": "ยกเลิก",
"label.domain": "โดเมน",
"label.edit": "แก้ไข",
"label.edit-account": "แก้ไขบัญชี",
"label.edit-website": "แก้ไขเว็บไซต์",
"label.enable-share-url": "เปิดใช้งานการแชร์ลิงก์",
"label.invalid": "ไม่ถูกต้อง",
"label.invalid-domain": "โดเมนไม่ถูกต้อง",
"label.language": "ภาษา",
"label.last-days": "{x} วันที่ผ่านมา",
"label.last-hours": "{x} ชั่วโมงที่ผ่านมา",
"label.logged-in-as": "เข้าสู่ระบบโดย {username}",
"label.login": "เข้าสู่ระบบ",
"label.logout": "ออกจากระบบ",
"label.more": "เพิ่มเติม",
"label.name": "ชื่อ",
"label.new-password": "รหัสผ่านใหม่",
"label.none": "ไม่ได้กำหนด",
"label.owner": "เจ้าของ",
"label.password": "รหัสผ่าน",
"label.passwords-dont-match": "รหัสผ่านไม่ตรงกัน",
"label.profile": "โปรไฟล์",
"label.realtime": "เรียลไทม์",
"label.realtime-logs": "Log แบบเรียลไทม์",
"label.refresh": "รีเฟรช",
"label.required": "ต้องการ",
"label.reset": "รีเซต",
"label.reset-website": "รีเซตข้อมูลสถิติ",
"label.save": "บันทึก",
"label.settings": "ตั้งค่า",
"label.share-url": "แชร์ลิงก์",
"label.single-day": "วันที่",
"label.theme": "ธีม",
"label.this-month": "เดือนปัจจุบัน",
"label.this-week": "สัปดาห์ปัจจุบัน",
"label.this-year": "ปีปัจจุบัน",
"label.timezone": "เขตเวลา",
"label.today": "วันนี้",
"label.tracking-code": "โค้ดสำหรับใช้ติดตาม",
"label.unknown": "ไม่รู้จัก",
"label.username": "ชื่อผู้ใช้",
"label.view-details": "แสดงรายละเอียด",
"label.websites": "เว็บไซต์",
"message.active-users": "มีผู้ใช้งาน {x} {x, plural, one {คนในขณะนี้} other {คนในขณะนี้}}",
"message.confirm-delete": "คุณแน่ใจหรือไม่ว่าต้องการลบ {target} ?",
"message.confirm-reset": "คุณแน่ใจหรือไม่ว่าต้องการรีเซตข้อมูลสถิติของ {target} ?",
"message.copied": "คัดลอกแล้ว!",
"message.delete-warning": "ข้อมูลที่เกี่ยวข้องทั้งหมดจะถูกลบ.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "เกิดข้อผิดพลาด.",
"message.get-share-url": "รับลิงก์สำหรับแชร์",
"message.get-tracking-code": "รับโค้ดสำหรับใช้ติดตาม",
"message.go-to-settings": "ไปที่การตั้งค่า",
"message.incorrect-username-password": "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง.",
"message.log.visitor": "ผู้เข้าชมจาก {country} กำลังใช้งานผ่าน {browser} บน {os} {device}",
"message.new-version-available": "umami เวอร์ชันใหม่ ({version}) มาแล้ว!",
"message.no-data-available": "ไม่มีข้อมูล.",
"message.no-websites-configured": "คุณยังไม่ได้ตั้งค่าเว็บไซต์ใด ๆ ไว้.",
"message.page-not-found": "ไม่พบหน้านี้.",
"message.powered-by": "ขับเคลื่อนโดย {name}",
"message.reset-warning": "สถิติทั้งหมดสำหรับเว็บไซต์นี้จะถูกลบออก แต่โค้ดสำหรับใช้ติดตามของคุณจะยังคงอยู่เหมือนเดิม.",
"message.save-success": "บันทึกข้อมูลเรียบร้อย.",
"message.share-url": "นี่คือลิงก์ที่แชร์แบบสาธารณะสำหรับ {target}.",
"message.toggle-charts": "เปิด/ปิดแผนภูมิ",
"message.track-stats": "หากต้องการติดตามสถิติสำหรับ {target} ให้วางโค้ดต่อไปนี้ในส่วน {head} ของเว็บไซต์ของคุณ.",
"message.type-delete": "พิมพ์ข้อความ {delete} ในช่องด้านล่างเพื่อยืนยัน.",
"message.type-reset": "พิมพ์ข้อความ {reset} ในช่องด้านล่างเพื่อยืนยัน.",
"metrics.actions": "การกระทำ",
"metrics.average-visit-time": "ระยะเวลาเข้าชมเฉลี่ย",
"metrics.bounce-rate": "อัตราตีกลับ",
"metrics.browsers": "เบราว์เซอร์",
"metrics.countries": "ประเทศ",
"metrics.device.desktop": "เดสก์ท็อป",
"metrics.device.laptop": "แล็ปท็อป",
"metrics.device.mobile": "โทรศัพท์มือถือ",
"metrics.device.tablet": "แท็บเล็ต",
"metrics.devices": "อุปกรณ์",
"metrics.events": "เหตุการณ์",
"metrics.filter.combined": "ข้อมูลรวม",
"metrics.filter.raw": "ข้อมูลดิบ",
"metrics.languages": "ภาษา",
"metrics.operating-systems": "ระบบปฏิบัติการ",
"metrics.page-views": "การเข้าชม",
"metrics.pages": "หน้าเพจ",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "แหล่งที่มา",
"metrics.screens": "ขนาดหน้าจอ",
"metrics.unique-visitors": "ผู้เข้าชม",
"metrics.views": "การเข้าชม",
"metrics.visitors": "ผู้เข้าชม"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Web sitesi ekle", "label.add-website": "Web sitesi ekle",
"label.administrator": "Yönetici", "label.administrator": "Yönetici",
"label.all": "Tümü", "label.all": "Tümü",
"label.all-events": "All events",
"label.all-time": "All time", "label.all-time": "All time",
"label.all-websites": "Tüm web siteleri", "label.all-websites": "Tüm web siteleri",
"label.back": "Geri", "label.back": "Geri",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Panoya kopyalandı!", "message.copied": "Panoya kopyalandı!",
"message.delete-warning": "İlişkili tüm veriler de silinecektir.", "message.delete-warning": "İlişkili tüm veriler de silinecektir.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Bir şeyler ters gitti!", "message.failure": "Bir şeyler ters gitti!",
"message.get-share-url": "Paylaşım adresini al", "message.get-share-url": "Paylaşım adresini al",
"message.get-tracking-code": "İzleme kodunu al", "message.get-tracking-code": "İzleme kodunu al",
@ -103,15 +103,10 @@
"metrics.operating-systems": "İşletim sistemi", "metrics.operating-systems": "İşletim sistemi",
"metrics.page-views": "Sayfa görünümü", "metrics.page-views": "Sayfa görünümü",
"metrics.pages": "Sayfalar", "metrics.pages": "Sayfalar",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Yönlendirenler", "metrics.referrers": "Yönlendirenler",
"metrics.screens": "Ekranlar", "metrics.screens": "Ekranlar",
"metrics.unique-visitors": "Tekil kullanıcı", "metrics.unique-visitors": "Tekil kullanıcı",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Görüntüleme", "metrics.views": "Görüntüleme",
"metrics.visitors": "Ziyaretçi" "metrics.visitors": "Ziyaretçi"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Додати сайт", "label.add-website": "Додати сайт",
"label.administrator": "Адміністратор", "label.administrator": "Адміністратор",
"label.all": "Всі", "label.all": "Всі",
"label.all-events": "Всі події",
"label.all-time": "Весь час", "label.all-time": "Весь час",
"label.all-websites": "Всі сайти", "label.all-websites": "Всі сайти",
"label.back": "Назад", "label.back": "Назад",
@ -68,6 +67,7 @@
"message.confirm-reset": "Ви впевнені, що бажаєте скинути статистику для {target}?", "message.confirm-reset": "Ви впевнені, що бажаєте скинути статистику для {target}?",
"message.copied": "Скопійовано!", "message.copied": "Скопійовано!",
"message.delete-warning": "Усі пов'язані дані будуть видалені також.", "message.delete-warning": "Усі пов'язані дані будуть видалені також.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Щось пішло не так.", "message.failure": "Щось пішло не так.",
"message.get-share-url": "Отримати публічне посилання", "message.get-share-url": "Отримати публічне посилання",
"message.get-tracking-code": "Отримати код для відслідковування", "message.get-tracking-code": "Отримати код для відслідковування",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Операційні системи", "metrics.operating-systems": "Операційні системи",
"metrics.page-views": "Перегляди сторінок", "metrics.page-views": "Перегляди сторінок",
"metrics.pages": "Сторінки", "metrics.pages": "Сторінки",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Джерела", "metrics.referrers": "Джерела",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Унікальні відвідувачі", "metrics.unique-visitors": "Унікальні відвідувачі",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Перегляди", "metrics.views": "Перегляди",
"metrics.visitors": "Відвідувачі" "metrics.visitors": "Відвідувачі"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "ویب سائٹ کا اضافہ کریں", "label.add-website": "ویب سائٹ کا اضافہ کریں",
"label.administrator": "منتظم", "label.administrator": "منتظم",
"label.all": "تمام", "label.all": "تمام",
"label.all-events": "تمام واقعات",
"label.all-time": "تمام وقت", "label.all-time": "تمام وقت",
"label.all-websites": "تمام ویب سائٹس", "label.all-websites": "تمام ویب سائٹس",
"label.back": "پیچھے", "label.back": "پیچھے",
@ -68,6 +67,7 @@
"message.confirm-reset": "کیا آپ واقعی {target} کے اعدادوشمار کو دوبارہ ترتیب دینا چاہتے ہیں؟", "message.confirm-reset": "کیا آپ واقعی {target} کے اعدادوشمار کو دوبارہ ترتیب دینا چاہتے ہیں؟",
"message.copied": "کاپی کیا گیا!", "message.copied": "کاپی کیا گیا!",
"message.delete-warning": "تمام متعلقہ ڈیٹا بھی حذف کر دیا جائے گا۔", "message.delete-warning": "تمام متعلقہ ڈیٹا بھی حذف کر دیا جائے گا۔",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "کچھ غلط ہو گیا.", "message.failure": "کچھ غلط ہو گیا.",
"message.get-share-url": "شیئر URL حاصل کریں", "message.get-share-url": "شیئر URL حاصل کریں",
"message.get-tracking-code": "ٹریکنگ کوڈ حاصل کریں", "message.get-tracking-code": "ٹریکنگ کوڈ حاصل کریں",
@ -103,15 +103,10 @@
"metrics.operating-systems": "آپریٹنگ سسٹمز", "metrics.operating-systems": "آپریٹنگ سسٹمز",
"metrics.page-views": "صفحہ کے نظارے", "metrics.page-views": "صفحہ کے نظارے",
"metrics.pages": "صفحات", "metrics.pages": "صفحات",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "بھیجنے والے", "metrics.referrers": "بھیجنے والے",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "منفرد زائرین", "metrics.unique-visitors": "منفرد زائرین",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "مناظر", "metrics.views": "مناظر",
"metrics.visitors": "زائرین" "metrics.visitors": "زائرین"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "Thêm website", "label.add-website": "Thêm website",
"label.administrator": "Quản trị", "label.administrator": "Quản trị",
"label.all": "Tất cả", "label.all": "Tất cả",
"label.all-events": "Tất cả sự kiện",
"label.all-time": "Toàn thời gian", "label.all-time": "Toàn thời gian",
"label.all-websites": "Tất cả website", "label.all-websites": "Tất cả website",
"label.back": "Quay về", "label.back": "Quay về",
@ -68,6 +67,7 @@
"message.confirm-reset": "Bạn có chắc chắn muốn tái thiết lập thống kê {target}?", "message.confirm-reset": "Bạn có chắc chắn muốn tái thiết lập thống kê {target}?",
"message.copied": "Đã sao chép!", "message.copied": "Đã sao chép!",
"message.delete-warning": "Tất cả các dữ liệu liên quan cũng sẽ bị xoá.", "message.delete-warning": "Tất cả các dữ liệu liên quan cũng sẽ bị xoá.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Đã xảy ra lỗi.", "message.failure": "Đã xảy ra lỗi.",
"message.get-share-url": "Lấy URL chia sẻ", "message.get-share-url": "Lấy URL chia sẻ",
"message.get-tracking-code": "Lấy mã theo dõi", "message.get-tracking-code": "Lấy mã theo dõi",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Hệ điều hành", "metrics.operating-systems": "Hệ điều hành",
"metrics.page-views": "Lượt xem", "metrics.page-views": "Lượt xem",
"metrics.pages": "Trang", "metrics.pages": "Trang",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Liên kết giới thiệu", "metrics.referrers": "Liên kết giới thiệu",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Khách truy cập một lần", "metrics.unique-visitors": "Khách truy cập một lần",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Xem", "metrics.views": "Xem",
"metrics.visitors": "Khách" "metrics.visitors": "Khách"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "添加网站", "label.add-website": "添加网站",
"label.administrator": "管理员", "label.administrator": "管理员",
"label.all": "所有", "label.all": "所有",
"label.all-events": "所有事件",
"label.all-time": "所有时间段", "label.all-time": "所有时间段",
"label.all-websites": "全部网站", "label.all-websites": "全部网站",
"label.back": "返回", "label.back": "返回",
@ -68,6 +67,7 @@
"message.confirm-reset": "您确定要重置 {target} 的数据吗?", "message.confirm-reset": "您确定要重置 {target} 的数据吗?",
"message.copied": "复制成功!", "message.copied": "复制成功!",
"message.delete-warning": "所有相关数据将会被删除。", "message.delete-warning": "所有相关数据将会被删除。",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "出现错误。", "message.failure": "出现错误。",
"message.get-share-url": "获取共享链接", "message.get-share-url": "获取共享链接",
"message.get-tracking-code": "获取跟踪代码", "message.get-tracking-code": "获取跟踪代码",
@ -103,15 +103,10 @@
"metrics.operating-systems": "操作系统", "metrics.operating-systems": "操作系统",
"metrics.page-views": "页面浏览量", "metrics.page-views": "页面浏览量",
"metrics.pages": "网页", "metrics.pages": "网页",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "来源域名", "metrics.referrers": "来源域名",
"metrics.screens": "屏幕尺寸", "metrics.screens": "屏幕尺寸",
"metrics.unique-visitors": "独立访客", "metrics.unique-visitors": "独立访客",
"metrics.utm": "流量渠道标记UTM",
"metrics.utm_campaign": "流量标识",
"metrics.utm_content": "搜索关键字",
"metrics.utm_medium": "流量来源类型",
"metrics.utm_source": "流量来源",
"metrics.utm_term": "流量搜索关键字",
"metrics.views": "浏览量", "metrics.views": "浏览量",
"metrics.visitors": "访客" "metrics.visitors": "访客"
} }

View File

@ -4,7 +4,6 @@
"label.add-website": "增加網站", "label.add-website": "增加網站",
"label.administrator": "管理員", "label.administrator": "管理員",
"label.all": "所有", "label.all": "所有",
"label.all-events": "所有事件",
"label.all-time": "所有時間段", "label.all-time": "所有時間段",
"label.all-websites": "全部網站", "label.all-websites": "全部網站",
"label.back": "返回", "label.back": "返回",
@ -37,8 +36,8 @@
"label.more": "更多", "label.more": "更多",
"label.name": "名字", "label.name": "名字",
"label.new-password": "新密碼", "label.new-password": "新密碼",
"label.none": "None", "label.none": "",
"label.owner": "Owner", "label.owner": "擁有者",
"label.password": "密碼", "label.password": "密碼",
"label.passwords-dont-match": "密碼不一致", "label.passwords-dont-match": "密碼不一致",
"label.profile": "個人資料", "label.profile": "個人資料",
@ -52,7 +51,7 @@
"label.settings": "設置", "label.settings": "設置",
"label.share-url": "分享連結", "label.share-url": "分享連結",
"label.single-day": "單日", "label.single-day": "單日",
"label.theme": "Theme", "label.theme": "主題",
"label.this-month": "本月", "label.this-month": "本月",
"label.this-week": "本週", "label.this-week": "本週",
"label.this-year": "今年", "label.this-year": "今年",
@ -68,6 +67,7 @@
"message.confirm-reset": "您確定要重置 {target} 的數據嗎?", "message.confirm-reset": "您確定要重置 {target} 的數據嗎?",
"message.copied": "複製成功!", "message.copied": "複製成功!",
"message.delete-warning": "所有相關數據將會被刪除。", "message.delete-warning": "所有相關數據將會被刪除。",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "出現錯誤。", "message.failure": "出現錯誤。",
"message.get-share-url": "獲得分享連結", "message.get-share-url": "獲得分享連結",
"message.get-tracking-code": "獲得追蹤代碼", "message.get-tracking-code": "獲得追蹤代碼",
@ -82,7 +82,7 @@
"message.reset-warning": "本網站的所有統計數據將被刪除,但您的跟蹤代碼將保持不變。", "message.reset-warning": "本網站的所有統計數據將被刪除,但您的跟蹤代碼將保持不變。",
"message.save-success": "成功保存。", "message.save-success": "成功保存。",
"message.share-url": "這是 {target} 的分享連結。", "message.share-url": "這是 {target} 的分享連結。",
"message.toggle-charts": "Toggle charts", "message.toggle-charts": "切換圖表",
"message.track-stats": "將以下代碼放入被設定網站的 {head} 部分來收集 {target} 的資料。", "message.track-stats": "將以下代碼放入被設定網站的 {head} 部分來收集 {target} 的資料。",
"message.type-delete": "在下方空格輸入 {delete} 確認删除", "message.type-delete": "在下方空格輸入 {delete} 確認删除",
"message.type-reset": "在下方空格輸入 {reset} 確認删除", "message.type-reset": "在下方空格輸入 {reset} 確認删除",
@ -99,19 +99,14 @@
"metrics.events": "行為類別", "metrics.events": "行為類別",
"metrics.filter.combined": "總和", "metrics.filter.combined": "總和",
"metrics.filter.raw": "原始", "metrics.filter.raw": "原始",
"metrics.languages": "Languages", "metrics.languages": "語言",
"metrics.operating-systems": "操作系", "metrics.operating-systems": "操作系",
"metrics.page-views": "網頁流量", "metrics.page-views": "網頁流量",
"metrics.pages": "網頁", "metrics.pages": "網頁",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "指入域名", "metrics.referrers": "指入域名",
"metrics.screens": "Screens", "metrics.screens": "屏幕尺寸",
"metrics.unique-visitors": "獨立訪客", "metrics.unique-visitors": "獨立訪客",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "頁面流量", "metrics.views": "頁面流量",
"metrics.visitors": "獨立訪客" "metrics.visitors": "獨立訪客"
} }

View File

@ -9,3 +9,10 @@ export function chunk(arr, size) {
return chunks; return chunks;
} }
export function sortArrayByMap(arr, map = [], key) {
if (!arr) return [];
if (map.length === 0) return arr;
return map.map(id => arr.find(item => item[key] === id));
}

View File

@ -1,3 +1,4 @@
export const CURRENT_VERSION = process.env.currentVersion;
export const AUTH_TOKEN = 'umami.auth'; export const AUTH_TOKEN = 'umami.auth';
export const LOCALE_CONFIG = 'umami.locale'; export const LOCALE_CONFIG = 'umami.locale';
export const TIMEZONE_CONFIG = 'umami.timezone'; export const TIMEZONE_CONFIG = 'umami.timezone';
@ -9,6 +10,7 @@ export const SHARE_TOKEN_HEADER = 'x-umami-share-token';
export const HOMEPAGE_URL = 'https://umami.is'; export const HOMEPAGE_URL = 'https://umami.is';
export const REPO_URL = 'https://github.com/umami-software/umami'; export const REPO_URL = 'https://github.com/umami-software/umami';
export const UPDATES_URL = 'https://api.umami.is/v1/updates'; export const UPDATES_URL = 'https://api.umami.is/v1/updates';
export const TELEMETRY_PIXEL = 'https://i.umami.is/a.png';
export const DEFAULT_LOCALE = 'en-US'; export const DEFAULT_LOCALE = 'en-US';
export const DEFAULT_THEME = 'light'; export const DEFAULT_THEME = 'light';

View File

@ -168,7 +168,6 @@ export function getFilterQuery(table, column, filters = {}, params = []) {
if (table === 'pageview' || table === 'event') { if (table === 'pageview' || table === 'event') {
arr.push(`and ${table}.${key}=$${params.length + 1}`); arr.push(`and ${table}.${key}=$${params.length + 1}`);
params.push(decodeURIComponent(filter)); params.push(decodeURIComponent(filter));
console.log(params);
} }
break; break;
@ -182,7 +181,7 @@ export function getFilterQuery(table, column, filters = {}, params = []) {
} }
break; break;
case 'event_type': case 'event_name':
if (table === 'event') { if (table === 'event') {
arr.push(`and ${table}.${key}=$${params.length + 1}`); arr.push(`and ${table}.${key}=$${params.length + 1}`);
params.push(decodeURIComponent(filter)); params.push(decodeURIComponent(filter));
@ -203,6 +202,11 @@ export function getFilterQuery(table, column, filters = {}, params = []) {
params.push(`%://${filter}/%`); params.push(`%://${filter}/%`);
} }
break; break;
case 'query':
if (table === 'pageview') {
arr.push(`and ${table}.url like '%?%'`);
}
} }
return arr; return arr;
@ -212,17 +216,20 @@ export function getFilterQuery(table, column, filters = {}, params = []) {
} }
export function parseFilters(table, column, filters = {}, params = [], sessionKey = 'session_id') { export function parseFilters(table, column, filters = {}, params = [], sessionKey = 'session_id') {
const { domain, url, event_url, referrer, os, browser, device, country, event_type } = filters; const { domain, url, event_url, referrer, os, browser, device, country, event_name, query } =
filters;
const pageviewFilters = { domain, url, referrer }; console.log({ table, column, filters, params });
const pageviewFilters = { domain, url, referrer, query };
const sessionFilters = { os, browser, device, country }; const sessionFilters = { os, browser, device, country };
const eventFilters = { url: event_url, event_type }; const eventFilters = { url: event_url, event_name };
return { return {
pageviewFilters, pageviewFilters,
sessionFilters, sessionFilters,
eventFilters, eventFilters,
event: { event_type }, event: { event_name },
joinSession: joinSession:
os || browser || device || country os || browser || device || country
? `inner join session on ${table}.${sessionKey} = session.${sessionKey}` ? `inner join session on ${table}.${sessionKey} = session.${sessionKey}`
@ -277,14 +284,22 @@ export async function rawQueryClickhouse(query, params = [], debug = false) {
return clickhouse.query(formattedQuery).toPromise(); return clickhouse.query(formattedQuery).toPromise();
} }
export async function findUnique(data) {
if (data.length > 1) {
throw `${data.length} records found when expecting 1.`;
}
return data[0] ?? null;
}
export async function runAnalyticsQuery(queries) { export async function runAnalyticsQuery(queries) {
const db = getAnalyticsDatabase(); const db = getAnalyticsDatabase();
if (db === POSTGRESQL || db === MYSQL) { if (db === POSTGRESQL || db === MYSQL) {
return queries[`${RELATIONAL}`](); return queries[RELATIONAL]();
} }
if (db === CLICKHOUSE) { if (db === CLICKHOUSE) {
return queries[`${CLICKHOUSE}`](); return queries[CLICKHOUSE]();
} }
} }

View File

@ -68,18 +68,37 @@ export const refFilter = data => {
return Object.keys(map).map(key => ({ x: key, y: map[key], w: links[key] })); return Object.keys(map).map(key => ({ x: key, y: map[key], w: links[key] }));
}; };
export const eventTypeFilter = (data, types) => {
if (!types || types.length === 0) {
return data;
}
return data.filter(({ x }) => {
const [event] = x.split('\t');
return types.some(type => type === event);
});
};
export const percentFilter = data => { export const percentFilter = data => {
const total = data.reduce((n, { y }) => n + y, 0); const total = data.reduce((n, { y }) => n + y, 0);
return data.map(({ x, y, ...props }) => ({ x, y, z: total ? (y / total) * 100 : 0, ...props })); return data.map(({ x, y, ...props }) => ({ x, y, z: total ? (y / total) * 100 : 0, ...props }));
}; };
export const paramFilter = data => {
const map = data.reduce((obj, { x, y }) => {
try {
const searchParams = new URLSearchParams(x.split('?')[1]);
for (const [key, value] of searchParams) {
if (!obj[key]) {
obj[key] = { [value]: y };
} else if (!obj[key][value]) {
obj[key][value] = y;
} else {
obj[key][value] += y;
}
}
} catch {
// Ignore
}
return obj;
}, {});
const d = Object.keys(map).flatMap(key =>
Object.keys(map[key]).map(n => ({ x: `${key}=${n}`, p: key, v: n, y: map[key][n] })),
);
console.log({ map, d });
return d;
};

View File

@ -1,5 +1,6 @@
import { import {
arSA, arSA,
bn,
cs, cs,
sk, sk,
da, da,
@ -30,6 +31,7 @@ import {
sl, sl,
sv, sv,
ta, ta,
th,
tr, tr,
uk, uk,
zhCN, zhCN,
@ -41,6 +43,7 @@ import {
export const languages = { export const languages = {
'ar-SA': { label: 'العربية', dateLocale: arSA, dir: 'rtl' }, 'ar-SA': { label: 'العربية', dateLocale: arSA, dir: 'rtl' },
'bn-BD': { label: 'বাংলা', dateLocale: bn },
'zh-CN': { label: '中文', dateLocale: zhCN }, 'zh-CN': { label: '中文', dateLocale: zhCN },
'zh-TW': { label: '中文(繁體)', dateLocale: zhTW }, 'zh-TW': { label: '中文(繁體)', dateLocale: zhTW },
'ca-ES': { label: 'Català', dateLocale: ca }, 'ca-ES': { label: 'Català', dateLocale: ca },
@ -77,6 +80,7 @@ export const languages = {
'fi-FI': { label: 'Suomi', dateLocale: fi }, 'fi-FI': { label: 'Suomi', dateLocale: fi },
'sv-SE': { label: 'Svenska', dateLocale: sv }, 'sv-SE': { label: 'Svenska', dateLocale: sv },
'ta-IN': { label: 'தமிழ்', dateLocale: ta }, 'ta-IN': { label: 'தமிழ்', dateLocale: ta },
'th-TH': { label: 'ภาษาไทย', dateLocale: th },
'tr-TR': { label: 'Türkçe', dateLocale: tr }, 'tr-TR': { label: 'Türkçe', dateLocale: tr },
'uk-UA': { label: 'українська', dateLocale: uk }, 'uk-UA': { label: 'українська', dateLocale: uk },
'ur-PK': { label: 'Urdu (Pakistan)', dateLocale: uk, dir: 'rtl' }, 'ur-PK': { label: 'Urdu (Pakistan)', dateLocale: uk, dir: 'rtl' },

View File

@ -68,7 +68,7 @@ export async function getCountry(req, ip) {
// Database lookup // Database lookup
if (!lookup) { if (!lookup) {
lookup = await maxmind.open(path.resolve('./public/geo/GeoLite2-Country.mmdb')); lookup = await maxmind.open(path.resolve('node_modules/.geo/GeoLite2-Country.mmdb'));
} }
const result = lookup.get(ip); const result = lookup.get(ip);

View File

@ -37,8 +37,6 @@ export async function getSession(req) {
let session = await getSessionByUuid(session_uuid); let session = await getSessionByUuid(session_uuid);
session = Array.isArray(session) && session[0] ? session[0] : session;
if (!session) { if (!session) {
try { try {
session = await createSession(website_id, { session = await createSession(website_id, {

View File

@ -61,10 +61,15 @@ export const setItem = (key, data, session) => {
} }
}; };
export const getItem = (key, session) => export const getItem = (key, session) => {
typeof window !== 'undefined' if (typeof window !== 'undefined') {
? JSON.parse((session ? sessionStorage : localStorage).getItem(key) || null) const value = (session ? sessionStorage : localStorage).getItem(key);
: null;
if (value !== 'undefined') {
return JSON.parse(value);
}
}
};
export const removeItem = (key, session) => { export const removeItem = (key, session) => {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {

View File

@ -33,14 +33,6 @@ function customScriptName(req) {
} }
} }
function forceSSL(req, res) {
if (process.env.FORCE_SSL && req.nextUrl.protocol === 'http:') {
res.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
}
return res;
}
export default function middleware(req) { export default function middleware(req) {
const fns = [customCollectEndpoint, customScriptName]; const fns = [customCollectEndpoint, customScriptName];
@ -51,5 +43,5 @@ export default function middleware(req) {
} }
} }
return forceSSL(req, NextResponse.next()); return NextResponse.next();
} }

View File

@ -1,12 +1,41 @@
require('dotenv').config(); require('dotenv').config();
const pkg = require('./package.json'); const pkg = require('./package.json');
const contentSecurityPolicy = `
default-src 'self';
img-src *;
script-src 'self' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
connect-src 'self' api.umami.is;
frame-ancestors 'self';
`;
const headers = [
{
key: 'X-DNS-Prefetch-Control',
value: 'on',
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
},
{
key: 'Content-Security-Policy',
value: contentSecurityPolicy.replace(/\s{2,}/g, ' ').trim(),
},
];
if (process.env.FORCE_SSL) {
headers.push({
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
});
}
module.exports = { module.exports = {
env: { env: {
currentVersion: pkg.version, currentVersion: pkg.version,
loginDisabled: process.env.DISABLE_LOGIN, isProduction: process.env.NODE_ENV === 'production',
updatesDisabled: process.env.DISABLE_UPDATES,
telemetryDisabled: process.env.DISABLE_TELEMETRY,
}, },
basePath: process.env.BASE_PATH, basePath: process.env.BASE_PATH,
output: 'standalone', output: 'standalone',
@ -25,13 +54,16 @@ module.exports = {
async headers() { async headers() {
return [ return [
{ {
source: `/(.*\\.js)`, source: '/:path*',
headers: [ headers,
{ },
key: 'Cache-Control', ];
value: 'public, max-age=2592000', // 30 days },
}, async rewrites() {
], return [
{
source: '/telemetry.js',
destination: '/api/scripts/telemetry',
}, },
]; ];
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "umami", "name": "umami",
"version": "1.36.1", "version": "1.37.0",
"description": "A simple, fast, privacy-focused alternative to Google Analytics.", "description": "A simple, fast, privacy-focused alternative to Google Analytics.",
"author": "Mike Cao <mike@mikecao.com>", "author": "Mike Cao <mike@mikecao.com>",
"license": "MIT", "license": "MIT",
@ -13,17 +13,18 @@
"dev": "next dev", "dev": "next dev",
"build": "npm-run-all build-tracker build-geo build-db build-app", "build": "npm-run-all build-tracker build-geo build-db build-app",
"start": "npm-run-all check-db start-next", "start": "npm-run-all check-db start-next",
"start-docker": "npm-run-all check-db start-server", "start-docker": "npm-run-all check-db update-tracker start-server",
"start-env": "node scripts/start-env.js", "start-env": "node scripts/start-env.js",
"start-server": "node server.js", "start-server": "node server.js",
"start-next": "next start", "start-next": "next start",
"build-app": "next build", "build-app": "next build",
"build-tracker": "rollup -c rollup.tracker.config.js", "build-tracker": "rollup -c rollup.tracker.config.js",
"build-db": "npm-run-all copy-db-files build-db-client", "build-db": "npm-run-all copy-db-files build-db-client",
"build-lang": "npm-run-all format-lang compile-lang", "build-lang": "npm-run-all format-lang compile-lang download-country-names download-language-names",
"build-geo": "node scripts/build-geo.js", "build-geo": "node scripts/build-geo.js",
"build-db-schema": "prisma db pull", "build-db-schema": "prisma db pull",
"build-db-client": "prisma generate", "build-db-client": "prisma generate",
"update-tracker": "node scripts/update-tracker.js",
"update-db": "prisma migrate deploy", "update-db": "prisma migrate deploy",
"check-db": "node scripts/check-db.js", "check-db": "node scripts/check-db.js",
"copy-db-files": "node scripts/copy-db-files.js", "copy-db-files": "node scripts/copy-db-files.js",
@ -55,7 +56,7 @@
}, },
"dependencies": { "dependencies": {
"@fontsource/inter": "4.5.7", "@fontsource/inter": "4.5.7",
"@prisma/client": "4.1.0", "@prisma/client": "4.1.1",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"chalk": "^4.1.1", "chalk": "^4.1.1",
"chart.js": "^2.9.4", "chart.js": "^2.9.4",
@ -80,11 +81,12 @@
"jose": "2.0.5", "jose": "2.0.5",
"maxmind": "^4.3.6", "maxmind": "^4.3.6",
"moment-timezone": "^0.5.33", "moment-timezone": "^0.5.33",
"next": "^12.2.0", "next": "^12.2.4",
"node-fetch": "^3.2.8", "node-fetch": "^3.2.8",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"react": "^17.0.0", "react": "^17.0.0",
"react-beautiful-dnd": "^13.1.0",
"react-dom": "^17.0.0", "react-dom": "^17.0.0",
"react-intl": "^5.24.7", "react-intl": "^5.24.7",
"react-simple-maps": "^2.3.0", "react-simple-maps": "^2.3.0",
@ -106,7 +108,7 @@
"@svgr/webpack": "^6.2.1", "@svgr/webpack": "^6.2.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"eslint": "^7.32.0", "eslint": "^7.32.0",
"eslint-config-next": "^12.2.0", "eslint-config-next": "^12.2.4",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^4.0.0",
"extract-react-intl-messages": "^4.1.1", "extract-react-intl-messages": "^4.1.1",
@ -118,7 +120,7 @@
"postcss-preset-env": "7.4.3", "postcss-preset-env": "7.4.3",
"postcss-rtlcss": "^3.6.1", "postcss-rtlcss": "^3.6.1",
"prettier": "^2.6.2", "prettier": "^2.6.2",
"prisma": "4.1.0", "prisma": "4.1.1",
"prompts": "2.4.2", "prompts": "2.4.2",
"rollup": "^2.70.1", "rollup": "^2.70.1",
"rollup-plugin-terser": "^7.0.2", "rollup-plugin-terser": "^7.0.2",
@ -127,5 +129,8 @@
"stylelint-config-prettier": "^9.0.3", "stylelint-config-prettier": "^9.0.3",
"stylelint-config-recommended": "^7.0.0", "stylelint-config-recommended": "^7.0.0",
"tar": "^6.1.2" "tar": "^6.1.2"
} },
"cacheDirectories": [
".next/cache"
]
} }

View File

@ -1,4 +1,3 @@
import React from 'react';
import Head from 'next/head'; import Head from 'next/head';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { IntlProvider } from 'react-intl'; import { IntlProvider } from 'react-intl';

View File

@ -65,7 +65,7 @@ export default async (req, res) => {
const { type, payload } = getJsonBody(req); const { type, payload } = getJsonBody(req);
let { url, referrer, event_type, event_value } = payload; let { url, referrer, event_name, event_data } = payload;
if (process.env.REMOVE_TRAILING_SLASH) { if (process.env.REMOVE_TRAILING_SLASH) {
url = removeTrailingSlash(url); url = removeTrailingSlash(url);
@ -74,7 +74,7 @@ export default async (req, res) => {
if (type === 'pageview') { if (type === 'pageview') {
await savePageView(website_id, { session_id, session_uuid, url, referrer }); await savePageView(website_id, { session_id, session_uuid, url, referrer });
} else if (type === 'event') { } else if (type === 'event') {
await saveEvent(website_id, { session_id, session_uuid, url, event_type, event_value }); await saveEvent(website_id, { session_id, session_uuid, url, event_name, event_data });
} else { } else {
return badRequest(res); return badRequest(res);
} }

14
pages/api/config.js Normal file
View File

@ -0,0 +1,14 @@
import { ok, methodNotAllowed } from 'lib/response';
export default async (req, res) => {
if (req.method === 'GET') {
return ok(res, {
basePath: process.env.BASE_PATH || '',
trackerScriptName: process.env.TRACKER_SCRIPT_NAME,
updatesDisabled: !!process.env.DISABLE_UPDATES,
telemetryDisabled: !!process.env.DISABLE_TELEMETRY,
});
}
return methodNotAllowed(res);
};

View File

@ -0,0 +1,18 @@
import { CURRENT_VERSION, TELEMETRY_PIXEL } from 'lib/constants';
export default function handler(req, res) {
res.setHeader('content-type', 'text/javascript');
if (process.env.DISABLE_TELEMETRY) {
return res.send('/* telemetry disabled */');
}
const script = `
(()=>{const i=document.createElement('img');
i.setAttribute('src','${TELEMETRY_PIXEL}?v=${CURRENT_VERSION}');
i.setAttribute('style','width:0;height:0;position:absolute;pointer-events:none;');
document.body.appendChild(i);})();
`;
return res.send(script.replace(/\s\s+/g, ''));
}

View File

@ -14,7 +14,7 @@ export default async (req, res) => {
return unauthorized(res); return unauthorized(res);
} }
const { id, start_at, end_at, unit, tz, url, event_type } = req.query; const { id, start_at, end_at, unit, tz, url, event_name } = req.query;
if (!moment.tz.zone(tz) || !unitTypes.includes(unit)) { if (!moment.tz.zone(tz) || !unitTypes.includes(unit)) {
return badRequest(res); return badRequest(res);
@ -26,7 +26,7 @@ export default async (req, res) => {
const events = await getEventMetrics(websiteId, startDate, endDate, tz, unit, { const events = await getEventMetrics(websiteId, startDate, endDate, tz, unit, {
url, url,
event_type, event_name,
}); });
return ok(res, events); return ok(res, events);

View File

@ -1,12 +1,11 @@
import { getPageviewMetrics, getSessionMetrics, getWebsiteById, getPageviewParams } from 'queries'; import { getPageviewMetrics, getSessionMetrics, getWebsiteById } from 'queries';
import { ok, methodNotAllowed, unauthorized, badRequest } from 'lib/response'; import { ok, methodNotAllowed, unauthorized, badRequest } from 'lib/response';
import { allowQuery } from 'lib/auth'; import { allowQuery } from 'lib/auth';
import { useCors } from 'lib/middleware'; import { useCors } from 'lib/middleware';
import { FILTER_IGNORED } from 'lib/constants'; import { FILTER_IGNORED } from 'lib/constants';
const sessionColumns = ['browser', 'os', 'device', 'screen', 'country', 'language']; const sessionColumns = ['browser', 'os', 'device', 'screen', 'country', 'language'];
const pageviewColumns = ['url', 'referrer']; const pageviewColumns = ['url', 'referrer', 'query'];
const paramTypes = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term', 'ref'];
function getTable(type) { function getTable(type) {
if (type === 'event') { if (type === 'event') {
@ -17,12 +16,19 @@ function getTable(type) {
return 'session'; return 'session';
} }
return 'pageview'; if (pageviewColumns.includes(type)) {
return 'pageview';
}
throw new Error('Invalid type');
} }
function getColumn(type) { function getColumn(type) {
if (type === 'event') { if (type === 'event') {
return `concat(event_type, '\t', event_value)`; return 'event_name';
}
if (type === 'query') {
return 'url';
} }
return type; return type;
} }
@ -41,52 +47,6 @@ export default async (req, res) => {
const startDate = new Date(+start_at); const startDate = new Date(+start_at);
const endDate = new Date(+end_at); const endDate = new Date(+end_at);
if (paramTypes.includes(type)) {
const column = 'url';
const table = getTable(type);
let domain;
if (type === 'referrer') {
const website = await getWebsiteById(websiteId);
if (!website) {
return badRequest(res);
}
domain = website.domain;
}
const filters = {
domain,
url: type !== 'url' && table !== 'event' ? url : undefined,
referrer: type !== 'referrer' ? referrer : true,
os: type !== 'os' ? os : undefined,
browser: type !== 'browser' ? browser : undefined,
device: type !== 'device' ? device : undefined,
country: type !== 'country' ? country : undefined,
event_url: type !== 'url' && table === 'event' ? url : undefined,
};
let data = await getPageviewParams(
type,
websiteId,
startDate,
endDate,
column,
table,
filters,
);
let terms = {};
new Set(data.map(i => i.param)).forEach(term => (terms[term] = null));
for (let { param } of data) terms[param] += 1;
return ok(
res,
Object.keys(terms).map(i => ({ x: i, y: terms[i] })),
);
}
if (sessionColumns.includes(type)) { if (sessionColumns.includes(type)) {
let data = await getSessionMetrics(websiteId, startDate, endDate, type, { let data = await getSessionMetrics(websiteId, startDate, endDate, type, {
os, os,
@ -116,6 +76,7 @@ export default async (req, res) => {
if (pageviewColumns.includes(type) || type === 'event') { if (pageviewColumns.includes(type) || type === 'event') {
let domain; let domain;
if (type === 'referrer') { if (type === 'referrer') {
const website = await getWebsiteById(websiteId); const website = await getWebsiteById(websiteId);
@ -137,6 +98,7 @@ export default async (req, res) => {
device: type !== 'device' ? device : undefined, device: type !== 'device' ? device : undefined,
country: type !== 'country' ? country : undefined, country: type !== 'country' ? country : undefined,
event_url: type !== 'url' && table === 'event' ? url : undefined, event_url: type !== 'url' && table === 'event' ? url : undefined,
query: type === 'query' && table !== 'event' ? true : undefined,
}; };
const data = await getPageviewMetrics(websiteId, startDate, endDate, column, table, filters); const data = await getPageviewMetrics(websiteId, startDate, endDate, column, table, filters);

View File

@ -2,11 +2,13 @@ import React from 'react';
import Layout from 'components/layout/Layout'; import Layout from 'components/layout/Layout';
import TestConsole from 'components/pages/TestConsole'; import TestConsole from 'components/pages/TestConsole';
import useRequireLogin from 'hooks/useRequireLogin'; import useRequireLogin from 'hooks/useRequireLogin';
import useUser from 'hooks/useUser';
export default function TestPage() { export default function ConsolePage({ enabled }) {
const { loading } = useRequireLogin(); const { loading } = useRequireLogin();
const { user } = useUser();
if (loading) { if (loading || !enabled || !user?.is_admin) {
return null; return null;
} }
@ -16,3 +18,9 @@ export default function TestPage() {
</Layout> </Layout>
); );
} }
export async function getServerSideProps() {
return {
props: { enabled: !!process.env.ENABLE_TEST_CONSOLE },
};
}

View File

@ -2,8 +2,8 @@ import React from 'react';
import Layout from 'components/layout/Layout'; import Layout from 'components/layout/Layout';
import LoginForm from 'components/forms/LoginForm'; import LoginForm from 'components/forms/LoginForm';
export default function LoginPage() { export default function LoginPage({ loginDisabled }) {
if (process.env.loginDisabled) { if (loginDisabled) {
return null; return null;
} }
@ -13,3 +13,9 @@ export default function LoginPage() {
</Layout> </Layout>
); );
} }
export async function getServerSideProps() {
return {
props: { loginDisabled: !!process.env.DISABLE_LOGIN },
};
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -29,12 +29,6 @@
"value": "الكل" "value": "الكل"
} }
], ],
"label.all-events": [
{
"type": 0,
"value": "كافة الأحداث"
}
],
"label.all-time": [ "label.all-time": [
{ {
"type": 0, "type": 0,
@ -477,6 +471,12 @@
"value": "كافة البيانات المرتبطة سيم حذفها ايضا." "value": "كافة البيانات المرتبطة سيم حذفها ايضا."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,
@ -767,6 +767,12 @@
"value": "الصفحات" "value": "الصفحات"
} }
], ],
"metrics.query-parameters": [
{
"type": 0,
"value": "Query parameters"
}
],
"metrics.referrers": [ "metrics.referrers": [
{ {
"type": 0, "type": 0,
@ -785,42 +791,6 @@
"value": "زائرون فريدون" "value": "زائرون فريدون"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -0,0 +1,802 @@
{
"label.accounts": [
{
"type": 0,
"value": "অ্যাকাউন্ট"
}
],
"label.add-account": [
{
"type": 0,
"value": "অ্যাকাউন্ট যুক্ত করুন"
}
],
"label.add-website": [
{
"type": 0,
"value": "ওয়েবসাইট যুক্ত করুন"
}
],
"label.administrator": [
{
"type": 0,
"value": "অ্যাডমিন"
}
],
"label.all": [
{
"type": 0,
"value": "সবগুলো"
}
],
"label.all-time": [
{
"type": 0,
"value": "সব সময়"
}
],
"label.all-websites": [
{
"type": 0,
"value": "সবগুলো ওয়েবসাইট"
}
],
"label.back": [
{
"type": 0,
"value": "পেছনে"
}
],
"label.cancel": [
{
"type": 0,
"value": "বাতিল"
}
],
"label.change-password": [
{
"type": 0,
"value": "পাসওয়ার্ড পরিবর্তন করুন"
}
],
"label.confirm-password": [
{
"type": 0,
"value": "পাসওয়ার্ড নিশ্চিত করুন"
}
],
"label.copy-to-clipboard": [
{
"type": 0,
"value": "কপি করুন"
}
],
"label.current-password": [
{
"type": 0,
"value": "বর্তমান পাসওয়ার্ড"
}
],
"label.custom-range": [
{
"type": 0,
"value": "কাস্টম রেঞ্জ"
}
],
"label.dashboard": [
{
"type": 0,
"value": "ড্যাশবোর্ড"
}
],
"label.date-range": [
{
"type": 0,
"value": "তারিখের পরিসীমা"
}
],
"label.default-date-range": [
{
"type": 0,
"value": "ডিফল্ট তারিখের পরিসীমা"
}
],
"label.delete": [
{
"type": 0,
"value": "মুছে ফেলুন"
}
],
"label.delete-account": [
{
"type": 0,
"value": "অ্যাকাউন্ট মুছুন"
}
],
"label.delete-website": [
{
"type": 0,
"value": "ওয়েবসাইট মুছুন"
}
],
"label.dismiss": [
{
"type": 0,
"value": "বাতিল"
}
],
"label.domain": [
{
"type": 0,
"value": "ডোমেইন"
}
],
"label.edit": [
{
"type": 0,
"value": "সম্পাদনা করুন"
}
],
"label.edit-account": [
{
"type": 0,
"value": "অ্যাকাউন্ট সম্পাদনা করুন"
}
],
"label.edit-website": [
{
"type": 0,
"value": "ওয়েবসাইট সম্পাদনা করুন"
}
],
"label.enable-share-url": [
{
"type": 0,
"value": "শেয়ার ইউআরএল শেয়ার করুন"
}
],
"label.invalid": [
{
"type": 0,
"value": "ভুল"
}
],
"label.invalid-domain": [
{
"type": 0,
"value": "ভুল ডোমেন"
}
],
"label.language": [
{
"type": 0,
"value": "ভাষা"
}
],
"label.last-days": [
{
"type": 0,
"value": "শেষ "
},
{
"type": 1,
"value": "x"
},
{
"type": 0,
"value": " দিন"
}
],
"label.last-hours": [
{
"type": 0,
"value": "শেষ "
},
{
"type": 1,
"value": "x"
},
{
"type": 0,
"value": " ঘন্টা"
}
],
"label.logged-in-as": [
{
"type": 1,
"value": "username"
},
{
"type": 0,
"value": " অ্যাকাউন্টে লগ ইন"
}
],
"label.login": [
{
"type": 0,
"value": "লগিন"
}
],
"label.logout": [
{
"type": 0,
"value": "লগ আউট"
}
],
"label.more": [
{
"type": 0,
"value": "আরও"
}
],
"label.name": [
{
"type": 0,
"value": "নাম"
}
],
"label.new-password": [
{
"type": 0,
"value": "নতুন পাসওয়ার্ড"
}
],
"label.none": [
{
"type": 0,
"value": "কিছুই না"
}
],
"label.owner": [
{
"type": 0,
"value": "মালিক"
}
],
"label.password": [
{
"type": 0,
"value": "পাসওয়ার্ড"
}
],
"label.passwords-dont-match": [
{
"type": 0,
"value": "পাসওয়ার্ড মেলে না"
}
],
"label.profile": [
{
"type": 0,
"value": "প্রোফাইল"
}
],
"label.realtime": [
{
"type": 0,
"value": "সরাসরি"
}
],
"label.realtime-logs": [
{
"type": 0,
"value": "সরাসরি লগ"
}
],
"label.refresh": [
{
"type": 0,
"value": "রিফ্রেশ"
}
],
"label.required": [
{
"type": 0,
"value": "প্রয়োজনীয়"
}
],
"label.reset": [
{
"type": 0,
"value": "রিসেট"
}
],
"label.reset-website": [
{
"type": 0,
"value": "ওয়েবসাইট রিসেট করুন"
}
],
"label.save": [
{
"type": 0,
"value": "সংরক্ষণ"
}
],
"label.settings": [
{
"type": 0,
"value": "সেটিংস"
}
],
"label.share-url": [
{
"type": 0,
"value": "ইউআরএল শেয়ার করুন"
}
],
"label.single-day": [
{
"type": 0,
"value": "একদিন"
}
],
"label.theme": [
{
"type": 0,
"value": "থিম"
}
],
"label.this-month": [
{
"type": 0,
"value": "এই মাস"
}
],
"label.this-week": [
{
"type": 0,
"value": "এই সপ্তাহ"
}
],
"label.this-year": [
{
"type": 0,
"value": "এই বছর"
}
],
"label.timezone": [
{
"type": 0,
"value": "সময়স্থান"
}
],
"label.today": [
{
"type": 0,
"value": "আজ"
}
],
"label.tracking-code": [
{
"type": 0,
"value": "ট্র্যাকিং কোড"
}
],
"label.unknown": [
{
"type": 0,
"value": "অজানা"
}
],
"label.username": [
{
"type": 0,
"value": "ব্যবহারকারীর নাম"
}
],
"label.view-details": [
{
"type": 0,
"value": "বিস্তারিত দেখুন"
}
],
"label.websites": [
{
"type": 0,
"value": "সবগুলো ওয়েবসাইট"
}
],
"message.active-users": [
{
"type": 1,
"value": "x"
},
{
"type": 0,
"value": " বর্তমান "
},
{
"offset": 0,
"options": {
"one": {
"value": [
{
"type": 0,
"value": "visitor"
}
]
},
"other": {
"value": [
{
"type": 0,
"value": "visitors"
}
]
}
},
"pluralType": "cardinal",
"type": 6,
"value": "x"
}
],
"message.confirm-delete": [
{
"type": 0,
"value": "আপনি কি নিশ্চিত যে আপনি "
},
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": " মুছতে চান?"
}
],
"message.confirm-reset": [
{
"type": 0,
"value": "আপনি কি নিশ্চিত যে আপনি "
},
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": " এর পরিসংখ্যান পুনরায় সেট করতে চান?"
}
],
"message.copied": [
{
"type": 0,
"value": "কপি হয়েছে"
}
],
"message.delete-warning": [
{
"type": 0,
"value": "সমস্ত সম্পর্কিত ডেটা পাশাপাশি মুছে ফেলা হবে।"
}
],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [
{
"type": 0,
"value": "কিছু ভুল হয়েছে।"
}
],
"message.get-share-url": [
{
"type": 0,
"value": "শেয়ার ইউআরএল"
}
],
"message.get-tracking-code": [
{
"type": 0,
"value": "ট্র্যাকিং কোড পান"
}
],
"message.go-to-settings": [
{
"type": 0,
"value": "সেটিংস এ যান"
}
],
"message.incorrect-username-password": [
{
"type": 0,
"value": "ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড।"
}
],
"message.log.visitor": [
{
"type": 1,
"value": "country"
},
{
"type": 0,
"value": " থেকে একজন ভিসিটর "
},
{
"type": 1,
"value": "ব্রাউজার"
},
{
"type": 0,
"value": ", ব্যবহার করছেন "
},
{
"type": 1,
"value": "os"
},
{
"type": 0,
"value": " "
},
{
"type": 1,
"value": "device"
},
{
"type": 0,
"value": " এর মধ্যে।"
}
],
"message.new-version-available": [
{
"type": 0,
"value": "নতুন সংস্করণ "
},
{
"type": 1,
"value": "version"
},
{
"type": 0,
"value": " পাওয়া গিয়েছে।"
}
],
"message.no-data-available": [
{
"type": 0,
"value": "কোন তথ্য নেই।"
}
],
"message.no-websites-configured": [
{
"type": 0,
"value": "কোনও ওয়েবসাইট কনফিগার করা নেই।"
}
],
"message.page-not-found": [
{
"type": 0,
"value": "পৃষ্ঠা খুঁজে পাওয়া যায়নি।"
}
],
"message.powered-by": [
{
"type": 1,
"value": "name"
},
{
"type": 0,
"value": " দ্বারা চালিত"
}
],
"message.reset-warning": [
{
"type": 0,
"value": "এই ওয়েবসাইটের সমস্ত পরিসংখ্যান মুছে ফেলা হবে, তবে আপনার ট্র্যাকিং কোডটি অক্ষত থাকবে।"
}
],
"message.save-success": [
{
"type": 0,
"value": "সংরক্ষিত হয়েছে।"
}
],
"message.share-url": [
{
"type": 0,
"value": "এটি "
},
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": " এর জন্য প্রকাশ্যে শেয়ার করার ইউআরএল।"
}
],
"message.toggle-charts": [
{
"type": 0,
"value": "চার্ট পরিবর্তন করুন"
}
],
"message.track-stats": [
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": " এর জন্য পরিসংখ্যানগুলি ট্র্যাক করতে, আপনার ওয়েবসাইটের "
},
{
"type": 1,
"value": "head"
},
{
"type": 0,
"value": " বিভাগে নিম্নলিখিত কোডটি রাখুন।"
}
],
"message.type-delete": [
{
"type": 0,
"value": "নিশ্চিত করতে নীচের বাক্সে "
},
{
"type": 1,
"value": "delete"
},
{
"type": 0,
"value": " টাইপ করুন।"
}
],
"message.type-reset": [
{
"type": 0,
"value": "নিশ্চিত করতে নীচের বাক্সে "
},
{
"type": 1,
"value": "reset"
},
{
"type": 0,
"value": " টাইপ করুন।"
}
],
"metrics.actions": [
{
"type": 0,
"value": "অ্যাকশনস"
}
],
"metrics.average-visit-time": [
{
"type": 0,
"value": "গড় পরিদর্শনের সময়"
}
],
"metrics.bounce-rate": [
{
"type": 0,
"value": "বহিষ্কারের হার"
}
],
"metrics.browsers": [
{
"type": 0,
"value": "ব্রাউজার"
}
],
"metrics.countries": [
{
"type": 0,
"value": "দেশ"
}
],
"metrics.device.desktop": [
{
"type": 0,
"value": "ডেস্কটপ"
}
],
"metrics.device.laptop": [
{
"type": 0,
"value": "ল্যাপটপ"
}
],
"metrics.device.mobile": [
{
"type": 0,
"value": "মুঠোফোন"
}
],
"metrics.device.tablet": [
{
"type": 0,
"value": "ট্যাবলেট"
}
],
"metrics.devices": [
{
"type": 0,
"value": "ডিভাইস গুলো"
}
],
"metrics.events": [
{
"type": 0,
"value": "ঘটনা"
}
],
"metrics.filter.combined": [
{
"type": 0,
"value": "সম্মিলিত"
}
],
"metrics.filter.raw": [
{
"type": 0,
"value": "অপরিশোধিত"
}
],
"metrics.languages": [
{
"type": 0,
"value": "ভাষা"
}
],
"metrics.operating-systems": [
{
"type": 0,
"value": "অপারেটিং সিস্টেম গুলো"
}
],
"metrics.page-views": [
{
"type": 0,
"value": "পৃষ্ঠা পরিদর্শন গুলো"
}
],
"metrics.pages": [
{
"type": 0,
"value": "পৃষ্ঠাগুলি"
}
],
"metrics.query-parameters": [
{
"type": 0,
"value": "Query parameters"
}
],
"metrics.referrers": [
{
"type": 0,
"value": "রেফারার্স"
}
],
"metrics.screens": [
{
"type": 0,
"value": "স্ক্রিনগুলি"
}
],
"metrics.unique-visitors": [
{
"type": 0,
"value": "অনন্য ভিজিটর"
}
],
"metrics.views": [
{
"type": 0,
"value": "ভিউস"
}
],
"metrics.visitors": [
{
"type": 0,
"value": "পরিদর্শনার্থী"
}
]
}

View File

@ -29,12 +29,6 @@
"value": "Tots" "value": "Tots"
} }
], ],
"label.all-events": [
{
"type": 0,
"value": "Tots els esdeveniments"
}
],
"label.all-time": [ "label.all-time": [
{ {
"type": 0, "type": 0,
@ -477,6 +471,12 @@
"value": "També s'esborraran totes les dades relacionades." "value": "També s'esborraran totes les dades relacionades."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,
@ -767,6 +767,12 @@
"value": "Pàgines" "value": "Pàgines"
} }
], ],
"metrics.query-parameters": [
{
"type": 0,
"value": "Query parameters"
}
],
"metrics.referrers": [ "metrics.referrers": [
{ {
"type": 0, "type": 0,
@ -785,42 +791,6 @@
"value": "Visitants únics" "value": "Visitants únics"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

Some files were not shown because too many files have changed in this diff Show More