Refactored website ordering feature.

This commit is contained in:
Mike Cao 2022-08-04 03:56:30 -07:00
parent 62dce0a8d1
commit 1d4aa7c535
96 changed files with 518 additions and 174 deletions

View File

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

View File

@ -0,0 +1,100 @@
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';
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 });
}
function handleReset() {
setOrder({});
saveDashboard({ websiteOrder: {} });
}
return (
<>
<div className={styles.buttons}>
<Button onClick={handleSave} 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 => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
className={styles.item}
>
<h1>{name}</h1>
<h2>{domain}</h2>
</div>
)}
</Draggable>
))}
</div>
)}
</Droppable>
</DragDropContext>
</div>
</>
);
}

View File

@ -0,0 +1,34 @@
.buttons {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-bottom: 20px;
}
.item {
padding: 20px;
border-radius: 5px;
border: 1px solid var(--gray300);
}
.item + .item {
margin-top: 10px;
}
.item h1 {
font-weight: 600;
font-size: 16px;
}
.item h2 {
font-size: 14px;
color: var(--gray700);
}
.dragActive {
cursor: grab;
}
.dragActive:active {
cursor: grabbing;
}

View File

@ -1,4 +1,3 @@
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } 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';
@ -6,37 +5,14 @@ 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 { orderByWebsiteMap } from 'lib/format';
import { useMemo } from 'react'; import { useMemo } from 'react';
import useStore, { setDashboard } from 'store/app';
const selector = state => state.dashboard; export default function WebsiteList({ data, showCharts, limit }) {
const { websiteOrder } = useDashboard();
export default function WebsiteList({ websites, showCharts, limit }) { const websites = useMemo(() => orderByWebsiteMap(data, websiteOrder), [data, websiteOrder]);
const store = useStore(selector);
const { websiteOrdering, changeOrderMode } = store;
const ordered = useMemo(
() => orderByWebsiteMap(websites, websiteOrdering),
[websites, websiteOrdering],
);
const dragId = 'dashboard-website-ordering';
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);
setDashboard({
...store,
websiteOrdering: orderedWebsites
.map((i, k) => ({ [i.website_uuid]: k }))
.reduce((a, b) => ({ ...a, ...b })),
});
}
if (websites.length === 0) { if (websites.length === 0) {
return ( return (
@ -58,60 +34,19 @@ export default function WebsiteList({ websites, showCharts, limit }) {
} }
return ( return (
<div className={changeOrderMode && styles.websiteDragActive}> <div>
{changeOrderMode ? ( {websites.map(({ website_id, name, domain }, index) =>
<DragDropContext onDragEnd={handleWebsiteDrag}> index < limit ? (
<Droppable droppableId={dragId}> <div key={website_id} className={styles.website}>
{(provided, snapshot) => ( <WebsiteChart
<div websiteId={website_id}
{...provided.droppableProps} title={name}
ref={provided.innerRef} domain={domain}
style={{ marginBottom: snapshot.isDraggingOver ? 260 : null }} showChart={showCharts}
> showLink
{ordered.map(({ website_id, name, domain }, index) => />
index < limit ? ( </div>
<Draggable ) : null,
key={website_id}
draggableId={`${dragId}-${website_id}`}
index={index}
>
{provided => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
className={styles.website}
>
<WebsiteChart
websiteId={website_id}
title={name}
domain={domain}
showChart={changeOrderMode ? false : showCharts}
showLink
/>
</div>
)}
</Draggable>
) : null,
)}
</div>
)}
</Droppable>
</DragDropContext>
) : (
ordered.map(({ website_id, name, domain }, index) =>
index < limit ? (
<div key={website_id} className={styles.website}>
<WebsiteChart
websiteId={website_id}
title={name}
domain={domain}
showChart={showCharts}
showLink
/>
</div>
) : null,
)
)} )}
</div> </div>
); );

View File

@ -9,12 +9,3 @@
border-bottom: 0; border-bottom: 0;
margin-bottom: 20px; margin-bottom: 20px;
} }
.websiteDragActive {
opacity: 0.6;
cursor: grab;
}
.websiteDragActive:active {
cursor: grabbing;
}

View File

