Add maintenance options.

- Add new maintenance UI with options to garbage collect (delete)
  orphan subscriber and analytics records.
This commit is contained in:
Kailash Nadh 2022-09-03 13:18:02 +05:30
parent 8ace25849e
commit 6d820f4f6e
34 changed files with 553 additions and 14 deletions

View file

@ -139,6 +139,10 @@ func initHTTPHandlers(e *echo.Echo, app *App) {
g.PUT("/api/templates/:id/default", handleTemplateSetDefault) g.PUT("/api/templates/:id/default", handleTemplateSetDefault)
g.DELETE("/api/templates/:id", handleDeleteTemplate) g.DELETE("/api/templates/:id", handleDeleteTemplate)
g.DELETE("/api/maintenance/subscribers/:type", handleGCSubscribers)
g.DELETE("/api/maintenance/analytics/:type", handleGCCampaignAnalytics)
g.DELETE("/api/maintenance/subscriptions/unconfirmed", handleGCSubscriptions)
g.POST("/api/tx", handleSendTxMessage) g.POST("/api/tx", handleSendTxMessage)
if app.constants.BounceWebhooksEnabled { if app.constants.BounceWebhooksEnabled {

92
cmd/maintenance.go Normal file
View file

@ -0,0 +1,92 @@
package main
import (
"net/http"
"time"
"github.com/labstack/echo/v4"
)
// handleGCSubscribers garbage collects (deletes) orphaned or blocklisted subscribers.
func handleGCSubscribers(c echo.Context) error {
var (
app = c.Get("app").(*App)
typ = c.Param("type")
)
var (
n int
err error
)
switch typ {
case "blocklisted":
n, err = app.core.DeleteBlocklistedSubscribers()
case "orphan":
n, err = app.core.DeleteOrphanSubscribers()
default:
err = echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("globals.messages.invalidData"))
}
if err != nil {
return err
}
return c.JSON(http.StatusOK, okResp{struct {
Count int `json:"count"`
}{n}})
}
// handleGCSubscriptions garbage collects (deletes) orphaned or blocklisted subscribers.
func handleGCSubscriptions(c echo.Context) error {
var (
app = c.Get("app").(*App)
)
t, err := time.Parse(time.RFC3339, c.FormValue("before_date"))
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("globals.messages.invalidData"))
}
n, err := app.core.DeleteUnconfirmedSubscriptions(t)
if err != nil {
return err
}
return c.JSON(http.StatusOK, okResp{struct {
Count int `json:"count"`
}{n}})
}
// handleGCCampaignAnalytics garbage collects (deletes) campaign analytics.
func handleGCCampaignAnalytics(c echo.Context) error {
var (
app = c.Get("app").(*App)
typ = c.Param("type")
)
t, err := time.Parse(time.RFC3339, c.FormValue("before_date"))
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("globals.messages.invalidData"))
}
switch typ {
case "all":
if err := app.core.DeleteCampaignViews(t); err != nil {
return err
}
err = app.core.DeleteCampaignLinkClicks(t)
case "views":
err = app.core.DeleteCampaignViews(t)
case "clicks":
err = app.core.DeleteCampaignLinkClicks(t)
default:
err = echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("globals.messages.invalidData"))
}
if err != nil {
return err
}
return c.JSON(http.StatusOK, okResp{true})
}

View file

@ -566,6 +566,20 @@
"logout-variant" "logout-variant"
] ]
}, },
{
"uid": "10098901a143c53df6eeaeb317ae3da6",
"css": "wrench-outline",
"code": 986080,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M941.4 791L564.5 412.1Q593.8 337.9 578.1 258.8T503.9 121.1Q431.6 50.8 332 43T152.3 93.8L312.5 253.9 253.9 312.5 93.8 154.3Q35.2 234.4 42 334T121.1 503.9Q177.7 562.5 255.9 578.1T408.2 566.4L787.1 945.3Q798.8 959 816.4 959T845.7 945.3L941.4 849.6Q955.1 837.9 955.1 821.3T941.4 791ZM816.4 857.4L423.8 462.9Q384.8 492.2 340.8 498T253.9 491.2 180.7 447.3 136.7 378.9 125 302.7L253.9 431.6 429.7 253.9 300.8 125Q384.8 121.1 445.3 179.7 478.5 212.9 491.2 256.8T496.1 344.7 460.9 427.7L853.5 820.3Z",
"width": 1000
},
"search": [
"wrench-outline"
]
},
{ {
"uid": "f4ad3f6d071a0bfb3a8452b514ed0892", "uid": "f4ad3f6d071a0bfb3a8452b514ed0892",
"css": "vector-square", "css": "vector-square",
@ -42748,20 +42762,6 @@
"wrap-disabled" "wrap-disabled"
] ]
}, },
{
"uid": "10098901a143c53df6eeaeb317ae3da6",
"css": "wrench-outline",
"code": 986080,
"src": "custom_icons",
"selected": false,
"svg": {
"path": "M941.4 791L564.5 412.1Q593.8 337.9 578.1 258.8T503.9 121.1Q431.6 50.8 332 43T152.3 93.8L312.5 253.9 253.9 312.5 93.8 154.3Q35.2 234.4 42 334T121.1 503.9Q177.7 562.5 255.9 578.1T408.2 566.4L787.1 945.3Q798.8 959 816.4 959T845.7 945.3L941.4 849.6Q955.1 837.9 955.1 821.3T941.4 791ZM816.4 857.4L423.8 462.9Q384.8 492.2 340.8 498T253.9 491.2 180.7 447.3 136.7 378.9 125 302.7L253.9 431.6 429.7 253.9 300.8 125Q384.8 121.1 445.3 179.7 478.5 212.9 491.2 256.8T496.1 344.7 460.9 427.7L853.5 820.3Z",
"width": 1000
},
"search": [
"wrench-outline"
]
},
{ {
"uid": "d670b0f395ba3a61b975a6387f8a2471", "uid": "d670b0f395ba3a61b975a6387f8a2471",
"css": "access-point-network-off", "css": "access-point-network-off",

View file

@ -289,3 +289,12 @@ export const getLang = async (lang) => http.get(`/api/lang/${lang}`,
export const logout = async () => http.get('/api/logout', { export const logout = async () => http.get('/api/logout', {
auth: { username: 'wrong', password: 'wrong' }, auth: { username: 'wrong', password: 'wrong' },
}); });
export const deleteGCCampaignAnalytics = async (typ, beforeDate) => http.delete(`/api/maintenance/analytics/${typ}`,
{ loading: models.maintenance, params: { before_date: beforeDate } });
export const deleteGCSubscribers = async (typ) => http.delete(`/api/maintenance/subscribers/${typ}`,
{ loading: models.maintenance });
export const deleteGCSubscriptions = async (beforeDate) => http.delete('/api/maintenance/subscriptions/unconfirmed',
{ loading: models.maintenance, params: { before_date: beforeDate } });

View file

@ -40,6 +40,7 @@
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
} }
.mdi-view-dashboard-variant-outline:before { content: '\e800'; } /* '' */ .mdi-view-dashboard-variant-outline:before { content: '\e800'; } /* '' */
.mdi-format-list-bulleted-square:before { content: '\e801'; } /* '' */ .mdi-format-list-bulleted-square:before { content: '\e801'; } /* '' */
.mdi-newspaper-variant-outline:before { content: '\e802'; } /* '' */ .mdi-newspaper-variant-outline:before { content: '\e802'; } /* '' */
@ -80,3 +81,4 @@
.mdi-email-bounce:before { content: '\e825'; } /* '' */ .mdi-email-bounce:before { content: '\e825'; } /* '' */
.mdi-speedometer:before { content: '\e826'; } /* '' */ .mdi-speedometer:before { content: '\e826'; } /* '' */
.mdi-logout-variant:before { content: '󰗽'; } /* '\f05fd' */ .mdi-logout-variant:before { content: '󰗽'; } /* '\f05fd' */
.mdi-wrench-outline:before { content: '󰯠'; } /* '\f0be0' */

View file

@ -69,6 +69,10 @@
data-cy="all-settings" icon="cog-outline" :label="$t('menu.settings')"> data-cy="all-settings" icon="cog-outline" :label="$t('menu.settings')">
</b-menu-item> </b-menu-item>
<b-menu-item :to="{name: 'maintenance'}" tag="router-link" :active="activeItem.maintenance"
data-cy="maintenance" icon="wrench-outline" :label="$t('menu.maintenance')">
</b-menu-item>
<b-menu-item :to="{name: 'logs'}" tag="router-link" :active="activeItem.logs" <b-menu-item :to="{name: 'logs'}" tag="router-link" :active="activeItem.logs"
data-cy="logs" icon="newspaper-variant-outline" :label="$t('menu.logs')"> data-cy="logs" icon="newspaper-variant-outline" :label="$t('menu.logs')">
</b-menu-item> </b-menu-item>

View file

@ -10,6 +10,7 @@ export const models = Object.freeze({
bounces: 'bounces', bounces: 'bounces',
settings: 'settings', settings: 'settings',
logs: 'logs', logs: 'logs',
maintenance: 'maintenance',
}); });
// Ad-hoc URIs that are used outside of vuex requests. // Ad-hoc URIs that are used outside of vuex requests.

View file

