Added Subscribers page that list newsletter subscribers (paged)
This commit is contained in:
parent
3aee412a4e
commit
4a4110b7ae
|
@ -44,6 +44,7 @@
|
|||
<Authorized>
|
||||
<li><NavLink href="manage/api">@Localizer["ManageApi_Label"]</NavLink></li>
|
||||
<li><NavLink href="newsletter">@Localizer["Newsletter_Label"]</NavLink></li>
|
||||
<li><NavLink href="subscribers">@Localizer["Subscribers_Label"]</NavLink></li>
|
||||
</Authorized>
|
||||
</AuthorizeView>
|
||||
</ul>
|
||||
|
|
114
Wave/Components/Pages/Subscribers.razor
Normal file
114
Wave/Components/Pages/Subscribers.razor
Normal file
|
@ -0,0 +1,114 @@
|
|||
@page "/Subscribers"
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using Microsoft.Extensions.Options
|
||||
@using Wave.Data
|
||||
@using Wave.Utilities
|
||||
|
||||
@attribute [Authorize(Roles = "Admin")]
|
||||
|
||||
@inject IStringLocalizer<Subscribers> Localizer
|
||||
@inject IDbContextFactory<ApplicationDbContext> ContextFactory
|
||||
@inject ILogger<Subscribers> Logger
|
||||
@inject IMessageDisplay Message
|
||||
@inject IOptions<Features> Features
|
||||
|
||||
<PageTitle>@(Localizer["Title"] + TitlePostfix)</PageTitle>
|
||||
|
||||
<h1 class="text-3xl lg:text-5xl font-light mb-6 text-primary">@Localizer["Title"]</h1>
|
||||
|
||||
<section>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-zebra">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>@Localizer["Header_Email"]</th>
|
||||
<th>@Localizer["Header_Name"]</th>
|
||||
<th>@Localizer["Header_LastReceived"]</th>
|
||||
<th>@Localizer["Header_LastOpen"]</th>
|
||||
<th>@Localizer["Header_UnsubscribeReason"]</th>
|
||||
<th>@Localizer["Header_Subscribed"]</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<PageComponent Page="@Page" LoadCallback="LoadSubscribers" ItemsPerPage="ItemsPerPage">
|
||||
<tr>
|
||||
<td>@context.Email</td>
|
||||
<td>@context.Name</td>
|
||||
<td>@context.LastMailReceived?.ToString("g")</td>
|
||||
<td>@context.LastMailOpened?.ToString("g")</td>
|
||||
<td>@context.UnsubscribeReason</td>
|
||||
<td><input type="checkbox" class="checkbox" checked="@(!context.Unsubscribed)"/></td>
|
||||
</tr>
|
||||
</PageComponent>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="3">@Localizer["Newsletter_Footer_Timezone"] @TimeZoneInfo.Local</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="grid place-content-center my-3">
|
||||
<div class="join">
|
||||
@if (Page < 1) {
|
||||
<button class="join-item btn" disabled title="@Localizer["Paging_Previous"]">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
|
||||
<path fill-rule="evenodd" d="M7.72 12.53a.75.75 0 0 1 0-1.06l7.5-7.5a.75.75 0 1 1 1.06 1.06L9.31 12l6.97 6.97a.75.75 0 1 1-1.06 1.06l-7.5-7.5Z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
} else {
|
||||
<a class="join-item btn" target="_top" href="@(Page < 2 ? "/subscribers" : $"/subscribers?page={Page - 1}")" title="@Localizer["Paging_Previous"]">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
|
||||
<path fill-rule="evenodd" d="M7.72 12.53a.75.75 0 0 1 0-1.06l7.5-7.5a.75.75 0 1 1 1.06 1.06L9.31 12l6.97 6.97a.75.75 0 1 1-1.06 1.06l-7.5-7.5Z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</a>
|
||||
}
|
||||
<button class="join-item btn md:btn-wide no-animation">@Localizer["Paging_Page"] @(Page + 1)</button>
|
||||
@if (Page >= TotalPages - 1) {
|
||||
<button class="join-item btn" disabled title="@Localizer["Paging_Next"]">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
|
||||
<path fill-rule="evenodd" d="M16.28 11.47a.75.75 0 0 1 0 1.06l-7.5 7.5a.75.75 0 0 1-1.06-1.06L14.69 12 7.72 5.03a.75.75 0 0 1 1.06-1.06l7.5 7.5Z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</button>
|
||||
} else {
|
||||
<a class="join-item btn" target="_top" href="/subscribers?page=@(Page + 1)" title="@Localizer["Paging_Next"]">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
|
||||
<path fill-rule="evenodd" d="M16.28 11.47a.75.75 0 0 1 0 1.06l-7.5 7.5a.75.75 0 0 1-1.06-1.06L14.69 12 7.72 5.03a.75.75 0 0 1 1.06-1.06l7.5 7.5Z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@code {
|
||||
[CascadingParameter(Name = "TitlePostfix")]
|
||||
private string TitlePostfix { get; set; } = default!;
|
||||
[SupplyParameterFromQuery]
|
||||
public int Page { get; set; } = 0;
|
||||
|
||||
private const int ItemsPerPage = 10;
|
||||
private int TotalPages { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync() {
|
||||
await using var context = await ContextFactory.CreateDbContextAsync();
|
||||
var query = context.Set<EmailSubscriber>();
|
||||
TotalPages = (int)Math.Max(Math.Ceiling((await query.CountAsync() - 1) / (double)ItemsPerPage), 1);
|
||||
}
|
||||
|
||||
private async ValueTask<IEnumerable<EmailSubscriber>> LoadSubscribers(int page, int count) {
|
||||
try {
|
||||
await using var context = await ContextFactory.CreateDbContextAsync();
|
||||
return await context.Set<EmailSubscriber>()
|
||||
.IgnoreAutoIncludes().IgnoreQueryFilters()
|
||||
.OrderBy(s => s.Email).ThenBy(s => s.Id)
|
||||
.Skip(page + 1).Take(count).ToListAsync();
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Failed to load subscribers on page {Page} with count {Count}.", page, count);
|
||||
Message.ShowError(Localizer["Subscriber_Load_Error"]);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -134,4 +134,7 @@
|
|||
<data name="Deleted_Label" xml:space="preserve">
|
||||
<value>Gelöscht</value>
|
||||
</data>
|
||||
<data name="Subscribers_Label" xml:space="preserve">
|
||||
<value>Abonnenten</value>
|
||||
</data>
|
||||
</root>
|
|
@ -137,4 +137,7 @@
|
|||
<data name="Deleted_Label" xml:space="preserve">
|
||||
<value>Deleted</value>
|
||||
</data>
|
||||
<data name="Subscribers_Label" xml:space="preserve">
|
||||
<value>Subscribers</value>
|
||||
</data>
|
||||
</root>
|
134
Wave/Resources/Components/Pages/Subscribers.de-DE.resx
Normal file
134
Wave/Resources/Components/Pages/Subscribers.de-DE.resx
Normal file
|
@ -0,0 +1,134 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Title" xml:space="preserve">
|
||||
<value>Abonnenten</value>
|
||||
</data>
|
||||
<data name="Paging_Next" xml:space="preserve">
|
||||
<value>Nächste Seite</value>
|
||||
</data>
|
||||
<data name="Paging_Page" xml:space="preserve">
|
||||
<value>Seite</value>
|
||||
</data>
|
||||
<data name="Paging_Previous" xml:space="preserve">
|
||||
<value>Vorherige Seite</value>
|
||||
</data>
|
||||
<data name="Subscriber_Load_Error" xml:space="preserve">
|
||||
<value>Unerwarteter Fehler beim laden der Abonnenten</value>
|
||||
</data>
|
||||
<data name="Header_Email" xml:space="preserve">
|
||||
<value>E-Mail</value>
|
||||
</data>
|
||||
<data name="Header_UnsubscribeReason" xml:space="preserve">
|
||||
<value>Notiz</value>
|
||||
</data>
|
||||
<data name="Header_Subscribed" xml:space="preserve">
|
||||
<value>Angemeldet</value>
|
||||
</data>
|
||||
<data name="Header_LastReceived" xml:space="preserve">
|
||||
<value>Zuletzt Zugestellt</value>
|
||||
</data>
|
||||
<data name="Header_LastOpen" xml:space="preserve">
|
||||
<value>Zuletzt Geöffnet</value>
|
||||
</data>
|
||||
<data name="Newsletter_Footer_Timezone" xml:space="preserve">
|
||||
<value>Alle Uhrzeiten sind in der folgenden Zeitzone:</value>
|
||||
</data>
|
||||
</root>
|
101
Wave/Resources/Components/Pages/Subscribers.en-GB.resx
Normal file
101
Wave/Resources/Components/Pages/Subscribers.en-GB.resx
Normal file
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
137
Wave/Resources/Components/Pages/Subscribers.resx
Normal file
137
Wave/Resources/Components/Pages/Subscribers.resx
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Title" xml:space="preserve">
|
||||
<value>Subscribers</value>
|
||||
</data>
|
||||
<data name="Paging_Next" xml:space="preserve">
|
||||
<value>Next page</value>
|
||||
</data>
|
||||
<data name="Paging_Page" xml:space="preserve">
|
||||
<value>Page</value>
|
||||
</data>
|
||||
<data name="Paging_Previous" xml:space="preserve">
|
||||
<value>Previous page</value>
|
||||
</data>
|
||||
<data name="Subscriber_Load_Error" xml:space="preserve">
|
||||
<value>Unknown error loading subscribers</value>
|
||||
</data>
|
||||
<data name="Header_Email" xml:space="preserve">
|
||||
<value>Email</value>
|
||||
</data>
|
||||
<data name="Header_Name" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
</data>
|
||||
<data name="Header_UnsubscribeReason" xml:space="preserve">
|
||||
<value>Note</value>
|
||||
</data>
|
||||
<data name="Header_Subscribed" xml:space="preserve">
|
||||
<value>Subscribed</value>
|
||||
</data>
|
||||
<data name="Header_LastReceived" xml:space="preserve">
|
||||
<value>Last Received</value>
|
||||
</data>
|
||||
<data name="Header_LastOpen" xml:space="preserve">
|
||||
<value>Last Open</value>
|
||||
</data>
|
||||
<data name="Newsletter_Footer_Timezone" xml:space="preserve">
|
||||
<value>All times are using this timezone:</value>
|
||||
</data>
|
||||
</root>
|
Loading…
Reference in a new issue