mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-14 21:10:34 +01:00
Merge branch 'dev' of https://github.com/umami-software/umami into francis/uc-24-kafka-test
This commit is contained in:
commit
1ffd5775f8
@ -6,10 +6,15 @@ import { setItem } from 'lib/web';
|
|||||||
import { REPO_URL, VERSION_CHECK } from 'lib/constants';
|
import { REPO_URL, VERSION_CHECK } from 'lib/constants';
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
import styles from './UpdateNotice.module.css';
|
import styles from './UpdateNotice.module.css';
|
||||||
|
import useUser from 'hooks/useUser';
|
||||||
|
import useConfig from 'hooks/useConfig';
|
||||||
|
|
||||||
export default function UpdateNotice() {
|
export default function UpdateNotice() {
|
||||||
|
const { user } = useUser();
|
||||||
|
const { updatesDisabled } = useConfig();
|
||||||
const { latest, checked, hasUpdate, releaseUrl } = useStore();
|
const { latest, checked, hasUpdate, releaseUrl } = useStore();
|
||||||
const [dismissed, setDismissed] = useState(false);
|
const [dismissed, setDismissed] = useState(false);
|
||||||
|
const allowCheck = user?.is_admin && !updatesDisabled;
|
||||||
|
|
||||||
const updateCheck = useCallback(() => {
|
const updateCheck = useCallback(() => {
|
||||||
setItem(VERSION_CHECK, { version: latest, time: Date.now() });
|
setItem(VERSION_CHECK, { version: latest, time: Date.now() });
|
||||||
@ -27,12 +32,12 @@ export default function UpdateNotice() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!checked) {
|
if (!checked && allowCheck) {
|
||||||
checkVersion();
|
checkVersion();
|
||||||
}
|
}
|
||||||
}, []);
|
}, [checked]);
|
||||||
|
|
||||||
if (!hasUpdate || dismissed) {
|
if (!hasUpdate || dismissed || !allowCheck) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
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';
|
||||||
@ -8,6 +9,7 @@ import { HOMEPAGE_URL, REPO_URL } from 'lib/constants';
|
|||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
const { current } = useStore();
|
const { current } = useStore();
|
||||||
|
const { pathname } = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className={classNames(styles.footer, 'row')}>
|
<footer className={classNames(styles.footer, 'row')}>
|
||||||
@ -28,9 +30,7 @@ export default function Footer() {
|
|||||||
<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}`}</Link>
|
||||||
</div>
|
</div>
|
||||||
{!process.env.telemetryDisabled && (
|
{!pathname.includes('/share/') && <Script src={`/telemetry.js?v=${current}`} />}
|
||||||
<img src={`https://i.umami.is/a.png?v=${current}`} alt="" />
|
|
||||||
)}
|
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,10 @@ 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 Logo from 'assets/logo.svg';
|
|
||||||
import styles from './Header.module.css';
|
|
||||||
import useUser from 'hooks/useUser';
|
import useUser from 'hooks/useUser';
|
||||||
import { HOMEPAGE_URL } from 'lib/constants';
|
import { HOMEPAGE_URL } from 'lib/constants';
|
||||||
|
import Logo from 'assets/logo.svg';
|
||||||
|
import styles from './Header.module.css';
|
||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
@ -19,7 +19,7 @@ export default function Header() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{user?.is_admin && !process.env.updatesDisabled && <UpdateNotice />}
|
<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} />
|
||||||
|
@ -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(() => {
|
||||||
|
@ -92,8 +92,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,10 +102,10 @@ export default function RealtimeLog({ data, websites, websiteId }) {
|
|||||||
device,
|
device,
|
||||||
website_id,
|
website_id,
|
||||||
}) {
|
}) {
|
||||||
if (event_type) {
|
if (event_name) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Tag>{event_type}</Tag> {event_value}
|
<Tag>{event_name}</Tag>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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 data={data} />}
|
||||||
|
{!editing && <WebsiteList data={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>
|
||||||
|
104
components/pages/DashboardEdit.js
Normal file
104
components/pages/DashboardEdit.js
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
|
||||||
|
import useDashboard, { saveDashboard } from 'store/dashboard';
|
||||||
|
import Button from 'components/common/Button';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { orderByWebsiteMap } from 'lib/format';
|
||||||
|
import styles from './DashboardEdit.module.css';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
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({ data: websites }) {
|
||||||
|
const settings = useDashboard();
|
||||||
|
const { websiteOrder } = settings;
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
const [order, setOrder] = useState(websiteOrder);
|
||||||
|
|
||||||
|
const ordered = useMemo(() => orderByWebsiteMap(websites, order), [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((i, k) => ({ [i.website_uuid]: k })).reduce((a, b) => ({ ...a, ...b })),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Droppable>
|
||||||
|
</DragDropContext>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
40
components/pages/DashboardEdit.module.css
Normal file
40
components/pages/DashboardEdit.module.css
Normal 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;
|
||||||
|
}
|
@ -37,7 +37,8 @@ export default function TestConsole() {
|
|||||||
function handleClick() {
|
function handleClick() {
|
||||||
window.umami('event (default)');
|
window.umami('event (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('event (custom)', null, 'custom-type');
|
||||||
|
window.umami.trackEvent('event (custom)', { test: 'test-data' }, 'custom-data-type');
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,25 +1,37 @@
|
|||||||
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 { orderByWebsiteMap } from 'lib/format';
|
||||||
|
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({ data, showCharts, limit }) {
|
||||||
|
const { websiteOrder } = useDashboard();
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
|
const websites = useMemo(() => orderByWebsiteMap(data, websiteOrder), [data, websiteOrder]);
|
||||||
|
|
||||||
export default function WebsiteList({ websites, showCharts, limit }) {
|
|
||||||
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>
|
||||||
|
@ -1,26 +1,39 @@
|
|||||||
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 => {
|
||||||
|
const bs = { showCharts: !state.showCharts };
|
||||||
|
console.log('WTF', { state, bs });
|
||||||
|
return bs;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
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 />;
|
||||||
|
5
components/settings/DashboardSettingsButton.module.css
Normal file
5
components/settings/DashboardSettingsButton.module.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.buttonGroup {
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
@ -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 => (
|
||||||
|
62
db/mysql/migrations/02_add_event_data/migration.sql
Normal file
62
db/mysql/migrations/02_add_event_data/migration.sql
Normal 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`;
|
@ -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[]
|
||||||
|
66
db/postgresql/migrations/02_add_event_data/migration.sql
Normal file
66
db/postgresql/migrations/02_add_event_data/migration.sql
Normal 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";
|
@ -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])
|
||||||
}
|
}
|
||||||
|
@ -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
24
hooks/useConfig.js
Normal 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 || {};
|
||||||
|
}
|
@ -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"],
|
||||||
|
@ -68,6 +68,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": "احصل على كود التتبع",
|
||||||
|
@ -68,6 +68,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": "ট্র্যাকিং কোড পান",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -37,7 +37,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 +68,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",
|
||||||
@ -107,11 +108,11 @@
|
|||||||
"metrics.screens": "Bildschirmauflösungen",
|
"metrics.screens": "Bildschirmauflösungen",
|
||||||
"metrics.unique-visitors": "Eindeutige Besucher",
|
"metrics.unique-visitors": "Eindeutige Besucher",
|
||||||
"metrics.utm": "UTM",
|
"metrics.utm": "UTM",
|
||||||
"metrics.utm_campaign": "UTM Campaign",
|
"metrics.utm_campaign": "UTM Kampagne",
|
||||||
"metrics.utm_content": "UTM Content",
|
"metrics.utm_content": "UTM Inhalt",
|
||||||
"metrics.utm_medium": "UTM Medium",
|
"metrics.utm_medium": "UTM Medium",
|
||||||
"metrics.utm_source": "UTM Source",
|
"metrics.utm_source": "UTM Quelle",
|
||||||
"metrics.utm_term": "UTM Term",
|
"metrics.utm_term": "UTM Begriff",
|
||||||
"metrics.views": "Aufrufe",
|
"metrics.views": "Aufrufe",
|
||||||
"metrics.visitors": "Besucher"
|
"metrics.visitors": "Besucher"
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,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": "Λήψη κώδικα παρακολούθησης",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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": "گرفتن کد رهگیری",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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": "קבלת קוד מעקב",
|
||||||
|
@ -68,6 +68,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": "ट्रैकिंग कोड प्राप्त करें",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,7 @@
|
|||||||
"message.confirm-reset": "Anda yakin ingin mengatur ulang statistik {target}?",
|
"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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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": "トラッキングコードを取得",
|
||||||
|
@ -68,6 +68,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": "추적 코드 가져오기",
|
||||||
|
@ -68,6 +68,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ą",
|
||||||
|
@ -68,6 +68,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": "Мөрдөх код авах",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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": "Получить код отслеживания",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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": "கண்காணிப்பு குறியீட்டைப் பெறுக",
|
||||||
|
118
lang/th-TH.json
Normal file
118
lang/th-TH.json
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
{
|
||||||
|
"label.accounts": "บัญชี",
|
||||||
|
"label.add-account": "เพิ่มบัญชี",
|
||||||
|
"label.add-website": "เพิ่มเว็บไซต์",
|
||||||
|
"label.administrator": "ผู้ดูแลระบบ",
|
||||||
|
"label.all": "ทั้งหมด",
|
||||||
|
"label.all-events": "เหตุการณ์ทั้งหมด",
|
||||||
|
"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.referrers": "แหล่งที่มา",
|
||||||
|
"metrics.screens": "ขนาดหน้าจอ",
|
||||||
|
"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.visitors": "ผู้เข้าชม"
|
||||||
|
}
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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": "Отримати код для відслідковування",
|
||||||
|
@ -68,6 +68,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": "ٹریکنگ کوڈ حاصل کریں",
|
||||||
|
@ -68,6 +68,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",
|
||||||
|
@ -68,6 +68,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": "获取跟踪代码",
|
||||||
|
@ -68,6 +68,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": "獲得追蹤代碼",
|
||||||
|
@ -9,6 +9,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';
|
||||||
|
@ -217,7 +217,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));
|
||||||
@ -247,17 +247,17 @@ 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 } = filters;
|
||||||
|
|
||||||
const pageviewFilters = { domain, url, referrer };
|
const pageviewFilters = { domain, url, referrer };
|
||||||
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}`
|
||||||
|
@ -78,3 +78,14 @@ export function stringToColor(str) {
|
|||||||
}
|
}
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function orderByWebsiteMap(websites, orderMap) {
|
||||||
|
if (!websites) return [];
|
||||||
|
|
||||||
|
let ordered = [...websites];
|
||||||
|
for (let website of websites) {
|
||||||
|
ordered[orderMap[website.website_uuid]] = website;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ordered;
|
||||||
|
}
|
||||||
|
@ -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' },
|
||||||
|
@ -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);
|
||||||
|
15
lib/web.js
15
lib/web.js
@ -61,10 +61,17 @@ 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
export const removeItem = (key, session) => {
|
export const removeItem = (key, session) => {
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,40 @@
|
|||||||
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,
|
|
||||||
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 +53,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',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
"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",
|
||||||
@ -86,6 +86,7 @@
|
|||||||
"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",
|
||||||
@ -128,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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
@ -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';
|
||||||
|
@ -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
14
pages/api/config.js
Normal 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);
|
||||||
|
};
|
18
pages/api/scripts/telemetry.js
Normal file
18
pages/api/scripts/telemetry.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { TELEMETRY_PIXEL } from 'lib/constants';
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
const { v } = req.query;
|
||||||
|
const script = `
|
||||||
|
(()=>{const i=document.createElement('img');
|
||||||
|
i.setAttribute('src','${TELEMETRY_PIXEL}?v=${v}');
|
||||||
|
i.setAttribute('style','width:0;height:0;position:absolute;pointer-events:none;');
|
||||||
|
document.body.appendChild(i);})();
|
||||||
|
`;
|
||||||
|
|
||||||
|
res.setHeader('content-type', 'text/javascript');
|
||||||
|
if (process.env.DISABLE_TELEMETRY) {
|
||||||
|
res.send('/* telemetry disabled */');
|
||||||
|
} else {
|
||||||
|
res.send(script.replace(/\s\s+/g, ''));
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
@ -22,7 +22,7 @@ function getTable(type) {
|
|||||||
|
|
||||||
function getColumn(type) {
|
function getColumn(type) {
|
||||||
if (type === 'event') {
|
if (type === 'event') {
|
||||||
return `concat(event_type, '\t', event_value)`;
|
return `event_name`;
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -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 },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
1
public/intl/country/bn-BD.json
Normal file
1
public/intl/country/bn-BD.json
Normal file
File diff suppressed because one or more lines are too long
1
public/intl/country/th-TH.json
Normal file
1
public/intl/country/th-TH.json
Normal file
File diff suppressed because one or more lines are too long
1
public/intl/language/bn-BD.json
Normal file
1
public/intl/language/bn-BD.json
Normal file
File diff suppressed because one or more lines are too long
1
public/intl/language/th-TH.json
Normal file
1
public/intl/language/th-TH.json
Normal file
File diff suppressed because one or more lines are too long
@ -477,6 +477,12 @@
|
|||||||
"value": "كافة البيانات المرتبطة سيم حذفها ايضا."
|
"value": "كافة البيانات المرتبطة سيم حذفها ايضا."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
838
public/intl/messages/bn-BD.json
Normal file
838
public/intl/messages/bn-BD.json
Normal file
@ -0,0 +1,838 @@
|
|||||||
|
{
|
||||||
|
"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-events": [
|
||||||
|
{
|
||||||
|
"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.referrers": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "রেফারার্স"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metrics.screens": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "স্ক্রিনগুলি"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metrics.unique-visitors": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "অনন্য ভিজিটর"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metrics.utm": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "UTM"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metrics.utm_campaign": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "UTM প্রচার"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metrics.utm_content": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "UTM সামগ্রী"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metrics.utm_medium": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "UTM মিডিয়াম"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metrics.utm_source": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "UTM উৎস"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metrics.utm_term": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "UTM শব্দ"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metrics.views": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "ভিউস"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metrics.visitors": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "পরিদর্শনার্থী"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -477,6 +477,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,
|
||||||
|
@ -477,6 +477,12 @@
|
|||||||
"value": "Všechna související data budou také smazána."
|
"value": "Všechna související data budou také smazána."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -477,6 +477,12 @@
|
|||||||
"value": "Alle tilknyttede data slettes også."
|
"value": "Alle tilknyttede data slettes også."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -250,7 +250,7 @@
|
|||||||
"label.none": [
|
"label.none": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "None"
|
"value": "Keine"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"label.owner": [
|
"label.owner": [
|
||||||
@ -477,6 +477,12 @@
|
|||||||
"value": "Alle zugehörigen Daten werden ebenfalls gelöscht."
|
"value": "Alle zugehörigen Daten werden ebenfalls gelöscht."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
@ -794,13 +800,13 @@
|
|||||||
"metrics.utm_campaign": [
|
"metrics.utm_campaign": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "UTM Campaign"
|
"value": "UTM Kampagne"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metrics.utm_content": [
|
"metrics.utm_content": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "UTM Content"
|
"value": "UTM Inhalt"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metrics.utm_medium": [
|
"metrics.utm_medium": [
|
||||||
@ -812,13 +818,13 @@
|
|||||||
"metrics.utm_source": [
|
"metrics.utm_source": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "UTM Source"
|
"value": "UTM Quelle"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metrics.utm_term": [
|
"metrics.utm_term": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "UTM Term"
|
"value": "UTM Begriff"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metrics.views": [
|
"metrics.views": [
|
||||||
|
@ -477,6 +477,12 @@
|
|||||||
"value": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης."
|
"value": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -477,6 +477,12 @@
|
|||||||
"value": "All associated data will be deleted as well."
|
"value": "All associated data will be deleted as well."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -477,6 +477,12 @@
|
|||||||
"value": "All associated data will be deleted as well."
|
"value": "All associated data will be deleted as well."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -477,6 +477,12 @@
|
|||||||
"value": "Toda la información relacionada será eliminada."
|
"value": "Toda la información relacionada será eliminada."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -477,6 +477,12 @@
|
|||||||
"value": "همهی دادههای مرتبط هم حذف خواهد شد."
|
"value": "همهی دادههای مرتبط هم حذف خواهد شد."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -477,6 +477,12 @@
|
|||||||
"value": "Kaikki siihen liittyvät tiedot poistetaan."
|
"value": "Kaikki siihen liittyvät tiedot poistetaan."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -477,6 +477,12 @@
|
|||||||
"value": "Øll data ið er knýtt at verður eisini strika."
|
"value": "Øll data ið er knýtt at verður eisini strika."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -473,6 +473,12 @@
|
|||||||
"value": "Toutes les données associées seront également supprimées."
|
"value": "Toutes les données associées seront également supprimées."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -477,6 +477,12 @@
|
|||||||
"value": "Tamén serán borrados tódolos datos asociados."
|
"value": "Tamén serán borrados tódolos datos asociados."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
@ -469,6 +469,12 @@
|
|||||||
"value": "כל המידע המקושר יימחק"
|
"value": "כל המידע המקושר יימחק"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"message.edit-dashboard": [
|
||||||
|
{
|
||||||
|
"type": 0,
|
||||||
|
"value": "Edit dashboard"
|
||||||
|
}
|
||||||
|
],
|
||||||
"message.failure": [
|
"message.failure": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user