@ -107,6 +107,12 @@ const routes = [
meta: { title: 'logs.title', group: 'settings' }, meta: { title: 'logs.title', group: 'settings' },
component: () => import(/* webpackChunkName: "main" */ '../views/Logs.vue'), component: () => import(/* webpackChunkName: "main" */ '../views/Logs.vue'),
}, },
{
path: '/settings/maintenance',
name: 'maintenance',
meta: { title: 'logs.title', group: 'settings' },
component: () => import(/* webpackChunkName: "main" */ '../views/Maintenance.vue'),
},
]; ];
const router = new VueRouter({ const router = new VueRouter({

View file

@ -0,0 +1,163 @@
<template>
<section class="maintenance wrap">
<h1 class="title is-4">{{ $t('maintenance.title') }}</h1>
<hr />
<p class="has-text-grey">
{{ $t('maintenance.help') }}
</p>
<br />
<div class="box">
<h4 class="is-size-5">{{ $t('globals.terms.subscribers') }}</h4><br />
<div class="columns">
<div class="column is-4">
<b-field label="Data" message="Orpans = subscribers with no lists">
<b-select v-model="subscriberType" expanded>
<option value="orphan">{{ $t('dashboard.orphanSubs') }}</option>
<option value="blocklisted">{{ $t('subscribers.status.blocklisted') }}</option>
</b-select>
</b-field>
</div>
<div class="column is-5"></div>
<div class="column">
<b-field label=".">
<b-button class="is-primary" :loading="loading.maintenance"
@click="deleteSubscribers" expanded>{{ $t('globals.buttons.delete') }}</b-button>
</b-field>
</div>
</div>
</div><!-- subscribers -->
<div class="box">
<h4 class="is-size-5">{{ $tc('globals.terms.subscriptions', 2) }}</h4><br />
<div class="columns">
<div class="column is-4">
<b-field label="Data">
<b-select v-model="subscriptionType" expanded>
<option value="optin">{{ $t('maintenance.maintenance.unconfirmedOptins') }}</option>
</b-select>
</b-field>
</div>
<div class="column is-4">
<b-field :label="$t('maintenance.olderThan')">
<b-datepicker
v-model="subscriptionDate"
required expanded
icon="calendar-clock"
:date-formatter="formatDateTime">
</b-datepicker>
</b-field>
</div>
<div class="column is-1"></div>
<div class="column">
<b-field label=".">
<b-button class="is-primary" :loading="loading.maintenance"
@click="deleteSubscriptions" expanded>{{ $t('globals.buttons.delete') }}</b-button>
</b-field>
</div>
</div>
</div><!-- subscriptions -->
<div class="box mt-6">
<h4 class="is-size-5">{{ $t('globals.terms.analytics') }}</h4><br />
<div class="columns">
<div class="column is-4">
<b-field label="Data">
<b-select v-model="analyticsType" expanded>
<option selected value="all">{{ $t('globals.terms.all') }}</option>
<option value="views">{{ $t('dashboard.campaignViews') }}</option>
<option value="clicks">{{ $t('dashboard.linkClicks') }}</option>
</b-select>
</b-field>
</div>
<div class="column is-4">
<b-field :label="$t('maintenance.olderThan')">
<b-datepicker
v-model="analyticsDate"
required expanded
icon="calendar-clock"
:date-formatter="formatDateTime">
</b-datepicker>
</b-field>
</div>
<div class="column is-1"></div>
<div class="column">
<b-field label=".">
<b-button expanded class="is-primary" :loading="loading.maintenance"
@click="deleteAnalytics">{{ $t('globals.buttons.delete') }}</b-button>
</b-field>
</div>
</div>
</div><!-- analytics -->
</section>
</template>
<script>
import Vue from 'vue';
import { mapState } from 'vuex';
import dayjs from 'dayjs';
export default Vue.extend({
components: {
},
data() {
return {
subscriberType: 'orphan',
analyticsType: 'all',
subscriptionType: 'optin',
analyticsDate: dayjs().subtract(7, 'day').toDate(),
subscriptionDate: dayjs().subtract(7, 'day').toDate(),
};
},
methods: {
formatDateTime(s) {
return dayjs(s).format('YYYY-MM-DD');
},
deleteSubscribers() {
this.$utils.confirm(
null,
() => {
this.$api.deleteGCSubscribers(this.subscriberType).then((data) => {
this.$utils.toast(this.$t('globals.messages.deletedCount',
{ name: this.$tc('globals.terms.subscribers', 2), num: data.count }));
});
},
);
},
deleteSubscriptions() {
this.$utils.confirm(
null,
() => {
this.$api.deleteGCSubscriptions(this.subscriptionDate).then((data) => {
this.$utils.toast(this.$t('globals.messages.deletedCount',
{ name: this.$tc('globals.terms.subscriptions', 2), num: data.count }));
});
},
);
},
deleteAnalytics() {
this.$utils.confirm(
null,
() => {
this.$api.deleteGCCampaignAnalytics(this.analyticsType, this.analyticsDate)
.then(() => {
this.$utils.toast(this.$t('globals.messages.done'));
});
},
);
},
},
computed: {
...mapState(['loading']),
},
});
</script>

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" vytvořen", "globals.messages.created": "\"{name}\" vytvořen",
"globals.messages.deleted": "\"{name}\" odstraněn", "globals.messages.deleted": "\"{name}\" odstraněn",
"globals.messages.deletedCount": "{name} ({num}) odstraněn", "globals.messages.deletedCount": "{name} ({num}) odstraněn",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Nic zde není", "globals.messages.emptyState": "Nic zde není",
"globals.messages.errorCreating": "Chyba při vytváření {name}: {error}", "globals.messages.errorCreating": "Chyba při vytváření {name}: {error}",
"globals.messages.errorDeleting": "Chyba při odstraňování {name}: {error}", "globals.messages.errorDeleting": "Chyba při odstraňování {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Srp", "globals.months.8": "Srp",
"globals.months.9": "Zář", "globals.months.9": "Zář",
"globals.states.off": "Vypnout", "globals.states.off": "Vypnout",
"globals.terms.all": "All",
"globals.terms.analytics": "Analytika", "globals.terms.analytics": "Analytika",
"globals.terms.bounce": "Nedoručitelnost | Případy nedoručitelnosti", "globals.terms.bounce": "Nedoručitelnost | Případy nedoručitelnosti",
"globals.terms.bounces": "Případy nedoručitelnosti", "globals.terms.bounces": "Případy nedoručitelnosti",
@ -202,6 +204,7 @@
"globals.terms.settings": "Nastavení", "globals.terms.settings": "Nastavení",
"globals.terms.subscriber": "Odběratel | Odběratelé", "globals.terms.subscriber": "Odběratel | Odběratelé",
"globals.terms.subscribers": "Odběratelé", "globals.terms.subscribers": "Odběratelé",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Značka | Značky", "globals.terms.tag": "Značka | Značky",
"globals.terms.tags": "Značky", "globals.terms.tags": "Značky",
"globals.terms.template": "Šablona | Šablony", "globals.terms.template": "Šablona | Šablony",
@ -252,6 +255,11 @@
"lists.types.private": "Soukromý", "lists.types.private": "Soukromý",
"lists.types.public": "Veřejný", "lists.types.public": "Veřejný",
"logs.title": "Protokoly", "logs.title": "Protokoly",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Chyba při čtení souboru: {error}", "media.errorReadingFile": "Chyba při čtení souboru: {error}",
"media.errorResizing": "Chyba při změně velikosti obrázku: {error}", "media.errorResizing": "Chyba při změně velikosti obrázku: {error}",
"media.errorSavingThumbnail": "Chyba při ukládání miniatury: {error}", "media.errorSavingThumbnail": "Chyba při ukládání miniatury: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Formuláře", "menu.forms": "Formuláře",
"menu.import": "Import", "menu.import": "Import",
"menu.logs": "Protokoly", "menu.logs": "Protokoly",
"menu.maintenance": "Maintenance",
"menu.media": "Médium", "menu.media": "Médium",
"menu.newCampaign": "Vytvořit nový", "menu.newCampaign": "Vytvořit nový",
"menu.settings": "Nastavení", "menu.settings": "Nastavení",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" erstellt", "globals.messages.created": "\"{name}\" erstellt",
"globals.messages.deleted": "\"{name}\" gelöscht", "globals.messages.deleted": "\"{name}\" gelöscht",
"globals.messages.deletedCount": "{name} ({num}) gelöscht", "globals.messages.deletedCount": "{name} ({num}) gelöscht",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Hier ist nichts", "globals.messages.emptyState": "Hier ist nichts",
"globals.messages.errorCreating": "Fehler beim Erstellen von {name}: {error}", "globals.messages.errorCreating": "Fehler beim Erstellen von {name}: {error}",
"globals.messages.errorDeleting": "Fehler beim Löschen von {name}: {error}", "globals.messages.errorDeleting": "Fehler beim Löschen von {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Aug", "globals.months.8": "Aug",
"globals.months.9": "Sep", "globals.months.9": "Sep",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Statistiken", "globals.terms.analytics": "Statistiken",
"globals.terms.bounce": "Bounce | Bounces", "globals.terms.bounce": "Bounce | Bounces",
"globals.terms.bounces": "Bounces", "globals.terms.bounces": "Bounces",
@ -202,6 +204,7 @@
"globals.terms.settings": "Einstellungen", "globals.terms.settings": "Einstellungen",
"globals.terms.subscriber": "Abonnent | Abonnenten", "globals.terms.subscriber": "Abonnent | Abonnenten",
"globals.terms.subscribers": "Abonnenten", "globals.terms.subscribers": "Abonnenten",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Tag | Tags", "globals.terms.tag": "Tag | Tags",
"globals.terms.tags": "Tags", "globals.terms.tags": "Tags",
"globals.terms.template": "Vorlage | Vorlagen", "globals.terms.template": "Vorlage | Vorlagen",
@ -252,6 +255,11 @@
"lists.types.private": "Privat", "lists.types.private": "Privat",
"lists.types.public": "Öffentlich", "lists.types.public": "Öffentlich",
"logs.title": "Logs", "logs.title": "Logs",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Fehler beim Lesen der Datei: {error}", "media.errorReadingFile": "Fehler beim Lesen der Datei: {error}",
"media.errorResizing": "Fehler beim Anpassen der Größe des Bildes: {error}", "media.errorResizing": "Fehler beim Anpassen der Größe des Bildes: {error}",
"media.errorSavingThumbnail": "Fehler beim Speichern des Thumbnails: {error}", "media.errorSavingThumbnail": "Fehler beim Speichern des Thumbnails: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Formulare", "menu.forms": "Formulare",
"menu.import": "Importieren", "menu.import": "Importieren",
"menu.logs": "Logs", "menu.logs": "Logs",
"menu.maintenance": "Maintenance",
"menu.media": "Medien", "menu.media": "Medien",
"menu.newCampaign": "Neu Anlegen", "menu.newCampaign": "Neu Anlegen",
"menu.settings": "Einstellungen", "menu.settings": "Einstellungen",

View file

@ -154,6 +154,7 @@
"globals.messages.created": "\"{name}\" created", "globals.messages.created": "\"{name}\" created",
"globals.messages.deleted": "\"{name}\" deleted", "globals.messages.deleted": "\"{name}\" deleted",
"globals.messages.deletedCount": "{name} ({num}) deleted", "globals.messages.deletedCount": "{name} ({num}) deleted",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Nothing here", "globals.messages.emptyState": "Nothing here",
"globals.messages.errorCreating": "Error creating {name}: {error}", "globals.messages.errorCreating": "Error creating {name}: {error}",
"globals.messages.errorDeleting": "Error deleting {name}: {error}", "globals.messages.errorDeleting": "Error deleting {name}: {error}",
@ -182,6 +183,7 @@
"globals.months.8": "Aug", "globals.months.8": "Aug",
"globals.months.9": "Sep", "globals.months.9": "Sep",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Analytics", "globals.terms.analytics": "Analytics",
"globals.terms.bounce": "Bounce | Bounces", "globals.terms.bounce": "Bounce | Bounces",
"globals.terms.bounces": "Bounces", "globals.terms.bounces": "Bounces",
@ -201,6 +203,7 @@
"globals.terms.settings": "Settings", "globals.terms.settings": "Settings",
"globals.terms.subscriber": "Subscriber | Subscribers", "globals.terms.subscriber": "Subscriber | Subscribers",
"globals.terms.subscribers": "Subscribers", "globals.terms.subscribers": "Subscribers",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Tag | Tags", "globals.terms.tag": "Tag | Tags",
"globals.terms.tags": "Tags", "globals.terms.tags": "Tags",
"globals.terms.template": "Template | Templates", "globals.terms.template": "Template | Templates",
@ -251,6 +254,11 @@
"lists.types.private": "Private", "lists.types.private": "Private",
"lists.types.public": "Public", "lists.types.public": "Public",
"logs.title": "Logs", "logs.title": "Logs",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Error reading file: {error}", "media.errorReadingFile": "Error reading file: {error}",
"media.errorResizing": "Error resizing image: {error}", "media.errorResizing": "Error resizing image: {error}",
"media.errorSavingThumbnail": "Error saving thumbnail: {error}", "media.errorSavingThumbnail": "Error saving thumbnail: {error}",
@ -268,6 +276,7 @@
"menu.forms": "Forms", "menu.forms": "Forms",
"menu.import": "Import", "menu.import": "Import",
"menu.logs": "Logs", "menu.logs": "Logs",
"menu.maintenance": "Maintenance",
"menu.media": "Media", "menu.media": "Media",
"menu.newCampaign": "Create new", "menu.newCampaign": "Create new",
"menu.settings": "Settings", "menu.settings": "Settings",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" creado", "globals.messages.created": "\"{name}\" creado",
"globals.messages.deleted": "\"{name}\" eliminado", "globals.messages.deleted": "\"{name}\" eliminado",
"globals.messages.deletedCount": "{name} ({num}) eliminado(s)", "globals.messages.deletedCount": "{name} ({num}) eliminado(s)",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Vacío", "globals.messages.emptyState": "Vacío",
"globals.messages.errorCreating": "Error creando {name}: {error}", "globals.messages.errorCreating": "Error creando {name}: {error}",
"globals.messages.errorDeleting": "Error eliminando {name}: {error}", "globals.messages.errorDeleting": "Error eliminando {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Agosto", "globals.months.8": "Agosto",
"globals.months.9": "Setiembre", "globals.months.9": "Setiembre",
"globals.states.off": "Apagado", "globals.states.off": "Apagado",
"globals.terms.all": "All",
"globals.terms.analytics": "Analitica", "globals.terms.analytics": "Analitica",
"globals.terms.bounce": "Rebote | Rebotes", "globals.terms.bounce": "Rebote | Rebotes",
"globals.terms.bounces": "Rebotes", "globals.terms.bounces": "Rebotes",
@ -202,6 +204,7 @@
"globals.terms.settings": "Configuraciones", "globals.terms.settings": "Configuraciones",
"globals.terms.subscriber": "Subscriptor | Subscriptores", "globals.terms.subscriber": "Subscriptor | Subscriptores",
"globals.terms.subscribers": "Subscriptores", "globals.terms.subscribers": "Subscriptores",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Etiqueta | Etiquetas", "globals.terms.tag": "Etiqueta | Etiquetas",
"globals.terms.tags": "Etiqueta", "globals.terms.tags": "Etiqueta",
"globals.terms.template": "Plantilla | Plantillas", "globals.terms.template": "Plantilla | Plantillas",
@ -252,6 +255,11 @@
"lists.types.private": "Privada", "lists.types.private": "Privada",
"lists.types.public": "Pública", "lists.types.public": "Pública",
"logs.title": "Registros", "logs.title": "Registros",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Error leyendo archivo: {error}", "media.errorReadingFile": "Error leyendo archivo: {error}",
"media.errorResizing": "Error cambiando tamaño de imagen: {error}", "media.errorResizing": "Error cambiando tamaño de imagen: {error}",
"media.errorSavingThumbnail": "Error guardando miniatura: {error}", "media.errorSavingThumbnail": "Error guardando miniatura: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Formularios", "menu.forms": "Formularios",
"menu.import": "Importar", "menu.import": "Importar",
"menu.logs": "Registros (logs)", "menu.logs": "Registros (logs)",
"menu.maintenance": "Maintenance",
"menu.media": "Multimedia", "menu.media": "Multimedia",
"menu.newCampaign": "Crear nueva", "menu.newCampaign": "Crear nueva",
"menu.settings": "Configuraciones", "menu.settings": "Configuraciones",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" created", "globals.messages.created": "\"{name}\" created",
"globals.messages.deleted": "\"{name}\" deleted", "globals.messages.deleted": "\"{name}\" deleted",
"globals.messages.deletedCount": "{name} ({num}) deleted", "globals.messages.deletedCount": "{name} ({num}) deleted",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Nothing here", "globals.messages.emptyState": "Nothing here",
"globals.messages.errorCreating": "Error creating {name}: {error}", "globals.messages.errorCreating": "Error creating {name}: {error}",
"globals.messages.errorDeleting": "Error deleting {name}: {error}", "globals.messages.errorDeleting": "Error deleting {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Aug", "globals.months.8": "Aug",
"globals.months.9": "Sep", "globals.months.9": "Sep",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Analytics", "globals.terms.analytics": "Analytics",
"globals.terms.bounce": "Bounce | Bounces", "globals.terms.bounce": "Bounce | Bounces",
"globals.terms.bounces": "Bounces", "globals.terms.bounces": "Bounces",
@ -202,6 +204,7 @@
"globals.terms.settings": "Settings", "globals.terms.settings": "Settings",
"globals.terms.subscriber": "Subscriber | Subscribers", "globals.terms.subscriber": "Subscriber | Subscribers",
"globals.terms.subscribers": "Subscribers", "globals.terms.subscribers": "Subscribers",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Tag | Tags", "globals.terms.tag": "Tag | Tags",
"globals.terms.tags": "Tags", "globals.terms.tags": "Tags",
"globals.terms.template": "Template | Templates", "globals.terms.template": "Template | Templates",
@ -252,6 +255,11 @@
"lists.types.private": "Private", "lists.types.private": "Private",
"lists.types.public": "Public", "lists.types.public": "Public",
"logs.title": "Logs", "logs.title": "Logs",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Error reading file: {error}", "media.errorReadingFile": "Error reading file: {error}",
"media.errorResizing": "Error resizing image: {error}", "media.errorResizing": "Error resizing image: {error}",
"media.errorSavingThumbnail": "Error saving thumbnail: {error}", "media.errorSavingThumbnail": "Error saving thumbnail: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Forms", "menu.forms": "Forms",
"menu.import": "Import", "menu.import": "Import",
"menu.logs": "Logs", "menu.logs": "Logs",
"menu.maintenance": "Maintenance",
"menu.media": "Media", "menu.media": "Media",
"menu.newCampaign": "Create new", "menu.newCampaign": "Create new",
"menu.settings": "Settings", "menu.settings": "Settings",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "Création de « {name} »", "globals.messages.created": "Création de « {name} »",
"globals.messages.deleted": "Suppression de « {name} »", "globals.messages.deleted": "Suppression de « {name} »",
"globals.messages.deletedCount": "{name} ({num}) effacé(s)", "globals.messages.deletedCount": "{name} ({num}) effacé(s)",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Rien", "globals.messages.emptyState": "Rien",
"globals.messages.errorCreating": "Erreur lors de la création de {name} : {error}", "globals.messages.errorCreating": "Erreur lors de la création de {name} : {error}",
"globals.messages.errorDeleting": "Erreur lors de la suppression de {name} : {error}", "globals.messages.errorDeleting": "Erreur lors de la suppression de {name} : {error}",
@ -183,6 +184,7 @@
"globals.months.8": "août", "globals.months.8": "août",
"globals.months.9": "sept.", "globals.months.9": "sept.",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Analyses", "globals.terms.analytics": "Analyses",
"globals.terms.bounce": "Rebond | Rebonds", "globals.terms.bounce": "Rebond | Rebonds",
"globals.terms.bounces": "Rebonds", "globals.terms.bounces": "Rebonds",
@ -202,6 +204,7 @@
"globals.terms.settings": "Paramètres", "globals.terms.settings": "Paramètres",
"globals.terms.subscriber": "Abonné·e | Abonné·es", "globals.terms.subscriber": "Abonné·e | Abonné·es",
"globals.terms.subscribers": "Abonné·es", "globals.terms.subscribers": "Abonné·es",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Étiquette | Étiquettes", "globals.terms.tag": "Étiquette | Étiquettes",
"globals.terms.tags": "Étiquettes", "globals.terms.tags": "Étiquettes",
"globals.terms.template": "Modèle | Modèles", "globals.terms.template": "Modèle | Modèles",
@ -252,6 +255,11 @@
"lists.types.private": "Privée", "lists.types.private": "Privée",
"lists.types.public": "Publique", "lists.types.public": "Publique",
"logs.title": "Journalisations", "logs.title": "Journalisations",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Erreur de lecture du fichier : {error}", "media.errorReadingFile": "Erreur de lecture du fichier : {error}",
"media.errorResizing": "Erreur lors du redimensionnement de l'image : {error}", "media.errorResizing": "Erreur lors du redimensionnement de l'image : {error}",
"media.errorSavingThumbnail": "Erreur lors de l'enregistrement de la miniature : {error}", "media.errorSavingThumbnail": "Erreur lors de l'enregistrement de la miniature : {error}",
@ -269,6 +277,7 @@
"menu.forms": "Formulaires", "menu.forms": "Formulaires",
"menu.import": "Importer", "menu.import": "Importer",
"menu.logs": "Journalisations", "menu.logs": "Journalisations",
"menu.maintenance": "Maintenance",
"menu.media": "Fichiers", "menu.media": "Fichiers",
"menu.newCampaign": "Nouvelle campagne", "menu.newCampaign": "Nouvelle campagne",
"menu.settings": "Paramètres", "menu.settings": "Paramètres",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" készítette", "globals.messages.created": "\"{name}\" készítette",
"globals.messages.deleted": "\"{name}\" törölte", "globals.messages.deleted": "\"{name}\" törölte",
"globals.messages.deletedCount": "{name} ({num}) törölve", "globals.messages.deletedCount": "{name} ({num}) törölve",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Semmi sincs itt", "globals.messages.emptyState": "Semmi sincs itt",
"globals.messages.errorCreating": "Hiba a létrehozásnál {name}: {error}", "globals.messages.errorCreating": "Hiba a létrehozásnál {name}: {error}",
"globals.messages.errorDeleting": "Hiba a törléskor {name}: {error}", "globals.messages.errorDeleting": "Hiba a törléskor {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Aug", "globals.months.8": "Aug",
"globals.months.9": "Sep", "globals.months.9": "Sep",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Analitika", "globals.terms.analytics": "Analitika",
"globals.terms.bounce": "Visszapattanó | Visszapattanók", "globals.terms.bounce": "Visszapattanó | Visszapattanók",
"globals.terms.bounces": "Visszapattanók", "globals.terms.bounces": "Visszapattanók",
@ -202,6 +204,7 @@
"globals.terms.settings": "Beállítások", "globals.terms.settings": "Beállítások",
"globals.terms.subscriber": "Feliratkozó | Feliratkozók", "globals.terms.subscriber": "Feliratkozó | Feliratkozók",
"globals.terms.subscribers": "Feliratkozók", "globals.terms.subscribers": "Feliratkozók",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Címke | Címkék", "globals.terms.tag": "Címke | Címkék",
"globals.terms.tags": "Címkék", "globals.terms.tags": "Címkék",
"globals.terms.template": "Sablon | Sablonok", "globals.terms.template": "Sablon | Sablonok",
@ -252,6 +255,11 @@
"lists.types.private": "Privát", "lists.types.private": "Privát",
"lists.types.public": "Nyilvános", "lists.types.public": "Nyilvános",
"logs.title": "Logok", "logs.title": "Logok",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Hiba a fájl olvasásakor : {error}", "media.errorReadingFile": "Hiba a fájl olvasásakor : {error}",
"media.errorResizing": "Hiba a kép átméretezésekor : {error}", "media.errorResizing": "Hiba a kép átméretezésekor : {error}",
"media.errorSavingThumbnail": "Hiba az indexkép mentésekor : {error}", "media.errorSavingThumbnail": "Hiba az indexkép mentésekor : {error}",
@ -269,6 +277,7 @@
"menu.forms": "Űrlapok", "menu.forms": "Űrlapok",
"menu.import": "Importálás", "menu.import": "Importálás",
"menu.logs": "Logok", "menu.logs": "Logok",
"menu.maintenance": "Maintenance",
"menu.media": "Média", "menu.media": "Média",
"menu.newCampaign": "Új készítése", "menu.newCampaign": "Új készítése",
"menu.settings": "Beállítások", "menu.settings": "Beállítások",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" creato", "globals.messages.created": "\"{name}\" creato",
"globals.messages.deleted": "\"{name}\" cancellato", "globals.messages.deleted": "\"{name}\" cancellato",
"globals.messages.deletedCount": "{name} ({num}) deleted", "globals.messages.deletedCount": "{name} ({num}) deleted",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Niente da visualizzare", "globals.messages.emptyState": "Niente da visualizzare",
"globals.messages.errorCreating": "Errore durante la creazione di {name}: {error}", "globals.messages.errorCreating": "Errore durante la creazione di {name}: {error}",
"globals.messages.errorDeleting": "Errore durante la cancellazione di {name}: {error}", "globals.messages.errorDeleting": "Errore durante la cancellazione di {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Ago", "globals.months.8": "Ago",
"globals.months.9": "Set", "globals.months.9": "Set",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Analytics", "globals.terms.analytics": "Analytics",
"globals.terms.bounce": "Bounce | Bounces", "globals.terms.bounce": "Bounce | Bounces",
"globals.terms.bounces": "Bounces", "globals.terms.bounces": "Bounces",
@ -202,6 +204,7 @@
"globals.terms.settings": "Impostazioni", "globals.terms.settings": "Impostazioni",
"globals.terms.subscriber": "Iscritto | Iscritti", "globals.terms.subscriber": "Iscritto | Iscritti",
"globals.terms.subscribers": "Iscritti", "globals.terms.subscribers": "Iscritti",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Etichetta | Etichette", "globals.terms.tag": "Etichetta | Etichette",
"globals.terms.tags": "Etichette", "globals.terms.tags": "Etichette",
"globals.terms.template": "Modello | Modelli", "globals.terms.template": "Modello | Modelli",
@ -252,6 +255,11 @@
"lists.types.private": "Privata", "lists.types.private": "Privata",
"lists.types.public": "Pubblico", "lists.types.public": "Pubblico",
"logs.title": "Logs", "logs.title": "Logs",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Errore di lettura del file: {error}", "media.errorReadingFile": "Errore di lettura del file: {error}",
"media.errorResizing": "Errore di ridimensionamento dell'immagine: {error}", "media.errorResizing": "Errore di ridimensionamento dell'immagine: {error}",
"media.errorSavingThumbnail": "Errore durante il salvataggio dell'immagine: {error}", "media.errorSavingThumbnail": "Errore durante il salvataggio dell'immagine: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Formulari", "menu.forms": "Formulari",
"menu.import": "Importare", "menu.import": "Importare",
"menu.logs": "Logs", "menu.logs": "Logs",
"menu.maintenance": "Maintenance",
"menu.media": "Media", "menu.media": "Media",
"menu.newCampaign": "Creare nuovo", "menu.newCampaign": "Creare nuovo",
"menu.settings": "Impostazioni", "menu.settings": "Impostazioni",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" が作成されました", "globals.messages.created": "\"{name}\" が作成されました",
"globals.messages.deleted": "\"{name}\" が削除されました", "globals.messages.deleted": "\"{name}\" が削除されました",
"globals.messages.deletedCount": "{name} ({num}) が削除されました。", "globals.messages.deletedCount": "{name} ({num}) が削除されました。",
"globals.messages.done": "Done",
"globals.messages.emptyState": "ここには何もありません", "globals.messages.emptyState": "ここには何もありません",
"globals.messages.errorCreating": "{name}作成エラー: {error}", "globals.messages.errorCreating": "{name}作成エラー: {error}",
"globals.messages.errorDeleting": "{name}削除エラー: {error}", "globals.messages.errorDeleting": "{name}削除エラー: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "8月", "globals.months.8": "8月",
"globals.months.9": "9月", "globals.months.9": "9月",
"globals.states.off": "オフ", "globals.states.off": "オフ",
"globals.terms.all": "All",
"globals.terms.analytics": "分析", "globals.terms.analytics": "分析",
"globals.terms.bounce": "バウンス | バウンス", "globals.terms.bounce": "バウンス | バウンス",
"globals.terms.bounces": "バウンス", "globals.terms.bounces": "バウンス",
@ -202,6 +204,7 @@
"globals.terms.settings": "設定", "globals.terms.settings": "設定",
"globals.terms.subscriber": "加入者 | 加入者", "globals.terms.subscriber": "加入者 | 加入者",
"globals.terms.subscribers": "加入者", "globals.terms.subscribers": "加入者",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "タグ | タグ", "globals.terms.tag": "タグ | タグ",
"globals.terms.tags": "タグ", "globals.terms.tags": "タグ",
"globals.terms.template": "テンプレート | テンプレート", "globals.terms.template": "テンプレート | テンプレート",
@ -252,6 +255,11 @@
"lists.types.private": "プライベート", "lists.types.private": "プライベート",
"lists.types.public": "パブリック", "lists.types.public": "パブリック",
"logs.title": "ログ", "logs.title": "ログ",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "ファイル読み込みエラー: {error}", "media.errorReadingFile": "ファイル読み込みエラー: {error}",
"media.errorResizing": "画像のリサイズエラー: {error}", "media.errorResizing": "画像のリサイズエラー: {error}",
"media.errorSavingThumbnail": "サムネイル保存エラー: {error}", "media.errorSavingThumbnail": "サムネイル保存エラー: {error}",
@ -269,6 +277,7 @@
"menu.forms": "フォーム", "menu.forms": "フォーム",
"menu.import": "インポート", "menu.import": "インポート",
"menu.logs": "ログ", "menu.logs": "ログ",
"menu.maintenance": "Maintenance",
"menu.media": "メディア", "menu.media": "メディア",
"menu.newCampaign": "新規作成", "menu.newCampaign": "新規作成",
"menu.settings": "設定", "menu.settings": "設定",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" നിർമ്മിച്ചു", "globals.messages.created": "\"{name}\" നിർമ്മിച്ചു",
"globals.messages.deleted": "\"{name}\" നീക്കം ചെയ്തു", "globals.messages.deleted": "\"{name}\" നീക്കം ചെയ്തു",
"globals.messages.deletedCount": "{name} ({num}) deleted", "globals.messages.deletedCount": "{name} ({num}) deleted",
"globals.messages.done": "Done",
"globals.messages.emptyState": "ഇവിടൊന്നുമില്ല", "globals.messages.emptyState": "ഇവിടൊന്നുമില്ല",
"globals.messages.errorCreating": "{name} നിർമ്മിക്കുന്നതിൽ പിശകുണ്ടായി: {error}", "globals.messages.errorCreating": "{name} നിർമ്മിക്കുന്നതിൽ പിശകുണ്ടായി: {error}",
"globals.messages.errorDeleting": "{name} നീക്കം ചെയ്യുന്നതിൽ പിശകുണ്ടായി: {error}", "globals.messages.errorDeleting": "{name} നീക്കം ചെയ്യുന്നതിൽ പിശകുണ്ടായി: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "ഓഗസ്റ്റ്", "globals.months.8": "ഓഗസ്റ്റ്",
"globals.months.9": "സെപ്റ്റംബർ", "globals.months.9": "സെപ്റ്റംബർ",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Analytics", "globals.terms.analytics": "Analytics",
"globals.terms.bounce": "Bounce | Bounces", "globals.terms.bounce": "Bounce | Bounces",
"globals.terms.bounces": "Bounces", "globals.terms.bounces": "Bounces",
@ -202,6 +204,7 @@
"globals.terms.settings": "ക്രമീകരണങ്ങൾ", "globals.terms.settings": "ക്രമീകരണങ്ങൾ",
"globals.terms.subscriber": "വരിക്കാരൻ | വരിക്കാർ", "globals.terms.subscriber": "വരിക്കാരൻ | വരിക്കാർ",
"globals.terms.subscribers": "വരിക്കാർ", "globals.terms.subscribers": "വരിക്കാർ",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "ടാഗ് | ടാഗുകൾ", "globals.terms.tag": "ടാഗ് | ടാഗുകൾ",
"globals.terms.tags": "ടാഗുകൾ", "globals.terms.tags": "ടാഗുകൾ",
"globals.terms.template": "ടെംപ്ലേറ്റ് | ടെംപ്ലേറ്റുകൾ", "globals.terms.template": "ടെംപ്ലേറ്റ് | ടെംപ്ലേറ്റുകൾ",
@ -252,6 +255,11 @@
"lists.types.private": "സ്വകാര്യം", "lists.types.private": "സ്വകാര്യം",
"lists.types.public": "പൊതു", "lists.types.public": "പൊതു",
"logs.title": "ലോഗുകൾ", "logs.title": "ലോഗുകൾ",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "ഫയൽ വായിക്കാനായില്ല: {error}", "media.errorReadingFile": "ഫയൽ വായിക്കാനായില്ല: {error}",
"media.errorResizing": "ചിത്രത്തിന്റ വലിപ്പം മാറ്റാനായില്ല: {error}", "media.errorResizing": "ചിത്രത്തിന്റ വലിപ്പം മാറ്റാനായില്ല: {error}",
"media.errorSavingThumbnail": "തമ്പ്നെയിൽ സേവ് ചെയ്യാനായില്ല: {error}", "media.errorSavingThumbnail": "തമ്പ്നെയിൽ സേവ് ചെയ്യാനായില്ല: {error}",
@ -269,6 +277,7 @@
"menu.forms": "ഫോമുകൾ", "menu.forms": "ഫോമുകൾ",
"menu.import": "ഇമ്പോർട്ട്", "menu.import": "ഇമ്പോർട്ട്",
"menu.logs": "ലോഗുകൾ", "menu.logs": "ലോഗുകൾ",
"menu.maintenance": "Maintenance",
"menu.media": "മീഡിയ", "menu.media": "മീഡിയ",
"menu.newCampaign": "പുതിയത് തുടങ്ങുക", "menu.newCampaign": "പുതിയത് തുടങ്ങുക",
"menu.settings": "ക്രമീകരണങ്ങൾ", "menu.settings": "ക്രമീകരണങ്ങൾ",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" aangemaakt", "globals.messages.created": "\"{name}\" aangemaakt",
"globals.messages.deleted": "\"{name}\" verwijderd", "globals.messages.deleted": "\"{name}\" verwijderd",
"globals.messages.deletedCount": "{name} ({num}) verwijderd", "globals.messages.deletedCount": "{name} ({num}) verwijderd",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Niks te zien hier", "globals.messages.emptyState": "Niks te zien hier",
"globals.messages.errorCreating": "Fout bij aanmaken {name}: {error}", "globals.messages.errorCreating": "Fout bij aanmaken {name}: {error}",
"globals.messages.errorDeleting": "Fout bij verwijderen {name}: {error}", "globals.messages.errorDeleting": "Fout bij verwijderen {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Aug", "globals.months.8": "Aug",
"globals.months.9": "Sep", "globals.months.9": "Sep",
"globals.states.off": "Uit", "globals.states.off": "Uit",
"globals.terms.all": "All",
"globals.terms.analytics": "Analyse", "globals.terms.analytics": "Analyse",
"globals.terms.bounce": "Bounce | Bounces", "globals.terms.bounce": "Bounce | Bounces",
"globals.terms.bounces": "Bounces", "globals.terms.bounces": "Bounces",
@ -202,6 +204,7 @@
"globals.terms.settings": "Instellingen", "globals.terms.settings": "Instellingen",
"globals.terms.subscriber": "Abonnee | Abonnees", "globals.terms.subscriber": "Abonnee | Abonnees",
"globals.terms.subscribers": "Abonnees", "globals.terms.subscribers": "Abonnees",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Label | Labels", "globals.terms.tag": "Label | Labels",
"globals.terms.tags": "Labels", "globals.terms.tags": "Labels",
"globals.terms.template": "Sjabloon | Sjablonen", "globals.terms.template": "Sjabloon | Sjablonen",
@ -252,6 +255,11 @@
"lists.types.private": "Privé", "lists.types.private": "Privé",
"lists.types.public": "Publiek", "lists.types.public": "Publiek",
"logs.title": "Logboeken", "logs.title": "Logboeken",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Fout bij lezen bestand: {error}", "media.errorReadingFile": "Fout bij lezen bestand: {error}",
"media.errorResizing": "Fout bij wijzigen formaat afbeelding: {error}", "media.errorResizing": "Fout bij wijzigen formaat afbeelding: {error}",
"media.errorSavingThumbnail": "Fout bij opslaan thumbnail: {error}", "media.errorSavingThumbnail": "Fout bij opslaan thumbnail: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Formulieren", "menu.forms": "Formulieren",
"menu.import": "Importeer", "menu.import": "Importeer",
"menu.logs": "Logboeken", "menu.logs": "Logboeken",
"menu.maintenance": "Maintenance",
"menu.media": "Media", "menu.media": "Media",
"menu.newCampaign": "Nieuwe aanmaken", "menu.newCampaign": "Nieuwe aanmaken",
"menu.settings": "Instellingen", "menu.settings": "Instellingen",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" utworzono", "globals.messages.created": "\"{name}\" utworzono",
"globals.messages.deleted": "\"{name}\" usunięto", "globals.messages.deleted": "\"{name}\" usunięto",
"globals.messages.deletedCount": "{name} ({num}) deleted", "globals.messages.deletedCount": "{name} ({num}) deleted",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Nic tutaj nie ma", "globals.messages.emptyState": "Nic tutaj nie ma",
"globals.messages.errorCreating": "Błąd podczas tworzenia {name}: {error}", "globals.messages.errorCreating": "Błąd podczas tworzenia {name}: {error}",
"globals.messages.errorDeleting": "Błąd podczas usuwania {name}: {error}", "globals.messages.errorDeleting": "Błąd podczas usuwania {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Sie", "globals.months.8": "Sie",
"globals.months.9": "Wrz", "globals.months.9": "Wrz",
"globals.states.off": "Wyłączone", "globals.states.off": "Wyłączone",
"globals.terms.all": "All",
"globals.terms.analytics": "Analityka", "globals.terms.analytics": "Analityka",
"globals.terms.bounce": "Odbicie | Obicia", "globals.terms.bounce": "Odbicie | Obicia",
"globals.terms.bounces": "Odbicia", "globals.terms.bounces": "Odbicia",
@ -202,6 +204,7 @@
"globals.terms.settings": "Ustawienia", "globals.terms.settings": "Ustawienia",
"globals.terms.subscriber": "Subskrypcja | Subskrypcje", "globals.terms.subscriber": "Subskrypcja | Subskrypcje",
"globals.terms.subscribers": "Subskrypcje", "globals.terms.subscribers": "Subskrypcje",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Tag | Tagi", "globals.terms.tag": "Tag | Tagi",
"globals.terms.tags": "Tagi", "globals.terms.tags": "Tagi",
"globals.terms.template": "Szablon | Szablony", "globals.terms.template": "Szablon | Szablony",
@ -252,6 +255,11 @@
"lists.types.private": "Prywatna", "lists.types.private": "Prywatna",
"lists.types.public": "Publiczna", "lists.types.public": "Publiczna",
"logs.title": "Logi", "logs.title": "Logi",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Błąd odczytu pliku: {error}", "media.errorReadingFile": "Błąd odczytu pliku: {error}",
"media.errorResizing": "Błąd zmiany rozmiaru obrazu: {error}", "media.errorResizing": "Błąd zmiany rozmiaru obrazu: {error}",
"media.errorSavingThumbnail": "Błąd zapisywania miniaturki: {error}", "media.errorSavingThumbnail": "Błąd zapisywania miniaturki: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Formularze", "menu.forms": "Formularze",
"menu.import": "Import", "menu.import": "Import",
"menu.logs": "Logi", "menu.logs": "Logi",
"menu.maintenance": "Maintenance",
"menu.media": "Media", "menu.media": "Media",
"menu.newCampaign": "Utwórz nową", "menu.newCampaign": "Utwórz nową",
"menu.settings": "Ustawienia", "menu.settings": "Ustawienia",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" criado", "globals.messages.created": "\"{name}\" criado",
"globals.messages.deleted": "\"{name}\" excluído", "globals.messages.deleted": "\"{name}\" excluído",
"globals.messages.deletedCount": "{name} ({num}) deletado", "globals.messages.deletedCount": "{name} ({num}) deletado",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Nada por aqui", "globals.messages.emptyState": "Nada por aqui",
"globals.messages.errorCreating": "Erro ao criar {name}: {error}", "globals.messages.errorCreating": "Erro ao criar {name}: {error}",
"globals.messages.errorDeleting": "Erro ao excluir {name}: {error}", "globals.messages.errorDeleting": "Erro ao excluir {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Ago", "globals.months.8": "Ago",
"globals.months.9": "Set", "globals.months.9": "Set",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Analytics", "globals.terms.analytics": "Analytics",
"globals.terms.bounce": "Bounce | Bounces", "globals.terms.bounce": "Bounce | Bounces",
"globals.terms.bounces": "Bounces", "globals.terms.bounces": "Bounces",
@ -202,6 +204,7 @@
"globals.terms.settings": "Configurações", "globals.terms.settings": "Configurações",
"globals.terms.subscriber": "Assinante | Assinantes", "globals.terms.subscriber": "Assinante | Assinantes",
"globals.terms.subscribers": "Assinantes", "globals.terms.subscribers": "Assinantes",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Tag | Tags", "globals.terms.tag": "Tag | Tags",
"globals.terms.tags": "Tags", "globals.terms.tags": "Tags",
"globals.terms.template": "Modelo | Modelos", "globals.terms.template": "Modelo | Modelos",
@ -252,6 +255,11 @@
"lists.types.private": "Privada", "lists.types.private": "Privada",
"lists.types.public": "Pública", "lists.types.public": "Pública",
"logs.title": "Logs", "logs.title": "Logs",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Erro ao ler arquivo: {error}", "media.errorReadingFile": "Erro ao ler arquivo: {error}",
"media.errorResizing": "Erro ao redimensionar imagem: {error}", "media.errorResizing": "Erro ao redimensionar imagem: {error}",
"media.errorSavingThumbnail": "Erro ao salvar miniatura: {error}", "media.errorSavingThumbnail": "Erro ao salvar miniatura: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Formulários", "menu.forms": "Formulários",
"menu.import": "Importação", "menu.import": "Importação",
"menu.logs": "Logs", "menu.logs": "Logs",
"menu.maintenance": "Maintenance",
"menu.media": "Mídia", "menu.media": "Mídia",
"menu.newCampaign": "Criar nova", "menu.newCampaign": "Criar nova",
"menu.settings": "Configurações", "menu.settings": "Configurações",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" criado", "globals.messages.created": "\"{name}\" criado",
"globals.messages.deleted": "\"{name}\" eliminado", "globals.messages.deleted": "\"{name}\" eliminado",
"globals.messages.deletedCount": "{name} ({num}) deleted", "globals.messages.deletedCount": "{name} ({num}) deleted",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Não há nada aqui", "globals.messages.emptyState": "Não há nada aqui",
"globals.messages.errorCreating": "Erro ao criar {name}: {error}", "globals.messages.errorCreating": "Erro ao criar {name}: {error}",
"globals.messages.errorDeleting": "Erro ao eliminar {name}: {error}", "globals.messages.errorDeleting": "Erro ao eliminar {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Ago", "globals.months.8": "Ago",
"globals.months.9": "Set", "globals.months.9": "Set",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Analytics", "globals.terms.analytics": "Analytics",
"globals.terms.bounce": "Bounce | Bounces", "globals.terms.bounce": "Bounce | Bounces",
"globals.terms.bounces": "Bounces", "globals.terms.bounces": "Bounces",
@ -202,6 +204,7 @@
"globals.terms.settings": "Definições", "globals.terms.settings": "Definições",
"globals.terms.subscriber": "Subscritor | Subcritores", "globals.terms.subscriber": "Subscritor | Subcritores",
"globals.terms.subscribers": "Subscritores", "globals.terms.subscribers": "Subscritores",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Etiqueta | Etiquetas", "globals.terms.tag": "Etiqueta | Etiquetas",
"globals.terms.tags": "Etiquetas", "globals.terms.tags": "Etiquetas",
"globals.terms.template": "Modelo | Modelos", "globals.terms.template": "Modelo | Modelos",
@ -252,6 +255,11 @@
"lists.types.private": "Privado", "lists.types.private": "Privado",
"lists.types.public": "Público", "lists.types.public": "Público",
"logs.title": "Logs (Histórico)", "logs.title": "Logs (Histórico)",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Erro ao ler ficheiro: {error}", "media.errorReadingFile": "Erro ao ler ficheiro: {error}",
"media.errorResizing": "Erro ao alterar tamanho da imagem: {error}", "media.errorResizing": "Erro ao alterar tamanho da imagem: {error}",
"media.errorSavingThumbnail": "Erro ao guardar miniatura: {error}", "media.errorSavingThumbnail": "Erro ao guardar miniatura: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Formulários", "menu.forms": "Formulários",
"menu.import": "Importar", "menu.import": "Importar",
"menu.logs": "Logs", "menu.logs": "Logs",
"menu.maintenance": "Maintenance",
"menu.media": "Mídia", "menu.media": "Mídia",
"menu.newCampaign": "Criar nova", "menu.newCampaign": "Criar nova",
"menu.settings": "Definições", "menu.settings": "Definições",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{nume}\" creat", "globals.messages.created": "\"{nume}\" creat",
"globals.messages.deleted": "\"{nume}\" șters", "globals.messages.deleted": "\"{nume}\" șters",
"globals.messages.deletedCount": "{nume} ({număr}) șters", "globals.messages.deletedCount": "{nume} ({număr}) șters",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Nimic aici", "globals.messages.emptyState": "Nimic aici",
"globals.messages.errorCreating": "Eroare creare {nume}: {eroare}", "globals.messages.errorCreating": "Eroare creare {nume}: {eroare}",
"globals.messages.errorDeleting": "Eroare ștergere {nume}: {eroare}", "globals.messages.errorDeleting": "Eroare ștergere {nume}: {eroare}",
@ -183,6 +184,7 @@
"globals.months.8": "Aug", "globals.months.8": "Aug",
"globals.months.9": "Sep", "globals.months.9": "Sep",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Analitice", "globals.terms.analytics": "Analitice",
"globals.terms.bounce": "Respins | Respinse", "globals.terms.bounce": "Respins | Respinse",
"globals.terms.bounces": "Respinse", "globals.terms.bounces": "Respinse",
@ -202,6 +204,7 @@
"globals.terms.settings": "Setări", "globals.terms.settings": "Setări",
"globals.terms.subscriber": "Abonat | Abonați", "globals.terms.subscriber": "Abonat | Abonați",
"globals.terms.subscribers": "Abonați", "globals.terms.subscribers": "Abonați",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Etichetă | Etichete", "globals.terms.tag": "Etichetă | Etichete",
"globals.terms.tags": "Etichete", "globals.terms.tags": "Etichete",
"globals.terms.template": "Șablon | Șabloane", "globals.terms.template": "Șablon | Șabloane",
@ -252,6 +255,11 @@
"lists.types.private": "Privat", "lists.types.private": "Privat",
"lists.types.public": "Public", "lists.types.public": "Public",
"logs.title": "Jurnale", "logs.title": "Jurnale",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Eroare citire fisier: {eroare}", "media.errorReadingFile": "Eroare citire fisier: {eroare}",
"media.errorResizing": "Eroare redimensionare imagine: {eroare}", "media.errorResizing": "Eroare redimensionare imagine: {eroare}",
"media.errorSavingThumbnail": "Eroare la salvarea miniaturii: {eroare}", "media.errorSavingThumbnail": "Eroare la salvarea miniaturii: {eroare}",
@ -269,6 +277,7 @@
"menu.forms": "Formulare", "menu.forms": "Formulare",
"menu.import": "Import", "menu.import": "Import",
"menu.logs": "Jurnale", "menu.logs": "Jurnale",
"menu.maintenance": "Maintenance",
"menu.media": "Media", "menu.media": "Media",
"menu.newCampaign": "Creaza nou", "menu.newCampaign": "Creaza nou",
"menu.settings": "Setări", "menu.settings": "Setări",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" создано", "globals.messages.created": "\"{name}\" создано",
"globals.messages.deleted": "\"{name}\" удалено", "globals.messages.deleted": "\"{name}\" удалено",
"globals.messages.deletedCount": "{name} ({num}) удалено", "globals.messages.deletedCount": "{name} ({num}) удалено",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Ничего нет", "globals.messages.emptyState": "Ничего нет",
"globals.messages.errorCreating": "Ошибка создания {name}: {error}", "globals.messages.errorCreating": "Ошибка создания {name}: {error}",
"globals.messages.errorDeleting": "Ошибка удаления {name}: {error}", "globals.messages.errorDeleting": "Ошибка удаления {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Авг", "globals.months.8": "Авг",
"globals.months.9": "Сен", "globals.months.9": "Сен",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Аналитика", "globals.terms.analytics": "Аналитика",
"globals.terms.bounce": "Отскок | Отскоки", "globals.terms.bounce": "Отскок | Отскоки",
"globals.terms.bounces": "Отскоки", "globals.terms.bounces": "Отскоки",
@ -202,6 +204,7 @@
"globals.terms.settings": "Параметры", "globals.terms.settings": "Параметры",
"globals.terms.subscriber": "Подписчик | Подписчики", "globals.terms.subscriber": "Подписчик | Подписчики",
"globals.terms.subscribers": "Подписчики", "globals.terms.subscribers": "Подписчики",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Тег | Теги", "globals.terms.tag": "Тег | Теги",
"globals.terms.tags": "Теги", "globals.terms.tags": "Теги",
"globals.terms.template": "Шаблон | Шаблоны", "globals.terms.template": "Шаблон | Шаблоны",
@ -252,6 +255,11 @@
"lists.types.private": "Приватный", "lists.types.private": "Приватный",
"lists.types.public": "Публичный", "lists.types.public": "Публичный",
"logs.title": "Логи", "logs.title": "Логи",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Ошибка чтения файла: {error}", "media.errorReadingFile": "Ошибка чтения файла: {error}",
"media.errorResizing": "Ошибка изменения размера изображения: {error}", "media.errorResizing": "Ошибка изменения размера изображения: {error}",
"media.errorSavingThumbnail": "Ошибка сохранения миниатюры: {error}", "media.errorSavingThumbnail": "Ошибка сохранения миниатюры: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Формы", "menu.forms": "Формы",
"menu.import": "Импорт", "menu.import": "Импорт",
"menu.logs": "Логи", "menu.logs": "Логи",
"menu.maintenance": "Maintenance",
"menu.media": "Медиа", "menu.media": "Медиа",
"menu.newCampaign": "Создать новую", "menu.newCampaign": "Создать новую",
"menu.settings": "Параметры", "menu.settings": "Параметры",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" oluşturma", "globals.messages.created": "\"{name}\" oluşturma",
"globals.messages.deleted": "\"{name}\" silme", "globals.messages.deleted": "\"{name}\" silme",
"globals.messages.deletedCount": "{name} ({num}) deleted", "globals.messages.deletedCount": "{name} ({num}) deleted",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Burası Boş", "globals.messages.emptyState": "Burası Boş",
"globals.messages.errorCreating": "Hata oluşturma {name}: {error}", "globals.messages.errorCreating": "Hata oluşturma {name}: {error}",
"globals.messages.errorDeleting": "Hata silme {name}: {error}", "globals.messages.errorDeleting": "Hata silme {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Aug", "globals.months.8": "Aug",
"globals.months.9": "Eyl", "globals.months.9": "Eyl",
"globals.states.off": "Off", "globals.states.off": "Off",
"globals.terms.all": "All",
"globals.terms.analytics": "Analytics", "globals.terms.analytics": "Analytics",
"globals.terms.bounce": "Bounce | Bounces", "globals.terms.bounce": "Bounce | Bounces",
"globals.terms.bounces": "Bounces", "globals.terms.bounces": "Bounces",
@ -202,6 +204,7 @@
"globals.terms.settings": "Ayarlar", "globals.terms.settings": "Ayarlar",
"globals.terms.subscriber": "Üye | Üyeler", "globals.terms.subscriber": "Üye | Üyeler",
"globals.terms.subscribers": "Üyeler", "globals.terms.subscribers": "Üyeler",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Tag | Tag(lar)", "globals.terms.tag": "Tag | Tag(lar)",
"globals.terms.tags": "Tag(lar)", "globals.terms.tags": "Tag(lar)",
"globals.terms.template": "Taslak | Taslaklar", "globals.terms.template": "Taslak | Taslaklar",
@ -252,6 +255,11 @@
"lists.types.private": "Kişisel", "lists.types.private": "Kişisel",
"lists.types.public": "Erişime açık", "lists.types.public": "Erişime açık",
"logs.title": "Loglar", "logs.title": "Loglar",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Hata, dosya okurken: {error}", "media.errorReadingFile": "Hata, dosya okurken: {error}",
"media.errorResizing": "Hata, resim büyüklüğü değişirken: {error}", "media.errorResizing": "Hata, resim büyüklüğü değişirken: {error}",
"media.errorSavingThumbnail": "Hata, önizleme oluşurken: {error}", "media.errorSavingThumbnail": "Hata, önizleme oluşurken: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Formlar", "menu.forms": "Formlar",
"menu.import": "İçeri aktar", "menu.import": "İçeri aktar",
"menu.logs": "Loglar", "menu.logs": "Loglar",
"menu.maintenance": "Maintenance",
"menu.media": "Medya", "menu.media": "Medya",
"menu.newCampaign": "Yeni oluştur", "menu.newCampaign": "Yeni oluştur",
"menu.settings": "Ayarlar", "menu.settings": "Ayarlar",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "\"{name}\" đã tạo", "globals.messages.created": "\"{name}\" đã tạo",
"globals.messages.deleted": "\"{name}\" đã xóa", "globals.messages.deleted": "\"{name}\" đã xóa",
"globals.messages.deletedCount": "{name} ({num}) đã xóa", "globals.messages.deletedCount": "{name} ({num}) đã xóa",
"globals.messages.done": "Done",
"globals.messages.emptyState": "Không có gì ở đây", "globals.messages.emptyState": "Không có gì ở đây",
"globals.messages.errorCreating": "Lỗi khi tạo {name}: {error}", "globals.messages.errorCreating": "Lỗi khi tạo {name}: {error}",
"globals.messages.errorDeleting": "Lỗi khi xóa {name}: {error}", "globals.messages.errorDeleting": "Lỗi khi xóa {name}: {error}",
@ -183,6 +184,7 @@
"globals.months.8": "Tháng 8", "globals.months.8": "Tháng 8",
"globals.months.9": "Tháng 9", "globals.months.9": "Tháng 9",
"globals.states.off": "Tắt", "globals.states.off": "Tắt",
"globals.terms.all": "All",
"globals.terms.analytics": "phân tích", "globals.terms.analytics": "phân tích",
"globals.terms.bounce": "Bounces | Bounces", "globals.terms.bounce": "Bounces | Bounces",
"globals.terms.bounces": "Bị trả lại", "globals.terms.bounces": "Bị trả lại",
@ -202,6 +204,7 @@
"globals.terms.settings": "Cài đặt", "globals.terms.settings": "Cài đặt",
"globals.terms.subscriber": "Subscriber | Subscribers", "globals.terms.subscriber": "Subscriber | Subscribers",
"globals.terms.subscribers": "Người đăng ký", "globals.terms.subscribers": "Người đăng ký",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "Tag | Tags", "globals.terms.tag": "Tag | Tags",
"globals.terms.tags": "Thẻ", "globals.terms.tags": "Thẻ",
"globals.terms.template": "Template | Templates", "globals.terms.template": "Template | Templates",
@ -252,6 +255,11 @@
"lists.types.private": "Riêng tư", "lists.types.private": "Riêng tư",
"lists.types.public": "Công cộng", "lists.types.public": "Công cộng",
"logs.title": "Nhật ký", "logs.title": "Nhật ký",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "Lỗi khi đọc tệp: {error}", "media.errorReadingFile": "Lỗi khi đọc tệp: {error}",
"media.errorResizing": "Lỗi khi thay đổi kích thước hình ảnh: {error}", "media.errorResizing": "Lỗi khi thay đổi kích thước hình ảnh: {error}",
"media.errorSavingThumbnail": "Lỗi khi lưu hình thu nhỏ: {error}", "media.errorSavingThumbnail": "Lỗi khi lưu hình thu nhỏ: {error}",
@ -269,6 +277,7 @@
"menu.forms": "Biểu mẫu", "menu.forms": "Biểu mẫu",
"menu.import": "Nhập", "menu.import": "Nhập",
"menu.logs": "Nhật kí", "menu.logs": "Nhật kí",
"menu.maintenance": "Maintenance",
"menu.media": "Dữ liệu truyền thông", "menu.media": "Dữ liệu truyền thông",
"menu.newCampaign": "Tạo mới", "menu.newCampaign": "Tạo mới",
"menu.settings": "Cài đặt", "menu.settings": "Cài đặt",

View file

@ -155,6 +155,7 @@
"globals.messages.created": "“{name}”已创建", "globals.messages.created": "“{name}”已创建",
"globals.messages.deleted": "“{name}”已删除", "globals.messages.deleted": "“{name}”已删除",
"globals.messages.deletedCount": "{name} ({num}) 个已删除", "globals.messages.deletedCount": "{name} ({num}) 个已删除",
"globals.messages.done": "Done",
"globals.messages.emptyState": "这里没有什么", "globals.messages.emptyState": "这里没有什么",
"globals.messages.errorCreating": "创建 {name} 时出错:{error}", "globals.messages.errorCreating": "创建 {name} 时出错:{error}",
"globals.messages.errorDeleting": "删除 {name} 时出错:{error}", "globals.messages.errorDeleting": "删除 {name} 时出错:{error}",
@ -183,6 +184,7 @@
"globals.months.8": "八月", "globals.months.8": "八月",
"globals.months.9": "九月", "globals.months.9": "九月",
"globals.states.off": "关闭", "globals.states.off": "关闭",
"globals.terms.all": "All",
"globals.terms.analytics": "统计", "globals.terms.analytics": "统计",
"globals.terms.bounce": "反弹 | 多个反弹", "globals.terms.bounce": "反弹 | 多个反弹",
"globals.terms.bounces": "反弹", "globals.terms.bounces": "反弹",
@ -202,6 +204,7 @@
"globals.terms.settings": "设置", "globals.terms.settings": "设置",
"globals.terms.subscriber": "订阅者 | 多个订阅者", "globals.terms.subscriber": "订阅者 | 多个订阅者",
"globals.terms.subscribers": "订阅者", "globals.terms.subscribers": "订阅者",
"globals.terms.subscriptions": "Subscription | Subscriptions",
"globals.terms.tag": "标签 | 多个标签", "globals.terms.tag": "标签 | 多个标签",
"globals.terms.tags": "标签", "globals.terms.tags": "标签",
"globals.terms.template": "模板 | 多个模板", "globals.terms.template": "模板 | 多个模板",
@ -252,6 +255,11 @@
"lists.types.private": "私人的", "lists.types.private": "私人的",
"lists.types.public": "公开", "lists.types.public": "公开",
"logs.title": "日志", "logs.title": "日志",
"maintenance.help": "Some actions may take a while to complete depending on the amount of data.",
"maintenance.maintenance.unconfirmedOptins": "Unconfirmed opt-in subscriptions",
"maintenance.olderThan": "Older than",
"maintenance.title": "Maintenance",
"maintenance.unconfirmedSubs": "Unconfirmed subscriptions older than {name} days.",
"media.errorReadingFile": "读取文件时出错:{error}", "media.errorReadingFile": "读取文件时出错:{error}",
"media.errorResizing": "调整图像大小时出错:{error}", "media.errorResizing": "调整图像大小时出错:{error}",
"media.errorSavingThumbnail": "保存缩略图时出错:{error}", "media.errorSavingThumbnail": "保存缩略图时出错:{error}",
@ -269,6 +277,7 @@
"menu.forms": "表格", "menu.forms": "表格",
"menu.import": "导入", "menu.import": "导入",
"menu.logs": "日志", "menu.logs": "日志",
"menu.maintenance": "Maintenance",
"menu.media": "媒体", "menu.media": "媒体",
"menu.newCampaign": "创建新的", "menu.newCampaign": "创建新的",
"menu.settings": "设置", "menu.settings": "设置",

View file

@ -3,6 +3,7 @@ package core
import ( import (
"database/sql" "database/sql"
"net/http" "net/http"
"time"
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
@ -342,3 +343,23 @@ func (c *Core) RegisterCampaignLinkClick(linkUUID, campUUID, subUUID string) (st
return url, nil return url, nil
} }
// DeleteCampaignViews deletes campaign views older than a given date.
func (c *Core) DeleteCampaignViews(before time.Time) error {
if _, err := c.q.DeleteCampaignViews.Exec(before); err != nil {
c.log.Printf("error deleting campaign views: %s", err)
return echo.NewHTTPError(http.StatusInternalServerError, c.i18n.Ts("public.errorProcessingRequest"))
}
return nil
}
// DeleteCampaignLinkClicks deletes campaign views older than a given date.
func (c *Core) DeleteCampaignLinkClicks(before time.Time) error {
if _, err := c.q.DeleteCampaignLinkClicks.Exec(before); err != nil {
c.log.Printf("error deleting campaign link clicks: %s", err)
return echo.NewHTTPError(http.StatusInternalServerError, c.i18n.Ts("public.errorProcessingRequest"))
}
return nil
}

View file

@ -432,3 +432,29 @@ func (c *Core) DeleteSubscriberBounces(id int, uuid string) error {
return nil return nil
} }
// DeleteOrphanSubscribers deletes orphan subscriber records (subscribers without lists).
func (c *Core) DeleteOrphanSubscribers() (int, error) {
res, err := c.q.DeleteOrphanSubscribers.Exec()
if err != nil {
c.log.Printf("error deleting orphan subscribers: %v", err)
return 0, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorDeleting", "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
}
n, _ := res.RowsAffected()
return int(n), nil
}
// DeleteBlocklistedSubscribers deletes blocklisted subscribers.
func (c *Core) DeleteBlocklistedSubscribers() (int, error) {
res, err := c.q.DeleteBlocklistedSubscribers.Exec()
if err != nil {
c.log.Printf("error deleting blocklisted subscribers: %v", err)
return 0, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorDeleting", "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
}
n, _ := res.RowsAffected()
return int(n), nil
}

View file

@ -2,6 +2,7 @@ package core
import ( import (
"net/http" "net/http"
"time"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/lib/pq" "github.com/lib/pq"
@ -91,3 +92,17 @@ func (c *Core) UnsubscribeListsByQuery(query string, sourceListIDs, targetListID
return nil return nil
} }
// DeleteUnconfirmedSubscriptions sets list subscriptions to 'ubsubscribed' by a given arbitrary query expression.
// sourceListIDs is the list of list IDs to filter the subscriber query with.
func (c *Core) DeleteUnconfirmedSubscriptions(beforeDate time.Time) (int, error) {
res, err := c.q.DeleteUnconfirmedSubscriptions.Exec(beforeDate)
if err != nil {
c.log.Printf("error deleting unconfirmed subscribers: %v", err)
return 0, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorDeleting", "name", "{globals.terms.subscribers}", "error", pqErrMsg(err)))
}
n, _ := res.RowsAffected()
return int(n), nil
}

View file

@ -25,9 +25,12 @@ type Queries struct {
BlocklistSubscribers *sqlx.Stmt `query:"blocklist-subscribers"` BlocklistSubscribers *sqlx.Stmt `query:"blocklist-subscribers"`
AddSubscribersToLists *sqlx.Stmt `query:"add-subscribers-to-lists"` AddSubscribersToLists *sqlx.Stmt `query:"add-subscribers-to-lists"`
DeleteSubscriptions *sqlx.Stmt `query:"delete-subscriptions"` DeleteSubscriptions *sqlx.Stmt `query:"delete-subscriptions"`
DeleteUnconfirmedSubscriptions *sqlx.Stmt `query:"delete-unconfirmed-subscriptions"`
ConfirmSubscriptionOptin *sqlx.Stmt `query:"confirm-subscription-optin"` ConfirmSubscriptionOptin *sqlx.Stmt `query:"confirm-subscription-optin"`
UnsubscribeSubscribersFromLists *sqlx.Stmt `query:"unsubscribe-subscribers-from-lists"` UnsubscribeSubscribersFromLists *sqlx.Stmt `query:"unsubscribe-subscribers-from-lists"`
DeleteSubscribers *sqlx.Stmt `query:"delete-subscribers"` DeleteSubscribers *sqlx.Stmt `query:"delete-subscribers"`
DeleteBlocklistedSubscribers *sqlx.Stmt `query:"delete-blocklisted-subscribers"`
DeleteOrphanSubscribers *sqlx.Stmt `query:"delete-orphan-subscribers"`
UnsubscribeByCampaign *sqlx.Stmt `query:"unsubscribe-by-campaign"` UnsubscribeByCampaign *sqlx.Stmt `query:"unsubscribe-by-campaign"`
ExportSubscriberData *sqlx.Stmt `query:"export-subscriber-data"` ExportSubscriberData *sqlx.Stmt `query:"export-subscriber-data"`
@ -65,6 +68,8 @@ type Queries struct {
GetCampaignClickCounts *sqlx.Stmt `query:"get-campaign-click-counts"` GetCampaignClickCounts *sqlx.Stmt `query:"get-campaign-click-counts"`
GetCampaignLinkCounts *sqlx.Stmt `query:"get-campaign-link-counts"` GetCampaignLinkCounts *sqlx.Stmt `query:"get-campaign-link-counts"`
GetCampaignBounceCounts *sqlx.Stmt `query:"get-campaign-bounce-counts"` GetCampaignBounceCounts *sqlx.Stmt `query:"get-campaign-bounce-counts"`
DeleteCampaignViews *sqlx.Stmt `query:"delete-campaign-views"`
DeleteCampaignLinkClicks *sqlx.Stmt `query:"delete-campaign-link-clicks"`
NextCampaigns *sqlx.Stmt `query:"next-campaigns"` NextCampaigns *sqlx.Stmt `query:"next-campaigns"`
NextCampaignSubscribers *sqlx.Stmt `query:"next-campaign-subscribers"` NextCampaignSubscribers *sqlx.Stmt `query:"next-campaign-subscribers"`

View file

@ -147,6 +147,13 @@ INSERT INTO subscriber_lists (subscriber_id, list_id, status)
-- Delete one or more subscribers by ID or UUID. -- Delete one or more subscribers by ID or UUID.
DELETE FROM subscribers WHERE CASE WHEN ARRAY_LENGTH($1::INT[], 1) > 0 THEN id = ANY($1) ELSE uuid = ANY($2::UUID[]) END; DELETE FROM subscribers WHERE CASE WHEN ARRAY_LENGTH($1::INT[], 1) > 0 THEN id = ANY($1) ELSE uuid = ANY($2::UUID[]) END;
-- name: delete-blocklisted-subscribers
DELETE FROM subscribers WHERE status = 'blocklisted';
-- name: delete-orphan-subscribers
DELETE FROM subscribers a WHERE NOT EXISTS
(SELECT 1 FROM subscriber_lists b WHERE b.subscriber_id = a.id);
-- name: blocklist-subscribers -- name: blocklist-subscribers
WITH b AS ( WITH b AS (
UPDATE subscribers SET status='blocklisted', updated_at=NOW() UPDATE subscribers SET status='blocklisted', updated_at=NOW()
@ -196,6 +203,13 @@ UPDATE subscriber_lists SET status = 'unsubscribed' WHERE
-- If $3 is false, unsubscribe from the campaign's lists, otherwise all lists. -- If $3 is false, unsubscribe from the campaign's lists, otherwise all lists.
CASE WHEN $3 IS FALSE THEN list_id = ANY(SELECT list_id FROM lists) ELSE list_id != 0 END; CASE WHEN $3 IS FALSE THEN list_id = ANY(SELECT list_id FROM lists) ELSE list_id != 0 END;
-- name: delete-unconfirmed-subscriptions
WITH optins AS (
SELECT id FROM lists WHERE optin = 'double'
)
DELETE FROM subscriber_lists
WHERE status = 'unconfirmed' AND list_id IN (SELECT id FROM optins) AND created_at < $1;
-- privacy -- privacy
-- name: export-subscriber-data -- name: export-subscriber-data
WITH prof AS ( WITH prof AS (
@ -670,6 +684,12 @@ u AS (
) )
SELECT * FROM subs; SELECT * FROM subs;
-- name: delete-campaign-views
DELETE FROM campaign_views WHERE created_at < $1;
-- name: delete-campaign-link-clicks
DELETE FROM link_clicks WHERE created_at < $1;
-- name: get-one-campaign-subscriber -- name: get-one-campaign-subscriber
SELECT * FROM subscribers SELECT * FROM subscribers
LEFT JOIN subscriber_lists ON (subscribers.id = subscriber_lists.subscriber_id AND subscriber_lists.status != 'unsubscribed') LEFT JOIN subscriber_lists ON (subscribers.id = subscriber_lists.subscriber_id AND subscriber_lists.status != 'unsubscribed')