Neues Kalendermodul und DevExpress Übersetzungen
This commit is contained in:
@@ -193,6 +193,7 @@
|
||||
<HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\lib\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.Extensions.FileSystemGlobbing, Version=9.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL" />
|
||||
<Reference Include="Microsoft.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebHelpers.3.3.0\lib\net45\Microsoft.Web.Helpers.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -400,6 +401,7 @@
|
||||
<Compile Include="Util\JsonPerson.cs" />
|
||||
<Compile Include="Util\SchedulerUtils\CustomAppointmentTemplateContainer.cs" />
|
||||
<Compile Include="Util\SchedulerUtils\EmployeeAvailabilityObject.cs" />
|
||||
<Compile Include="Util\SchedulerUtils\OwnSoftSchedulerLocalizer.cs" />
|
||||
<Compile Include="Util\ServiceRecord2Validation.cs" />
|
||||
<Compile Include="Util\SignatureUtils.cs" />
|
||||
<Compile Include="Util\SupportConceptStatisticsData.cs" />
|
||||
|
||||
@@ -12641,4 +12641,13 @@ a.text-bewo-report:hover, a.text-bewo-report:focus {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='25' height='25' viewBox='0 0 20 20'%3E%3Cg %3E%3Cpolygon fill='%23FFCA00' points='20 10 10 0 0 0 20 20'/%3E%3Cpolygon fill='%23FFCA00' points='0 10 0 20 10 20'/%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.btn-sm-auto {
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=style.css.map */
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -255,4 +255,13 @@ $font-family-sans-serif: 'Signika Negative', sans-serif;
|
||||
.bewo-dev-bg {
|
||||
background-color: #000000;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='25' height='25' viewBox='0 0 20 20'%3E%3Cg %3E%3Cpolygon fill='%23FFCA00' points='20 10 10 0 0 0 20 20'/%3E%3Cpolygon fill='%23FFCA00' points='0 10 0 20 10 20'/%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
@media(max-width: 575.98px) {
|
||||
.btn-sm-auto {
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
}
|
||||
@@ -121,6 +121,7 @@ namespace BeWoPlanerMobil.Controllers
|
||||
Model.PossibleCustomers = CustomerService.GetAllAuthorizedCompactCustomers();
|
||||
Model.PossibleResources = KalenderService.GetAllResources();
|
||||
|
||||
// Ressourcen
|
||||
if(Model.HasRightToInsertRessourceAppointments || Model.HasRightToViewAllResourceAppointments)
|
||||
{
|
||||
var allResources = KalenderService.GetAllResources().OrderBy(r => r.Name).ToList();
|
||||
@@ -135,6 +136,7 @@ namespace BeWoPlanerMobil.Controllers
|
||||
Model.ResourceCategories2Resources = categories2Resources.OrderBy(category2Resources => category2Resources.Key.DisplayName).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||
}
|
||||
|
||||
// Teams
|
||||
Model.MyTeamEmployees = EmployeeService.GetAllTeamMember(compactEmployee).OrderBy(employee => employee.LastName).ToList();
|
||||
|
||||
if(Model.HasRightToViewTeams)
|
||||
@@ -143,6 +145,7 @@ namespace BeWoPlanerMobil.Controllers
|
||||
}
|
||||
|
||||
Model.TeamMemberCustomerOids = EmployeeService.LoadTeamsRelatedCustomerOids(employeeOid);
|
||||
// /Teams
|
||||
|
||||
Model.SelectedEmployeesForFiltering = Model.PossibleEmployees.Where(possibleEmployee => Model.SelectedEmployeeOidsForFiltering?.Contains(possibleEmployee.EmployeeOid) ?? false).ToList();
|
||||
Model.SelectedCustomersForFiltering = Model.PossibleCustomers.Where(possibleCustomer => Model.SelectedCustomerOidsForFiltering?.Contains(possibleCustomer.CustomerOid) ?? false).ToList();
|
||||
@@ -171,7 +174,7 @@ namespace BeWoPlanerMobil.Controllers
|
||||
var intervalStart = DateTimeExtensions.GetDayOfWeek(DayOfWeek.Monday);
|
||||
var intervalEnd = intervalStart.AddDays(7);
|
||||
|
||||
var allAppointments = KalenderService.LoadFilteredAppointmentsMitAufgaben
|
||||
var allAppointments = KalenderService.LoadFilteredAppointmentsMitAufgabenForMoK
|
||||
(
|
||||
Model.HasRightKalenderMitarbeitertermineAnsehen,
|
||||
employeeOid,
|
||||
@@ -278,24 +281,44 @@ namespace BeWoPlanerMobil.Controllers
|
||||
if(Model.HasRightKalenderRessourcenTermineAndererAendern is false)
|
||||
{
|
||||
appointments
|
||||
.Where(appointment => appointment.Originator.Equals(Model.LoggedInCompactEmployee) is false && appointment.ResourceList.Any())
|
||||
.Where(appointment =>
|
||||
appointment.IsTask is false &&
|
||||
appointment.IsAbsenceTime is false &&
|
||||
appointment.Originator.Equals(Model.LoggedInCompactEmployee) is false && appointment.ResourceList.Any())
|
||||
.DoForEach(appointment => appointment.CanBeEdited = false);
|
||||
}
|
||||
|
||||
if(Model.HasRightKalenderKlientenTermineAendern is false)
|
||||
{
|
||||
appointments
|
||||
.Where(appointment => appointment.Originator.Equals(Model.LoggedInCompactEmployee) is false && appointment.CustomerList.Any(customer => relatedCustomerOids.Contains(customer.CustomerOid) is false))
|
||||
.Where(appointment =>
|
||||
appointment.IsTask is false &&
|
||||
appointment.IsAbsenceTime is false &&
|
||||
appointment.Originator.Equals(Model.LoggedInCompactEmployee) is false && appointment.CustomerList.Any())
|
||||
.DoForEach(appointment => appointment.CanBeEdited = false);
|
||||
}
|
||||
|
||||
if(Model.HasRightKalenderMitarbeiterTermineAendern is false)
|
||||
{
|
||||
appointments
|
||||
.Where(appointment => appointment.Originator.Equals(Model.LoggedInCompactEmployee) is false)
|
||||
.Where(appointment =>
|
||||
appointment.IsTask is false &&
|
||||
appointment.IsAbsenceTime is false &&
|
||||
appointment.Originator.Equals(Model.LoggedInCompactEmployee) is false)
|
||||
.DoForEach(appointment => appointment.CanBeEdited = false);
|
||||
}
|
||||
|
||||
foreach(var appointment in appointments.Where(apt => apt.IsTask is false && apt.IsAbsenceTime is false && apt.Originator.Equals(Model.LoggedInCompactEmployee) is false && apt.CustomerList.Any()))
|
||||
{
|
||||
var canEdit = appointment.CanBeEdited;
|
||||
var canView = appointment.CanBeViewed;
|
||||
var canDelete = appointment.CanBeDeleted;
|
||||
|
||||
var subject = appointment.Subject;
|
||||
}
|
||||
|
||||
var x = appointments.Where(w => w.SchedulerAppointmentOid is null).ToList();
|
||||
|
||||
Model.Appointments = appointments;
|
||||
|
||||
LoadNotificationCount();
|
||||
@@ -1580,7 +1603,7 @@ namespace BeWoPlanerMobil.Controllers
|
||||
}
|
||||
|
||||
AppointmentModel.SelectedResourceOids = selectedOids.Length == 0 ? new List<long>() : selectedOids.Split(',').Select(long.Parse).ToList();
|
||||
|
||||
|
||||
return JsonConvert.SerializeObject(AppointmentModel.SelectedResourceOids?.Count ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ using BeWoPlanerMobil.Service;
|
||||
using BeWoPlanerMobil.Util;
|
||||
using BS.Shared;
|
||||
using BS.Shared.DataContracts;
|
||||
using DevExpress.XtraPrinting;
|
||||
using HttpCookie = System.Web.HttpCookie;
|
||||
|
||||
|
||||
|
||||
63
BeWoPlanerMobil/DXLocalization.Designer.cs
generated
Normal file
63
BeWoPlanerMobil/DXLocalization.Designer.cs
generated
Normal file
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace BeWoPlanerMobil {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class DXLocalization {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal DXLocalization() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if(object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BeWoPlanerMobil.DXLocalization", typeof(DXLocalization).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
141
BeWoPlanerMobil/DXLocalization.de.resx
Normal file
141
BeWoPlanerMobil/DXLocalization.de.resx
Normal file
@@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
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">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<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" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ASPxSchedulerStringId.FloatingActionButton_NewAppointment" xml:space="preserve">
|
||||
<value>Neuer Termin</value>
|
||||
</data>
|
||||
<data name="ASPxSchedulerStringId.ToolTip_DeleteAppointment" xml:space="preserve">
|
||||
<value>Löschen</value>
|
||||
</data>
|
||||
<data name="ASPxSchedulerStringId.FloatingActionButton_DeleteAppointment" xml:space="preserve">
|
||||
<value>Löschen</value>
|
||||
</data>
|
||||
<data name="SchedulerStringId.AppointmentLabel_Birthday" xml:space="preserve">
|
||||
<value>Geburtstag</value>
|
||||
</data>
|
||||
<data name="SchedulerStringId.ViewShortDisplayName_Day" xml:space="preserve">
|
||||
<value>Tag</value>
|
||||
</data>
|
||||
<data name="ASPxEditorsStringId.Calendar_Today" xml:space="preserve">
|
||||
<value>Heute</value>
|
||||
</data>
|
||||
<data name="SchedulerStringId.ViewShortDisplayName_WorkDays" xml:space="preserve">
|
||||
<value>Arbeitswoche</value>
|
||||
</data>
|
||||
</root>
|
||||
120
BeWoPlanerMobil/DXLocalization.resx
Normal file
120
BeWoPlanerMobil/DXLocalization.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
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">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<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" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -9,6 +9,7 @@ using System.Web.Http;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Optimization;
|
||||
using System.Web.Routing;
|
||||
using BeWoPlanerMobil.Util.SchedulerUtils;
|
||||
|
||||
|
||||
namespace BeWoPlanerMobil
|
||||
@@ -33,6 +34,12 @@ namespace BeWoPlanerMobil
|
||||
BundleConfig.RegisterBundles(BundleTable.Bundles);
|
||||
|
||||
XmlConfigurator.Configure();
|
||||
|
||||
OwnSoftSchedulerLocalizer.Activate();
|
||||
|
||||
// Für den Localizer. Für Release wieder entfernen und durch die Zeile darunter ersetzen
|
||||
//DevExpress.Utils.Localization.XtraLocalizer.EnableTraceSource("BeWoPlanerMobil");
|
||||
//RELEASE: DevExpress.Utils.Localization.XtraLocalizer.UserResourceManager = DXLocalization.ResourceManager;
|
||||
}
|
||||
|
||||
protected void Application_BeginRequest(object sender, EventArgs e)
|
||||
@@ -41,6 +48,9 @@ namespace BeWoPlanerMobil
|
||||
|
||||
// ToDo: Könnte Probleme beim Login machen, falls der den Header der Login-Anfrage benutzt.
|
||||
Response.Headers["Referrer-Policy"] = "no-referrer";
|
||||
|
||||
Thread.CurrentThread.CurrentCulture = _CultureInfo;
|
||||
Thread.CurrentThread.CurrentUICulture = _CultureInfo;
|
||||
}
|
||||
|
||||
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
|
||||
|
||||
@@ -34,6 +34,8 @@ namespace BeWoPlanerMobil.Models
|
||||
public bool HasServiceRecordEntry { get; set; }
|
||||
public long? OriginatorOid { get; set; }
|
||||
|
||||
public int? RecurrenceIndex { get; set; }
|
||||
|
||||
public bool ShowEmployeeColors { get; set; }
|
||||
public List<ServiceRecordDC> ServiceRecordList { get; set; }
|
||||
|
||||
|
||||
@@ -10,7 +10,20 @@ namespace BeWoPlanerMobil.Models
|
||||
public List<long> SelectedResourceOids { get; set; }
|
||||
public SchedulerViewType CurrentSchedulerViewType { get; set; }
|
||||
|
||||
public List<long> SelectedEmployeeOidsForFiltering { get; set; }
|
||||
private List<long> _SelectedEmployeeOidsForFiltering;
|
||||
|
||||
public List<long> SelectedEmployeeOidsForFiltering
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SelectedEmployeeOidsForFiltering;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_SelectedEmployeeOidsForFiltering = value;
|
||||
}
|
||||
}
|
||||
public List<long> SelectedCustomerOidsForFiltering { get; set; }
|
||||
public List<long> SelectedResourceOidsForFiltering { get; set; }
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Diagnostics;
|
||||
using DevExpress.Utils.Localization.Internal;
|
||||
using DevExpress.XtraScheduler.Localization;
|
||||
|
||||
namespace BeWoPlanerMobil.Util.SchedulerUtils
|
||||
{
|
||||
public class OwnSoftSchedulerLocalizer : SchedulerLocalizer
|
||||
{
|
||||
public override string GetLocalizedString(SchedulerStringId id)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case SchedulerStringId.ViewShortDisplayName_Day:
|
||||
return "Tag";
|
||||
case SchedulerStringId.ViewShortDisplayName_Week:
|
||||
return "Woche";
|
||||
case SchedulerStringId.TimeScaleDisplayName_Week:
|
||||
return "Woche";
|
||||
case SchedulerStringId.ViewShortDisplayName_WorkDays:
|
||||
return "Arbeitswoche";
|
||||
case SchedulerStringId.ViewDisplayName_WorkDays:
|
||||
return "Arbeitswoche";
|
||||
case SchedulerStringId.ViewShortDisplayName_Timeline:
|
||||
return "Zeitleiste";
|
||||
case SchedulerStringId.ViewDisplayName_Timeline:
|
||||
return "Zeitleiste";
|
||||
case SchedulerStringId.ViewDisplayName_Month:
|
||||
return "Monat";
|
||||
case SchedulerStringId.ViewShortDisplayName_Month:
|
||||
return "Monat";
|
||||
}
|
||||
|
||||
return base.GetLocalizedString(id);
|
||||
}
|
||||
|
||||
public static void Activate()
|
||||
{
|
||||
var localizer = new OwnSoftSchedulerLocalizer();
|
||||
var provider = new DefaultActiveLocalizerProvider<SchedulerStringId>(localizer);
|
||||
|
||||
SetActiveLocalizerProvider(provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@
|
||||
</div>
|
||||
<input class="form-control w-100" type="text" placeholder="Suchen..." oninput="employeeListSearchOnChange()" id="employee-search-input" />
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary" type="button" onclick="resetEmployeeSearch()">
|
||||
<button class="btn btn-sm btn-outline-secondary" type="button" onclick="resetEmployeeSearch()">
|
||||
<span class="fas fa-times-circle"></span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -137,7 +137,7 @@
|
||||
<div class="card-body">
|
||||
@foreach(var team in Model.MyTeams)
|
||||
{
|
||||
<button type="button" class="btn btn-bewo-teams w-100 my-2" onclick="selectTeamForAppointment(@team.TeamOid)">@team.Name</button>
|
||||
<button type="button" class="btn btn-sm btn-bewo-teams w-100 my-2" onclick="selectTeamForAppointment(@team.TeamOid)">@team.Name</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
@using BeWoPlanerMobil.Util
|
||||
<script type="text/javascript">
|
||||
<script type="text/javascript">
|
||||
function onAppointmentDragTipDisplaying(s, e) {
|
||||
const newIntervalText = e.toolTip.ConvertIntervalToString(e.data.GetInterval());
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
Html.EnableClientValidation();
|
||||
Html.EnableUnobtrusiveJavaScript();
|
||||
|
||||
var isNew = Model.Oid is null;
|
||||
// Ist bei Serientermininstanzen ebenfalls null!
|
||||
var isNew = Model.Oid is null && Model.RecurrenceIndex == 0 && Model.RecurrenceInfo is null;
|
||||
|
||||
var cancelButtonText = "Abbrechen";
|
||||
|
||||
@@ -84,6 +85,11 @@
|
||||
var showResourceButton = (Model.HasRightKalenderRessourcentermineAnsehen && Model.Oid.HasValue) ||
|
||||
(Model.Oid.HasValue && (Model.HasRightKalenderRessourcenTermineAendern && isOriginator || isOriginator is false && Model.HasRightKalenderRessourcenTermineAndererAendern)) ||
|
||||
(Model.Oid is null && Model.HasRightKalenderRessourcenTermineAnlegen);
|
||||
|
||||
if(areButtonsVisible != Model.CanBeEdited)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
<style type="text/css">
|
||||
@@ -95,168 +101,154 @@
|
||||
|
||||
@using(Html.BeginForm())
|
||||
{
|
||||
<table id="abc-table" class="w-100">
|
||||
@* Betreff *@
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Betreff</span>
|
||||
</div>
|
||||
<input class="form-control" type="text" @disabled id="Subject" name="Subject" value="@Model.Subject" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@* Ort *@
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Ort</span>
|
||||
</div>
|
||||
<input class="form-control" type="text" @disabled id="Location" name="Location" value="@Model.Location" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@* Start *@
|
||||
<tr>
|
||||
<td>
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Start</span>
|
||||
</div>
|
||||
<input class="form-control" type="@dateInputType" @disabled id="StartDate" name="StartDate" value="@start" />
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group pl-2 mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
@Html.DevExpress().CheckBox(
|
||||
settings =>
|
||||
{
|
||||
settings.Name = nameof(SchedulerAppointmentDC.AllDay);
|
||||
settings.Width = Unit.Percentage(100);
|
||||
settings.ReadOnly = disabled.Length > 0;
|
||||
}).Bind(Model.AllDay).GetHtml()
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">Ganztägig</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@* Ende *@
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Ende</span>
|
||||
</div>
|
||||
<input class="form-control" type="@dateInputType" @disabled id="EndDate" name="EndDate" value="@end" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@* Privat *@
|
||||
<tr>
|
||||
|
||||
<td >
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
@Html.DevExpress().CheckBox(
|
||||
settings =>
|
||||
{
|
||||
settings.Name = nameof(SchedulerAppointmentDC.IsPrivate);
|
||||
settings.Width = Unit.Percentage(100);
|
||||
settings.Properties.RootStyle.CssClass = "";
|
||||
settings.ReadOnly = disabled.Length > 0;
|
||||
}).Bind(Model.IsPrivate).GetHtml()
|
||||
<div class="row" id="abc-table">
|
||||
<div class="col">
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Betreff</span>
|
||||
</div>
|
||||
<input class="form-control" type="text" @disabled id="Subject" name="Subject" value="@Model.Subject" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Ort</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">Privat</span>
|
||||
<input class="form-control" type="text" @disabled id="Location" name="Location" value="@Model.Location" />
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Start</span>
|
||||
</div>
|
||||
<input class="form-control" type="@dateInputType" @disabled id="StartDate" name="StartDate" value="@start" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Ende</span>
|
||||
</div>
|
||||
<input class="form-control" type="@dateInputType" @disabled id="EndDate" name="EndDate" value="@end" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
@Html.DevExpress().CheckBox(
|
||||
settings =>
|
||||
{
|
||||
settings.Name = nameof(SchedulerAppointmentDC.IsPrivate);
|
||||
settings.Width = Unit.Percentage(100);
|
||||
settings.Properties.RootStyle.CssClass = "";
|
||||
settings.ReadOnly = disabled.Length > 0;
|
||||
}).Bind(Model.IsPrivate).GetHtml()
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">Privat</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="input-group pl-2 mb-2 justify-content-end">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">
|
||||
@Html.DevExpress().CheckBox(
|
||||
settings =>
|
||||
{
|
||||
settings.Name = nameof(SchedulerAppointmentDC.AllDay);
|
||||
settings.Width = Unit.Percentage(100);
|
||||
settings.ReadOnly = disabled.Length > 0;
|
||||
}).Bind(Model.AllDay).GetHtml()
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">Ganztägig</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if(Model.HasRightKalenderMitarbeitertermineAnsehen || Model.HasRightKalenderKliententermineAnsehen || Model.HasRightKalenderRessourcentermineAnsehen)
|
||||
{
|
||||
<tr>
|
||||
@* colspan="4" *@
|
||||
<td colspan="2">
|
||||
<table class="w-100">
|
||||
<tr>
|
||||
<td style="width: 33%; padding: .25em;">
|
||||
@if(showEmployeeButton)
|
||||
{
|
||||
@Html.Partial("CustomEmployeeSelectPartial", Model)
|
||||
}
|
||||
</td>
|
||||
<td style="width: 33%; padding: .25em;">
|
||||
@if(showCustomerButton)
|
||||
{
|
||||
@Html.Partial("CustomCustomerSelectPartial", Model)
|
||||
}
|
||||
</td>
|
||||
<td style="width: 33%; padding: .25em;">
|
||||
@if(showResourceButton)
|
||||
{
|
||||
@Html.Partial("CustomResourceSelectPartial", Model)
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if(Model.HasRightKalenderMitarbeitertermineAnsehen || Model.HasRightKalenderKliententermineAnsehen || Model.HasRightKalenderRessourcentermineAnsehen)
|
||||
{
|
||||
<div class="form-row justify-content-center">
|
||||
@if(showEmployeeButton)
|
||||
{
|
||||
@Html.Partial("CustomEmployeeSelectPartial", Model)
|
||||
}
|
||||
|
||||
@* Notiz *@
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="form-group">
|
||||
<label for="Description">Notiz</label>
|
||||
<textarea class="form-control" @disabled id="Description" name="Description">@Model.Description</textarea>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@if(showCustomerButton)
|
||||
{
|
||||
@Html.Partial("CustomCustomerSelectPartial", Model)
|
||||
}
|
||||
|
||||
@Html.DevExpress().AppointmentRecurrenceForm(ViewBag.AppointmentRecurrenceFormSettings).GetHtml()
|
||||
@if(showResourceButton)
|
||||
{
|
||||
@Html.Partial("CustomResourceSelectPartial", Model)
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<table style="width: 100%">
|
||||
<tr>
|
||||
@if(areButtonsVisible)
|
||||
{
|
||||
<button type="button" class="btn btn-primary mr-2" id="Apply" name="Apply" onclick="OnAppointmentFormSave()">OK</button>
|
||||
}
|
||||
<div class="form-row">
|
||||
<div class="col-md">
|
||||
<div class="form-group">
|
||||
<label for="Description">Notiz</label>
|
||||
<textarea class="form-control" @disabled id="Description" name="Description">@Model.Description</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="recurrence-container">
|
||||
@{
|
||||
var recurrenceSettings = (AppointmentRecurrenceFormSettings) ViewBag.AppointmentRecurrenceFormSettings;
|
||||
|
||||
<button type="button" class="btn btn-primary mr-2" id="Cancel" name="Cancel" onclick="OnAppointmentFormCancel()">@cancelButtonText</button>
|
||||
recurrenceSettings.Enabled = areButtonsVisible;
|
||||
}
|
||||
|
||||
@if(isDeleteButtonVisible)
|
||||
{
|
||||
<button type="button" class="btn btn-danger" id="Delete" name="Delete" onclick="OnAppointmentFormDelete()">Löschen</button>
|
||||
}
|
||||
</tr>
|
||||
</table>
|
||||
@Html.DevExpress().AppointmentRecurrenceForm(recurrenceSettings).GetHtml()
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="col">
|
||||
<div class="float-right">
|
||||
@if(areButtonsVisible)
|
||||
{
|
||||
<button type="button" class="btn btn-sm-auto btn-primary mr-2" id="Apply" name="Apply" onclick="OnAppointmentFormSave()">OK</button>
|
||||
}
|
||||
|
||||
<table class="w-100">
|
||||
<tr>
|
||||
<td style="width: 100%;">
|
||||
<button type="button" class="btn btn-sm-auto btn-primary mr-2" id="Cancel" name="Cancel" onclick="OnAppointmentFormCancel()">@cancelButtonText</button>
|
||||
|
||||
@if(isDeleteButtonVisible)
|
||||
{
|
||||
<button type="button" class="btn btn-sm-auto btn-danger" id="Delete" name="Delete" onclick="OnAppointmentFormDelete()">Löschen</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@Html.DevExpress().SchedulerStatusInfo(
|
||||
settings =>
|
||||
{
|
||||
settings.Name = "schedulerStatusInfo";
|
||||
settings.Priority = 1;
|
||||
settings.SchedulerName = "scheduler";
|
||||
}).GetHtml()
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
settings =>
|
||||
{
|
||||
settings.Name = "schedulerStatusInfo";
|
||||
settings.Priority = 1;
|
||||
settings.SchedulerName = "scheduler";
|
||||
}).GetHtml()
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -12,9 +12,7 @@
|
||||
const participationInfos = currentApt.ParticipationInfos;
|
||||
const resourceInfos = currentApt.ResourceInfos;
|
||||
const customerInfos = currentApt.CustomerInfos;
|
||||
|
||||
logInfo(`Mitarbeiter: ${participationInfos.length}\r\nKlienten: ${customerInfos.length}\r\nRessourcen: ${resourceInfos.length}`);
|
||||
|
||||
console.log(currentApt); // ToDo: Icon bei Serientermin! Index auch?
|
||||
let bgClass = "";
|
||||
|
||||
$("#tool-tip-info").empty();
|
||||
@@ -57,7 +55,6 @@
|
||||
$("#resources-container").append(`<span class="small pr-1">Ressourcen:</span>`);
|
||||
|
||||
resourceInfos.forEach((info) => {
|
||||
logInfo2(`Farbe der Ressource <<${info.ResourceName}>>: ${info.ResourceColor}`);
|
||||
$("#resources-container").append(`<span class="badge badge-light border"><div class="mr-1" style="display:inline-block;border-radius:3px;vertical-align:middle;width:10px;height:10px;border:1px slategray;background-color: ${info.ResourceColor};"></div>${info.ResourceName}</span>`);
|
||||
});
|
||||
}
|
||||
@@ -66,7 +63,7 @@
|
||||
|
||||
const textInterval = e.toolTip.ConvertIntervalToString(currentApt.interval);
|
||||
|
||||
$('#tool-tip-title').html(textInterval);
|
||||
$('#tool-tip-title').html(`${textInterval}: ${currentApt.GetSubject()}`);
|
||||
|
||||
if(currentApt.CanBeDeleted === false) {
|
||||
$("#aptToolTipDelete").hide();
|
||||
@@ -117,4 +114,12 @@
|
||||
<div id="originator-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer m-0 p-1">
|
||||
<button type="button" id="aptToolTipEdit" class="btn btn-sm btn-primary" onclick="onAptToolTipEditClick()">
|
||||
Bearbeiten
|
||||
</button>
|
||||
<button type="button" id="aptToolTipDelete" class="btn btn-sm btn-danger float-right" onclick="onAptToolTipDeleteClick()">
|
||||
Löschen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -7,15 +7,15 @@
|
||||
var allChecked = areAllSelected ? "checked" : string.Empty;
|
||||
|
||||
var canEdit = Model.Oid.HasValue && Model.HasRightKalenderKlientenTermineAendern;
|
||||
var canCreate = Model.Oid is null && Model.HasRightKalenderKlientenTermineAnlegen;
|
||||
var canCreate = Model.Oid is null && Model.RecurrenceIndex == 0 && Model.RecurrenceInfo is null && Model.HasRightKalenderKlientenTermineAnlegen;
|
||||
|
||||
var checkBoxEnabled = canEdit || canCreate;
|
||||
|
||||
var disabled = checkBoxEnabled ? string.Empty : "disabled";
|
||||
}
|
||||
|
||||
<div class="dropdown w-100" id="customers-dropdown">
|
||||
<button class="btn btn-bewo-customers dropdown-toggle w-100" type="button" data-toggle="dropdown">
|
||||
<div class="dropdown pr-1" id="customers-dropdown">
|
||||
<button class="btn btn-sm-auto btn-bewo-customers dropdown-toggle w-100" type="button" data-toggle="dropdown">
|
||||
Klienten <span class="badge badge-light" id="apt-cus-badge">@Model.SelectedCustomerOids.Count</span>
|
||||
</button>
|
||||
<div class="dropdown-menu" onclick="event.stopPropagation();">
|
||||
@@ -28,7 +28,7 @@
|
||||
</div>
|
||||
<input type="text" class="form-control" @disabled id="cus-drop-search-input" placeholder="Suchen ..." oninput="onNewSearchInput('cus')">
|
||||
<div class="input-group-append">
|
||||
<button type="button" class="btn btn-outline-secondary" @disabled onclick="resetNewSearch('cus')">
|
||||
<button type="button" class="btn btn-sm-auto btn-outline-secondary" @disabled onclick="resetNewSearch('cus')">
|
||||
<span class="fas fa-times-circle"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -37,15 +37,15 @@
|
||||
|
||||
var allChecked = areAllSelected ? "checked" : string.Empty;
|
||||
|
||||
var isNew = Model.Oid is null;
|
||||
var isNew = Model.Oid is null && Model.RecurrenceIndex == 0 && Model.RecurrenceInfo is null;
|
||||
var isEdit = isNew is false;
|
||||
|
||||
|
||||
var checkBoxEnabled = isEdit && Model.HasRightKalenderMitarbeiterTermineAendern || isNew && Model.HasRightKalenderMitarbeiterTermineAnlegen;
|
||||
var disabled = checkBoxEnabled is false || (Model.CanBeEdited is false && isNew is false) ? "disabled" : string.Empty;
|
||||
}
|
||||
|
||||
<div class="dropdown w-100" id="employees-dropdown">
|
||||
<button class="btn btn-bewo-employee dropdown-toggle w-100" type="button" data-toggle="dropdown">
|
||||
<div class="dropdown pr-1" id="employees-dropdown">
|
||||
<button class="btn btn-sm-auto btn-bewo-employee dropdown-toggle w-100" type="button" data-toggle="dropdown">
|
||||
Mitarbeiter <span class="badge badge-light" id="apt-emp-badge">@Model.SelectedEmployee2SchedulerAppointments.Count</span>
|
||||
</button>
|
||||
<div class="dropdown-menu" onclick="event.stopPropagation();">
|
||||
@@ -58,7 +58,7 @@
|
||||
</div>
|
||||
<input type="text" class="form-control" @disabled id="emp-drop-search-input" placeholder="Suchen ..." oninput="onNewSearchInput('emp')">
|
||||
<div class="input-group-append">
|
||||
<button type="button" class="btn btn-outline-secondary" @disabled onclick="resetNewSearch('emp')">
|
||||
<button type="button" class="btn btn-sm-auto btn-outline-secondary" @disabled onclick="resetNewSearch('emp')">
|
||||
<span class="fas fa-times-circle"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
var checkedValue = areAllSelected ? "checked" : string.Empty;
|
||||
|
||||
var isOriginator = Model.OriginatorOid.HasValue && Model.OriginatorOid.Value == Model.LoggedInCompactEmployee.EmployeeOid;
|
||||
var isNew = Model.Oid is null;
|
||||
var isNew = Model.Oid is null && Model.RecurrenceIndex == 0 && Model.RecurrenceInfo is null;
|
||||
var canEditResApt = Model.HasRightKalenderRessourcenTermineAendern;
|
||||
var canEditOthersResApt = Model.HasRightKalenderRessourcenTermineAndererAendern;
|
||||
var canCreateResApt = Model.HasRightKalenderRessourcenTermineAnlegen;
|
||||
@@ -33,8 +33,8 @@
|
||||
var disabled = isDisabled ? "disabled" : string.Empty;
|
||||
}
|
||||
|
||||
<div class="dropdown w-100" id="resources-dropdown">
|
||||
<button class="btn btn-bewo-resource dropdown-toggle w-100" type="button" data-toggle="dropdown">
|
||||
<div class="dropdown pr-1" id="resources-dropdown">
|
||||
<button class="btn btn-sm-auto btn-bewo-resource dropdown-toggle w-100" type="button" data-toggle="dropdown">
|
||||
Ressourcen <span class="badge badge-light" id="apt-res-badge">@Model.SelectedResourceOids.Count</span>
|
||||
</button>
|
||||
<div class="dropdown-menu" onclick="event.stopPropagation();">
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
<input type="text" class="form-control" id="res-drop-search-input" placeholder="Suchen ..." oninput="onNewResourceSeachInput()">
|
||||
<div class="input-group-append">
|
||||
<button type="button" class="btn btn-outline-secondary" onclick="resetNewResourceSearch()">
|
||||
<button type="button" class="btn btn-sm-auto btn-outline-secondary" onclick="resetNewResourceSearch()">
|
||||
<span class="fas fa-times-circle"></span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -110,31 +110,4 @@
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@* ToDo: Mit den Kategorien wie im alten Kalendermodul bauen!
|
||||
@for(var i = 0; i < Model.PossibleResources.Count; i++)
|
||||
{
|
||||
var resource = Model.PossibleResources[i];
|
||||
var isChecked = resource.ResourceOid.HasValue && Model.SelectedResourceOids.Contains(resource.ResourceOid.Value) ? "checked" : string.Empty;
|
||||
|
||||
var dNone = i / Model.ResourcePageLimit + 1 != 1 ? " d-none" : string.Empty;
|
||||
|
||||
<div class="dropdown-item w-100 @dNone" id="dropdown-item-@i">
|
||||
<form class="form-inline justify-content-between">
|
||||
<div class="form-group form-check">
|
||||
<input class="form-check-input" type="checkbox" id="apt-edit-res-@resource.ResourceOid.Value" @isChecked onclick="updateEmployeeCustomerResourceSelection('res')"/>
|
||||
<label for="apt-edit-res-@resource.ResourceOid.Value" class="form-check-label">
|
||||
@resource.DetailDescription
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@if(WebUtils.CheckColorString(resource.Color))
|
||||
{
|
||||
<div class="float-right" style="width: 10px; height: 10px; background-color: @resource.Color; border: 1px solid @resource.Color; border-radius: 3px;"></div>
|
||||
}
|
||||
</form>
|
||||
</div>
|
||||
}*@
|
||||
</div>
|
||||
@@ -6,6 +6,15 @@
|
||||
}
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(() => {
|
||||
const newAptBtn = $("#scheduler_fab").children().find(".dx-fab-context-text");
|
||||
|
||||
if(newAptBtn.length) {
|
||||
newAptBtn.empty();
|
||||
newAptBtn.append("<span>Neuer Termin</span>");
|
||||
}
|
||||
});
|
||||
|
||||
function UpdateSchedulerHeight() {
|
||||
scheduler.SetHeight(1);
|
||||
|
||||
@@ -18,22 +27,44 @@
|
||||
scheduler.SetHeight(containerHeight);
|
||||
}
|
||||
|
||||
function getLabelByTextFromRecurrenceForm(labelText) {
|
||||
return $("#appointmentRecurrenceForm_AptRecCtl_mainDiv").filter(function() {
|
||||
return $(this).text().trim() === labelText;
|
||||
});
|
||||
}
|
||||
|
||||
function resizeSchedulerEditForm() {
|
||||
const editFormPopup = $("#abc-table").parent().parent().parent();
|
||||
|
||||
const vw = $(window).width();
|
||||
|
||||
if(editFormPopup.css("top") !== undefined) {
|
||||
editFormPopup.css("top", "50px");
|
||||
|
||||
const recurrence = $("#appointmentRecurrenceForm_AptRecCtl_mainDiv label:contains('Recurrence')");
|
||||
const daily = $("#appointmentRecurrenceForm_AptRecCtl_mainDiv label:contains('Daily')");
|
||||
const weekly = $("#appointmentRecurrenceForm_AptRecCtl_mainDiv label:contains('Weekly')");
|
||||
const monthly = $("#appointmentRecurrenceForm_AptRecCtl_mainDiv label:contains('Monthly')");
|
||||
const yearly = $("#appointmentRecurrenceForm_AptRecCtl_mainDiv label:contains('Yearly')");
|
||||
|
||||
recurrence.text("Serie");
|
||||
daily.text("Täglich");
|
||||
weekly.text("Wöchentlich");
|
||||
monthly.text("Monatlich");
|
||||
yearly.text("Jährlich");
|
||||
}
|
||||
|
||||
if(editFormPopup.outerWidth() !== undefined) {
|
||||
$.get("@Url.Action("GetEmployeePageCount")", function(editFormInfo) {
|
||||
pageCountCallback(editFormInfo, "emp");
|
||||
pageCountCallback(editFormInfo, "emp");
|
||||
});
|
||||
|
||||
$.get("@Url.Action("GetCustomerPageCount")", function(editFormInfo) {
|
||||
pageCountCallback(editFormInfo, "cus");
|
||||
pageCountCallback(editFormInfo, "cus");
|
||||
});
|
||||
|
||||
$.get("@Url.Action("GetResourcePageCount")", function(editFormInfo) {
|
||||
pageCountCallback(editFormInfo, "res");
|
||||
pageCountCallback(editFormInfo, "res");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -66,11 +97,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
function pageCountCallback(editFormInfo, prefix) {
|
||||
function pageCountCallback(editFormInfo, prefix) {
|
||||
const info = JSON.parse(editFormInfo);
|
||||
const items = $(`#dropdown-${prefix}-itm-container .dropdown-item`);
|
||||
const items = $(`#dropdown-${prefix}-itm-container .dropdown-item`);
|
||||
|
||||
switch(prefix) {
|
||||
switch(prefix) {
|
||||
case "emp":
|
||||
aptEmpSelPageCount = info.PageCount;
|
||||
aptEmpSelPageLimit = info.PageLimit;
|
||||
@@ -88,7 +119,7 @@
|
||||
break;
|
||||
}
|
||||
|
||||
window.buildPagination(1, 5, 1, prefix);
|
||||
window.buildPagination(1, 5, 1, prefix);
|
||||
}
|
||||
|
||||
function OnAppointmentFormSave(s, e) {
|
||||
@@ -97,13 +128,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
function OnAppointmentFormCancel(s, e) {
|
||||
scheduler.AppointmentFormCancel();
|
||||
}
|
||||
function OnAppointmentFormCancel(s, e) {
|
||||
scheduler.AppointmentFormCancel();
|
||||
}
|
||||
|
||||
function OnAppointmentFormDelete(s, e) {
|
||||
scheduler.AppointmentFormDelete();
|
||||
}
|
||||
function OnAppointmentFormDelete(s, e) {
|
||||
scheduler.AppointmentFormDelete();
|
||||
}
|
||||
|
||||
function IsValidAppointment() {
|
||||
$.validator.unobtrusive.parse("form");
|
||||
@@ -249,25 +280,25 @@
|
||||
}
|
||||
|
||||
function performReload(shouldDoReloadNotifications) {
|
||||
if(shouldDoReloadNotifications === false) {
|
||||
return;
|
||||
}
|
||||
if(shouldDoReloadNotifications === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$("#scheduler-notification-container").load("@Url.Action("GetNotifications")");
|
||||
}
|
||||
|
||||
function reloadScheduler(shouldDoReloadNotifications) {
|
||||
scheduler.PerformCallback({apptID: "", actionId: "Reload", args: null}, () => {performReload(shouldDoReloadNotifications); hideSpinner(); });
|
||||
scheduler.PerformCallback({apptID: "", actionId: "Reload", args: null}, () => {performReload(shouldDoReloadNotifications); hideSpinner(); });
|
||||
}
|
||||
|
||||
@* CustomECRSelectionPartial *@
|
||||
function onNewSearchInput(prefix) {
|
||||
var searchText = $(`#${prefix}-drop-search-input`).val();
|
||||
var searchText = $(`#${prefix}-drop-search-input`).val();
|
||||
|
||||
const menuItems = $(`#dropdown-${prefix}-itm-container .dropdown-item`);
|
||||
const menuItems = $(`#dropdown-${prefix}-itm-container .dropdown-item`);
|
||||
|
||||
if(searchText === null || searchText === undefined || searchText.length === 0) {
|
||||
menuItems.show();
|
||||
menuItems.show();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -285,7 +316,7 @@
|
||||
}
|
||||
|
||||
function resetNewSearch(prefix) {
|
||||
$(`#${prefix}-drop-search-input`).val("");
|
||||
$(`#${prefix}-drop-search-input`).val("");
|
||||
|
||||
buildPagination(1, 5, 1, prefix);
|
||||
showPage(1, prefix);
|
||||
@@ -314,7 +345,7 @@
|
||||
var aptResSelPageLimit = 0;
|
||||
|
||||
function buildPagination(firstShownButton, lastShownButton, activeButton, prefix) {
|
||||
const pagination = $(`#apt-${prefix}-pagination`);
|
||||
const pagination = $(`#apt-${prefix}-pagination`);
|
||||
pagination.empty();
|
||||
|
||||
var pageCount = 1;
|
||||
@@ -335,38 +366,34 @@
|
||||
break;
|
||||
}
|
||||
|
||||
if(prefix === "res") {
|
||||
logInfo2(`Es gibt ${pageCount} Seiten für die Ressourcen`);
|
||||
}
|
||||
|
||||
if(pageCount <= 1) {
|
||||
$(`#apt-${prefix}-pag-divider, #apt-${prefix}-pag-dropdow-item`).hide();
|
||||
$(`#apt-${prefix}-pag-divider, #apt-${prefix}-pag-dropdow-item`).hide();
|
||||
return;
|
||||
}
|
||||
|
||||
$(`#apt-${prefix}-pag-divider, #apt-${prefix}-pag-dropdow-item`).show();
|
||||
$(`#apt-${prefix}-pag-divider, #apt-${prefix}-pag-dropdow-item`).show();
|
||||
|
||||
var limit = lastShownButton;
|
||||
|
||||
if(pageCount < limit) {
|
||||
limit = pageCount;
|
||||
if(pageCount < limit) {
|
||||
limit = pageCount;
|
||||
}
|
||||
|
||||
const firstPageLiClass = firstShownButton === 1 ? "page-item disabled" : "page-igem";
|
||||
const lastPageLiClass = lastShownButton === pageCount ? "page-item disabled" : "page-igem";
|
||||
const lastPageLiClass = lastShownButton === pageCount ? "page-item disabled" : "page-igem";
|
||||
|
||||
const prevPageLiClass = activeButton === 1 ? "page-item disabled" : "page-item";
|
||||
const nextPageLiClass = activeButton === pageCount ? "page-item disabled" : "page-igem";
|
||||
const nextPageLiClass = activeButton === pageCount ? "page-item disabled" : "page-igem";
|
||||
|
||||
$(`<li class="${firstPageLiClass}" id="first-page-li"><button type="button" class="page-link" tabeindex="-1" onclick="showPage(${1}, '${prefix}')"><span class="fas fa-angle-double-left"></span></button></li>`).appendTo(pagination);
|
||||
$(`<li class="${prevPageLiClass}" id="prev-page-li"><button type="button" class="page-link" tabeindex="-1" onclick="showPage(${currentPage - 1}, '${prefix}')"><span class="fas fa-angle-left"></span></button></li>`).appendTo(pagination);
|
||||
$(`<li class="${prevPageLiClass}" id="prev-page-li"><button type="button" class="page-link" tabeindex="-1" onclick="showPage(${currentPage - 1}, '${prefix}')"><span class="fas fa-angle-left"></span></button></li>`).appendTo(pagination);
|
||||
|
||||
for(let i = firstShownButton; i <= limit; i++) {
|
||||
$(`<li class="page-item ${(i === activeButton ? "active" : "")}"><button class="page-link" tabindex="-1" type="button" onclick="showPage(${i}, '${prefix}')">${i}</button></li>`).appendTo(pagination);
|
||||
$(`<li class="page-item ${(i === activeButton ? "active" : "")}"><button class="page-link" tabindex="-1" type="button" onclick="showPage(${i}, '${prefix}')">${i}</button></li>`).appendTo(pagination);
|
||||
}
|
||||
|
||||
$(`<li class="${nextPageLiClass}" id="next-page-li"><button type="button" class="page-link" tabeindex="-1" onclick="showPage(${currentPage + 1}, '${prefix}')"><span class="fas fa-angle-right"></span></button></li>`).appendTo(pagination);
|
||||
$(`<li class="${lastPageLiClass}" id="last-page-li"><button type="button" class="page-link" tabeindex="-1" onclick="showPage(${pageCount}, '${prefix}')"><span class="fas fa-angle-double-right"></span></button></li>`).appendTo(pagination);
|
||||
$(`<li class="${nextPageLiClass}" id="next-page-li"><button type="button" class="page-link" tabeindex="-1" onclick="showPage(${currentPage + 1}, '${prefix}')"><span class="fas fa-angle-right"></span></button></li>`).appendTo(pagination);
|
||||
$(`<li class="${lastPageLiClass}" id="last-page-li"><button type="button" class="page-link" tabeindex="-1" onclick="showPage(${pageCount}, '${prefix}')"><span class="fas fa-angle-double-right"></span></button></li>`).appendTo(pagination);
|
||||
}
|
||||
|
||||
function showPage(page, prefix) {
|
||||
@@ -388,8 +415,8 @@
|
||||
break;
|
||||
}
|
||||
|
||||
const total = (items.length / 10) | 0;
|
||||
const currentPage = Math.max(1, Math.min(page, total));
|
||||
const total = (items.length / 10) | 0;
|
||||
const currentPage = Math.max(1, Math.min(page, total));
|
||||
|
||||
switch(prefix) {
|
||||
case "emp":
|
||||
@@ -403,28 +430,28 @@
|
||||
break;
|
||||
}
|
||||
|
||||
const start = (currentPage - 1) * 10;
|
||||
const end = currentPage * 10;
|
||||
const start = (currentPage - 1) * 10;
|
||||
const end = currentPage * 10;
|
||||
|
||||
items.hide();
|
||||
items.hide();
|
||||
|
||||
$.each(items.slice(start, end), function(index, item) {
|
||||
$.each(items.slice(start, end), function(index, item) {
|
||||
$(item).removeClass("d-none");
|
||||
$(item).show();
|
||||
});
|
||||
|
||||
const last = Math.min(pageCount, currentPage + 2);
|
||||
const last = Math.min(pageCount, currentPage + 2);
|
||||
const first = Math.max(1, last - 4);
|
||||
|
||||
buildPagination(first, last, currentPage, prefix);
|
||||
buildPagination(first, last, currentPage, prefix);
|
||||
}
|
||||
|
||||
function updateEmployeeCustomerResourceSelection(prefix) {
|
||||
const checkedBoxes = $(`#dropdown-${prefix}-itm-container input[type=checkbox]:checked`);
|
||||
const checkedBoxes = $(`#dropdown-${prefix}-itm-container input[type=checkbox]:checked`);
|
||||
|
||||
var url = "";
|
||||
var url = "";
|
||||
|
||||
switch(prefix) {
|
||||
switch(prefix) {
|
||||
case "emp":
|
||||
url = "@Url.Action("UpdateAppointmentEmployeeSelection")";
|
||||
break;
|
||||
@@ -434,7 +461,7 @@
|
||||
case "res":
|
||||
url = "@Url.Action("UpdateAppointmentResourceSelection")";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var selectedOids = [];
|
||||
|
||||
@@ -449,7 +476,7 @@
|
||||
showSpinner();
|
||||
$.get(
|
||||
url,
|
||||
{ selectedOids: selectedOids.join(", ") },
|
||||
{ selectedOids: selectedOids.join(", ") },
|
||||
function(elementCount) {
|
||||
$(`#apt-${prefix}-badge`).text(elementCount);
|
||||
|
||||
@@ -459,28 +486,28 @@
|
||||
|
||||
|
||||
function selectAllEmployeeCustomerResource(prefix) {
|
||||
const isChecked = $(`#apt-${prefix}-select-all`).prop("checked");
|
||||
const isChecked = $(`#apt-${prefix}-select-all`).prop("checked");
|
||||
|
||||
$(`#dropdown-${prefix}-itm-container input[type=checkbox]`).prop("checked", isChecked);
|
||||
$(`#dropdown-${prefix}-itm-container input[type=checkbox]`).prop("checked", isChecked);
|
||||
|
||||
updateEmployeeCustomerResourceSelection(prefix);
|
||||
}
|
||||
|
||||
function categoryCardHeaderClick(collapsibleId) {
|
||||
const collapsible = $(`#${collapsibleId}`);
|
||||
function categoryCardHeaderClick(collapsibleId) {
|
||||
const collapsible = $(`#${collapsibleId}`);
|
||||
|
||||
if(collapsible.length === false) {
|
||||
return;
|
||||
if(collapsible.length === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
collapsible.collapse("toggle");
|
||||
collapsible.collapse("toggle");
|
||||
|
||||
const e = window.event;
|
||||
e.cancelBubble = true;
|
||||
const e = window.event;
|
||||
e.cancelBubble = true;
|
||||
|
||||
if(e.stopPropagation) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
if(e.stopPropagation) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
function onNewResourceSeachInput() {
|
||||
@@ -490,7 +517,7 @@
|
||||
const collapse = $(`#dropdown-res-itm-container .dropdown-item .collapse`);
|
||||
|
||||
if(searchText === null || searchText === undefined || searchText.length === 0) {
|
||||
showAllResources();
|
||||
showAllResources();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -498,7 +525,7 @@
|
||||
|
||||
$.each(category2Resources,
|
||||
function(index, item) {
|
||||
const categoryName = $(item).find("h6").text().toLowerCase();
|
||||
const categoryName = $(item).find("h6").text().toLowerCase();
|
||||
|
||||
if(categoryName.includes(searchText)) {
|
||||
$(item).show();
|
||||
@@ -521,20 +548,20 @@
|
||||
);
|
||||
}
|
||||
|
||||
function resetNewResourceSearch() {
|
||||
$(`#res-drop-search-input`).val("");
|
||||
function resetNewResourceSearch() {
|
||||
$(`#res-drop-search-input`).val("");
|
||||
|
||||
showAllResources();
|
||||
showAllResources();
|
||||
|
||||
buildPagination(1, 5, 1, "res");
|
||||
showPage(1, "res");
|
||||
buildPagination(1, 5, 1, "res");
|
||||
showPage(1, "res");
|
||||
|
||||
const e = window.event;
|
||||
e.cancelBubble = true;
|
||||
const e = window.event;
|
||||
e.cancelBubble = true;
|
||||
|
||||
if(e.stopPropagation) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
if(e.stopPropagation) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
function showAllResources() {
|
||||
@@ -551,7 +578,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
collapse.collapse("show");
|
||||
collapse.collapse("show");
|
||||
}
|
||||
@* /CustomECRSelectionPartial *@
|
||||
|
||||
@@ -562,9 +589,9 @@
|
||||
|
||||
|
||||
@* ToolTip *@
|
||||
var toolTipContext;
|
||||
function onToolTipDisplaying(s, e) {
|
||||
toolTipContext = e;
|
||||
var toolTipContext;
|
||||
function onToolTipDisplaying(s, e) {
|
||||
toolTipContext = e;
|
||||
|
||||
switch(e.toolTip.type) {
|
||||
case MVCxSchedulerToolTipType.Appointment:
|
||||
@@ -573,7 +600,7 @@
|
||||
onAppointmentDragTipDisplaying(s, e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="dropdown">
|
||||
|
||||
@@ -193,15 +193,9 @@
|
||||
settings.CustomActionRouteValues = new { Controller = "DevExpressScheduler", Action = "CustomCallBackAction" };
|
||||
|
||||
settings.ClientSideEvents.ToolTipDisplaying = "onToolTipDisplaying";
|
||||
settings.OptionsToolTips.SetAppointmentToolTipTemplateContent(() =>
|
||||
{
|
||||
Html.RenderPartial("CustomAppointmentToolTipPartial");
|
||||
});
|
||||
settings.OptionsToolTips.SetAppointmentToolTipTemplateContent(() => { Html.RenderPartial("CustomAppointmentToolTipPartial"); });
|
||||
settings.OptionsToolTips.SetAppointmentMobileToolTipTemplateContent(() => { Html.RenderPartial("CustomAppointmentToolTipPartial"); });
|
||||
settings.OptionsToolTips.SetAppointmentDragToolTipTemplateContent(() =>
|
||||
{
|
||||
Html.RenderPartial("CustomAppointmentDragToolTip");
|
||||
});
|
||||
settings.OptionsToolTips.SetAppointmentDragToolTipTemplateContent(() => { Html.RenderPartial("CustomAppointmentDragToolTip"); });
|
||||
|
||||
settings.OptionsCustomization.AllowInplaceEditor = UsedAppointmentType.None;
|
||||
settings.OptionsCustomization.AllowDisplayAppointmentFlyout = false;
|
||||
@@ -384,7 +378,9 @@
|
||||
IsTask = container.Appointment.CustomFields["IsTask"] is true,
|
||||
DueDate = container.Appointment.CustomFields["DueDate"] is DateTime dueDate ? dueDate : null,
|
||||
CompletedDate = container.Appointment.CustomFields["CompletedDate"] is DateTime completedDate ? completedDate : null,
|
||||
OriginatorOid = (container.Appointment.CustomFields["Originator"] as CompactEmployeeDC)?.EmployeeOid
|
||||
OriginatorOid = (container.Appointment.CustomFields["Originator"] as CompactEmployeeDC)?.EmployeeOid,
|
||||
RecurrenceInfo = container.Appointment.RecurrenceInfo?.ToXml(),
|
||||
RecurrenceIndex = container.Appointment.RecurrenceIndex
|
||||
};
|
||||
|
||||
var appointmentModel = ViewData["EditableAppointmentModel"] != null ? (AppointmentModel)ViewData["EditableAppointmentModel"] : newModel;
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
var $target;
|
||||
var targetIndex;
|
||||
|
||||
// Prüfen ob die Tab-Ansicht sichtbar ist (mehrere Dokutypes vorhanden)
|
||||
// Prüfen, ob die Tab-Ansicht sichtbar ist (mehrere Dokutypes vorhanden)
|
||||
var $activeTabTextarea = $('#dokufelderTab .tab-pane.active textarea');
|
||||
if ($activeTabTextarea.length > 0) {
|
||||
// Das aktive Tab-Textarea verwenden; Index aus der ID auslesen (sb-doku-textarea-{i})
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
oidString: selectedEmployeeOids.toString()
|
||||
},
|
||||
() => {
|
||||
$("#one-day-scheduler-partial-container").load('@Url.Action("FetchAppointments", "Scheduler")');
|
||||
@*$("#one-day-scheduler-partial-container").load('@Url.Action("FetchAppointments", "Scheduler")');*@
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,10 @@
|
||||
<link type="text/css" rel="stylesheet" href="@Url.Content("~/Content/dx.common.css")" />
|
||||
<link type="text/css" rel="stylesheet" href="@Url.Content("~/Content/dx.light.css")" />
|
||||
|
||||
<script>
|
||||
DevExpress.localization.locale("de");
|
||||
</script>
|
||||
|
||||
@* CSS für den neuen Kalender-Tooltip *@
|
||||
<style type="text/css">
|
||||
.toolTipPanel {
|
||||
@@ -406,16 +410,6 @@
|
||||
<ul class="navbar-nav ml-auto">
|
||||
@if (Html.IsInDebugMode())
|
||||
{
|
||||
using (Html.BeginForm("RedirectToDevExpressScheduler", "Main", FormMethod.Post))
|
||||
{
|
||||
<li class="nav-item">
|
||||
<button class="btn btn-link text-light no-underline" onclick="showSpinner()">
|
||||
<i class="far fa-calendar-alt text-bewo-calendar"></i>
|
||||
DX Kalender
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
|
||||
<li class="nav-item">
|
||||
<button class="btn btn-link text-light no-underline" type="button" onclick="printLocalStorage()">
|
||||
<i class="fab fa-firefox-browser text-bewo-dev"></i>
|
||||
@@ -433,6 +427,19 @@
|
||||
</li>
|
||||
}
|
||||
}
|
||||
|
||||
@if(Model.IsAllowedToSeeScheduler)
|
||||
{
|
||||
using (Html.BeginForm("RedirectToDevExpressScheduler", "Main", FormMethod.Post))
|
||||
{
|
||||
<li class="nav-item">
|
||||
<button class="btn btn-link text-light no-underline" onclick="showSpinner()">
|
||||
<i class="far fa-calendar-alt text-bewo-calendar"></i>
|
||||
DX Kalender
|
||||
</button>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
|
||||
@if (Model.IsAllowedToSeePersons)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
INSERT INTO `.executedscripts`
|
||||
VALUES ('Changes_2026-05-12 AiPromptbausteinRoutine Favoriten', CURDATE());
|
||||
|
||||
ALTER TABLE `aipromptbauteinroutine`
|
||||
ALTER TABLE `aipromptbausteinroutine`
|
||||
RENAME TO `aipromptbausteinroutine` ;
|
||||
|
||||
CREATE TABLE `aipromptbausteinroutine2empfavorite` (
|
||||
|
||||
@@ -272,5 +272,9 @@ namespace BeWo.Service.ServiceContracts
|
||||
[FaultContract(typeof(BeWoFault))]
|
||||
[OperationContract]
|
||||
Dictionary<DateTimeSpan, Dictionary<DateTime, bool>> FindAppointmentsInRangeForIntervalFinder(int duration, DateTime startDate, DateTime endDate, List<long> resourceOids, List<long> customerOids, List<long> employeeOids, long loggedInEmployeeOid, int intervalBuffer = 30, bool skipWeekends = true);
|
||||
|
||||
[FaultContract(typeof(BeWoFault))]
|
||||
[OperationContract]
|
||||
List<SchedulerAppointmentDC> LoadFilteredAppointmentsMitAufgabenForMoK(bool pHasRightToSeeAllEmployeeAppointments, long pEmployeeOid, DateTime pIntervalStart, DateTime pIntervalEnd, List<long> pSelectedEmployees, List<long> pSelectedCustomer, List<long> pSelectedResources, bool pEmployeesOnly, bool pCustomersOnly, bool pResourcesOnly, bool pPrivateAppointmentsOnly, bool pOnlyMyAppointments, bool pShowTasks);
|
||||
}
|
||||
}
|
||||
@@ -1191,6 +1191,7 @@ namespace BeWo.Service.ServiceImplementations
|
||||
ownerOid = pEmployeeOid;
|
||||
}
|
||||
|
||||
// ToDo: Mit lokaler Variable arbeiten, weil sonst der angemeldete Mitarbeiter ignoriert wird!
|
||||
if(!(!pHasRightToSeeAllEmployeeAppointments && pSelectedEmployees != null && pSelectedEmployees.Count == 1 && pSelectedEmployees.Contains(pEmployeeOid)))
|
||||
{
|
||||
//Rausnehmen, sonst werden Termine nicht gezeigt, bei denen man Owner ist und kein Employee ausgewählt wurde.
|
||||
@@ -2982,5 +2983,168 @@ namespace BeWo.Service.ServiceImplementations
|
||||
throw Utils.CreateBeWoFaultException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<SchedulerAppointmentDC> LoadFilteredAppointmentsMitAufgabenForMoK(bool pHasRightToSeeAllEmployeeAppointments, long pEmployeeOid, DateTime pIntervalStart, DateTime pIntervalEnd, List<long> pSelectedEmployees, List<long> pSelectedCustomer, List<long> pSelectedResources, bool pEmployeesOnly, bool pCustomersOnly, bool pResourcesOnly, bool pPrivateAppointmentsOnly, bool pOnlyMyAppointments, bool pShowTasks)
|
||||
{
|
||||
try
|
||||
{
|
||||
long? ownerOid = null;
|
||||
var selectedEmployees = new List<long>(pSelectedEmployees ?? new List<long>());
|
||||
|
||||
//Keine Auswahl getroffen: Nur meine Termine anzeigen
|
||||
if(selectedEmployees?.Count == 0 && pSelectedCustomer?.Count == 0 && pSelectedResources?.Count == 0)
|
||||
{
|
||||
ownerOid = pEmployeeOid;
|
||||
}
|
||||
|
||||
//Benutzer hat sich selber selektiert
|
||||
if((bool) selectedEmployees?.Exists(e => e == pEmployeeOid))
|
||||
{
|
||||
ownerOid = pEmployeeOid;
|
||||
}
|
||||
|
||||
//Man hat nur Customer und/oder Ressourcen ausgewählt, dann dürfen die eigenen nicht angezeigt werden
|
||||
if(selectedEmployees?.Count == 0 &&
|
||||
(pSelectedCustomer?.Count > 0 ||
|
||||
pSelectedResources?.Count > 0))
|
||||
{
|
||||
ownerOid = null;
|
||||
}
|
||||
|
||||
//Wenn man kein Recht hat alle zu sehen, muss immer auf Owner gefiltert werden, außer es sind Ressourcen vorhanden. Dann wird anonymisiert.
|
||||
if(!pHasRightToSeeAllEmployeeAppointments && pSelectedResources?.Count == 0)
|
||||
{
|
||||
ownerOid = pEmployeeOid;
|
||||
}
|
||||
|
||||
// ToDo: Mit lokaler Variable arbeiten, weil sonst der angemeldete Mitarbeiter ignoriert wird!
|
||||
if(!(!pHasRightToSeeAllEmployeeAppointments && selectedEmployees.Count == 1 && selectedEmployees.Contains(pEmployeeOid)))
|
||||
{
|
||||
//Rausnehmen, sonst werden Termine nicht gezeigt, bei denen man Owner ist und kein Employee ausgewählt wurde.
|
||||
//Wird nicht rausgenommen, wenn man die Termine anderer Mitarbeiter nicht sehen darf und "nur meine Termine" ausgewählt hat.
|
||||
//Sonst werden die Filter mit and und nicht mit or verknüpft.
|
||||
selectedEmployees?.Remove(pEmployeeOid);
|
||||
}
|
||||
|
||||
if(pPrivateAppointmentsOnly && selectedEmployees?.Count == 0 && pSelectedCustomer?.Count == 0 && pSelectedResources?.Count == 0 && selectedEmployees?.Count != 0 &&
|
||||
(pSelectedCustomer?.Count > 0 || pSelectedResources?.Count > 0))
|
||||
{
|
||||
ownerOid = pEmployeeOid;
|
||||
}
|
||||
|
||||
var appointments = DAOFactory.SearchDAO.LoadFilteredAppointmentsForEmployee(pHasRightToSeeAllEmployeeAppointments, ownerOid, pIntervalStart, pIntervalEnd, selectedEmployees, pSelectedCustomer, pSelectedResources, pEmployeesOnly, pCustomersOnly, pResourcesOnly, pPrivateAppointmentsOnly, pOnlyMyAppointments, false).ToList();
|
||||
|
||||
var serientermine = appointments.Where(app => app.RecurrenceInfo != null && app.Type == 1).ToList();
|
||||
|
||||
var all = MapperFactory.SchedulerAppointmentDCSchedulerAppointment.MapToNewDCs(appointments).OrderBy(a => a.StartDate).ToList();
|
||||
|
||||
var filteredEmployeeOids = new List<long>();
|
||||
if(ownerOid.HasValue)
|
||||
{
|
||||
filteredEmployeeOids.Add(ownerOid.Value);
|
||||
}
|
||||
|
||||
foreach(var empOid in selectedEmployees)
|
||||
{
|
||||
filteredEmployeeOids.Add(empOid);
|
||||
}
|
||||
|
||||
var result = FilterAppointments(all, pEmployeeOid, filteredEmployeeOids, pSelectedCustomer, pSelectedResources, pCustomersOnly, pResourcesOnly, pShowTasks);
|
||||
|
||||
//Check fehlerhafte RecurrenceInfos
|
||||
foreach(var app in result)
|
||||
{
|
||||
if(!IsNullOrEmpty(app.RecurrenceInfo))
|
||||
{
|
||||
if(app.RecurrenceInfo.Contains("WeekDays=\"0\""))
|
||||
{
|
||||
app.RecurrenceInfo = app.RecurrenceInfo.Replace("WeekDays=\"0\"", "WeekDays=\"2\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var test = result.Count;
|
||||
// Ausnahmen immer laden. Entsprechen die Ausnahmen nicht den Filterkriterien, werden sie als gelöscht markiert, um nicht auf dem Client angezeigt zu werden.
|
||||
var ausnahmen = MapperFactory.SchedulerAppointmentDCSchedulerAppointment.MapToNewDCs(DAOFactory.SearchDAO.FindAppointmentsByRecurrenecInfo(result.Where(w => w.Type == 1).Select(s => s.RecurrenceInfo).ToList(), true));
|
||||
var demFilterEntsprechendeTermine = FilterAppointments(ausnahmen, pEmployeeOid, filteredEmployeeOids, pSelectedCustomer, pSelectedResources, pCustomersOnly, pResourcesOnly, pShowTasks);
|
||||
|
||||
foreach(var appointment in ausnahmen.Where(w => !demFilterEntsprechendeTermine.Contains(w)))
|
||||
{
|
||||
var kosmetisch = new SchedulerAppointmentDC
|
||||
{
|
||||
SchedulerAppointmentOid = appointment.SchedulerAppointmentOid * -1,
|
||||
NewSchedulerAppointmentVersion = 1,
|
||||
Type = 4,
|
||||
RecurrenceInfo = appointment.RecurrenceInfo,
|
||||
EmployeeList = appointment.EmployeeList,
|
||||
CustomerList = appointment.CustomerList,
|
||||
ResourceList = appointment.ResourceList,
|
||||
Originator = appointment.Originator
|
||||
};
|
||||
|
||||
result.Add(kosmetisch);
|
||||
}
|
||||
|
||||
UserDC user;
|
||||
if(LoggedInUserOperationContextExt.Current != null && LoggedInUserOperationContextExt.Current.User != null)
|
||||
{
|
||||
user = MapperFactory.UserDC_User.MapToNewDC(LoggedInUserOperationContextExt.Current.User);
|
||||
}
|
||||
else
|
||||
{
|
||||
user = MapperFactory.UserDC_User.MapToNewDC(SessionFacade.LoggedInUser);
|
||||
}
|
||||
|
||||
var appointmentsToCheckForAnonymization = new List<SchedulerAppointmentDC>();
|
||||
|
||||
var relatedCustomerOids = DAOFactory.SearchDAO.FindTeamRelatedCustomerOids(user.Employee.EmployeeOid);
|
||||
|
||||
if(!(user is null))
|
||||
{
|
||||
// Bei ausgewählten Ressourcen oder auch "Nur Ressourcen" werden auch Termine mit den ausgewählten Ressourcen geladen und anonymisiert angezeigt, die der angemeldete Mitarbeiter nicht sehen darf.
|
||||
// ToDo: Hat man das Rechte "Alles Ansehen", wird nicht anonymisiert, da CheckSchedulerRights true zurückgibt!
|
||||
//var hasRightToSeeAll = user.HasRight(UserRightType.ViewAll);
|
||||
|
||||
//appointmentsToCheckForAnonymization =
|
||||
// pSelectedResources.Any() || pResourcesOnly ?
|
||||
// result.Where(w =>
|
||||
// w.ResourceList.Any() && false == SUtils.CheckSchedulerRights(w, SchedulerRightsCheckType.View, user, relatedCustomerOids, true)).ToList() :
|
||||
// new List<SchedulerAppointmentDC>();
|
||||
|
||||
AnonymizeAppointments(result.Where(w => false == SUtils.CheckSchedulerRights(w, SchedulerRightsCheckType.View, user, relatedCustomerOids, true)).ToList());
|
||||
|
||||
if(pSelectedResources?.Any() ?? false)
|
||||
{
|
||||
AnonymizeAppointments(result.Where(appointment => appointment.ResourceList.Any()).ToList());
|
||||
}
|
||||
|
||||
// Es wird nach zugewiesenen Rechten gefiltert und ob die Termine bereits in der Liste mit den anonymisierten Terminen sind.
|
||||
//result = result.Where(w => (!w.ResourceList.Any() || SUtils.CheckSchedulerRights(w, SchedulerRightsCheckType.View, user, relatedCustomerOids, true)) && !appointmentsToCheckForAnonymization.Any(a => a.SchedulerAppointmentOid == w.SchedulerAppointmentOid)).ToList();
|
||||
|
||||
//result.AddRange(appointmentsToCheckForAnonymization);
|
||||
}
|
||||
|
||||
// Aufgaben laden
|
||||
ConvertOldTasks(pEmployeeOid);
|
||||
|
||||
var taskAppointmentDCs = MapperFactory.SchedulerAppointmentDCSchedulerAppointment.MapToNewDCs(DAOFactory.SearchDAO.LoadTaskAppointmentsForEmployee(pEmployeeOid, true));
|
||||
|
||||
result.AddRangeIfElementsNotIn(taskAppointmentDCs);
|
||||
|
||||
//DebugUtils.WriteToLogFile($"{DateTime.Now:dd.MM.yyyy HH:mm:ss:fff}: {result.Count} Termine und {result.Count(w => w.IsTask)} Aufgaben aus der Datenbank geladen. {appointmentsToCheckForAnonymization.Count} davon anonymisiert.");
|
||||
Debug.WriteLine($"+++>{DateTime.Now:dd.MM.yyyy HH:mm:ss:fff}: {result.Count} Termine und {result.Count(w => w.IsTask)} Aufgaben aus der Datenbank geladen. {appointmentsToCheckForAnonymization.Count} davon anonymisiert.");
|
||||
|
||||
// ToDo: durch jeden Termin gehen und prüfen, ob Klienten oder Mitarbeiter anonymisiert und auf read-only gesetzt werden müssen?
|
||||
var appointmentsToBeAnonymized = result.Where(a => !SUtils.CheckSchedulerRights(a, SchedulerRightsCheckType.View, user, relatedCustomerOids, true)).ToList();
|
||||
|
||||
var rest = result.Except(appointmentsToBeAnonymized);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
throw Utils.CreateBeWoFaultException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ namespace BeWoDatabaseUpdater
|
||||
|
||||
Console.WriteLine($"{DateTime.Now:dd.MM.yyyy HH:mm:ss.fff}: Führe Updates durch ...{Environment.NewLine}");
|
||||
|
||||
_BeWoSchemaNames = await MySqlBeWoHelper.LoadBeWoDatabaseNames(_ConnectionString) ?? [];
|
||||
_BeWoSchemaNames = ["3522103738"]; //await MySqlBeWoHelper.LoadBeWoDatabaseNames(_ConnectionString) ?? [];
|
||||
|
||||
LoadSqlScriptsFromFilesToMemory(() =>
|
||||
{
|
||||
@@ -74,6 +74,11 @@ namespace BeWoDatabaseUpdater
|
||||
|
||||
_FilePaths2Sql.DoForEach(path2Commands =>
|
||||
{
|
||||
if(path2Commands is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
commandCount += path2Commands.Commands.Count;
|
||||
fileCount++;
|
||||
});
|
||||
@@ -160,6 +165,8 @@ namespace BeWoDatabaseUpdater
|
||||
//MySqlBeWoHelper.WriteSqlErrorsToFile();
|
||||
|
||||
MySqlBeWoHelper.DistinctErrors.DoForEach(number2Message => Console.WriteLine($"{number2Message.Key}: {number2Message.Value}"));
|
||||
|
||||
Console.WriteLine("Alle Updates durchgeführt!");
|
||||
}
|
||||
|
||||
private static void GetTextAndSqlFiles()
|
||||
|
||||
Reference in New Issue
Block a user