@ -1,57 +1,40 @@
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 } from 'store/app'; import { saveDashboard } from 'store/dashboard';
import Button from 'components/common/Button';
import Check from 'assets/check.svg';
import styles from './DashboardSettingsButton.module.css';
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: <FormattedMessage id="message.edit-dashboard" defaultMessage="Edit dashboard" />, label: formatMessage(messages.editDashboard),
value: 'order', value: 'order',
}, },
]; ];
function handleSelect(value) { function handleSelect(value) {
if (value === 'charts') { if (value === 'charts') {
setDashboard({ ...settings, showCharts: !settings.showCharts }); saveDashboard(state => {
const bs = { showCharts: !state.showCharts };
console.log('WTF', { state, bs });
return bs;
});
} }
if (value === 'order') { if (value === 'order') {
setDashboard({ ...settings, changeOrderMode: !settings.changeOrderMode }); saveDashboard({ editing: true });
} }
//setDashboard(value);
} }
function handleExitChangeOrderMode() {
setDashboard({ ...settings, changeOrderMode: !settings.changeOrderMode });
}
function resetWebsiteOrder() {
setDashboard({ ...settings, websiteOrdering: {} });
}
if (settings.changeOrderMode)
return (
<div className={styles.buttonGroup}>
<Button onClick={resetWebsiteOrder} size="small">
<FormattedMessage id="label.reset-order" defaultMessage="Reset order" />
</Button>
<Button onClick={handleExitChangeOrderMode} size="small" icon={<Check />}>
<FormattedMessage id="label.done" defaultMessage="Done" />
</Button>
</div>
);
return <MenuButton icon={<Gear />} options={menuOptions} onSelect={handleSelect} hideLabel />; return <MenuButton icon={<Gear />} options={menuOptions} onSelect={handleSelect} hideLabel />;
} }

View File

@ -1,4 +1,4 @@
import React, { useMemo, useState } from 'react'; import React, { useState } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import Link from 'components/common/Link'; import Link from 'components/common/Link';
@ -24,12 +24,8 @@ import Code from 'assets/code.svg';
import LinkIcon from 'assets/link.svg'; import LinkIcon from 'assets/link.svg';
import useFetch from 'hooks/useFetch'; import useFetch from 'hooks/useFetch';
import useUser from 'hooks/useUser'; import useUser from 'hooks/useUser';
import { orderByWebsiteMap } from 'lib/format';
import useStore from 'store/app';
import styles from './WebsiteSettings.module.css'; import styles from './WebsiteSettings.module.css';
const selector = state => state.dashboard;
export default function WebsiteSettings() { export default function WebsiteSettings() {
const { user } = useUser(); const { user } = useUser();
const [editWebsite, setEditWebsite] = useState(); const [editWebsite, setEditWebsite] = useState();
@ -41,13 +37,8 @@ export default function WebsiteSettings() {
const [saved, setSaved] = useState(0); const [saved, setSaved] = useState(0);
const [message, setMessage] = useState(); const [message, setMessage] = useState();
const store = useStore(selector);
const { websiteOrdering } = store;
const { data } = useFetch('/websites', { params: { include_all: !!user?.is_admin } }, [saved]); const { data } = useFetch('/websites', { params: { include_all: !!user?.is_admin } }, [saved]);
const ordered = useMemo(() => orderByWebsiteMap(data, websiteOrdering), [data, websiteOrdering]);
const Buttons = row => ( const Buttons = row => (
<ButtonLayout align="right"> <ButtonLayout align="right">
{row.share_id && ( {row.share_id && (
@ -196,7 +187,7 @@ export default function WebsiteSettings() {
<FormattedMessage id="label.add-website" defaultMessage="Add website" /> <FormattedMessage id="label.add-website" defaultMessage="Add website" />
</Button> </Button>
</PageHeader> </PageHeader>
<Table columns={user.is_admin ? adminColumns : columns} rows={ordered} empty={empty} /> <Table columns={user.is_admin ? adminColumns : columns} rows={data} empty={empty} />
{editWebsite && ( {editWebsite && (
<Modal title={<FormattedMessage id="label.edit-website" defaultMessage="Edit website" />}> <Modal title={<FormattedMessage id="label.edit-website" defaultMessage="Edit website" />}>
<WebsiteEditForm values={editWebsite} onSave={handleSave} onClose={handleClose} /> <WebsiteEditForm values={editWebsite} onSave={handleSave} onClose={handleClose} />

View File

@ -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": "احصل على كود التتبع",

View File

@ -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": "ট্র্যাকিং কোড পান",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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": "Λήψη κώδικα παρακολούθησης",

View File

@ -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",

View File

@ -22,10 +22,8 @@
"label.delete-website": "Delete website", "label.delete-website": "Delete website",
"label.dismiss": "Dismiss", "label.dismiss": "Dismiss",
"label.domain": "Domain", "label.domain": "Domain",
"label.done": "Done",
"label.edit": "Edit", "label.edit": "Edit",
"label.edit-account": "Edit account", "label.edit-account": "Edit account",
"label.edit-dashboard": "Edit dashboard",
"label.edit-website": "Edit website", "label.edit-website": "Edit website",
"label.enable-share-url": "Enable share URL", "label.enable-share-url": "Enable share URL",
"label.invalid": "Invalid", "label.invalid": "Invalid",
@ -49,7 +47,6 @@
"label.refresh": "Refresh", "label.refresh": "Refresh",
"label.required": "Required", "label.required": "Required",
"label.reset": "Reset", "label.reset": "Reset",
"label.reset-order": "Reset order",
"label.reset-website": "Reset statistics", "label.reset-website": "Reset statistics",
"label.save": "Save", "label.save": "Save",
"label.settings": "Settings", "label.settings": "Settings",
@ -71,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",

View File

@ -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",

View File

@ -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": "گرفتن کد رهگیری",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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": "קבלת קוד מעקב",

View File

@ -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": "ट्रैकिंग कोड प्राप्त करें",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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": "トラッキングコードを取得",

View File

@ -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": "추적 코드 가져오기",

View File

@ -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ą",

View File

@ -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": "Мөрдөх код авах",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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": "Получить код отслеживания",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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": "கண்காணிப்பு குறியீட்டைப் பெறுக",

View File

@ -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": "รับโค้ดสำหรับใช้ติดตาม",

View File

@ -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",

View File

@ -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": "Отримати код для відслідковування",

View File

@ -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": "ٹریکنگ کوڈ حاصل کریں",

View File

@ -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",

View File

@ -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": "获取跟踪代码",

View File

@ -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": "獲得追蹤代碼",

View File

@ -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') {

View File

@ -477,6 +477,12 @@
"value": "كافة البيانات المرتبطة سيم حذفها ايضا." "value": "كافة البيانات المرتبطة سيم حذفها ايضا."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -477,6 +477,12 @@
"value": "সমস্ত সম্পর্কিত ডেটা পাশাপাশি মুছে ফেলা হবে।" "value": "সমস্ত সম্পর্কিত ডেটা পাশাপাশি মুছে ফেলা হবে।"
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -477,6 +477,12 @@
"value": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης." "value": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -477,6 +477,12 @@
"value": "همه‌ی داده‌های مرتبط هم حذف خواهد شد." "value": "همه‌ی داده‌های مرتبط هم حذف خواهد شد."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -469,6 +469,12 @@
"value": "כל המידע המקושר יימחק" "value": "כל המידע המקושר יימחק"
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -477,6 +477,12 @@
"value": "सभी संबद्ध डेटा को भी हटा दिया जाएगा।" "value": "सभी संबद्ध डेटा को भी हटा दिया जाएगा।"
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -481,6 +481,12 @@
"value": "Minden társított adat törlésre kerül." "value": "Minden társított adat törlésre kerül."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -445,6 +445,12 @@
"value": "Semua data terkait juga akan dihapus." "value": "Semua data terkait juga akan dihapus."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -481,6 +481,12 @@
"value": "Saranno eliminati anche tutti i dati associati." "value": "Saranno eliminati anche tutti i dati associati."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -449,6 +449,12 @@
"value": "関連するすべてのデータも削除されます。" "value": "関連するすべてのデータも削除されます。"
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -449,6 +449,12 @@
"value": "관련된 모든 데이터도 삭제됩니다." "value": "관련된 모든 데이터도 삭제됩니다."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -602,6 +602,12 @@
"value": "Visi susiję duomenys taip pat bus ištrinti." "value": "Visi susiję duomenys taip pat bus ištrinti."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -485,6 +485,12 @@
"value": "Үүнтэй холбоотой бүх өгөгдөл устах болно." "value": "Үүнтэй холбоотой бүх өгөгдөл устах болно."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -469,6 +469,12 @@
"value": "Semua data yang berkaitan juga akan dihapuskan." "value": "Semua data yang berkaitan juga akan dihapuskan."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -481,6 +481,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,

View File

@ -477,6 +477,12 @@
"value": "Alle verwante gegezens zullen ook verwijderd worden." "value": "Alle verwante gegezens zullen ook verwijderd worden."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -477,6 +477,12 @@
"value": "Wszystkie powiązane dane również zostaną usunięte." "value": "Wszystkie powiązane dane również zostaną usunięte."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -481,6 +481,12 @@
"value": "Todos os dados associados também serão eliminados." "value": "Todos os dados associados também serão eliminados."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -481,6 +481,12 @@
"value": "Todos os dados associados também serão eliminados." "value": "Todos os dados associados também serão eliminados."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -477,6 +477,12 @@
"value": "Toate datele asociate vor fi șterse, de asemenea." "value": "Toate datele asociate vor fi șterse, de asemenea."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -453,6 +453,12 @@
"value": "Все связанные данные будут также удалены." "value": "Все связанные данные будут также удалены."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -477,6 +477,12 @@
"value": "Všetky príbuzné data budu tiež zmazané." "value": "Všetky príbuzné data budu tiež zmazané."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -477,6 +477,12 @@
"value": "Izbrisani bodo tudi vsi povezani podatki." "value": "Izbrisani bodo tudi vsi povezani podatki."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -481,6 +481,12 @@
"value": "All tillhörande data kommer också raderas." "value": "All tillhörande data kommer också raderas."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -477,6 +477,12 @@
"value": "தொடர்புடைய எல்லா தரவும் நீக்கப்படும்." "value": "தொடர்புடைய எல்லா தரவும் நீக்கப்படும்."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -473,6 +473,12 @@
"value": "ข้อมูลที่เกี่ยวข้องทั้งหมดจะถูกลบ." "value": "ข้อมูลที่เกี่ยวข้องทั้งหมดจะถูกลบ."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -449,6 +449,12 @@
"value": "İlişkili tüm veriler de silinecektir." "value": "İlişkili tüm veriler de silinecektir."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -453,6 +453,12 @@
"value": "Усі пов'язані дані будуть видалені також." "value": "Усі пов'язані дані будуть видалені також."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -481,6 +481,12 @@
"value": "تمام متعلقہ ڈیٹا بھی حذف کر دیا جائے گا۔" "value": "تمام متعلقہ ڈیٹا بھی حذف کر دیا جائے گا۔"
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -469,6 +469,12 @@
"value": "Tất cả các dữ liệu liên quan cũng sẽ bị xoá." "value": "Tất cả các dữ liệu liên quan cũng sẽ bị xoá."
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -457,6 +457,12 @@
"value": "所有相关数据将会被删除。" "value": "所有相关数据将会被删除。"
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -457,6 +457,12 @@
"value": "所有相關數據將會被刪除。" "value": "所有相關數據將會被刪除。"
} }
], ],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [ "message.failure": [
{ {
"type": 0, "type": 0,

View File

@ -1,25 +1,10 @@
import create from 'zustand'; import create from 'zustand';
import { import { DEFAULT_LOCALE, DEFAULT_THEME, LOCALE_CONFIG, THEME_CONFIG } from 'lib/constants';
DASHBOARD_CONFIG, import { getItem } from 'lib/web';
DEFAULT_LOCALE,
DEFAULT_THEME,
LOCALE_CONFIG,
THEME_CONFIG,
DEFAULT_WEBSITE_LIMIT,
} from 'lib/constants';
import { getItem, setItem } from 'lib/web';
export const defaultDashboardConfig = {
showCharts: true,
limit: DEFAULT_WEBSITE_LIMIT,
websiteOrdering: {},
changeOrderMode: false,
};
const initialState = { const initialState = {
locale: getItem(LOCALE_CONFIG) || DEFAULT_LOCALE, locale: getItem(LOCALE_CONFIG) || DEFAULT_LOCALE,
theme: getItem(THEME_CONFIG) || DEFAULT_THEME, theme: getItem(THEME_CONFIG) || DEFAULT_THEME,
dashboard: getItem(DASHBOARD_CONFIG) || defaultDashboardConfig,
shareToken: null, shareToken: null,
user: null, user: null,
config: null, config: null,
@ -43,11 +28,6 @@ export function setUser(user) {
store.setState({ user }); store.setState({ user });
} }
export function setDashboard(dashboard) {
store.setState({ dashboard });
setItem(DASHBOARD_CONFIG, dashboard);
}
export function setConfig(config) { export function setConfig(config) {
store.setState({ config }); store.setState({ config });
} }

21
store/dashboard.js Normal file
View File

@ -0,0 +1,21 @@
import create from 'zustand';
import { DASHBOARD_CONFIG, DEFAULT_WEBSITE_LIMIT } from 'lib/constants';
import { getItem, setItem } from 'lib/web';
export const initialState = {
showCharts: true,
limit: DEFAULT_WEBSITE_LIMIT,
websiteOrder: {},
editing: false,
};
const store = create(() => ({ ...initialState, ...getItem(DASHBOARD_CONFIG) }));
export function saveDashboard(settings) {
const state = typeof settings === 'function' ? settings(store.getState()) : settings;
store.setState(state);
setItem(DASHBOARD_CONFIG, store.getState());
}
export default store;